#254

feat: support xterm modifyOtherKeys level 2

OpenRaillywants to merge intofrom

Problem

Legacy key encoding drops modifiers: Ctrl+Shift+E and Ctrl+E both send 0x05, Shift+Tab and Alt+Tab collide with other keys, and so on. Applications ask for xterm modifyOtherKeys level 2 to tell them apart, and neither core tracked or reported it.

Changes

  • Both cores track level 2: CSI > 4 ; 2 m enables it; any other valid CSI > Pp m, CSI > n or RIS leaves it; CSI ? 4 m reports it. The Ghostty wrapper answers the query, which upstream ignores.
  • TerminalCore.modifyOtherKeys() (optional) exposes the level.
  • With level 2 active and Kitty keyboard mode not negotiated, keys whose legacy encoding loses a modifier are sent as CSI 27 ; modifier ; code ~. Like xterm, Ctrl+letter is encoded too: Vim confirms level 2 with the query and then stops reading raw control bytes. Other keys keep their legacy encoding; Meta stays with the browser.
  • e2e (e2e/harness/tests/modify-other-keys.spec.ts, both cores, Chromium, Firefox and WebKit): Vim in a real PTY negotiates level 2, maps Ctrl+Shift+E apart from Ctrl+E, and returns to legacy input on quit.
  • Docs: keyboard input in the vanilla guide and DOM README, the core method in the API reference.

Fixes LABS-91.

Visual proof

Vim with <C-S-e> and <C-e> mapped apart, after pressing Ctrl+Shift+E.

Before, it arrives as Ctrl+E:

After:

Activity

5
vercel[bot]4d ago

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated
wterm ReadyPreview, v0Oct 27, 2026 1:49am UTC
vercel[bot]reviewed4d ago