key-state: make nr-pressed-keys check more accurate

...to avoid counting keys which never send release events and thus
disable all keybinds.

We do not want to match keybinds if additional 'normal' (non-modifiers)
are pressed at the samet time. We must ignore keys which do not send
release events such as XKB_KEY_ISO_Next_Group and XKB_KEY_XF86WakeUP.

Issue #1208
This commit is contained in:
Johan Malm 2023-10-29 22:14:48 +00:00
parent 7b644b3b94
commit ce8420d978
3 changed files with 35 additions and 5 deletions

View file

@ -21,6 +21,6 @@ void key_state_store_pressed_keys_as_bound(void);
bool key_state_corresponding_press_event_was_bound(uint32_t keycode); bool key_state_corresponding_press_event_was_bound(uint32_t keycode);
void key_state_bound_key_remove(uint32_t keycode); void key_state_bound_key_remove(uint32_t keycode);
int key_state_nr_bound_keys(void); int key_state_nr_bound_keys(void);
int key_state_nr_pressed_keys(void); bool key_state_multiple_normal_keys_pressed(void);
#endif /* LABWC_KEY_STATE_H */ #endif /* LABWC_KEY_STATE_H */

View file

@ -103,8 +103,38 @@ key_state_nr_bound_keys(void)
return bound.nr_keys; return bound.nr_keys;
} }
int /*
key_state_nr_pressed_keys(void) * Reference:
* https://github.com/xkbcommon/libxkbcommon/blob/HEAD/include/xkbcommon/xkbcommon-keysyms.h
*/
bool
key_state_multiple_normal_keys_pressed(void)
{ {
return pressed.nr_keys; if (pressed.nr_keys < 2) {
return false;
}
/*
* If the pressed array contains multiple keys, we have to analyze a bit
* further because some keys like those listed below do not always
* receive release events.
* - XKB_KEY_ISO_Group_Next
* - XKB_KEY_XF86WakeUp
* - XKB_KEY_XF86Suspend
* - XKB_KEY_XF86Hibernate
*/
size_t count = 0;
for (int i = 0; i < pressed.nr_keys; ++i) {
/* Convert from udev event to xkbcommon code */
uint32_t keycode = pressed.keys[i] + 8;
if (keycode >= 0x1000000) {
/* XFree86 vendor specific keysyms */
continue;
} else if (keycode >= 0xFE00 && keycode <= 0xFEFF) {
/* Extension function and modifier keys */
continue;
}
++count;
}
return count > 1;
} }

View file

@ -361,7 +361,7 @@ handle_compositor_keybindings(struct keyboard *keyboard,
* avoids false positive matches where 'other' keys were pressed at the * avoids false positive matches where 'other' keys were pressed at the
* same time. * same time.
*/ */
if (key_state_nr_pressed_keys() > 1) { if (key_state_multiple_normal_keys_pressed()) {
return false; return false;
} }