Skip to content

fix(tui): resolve Num Lock and unmapped modified keys instead of typing escape text - #35

Merged
wowi42 merged 1 commit into
mainfrom
fix/tui-lock-and-modified-keys
Oct 14, 2026
Merged

wowi42 merged 1 commit into
mainfrom
fix/tui-lock-and-modified-keys

Conversation

@Mouhand-Kaddo

Copy link
Copy Markdown
Contributor

Summary

Kitty-protocol terminals put Num/Caps Lock in the modifier field (+128 / +64), so keys missed every mapping and were typed as raw escape text.

match(sequence)
  exact ANSI_SEQUENCES hit            -> done
  xterm unicode (27;mod;code~)        -> char
+ for mask in (locks, shift, alt)
+   drop those modifier bits and re-match
+     locks: ignored          Left 1;129D        -> Left
+     shift: acts as plain    Shift+Backspace    -> Backspace
+     alt:   Esc + base key   Alt+F5             -> Esc, F5
+ any other CSI key chord      Ctrl+1, Super+x   -> Keys.Ignore (not typed)

Also: single-char matches from stripped sequences now insert the character, not the raw sequence (normalize_xterm_shift). test_headless_timeout_kills_foreground_shell pins SHELL=/bin/sh, since its POSIX $$ is invalid in fish and the test failed for fish users.

Evidence

  • Before: [1;129D, [127;133u, [13;130u typed into the prompt; Shift+Backspace likewise.
    After: new tests send them through the real input area:
    "ab" + ESC[1;129D + "X"                 -> "aXb"
    "ab" + ESC[13;130u / ESC[127;133u       -> newline / backspace
    "ab" + ESC[127;2u (and ;130u, ;194u) + "X" -> "aX"
    "ab" + ESC[32;2u + "X"                  -> "ab X"
    "ab" + ESC[49;5u | ESC[120;9u | ESC[15;3~ + "X" -> "abX"
    
    Reverting the fix fails the Num Lock test. tests/test_tui_app.py, test_tui_input.py, test_tui_streaming_pty.py: 157 passed; ruff check/format clean. Not tried in a real terminal.

Merge Danger

Door: two-way

Blast Radius: TUI key input

Only sequences that previously matched nothing change behavior. Known gaps: Shift+F3 (ESC[1;2R) still collides with the cursor-position reply; Kitty :event-type suffixes are not handled.

…ng escape text

Kitty reports Num/Caps Lock as modifier bits, so Left, Shift+Enter and Ctrl+Backspace arrived as ESC[1;129D, ESC[13;130u, ESC[127;133u. Strip lock bits, fall back from Shift (Shift+Backspace acts as Backspace), map Alt+F-keys to Esc+key, and swallow remaining unbound chords. Also pin SHELL=/bin/sh in the headless timeout test, which uses POSIX $$.
@wowi42
wowi42 merged commit 5625a41 into main Oct 14, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants