diff --git a/src/host/VtIo.cpp b/src/host/VtIo.cpp index 17789de025f..f7ac039bc5c 100644 --- a/src/host/VtIo.cpp +++ b/src/host/VtIo.cpp @@ -213,6 +213,7 @@ bool VtIo::IsUsingVt() const { g.pRender->AddRenderEngine(_pVtRenderEngine.get()); g.getConsoleInformation().GetActiveOutputBuffer().SetTerminalConnection(_pVtRenderEngine.get()); + g.getConsoleInformation().GetActiveInputBuffer()->SetTerminalConnection(_pVtRenderEngine.get()); } CATCH_RETURN(); } diff --git a/src/host/getset.cpp b/src/host/getset.cpp index cbf3868897a..0b2ea53528c 100644 --- a/src/host/getset.cpp +++ b/src/host/getset.cpp @@ -334,6 +334,8 @@ void ApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept LockConsole(); auto Unlock = wil::scope_exit([&] { UnlockConsole(); }); + const auto oldQuickEditMode{ WI_IsFlagSet(gci.Flags, CONSOLE_QUICK_EDIT_MODE) }; + if (WI_IsAnyFlagSet(mode, PRIVATE_MODES)) { WI_SetFlag(gci.Flags, CONSOLE_USE_PRIVATE_FLAGS); @@ -357,6 +359,19 @@ void ApiRoutines::GetNumberOfConsoleMouseButtonsImpl(ULONG& buttons) noexcept WI_ClearFlag(gci.Flags, CONSOLE_USE_PRIVATE_FLAGS); } + const auto newQuickEditMode{ WI_IsFlagSet(gci.Flags, CONSOLE_QUICK_EDIT_MODE) }; + + // Mouse input should be received when mouse mode is on and quick edit mode is off + // (for more information regarding the quirks of mouse mode and why/how it relates + // to quick edit mode, see GH#9970) + const auto oldMouseMode{ !oldQuickEditMode && WI_IsFlagSet(context.InputMode, ENABLE_MOUSE_INPUT) }; + const auto newMouseMode{ !newQuickEditMode && WI_IsFlagSet(mode, ENABLE_MOUSE_INPUT) }; + + if (oldMouseMode != newMouseMode) + { + gci.GetActiveInputBuffer()->PassThroughWin32MouseRequest(newMouseMode); + } + context.InputMode = mode; WI_ClearAllFlags(context.InputMode, PRIVATE_MODES); diff --git a/src/host/inputBuffer.cpp b/src/host/inputBuffer.cpp index 9b8001723a3..0c855a894af 100644 --- a/src/host/inputBuffer.cpp +++ b/src/host/inputBuffer.cpp @@ -15,6 +15,7 @@ using Microsoft::Console::Interactivity::ServiceLocator; using Microsoft::Console::VirtualTerminal::TerminalInput; +using namespace Microsoft::Console; // Routine Description: // - This method creates an input buffer. @@ -25,6 +26,7 @@ using Microsoft::Console::VirtualTerminal::TerminalInput; InputBuffer::InputBuffer() : InputMode{ INPUT_BUFFER_DEFAULT_INPUT_MODE }, WaitQueue{}, + _pTtyConnection(nullptr), _termInput(std::bind(&InputBuffer::_HandleTerminalInputCallback, this, std::placeholders::_1)) { // The _termInput's constructor takes a reference to this object's _HandleTerminalInputCallback. @@ -218,6 +220,26 @@ void InputBuffer::FlushAllButKeys() _storage.erase(newEnd, _storage.end()); } +void InputBuffer::SetTerminalConnection(_In_ ITerminalOutputConnection* const pTtyConnection) +{ + this->_pTtyConnection = pTtyConnection; +} + +void InputBuffer::PassThroughWin32MouseRequest(bool enable) +{ + if (_pTtyConnection) + { + if (enable) + { + LOG_IF_FAILED(_pTtyConnection->WriteTerminalW(L"\x1b[?1003;1006h")); + } + else + { + LOG_IF_FAILED(_pTtyConnection->WriteTerminalW(L"\x1b[?1003;1006l")); + } + } +} + // Routine Description: // - This routine reads from the input buffer. // - It can convert returned data to through the currently set Input CP, it can optionally return a wait condition diff --git a/src/host/inputBuffer.hpp b/src/host/inputBuffer.hpp index 401e956c53e..fabdadee173 100644 --- a/src/host/inputBuffer.hpp +++ b/src/host/inputBuffer.hpp @@ -26,6 +26,8 @@ Revision History: #include "../server/ObjectHeader.h" #include "../terminal/input/terminalInput.hpp" +#include "../inc/ITerminalOutputConnection.hpp" + #include class InputBuffer final : public ConsoleObjectHeader @@ -75,12 +77,15 @@ class InputBuffer final : public ConsoleObjectHeader bool IsInVirtualTerminalInputMode() const; Microsoft::Console::VirtualTerminal::TerminalInput& GetTerminalInput(); + void SetTerminalConnection(_In_ Microsoft::Console::ITerminalOutputConnection* const pTtyConnection); + void PassThroughWin32MouseRequest(bool enable); private: std::deque> _storage; std::unique_ptr _readPartialByteSequence; std::unique_ptr _writePartialByteSequence; Microsoft::Console::VirtualTerminal::TerminalInput _termInput; + Microsoft::Console::ITerminalOutputConnection* _pTtyConnection; // This flag is used in _HandleTerminalInputCallback // If the InputBuffer leads to a _HandleTerminalInputCallback call,