Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
j4james opened this issue Apr 23, 2020 · 4 comments · Fixed by #5509
Closed

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

j4james opened this issue Apr 23, 2020 · 4 comments · Fixed by #5509
Labels
Area-VT Virtual Terminal sequence support Issue-Bug It either shouldn't be doing this or needs an investigation. Needs-Tag-Fix Doesn't match tag requirements Priority-2 A description (P2) Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Milestone

Comments

@j4james
Copy link
Collaborator

j4james commented 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.

@ghost ghost added Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting Needs-Tag-Fix Doesn't match tag requirements labels Apr 23, 2020
@j4james
Copy link
Collaborator Author

j4james commented Apr 23, 2020

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

return _terminalApi.BoldText(bold);

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 j4james changed the title SGR 7 (reverse video) makes text in invisible in Windows Terminal SGR 7 (reverse video) makes text invisible in Windows Terminal Apr 23, 2020
@DHowett-MSFT DHowett-MSFT added Area-VT Virtual Terminal sequence support Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-2 A description (P2) Product-Terminal The new Windows Terminal. labels Apr 23, 2020
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label Apr 23, 2020
@j4james
Copy link
Collaborator Author

j4james commented 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:

// We only care about alpha for the default BG (which enables acrylic)
// If the bg isn't the default bg color, then make it fully opaque.
if (!attr.BackgroundIsDefault())
{
return 0xff000000 | bgColor;
}

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.

@DHowett-MSFT
Copy link
Contributor

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
Copy link
Contributor

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

@DHowett-MSFT DHowett-MSFT removed the Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting label Apr 23, 2020
@DHowett-MSFT DHowett-MSFT added this to the Terminal v1.x milestone Apr 23, 2020
@ghost ghost added the In-PR This issue has a related PR label Apr 23, 2020
@ghost ghost removed the In-PR This issue has a related PR label Apr 23, 2020
DHowett-MSFT pushed a commit that referenced this issue Apr 23, 2020
In order to support a transparent background for the acrylic effect, the
renderer sets the alpha value to zero for the default background color.
However, when the _reversed video_ attribute is set, the background is
actually filled with the foreground color, and will not be displayed
correctly if it is made transparent. This PR addresses that issue by
making sure the rendered background color is opaque if the reversed
video attribute is set.

## References

* This is not a major issue at the moment, since the _reverse video_
  attribute is not typically forwarded though conpty, but that will
  change once #2661 is fixed.

## PR Checklist
* [x] Closes #5498
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Requires documentation to be updated
* [x] I've discussed this with core contributors already. If not
  checked, I'm ready to accept this work might be rejected in favor of a
  different grand plan. Issue number where discussion took place: #5498

## Detailed Description of the Pull Request / Additional comments

This simply adds an additional check in `Terminal::GetBackgroundColor`
to make sure the returned color is opaque if the _reverse video_
attribute is set. At some point in the future this check may need to be
extended to support the `DECSCNM` reverse screen mode, but for now
that's not an issue.

## Validation Steps Performed

I've run the test case from issue #5498, and confirmed that it now works
as expected. I've also got an experimental fix for #2661 that I've
tested with this patch, and that now displays _reverse video_ attributes
correctly too.

Closes #5498
@ghost ghost added Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release. Needs-Tag-Fix Doesn't match tag requirements labels Apr 23, 2020
DHowett-MSFT pushed a commit that referenced this issue Apr 27, 2020
In order to support a transparent background for the acrylic effect, the
renderer sets the alpha value to zero for the default background color.
However, when the _reversed video_ attribute is set, the background is
actually filled with the foreground color, and will not be displayed
correctly if it is made transparent. This PR addresses that issue by
making sure the rendered background color is opaque if the reversed
video attribute is set.

## References

* This is not a major issue at the moment, since the _reverse video_
  attribute is not typically forwarded though conpty, but that will
  change once #2661 is fixed.

## PR Checklist
* [x] Closes #5498
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Requires documentation to be updated
* [x] I've discussed this with core contributors already. If not
  checked, I'm ready to accept this work might be rejected in favor of a
  different grand plan. Issue number where discussion took place: #5498

## Detailed Description of the Pull Request / Additional comments

This simply adds an additional check in `Terminal::GetBackgroundColor`
to make sure the returned color is opaque if the _reverse video_
attribute is set. At some point in the future this check may need to be
extended to support the `DECSCNM` reverse screen mode, but for now
that's not an issue.

## Validation Steps Performed

I've run the test case from issue #5498, and confirmed that it now works
as expected. I've also got an experimental fix for #2661 that I've
tested with this patch, and that now displays _reverse video_ attributes
correctly too.

Closes #5498
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-VT Virtual Terminal sequence support Issue-Bug It either shouldn't be doing this or needs an investigation. Needs-Tag-Fix Doesn't match tag requirements Priority-2 A description (P2) Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants