[Conpty] Pass through request for mouse mode to the Terminal (#9970)

<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
When the client application sets the console input mode with the `ENABLE_MOUSE_INPUT` flag, we send along the appropriate VT sequences to the connected terminal (if there is one).

<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> 
## References
#376 
#6859 

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [ ] Closes #xxx
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I work here

<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Far manager works
This commit is contained in:
PankajBhojwani 2021-05-06 19:46:11 -07:00 committed by GitHub
parent f518235599
commit b3775bc2b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 0 deletions

View file

@ -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();
}

View file

@ -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);

View file

@ -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

View file

@ -26,6 +26,8 @@ Revision History:
#include "../server/ObjectHeader.h"
#include "../terminal/input/terminalInput.hpp"
#include "../inc/ITerminalOutputConnection.hpp"
#include <deque>
class InputBuffer final : public ConsoleObjectHeader
@ -75,12 +77,15 @@ public:
bool IsInVirtualTerminalInputMode() const;
Microsoft::Console::VirtualTerminal::TerminalInput& GetTerminalInput();
void SetTerminalConnection(_In_ Microsoft::Console::ITerminalOutputConnection* const pTtyConnection);
void PassThroughWin32MouseRequest(bool enable);
private:
std::deque<std::unique_ptr<IInputEvent>> _storage;
std::unique_ptr<IInputEvent> _readPartialByteSequence;
std::unique_ptr<IInputEvent> _writePartialByteSequence;
Microsoft::Console::VirtualTerminal::TerminalInput _termInput;
Microsoft::Console::ITerminalOutputConnection* _pTtyConnection;
// This flag is used in _HandleTerminalInputCallback
// If the InputBuffer leads to a _HandleTerminalInputCallback call,