Skip to content

Commit

Permalink
[1.14] Fix moving selection past scroll area (#13353)
Browse files Browse the repository at this point in the history
## Summary of the Pull Request
1.14 port of #13318

Introduced in #10824, this fixes a bug where you could use keyboard selection to move below the scroll area. Instead, we now clamp movement to the mutable viewport (aka the scrollable area). Specifically, we only clamp the y-coordinate to make the experience similar to that of mouse selection.

## Validation Steps Performed
✅ (no output) try to move past bottom of viewport
✅ (with output, at bottom of scroll area) try to move past viewport
✅ (with output, NOT at bottom of scroll area) try to move past viewport
✅ try to move past top of viewport
  • Loading branch information
carlos-zamora authored Jun 22, 2022
1 parent 997b4ac commit 7506a3a
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions src/cascadia/TerminalCore/TerminalSelection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ void Terminal::UpdateSelection(SelectionDirection direction, SelectionExpansion
const auto movingEnd{ _selection->start == _selection->pivot };
auto targetPos{ movingEnd ? _selection->end : _selection->start };

// 2. Perform the movement
// 2.A) Perform the movement
switch (mode)
{
case SelectionExpansion::Char:
Expand All @@ -305,23 +305,32 @@ void Terminal::UpdateSelection(SelectionDirection direction, SelectionExpansion
break;
}

// 2.B) Clamp the movement to the mutable viewport
const auto bufferSize = _activeBuffer().GetSize();
const auto mutableViewport = _GetMutableViewport();
const COORD bottomRightInclusive{ mutableViewport.RightInclusive(), mutableViewport.BottomInclusive() };
if (bufferSize.CompareInBounds(targetPos, bottomRightInclusive) > 0)
{
targetPos = bottomRightInclusive;
}

// 3. Actually modify the selection
// NOTE: targetStart doesn't matter here
auto targetStart = false;
std::tie(_selection->start, _selection->end) = _PivotSelection(targetPos, targetStart);

// 4. Scroll (if necessary)
if (const auto viewport = _GetVisibleViewport(); !viewport.IsInBounds(targetPos))
if (const auto visibleViewport = _GetVisibleViewport(); !visibleViewport.IsInBounds(targetPos))
{
if (const auto amtAboveView = viewport.Top() - targetPos.Y; amtAboveView > 0)
if (const auto amtAboveView = visibleViewport.Top() - targetPos.Y; amtAboveView > 0)
{
// anchor is above visible viewport, scroll by that amount
_scrollOffset += amtAboveView;
}
else
{
// anchor is below visible viewport, scroll by that amount
const auto amtBelowView = targetPos.Y - viewport.BottomInclusive();
const auto amtBelowView = targetPos.Y - visibleViewport.BottomInclusive();
_scrollOffset -= amtBelowView;
}
_NotifyScrollEvent();
Expand Down

0 comments on commit 7506a3a

Please sign in to comment.