aboutsummaryrefslogtreecommitdiffstats
path: root/sway/input/keyboard.c
diff options
context:
space:
mode:
authorLibravatar Tony Crisci <tony@dubstepdish.com>2018-01-04 07:25:52 -0500
committerLibravatar Tony Crisci <tony@dubstepdish.com>2018-01-04 07:25:52 -0500
commit50e791cadbfc51d531fff44cfbe3323a3b456adf (patch)
treee4df808bc367d7c479df3ceeda6ba0aa772d2df6 /sway/input/keyboard.c
parentfix nitpicks (diff)
downloadsway-50e791cadbfc51d531fff44cfbe3323a3b456adf.tar.gz
sway-50e791cadbfc51d531fff44cfbe3323a3b456adf.tar.zst
sway-50e791cadbfc51d531fff44cfbe3323a3b456adf.zip
binding release
Diffstat (limited to 'sway/input/keyboard.c')
-rw-r--r--sway/input/keyboard.c96
1 files changed, 75 insertions, 21 deletions
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c
index 3090d32f..7b90dacf 100644
--- a/sway/input/keyboard.c
+++ b/sway/input/keyboard.c
@@ -1,3 +1,4 @@
1#include <assert.h>
1#include <wlr/backend/multi.h> 2#include <wlr/backend/multi.h>
2#include <wlr/backend/session.h> 3#include <wlr/backend/session.h>
3#include "sway/input/seat.h" 4#include "sway/input/seat.h"
@@ -54,6 +55,18 @@ static bool keyboard_execute_compositor_binding(struct sway_keyboard *keyboard,
54 return false; 55 return false;
55} 56}
56 57
58static bool binding_matches_keystate(struct sway_binding *binding,
59 enum wlr_key_state key_state) {
60 if (key_state == WLR_KEY_PRESSED && !binding->release) {
61 return true;
62 }
63 if (key_state == WLR_KEY_RELEASED && binding->release) {
64 return true;
65 }
66
67 return false;
68}
69
57/** 70/**
58 * Execute keyboard bindings bound with `bindysm`. 71 * Execute keyboard bindings bound with `bindysm`.
59 * 72 *
@@ -61,13 +74,15 @@ static bool keyboard_execute_compositor_binding(struct sway_keyboard *keyboard,
61 * should be propagated to clients. 74 * should be propagated to clients.
62 */ 75 */
63static bool keyboard_execute_bindsym(struct sway_keyboard *keyboard, 76static bool keyboard_execute_bindsym(struct sway_keyboard *keyboard,
64 xkb_keysym_t *pressed_keysyms, uint32_t modifiers, size_t keysyms_len) { 77 xkb_keysym_t *pressed_keysyms, uint32_t modifiers, enum wlr_key_state key_state) {
65 // configured bindings 78 // configured bindings
66 int n = pressed_keysyms_length(pressed_keysyms); 79 int n = pressed_keysyms_length(pressed_keysyms);
67 list_t *keysym_bindings = config->current_mode->keysym_bindings; 80 list_t *keysym_bindings = config->current_mode->keysym_bindings;
68 for (int i = 0; i < keysym_bindings->length; ++i) { 81 for (int i = 0; i < keysym_bindings->length; ++i) {
69 struct sway_binding *binding = keysym_bindings->items[i]; 82 struct sway_binding *binding = keysym_bindings->items[i];
70 if (modifiers ^ binding->modifiers || n != binding->keys->length) { 83 if (!binding_matches_keystate(binding, key_state) ||
84 modifiers ^ binding->modifiers ||
85 n != binding->keys->length) {
71 continue; 86 continue;
72 } 87 }
73 88
@@ -115,16 +130,43 @@ static bool keysym_is_modifier(xkb_keysym_t keysym) {
115} 130}
116 131
117static bool binding_matches_keycodes(struct wlr_keyboard *keyboard, 132static bool binding_matches_keycodes(struct wlr_keyboard *keyboard,
118 struct sway_binding *binding) { 133 struct sway_binding *binding, struct wlr_event_keyboard_key *event) {
134 assert(binding->bindcode);
135
136 uint32_t keycode = event->keycode + 8;
137
138 if (!binding_matches_keystate(binding, event->state)) {
139 return false;
140 }
141
119 uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard); 142 uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard);
120 if (modifiers ^ binding->modifiers) { 143 if (modifiers ^ binding->modifiers) {
121 return false; 144 return false;
122 } 145 }
123 146
147 // on release, the released key must be in the binding
148 if (event->state == WLR_KEY_RELEASED) {
149 bool found = false;
150 for (int i = 0; i < binding->keys->length; ++i) {
151 uint32_t binding_keycode = *(uint32_t*)binding->keys->items[i] + 8;
152 if (binding_keycode == keycode) {
153 found = true;
154 break;
155 }
156 }
157 if (!found) {
158 return false;
159 }
160 }
161
124 // every keycode in the binding must be present in the pressed keys on the 162 // every keycode in the binding must be present in the pressed keys on the
125 // keyboard 163 // keyboard
126 for (int i = 0; i < binding->keys->length; ++i) { 164 for (int i = 0; i < binding->keys->length; ++i) {
127 uint32_t binding_keycode = *(uint32_t*)binding->keys->items[i] + 8; 165 uint32_t binding_keycode = *(uint32_t*)binding->keys->items[i] + 8;
166 if (event->state == WLR_KEY_RELEASED && keycode == binding_keycode) {
167 continue;
168 }
169
128 bool found = false; 170 bool found = false;
129 for (size_t j = 0; j < keyboard->num_keycodes; ++j) { 171 for (size_t j = 0; j < keyboard->num_keycodes; ++j) {
130 xkb_keycode_t keycode = keyboard->keycodes[j] + 8; 172 xkb_keycode_t keycode = keyboard->keycodes[j] + 8;
@@ -178,13 +220,14 @@ static bool binding_matches_keycodes(struct wlr_keyboard *keyboard,
178 * Returns true if the keysym was handled by a binding and false if the event 220 * Returns true if the keysym was handled by a binding and false if the event
179 * should be propagated to clients. 221 * should be propagated to clients.
180 */ 222 */
181static bool keyboard_execute_bindcode(struct sway_keyboard *keyboard) { 223static bool keyboard_execute_bindcode(struct sway_keyboard *keyboard,
224 struct wlr_event_keyboard_key *event) {
182 struct wlr_keyboard *wlr_keyboard = 225 struct wlr_keyboard *wlr_keyboard =
183 keyboard->seat_device->input_device->wlr_device->keyboard; 226 keyboard->seat_device->input_device->wlr_device->keyboard;
184 list_t *keycode_bindings = config->current_mode->keycode_bindings; 227 list_t *keycode_bindings = config->current_mode->keycode_bindings;
185 for (int i = 0; i < keycode_bindings->length; ++i) { 228 for (int i = 0; i < keycode_bindings->length; ++i) {
186 struct sway_binding *binding = keycode_bindings->items[i]; 229 struct sway_binding *binding = keycode_bindings->items[i];
187 if (binding_matches_keycodes(wlr_keyboard, binding)) { 230 if (binding_matches_keycodes(wlr_keyboard, binding, event)) {
188 struct cmd_results *results = handle_command(binding->command); 231 struct cmd_results *results = handle_command(binding->command);
189 if (results->status != CMD_SUCCESS) { 232 if (results->status != CMD_SUCCESS) {
190 sway_log(L_DEBUG, "could not run command for binding: %s", 233 sway_log(L_DEBUG, "could not run command for binding: %s",
@@ -289,50 +332,61 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
289 bool handled = false; 332 bool handled = false;
290 333
291 // handle keycodes 334 // handle keycodes
292 handled = keyboard_execute_bindcode(keyboard); 335 handled = keyboard_execute_bindcode(keyboard, event);
293 336
294 // handle translated keysyms 337 // handle translated keysyms
338 if (!handled && event->state == WLR_KEY_RELEASED) {
339 handled = keyboard_execute_bindsym(keyboard,
340 keyboard->pressed_keysyms_translated,
341 keyboard->modifiers_translated,
342 event->state);
343 }
295 const xkb_keysym_t *translated_keysyms; 344 const xkb_keysym_t *translated_keysyms;
296 uint32_t translated_modifiers;
297 size_t translated_keysyms_len = 345 size_t translated_keysyms_len =
298 keyboard_keysyms_translated(keyboard, keycode, &translated_keysyms, 346 keyboard_keysyms_translated(keyboard, keycode, &translated_keysyms,
299 &translated_modifiers); 347 &keyboard->modifiers_translated);
300 pressed_keysyms_update(keyboard->pressed_keysyms_translated, 348 pressed_keysyms_update(keyboard->pressed_keysyms_translated,
301 translated_keysyms, translated_keysyms_len, event->state); 349 translated_keysyms, translated_keysyms_len, event->state);
302 if (event->state == WLR_KEY_PRESSED && !handled) { 350 if (!handled && event->state == WLR_KEY_PRESSED) {
303 handled = keyboard_execute_bindsym(keyboard, 351 handled = keyboard_execute_bindsym(keyboard,
304 keyboard->pressed_keysyms_translated, translated_modifiers, 352 keyboard->pressed_keysyms_translated,
305 translated_keysyms_len); 353 keyboard->modifiers_translated,
354 event->state);
306 } 355 }
307 356
308 // Handle raw keysyms 357 // Handle raw keysyms
358 if (!handled && event->state == WLR_KEY_RELEASED) {
359 handled = keyboard_execute_bindsym(keyboard,
360 keyboard->pressed_keysyms_raw, keyboard->modifiers_raw,
361 event->state);
362 }
309 const xkb_keysym_t *raw_keysyms; 363 const xkb_keysym_t *raw_keysyms;
310 uint32_t raw_modifiers;
311 size_t raw_keysyms_len = 364 size_t raw_keysyms_len =
312 keyboard_keysyms_raw(keyboard, keycode, &raw_keysyms, &raw_modifiers); 365 keyboard_keysyms_raw(keyboard, keycode, &raw_keysyms, &keyboard->modifiers_raw);
313 pressed_keysyms_update(keyboard->pressed_keysyms_raw, raw_keysyms, 366 pressed_keysyms_update(keyboard->pressed_keysyms_raw, raw_keysyms,
314 raw_keysyms_len, event->state); 367 raw_keysyms_len, event->state);
315 if (event->state == WLR_KEY_PRESSED && !handled) { 368 if (!handled && event->state == WLR_KEY_PRESSED) {
316 handled = keyboard_execute_bindsym(keyboard, 369 handled = keyboard_execute_bindsym(keyboard,
317 keyboard->pressed_keysyms_raw, raw_modifiers, 370 keyboard->pressed_keysyms_raw, keyboard->modifiers_raw,
318 raw_keysyms_len); 371 event->state);
319 } 372 }
320 373
321 // Compositor bindings 374 // Compositor bindings
322 if (event->state == WLR_KEY_PRESSED && !handled) { 375 if (!handled && event->state == WLR_KEY_PRESSED) {
323 handled = 376 handled =
324 keyboard_execute_compositor_binding(keyboard, 377 keyboard_execute_compositor_binding(keyboard,
325 keyboard->pressed_keysyms_translated, translated_modifiers, 378 keyboard->pressed_keysyms_translated,
379 keyboard->modifiers_translated,
326 translated_keysyms_len); 380 translated_keysyms_len);
327 } 381 }
328 if (event->state == WLR_KEY_PRESSED && !handled) { 382 if (!handled && event->state == WLR_KEY_PRESSED) {
329 handled = 383 handled =
330 keyboard_execute_compositor_binding(keyboard, 384 keyboard_execute_compositor_binding(keyboard,
331 keyboard->pressed_keysyms_raw, raw_modifiers, 385 keyboard->pressed_keysyms_raw, keyboard->modifiers_raw,
332 raw_keysyms_len); 386 raw_keysyms_len);
333 } 387 }
334 388
335 if (!handled) { 389 if (!handled || event->state == WLR_KEY_RELEASED) {
336 wlr_seat_set_keyboard(wlr_seat, wlr_device); 390 wlr_seat_set_keyboard(wlr_seat, wlr_device);
337 wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec, 391 wlr_seat_keyboard_notify_key(wlr_seat, event->time_msec,
338 event->keycode, event->state); 392 event->keycode, event->state);