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

Add support for the DECSCNM screen mode #3817

Merged
8 commits merged into from
Jan 22, 2020
Merged

Conversation

j4james
Copy link
Collaborator

@j4james j4james commented Dec 3, 2019

Summary of the Pull Request

This adds support for the DECSCNM private mode escape sequence, which toggles the display between normal and reverse screen modes. When reversed, the background and foreground colors are switched. Tested manually, with Vttest, and with some new unit tests.

References

This also fixes issue #72 for the most part, although if you toggle the mode too fast, there is no discernible flash.

PR Checklist

  • Closes Add support for the DECSCNM Screen Mode #3773
  • CLA signed. If not, go over here and sign the CLA
  • Tests added/passed
  • Requires documentation to be updated
  • 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: #xxx

Detailed Description of the Pull Request / Additional comments

I've implemented this as a new flag in the Settings class, along with updates to the LookupForegroundColor and LookupBackgroundColor methods, to switch the returned foreground and background colors when that flag is set.

It also required a new private API in the ConGetSet interface to toggle the setting. And that API is then called from the AdaptDispatch class when the screen mode escape sequence is received.

The last thing needed was to add a step to the HardReset method, to reset the mode back to normal, which is one of the RIS requirements.

Note that this does currently work in the Windows Terminal, but once #2661 is implemented that may no longer be the case. It might become necessary to let the mode change sequences pass through conpty, and handle the color reversing on the client side.

Validation Steps Performed

I've added a state machine test to make sure the escape sequence is dispatched correctly, and a screen buffer test to confirm that the mode change does alter the interpretation of colors as expected.

I've also confirmed that the various "light background" tests in Vttest now display correctly, and that the tput flash command (in a bash shell) does actually cause the screen to flash.

@j4james j4james mentioned this pull request Dec 3, 2019
Copy link
Member

@zadjii-msft zadjii-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. We should file a follow-up to "passthrough DECSCNM and implement support in Windows Terminal"
  2. If someone emits enables reverse mode, then switches to the alt/main buffer, is the other buffer reversed too? (That's what'll happen here, but I'm not sure if that's how other terminals work)
  3. Great work as always 😄

src/host/getset.cpp Show resolved Hide resolved
@j4james
Copy link
Collaborator Author

j4james commented Dec 5, 2019

2. If someone emits enables reverse mode, then switches to the alt/main buffer, is the other buffer reversed too? (That's what'll happen here, but I'm not sure if that's how other terminals work)

That's the way XTerm works - other terminals vary wildly, but that's typical for anything to do with the alt buffer. For XTerm, the reverse screen mode is kind of like a theme for people that prefer a light background (which was the original VT use case too - it could be configured from the setup screen), so it makes sense that they wouldn't reset that mode when switching buffers.

@zadjii-msft zadjii-msft added Area-VT Virtual Terminal sequence support Product-Conhost For issues in the Console codebase labels Dec 5, 2019
@miniksa
Copy link
Member

miniksa commented Dec 31, 2019

I don't have any qualms with the implementation. It looks just fine to me. I'll sign after we finish discussion below.

But what I'm looking at here is how this works relative to the existing inversion flag COMMON_LVB_REVERSE_VIDEO which can be applied to any cell in the buffer.

It's probably inappropriate to use that flag and apply it uniformly throughout the buffer for the sake of toggling, so an additional flag is almost certainly warranted.

But I have two questions:

  1. Is DECSCNM only supposed to flip flop the two default colors and not any of the other colors applied to text elsewhere in the buffer? Like if I used SGR sequences to make red on blue text... it stays red on blue even with DECSCNM=ON?
  2. Is it supposed to have "no lasting effect" in that it doesn't really adjust the way that any text is written into the buffer while it is DECSCNM=ON, it only inverts the display in "real time" and stops doing the inversion when DECSCNM=OFF?

@j4james
Copy link
Collaborator Author

j4james commented Jan 1, 2020

  1. Is DECSCNM only supposed to flip flop the two default colors and not any of the other colors applied to text elsewhere in the buffer? Like if I used SGR sequences to make red on blue text... it stays red on blue even with DECSCNM=ON?

No, it applies to all colors, so red on blue would become blue on red. At the time a cell is rendered, if DECSCNM is enabled, the foreground color is used to render the background and the background color is used to render the foreground. It's essentially the same effect as the COMMON_LVB_REVERSE_VIDEO flag but applied to the entire display.

For cells that already have the COMMON_LVB_REVERSE_VIDEO attribute set, this mode inverts that behaviour, i.e. a cell with the COMMON_LVB_REVERSE_VIDEO attribute would be displayed as normal, while a normal cell is displayed reversed. In other words, the reversed state is the XOR of the COMMON_LVB_REVERSE_VIDEO flag and the DECSCNM mode.

  1. Is it supposed to have "no lasting effect" in that it doesn't really adjust the way that any text is written into the buffer while it is DECSCNM=ON, it only inverts the display in "real time" and stops doing the inversion when DECSCNM=OFF?

That's exactly right. It's purely a render-time effect.

@zadjii-msft zadjii-msft added this to the Terminal-2001 milestone Jan 3, 2020
@zadjii-msft zadjii-msft added the Needs-Second It's a PR that needs another sign-off label Jan 15, 2020
Copy link
Member

@miniksa miniksa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm good with this after updating the one style thing about if/else blocks.

src/host/settings.cpp Outdated Show resolved Hide resolved
src/host/settings.cpp Outdated Show resolved Hide resolved
@ghost ghost added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Jan 17, 2020
@ghost ghost removed the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Jan 17, 2020
Copy link
Member

@miniksa miniksa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to go.

@miniksa miniksa added AutoMerge Marked for automatic merge by the bot when requirements are met and removed Needs-Second It's a PR that needs another sign-off labels Jan 22, 2020
@ghost
Copy link

ghost commented Jan 22, 2020

Hello @miniksa!

Because this pull request has the AutoMerge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

@ghost ghost merged commit e675de3 into microsoft:master Jan 22, 2020
@j4james j4james deleted the feature-decscnm branch January 26, 2020 23:03
@ghost
Copy link

ghost commented Feb 13, 2020

🎉Windows Terminal Preview v0.9.433.0 has been released which incorporates this pull request.:tada:

Handy links:

@DHowett-MSFT
Copy link
Contributor

🎉 Once again, thanks for the contribution!

This pull request was included in a set of conhost changes that was just
released with Windows Insider Build 19603.

ghost pushed a commit that referenced this pull request Jul 9, 2020
## Summary of the Pull Request

This PR adds full support for the `DECSCNM` reverse screen mode in the Windows Terminal to align with the implementation in conhost.

## References

* The conhost implementation of `DECSCNM` was in PR #3817.
* WT originally inherited that functionality via the colors being passed through, but that behaviour was lost in PR #6506.

## PR Checklist
* [x] Closes #6622
* [x] CLA signed.
* [ ] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema 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: #6622

## Detailed Description of the Pull Request / Additional comments

The `AdaptDispatch::SetScreenMode` now checks if it's in conpty mode and simply returns false to force a pass-through of the mode change. And the `TerminalDispatch` now has its own `SetScreenMode` implementation that tracks any changes to the reversed state, and triggers a redraw in the renderer.

To make the renderer work, we just needed to update the `GetForegroundColor` and `GetBackgroundColor` methods of the terminal's `IRenderData` implementation to check the reversed state, and switch the colors being calculated, the same way the `LookupForegroundColor` and `LookupBackgroundColor` methods work in the conhost `Settings` class.

## Validation Steps Performed

I've manually tested the `DECSCNM` functionality for Windows Terminal in Vttest, and also with some of my own test scripts.
ghost pushed a commit that referenced this pull request Jul 10, 2020
This is a refactoring of the renderer color calculations to simplify the
implementation, and to make it easier to support additional
color-altering rendition attributes in the future (e.g. _faint_ and
_conceal_).

## References

* This is a followup to PRs #3817 and #6809, which introduced additional
  complexity in the color calculations, and which suggested the need for
  refactoring. 

## Detailed Description of the Pull Request / Additional comments

When we added support for `DECSCNM`, that required the foreground and
background color lookup methods to be able to return the opposite of
what was requested when the reversed mode was set. That made those
methods unnecessarily complicated, and I thought we could simplify them
considerably just by combining the calculations into a single method
that derived both colors at the same time.

And since both conhost and Windows Terminal needed to perform the same
calculations, it also made sense to move that functionality into the
`TextAttribute` class, where it could easily be shared.

In general this way of doing things is a bit more efficient. However, it
does result in some unnecessary work when only one of the colors is
required, as is the case for the gridline painter. So to make that less
of an issue, I've reordered the gridline code a bit so it at least
avoids looking up the colors when no gridlines are needed.

## Validation Steps Performed

Because of the API changes, quite a lot of the unit tests had to be
updated. For example instead of verifying colors with two separate calls
to `LookupForegroundColor` and `LookupBackgroundColor`, that's now
achieved with a single `LookupAttributeColors` call, comparing against a
pair of values. The specifics of the tests haven't changed though, and
they're all still working as expected.

I've also manually confirmed that the various color sequences and
rendition attributes are rendering correctly with the new refactoring.
This pull request was closed.
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 AutoMerge Marked for automatic merge by the bot when requirements are met Product-Conhost For issues in the Console codebase
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for the DECSCNM Screen Mode
4 participants