Port shortcut and sequence matching code

This commit is contained in:
Kovid Goyal 2021-01-14 04:26:03 +05:30
parent f94a5f4e5c
commit 6b2ffc774f
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 30 additions and 24 deletions

View File

@ -575,6 +575,10 @@ Note that the escape codes above of the form ``CSI 1 letter`` will omit the
Bugs in fixterms
-------------------
The following is a list of errata in the `original fixterms proposal
<http://www.leonerd.org.uk/hacks/fixterms/>`_ , corrected in this
specification.
* No way to disambiguate :kbd:`Esc` keypresses, other than using 8-bit controls
which are undesirable for other reasons
* Incorrectly claims special keys are sometimes encoded using ``CSI letter`` encodings when it

View File

@ -30,14 +30,14 @@
)
from .fast_data_types import (
CLOSE_BEING_CONFIRMED, IMPERATIVE_CLOSE_REQUESTED, NO_CLOSE_REQUESTED,
ChildMonitor, add_timer, background_opacity_of, change_background_opacity,
change_os_window_state, cocoa_set_menubar_title, create_os_window,
current_application_quit_request, current_os_window, destroy_global_data,
focus_os_window, get_clipboard_string, global_font_size,
mark_os_window_for_close, os_window_font_size, patch_global_colors,
safe_pipe, set_application_quit_request, set_background_image, set_boss,
set_clipboard_string, set_in_sequence_mode, thread_write,
toggle_fullscreen, toggle_maximized
ChildMonitor, KeyEvent, add_timer, background_opacity_of,
change_background_opacity, change_os_window_state, cocoa_set_menubar_title,
create_os_window, current_application_quit_request, current_os_window,
destroy_global_data, focus_os_window, get_clipboard_string,
global_font_size, mark_os_window_for_close, os_window_font_size,
patch_global_colors, safe_pipe, set_application_quit_request,
set_background_image, set_boss, set_clipboard_string, set_in_sequence_mode,
thread_write, toggle_fullscreen, toggle_maximized
)
from .keys import get_shortcut, shortcut_matches
from .layout.base import set_layout_options
@ -663,20 +663,19 @@ def active_window(self) -> Optional[Window]:
if t is not None:
return t.active_window
def dispatch_special_key(self, key: int, native_key: int, action: int, mods: int) -> bool:
def dispatch_possible_special_key(self, ev: KeyEvent) -> bool:
# Handles shortcuts, return True if the key was consumed
key_action = get_shortcut(self.keymap, mods, key, native_key)
key_action = get_shortcut(self.keymap, ev)
if key_action is None:
sequences = get_shortcut(self.opts.sequence_map, mods, key, native_key)
sequences = get_shortcut(self.opts.sequence_map, ev)
if sequences and not isinstance(sequences, KeyAction):
self.pending_sequences = sequences
set_in_sequence_mode(True)
return True
elif isinstance(key_action, KeyAction):
self.current_key_press_info = key, native_key, action, mods
return self.dispatch_action(key_action)
def process_sequence(self, key: int, native_key: int, action: Any, mods: int) -> None:
def process_sequence(self, ev: KeyEvent) -> None:
if not self.pending_sequences:
set_in_sequence_mode(False)
return
@ -684,7 +683,7 @@ def process_sequence(self, key: int, native_key: int, action: Any, mods: int) ->
remaining = {}
matched_action = None
for seq, key_action in self.pending_sequences.items():
if shortcut_matches(seq[0], mods, key, native_key):
if shortcut_matches(seq[0], ev):
seq = seq[1:]
if seq:
remaining[seq] = key_action

View File

@ -157,6 +157,7 @@ def sub(m: Match) -> str:
return {
'layouts': 'https://sw.kovidgoyal.net/kitty/index.html#layouts',
'sessions': 'https://sw.kovidgoyal.net/kitty/index.html#sessions',
'functional': 'https://sw.kovidgoyal.net/kitty/keyboard-protocol.html#functional-key-definitions',
}[m.group(2)]
return str(m.group(2))

View File

@ -135,7 +135,8 @@ def uniq(vals: Iterable[T]) -> List[T]:
_('Keyboard shortcuts'),
_('''\
Keys are identified simply by their lowercase unicode characters. For example:
``a`` for the A key, ``[`` for the left square bracket key, etc.
``a`` for the A key, ``[`` for the left square bracket key, etc. For functional
keys, such as ``Enter or Escape`` the names are present at :ref:`functional`.
For a list of modifier names, see:
:link:`GLFW mods <https://www.glfw.org/docs/latest/group__mods.html>`

View File

@ -4,8 +4,9 @@
from typing import Optional, Union
from .constants import SingleKey
from .config import KeyAction, KeyMap, SequenceMap, SubSequenceMap
from .constants import SingleKey
from .fast_data_types import KeyEvent
from .typing import ScreenType
@ -16,15 +17,15 @@ def keyboard_mode_name(screen: ScreenType) -> str:
return 'application' if screen.cursor_key_mode else 'normal'
def get_shortcut(keymap: Union[KeyMap, SequenceMap], mods: int, key: int, native_key: int) -> Optional[Union[KeyAction, SubSequenceMap]]:
mods &= 0b1111
ans = keymap.get(SingleKey(mods, False, key))
def get_shortcut(keymap: Union[KeyMap, SequenceMap], ev: KeyEvent) -> Optional[Union[KeyAction, SubSequenceMap]]:
mods = ev.mods & 0b1111
ans = keymap.get(SingleKey(mods, False, ev.key))
if ans is None:
ans = keymap.get(SingleKey(mods, True, native_key))
ans = keymap.get(SingleKey(mods, True, ev.native_key))
return ans
def shortcut_matches(s: SingleKey, mods: int, key: int, native_key: int) -> bool:
mods &= 0b1111
q = native_key if s[1] else key
return bool(s[0] & 0b1111 == mods & 0b1111 and s[2] == q)
def shortcut_matches(s: SingleKey, ev: KeyEvent) -> bool:
mods = ev.mods & 0b1111
q = ev.native_key if s.is_native else ev.key
return bool(s.mods & 0b1111 == mods & 0b1111 and s.key == q)