From 98bf316ee6632f62ec205904d74eabd8b3e9d15b Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Fri, 10 Nov 2023 23:43:46 -0500 Subject: [PATCH] keyboard: include pressed modifiers in bound set This prevents applications from seeing and handling the release event for a modifier key that was part of a keybinding (e.g. Firefox displays its menu bar for a lone Alt press + release). --- include/input/key-state.h | 2 +- src/input/key-state.c | 19 ++++++++++++++++--- src/input/keyboard.c | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/include/input/key-state.h b/include/input/key-state.h index 1fd83523..1b5b7ed2 100644 --- a/include/input/key-state.h +++ b/include/input/key-state.h @@ -19,7 +19,7 @@ uint32_t *key_state_pressed_sent_keycodes(void); int key_state_nr_pressed_sent_keycodes(void); -void key_state_set_pressed(uint32_t keycode, bool ispressed); +void key_state_set_pressed(uint32_t keycode, bool is_pressed, bool is_modifier); void key_state_store_pressed_key_as_bound(uint32_t keycode); bool key_state_corresponding_press_event_was_bound(uint32_t keycode); void key_state_bound_key_remove(uint32_t keycode); diff --git a/src/input/key-state.c b/src/input/key-state.c index 193022a7..603b8c5a 100644 --- a/src/input/key-state.c +++ b/src/input/key-state.c @@ -11,7 +11,7 @@ struct key_array { int nr_keys; }; -static struct key_array pressed, bound, pressed_sent; +static struct key_array pressed, pressed_mods, bound, pressed_sent; static bool key_present(struct key_array *array, uint32_t keycode) @@ -69,12 +69,16 @@ key_state_nr_pressed_sent_keycodes(void) } void -key_state_set_pressed(uint32_t keycode, bool ispressed) +key_state_set_pressed(uint32_t keycode, bool is_pressed, bool is_modifier) { - if (ispressed) { + if (is_pressed) { add_key(&pressed, keycode); + if (is_modifier) { + add_key(&pressed_mods, keycode); + } } else { remove_key(&pressed, keycode); + remove_key(&pressed_mods, keycode); } } @@ -82,6 +86,15 @@ void key_state_store_pressed_key_as_bound(uint32_t keycode) { add_key(&bound, keycode); + /* + * Also store any pressed modifiers as bound. This prevents + * applications from seeing and handling the release event for + * a modifier key that was part of a keybinding (e.g. Firefox + * displays its menu bar for a lone Alt press + release). + */ + for (int i = 0; i < pressed_mods.nr_keys; ++i) { + add_key(&bound, pressed_mods.keys[i]); + } } bool diff --git a/src/input/keyboard.c b/src/input/keyboard.c index e3526b7f..078209a6 100644 --- a/src/input/keyboard.c +++ b/src/input/keyboard.c @@ -237,7 +237,7 @@ handle_compositor_keybindings(struct keyboard *keyboard, } key_state_set_pressed(event->keycode, - event->state == WL_KEYBOARD_KEY_STATE_PRESSED); + event->state == WL_KEYBOARD_KEY_STATE_PRESSED, is_modifier); if (event->state == WL_KEYBOARD_KEY_STATE_RELEASED) { /*