More removal of GLFW_KEY_ constants
This commit is contained in:
parent
774a6c8c8b
commit
1690718710
@ -430,6 +430,9 @@ Bugs in fixterms
|
||||
* Incorrectly claims special keys are sometimes encoded using ``CSI letter`` encodings when it
|
||||
is actually ``ESC O letter``.
|
||||
* ``Enter`` and ``F3`` are both assigned the number 13.
|
||||
* :kbd:`ctrl+shift+tab`` should be ``CSI 9 ; 6 u`` not ``CSI 1 ; 5 Z``
|
||||
(shift+tab is not a separate key from tab)
|
||||
* No support for the :kbd:`super` modifier.
|
||||
* Makes no mention of cursor key mode and how it changes encodings
|
||||
* Incorrectly encoding shifted keys when shift modifier is used, for
|
||||
instance, for :kbd:`ctrl+shift+I`.
|
||||
|
||||
@ -180,7 +180,7 @@ def generate_glfw_header() -> None:
|
||||
lines.append('} GLFWFunctionKey;')
|
||||
patch_file('glfw/glfw3.h', 'functional key names', '\n'.join(lines))
|
||||
patch_file('kitty/glfw.c', 'glfw functional keys', '\n'.join(klines))
|
||||
patch_file('kitty/fast_data_types.pyi', 'glfw functional keys', '\n'.join(klines), start_marker='# ', end_marker='')
|
||||
patch_file('kitty/fast_data_types.pyi', 'glfw functional keys', '\n'.join(pyi), start_marker='# ', end_marker='')
|
||||
patch_file('glfw/input.c', 'functional key names', '\n'.join(names))
|
||||
|
||||
|
||||
|
||||
@ -394,7 +394,7 @@ def parse_key(val: str, key_definitions: List[KeyDefinition]) -> None:
|
||||
mods, is_native, key = parse_shortcut(part)
|
||||
except InvalidMods:
|
||||
return
|
||||
if key is defines.GLFW_KEY_UNKNOWN:
|
||||
if key == 0:
|
||||
if mods is not None:
|
||||
log_error('Shortcut: {} has unknown key, ignoring'.format(sc))
|
||||
return
|
||||
@ -408,7 +408,7 @@ def parse_key(val: str, key_definitions: List[KeyDefinition]) -> None:
|
||||
mods, is_native, key = parse_shortcut(sc)
|
||||
except InvalidMods:
|
||||
return
|
||||
if key is defines.GLFW_KEY_UNKNOWN:
|
||||
if key == 0:
|
||||
if mods is not None:
|
||||
log_error('Shortcut: {} has unknown key, ignoring'.format(sc))
|
||||
return
|
||||
|
||||
@ -78,7 +78,7 @@ def parse_shortcut(sc: str) -> SingleKey:
|
||||
else:
|
||||
key = get_key_name_lookup()(q, False)
|
||||
is_native = key is not None
|
||||
return SingleKey(mods, is_native, key or defines.GLFW_KEY_UNKNOWN)
|
||||
return SingleKey(mods, is_native, key or 0)
|
||||
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
@ -18,110 +18,110 @@ ERROR_PREFIX: str
|
||||
GLSL_VERSION: int
|
||||
GLFW_IBEAM_CURSOR: int
|
||||
# start glfw functional keys (auto generated by gen-key-constants.py do not edit)
|
||||
ADDC(GLFW_FKEY_ESCAPE);
|
||||
ADDC(GLFW_FKEY_ENTER);
|
||||
ADDC(GLFW_FKEY_TAB);
|
||||
ADDC(GLFW_FKEY_BACKSPACE);
|
||||
ADDC(GLFW_FKEY_INSERT);
|
||||
ADDC(GLFW_FKEY_DELETE);
|
||||
ADDC(GLFW_FKEY_LEFT);
|
||||
ADDC(GLFW_FKEY_RIGHT);
|
||||
ADDC(GLFW_FKEY_UP);
|
||||
ADDC(GLFW_FKEY_DOWN);
|
||||
ADDC(GLFW_FKEY_PAGE_UP);
|
||||
ADDC(GLFW_FKEY_PAGE_DOWN);
|
||||
ADDC(GLFW_FKEY_HOME);
|
||||
ADDC(GLFW_FKEY_END);
|
||||
ADDC(GLFW_FKEY_CAPS_LOCK);
|
||||
ADDC(GLFW_FKEY_SCROLL_LOCK);
|
||||
ADDC(GLFW_FKEY_NUM_LOCK);
|
||||
ADDC(GLFW_FKEY_PRINT_SCREEN);
|
||||
ADDC(GLFW_FKEY_PAUSE);
|
||||
ADDC(GLFW_FKEY_MENU);
|
||||
ADDC(GLFW_FKEY_F1);
|
||||
ADDC(GLFW_FKEY_F2);
|
||||
ADDC(GLFW_FKEY_F3);
|
||||
ADDC(GLFW_FKEY_F4);
|
||||
ADDC(GLFW_FKEY_F5);
|
||||
ADDC(GLFW_FKEY_F6);
|
||||
ADDC(GLFW_FKEY_F7);
|
||||
ADDC(GLFW_FKEY_F8);
|
||||
ADDC(GLFW_FKEY_F9);
|
||||
ADDC(GLFW_FKEY_F10);
|
||||
ADDC(GLFW_FKEY_F11);
|
||||
ADDC(GLFW_FKEY_F12);
|
||||
ADDC(GLFW_FKEY_F13);
|
||||
ADDC(GLFW_FKEY_F14);
|
||||
ADDC(GLFW_FKEY_F15);
|
||||
ADDC(GLFW_FKEY_F16);
|
||||
ADDC(GLFW_FKEY_F17);
|
||||
ADDC(GLFW_FKEY_F18);
|
||||
ADDC(GLFW_FKEY_F19);
|
||||
ADDC(GLFW_FKEY_F20);
|
||||
ADDC(GLFW_FKEY_F21);
|
||||
ADDC(GLFW_FKEY_F22);
|
||||
ADDC(GLFW_FKEY_F23);
|
||||
ADDC(GLFW_FKEY_F24);
|
||||
ADDC(GLFW_FKEY_F25);
|
||||
ADDC(GLFW_FKEY_F26);
|
||||
ADDC(GLFW_FKEY_F27);
|
||||
ADDC(GLFW_FKEY_F28);
|
||||
ADDC(GLFW_FKEY_F29);
|
||||
ADDC(GLFW_FKEY_F30);
|
||||
ADDC(GLFW_FKEY_F31);
|
||||
ADDC(GLFW_FKEY_F32);
|
||||
ADDC(GLFW_FKEY_F33);
|
||||
ADDC(GLFW_FKEY_F34);
|
||||
ADDC(GLFW_FKEY_F35);
|
||||
ADDC(GLFW_FKEY_KP_0);
|
||||
ADDC(GLFW_FKEY_KP_1);
|
||||
ADDC(GLFW_FKEY_KP_2);
|
||||
ADDC(GLFW_FKEY_KP_3);
|
||||
ADDC(GLFW_FKEY_KP_4);
|
||||
ADDC(GLFW_FKEY_KP_5);
|
||||
ADDC(GLFW_FKEY_KP_6);
|
||||
ADDC(GLFW_FKEY_KP_7);
|
||||
ADDC(GLFW_FKEY_KP_8);
|
||||
ADDC(GLFW_FKEY_KP_9);
|
||||
ADDC(GLFW_FKEY_KP_DECIMAL);
|
||||
ADDC(GLFW_FKEY_KP_DIVIDE);
|
||||
ADDC(GLFW_FKEY_KP_MULTIPLY);
|
||||
ADDC(GLFW_FKEY_KP_SUBTRACT);
|
||||
ADDC(GLFW_FKEY_KP_ADD);
|
||||
ADDC(GLFW_FKEY_KP_ENTER);
|
||||
ADDC(GLFW_FKEY_KP_EQUAL);
|
||||
ADDC(GLFW_FKEY_KP_SEPARATOR);
|
||||
ADDC(GLFW_FKEY_KP_LEFT);
|
||||
ADDC(GLFW_FKEY_KP_RIGHT);
|
||||
ADDC(GLFW_FKEY_KP_UP);
|
||||
ADDC(GLFW_FKEY_KP_DOWN);
|
||||
ADDC(GLFW_FKEY_KP_PAGE_UP);
|
||||
ADDC(GLFW_FKEY_KP_PAGE_DOWN);
|
||||
ADDC(GLFW_FKEY_KP_HOME);
|
||||
ADDC(GLFW_FKEY_KP_END);
|
||||
ADDC(GLFW_FKEY_KP_INSERT);
|
||||
ADDC(GLFW_FKEY_KP_DELETE);
|
||||
ADDC(GLFW_FKEY_LEFT_SHIFT);
|
||||
ADDC(GLFW_FKEY_LEFT_CONTROL);
|
||||
ADDC(GLFW_FKEY_LEFT_ALT);
|
||||
ADDC(GLFW_FKEY_LEFT_SUPER);
|
||||
ADDC(GLFW_FKEY_RIGHT_SHIFT);
|
||||
ADDC(GLFW_FKEY_RIGHT_CONTROL);
|
||||
ADDC(GLFW_FKEY_RIGHT_ALT);
|
||||
ADDC(GLFW_FKEY_RIGHT_SUPER);
|
||||
ADDC(GLFW_FKEY_MEDIA_PLAY);
|
||||
ADDC(GLFW_FKEY_MEDIA_PAUSE);
|
||||
ADDC(GLFW_FKEY_MEDIA_PLAY_PAUSE);
|
||||
ADDC(GLFW_FKEY_MEDIA_REVERSE);
|
||||
ADDC(GLFW_FKEY_MEDIA_STOP);
|
||||
ADDC(GLFW_FKEY_MEDIA_FAST_FORWARD);
|
||||
ADDC(GLFW_FKEY_MEDIA_REWIND);
|
||||
ADDC(GLFW_FKEY_MEDIA_TRACK_NEXT);
|
||||
ADDC(GLFW_FKEY_MEDIA_TRACK_PREVIOUS);
|
||||
ADDC(GLFW_FKEY_MEDIA_RECORD);
|
||||
ADDC(GLFW_FKEY_LOWER_VOLUME);
|
||||
ADDC(GLFW_FKEY_RAISE_VOLUME);
|
||||
ADDC(GLFW_FKEY_MUTE_VOLUME);
|
||||
GLFW_FKEY_ESCAPE: int
|
||||
GLFW_FKEY_ENTER: int
|
||||
GLFW_FKEY_TAB: int
|
||||
GLFW_FKEY_BACKSPACE: int
|
||||
GLFW_FKEY_INSERT: int
|
||||
GLFW_FKEY_DELETE: int
|
||||
GLFW_FKEY_LEFT: int
|
||||
GLFW_FKEY_RIGHT: int
|
||||
GLFW_FKEY_UP: int
|
||||
GLFW_FKEY_DOWN: int
|
||||
GLFW_FKEY_PAGE_UP: int
|
||||
GLFW_FKEY_PAGE_DOWN: int
|
||||
GLFW_FKEY_HOME: int
|
||||
GLFW_FKEY_END: int
|
||||
GLFW_FKEY_CAPS_LOCK: int
|
||||
GLFW_FKEY_SCROLL_LOCK: int
|
||||
GLFW_FKEY_NUM_LOCK: int
|
||||
GLFW_FKEY_PRINT_SCREEN: int
|
||||
GLFW_FKEY_PAUSE: int
|
||||
GLFW_FKEY_MENU: int
|
||||
GLFW_FKEY_F1: int
|
||||
GLFW_FKEY_F2: int
|
||||
GLFW_FKEY_F3: int
|
||||
GLFW_FKEY_F4: int
|
||||
GLFW_FKEY_F5: int
|
||||
GLFW_FKEY_F6: int
|
||||
GLFW_FKEY_F7: int
|
||||
GLFW_FKEY_F8: int
|
||||
GLFW_FKEY_F9: int
|
||||
GLFW_FKEY_F10: int
|
||||
GLFW_FKEY_F11: int
|
||||
GLFW_FKEY_F12: int
|
||||
GLFW_FKEY_F13: int
|
||||
GLFW_FKEY_F14: int
|
||||
GLFW_FKEY_F15: int
|
||||
GLFW_FKEY_F16: int
|
||||
GLFW_FKEY_F17: int
|
||||
GLFW_FKEY_F18: int
|
||||
GLFW_FKEY_F19: int
|
||||
GLFW_FKEY_F20: int
|
||||
GLFW_FKEY_F21: int
|
||||
GLFW_FKEY_F22: int
|
||||
GLFW_FKEY_F23: int
|
||||
GLFW_FKEY_F24: int
|
||||
GLFW_FKEY_F25: int
|
||||
GLFW_FKEY_F26: int
|
||||
GLFW_FKEY_F27: int
|
||||
GLFW_FKEY_F28: int
|
||||
GLFW_FKEY_F29: int
|
||||
GLFW_FKEY_F30: int
|
||||
GLFW_FKEY_F31: int
|
||||
GLFW_FKEY_F32: int
|
||||
GLFW_FKEY_F33: int
|
||||
GLFW_FKEY_F34: int
|
||||
GLFW_FKEY_F35: int
|
||||
GLFW_FKEY_KP_0: int
|
||||
GLFW_FKEY_KP_1: int
|
||||
GLFW_FKEY_KP_2: int
|
||||
GLFW_FKEY_KP_3: int
|
||||
GLFW_FKEY_KP_4: int
|
||||
GLFW_FKEY_KP_5: int
|
||||
GLFW_FKEY_KP_6: int
|
||||
GLFW_FKEY_KP_7: int
|
||||
GLFW_FKEY_KP_8: int
|
||||
GLFW_FKEY_KP_9: int
|
||||
GLFW_FKEY_KP_DECIMAL: int
|
||||
GLFW_FKEY_KP_DIVIDE: int
|
||||
GLFW_FKEY_KP_MULTIPLY: int
|
||||
GLFW_FKEY_KP_SUBTRACT: int
|
||||
GLFW_FKEY_KP_ADD: int
|
||||
GLFW_FKEY_KP_ENTER: int
|
||||
GLFW_FKEY_KP_EQUAL: int
|
||||
GLFW_FKEY_KP_SEPARATOR: int
|
||||
GLFW_FKEY_KP_LEFT: int
|
||||
GLFW_FKEY_KP_RIGHT: int
|
||||
GLFW_FKEY_KP_UP: int
|
||||
GLFW_FKEY_KP_DOWN: int
|
||||
GLFW_FKEY_KP_PAGE_UP: int
|
||||
GLFW_FKEY_KP_PAGE_DOWN: int
|
||||
GLFW_FKEY_KP_HOME: int
|
||||
GLFW_FKEY_KP_END: int
|
||||
GLFW_FKEY_KP_INSERT: int
|
||||
GLFW_FKEY_KP_DELETE: int
|
||||
GLFW_FKEY_LEFT_SHIFT: int
|
||||
GLFW_FKEY_LEFT_CONTROL: int
|
||||
GLFW_FKEY_LEFT_ALT: int
|
||||
GLFW_FKEY_LEFT_SUPER: int
|
||||
GLFW_FKEY_RIGHT_SHIFT: int
|
||||
GLFW_FKEY_RIGHT_CONTROL: int
|
||||
GLFW_FKEY_RIGHT_ALT: int
|
||||
GLFW_FKEY_RIGHT_SUPER: int
|
||||
GLFW_FKEY_MEDIA_PLAY: int
|
||||
GLFW_FKEY_MEDIA_PAUSE: int
|
||||
GLFW_FKEY_MEDIA_PLAY_PAUSE: int
|
||||
GLFW_FKEY_MEDIA_REVERSE: int
|
||||
GLFW_FKEY_MEDIA_STOP: int
|
||||
GLFW_FKEY_MEDIA_FAST_FORWARD: int
|
||||
GLFW_FKEY_MEDIA_REWIND: int
|
||||
GLFW_FKEY_MEDIA_TRACK_NEXT: int
|
||||
GLFW_FKEY_MEDIA_TRACK_PREVIOUS: int
|
||||
GLFW_FKEY_MEDIA_RECORD: int
|
||||
GLFW_FKEY_LOWER_VOLUME: int
|
||||
GLFW_FKEY_RAISE_VOLUME: int
|
||||
GLFW_FKEY_MUTE_VOLUME: int
|
||||
# end glfw functional keys
|
||||
GLFW_MOD_SHIFT: int
|
||||
GLFW_MOD_CONTROL: int
|
||||
@ -257,6 +257,19 @@ MOVE: int
|
||||
# }}}
|
||||
|
||||
|
||||
def encode_key_for_tty(
|
||||
key: int = 0,
|
||||
shifted_key: int = 0,
|
||||
alternate_key: int = 0,
|
||||
mods: int = 0,
|
||||
action: int = 1,
|
||||
key_encoding_flags: int = 0,
|
||||
text: str = "",
|
||||
cursor_key_mode: bool = False
|
||||
) -> str:
|
||||
pass
|
||||
|
||||
|
||||
def log_error_string(s: str) -> None:
|
||||
pass
|
||||
|
||||
@ -908,7 +921,6 @@ class Screen:
|
||||
scrolled_by: int
|
||||
cursor: Cursor
|
||||
disable_ligatures: int
|
||||
extended_keyboard: bool
|
||||
cursor_key_mode: bool
|
||||
auto_repeat_enabled: bool
|
||||
|
||||
@ -922,6 +934,9 @@ class Screen:
|
||||
):
|
||||
pass
|
||||
|
||||
def current_key_encoding_flags(self) -> int:
|
||||
pass
|
||||
|
||||
def line(self, num: int) -> Line:
|
||||
pass
|
||||
|
||||
@ -1086,9 +1101,5 @@ def spawn(
|
||||
pass
|
||||
|
||||
|
||||
def key_to_bytes(glfw_key: int, smkx: bool, extended: bool, mods: int, action: int) -> bytes:
|
||||
pass
|
||||
|
||||
|
||||
def set_window_padding(os_window_id: int, tab_id: int, window_id: int, left: int, top: int, right: int, bottom: int) -> None:
|
||||
pass
|
||||
|
||||
@ -116,11 +116,6 @@ encode_function_key(const KeyEvent *ev, char *output) {
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
if (key_number == GLFW_FKEY_TAB) {
|
||||
if (ev->mods.value == SHIFT) return encode_csi_string('Z', "", output);
|
||||
if (ev->mods.value == (CTRL | SHIFT)) return encode_csi_string('Z', "1;5", output);
|
||||
if (ev->mods.value == ALT) SIMPLE("\x1b\t");
|
||||
}
|
||||
if (ev->mods.value == ALT) {
|
||||
switch(key_number) {
|
||||
case GLFW_FKEY_TAB: SIMPLE("\x1b\t");
|
||||
@ -128,6 +123,7 @@ encode_function_key(const KeyEvent *ev, char *output) {
|
||||
case GLFW_FKEY_BACKSPACE: SIMPLE("\x1b\x7f");
|
||||
}
|
||||
}
|
||||
if (ev->mods.value == SHIFT && key_number == GLFW_FKEY_TAB) { SIMPLE("\x1b[Z"); }
|
||||
#undef SIMPLE
|
||||
|
||||
#define S(number, trailer) key_number = number; csi_trailer = trailer; break
|
||||
@ -185,7 +181,7 @@ encode_printable_ascii_key_legacy(const KeyEvent *ev, char *output) {
|
||||
shifted_key = (shifted_key && ev->mods.shift) ? shifted_key : (char)ev->key;
|
||||
if ((ev->mods.value == ALT || ev->mods.value == (SHIFT | ALT)))
|
||||
return snprintf(output, KEY_BUFFER_SIZE, "\x1b%c", shifted_key);
|
||||
if (ev->mods.value == CTRL)
|
||||
if (ev->mods.value == CTRL && ev->key && 0x1f != ev->key)
|
||||
return snprintf(output, KEY_BUFFER_SIZE, "%c", ev->key & 0x1f);
|
||||
if (ev->mods.value == (CTRL | ALT))
|
||||
return snprintf(output, KEY_BUFFER_SIZE, "\x1b%c", ev->key & 0x1f);
|
||||
|
||||
@ -34,57 +34,6 @@ key_name_aliases = {
|
||||
'^': 'CIRCUMFLEX',
|
||||
'_': 'UNDERSCORE',
|
||||
'`': 'GRAVE_ACCENT',
|
||||
'§': 'PARAGRAPH',
|
||||
'º': 'MASCULINE',
|
||||
'À': 'A_GRAVE',
|
||||
'Ä': 'A_DIAERESIS',
|
||||
'Å': 'A_RING',
|
||||
'Æ': 'AE',
|
||||
'Ç': 'C_CEDILLA',
|
||||
'È': 'E_GRAVE',
|
||||
'É': 'E_ACUTE',
|
||||
'Ì': 'I_GRAVE',
|
||||
'Ñ': 'N_TILDE',
|
||||
'Ò': 'O_GRAVE',
|
||||
'Ö': 'O_DIAERESIS',
|
||||
'Ø': 'O_SLASH',
|
||||
'Ù': 'U_GRAVE',
|
||||
'Ü': 'U_DIAERESIS',
|
||||
'SS': 'S_SHARP', # 'ß'.upper() == 'SS'
|
||||
'А': 'CYRILLIC_A',
|
||||
'Б': 'CYRILLIC_BE',
|
||||
'В': 'CYRILLIC_VE',
|
||||
'Г': 'CYRILLIC_GHE',
|
||||
'Д': 'CYRILLIC_DE',
|
||||
'Е': 'CYRILLIC_IE',
|
||||
'Ж': 'CYRILLIC_ZHE',
|
||||
'З': 'CYRILLIC_ZE',
|
||||
'И': 'CYRILLIC_I',
|
||||
'Й': 'CYRILLIC_SHORT_I',
|
||||
'К': 'CYRILLIC_KA',
|
||||
'Л': 'CYRILLIC_EL',
|
||||
'М': 'CYRILLIC_EM',
|
||||
'Н': 'CYRILLIC_EN',
|
||||
'О': 'CYRILLIC_O',
|
||||
'П': 'CYRILLIC_PE',
|
||||
'Р': 'CYRILLIC_ER',
|
||||
'С': 'CYRILLIC_ES',
|
||||
'Т': 'CYRILLIC_TE',
|
||||
'У': 'CYRILLIC_U',
|
||||
'Ф': 'CYRILLIC_EF',
|
||||
'Х': 'CYRILLIC_HA',
|
||||
'Ц': 'CYRILLIC_TSE',
|
||||
'Ч': 'CYRILLIC_CHE',
|
||||
'Ш': 'CYRILLIC_SHA',
|
||||
'Щ': 'CYRILLIC_SHCHA',
|
||||
'Ъ': 'CYRILLIC_HARD_SIGN',
|
||||
'Ы': 'CYRILLIC_YERU',
|
||||
'Ь': 'CYRILLIC_SOFT_SIGN',
|
||||
'Э': 'CYRILLIC_E',
|
||||
'Ю': 'CYRILLIC_YU',
|
||||
'Я': 'CYRILLIC_YA',
|
||||
'Ё': 'CYRILLIC_IO',
|
||||
|
||||
'ESC': 'ESCAPE',
|
||||
'PGUP': 'PAGE_UP',
|
||||
'PAGEUP': 'PAGE_UP',
|
||||
|
||||
374
kitty/keys.py
374
kitty/keys.py
@ -2,281 +2,19 @@
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import string
|
||||
from typing import Any, Callable, Dict, Iterable, Optional, Tuple, Union
|
||||
from typing import Optional, Union
|
||||
|
||||
from . import fast_data_types as defines
|
||||
from .constants import SingleKey
|
||||
from .config import KeyAction, KeyMap, SequenceMap, SubSequenceMap
|
||||
from .key_encoding import KEY_MAP
|
||||
from .terminfo import key_as_bytes, modify_key_bytes
|
||||
from .typing import ScreenType, WindowType
|
||||
from .utils import base64_encode
|
||||
|
||||
|
||||
def modify_complex_key(name: Union[str, bytes], amt: int) -> bytes:
|
||||
q = name if isinstance(name, bytes) else key_as_bytes(name)
|
||||
return modify_key_bytes(q, amt)
|
||||
|
||||
|
||||
control_codes: Dict[int, Union[bytes, Tuple[int, ...]]] = {
|
||||
defines.GLFW_KEY_BACKSPACE: b'\x08'
|
||||
}
|
||||
smkx_key_map = {}
|
||||
alt_codes = {
|
||||
defines.GLFW_KEY_TAB: b'\033\t',
|
||||
defines.GLFW_KEY_ENTER: b'\033\r',
|
||||
defines.GLFW_KEY_ESCAPE: b'\033\033',
|
||||
defines.GLFW_KEY_BACKSPACE: b'\033\177'
|
||||
}
|
||||
shift_alt_codes = alt_codes.copy()
|
||||
shift_alt_codes[defines.GLFW_KEY_TAB] = key_as_bytes('kcbt')
|
||||
alt_mods = (defines.GLFW_MOD_ALT, defines.GLFW_MOD_SHIFT | defines.GLFW_MOD_ALT)
|
||||
ctrl_shift_mod = defines.GLFW_MOD_SHIFT | defines.GLFW_MOD_CONTROL
|
||||
ctrl_alt_mod = defines.GLFW_MOD_ALT | defines.GLFW_MOD_CONTROL
|
||||
ctrl_alt_shift_mod = ctrl_alt_mod | defines.GLFW_MOD_SHIFT
|
||||
SHIFTED_KEYS = {
|
||||
defines.GLFW_KEY_TAB: key_as_bytes('kcbt'),
|
||||
defines.GLFW_KEY_HOME: key_as_bytes('kHOM'),
|
||||
defines.GLFW_KEY_END: key_as_bytes('kEND'),
|
||||
defines.GLFW_KEY_LEFT: key_as_bytes('kLFT'),
|
||||
defines.GLFW_KEY_RIGHT: key_as_bytes('kRIT'),
|
||||
defines.GLFW_KEY_UP: key_as_bytes('kri'),
|
||||
defines.GLFW_KEY_DOWN: key_as_bytes('kind'),
|
||||
defines.GLFW_KEY_PAGE_UP: modify_complex_key('kpp', 2),
|
||||
defines.GLFW_KEY_PAGE_DOWN: modify_complex_key('knp', 2),
|
||||
}
|
||||
|
||||
control_alt_codes = {
|
||||
defines.GLFW_KEY_SPACE: b'\x1b\0',
|
||||
}
|
||||
control_alt_shift_codes: Dict[int, bytes] = {}
|
||||
ASCII_C0_SHIFTED = {
|
||||
# ^@
|
||||
'2': b'\x00',
|
||||
# ^^
|
||||
'6': b'\x1e',
|
||||
# ^_
|
||||
'MINUS': b'\x1f',
|
||||
# ^?
|
||||
'SLASH': b'\x7f',
|
||||
}
|
||||
control_shift_keys = {getattr(defines, 'GLFW_KEY_' + k): v for k, v in ASCII_C0_SHIFTED.items()}
|
||||
|
||||
|
||||
def create_modifier_variants(keycode: int, terminfo_name_or_bytes: Union[str, bytes], add_shifted_key: bool = True) -> None:
|
||||
kn = terminfo_name_or_bytes
|
||||
smkx_key_map[keycode] = kn if isinstance(kn, bytes) else key_as_bytes(kn)
|
||||
if add_shifted_key:
|
||||
SHIFTED_KEYS[keycode] = modify_complex_key(kn, 2)
|
||||
alt_codes[keycode] = modify_complex_key(kn, 3)
|
||||
shift_alt_codes[keycode] = modify_complex_key(kn, 4)
|
||||
control_codes[keycode] = modify_complex_key(kn, 5)
|
||||
control_shift_keys[keycode] = modify_complex_key(kn, 6)
|
||||
control_alt_codes[keycode] = modify_complex_key(kn, 7)
|
||||
control_alt_shift_codes[keycode] = modify_complex_key(kn, 8)
|
||||
|
||||
|
||||
for kf, kn in {
|
||||
defines.GLFW_KEY_UP: 'kcuu1',
|
||||
defines.GLFW_KEY_DOWN: 'kcud1',
|
||||
defines.GLFW_KEY_LEFT: 'kcub1',
|
||||
defines.GLFW_KEY_RIGHT: 'kcuf1',
|
||||
defines.GLFW_KEY_HOME: 'khome',
|
||||
defines.GLFW_KEY_END: 'kend',
|
||||
defines.GLFW_KEY_INSERT: 'kich1',
|
||||
defines.GLFW_KEY_DELETE: 'kdch1',
|
||||
defines.GLFW_KEY_PAGE_UP: 'kpp',
|
||||
defines.GLFW_KEY_PAGE_DOWN: 'knp',
|
||||
}.items():
|
||||
create_modifier_variants(kf, kn, add_shifted_key=False)
|
||||
for f in range(1, 13):
|
||||
kf = getattr(defines, 'GLFW_KEY_F{}'.format(f))
|
||||
kn = 'kf{}'.format(f)
|
||||
create_modifier_variants(kf, kn)
|
||||
for f in range(13, 26):
|
||||
kf = getattr(defines, 'GLFW_KEY_F{}'.format(f))
|
||||
kn = 'kf{}'.format(f)
|
||||
smkx_key_map[kf] = key_as_bytes(kn)
|
||||
create_modifier_variants(defines.GLFW_KEY_MENU, b'\x1b[29~')
|
||||
f_ = {k: k for k in '0123456789'}
|
||||
f_.update({
|
||||
'COMMA': ',',
|
||||
'PERIOD': '.',
|
||||
'SEMICOLON': ';',
|
||||
'APOSTROPHE': "'",
|
||||
'MINUS': '-',
|
||||
'EQUAL': '=',
|
||||
})
|
||||
for kf_, kn_ in f_.items():
|
||||
control_codes[getattr(defines, 'GLFW_KEY_' + kf_)] = (ord(kn_),)
|
||||
del f, f_, kf, kn, kf_, kn_
|
||||
|
||||
smkx_key_map[defines.GLFW_KEY_ESCAPE] = b'\033'
|
||||
smkx_key_map[defines.GLFW_KEY_ENTER] = b'\r'
|
||||
smkx_key_map[defines.GLFW_KEY_KP_ENTER] = b'\r'
|
||||
smkx_key_map[defines.GLFW_KEY_BACKSPACE] = key_as_bytes('kbs')
|
||||
smkx_key_map[defines.GLFW_KEY_TAB] = b'\t'
|
||||
|
||||
control_codes.update({
|
||||
k: (1 + i, )
|
||||
for i, k in
|
||||
enumerate(range(defines.GLFW_KEY_A, defines.GLFW_KEY_RIGHT_BRACKET + 1))
|
||||
})
|
||||
control_codes[defines.GLFW_KEY_GRAVE_ACCENT] = control_codes[defines.GLFW_KEY_UNDERSCORE] = \
|
||||
control_codes[defines.GLFW_KEY_SPACE] = control_codes[defines.GLFW_KEY_2] = (0,)
|
||||
control_codes[defines.GLFW_KEY_3] = (27,)
|
||||
control_codes[defines.GLFW_KEY_4] = (28,)
|
||||
control_codes[defines.GLFW_KEY_5] = (29,)
|
||||
control_codes[defines.GLFW_KEY_6] = control_codes[defines.GLFW_KEY_CIRCUMFLEX] = (30,)
|
||||
control_codes[defines.GLFW_KEY_7] = control_codes[defines.GLFW_KEY_SLASH] = (31,)
|
||||
control_codes[defines.GLFW_KEY_8] = (127,)
|
||||
|
||||
rmkx_key_map = smkx_key_map.copy()
|
||||
rmkx_key_map.update({
|
||||
defines.GLFW_KEY_UP: b'\033[A',
|
||||
defines.GLFW_KEY_DOWN: b'\033[B',
|
||||
defines.GLFW_KEY_LEFT: b'\033[D',
|
||||
defines.GLFW_KEY_RIGHT: b'\033[C',
|
||||
defines.GLFW_KEY_HOME: b'\033[H',
|
||||
defines.GLFW_KEY_END: b'\033[F',
|
||||
})
|
||||
|
||||
cursor_key_mode_map = {True: smkx_key_map, False: rmkx_key_map}
|
||||
from .typing import ScreenType
|
||||
|
||||
|
||||
def keyboard_mode_name(screen: ScreenType) -> str:
|
||||
if screen.extended_keyboard:
|
||||
if screen.current_key_encoding_flags() & 0b1000:
|
||||
return 'kitty'
|
||||
return 'application' if screen.cursor_key_mode else 'normal'
|
||||
|
||||
|
||||
action_map = {
|
||||
defines.GLFW_PRESS: 'p',
|
||||
defines.GLFW_RELEASE: 'r',
|
||||
defines.GLFW_REPEAT: 't'
|
||||
}
|
||||
|
||||
|
||||
def extended_key_event(key: int, mods: int, action: int) -> bytes:
|
||||
if key >= defines.GLFW_KEY_LAST or key == defines.GLFW_KEY_UNKNOWN or (
|
||||
# Shifted printable key should be handled by on_text_input()
|
||||
mods <= defines.GLFW_MOD_SHIFT and defines.GLFW_KEY_SPACE <= key <= defines.GLFW_KEY_LAST_PRINTABLE
|
||||
):
|
||||
return b''
|
||||
if mods == 0 and key in (
|
||||
defines.GLFW_KEY_BACKSPACE, defines.GLFW_KEY_ENTER
|
||||
):
|
||||
if action == defines.GLFW_RELEASE:
|
||||
return b''
|
||||
return smkx_key_map[key]
|
||||
if key in (defines.GLFW_KEY_LEFT_SHIFT, defines.GLFW_KEY_RIGHT_SHIFT):
|
||||
return b''
|
||||
name = KEY_MAP.get(key)
|
||||
if name is None:
|
||||
return b''
|
||||
m = 0
|
||||
if mods & defines.GLFW_MOD_SHIFT:
|
||||
m |= 0x1
|
||||
if mods & defines.GLFW_MOD_ALT:
|
||||
m |= 0x2
|
||||
if mods & defines.GLFW_MOD_CONTROL:
|
||||
m |= 0x4
|
||||
if mods & defines.GLFW_MOD_SUPER:
|
||||
m |= 0x8
|
||||
return 'K{}{}{}'.format(
|
||||
action_map[action], base64_encode(m), name
|
||||
).encode('ascii')
|
||||
|
||||
|
||||
def pmap(names: str, r: Iterable[str]) -> Dict[int, bytes]:
|
||||
snames = names.split()
|
||||
b = [x.encode('ascii') for x in r]
|
||||
if len(snames) != len(b):
|
||||
raise ValueError('Incorrect mapping for {}'.format(names))
|
||||
anames = [getattr(defines, 'GLFW_KEY_' + n) for n in snames]
|
||||
return dict(zip(anames, b))
|
||||
|
||||
|
||||
UN_SHIFTED_PRINTABLE = {
|
||||
getattr(defines, 'GLFW_KEY_' + x): x.lower().encode('ascii')
|
||||
for x in string.digits + string.ascii_uppercase
|
||||
}
|
||||
UN_SHIFTED_PRINTABLE.update(pmap(
|
||||
'SPACE APOSTROPHE COMMA MINUS PERIOD SLASH SEMICOLON EQUAL',
|
||||
" ',-./;="
|
||||
))
|
||||
UN_SHIFTED_PRINTABLE.update(pmap(
|
||||
'LEFT_BRACKET BACKSLASH RIGHT_BRACKET GRAVE_ACCENT UNDERSCORE',
|
||||
"[\\]`_"
|
||||
))
|
||||
SHIFTED_PRINTABLE = UN_SHIFTED_PRINTABLE.copy()
|
||||
SHIFTED_PRINTABLE.update({
|
||||
getattr(defines, 'GLFW_KEY_' + x): x.encode('ascii') for x in string.ascii_uppercase
|
||||
})
|
||||
SHIFTED_PRINTABLE.update(pmap(
|
||||
'1 2 3 4 5 6 7 8 9 0',
|
||||
'!@#$%^&*()'
|
||||
))
|
||||
SHIFTED_PRINTABLE.update(pmap(
|
||||
'APOSTROPHE COMMA MINUS PERIOD SLASH SEMICOLON EQUAL',
|
||||
'"<_>?:+'
|
||||
))
|
||||
SHIFTED_PRINTABLE.update(pmap(
|
||||
'LEFT_BRACKET BACKSLASH RIGHT_BRACKET GRAVE_ACCENT',
|
||||
"{|}~"
|
||||
))
|
||||
|
||||
CTRL_ALT_KEYS = {getattr(defines, 'GLFW_KEY_' + k) for k in string.ascii_uppercase}
|
||||
all_control_alt_keys = set(CTRL_ALT_KEYS) | set(control_alt_codes)
|
||||
|
||||
|
||||
def key_to_bytes(key: int, smkx: bool, extended: bool, mods: int, action: int) -> bytes:
|
||||
if extended:
|
||||
return extended_key_event(key, mods, action)
|
||||
data = bytearray()
|
||||
if mods == defines.GLFW_MOD_CONTROL and key in control_codes:
|
||||
# Map Ctrl-key to ascii control code
|
||||
data.extend(control_codes[key])
|
||||
elif mods == ctrl_shift_mod and key in control_shift_keys:
|
||||
data.extend(control_shift_keys[key])
|
||||
elif mods in alt_mods:
|
||||
if key in alt_codes:
|
||||
data.extend((alt_codes if mods == defines.GLFW_MOD_ALT else shift_alt_codes)[key])
|
||||
elif key in UN_SHIFTED_PRINTABLE:
|
||||
m = UN_SHIFTED_PRINTABLE if mods == defines.GLFW_MOD_ALT else SHIFTED_PRINTABLE
|
||||
data.append(0o33)
|
||||
data.extend(m[key])
|
||||
elif mods == ctrl_alt_mod and key in all_control_alt_keys:
|
||||
if key in CTRL_ALT_KEYS:
|
||||
data.append(0x1b)
|
||||
data.extend(control_codes[key])
|
||||
else:
|
||||
data.extend(control_alt_codes[key])
|
||||
elif mods == ctrl_alt_shift_mod and key in control_alt_shift_codes:
|
||||
data.extend(control_alt_shift_codes[key])
|
||||
else:
|
||||
key_map = cursor_key_mode_map[smkx]
|
||||
x = key_map.get(key)
|
||||
if x is not None:
|
||||
if mods == defines.GLFW_MOD_SHIFT:
|
||||
x = SHIFTED_KEYS.get(key, x)
|
||||
assert x is not None
|
||||
data.extend(x)
|
||||
return bytes(data)
|
||||
|
||||
|
||||
def interpret_key_event(key: int, native_key: int, mods: int, window: WindowType, action: int) -> bytes:
|
||||
screen = window.screen
|
||||
if (
|
||||
action == defines.GLFW_PRESS or
|
||||
(action == defines.GLFW_REPEAT and screen.auto_repeat_enabled) or
|
||||
screen.extended_keyboard
|
||||
):
|
||||
return defines.key_to_bytes(key, screen.cursor_key_mode, screen.extended_keyboard, mods, action)
|
||||
return b''
|
||||
|
||||
|
||||
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))
|
||||
@ -289,109 +27,3 @@ 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 generate_key_table_impl(w: Callable) -> None:
|
||||
w('// auto-generated from keys.py, do not edit!')
|
||||
w('#pragma once')
|
||||
w('#include <stddef.h>')
|
||||
w('#include <stdint.h>')
|
||||
w('#include <stdbool.h>')
|
||||
w('#include <limits.h>')
|
||||
number_of_keys = defines.GLFW_KEY_LAST + 1
|
||||
w('// map glfw key numbers to 7-bit numbers for compact data storage')
|
||||
w('static const uint8_t key_map[%d] = {' % number_of_keys)
|
||||
key_count = 0
|
||||
|
||||
def key_name(k: str) -> str:
|
||||
return k[len('GLFW_KEY_'):]
|
||||
|
||||
keys = {v: k for k, v in vars(defines).items() if k.startswith('GLFW_KEY_') and k not in {'GLFW_KEY_LAST', 'GLFW_KEY_LAST_PRINTABLE', 'GLFW_KEY_UNKNOWN'}}
|
||||
key_rmap = []
|
||||
for i in range(number_of_keys):
|
||||
k = keys.get(i)
|
||||
if k is None:
|
||||
w('UINT8_MAX,')
|
||||
else:
|
||||
w('%d, /* %s */' % (key_count, key_name(k)))
|
||||
key_rmap.append(i)
|
||||
key_count += 1
|
||||
if key_count > 256:
|
||||
raise OverflowError('Too many keys')
|
||||
w('};\n')
|
||||
w('static inline const char* key_name(int key) { switch(key) {')
|
||||
for i in range(number_of_keys):
|
||||
k = keys.get(i)
|
||||
if k is not None:
|
||||
w('case %d: return "%s";' % (i, key_name(k)))
|
||||
w('default: return NULL; }}\n')
|
||||
w('typedef enum { NORMAL, APPLICATION, EXTENDED } KeyboardMode;\n')
|
||||
w('static inline const char*\nkey_lookup(uint8_t key, KeyboardMode mode, uint8_t mods, uint8_t action) {')
|
||||
i = 1
|
||||
|
||||
def ind(*a: Any) -> None:
|
||||
w((' ' * i)[:-1], *a)
|
||||
ind('switch(mode) {')
|
||||
mmap = [(False, False), (True, False), (False, True)]
|
||||
for (smkx, extended), mode in zip(mmap, 'NORMAL APPLICATION EXTENDED'.split()):
|
||||
i += 1
|
||||
ind('case {}:'.format(mode))
|
||||
i += 1
|
||||
ind('switch(action & 3) { case 3: return NULL;')
|
||||
for action in (defines.GLFW_RELEASE, defines.GLFW_PRESS, defines.GLFW_REPEAT):
|
||||
i += 1
|
||||
ind('case {}: // {}'.format(action, 'RELEASE PRESS REPEAT'.split()[action]))
|
||||
i += 1
|
||||
if action != defines.GLFW_RELEASE or mode == 'EXTENDED':
|
||||
ind('switch (mods & 0xf) {')
|
||||
i += 1
|
||||
for mods in range(16):
|
||||
key_bytes = {}
|
||||
for key in range(key_count):
|
||||
glfw_key = key_rmap[key]
|
||||
data = key_to_bytes(glfw_key, smkx, extended, mods, action)
|
||||
if data:
|
||||
key_bytes[key] = data, glfw_key
|
||||
i += 1
|
||||
ind('case 0x{:x}:'.format(mods))
|
||||
i += 1
|
||||
if key_bytes:
|
||||
ind('switch(key & 0xff) { default: return NULL;')
|
||||
i += 1
|
||||
for key, (data, glfw_key) in key_bytes.items():
|
||||
ind('case {}: // {}'.format(key, key_name(keys[glfw_key])))
|
||||
i += 1
|
||||
items = bytearray(data)
|
||||
items.insert(0, len(items))
|
||||
ind('return "{}";'.format(''.join('\\x{:02x}'.format(x) for x in items)))
|
||||
i -= 1
|
||||
i -= 1
|
||||
ind('} // end switch(key)')
|
||||
else:
|
||||
ind('return NULL;')
|
||||
i -= 2
|
||||
i -= 1
|
||||
ind('} // end switch(mods)')
|
||||
ind('break;\n')
|
||||
i -= 1
|
||||
else:
|
||||
ind('return NULL;\n')
|
||||
i -= 1
|
||||
i -= 1
|
||||
ind('}} // end switch(action) in mode {}'.format(mode))
|
||||
ind('break;\n\n')
|
||||
i -= 1
|
||||
i -= 1
|
||||
ind('}')
|
||||
ind('return NULL;')
|
||||
i -= 1
|
||||
w('}')
|
||||
|
||||
|
||||
def generate_key_table() -> None:
|
||||
# To run this, use: ./kitty/launcher/kitty +runpy "from kitty.keys import *; generate_key_table()"
|
||||
import os
|
||||
from functools import partial
|
||||
with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'keys.h'), 'w') as f:
|
||||
w = partial(print, file=f)
|
||||
generate_key_table_impl(w)
|
||||
|
||||
@ -2324,6 +2324,7 @@ WRAP0(carriage_return)
|
||||
WRAP2(resize, 1, 1)
|
||||
WRAP2(set_margins, 1, 1)
|
||||
WRAP0(rescale_images)
|
||||
WRAP0(current_key_encoding_flags)
|
||||
|
||||
static PyObject*
|
||||
start_selection(Screen *self, PyObject *args) {
|
||||
@ -2886,6 +2887,7 @@ static PyMethodDef methods[] = {
|
||||
MND(resize, METH_VARARGS)
|
||||
MND(set_margins, METH_VARARGS)
|
||||
MND(rescale_images, METH_NOARGS)
|
||||
MND(current_key_encoding_flags, METH_NOARGS)
|
||||
MND(text_for_selection, METH_NOARGS)
|
||||
MND(is_rectangle_select, METH_NOARGS)
|
||||
MND(scroll, METH_VARARGS)
|
||||
|
||||
@ -22,16 +22,16 @@ from .config import build_ansi_color_table
|
||||
from .constants import ScreenGeometry, WindowGeometry, appname, wakeup
|
||||
from .fast_data_types import (
|
||||
BGIMAGE_PROGRAM, BLIT_PROGRAM, CELL_BG_PROGRAM, CELL_FG_PROGRAM,
|
||||
CELL_PROGRAM, CELL_SPECIAL_PROGRAM, DCS, DECORATION, DIM,
|
||||
CELL_PROGRAM, CELL_SPECIAL_PROGRAM, DCS, DECORATION, DIM, GLFW_MOD_CONTROL,
|
||||
GRAPHICS_ALPHA_MASK_PROGRAM, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_PROGRAM,
|
||||
MARK, MARK_MASK, OSC, REVERSE, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE,
|
||||
STRIKETHROUGH, TINT_PROGRAM, Screen, add_timer, add_window,
|
||||
cell_size_for_window, compile_program, get_boss, get_clipboard_string,
|
||||
init_cell_program, pt_to_px, set_clipboard_string, set_titlebar_color,
|
||||
set_window_padding, set_window_render_data, update_window_title,
|
||||
update_window_visibility, viewport_for_window
|
||||
cell_size_for_window, compile_program, encode_key_for_tty, get_boss,
|
||||
get_clipboard_string, init_cell_program, pt_to_px, set_clipboard_string,
|
||||
set_titlebar_color, set_window_padding, set_window_render_data,
|
||||
update_window_title, update_window_visibility, viewport_for_window
|
||||
)
|
||||
from .keys import defines, extended_key_event, keyboard_mode_name
|
||||
from .keys import keyboard_mode_name
|
||||
from .notify import NotificationCommand, handle_notification_cmd
|
||||
from .options_stub import Options
|
||||
from .rgb import to_color
|
||||
@ -886,9 +886,11 @@ class Window:
|
||||
if text:
|
||||
set_clipboard_string(text)
|
||||
else:
|
||||
mode = keyboard_mode_name(self.screen)
|
||||
data = extended_key_event(defines.GLFW_KEY_C, defines.GLFW_MOD_CONTROL, defines.GLFW_PRESS) if mode == 'kitty' else b'\x03'
|
||||
self.write_to_child(data)
|
||||
data = encode_key_for_tty(
|
||||
key=ord('c'), mods=GLFW_MOD_CONTROL, key_encoding_flags=self.screen.current_key_encoding_flags(),
|
||||
cursor_key_mode=self.screen.cursor_key_mode
|
||||
)
|
||||
self.write_to_child(data.encode('ascii'))
|
||||
|
||||
def copy_and_clear_or_interrupt(self) -> None:
|
||||
self.copy_or_interrupt()
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from functools import partial
|
||||
import kitty.fast_data_types as defines
|
||||
from . import BaseTest
|
||||
|
||||
@ -9,7 +10,46 @@ from . import BaseTest
|
||||
class TestKeys(BaseTest):
|
||||
|
||||
def test_encode_key_event(self):
|
||||
pass
|
||||
enc = defines.encode_key_for_tty
|
||||
ae = self.assertEqual
|
||||
shift, alt, ctrl, super = defines.GLFW_MOD_SHIFT, defines.GLFW_MOD_ALT, defines.GLFW_MOD_CONTROL, defines.GLFW_MOD_SUPER # noqa
|
||||
press, repeat, release = defines.GLFW_PRESS, defines.GLFW_REPEAT, defines.GLFW_RELEASE # noqa
|
||||
|
||||
def csi(mods=0, num=1, trailer='u'):
|
||||
ans = f'\033[{num}'
|
||||
if mods:
|
||||
m = 0
|
||||
if mods & shift:
|
||||
m |= 1
|
||||
if mods & alt:
|
||||
m |= 2
|
||||
if mods & ctrl:
|
||||
m |= 4
|
||||
if mods & super:
|
||||
m |= 8
|
||||
ans += f';{m+1}'
|
||||
return ans + trailer
|
||||
|
||||
def mods_test(key, plain, shift=None, ctrl=None, alt=None, calt=None, cshift=None, ashift=None, csi_num=None, trailer='u'):
|
||||
c = partial(csi, num=csi_num or key, trailer=trailer)
|
||||
e = partial(enc, key=key)
|
||||
ae(e(), plain)
|
||||
ae(e(mods=defines.GLFW_MOD_SHIFT), shift or c(defines.GLFW_MOD_SHIFT))
|
||||
ae(e(mods=defines.GLFW_MOD_CONTROL), ctrl or c(defines.GLFW_MOD_CONTROL))
|
||||
ae(e(mods=defines.GLFW_MOD_ALT | defines.GLFW_MOD_CONTROL), calt or c(defines.GLFW_MOD_ALT | defines.GLFW_MOD_CONTROL))
|
||||
ae(e(mods=defines.GLFW_MOD_SHIFT | defines.GLFW_MOD_CONTROL), cshift or c(defines.GLFW_MOD_CONTROL | defines.GLFW_MOD_SHIFT))
|
||||
ae(e(mods=defines.GLFW_MOD_SHIFT | defines.GLFW_MOD_ALT), ashift or c(defines.GLFW_MOD_ALT | defines.GLFW_MOD_SHIFT))
|
||||
|
||||
mods_test(defines.GLFW_FKEY_ENTER, '\x0d', alt='\033\x0d', csi_num=ord('\r'))
|
||||
mods_test(defines.GLFW_FKEY_ESCAPE, '\x1b', alt='\033\033', csi_num=27)
|
||||
mods_test(defines.GLFW_FKEY_BACKSPACE, '\x7f', alt='\033\x7f', csi_num=127)
|
||||
mods_test(defines.GLFW_FKEY_TAB, '\t', alt='\033\t', shift='\x1b[Z', csi_num=ord('\t'))
|
||||
|
||||
q = partial(enc, key=ord('a'))
|
||||
ae(q(), 'a')
|
||||
ae(q(text='a'), 'a')
|
||||
ae(q(action=repeat), 'a')
|
||||
ae(q(action=release), '')
|
||||
|
||||
def test_encode_mouse_event(self):
|
||||
NORMAL_PROTOCOL, UTF8_PROTOCOL, SGR_PROTOCOL, URXVT_PROTOCOL = range(4)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user