tCheck keybinding more precisely - spkp - Stacking wayland compositor
(HTM) git clone git://git.z3bra.org/spkp.git
(DIR) Log
(DIR) Files
(DIR) Refs
---
(DIR) commit 3ef3cdaa95f81c89cd08658815e3d309aebc282c
(DIR) parent eb601d97f773fb0de0f3200b802e6d65a84f1f4b
(HTM) Author: Willy Goiffon <dev@z3bra.org>
Date: Fri, 13 Nov 2020 09:43:30 +0100
Check keybinding more precisely
Pressing keybinds with mods pressed (especially SHIFT) can yeld a
different keysym. A typical example is pressing Shift+Tab, which gives
XKB_KEY_ISO_Left_Tab, rather than just XKB_KEY_Tab with the SHIFT
modifier.
To make keybindings configuration simpler, we always retrieve the keysyms
corresponding to the level 0 (unshifted) of the keycode received.
Upon checking mods, some "unrelated" mods (like capslock) are ignored
when checking mods against the config.
Diffstat:
M compositor.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
---
(DIR) diff --git a/compositor.c b/compositor.c
t@@ -26,6 +26,8 @@
#include "arg.h"
+#define CLEANMASK(mask) (mask & ~(WLR_MODIFIER_CAPS|WLR_MODIFIER_SHIFT))
+
enum {
NORMAL,
MOVE,
t@@ -515,6 +517,8 @@ cb_kb_key(struct wl_listener *listener, void *data)
int nsym;
uint32_t kc, mod;
+ xkb_layout_index_t layout;
+ struct xkb_keymap *keymap;
const xkb_keysym_t *syms;
ev = data;
t@@ -525,9 +529,13 @@ cb_kb_key(struct wl_listener *listener, void *data)
/* translate libinput keycode to xkbcommon */
kc = ev->keycode + 8;
- nsym = xkb_state_key_get_syms(kb->device->keyboard->xkb_state, kc, &syms);
+ /* get keysym as if no modifier was held (level 0) */
+ keymap = xkb_state_get_keymap(kb->device->keyboard->xkb_state);
+ layout = xkb_state_key_get_layout(kb->device->keyboard->xkb_state, kc);
+ nsym = xkb_keymap_key_get_syms_by_level(keymap, kc, layout, 0, &syms);
mod = wlr_keyboard_get_modifiers(kb->device->keyboard);
+
for (int i = 0; i < nsym; i++) {
if (keybinding(server, mod, syms[i], ev->state))
continue;
t@@ -875,9 +883,10 @@ keybinding(struct state *server, uint32_t mod, uint32_t key, enum wlr_key_state
nkey = sizeof(keys)/sizeof(*keys);
for (i=0; i<nkey; i++) {
- if (keys[i].mod == mod && keys[i].key == key) {
+ if (keys[i].mod == CLEANMASK(mod) && keys[i].key == key) {
if (state == WLR_KEY_PRESSED)
keys[i].func(server, NULL);
+
return 1;
}
}