diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index b71471fc7ef..7f106ba1f90 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -430,6 +430,19 @@ bool Terminal::SendKeyEvent(const WORD vkey, _StoreKeyEvent(vkey, scanCode); + // As a Terminal we're mostly interested in getting key events from physical hardware (mouse & keyboard). + // We're thus ignoring events whose values are outside the valid range and unlikely to be generated by the current keyboard. + // It's very likely that a proper followup character event will be sent to us. + // This prominently happens using AutoHotKey's keyboard remapping feature, + // which sends input events whose vkey is 0xff and scanCode is 0. + // We need to check for this early, as _CharacterFromKeyEvent() always returns 0 for such invalid values, + // making us believe that this is an actual non-character input, while it usually isn't. + // GH#7064 + if (vkey == 0 || vkey >= 0xff || scanCode == 0) + { + return false; + } + const auto isAltOnlyPressed = states.IsAltPressed() && !states.IsCtrlPressed(); const auto isSuppressedAltGrAlias = !_altGrAliasing && states.IsAltPressed() && states.IsCtrlPressed(); diff --git a/src/cascadia/UnitTests_TerminalCore/InputTest.cpp b/src/cascadia/UnitTests_TerminalCore/InputTest.cpp index 037c81db45b..9745b0e6b2d 100644 --- a/src/cascadia/UnitTests_TerminalCore/InputTest.cpp +++ b/src/cascadia/UnitTests_TerminalCore/InputTest.cpp @@ -30,6 +30,7 @@ namespace TerminalCoreUnitTests TEST_METHOD(AltShiftKey); TEST_METHOD(AltSpace); + TEST_METHOD(InvalidKeyEvent); void _VerifyExpectedInput(std::wstring& actualInput) { @@ -65,4 +66,14 @@ namespace TerminalCoreUnitTests VERIFY_IS_FALSE(term.SendKeyEvent(L' ', 0, ControlKeyStates::LeftAltPressed, false)); VERIFY_IS_FALSE(term.SendCharEvent(L' ', 0, ControlKeyStates::LeftAltPressed)); } + + void InputTest::InvalidKeyEvent() + { + // Certain applications like AutoHotKey and its keyboard remapping feature, + // send us key events using SendInput() whose values are outside of the valid range. + // We don't want to handle those events as we're probably going to get a proper followup character event. + VERIFY_IS_FALSE(term.SendKeyEvent(0, 123, {}, true)); + VERIFY_IS_FALSE(term.SendKeyEvent(255, 123, {}, true)); + VERIFY_IS_FALSE(term.SendKeyEvent(123, 0, {}, true)); + } }