From 315abf6fa6e096f0ad8ba7db68fa8a3fd9a591b1 Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Fri, 14 Jun 2019 17:00:46 -0500 Subject: [PATCH] Don't always send an uppercase letter for Alt+key (#1259) * Don't always send an uppercase letter for Alt+key Fix #637. Also add a test. * runformat * Use `towlower` instead of just subtracting 32. --- src/cascadia/TerminalCore/Terminal.cpp | 13 +++- .../UnitTests_TerminalCore/InputTest.cpp | 66 +++++++++++++++++++ .../UnitTests_TerminalCore/UnitTests.vcxproj | 3 +- 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 src/cascadia/UnitTests_TerminalCore/InputTest.cpp diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 006ee1e506..dbd4c8044c 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -223,7 +223,18 @@ bool Terminal::SendKeyEvent(const WORD vkey, // KeyEvent. // DON'T manually handle Alt+Space - the system will use this to bring up // the system menu for restore, min/maximimize, size, move, close - wchar_t ch = altPressed && vkey != VK_SPACE ? static_cast(LOWORD(MapVirtualKey(vkey, MAPVK_VK_TO_CHAR))) : UNICODE_NULL; + wchar_t ch = UNICODE_NULL; + if (altPressed && vkey != VK_SPACE) + { + ch = static_cast(LOWORD(MapVirtualKey(vkey, MAPVK_VK_TO_CHAR))); + // MapVirtualKey will give us the capitalized version of the char. + // However, if shift isn't pressed, we want to send the lowercase version. + // (See GH#637) + if (!shiftPressed) + { + ch = towlower(ch); + } + } // Manually handle Ctrl+H. Ctrl+H should be handled as Backspace. To do this // correctly, the keyEvents's char needs to be set to Backspace. diff --git a/src/cascadia/UnitTests_TerminalCore/InputTest.cpp b/src/cascadia/UnitTests_TerminalCore/InputTest.cpp new file mode 100644 index 0000000000..9fa0a51b8a --- /dev/null +++ b/src/cascadia/UnitTests_TerminalCore/InputTest.cpp @@ -0,0 +1,66 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#include "precomp.h" +#include + +#include "../cascadia/TerminalCore/Terminal.hpp" +#include "../renderer/inc/DummyRenderTarget.hpp" +#include "consoletaeftemplates.hpp" + +using namespace WEX::Logging; +using namespace WEX::TestExecution; + +using namespace Microsoft::Terminal::Core; +using namespace Microsoft::Console::Render; + +namespace TerminalCoreUnitTests +{ + class InputTest + { + TEST_CLASS(InputTest); + TEST_CLASS_SETUP(ClassSetup) + { + DummyRenderTarget emptyRT; + term.Create({ 100, 100 }, 0, emptyRT); + auto inputFn = std::bind(&InputTest::_VerifyExpectedInput, this, std::placeholders::_1); + term.SetWriteInputCallback(inputFn); + return true; + }; + + TEST_METHOD(AltShiftKey); + TEST_METHOD(AltSpace); + + void _VerifyExpectedInput(std::wstring& actualInput) + { + VERIFY_ARE_EQUAL(expectedinput.size(), actualInput.size()); + VERIFY_ARE_EQUAL(expectedinput, actualInput); + }; + + Terminal term{}; + std::wstring expectedinput{}; + }; + + void InputTest::AltShiftKey() + { + // Tests GH:637 + + // Verify that Alt+a generates a lowercase a on the input + expectedinput = L"\x1b" + "a"; + VERIFY_IS_TRUE(term.SendKeyEvent(L'A', false, true, false)); + + // Verify that Alt+shift+a generates a uppercase a on the input + expectedinput = L"\x1b" + "A"; + VERIFY_IS_TRUE(term.SendKeyEvent(L'A', false, true, true)); + } + + void InputTest::AltSpace() + { + // Make sure we don't handle Alt+Space. The system will use this to + // bring up the system menu for restore, min/maximimize, size, move, + // close + VERIFY_IS_FALSE(term.SendKeyEvent(L' ', false, true, false)); + } +} diff --git a/src/cascadia/UnitTests_TerminalCore/UnitTests.vcxproj b/src/cascadia/UnitTests_TerminalCore/UnitTests.vcxproj index be07732931..1e71d072cc 100644 --- a/src/cascadia/UnitTests_TerminalCore/UnitTests.vcxproj +++ b/src/cascadia/UnitTests_TerminalCore/UnitTests.vcxproj @@ -5,6 +5,7 @@ + Create @@ -49,4 +50,4 @@ - \ No newline at end of file +