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