560 lines
23 KiB
ReStructuredText
560 lines
23 KiB
ReStructuredText
A protocol for comprehensive keyboard handling in terminals
|
||
=================================================================
|
||
|
||
There are various problems with the current state of keyboard handling in
|
||
terminals. They include:
|
||
|
||
* No way to use modifiers other than ``ctrl`` and ``alt``
|
||
|
||
* No way to reliably use multiple modifier keys, other than, ``shift+alt`` and
|
||
``ctrl+alt``.
|
||
|
||
* Many of the existing escape codes used to encode these events are ambiguous
|
||
with different key presses mapping to the same escape code.
|
||
|
||
* No way to handle different types of keyboard events, such as press, release or repeat
|
||
|
||
* No reliable way to distinguish single ``Esc`` keypresses from the start of a
|
||
escape sequence. Currently, client programs use fragile timing related hacks
|
||
for this, leading to bugs, for example:
|
||
`neovim #2035 <https://github.com/neovim/neovim/issues/2035>`_.
|
||
|
||
To solve these issues and others, kitty has created a new keyboard protocol,
|
||
that is backward compatible but allows applications to opt-in to support more
|
||
advanced usages. The protocol is based on initial work in `fixterms
|
||
<http://www.leonerd.org.uk/hacks/fixterms/>`_, however, it corrects various
|
||
issues in that proposal, listed at the :ref:`bottom of this document
|
||
<fixterms_bugs>`.
|
||
|
||
.. versionadded:: 0.20.0
|
||
|
||
A basic overview
|
||
------------------
|
||
|
||
Key events are divided into two types, those that produce text and those that
|
||
do not. When a key event produces text, the text is sent directly as UTF-8
|
||
encoded bytes. This is safe as UTF-8 contains no C0 control codes.
|
||
When the key event does not have text, the key event is encoded as an escape code. In
|
||
legacy compatibility mode (the default) this uses legacy escape codes, so old terminal
|
||
applications continue to work. Key events that could not be represented in
|
||
legacy mode are encoded using a ``CSI u`` escape code, that most terminal
|
||
programs should just ignore. For more advanced features, such as release/repeat
|
||
reporting etc., applications can tell the terminal they want this information by
|
||
sending an escape code to :ref:`progressively enhance <progressive_enhancement>` the data reported for
|
||
key events.
|
||
|
||
The central escape code used to encode key events is::
|
||
|
||
CSI unicode-key-code:alternate-key-codes ; modifiers:event-type ; text-as-codepoints u
|
||
|
||
Spaces in the above definition are present for clarity and should be ignored.
|
||
``CSI`` is the bytes ``0x1b 0x5b``. All parameters are decimal numbers. Fields
|
||
are separated by the semi-colon and sub-fields by the colon. Only the
|
||
``unicode-key-code`` field is mandatory, everything else is optional. The
|
||
escape code is terminated by the ``u`` character (the byte ``0x75``).
|
||
|
||
|
||
.. _key_codes:
|
||
|
||
Key codes
|
||
~~~~~~~~~~~~~~
|
||
|
||
The ``unicode-key-code`` above is the Unicode codepoint representing the key, as a
|
||
decimal number. For example, the :kbd:`A` key is represented as ``97`` which is
|
||
the unicode code for lowercase ``a``. Note that the codepoint used is *always*
|
||
the lower-case (or more technically, un-shifted) version of the key. If the
|
||
user presses, for example, :kbd:`ctrl+shift+a` the escape code would be ``CSI
|
||
97;modifiers u``. It *must not* by ``CSI 65; modifiers u``.
|
||
|
||
If *alternate key reporting* is requested by the program running in the
|
||
terminal, the terminal can send two additional Unicode codepoints, the
|
||
*shifted key* and *base layout key*, separated by colons.
|
||
The shifted key is simply the upper-case version of ``unicode-codepoint``, or
|
||
more technically, the shifted version. So `a` becomes `A` and so on, based on
|
||
the current keyboard layout. This is needed to be able to match against a
|
||
shortcut such as :kbd:`ctrl+plus` which depending on the type of keyboard could
|
||
be either :kbd:`ctrl+shift+equal` or :kbd:`ctrl+plus`. Note that the shifted
|
||
key must be present only if shift is also present in the modifiers.
|
||
|
||
The *base layout key* is the key corresponding to the physical key in the
|
||
standard PC-101 key layout. So for example, if the user is using a Cyrillic
|
||
keyboard with a Cyrillic keyboard layout pressing the :kbd:`ctrl+С` key will
|
||
be :kbd:`ctrl+c` in the standard layout. So the terminal should send the *base
|
||
layout key* as ``99`` corresponding to the ``c`` key.
|
||
|
||
If only one alternate key is present, it is the *shifted key* if the terminal
|
||
wants to send only a base layout key but no shifted key, it must use an empty
|
||
sub-field for the shifted key, like this::
|
||
|
||
CSI unicode-key-code::base-layout-key
|
||
|
||
|
||
.. _modifiers:
|
||
|
||
Modifiers
|
||
~~~~~~~~~~~~~~
|
||
|
||
This protocol supports four modifier keys, :kbd:`shift, alt, ctrl and super`.
|
||
Here super is either the *Windows/Linux* key or the *Cmd* key on mac keyboards.
|
||
Modifiers are encoded as a bit field with::
|
||
|
||
shift 0b1 (1)
|
||
alt 0b10 (2)
|
||
ctrl 0b100 (4)
|
||
super 0b1000 (8)
|
||
|
||
In the escape code, the modifier value is encoded as a decimal number which is
|
||
``1 + actual modifiers``. So to represent :kbd:`shift` only, the value would be ``1 +
|
||
1 = 2``, to represent :kbd:`ctrl+shift` the value would be ``1 + 0b101 = 5``
|
||
and so on. If the modifier field is not present in the escape code, its default
|
||
value is ``1`` which means no modifiers.
|
||
|
||
|
||
.. _event_types:
|
||
|
||
Event types
|
||
~~~~~~~~~~~~~~~~
|
||
|
||
There are three key event types: ``press, repeat and release``. They are
|
||
reported (if requested ``0b10``) as a sub-field of the modifiers field
|
||
(separated by a colon). If no modifiers are present, the modifiers field must
|
||
have the value ``1`` and the event type sub-field the type of event. The
|
||
``press`` event type has value ``1`` and is the default if no event type sub
|
||
field is present. The ``repeat`` type is ``2`` and the ``release`` type is
|
||
``3``. So for example::
|
||
|
||
CSI key-code # this is a press event
|
||
CSI key-code;modifier # this is a press event
|
||
CSI key-code;modifier:1 # this is a press event
|
||
CSI key-code;modifier:2 # this is a repeat event
|
||
CSI key-code:modifier:3 # this is a release event
|
||
|
||
|
||
.. note:: Key events that result in text are reported as plain UTF-8 text, so
|
||
events are not supported for them, unless the application requests *key
|
||
report mode*, see below.
|
||
|
||
.. _text_as_codepoints:
|
||
|
||
Text as code points
|
||
~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
The terminal can optionally send the text associated with key events as a
|
||
sequence of Unicode code points. This behavior is opt-in by the :ref:`progressive
|
||
enhancement <progressive_enhancement>` mechanism described below. Some examples::
|
||
|
||
shift+a -> CSI 97 ; 2 ; 65 u # The text 'A' is reported as 65
|
||
option+a -> CSI 97 ; ; 229 u # The text 'å' is reported as 229
|
||
|
||
If multiple code points are present, they must be separated by colons.
|
||
If no known key is associated with the text the key number ``0`` must be used.
|
||
|
||
|
||
Non-Unicode keys
|
||
~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
There are many keys that don't correspond to letters from human languages, and
|
||
thus aren't represented in Unicode. Think of functional keys, such as
|
||
:kbd:`Escape, Play, Pause, F1, Home, etc`. These are encoded using Unicode code
|
||
points from the Private Use Area (``57344 - 63743``). The mapping of key
|
||
names to code points for these keys is in the
|
||
:ref:`Functional key definition table below <functional>`.
|
||
|
||
|
||
.. _progressive_enhancement:
|
||
|
||
Progressive enhancement
|
||
--------------------------
|
||
|
||
While, in theory, every key event could be completely represented by this
|
||
protocol and all would be hunk-dory, in reality there is a vast universe of
|
||
existing terminal programs that expect legacy control codes for key events and
|
||
that are not likely to ever be updated. To support these, in default mode,
|
||
the terminal will emit legacy escape codes for compatibility. If a terminal
|
||
program wants more robust key handling, it can request it from the terminal,
|
||
via the mechanism described here. Each enhancement is described in detail
|
||
below. The escape code for requesting enhancements is::
|
||
|
||
CSI = flags ; mode u
|
||
|
||
Here ``flags`` is a decimal encoded integer to specify a set of bit-flags. The
|
||
meanings of the flags are given below. The second, ``mode`` parameter is
|
||
optional (defaulting to ``1``) and specifies how the flags are applied.
|
||
The value ``1`` means all set bits are set and all unset bits are reset.
|
||
The value ``2`` means all set bits are set, unset bits are left unchanged.
|
||
The value ``3`` means all set bits are reset, unset bits are left unchanged.
|
||
|
||
.. csv-table:: The progressive enhancement flags
|
||
:header: "Bit", "Meaning"
|
||
|
||
"0b1 (1)", ":ref:`disambiguate`"
|
||
"0b10 (2)", ":ref:`report_events`"
|
||
"0b100 (4)", ":ref:`report_alternates`"
|
||
"0b1000 (8)", ":ref:`report_all_keys`"
|
||
"0b10000 (16)", ":ref:`report_text`"
|
||
|
||
The program running in the terminal can query the terminal for the
|
||
current values of the flags by sending::
|
||
|
||
CSI ? u
|
||
|
||
The terminal will reply with::
|
||
|
||
CSI ? flags u
|
||
|
||
The program can also push/pop the current flags onto a stack in the
|
||
terminal with::
|
||
|
||
CSI > flags u # for push, if flags ommitted default to zero
|
||
CSI < number u # to pop number entries, defaulting to 1 if unspecified
|
||
|
||
Terminals should limit the size of the stack as appropriate, to prevent
|
||
Denial-of-Service attacks. Terminals must maintain separate stacks for the main
|
||
and alternate screens. If a pop request is received that empties the stack,
|
||
all flags are reset. If a push request is received and the stack is full, the
|
||
oldest entry from the stack must be evicted.
|
||
|
||
.. _disambiguate:
|
||
|
||
Disambiguate escape codes
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
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 <functional>`.
|
||
|
||
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. The only exceptions
|
||
are the :kbd:`Enter, Tab and Backspace` keys which still generate the same
|
||
bytes as in legacy mode this is to allow the user to type and execute commands
|
||
in the shell such as ``reset`` after a program that sets this mode crashes
|
||
without clearing it.
|
||
|
||
.. _report_events:
|
||
|
||
Report event types
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
This progressive enhancement (``0b10``) causes the terminal to report key repeat
|
||
and key release events. Normally only key press events are reported and key
|
||
repeat events are treated as key press events. See :ref:`event_types` for
|
||
details on how these are reported.
|
||
|
||
.. _report_alternates:
|
||
|
||
Report alternate keys
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
This progressive enhancement (``0b100``) causes the terminal to report
|
||
alternate key values in addition to the main value, to aid in shortcut
|
||
matching. See :ref:`key_codes` for details on how these are reported.
|
||
|
||
.. _report_all_keys:
|
||
|
||
Report all keys as escape codes
|
||
----------------------------------
|
||
|
||
Key events that generate text, such as plain key presses without modifiers,
|
||
result in just the text being sent, in the legacy protocol. There is no way to
|
||
be notified of key repeat/release events. These types of events are needed for
|
||
some applications, such as games (think of movement using the ``WASD`` keys).
|
||
|
||
This progressive enhancement (``0b1000``) turns on key reporting even for key
|
||
events that generate next. When it is enabled, text will not be sent, instead
|
||
only key events are sent. If the text is needed as well, combine with the
|
||
Report associated text enhancement below.
|
||
|
||
.. _report_text:
|
||
|
||
Report associated text
|
||
------------------------
|
||
|
||
This progressive enhancement (``0b10000``) causes key events that generate text
|
||
to be reported as ``CSI u`` escape codes with the text embedded in the escape
|
||
code. See :ref:`text_as_codepoints` above for details on the mechanism.
|
||
|
||
Legacy key event encoding
|
||
--------------------------------
|
||
|
||
In the default mode, the terminal uses a legacy encoding for key events. In
|
||
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 encodable in the legacy
|
||
encoding, thereby increasing the space of usable key combinations even without
|
||
progressive enhancement.
|
||
|
||
Legacy functional keys
|
||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
These keys are encoded using three schemes::
|
||
|
||
CSI number ; modifier ~
|
||
CSI 1 ; modifier {ABCDFHPQRS}
|
||
SS3 {ABCDFHPQRS}
|
||
|
||
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,
|
||
above. When the second form is used, the number is always ``1`` and must be
|
||
omitted if the modifiers field is also absent. The third form becomes the
|
||
second form when modifiers are present (``SS3 is the bytes 0x1b 0x4f``).
|
||
|
||
These sequences must match entries in the terminfo database for maximum
|
||
compatibility. The table below lists the key, its terminfo entry name and
|
||
the escape code used for it by kitty. A different terminal would use whatever
|
||
escape code is present in its terminfo database for the key.
|
||
Some keys have an alternate representation when the terminal is in *cursor key
|
||
mode* (the ``smkx/rmkx`` terminfo capabilities). This form is used only in
|
||
*cursor key mode* and only when no modifiers are present.
|
||
|
||
.. csv-table:: Legacy functional encoding
|
||
:header: "Name", "Terminfo name", "Escape code"
|
||
|
||
"INSERT", "kich1", "CSI 2 ~"
|
||
"DELETE", "kdch1", "CSI 3 ~"
|
||
"PAGE_UP", "kpp", "CSI 5 ~"
|
||
"PAGE_DOWN", "knp", "CSI 6 ~"
|
||
"UP", "cuu1,kcuu1", "CSI A, SS3 A"
|
||
"DOWN", "cud1,kcud1", "CSI B, SS3 B"
|
||
"RIGHT", "cuf1,kcuf1", "CSI C, SS3 C"
|
||
"LEFT", "cub1,kcub1", "CSI D, SS3 D"
|
||
"HOME", "home,khome", "CSI H, SS3 H"
|
||
"END", "-,kend", "CSI F, SS3 F"
|
||
"F1", "kf1", "SS3 P"
|
||
"F2", "kf2", "SS3 Q"
|
||
"F3", "kf3", "SS3 R"
|
||
"F4", "kf4", "SS3 S"
|
||
"F5", "kf5", "CSI 15 ~"
|
||
"F6", "kf6", "CSI 17 ~"
|
||
"F7", "kf7", "CSI 18 ~"
|
||
"F8", "kf8", "CSI 19 ~"
|
||
"F9", "kf9", "CSI 20 ~"
|
||
"F10", "kf10", "CSI 21 ~"
|
||
"F11", "kf11", "CSI 23 ~"
|
||
"F12", "kf12", "CSI 24 ~"
|
||
|
||
There are a few more functional keys that have special cased legacy
|
||
encodings:
|
||
|
||
.. csv-table:: C0 controls
|
||
:header: "Key", "Encodings"
|
||
|
||
"Enter", "Plain - 0xd, alt+Enter - 0x1b 0x1d"
|
||
"Escape", "Plain - 0x1b, alt+Esc - 0x1b 0x1b"
|
||
"Backspace", "Plain - 0x7f, alt+Backspace - 0x1b 0x7f, ctrl+Backspace - 0x08"
|
||
"Space", "Plain - 0x20, ctrl+Space - 0x0, alt+space - 0x1b 0x20"
|
||
"Tab", "Plain - 0x09, shift+Tab - CSI Z"
|
||
|
||
Note that :kbd:`Backspace` and :kbd:`ctrl+backspace` are swapped in some
|
||
terminals.
|
||
|
||
All keypad keys are reported as there equivalent non-keypad keys. To
|
||
distinguish these, use the :ref:`disambiguate <disambiguate>` flag.
|
||
|
||
.. _legacy_text:
|
||
|
||
Legacy text keys
|
||
~~~~~~~~~~~~~~~~~~~
|
||
|
||
For legacy compatibility, the keys
|
||
:kbd:`a-z 0-9 \` - = [ ] \ ; ' , . /` with the modifiers
|
||
:kbd:`shift, alt, ctrl, shift+alt, ctrl+alt` are output using the
|
||
following algorithm:
|
||
|
||
#. If the :kbd:`alt` key is pressed output the byte for ``ESC (0x1b)``
|
||
#. If the :kbd:`ctrl` modifier is pressed mask the seventh bit ``(0b1000000)``
|
||
in the key's ASCII code number and output that
|
||
#. Otherwise, if the :kbd:`shift` modifier is pressed, output the shifted key,
|
||
for example, ``A`` for ``a`` and ``$`` for ``4``.
|
||
#. Otherwise, output the key unmodified
|
||
|
||
Additionally, :kbd:`ctrl+space` is output as the NULL byte ``(0x0)``.
|
||
|
||
Any other combination of modifiers with these keys is output as the appropriate
|
||
``CSI u`` escape code.
|
||
|
||
.. csv-table:: Example encodings
|
||
:header: "Key", "Plain", "shift", "alt", "ctrl", "shift+alt", "alt+ctrl", "ctrl+shift"
|
||
|
||
"i", "i (105)", "I (73)", "ESC i", ") (41)", "ESC I", "ESC )", "CSI 105; 6 u"
|
||
"3", "3 (51)", "# (35)", "ESC 3", "3 (51)", "ESC #", "ESC 3", "CSI 51; 6 u"
|
||
";", "; (59)", ": (58)", "ESC ;", "; (59)", "ESC :", "ESC ;", "CSI 59; 6 u"
|
||
|
||
.. note::
|
||
Many of the legacy escape codes are ambiguous with multiple different key
|
||
presses yielding the same escape code(s), for example, :kbd:`ctrl+i` is the
|
||
same as :kbd:`tab`, :kbd:`ctrl+m` is the same as :kbd:`Enter`, :kbd:`ctrl+r`
|
||
is the same :kbd:`ctrl+shift+r`, etc. To resolve these use the
|
||
:ref:`disambiguate progressive enhancement <disambiguate>`.
|
||
|
||
|
||
.. _functional:
|
||
|
||
Functional key definitions
|
||
----------------------------
|
||
|
||
All numbers are in the Unicode Private Use Area (``57344 - 63743``) except
|
||
for a handful of keys that use numbers under 32 and 127 (C0 control codes) for legacy
|
||
compatibility reasons.
|
||
|
||
.. {{{
|
||
.. start functional key table (auto generated by gen-key-constants.py do not edit)
|
||
|
||
.. csv-table:: Functional key codes
|
||
:header: "Name", "CSI sequence"
|
||
|
||
"ESCAPE", "CSI 27 u"
|
||
"ENTER", "CSI 13 u"
|
||
"TAB", "CSI 9 u"
|
||
"BACKSPACE", "CSI 127 u"
|
||
"INSERT", "CSI 2 ~"
|
||
"DELETE", "CSI 3 ~"
|
||
"LEFT", "CSI 1 D"
|
||
"RIGHT", "CSI 1 C"
|
||
"UP", "CSI 1 A"
|
||
"DOWN", "CSI 1 B"
|
||
"PAGE_UP", "CSI 5 ~"
|
||
"PAGE_DOWN", "CSI 6 ~"
|
||
"HOME", "CSI 1 H or CSI 7 ~"
|
||
"END", "CSI 1 F or CSI 8 ~"
|
||
"CAPS_LOCK", "CSI 57358 u"
|
||
"SCROLL_LOCK", "CSI 57359 u"
|
||
"NUM_LOCK", "CSI 57360 u"
|
||
"PRINT_SCREEN", "CSI 57361 u"
|
||
"PAUSE", "CSI 57362 u"
|
||
"MENU", "CSI 57363 u"
|
||
"F1", "CSI 1 P or CSI 11 ~"
|
||
"F2", "CSI 1 Q or CSI 12 ~"
|
||
"F3", "CSI 1 R or CSI 13 ~"
|
||
"F4", "CSI 1 S or CSI 14 ~"
|
||
"F5", "CSI 15 ~"
|
||
"F6", "CSI 17 ~"
|
||
"F7", "CSI 18 ~"
|
||
"F8", "CSI 19 ~"
|
||
"F9", "CSI 20 ~"
|
||
"F10", "CSI 21 ~"
|
||
"F11", "CSI 23 ~"
|
||
"F12", "CSI 24 ~"
|
||
"F13", "CSI 57376 u"
|
||
"F14", "CSI 57377 u"
|
||
"F15", "CSI 57378 u"
|
||
"F16", "CSI 57379 u"
|
||
"F17", "CSI 57380 u"
|
||
"F18", "CSI 57381 u"
|
||
"F19", "CSI 57382 u"
|
||
"F20", "CSI 57383 u"
|
||
"F21", "CSI 57384 u"
|
||
"F22", "CSI 57385 u"
|
||
"F23", "CSI 57386 u"
|
||
"F24", "CSI 57387 u"
|
||
"F25", "CSI 57388 u"
|
||
"F26", "CSI 57389 u"
|
||
"F27", "CSI 57390 u"
|
||
"F28", "CSI 57391 u"
|
||
"F29", "CSI 57392 u"
|
||
"F30", "CSI 57393 u"
|
||
"F31", "CSI 57394 u"
|
||
"F32", "CSI 57395 u"
|
||
"F33", "CSI 57396 u"
|
||
"F34", "CSI 57397 u"
|
||
"F35", "CSI 57398 u"
|
||
"KP_0", "CSI 57399 u"
|
||
"KP_1", "CSI 57400 u"
|
||
"KP_2", "CSI 57401 u"
|
||
"KP_3", "CSI 57402 u"
|
||
"KP_4", "CSI 57403 u"
|
||
"KP_5", "CSI 57404 u"
|
||
"KP_6", "CSI 57405 u"
|
||
"KP_7", "CSI 57406 u"
|
||
"KP_8", "CSI 57407 u"
|
||
"KP_9", "CSI 57408 u"
|
||
"KP_DECIMAL", "CSI 57409 u"
|
||
"KP_DIVIDE", "CSI 57410 u"
|
||
"KP_MULTIPLY", "CSI 57411 u"
|
||
"KP_SUBTRACT", "CSI 57412 u"
|
||
"KP_ADD", "CSI 57413 u"
|
||
"KP_ENTER", "CSI 57414 u"
|
||
"KP_EQUAL", "CSI 57415 u"
|
||
"KP_SEPARATOR", "CSI 57416 u"
|
||
"KP_LEFT", "CSI 57417 u"
|
||
"KP_RIGHT", "CSI 57418 u"
|
||
"KP_UP", "CSI 57419 u"
|
||
"KP_DOWN", "CSI 57420 u"
|
||
"KP_PAGE_UP", "CSI 57421 u"
|
||
"KP_PAGE_DOWN", "CSI 57422 u"
|
||
"KP_HOME", "CSI 57423 u"
|
||
"KP_END", "CSI 57424 u"
|
||
"KP_INSERT", "CSI 57425 u"
|
||
"KP_DELETE", "CSI 57426 u"
|
||
"LEFT_SHIFT", "CSI 57427 u"
|
||
"LEFT_CONTROL", "CSI 57428 u"
|
||
"LEFT_ALT", "CSI 57429 u"
|
||
"LEFT_SUPER", "CSI 57430 u"
|
||
"RIGHT_SHIFT", "CSI 57431 u"
|
||
"RIGHT_CONTROL", "CSI 57432 u"
|
||
"RIGHT_ALT", "CSI 57433 u"
|
||
"RIGHT_SUPER", "CSI 57434 u"
|
||
"MEDIA_PLAY", "CSI 57435 u"
|
||
"MEDIA_PAUSE", "CSI 57436 u"
|
||
"MEDIA_PLAY_PAUSE", "CSI 57437 u"
|
||
"MEDIA_REVERSE", "CSI 57438 u"
|
||
"MEDIA_STOP", "CSI 57439 u"
|
||
"MEDIA_FAST_FORWARD", "CSI 57440 u"
|
||
"MEDIA_REWIND", "CSI 57441 u"
|
||
"MEDIA_TRACK_NEXT", "CSI 57442 u"
|
||
"MEDIA_TRACK_PREVIOUS", "CSI 57443 u"
|
||
"MEDIA_RECORD", "CSI 57444 u"
|
||
"LOWER_VOLUME", "CSI 57445 u"
|
||
"RAISE_VOLUME", "CSI 57446 u"
|
||
"MUTE_VOLUME", "CSI 57447 u"
|
||
|
||
.. end functional key table
|
||
.. }}}
|
||
|
||
Note that the escape codes above of the form ``CSI 1 letter`` will omit the
|
||
``1`` if there are no modifiers, since ``1`` is the default value.
|
||
|
||
.. _fixterms_bugs:
|
||
|
||
Bugs in fixterms
|
||
-------------------
|
||
|
||
* 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
|
||
is actually ``SS3 letter``.
|
||
* :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`.
|
||
* No way to have non-conflicting escape codes for :kbd:`alt+letter,
|
||
ctrl+letter, ctrl+alt+letter` key presses
|
||
* No way to specify both shifted and unshifted keys for robust shortcut
|
||
matching (think matching :kbd:`ctrl+shift+equal` and :kbd:`ctrl+plus`)
|
||
* No way to specify alternate layout key. This is useful for keyboard layouts
|
||
such as Cyrillic where you want the shortcut :kbd:`ctrl+c` to work when
|
||
pressing the :kbd:`ctrl+С` on the keyboard.
|
||
* No way to report repeat and release key events, only key press events
|
||
* No way to report key events for presses that generate text, useful for
|
||
gaming. Think of using the :kbd:`WASD` keys to control movement.
|
||
* Only a small subset of all possible functional keys are assigned numbers.
|