Skip to content

Commit

Permalink
Add support for the keypad Begin key
Browse files Browse the repository at this point in the history
Fixes #3468
  • Loading branch information
kovidgoyal committed Apr 11, 2021
1 parent 084b028 commit c989a71
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 108 deletions.
39 changes: 20 additions & 19 deletions docs/keyboard-protocol.rst
Expand Up @@ -53,7 +53,7 @@ text, or using the following escape codes, for those keys that do not produce
text (``CSI`` is the bytes ``0x1b 0x5b``)::

CSI number ; modifiers [u~]
CSI 1; modifiers [ABCDFHPQRS]
CSI 1; modifiers [ABCDEFHPQRS]
0x0d - for the Enter key
0x7f or 0x08 - for Backspace
0x09 - for Tab
Expand All @@ -67,7 +67,7 @@ modifiers pressed for the key event. The encoding is described in the
The second form is used for a few functional keys, such as the :kbd:`Home, End,
Arrow keys and F1-F4`, they are enumerated in the :ref:`functional` table below.
Note that if no modifiers are present the parameters are omitted entirely
giving an escape code of the form ``CSI [ABCDFHPQRS]``.
giving an escape code of the form ``CSI [ABCDEFHPQRS]``.

If you want support for more advanced features such as repeat and release
events, alternate keys for shortcut matching et cetera, these can be turned on
Expand Down Expand Up @@ -289,7 +289,7 @@ With this flag turned on, all key events that do not generate text are
represented in one of the following two forms::

CSI number; modifier u
CSI 1; modifier [~ABCDFHPQRS]
CSI 1; modifier [~ABCDEFHPQRS]

This makes it very easy to parse key events in an application. In particular,
:kbd:`ctrl+c` will no longer generate the ``SIGINT`` signal, but instead be
Expand Down Expand Up @@ -380,8 +380,8 @@ Legacy functional keys
These keys are encoded using three schemes::

CSI number ; modifier ~
CSI 1 ; modifier {ABCDFHPQRS}
SS3 {ABCDFHPQRS}
CSI 1 ; modifier {ABCDEFHPQRS}
SS3 {ABCDEFHPQRS}

In the above, if there are no modifiers, the modifier parameter is omitted.
The modifier value is encoded as described in the :ref:`modifiers` section,
Expand Down Expand Up @@ -536,20 +536,21 @@ compatibility reasons.
"KP_DOWN", "``57420 u``", "KP_PAGE_UP", "``57421 u``"
"KP_PAGE_DOWN", "``57422 u``", "KP_HOME", "``57423 u``"
"KP_END", "``57424 u``", "KP_INSERT", "``57425 u``"
"KP_DELETE", "``57426 u``", "MEDIA_PLAY", "``57427 u``"
"MEDIA_PAUSE", "``57428 u``", "MEDIA_PLAY_PAUSE", "``57429 u``"
"MEDIA_REVERSE", "``57430 u``", "MEDIA_STOP", "``57431 u``"
"MEDIA_FAST_FORWARD", "``57432 u``", "MEDIA_REWIND", "``57433 u``"
"MEDIA_TRACK_NEXT", "``57434 u``", "MEDIA_TRACK_PREVIOUS", "``57435 u``"
"MEDIA_RECORD", "``57436 u``", "LOWER_VOLUME", "``57437 u``"
"RAISE_VOLUME", "``57438 u``", "MUTE_VOLUME", "``57439 u``"
"LEFT_SHIFT", "``57440 u``", "LEFT_CONTROL", "``57441 u``"
"LEFT_ALT", "``57442 u``", "LEFT_SUPER", "``57443 u``"
"LEFT_HYPER", "``57444 u``", "LEFT_META", "``57445 u``"
"RIGHT_SHIFT", "``57446 u``", "RIGHT_CONTROL", "``57447 u``"
"RIGHT_ALT", "``57448 u``", "RIGHT_SUPER", "``57449 u``"
"RIGHT_HYPER", "``57450 u``", "RIGHT_META", "``57451 u``"
"ISO_LEVEL3_SHIFT", "``57452 u``", "ISO_LEVEL5_SHIFT", "``57453 u``"
"KP_DELETE", "``57426 u``", "KP_BEGIN", "``1 E or 57427 ~``"
"MEDIA_PLAY", "``57428 u``", "MEDIA_PAUSE", "``57429 u``"
"MEDIA_PLAY_PAUSE", "``57430 u``", "MEDIA_REVERSE", "``57431 u``"
"MEDIA_STOP", "``57432 u``", "MEDIA_FAST_FORWARD", "``57433 u``"
"MEDIA_REWIND", "``57434 u``", "MEDIA_TRACK_NEXT", "``57435 u``"
"MEDIA_TRACK_PREVIOUS", "``57436 u``", "MEDIA_RECORD", "``57437 u``"
"LOWER_VOLUME", "``57438 u``", "RAISE_VOLUME", "``57439 u``"
"MUTE_VOLUME", "``57440 u``", "LEFT_SHIFT", "``57441 u``"
"LEFT_CONTROL", "``57442 u``", "LEFT_ALT", "``57443 u``"
"LEFT_SUPER", "``57444 u``", "LEFT_HYPER", "``57445 u``"
"LEFT_META", "``57446 u``", "RIGHT_SHIFT", "``57447 u``"
"RIGHT_CONTROL", "``57448 u``", "RIGHT_ALT", "``57449 u``"
"RIGHT_SUPER", "``57450 u``", "RIGHT_HYPER", "``57451 u``"
"RIGHT_META", "``57452 u``", "ISO_LEVEL3_SHIFT", "``57453 u``"
"ISO_LEVEL5_SHIFT", "``57454 u``"

.. end functional key table
.. }}}
Expand Down
5 changes: 3 additions & 2 deletions gen-key-constants.py
Expand Up @@ -91,6 +91,7 @@
kp_end KP_End - -
kp_insert KP_Insert - -
kp_delete KP_Delete - -
kp_begin KP_Begin - -
media_play XF86AudioPlay - -
media_pause XF86AudioPause - -
media_play_pause - - -
Expand Down Expand Up @@ -129,7 +130,7 @@
'f11': 23, 'f12': 24, 'escape': 27, 'backspace': 127
}
different_trailer_functionals = {
'up': 'A', 'down': 'B', 'right': 'C', 'left': 'D', 'end': 'F', 'home': 'H',
'up': 'A', 'down': 'B', 'right': 'C', 'left': 'D', 'kp_begin': 'E', 'end': 'F', 'home': 'H',
'f1': 'P', 'f2': 'Q', 'f3': 'R', 'f4': 'S', 'enter': 'u', 'tab': 'u',
'backspace': 'u', 'escape': 'u'
}
Expand Down Expand Up @@ -311,7 +312,7 @@ def generate_functional_table() -> None:
csi_map = {v: name_to_code[k] for k, v in functional_encoding_overrides.items()}
letter_trailer_codes = {
v: functional_encoding_overrides.get(k, name_to_code.get(k))
for k, v in different_trailer_functionals.items() if v in 'ABCDHFPQRSZ'}
for k, v in different_trailer_functionals.items() if v in 'ABCDEHFPQRSZ'}
text = f'functional_key_number_to_name_map = {serialize_dict(code_to_name)}'
text += f'\ncsi_number_to_functional_number_map = {serialize_dict(csi_map)}'
text += f'\nletter_trailer_to_csi_number_map = {letter_trailer_codes!r}'
Expand Down
57 changes: 29 additions & 28 deletions glfw/glfw3.h
Expand Up @@ -428,34 +428,35 @@ typedef enum {
GLFW_FKEY_KP_END = 0xe050u,
GLFW_FKEY_KP_INSERT = 0xe051u,
GLFW_FKEY_KP_DELETE = 0xe052u,
GLFW_FKEY_MEDIA_PLAY = 0xe053u,
GLFW_FKEY_MEDIA_PAUSE = 0xe054u,
GLFW_FKEY_MEDIA_PLAY_PAUSE = 0xe055u,
GLFW_FKEY_MEDIA_REVERSE = 0xe056u,
GLFW_FKEY_MEDIA_STOP = 0xe057u,
GLFW_FKEY_MEDIA_FAST_FORWARD = 0xe058u,
GLFW_FKEY_MEDIA_REWIND = 0xe059u,
GLFW_FKEY_MEDIA_TRACK_NEXT = 0xe05au,
GLFW_FKEY_MEDIA_TRACK_PREVIOUS = 0xe05bu,
GLFW_FKEY_MEDIA_RECORD = 0xe05cu,
GLFW_FKEY_LOWER_VOLUME = 0xe05du,
GLFW_FKEY_RAISE_VOLUME = 0xe05eu,
GLFW_FKEY_MUTE_VOLUME = 0xe05fu,
GLFW_FKEY_LEFT_SHIFT = 0xe060u,
GLFW_FKEY_LEFT_CONTROL = 0xe061u,
GLFW_FKEY_LEFT_ALT = 0xe062u,
GLFW_FKEY_LEFT_SUPER = 0xe063u,
GLFW_FKEY_LEFT_HYPER = 0xe064u,
GLFW_FKEY_LEFT_META = 0xe065u,
GLFW_FKEY_RIGHT_SHIFT = 0xe066u,
GLFW_FKEY_RIGHT_CONTROL = 0xe067u,
GLFW_FKEY_RIGHT_ALT = 0xe068u,
GLFW_FKEY_RIGHT_SUPER = 0xe069u,
GLFW_FKEY_RIGHT_HYPER = 0xe06au,
GLFW_FKEY_RIGHT_META = 0xe06bu,
GLFW_FKEY_ISO_LEVEL3_SHIFT = 0xe06cu,
GLFW_FKEY_ISO_LEVEL5_SHIFT = 0xe06du,
GLFW_FKEY_LAST = 0xe06du
GLFW_FKEY_KP_BEGIN = 0xe053u,
GLFW_FKEY_MEDIA_PLAY = 0xe054u,
GLFW_FKEY_MEDIA_PAUSE = 0xe055u,
GLFW_FKEY_MEDIA_PLAY_PAUSE = 0xe056u,
GLFW_FKEY_MEDIA_REVERSE = 0xe057u,
GLFW_FKEY_MEDIA_STOP = 0xe058u,
GLFW_FKEY_MEDIA_FAST_FORWARD = 0xe059u,
GLFW_FKEY_MEDIA_REWIND = 0xe05au,
GLFW_FKEY_MEDIA_TRACK_NEXT = 0xe05bu,
GLFW_FKEY_MEDIA_TRACK_PREVIOUS = 0xe05cu,
GLFW_FKEY_MEDIA_RECORD = 0xe05du,
GLFW_FKEY_LOWER_VOLUME = 0xe05eu,
GLFW_FKEY_RAISE_VOLUME = 0xe05fu,
GLFW_FKEY_MUTE_VOLUME = 0xe060u,
GLFW_FKEY_LEFT_SHIFT = 0xe061u,
GLFW_FKEY_LEFT_CONTROL = 0xe062u,
GLFW_FKEY_LEFT_ALT = 0xe063u,
GLFW_FKEY_LEFT_SUPER = 0xe064u,
GLFW_FKEY_LEFT_HYPER = 0xe065u,
GLFW_FKEY_LEFT_META = 0xe066u,
GLFW_FKEY_RIGHT_SHIFT = 0xe067u,
GLFW_FKEY_RIGHT_CONTROL = 0xe068u,
GLFW_FKEY_RIGHT_ALT = 0xe069u,
GLFW_FKEY_RIGHT_SUPER = 0xe06au,
GLFW_FKEY_RIGHT_HYPER = 0xe06bu,
GLFW_FKEY_RIGHT_META = 0xe06cu,
GLFW_FKEY_ISO_LEVEL3_SHIFT = 0xe06du,
GLFW_FKEY_ISO_LEVEL5_SHIFT = 0xe06eu,
GLFW_FKEY_LAST = 0xe06eu
} GLFWFunctionKey;
/* end functional key names */

Expand Down
1 change: 1 addition & 0 deletions glfw/input.c
Expand Up @@ -607,6 +607,7 @@ _glfwGetKeyName(int key)
case GLFW_FKEY_KP_END: return "KP_END";
case GLFW_FKEY_KP_INSERT: return "KP_INSERT";
case GLFW_FKEY_KP_DELETE: return "KP_DELETE";
case GLFW_FKEY_KP_BEGIN: return "KP_BEGIN";
case GLFW_FKEY_MEDIA_PLAY: return "MEDIA_PLAY";
case GLFW_FKEY_MEDIA_PAUSE: return "MEDIA_PAUSE";
case GLFW_FKEY_MEDIA_PLAY_PAUSE: return "MEDIA_PLAY_PAUSE";
Expand Down
2 changes: 2 additions & 0 deletions glfw/xkb_glfw.c
Expand Up @@ -128,6 +128,7 @@ glfw_key_for_sym(xkb_keysym_t key) {
case XKB_KEY_KP_End: return GLFW_FKEY_KP_END;
case XKB_KEY_KP_Insert: return GLFW_FKEY_KP_INSERT;
case XKB_KEY_KP_Delete: return GLFW_FKEY_KP_DELETE;
case XKB_KEY_KP_Begin: return GLFW_FKEY_KP_BEGIN;
case XKB_KEY_XF86AudioPlay: return GLFW_FKEY_MEDIA_PLAY;
case XKB_KEY_XF86AudioPause: return GLFW_FKEY_MEDIA_PAUSE;
case XKB_KEY_XF86AudioStop: return GLFW_FKEY_MEDIA_STOP;
Expand Down Expand Up @@ -246,6 +247,7 @@ glfw_xkb_sym_for_key(uint32_t key) {
case GLFW_FKEY_KP_END: return XKB_KEY_KP_End;
case GLFW_FKEY_KP_INSERT: return XKB_KEY_KP_Insert;
case GLFW_FKEY_KP_DELETE: return XKB_KEY_KP_Delete;
case GLFW_FKEY_KP_BEGIN: return XKB_KEY_KP_Begin;
case GLFW_FKEY_MEDIA_PLAY: return XKB_KEY_XF86AudioPlay;
case GLFW_FKEY_MEDIA_PAUSE: return XKB_KEY_XF86AudioPause;
case GLFW_FKEY_MEDIA_STOP: return XKB_KEY_XF86AudioStop;
Expand Down
2 changes: 1 addition & 1 deletion kittens/tui/loop.py
Expand Up @@ -277,7 +277,7 @@ def _on_csi(self, csi: str) -> None:
pass
else:
self.handler.on_mouse(ev)
elif q in 'u~ABCDHFPQRS':
elif q in 'u~ABCDEHFPQRS':
if csi == '200~':
self.in_bracketed_paste = True
return
Expand Down
1 change: 1 addition & 0 deletions kitty/fast_data_types.pyi
Expand Up @@ -101,6 +101,7 @@ GLFW_FKEY_KP_HOME: int
GLFW_FKEY_KP_END: int
GLFW_FKEY_KP_INSERT: int
GLFW_FKEY_KP_DELETE: int
GLFW_FKEY_KP_BEGIN: int
GLFW_FKEY_MEDIA_PLAY: int
GLFW_FKEY_MEDIA_PAUSE: int
GLFW_FKEY_MEDIA_PLAY_PAUSE: int
Expand Down
57 changes: 29 additions & 28 deletions kitty/glfw-wrapper.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions kitty/glfw.c
Expand Up @@ -1019,6 +1019,7 @@ glfw_get_key_name(PyObject UNUSED *self, PyObject *args) {
case GLFW_FKEY_KP_END: return PyUnicode_FromString("kp_end");
case GLFW_FKEY_KP_INSERT: return PyUnicode_FromString("kp_insert");
case GLFW_FKEY_KP_DELETE: return PyUnicode_FromString("kp_delete");
case GLFW_FKEY_KP_BEGIN: return PyUnicode_FromString("kp_begin");
case GLFW_FKEY_MEDIA_PLAY: return PyUnicode_FromString("media_play");
case GLFW_FKEY_MEDIA_PAUSE: return PyUnicode_FromString("media_pause");
case GLFW_FKEY_MEDIA_PLAY_PAUSE: return PyUnicode_FromString("media_play_pause");
Expand Down Expand Up @@ -1530,6 +1531,7 @@ init_glfw(PyObject *m) {
ADDC(GLFW_FKEY_KP_END);
ADDC(GLFW_FKEY_KP_INSERT);
ADDC(GLFW_FKEY_KP_DELETE);
ADDC(GLFW_FKEY_KP_BEGIN);
ADDC(GLFW_FKEY_MEDIA_PLAY);
ADDC(GLFW_FKEY_MEDIA_PAUSE);
ADDC(GLFW_FKEY_MEDIA_PLAY_PAUSE);
Expand Down
4 changes: 3 additions & 1 deletion kitty/key_encoding.c
Expand Up @@ -169,6 +169,7 @@ encode_function_key(const KeyEvent *ev, char *output) {
case GLFW_FKEY_DOWN: SIMPLE("\x1bOB");
case GLFW_FKEY_RIGHT: SIMPLE("\x1bOC");
case GLFW_FKEY_LEFT: SIMPLE("\x1bOD");
case GLFW_FKEY_KP_BEGIN: SIMPLE("\x1bOE");
case GLFW_FKEY_END: SIMPLE("\x1bOF");
case GLFW_FKEY_HOME: SIMPLE("\x1bOH");
case GLFW_FKEY_F1: SIMPLE("\x1bOP");
Expand Down Expand Up @@ -222,6 +223,7 @@ encode_function_key(const KeyEvent *ev, char *output) {
case GLFW_FKEY_F10: S(21, '~');
case GLFW_FKEY_F11: S(23, '~');
case GLFW_FKEY_F12: S(24, '~');
case GLFW_FKEY_KP_BEGIN: S(1, 'E');
/* end special numbers */
default: break;
}
Expand Down Expand Up @@ -426,7 +428,7 @@ encode_glfw_key_event(const GLFWkeyevent *e, const bool cursor_key_mode, const u
ev.has_text = e->text && !startswith_ascii_control_char(e->text);
if (!ev.key && !ev.has_text) return 0;
bool send_text_standalone = !ev.report_text;
if (!ev.disambiguate && GLFW_FKEY_KP_0 <= ev.key && ev.key <= GLFW_FKEY_KP_DELETE) {
if (!ev.disambiguate && GLFW_FKEY_KP_0 <= ev.key && ev.key <= GLFW_FKEY_KP_BEGIN) {
ev.key = convert_kp_key_to_normal_key(ev.key);
}
switch (e->action) {
Expand Down
59 changes: 30 additions & 29 deletions kitty/key_encoding.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c989a71

Please sign in to comment.