-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
win,tty: allow setting ENABLE_VIRTUAL_TERMINAL_INPUT
for raw mode
#4688
win,tty: allow setting ENABLE_VIRTUAL_TERMINAL_INPUT
for raw mode
#4688
Conversation
I see there's related CI failures here, but I think I'd first like to get some feedback on the general approach before starting to fix those up. |
There's I don't think it's possible to fully automate a TTY reset in a bulletproof manner. Example edge case: what if libuv is loaded and unloaded as a DLL? What if it's loaded and unloaded multiple times? |
Looking at the test failures suggests this change changes the observable behavior. That suggests it should be opt-in. |
ENABLE_VIRTUAL_TERMINAL_INPUT
for raw modeENABLE_VIRTUAL_TERMINAL_INPUT
for raw mode
20506b2
to
c379f91
Compare
@bnoordhuis Thanks for taking a look! Updated the PR and the PR description/commit message. Yes, this does result in changes in observable behavior. Whether these would be breaking changes is probably a matter of perspective, though -- the origin of these changes is the fact that different UNIX terminal emulators chose different escape sequences to represent the same keys, and libuv already provided its own translation for some Windows key events to escape sequences, while Windows chose different ones when it added Ultimately, I do think that setting And |
Windows provides the `ENABLE_VIRTUAL_TERMINAL_INPUT` flag for TTY input streams as a companion flag to `ENABLE_VIRTUAL_TERMINAL_PROCESSING`, which libuv is already setting for TTY output streams. Setting this flag lets the terminal emulator perform some of the processing that libuv already currently does for input events, but most notably enables receiving control sequences that are otherwise entirely unavailable, e.g. for bracketed paste (which the Node.js readline implementation added basic support for in nodejs/node@87af913b66eab78088acfd). libuv currently already provides translations for key events to control sequences, i.e. what this mode is intended to provide, but libuv does not and cannot translate all such events. Since the control sequences differ from the ones that Windows has chosen to standardize on, and applications may not be expecting this change, this is opt-in for now (but ideally will be the default behavior starting in libuv v2.x, should that ever happen). Another downside of this change is that not all shells reset this mode when an application exits. For example, when running a Node.js program with this flag enabled inside of PowerShell in Windows terminal, if the application exits while in raw TTY input mode, neither the shell nor the terminal emulator reset this flag, rendering the input stream unusable. While there's general awareness of the problem that console state is global state rather than per-process (same as on UNIX platforms), it seems that applications like PowerShell aren't expecting to need to unset this flag on the input stream, only its output counterpart (e.g. https://github.com/PowerShell/PowerShell/blob/4e7942135f998ab40fd3ae298b020e161a76d4ef/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs#L1156). Hence, `uv_tty_reset_mode()` is extended to reset the terminal to its original state if the new mode is being used. Refs: nodejs/node@87af913 Refs: microsoft/terminal#4954
0dce57b
to
11d4e61
Compare
03d28bc
to
c785048
Compare
@bnoordhuis If you get the chance to take another look, that would be great 🙂 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but maybe another maintainer can take a quick look just in case?
I don't see any obvious issues with it. There are many existing state management bugs in the tty code on both platforms, and this seems to be handle everything consistent with the existing bugs, which seems an adequate state of affairs, and a strict improvement from before the PR. |
Windows provides the
ENABLE_VIRTUAL_TERMINAL_INPUT
flag for TTY input streams as a companion flag toENABLE_VIRTUAL_TERMINAL_PROCESSING
, which libuv is already setting for TTY output streams.Setting this flag lets the terminal emulator perform some of the processing that libuv already currently does for input events, but most notably enables receiving control sequences that are otherwise entirely unavailable, e.g. for bracketed paste (which the Node.js readline implementation added basic support for in nodejs/node@87af913b66eab78088acfd).
libuv currently already provides translations for key events to control sequences, i.e. what this mode is intended to provide, but libuv does not and cannot translate all such events. Since the control sequences differ from the ones that Windows has chosen to standardize on, and applications may not be expecting this change, this is opt-in for now (but ideally will be the default behavior starting in libuv v2.x, should that ever happen).
Another downside of this change is that not all shells reset this mode when an application exits. For example, when running a Node.js program with this flag enabled inside of PowerShell in Windows terminal, if the application exits while in raw TTY input mode, neither the shell nor the terminal emulator reset this flag, rendering the input stream unusable.
While there's general awareness of the problem that console state is global state rather than per-process (same as on UNIX platforms), it seems that applications like PowerShell aren't expecting to need to unset this flag on the input stream, only its output counterpart (e.g. https://github.com/PowerShell/PowerShell/blob/4e7942135f998ab40fd3ae298b020e161a76d4ef/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs#L1156).
Hence,
uv_tty_reset_mode()
is extended to reset the terminal to its original state if the new mode is being used.Refs: nodejs/node@87af913
Refs: microsoft/terminal#4954