Implement preventing auto-scroll on new output (#6062)

## Summary of the Pull Request
Updates the Terminal's scroll response to new output. The Terminal will not automatically scroll if...
- a selection is active, or
- the viewport is at the bottom of the scroll history

## References
#2529 - Spec
#3863 - Implementation

## PR Checklist
* [X] Closes #980
* [X] Closes #3863
* [ ] Tests added/passed
* [ ] Requires documentation to be updated

## Detailed Description of the Pull Request / Additional comments
Updates the `_scrollOffset` value properly in TerminalCore when the cursor moves. We calculate a new `_scrollOffset` based on if we are circling the buffer and how far below the mutable bottom is.

We specifically check for if a selection is active and if the viewport is at the bottom, then use that as a condition for deciding if we should update `_scrollOffset` to the new calculated value or 0 (the bottom of the scroll history).

## Validation Steps Performed
Manual testing. Though I should add automated tests.
- [X] new output
- [X] new output when circling
- [X] new output when circling and viewport is at the top
This commit is contained in:
Carlos Zamora 2020-07-09 04:24:20 -07:00 committed by GitHub
parent 9e44df0c9f
commit 9e26c020e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -788,9 +788,9 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
// If we're about to scroll past the bottom of the buffer, instead cycle the
// buffer.
SHORT rowsPushedOffTopOfBuffer = 0;
const auto newRows = std::max(0, proposedCursorPosition.Y - bufferSize.Height() + 1);
if (proposedCursorPosition.Y >= bufferSize.Height())
{
const auto newRows = proposedCursorPosition.Y - bufferSize.Height() + 1;
for (auto dy = 0; dy < newRows; dy++)
{
_buffer->IncrementCircularBuffer();
@ -804,7 +804,8 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
// Move the viewport down if the cursor moved below the viewport.
bool updatedViewport = false;
if (proposedCursorPosition.Y > _mutableViewport.BottomInclusive())
const auto scrollAmount = std::max(0, proposedCursorPosition.Y - _mutableViewport.BottomInclusive());
if (scrollAmount > 0)
{
const auto newViewTop = std::max(0, proposedCursorPosition.Y - (_mutableViewport.Height() - 1));
if (newViewTop != _mutableViewport.Top())
@ -817,6 +818,13 @@ void Terminal::_AdjustCursorPosition(const COORD proposedPosition)
if (updatedViewport)
{
// scroll if...
// - no selection is active
// - viewport is already at the bottom
const bool scrollToOutput = !IsSelectionActive() && _scrollOffset == 0;
_scrollOffset = scrollToOutput ? 0 : _scrollOffset + scrollAmount + newRows;
_NotifyScrollEvent();
}