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

RIS reset doesn't clear the display and scrollback correctly #2307

Closed
j4james opened this issue Aug 6, 2019 · 6 comments · Fixed by #2367
Closed

RIS reset doesn't clear the display and scrollback correctly #2307

j4james opened this issue Aug 6, 2019 · 6 comments · Fixed by #2367
Assignees
Labels
Area-VT Virtual Terminal sequence support Issue-Bug It either shouldn't be doing this or needs an investigation. Product-Conhost For issues in the Console codebase Resolution-Fix-Available It's available in an Insiders build or a release
Milestone

Comments

@j4james
Copy link
Collaborator

j4james commented Aug 6, 2019

Environment

Windows build number: Version 10.0.18362.175

Steps to reproduce

  1. Open a conhost WSL shell.
  2. Execute printf "\ec" (the RIS escape sequence).
  3. Note that the display isn't cleared.
  4. Do a few directory listings or something to fill the scrollback buffer.
  5. Execute printf "\e[41m\ec" (setting the background to red, followed by RIS).
  6. Note that the display has been cleared with a red background, and the scrollback is only partially cleared.

Expected behavior

The RIS escape sequence should clear the display with the default background color, and should erase everything in the scrollback buffer.

Actual behavior

The RIS escape sequence doesn't work at all when there isn't anything in the scrollback. And when it does work, it clears the display with the wrong color, and doesn't completely erase the scrollback buffer.

More details

The initial RIS doesn't work because of the way the Viewport::Subtract method is implemented. When the removeMe viewport completely overlaps the original viewport, it returns a single empty viewport, but it really ought to return nothing. An empty viewport throws an exception when passed to the SCREEN_INFORMATION::WriteRect method, which is what happens when called from the ScrollRegion function here. This in turn causes the AdaptDispatch::_EraseScrollback method to fail, which then aborts the AdaptDispatch::HardReset method.

The reason the color is wrong, and the scrollback isn't fully erased, is because of the order of the steps in the AdaptDispatch::HardReset method. You need to reset the SGR state before clearing the display, otherwise it'll use the current background color for the fill color. And you need to clear the display before clearing the scrollback, otherwise the last page of content will be retained in the scrollback.

I'd be happy to provide a PR with these fixes if nobody disagrees with my assessment.

@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 Aug 6, 2019
@DHowett-MSFT DHowett-MSFT added Area-VT Virtual Terminal sequence support Help Wanted We encourage anyone to jump in on these. Issue-Bug It either shouldn't be doing this or needs an investigation. Product-Conhost For issues in the Console codebase and removed Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting labels Aug 8, 2019
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label Aug 8, 2019
@DHowett-MSFT
Copy link
Contributor

I've tagged this up for you, but we can wait for @zadjii-msft if you don't want to start on it just yet. 😄

@zadjii-msft
Copy link
Member

Yea this seems like an accurate assessment of the situation. Great find :)

@ghost ghost added the In-PR This issue has a related PR label Aug 8, 2019
@ghost ghost added Needs-Tag-Fix Doesn't match tag requirements and removed Help Wanted We encourage anyone to jump in on these. labels Aug 28, 2019
DHowett-MSFT pushed a commit that referenced this issue Aug 28, 2019
When the scrollback buffer is empty, the RIS escape sequence (Reset to Initial
State) will fail to clear the screen, or reset any of the state. And when there
is something in the scrollback, it doesn't get cleared completely, and the
screen may get filled with the wrong background color (it should use the
default color, but it actually uses the previously active background color).
This commit attempts to fix those issues.

The initial failure is caused by the `SCREEN_INFORMATION::WriteRect` method
throwing an exception when passed an empty viewport. And the reason it's passed
an empty viewport is because that's what the `Viewport::Subtract` method
returns when the result of the subtraction is nothing.  The PR fixes the
problem by making the `Viewport::Subtract` method actually return nothing in
that situation. 

This is a change in the defined behavior that also required the associated
viewport tests to be updated. However, it does seem a sensible change, since
the `Subtract` method never returns empty viewports under any other
circumstances. And the only place the method seems to be used is in the
`ScrollRegion` implementation, where the previous behavior is guaranteed to
throw an exception.

