spkp

Stacking wayland compositor
git clone git://git.z3bra.org/sp:kp.git
Log | Files | Refs

commit 3ef3cdaa95f81c89cd08658815e3d309aebc282c
parent eb601d97f773fb0de0f3200b802e6d65a84f1f4b
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:
Mcompositor.c | 13+++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/compositor.c b/compositor.c @@ -26,6 +26,8 @@ #include "arg.h" +#define CLEANMASK(mask) (mask & ~(WLR_MODIFIER_CAPS|WLR_MODIFIER_SHIFT)) + enum { NORMAL, MOVE, @@ -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; @@ -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; @@ -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; } }