-
Notifications
You must be signed in to change notification settings - Fork 8.4k
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
wslsys in alt buffer toggles DISABLE_NEWLINE_AUTO_RETURN #14690
Comments
holy hell Like, how do you even find this kind of stuff. This is 👌 So, seems like if we change it so that changing |
If we just want a quick fix, we could make the This isn't really correct though. Because we can still have a situation where one buffer has the mode set, and another has it reset, but the only state we care about internally is the global flag. So at least some of the buffers will be reporting a mode that doesn't match the active behavior. Ideally we'd just make the |
Just so you know how things currently stand, this is my understanding of the various modes: The The The In short: The first two should definitely be strictly global modes, the third I think could reasonably be made global, but the last two might need to remain as per-buffer modes for backwards compatibility. |
I'd bet there's a wacky chance that there's an app out there that uses different screen buffers (not VT ones) and relies on different modes in each. That just feels like the kind of weird gap that's been abused in the last 40 years. That being said, if there's anything to do to help mitigate #6987, I think we should try it. I think I'm cool with the breakdown you posted above. Let's just leave the last two per-buffer, but initialized by the global state. |
I think that this has been "officially supported" ever since the We may want to draw a clear line between what is shared between console buffers allocated via ¹ [irony intensifies] |
I've had another idea for this which I think should be a cleaner solution. If we can't make all of the modes global, the next best option would be to make all of them per-buffer modes. For legacy console apps, every buffer will have its own set of modes, and the When creating a new buffer, the defaults are largely static:
And note that the VT default is decided at startup and then is static for the life of the process - it's not affected by mode changes. The only special case is the VT alt buffer, which needs to give the impression that the modes are global. However, that can easily be achieved by copying the current modes from the main buffer into the alt buffer when it's created, and copying them back again when it's closed (we already do something similar for other buffer state). I think this fixes all of the existing problems, without changing any of the legacy behavior, and the model is easy to understand (all modes work the same way, rather than a mix of global and non-global modes). |
That seems like a fine solution to me! |
What would/should the behavior be for input modes? I'm asking because I really wish that I could call (Semi-offtopic rant - although Dustin is obviously right that |
@zadjii-msft Thanks for the pointer, I didn't know about that. Note though that per-process != per-buffer, and the two are not even incompatible with each other. I'd assert that per-buffer is "safe" in the sense that software using alternate buffers is really trying to explicitly save/restore state. Per-process is more interesting/challenging - I can personally vouch for the existence of a mountain of code trying to "set up" modes for the benefit of child processes and revert them later. On the one hand, it'd be great to delete; on the other, there's a lot of fragility there. One callout would be the absurdly complex Ctrl+C handling where the existence of |
The original console output modes were considered attributes of the buffer, while later additions were treated as global state, and yet both were accessed via the same buffer-based API. This could result in the reported modes being out of sync with the way the system was actually behaving, and a call to `SetConsoleMode` without updating anything could still trigger unpredictable changes in behavior. This PR attempts to address that problem by making all modes part of the buffer state, and giving them predictable default values. While this won't solve all the tmux layout-breaking issues in #6987, it does at least fix one case which was the result of an unexpected change in the `DISABLE_NEWLINE_AUTO_RETURN` mode. All access to the output modes is now done via the `OutputMode` field in `SCREEN_INFORMATION`. The fields that were tracking global state in the `Settings` class (`_fAutoReturnOnNewline` and `_fRenderGridWorldwide`) have now been removed. We still have a global `_dwVirtTermLevel` field, though, but that now serves as a default value for the `ENABLE_VIRTUAL_TERMINAL_PROCESSING` mode when creating a new buffer. It's enabled for conpty mode, and when the VT level in the registry is not 0. That default doesn't change. For the VT alternate buffer, things works slightly differently, since there is an expectation that VT modes are global. So when creating an alt buffer, we copy the current modes from the main buffer, and when it's closed, we copy them back again. ## Validation Steps Performed I've manually confirmed that this fixes the problem described in issue #14690. I've also added a basic feature test that confirms the modes are initialized as expected when creating new buffers, and changes to the modes in one buffer do not impact any other buffers. Closes #14690
Windows Terminal version
1.16.2641.0
Windows build number
10.0.19044.2364
Other Software
No response
Steps to reproduce
printf "\e[?1049h"
printf "\e[10CX\b\fY\n"
wslsys
printf "\e[10CX\b\fY\n"
Expected Behavior
The test case above moves the cursor right 10 columns, outputs an
X
, aBS
control (moving the cursor back a column), and aFF
control (moving the cursor down a row), then finally outputs aY
.In both cases the
Y
should be directly below theX
.Actual Behavior
After
wslsys
has been run, theDISABLE_NEWLINE_AUTO_RETURN
mode is turned off, so theFF
control also triggers a carriage return, and theY
is output in the first column.The problem is that the auto-return mode is tracked in two separates places. It's one of the modes of the
OutputMode
field in theSCREEN_INFORMATION
class, but it's also stored in the_fAutoReturnOnNewline
flag in the globalSettings
. These two places have different scope!By default
_fAutoReturnOnNewline
is true, and theDISABLE_NEWLINE_AUTO_RETURN
mode isn't set. But WSL toggles that state on startup, so in WSL the mode is set, and_fAutoReturnOnNewline
flag is false. When you switch to the alt buffer, though, you get a newSCREEN_INFORMATION
instance with the defaults again, so the mode is again not set, but the global_fAutoReturnOnNewline
is still false!This isn't immediately a problem, because the line feed operations rely on the
_fAutoReturnOnNewline
flag which still has the correct value. But once you runwslsys
, it makes a call setSetConsoleMode
which forces the_fAutoReturnOnNewline
flag to be refreshed. And although it doesn't change the mode, the mode was already wrong at this point, so that incorrect state is now transferred to the_fAutoReturnOnNewline
flag.From then, all the line feed controls will trigger a carriage return, which can be problematic for apps that weren't expecting that behavior. One case in particular is
tmux
, which relies on line feed controls to move down without a carriage return when redrawing the screen. If that isn't correct, the entire display gets messed up. This is at least one of the causes of #6987.The text was updated successfully, but these errors were encountered: