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 = {