# Keyboard Encoding

When input that doesn't match a key assignment is processed, it is encoded into
a byte stream and sent to the PTY associated with the program that is running
in the active pane.

The default encoding scheme used by wezterm is xterm compatible, but there are
some configuration options that can modify the encoding.

The standard xterm compatible encoding generates events for key presses (but
not releases) and can represent the set of keys that existed on terminal
hardware of the 1980's.

That scheme has worked well for quite some time, but has some ambiguity due
to the way that the Control modifier "shifts" the ASCII representation of
keypresses like `Control-I` to be ASCII Tab, as an example.

## xterm `modifyOtherKeys`

{{since('20221119-145034-49b9839f')}}

When wezterm receives the sequence `CSI >4;Nm`, where `N` is `0`, `1` or `2`,
the keyboard encoding is changed according to
[modifyOtherKeys](https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys),
which causes certain modified keys to be encoded as [described in xterms
docs](https://invisible-island.net/xterm/modified-keys.html), making it
possible for applications to distinguish between the modified and unmodified
key presses.

Note that [enable_csi_u_key_encoding](lua/config/enable_csi_u_key_encoding.md)
and [allow_win32_input_mode](lua/config/allow_win32_input_mode.md) both take
precedence over this behavior.

## CSI-u/fixterms/libtickit

[Fix Keyboard Input on Terminals](http://www.leonerd.org.uk/hacks/fixterms/) is
an attempt at resolving the ambiguous encoding and doing a better job at
representing more modifiers. It's not a perfect attempt as there are [a number
of issues with
it](https://sw.kovidgoyal.net/kitty/keyboard-protocol/#bugs-in-fixterms).

You can enable support for this encoding by setting `enable_csi_u_key_encoding
= true`, however, it is not recommended as it does change the behavior of some
keys in backwards incompatible ways and there isn't a way for applications to
detect or request this behavior.

See also: [enable_csi_u_key_encoding](lua/config/enable_csi_u_key_encoding.md).

Note that [allow_win32_input_mode](lua/config/allow_win32_input_mode.md) takes
precedence over this option.

## Kitty Keyboard Protocol

The Kitty terminal extended and enhanced the CSI-u based encoding scheme with
its [Comprehensive keyboard handling
protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/).

The kitty protocol allows applications to request varying degrees of
enhancement over the standard encoding scheme and also allows for more modifier
keys (notably: `CMD`/`Super`/`Windows`) to be reported to the application.

[enable_kitty_keyboard](lua/config/enable_kitty_keyboard.md) controls whether
wezterm will honor the application requests to modify the keyboard encoding.

## Windows

On Windows, [allow_win32_input_mode](lua/config/allow_win32_input_mode.md)
defaults to `true` which causes wezterm to listen for an escape sequence
generated by the ConPTY layer of Windows to enable [Win32 Input Mode](https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md).

In this mode, key release events as well as events that can distinguish between
positional (left/right) modifier keys are generated and this mode provides the
best compatibility with win32 console applications such as Far Manager.

`allow_win32_input_mode` takes precedence over
[enable_csi_u_key_encoding](lua/config/enable_csi_u_key_encoding.md).

