From cb3bab4ea8fb71d1a6080de9986f4296c0db4e7a Mon Sep 17 00:00:00 2001 From: James Holderness Date: Mon, 23 Mar 2020 13:00:59 +0000 Subject: [PATCH] Fix the Alternate Scroll Mode when DECCKM enabled (#5081) ## Summary of the Pull Request If the _Alternate Scroll Mode_ is enabled, the terminal generates up/down keystrokes when the mouse wheel is scrolled. However, the expected escape sequences for those keys are dependent on the state of the _Cursor Keys Mode_ ( `DECCKM`), but we haven't taken that into account. This PR updates the alternate scroll implementation to make sure the appropriate sequences are sent for both `DECCKM` modes. ## References #3321 ## PR Checklist * [ ] Closes #xxx * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [x] Tests added/passed * [ ] Requires documentation to be updated * [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx ## Detailed Description of the Pull Request / Additional comments I've simply added a condition in the `TerminalInput::_SendAlternateScroll` method to send a different pair of sequences dependent on the state of `_cursorApplicationMode` flag. ## Validation Steps Performed Manually tested in VIM (although that required me enabling the _Alternate Scroll Mode_ myself first). Also added a new unit test in `MouseInputTest` to confirm the correct sequences were generated for both `DECCKM` modes. --- .../adapter/ut_adapter/MouseInputTest.cpp | 40 +++++++++++++++++++ src/terminal/input/mouseInput.cpp | 6 ++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/terminal/adapter/ut_adapter/MouseInputTest.cpp b/src/terminal/adapter/ut_adapter/MouseInputTest.cpp index c8823e9097e..e740467cc5a 100644 --- a/src/terminal/adapter/ut_adapter/MouseInputTest.cpp +++ b/src/terminal/adapter/ut_adapter/MouseInputTest.cpp @@ -593,4 +593,44 @@ class MouseInputTest NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } } + + TEST_METHOD(AlternateScrollModeTests) + { + Log::Comment(L"Starting test..."); + std::unique_ptr mouseInput = std::make_unique(s_MouseInputTestCallback); + const short noModifierKeys = 0; + + Log::Comment(L"Enable alternate scroll mode in the alt screen buffer"); + mouseInput->UseAlternateScreenBuffer(); + mouseInput->EnableAlternateScroll(true); + + Log::Comment(L"Test mouse wheel scrolling up"); + s_pwszInputExpected = L"\x1B[A"; + VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, 1)); + + Log::Comment(L"Test mouse wheel scrolling down"); + s_pwszInputExpected = L"\x1B[B"; + VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, -1)); + + Log::Comment(L"Enable cursor keys mode"); + mouseInput->ChangeCursorKeysMode(true); + + Log::Comment(L"Test mouse wheel scrolling up"); + s_pwszInputExpected = L"\x1BOA"; + VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, 1)); + + Log::Comment(L"Test mouse wheel scrolling down"); + s_pwszInputExpected = L"\x1BOB"; + VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, -1)); + + Log::Comment(L"Confirm no effect when scroll mode is disabled"); + mouseInput->UseAlternateScreenBuffer(); + mouseInput->EnableAlternateScroll(false); + VERIFY_IS_FALSE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, 1)); + + Log::Comment(L"Confirm no effect when using the main buffer"); + mouseInput->UseMainScreenBuffer(); + mouseInput->EnableAlternateScroll(true); + VERIFY_IS_FALSE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, 1)); + } }; diff --git a/src/terminal/input/mouseInput.cpp b/src/terminal/input/mouseInput.cpp index 769b6405ff4..c215c810146 100644 --- a/src/terminal/input/mouseInput.cpp +++ b/src/terminal/input/mouseInput.cpp @@ -19,6 +19,8 @@ static constexpr short KeyPressed{ gsl::narrow_cast(0x8000) }; // Alternate scroll sequences static constexpr std::wstring_view CursorUpSequence{ L"\x1b[A" }; static constexpr std::wstring_view CursorDownSequence{ L"\x1b[B" }; +static constexpr std::wstring_view ApplicationUpSequence{ L"\x1bOA" }; +static constexpr std::wstring_view ApplicationDownSequence{ L"\x1bOB" }; // Routine Description: // - Determines if the input windows message code describes a button event @@ -523,11 +525,11 @@ bool TerminalInput::_SendAlternateScroll(const short delta) const noexcept { if (delta > 0) { - _SendInputSequence(CursorUpSequence); + _SendInputSequence(_cursorApplicationMode ? ApplicationUpSequence : CursorUpSequence); } else { - _SendInputSequence(CursorDownSequence); + _SendInputSequence(_cursorApplicationMode ? ApplicationDownSequence : CursorDownSequence); } return true; }