diff --git a/glfw/glfw3.h b/glfw/glfw3.h index 005144276..760fa5849 100644 --- a/glfw/glfw3.h +++ b/glfw/glfw3.h @@ -1394,6 +1394,11 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); * @param[in] text UTF-8 encoded text generated by this key event or empty string. * @param[in] reserved Reserved for future use. * + * @note On X11/Wayland if a modifier other than the modifiers GLFW reports + * (ctrl/shift/alt/super) is used, GLFW will report the shifted key rather + * than the unshifted key. So for example, if ISO_Shift_Level_5 is used to + * convert the key A into UP GLFW will report the key as UP with no modifiers. + * * @sa @ref input_key * @sa @ref glfwSetKeyboardCallback * diff --git a/glfw/wl_init.c b/glfw/wl_init.c index 5576b9f6d..1df2b0a77 100644 --- a/glfw/wl_init.c +++ b/glfw/wl_init.c @@ -434,7 +434,7 @@ static void keyboardHandleModifiers(void* data, uint32_t modsLocked, uint32_t group) { - glfw_xkb_update_modifiers(&_glfw.wl.xkb, modsDepressed, modsLatched, modsLocked, group); + glfw_xkb_update_modifiers(&_glfw.wl.xkb, modsDepressed, modsLatched, modsLocked, 0, 0, group); } static void keyboardHandleRepeatInfo(void* data, diff --git a/glfw/x11_window.c b/glfw/x11_window.c index 560c566cd..47f68bd27 100644 --- a/glfw/x11_window.c +++ b/glfw/x11_window.c @@ -1166,7 +1166,10 @@ static void processEvent(XEvent *event) case XkbStateNotify: { XkbStateNotifyEvent *state_event = (XkbStateNotifyEvent*)kb_event; - glfw_xkb_update_modifiers(&_glfw.x11.xkb, state_event->base_mods, state_event->latched_mods, state_event->locked_mods, state_event->group); + glfw_xkb_update_modifiers( + &_glfw.x11.xkb, state_event->base_mods, state_event->latched_mods, + state_event->locked_mods, state_event->base_group, state_event->latched_group, state_event->locked_group + ); return; } } diff --git a/glfw/xkb_glfw.c b/glfw/xkb_glfw.c index 6c4ec5d73..52746f362 100644 --- a/glfw/xkb_glfw.c +++ b/glfw/xkb_glfw.c @@ -288,10 +288,10 @@ active_unknown_modifiers(_GLFWXKBData *xkb) { void -glfw_xkb_update_modifiers(_GLFWXKBData *xkb, unsigned int depressed, unsigned int latched, unsigned int locked, unsigned int group) { +glfw_xkb_update_modifiers(_GLFWXKBData *xkb, xkb_mod_mask_t depressed, xkb_mod_mask_t latched, xkb_mod_mask_t locked, xkb_layout_index_t base_group, xkb_layout_index_t latched_group, xkb_layout_index_t locked_group) { if (!xkb->keymap) return; xkb->modifiers = 0; - xkb_state_update_mask(xkb->state, depressed, latched, locked, 0, 0, group); + xkb_state_update_mask(xkb->state, depressed, latched, locked, base_group, latched_group, locked_group); #define S(attr, name) if (xkb_state_mod_index_is_active(xkb->state, xkb->attr##Idx, XKB_STATE_MODS_EFFECTIVE)) xkb->modifiers |= GLFW_MOD_##name S(control, CONTROL); S(alt, ALT); S(shift, SHIFT); S(super, SUPER); S(capsLock, CAPS_LOCK); S(numLock, NUM_LOCK); #undef S @@ -403,8 +403,8 @@ glfw_xkb_handle_key_event(_GLFWwindow *window, _GLFWXKBData *xkb, xkb_keycode_t } debug("composed_sym: %s ", glfw_xkb_keysym_name(glfw_sym)); if (glfw_sym == syms[0]) { // composed sym is the same as non-composed sym - // Only use the clean_sym if the mods other than the mods we report - // are active (for example if ISO_Shift_Level_* mods are pressed + // Only use the clean_sym if no mods other than the mods we report + // are active (for example if ISO_Shift_Level_* mods are active // they are not reported by GLFW so the key should be the shifted // key). See https://github.com/kovidgoyal/kitty/issues/171#issuecomment-377557053 xkb_mod_mask_t consumed_unknown_mods = xkb_state_key_get_consumed_mods(xkb->state, code_for_sym) & xkb->activeUnknownModifiers; diff --git a/glfw/xkb_glfw.h b/glfw/xkb_glfw.h index 59377eee8..083bafab6 100644 --- a/glfw/xkb_glfw.h +++ b/glfw/xkb_glfw.h @@ -76,7 +76,7 @@ GLFWbool glfw_xkb_update_x11_keyboard_id(_GLFWXKBData *xkb); void glfw_xkb_release(_GLFWXKBData *xkb); GLFWbool glfw_xkb_create_context(_GLFWXKBData *xkb); GLFWbool glfw_xkb_compile_keymap(_GLFWXKBData *xkb, const char *map_str); -void glfw_xkb_update_modifiers(_GLFWXKBData *xkb, unsigned int depressed, unsigned int latched, unsigned int locked, unsigned int group); +void glfw_xkb_update_modifiers(_GLFWXKBData *xkb, xkb_mod_mask_t depressed, xkb_mod_mask_t latched, xkb_mod_mask_t locked, xkb_layout_index_t base_group, xkb_layout_index_t latched_group, xkb_layout_index_t locked_group); GLFWbool glfw_xkb_should_repeat(_GLFWXKBData *xkb, xkb_keycode_t scancode); const char* glfw_xkb_keysym_name(xkb_keysym_t sym); xkb_keysym_t glfw_xkb_sym_for_key(int key); diff --git a/kitty/glfw-wrapper.h b/kitty/glfw-wrapper.h index a709186a8..c22ba5500 100644 --- a/kitty/glfw-wrapper.h +++ b/kitty/glfw-wrapper.h @@ -1152,6 +1152,11 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); * @param[in] text UTF-8 encoded text generated by this key event or empty string. * @param[in] reserved Reserved for future use. * + * @note On X11/Wayland if a modifier other than the modifiers GLFW reports + * (ctrl/shift/alt/super) is used, GLFW will report the shifted key rather + * than the unshifted key. So for example, if ISO_Shift_Level_5 is used to + * convert the key A into UP GLFW will report the key as UP with no modifiers. + * * @sa @ref input_key * @sa @ref glfwSetKeyboardCallback *