Conhost color selection doesn't work correctly with wrapping and DBCS #11790

Closed
opened 2026-01-31 02:57:26 +00:00 by claunia · 2 comments
Owner

Originally created by @j4james on GitHub (Dec 13, 2020).

Environment

Windows build number: Version 10.0.18363.1198
Windows Terminal version (if applicable):

Steps to reproduce

  1. Open a cmd shell in conhost.
  2. Open the Properties dialog and make sure Enable line wrapping selection is turned on.
  3. Select a range of text wrapped across multiple lines.
  4. Press Ctrl+4 to highlight the selected text in green.
  5. Output some text from double byte character set.
  6. Select a range of those characters starting and ending halfway through a double width character.
  7. Again press Ctrl+4 to highlight the selected text in green.

Expected behavior

When the selection wraps across multiple lines, the green highlighting should also wrap in exactly the same way. When selecting halfway through a double width character, the selection always covers the full width, so I'd expect the green highlighting to work in the same way.

image

Actual behavior

The wrapped selection changes to a block selection when painting the green background. And only half of the start and end characters in the DBCS range are painted green (I should note that this renders differently in the current openconsole build, but is still doesn't match the initial selection).

image

The reason for this behaviour is that the color selection code just uses a simple rect spanning the start and end points of the selection, where typically a selection operation should be using the Selection::GetSelectionRects method to obtain the affected range (which automatically handles the line wrapping option, and makes sure double width characters are fully covered).

The code I'm referring to is here:

d09fdd61cb/src/host/selectionInput.cpp (L720)

And my recommendation would be to change the line above to use the GetSelectionRects method like this:

const auto selectionRects = GetSelectionRects();
for (const auto& selectionRect : selectionRects)
{
    ColorSelection(selectionRect, selectionAttr);
}

I suppose it's possible the current behaviour is deliberate, but I think it's more likely it was just an oversight when conhost was updated to support wrapped selections.

Originally created by @j4james on GitHub (Dec 13, 2020). # Environment ```none Windows build number: Version 10.0.18363.1198 Windows Terminal version (if applicable): ``` # Steps to reproduce 1. Open a cmd shell in conhost. 2. Open the _Properties_ dialog and make sure _Enable line wrapping selection_ is turned on. 3. Select a range of text wrapped across multiple lines. 4. Press `Ctrl+4` to highlight the selected text in green. 5. Output some text from double byte character set. 6. Select a range of those characters starting and ending halfway through a double width character. 7. Again press `Ctrl+4` to highlight the selected text in green. # Expected behavior When the selection wraps across multiple lines, the green highlighting should also wrap in exactly the same way. When selecting halfway through a double width character, the selection always covers the full width, so I'd expect the green highlighting to work in the same way. ![image](https://user-images.githubusercontent.com/4181424/102002429-45764e00-3cf4-11eb-8756-ad816ac8d7b0.png) # Actual behavior The wrapped selection changes to a block selection when painting the green background. And only half of the start and end characters in the DBCS range are painted green (I should note that this renders differently in the current openconsole build, but is still doesn't match the initial selection). ![image](https://user-images.githubusercontent.com/4181424/102002438-60e15900-3cf4-11eb-8d5c-f9da282af6b3.png) The reason for this behaviour is that the color selection code just uses a simple rect spanning the start and end points of the selection, where typically a selection operation should be using the `Selection::GetSelectionRects` method to obtain the affected range (which automatically handles the line wrapping option, and makes sure double width characters are fully covered). The code I'm referring to is here: https://github.com/microsoft/terminal/blob/d09fdd61cbb11b7ef2ccdd4820349ffe898ad583/src/host/selectionInput.cpp#L720 And my recommendation would be to change the line above to use the `GetSelectionRects` method like this: ```cpp const auto selectionRects = GetSelectionRects(); for (const auto& selectionRect : selectionRects) { ColorSelection(selectionRect, selectionAttr); } ``` I suppose it's possible the current behaviour is deliberate, but I think it's more likely it was just an oversight when conhost was updated to support wrapped selections.
claunia added the Needs-TriageResolution-Fix-CommittedNeeds-Tag-Fix labels 2026-01-31 02:57:27 +00:00
Author
Owner

@DHowett commented on GitHub (Dec 13, 2020):

Definitely an oversight, probably owing to Color Select being a hidden feature 😄

Legend has it, someone who uses CDB a lot inside the Windows organization added it as well as the “strip leading zeroes on copy” option long before Michael took over the project in ca. 2015.

I think it’s cool; my only beef with it (apart from this bug. Excellent find on your part!) is that it actually manipulates the buffer.

We have some plans to build on the TextBuffer pattern range support + a new interface to pass to the renderer (ICustomTextEffect?) to make this kind of stuff render-only. Eventually, eventually.

@DHowett commented on GitHub (Dec 13, 2020): Definitely an oversight, probably owing to Color Select being a hidden feature :smile: Legend has it, someone who uses CDB a lot inside the Windows organization added it as well as the “strip leading zeroes on copy” option long before Michael took over the project in ca. 2015. I think it’s cool; my only beef with it (apart from this bug. Excellent find on your part!) is that it actually manipulates the buffer. We have some plans to build on the TextBuffer pattern range support + a new interface to pass to the renderer (ICustomTextEffect?) to make this kind of stuff render-only. Eventually, eventually.
Author
Owner

@ghost commented on GitHub (Jan 28, 2021):

:tada:This issue was addressed in #8577, which has now been successfully released as Windows Terminal Preview v1.6.10272.0.🎉

Handy links:

@ghost commented on GitHub (Jan 28, 2021): :tada:This issue was addressed in #8577, which has now been successfully released as `Windows Terminal Preview v1.6.10272.0`.:tada: Handy links: * [Release Notes](https://github.com/microsoft/terminal/releases/tag/v1.6.10272.0) * [Store Download](https://www.microsoft.com/store/apps/9n8g5rfz9xk3?cid=storebadge&ocid=badge)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#11790