fuzzball 1.0.0

Encoder and decoder for the Fuzzball terminal protocol (DCS Fz graphics, keyboard, shell and plugin messages)
Documentation
# Fuzzball keyboard — v0.1 (implementable draft)

Subsystem letter: `k`. Framing, replies and errors: see [README](README.md).

## 1. One mode

There is exactly one mode: **structured key events**. While it is on, every key event
(press, repeat, release) is reported as one message; nothing is sent in legacy form.
While it is off, the terminal sends legacy (xterm/VT) bytes.

Enable / disable (per screen; the main and alternate screens are independent):

```
ESC P = F z k s ; on=1[,v=0][,id=<n>] ESC \     enable
ESC P = F z k s ; on=0[,id=<n>] ESC \           disable
ESC P = F z k q ; id=<n> ESC \                  query
→ ESC P = F z k r ; id=<n>,ok=1,on=1 ESC \
```

The mode is also turned off by RIS and when the program's screen is left (e.g. leaving
the alternate screen restores the main screen's own state).

## 2. Event message

Sent by the terminal to the application:

```
ESC P = F z k e ; t=<p|r|u>,code=<phys>,key=<logical>[,mods=<n>][,locks=<n>][,text=<hex>][,ime=<phase>] ESC \
```

| field | meaning |
|---|---|
| `t` | `p` press, `r` repeat, `u` release. |
| `code` | physical key, as the USB HID usage name from the W3C UI Events `code` list, e.g. `KeyA`, `Digit1`, `ArrowUp`, `ShiftLeft`, `Numpad7`. Layout independent. |
| `key` | logical key: a W3C UI Events `key` name for non-text keys (`Enter`, `Escape`, `F13`, `MediaPlayPause`…), or `U+XXXX` for the unmodified character the key produces on the current layout (e.g. `U+0061` for `a`, `U+0444` for `ф`). |
| `mods` | bitmask of held modifiers: 1 Shift, 2 Alt, 4 Ctrl, 8 Super, 16 Hyper, 32 Meta, 64 AltGr. Omitted when 0. |
| `locks` | 1 CapsLock, 2 NumLock, 4 ScrollLock. Omitted when 0. |
| `text` | UTF-8 text this event inserts, hex-encoded (so any character is safe on the wire). Omitted when none. Present for presses and repeats only. |
| `ime` | `start`, `update`, `commit`, `cancel` — composition state; see §3. |

Modifier keys themselves produce events (`code=ShiftLeft,key=Shift`), with `mods`
reflecting the state **after** the event.

Examples:

```
a              ESC P = F z k e ; t=p,code=KeyA,key=U+0061,text=61 ESC \
Shift+a        ESC P = F z k e ; t=p,code=KeyA,key=U+0061,mods=1,text=41 ESC \
release a      ESC P = F z k e ; t=u,code=KeyA,key=U+0061 ESC \
Ctrl+c         ESC P = F z k e ; t=p,code=KeyC,key=U+0063,mods=4 ESC \
Ctrl+ф (RU)    ESC P = F z k e ; t=p,code=KeyA,key=U+0444,mods=4 ESC \
Enter          ESC P = F z k e ; t=p,code=Enter,key=Enter,text=0d ESC \
Up (repeat)    ESC P = F z k e ; t=r,code=ArrowUp,key=ArrowUp ESC \
Left Shift     ESC P = F z k e ; t=p,code=ShiftLeft,key=Shift,mods=1 ESC \
```

Applications get both the physical key (for shortcuts that should not move with the
layout, e.g. games, vim's `hjkl` on Dvorak if desired) and the logical key (for shortcuts
by letter), without the terminal guessing which one is meant.

## 3. IME and composed text

Composition is reported separately from key presses so applications don't mistake
pre-edit keystrokes for input:

```
ESC P = F z k e ; t=p,ime=start ESC \
ESC P = F z k e ; t=p,ime=update,text=e3818b ESC \        pre-edit "か", not inserted
ESC P = F z k e ; t=p,ime=commit,text=e6bca2e5ad97 ESC \  insert "漢字"
ESC P = F z k e ; t=p,ime=cancel ESC \
```

Key events consumed by the IME are not reported. Dead keys behave like a one-character
composition (`start` … `commit`). Applications that don't care about pre-edit only act on
`commit`.

## 4. Paste

Pasted text is not keyboard input; it stays on bracketed paste (mode 2004) whether or not
this mode is on.

## 5. Capability keys

In the common capability reply: `k=1` (mode available), `k_ime=1` if IME events are
reported, `k_release=1` if the platform delivers release events (some remote setups
cannot).

## 6. Differences from the Kitty keyboard protocol

- No flag bits: one mode, always full information.
- Physical and logical keys are separate named fields instead of numeric code points
  plus "alternate keys".
- Text is always explicit (hex), so control characters and non-BMP text are unambiguous.
- IME composition is part of the protocol.