Make disabling the Kitty Keyboard Protocol possible (#19995)

Avoid translating W32IM sequences to KKP.

Closes #19977

## Validation Steps Performed
* Use French Bepo keyboard layout
* Disable KKP
* Use fish shell
* `AltGr+Y` produces `{` 
This commit is contained in:
Leonard Hecker
2026-03-19 21:42:15 +01:00
committed by GitHub
parent ad7b34e55f
commit 0f5d883c59
8 changed files with 43 additions and 1 deletions

View File

@@ -132,6 +132,7 @@ public:
#pragma region ITerminalApi
// These methods are defined in TerminalApi.cpp
void ReturnResponse(const std::wstring_view response) override;
bool IsConPTY() const noexcept override;
Microsoft::Console::VirtualTerminal::StateMachine& GetStateMachine() noexcept override;
BufferState GetBufferAndViewport() noexcept override;
void SetViewportPosition(const til::point position) noexcept override;

View File

@@ -28,6 +28,11 @@ void Terminal::ReturnResponse(const std::wstring_view response)
}
}
bool Terminal::IsConPTY() const noexcept
{
return false;
}
Microsoft::Console::VirtualTerminal::StateMachine& Terminal::GetStateMachine() noexcept
{
return *_stateMachine;

View File

@@ -48,6 +48,12 @@ void ConhostInternalGetSet::ReturnResponse(const std::wstring_view response)
_io.GetActiveInputBuffer()->WriteString(response);
}
bool ConhostInternalGetSet::IsConPTY() const noexcept
{
const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
return gci.IsInVtIoMode();
}
// Routine Description:
// - Retrieves the state machine for the active output buffer.
// Arguments:

View File

@@ -31,6 +31,7 @@ public:
void ReturnResponse(const std::wstring_view response) override;
bool IsConPTY() const noexcept override;
Microsoft::Console::VirtualTerminal::StateMachine& GetStateMachine() override;
BufferState GetBufferAndViewport() override;
void SetViewportPosition(const til::point position) override;

View File

@@ -46,6 +46,7 @@ namespace Microsoft::Console::VirtualTerminal
bool isMainBuffer;
};
virtual bool IsConPTY() const noexcept = 0;
virtual StateMachine& GetStateMachine() = 0;
virtual BufferState GetBufferAndViewport() = 0;
virtual void SetViewportPosition(const til::point position) = 0;

View File

@@ -2073,6 +2073,13 @@ void AdaptDispatch::SetAnsiMode(const bool ansiMode)
// CSI = flags ; mode u - Sets kitty keyboard protocol flags
void AdaptDispatch::SetKittyKeyboardProtocol(const VTParameter flags, const VTParameter mode) noexcept
{
// Avoid setting KKP flags in `_terminalInput` when we're ConPTY. Otherwise, we'd be translating
// W32IM to KKP, even when KKP is not supported by the hosting terminal (possibly intentionally).
if (_api.IsConPTY())
{
return;
}
const auto kittyFlags = gsl::narrow_cast<uint8_t>(flags.value_or(0));
const auto KittyKeyboardProtocol = static_cast<TerminalInput::KittyKeyboardProtocolMode>(mode.value_or(1));
_terminalInput.SetKittyKeyboardProtocol(kittyFlags, KittyKeyboardProtocol);
@@ -2081,6 +2088,11 @@ void AdaptDispatch::SetKittyKeyboardProtocol(const VTParameter flags, const VTPa
// CSI ? u - Queries current kitty keyboard protocol flags
void AdaptDispatch::QueryKittyKeyboardProtocol()
{
if (_api.IsConPTY())
{
return;
}
const auto flags = static_cast<VTInt>(_terminalInput.GetKittyFlags());
_ReturnCsiResponse(fmt::format(FMT_COMPILE(L"?{}u"), flags));
}
@@ -2088,6 +2100,11 @@ void AdaptDispatch::QueryKittyKeyboardProtocol()
// CSI > flags u - Pushes current kitty keyboard flags onto the stack and sets new flags
void AdaptDispatch::PushKittyKeyboardProtocol(const VTParameter flags)
{
if (_api.IsConPTY())
{
return;
}
const auto kittyFlags = gsl::narrow_cast<uint8_t>(flags.value_or(0));
_terminalInput.PushKittyFlags(kittyFlags);
}
@@ -2095,6 +2112,11 @@ void AdaptDispatch::PushKittyKeyboardProtocol(const VTParameter flags)
// CSI < count u - Pops one or more entries from the kitty keyboard stack
void AdaptDispatch::PopKittyKeyboardProtocol(const VTParameter count)
{
if (_api.IsConPTY())
{
return;
}
const auto popCount = static_cast<size_t>(count.value_or(1));
_terminalInput.PopKittyFlags(popCount);
}

View File

@@ -76,6 +76,11 @@ public:
}
}
bool IsConPTY() const noexcept override
{
return false;
}
StateMachine& GetStateMachine() override
{
return *_stateMachine;

View File

@@ -228,7 +228,8 @@ TerminalInput::OutputType TerminalInput::HandleKey(const INPUT_RECORD& event)
// GH#4999 - If we're in win32-input mode, skip straight to doing that.
// Since this mode handles all types of key events, do nothing else.
//
// The kitty keyboard protocol takes precedence, because it's cross-platform.
// ConPTY assumes that W32IM always remains enabled. We have to prefer
// the kitty keyboard protocol, because otherwise it would never be used.
if (_inputMode.test(Mode::Win32) && !_forceDisableWin32InputMode && !_kittyFlags)
{
return _makeWin32Output(event.Event.KeyEvent);