The other issues are fixed simply by changing the order in which things are
reset in the `AdaptDispatch::HardReset` method. The call to `SoftReset` needed
to be made first, so that the SGR attributes would be reset before the screen
was cleared, thus making sure that the default background color would be used.
And the screen needed to be cleared before the scrollback was erased, otherwise
the last view of the screen would be retained in the scrollback buffer.

These changes also required existing adapter tests to be updated, but not
because of a change in the expected behaviour. It's just that certain tests
relied on the `SoftReset` happening later in the order, so weren't expecting it
to be called if say the scrollback erase had failed. It doesn't seem like the
tests were deliberately trying to verify that the SoftReset _hadn't_ been
called.

In addition to the updates to existing tests, this PR also add a new screen
buffer test which verifies the display and scrollback are correctly cleared
under the conditions that were previously failing.

Fixes #2307.
@ghost ghost added Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release. and removed In-PR This issue has a related PR labels Aug 28, 2019
@ghost
Copy link

ghost commented Aug 29, 2019

I tried the CI build but printf "\ec" still doesn't clear all scrollback; reset and Ctrl-L doesn't work either. It seems that only the viewport is cleared when Ctrl-L is pressed.

DHowett-MSFT pushed a commit that referenced this issue Sep 3, 2019
When the scrollback buffer is empty, the RIS escape sequence (Reset to Initial
State) will fail to clear the screen, or reset any of the state. And when there
is something in the scrollback, it doesn't get cleared completely, and the
screen may get filled with the wrong background color (it should use the
default color, but it actually uses the previously active background color).
This commit attempts to fix those issues.

The initial failure is caused by the `SCREEN_INFORMATION::WriteRect` method
throwing an exception when passed an empty viewport. And the reason it's passed
an empty viewport is because that's what the `Viewport::Subtract` method
returns when the result of the subtraction is nothing.  The PR fixes the
problem by making the `Viewport::Subtract` method actually return nothing in
that situation.

This is a change in the defined behavior that also required the associated
viewport tests to be updated. However, it does seem a sensible change, since
the `Subtract` method never returns empty viewports under any other
circumstances. And the only place the method seems to be used is in the
`ScrollRegion` implementation, where the previous behavior is guaranteed to
throw an exception.

The other issues are fixed simply by changing the order in which things are
reset in the `AdaptDispatch::HardReset` method. The call to `SoftReset` needed
to be made first, so that the SGR attributes would be reset before the screen
was cleared, thus making sure that the default background color would be used.
And the screen needed to be cleared before the scrollback was erased, otherwise
the last view of the screen would be retained in the scrollback buffer.

These changes also required existing adapter tests to be updated, but not
because of a change in the expected behaviour. It's just that certain tests
relied on the `SoftReset` happening later in the order, so weren't expecting it
to be called if say the scrollback erase had failed. It doesn't seem like the
tests were deliberately trying to verify that the SoftReset _hadn't_ been
called.

In addition to the updates to existing tests, this PR also add a new screen
buffer test which verifies the display and scrollback are correctly cleared
under the conditions that were previously failing.

Fixes #2307.

(cherry picked from commit 974e95e)
@j4james
Copy link
Collaborator Author

j4james commented Sep 10, 2019

@Visualer Note that this is a fix for conhost - Window Terminal may have other problems of its own.

@ghost
Copy link

ghost commented Sep 24, 2019

🎉This issue was addressed in #2367, which has now been successfully released as Windows Terminal Preview v0.5.2661.0.:tada:

Handy links:

@DHowett-MSFT DHowett-MSFT added Resolution-Fix-Available It's available in an Insiders build or a release and removed Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release. labels Sep 25, 2019
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label Sep 25, 2019
@DHowett-MSFT
Copy link
Contributor

This also went out with Windows Insider Fast 18990! 😄

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. Product-Conhost For issues in the Console codebase Resolution-Fix-Available It's available in an Insiders build or a release
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants