From 0f8d284e1832abf2858decafd8180a358ac7dc3d Mon Sep 17 00:00:00 2001 From: Scott Leggett Date: Tue, 29 May 2018 00:11:51 +1000 Subject: [PATCH 1/4] Clear the translated keysyms on modifier release. --- sway/input/keyboard.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index e873eea31..2bd0bb527 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c @@ -66,14 +66,25 @@ static void pressed_keysyms_remove(xkb_keysym_t *pressed_keysyms, static void pressed_keysyms_update(xkb_keysym_t *pressed_keysyms, const xkb_keysym_t *keysyms, size_t keysyms_len, - enum wlr_key_state state) { + enum wlr_key_state state, bool mod_release_invalidate) { for (size_t i = 0; i < keysyms_len; ++i) { - if (keysym_is_modifier(keysyms[i])) { - continue; - } if (state == WLR_KEY_PRESSED) { + if (keysym_is_modifier(keysyms[i])) { + continue; + } pressed_keysyms_add(pressed_keysyms, keysyms[i]); } else { // WLR_KEY_RELEASED + if (keysym_is_modifier(keysyms[i])) { + if (mod_release_invalidate) { + // clear the translated keysyms since they are no longer valid + for (size_t j = 0; j < SWAY_KEYBOARD_PRESSED_KEYSYMS_CAP; ++j) { + pressed_keysyms[j] = XKB_KEY_NoSymbol; + return; + } + } else { + continue; + } + } pressed_keysyms_remove(pressed_keysyms, keysyms[i]); } } @@ -357,7 +368,7 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { keyboard_keysyms_translated(keyboard, keycode, &translated_keysyms, &keyboard->modifiers_translated); pressed_keysyms_update(keyboard->pressed_keysyms_translated, - translated_keysyms, translated_keysyms_len, event->state); + translated_keysyms, translated_keysyms_len, event->state, true); if (!handled && event->state == WLR_KEY_PRESSED) { handled = keyboard_execute_bindsym(keyboard, keyboard->pressed_keysyms_translated, @@ -375,7 +386,7 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { size_t raw_keysyms_len = keyboard_keysyms_raw(keyboard, keycode, &raw_keysyms, &keyboard->modifiers_raw); pressed_keysyms_update(keyboard->pressed_keysyms_raw, raw_keysyms, - raw_keysyms_len, event->state); + raw_keysyms_len, event->state, false); if (!handled && event->state == WLR_KEY_PRESSED) { handled = keyboard_execute_bindsym(keyboard, keyboard->pressed_keysyms_raw, keyboard->modifiers_raw, From 0687b98a7c3588b8cf51ff8b8276f7280d9fd664 Mon Sep 17 00:00:00 2001 From: Scott Leggett Date: Tue, 29 May 2018 21:22:12 +1000 Subject: [PATCH 2/4] Copy all keysyms from wlr_keyboard. --- sway/input/keyboard.c | 124 ++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 78 deletions(-) diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 2bd0bb527..65909246c 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c @@ -45,48 +45,18 @@ static ssize_t pressed_keysyms_index(xkb_keysym_t *pressed_keysyms, return -1; } -static void pressed_keysyms_add(xkb_keysym_t *pressed_keysyms, - xkb_keysym_t keysym) { - ssize_t i = pressed_keysyms_index(pressed_keysyms, keysym); - if (i < 0) { - i = pressed_keysyms_index(pressed_keysyms, XKB_KEY_NoSymbol); - if (i >= 0) { - pressed_keysyms[i] = keysym; - } - } -} - -static void pressed_keysyms_remove(xkb_keysym_t *pressed_keysyms, - xkb_keysym_t keysym) { - ssize_t i = pressed_keysyms_index(pressed_keysyms, keysym); - if (i >= 0) { - pressed_keysyms[i] = XKB_KEY_NoSymbol; - } -} - static void pressed_keysyms_update(xkb_keysym_t *pressed_keysyms, - const xkb_keysym_t *keysyms, size_t keysyms_len, - enum wlr_key_state state, bool mod_release_invalidate) { + const xkb_keysym_t *keysyms, size_t keysyms_len) { + size_t keysym_count = 0; + // copy the translated keysyms for (size_t i = 0; i < keysyms_len; ++i) { - if (state == WLR_KEY_PRESSED) { - if (keysym_is_modifier(keysyms[i])) { - continue; - } - pressed_keysyms_add(pressed_keysyms, keysyms[i]); - } else { // WLR_KEY_RELEASED - if (keysym_is_modifier(keysyms[i])) { - if (mod_release_invalidate) { - // clear the translated keysyms since they are no longer valid - for (size_t j = 0; j < SWAY_KEYBOARD_PRESSED_KEYSYMS_CAP; ++j) { - pressed_keysyms[j] = XKB_KEY_NoSymbol; - return; - } - } else { - continue; - } - } - pressed_keysyms_remove(pressed_keysyms, keysyms[i]); + if (keysym_is_modifier(keysyms[i])) { + continue; } + pressed_keysyms[keysym_count++] = keysyms[i]; + } + for (size_t i = keysym_count; i < SWAY_KEYBOARD_PRESSED_KEYSYMS_CAP; i++) { + pressed_keysyms[i] = XKB_KEY_NoSymbol; } } @@ -346,66 +316,64 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { struct wlr_seat *wlr_seat = keyboard->seat_device->sway_seat->wlr_seat; struct wlr_input_device *wlr_device = keyboard->seat_device->input_device->wlr_device; - wlr_idle_notify_activity(keyboard->seat_device->sway_seat->input->server->idle, wlr_seat); struct wlr_event_keyboard_key *event = data; - bool input_inhibited = keyboard->seat_device->sway_seat->exclusive_client != NULL; + bool input_inhibited = + keyboard->seat_device->sway_seat->exclusive_client != NULL; + + wlr_idle_notify_activity( + keyboard->seat_device->sway_seat->input->server->idle, wlr_seat); xkb_keycode_t keycode = event->keycode + 8; - bool handled = false; - // handle keycodes - handled = keyboard_execute_bindcode(keyboard, event, input_inhibited); - - // handle translated keysyms - if (!handled && event->state == WLR_KEY_RELEASED) { - handled = keyboard_execute_bindsym(keyboard, - keyboard->pressed_keysyms_translated, - keyboard->modifiers_translated, - event->state, input_inhibited); - } + // update translated keysyms const xkb_keysym_t *translated_keysyms; size_t translated_keysyms_len = keyboard_keysyms_translated(keyboard, keycode, &translated_keysyms, &keyboard->modifiers_translated); pressed_keysyms_update(keyboard->pressed_keysyms_translated, - translated_keysyms, translated_keysyms_len, event->state, true); - if (!handled && event->state == WLR_KEY_PRESSED) { + translated_keysyms, translated_keysyms_len); + + // update raw keysyms + const xkb_keysym_t *raw_keysyms; + size_t raw_keysyms_len = + keyboard_keysyms_raw(keyboard, keycode, &raw_keysyms, &keyboard->modifiers_raw); + pressed_keysyms_update(keyboard->pressed_keysyms_raw, raw_keysyms, + raw_keysyms_len); + + // handle keycodes + bool handled = keyboard_execute_bindcode(keyboard, event, input_inhibited); + + // handle translated keysyms + if (!handled) { handled = keyboard_execute_bindsym(keyboard, keyboard->pressed_keysyms_translated, keyboard->modifiers_translated, event->state, input_inhibited); } - // Handle raw keysyms - if (!handled && event->state == WLR_KEY_RELEASED) { - handled = keyboard_execute_bindsym(keyboard, - keyboard->pressed_keysyms_raw, keyboard->modifiers_raw, - event->state, input_inhibited); - } - const xkb_keysym_t *raw_keysyms; - size_t raw_keysyms_len = - keyboard_keysyms_raw(keyboard, keycode, &raw_keysyms, &keyboard->modifiers_raw); - pressed_keysyms_update(keyboard->pressed_keysyms_raw, raw_keysyms, - raw_keysyms_len, event->state, false); - if (!handled && event->state == WLR_KEY_PRESSED) { + // handle raw keysyms + if (!handled) { handled = keyboard_execute_bindsym(keyboard, keyboard->pressed_keysyms_raw, keyboard->modifiers_raw, event->state, input_inhibited); } // Compositor bindings - if (!handled && event->state == WLR_KEY_PRESSED) { - handled = - keyboard_execute_compositor_binding(keyboard, - keyboard->pressed_keysyms_translated, - keyboard->modifiers_translated, - translated_keysyms_len); - } - if (!handled && event->state == WLR_KEY_PRESSED) { - handled = - keyboard_execute_compositor_binding(keyboard, - keyboard->pressed_keysyms_raw, keyboard->modifiers_raw, - raw_keysyms_len); + if (event->state == WLR_KEY_PRESSED) { + if (!handled) { + handled = + keyboard_execute_compositor_binding(keyboard, + keyboard->pressed_keysyms_translated, + keyboard->modifiers_translated, + translated_keysyms_len); + } + if (!handled) { + handled = + keyboard_execute_compositor_binding(keyboard, + keyboard->pressed_keysyms_raw, + keyboard->modifiers_raw, + raw_keysyms_len); + } } if (!handled || event->state == WLR_KEY_RELEASED) { From 15b471ded072865853cf015f5200b51b442ee852 Mon Sep 17 00:00:00 2001 From: Scott Leggett Date: Tue, 29 May 2018 21:49:14 +1000 Subject: [PATCH 3/4] Fix line length. --- sway/input/keyboard.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 65909246c..40473c878 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c @@ -336,7 +336,8 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { // update raw keysyms const xkb_keysym_t *raw_keysyms; size_t raw_keysyms_len = - keyboard_keysyms_raw(keyboard, keycode, &raw_keysyms, &keyboard->modifiers_raw); + keyboard_keysyms_raw(keyboard, keycode, &raw_keysyms, + &keyboard->modifiers_raw); pressed_keysyms_update(keyboard->pressed_keysyms_raw, raw_keysyms, raw_keysyms_len); From 6afa4d7bf08278d52a71c31baa6e72316c7a3961 Mon Sep 17 00:00:00 2001 From: Scott Leggett Date: Wed, 30 May 2018 12:58:28 +1000 Subject: [PATCH 4/4] Calculate raw keysyms for all wlr_keyboard->keycodes. --- sway/input/keyboard.c | 54 ++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 40473c878..8671a05ac 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c @@ -298,16 +298,39 @@ static size_t keyboard_keysyms_translated(struct sway_keyboard *keyboard, * This will trigger keybinds such as Alt+Shift+2. */ static size_t keyboard_keysyms_raw(struct sway_keyboard *keyboard, - xkb_keycode_t keycode, const xkb_keysym_t **keysyms, + xkb_keysym_t *keysyms, uint32_t *modifiers) { struct wlr_input_device *device = keyboard->seat_device->input_device->wlr_device; *modifiers = wlr_keyboard_get_modifiers(device->keyboard); - xkb_layout_index_t layout_index = xkb_state_key_get_layout( - device->keyboard->xkb_state, keycode); - return xkb_keymap_key_get_syms_by_level(device->keyboard->keymap, - keycode, layout_index, 0, keysyms); + size_t num_keysyms = 0, num_keysyms_for_keycode; + const xkb_keysym_t *keysyms_for_keycode; + xkb_keycode_t keycode; + for (size_t i = 0; i < device->keyboard->num_keycodes; i++) { + keycode = device->keyboard->keycodes[i] + 8; + xkb_layout_index_t layout_index = + xkb_state_key_get_layout(device->keyboard->xkb_state, keycode); + num_keysyms_for_keycode = + xkb_keymap_key_get_syms_by_level(device->keyboard->keymap, + keycode, + layout_index, + 0, + &keysyms_for_keycode); + for (size_t j = 0, k; j < num_keysyms_for_keycode; j++) { + // search the existing keysyms for the new keysym + for (k = 0; k < num_keysyms; k++) { + if (keysyms[k] == keysyms_for_keycode[j]) { + break; + } + } + if (k == num_keysyms) { + // this is a new keysym, so add to the array + keysyms[num_keysyms++] = keysyms_for_keycode[j]; + } + } + } + return num_keysyms; } static void handle_keyboard_key(struct wl_listener *listener, void *data) { @@ -318,28 +341,27 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) { keyboard->seat_device->input_device->wlr_device; struct wlr_event_keyboard_key *event = data; bool input_inhibited = - keyboard->seat_device->sway_seat->exclusive_client != NULL; + keyboard->seat_device->sway_seat->exclusive_client != NULL; wlr_idle_notify_activity( keyboard->seat_device->sway_seat->input->server->idle, wlr_seat); - xkb_keycode_t keycode = event->keycode + 8; - // update translated keysyms const xkb_keysym_t *translated_keysyms; - size_t translated_keysyms_len = - keyboard_keysyms_translated(keyboard, keycode, &translated_keysyms, + size_t translated_keysyms_len = keyboard_keysyms_translated(keyboard, + event->keycode + 8, + &translated_keysyms, &keyboard->modifiers_translated); pressed_keysyms_update(keyboard->pressed_keysyms_translated, translated_keysyms, translated_keysyms_len); // update raw keysyms - const xkb_keysym_t *raw_keysyms; - size_t raw_keysyms_len = - keyboard_keysyms_raw(keyboard, keycode, &raw_keysyms, - &keyboard->modifiers_raw); - pressed_keysyms_update(keyboard->pressed_keysyms_raw, raw_keysyms, - raw_keysyms_len); + xkb_keysym_t raw_keysyms[SWAY_KEYBOARD_PRESSED_KEYSYMS_CAP] = {0}; + size_t raw_keysyms_len = keyboard_keysyms_raw( + keyboard, raw_keysyms, &keyboard->modifiers_raw); + pressed_keysyms_update(keyboard->pressed_keysyms_raw, + (const xkb_keysym_t*)raw_keysyms, + raw_keysyms_len); // handle keycodes bool handled = keyboard_execute_bindcode(keyboard, event, input_inhibited);