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

Code before:
                mark.start.to_core_point(),
                mark.end.to_core_point(),
                OptionalFromColor(_terminal->GetColorForMark(mark)));
        }

        return winrt::single_threaded_vector(std::move(v));
    }

    void ControlCore::AddMark(const Control::ScrollMark& mark)
    {
        ::ScrollMark m{};

        if (mark.Color.HasValue)
        {
            m.color = til::color{ mark.Color.Color };
        }

        if (HasSelection())
        {
            m.start = til::point{ _terminal->GetSelectionAnchor() };
            m.end = til::point{ _terminal->GetSelectionEnd() };
        }
        else
        {
            m.start = m.end = til::point{ _terminal->GetTextBuffer().GetCursor().GetPosition() };
        }

        // The version of this that only accepts a ScrollMark will automatically
        // set the start & end to the cursor position.
        _terminal->AddMark(m, m.start, m.end, true);
    }
    void ControlCore::ClearMark() { _terminal->ClearMark(); }
    void ControlCore::ClearAllMarks() { _terminal->ClearAllMarks(); }

    void ControlCore::ScrollToMark(const Control::ScrollToMarkDirection& direction)
    {
        const auto currentOffset = ScrollOffset();
        const auto& marks{ _terminal->GetScrollMarks() };

        std::optional<::ScrollMark> tgt;

        switch (direction)
        {
        case ScrollToMarkDirection::Last:
        {
            int highest = currentOffset;
            for (const auto& mark : marks)
            {
                const auto newY = mark.start.y;
                if (newY > highest)
                {

Review comment (suggestion):
Adding this to the PR was a bit of a mistake (I did `git restore` from another branch). But it might be something we'd want to keep anyways - up to you all! 😅
The benefits are:
* Much much faster vector creation (without WinRT indirection)
* Reserve the right amount of memory
* `emplace_back` constructs the trivial struct in-place instead of constructing it on the stack first and then copying it over to the heap

~~BTW I think this method is missing lock guards. Scroll marks are being written by the VT thread after all. I'm sure my other PR adds them. ^^~~ Merged the fix from main.

Code after:
        {
            if (auto conpty{ _connection.try_as<TerminalConnection::ConptyConnection>() })
            {
                conpty.ReparentWindow(owner);
            }
        }
        _owningHwnd = owner;
    }

    Windows::Foundation::Collections::IVector<Control::ScrollMark> ControlCore::ScrollMarks() const
    {
        const auto lock = _terminal->LockForReading();
        const auto& internalMarks = _terminal->GetScrollMarks();
        std::vector<Control::ScrollMark> v;

        v.reserve(internalMarks.size());

        for (const auto& mark : internalMarks)
        {
            v.emplace_back(
                mark.start.to_core_point(),
                mark.end.to_core_point(),
                OptionalFromColor(_terminal->GetColorForMark(mark)));
        }

        return winrt::single_threaded_vector(std::move(v));
    }

    void ControlCore::AddMark(const Control::ScrollMark& mark)
    {
        const auto lock = _terminal->LockForReading();
        ::ScrollMark m{};

        if (mark.Color.HasValue)
        {
            m.color = til::color{ mark.Color.Color };
        }

        if (_terminal->IsSelectionActive())
        {
            m.start = til::point{ _terminal->GetSelectionAnchor() };
            m.end = til::point{ _terminal->GetSelectionEnd() };
        }
        else
        {
            m.start = m.end = til::point{ _terminal->GetTextBuffer().GetCursor().GetPosition() };
        }

        // The version of this that only accepts a ScrollMark will automatically
        // set the start & end to the cursor position.
        _terminal->AddMark(m, m.start, m.end, true);