---
title: "WezTerm Keyboard Encoding"
aliases: [wezterm-key-encoding, terminal-keyboard-encoding]
tags: [wezterm, terminal, keyboard, encoding, kitty-protocol, xterm]
sources: [raw/Keyboard Encoding - Wez's Terminal Emulator.md]
created: 2026-04-17
updated: 2026-04-17
---

## Overview

When a keypress doesn't match a key assignment, WezTerm encodes it into a byte stream sent to the PTY. Four encoding schemes are supported, with a priority order that determines which wins.

## Encoding Schemes

### 1. Default — xterm Compatible
- Generates events for key **presses only** (not releases)
- Covers the key set from 1980s terminal hardware
- Main limitation: ambiguity with Control modifier — e.g. `Ctrl-I` = ASCII Tab, indistinguishable from Tab itself

### 2. xterm modifyOtherKeys
- Triggered by escape sequence `CSI >4;Nm` (N = 0, 1, or 2)
- Encodes certain modified keys unambiguously so apps can tell `Ctrl-I` from Tab
- Spec: [modifyOtherKeys](https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys)
- Available since WezTerm `20221119-145034-49b9839f`
- Overridden by `enable_csi_u_key_encoding` and `allow_win32_input_mode`

### 3. CSI-u / fixterms / libtickit
- Config: `enable_csi_u_key_encoding = true`
- Attempts to resolve xterm ambiguity and expose more modifiers
- **Not recommended** — breaks some keys in backwards-incompatible ways; apps cannot detect or request it
- Overridden by `allow_win32_input_mode`

### 4. Kitty Keyboard Protocol
- Config: `enable_kitty_keyboard = true`
- Most capable: apps can request varying levels of enhancement
- Adds support for `CMD` / `Super` / `Windows` modifier keys
- Apps opt-in via escape sequences; WezTerm honors those requests when enabled
- Spec: [Kitty comprehensive keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/)

### 5. Win32 Input Mode (Windows only)
- Config: `allow_win32_input_mode` — defaults to `true` on Windows
- Enables key **release** events and distinguishes left/right modifier keys
- Best compatibility with win32 console apps (e.g. Far Manager)
- Highest priority — overrides both CSI-u and modifyOtherKeys

## Priority Order

```
Win32 Input Mode  >  CSI-u  >  Kitty Protocol  >  modifyOtherKeys  >  xterm default
```

> `allow_win32_input_mode` wins everything on Windows. `enable_csi_u_key_encoding` beats modifyOtherKeys.

## Config Options Reference

| Option | Type | Default | Effect |
|--------|------|---------|--------|
| `enable_kitty_keyboard` | bool | false | Honor app requests for kitty protocol |
| `enable_csi_u_key_encoding` | bool | false | Enable CSI-u/fixterms encoding (not recommended) |
| `allow_win32_input_mode` | bool | true (Win) | Enable Win32 Input Mode on Windows |

## Key Takeaways

- WezTerm defaults to **xterm-compatible** encoding — works everywhere but has modifier ambiguity
- **Kitty Keyboard Protocol** is the modern, recommended enhancement — apps opt in via escape sequences
- **CSI-u** (`enable_csi_u_key_encoding`) is available but not recommended due to backwards-compatibility breakage
- On **Windows**, `allow_win32_input_mode = true` by default and takes highest priority
- Encoding scheme choice matters for Neovim, Emacs, and other apps that rely on distinguishing modified keys

## Related

- [[wiki/dotfiles/wezterm-key-bindings|WezTerm Key Bindings]] — how to configure key assignments in Lua
- [[wiki/dotfiles/wezterm-key-tables|WezTerm Key Tables]] — modal keybinding layers
- [[wiki/dotfiles/wezterm-keyboard-concepts|WezTerm Keyboard Concepts]] — OS-level input concepts (IME, dead keys, AltGr)
- [[wiki/dotfiles/wezterm-default-keybindings|WezTerm Default Keybindings]] — full default key assignment table
