SGR 7 (reverse video) makes text invisible in Windows Terminal #7590

Closed
opened 2026-01-31 01:08:01 +00:00 by claunia · 4 comments
Owner

Originally created by @j4james on GitHub (Apr 23, 2020).

Environment

Windows build number: Version 10.0.18362.657
Windows Terminal version (if applicable): 0.11.1121.0

Steps to reproduce

  1. Open a bash shell in Windows Terminal.
  2. Execute printf "\e[mNORMAL \e[7;38m REVERSE \e[m\n"

Expected behavior

This is a weird test case, because conpty wouldn't usually forward SGR 7, so it's relying on a "feature" in conhost that forces it to pass-through any sequence that the dispatcher doesn't understand. In this case I'm relying on SGR 38 with a missing type parameter to trigger this pass-through. What this means is that the sequences that actually get sent down the conpty pipe look more like this:

\e[7;38mNORMAL \e[30;47m REVERSE \e[m\n

So ignoring the fact that the "pass through" feature is generally a bad idea, and this sequence is wrong to start with, I'd expect it to be interpreted as black on white (i.e. reversed), followed by white on black (colors changed to black on white, but still reversed).

Actual behavior

SGR 7 somehow seems to make the text invisible, so the first part of the line is blank, and the second half is white on black. Even stranger, it makes the first part of the shell prompt on the following line invisible too.

image

This may seem like an unimportant edge case, but I actually discovered this bug while experimenting with a fix for #2661 (which ended up causing more problems than it solved). Until we can get Windows Terminal to handle all the SGR sequences correctly, I don't think we'll be able to fix issues like #2661.

Originally created by @j4james on GitHub (Apr 23, 2020). # Environment Windows build number: Version 10.0.18362.657 Windows Terminal version (if applicable): 0.11.1121.0 # Steps to reproduce 1. Open a bash shell in Windows Terminal. 2. Execute `printf "\e[mNORMAL \e[7;38m REVERSE \e[m\n"` # Expected behavior This is a weird test case, because conpty wouldn't usually forward `SGR 7`, so it's relying on a "feature" in conhost that forces it to pass-through any sequence that the dispatcher doesn't understand. In this case I'm relying on `SGR 38` with a missing type parameter to trigger this pass-through. What this means is that the sequences that actually get sent down the conpty pipe look more like this: \e[7;38mNORMAL \e[30;47m REVERSE \e[m\n So ignoring the fact that the "pass through" feature is generally a bad idea, and this sequence is wrong to start with, I'd expect it to be interpreted as black on white (i.e. reversed), followed by white on black (colors changed to black on white, but still reversed). # Actual behavior `SGR 7` somehow seems to make the text invisible, so the first part of the line is blank, and the second half is white on black. Even stranger, it makes the first part of the shell prompt on the following line invisible too. ![image](https://user-images.githubusercontent.com/4181424/80116803-52d0a380-857e-11ea-89d7-0752d21ce458.png) This may seem like an unimportant edge case, but I actually discovered this bug while experimenting with a fix for #2661 (which ended up causing more problems than it solved). Until we can get Windows Terminal to handle all the SGR sequences correctly, I don't think we'll be able to fix issues like #2661.
Author
Owner

@j4james commented on GitHub (Apr 23, 2020):

Another easy way to demonstrate this issue is by changing this line:

d711d731d7/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp (L135)

to this:

    return _terminalApi.ReverseText(bold);

That's essentially making the bold attribute be interpreted as reversed video, and thus any bold text becomes invisible.

@j4james commented on GitHub (Apr 23, 2020): Another easy way to demonstrate this issue is by changing this line: https://github.com/microsoft/terminal/blob/d711d731d7d00259b2e0fe5847928c9f1c1121ed/src/cascadia/TerminalCore/TerminalDispatchGraphics.cpp#L135 to this: ```cpp return _terminalApi.ReverseText(bold); ``` That's essentially making the bold attribute be interpreted as reversed video, and thus any bold text becomes invisible.
Author
Owner

@j4james commented on GitHub (Apr 23, 2020):

Well I finally figured this out. It's a lot more obvious what's going on if you have the acrylic effect enabled. What's happening is it's testing to see if the background color is default, and if so it makes the background transparent. When reverse video is enabled, though, the background is no longer rendered with the background color, so that test isn't valid. See here:

fe3f528827/src/cascadia/TerminalCore/terminalrenderdata.cpp (L61-L66)

Essentially we need an extra check there to make sure the background is also made opaque when reverse video is enabled. Long term it'll get more complicated once we support DECSCNM mode on the WT side, but that still shouldn't be that big a deal.

Is it worth doing a PR for this now? It's only a one line change.

@j4james commented on GitHub (Apr 23, 2020): Well I finally figured this out. It's a lot more obvious what's going on if you have the acrylic effect enabled. What's happening is it's testing to see if the background color is default, and if so it makes the background transparent. When reverse video is enabled, though, the background is no longer rendered with the background color, so that test isn't valid. See here: https://github.com/microsoft/terminal/blob/fe3f52882758812f0f7ae780dfb4987d5cb7d41d/src/cascadia/TerminalCore/terminalrenderdata.cpp#L61-L66 Essentially we need an extra check there to make sure the background is also made opaque when reverse video is enabled. Long term it'll get more complicated once we support `DECSCNM` mode on the WT side, but that still shouldn't be that big a deal. Is it worth doing a PR for this now? It's only a one line change.
Author
Owner

@DHowett-MSFT commented on GitHub (Apr 23, 2020):

I'd absolutely appreciate a PR here. Puzzlingly, I love learning about the deficiencies in Terminal's VT implementation. We think conhost's is okay, so when we eventually do want to converge it's another datapoint in favor of why and when and how.

@DHowett-MSFT commented on GitHub (Apr 23, 2020): I'd absolutely appreciate a PR here. Puzzlingly, I love learning about the deficiencies in Terminal's VT implementation. We think conhost's is _okay_, so when we eventually do want to converge it's another datapoint in favor of _why_ and _when_ and _how_.
Author
Owner

@DHowett-MSFT commented on GitHub (Apr 23, 2020):

And thank you for looking at 2661. It's my great white whale issue. 😄

@DHowett-MSFT commented on GitHub (Apr 23, 2020): And thank you for looking at 2661. It's my great white whale issue. :smile:
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#7590