From ce91b6d9d95a680b93cdc742f044466b7b292dfa Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 12 Aug 2022 12:21:06 +0530 Subject: [PATCH] Switch to using the new SingleKey implementation --- kitty/boss.py | 4 ++-- kitty/fast_data_types.pyi | 1 + kitty/keys.c | 13 +++++++++++++ kitty/keys.py | 3 +-- kitty/main.py | 5 ++--- kitty/options/definition.py | 2 +- kitty/options/types.py | 4 ++-- kitty/options/utils.py | 11 ++++------- kitty/types.py | 32 +++----------------------------- 9 files changed, 29 insertions(+), 46 deletions(-) diff --git a/kitty/boss.py b/kitty/boss.py index 7e77ef3e1..1ce94c490 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -31,7 +31,7 @@ from .fast_data_types import ( CLOSE_BEING_CONFIRMED, GLFW_MOD_ALT, GLFW_MOD_CONTROL, GLFW_MOD_SHIFT, GLFW_MOD_SUPER, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, IMPERATIVE_CLOSE_REQUESTED, NO_CLOSE_REQUESTED, ChildMonitor, Color, - EllipticCurveKey, KeyEvent, add_timer, apply_options_update, + EllipticCurveKey, KeyEvent, SingleKey, add_timer, apply_options_update, 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, @@ -56,7 +56,7 @@ from .session import Session, create_sessions, get_os_window_sizing_data from .tabs import ( SpecialWindow, SpecialWindowInstance, Tab, TabDict, TabManager ) -from .types import _T, AsyncResponse, SingleKey, WindowSystemMouseEvent, ac +from .types import _T, AsyncResponse, WindowSystemMouseEvent, ac from .typing import PopenType, TypedDict from .utils import ( cleanup_ssh_control_masters, func_name, get_editor, get_new_os_window_size, diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index 2e6d27079..44491dceb 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -1480,3 +1480,4 @@ class SingleKey: def key(self) -> int: ... def __iter__(self) -> Iterator[int]: ... def _replace(self, mods: int = 0, is_native: object = False, key: int = -1) -> 'SingleKey': ... + def resolve_kitty_mod(self, mod: int) -> 'SingleKey': ... diff --git a/kitty/keys.c b/kitty/keys.c index 566dcc2c2..fec331d32 100644 --- a/kitty/keys.c +++ b/kitty/keys.c @@ -412,6 +412,18 @@ static PySequenceMethods SingleKey_sequence_methods = { .sq_item = SingleKey_item, }; +static PyObject* +SingleKey_resolve_kitty_mod(SingleKey *self, PyObject *km) { + if (!(self->key.mods & GLFW_MOD_KITTY)) { Py_INCREF(self); return (PyObject*)self; } + unsigned long kitty_mod = PyLong_AsUnsignedLong(km); + if (PyErr_Occurred()) return NULL; + SingleKey *ans = (SingleKey*)SingleKey_Type.tp_alloc(&SingleKey_Type, 0); + if (!ans) return NULL; + ans->key.val = self->key.val; + ans->key.mods = (ans->key.mods & ~GLFW_MOD_KITTY) | kitty_mod; + return (PyObject*)ans; +} + static PyObject* SingleKey_replace(SingleKey *self, PyObject *args, PyObject *kw) { long key = -2; unsigned short mods = 1 << (MOD_BITS + 1); int is_native = -1; @@ -427,6 +439,7 @@ SingleKey_replace(SingleKey *self, PyObject *args, PyObject *kw) { static PyMethodDef SingleKey_methods[] = { {"_replace", (PyCFunction)(void (*) (void))SingleKey_replace, METH_VARARGS | METH_KEYWORDS, ""}, + {"resolve_kitty_mod", (PyCFunction)SingleKey_resolve_kitty_mod, METH_O, ""}, {NULL} /* Sentinel */ }; diff --git a/kitty/keys.py b/kitty/keys.py index de3dbdd3c..2663adcab 100644 --- a/kitty/keys.py +++ b/kitty/keys.py @@ -5,10 +5,9 @@ from typing import Union from .fast_data_types import ( GLFW_MOD_ALT, GLFW_MOD_CONTROL, GLFW_MOD_HYPER, GLFW_MOD_META, - GLFW_MOD_SHIFT, GLFW_MOD_SUPER, KeyEvent + GLFW_MOD_SHIFT, GLFW_MOD_SUPER, KeyEvent, SingleKey ) from .options.utils import KeyMap, SequenceMap, SubSequenceMap -from .types import SingleKey from .typing import ScreenType mod_mask = GLFW_MOD_ALT | GLFW_MOD_CONTROL | GLFW_MOD_SHIFT | GLFW_MOD_SUPER | GLFW_MOD_META | GLFW_MOD_HYPER diff --git a/kitty/main.py b/kitty/main.py index 170c25b5f..3045ad418 100644 --- a/kitty/main.py +++ b/kitty/main.py @@ -21,8 +21,8 @@ from .constants import ( running_in_kitty, website_url ) from .fast_data_types import ( - GLFW_IBEAM_CURSOR, GLFW_MOD_ALT, GLFW_MOD_SHIFT, create_os_window, - free_font_data, glfw_init, glfw_terminate, load_png_data, + GLFW_IBEAM_CURSOR, GLFW_MOD_ALT, GLFW_MOD_SHIFT, SingleKey, + create_os_window, free_font_data, glfw_init, glfw_terminate, load_png_data, set_custom_cursor, set_default_window_icon, set_options ) from .fonts.box_drawing import set_scale @@ -32,7 +32,6 @@ from .options.utils import DELETE_ENV_VAR from .os_window_size import initial_window_size_func from .prewarm import PrewarmProcess, fork_prewarm_process from .session import create_sessions, get_os_window_sizing_data -from .types import SingleKey from .utils import ( cleanup_ssh_control_masters, detach, expandvars, log_error, single_instance, startup_notification_handler, unix_socket_paths diff --git a/kitty/options/definition.py b/kitty/options/definition.py index 91ec0ce19..867c430cb 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -11,7 +11,7 @@ from kitty.constants import website_url definition = Definition( 'kitty', Action('map', 'parse_map', {'keymap': 'KeyMap', 'sequence_map': 'SequenceMap', 'alias_map': 'AliasMap'}, - ['KeyDefinition', 'kitty.types.SingleKey']), + ['KeyDefinition', 'kitty.fast_data_types.SingleKey']), Action('mouse_map', 'parse_mouse_map', {'mousemap': 'MouseMap'}, ['MouseMapping']), has_color_table=True, ) diff --git a/kitty/options/types.py b/kitty/options/types.py index e741581dd..d60eb3398 100644 --- a/kitty/options/types.py +++ b/kitty/options/types.py @@ -4,12 +4,12 @@ import typing from array import array from kitty.constants import is_macos import kitty.constants -from kitty.fast_data_types import Color +from kitty.fast_data_types import Color, SingleKey import kitty.fast_data_types import kitty.fonts from kitty.options.utils import AliasMap, KeyDefinition, KeyMap, MouseMap, MouseMapping, SequenceMap, TabBarMarginHeight import kitty.options.utils -from kitty.types import FloatEdges, SingleKey +from kitty.types import FloatEdges import kitty.types if typing.TYPE_CHECKING: diff --git a/kitty/options/utils.py b/kitty/options/utils.py index de6558ee6..2f5ef4f22 100644 --- a/kitty/options/utils.py +++ b/kitty/options/utils.py @@ -18,7 +18,7 @@ from kitty.conf.utils import ( ) from kitty.constants import is_macos from kitty.fast_data_types import ( - CURSOR_BEAM, CURSOR_BLOCK, CURSOR_UNDERLINE, Color + CURSOR_BEAM, CURSOR_BLOCK, CURSOR_UNDERLINE, Color, SingleKey ) from kitty.fonts import ( FontFeature, FontModification, ModificationType, ModificationUnit, @@ -29,7 +29,7 @@ from kitty.key_names import ( get_key_name_lookup ) from kitty.rgb import color_as_int -from kitty.types import FloatEdges, MouseEvent, SingleKey +from kitty.types import FloatEdges, MouseEvent from kitty.utils import expandvars, log_error, resolve_abs_or_config_path KeyMap = Dict[SingleKey, str] @@ -1023,9 +1023,7 @@ class BaseDefinition: def resolve_key_mods(kitty_mod: int, mods: int) -> int: - if mods & defines.GLFW_MOD_KITTY: - mods = (mods & ~defines.GLFW_MOD_KITTY) | kitty_mod - return mods + return SingleKey(mods=mods).resolve_kitty_mod(kitty_mod).mods class MouseMapping(BaseDefinition): @@ -1072,8 +1070,7 @@ class KeyDefinition(BaseDefinition): def resolve_and_copy(self, kitty_mod: int) -> 'KeyDefinition': def r(k: SingleKey) -> SingleKey: - mods = resolve_key_mods(kitty_mod, k.mods) - return k._replace(mods=mods) + return k.resolve_kitty_mod(kitty_mod) ans = KeyDefinition( self.is_sequence, r(self.trigger), tuple(map(r, self.rest)), self.definition diff --git a/kitty/types.py b/kitty/types.py index bb73a0f60..45803cdf9 100644 --- a/kitty/types.py +++ b/kitty/types.py @@ -5,6 +5,8 @@ from functools import update_wrapper from typing import ( TYPE_CHECKING, Any, Callable, Generic, NamedTuple, Tuple, TypeVar, Union, Iterator, Dict ) +if TYPE_CHECKING: + from kitty.fast_data_types import SingleKey _T = TypeVar('_T') @@ -59,36 +61,8 @@ def mod_to_names(mods: int, kitty_mod: int = 0) -> Iterator[str]: yield name -class SingleKey(NamedTuple): - mods: int = 0 - is_native: bool = False - key: int = -1 - - def __repr__(self) -> str: - kwds = [] - for i, f in enumerate(self._fields): - val = self[i] - if val != self._field_defaults[f]: - kwds.append(f'{f}={val!r}') - return 'SingleKey(' + ', '.join(kwds) + ')' - - def human_repr_with_kitty_mod(self, kitty_mod: int = 0) -> str: - from .fast_data_types import glfw_get_key_name - names = [] - names = list(mod_to_names(self.mods, kitty_mod)) - if self.key > 0: - kname = (glfw_get_key_name(0, self.key) if self.is_native else glfw_get_key_name(self.key, 0)) or f'{self.key}' - kname = {' ': 'space'}.get(kname, kname) - names.append(kname) - return '+'.join(names) - - @property - def human_repr(self) -> str: - return self.human_repr_with_kitty_mod() - - class Shortcut(NamedTuple): - keys: Tuple[SingleKey, ...] + keys: Tuple['SingleKey', ...] kitty_mod: int = 0 @property