| Rewrite TerminalInput key handling around a new Kitty-aware encoding pipeline that prefers KKP over Win32/legacy VT and unifies surrogate, modifier, and keypad handling. |
- Introduce SanitizedKeyEvent, KeyboardHelper, EncodingHelper, and several helper methods to normalize KEY_EVENT_RECORDs, query layout text via ToUnicodeEx, and build CSI/SS3/plain sequences.
- Add Kitty keyboard protocol flags and stack state to TerminalInput, including enabling/disabling KKP, pushing/popping flag stacks per main/alternate buffer, and integrating buffer switches into that state.
- Replace the keymap-based _initKeyboardMap and legacy key->sequence lookup with logic that encodes Kitty CSI u sequences when enabled and otherwise falls back to a regular VT/VT52 encoder plus a keyboard-layout-based fallback mapper.
- Update HandleKey to prioritize KKP (when flags are non-zero), support event-type reporting, repeat detection, Alt-Numpad composition, surrogate pairing, and to emit correct sequences for Enter/Tab/Backspace, modifiers, and keypad keys.
- Refactor _makeCtrlChar, character output, and Ctrl/Alt handling to operate on Unicode codepoints and centralized helpers instead of scattered logic.
|
src/terminal/input/terminalInput.cpp
src/terminal/input/terminalInput.hpp
src/terminal/input/sources.inc
src/terminal/input/lib/terminalinput.vcxproj
src/terminal/input/mouseInput.cpp |
| Add full VT parser/dispatch support for Kitty Keyboard Protocol CSI u control sequences and integrate them with AdaptDispatch and TermDispatch. |
- Extend CsiActionCodes with new KKP_* entries for setting, querying, pushing, and popping Kitty keyboard flags.
- Wire OutputStateMachineEngine::ActionCsiDispatch to call new ITermDispatch KKP methods.
- Extend ITermDispatch, AdaptDispatch, and TermDispatch with SetKittyKeyboardProtocol, QueryKittyKeyboardProtocol, PushKittyKeyboardProtocol, and PopKittyKeyboardProtocol implementations, including DECANM refactor placement.
- Ensure AdaptDispatch manipulates TerminalInput’s KKP state via the new APIs and returns appropriate CSI responses from QueryKittyKeyboardProtocol.
|
src/terminal/parser/OutputStateMachineEngine.hpp
src/terminal/parser/OutputStateMachineEngine.cpp
src/terminal/adapter/ITermDispatch.hpp
src/terminal/adapter/adaptDispatch.hpp
src/terminal/adapter/adaptDispatch.cpp
src/terminal/adapter/termDispatch.hpp |
| Expose configuration and host toggles for Kitty Keyboard Protocol in Terminal and ConPTY, and temporarily disable KKP behind ConPTY to avoid double-translation. |
- Add AllowKittyKeyboardMode profile/ICoreSettings property, wire it through Terminal settings model, view model, and XAML editor, with default enabled and compatibility namespace wiring.
- Update Terminal::UpdateSettings to disable Kitty Keyboard Protocol in TerminalInput when the profile disallows it.
- Modify VtIo initialization to forcibly disable Kitty Keyboard Protocol on the server side input buffer to prevent ConPTY from translating Win32 input to KKP while Terminal is still stabilizing the feature (GH#19847).
|
src/cascadia/TerminalCore/Terminal.cpp
src/cascadia/TerminalCore/ICoreSettings.idl
src/cascadia/TerminalSettingsModel/MTSMSettings.h
src/cascadia/TerminalSettingsModel/Profile.idl
src/cascadia/TerminalSettingsAppAdapterLib/TerminalSettings.cpp
src/cascadia/TerminalSettingsEditor/ProfileViewModel.h
src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl
src/cascadia/TerminalSettingsEditor/Profiles_Terminal.xaml
src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw
src/cascadia/inc/ControlProperties.h
src/host/VtIo.cpp |
| Refactor TAEF data source boilerplate into a shared helper and reuse it in existing test suites. |
- Introduce shared ArrayIndexTaefAdapterRow and ArrayIndexTaefAdapterSource implementations in consoletaeftemplates.hpp to adapt index-based test arrays into IDataSource/IDataRow.
- Replace duplicated anonymous namespace adapter implementations in UiaTextRangeTests and ReflowTests with uses of the shared helpers.
- Include IDataSource.h in consoletaeftemplates.hpp and adjust test data source exports to construct ArrayIndexTaefAdapterSource with the correct size.
|
src/inc/consoletaeftemplates.hpp
src/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cpp
src/buffer/out/ut_textbuffer/ReflowTests.cpp |
| Add a comprehensive KKP unit test suite to validate Kitty Keyboard Protocol encoding of keys, modifiers, event types, keypad behavior, and alternate/associated text. |
- Create kittyKeyboardProtocol.cpp test file that constructs TerminalInput with various KKP flag combinations and feeds synthetic KEY_EVENT_RECORDs through HandleKey.
- Define a large parameterized test table of expected CSI u sequences for common and edge-case key combinations (text keys, modifiers, Enter/Tab/Backspace, keypad, navigation, media, and lock keys).
- Add additional tests that specifically exercise key repeat semantics, repeat reset behavior, and repeat under modifiers.
- Wire the new test file into the adapter unit test project and filters, and add a TAEF data source export (KittyKeyTestDataSource) using the shared ArrayIndexTaefAdapterSource helper.
|
src/terminal/adapter/ut_adapter/kittyKeyboardProtocol.cpp
src/terminal/adapter/ut_adapter/Adapter.UnitTests.vcxproj
src/terminal/adapter/ut_adapter/Adapter.UnitTests.vcxproj.filters
src/terminal/adapter/ut_adapter/sources |
Reviewer's Guide
Rewrites TerminalInput’s key handling to implement the Kitty Keyboard Protocol (KKP) on top of a new, shared encoding pipeline, wires new CSI u KKP control sequences through the VT parser/dispatch, adds settings and toggles in Terminal/ConPTY, and centralizes TAEF data-source helpers, with comprehensive unit tests verifying KKP behavior.
Updated class diagram for TerminalInput and Kitty keyboard protocol
classDiagram class TerminalInput { +TerminalInput() +UseAlternateScreenBuffer() void +UseMainScreenBuffer() void +SetInputMode(Mode mode, bool enabled) void +GetInputMode(Mode mode) bool +ResetInputModes() void +ForceDisableWin32InputMode(bool win32InputMode) void +ForceDisableKittyKeyboardProtocol(bool disable) void +SetKittyKeyboardProtocol(uint8_t flags, KittyKeyboardProtocolMode mode) void +GetKittyFlags() uint8_t +PushKittyFlags(uint8_t flags) void +PopKittyFlags(size_t count) void +ResetKittyKeyboardProtocols() void +HandleKey(INPUT_RECORD event) OutputType +HandleFocus(bool focused) OutputType +_makeWin32Output(KEY_EVENT_RECORD key) OutputType -_encodeKitty(KeyboardHelper kbd, EncodingHelper enc, SanitizedKeyEvent key) bool -_encodeRegular(EncodingHelper enc, SanitizedKeyEvent key) void -_formatEncodingHelper(EncodingHelper enc, wstring seq) bool -_formatFallback(KeyboardHelper kbd, EncodingHelper enc, SanitizedKeyEvent key, wstring seq) void -_stringPushCodepoint(wstring str, uint32_t cp) void -_codepointToLower(uint32_t cp) uint32_t -_trackControlKeyState(KEY_EVENT_RECORD key) DWORD -_initKeyboardMap() void -_leadingSurrogate wchar_t -_lastVirtualKeyCode optional~WORD~ -_lastControlKeyState DWORD -_lastLeftCtrlTime uint64_t -_lastRightAltTime uint64_t -_inputMode enumset~Mode~ -_forceDisableWin32InputMode bool -_inAlternateBuffer bool -KittyStackMaxSize size_t -_forceDisableKittyKeyboardProtocol bool -_kittyFlags uint8_t -_kittyMainStack vector~uint8_t~ -_kittyAltStack vector~uint8_t~ -_csi wstring_view -_ss3 wstring_view -_focusInSequence wstring_view -_focusOutSequence wstring_view } class KittyKeyboardProtocolFlags { <<struct>> +None uint8_t +DisambiguateEscapeCodes uint8_t +ReportEventTypes uint8_t +ReportAlternateKeys uint8_t +ReportAllKeysAsEscapeCodes uint8_t +ReportAssociatedText uint8_t +All uint8_t } class KittyKeyboardProtocolMode { <<enum>> Replace Set Reset } class SanitizedKeyEvent { <<struct>> +virtualKey uint16_t +scanCode uint16_t +codepoint uint32_t +controlKeyState uint32_t +leftCtrlIsReallyPressed bool +keyDown bool +keyRepeat bool +anyAltPressed() bool +bothAltPressed() bool +rightAltPressed() bool +bothCtrlPressed() bool +altGrPressed() bool } class KeyboardHelper { <<struct>> +KeyboardHelper() +getUnmodifiedKeyboardKey(SanitizedKeyEvent key) uint32_t +getKittyBaseKey(SanitizedKeyEvent key) uint32_t +getKittyShiftedKey(SanitizedKeyEvent key) uint32_t +getKittyUSBaseKey(SanitizedKeyEvent key) uint32_t -getKeyboardKey(UINT vkey, DWORD controlKeyState, HKL hkl) uint32_t -init() void -initSlow() void -_initialized bool -_keyboardLayout HKL -_keyboardState uint8_t[256] } class EncodingHelper { <<struct>> +EncodingHelper() +shiftPressed() bool +altPressed() bool +ctrlPressed() bool +csiUnicodeKeyCode uint32_t +csiAltKeyCodeShifted uint32_t +csiAltKeyCodeBase uint32_t +csiModifier uint32_t +csiEventType uint32_t +csiTextAsCodepoint uint32_t +csiFinal wchar_t +ss3Final wchar_t +altPrefix bool +plain wstring_view } class CodepointBuffer { <<struct>> +CodepointBuffer() +CodepointBuffer(uint32_t cp) +convertLowercase() void +asSingleCodepoint() uint32_t +buf wchar_t[4] +len int } class ITermDispatch { <<interface>> +SetKittyKeyboardProtocol(VTParameter flags, VTParameter mode) void +QueryKittyKeyboardProtocol() void +PushKittyKeyboardProtocol(VTParameter flags) void +PopKittyKeyboardProtocol(VTParameter count) void } class AdaptDispatch { +SetKittyKeyboardProtocol(VTParameter flags, VTParameter mode) void +QueryKittyKeyboardProtocol() void +PushKittyKeyboardProtocol(VTParameter flags) void +PopKittyKeyboardProtocol(VTParameter count) void -_terminalInput TerminalInput } TerminalInput *-- KittyKeyboardProtocolFlags TerminalInput *-- KittyKeyboardProtocolMode TerminalInput *-- SanitizedKeyEvent TerminalInput *-- KeyboardHelper TerminalInput *-- EncodingHelper TerminalInput *-- CodepointBuffer AdaptDispatch ..|> ITermDispatch AdaptDispatch o--> TerminalInputFile-Level Changes
src/terminal/input/terminalInput.cppsrc/terminal/input/terminalInput.hppsrc/terminal/input/sources.incsrc/terminal/input/lib/terminalinput.vcxprojsrc/terminal/input/mouseInput.cppsrc/terminal/parser/OutputStateMachineEngine.hppsrc/terminal/parser/OutputStateMachineEngine.cppsrc/terminal/adapter/ITermDispatch.hppsrc/terminal/adapter/adaptDispatch.hppsrc/terminal/adapter/adaptDispatch.cppsrc/terminal/adapter/termDispatch.hppsrc/cascadia/TerminalCore/Terminal.cppsrc/cascadia/TerminalCore/ICoreSettings.idlsrc/cascadia/TerminalSettingsModel/MTSMSettings.hsrc/cascadia/TerminalSettingsModel/Profile.idlsrc/cascadia/TerminalSettingsAppAdapterLib/TerminalSettings.cppsrc/cascadia/TerminalSettingsEditor/ProfileViewModel.hsrc/cascadia/TerminalSettingsEditor/ProfileViewModel.idlsrc/cascadia/TerminalSettingsEditor/Profiles_Terminal.xamlsrc/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.reswsrc/cascadia/inc/ControlProperties.hsrc/host/VtIo.cppsrc/inc/consoletaeftemplates.hppsrc/interactivity/win32/ut_interactivity_win32/UiaTextRangeTests.cppsrc/buffer/out/ut_textbuffer/ReflowTests.cppsrc/terminal/adapter/ut_adapter/kittyKeyboardProtocol.cppsrc/terminal/adapter/ut_adapter/Adapter.UnitTests.vcxprojsrc/terminal/adapter/ut_adapter/Adapter.UnitTests.vcxproj.filterssrc/terminal/adapter/ut_adapter/sourcesTips and commands
Interacting with Sourcery
@sourcery-ai reviewon the pull request.issue from a review comment by replying to it. You can also reply to a
review comment with
@sourcery-ai issueto create an issue from it.@sourcery-aianywhere in the pullrequest title to generate a title at any time. You can also comment
@sourcery-ai titleon the pull request to (re-)generate the title at any time.@sourcery-ai summaryanywhere inthe pull request body to generate a PR summary at any time exactly where you
want it. You can also comment
@sourcery-ai summaryon the pull request to(re-)generate the summary at any time.
@sourcery-ai guideon the pullrequest to (re-)generate the reviewer's guide at any time.
@sourcery-ai resolveon thepull request to resolve all Sourcery comments. Useful if you've already
addressed all the comments and don't want to see them anymore.
@sourcery-ai dismisson the pullrequest to dismiss all existing Sourcery reviews. Especially useful if you
want to start fresh with a new review - don't forget to comment
@sourcery-ai reviewto trigger a new review!Customizing Your Experience
Access your dashboard to:
summary, the reviewer's guide, and others.
Getting Help
Originally posted by @sourcery-ai[bot] in #7 (comment)