Repository: microsoft/terminal
File: src/cascadia/TerminalControl/ControlCore.cpp (C++)

Code before:
    // - newHeight: the new height of the swapchain, in pixels.
    void ControlCore::_doResizeUnderLock(const double newWidth,
                                         const double newHeight)
    {
        SIZE size;
        size.cx = static_cast<long>(newWidth);
        size.cy = static_cast<long>(newHeight);

        // Don't actually resize so small that a single character wouldn't fit
        // in either dimension. The buffer really doesn't like being size 0.
        if (size.cx < _actualFont.GetSize().X || size.cy < _actualFont.GetSize().Y)
        {
            return;
        }

        // Convert our new dimensions to characters
        const auto viewInPixels = Viewport::FromDimensions({ 0, 0 },
                                                           { static_cast<short>(size.cx), static_cast<short>(size.cy) });
        const auto vp = _renderEngine->GetViewportInCharacters(viewInPixels);
        const auto currentVP = _terminal->GetViewport();

        // Don't actually resize if viewport dimensions didn't change
        if (vp.Height() == currentVP.Height() && vp.Width() == currentVP.Width())
        {
            return;
        }

        _terminal->ClearSelection();

        // Tell the dx engine that our window is now the new size.
        THROW_IF_FAILED(_renderEngine->SetWindowSize(size));

        // Invalidate everything
        _renderer->TriggerRedrawAll();

        // If this function succeeds with S_FALSE, then the terminal didn't
        // actually change size. No need to notify the connection of this no-op.
        const HRESULT hr = _terminal->UserResize({ vp.Width(), vp.Height() });
        if (SUCCEEDED(hr) && hr != S_FALSE)
        {
            _connection.Resize(vp.Height(), vp.Width());
        }
    }

    void ControlCore::SizeChanged(const double width,
                                  const double height)
    {
        _panelWidth = width;
        _panelHeight = height;

        auto lock = _terminal->LockForWriting();

Review comment (bug):
This is the bug fix. The rest are "performance-restoration-refactorizations" to limit calls to `_refreshSizeUnderLock`.

Code after:
    }

    void ControlCore::SizeChanged(const double width,
                                  const double height)
    {
        // _refreshSizeUnderLock redraws the entire terminal.
        // Don't call it if we don't have to.
        if (_panelWidth == width && _panelHeight == height)
        {
            return;
        }

        _panelWidth = width;
        _panelHeight = height;

        auto lock = _terminal->LockForWriting();
        _refreshSizeUnderLock();
    }

    void ControlCore::ScaleChanged(const double scale)
    {
        if (!_renderEngine)
        {
            return;
        }

        // _refreshSizeUnderLock redraws the entire terminal.
        // Don't call it if we don't have to.
        if (_compositionScale == scale)
        {
            return;
        }

        _compositionScale = scale;

        auto lock = _terminal->LockForWriting();
        // _updateFont relies on the new _compositionScale set above
        _updateFont();
        _refreshSizeUnderLock();
    }

    void ControlCore::SetSelectionAnchor(til::point const& position)
    {
        auto lock = _terminal->LockForWriting();
        _terminal->SetSelectionAnchor(position.to_win32_coord());
    }

    // Method Description:
    // - Sets selection's end position to match supplied cursor position, e.g. while mouse dragging.
    // Arguments:
    // - position: the point in terminal coordinates (in cells, not pixels)