From 20e43a3e7d5f6e0ae0bbff3d0cce5dc1f6a85c9a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 20 Jan 2024 08:13:12 +0530 Subject: [PATCH] Fix a regression in the previous release that caused multi-key sequences to not abort when pressing an unknown key Fixes #7022 --- docs/changelog.rst | 2 ++ kitty/boss.py | 11 +++++++++-- kitty/options/utils.py | 2 +- kitty/window.py | 11 +++++++++++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 2bd3167db..3c50128ad 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -48,6 +48,8 @@ Detailed list of changes - macOS: Fix a regression in the previous release that broke overriding keyboard shortcuts for actions present in the global menu bar (:iss:`7016`) +- Fix a regression in the previous release that caused multi-key sequences to not abort when pressing an unknown key (:iss:`7022`) + 0.32.0 [2024-01-19] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/kitty/boss.py b/kitty/boss.py index 6ba84f38a..f8e9eaeb9 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -1371,6 +1371,12 @@ class Boss: if self.global_shortcuts_map and get_shortcut(self.global_shortcuts_map, ev): return True if not is_root_mode: + if mode.sequence_keys is not None: + self.pop_keyboard_mode() + w = self.active_window + if w is not None: + w.send_key_sequence(*mode.sequence_keys) + return False if mode.on_unknown in ('beep', 'ignore'): if mode.on_unknown == 'beep' and get_options().enable_audio_bell: ring_bell() @@ -1386,16 +1392,17 @@ class Boss: if final_actions: mode_pos = len(self.keyboard_mode_stack) - 1 if final_actions[0].is_sequence: - if not mode.is_sequence: + if mode.sequence_keys is None: sm = KeyboardMode('__sequence__') sm.on_action = 'end' - sm.is_sequence = True + sm.sequence_keys = [ev] for fa in final_actions: sm.keymap[fa.rest[0]].append(fa.shift_sequence_and_copy()) self._push_keyboard_mode(sm) if self.args.debug_keyboard: print('\n\x1b[35mKeyPress\x1b[m matched sequence prefix, ', end='', flush=True) else: + mode.sequence_keys.append(ev) if len(final_actions) == 1: self.pop_keyboard_mode() return self.combine(final_actions[0].definition) diff --git a/kitty/options/utils.py b/kitty/options/utils.py index e5a60fe46..a4c146f49 100644 --- a/kitty/options/utils.py +++ b/kitty/options/utils.py @@ -1234,7 +1234,7 @@ class KeyboardMode: on_unknown: OnUnknown = get_args(OnUnknown)[0] on_action : OnAction = get_args(OnAction)[0] - is_sequence: bool = False + sequence_keys: Optional[List[defines.KeyEvent]] = None def __init__(self, name: str = '') -> None: self.name = name diff --git a/kitty/window.py b/kitty/window.py index 23555924e..33a9143ad 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -913,6 +913,17 @@ class Window: passthrough = False return passthrough + def send_key_sequence(self, *keys: KeyEvent, synthesize_release_events: bool = True) -> None: + for key in keys: + enc = self.encoded_key(key) + if enc: + self.write_to_child(enc) + if synthesize_release_events and key.action != GLFW_RELEASE: + rkey = KeyEvent(key=key.key, mods=key.mods, action=GLFW_RELEASE) + enc = self.encoded_key(rkey) + if enc: + self.write_to_child(enc) + @ac('debug', 'Show a dump of the current lines in the scrollback + screen with their line attributes') def dump_lines_with_attrs(self) -> None: strings: List[str] = []