-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Certain SGR attributes are not preserved after a resize sequence #2540
Comments
Great analysis. This stems from the fact that we tried, in VT dispatch, to use the "public" console API (or whatever local simulacrum we could get our hands on)... we probably need a private resize for VT to hit. |
This is also kinda related to #1765/#1795, The |
Just as a note to ourselves, this is better, but not fixed: (this is 22519) On The reverse one is fixed, it's the orange one that's broken still. printf "\e[30;48;5;214m ORANGE \n\e[8;24;80t ORANGE \e[m\n" Guess: On the resize, we're resetting the ACTIVE attributes to the closest one on the 16 color table. That's resulting in the 256-color orange being emitted with a 16-color color instead. |
## Summary of the Pull Request When the screen is resized in ConHost via a VT escape sequence, the active text attributes could end up being corrupted if they were set to something that the legacy console APIs didn't support (e.g. RGB colors). This PR fixes that issue. ## Detailed Description of the Pull Request / Additional comments The way a resize is implemented is by retrieving the buffer information with `GetConsoleScreenBufferInfoEx`, updating the size fields, and then writing the data back out again with `SetConsoleScreenBufferInfoEx`. However, this also results in the active attributes being updated via the `wAttributes` field, and that's only capable of representing legacy console attributes. We address this by saving the full `TextAttribute` value before it gets corrupted in the `SetConsoleScreenBufferInfoEx` call, and then restore it again afterwards. ## Validation Steps Performed I've added a unit test to verify the attributes are correctly preserved for all VT resize operations, and I've also manually confirmed the test case in #2540 is now working as expected. ## PR Checklist - [x] Closes #2540 - [x] Tests added/passed - [ ] Documentation updated - [ ] Schema updated (if necessary)
Environment
Steps to reproduce
Open a WSL conhost shell, and execute the following two commands:
The first command uses an SGR escape sequence to set the background color to index 214 (a shade of orange), writes out the text "ORANGE", then uses the XTerm window manipulation sequence to resize the screen, and writes out "ORANGE" again.
The second command does the same sort of thing but with different attributes. It sets the colors to bright white (index 15) on blue (index 4), and also enable the reverse video attribute (making it blue on white).
Expected behavior
The screen resize should have no effect on the active SGR attributes, so in each case I'd expect to see two matching lines of text with identical colors.
Actual behavior
In the first test, the second "ORANGE" line is a shade of yellow rather than orange (the exact color will likely depend on your palette).
In the second test, the second "REVERSE" line is not actually reversed - it's white on blue instead of blue on white.
Cause
The resize escape sequence is handled by the
DispatchCommon::s_ResizeWindow
method, which does so by reading the screen buffer info withGetConsoleScreenBufferInfoEx
, modifiying just thedwSize
andsrWindow
fields (i.e the buffer and viewport sizes), and then writing the updated info back withSetConsoleScreenBufferInfoEx
. The problem is that theCONSOLE_SCREEN_BUFFER_INFOEX
structure can't reliable represent the text attributes in thewAttributes
field, so they can become corrupted in the process.The DECCOLM escape sequence, which is handled by the
AdaptDispatch::SetColumns
method, has essentially the same problem.The reverse video case could probably be fixed with improvements to the
GenerateLegacyAttributes
method, but it's never going to be possible to accurately handle every attribute value with a legacy equivalent. I think the real solution is to avoid using theSetConsoleScreenBufferInfoEx
method, and try and update the window and buffer size more directly, viaSetConsoleWindowInfo
andSetConsoleScreenBufferSize
. I haven't actually tried that, though, so maybe it's not as simple as I think.The text was updated successfully, but these errors were encountered: