{"action":"created","comment":{"url":"https://api.github.com/repos/swaywm/wlroots/pulls/comments/191078507","pull_request_review_id":123585903,"id":191078507,"diff_hunk":"@@ -0,0 +1,208 @@\n+#define _POSIX_C_SOURCE 1\n+#include <assert.h>\n+#include <stdlib.h>\n+#include <sys/mman.h>\n+#include <wlr/types/wlr_seat.h>\n+#include <wlr/types/wlr_virtual_keyboard.h>\n+#include <wlr/util/log.h>\n+#include <xkbcommon/xkbcommon.h>\n+#include \"util/signal.h\"\n+#include \"virtual-keyboard-unstable-v1-protocol.h\"\n+\n+\n+static void keyboard_led_update(struct wlr_keyboard *wlr_kb, uint32_t leds) {\n+\t// unsupported by virtual keyboard protocol\n+}\n+\n+static void keyboard_destroy(struct wlr_keyboard *wlr_kb) {\n+\t// safe to ignore - keyboard will be destroyed only iff associated virtual\n+\t// keyboard is torn down, no need to tear down the keyboard separately\n+}\n+\n+static const struct wlr_keyboard_impl keyboard_impl = {\n+\t.destroy = keyboard_destroy,\n+\t.led_update = keyboard_led_update\n+};\n+\n+static void input_device_destroy(struct wlr_input_device *dev) {\n+}\n+\n+static const struct wlr_input_device_impl input_device_impl = {\n+\t.destroy = input_device_destroy\n+};\n+\n+static const struct zwp_virtual_keyboard_v1_interface virtual_keyboard_impl;\n+\n+static struct wlr_virtual_keyboard *virtual_keyboard_from_resource(\n+\t\tstruct wl_resource *resource) {\n+\tassert(wl_resource_instance_of(resource,\n+\t\t&zwp_virtual_keyboard_v1_interface, &virtual_keyboard_impl));\n+\treturn wl_resource_get_user_data(resource);\n+}\n+\n+static void virtual_keyboard_keymap(struct wl_client *client,\n+\t\tstruct wl_resource *resource, uint32_t format, int32_t fd,\n+\t\tuint32_t size) {\n+\tstruct wlr_virtual_keyboard *keyboard =\n+\t\tvirtual_keyboard_from_resource(resource);\n+\n+\tstruct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);\n+\tif (!context) {\n+\t\tgoto context_fail;\n+\t}\n+\tvoid *data = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);\n+\tif (!data) {\n+\t\tgoto fd_fail;\n+\t}\n+\tstruct xkb_keymap *keymap = xkb_keymap_new_from_string(context, data,\n+\t\tXKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);\n+\tif (!keymap) {\n+\t\tgoto keymap_fail;\n+\t}\n+\twlr_keyboard_set_keymap(keyboard->input_device.keyboard, keymap);\n+\txkb_keymap_unref(keymap);\n+\txkb_context_unref(context);\n+\treturn;\n+keymap_fail:\n+\tmunmap(data, size);\n+fd_fail:\n+\txkb_context_unref(context);\n+context_fail:\n+\twl_client_post_no_memory(client);\n+}\n+\n+static void virtual_keyboard_key(struct wl_client *client,\n+\t\tstruct wl_resource *resource, uint32_t time, uint32_t key,\n+\t\tuint32_t state) {\n+\tstruct wlr_virtual_keyboard *keyboard =\n+\t\tvirtual_keyboard_from_resource(resource);\n+\tstruct wlr_event_keyboard_key event = {\n+\t\t.time_msec = time,\n+\t\t.keycode = key,\n+\t\t.update_state = false,\n+\t\t.state = state,\n+\t};\n+\twlr_keyboard_notify_key(keyboard->input_device.keyboard, &event);\n+}\n+\n+static void virtual_keyboard_modifiers(struct wl_client *client,\n+\t\tstruct wl_resource *resource, uint32_t mods_depressed,\n+\t\tuint32_t mods_latched, uint32_t mods_locked, uint32_t group) {\n+\tstruct wlr_virtual_keyboard *keyboard =\n+\t\tvirtual_keyboard_from_resource(resource);\n+\twlr_keyboard_notify_modifiers(keyboard->input_device.keyboard,\n+\t\tmods_depressed, mods_latched, mods_locked, group);\n+}\n+\n+static void virtual_keyboard_destroy_resource(struct wl_resource *resource) {\n+\tstruct wlr_virtual_keyboard *keyboard =\n+\t\tvirtual_keyboard_from_resource(resource);\n+\twlr_signal_emit_safe(&keyboard->events.destroy, keyboard);\n+\twlr_keyboard_destroy(keyboard->input_device.keyboard);\n+\tfree(keyboard);\n+}\n+\n+static void virtual_keyboard_destroy(struct wl_client *client,\n+\t\tstruct wl_resource *resource) {\n+\tvirtual_keyboard_destroy_resource(resource);\n+}\n+\n+static const struct zwp_virtual_keyboard_v1_interface virtual_keyboard_impl = {\n+\t.keymap = virtual_keyboard_keymap,\n+\t.key = virtual_keyboard_key,\n+\t.modifiers = virtual_keyboard_modifiers,\n+\t.destroy = virtual_keyboard_destroy,\n+};\n+\n+static const struct zwp_virtual_keyboard_manager_v1_interface manager_impl;\n+\n+static struct wlr_virtual_keyboard_manager *manager_from_resource(\n+\t\tstruct wl_resource *resource) {\n+\tassert(wl_resource_instance_of(resource,\n+\t\t&zwp_virtual_keyboard_manager_v1_interface, &manager_impl));\n+\treturn wl_resource_get_user_data(resource);\n+}\n+\n+static void virtual_keyboard_manager_create_virtual_keyboard(\n+\t\tstruct wl_client *client, struct wl_resource *resource,\n+\t\tstruct wl_resource *seat,\n+\t\tuint32_t id) {\n+\tstruct wlr_virtual_keyboard_manager *manager =\n+\t\tmanager_from_resource(resource);\n+\n+\tstruct wlr_virtual_keyboard *virtual_keyboard = calloc(1,\n+\t\tsizeof(struct wlr_virtual_keyboard));\n+\tif (!virtual_keyboard) {\n+\t\twl_client_post_no_memory(client);\n+\t\treturn;\n+\t}\n+\n+\tstruct wlr_keyboard* keyboard = calloc(1, sizeof(struct wlr_keyboard));\n+\tif (!keyboard) {\n+\t\twlr_log(L_ERROR, \"Cannot allocate wlr_keyboard\");\n+\t\tfree(virtual_keyboard);\n+\t\twl_client_post_no_memory(client);\n+\t\treturn;\n+\t}\n+\twlr_keyboard_init(keyboard, &keyboard_impl);\n+\n+\tstruct wl_resource *keyboard_resource = wl_resource_create(client,\n+\t\t&zwp_virtual_keyboard_v1_interface, wl_resource_get_version(resource),\n+\t\tid);\n+\tif (!keyboard_resource) {\n+\t\tfree(keyboard);\n+\t\tfree(virtual_keyboard);\n+\t\twl_client_post_no_memory(client);\n+\t\treturn;\n+\t}\n+\n+\twl_resource_set_implementation(keyboard_resource, &virtual_keyboard_impl,\n+\t\tvirtual_keyboard, virtual_keyboard_destroy_resource);\n+\n+\twlr_input_device_init(&virtual_keyboard->input_device,\n+\t\tWLR_INPUT_DEVICE_KEYBOARD, &input_device_impl, \"virtual keyboard\",\n+\t\t0xabcd, 0x1234);\n+\n+\tstruct wlr_seat_client *seat_client = wlr_seat_client_from_resource(seat);\n+\n+\tvirtual_keyboard->input_device.keyboard = keyboard;\n+\tvirtual_keyboard->resource = keyboard_resource;\n+\tvirtual_keyboard->seat = seat_client->seat;\n+\twl_signal_init(&virtual_keyboard->events.destroy);\n+\twlr_signal_emit_safe(&manager->events.new_virtual_keyboard, virtual_keyboard);","path":"types/wlr_virtual_keyboard.c","position":172,"original_position":172,"commit_id":"9196d22055e36bc59d9780e30c83e47c47f06033","original_commit_id":"8c64f160b62be7fb5ebc547f2b9c04ae0f3a2331","user":{"login":"emersion","id":506932,"avatar_url":"https://avatars1.githubusercontent.com/u/506932?v=4","gravatar_id":"","url":"https://api.github.com/users/emersion","html_url":"https://github.com/emersion","followers_url":"https://api.github.com/users/emersion/followers","following_url":"https://api.github.com/users/emersion/following{/other_user}","gists_url":"https://api.github.com/users/emersion/gists{/gist_id}","starred_url":"https://api.github.com/users/emersion/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/emersion/subscriptions","organizations_url":"https://api.github.com/users/emersion/orgs","repos_url":"https://api.github.com/users/emersion/repos","events_url":"https://api.github.com/users/emersion/events{/privacy}","received_events_url":"https://api.github.com/users/emersion/received_events","type":"User","site_admin":false},"body":"Let the users iterate on the list and properly cleanup when destroying the manager.","created_at":"2018-05-27T14:34:27Z","updated_at":"2018-05-27T14:34:28Z","html_url":"https://github.com/swaywm/wlroots/pull/999#discussion_r191078507","pull_request_url":"https://api.github.com/repos/swaywm/wlroots/pulls/999","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/swaywm/wlroots/pulls/comments/191078507"},"html":{"href":"https://github.com/swaywm/wlroots/pull/999#discussion_r191078507"},"pull_request":{"href":"https://api.github.com/repos/swaywm/wlroots/pulls/999"}},"in_reply_to_id":191076915},"pull_request":{"url":"https://api.github.com/repos/swaywm/wlroots/pulls/999","id":190378305,"html_url":"https://github.com/swaywm/wlroots/pull/999","diff_url":"https://github.com/swaywm/wlroots/pull/999.diff","patch_url":"https://github.com/swaywm/wlroots/pull/999.patch","issue_url":"https://api.github.com/repos/swaywm/wlroots/issues/999","number":999,"state":"open","locked":false,"title":"Support virtual keyboard protocol","user":{"login":"dcz-purism","id":37271098,"avatar_url":"https://avatars0.githubusercontent.com/u/37271098?v=4","gravatar_id":"","url":"https://api.github.com/users/dcz-purism","html_url":"https://github.com/dcz-purism","followers_url":"https://api.github.com/users/dcz-purism/followers","following_url":"https://api.github.com/users/dcz-purism/following{/other_user}","gists_url":"https://api.github.com/users/dcz-purism/gists{/gist_id}","starred_url":"https://api.github.com/users/dcz-purism/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dcz-purism/subscriptions","organizations_url":"https://api.github.com/users/dcz-purism/orgs","repos_url":"https://api.github.com/users/dcz-purism/repos","events_url":"https://api.github.com/users/dcz-purism/events{/privacy}","received_events_url":"https://api.github.com/users/dcz-purism/received_events","type":"User","site_admin":false},"body":"This change is to support the recently proposed `virtual-keyboard-v1` protocol.\r\n\r\nBecause virtual keyboards are privileged, the commits setting up an authorization system - meant to be general for all input methods - are separate.\r\n\r\nThe main commit provides support in wlroots as well as rootston. The keyboard does not attempt to synchronize its modifier status with the rest of the system, and code for having multiple instances running at the same time has not been extensively tested, however it's rather simple and wasn't failing either.","created_at":"2018-05-24T18:21:09Z","updated_at":"2018-05-27T14:34:28Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c47c4c14d875660fcff6c01a60a364f7c47ab389","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/swaywm/wlroots/pulls/999/commits","review_comments_url":"https://api.github.com/repos/swaywm/wlroots/pulls/999/comments","review_comment_url":"https://api.github.com/repos/swaywm/wlroots/pulls/comments{/number}","comments_url":"https://api.github.com/repos/swaywm/wlroots/issues/999/comments","statuses_url":"https://api.github.com/repos/swaywm/wlroots/statuses/9196d22055e36bc59d9780e30c83e47c47f06033","head":{"label":"dcz-purism:virtual-keyboard","ref":"virtual-keyboard","sha":"9196d22055e36bc59d9780e30c83e47c47f06033","user":{"login":"dcz-purism","id":37271098,"avatar_url":"https://avatars0.githubusercontent.com/u/37271098?v=4","gravatar_id":"","url":"https://api.github.com/users/dcz-purism","html_url":"https://github.com/dcz-purism","followers_url":"https://api.github.com/users/dcz-purism/followers","following_url":"https://api.github.com/users/dcz-purism/following{/other_user}","gists_url":"https://api.github.com/users/dcz-purism/gists{/gist_id}","starred_url":"https://api.github.com/users/dcz-purism/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dcz-purism/subscriptions","organizations_url":"https://api.github.com/users/dcz-purism/orgs","repos_url":"https://api.github.com/users/dcz-purism/repos","events_url":"https://api.github.com/users/dcz-purism/events{/privacy}","received_events_url":"https://api.github.com/users/dcz-purism/received_events","type":"User","site_admin":false},"repo":{"id":127146104,"name":"wlroots","full_name":"dcz-purism/wlroots","owner":{"login":"dcz-purism","id":37271098,"avatar_url":"https://avatars0.githubusercontent.com/u/37271098?v=4","gravatar_id":"","url":"https://api.github.com/users/dcz-purism","html_url":"https://github.com/dcz-purism","followers_url":"https://api.github.com/users/dcz-purism/followers","following_url":"https://api.github.com/users/dcz-purism/following{/other_user}","gists_url":"https://api.github.com/users/dcz-purism/gists{/gist_id}","starred_url":"https://api.github.com/users/dcz-purism/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dcz-purism/subscriptions","organizations_url":"https://api.github.com/users/dcz-purism/orgs","repos_url":"https://api.github.com/users/dcz-purism/repos","events_url":"https://api.github.com/users/dcz-purism/events{/privacy}","received_events_url":"https://api.github.com/users/dcz-purism/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/dcz-purism/wlroots","description":"A modular Wayland compositor library","fork":true,"url":"https://api.github.com/repos/dcz-purism/wlroots","forks_url":"https://api.github.com/repos/dcz-purism/wlroots/forks","keys_url":"https://api.github.com/repos/dcz-purism/wlroots/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dcz-purism/wlroots/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dcz-purism/wlroots/teams","hooks_url":"https://api.github.com/repos/dcz-purism/wlroots/hooks","issue_events_url":"https://api.github.com/repos/dcz-purism/wlroots/issues/events{/number}","events_url":"https://api.github.com/repos/dcz-purism/wlroots/events","assignees_url":"https://api.github.com/repos/dcz-purism/wlroots/assignees{/user}","branches_url":"https://api.github.com/repos/dcz-purism/wlroots/branches{/branch}","tags_url":"https://api.github.com/repos/dcz-purism/wlroots/tags","blobs_url":"https://api.github.com/repos/dcz-purism/wlroots/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dcz-purism/wlroots/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dcz-purism/wlroots/git/refs{/sha}","trees_url":"https://api.github.com/repos/dcz-purism/wlroots/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dcz-purism/wlroots/statuses/{sha}","languages_url":"https://api.github.com/repos/dcz-purism/wlroots/languages","stargazers_url":"https://api.github.com/repos/dcz-purism/wlroots/stargazers","contributors_url":"https://api.github.com/repos/dcz-purism/wlroots/contributors","subscribers_url":"https://api.github.com/repos/dcz-purism/wlroots/subscribers","subscription_url":"https://api.github.com/repos/dcz-purism/wlroots/subscription","commits_url":"https://api.github.com/repos/dcz-purism/wlroots/commits{/sha}","git_commits_url":"https://api.github.com/repos/dcz-purism/wlroots/git/commits{/sha}","comments_url":"https://api.github.com/repos/dcz-purism/wlroots/comments{/number}","issue_comment_url":"https://api.github.com/repos/dcz-purism/wlroots/issues/comments{/number}","contents_url":"https://api.github.com/repos/dcz-purism/wlroots/contents/{+path}","compare_url":"https://api.github.com/repos/dcz-purism/wlroots/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dcz-purism/wlroots/merges","archive_url":"https://api.github.com/repos/dcz-purism/wlroots/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dcz-purism/wlroots/downloads","issues_url":"https://api.github.com/repos/dcz-purism/wlroots/issues{/number}","pulls_url":"https://api.github.com/repos/dcz-purism/wlroots/pulls{/number}","milestones_url":"https://api.github.com/repos/dcz-purism/wlroots/milestones{/number}","notifications_url":"https://api.github.com/repos/dcz-purism/wlroots/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dcz-purism/wlroots/labels{/name}","releases_url":"https://api.github.com/repos/dcz-purism/wlroots/releases{/id}","deployments_url":"https://api.github.com/repos/dcz-purism/wlroots/deployments","created_at":"2018-03-28T13:40:15Z","updated_at":"2018-05-24T14:16:06Z","pushed_at":"2018-05-27T14:07:09Z","git_url":"git://github.com/dcz-purism/wlroots.git","ssh_url":"git@github.com:dcz-purism/wlroots.git","clone_url":"https://github.com/dcz-purism/wlroots.git","svn_url":"https://github.com/dcz-purism/wlroots","homepage":"http://swaywm.org","size":4439,"stargazers_count":0,"watchers_count":0,"language":"C","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"swaywm:master","ref":"master","sha":"f95bd1facf5b61efc72ac9c09480d77fea6ee39a","user":{"login":"swaywm","id":32400794,"avatar_url":"https://avatars1.githubusercontent.com/u/32400794?v=4","gravatar_id":"","url":"https://api.github.com/users/swaywm","html_url":"https://github.com/swaywm","followers_url":"https://api.github.com/users/swaywm/followers","following_url":"https://api.github.com/users/swaywm/following{/other_user}","gists_url":"https://api.github.com/users/swaywm/gists{/gist_id}","starred_url":"https://api.github.com/users/swaywm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/swaywm/subscriptions","organizations_url":"https://api.github.com/users/swaywm/orgs","repos_url":"https://api.github.com/users/swaywm/repos","events_url":"https://api.github.com/users/swaywm/events{/privacy}","received_events_url":"https://api.github.com/users/swaywm/received_events","type":"Organization","site_admin":false},"repo":{"id":89377392,"name":"wlroots","full_name":"swaywm/wlroots","owner":{"login":"swaywm","id":32400794,"avatar_url":"https://avatars1.githubusercontent.com/u/32400794?v=4","gravatar_id":"","url":"https://api.github.com/users/swaywm","html_url":"https://github.com/swaywm","followers_url":"https://api.github.com/users/swaywm/followers","following_url":"https://api.github.com/users/swaywm/following{/other_user}","gists_url":"https://api.github.com/users/swaywm/gists{/gist_id}","starred_url":"https://api.github.com/users/swaywm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/swaywm/subscriptions","organizations_url":"https://api.github.com/users/swaywm/orgs","repos_url":"https://api.github.com/users/swaywm/repos","events_url":"https://api.github.com/users/swaywm/events{/privacy}","received_events_url":"https://api.github.com/users/swaywm/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/swaywm/wlroots","description":"A modular Wayland compositor library","fork":false,"url":"https://api.github.com/repos/swaywm/wlroots","forks_url":"https://api.github.com/repos/swaywm/wlroots/forks","keys_url":"https://api.github.com/repos/swaywm/wlroots/keys{/key_id}","collaborators_url":"https://api.github.com/repos/swaywm/wlroots/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/swaywm/wlroots/teams","hooks_url":"https://api.github.com/repos/swaywm/wlroots/hooks","issue_events_url":"https://api.github.com/repos/swaywm/wlroots/issues/events{/number}","events_url":"https://api.github.com/repos/swaywm/wlroots/events","assignees_url":"https://api.github.com/repos/swaywm/wlroots/assignees{/user}","branches_url":"https://api.github.com/repos/swaywm/wlroots/branches{/branch}","tags_url":"https://api.github.com/repos/swaywm/wlroots/tags","blobs_url":"https://api.github.com/repos/swaywm/wlroots/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/swaywm/wlroots/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/swaywm/wlroots/git/refs{/sha}","trees_url":"https://api.github.com/repos/swaywm/wlroots/git/trees{/sha}","statuses_url":"https://api.github.com/repos/swaywm/wlroots/statuses/{sha}","languages_url":"https://api.github.com/repos/swaywm/wlroots/languages","stargazers_url":"https://api.github.com/repos/swaywm/wlroots/stargazers","contributors_url":"https://api.github.com/repos/swaywm/wlroots/contributors","subscribers_url":"https://api.github.com/repos/swaywm/wlroots/subscribers","subscription_url":"https://api.github.com/repos/swaywm/wlroots/subscription","commits_url":"https://api.github.com/repos/swaywm/wlroots/commits{/sha}","git_commits_url":"https://api.github.com/repos/swaywm/wlroots/git/commits{/sha}","comments_url":"https://api.github.com/repos/swaywm/wlroots/comments{/number}","issue_comment_url":"https://api.github.com/repos/swaywm/wlroots/issues/comments{/number}","contents_url":"https://api.github.com/repos/swaywm/wlroots/contents/{+path}","compare_url":"https://api.github.com/repos/swaywm/wlroots/compare/{base}...{head}","merges_url":"https://api.github.com/repos/swaywm/wlroots/merges","archive_url":"https://api.github.com/repos/swaywm/wlroots/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/swaywm/wlroots/downloads","issues_url":"https://api.github.com/repos/swaywm/wlroots/issues{/number}","pulls_url":"https://api.github.com/repos/swaywm/wlroots/pulls{/number}","milestones_url":"https://api.github.com/repos/swaywm/wlroots/milestones{/number}","notifications_url":"https://api.github.com/repos/swaywm/wlroots/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/swaywm/wlroots/labels{/name}","releases_url":"https://api.github.com/repos/swaywm/wlroots/releases{/id}","deployments_url":"https://api.github.com/repos/swaywm/wlroots/deployments","created_at":"2017-04-25T15:33:43Z","updated_at":"2018-05-27T12:58:08Z","pushed_at":"2018-05-27T14:07:11Z","git_url":"git://github.com/swaywm/wlroots.git","ssh_url":"git@github.com:swaywm/wlroots.git","clone_url":"https://github.com/swaywm/wlroots.git","svn_url":"https://github.com/swaywm/wlroots","homepage":"http://swaywm.org","size":4398,"stargazers_count":403,"watchers_count":403,"language":"C","has_issues":true,"has_projects":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":75,"mirror_url":null,"archived":false,"open_issues_count":114,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit"},"forks":75,"open_issues":114,"watchers":403,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/swaywm/wlroots/pulls/999"},"html":{"href":"https://github.com/swaywm/wlroots/pull/999"},"issue":{"href":"https://api.github.com/repos/swaywm/wlroots/issues/999"},"comments":{"href":"https://api.github.com/repos/swaywm/wlroots/issues/999/comments"},"review_comments":{"href":"https://api.github.com/repos/swaywm/wlroots/pulls/999/comments"},"review_comment":{"href":"https://api.github.com/repos/swaywm/wlroots/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/swaywm/wlroots/pulls/999/commits"},"statuses":{"href":"https://api.github.com/repos/swaywm/wlroots/statuses/9196d22055e36bc59d9780e30c83e47c47f06033"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"emersion"}}