mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-10 00:48:23 -06:00
Add support for VT horizontal mouse wheel events (#19248)
This adds support for horizontal mouse wheel events (`WM_MOUSEHWHEEL`). With this change, applications running in the terminal can now receive and respond to horizontal scroll inputs from the mouse/trackpad. Closes #19245 Closes #10329
This commit is contained in:
parent
eb16eb26ab
commit
814f78ed2c
@ -485,7 +485,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - modifiers: The modifiers pressed during this event, in the form of a VirtualKeyModifiers
|
||||
// - delta: the mouse wheel delta that triggered this event.
|
||||
bool ControlInteractivity::MouseWheel(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||
const int32_t delta,
|
||||
const Core::Point delta,
|
||||
const Core::Point pixelPosition,
|
||||
const Control::MouseButtonState buttonState)
|
||||
{
|
||||
@ -506,9 +506,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// PointerPoint to work with. So, we're just going to do a
|
||||
// mousewheel event manually
|
||||
return _sendMouseEventHelper(terminalPosition,
|
||||
WM_MOUSEWHEEL,
|
||||
delta.Y != 0 ? WM_MOUSEWHEEL : WM_MOUSEHWHEEL,
|
||||
modifiers,
|
||||
::base::saturated_cast<short>(delta),
|
||||
::base::saturated_cast<short>(delta.Y != 0 ? delta.Y : delta.X),
|
||||
buttonState);
|
||||
}
|
||||
|
||||
@ -517,15 +517,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
if (ctrlPressed && shiftPressed && _core->Settings().ScrollToChangeOpacity())
|
||||
{
|
||||
_mouseTransparencyHandler(delta);
|
||||
_mouseTransparencyHandler(delta.Y);
|
||||
}
|
||||
else if (ctrlPressed && !shiftPressed && _core->Settings().ScrollToZoom())
|
||||
{
|
||||
_mouseZoomHandler(delta);
|
||||
_mouseZoomHandler(delta.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
_mouseScrollHandler(delta, pixelPosition, WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown));
|
||||
_mouseScrollHandler(delta.Y, pixelPosition, WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -659,7 +659,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return _core->IsVtMouseModeEnabled();
|
||||
}
|
||||
|
||||
bool ControlInteractivity::_shouldSendAlternateScroll(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const int32_t delta)
|
||||
bool ControlInteractivity::_shouldSendAlternateScroll(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const Core::Point delta)
|
||||
{
|
||||
// If the user is holding down Shift, suppress mouse events
|
||||
// TODO GH#4875: disable/customize this functionality
|
||||
@ -667,7 +667,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return _core->ShouldSendAlternateScroll(WM_MOUSEWHEEL, delta);
|
||||
if (delta.Y != 0)
|
||||
{
|
||||
return _core->ShouldSendAlternateScroll(WM_MOUSEWHEEL, delta.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _core->ShouldSendAlternateScroll(WM_MOUSEHWHEEL, delta.X);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@ -74,7 +74,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void TouchReleased();
|
||||
|
||||
bool MouseWheel(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers,
|
||||
const int32_t delta,
|
||||
const Core::Point delta,
|
||||
const Core::Point pixelPosition,
|
||||
const Control::MouseButtonState state);
|
||||
|
||||
@ -153,7 +153,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
void _hyperlinkHandler(const std::wstring_view uri);
|
||||
bool _canSendVTMouseInput(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers);
|
||||
bool _shouldSendAlternateScroll(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const int32_t delta);
|
||||
bool _shouldSendAlternateScroll(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const Core::Point delta);
|
||||
|
||||
til::point _getTerminalPosition(const til::point pixelPosition, bool roundToNearestCell);
|
||||
|
||||
|
||||
@ -60,7 +60,7 @@ namespace Microsoft.Terminal.Control
|
||||
void TouchReleased();
|
||||
|
||||
Boolean MouseWheel(Microsoft.Terminal.Core.ControlKeyStates modifiers,
|
||||
Int32 delta,
|
||||
Microsoft.Terminal.Core.Point delta,
|
||||
Microsoft.Terminal.Core.Point pixelPosition,
|
||||
MouseButtonState state);
|
||||
|
||||
|
||||
@ -11,6 +11,6 @@ namespace Microsoft.Terminal.Control
|
||||
[uuid("65b8b8c5-988f-43ff-aba9-e89368da1598")]
|
||||
interface IMouseWheelListener
|
||||
{
|
||||
Boolean OnMouseWheel(Windows.Foundation.Point coord, Int32 delta, Boolean leftButtonDown, Boolean midButtonDown, Boolean rightButtonDown);
|
||||
Boolean OnMouseWheel(Windows.Foundation.Point coord, Microsoft.Terminal.Core.Point delta, Boolean leftButtonDown, Boolean midButtonDown, Boolean rightButtonDown);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2160,15 +2160,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
RestorePointerCursor.raise(*this, nullptr);
|
||||
|
||||
const auto point = args.GetCurrentPoint(*this);
|
||||
// GH#10329 - we don't need to handle horizontal scrolls. Only vertical ones.
|
||||
// So filter out the horizontal ones.
|
||||
if (point.Properties().IsHorizontalMouseWheel())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto delta = point.Properties().MouseWheelDelta();
|
||||
auto result = _interactivity.MouseWheel(ControlKeyStates{ args.KeyModifiers() },
|
||||
point.Properties().MouseWheelDelta(),
|
||||
point.Properties().IsHorizontalMouseWheel() ?
|
||||
Core::Point{ delta, 0 } :
|
||||
Core::Point{ 0, delta },
|
||||
_toTerminalOrigin(point.Position()),
|
||||
TermControl::GetPressedMouseButtons(point));
|
||||
if (result)
|
||||
@ -2188,7 +2184,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - 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 Core::Point delta,
|
||||
const bool leftButtonDown,
|
||||
const bool midButtonDown,
|
||||
const bool rightButtonDown)
|
||||
|
||||
@ -148,7 +148,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
bool OnDirectKeyEvent(const uint32_t vkey, const uint8_t scanCode, const bool down);
|
||||
|
||||
bool OnMouseWheel(const Windows::Foundation::Point location, const int32_t delta, const bool leftButtonDown, const bool midButtonDown, const bool rightButtonDown);
|
||||
bool OnMouseWheel(const Windows::Foundation::Point location, const winrt::Microsoft::Terminal::Core::Point delta, const bool leftButtonDown, const bool midButtonDown, const bool rightButtonDown);
|
||||
|
||||
~TermControl();
|
||||
|
||||
|
||||
@ -170,7 +170,7 @@ namespace ControlUnitTests
|
||||
|
||||
// The mouse location and buttons don't matter here.
|
||||
interactivity->MouseWheel(modifiers,
|
||||
30,
|
||||
Core::Point{ 0, 30 },
|
||||
Core::Point{ 0, 0 },
|
||||
buttonState);
|
||||
}
|
||||
@ -188,7 +188,7 @@ namespace ControlUnitTests
|
||||
|
||||
// The mouse location and buttons don't matter here.
|
||||
interactivity->MouseWheel(modifiers,
|
||||
-30,
|
||||
Core::Point{ 0, -30 },
|
||||
Core::Point{ 0, 0 },
|
||||
buttonState);
|
||||
}
|
||||
@ -245,7 +245,7 @@ namespace ControlUnitTests
|
||||
expectedTop = 20;
|
||||
|
||||
interactivity->MouseWheel(modifiers,
|
||||
WHEEL_DELTA,
|
||||
Core::Point{ 0, WHEEL_DELTA },
|
||||
Core::Point{ 0, 0 },
|
||||
buttonState);
|
||||
|
||||
@ -254,18 +254,18 @@ namespace ControlUnitTests
|
||||
{
|
||||
expectedTop--;
|
||||
interactivity->MouseWheel(modifiers,
|
||||
WHEEL_DELTA,
|
||||
Core::Point{ 0, WHEEL_DELTA },
|
||||
Core::Point{ 0, 0 },
|
||||
buttonState);
|
||||
}
|
||||
Log::Comment(L"Scrolling up more should do nothing");
|
||||
expectedTop = 0;
|
||||
interactivity->MouseWheel(modifiers,
|
||||
WHEEL_DELTA,
|
||||
Core::Point{ 0, WHEEL_DELTA },
|
||||
Core::Point{ 0, 0 },
|
||||
buttonState);
|
||||
interactivity->MouseWheel(modifiers,
|
||||
WHEEL_DELTA,
|
||||
Core::Point{ 0, WHEEL_DELTA },
|
||||
Core::Point{ 0, 0 },
|
||||
buttonState);
|
||||
|
||||
@ -275,7 +275,7 @@ namespace ControlUnitTests
|
||||
Log::Comment(NoThrowString().Format(L"---scroll down #%d---", i));
|
||||
expectedTop++;
|
||||
interactivity->MouseWheel(modifiers,
|
||||
-WHEEL_DELTA,
|
||||
Core::Point{ 0, -WHEEL_DELTA },
|
||||
Core::Point{ 0, 0 },
|
||||
buttonState);
|
||||
Log::Comment(NoThrowString().Format(L"internal scrollbar pos:%f", interactivity->_internalScrollbarPosition));
|
||||
@ -283,11 +283,11 @@ namespace ControlUnitTests
|
||||
Log::Comment(L"Scrolling down more should do nothing");
|
||||
expectedTop = 21;
|
||||
interactivity->MouseWheel(modifiers,
|
||||
-WHEEL_DELTA,
|
||||
Core::Point{ 0, -WHEEL_DELTA },
|
||||
Core::Point{ 0, 0 },
|
||||
buttonState);
|
||||
interactivity->MouseWheel(modifiers,
|
||||
-WHEEL_DELTA,
|
||||
Core::Point{ 0, -WHEEL_DELTA },
|
||||
Core::Point{ 0, 0 },
|
||||
buttonState);
|
||||
}
|
||||
@ -444,7 +444,7 @@ namespace ControlUnitTests
|
||||
|
||||
Log::Comment(L"Scroll up a line, with the left mouse button selected");
|
||||
interactivity->MouseWheel(modifiers,
|
||||
WHEEL_DELTA,
|
||||
Core::Point{ 0, WHEEL_DELTA },
|
||||
cursorPosition1.to_core_point(),
|
||||
leftMouseDown);
|
||||
|
||||
@ -492,55 +492,55 @@ namespace ControlUnitTests
|
||||
const Core::Point mousePos{ 0, 0 };
|
||||
Control::MouseButtonState state{};
|
||||
|
||||
interactivity->MouseWheel(modifiers, delta, mousePos, state); // 1/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, delta }, mousePos, state); // 1/5
|
||||
VERIFY_ARE_EQUAL(21, core->ScrollOffset());
|
||||
|
||||
Log::Comment(L"Scroll up 4 more times. Once we're at 3/5 scrolls, "
|
||||
L"we'll round the internal scrollbar position to scrolling to the next row.");
|
||||
interactivity->MouseWheel(modifiers, delta, mousePos, state); // 2/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, delta }, mousePos, state); // 2/5
|
||||
VERIFY_ARE_EQUAL(21, core->ScrollOffset());
|
||||
interactivity->MouseWheel(modifiers, delta, mousePos, state); // 3/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, delta }, mousePos, state); // 3/5
|
||||
VERIFY_ARE_EQUAL(20, core->ScrollOffset());
|
||||
interactivity->MouseWheel(modifiers, delta, mousePos, state); // 4/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, delta }, mousePos, state); // 4/5
|
||||
VERIFY_ARE_EQUAL(20, core->ScrollOffset());
|
||||
interactivity->MouseWheel(modifiers, delta, mousePos, state); // 5/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, delta }, mousePos, state); // 5/5
|
||||
VERIFY_ARE_EQUAL(20, core->ScrollOffset());
|
||||
|
||||
Log::Comment(L"Jump to line 5, so we can scroll down from there.");
|
||||
interactivity->UpdateScrollbar(5);
|
||||
VERIFY_ARE_EQUAL(5, core->ScrollOffset());
|
||||
Log::Comment(L"Scroll down 5 times, at which point we should accumulate a whole row of delta.");
|
||||
interactivity->MouseWheel(modifiers, -delta, mousePos, state); // 1/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, -delta }, mousePos, state); // 1/5
|
||||
VERIFY_ARE_EQUAL(5, core->ScrollOffset());
|
||||
interactivity->MouseWheel(modifiers, -delta, mousePos, state); // 2/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, -delta }, mousePos, state); // 2/5
|
||||
VERIFY_ARE_EQUAL(5, core->ScrollOffset());
|
||||
interactivity->MouseWheel(modifiers, -delta, mousePos, state); // 3/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, -delta }, mousePos, state); // 3/5
|
||||
VERIFY_ARE_EQUAL(6, core->ScrollOffset());
|
||||
interactivity->MouseWheel(modifiers, -delta, mousePos, state); // 4/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, -delta }, mousePos, state); // 4/5
|
||||
VERIFY_ARE_EQUAL(6, core->ScrollOffset());
|
||||
interactivity->MouseWheel(modifiers, -delta, mousePos, state); // 5/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, -delta }, mousePos, state); // 5/5
|
||||
VERIFY_ARE_EQUAL(6, core->ScrollOffset());
|
||||
|
||||
Log::Comment(L"Jump to the bottom.");
|
||||
interactivity->UpdateScrollbar(21);
|
||||
VERIFY_ARE_EQUAL(21, core->ScrollOffset());
|
||||
Log::Comment(L"Scroll a bit, then emit a line of text. We should reset our internal scroll position.");
|
||||
interactivity->MouseWheel(modifiers, delta, mousePos, state); // 1/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, delta }, mousePos, state); // 1/5
|
||||
VERIFY_ARE_EQUAL(21, core->ScrollOffset());
|
||||
interactivity->MouseWheel(modifiers, delta, mousePos, state); // 2/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, delta }, mousePos, state); // 2/5
|
||||
VERIFY_ARE_EQUAL(21, core->ScrollOffset());
|
||||
|
||||
conn->WriteInput(winrt_wstring_to_array_view(L"Foo\r\n"));
|
||||
VERIFY_ARE_EQUAL(22, core->ScrollOffset());
|
||||
interactivity->MouseWheel(modifiers, delta, mousePos, state); // 1/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, delta }, mousePos, state); // 1/5
|
||||
VERIFY_ARE_EQUAL(22, core->ScrollOffset());
|
||||
interactivity->MouseWheel(modifiers, delta, mousePos, state); // 2/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, delta }, mousePos, state); // 2/5
|
||||
VERIFY_ARE_EQUAL(22, core->ScrollOffset());
|
||||
interactivity->MouseWheel(modifiers, delta, mousePos, state); // 3/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, delta }, mousePos, state); // 3/5
|
||||
VERIFY_ARE_EQUAL(21, core->ScrollOffset());
|
||||
interactivity->MouseWheel(modifiers, delta, mousePos, state); // 4/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, delta }, mousePos, state); // 4/5
|
||||
VERIFY_ARE_EQUAL(21, core->ScrollOffset());
|
||||
interactivity->MouseWheel(modifiers, delta, mousePos, state); // 5/5
|
||||
interactivity->MouseWheel(modifiers, Core::Point{ 0, delta }, mousePos, state); // 5/5
|
||||
VERIFY_ARE_EQUAL(21, core->ScrollOffset());
|
||||
}
|
||||
|
||||
@ -709,7 +709,7 @@ namespace ControlUnitTests
|
||||
{
|
||||
expectedTop--;
|
||||
interactivity->MouseWheel(modifiers,
|
||||
WHEEL_DELTA,
|
||||
Core::Point{ 0, WHEEL_DELTA },
|
||||
Core::Point{ 0, 0 },
|
||||
noMouseDown);
|
||||
}
|
||||
|
||||
@ -745,7 +745,7 @@ void AppHost::_RaiseVisualBell(const winrt::Windows::Foundation::IInspectable&,
|
||||
// - delta: the wheel delta that triggered this event.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void AppHost::_WindowMouseWheeled(const winrt::Windows::Foundation::Point coord, const int32_t delta)
|
||||
void AppHost::_WindowMouseWheeled(const winrt::Windows::Foundation::Point coord, const winrt::Microsoft::Terminal::Core::Point delta)
|
||||
{
|
||||
if (_windowLogic)
|
||||
{
|
||||
|
||||
@ -73,7 +73,7 @@ private:
|
||||
|
||||
void _RaiseVisualBell(const winrt::Windows::Foundation::IInspectable& sender,
|
||||
const winrt::Windows::Foundation::IInspectable& arg);
|
||||
void _WindowMouseWheeled(const winrt::Windows::Foundation::Point coord, const int32_t delta);
|
||||
void _WindowMouseWheeled(const winrt::Windows::Foundation::Point coord, const winrt::Microsoft::Terminal::Core::Point delta);
|
||||
void _WindowActivated(bool activated);
|
||||
void _WindowMoved();
|
||||
|
||||
|
||||
@ -595,6 +595,7 @@ void IslandWindow::_OnGetMinMaxInfo(const WPARAM /*wParam*/, const LPARAM lParam
|
||||
WindowCloseButtonClicked.raise();
|
||||
return 0;
|
||||
}
|
||||
case WM_MOUSEHWHEEL:
|
||||
case WM_MOUSEWHEEL:
|
||||
try
|
||||
{
|
||||
@ -623,7 +624,11 @@ void IslandWindow::_OnGetMinMaxInfo(const WPARAM /*wParam*/, const LPARAM lParam
|
||||
const auto scale = GetCurrentDpiScale();
|
||||
const winrt::Windows::Foundation::Point real{ relative.x / scale, relative.y / scale };
|
||||
|
||||
const auto wheelDelta = static_cast<short>(HIWORD(wparam));
|
||||
winrt::Microsoft::Terminal::Core::Point wheelDelta{ 0, static_cast<int32_t>(HIWORD(wparam)) };
|
||||
if (message == WM_MOUSEHWHEEL)
|
||||
{
|
||||
std::swap(wheelDelta.X, wheelDelta.Y);
|
||||
}
|
||||
|
||||
// Raise an event, so any listeners can handle the mouse wheel event manually.
|
||||
MouseScrolled.raise(real, wheelDelta);
|
||||
|
||||
@ -74,7 +74,7 @@ public:
|
||||
|
||||
til::event<winrt::delegate<>> DragRegionClicked;
|
||||
til::event<winrt::delegate<>> WindowCloseButtonClicked;
|
||||
til::event<winrt::delegate<void(winrt::Windows::Foundation::Point, int32_t)>> MouseScrolled;
|
||||
til::event<winrt::delegate<void(winrt::Windows::Foundation::Point, winrt::Microsoft::Terminal::Core::Point)>> MouseScrolled;
|
||||
til::event<winrt::delegate<void(bool)>> WindowActivated;
|
||||
til::event<winrt::delegate<void()>> NotifyNotificationIconPressed;
|
||||
til::event<winrt::delegate<void()>> NotifyWindowHidden;
|
||||
|
||||
@ -567,7 +567,7 @@ BOOL HandleMouseEvent(const SCREEN_INFORMATION& ScreenInfo,
|
||||
if (!fShiftPressed && !pSelection->IsInSelectingState())
|
||||
{
|
||||
short sDelta = 0;
|
||||
if (Message == WM_MOUSEWHEEL)
|
||||
if (Message == WM_MOUSEWHEEL || Message == WM_MOUSEHWHEEL)
|
||||
{
|
||||
sDelta = GET_WHEEL_DELTA_WPARAM(wParam);
|
||||
}
|
||||
|
||||
@ -127,10 +127,13 @@ public:
|
||||
wch = L'!';
|
||||
break;
|
||||
case WM_MOUSEWHEEL:
|
||||
case WM_MOUSEHWHEEL:
|
||||
Log::Comment(NoThrowString().Format(L"MOUSEWHEEL"));
|
||||
wch = L'`' + (sScrollDelta > 0 ? 0 : 1);
|
||||
break;
|
||||
case WM_MOUSEHWHEEL:
|
||||
Log::Comment(NoThrowString().Format(L"MOUSEHWHEEL"));
|
||||
wch = L'b' + (sScrollDelta > 0 ? 1 : 0);
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
default:
|
||||
Log::Comment(NoThrowString().Format(L"DEFAULT"));
|
||||
@ -168,9 +171,11 @@ public:
|
||||
result = 3 + 0x20; // we add 0x20 to hover events, which are all encoded as WM_MOUSEMOVE events
|
||||
break;
|
||||
case WM_MOUSEWHEEL:
|
||||
case WM_MOUSEHWHEEL:
|
||||
result = (sScrollDelta > 0 ? 64 : 65);
|
||||
break;
|
||||
case WM_MOUSEHWHEEL:
|
||||
result = (sScrollDelta > 0 ? 67 : 66);
|
||||
break;
|
||||
default:
|
||||
result = 0;
|
||||
break;
|
||||
@ -582,6 +587,12 @@ public:
|
||||
Log::Comment(L"Test mouse wheel scrolling down");
|
||||
VERIFY_ARE_EQUAL(TerminalInput::MakeOutput(L"\x1B[B"), mouseInput.HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, -WHEEL_DELTA, {}));
|
||||
|
||||
Log::Comment(L"Test mouse wheel scrolling right");
|
||||
VERIFY_ARE_EQUAL(TerminalInput::MakeOutput(L"\x1B[C"), mouseInput.HandleMouse({ 0, 0 }, WM_MOUSEHWHEEL, noModifierKeys, WHEEL_DELTA, {}));
|
||||
|
||||
Log::Comment(L"Test mouse wheel scrolling left");
|
||||
VERIFY_ARE_EQUAL(TerminalInput::MakeOutput(L"\x1B[D"), mouseInput.HandleMouse({ 0, 0 }, WM_MOUSEHWHEEL, noModifierKeys, -WHEEL_DELTA, {}));
|
||||
|
||||
Log::Comment(L"Enable cursor keys mode");
|
||||
mouseInput.SetInputMode(TerminalInput::Mode::CursorKey, true);
|
||||
|
||||
@ -591,6 +602,12 @@ public:
|
||||
Log::Comment(L"Test mouse wheel scrolling down");
|
||||
VERIFY_ARE_EQUAL(TerminalInput::MakeOutput(L"\x1BOB"), mouseInput.HandleMouse({ 0, 0 }, WM_MOUSEWHEEL, noModifierKeys, -WHEEL_DELTA, {}));
|
||||
|
||||
Log::Comment(L"Test mouse wheel scrolling right");
|
||||
VERIFY_ARE_EQUAL(TerminalInput::MakeOutput(L"\x1BOC"), mouseInput.HandleMouse({ 0, 0 }, WM_MOUSEHWHEEL, noModifierKeys, WHEEL_DELTA, {}));
|
||||
|
||||
Log::Comment(L"Test mouse wheel scrolling left");
|
||||
VERIFY_ARE_EQUAL(TerminalInput::MakeOutput(L"\x1BOD"), mouseInput.HandleMouse({ 0, 0 }, WM_MOUSEHWHEEL, noModifierKeys, -WHEEL_DELTA, {}));
|
||||
|
||||
Log::Comment(L"Confirm no effect when scroll mode is disabled");
|
||||
mouseInput.UseAlternateScreenBuffer();
|
||||
mouseInput.SetInputMode(TerminalInput::Mode::AlternateScroll, false);
|
||||
|
||||
@ -163,9 +163,11 @@ static constexpr wchar_t _windowsButtonToXEncoding(const unsigned int button,
|
||||
xvalue = 1;
|
||||
break;
|
||||
case WM_MOUSEWHEEL:
|
||||
case WM_MOUSEHWHEEL:
|
||||
xvalue = delta > 0 ? 0x40 : 0x41;
|
||||
break;
|
||||
case WM_MOUSEHWHEEL:
|
||||
xvalue = delta > 0 ? 0x43 : 0x42;
|
||||
break;
|
||||
default:
|
||||
xvalue = 0;
|
||||
break;
|
||||
@ -221,9 +223,11 @@ static constexpr int _windowsButtonToSGREncoding(const unsigned int button,
|
||||
xvalue = 3;
|
||||
break;
|
||||
case WM_MOUSEWHEEL:
|
||||
case WM_MOUSEHWHEEL:
|
||||
xvalue = delta > 0 ? 0x40 : 0x41;
|
||||
break;
|
||||
case WM_MOUSEHWHEEL:
|
||||
xvalue = delta > 0 ? 0x43 : 0x42;
|
||||
break;
|
||||
default:
|
||||
xvalue = 0;
|
||||
break;
|
||||
@ -378,7 +382,7 @@ TerminalInput::OutputType TerminalInput::HandleMouse(const til::point position,
|
||||
|
||||
if (ShouldSendAlternateScroll(button, delta))
|
||||
{
|
||||
return _makeAlternateScrollOutput(delta);
|
||||
return _makeAlternateScrollOutput(button, delta);
|
||||
}
|
||||
|
||||
return {};
|
||||
@ -493,7 +497,9 @@ bool TerminalInput::ShouldSendAlternateScroll(const unsigned int button, const s
|
||||
// - Sends a sequence to the input corresponding to cursor up / down depending on the sScrollDelta.
|
||||
// Parameters:
|
||||
// - delta: The scroll wheel delta of the input event
|
||||
TerminalInput::OutputType TerminalInput::_makeAlternateScrollOutput(const short delta) const
|
||||
TerminalInput::OutputType TerminalInput::_makeAlternateScrollOutput(const unsigned int button, const short delta) const
|
||||
{
|
||||
if (button == WM_MOUSEWHEEL)
|
||||
{
|
||||
if (delta > 0)
|
||||
{
|
||||
@ -504,3 +510,19 @@ TerminalInput::OutputType TerminalInput::_makeAlternateScrollOutput(const short
|
||||
return MakeOutput(_keyMap.at(VK_DOWN));
|
||||
}
|
||||
}
|
||||
else if (button == WM_MOUSEHWHEEL)
|
||||
{
|
||||
if (delta > 0)
|
||||
{
|
||||
return MakeOutput(_keyMap.at(VK_RIGHT));
|
||||
}
|
||||
else
|
||||
{
|
||||
return MakeOutput(_keyMap.at(VK_LEFT));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
[[nodiscard]] OutputType _GenerateUtf8Sequence(til::point position, unsigned int button, bool isHover, short modifierKeyState, short delta);
|
||||
[[nodiscard]] OutputType _GenerateSGRSequence(til::point position, unsigned int button, bool isRelease, bool isHover, short modifierKeyState, short delta);
|
||||
|
||||
[[nodiscard]] OutputType _makeAlternateScrollOutput(short delta) const;
|
||||
[[nodiscard]] OutputType _makeAlternateScrollOutput(unsigned int button, short delta) const;
|
||||
|
||||
static constexpr unsigned int s_GetPressedButton(const MouseButtonState state) noexcept;
|
||||
#pragma endregion
|
||||
|
||||
@ -897,6 +897,22 @@ bool InputStateMachineEngine::_UpdateSGRMouseButtonState(const VTID id,
|
||||
eventFlags |= MOUSE_WHEELED;
|
||||
break;
|
||||
}
|
||||
case CsiMouseButtonCodes::ScrollLeft:
|
||||
{
|
||||
// set high word to proper scroll direction
|
||||
// scroll intensity is assumed to be constant value
|
||||
buttonState |= SCROLL_DELTA_BACKWARD;
|
||||
eventFlags |= MOUSE_HWHEELED;
|
||||
break;
|
||||
}
|
||||
case CsiMouseButtonCodes::ScrollRight:
|
||||
{
|
||||
// set high word to proper scroll direction
|
||||
// scroll intensity is assumed to be constant value
|
||||
buttonState |= SCROLL_DELTA_FORWARD;
|
||||
eventFlags |= MOUSE_HWHEELED;
|
||||
break;
|
||||
}
|
||||
case CsiMouseButtonCodes::Released:
|
||||
// hover event, we still want to send these but we don't
|
||||
// need to do anything special here, so just break
|
||||
|
||||
@ -111,6 +111,8 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
Released = 3,
|
||||
ScrollForward = 4,
|
||||
ScrollBack = 5,
|
||||
ScrollLeft = 6,
|
||||
ScrollRight = 7,
|
||||
};
|
||||
|
||||
constexpr unsigned short CsiMouseModifierCode_Drag = 32;
|
||||
|
||||
@ -1196,6 +1196,8 @@ void InputEngineTest::SGRMouseTest_Scroll()
|
||||
// TEST INPUT EXPECTED OUTPUT
|
||||
{ { CsiMouseButtonCodes::ScrollForward, 0, { 1, 1 }, CsiActionCodes::MouseDown }, { SCROLL_DELTA_FORWARD, 0, { 0, 0 }, MOUSE_WHEELED } },
|
||||
{ { CsiMouseButtonCodes::ScrollBack, 0, { 1, 1 }, CsiActionCodes::MouseDown }, { SCROLL_DELTA_BACKWARD, 0, { 0, 0 }, MOUSE_WHEELED } },
|
||||
{ { CsiMouseButtonCodes::ScrollLeft, 0, { 1, 1 }, CsiActionCodes::MouseDown }, { SCROLL_DELTA_BACKWARD, 0, { 0, 0 }, MOUSE_HWHEELED } },
|
||||
{ { CsiMouseButtonCodes::ScrollRight, 0, { 1, 1 }, CsiActionCodes::MouseDown }, { SCROLL_DELTA_FORWARD, 0, { 0, 0 }, MOUSE_HWHEELED } },
|
||||
};
|
||||
// clang-format on
|
||||
VerifySGRMouseData(testData);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user