diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index 86747d0f8ff..f10847fbfeb 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -2075,7 +2075,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation // the selection (we need to reset selection on double-click or // triple-click, so it captures the word or the line, rather than // extending the selection) - if (_terminal->IsSelectionActive() && (!shiftEnabled || isOnOriginalPosition)) + // - GH#9608: VT mouse mode is enabled. In this mode, Shift is used + // to override mouse input, so Shift+Click should start a fresh + // selection rather than extending the previous one. + if (_terminal->IsSelectionActive() && (!shiftEnabled || isOnOriginalPosition || _terminal->IsTrackingMouseInput())) { // Reset the selection _terminal->ClearSelection(); diff --git a/src/cascadia/TerminalControl/ControlInteractivity.cpp b/src/cascadia/TerminalControl/ControlInteractivity.cpp index 0c4e788961d..023d00007b5 100644 --- a/src/cascadia/TerminalControl/ControlInteractivity.cpp +++ b/src/cascadia/TerminalControl/ControlInteractivity.cpp @@ -285,8 +285,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation } const auto isOnOriginalPosition = _lastMouseClickPosNoSelection == pixelPosition; - // Rounded coordinates for text selection - _core->LeftClickOnTerminal(_getTerminalPosition(til::point{ pixelPosition }, true), + // Rounded coordinates for text selection. + // Don't round in VT mouse mode; cell-level precision matters more + const auto round = !_core->IsVtMouseModeEnabled(); + _core->LeftClickOnTerminal(_getTerminalPosition(til::point{ pixelPosition }, round), multiClickMapper, altEnabled, shiftEnabled, @@ -296,8 +298,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (_core->HasSelection()) { // GH#9787: if selection is active we don't want to track the touchdown position - // so that dragging the mouse will extend the selection rather than starting the new one - _singleClickTouchdownPos = std::nullopt; + // so that dragging the mouse will extend the selection rather than starting the new one. + // In VT mouse mode, keep tracking the touchdown point so that PointerMoved + // can re-anchor the selection based on drag direction (the dx < 0 adjustment). + // Without this, dragging left wouldn't include the initially clicked cell + // because floored coordinates place the anchor on the cell's left edge. + if (!_core->IsVtMouseModeEnabled()) + { + _singleClickTouchdownPos = std::nullopt; + } } } else if (WI_IsFlagSet(buttonState, MouseButtonState::IsRightButtonDown)) @@ -682,7 +691,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation // - cursorPosition: in pixels, relative to the origin of the control void ControlInteractivity::SetEndSelectionPoint(const Core::Point pixelPosition) { - _core->SetEndSelectionPoint(_getTerminalPosition(til::point{ pixelPosition }, true)); + // Don't round in VT mouse mode; cell-level precision matters more + const auto round = !_core->IsVtMouseModeEnabled(); + _core->SetEndSelectionPoint(_getTerminalPosition(til::point{ pixelPosition }, round)); _selectionNeedsToBeCopied = true; }