Pass mouse button state into HandleMouse instead of asking win32 (#6765)
MouseInput was directly asking user32 about the state of the mouse buttons, which was somewhat of a layering violation. This commit makes all callers have to pass the mouse state in themselves. Closes #4869
This commit is contained in:
parent
70fd03f247
commit
20a288020e
|
@ -16,6 +16,10 @@ using namespace ::Microsoft::Terminal::Core;
|
|||
|
||||
static LPCWSTR term_window_class = L"HwndTerminalClass";
|
||||
|
||||
// This magic flag is "documented" at https://msdn.microsoft.com/en-us/library/windows/desktop/ms646301(v=vs.85).aspx
|
||||
// "If the high-order bit is 1, the key is down; otherwise, it is up."
|
||||
static constexpr short KeyPressed{ gsl::narrow_cast<short>(0x8000) };
|
||||
|
||||
static constexpr bool _IsMouseMessage(UINT uMsg)
|
||||
{
|
||||
return uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP || uMsg == WM_LBUTTONDBLCLK ||
|
||||
|
@ -645,7 +649,13 @@ try
|
|||
cursorPosition = coordsToTransform;
|
||||
}
|
||||
|
||||
return _terminal->SendMouseEvent(cursorPosition / fontSize, uMsg, getControlKeyState(), wheelDelta);
|
||||
const TerminalInput::MouseButtonState state{
|
||||
WI_IsFlagSet(GetKeyState(VK_LBUTTON), KeyPressed),
|
||||
WI_IsFlagSet(GetKeyState(VK_MBUTTON), KeyPressed),
|
||||
WI_IsFlagSet(GetKeyState(VK_RBUTTON), KeyPressed)
|
||||
};
|
||||
|
||||
return _terminal->SendMouseEvent(cursorPosition / fontSize, uMsg, getControlKeyState(), wheelDelta, state);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
|
|
@ -11,6 +11,6 @@ namespace Microsoft.Terminal.TerminalControl
|
|||
[uuid("65b8b8c5-988f-43ff-aba9-e89368da1598")]
|
||||
interface IMouseWheelListener
|
||||
{
|
||||
Boolean OnMouseWheel(Windows.Foundation.Point coord, Int32 delta);
|
||||
Boolean OnMouseWheel(Windows.Foundation.Point coord, Int32 delta, Boolean leftButtonDown, Boolean midButtonDown, Boolean rightButtonDown);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "TermControlAutomationPeer.h"
|
||||
|
||||
using namespace ::Microsoft::Console::Types;
|
||||
using namespace ::Microsoft::Console::VirtualTerminal;
|
||||
using namespace ::Microsoft::Terminal::Core;
|
||||
using namespace winrt::Windows::Graphics::Display;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
|
@ -1007,7 +1008,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
}
|
||||
|
||||
const auto modifiers = _GetPressedModifierKeys();
|
||||
return _terminal->SendMouseEvent(terminalPosition, uiButton, modifiers, sWheelDelta);
|
||||
const TerminalInput::MouseButtonState state{ props.IsLeftButtonPressed(), props.IsMiddleButtonPressed(), props.IsRightButtonPressed() };
|
||||
return _terminal->SendMouseEvent(terminalPosition, uiButton, modifiers, sWheelDelta, state);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
@ -1331,10 +1333,12 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
}
|
||||
|
||||
const auto point = args.GetCurrentPoint(*this);
|
||||
const auto props = point.Properties();
|
||||
const TerminalInput::MouseButtonState state{ props.IsLeftButtonPressed(), props.IsMiddleButtonPressed(), props.IsRightButtonPressed() };
|
||||
auto result = _DoMouseWheel(point.Position(),
|
||||
ControlKeyStates{ args.KeyModifiers() },
|
||||
point.Properties().MouseWheelDelta(),
|
||||
point.Properties().IsLeftButtonPressed());
|
||||
state);
|
||||
if (result)
|
||||
{
|
||||
args.Handled(true);
|
||||
|
@ -1357,7 +1361,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
bool TermControl::_DoMouseWheel(const Windows::Foundation::Point point,
|
||||
const ControlKeyStates modifiers,
|
||||
const int32_t delta,
|
||||
const bool isLeftButtonPressed)
|
||||
const TerminalInput::MouseButtonState state)
|
||||
{
|
||||
if (_CanSendVTMouseInput())
|
||||
{
|
||||
|
@ -1369,7 +1373,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
return _terminal->SendMouseEvent(_GetTerminalPosition(point),
|
||||
WM_MOUSEWHEEL,
|
||||
_GetPressedModifierKeys(),
|
||||
::base::saturated_cast<short>(delta));
|
||||
::base::saturated_cast<short>(delta),
|
||||
state);
|
||||
}
|
||||
|
||||
const auto ctrlPressed = modifiers.IsCtrlPressed();
|
||||
|
@ -1385,7 +1390,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
}
|
||||
else
|
||||
{
|
||||
_MouseScrollHandler(delta, point, isLeftButtonPressed);
|
||||
_MouseScrollHandler(delta, point, state.isLeftButtonDown);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1399,11 +1404,16 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
// - location: the location of the mouse during this event. This location is
|
||||
// relative to the origin of the control
|
||||
// - delta: the mouse wheel delta that triggered this event.
|
||||
// - state: the state for each of the mouse buttons individually (pressed/unpressed)
|
||||
bool TermControl::OnMouseWheel(const Windows::Foundation::Point location,
|
||||
const int32_t delta)
|
||||
const int32_t delta,
|
||||
const bool leftButtonDown,
|
||||
const bool midButtonDown,
|
||||
const bool rightButtonDown)
|
||||
{
|
||||
const auto modifiers = _GetPressedModifierKeys();
|
||||
return _DoMouseWheel(location, modifiers, delta, false);
|
||||
TerminalInput::MouseButtonState state{ leftButtonDown, midButtonDown, rightButtonDown };
|
||||
return _DoMouseWheel(location, modifiers, delta, state);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
#include "SearchBoxControl.h"
|
||||
#include "ThrottledFunc.h"
|
||||
|
||||
namespace Microsoft::Console::VirtualTerminal
|
||||
{
|
||||
struct MouseButtonState;
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
||||
{
|
||||
struct CopyToClipboardEventArgs :
|
||||
|
@ -87,7 +92,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
|
||||
bool OnDirectKeyEvent(const uint32_t vkey, const bool down);
|
||||
|
||||
bool OnMouseWheel(const Windows::Foundation::Point location, const int32_t delta);
|
||||
bool OnMouseWheel(const Windows::Foundation::Point location, const int32_t delta, const bool leftButtonDown, const bool midButtonDown, const bool rightButtonDown);
|
||||
|
||||
~TermControl();
|
||||
|
||||
|
@ -230,7 +235,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation
|
|||
void _MouseScrollHandler(const double mouseDelta, const Windows::Foundation::Point point, const bool isLeftButtonPressed);
|
||||
void _MouseZoomHandler(const double delta);
|
||||
void _MouseTransparencyHandler(const double delta);
|
||||
bool _DoMouseWheel(const Windows::Foundation::Point point, const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const int32_t delta, const bool isLeftButtonPressed);
|
||||
bool _DoMouseWheel(const Windows::Foundation::Point point, const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const int32_t delta, const ::Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state);
|
||||
|
||||
bool _CapturePointer(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e);
|
||||
bool _ReleasePointerCapture(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs const& e);
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Microsoft::Terminal::Core
|
|||
ITerminalInput& operator=(ITerminalInput&&) = default;
|
||||
|
||||
virtual bool SendKeyEvent(const WORD vkey, const WORD scanCode, const ControlKeyStates states, const bool keyDown) = 0;
|
||||
virtual bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta) = 0;
|
||||
virtual bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) = 0;
|
||||
virtual bool SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) = 0;
|
||||
|
||||
// void SendMouseEvent(uint row, uint col, KeyModifiers modifiers);
|
||||
|
|
|
@ -510,7 +510,7 @@ bool Terminal::SendKeyEvent(const WORD vkey,
|
|||
// Return Value:
|
||||
// - true if we translated the key event, and it should not be processed any further.
|
||||
// - false if we did not translate the key, and it should be processed into a character.
|
||||
bool Terminal::SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta)
|
||||
bool Terminal::SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const TerminalInput::MouseButtonState state)
|
||||
{
|
||||
// GH#6401: VT applications should be able to receive mouse events from outside the
|
||||
// terminal buffer. This is likely to happen when the user drags the cursor offscreen.
|
||||
|
@ -519,7 +519,7 @@ bool Terminal::SendMouseEvent(const COORD viewportPos, const unsigned int uiButt
|
|||
#pragma warning(suppress : 26496) // analysis can't tell we're assigning through a reference below
|
||||
auto clampedPos{ viewportPos };
|
||||
_mutableViewport.ToOrigin().Clamp(clampedPos);
|
||||
return _terminalInput->HandleMouse(clampedPos, uiButton, GET_KEYSTATE_WPARAM(states.Value()), wheelDelta);
|
||||
return _terminalInput->HandleMouse(clampedPos, uiButton, GET_KEYSTATE_WPARAM(states.Value()), wheelDelta, state);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
|
|
@ -116,7 +116,7 @@ public:
|
|||
#pragma region ITerminalInput
|
||||
// These methods are defined in Terminal.cpp
|
||||
bool SendKeyEvent(const WORD vkey, const WORD scanCode, const Microsoft::Terminal::Core::ControlKeyStates states, const bool keyDown) override;
|
||||
bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta) override;
|
||||
bool SendMouseEvent(const COORD viewportPos, const unsigned int uiButton, const ControlKeyStates states, const short wheelDelta, const Microsoft::Console::VirtualTerminal::TerminalInput::MouseButtonState state) override;
|
||||
bool SendCharEvent(const wchar_t ch, const WORD scanCode, const ControlKeyStates states) override;
|
||||
|
||||
[[nodiscard]] HRESULT UserResize(const COORD viewportSize) noexcept override;
|
||||
|
|
|
@ -17,6 +17,10 @@ using namespace winrt::Windows::Foundation::Numerics;
|
|||
using namespace ::Microsoft::Console;
|
||||
using namespace ::Microsoft::Console::Types;
|
||||
|
||||
// This magic flag is "documented" at https://msdn.microsoft.com/en-us/library/windows/desktop/ms646301(v=vs.85).aspx
|
||||
// "If the high-order bit is 1, the key is down; otherwise, it is up."
|
||||
static constexpr short KeyPressed{ gsl::narrow_cast<short>(0x8000) };
|
||||
|
||||
AppHost::AppHost() noexcept :
|
||||
_app{},
|
||||
_logic{ nullptr }, // don't make one, we're going to take a ref on app's
|
||||
|
@ -405,7 +409,11 @@ void AppHost::_WindowMouseWheeled(const til::point coord, const int32_t delta)
|
|||
|
||||
const til::point offsetPoint = coord - controlOrigin;
|
||||
|
||||
if (control.OnMouseWheel(offsetPoint, delta))
|
||||
const auto lButtonDown = WI_IsFlagSet(GetKeyState(VK_LBUTTON), KeyPressed);
|
||||
const auto mButtonDown = WI_IsFlagSet(GetKeyState(VK_MBUTTON), KeyPressed);
|
||||
const auto rButtonDown = WI_IsFlagSet(GetKeyState(VK_RBUTTON), KeyPressed);
|
||||
|
||||
if (control.OnMouseWheel(offsetPoint, delta, lButtonDown, mButtonDown, rButtonDown))
|
||||
{
|
||||
// If the element handled the mouse wheel event, don't
|
||||
// continue to iterate over the remaining controls.
|
||||
|
|
|
@ -23,12 +23,17 @@
|
|||
#pragma hdrstop
|
||||
|
||||
using namespace Microsoft::Console::Interactivity::Win32;
|
||||
using namespace Microsoft::Console::VirtualTerminal;
|
||||
using Microsoft::Console::Interactivity::ServiceLocator;
|
||||
// For usage with WM_SYSKEYDOWN message processing.
|
||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms646286(v=vs.85).aspx
|
||||
// Bit 29 is whether ALT was held when the message was posted.
|
||||
#define WM_SYSKEYDOWN_ALT_PRESSED (0x20000000)
|
||||
|
||||
// This magic flag is "documented" at https://msdn.microsoft.com/en-us/library/windows/desktop/ms646301(v=vs.85).aspx
|
||||
// "If the high-order bit is 1, the key is down; otherwise, it is up."
|
||||
static constexpr short KeyPressed{ gsl::narrow_cast<short>(0x8000) };
|
||||
|
||||
// ----------------------------
|
||||
// Helpers
|
||||
// ----------------------------
|
||||
|
@ -123,6 +128,12 @@ bool HandleTerminalMouseEvent(const COORD cMousePosition,
|
|||
// Virtual terminal input mode
|
||||
if (IsInVirtualTerminalInputMode())
|
||||
{
|
||||
const TerminalInput::MouseButtonState state{
|
||||
WI_IsFlagSet(GetKeyState(VK_LBUTTON), KeyPressed),
|
||||
WI_IsFlagSet(GetKeyState(VK_MBUTTON), KeyPressed),
|
||||
WI_IsFlagSet(GetKeyState(VK_RBUTTON), KeyPressed)
|
||||
};
|
||||
|
||||
// GH#6401: VT applications should be able to receive mouse events from outside the
|
||||
// terminal buffer. This is likely to happen when the user drags the cursor offscreen.
|
||||
// We shouldn't throw away perfectly good events when they're offscreen, so we just
|
||||
|
@ -130,7 +141,7 @@ bool HandleTerminalMouseEvent(const COORD cMousePosition,
|
|||
auto clampedPosition{ cMousePosition };
|
||||
const auto clampViewport{ gci.GetActiveOutputBuffer().GetViewport().ToOrigin() };
|
||||
clampViewport.Clamp(clampedPosition);
|
||||
fWasHandled = gci.GetActiveInputBuffer()->GetTerminalInput().HandleMouse(clampedPosition, uiButton, sModifierKeystate, sWheelDelta);
|
||||
fWasHandled = gci.GetActiveInputBuffer()->GetTerminalInput().HandleMouse(clampedPosition, uiButton, sModifierKeystate, sWheelDelta, state);
|
||||
}
|
||||
|
||||
return fWasHandled;
|
||||
|
|
|
@ -292,7 +292,7 @@ public:
|
|||
|
||||
bool fExpectedKeyHandled = false;
|
||||
s_pwszInputExpected = L"\x0";
|
||||
VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta));
|
||||
VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta, {}));
|
||||
|
||||
mouseInput->EnableDefaultTracking(true);
|
||||
|
||||
|
@ -309,7 +309,8 @@ public:
|
|||
mouseInput->HandleMouse(Coord,
|
||||
uiButton,
|
||||
sModifierKeystate,
|
||||
sScrollDelta),
|
||||
sScrollDelta,
|
||||
{}),
|
||||
NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y));
|
||||
}
|
||||
|
||||
|
@ -327,7 +328,8 @@ public:
|
|||
mouseInput->HandleMouse(Coord,
|
||||
uiButton,
|
||||
sModifierKeystate,
|
||||
sScrollDelta),
|
||||
sScrollDelta,
|
||||
{}),
|
||||
NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y));
|
||||
}
|
||||
|
||||
|
@ -345,7 +347,8 @@ public:
|
|||
mouseInput->HandleMouse(Coord,
|
||||
uiButton,
|
||||
sModifierKeystate,
|
||||
sScrollDelta),
|
||||
sScrollDelta,
|
||||
{}),
|
||||
NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y));
|
||||
}
|
||||
}
|
||||
|
@ -371,7 +374,7 @@ public:
|
|||
|
||||
bool fExpectedKeyHandled = false;
|
||||
s_pwszInputExpected = L"\x0";
|
||||
VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta));
|
||||
VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta, {}));
|
||||
|
||||
mouseInput->SetUtf8ExtendedMode(true);
|
||||
|
||||
|
@ -391,7 +394,8 @@ public:
|
|||
mouseInput->HandleMouse(Coord,
|
||||
uiButton,
|
||||
sModifierKeystate,
|
||||
sScrollDelta),
|
||||
sScrollDelta,
|
||||
{}),
|
||||
NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y));
|
||||
}
|
||||
|
||||
|
@ -409,7 +413,8 @@ public:
|
|||
mouseInput->HandleMouse(Coord,
|
||||
uiButton,
|
||||
sModifierKeystate,
|
||||
sScrollDelta),
|
||||
sScrollDelta,
|
||||
{}),
|
||||
NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y));
|
||||
}
|
||||
|
||||
|
@ -427,7 +432,8 @@ public:
|
|||
mouseInput->HandleMouse(Coord,
|
||||
uiButton,
|
||||
sModifierKeystate,
|
||||
sScrollDelta),
|
||||
sScrollDelta,
|
||||
{}),
|
||||
NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y));
|
||||
}
|
||||
}
|
||||
|
@ -453,7 +459,7 @@ public:
|
|||
|
||||
bool fExpectedKeyHandled = false;
|
||||
s_pwszInputExpected = L"\x0";
|
||||
VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta));
|
||||
VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta, {}));
|
||||
|
||||
mouseInput->SetSGRExtendedMode(true);
|
||||
|
||||
|
@ -471,7 +477,7 @@ public:
|
|||
|
||||
// validate translation
|
||||
VERIFY_ARE_EQUAL(fExpectedKeyHandled,
|
||||
mouseInput->HandleMouse(Coord, uiButton, sModifierKeystate, sScrollDelta),
|
||||
mouseInput->HandleMouse(Coord, uiButton, sModifierKeystate, sScrollDelta, {}),
|
||||
NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y));
|
||||
}
|
||||
|
||||
|
@ -488,7 +494,8 @@ public:
|
|||
mouseInput->HandleMouse(Coord,
|
||||
uiButton,
|
||||
sModifierKeystate,
|
||||
sScrollDelta),
|
||||
sScrollDelta,
|
||||
{}),
|
||||
NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y));
|
||||
}
|
||||
|
||||
|
@ -506,7 +513,8 @@ public:
|
|||
mouseInput->HandleMouse(Coord,
|
||||
uiButton,
|
||||
sModifierKeystate,
|
||||
sScrollDelta),
|
||||
sScrollDelta,
|
||||
{}),
|
||||
NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y));
|
||||
}
|
||||
}
|
||||
|
@ -532,7 +540,7 @@ public:
|
|||
|
||||
bool fExpectedKeyHandled = false;
|
||||
s_pwszInputExpected = L"\x0";
|
||||
VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta));
|
||||
VERIFY_ARE_EQUAL(fExpectedKeyHandled, mouseInput->HandleMouse({ 0, 0 }, uiButton, sModifierKeystate, sScrollDelta, {}));
|
||||
|
||||
// Default Tracking, Default Encoding
|
||||
mouseInput->EnableDefaultTracking(true);
|
||||
|
@ -550,7 +558,8 @@ public:
|
|||
mouseInput->HandleMouse(Coord,
|
||||
uiButton,
|
||||
sModifierKeystate,
|
||||
sScrollDelta),
|
||||
sScrollDelta,
|
||||
{}),
|
||||
NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y));
|
||||
}
|
||||
|
||||
|
@ -570,7 +579,8 @@ public:
|
|||
mouseInput->HandleMouse(Coord,
|
||||
uiButton,
|
||||
sModifierKeystate,
|
||||
sScrollDelta),
|
||||
sScrollDelta,
|
||||
{}),
|
||||
NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y));
|
||||
}
|
||||
|
||||
|
@ -589,7 +599,8 @@ public:
|
|||
mouseInput->HandleMouse(Coord,
|
||||
uiButton,
|
||||
sModifierKeystate,
|
||||
sScrollDelta),
|
||||
sScrollDelta,
|
||||
{}),
|
||||
NoThrowString().Format(L"(x,y)=(%d,%d)", Coord.X, Coord.Y));
|
||||
}
|
||||
}
|
||||
|
@ -606,31 +617,31 @@ public:
|
|||
|
||||
Log::Comment(L"Test mouse wheel scrolling up");
|
||||
s_pwszInputExpected = L"\x1B[A";
|
||||
VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, WHEEL_DELTA));
|
||||
VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, WHEEL_DELTA, {}));
|
||||
|
||||
Log::Comment(L"Test mouse wheel scrolling down");
|
||||
s_pwszInputExpected = L"\x1B[B";
|
||||
VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, -WHEEL_DELTA));
|
||||
VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, -WHEEL_DELTA, {}));
|
||||
|
||||
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, WHEEL_DELTA));
|
||||
VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, WHEEL_DELTA, {}));
|
||||
|
||||
Log::Comment(L"Test mouse wheel scrolling down");
|
||||
s_pwszInputExpected = L"\x1BOB";
|
||||
VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, -WHEEL_DELTA));
|
||||
VERIFY_IS_TRUE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, -WHEEL_DELTA, {}));
|
||||
|
||||
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, WHEEL_DELTA));
|
||||
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);
|
||||
VERIFY_IS_FALSE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, WHEEL_DELTA));
|
||||
VERIFY_IS_FALSE(mouseInput->HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, WHEEL_DELTA, {}));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -13,10 +13,6 @@ using namespace Microsoft::Console::VirtualTerminal;
|
|||
#endif
|
||||
static const int s_MaxDefaultCoordinate = 94;
|
||||
|
||||
// This magic flag is "documented" at https://msdn.microsoft.com/en-us/library/windows/desktop/ms646301(v=vs.85).aspx
|
||||
// "If the high-order bit is 1, the key is down; otherwise, it is up."
|
||||
static constexpr short KeyPressed{ gsl::narrow_cast<short>(0x8000) };
|
||||
|
||||
// Alternate scroll sequences
|
||||
static constexpr std::wstring_view CursorUpSequence{ L"\x1b[A" };
|
||||
static constexpr std::wstring_view CursorDownSequence{ L"\x1b[B" };
|
||||
|
@ -105,22 +101,22 @@ static constexpr bool _isButtonDown(const unsigned int button) noexcept
|
|||
// - Retrieves which mouse button is currently pressed. This is needed because
|
||||
// MOUSEMOVE events do not also tell us if any mouse buttons are pressed during the move.
|
||||
// Parameters:
|
||||
// <none>
|
||||
// - state - the current state of which mouse buttons are pressed
|
||||
// Return value:
|
||||
// - a button corresponding to any pressed mouse buttons, else WM_LBUTTONUP if none are pressed.
|
||||
unsigned int TerminalInput::s_GetPressedButton() noexcept
|
||||
constexpr unsigned int TerminalInput::s_GetPressedButton(const MouseButtonState state) noexcept
|
||||
{
|
||||
// TODO GH#4869: Have the caller pass the mouse button state into HandleMouse
|
||||
unsigned int button = WM_LBUTTONUP; // Will be treated as a release, or no button pressed.
|
||||
if (WI_IsFlagSet(GetKeyState(VK_LBUTTON), KeyPressed))
|
||||
// Will be treated as a release, or no button pressed.
|
||||
unsigned int button = WM_LBUTTONUP;
|
||||
if (state.isLeftButtonDown)
|
||||
{
|
||||
button = WM_LBUTTONDOWN;
|
||||
}
|
||||
else if (WI_IsFlagSet(GetKeyState(VK_MBUTTON), KeyPressed))
|
||||
else if (state.isMiddleButtonDown)
|
||||
{
|
||||
button = WM_MBUTTONDOWN;
|
||||
}
|
||||
else if (WI_IsFlagSet(GetKeyState(VK_RBUTTON), KeyPressed))
|
||||
else if (state.isRightButtonDown)
|
||||
{
|
||||
button = WM_RBUTTONDOWN;
|
||||
}
|
||||
|
@ -298,12 +294,14 @@ bool TerminalInput::IsTrackingMouseInput() const noexcept
|
|||
// - button - the message to decode.
|
||||
// - modifierKeyState - the modifier keys pressed with this button
|
||||
// - delta - the amount that the scroll wheel changed (should be 0 unless button is a WM_MOUSE*WHEEL)
|
||||
// - state - the state of the mouse buttons at this moment
|
||||
// Return value:
|
||||
// - true if the event was handled and we should stop event propagation to the default window handler.
|
||||
bool TerminalInput::HandleMouse(const COORD position,
|
||||
const unsigned int button,
|
||||
const short modifierKeyState,
|
||||
const short delta)
|
||||
const short delta,
|
||||
const MouseButtonState state)
|
||||
{
|
||||
if (Utils::Sign(delta) != Utils::Sign(_mouseInputState.accumulatedDelta))
|
||||
{
|
||||
|
@ -354,7 +352,7 @@ bool TerminalInput::HandleMouse(const COORD position,
|
|||
// _GetPressedButton will return the first pressed mouse button.
|
||||
// If it returns WM_LBUTTONUP, then we can assume that the mouse
|
||||
// moved without a button being pressed.
|
||||
const unsigned int realButton = isHover ? s_GetPressedButton() : button;
|
||||
const unsigned int realButton = isHover ? s_GetPressedButton(state) : button;
|
||||
|
||||
// In default mode, only button presses/releases are sent
|
||||
// In ButtonEvent mode, changing coord hovers WITH A BUTTON PRESSED
|
||||
|
|
|
@ -43,10 +43,19 @@ namespace Microsoft::Console::VirtualTerminal
|
|||
|
||||
#pragma region MouseInput
|
||||
// These methods are defined in mouseInput.cpp
|
||||
|
||||
struct MouseButtonState
|
||||
{
|
||||
bool isLeftButtonDown;
|
||||
bool isMiddleButtonDown;
|
||||
bool isRightButtonDown;
|
||||
};
|
||||
|
||||
bool HandleMouse(const COORD position,
|
||||
const unsigned int button,
|
||||
const short modifierKeyState,
|
||||
const short delta);
|
||||
const short delta,
|
||||
const MouseButtonState state);
|
||||
|
||||
bool IsTrackingMouseInput() const noexcept;
|
||||
#pragma endregion
|
||||
|
@ -136,7 +145,7 @@ namespace Microsoft::Console::VirtualTerminal
|
|||
bool _ShouldSendAlternateScroll(const unsigned int button, const short delta) const noexcept;
|
||||
bool _SendAlternateScroll(const short delta) const noexcept;
|
||||
|
||||
static unsigned int s_GetPressedButton() noexcept;
|
||||
static constexpr unsigned int s_GetPressedButton(const MouseButtonState state) noexcept;
|
||||
#pragma endregion
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue