From a9b424e307392fecf27718b32c74dc4cf45e1515 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 14 Dec 2023 08:46:30 +0530 Subject: [PATCH] Keyboard protocol: Clarify the behavior of the modifier bits during modifier key events I cant find any relevant standards for this, so am just picking the macOS behavior as it seems more sensible to me. Fixes #6913 --- docs/keyboard-protocol.rst | 11 +++++++++++ kitty/glfw.c | 2 ++ 2 files changed, 13 insertions(+) diff --git a/docs/keyboard-protocol.rst b/docs/keyboard-protocol.rst index f6bbf3ea8..c7523cb62 100644 --- a/docs/keyboard-protocol.rst +++ b/docs/keyboard-protocol.rst @@ -185,6 +185,17 @@ In the escape code, the modifier value is encoded as a decimal number which is and so on. If the modifier field is not present in the escape code, its default value is ``1`` which means no modifiers. +When the key event is related to an actual modifier key, the corresponding modifier's bit +must be set for the press event and reset for the release event. For example +when pressing the :kbd:`LEFT_CONTROL` key, the ``ctrl`` bit must be set and +when releasing it, it must be reset. When both left and right control keys are +pressed and one is released, the release event must again have the ``ctrl`` bit +reset. + +.. note:: Not all platforms will provide independent events for left and right + modifier keys. For example on macOS, the system does not send an event to + the application when the holding left control and also pressing right + control. Therefore applications are adviced to not rely on these. .. _event_types: diff --git a/kitty/glfw.c b/kitty/glfw.c index d5794c99e..c1d027019 100644 --- a/kitty/glfw.c +++ b/kitty/glfw.c @@ -427,6 +427,8 @@ key_callback(GLFWwindow *w, GLFWkeyevent *ev) { } else { mods_at_last_key_or_button_event |= key_modifier; } + // Normalize mods state to be what the kitty keyboard protocol requires + ev->mods = mods_at_last_key_or_button_event; } global_state.callback_os_window->cursor_blink_zero_time = monotonic(); if (is_window_ready_for_callbacks()) on_key_input(ev);