Fix(terminal): Resolved numpad keys reporting 'Unidentified' in TUI apps (Chromium 142 regression)#299408
Open
Ammar2123 wants to merge 2 commits intomicrosoft:mainfrom
Open
Fix(terminal): Resolved numpad keys reporting 'Unidentified' in TUI apps (Chromium 142 regression)#299408Ammar2123 wants to merge 2 commits intomicrosoft:mainfrom
Ammar2123 wants to merge 2 commits intomicrosoft:mainfrom
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes an Electron 39 / Chromium 142 regression where numpad KeyboardEvent.key becomes "Unidentified" in the integrated terminal, causing xterm.js Kitty keyboard protocol (CSI u) handling to drop numpad input for TUI apps.
Changes:
- Add a terminal-level workaround that repairs
"Unidentified"numpadKeyboardEvent.keyvalues before xterm.js processes the event. - Introduce an exported
resolveNumpadKey(code, numLockOn, decimalValue?)helper used to map numpadcode→ correctkey. - Add unit tests covering the new
resolveNumpadKeymapping behavior.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/vs/workbench/contrib/terminal/browser/terminalInstance.ts |
Injects IKeyboardLayoutService, patches numpad KeyboardEvent.key, and adds exported resolveNumpadKey mapping utility. |
src/vs/workbench/contrib/terminal/test/browser/terminalInstance.test.ts |
Adds unit tests validating numpad code→key resolution across NumLock/layout scenarios. |
Workaround for Chromium 142+ regression (chromium issue 405793116) where numpad KeyboardEvent.key is reported as "Unidentified", breaking xterm.js Kitty keyboard protocol handling used by TUI apps. Changes: - Inject IKeyboardLayoutService into TerminalInstance for locale-aware NumpadDecimal resolution (e.g. ',' on German layouts) - Add pre-xterm key event handler that detects 'Unidentified' numpad events and restores the correct key value from event.code - Create a derived KeyboardEvent for local dispatch instead of relying solely on mutating the original event - Patch the original event via Object.defineProperty so xterm.js also sees the corrected key after the handler returns - Extract resolveNumpadKey() as an exported pure function for testability - Add 6 unit tests covering operators, digits (NumLock on/off), locale- aware decimal, and unknown code handling
Workaround for Chromium 142+ regression (chromium issue 405793116) where numpad KeyboardEvent.key is reported as "Unidentified", breaking xterm.js Kitty keyboard protocol handling used by TUI apps. Changes: - Inject IKeyboardLayoutService into TerminalInstance for locale-aware NumpadDecimal resolution (e.g. ',' on German layouts) - Add pre-xterm key event handler that detects 'Unidentified' numpad events and restores the correct key value from event.code - Create a derived KeyboardEvent for local dispatch instead of relying solely on mutating the original event - Patch the original event via Object.defineProperty so xterm.js also sees the corrected key after the handler returns - Extract resolveNumpadKey() as an exported pure function for testability - Add 6 unit tests covering operators, digits (NumLock on/off), locale- aware decimal, and unknown code handling
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #299374
Summary
Numpad keys (0–9, Enter, Decimal, and operators) are completely ignored by
terminal TUI applications that activate the Kitty keyboard protocol (CSI u /
enhanced keyboard mode) — such as OpenCode, bubbletea-based, and opentui-based
apps — when running inside VS Code 1.110.0's integrated terminal.
The regression was introduced by Electron 39 / Chromium 142 (chromium issue
405793116), which causes numpad
KeyboardEventobjects to reportkey: "Unidentified"instead of the correct key value (e.g."5","Enter","+").Root Cause
Two-path keyboard handling in xterm.js:
keydown→ no match →keypress/inputevent fallback sends textkeydown→ xterm.js must produce a CSI u escape sequenceev.keyfor identity — gets"Unidentified"→ drops the eventWhen a TUI app activates the Kitty keyboard protocol, xterm.js's
KittyKeyboard.evaluate()must produce structured escape sequences (e.g.\x1b[57404ufor Numpad5). Whenev.key === "Unidentified"the key cannot beidentified,
result.keyis left undefined, and the TUI app receives nothing.The
keypressfallback path that saves normal shell input is NOT used in Kittymode, so strokes are silently dropped.
The
event.codeproperty ("Numpad0"–"Numpad9","NumpadAdd","NumpadEnter", etc.) is not affected by the Chromium regression andreliably identifies numpad keys.
Fix
In
terminalInstance.ts, inside theattachCustomKeyEventHandlercallbackthat runs before xterm.js evaluates any event:
event.key === 'Unidentified' && event.code.startsWith('Numpad')resolveNumpadKey(), respecting NumLock stateand the active keyboard layout (via
IKeyboardLayoutService)Object.defineProperty) so xterm.js sees thecorrected key when it processes the event after the handler returns
KeyboardEventwith the corrected key for localStandardKeyboardEventdispatch, avoiding sole reliance on mutationKey mapping (
resolveNumpadKey)Numpad0–Numpad9→"0"–"9",NumpadDecimal→ locale-aware(e.g.
"."for US,","for German — resolved viaIKeyboardLayoutService.getRawKeyboardMapping())Numpad0–Numpad9→ navigation keys (Insert,End,ArrowDown, …),NumpadDecimal→"Delete"NumpadAdd→"+",NumpadSubtract→"-",NumpadMultiply→"*",NumpadDivide→"/",NumpadEnter→"Enter",NumpadEqual→"="Design decisions
IKeyboardLayoutServiceinjection — needed for locale-awareNumpadDecimalresolution;
getRawKeyboardMapping()?.['NumpadDecimal']?.valuereturns thelayout-correct character with
'.'as fallback via??resolveNumpadKey(code, numLockOn, decimalValue?)is extracted as an exported function for direct unit testing without needing
a full
TerminalInstanceObject.definePropertyon the original event (forxterm.js) and a new
KeyboardEvent(for localStandardKeyboardEventdispatch) to avoid relying on property mutation alone
Testing
VS Code - Buildwatch task ✅ (0 errors)terminalInstance.test.ts✅ (all passing)NumpadDecimal→ locale-aware value when NumLock ON (US., German,)NumpadDecimal→Deletewhen NumLock OFF (locale does not affect this)undefinedcorrectly produce input in VS Code integrated terminal
Changed Files
src/vs/workbench/contrib/terminal/browser/terminalInstance.ts_resolveNumpadKeywrapper, exportedresolveNumpadKeypure functionsrc/vs/workbench/contrib/terminal/test/browser/terminalInstance.test.tsresolveNumpadKey