commit 600a874
Michael Forney
·
2018-11-10 00:02:22 +0000 UTC
parent 97069f8
input: Send keyboard/pointer events for each instance a client has bound Some clients (like firefox) may bind multiple wl_keyboard instances, and expect key press events on each one.
5 files changed,
+75,
-66
+29,
-24
1@@ -30,19 +30,23 @@
2 static inline void
3 focus(struct input_focus *input_focus, struct compositor_view *view)
4 {
5- struct wl_resource *resource = NULL;
6+ struct wl_client *client = NULL;
7+ struct wl_resource *resource, *tmp;
8
9 if (view) {
10- struct wl_client *client;
11-
12 client = wl_resource_get_client(view->surface->resource);
13- resource = wl_resource_find_for_client(&input_focus->resources, client);
14+ wl_resource_for_each_safe (resource, tmp, &input_focus->inactive) {
15+ if (wl_resource_get_client(resource) == client) {
16+ wl_list_remove(wl_resource_get_link(resource));
17+ wl_list_insert(&input_focus->active, wl_resource_get_link(resource));
18+ }
19+ }
20 wl_signal_add(&view->destroy_signal, &input_focus->view_destroy_listener);
21 }
22
23+ input_focus->client = client;
24 input_focus->view = view;
25- input_focus->resource = resource;
26- input_focus->handler->enter(input_focus->handler, resource, view);
27+ input_focus->handler->enter(input_focus->handler, &input_focus->active, view);
28 }
29
30 static inline void
31@@ -50,7 +54,9 @@ unfocus(struct input_focus *input_focus)
32 {
33 if (input_focus->view)
34 wl_list_remove(&input_focus->view_destroy_listener.link);
35- input_focus->handler->leave(input_focus->handler, input_focus->resource, input_focus->view);
36+ input_focus->handler->leave(input_focus->handler, &input_focus->active, input_focus->view);
37+ wl_list_insert_list(&input_focus->inactive, &input_focus->active);
38+ wl_list_init(&input_focus->active);
39 }
40
41 static void
42@@ -58,19 +64,23 @@ handle_focus_view_destroy(struct wl_listener *listener, void *data)
43 {
44 struct input_focus *input_focus = wl_container_of(listener, input_focus, view_destroy_listener);
45
46- input_focus->resource = NULL;
47+ /* XXX: Should this call unfocus? */
48+ wl_list_insert_list(&input_focus->inactive, &input_focus->active);
49+ wl_list_init(&input_focus->active);
50+ input_focus->client = NULL;
51 input_focus->view = NULL;
52 }
53
54 bool
55 input_focus_initialize(struct input_focus *input_focus, struct input_focus_handler *handler)
56 {
57- input_focus->resource = NULL;
58+ input_focus->client = NULL;
59 input_focus->view = NULL;
60 input_focus->view_destroy_listener.notify = &handle_focus_view_destroy;
61 input_focus->handler = handler;
62
63- wl_list_init(&input_focus->resources);
64+ wl_list_init(&input_focus->active);
65+ wl_list_init(&input_focus->inactive);
66 wl_signal_init(&input_focus->event_signal);
67
68 return true;
69@@ -85,29 +95,24 @@ input_focus_finalize(struct input_focus *input_focus)
70 void
71 input_focus_add_resource(struct input_focus *input_focus, struct wl_resource *resource)
72 {
73- /* If this new input resource corresponds to our focus, set it as our focus. */
74- if (input_focus->view) {
75- struct wl_client *client, *surface_client;
76+ struct wl_list resources, *target = &input_focus->inactive;
77
78- client = wl_resource_get_client(resource);
79- surface_client = wl_resource_get_client(input_focus->view->surface->resource);
80+ wl_list_init(&resources);
81+ wl_list_insert(&resources, wl_resource_get_link(resource));
82
83- if (client == surface_client) {
84- input_focus->handler->enter(input_focus->handler, resource, input_focus->view);
85- input_focus->resource = resource;
86- }
87+ /* If this new input resource corresponds to the focused client, send an enter event. */
88+ if (wl_resource_get_client(resource) == input_focus->client) {
89+ input_focus->handler->enter(input_focus->handler, &resources, input_focus->view);
90+ target = &input_focus->active;
91 }
92
93- wl_list_insert(&input_focus->resources, wl_resource_get_link(resource));
94+ wl_list_insert_list(target, &resources);
95 }
96
97 void
98 input_focus_remove_resource(struct input_focus *input_focus, struct wl_resource *resource)
99 {
100- if (resource == input_focus->resource)
101- input_focus->resource = NULL;
102-
103- remove_resource(resource);
104+ wl_list_remove(wl_resource_get_link(resource));
105 }
106
107 void
+4,
-4
1@@ -38,17 +38,17 @@ struct input_focus_event_data {
2 };
3
4 struct input_focus_handler {
5- void (*enter)(struct input_focus_handler *handler, struct wl_resource *resource, struct compositor_view *view);
6- void (*leave)(struct input_focus_handler *handler, struct wl_resource *resource, struct compositor_view *view);
7+ void (*enter)(struct input_focus_handler *handler, struct wl_list *resources, struct compositor_view *view);
8+ void (*leave)(struct input_focus_handler *handler, struct wl_list *resources, struct compositor_view *view);
9 };
10
11 struct input_focus {
12- struct wl_resource *resource;
13+ struct wl_client *client;
14 struct compositor_view *view;
15 struct wl_listener view_destroy_listener;
16
17 struct input_focus_handler *handler;
18- struct wl_list resources;
19+ struct wl_list active, inactive;
20
21 struct wl_signal event_signal;
22 };
+18,
-20
1@@ -44,34 +44,36 @@ static const int repeat_delay = 500, repeat_rate = 40;
2 static const char keymap_file_template[] = "swc-xkb-keymap-XXXXXX";
3
4 static void
5-enter(struct input_focus_handler *handler, struct wl_resource *resource, struct compositor_view *view)
6+enter(struct input_focus_handler *handler, struct wl_list *resources, struct compositor_view *view)
7 {
8 struct keyboard *keyboard = wl_container_of(handler, keyboard, focus_handler);
9 struct keyboard_modifier_state *state = &keyboard->modifier_state;
10+ struct wl_resource *resource;
11 uint32_t serial;
12
13- if (!resource)
14- return;
15 serial = wl_display_next_serial(swc.display);
16- wl_keyboard_send_modifiers(resource, serial, state->depressed, state->locked, state->latched, state->group);
17- wl_keyboard_send_enter(resource, serial, view->surface->resource, &keyboard->client_keys);
18+ wl_resource_for_each (resource, resources) {
19+ wl_keyboard_send_modifiers(resource, serial, state->depressed, state->locked, state->latched, state->group);
20+ wl_keyboard_send_enter(resource, serial, view->surface->resource, &keyboard->client_keys);
21+ }
22 }
23
24 static void
25-leave(struct input_focus_handler *handler, struct wl_resource *resource, struct compositor_view *view)
26+leave(struct input_focus_handler *handler, struct wl_list *resources, struct compositor_view *view)
27 {
28+ struct wl_resource *resource;
29 uint32_t serial;
30
31- if (!resource)
32- return;
33 serial = wl_display_next_serial(swc.display);
34- wl_keyboard_send_leave(resource, serial, view->surface->resource);
35+ wl_resource_for_each (resource, resources)
36+ wl_keyboard_send_leave(resource, serial, view->surface->resource);
37 }
38
39 static bool
40 client_handle_key(struct keyboard *keyboard, uint32_t time, struct key *key, uint32_t state)
41 {
42 uint32_t *value;
43+ struct wl_resource *resource;
44
45 if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
46 if (!(value = wl_array_add(&keyboard->client_keys, sizeof(*value))))
47@@ -87,27 +89,23 @@ client_handle_key(struct keyboard *keyboard, uint32_t time, struct key *key, uin
48 }
49 }
50
51- if (keyboard->focus.resource)
52- wl_keyboard_send_key(keyboard->focus.resource, key->press.serial, time, key->press.value, state);
53-
54+ wl_resource_for_each (resource, &keyboard->focus.active)
55+ wl_keyboard_send_key(resource, key->press.serial, time, key->press.value, state);
56 return true;
57 }
58
59 static bool
60 client_handle_modifiers(struct keyboard *keyboard, const struct keyboard_modifier_state *state)
61 {
62- struct wl_client *client;
63- struct wl_display *display;
64+ struct wl_resource *resource;
65 uint32_t serial;
66
67- if (!keyboard->focus.resource)
68+ if (wl_list_empty(&keyboard->focus.active))
69 return false;
70
71- client = wl_resource_get_client(keyboard->focus.resource);
72- display = wl_client_get_display(client);
73- serial = wl_display_next_serial(display);
74- wl_keyboard_send_modifiers(keyboard->focus.resource, serial, state->depressed, state->locked, state->latched, state->group);
75-
76+ serial = wl_display_next_serial(swc.display);
77+ wl_resource_for_each (resource, &keyboard->focus.active)
78+ wl_keyboard_send_modifiers(resource, serial, state->depressed, state->locked, state->latched, state->group);
79 return true;
80 }
81
+22,
-14
1@@ -35,31 +35,33 @@
2 #include <wld/wld.h>
3
4 static void
5-enter(struct input_focus_handler *handler, struct wl_resource *resource, struct compositor_view *view)
6+enter(struct input_focus_handler *handler, struct wl_list *resources, struct compositor_view *view)
7 {
8 struct pointer *pointer = wl_container_of(handler, pointer, focus_handler);
9+ struct wl_resource *resource;
10 uint32_t serial;
11 wl_fixed_t surface_x, surface_y;
12
13- if (!resource) {
14+ if (wl_list_empty(resources)) {
15 pointer_set_cursor(pointer, cursor_left_ptr);
16 return;
17 }
18 serial = wl_display_next_serial(swc.display);
19 surface_x = pointer->x - wl_fixed_from_int(view->base.geometry.x);
20 surface_y = pointer->y - wl_fixed_from_int(view->base.geometry.y);
21- wl_pointer_send_enter(resource, serial, view->surface->resource, surface_x, surface_y);
22+ wl_resource_for_each (resource, resources)
23+ wl_pointer_send_enter(resource, serial, view->surface->resource, surface_x, surface_y);
24 }
25
26 static void
27-leave(struct input_focus_handler *handler, struct wl_resource *resource, struct compositor_view *view)
28+leave(struct input_focus_handler *handler, struct wl_list *resources, struct compositor_view *view)
29 {
30+ struct wl_resource *resource;
31 uint32_t serial;
32
33- if (!resource)
34- return;
35 serial = wl_display_next_serial(swc.display);
36- wl_pointer_send_leave(resource, serial, view->surface->resource);
37+ wl_resource_for_each (resource, resources)
38+ wl_pointer_send_leave(resource, serial, view->surface->resource);
39 }
40
41 static void
42@@ -169,11 +171,13 @@ static bool
43 client_handle_button(struct pointer_handler *handler, uint32_t time, struct button *button, uint32_t state)
44 {
45 struct pointer *pointer = wl_container_of(handler, pointer, client_handler);
46+ struct wl_resource *resource;
47
48- if (!pointer->focus.resource)
49+ if (wl_list_empty(&pointer->focus.active))
50 return false;
51
52- wl_pointer_send_button(pointer->focus.resource, button->press.serial, time, button->press.value, state);
53+ wl_resource_for_each (resource, &pointer->focus.active)
54+ wl_pointer_send_button(resource, button->press.serial, time, button->press.value, state);
55 return true;
56 }
57
58@@ -181,11 +185,13 @@ static bool
59 client_handle_axis(struct pointer_handler *handler, uint32_t time, uint32_t axis, wl_fixed_t amount)
60 {
61 struct pointer *pointer = wl_container_of(handler, pointer, client_handler);
62+ struct wl_resource *resource;
63
64- if (!pointer->focus.resource)
65+ if (wl_list_empty(&pointer->focus.active))
66 return false;
67
68- wl_pointer_send_axis(pointer->focus.resource, time, axis, amount);
69+ wl_resource_for_each (resource, &pointer->focus.active)
70+ wl_pointer_send_axis(resource, time, axis, amount);
71 return true;
72 }
73
74@@ -193,14 +199,16 @@ static bool
75 client_handle_motion(struct pointer_handler *handler, uint32_t time, wl_fixed_t x, wl_fixed_t y)
76 {
77 struct pointer *pointer = wl_container_of(handler, pointer, client_handler);
78+ struct wl_resource *resource;
79 wl_fixed_t sx, sy;
80
81- if (!pointer->focus.resource)
82+ if (wl_list_empty(&pointer->focus.active))
83 return false;
84
85 sx = x - wl_fixed_from_int(pointer->focus.view->base.geometry.x);
86 sy = y - wl_fixed_from_int(pointer->focus.view->base.geometry.y);
87- wl_pointer_send_motion(pointer->focus.resource, time, sx, sy);
88+ wl_resource_for_each (resource, &pointer->focus.active)
89+ wl_pointer_send_motion(resource, time, sx, sy);
90 return true;
91 }
92
93@@ -298,7 +306,7 @@ set_cursor(struct wl_client *client, struct wl_resource *resource,
94 struct pointer *pointer = wl_resource_get_user_data(resource);
95 struct surface *surface;
96
97- if (!pointer->focus.resource || client != wl_resource_get_client(pointer->focus.resource))
98+ if (client != pointer->focus.client)
99 return;
100
101 if (pointer->cursor.surface) {
+2,
-4
1@@ -102,10 +102,8 @@ handle_data_device_event(struct wl_listener *listener, void *data)
2 if (ev->type != DATA_DEVICE_EVENT_SELECTION_CHANGED)
3 return;
4
5- if (seat.keyboard.focus.resource) {
6- struct wl_client *client = wl_resource_get_client(seat.keyboard.focus.resource);
7- data_device_offer_selection(&seat.data_device, client);
8- }
9+ if (seat.keyboard.focus.client)
10+ data_device_offer_selection(&seat.data_device, seat.keyboard.focus.client);
11 }
12
13 static struct wl_listener data_device_listener = {