Skip to content

Commit be4db0a

Browse files
PankajBhojwaniRosefield
authored andcommitted
Fix mouse coordinates when viewport is scrolled (microsoft#10642)
## Summary of the Pull Request Adjust the y-coordinate of the mouse coordinates we send based on how much the viewport has been scrolled ## Validation Steps Performed Validated: cannot repro the issue in microsoft#10190 Closes microsoft#10190
1 parent be50d53 commit be4db0a

File tree

2 files changed

+96
-1
lines changed

2 files changed

+96
-1
lines changed

src/cascadia/TerminalControl/ControlInteractivity.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
214214
}
215215
else if (_canSendVTMouseInput(modifiers))
216216
{
217-
_core->SendMouseEvent(terminalPosition, pointerUpdateKind, modifiers, 0, toInternalMouseState(buttonState));
217+
const auto adjustment = _core->ScrollOffset() > 0 ? _core->BufferHeight() - _core->ScrollOffset() - _core->ViewHeight() : 0;
218+
// If the click happened outside the active region, just don't send any mouse event
219+
if (const auto adjustedY = terminalPosition.y() - adjustment; adjustedY >= 0)
220+
{
221+
_core->SendMouseEvent({ terminalPosition.x(), adjustedY }, pointerUpdateKind, modifiers, 0, toInternalMouseState(buttonState));
222+
}
218223
}
219224
else if (WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown))
220225
{

src/cascadia/UnitTests_Control/ControlInteractivityTests.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ namespace ControlUnitTests
3232
TEST_METHOD(ScrollWithSelection);
3333
TEST_METHOD(TestScrollWithTrackpad);
3434
TEST_METHOD(TestQuickDragOnSelect);
35+
TEST_METHOD(PointerClickOutsideActiveRegion);
3536

3637
TEST_CLASS_SETUP(ClassSetup)
3738
{
@@ -544,4 +545,93 @@ namespace ControlUnitTests
544545
COORD expectedAnchor{ 0, 0 };
545546
VERIFY_ARE_EQUAL(expectedAnchor, core->_terminal->GetSelectionAnchor());
546547
}
548+
549+
void ControlInteractivityTests::PointerClickOutsideActiveRegion()
550+
{
551+
// This is a test for GH#10642
552+
WEX::TestExecution::DisableVerifyExceptions disableVerifyExceptions{};
553+
554+
auto [settings, conn] = _createSettingsAndConnection();
555+
auto [core, interactivity] = _createCoreAndInteractivity(*settings, *conn);
556+
_standardInit(core, interactivity);
557+
558+
// For this test, don't use any modifiers
559+
const auto modifiers = ControlKeyStates();
560+
const Control::MouseButtonState leftMouseDown{ Control::MouseButtonState::IsLeftButtonDown };
561+
const Control::MouseButtonState noMouseDown{};
562+
563+
const til::size fontSize{ 9, 21 };
564+
565+
interactivity->_rowsToScroll = 1;
566+
int expectedTop = 0;
567+
int expectedViewHeight = 20;
568+
int expectedBufferHeight = 20;
569+
570+
auto scrollChangedHandler = [&](auto&&, const Control::ScrollPositionChangedArgs& args) mutable {
571+
VERIFY_ARE_EQUAL(expectedTop, args.ViewTop());
572+
VERIFY_ARE_EQUAL(expectedViewHeight, args.ViewHeight());
573+
VERIFY_ARE_EQUAL(expectedBufferHeight, args.BufferSize());
574+
};
575+
core->ScrollPositionChanged(scrollChangedHandler);
576+
interactivity->ScrollPositionChanged(scrollChangedHandler);
577+
578+
for (int i = 0; i < 40; ++i)
579+
{
580+
Log::Comment(NoThrowString().Format(L"Writing line #%d", i));
581+
// The \r\n in the 19th loop will cause the view to start moving
582+
if (i >= 19)
583+
{
584+
expectedTop++;
585+
expectedBufferHeight++;
586+
}
587+
588+
conn->WriteInput(L"Foo\r\n");
589+
}
590+
// We printed that 40 times, but the final \r\n bumped the view down one MORE row.
591+
VERIFY_ARE_EQUAL(20, core->_terminal->GetViewport().Height());
592+
VERIFY_ARE_EQUAL(21, core->ScrollOffset());
593+
VERIFY_ARE_EQUAL(20, core->ViewHeight());
594+
VERIFY_ARE_EQUAL(41, core->BufferHeight());
595+
596+
expectedBufferHeight = 41;
597+
expectedTop = 21;
598+
599+
Log::Comment(L"Scroll up 10 times");
600+
for (int i = 0; i < 11; ++i)
601+
{
602+
expectedTop--;
603+
interactivity->MouseWheel(modifiers,
604+
WHEEL_DELTA,
605+
til::point{ 0, 0 },
606+
noMouseDown);
607+
}
608+
609+
// Enable VT mouse event tracking
610+
conn->WriteInput(L"\x1b[?1003;1006h");
611+
612+
// Mouse clicks in the inactive region (i.e. the top 10 rows in this case) should not register
613+
Log::Comment(L"Click on the terminal");
614+
const til::point terminalPosition0{ 4, 4 };
615+
const til::point cursorPosition0 = terminalPosition0 * fontSize;
616+
interactivity->PointerPressed(leftMouseDown,
617+
WM_LBUTTONDOWN, //pointerUpdateKind
618+
0, // timestamp
619+
modifiers,
620+
cursorPosition0);
621+
Log::Comment(L"Verify that there's not yet a selection");
622+
623+
VERIFY_IS_FALSE(core->HasSelection());
624+
625+
Log::Comment(L"Drag the mouse");
626+
// move the mouse as if to make a selection
627+
const til::point terminalPosition1{ 10, 4 };
628+
const til::point cursorPosition1 = terminalPosition1 * fontSize;
629+
interactivity->PointerMoved(leftMouseDown,
630+
WM_LBUTTONDOWN, //pointerUpdateKind
631+
modifiers,
632+
true, // focused,
633+
cursorPosition1);
634+
Log::Comment(L"Verify that there's still no selection");
635+
VERIFY_IS_FALSE(core->HasSelection());
636+
}
547637
}

0 commit comments

Comments
 (0)