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

Open
opened 2026-01-31 02:57:24 +00:00 by claunia · 0 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:24 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#11787