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;
                        }
                }