-
Notifications
You must be signed in to change notification settings - Fork 7.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
Linux pwsh enables DECCKM, but Windows pwsh cannot handle it; arrow keys stop working after exiting linux powershell #12268
Comments
|
Originally filed: microsoft/terminal#5257 |
|
@DHowett-MSFT As a workaround it seems like one could create a script that would emit the appropriate reset sequence. Would you post this sequence in PowerShell string format? |
|
|
Thanks for that. It gave me enough info to interpret this arcane knowledge. That sequence doesn't restore functionality, but the "Reset to Initial State" sequence ("`ec") does. |
|
It legitimately looks like it's being stripped out of the output. When I type this: I get this out of the pty: but when I run this: I get I wonder why it's being filtered from powershell's output stream. Similar sequences, like "`e[?2004l", are not. |
|
As a workaround, you can do this: Masking that you're requesting DECRST 1 by placing a |
Wow! |
|
Of note, this reproduces without PSReadline available 😄 (I tracked down why I can't forcibly print "`e[?1l" -- PowerShell isn't using VT input on Windows, so that value is technically meaningless to it. Conhost is ignoring it.) |
|
I have come across this bug when I SSH from Ubuntu to Windows machine. It works when I SSH from Bash without starting PowerShell. To reproduce in PowerShell on Ubuntu in Gnome Terminal: After some digging I have found dotnet/corefx#6488. The Pull Request fixed a number of bugs related to terminal escape codes handling. It seems to me the DECCKM might be set in System.Console, see lines 937 - 947 |
|
Found the issue: dotnet/runtime#27626 |
|
Excellent investigation. Thanks! |
|
Tagging @TylerLeonhardt so he's aware of this relative to https://github.com/PowerShell/GraphicalTools Specifically, this is why
|
There is another case, namely an "intra-Unix" one: The cursor keys in Since PowerShell unconditionally turns that mode on ( ( |
|
How can we detect whether SS3 mode is on? |
|
You don’t need to detect it. An application should set the states it needs on startup and set them back to reasonable defaults for a terminal on exit. Nothing to remember, nothing to restore. |
|
@DHowett, this isn't so much about terminals, but about the shells that run in them, and as my previous comment implies, different shells:
For instance:
Therefore, while it may be a challenge to implement, restoring the previous state seems like the right thing to do. |
|
@mklement0 I'm also not talking about terminals. As the reporter of the issue and engineering owner for a terminal, I'm supposed to be aware of how applications expect to work... so here goes: A shell that cannot go from a terminal left in its default state to its required state is broken. Introducing another back-and-forth call/response to determine the application keypad mode state—ESPECIALLY if you're going to do it every time control returns to the user—is madness. It limits the ability of users to pre-fill the keyboard input queue and the ability for terminals and applications across high-latency links to properly coordinate. There's a default assumption here: applications are started with the terminal in its default state, and applications that start other applications return the terminal to its default state. ¹ Per the above axiom, this is all applications. |
|
Your example above indicates that ksh is operating as expected (terminal not in default state => it isn't expected to get to the state it needs when that state is the default state) and that pwsh is broken (it expects a non-default state, but does not request it.) |
|
Given your premise, PowerShell is broken in two respects:
Fixing (a) would require the very back-and-forth you think should be avoided - even though probably only a minority of commands (other shells, CUIs) change the terminal state. So I gather that:
|
|
So, I do think powershell (or according to an earlier comment, the .NET runtime 😦) is broken here. Before reading user input where it cares about the format of the arrow/line editing keys, it should set the mode it wants. After it's done, it should reset that mode. That's very cheap, and it doesn't require any back-and-forth. I've observed zsh doing this:
There's no querying, just assertion. "DECCKM should be on now." "DECCKM should be off now." It never needs to know the state, because of two things:
|
|
@DHowett Many thanks! I think we should ask @SteveL-MSFT to add this in next milestone plan. |
|
@SteveL-MSFT & @TylerLeonhardt - is there a PowerShell issue tracking this? This impacts |
|
FWIW, this issue also applies to users of powershell on macos, running in any terminal emulator--it's not linux-specific. |
|
The problem is dotnet/runtime#27626. Seems like dotnet is not in a hurry to fix as it's in |
|
Please also disable that mode when running child processes! |
|
I don't particularly want to dive into the code in powershell; I'm here because cli/cli#3071 was initially reported as a bug in my terminal emulator :-p The test scenario is:
|
|
@wez You can just download the compiled artifacts, tests them in your environment and give a feedback before the PR will be merged. |
|
@wez, you can emulate what the PR will implement as follows: $Host.UI.Write("`e[?1l"); gh auth login; $Host.UI.Write("`e[?1h")For entire-session support - as a stopgap that should also work for older PS versions - you can place the following at the end of your # Turns application-key mode ON before displaying the PS prompt and back OFF right after.
$function:PSConsoleHostReadLine = " `$Host.UI.Write(`"``e[?1h`"); $function:PSConsoleHostReadLine; `$Host.UI.Write(`"``e[?1l`") "
# For non-interactive invocations of the PowerShell CLI: turn application-key mode off too,
# So that it is left OFF on exiting (obviously won't work for -NoProfile invocations).
$Host.UI.Write("`e[?1l") |
|
Thanks, but I don't use powershell; as I mentioned above, I'm just here because this issue was raised by one of the users of my terminal. @gaborbernat: perhaps you could try those suggestions? |
|
I can confirm that @mklement0 solution works on: |
|
🎉This issue was addressed in #14943, which has now been successfully released as Handy links: |

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.


Steps to reproduce
pwshLinux powershell emits the escape sequence
DECSETDECCKM[1] on startup before it emits the first prompt.This reconfigures the cursor keys, which usually emit
CSI A...D, to emitSS3 A...Dinstead.Linux powershell can handle
SS3arrow key sequences. This is fine.When Linux powershell exits, it does not restore
DECCKMto its original state. All applications that manipulate global terminal state are expected to return the terminal to "normal" once they are done.Because the state is not restored when you exit Linux powershell, Windows powershell (which doesn't know that the terminal state has been changed) will start to receive
SS3arrow key sequences.Windows powershell cannot handle
SS3arrow key sequences, and it ignores them, so the arrow keys do not work.This also reproduces when you SSH to a linux machine, but WSL is easier for a self-contained repro.
Expected behavior
DECCKMis disabled on exit.Actual behavior
DECCKMremains enabled on exit, downstream applications get confused.Environment data
[1] Notes about DECCKM
DECCKM reconfigures the arrow keys as follows
[2] I've investigated PowerShell, PSReadline and dotnet/runtime, and I cannot determine where DECCKM is being enabled.
The text was updated successfully, but these errors were encountered: