diff --git a/docs/keyboard-protocol.rst b/docs/keyboard-protocol.rst index 66de95305..8dc510fba 100644 --- a/docs/keyboard-protocol.rst +++ b/docs/keyboard-protocol.rst @@ -199,16 +199,29 @@ oldest entry from the stack must be evicted. Disambiguate escape codes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This type of progressive enhancement fixes the problem of some legacy key -press encodings overlapping with other control codes. For instance, pressing -the :kbd:`Esc` key generates the byte ``0x1b`` which also is used to indicate -the start of an escape code. Similarly pressing the key :kbd:`alt+[` will -generate the bytes used for CSI control codes. Turning on this flag will cause -the terminal to report the :kbd:`Esc, alt+letter, ctrl+letter, ctrl+alt+letter` -keys using ``CSI u`` sequences instead of legacy ones. Here letter is any printable -ASCII letter (from 32 (i.e. space) to 126 (i.e. ~)). Additionally, all keypad -keys will be reported as separate keys with ``CSI u`` encoding, using dedicated codes -from the :ref:`table below `. +This type of progressive enhancement (``0b1``) fixes the problem of some legacy key press +encodings overlapping with other control codes. For instance, pressing the +:kbd:`Esc` key generates the byte ``0x1b`` which also is used to indicate the +start of an escape code. Similarly pressing the key :kbd:`alt+[` will generate +the bytes used for CSI control codes. + +Turning on this flag will cause the terminal to report the :kbd:`Esc, alt+key, +ctrl+key, ctrl+alt+key, shift+alt+key` keys using ``CSI u`` sequences instead +of legacy ones. Here key is any ASCII key as described in :ref:`legacy_text`. +Additionally, all keypad keys will be reported as separate keys with ``CSI u`` +encoding, using dedicated numbers from the :ref:`table below `. + +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 [~ABCDFHPQRSZ] + +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 +delivers as a ``CSI u`` escape code. This has the nice side effect of making it +much easier to integrate into the application event loop. + Report event types ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -234,8 +247,8 @@ this encoding, only key press and repeat events are sent and there is no way to distinguish between them. Text is sent directly as UTF-8 bytes. Any key events not described in this section are sent using the standard -``CSI u`` encoding. This includes keys that are not encodeable in the legacy -encoding, thereby increasing the space of useable key combinations even without +``CSI u`` encoding. This includes keys that are not encodable in the legacy +encoding, thereby increasing the space of usable key combinations even without progressive enhancement. Legacy functional keys @@ -305,6 +318,8 @@ terminals. All keypad keys are reported as there equivalent non-keypad keys. To distinguish these, use the :ref:`disambiguate ` flag. +.. _legacy_text: + Legacy text keys ~~~~~~~~~~~~~~~~~~~ diff --git a/kitty/key_encoding.c b/kitty/key_encoding.c index e46d468b5..f7b11fac1 100644 --- a/kitty/key_encoding.c +++ b/kitty/key_encoding.c @@ -289,16 +289,18 @@ encode_key(const KeyEvent *ev, char *output) { bool simple_encoding_ok = !ed.add_actions && !ed.add_alternates; if (simple_encoding_ok) { - if (is_legacy_ascii_key(ev->key)) { - int ret = encode_printable_ascii_key_legacy(ev, output); - if (ret > 0) return ret; - } else if (ev->key == ' ' && ev->mods.value == CTRL) { - output[0] = 0; - return 1; + if (!ed.has_mods) return encode_utf8(ev->key, output); + if (!ev->disambiguate) { + if (is_legacy_ascii_key(ev->key)) { + int ret = encode_printable_ascii_key_legacy(ev, output); + if (ret > 0) return ret; + } else if (ev->key == ' ' && ev->mods.value == CTRL) { + output[0] = 0; + return 1; + } } } - if (simple_encoding_ok && !ed.has_mods) return encode_utf8(ev->key, output); return serialize(&ed, output, 'u'); } diff --git a/kitty_tests/keys.py b/kitty_tests/keys.py index bd305a878..f0fbe2f98 100644 --- a/kitty_tests/keys.py +++ b/kitty_tests/keys.py @@ -379,6 +379,17 @@ class TestKeys(BaseTest): ae(q(action=repeat), 'a') ae(q(action=release), '') + # test disambiguate + dq = partial(enc, key_encoding_flags=0b1) + ae(dq(ord('a')), 'a') + ae(dq(defines.GLFW_FKEY_ESCAPE), csi(num=27)) # esc + for mods in (ctrl, alt, ctrl | shift, alt | shift): + ae(dq(ord('a'), mods=mods), csi(mods, ord('a'))) + ae(dq(ord(' '), mods=ctrl), csi(ctrl, ord(' '))) + for k in (defines.GLFW_FKEY_KP_PAGE_UP, defines.GLFW_FKEY_KP_0): + ae(dq(k), csi(num=k)) + ae(dq(k, mods=ctrl), csi(ctrl, num=k)) + def test_encode_mouse_event(self): NORMAL_PROTOCOL, UTF8_PROTOCOL, SGR_PROTOCOL, URXVT_PROTOCOL = range(4) L, M, R = 1, 2, 3