Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/cascadia/TerminalControl/ControlCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
30 changes: 24 additions & 6 deletions src/cascadia/TerminalControl/ControlInteractivity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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))
Expand Down Expand Up @@ -392,7 +401,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
}
}

SetEndSelectionPoint(pixelPosition);
// Don't update the selection endpoint while still tracking
// the touchdown point — the initial selection from MultiClickSelection
// should remain visible until the drag threshold is met and
// the anchor is properly set based on drag direction.
if (!_singleClickTouchdownPos)
Comment thread
carlos-zamora marked this conversation as resolved.
Outdated
{
SetEndSelectionPoint(pixelPosition);
}
}

_core->SetHoveredCell(terminalPosition.to_core_point());
Expand Down Expand Up @@ -682,7 +698,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;
}

Expand Down
Loading