Repository: microsoft/terminal
File: src/renderer/base/renderer.cpp (C++)

Code before:
// - Called when we want to check if the viewport has moved and scroll accordingly if so.
// Arguments:
// - <none>
// Return Value:
// - True if something changed and we scrolled. False otherwise.
bool Renderer::_CheckViewportAndScroll()
{
    SMALL_RECT const srOldViewport = _viewport.ToInclusive();
    SMALL_RECT const srNewViewport = _pData->GetViewport().ToInclusive();

    COORD coordDelta;
    coordDelta.X = srOldViewport.Left - srNewViewport.Left;
    coordDelta.Y = srOldViewport.Top - srNewViewport.Top;

    for (auto engine : _rgpEngines)
    {
        LOG_IF_FAILED(engine->UpdateViewport(srNewViewport));
    }

    _viewport = Viewport::FromInclusive(srNewViewport);

    // If we're keeping some buffers between calls, let them know about the viewport size
    // so they can prepare the buffers for changes to either preallocate memory at once
    // (instead of growing naturally) or shrink down to reduce usage as appropriate.
    const size_t lineLength = gsl::narrow_cast<size_t>(til::rectangle{ srNewViewport }.width());
    til::manage_vector(_clusterBuffer, lineLength, _shrinkThreshold);

    if (coordDelta.X != 0 || coordDelta.Y != 0)
    {
        for (auto engine : _rgpEngines)
        {
            LOG_IF_FAILED(engine->InvalidateScroll(&coordDelta));
        }

        _ScrollPreviousSelection(coordDelta);

        return true;
    }

    return false;
}

// Routine Description:
// - Called when a scroll operation has occurred by manipulating the viewport.
// - This is a special case as calling out scrolls explicitly drastically improves performance.
// Arguments:
// - <none>
// Return Value:
// - <none>
void Renderer::TriggerScroll()
{

Review comment (suggestion):
to quote from Teams:

> `til::manage_vector` doesn't work that well btw...
> it uses linear shrinking, even though std::vector uses exponential growth
> most terminals probably have a default size of 120x30
>
> a `std::vector` has a minimum size of 16 elements and a growth factor of 2x
> ---> the `std::vector` has a capacity of 128 items when used with a 120-cell wide terminal
>
> and 80% of 128 isn't sufficient to shrink it
>
> so.... I just thought to myself "how likely is it anyways that a user resizes a terminal from a suuuuuper wide one to a super narrow one?" and then removed it



Code after:

// Routine Description:
// - Called when we want to check if the viewport has moved and scroll accordingly if so.
// Arguments:
// - <none>
// Return Value:
// - True if something changed and we scrolled. False otherwise.
bool Renderer::_CheckViewportAndScroll()
{
    SMALL_RECT const srOldViewport = _viewport.ToInclusive();
    SMALL_RECT const srNewViewport = _pData->GetViewport().ToInclusive();

    if (srOldViewport == srNewViewport)
    {
        return false;
    }

    _viewport = Viewport::FromInclusive(srNewViewport);

    COORD coordDelta;
    coordDelta.X = srOldViewport.Left - srNewViewport.Left;
    coordDelta.Y = srOldViewport.Top - srNewViewport.Top;

    FOREACH_ENGINE(engine)
    {
        LOG_IF_FAILED(engine->UpdateViewport(srNewViewport));
        LOG_IF_FAILED(engine->InvalidateScroll(&coordDelta));
    }

    _ScrollPreviousSelection(coordDelta);
    return true;
}

// Routine Description:
// - Called when a scroll operation has occurred by manipulating the viewport.
// - This is a special case as calling out scrolls explicitly drastically improves performance.
// Arguments:
// - <none>
// Return Value:
// - <none>
void Renderer::TriggerScroll()
{
    if (_CheckViewportAndScroll())
    {
        _NotifyPaintFrame();
    }
}

// Routine Description:
// - Called when a scroll operation wishes to explicitly adjust the frame by the given coordinate distance.
// - This is a special case as calling out scrolls explicitly drastically improves performance.