commit e8b0c05
Michael Forney
·
2013-12-06 10:10:33 +0000 UTC
parent f0477fa
Refactor swc_keyboard_handle_key
- Move key and modifier sending to it's own keyboard handler.
- Make keyboard handlers keep track of they keys they've handled. This
fixes a couple of issues:
* Surfaces no longer receive spurious key release events if they are
focused due to a key binding.
* Since xwayland sends key press events for every key pressed when
the keyboard enters a surface, keys pressed because they were part
of a key bindings were being sent to X clients.
- Use a list of keyboard handlers in case other handlers are added
later.
5 files changed,
+86,
-54
+1,
-1
1@@ -75,7 +75,7 @@ static bool handle_key(struct swc_keyboard * keyboard, uint32_t time,
2 return false;
3 }
4
5-static const struct swc_keyboard_handler binding_handler = {
6+static struct swc_keyboard_handler binding_handler = {
7 .key = &handle_key,
8 };
9
+1,
-1
1@@ -28,7 +28,7 @@
2
3 struct swc_bindings_global
4 {
5- const struct swc_keyboard_handler * keyboard_handler;
6+ struct swc_keyboard_handler * keyboard_handler;
7 };
8
9 bool swc_bindings_initialize();
+76,
-46
1@@ -46,7 +46,7 @@ static void enter(struct swc_input_focus_handler * handler,
2 serial = wl_display_next_serial(display);
3
4 wl_keyboard_send_enter(resource, serial, surface->resource,
5- &keyboard->keys);
6+ &keyboard->client_handler.keys);
7 }
8
9 static void leave(struct swc_input_focus_handler * handler,
10@@ -63,6 +63,45 @@ static void leave(struct swc_input_focus_handler * handler,
11 wl_keyboard_send_leave(resource, serial, surface->resource);
12 }
13
14+static bool client_handle_key(struct swc_keyboard * keyboard, uint32_t time,
15+ uint32_t key, uint32_t state)
16+{
17+ struct wl_client * client;
18+ struct wl_display * display;
19+ uint32_t serial;
20+
21+ if (!keyboard->focus.resource)
22+ return true;
23+
24+ client = wl_resource_get_client(keyboard->focus.resource);
25+ display = wl_client_get_display(client);
26+ serial = wl_display_next_serial(display);
27+ wl_keyboard_send_key(keyboard->focus.resource, serial, time, key, state);
28+
29+ return true;
30+}
31+
32+static bool client_handle_modifiers
33+ (struct swc_keyboard * keyboard,
34+ const struct swc_keyboard_modifier_state * state)
35+{
36+ struct wl_client * client;
37+ struct wl_display * display;
38+ uint32_t serial;
39+
40+ if (!keyboard->focus.resource)
41+ return false;
42+
43+ client = wl_resource_get_client(keyboard->focus.resource);
44+ display = wl_client_get_display(client);
45+ serial = wl_display_next_serial(display);
46+ wl_keyboard_send_modifiers(keyboard->focus.resource, serial,
47+ state->depressed, state->locked, state->latched,
48+ state->group);
49+
50+ return true;
51+}
52+
53 bool swc_keyboard_initialize(struct swc_keyboard * keyboard)
54 {
55 if (!swc_xkb_initialize(&keyboard->xkb))
56@@ -74,11 +113,15 @@ bool swc_keyboard_initialize(struct swc_keyboard * keyboard)
57 if (!swc_input_focus_initialize(&keyboard->focus, &keyboard->focus_handler))
58 goto error1;
59
60- wl_array_init(&keyboard->keys);
61 keyboard->modifier_state = (struct swc_keyboard_modifier_state) { 0 };
62 keyboard->modifiers = 0;
63 keyboard->focus_handler.enter = &enter;
64 keyboard->focus_handler.leave = &leave;
65+ keyboard->client_handler.key = &client_handle_key;
66+ keyboard->client_handler.modifiers = &client_handle_modifiers;
67+ wl_array_init(&keyboard->client_handler.keys);
68+ wl_list_init(&keyboard->handlers);
69+ wl_list_insert(&keyboard->handlers, &keyboard->client_handler.link);
70
71 swc_input_focus_initialize(&keyboard->focus, &keyboard->focus_handler);
72
73@@ -92,7 +135,7 @@ bool swc_keyboard_initialize(struct swc_keyboard * keyboard)
74
75 void swc_keyboard_finish(struct swc_keyboard * keyboard)
76 {
77- wl_array_release(&keyboard->keys);
78+ wl_array_release(&keyboard->client_handler.keys);
79 swc_input_focus_finish(&keyboard->focus);
80 swc_xkb_finish(&keyboard->xkb);
81 }
82@@ -135,52 +178,43 @@ void swc_keyboard_handle_key(struct swc_keyboard * keyboard, uint32_t time,
83 {
84 uint32_t * pressed_key;
85 struct swc_keyboard_modifier_state modifier_state;
86- struct wl_display * display;
87- uint32_t serial;
88 enum xkb_key_direction direction;
89 struct swc_xkb * xkb = &keyboard->xkb;
90+ struct swc_keyboard_handler * handler;
91
92- if (keyboard->focus.resource)
93+ /* First handle key events associated with a particular handler. */
94+ wl_list_for_each(handler, &keyboard->handlers, link)
95 {
96- struct wl_client * client
97- = wl_resource_get_client(keyboard->focus.resource);
98- display = wl_client_get_display(client);
99- }
100-
101- /* Update keyboard state state */
102- wl_array_for_each(pressed_key, &keyboard->keys)
103- {
104- if (*pressed_key == key)
105+ wl_array_for_each(pressed_key, &handler->keys)
106 {
107- /* Ignore repeat events. */
108- if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
109- return;
110- else
111+ if (*pressed_key == key)
112 {
113- /* Remove the key from the array */
114- swc_array_remove(&keyboard->keys, pressed_key, sizeof key);
115- break;
116+ /* Ignore repeat events. */
117+ if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
118+ return;
119+
120+ swc_array_remove(&handler->keys,
121+ pressed_key, sizeof *pressed_key);
122+ if (handler->key)
123+ handler->key(keyboard, time, key, state);
124+ goto update_xkb_state;
125 }
126 }
127 }
128
129- if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
130- {
131- pressed_key = wl_array_add(&keyboard->keys, sizeof key);
132- *pressed_key = key;
133- }
134-
135- /* Check if the key event is handled by the keyboard handler. */
136- if ((!keyboard->handler || !keyboard->handler->key
137- || !keyboard->handler->key(keyboard, time, key, state))
138- && keyboard->focus.resource)
139+ /* Go through handlers again to see if any will accept this key event. */
140+ wl_list_for_each(handler, &keyboard->handlers, link)
141 {
142- serial = wl_display_next_serial(display);
143- wl_keyboard_send_key(keyboard->focus.resource, serial, time,
144- key, state);
145+ if (handler->key && handler->key(keyboard, time, key, state))
146+ {
147+ if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
148+ *((uint32_t *) wl_array_add(&handler->keys, sizeof key)) = key;
149+ break;
150+ }
151 }
152
153 /* Update XKB state. */
154+ update_xkb_state:
155 direction = state == WL_KEYBOARD_KEY_STATE_PRESSED ? XKB_KEY_DOWN
156 : XKB_KEY_UP;
157 xkb_state_update_key(xkb->state, XKB_KEY(key), direction);
158@@ -204,17 +238,6 @@ void swc_keyboard_handle_key(struct swc_keyboard * keyboard, uint32_t time,
159
160 /* Update keyboard modifier state. */
161 keyboard->modifier_state = modifier_state;
162-
163- if (keyboard->focus.resource)
164- {
165- serial = wl_display_next_serial(display);
166- wl_keyboard_send_modifiers
167- (keyboard->focus.resource, serial, modifier_state.depressed,
168- modifier_state.latched, modifier_state.locked,
169- modifier_state.group);
170- }
171-
172-
173 keyboard->modifiers = 0;
174 if (mods_active & (1 << keyboard->xkb.indices.ctrl))
175 keyboard->modifiers |= SWC_MOD_CTRL;
176@@ -224,6 +247,13 @@ void swc_keyboard_handle_key(struct swc_keyboard * keyboard, uint32_t time,
177 keyboard->modifiers |= SWC_MOD_LOGO;
178 if (mods_active & (1 << keyboard->xkb.indices.shift))
179 keyboard->modifiers |= SWC_MOD_SHIFT;
180+
181+ /* Run any modifier handlers. */
182+ wl_list_for_each(handler, &keyboard->handlers, link)
183+ {
184+ if (handler->modifiers)
185+ handler->modifiers(keyboard, &modifier_state);
186+ }
187 }
188 }
189
+6,
-5
1@@ -47,20 +47,21 @@ struct swc_keyboard_handler
2 uint32_t key, uint32_t state);
3 bool (* modifiers)(struct swc_keyboard * keyboard,
4 const struct swc_keyboard_modifier_state * state);
5+
6+ struct wl_array keys;
7+ struct wl_list link;
8 };
9
10 struct swc_keyboard
11 {
12 struct swc_input_focus focus;
13 struct swc_input_focus_handler focus_handler;
14-
15- const struct swc_keyboard_handler * handler;
16-
17 struct swc_xkb xkb;
18
19- struct wl_array keys;
20- struct swc_keyboard_modifier_state modifier_state;
21+ struct wl_list handlers;
22+ struct swc_keyboard_handler client_handler;
23
24+ struct swc_keyboard_modifier_state modifier_state;
25 uint32_t modifiers;
26 };
27
+2,
-1
1@@ -52,7 +52,8 @@ static void setup_compositor()
2 pixman_region32_t pointer_region;
3 struct swc_output * output;
4
5- swc.seat->keyboard->handler = swc.bindings->keyboard_handler;
6+ wl_list_insert(&swc.seat->keyboard->handlers,
7+ &swc.bindings->keyboard_handler->link);
8 swc.seat->pointer->handler = &compositor.pointer_handler;
9 wl_signal_add(&swc.seat->pointer->focus.event_signal,
10 swc_window_enter_listener);