From 8fb641a7ed66bf57ca77e0a6d574c3be43d4ce0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 21 Nov 2021 11:53:22 +0100 Subject: [PATCH] =?UTF-8?q?input:=20handle=20=E2=80=9Cinvalid=E2=80=9D=20X?= =?UTF-8?q?KB=20modifiers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A modifier may not exist in a specific layout. This is indicated by XKB returning XKB_MOD_INVALID from xkb_keymap_mod_get_index(). --- input.c | 86 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/input.c b/input.c index b4a46ec7..8be6639d 100644 --- a/input.c +++ b/input.c @@ -362,10 +362,14 @@ conf_modifiers_to_mask(const struct seat *seat, const struct config_key_modifiers *modifiers) { xkb_mod_mask_t mods = 0; - mods |= modifiers->shift << seat->kbd.mod_shift; - mods |= modifiers->ctrl << seat->kbd.mod_ctrl; - mods |= modifiers->alt << seat->kbd.mod_alt; - mods |= modifiers->meta << seat->kbd.mod_meta; + if (seat->kbd.mod_shift != XKB_MOD_INVALID) + mods |= modifiers->shift << seat->kbd.mod_shift; + if (seat->kbd.mod_ctrl != XKB_MOD_INVALID) + mods |= modifiers->ctrl << seat->kbd.mod_ctrl; + if (seat->kbd.mod_alt != XKB_MOD_INVALID) + mods |= modifiers->alt << seat->kbd.mod_alt; + if (seat->kbd.mod_meta != XKB_MOD_INVALID) + mods |= modifiers->meta << seat->kbd.mod_meta; return mods; } @@ -677,15 +681,21 @@ keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, seat->kbd.mod_caps = xkb_keymap_mod_get_index(seat->kbd.xkb_keymap, XKB_MOD_NAME_CAPS); seat->kbd.mod_num = xkb_keymap_mod_get_index(seat->kbd.xkb_keymap, XKB_MOD_NAME_NUM); - seat->kbd.bind_significant = - 1 << seat->kbd.mod_shift | - 1 << seat->kbd.mod_alt | - 1 << seat->kbd.mod_ctrl | - 1 << seat->kbd.mod_meta; + seat->kbd.bind_significant = 0; + if (seat->kbd.mod_shift != XKB_MOD_INVALID) + seat->kbd.bind_significant |= 1 << seat->kbd.mod_shift; + if (seat->kbd.mod_alt != XKB_MOD_INVALID) + seat->kbd.bind_significant |= 1 << seat->kbd.mod_alt; + if (seat->kbd.mod_ctrl != XKB_MOD_INVALID) + seat->kbd.bind_significant |= 1 << seat->kbd.mod_ctrl; + if (seat->kbd.mod_meta != XKB_MOD_INVALID) + seat->kbd.bind_significant |= 1 << seat->kbd.mod_meta; - seat->kbd.kitty_significant = seat->kbd.bind_significant | - 1 << seat->kbd.mod_caps | - 1 << seat->kbd.mod_num; + seat->kbd.kitty_significant = seat->kbd.bind_significant; + if (seat->kbd.mod_caps != XKB_MOD_INVALID) + seat->kbd.kitty_significant |= 1 << seat->kbd.mod_caps; + if (seat->kbd.mod_num != XKB_MOD_INVALID) + seat->kbd.kitty_significant |= 1 << seat->kbd.mod_num; seat->kbd.key_arrow_up = xkb_keymap_key_by_name(seat->kbd.xkb_keymap, "UP"); seat->kbd.key_arrow_down = xkb_keymap_key_by_name(seat->kbd.xkb_keymap, "DOWN"); @@ -1129,6 +1139,9 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term, const xkb_mod_mask_t mods = ctx->mods & seat->kbd.kitty_significant; const xkb_mod_mask_t consumed = ctx->consumed & seat->kbd.kitty_significant; const xkb_mod_mask_t effective = mods & ~consumed; + const xkb_mod_mask_t caps_num = + (seat->kbd.mod_caps != XKB_MOD_INVALID ? 1 << seat->kbd.mod_caps : 0) | + (seat->kbd.mod_num != XKB_MOD_INVALID ? 1 << seat->kbd.mod_num : 0); const xkb_keysym_t sym = ctx->sym; const uint32_t utf32 = ctx->utf32; const uint8_t *const utf8 = ctx->utf8.buf; @@ -1156,20 +1169,24 @@ kitty_kbd_protocol(struct seat *seat, struct terminal *term, * keys, like Return and Backspace; figure out if there’s some * better magic than filtering out Caps- and Num-Lock here.. */ - if (iswprint(utf32) && (effective & ~(1 << seat->kbd.mod_caps | - 1 << seat->kbd.mod_num)) == 0) - { + if (iswprint(utf32) && (effective & ~caps_num) == 0) { term_to_slave(term, utf8, count); return; } unsigned int encoded_mods = 0; - encoded_mods |= mods & (1 << seat->kbd.mod_shift) ? (1 << 0) : 0; - encoded_mods |= mods & (1 << seat->kbd.mod_alt) ? (1 << 1) : 0; - encoded_mods |= mods & (1 << seat->kbd.mod_ctrl) ? (1 << 2) : 0; - encoded_mods |= mods & (1 << seat->kbd.mod_meta) ? (1 << 3) : 0; - encoded_mods |= mods & (1 << seat->kbd.mod_caps) ? (1 << 6) : 0; - encoded_mods |= mods & (1 << seat->kbd.mod_num) ? (1 << 7) : 0; + if (seat->kbd.mod_shift != XKB_MOD_INVALID) + encoded_mods |= mods & (1 << seat->kbd.mod_shift) ? (1 << 0) : 0; + if (seat->kbd.mod_alt != XKB_MOD_INVALID) + encoded_mods |= mods & (1 << seat->kbd.mod_alt) ? (1 << 1) : 0; + if (seat->kbd.mod_ctrl != XKB_MOD_INVALID) + encoded_mods |= mods & (1 << seat->kbd.mod_ctrl) ? (1 << 2) : 0; + if (seat->kbd.mod_meta != XKB_MOD_INVALID) + encoded_mods |= mods & (1 << seat->kbd.mod_meta) ? (1 << 3) : 0; + if (seat->kbd.mod_caps != XKB_MOD_INVALID) + encoded_mods |= mods & (1 << seat->kbd.mod_caps) ? (1 << 6) : 0; + if (seat->kbd.mod_num != XKB_MOD_INVALID) + encoded_mods |= mods & (1 << seat->kbd.mod_num) ? (1 << 7) : 0; encoded_mods++; int key = -1; @@ -1577,14 +1594,22 @@ keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, seat->kbd.xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group); /* Update state of modifiers we're interested in for e.g mouse events */ - seat->kbd.shift = xkb_state_mod_index_is_active( - seat->kbd.xkb_state, seat->kbd.mod_shift, XKB_STATE_MODS_EFFECTIVE); - seat->kbd.alt = xkb_state_mod_index_is_active( - seat->kbd.xkb_state, seat->kbd.mod_alt, XKB_STATE_MODS_EFFECTIVE); - seat->kbd.ctrl = xkb_state_mod_index_is_active( - seat->kbd.xkb_state, seat->kbd.mod_ctrl, XKB_STATE_MODS_EFFECTIVE); - seat->kbd.meta = xkb_state_mod_index_is_active( - seat->kbd.xkb_state, seat->kbd.mod_meta, XKB_STATE_MODS_EFFECTIVE); + seat->kbd.shift = seat->kbd.mod_shift != XKB_MOD_INVALID + ? xkb_state_mod_index_is_active( + seat->kbd.xkb_state, seat->kbd.mod_shift, XKB_STATE_MODS_EFFECTIVE) + : false; + seat->kbd.alt = seat->kbd.mod_alt != XKB_MOD_INVALID + ? xkb_state_mod_index_is_active( + seat->kbd.xkb_state, seat->kbd.mod_alt, XKB_STATE_MODS_EFFECTIVE) + : false; + seat->kbd.ctrl = seat->kbd.mod_ctrl != XKB_MOD_INVALID + ? xkb_state_mod_index_is_active( + seat->kbd.xkb_state, seat->kbd.mod_ctrl, XKB_STATE_MODS_EFFECTIVE) + : false; + seat->kbd.meta = seat->kbd.mod_meta != XKB_MOD_INVALID + ? xkb_state_mod_index_is_active( + seat->kbd.xkb_state, seat->kbd.mod_meta, XKB_STATE_MODS_EFFECTIVE) + : false; } if (seat->kbd_focus && seat->kbd_focus->active_surface == TERM_SURF_GRID) @@ -2304,7 +2329,8 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, /* Ignore Shift when matching modifiers, since it is * used to enable selection in mouse grabbing client * applications */ - mods &= ~(1 << seat->kbd.mod_shift); + if (seat->kbd.mod_shift != XKB_MOD_INVALID) + mods &= ~(1 << seat->kbd.mod_shift); const struct mouse_binding *match = NULL;