Windows Terminal Preview duplicates non-ASCII input in Codex TUI under WSL
Environment
- Codex CLI:
0.146.0 - Platform: WSL 2 on Windows
- Terminal: Windows Terminal Preview
1.25.1912.0 - Shell: zsh
- Keyboard layout: Czech
Reproduction
- Open Windows Terminal Preview and start a WSL shell.
- Run
codexand focus the chat composer. - Type a non-ASCII Czech-layout character, for example
ě,š,č,ř,ž,ý,á,í,é,ú,ů,§, or'.
Actual behavior
Each affected character is inserted twice. One copy appears on key-down and the second appears when the key is released. This happens only in Codex's TUI composer; the same keyboard and terminal work correctly in the WSL shell and other TUI CLI applications.
Expected behavior
Each keypress should insert exactly one character.
Context
Windows Terminal Preview 1.25's Kitty Keyboard Protocol support fixes important input behavior in Codex, including Ctrl+Backspace word deletion and modifier-aware Enter handling. Disabling keyboard enhancement avoids this duplication, but gives up those improvements, so it is not a viable workaround.
This appears to match the already-written minimal fix in #30480, which removes REPORT_ALTERNATE_KEYS. Its PR description/comment explicitly notes that some Kitty-protocol terminals emit duplicate non-ASCII text when alternate keycodes are requested. That PR was automatically closed after 14 days without review activity, rather than rejected on technical grounds.
Relevant current code: https://github.com/openai/codex/blob/main/codex-rs/tui/src/tui/keyboard_modes.rs
4 Comments
Additional impact: this is not limited to writing Czech prose. On the Czech layout, affected keys also include programming punctuation such as quotes and
/(and related layout-dependent symbols). Those characters are needed constantly for source code, commands, paths, JSON, and strings, so the current regression makes normal Codex use impractical rather than merely inconvenient for localized text.The common trait appears to be layout-dependent/alternate-key reporting, not simply whether the final character is non-ASCII. The title and reproduction should therefore be read as covering duplicated printable input produced by this layout under the Kitty keyboard protocol.
Confirmed workaround result from the affected setup:
CSI > 7 utoCSI > 3 u(disable onlyREPORT_ALTERNATE_KEYS) did not stop the duplicated input.CSI > 7 utoCSI > 1 u(retain onlyDISAMBIGUATE_ESCAPE_CODES, disable bothREPORT_EVENT_TYPESandREPORT_ALTERNATE_KEYS) does stop it.This narrows the Windows Terminal Preview + WSL regression:
REPORT_EVENT_TYPESis implicated as well, likely because the layout-dependent key-up event is not being handled correctly somewhere in the Codex/crossterm input path. Modifier disambiguation remains enabled, so the desired enhanced-key behavior can be retained without requesting event types.Consequently, #30480's removal of alternate-key reporting alone is insufficient for this reproduction.
Traced the codex side of this on
main@ 1f41cc5d92. The composer's own event handling is correct, which — combined with @AspireOne'sCSI > 1 u/CSI > 3 uexperiment — narrows the defect to how the release events reach the parser, and there's a one-line-shaped fix location already designed for exactly this situation.Codex already drops release events. The composer ignores
KeyEventKind::Release(chat_composer.rs L1939, L3532). So a key-release can only insert a second character if it arrives parsed as a press.Why a release can parse as a press. In the crossterm fork Codex pins (
openai-oss-forks/crossterm@ 45fecb95), the kitty CSI‑u parser takes the event type from the sub-parameter of the modifier field and defaults to1(Press) when the sub-parameter is absent (spec-compliant — kitty defines absent = press). So if Windows Terminal Preview encodes the release of a layout-dependent text key either (a) as a CSI‑u sequence without the:3event-type sub-param, or (b) as plain UTF-8 text bytes, crossterm emits a secondPresscarrying the character and the composer inserts it. That matches the reported timing exactly (first copy on key-down, second on release) and matches the flag experiment: withREPORT_EVENT_TYPESdisabled (CSI > 1 u), the terminal never sends release events at all, so the malformed encoding never happens.A 5-minute diagnostic that settles whether this is WT's encoder or crossterm's parser (runnable in the affected WSL setup, no Codex involved):
If the release sequences printed by
cat -vlack the:3sub-param (or appear as bare text), it's Windows Terminal Preview's encoder and worth filing against microsoft/terminal with those bytes; if they do carry:3, the fork's parser is mishandling them and it's fixable inopenai-oss-forks/crossterm.Codex can defend regardless.
keyboard_enhancement_flagsalready omitsREPORT_EVENT_TYPESper terminal for exactly this class of problem — Ghostty and iTerm2 (leaky release events) and tmux's xterm format:https://github.com/openai/codex/blob/1f41cc5d92722748e45cae9cecc6d883a4e7cbb1/codex-rs/tui/src/tui/keyboard_modes.rs#L152-L169
TerminalName::WindowsTerminalalready exists in codex-terminal-detection (detected viaWT_SESSION, which crosses into WSL), so adding it to that match arm suppresses event-type reporting for WT while keepingDISAMBIGUATE_ESCAPE_CODES+REPORT_ALTERNATE_KEYS— i.e.CSI > 5 u. One caveat worth a quick check on the affected setup: the experiments covered7u(fails),3u(fails), and1u(works), but not5u. If5ualso duplicates (i.e. alternate-key reporting alone also triggers the stray text), the same match arm can return bareDISAMBIGUATE_ESCAPE_CODESfor Windows Terminal instead — that's the reporter-verified1uconfiguration.(For anyone else landing here meanwhile:
CODEX_TUI_DISABLE_KEYBOARD_ENHANCEMENT=1is the existing big-hammer escape hatch, with the known cost of losing Ctrl+Backspace/modified-Enter handling.)Additional narrowing from the reporter:
NVIM v0.12.4) under WSL.CSI > 3 uat startup. Codex requestsCSI > 7 u; both requests include Kitty flag2(REPORT_EVENT_TYPES). The reporter has directly verified that changing Codex's request toCSI > 1 uremoves the duplication while retaining the desired Ctrl+Backspace behavior.This is correlation, not yet a claim that either application or Windows Terminal violates the protocol. The shared observation is that the failure appears whenever the report-event-types enhancement is requested in this Windows Terminal Preview + WSL + Czech-layout setup. We are checking Neovim's existing upstream report separately rather than filing a duplicate.
References: https://neovim.io/doc/user/tui/ and https://sw.kovidgoyal.net/kitty/keyboard-protocol/