diff --git a/src/cascadia/TerminalCore/ITerminalApi.hpp b/src/cascadia/TerminalCore/ITerminalApi.hpp index 24e484ddf..3f09cea8f 100644 --- a/src/cascadia/TerminalCore/ITerminalApi.hpp +++ b/src/cascadia/TerminalCore/ITerminalApi.hpp @@ -3,6 +3,7 @@ #pragma once #include "../../terminal/adapter/DispatchTypes.hpp" +#include "../../terminal/input/terminalInput.hpp" #include "../../buffer/out/TextAttribute.hpp" #include "../../types/inc/Viewport.hpp" @@ -47,16 +48,9 @@ namespace Microsoft::Terminal::Core virtual bool SetDefaultForeground(const DWORD color) noexcept = 0; virtual bool SetDefaultBackground(const DWORD color) noexcept = 0; - virtual bool EnableWin32InputMode(const bool win32InputMode) noexcept = 0; - virtual bool SetCursorKeysMode(const bool applicationMode) noexcept = 0; - virtual bool SetKeypadMode(const bool applicationMode) noexcept = 0; + virtual bool SetInputMode(const ::Microsoft::Console::VirtualTerminal::TerminalInput::Mode mode, const bool enabled) noexcept = 0; + virtual bool SetScreenMode(const bool reverseMode) noexcept = 0; - virtual bool EnableVT200MouseMode(const bool enabled) noexcept = 0; - virtual bool EnableUTF8ExtendedMouseMode(const bool enabled) noexcept = 0; - virtual bool EnableSGRExtendedMouseMode(const bool enabled) noexcept = 0; - virtual bool EnableButtonEventMouseMode(const bool enabled) noexcept = 0; - virtual bool EnableAnyEventMouseMode(const bool enabled) noexcept = 0; - virtual bool EnableAlternateScrollMode(const bool enabled) noexcept = 0; virtual bool EnableXtermBracketedPasteMode(const bool enabled) noexcept = 0; virtual bool IsXtermBracketedPasteModeEnabled() const = 0; diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 3a2f3dff1..5a7b08751 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -112,16 +112,9 @@ public: bool SetDefaultForeground(const COLORREF color) noexcept override; bool SetDefaultBackground(const COLORREF color) noexcept override; - bool EnableWin32InputMode(const bool win32InputMode) noexcept override; - bool SetCursorKeysMode(const bool applicationMode) noexcept override; - bool SetKeypadMode(const bool applicationMode) noexcept override; + bool SetInputMode(const ::Microsoft::Console::VirtualTerminal::TerminalInput::Mode mode, const bool enabled) noexcept override; + bool SetScreenMode(const bool reverseMode) noexcept override; - bool EnableVT200MouseMode(const bool enabled) noexcept override; - bool EnableUTF8ExtendedMouseMode(const bool enabled) noexcept override; - bool EnableSGRExtendedMouseMode(const bool enabled) noexcept override; - bool EnableButtonEventMouseMode(const bool enabled) noexcept override; - bool EnableAnyEventMouseMode(const bool enabled) noexcept override; - bool EnableAlternateScrollMode(const bool enabled) noexcept override; bool EnableXtermBracketedPasteMode(const bool enabled) noexcept override; bool IsXtermBracketedPasteModeEnabled() const noexcept override; diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp index 83c898e47..455851ac8 100644 --- a/src/cascadia/TerminalCore/TerminalApi.cpp +++ b/src/cascadia/TerminalCore/TerminalApi.cpp @@ -482,23 +482,13 @@ til::color Terminal::GetDefaultBackground() const noexcept return _defaultBg; } -bool Terminal::EnableWin32InputMode(const bool win32InputMode) noexcept +bool Terminal::SetInputMode(const TerminalInput::Mode mode, const bool enabled) noexcept +try { - _terminalInput->ChangeWin32InputMode(win32InputMode); - return true; -} - -bool Terminal::SetCursorKeysMode(const bool applicationMode) noexcept -{ - _terminalInput->ChangeCursorKeysMode(applicationMode); - return true; -} - -bool Terminal::SetKeypadMode(const bool applicationMode) noexcept -{ - _terminalInput->ChangeKeypadMode(applicationMode); + _terminalInput->SetInputMode(mode, enabled); return true; } +CATCH_RETURN_FALSE() bool Terminal::SetScreenMode(const bool reverseMode) noexcept try @@ -511,42 +501,6 @@ try } CATCH_RETURN_FALSE() -bool Terminal::EnableVT200MouseMode(const bool enabled) noexcept -{ - _terminalInput->EnableDefaultTracking(enabled); - return true; -} - -bool Terminal::EnableUTF8ExtendedMouseMode(const bool enabled) noexcept -{ - _terminalInput->SetUtf8ExtendedMode(enabled); - return true; -} - -bool Terminal::EnableSGRExtendedMouseMode(const bool enabled) noexcept -{ - _terminalInput->SetSGRExtendedMode(enabled); - return true; -} - -bool Terminal::EnableButtonEventMouseMode(const bool enabled) noexcept -{ - _terminalInput->EnableButtonEventTracking(enabled); - return true; -} - -bool Terminal::EnableAnyEventMouseMode(const bool enabled) noexcept -{ - _terminalInput->EnableAnyEventTracking(enabled); - return true; -} - -bool Terminal::EnableAlternateScrollMode(const bool enabled) noexcept -{ - _terminalInput->EnableAlternateScroll(enabled); - return true; -} - bool Terminal::EnableXtermBracketedPasteMode(const bool enabled) noexcept { _bracketedPasteMode = enabled; diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp index 725521f56..414291cb0 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.cpp @@ -321,9 +321,9 @@ CATCH_LOG_RETURN_FALSE() // - applicationMode - set to true to enable Application Mode Input, false for Numeric Mode Input. // Return Value: // - True if handled successfully. False otherwise. -bool TerminalDispatch::SetKeypadMode(const bool fApplicationMode) noexcept +bool TerminalDispatch::SetKeypadMode(const bool applicationMode) noexcept { - _terminalApi.SetKeypadMode(fApplicationMode); + _terminalApi.SetInputMode(TerminalInput::Mode::Keypad, applicationMode); return true; } @@ -334,7 +334,7 @@ bool TerminalDispatch::SetKeypadMode(const bool fApplicationMode) noexcept // - True if handled successfully. False otherwise. bool TerminalDispatch::SetCursorKeysMode(const bool applicationMode) noexcept { - _terminalApi.SetCursorKeysMode(applicationMode); + _terminalApi.SetInputMode(TerminalInput::Mode::CursorKey, applicationMode); return true; } @@ -359,7 +359,7 @@ bool TerminalDispatch::SetScreenMode(const bool reverseMode) noexcept // - True if handled successfully. False otherwise. bool TerminalDispatch::EnableWin32InputMode(const bool win32Mode) noexcept { - _terminalApi.EnableWin32InputMode(win32Mode); + _terminalApi.SetInputMode(TerminalInput::Mode::Win32, win32Mode); return true; } @@ -371,7 +371,7 @@ bool TerminalDispatch::EnableWin32InputMode(const bool win32Mode) noexcept // True if handled successfully. False otherwise. bool TerminalDispatch::EnableVT200MouseMode(const bool enabled) noexcept { - _terminalApi.EnableVT200MouseMode(enabled); + _terminalApi.SetInputMode(TerminalInput::Mode::DefaultMouseTracking, enabled); return true; } @@ -384,7 +384,7 @@ bool TerminalDispatch::EnableVT200MouseMode(const bool enabled) noexcept // True if handled successfully. False otherwise. bool TerminalDispatch::EnableUTF8ExtendedMouseMode(const bool enabled) noexcept { - _terminalApi.EnableUTF8ExtendedMouseMode(enabled); + _terminalApi.SetInputMode(TerminalInput::Mode::Utf8MouseEncoding, enabled); return true; } @@ -397,7 +397,7 @@ bool TerminalDispatch::EnableUTF8ExtendedMouseMode(const bool enabled) noexcept // True if handled successfully. False otherwise. bool TerminalDispatch::EnableSGRExtendedMouseMode(const bool enabled) noexcept { - _terminalApi.EnableSGRExtendedMouseMode(enabled); + _terminalApi.SetInputMode(TerminalInput::Mode::SgrMouseEncoding, enabled); return true; } @@ -409,7 +409,7 @@ bool TerminalDispatch::EnableSGRExtendedMouseMode(const bool enabled) noexcept // True if handled successfully. False otherwise. bool TerminalDispatch::EnableButtonEventMouseMode(const bool enabled) noexcept { - _terminalApi.EnableButtonEventMouseMode(enabled); + _terminalApi.SetInputMode(TerminalInput::Mode::ButtonEventMouseTracking, enabled); return true; } @@ -422,7 +422,7 @@ bool TerminalDispatch::EnableButtonEventMouseMode(const bool enabled) noexcept // True if handled successfully. False otherwise. bool TerminalDispatch::EnableAnyEventMouseMode(const bool enabled) noexcept { - _terminalApi.EnableAnyEventMouseMode(enabled); + _terminalApi.SetInputMode(TerminalInput::Mode::AnyEventMouseTracking, enabled); return true; } @@ -435,7 +435,7 @@ bool TerminalDispatch::EnableAnyEventMouseMode(const bool enabled) noexcept // True if handled successfully. False otherwise. bool TerminalDispatch::EnableAlternateScroll(const bool enabled) noexcept { - _terminalApi.EnableAlternateScrollMode(enabled); + _terminalApi.SetInputMode(TerminalInput::Mode::AlternateScroll, enabled); return true; } diff --git a/src/host/getset.cpp b/src/host/getset.cpp index c4e32b015..5ee114e6d 100644 --- a/src/host/getset.cpp +++ b/src/host/getset.cpp @@ -1248,55 +1248,6 @@ void ApiRoutines::GetConsoleDisplayModeImpl(ULONG& flags) noexcept CATCH_RETURN(); } -// Routine Description: -// - A private API call for changing the cursor keys input mode between normal and application mode. -// The cursor keys are the arrows, plus Home and End. -// Parameters: -// - fApplicationMode - set to true to enable Application Mode Input, false for Numeric Mode Input. -// Return value: -// - True if handled successfully. False otherwise. -[[nodiscard]] NTSTATUS DoSrvPrivateSetCursorKeysMode(_In_ bool fApplicationMode) -{ - CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - if (gci.pInputBuffer == nullptr) - { - return STATUS_UNSUCCESSFUL; - } - gci.pInputBuffer->GetTerminalInput().ChangeCursorKeysMode(fApplicationMode); - return STATUS_SUCCESS; -} - -// Routine Description: -// - A private API call for changing the keypad input mode between numeric and application mode. -// This controls what the keys on the numpad translate to. -// Parameters: -// - fApplicationMode - set to true to enable Application Mode Input, false for Numeric Mode Input. -// Return value: -// - True if handled successfully. False otherwise. -[[nodiscard]] NTSTATUS DoSrvPrivateSetKeypadMode(_In_ bool fApplicationMode) -{ - CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - if (gci.pInputBuffer == nullptr) - { - return STATUS_UNSUCCESSFUL; - } - gci.pInputBuffer->GetTerminalInput().ChangeKeypadMode(fApplicationMode); - return STATUS_SUCCESS; -} - -// Function Description: -// - A private API call which enables/disables sending full input records -// encoded as a string of characters to the client application. -// Parameters: -// - win32InputMode - set to true to enable win32-input-mode, false to disable. -// Return value: -// - -void DoSrvPrivateEnableWin32InputMode(const bool win32InputMode) -{ - CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - gci.pInputBuffer->GetTerminalInput().ChangeWin32InputMode(win32InputMode); -} - // Routine Description: // - A private API call for changing the screen mode between normal and reverse. // When in reverse screen mode, the background and foreground colors are switched. @@ -1525,78 +1476,6 @@ void DoSrvPrivateUseMainScreenBuffer(SCREEN_INFORMATION& screenInfo) screenInfo.GetActiveBuffer().UseMainScreenBuffer(); } -// Routine Description: -// - A private API call for enabling VT200 style mouse mode. -// Parameters: -// - fEnable - true to enable default tracking mode, false to disable mouse mode. -// Return value: -// - None -void DoSrvPrivateEnableVT200MouseMode(const bool fEnable) -{ - CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - gci.GetActiveInputBuffer()->GetTerminalInput().EnableDefaultTracking(fEnable); -} - -// Routine Description: -// - A private API call for enabling utf8 style mouse mode. -// Parameters: -// - fEnable - true to enable, false to disable. -// Return value: -// - None -void DoSrvPrivateEnableUTF8ExtendedMouseMode(const bool fEnable) -{ - CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - gci.GetActiveInputBuffer()->GetTerminalInput().SetUtf8ExtendedMode(fEnable); -} - -// Routine Description: -// - A private API call for enabling SGR style mouse mode. -// Parameters: -// - fEnable - true to enable, false to disable. -// Return value: -// - None -void DoSrvPrivateEnableSGRExtendedMouseMode(const bool fEnable) -{ - CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - gci.GetActiveInputBuffer()->GetTerminalInput().SetSGRExtendedMode(fEnable); -} - -// Routine Description: -// - A private API call for enabling button-event mouse mode. -// Parameters: -// - fEnable - true to enable button-event mode, false to disable mouse mode. -// Return value: -// - None -void DoSrvPrivateEnableButtonEventMouseMode(const bool fEnable) -{ - CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - gci.GetActiveInputBuffer()->GetTerminalInput().EnableButtonEventTracking(fEnable); -} - -// Routine Description: -// - A private API call for enabling any-event mouse mode. -// Parameters: -// - fEnable - true to enable any-event mode, false to disable mouse mode. -// Return value: -// - None -void DoSrvPrivateEnableAnyEventMouseMode(const bool fEnable) -{ - CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - gci.GetActiveInputBuffer()->GetTerminalInput().EnableAnyEventTracking(fEnable); -} - -// Routine Description: -// - A private API call for enabling alternate scroll mode -// Parameters: -// - fEnable - true to enable alternate scroll mode, false to disable. -// Return value: -// None -void DoSrvPrivateEnableAlternateScroll(const bool fEnable) -{ - CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); - gci.GetActiveInputBuffer()->GetTerminalInput().EnableAlternateScroll(fEnable); -} - // Routine Description: // - A private API call for performing a VT-style erase all operation on the buffer. // See SCREEN_INFORMATION::VtEraseAll's description for details. diff --git a/src/host/getset.h b/src/host/getset.h index e4c539580..5a084d206 100644 --- a/src/host/getset.h +++ b/src/host/getset.h @@ -18,10 +18,6 @@ Revision History: #include "../inc/conattrs.hpp" class SCREEN_INFORMATION; -[[nodiscard]] NTSTATUS DoSrvPrivateSetCursorKeysMode(_In_ bool fApplicationMode); -[[nodiscard]] NTSTATUS DoSrvPrivateSetKeypadMode(_In_ bool fApplicationMode); -void DoSrvPrivateEnableWin32InputMode(const bool win32InputMode); - [[nodiscard]] NTSTATUS DoSrvPrivateSetScreenMode(const bool reverseMode); [[nodiscard]] NTSTATUS DoSrvPrivateSetAutoWrapMode(const bool wrapAtEOL); @@ -35,13 +31,6 @@ void DoSrvPrivateAllowCursorBlinking(SCREEN_INFORMATION& screenInfo, const bool [[nodiscard]] NTSTATUS DoSrvPrivateUseAlternateScreenBuffer(SCREEN_INFORMATION& screenInfo); void DoSrvPrivateUseMainScreenBuffer(SCREEN_INFORMATION& screenInfo); -void DoSrvPrivateEnableVT200MouseMode(const bool fEnable); -void DoSrvPrivateEnableUTF8ExtendedMouseMode(const bool fEnable); -void DoSrvPrivateEnableSGRExtendedMouseMode(const bool fEnable); -void DoSrvPrivateEnableButtonEventMouseMode(const bool fEnable); -void DoSrvPrivateEnableAnyEventMouseMode(const bool fEnable); -void DoSrvPrivateEnableAlternateScroll(const bool fEnable); - [[nodiscard]] HRESULT DoSrvPrivateEraseAll(SCREEN_INFORMATION& screenInfo); [[nodiscard]] HRESULT DoSrvPrivateClearBuffer(SCREEN_INFORMATION& screenInfo); diff --git a/src/host/outputStream.cpp b/src/host/outputStream.cpp index bc15c1cdf..c6c0f9868 100644 --- a/src/host/outputStream.cpp +++ b/src/host/outputStream.cpp @@ -15,6 +15,7 @@ using namespace Microsoft::Console; using Microsoft::Console::Interactivity::ServiceLocator; +using Microsoft::Console::VirtualTerminal::TerminalInput; WriteBuffer::WriteBuffer(_In_ Microsoft::Console::IIoProvider& io) : _io{ io }, @@ -237,43 +238,28 @@ bool ConhostInternalGetSet::SetConsoleWindowInfo(const bool absolute, const SMAL } // Routine Description: -// - Connects the PrivateSetCursorKeysMode call directly into our Driver Message servicing call inside Conhost.exe -// PrivateSetCursorKeysMode is an internal-only "API" call that the vt commands can execute, +// - Sets the various terminal input modes. +// SetInputMode is an internal-only "API" call that the vt commands can execute, // but it is not represented as a function call on out public API surface. // Arguments: -// - fApplicationMode - set to true to enable Application Mode Input, false for Normal Mode. +// - mode - the input mode to change. +// - enabled - set to true to enable the mode, false to disable it. // Return Value: -// - true if successful (see DoSrvPrivateSetCursorKeysMode). false otherwise. -bool ConhostInternalGetSet::PrivateSetCursorKeysMode(const bool fApplicationMode) +// - true if successful. false otherwise. +bool ConhostInternalGetSet::SetInputMode(const TerminalInput::Mode mode, const bool enabled) { - return NT_SUCCESS(DoSrvPrivateSetCursorKeysMode(fApplicationMode)); -} + auto& terminalInput = _io.GetActiveInputBuffer()->GetTerminalInput(); + terminalInput.SetInputMode(mode, enabled); -// Routine Description: -// - Connects the PrivateSetKeypadMode call directly into our Driver Message servicing call inside Conhost.exe -// PrivateSetKeypadMode is an internal-only "API" call that the vt commands can execute, -// but it is not represented as a function call on out public API surface. -// Arguments: -// - fApplicationMode - set to true to enable Application Mode Input, false for Numeric Mode. -// Return Value: -// - true if successful (see DoSrvPrivateSetKeypadMode). false otherwise. -bool ConhostInternalGetSet::PrivateSetKeypadMode(const bool fApplicationMode) -{ - return NT_SUCCESS(DoSrvPrivateSetKeypadMode(fApplicationMode)); -} - -// Routine Description: -// - Connects the PrivateEnableWin32InputMode call directly into our Driver Message servicing call inside Conhost.exe -// PrivateEnableWin32InputMode is an internal-only "API" call that the vt commands can execute, -// but it is not represented as a function call on out public API surface. -// Arguments: -// - win32InputMode - set to true to enable win32-input-mode, false to disable. -// Return Value: -// - true always -bool ConhostInternalGetSet::PrivateEnableWin32InputMode(const bool win32InputMode) -{ - DoSrvPrivateEnableWin32InputMode(win32InputMode); - return true; + // If we're a conpty, AND WE'RE IN VT INPUT MODE, always pass input mode requests + // The VT Input mode check is to work around ssh.exe v7.7, which uses VT + // output, but not Input. + // The original comment said, "Once the conpty supports these types of input, + // this check can be removed. See GH#4911". Unfortunately, time has shown + // us that SSH 7.7 _also_ requests mouse input and that can have a user interface + // impact on the actual connected terminal. We can't remove this check, + // because SSH <=7.7 is out in the wild on all versions of Windows <=2004. + return !(IsConsolePty() && PrivateIsVtInputEnabled()); } // Routine Description: @@ -289,7 +275,7 @@ bool ConhostInternalGetSet::PrivateSetAnsiMode(const bool ansiMode) auto& stateMachine = _io.GetActiveOutputBuffer().GetStateMachine(); stateMachine.SetAnsiMode(ansiMode); auto& terminalInput = _io.GetActiveInputBuffer()->GetTerminalInput(); - terminalInput.ChangeAnsiMode(ansiMode); + terminalInput.SetInputMode(TerminalInput::Mode::Ansi, ansiMode); return true; } @@ -448,90 +434,6 @@ bool ConhostInternalGetSet::PrivateUseMainScreenBuffer() return true; } -// Routine Description: -// - Connects the PrivateEnableVT200MouseMode call directly into our Driver Message servicing call inside Conhost.exe -// PrivateEnableVT200MouseMode is an internal-only "API" call that the vt commands can execute, -// but it is not represented as a function call on out public API surface. -// Arguments: -// - enabled - set to true to enable vt200 mouse mode, false to disable -// Return Value: -// - true if successful (see DoSrvPrivateEnableVT200MouseMode). false otherwise. -bool ConhostInternalGetSet::PrivateEnableVT200MouseMode(const bool enabled) -{ - DoSrvPrivateEnableVT200MouseMode(enabled); - return true; -} - -// Routine Description: -// - Connects the PrivateEnableUTF8ExtendedMouseMode call directly into our Driver Message servicing call inside Conhost.exe -// PrivateEnableUTF8ExtendedMouseMode is an internal-only "API" call that the vt commands can execute, -// but it is not represented as a function call on out public API surface. -// Arguments: -// - enabled - set to true to enable utf8 extended mouse mode, false to disable -// Return Value: -// - true if successful (see DoSrvPrivateEnableUTF8ExtendedMouseMode). false otherwise. -bool ConhostInternalGetSet::PrivateEnableUTF8ExtendedMouseMode(const bool enabled) -{ - DoSrvPrivateEnableUTF8ExtendedMouseMode(enabled); - return true; -} - -// Routine Description: -// - Connects the PrivateEnableSGRExtendedMouseMode call directly into our Driver Message servicing call inside Conhost.exe -// PrivateEnableSGRExtendedMouseMode is an internal-only "API" call that the vt commands can execute, -// but it is not represented as a function call on out public API surface. -// Arguments: -// - enabled - set to true to enable SGR extended mouse mode, false to disable -// Return Value: -// - true if successful (see DoSrvPrivateEnableSGRExtendedMouseMode). false otherwise. -bool ConhostInternalGetSet::PrivateEnableSGRExtendedMouseMode(const bool enabled) -{ - DoSrvPrivateEnableSGRExtendedMouseMode(enabled); - return true; -} - -// Routine Description: -// - Connects the PrivateEnableButtonEventMouseMode call directly into our Driver Message servicing call inside Conhost.exe -// PrivateEnableButtonEventMouseMode is an internal-only "API" call that the vt commands can execute, -// but it is not represented as a function call on out public API surface. -// Arguments: -// - enabled - set to true to enable button-event mouse mode, false to disable -// Return Value: -// - true if successful (see DoSrvPrivateEnableButtonEventMouseMode). false otherwise. -bool ConhostInternalGetSet::PrivateEnableButtonEventMouseMode(const bool enabled) -{ - DoSrvPrivateEnableButtonEventMouseMode(enabled); - return true; -} - -// Routine Description: -// - Connects the PrivateEnableAnyEventMouseMode call directly into our Driver Message servicing call inside Conhost.exe -// PrivateEnableAnyEventMouseMode is an internal-only "API" call that the vt commands can execute, -// but it is not represented as a function call on out public API surface. -// Arguments: -// - enabled - set to true to enable any-event mouse mode, false to disable -// Return Value: -// - true if successful (see DoSrvPrivateEnableAnyEventMouseMode). false otherwise. -bool ConhostInternalGetSet::PrivateEnableAnyEventMouseMode(const bool enabled) -{ - DoSrvPrivateEnableAnyEventMouseMode(enabled); - return true; -} - -// Routine Description: -// - Connects the PrivateEnableAlternateScroll call directly into our Driver Message servicing call inside Conhost.exe -// PrivateEnableAlternateScroll is an internal-only "API" call that the vt commands can execute, -// but it is not represented as a function call on out public API surface. -// Arguments: -// - enabled - set to true to enable alternate scroll mode, false to disable -// Return Value: -// - true if successful (see DoSrvPrivateEnableAnyEventMouseMode). false otherwise. -bool ConhostInternalGetSet::PrivateEnableAlternateScroll(const bool enabled) -{ - DoSrvPrivateEnableAlternateScroll(enabled); - return true; -} - // Routine Description: // - Connects the PrivateEraseAll call directly into our Driver Message servicing call inside Conhost.exe // PrivateEraseAll is an internal-only "API" call that the vt commands can execute, diff --git a/src/host/outputStream.hpp b/src/host/outputStream.hpp index 9df19446f..51300f3a1 100644 --- a/src/host/outputStream.hpp +++ b/src/host/outputStream.hpp @@ -72,9 +72,7 @@ public: bool SetConsoleWindowInfo(bool const absolute, const SMALL_RECT& window) override; - bool PrivateSetCursorKeysMode(const bool applicationMode) override; - bool PrivateSetKeypadMode(const bool applicationMode) override; - bool PrivateEnableWin32InputMode(const bool win32InputMode) override; + bool SetInputMode(const Microsoft::Console::VirtualTerminal::TerminalInput::Mode mode, const bool enabled) override; bool PrivateSetAnsiMode(const bool ansiMode) override; bool PrivateSetScreenMode(const bool reverseMode) override; @@ -97,12 +95,6 @@ public: bool PrivateUseMainScreenBuffer() override; - bool PrivateEnableVT200MouseMode(const bool enabled) override; - bool PrivateEnableUTF8ExtendedMouseMode(const bool enabled) override; - bool PrivateEnableSGRExtendedMouseMode(const bool enabled) override; - bool PrivateEnableButtonEventMouseMode(const bool enabled) override; - bool PrivateEnableAnyEventMouseMode(const bool enabled) override; - bool PrivateEnableAlternateScroll(const bool enabled) override; bool PrivateEraseAll() override; bool PrivateClearBuffer() override; diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index 9bf49eeee..49a3f71a9 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -1167,15 +1167,7 @@ bool AdaptDispatch::ResetMode(const DispatchTypes::ModeParams param) // - True if handled successfully. False otherwise. bool AdaptDispatch::SetKeypadMode(const bool fApplicationMode) { - bool success = true; - success = _pConApi->PrivateSetKeypadMode(fApplicationMode); - - if (_ShouldPassThroughInputModeChange()) - { - return false; - } - - return success; + return _pConApi->SetInputMode(TerminalInput::Mode::Keypad, fApplicationMode); } // Method Description: @@ -1187,15 +1179,7 @@ bool AdaptDispatch::SetKeypadMode(const bool fApplicationMode) // - True if handled successfully. False otherwise. bool AdaptDispatch::EnableWin32InputMode(const bool win32InputMode) { - bool success = true; - success = _pConApi->PrivateEnableWin32InputMode(win32InputMode); - - if (_ShouldPassThroughInputModeChange()) - { - return false; - } - - return success; + return _pConApi->SetInputMode(TerminalInput::Mode::Win32, win32InputMode); } // - DECCKM - Sets the cursor keys input mode to either Application mode or Normal mode (true, false respectively) @@ -1205,15 +1189,7 @@ bool AdaptDispatch::EnableWin32InputMode(const bool win32InputMode) // - True if handled successfully. False otherwise. bool AdaptDispatch::SetCursorKeysMode(const bool applicationMode) { - bool success = true; - success = _pConApi->PrivateSetCursorKeysMode(applicationMode); - - if (_ShouldPassThroughInputModeChange()) - { - return false; - } - - return success; + return _pConApi->SetInputMode(TerminalInput::Mode::CursorKey, applicationMode); } // - att610 - Enables or disables the cursor blinking. @@ -2096,15 +2072,7 @@ bool AdaptDispatch::EnableDECCOLMSupport(const bool enabled) noexcept // True if handled successfully. False otherwise. bool AdaptDispatch::EnableVT200MouseMode(const bool enabled) { - bool success = true; - success = _pConApi->PrivateEnableVT200MouseMode(enabled); - - if (_ShouldPassThroughInputModeChange()) - { - return false; - } - - return success; + return _pConApi->SetInputMode(TerminalInput::Mode::DefaultMouseTracking, enabled); } //Routine Description: @@ -2116,15 +2084,7 @@ bool AdaptDispatch::EnableVT200MouseMode(const bool enabled) // True if handled successfully. False otherwise. bool AdaptDispatch::EnableUTF8ExtendedMouseMode(const bool enabled) { - bool success = true; - success = _pConApi->PrivateEnableUTF8ExtendedMouseMode(enabled); - - if (_ShouldPassThroughInputModeChange()) - { - return false; - } - - return success; + return _pConApi->SetInputMode(TerminalInput::Mode::Utf8MouseEncoding, enabled); } //Routine Description: @@ -2136,15 +2096,7 @@ bool AdaptDispatch::EnableUTF8ExtendedMouseMode(const bool enabled) // True if handled successfully. False otherwise. bool AdaptDispatch::EnableSGRExtendedMouseMode(const bool enabled) { - bool success = true; - success = _pConApi->PrivateEnableSGRExtendedMouseMode(enabled); - - if (_ShouldPassThroughInputModeChange()) - { - return false; - } - - return success; + return _pConApi->SetInputMode(TerminalInput::Mode::SgrMouseEncoding, enabled); } //Routine Description: @@ -2155,15 +2107,7 @@ bool AdaptDispatch::EnableSGRExtendedMouseMode(const bool enabled) // True if handled successfully. False otherwise. bool AdaptDispatch::EnableButtonEventMouseMode(const bool enabled) { - bool success = true; - success = _pConApi->PrivateEnableButtonEventMouseMode(enabled); - - if (_ShouldPassThroughInputModeChange()) - { - return false; - } - - return success; + return _pConApi->SetInputMode(TerminalInput::Mode::ButtonEventMouseTracking, enabled); } //Routine Description: @@ -2175,15 +2119,7 @@ bool AdaptDispatch::EnableButtonEventMouseMode(const bool enabled) // True if handled successfully. False otherwise. bool AdaptDispatch::EnableAnyEventMouseMode(const bool enabled) { - bool success = true; - success = _pConApi->PrivateEnableAnyEventMouseMode(enabled); - - if (_ShouldPassThroughInputModeChange()) - { - return false; - } - - return success; + return _pConApi->SetInputMode(TerminalInput::Mode::AnyEventMouseTracking, enabled); } //Routine Description: @@ -2195,15 +2131,7 @@ bool AdaptDispatch::EnableAnyEventMouseMode(const bool enabled) // True if handled successfully. False otherwise. bool AdaptDispatch::EnableAlternateScroll(const bool enabled) { - bool success = true; - success = _pConApi->PrivateEnableAlternateScroll(enabled); - - if (_ShouldPassThroughInputModeChange()) - { - return false; - } - - return success; + return _pConApi->SetInputMode(TerminalInput::Mode::AlternateScroll, enabled); } //Routine Description: @@ -2672,22 +2600,3 @@ void AdaptDispatch::_ReportDECSTBMSetting() const response += L"r\033\\"; _WriteResponse(response); } - -// Routine Description: -// - Determines whether we should pass any sequence that manipulates -// TerminalInput's input generator through the PTY. It encapsulates -// a check for whether the PTY is in use. -// Return value: -// True if the request should be passed. -bool AdaptDispatch::_ShouldPassThroughInputModeChange() const -{ - // If we're a conpty, AND WE'RE IN VT INPUT MODE, always pass input mode requests - // The VT Input mode check is to work around ssh.exe v7.7, which uses VT - // output, but not Input. - // The original comment said, "Once the conpty supports these types of input, - // this check can be removed. See GH#4911". Unfortunately, time has shown - // us that SSH 7.7 _also_ requests mouse input and that can have a user interface - // impact on the actual connected terminal. We can't remove this check, - // because SSH <=7.7 is out in the wild on all versions of Windows <=2004. - return _pConApi->IsConsolePty() && _pConApi->PrivateIsVtInputEnabled(); -} diff --git a/src/terminal/adapter/adaptDispatch.hpp b/src/terminal/adapter/adaptDispatch.hpp index b77345e51..da53109df 100644 --- a/src/terminal/adapter/adaptDispatch.hpp +++ b/src/terminal/adapter/adaptDispatch.hpp @@ -194,8 +194,6 @@ namespace Microsoft::Console::VirtualTerminal void _ReportSGRSetting() const; void _ReportDECSTBMSetting() const; - bool _ShouldPassThroughInputModeChange() const; - std::vector _tabStopColumns; bool _initDefaultTabStops = true; diff --git a/src/terminal/adapter/conGetSet.hpp b/src/terminal/adapter/conGetSet.hpp index 7576d3801..db61551e3 100644 --- a/src/terminal/adapter/conGetSet.hpp +++ b/src/terminal/adapter/conGetSet.hpp @@ -15,6 +15,7 @@ Author(s): #pragma once +#include "../input/terminalInput.hpp" #include "../../types/inc/IInputEvent.hpp" #include "../../buffer/out/LineRendition.hpp" #include "../../buffer/out/TextAttribute.hpp" @@ -46,9 +47,8 @@ namespace Microsoft::Console::VirtualTerminal size_t& eventsWritten) = 0; virtual bool SetConsoleWindowInfo(const bool absolute, const SMALL_RECT& window) = 0; - virtual bool PrivateSetCursorKeysMode(const bool applicationMode) = 0; - virtual bool PrivateSetKeypadMode(const bool applicationMode) = 0; - virtual bool PrivateEnableWin32InputMode(const bool win32InputMode) = 0; + + virtual bool SetInputMode(const TerminalInput::Mode mode, const bool enabled) = 0; virtual bool PrivateSetAnsiMode(const bool ansiMode) = 0; virtual bool PrivateSetScreenMode(const bool reverseMode) = 0; @@ -66,12 +66,6 @@ namespace Microsoft::Console::VirtualTerminal virtual bool PrivateUseAlternateScreenBuffer() = 0; virtual bool PrivateUseMainScreenBuffer() = 0; - virtual bool PrivateEnableVT200MouseMode(const bool enabled) = 0; - virtual bool PrivateEnableUTF8ExtendedMouseMode(const bool enabled) = 0; - virtual bool PrivateEnableSGRExtendedMouseMode(const bool enabled) = 0; - virtual bool PrivateEnableButtonEventMouseMode(const bool enabled) = 0; - virtual bool PrivateEnableAnyEventMouseMode(const bool enabled) = 0; - virtual bool PrivateEnableAlternateScroll(const bool enabled) = 0; virtual bool PrivateEraseAll() = 0; virtual bool PrivateClearBuffer() = 0; virtual bool GetUserDefaultCursorStyle(CursorType& style) = 0; diff --git a/src/terminal/adapter/ut_adapter/MouseInputTest.cpp b/src/terminal/adapter/ut_adapter/MouseInputTest.cpp index b16288f2b..6841c2782 100644 --- a/src/terminal/adapter/ut_adapter/MouseInputTest.cpp +++ b/src/terminal/adapter/ut_adapter/MouseInputTest.cpp @@ -298,7 +298,7 @@ public: s_pwszInputExpected = L"\x0"; VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta, {})); - mouseInput->EnableDefaultTracking(true); + mouseInput->SetInputMode(TerminalInput::Mode::DefaultMouseTracking, true); for (int i = 0; i < s_iTestCoordsLength; i++) { @@ -318,7 +318,7 @@ public: NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } - mouseInput->EnableButtonEventTracking(true); + mouseInput->SetInputMode(TerminalInput::Mode::ButtonEventMouseTracking, true); for (int i = 0; i < s_iTestCoordsLength; i++) { COORD Coord = s_rgTestCoords[i]; @@ -337,7 +337,7 @@ public: NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } - mouseInput->EnableAnyEventTracking(true); + mouseInput->SetInputMode(TerminalInput::Mode::AnyEventMouseTracking, true); for (int i = 0; i < s_iTestCoordsLength; i++) { COORD Coord = s_rgTestCoords[i]; @@ -381,11 +381,11 @@ public: s_pwszInputExpected = L"\x0"; VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta, {})); - mouseInput->SetUtf8ExtendedMode(true); + mouseInput->SetInputMode(TerminalInput::Mode::Utf8MouseEncoding, true); short MaxCoord = SHORT_MAX - 33; - mouseInput->EnableDefaultTracking(true); + mouseInput->SetInputMode(TerminalInput::Mode::DefaultMouseTracking, true); for (int i = 0; i < s_iTestCoordsLength; i++) { COORD Coord = s_rgTestCoords[i]; @@ -404,7 +404,7 @@ public: NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } - mouseInput->EnableButtonEventTracking(true); + mouseInput->SetInputMode(TerminalInput::Mode::ButtonEventMouseTracking, true); for (int i = 0; i < s_iTestCoordsLength; i++) { COORD Coord = s_rgTestCoords[i]; @@ -423,7 +423,7 @@ public: NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } - mouseInput->EnableAnyEventTracking(true); + mouseInput->SetInputMode(TerminalInput::Mode::AnyEventMouseTracking, true); for (int i = 0; i < s_iTestCoordsLength; i++) { COORD Coord = s_rgTestCoords[i]; @@ -467,13 +467,13 @@ public: s_pwszInputExpected = L"\x0"; VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta, {})); - mouseInput->SetSGRExtendedMode(true); + mouseInput->SetInputMode(TerminalInput::Mode::SgrMouseEncoding, true); // SGR Mode should be able to handle any arbitrary coords. // However, mouse moves are only handled in Any Event mode fExpectedKeyHandled = uiButton != WM_MOUSEMOVE; - mouseInput->EnableDefaultTracking(true); + mouseInput->SetInputMode(TerminalInput::Mode::DefaultMouseTracking, true); for (int i = 0; i < s_iTestCoordsLength; i++) { COORD Coord = s_rgTestCoords[i]; @@ -487,7 +487,7 @@ public: NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y)); } - mouseInput->EnableButtonEventTracking(true); + mouseInput->SetInputMode(TerminalInput::Mode::ButtonEventMouseTracking, true); for (int i = 0; i < s_iTestCoordsLength; i++) { COORD Coord = s_rgTestCoords[i]; @@ -506,7 +506,7 @@ public: } fExpectedKeyHandled = true; - mouseInput->EnableAnyEventTracking(true); + mouseInput->SetInputMode(TerminalInput::Mode::AnyEventMouseTracking, true); for (int i = 0; i < s_iTestCoordsLength; i++) { COORD Coord = s_rgTestCoords[i]; @@ -550,7 +550,7 @@ public: VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta, {})); // Default Tracking, Default Encoding - mouseInput->EnableDefaultTracking(true); + mouseInput->SetInputMode(TerminalInput::Mode::DefaultMouseTracking, true); for (int i = 0; i < s_iTestCoordsLength; i++) { @@ -571,7 +571,7 @@ public: } // Default Tracking, UTF8 Encoding - mouseInput->SetUtf8ExtendedMode(true); + mouseInput->SetInputMode(TerminalInput::Mode::Utf8MouseEncoding, true); short MaxCoord = SHORT_MAX - 33; for (int i = 0; i < s_iTestCoordsLength; i++) { @@ -592,7 +592,7 @@ public: } // Default Tracking, SGR Encoding - mouseInput->SetSGRExtendedMode(true); + mouseInput->SetInputMode(TerminalInput::Mode::SgrMouseEncoding, true); fExpectedKeyHandled = true; // SGR Mode should be able to handle any arbitrary coords. for (int i = 0; i < s_iTestCoordsLength; i++) { @@ -620,7 +620,7 @@ public: Log::Comment(L"Enable alternate scroll mode in the alt screen buffer"); mouseInput->UseAlternateScreenBuffer(); - mouseInput->EnableAlternateScroll(true); + mouseInput->SetInputMode(TerminalInput::Mode::AlternateScroll, true); Log::Comment(L"Test mouse wheel scrolling up"); s_pwszInputExpected = L"\x1B[A"; @@ -631,7 +631,7 @@ public: VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, -WHEEL_DELTA, {})); Log::Comment(L"Enable cursor keys mode"); - mouseInput->ChangeCursorKeysMode(true); + mouseInput->SetInputMode(TerminalInput::Mode::CursorKey, true); Log::Comment(L"Test mouse wheel scrolling up"); s_pwszInputExpected = L"\x1BOA"; @@ -643,12 +643,12 @@ public: Log::Comment(L"Confirm no effect when scroll mode is disabled"); mouseInput->UseAlternateScreenBuffer(); - mouseInput->EnableAlternateScroll(false); + mouseInput->SetInputMode(TerminalInput::Mode::AlternateScroll, false); VERIFY_IS_FALSE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, WHEEL_DELTA, {})); Log::Comment(L"Confirm no effect when using the main buffer"); mouseInput->UseMainScreenBuffer(); - mouseInput->EnableAlternateScroll(true); + mouseInput->SetInputMode(TerminalInput::Mode::AlternateScroll, true); VERIFY_IS_FALSE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, WHEEL_DELTA, {})); } }; diff --git a/src/terminal/adapter/ut_adapter/adapterTest.cpp b/src/terminal/adapter/ut_adapter/adapterTest.cpp index 876011422..b775f4c7a 100644 --- a/src/terminal/adapter/ut_adapter/adapterTest.cpp +++ b/src/terminal/adapter/ut_adapter/adapterTest.cpp @@ -112,35 +112,17 @@ public: return _setConsoleWindowInfoResult; } - bool PrivateSetCursorKeysMode(const bool applicationMode) override + bool SetInputMode(const TerminalInput::Mode mode, const bool enabled) override { - Log::Comment(L"PrivateSetCursorKeysMode MOCK called..."); + Log::Comment(L"SetInputMode MOCK called..."); - if (_privateSetCursorKeysModeResult) + if (_setInputModeResult) { - VERIFY_ARE_EQUAL(_cursorKeysApplicationMode, applicationMode); + VERIFY_ARE_EQUAL(_expectedInputMode, mode); + VERIFY_ARE_EQUAL(_expectedInputModeEnabled, enabled); } - return _privateSetCursorKeysModeResult; - } - - bool PrivateSetKeypadMode(const bool applicationMode) override - { - Log::Comment(L"PrivateSetKeypadMode MOCK called..."); - - if (_privateSetKeypadModeResult) - { - VERIFY_ARE_EQUAL(_keypadApplicationMode, applicationMode); - } - - return _privateSetKeypadModeResult; - } - - bool PrivateEnableWin32InputMode(const bool /*win32InputMode*/) override - { - Log::Comment(L"PrivateEnableWin32InputMode MOCK called..."); - - return true; + return _setInputModeResult; } bool PrivateSetAnsiMode(const bool ansiMode) override @@ -352,66 +334,6 @@ public: return true; } - bool PrivateEnableVT200MouseMode(const bool enabled) override - { - Log::Comment(L"PrivateEnableVT200MouseMode MOCK called..."); - if (_privateEnableVT200MouseModeResult) - { - VERIFY_ARE_EQUAL(_expectedMouseEnabled, enabled); - } - return _privateEnableVT200MouseModeResult; - } - - bool PrivateEnableUTF8ExtendedMouseMode(const bool enabled) override - { - Log::Comment(L"PrivateEnableUTF8ExtendedMouseMode MOCK called..."); - if (_privateEnableUTF8ExtendedMouseModeResult) - { - VERIFY_ARE_EQUAL(_expectedMouseEnabled, enabled); - } - return _privateEnableUTF8ExtendedMouseModeResult; - } - - bool PrivateEnableSGRExtendedMouseMode(const bool enabled) override - { - Log::Comment(L"PrivateEnableSGRExtendedMouseMode MOCK called..."); - if (_privateEnableSGRExtendedMouseModeResult) - { - VERIFY_ARE_EQUAL(_expectedMouseEnabled, enabled); - } - return _privateEnableSGRExtendedMouseModeResult; - } - - bool PrivateEnableButtonEventMouseMode(const bool enabled) override - { - Log::Comment(L"PrivateEnableButtonEventMouseMode MOCK called..."); - if (_privateEnableButtonEventMouseModeResult) - { - VERIFY_ARE_EQUAL(_expectedMouseEnabled, enabled); - } - return _privateEnableButtonEventMouseModeResult; - } - - bool PrivateEnableAnyEventMouseMode(const bool enabled) override - { - Log::Comment(L"PrivateEnableAnyEventMouseMode MOCK called..."); - if (_privateEnableAnyEventMouseModeResult) - { - VERIFY_ARE_EQUAL(_expectedMouseEnabled, enabled); - } - return _privateEnableAnyEventMouseModeResult; - } - - bool PrivateEnableAlternateScroll(const bool enabled) override - { - Log::Comment(L"PrivateEnableAlternateScroll MOCK called..."); - if (_privateEnableAlternateScrollResult) - { - VERIFY_ARE_EQUAL(_expectedAlternateScrollEnabled, enabled); - } - return _privateEnableAlternateScrollResult; - } - bool PrivateEraseAll() override { Log::Comment(L"PrivateEraseAll MOCK called..."); @@ -787,10 +709,9 @@ public: COORD _expectedScreenBufferSize = { 0, 0 }; SMALL_RECT _expectedScreenBufferViewport{ 0, 0, 0, 0 }; - bool _privateSetCursorKeysModeResult = false; - bool _privateSetKeypadModeResult = false; - bool _cursorKeysApplicationMode = false; - bool _keypadApplicationMode = false; + bool _setInputModeResult = false; + TerminalInput::Mode _expectedInputMode; + bool _expectedInputModeEnabled = false; bool _privateSetAnsiModeResult = false; bool _expectedAnsiMode = false; bool _privateAllowCursorBlinkingResult = false; @@ -803,14 +724,6 @@ public: bool _setConsoleTitleWResult = false; std::wstring_view _expectedWindowTitle{}; - bool _expectedMouseEnabled = false; - bool _expectedAlternateScrollEnabled = false; - bool _privateEnableVT200MouseModeResult = false; - bool _privateEnableUTF8ExtendedMouseModeResult = false; - bool _privateEnableSGRExtendedMouseModeResult = false; - bool _privateEnableButtonEventMouseModeResult = false; - bool _privateEnableAnyEventMouseModeResult = false; - bool _privateEnableAlternateScrollResult = false; bool _setCursorStyleResult = false; CursorType _expectedCursorStyle; bool _setCursorColorResult = false; @@ -2100,15 +2013,17 @@ public: // success cases // set numeric mode = true Log::Comment(L"Test 1: application mode = false"); - _testGetSet->_privateSetCursorKeysModeResult = TRUE; - _testGetSet->_cursorKeysApplicationMode = false; + _testGetSet->_setInputModeResult = true; + _testGetSet->_expectedInputMode = TerminalInput::Mode::CursorKey; + _testGetSet->_expectedInputModeEnabled = false; VERIFY_IS_TRUE(_pDispatch.get()->SetCursorKeysMode(false)); // set numeric mode = false Log::Comment(L"Test 2: application mode = true"); - _testGetSet->_privateSetCursorKeysModeResult = TRUE; - _testGetSet->_cursorKeysApplicationMode = true; + _testGetSet->_setInputModeResult = true; + _testGetSet->_expectedInputMode = TerminalInput::Mode::CursorKey; + _testGetSet->_expectedInputModeEnabled = true; VERIFY_IS_TRUE(_pDispatch.get()->SetCursorKeysMode(true)); } @@ -2120,15 +2035,17 @@ public: // success cases // set numeric mode = true Log::Comment(L"Test 1: application mode = false"); - _testGetSet->_privateSetKeypadModeResult = TRUE; - _testGetSet->_keypadApplicationMode = false; + _testGetSet->_setInputModeResult = true; + _testGetSet->_expectedInputMode = TerminalInput::Mode::Keypad; + _testGetSet->_expectedInputModeEnabled = false; VERIFY_IS_TRUE(_pDispatch.get()->SetKeypadMode(false)); // set numeric mode = false Log::Comment(L"Test 2: application mode = true"); - _testGetSet->_privateSetKeypadModeResult = TRUE; - _testGetSet->_keypadApplicationMode = true; + _testGetSet->_setInputModeResult = true; + _testGetSet->_expectedInputMode = TerminalInput::Mode::Keypad; + _testGetSet->_expectedInputModeEnabled = true; VERIFY_IS_TRUE(_pDispatch.get()->SetKeypadMode(true)); } @@ -2316,45 +2233,51 @@ public: Log::Comment(L"Starting test..."); Log::Comment(L"Test 1: Test Default Mouse Mode"); - _testGetSet->_expectedMouseEnabled = true; - _testGetSet->_privateEnableVT200MouseModeResult = TRUE; + _testGetSet->_expectedInputModeEnabled = true; + _testGetSet->_expectedInputMode = TerminalInput::Mode::DefaultMouseTracking; + _testGetSet->_setInputModeResult = true; VERIFY_IS_TRUE(_pDispatch.get()->EnableVT200MouseMode(true)); - _testGetSet->_expectedMouseEnabled = false; + _testGetSet->_expectedInputModeEnabled = false; VERIFY_IS_TRUE(_pDispatch.get()->EnableVT200MouseMode(false)); Log::Comment(L"Test 2: Test UTF-8 Extended Mouse Mode"); - _testGetSet->_expectedMouseEnabled = true; - _testGetSet->_privateEnableUTF8ExtendedMouseModeResult = TRUE; + _testGetSet->_expectedInputModeEnabled = true; + _testGetSet->_expectedInputMode = TerminalInput::Mode::Utf8MouseEncoding; + _testGetSet->_setInputModeResult = true; VERIFY_IS_TRUE(_pDispatch.get()->EnableUTF8ExtendedMouseMode(true)); - _testGetSet->_expectedMouseEnabled = false; + _testGetSet->_expectedInputModeEnabled = false; VERIFY_IS_TRUE(_pDispatch.get()->EnableUTF8ExtendedMouseMode(false)); Log::Comment(L"Test 3: Test SGR Extended Mouse Mode"); - _testGetSet->_expectedMouseEnabled = true; - _testGetSet->_privateEnableSGRExtendedMouseModeResult = TRUE; + _testGetSet->_expectedInputModeEnabled = true; + _testGetSet->_expectedInputMode = TerminalInput::Mode::SgrMouseEncoding; + _testGetSet->_setInputModeResult = true; VERIFY_IS_TRUE(_pDispatch.get()->EnableSGRExtendedMouseMode(true)); - _testGetSet->_expectedMouseEnabled = false; + _testGetSet->_expectedInputModeEnabled = false; VERIFY_IS_TRUE(_pDispatch.get()->EnableSGRExtendedMouseMode(false)); Log::Comment(L"Test 4: Test Button-Event Mouse Mode"); - _testGetSet->_expectedMouseEnabled = true; - _testGetSet->_privateEnableButtonEventMouseModeResult = TRUE; + _testGetSet->_expectedInputModeEnabled = true; + _testGetSet->_expectedInputMode = TerminalInput::Mode::ButtonEventMouseTracking; + _testGetSet->_setInputModeResult = true; VERIFY_IS_TRUE(_pDispatch.get()->EnableButtonEventMouseMode(true)); - _testGetSet->_expectedMouseEnabled = false; + _testGetSet->_expectedInputModeEnabled = false; VERIFY_IS_TRUE(_pDispatch.get()->EnableButtonEventMouseMode(false)); Log::Comment(L"Test 5: Test Any-Event Mouse Mode"); - _testGetSet->_expectedMouseEnabled = true; - _testGetSet->_privateEnableAnyEventMouseModeResult = TRUE; + _testGetSet->_expectedInputModeEnabled = true; + _testGetSet->_expectedInputMode = TerminalInput::Mode::AnyEventMouseTracking; + _testGetSet->_setInputModeResult = true; VERIFY_IS_TRUE(_pDispatch.get()->EnableAnyEventMouseMode(true)); - _testGetSet->_expectedMouseEnabled = false; + _testGetSet->_expectedInputModeEnabled = false; VERIFY_IS_TRUE(_pDispatch.get()->EnableAnyEventMouseMode(false)); Log::Comment(L"Test 6: Test Alt Scroll Mouse Mode"); - _testGetSet->_expectedAlternateScrollEnabled = true; - _testGetSet->_privateEnableAlternateScrollResult = TRUE; + _testGetSet->_expectedInputModeEnabled = true; + _testGetSet->_expectedInputMode = TerminalInput::Mode::AlternateScroll; + _testGetSet->_setInputModeResult = true; VERIFY_IS_TRUE(_pDispatch.get()->EnableAlternateScroll(true)); - _testGetSet->_expectedAlternateScrollEnabled = false; + _testGetSet->_expectedInputModeEnabled = false; VERIFY_IS_TRUE(_pDispatch.get()->EnableAlternateScroll(false)); } diff --git a/src/terminal/input/mouseInput.cpp b/src/terminal/input/mouseInput.cpp index ec02b2513..59c4ec910 100644 --- a/src/terminal/input/mouseInput.cpp +++ b/src/terminal/input/mouseInput.cpp @@ -285,13 +285,13 @@ static constexpr short _encodeDefaultCoordinate(const short sCoordinateValue) no // - true, if we are tracking mouse input. False, otherwise bool TerminalInput::IsTrackingMouseInput() const noexcept { - return (_mouseInputState.trackingMode != TrackingMode::None); + return _inputMode.any(Mode::DefaultMouseTracking, Mode::ButtonEventMouseTracking, Mode::AnyEventMouseTracking); } // Routine Description: // - Attempt to handle the given mouse coordinates and windows button as a VT-style mouse event. // If the event should be transmitted in the selected mouse mode, then we'll try and -// encode the event according to the rules of the selected ExtendedMode, and insert those characters into the input buffer. +// encode the event according to the rules of the encoding mode, and insert those characters into the input buffer. // Parameters: // - position - The windows coordinates (top,left = 0,0) of the mouse event // - button - the message to decode. @@ -339,7 +339,7 @@ bool TerminalInput::HandleMouse(const COORD position, } else { - success = (_mouseInputState.trackingMode != TrackingMode::None); + success = IsTrackingMouseInput(); if (success) { // isHover is only true for WM_MOUSEMOVE events @@ -363,30 +363,23 @@ bool TerminalInput::HandleMouse(const COORD position, // In AnyEvent, all coord change hovers are sent const bool physicalButtonPressed = realButton != WM_LBUTTONUP; - success = (isButton && _mouseInputState.trackingMode != TrackingMode::None) || - (isHover && _mouseInputState.trackingMode == TrackingMode::ButtonEvent && ((!sameCoord) && (physicalButtonPressed))) || - (isHover && _mouseInputState.trackingMode == TrackingMode::AnyEvent && !sameCoord); + success = (isButton && IsTrackingMouseInput()) || + (isHover && _inputMode.test(Mode::ButtonEventMouseTracking) && ((!sameCoord) && (physicalButtonPressed))) || + (isHover && _inputMode.test(Mode::AnyEventMouseTracking) && !sameCoord); if (success) { std::wstring sequence; - switch (_mouseInputState.extendedMode) + if (_inputMode.test(Mode::Utf8MouseEncoding)) { - case ExtendedMode::None: - sequence = _GenerateDefaultSequence(position, - realButton, - isHover, - modifierKeyState, - delta); - break; - case ExtendedMode::Utf8: sequence = _GenerateUtf8Sequence(position, realButton, isHover, modifierKeyState, delta); - break; - case ExtendedMode::Sgr: + } + else if (_inputMode.test(Mode::SgrMouseEncoding)) + { // For SGR encoding, if no physical buttons were pressed, // then we want to handle hovers with WM_MOUSEMOVE. // However, if we're dragging (WM_MOUSEMOVE with a button pressed), @@ -397,13 +390,15 @@ bool TerminalInput::HandleMouse(const COORD position, isHover, modifierKeyState, delta); - break; - case ExtendedMode::Urxvt: - default: - success = false; - break; } - + else + { + sequence = _GenerateDefaultSequence(position, + realButton, + isHover, + modifierKeyState, + delta); + } success = !sequence.empty(); if (success) @@ -411,7 +406,7 @@ bool TerminalInput::HandleMouse(const COORD position, _SendInputSequence(sequence); success = true; } - if (_mouseInputState.trackingMode == TrackingMode::ButtonEvent || _mouseInputState.trackingMode == TrackingMode::AnyEvent) + if (_inputMode.any(Mode::ButtonEventMouseTracking, Mode::AnyEventMouseTracking)) { _mouseInputState.lastPos.X = position.X; _mouseInputState.lastPos.Y = position.Y; @@ -547,10 +542,10 @@ std::wstring TerminalInput::_GenerateSGRSequence(const COORD position, // - delta: The scroll wheel delta of the input event // Return value: // True iff the alternate buffer is active and alternate scroll mode is enabled and the event is a mouse wheel event. -bool TerminalInput::_ShouldSendAlternateScroll(const unsigned int button, const short delta) const noexcept +bool TerminalInput::_ShouldSendAlternateScroll(const unsigned int button, const short delta) const { return _mouseInputState.inAlternateBuffer && - _mouseInputState.alternateScroll && + _inputMode.test(Mode::AlternateScroll) && (button == WM_MOUSEWHEEL || button == WM_MOUSEHWHEEL) && delta != 0; } @@ -560,15 +555,15 @@ bool TerminalInput::_ShouldSendAlternateScroll(const unsigned int button, const // - delta: The scroll wheel delta of the input event // Return value: // True iff the input sequence was sent successfully. -bool TerminalInput::_SendAlternateScroll(const short delta) const noexcept +bool TerminalInput::_SendAlternateScroll(const short delta) const { if (delta > 0) { - _SendInputSequence(_cursorApplicationMode ? ApplicationUpSequence : CursorUpSequence); + _SendInputSequence(_inputMode.test(Mode::CursorKey) ? ApplicationUpSequence : CursorUpSequence); } else { - _SendInputSequence(_cursorApplicationMode ? ApplicationDownSequence : CursorDownSequence); + _SendInputSequence(_inputMode.test(Mode::CursorKey) ? ApplicationDownSequence : CursorDownSequence); } return true; } diff --git a/src/terminal/input/mouseInputState.cpp b/src/terminal/input/mouseInputState.cpp index b1c2509de..bf94794c5 100644 --- a/src/terminal/input/mouseInputState.cpp +++ b/src/terminal/input/mouseInputState.cpp @@ -7,91 +7,6 @@ using namespace Microsoft::Console::VirtualTerminal; -// Routine Description: -// - Either enables or disables UTF-8 extended mode encoding. This *should* cause -// the coordinates of a mouse event to be encoded as a UTF-8 byte stream, however, because windows' input is -// typically UTF-16 encoded, it emits a UTF-16 stream. -// Does NOT enable or disable mouse mode by itself. This matches the behavior I found in Ubuntu terminals. -// Parameters: -// - enable - either enable or disable. -// Return value: -// -void TerminalInput::SetUtf8ExtendedMode(const bool enable) noexcept -{ - _mouseInputState.extendedMode = enable ? ExtendedMode::Utf8 : ExtendedMode::None; -} - -// Routine Description: -// - Either enables or disables SGR extended mode encoding. This causes the -// coordinates of a mouse event to be emitted in a human readable format, -// eg, x,y=203,504 -> "^[[ -void TerminalInput::SetSGRExtendedMode(const bool enable) noexcept -{ - _mouseInputState.extendedMode = enable ? ExtendedMode::Sgr : ExtendedMode::None; -} - -// Routine Description: -// - Either enables or disables mouse mode handling. Leaves the extended mode alone, -// so if we disable then re-enable mouse mode without toggling an extended mode, the mode will persist. -// Parameters: -// - enable - either enable or disable. -// Return value: -// -void TerminalInput::EnableDefaultTracking(const bool enable) noexcept -{ - _mouseInputState.trackingMode = enable ? TrackingMode::Default : TrackingMode::None; - _mouseInputState.lastPos = { -1, -1 }; // Clear out the last saved mouse position & button. - _mouseInputState.lastButton = 0; -} - -// Routine Description: -// - Either enables or disables ButtonEvent mouse handling. Button Event mode -// sends additional sequences when a button is pressed and the mouse changes character cells. -// Leaves the extended mode alone, so if we disable then re-enable mouse mode -// without toggling an extended mode, the mode will persist. -// Parameters: -// - enable - either enable or disable. -// Return value: -// -void TerminalInput::EnableButtonEventTracking(const bool enable) noexcept -{ - _mouseInputState.trackingMode = enable ? TrackingMode::ButtonEvent : TrackingMode::None; - _mouseInputState.lastPos = { -1, -1 }; // Clear out the last saved mouse position & button. - _mouseInputState.lastButton = 0; -} - -// Routine Description: -// - Either enables or disables AnyEvent mouse handling. Any Event mode sends sequences -// for any and every mouse event, regardless if a button is pressed or not. -// Leaves the extended mode alone, so if we disable then re-enable mouse mode -// without toggling an extended mode, the mode will persist. -// Parameters: -// - enable - either enable or disable. -// Return value: -// -void TerminalInput::EnableAnyEventTracking(const bool enable) noexcept -{ - _mouseInputState.trackingMode = enable ? TrackingMode::AnyEvent : TrackingMode::None; - _mouseInputState.lastPos = { -1, -1 }; // Clear out the last saved mouse position & button. - _mouseInputState.lastButton = 0; -} - -// Routine Description: -// - Enables alternate scroll mode. This sends Cursor Up/down sequences when in the alternate buffer -// Parameters: -// - enable - either enable or disable. -// Return value: -// -void TerminalInput::EnableAlternateScroll(const bool enable) noexcept -{ - _mouseInputState.alternateScroll = enable; -} - // Routine Description: // - Notify the MouseInput handler that the screen buffer has been swapped to the alternate buffer // Parameters: diff --git a/src/terminal/input/terminalInput.cpp b/src/terminal/input/terminalInput.cpp index 7430345b4..2d66699de 100644 --- a/src/terminal/input/terminalInput.cpp +++ b/src/terminal/input/terminalInput.cpp @@ -250,25 +250,32 @@ const wchar_t* const CTRL_QUESTIONMARK_SEQUENCE = L"\x7F"; const wchar_t* const CTRL_ALT_SLASH_SEQUENCE = L"\x1b\x1f"; const wchar_t* const CTRL_ALT_QUESTIONMARK_SEQUENCE = L"\x1b\x7F"; -void TerminalInput::ChangeAnsiMode(const bool ansiMode) noexcept +void TerminalInput::SetInputMode(const Mode mode, const bool enabled) { - _ansiMode = ansiMode; + // If we're changing a tracking mode, we always clear other tracking modes first. + // We also clear out the last saved mouse position & button. + if (mode == Mode::DefaultMouseTracking || mode == Mode::ButtonEventMouseTracking || mode == Mode::AnyEventMouseTracking) + { + _inputMode.reset_all(Mode::DefaultMouseTracking, Mode::ButtonEventMouseTracking, Mode::AnyEventMouseTracking); + _mouseInputState.lastPos = { -1, -1 }; + _mouseInputState.lastButton = 0; + } + + // But if we're changing the encoding, we only clear out the other encoding modes + // when enabling a new encoding - not when disabling. + if ((mode == Mode::Utf8MouseEncoding || mode == Mode::SgrMouseEncoding) && enabled) + { + _inputMode.reset_all(Mode::Utf8MouseEncoding, Mode::SgrMouseEncoding); + } + + _inputMode.set(mode, enabled); } -void TerminalInput::ChangeKeypadMode(const bool applicationMode) noexcept +bool TerminalInput::GetInputMode(const Mode mode) const { - _keypadApplicationMode = applicationMode; + return _inputMode.test(mode); } -void TerminalInput::ChangeCursorKeysMode(const bool applicationMode) noexcept -{ - _cursorApplicationMode = applicationMode; -} - -void TerminalInput::ChangeWin32InputMode(const bool win32InputMode) noexcept -{ - _win32InputMode = win32InputMode; -} void TerminalInput::ForceDisableWin32InputMode(const bool win32InputMode) noexcept { _forceDisableWin32InputMode = win32InputMode; @@ -530,7 +537,7 @@ bool TerminalInput::HandleKey(const IInputEvent* const pInEvent) // 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. // Only do this if win32-input-mode support isn't manually disabled. - if (_win32InputMode && !_forceDisableWin32InputMode) + if (_inputMode.test(Mode::Win32) && !_forceDisableWin32InputMode) { const auto seq = _GenerateWin32KeySequence(keyEvent); _SendInputSequence(seq); @@ -655,7 +662,7 @@ bool TerminalInput::HandleKey(const IInputEvent* const pInEvent) // Check any other key mappings (like those for the F1-F12 keys). // These mappings will kick in no matter which modifiers are pressed and as such // must be checked last, or otherwise we'd override more complex key combinations. - const auto mapping = _getKeyMapping(keyEvent, _ansiMode, _cursorApplicationMode, _keypadApplicationMode); + const auto mapping = _getKeyMapping(keyEvent, _inputMode.test(Mode::Ansi), _inputMode.test(Mode::CursorKey), _inputMode.test(Mode::Keypad)); if (_translateDefaultMapping(keyEvent, mapping, senderFunc)) { return true; diff --git a/src/terminal/input/terminalInput.hpp b/src/terminal/input/terminalInput.hpp index 0405ecca3..cb01937f9 100644 --- a/src/terminal/input/terminalInput.hpp +++ b/src/terminal/input/terminalInput.hpp @@ -34,11 +34,26 @@ namespace Microsoft::Console::VirtualTerminal ~TerminalInput() = default; bool HandleKey(const IInputEvent* const pInEvent); - void ChangeAnsiMode(const bool ansiMode) noexcept; - void ChangeKeypadMode(const bool applicationMode) noexcept; - void ChangeCursorKeysMode(const bool applicationMode) noexcept; - void ChangeWin32InputMode(const bool win32InputMode) noexcept; + enum class Mode : size_t + { + Ansi, + Keypad, + CursorKey, + Win32, + + Utf8MouseEncoding, + SgrMouseEncoding, + + DefaultMouseTracking, + ButtonEventMouseTracking, + AnyEventMouseTracking, + + AlternateScroll + }; + + void SetInputMode(const Mode mode, const bool enabled); + bool GetInputMode(const Mode mode) const; void ForceDisableWin32InputMode(const bool win32InputMode) noexcept; #pragma region MouseInput @@ -62,14 +77,6 @@ namespace Microsoft::Console::VirtualTerminal #pragma region MouseInputState Management // These methods are defined in mouseInputState.cpp - void SetUtf8ExtendedMode(const bool enable) noexcept; - void SetSGRExtendedMode(const bool enable) noexcept; - - void EnableDefaultTracking(const bool enable) noexcept; - void EnableButtonEventTracking(const bool enable) noexcept; - void EnableAnyEventTracking(const bool enable) noexcept; - - void EnableAlternateScroll(const bool enable) noexcept; void UseAlternateScreenBuffer() noexcept; void UseMainScreenBuffer() noexcept; #pragma endregion @@ -80,10 +87,7 @@ namespace Microsoft::Console::VirtualTerminal // storage location for the leading surrogate of a utf-16 surrogate pair std::optional _leadingSurrogate; - bool _ansiMode{ true }; - bool _keypadApplicationMode{ false }; - bool _cursorApplicationMode{ false }; - bool _win32InputMode{ false }; + til::enumset _inputMode{ Mode::Ansi }; bool _forceDisableWin32InputMode{ false }; void _SendChar(const wchar_t ch); @@ -94,27 +98,8 @@ namespace Microsoft::Console::VirtualTerminal #pragma region MouseInputState Management // These methods are defined in mouseInputState.cpp - enum class ExtendedMode : unsigned int - { - None, - Utf8, - Sgr, - Urxvt - }; - - enum class TrackingMode : unsigned int - { - None, - Default, - ButtonEvent, - AnyEvent - }; - struct MouseInputState { - ExtendedMode extendedMode{ ExtendedMode::None }; - TrackingMode trackingMode{ TrackingMode::None }; - bool alternateScroll{ false }; bool inAlternateBuffer{ false }; COORD lastPos{ -1, -1 }; unsigned int lastButton{ 0 }; @@ -142,8 +127,8 @@ namespace Microsoft::Console::VirtualTerminal const short modifierKeyState, const short delta); - bool _ShouldSendAlternateScroll(const unsigned int button, const short delta) const noexcept; - bool _SendAlternateScroll(const short delta) const noexcept; + bool _ShouldSendAlternateScroll(const unsigned int button, const short delta) const; + bool _SendAlternateScroll(const short delta) const; static constexpr unsigned int s_GetPressedButton(const MouseButtonState state) noexcept; #pragma endregion