[PR #17638] Introduce the concept of "selection spans" instead of "rects" #31301

Open
opened 2026-01-31 09:46:26 +00:00 by claunia · 0 comments
Owner

Original Pull Request: https://github.com/microsoft/terminal/pull/17638

State: closed
Merged: Yes


Right now, selections are stored as a set of points (start, end, pivot)
and converted into rectangles based on the contents of the screen buffer
every single render pass.

They are also painted fairly late in the rendering cycle.

This pull request makes a few changes to how selections happen.

Selections are now requested earlier in the rendering pass, during the
creation of the RenderInfo, and stored as a span<point_span>. To
make that span work, the selection data must be durably stored
somewhere.

Therefore, Terminal and conhost now take advantage of their new
generational selection data (#17676) to create and cache arrays of
point_spans covering their selections.

Unlike selection rects, linear (non-box) selections take only a single
entry in the span set. Also unlike selection rects, but like search
highlights, selection spans use buffer coordinates.

In the future, AtlasEngine can use the information sent in during
PrepareRenderInfo to influence text rendering decisions such as the
foreground and background color for a grapheme cluster or the gridlines.

Unfortunately, GDI is stuck with the old selection rendering
implementation and therefore, we still need to produce selection rects
with viewport coordinates
and filter them down to the render engine's
dirty region. This is because GDI wants to invert all on-screen
pixels in the selection range after the final render to make sure
sixels, pixels, and lines are all displayed in the appropriate vintage
style.

As part of this change, I've migrated conhost's search highlight to not
read text directly out of the buffer but instead use the new
CopyRequest added by @tusharsnx in #16377.

Many of the tests for conhost behavior had a copy of conhost's code in
them, which sorta begs the question. I migrated them to use hardcoded
expected values to better catch regressions.

In Terminal, the "SelectAfterScroll" ControlCore tests weren't testing
anything they said they were, so I made them do so.

**Original Pull Request:** https://github.com/microsoft/terminal/pull/17638 **State:** closed **Merged:** Yes --- Right now, selections are stored as a set of points (start, end, pivot) and converted into rectangles based on the contents of the screen buffer **every single render pass**. They are also painted fairly late in the rendering cycle. This pull request makes a few changes to how selections happen. Selections are now requested earlier in the rendering pass, during the creation of the `RenderInfo`, and stored as a `span<point_span>`. To make that `span` work, the selection data must be durably stored somewhere. Therefore, Terminal and conhost now take advantage of their new generational selection data (#17676) to create and cache arrays of `point_span`s covering their selections. Unlike selection rects, linear (non-box) selections take only a single entry in the span set. Also unlike selection rects, but _like_ search highlights, selection spans use buffer coordinates. In the future, AtlasEngine can use the information sent in during `PrepareRenderInfo` to influence text rendering decisions such as the foreground and background color for a grapheme cluster or the gridlines. Unfortunately, GDI is stuck with the old selection rendering implementation _and therefore, we still need to produce selection rects with viewport coordinates_ and filter them down to the render engine's dirty region. This is because GDI wants to **invert** all on-screen pixels in the selection range after the final render to make sure sixels, pixels, and lines are all displayed in the appropriate vintage style. As part of this change, I've migrated conhost's search highlight to not read text directly out of the buffer but instead use the new `CopyRequest` added by @tusharsnx in #16377. Many of the tests for conhost behavior had a copy of conhost's code in them, which sorta begs the question. I migrated them to use hardcoded expected values to better catch regressions. In Terminal, the "SelectAfterScroll" ControlCore tests weren't testing *anything* they said they were, so I made them do so.
claunia added the pull-request label 2026-01-31 09:46:26 +00:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#31301