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

Bug Report: Control+Space not sent to terminal emulator. #2865

Closed
christianparpart opened this issue Sep 24, 2019 · 54 comments · Fixed by #6309
Closed

Bug Report: Control+Space not sent to terminal emulator. #2865

christianparpart opened this issue Sep 24, 2019 · 54 comments · Fixed by #6309
Assignees
Labels
Area-Input Related to input processing (key presses, mouse, etc.) Area-VT Virtual Terminal sequence support Issue-Bug It either shouldn't be doing this or needs an investigation. Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something Product-Conpty For console issues specifically related to conpty Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Milestone

Comments

@christianparpart
Copy link

Environment

Windows build number: Version 10.0.18362.356
Windows Terminal version 0.4.2382.0

Any other software? yes, **mine** (also a terminal emulator)

Steps to reproduce

Best way to see this (if you don't have key tracing on in our own terminal app),
fire up a TMUX session, have it configured with at least one more line, like this:

bind ^space next-window

which basically states, that Ctrl+Space will cause the terminal to switch to the next window.

Except, that on Windows Terminal (or my terminal emulator, using ConPTY), it doesn't. :-)

Expected behavior

TMUX windows switching (i.e.: NUL-byte sent to PTY slave)

Actual behavior

Action Ignored.

@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 Sep 24, 2019
@zadjii-msft
Copy link
Member

I'm going to guess this is a combo of:

There might be some discussion here if conpty should interpret a single NUL byte as Ctrl+Space. Isn't Ctrl+@ also NUL though? There might just be no way to handle that, if we can't be sure what it was to begin with.

@zadjii-msft zadjii-msft added Area-VT Virtual Terminal sequence support Product-Conpty For console issues specifically related to conpty labels Sep 24, 2019
@christianparpart
Copy link
Author

christianparpart commented Sep 24, 2019

So I tested the following terminals:

  • xterm
  • Linux console
  • Konsole (KDE)
  • gnome-terminal (VTE)
  • urxvt
  • OS/X's standard terminal

And all of them interpret Ctrl+Space as NUL character.

After long digging I finally found where I was first reading about it.

he NULL character (code 0) is represented by Ctrl-@, "@" being the code immediately
before "A" in the ASCII character set.
For convenience, a lot of terminals accept Ctrl-Space as an alias for Ctrl-@.

(Reference: Wikipedia)

In the VT520 docs I sadly didn't find it with crossreading, but in VT220 docs (link found via Chapter 3.2.5) it looks like it is what I was looking for - even though it's not talking about Ctrl+@.

But in case of doubt, I'd go with what most (see list above) terminal emulators do. Mapping Ctrl+Space to emit a NUL byte. :)

EDIT: added OS/X terminal to the list.

@zadjii-msft
Copy link
Member

Ah but see the trick isn't in the Ctrl+Space -> NUL conversion. That's easy. The problem comes from conpty - the layer that's responsible for translating *nix-isms from the terminal into Windows-isms. We need to be able to build an INPUT_RECORD from the input that's sent from the terminal to conpty, so commandline applications can read that INPUT_RECORD. When commandline applications are attached to conpty, they still assume that they're able to read full INPUT_RECORDs from the input, not just a stream of characters. The problem comes from the fact that we can't be sure if NUL meant Ctrl+Space or Ctrl+@. If we also added the appropriate Ctrl+@ -> NUL mapping to the terminal, then conpty would be unable to differentiate between those keypresses.

I guess we could just presume one of them, with a note that it's by design, and hope for more robust input encoding to be able to support the other keystroke.

@christianparpart
Copy link
Author

christianparpart commented Sep 24, 2019

Hey @zadjii-msft, thx for the quick response. I am not a Windows-isms-dev, so I can't talk much about Windows internals, but how I'd see that, is, that Ctrl+space, A..Z, [, , ], ^, _ is being translated to C0 control codes.

I'm not sure you can simply construct an INPUT_RECORD that contains a C0 byte.

typedef struct _KEY_EVENT_RECORD {
  BOOL  bKeyDown;
  WORD  wRepeatCount;
  WORD  wVirtualKeyCode;
  WORD  wVirtualScanCode;
  union {
    WCHAR UnicodeChar;
    CHAR  AsciiChar;
  } uChar;
  DWORD dwControlKeyState;
} KEY_EVENT_RECORD;

Maybe KEY_EVENT_RECORD.AsciiChar could do the trick, since C0 is part of ASCII, that's how I'd understand that. p.s.: Please don't shoot at me, because I'm referencing the MSDN's KEY_EVENT_RECORD struct. :-)

The problem comes from the fact that we can't be sure if NUL meant Ctrl+Space or Ctrl+@. If we also added the appropriate Ctrl+@

WRT that, I don't think you really have to (from a console application's point of view, as - on the above terminal emulators, you can't either).

What part could I be missing?

@zadjii-msft
Copy link
Member

So you're definitely on the right track here, but I'll point you straight at the meat of the code we're talking about: https://github.com/microsoft/terminal/blob/master/src/terminal/parser/InputStateMachineEngine.cpp

The InputStateMachineEngine is the part of conpty that's responsible for translating a stream of characters into a stream of INPUT_RECORDs. You can see here us attempting to manually translate a bunch of other control keys already. Or here, where we're building the INPUT_RECORDs.

We absolutely could use the UnicodeChar/AcsiiChar part of the struct to hold the C0 char. That's true. However, the job of conpty is to try and maintain compatibility for Windows-like programs. So for something like powershell.exe, vim.exe, far manager, etc, these are all programs that only know the world through the Win32 Console API. When they're running in a conpty session, they still need to be able to read input as if they were running in a real console window. That's where the InputStateMachineEngine comes in. It takes the other C0 characters and translates them into full-fledged INPUT_RECORDs, similar to the records that would be generated by typing input directly into the console window.
So, we'll translate them into not into a singular INPUT_RECORD holding only that char, but a series of records, indicating a full sequence of keypresses. For something like Ctrl+H, we'll generate sequences akin to "ctrl down", "h down (with char=0x8)", "h up", "ctrl up". If a win32 console application wants to use these Win32 style keys, they can without any changes to their code. For something like WSL that doesn't actually care about these keys, and only cares about the chars, we'll actually do another translation from INPUT_RECORD back to a sequence of chars, but that's a entirely separate discussion 😉.

So we can do this translation, and we can just pick one of Ctrl+Space or Ctrl+@ to be the translation for NUL, but we'd have to document it as such, because Windows client applications would no longer be able to differentiate between the two when running in conpty. I suppose that's not such a big deal, considering that neither works at all right now, but we'd still have to document it clearly, otherwise we'd inevitably get bug reports that say "when I press Ctrl+@ in the Terminal powershell thinks I pressed Ctrl+Space".

@christianparpart
Copy link
Author

Thanks for the detailed explanation. I keep forgetting it's Windows OS, nah. When it comes to documentation, I'd go with what most common terminal emulators to at the time of this writing (I try hard being objectively here :-D).

But OTOH, I think maybe the #1173 could probably mitigate this issue?

@zadjii-msft
Copy link
Member

You're definitely right. #1173 will also apply to input to the client application, as well as output.

@zadjii-msft zadjii-msft added the Issue-Bug It either shouldn't be doing this or needs an investigation. label Sep 25, 2019
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label Sep 25, 2019
@DHowett-MSFT DHowett-MSFT removed the Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting label Oct 24, 2019
@DHowett-MSFT DHowett-MSFT added this to the Console Backlog milestone Oct 24, 2019
@impguard
Copy link

impguard commented Nov 7, 2019

Is this why ctrl-6 doesn't currently get passed through/interpreted properly? ctrl-any number seems to not be handled as expected at the moment

@zadjii-msft
Copy link
Member

Oh hey, did this get solved long before 1.1? I'm testing out a bunch of the #4999 scenarios right now, and this one just so happens to already work fine in the 0.11.1333 build of the Terminal I'm running. It's hard to know for sure, but I think we did something a while back that improved out NUL handling.

@zadjii-msft zadjii-msft added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label May 14, 2020
@digash
Copy link

digash commented Sep 28, 2021

Similar to this #2865 (comment)
just using less used sequence and windows terminal key remapping.

;; TODO: remove this hack when bug fixed: https://github.com/PowerShell/Win32-OpenSSH/issues/1842
;; Add this to your Windows Terminal settings.json
;; {
;;   "command":
;;   { "action": "sendInput",
;;     "input": "\u001b[9~"
;;   },
;;   "keys": "ctrl+space"
;; }

(global-set-key "\e[9~" 'set-mark-command)

And if you use scree on the other side then you only need this in your .screenrc:

bindkey "^[[9~" stuff ^@

@kim-dae-hyun
Copy link

kim-dae-hyun commented Mar 11, 2022

I had same issue in my development environment.
When I connect to WSL, windows terminal send Ctrl+space exatly, but when I connect to remote linux server via ssh, then Ctrl+Sapce is not sent to linux server.
I confirmed with cat -v command.
In conclusion, open-ssh for windows program does not send ctrl+sapce.
This issues was fixed by below patch
PowerShell/openssh-portable#569
If you use higher version than 8.9 of open-ssh ( 8.9 version does not include this patch)
this issue will be fixed.

@cpbotha
Copy link

cpbotha commented Jul 19, 2022

To fix this, you can install this fixed version of the PowerShell openssh-portable project: PowerShell/openssh-portable#569 (comment)

I just did so with msiexec, then re-connected from Windows with the newly installed c:\Program Files\OpenSSH\ssh.exe and Ctrl-Space was happily recognized by Emacs in tmux on the other side.

@mkq
Copy link

mkq commented Jul 26, 2022

Using Cygwin zsh inside Windows Terminal 1.13.11431.0, Ctrl+Space seems to do nothing, while it shoud do

> bindkey | grep set-mark
"^@" set-mark-command

so I can do Ctrl+Space to start selection, move the cursor, Ctrl+W ⇒ cut, move the cursor, Ctrl+Y ⇒ paste.

Will that be addressed in #1173 (which is much too technical for me)?

@DHowett
Copy link
Member

DHowett commented Jul 26, 2022

That seems like a Cygwin bug to me. Here's what I get in WSL...

@mkq
Copy link

mkq commented Jul 27, 2022

That seems like a Cygwin bug to me. Here's what I get in WSL...

Thanks. I don't know how to report that to the Cygwin devs, though, since Cygwin zsh inside Cygwin mintty works. I'll just live with this workaround: bindkey '\e[3;5~' set-mark-command (i.e. Ctrl+Del) in my .zshrc.

(Found by pressing Ctrl+V, Ctrl+Del, which prints ^[[3;5~, Ctrl+V being bound to quoted-insert.)

@thammegowda
Copy link
Member

thammegowda commented Nov 19, 2022

If anyone still facing this issue: This issue seems to be on ssh, as mentioned in the previous comments.
There maybe two ssh clients inside your $PATH.

# WSL / bash
$ which ssh ssh.exe
/usr/bin/ssh
/mnt/c/WINDOWS/System32/OpenSSH/ssh.exe

# Powershell 
PS C:>  get-command ssh
CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     ssh.exe                                            8.6.0.1    C:\WINDOWS\System32\OpenSSH\ssh.exe

The ssh.exe client from windows does not handle CTRL+Space as the way it should be (atleast as of the latest windows today). Remember to use ssh client from WSL and CTRL+Space works on emacs as expected!

@michael-ts
Copy link

michael-ts commented Dec 2, 2022

Remember to use ssh client from WSL and CTRL+Space works on emacs as expected!

@thammegowda
Uh... how? Powershell can't see anything in the WSL filesystem. I tried copying /usr/bin/ssh over to the Windows side, but when I try to execute it in Powershell it asks me what application I want to open it with. (Hey, since I can run Windows executables from within WSL I figured why not the reverse?)

Oh, and in case you ask, I can't run ssh within WSL because for some reason it times out trying to connect to the host. Which is in a Hyper-V VM on the same machine.

@thammegowda
Copy link
Member

@michael-ts I run ssh inside WSL (first, bash then ssh) and that's the way it works for me.

Looks like you have issue with networking setup inside WSL, and your ssh is unable to reach to the remote. Verify that internet works inside WSL by ping bing.com

@michael-ts
Copy link

michael-ts commented Dec 2, 2022

@thammegowda Thanks, I can ping the Internet from WSL, but I have had no end to the networking issues with Hyper-V. I used to be able to ssh to it but had more serious issues, namely that networking would completely stop working outside of between the host and the VM at odd intervals. The fix for that apparently which I no longer recall caused this issue. Trying to administer my own machine is too much work sometimes... ;-)
Anyway, I was hoping there was some solution besides running in WSL, but I guess not.

@thammegowda
Copy link
Member

@michael-ts I think the solution is that somebody has to patch the OpenSSH inside windows dir ( C:\WINDOWS\System32\OpenSSH\ssh.exe) to resolve this issue. I don't know who that somebody is and if they are aware of this issue.

@DHowett
Copy link
Member

DHowett commented Dec 2, 2022

For what it's worth, this issue has been fixed in newer versions of Win32-OpenSSH. They are often released to earlier versions of Windows by way of servicing updates.

At my disposal I have v8.9, which does properly record Ctrl+Space

image

@michael-ts
Copy link

@DHowett Thanks! I went searching for that and discovered I could update to that version from PowerShell using winget install "openssh beta".

@chiendo97
Copy link

For anyone which doesn't have admin rights, you guys can use scoop to install the latest verison of OpenSSH.
Then in any terminal apps (Windows Terminal, Iterms, PowerShell), use the scoop's ssh version to connect to any servers, the Ctrl-Space will work correctly.

scoop install openssh
cd .\scoop\shims\
.\ssh.exe ip:port

@fagg
Copy link

fagg commented Jun 2, 2023

This doesn't appear to be fixed for me, even in a local WSL Ubuntu instance. cat -v confirms that Ctrl-<SPACE> is ignored.

I am running Terminal version 1.16.10261.0 on Windows 10 19045.3031.

@iHeadway
Copy link

iHeadway commented Jun 2, 2023

Windows 11, Terminal 1.17.11461, powershell 7.3.4. ctrl-space isn't working in neovimj (no keycode sent after ctrl-q)

@ChildishhAlbino
Copy link

Yeah tried setting up my Tmux config on WSL2 and can't get Ctrl+Space prefix key to work

PS C:\Users\conno> wsl -v
WSL version: 1.2.5.0
Kernel version: 5.15.90.1
WSLg version: 1.0.51
MSRDC version: 1.2.3770
Direct3D version: 1.608.2-61064218
DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows version: 10.0.22621.1702

Windows Terminal Preview 1.18.1462.0

@brookst
Copy link

brookst commented Jun 9, 2023

Same. Regular WSL2 distro running bash inside Windows Terminal Preview Version: 1.18.1462.0.

> wsl.exe -v
WSL version: 1.2.5.0
Kernel version: 5.15.90.1
WSLg version: 1.0.51
MSRDC version: 1.2.3770
Direct3D version: 1.608.2-61064218
DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows version: 10.0.22621.1778

> showkey -a
Press any keys - Ctrl-D will terminate this program
         32 0040 0x20    # Space
^J       10 0012 0x0a    # Ctrl + Enter
^A        1 0001 0x01    # Ctrl + A
^B        2 0002 0x02    # Ctrl + B
^C        3 0003 0x03    # Ctrl + C
^D        4 0004 0x04    # Ctrl + D

Control + Space doesn't make it to the Linux shell.

@vinser

This comment was marked as off-topic.

@brookst
Copy link

brookst commented Oct 1, 2023

Checking again, there seems to have been a bump to Windows, but nothing else:

> wsl.exe -v
WSL version: 1.2.5.0
Kernel version: 5.15.90.1
WSLg version: 1.0.51
MSRDC version: 1.2.3770
Direct3D version: 1.608.2-61064218
DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows version: 10.0.22621.2283

Windows Terminal also seems to be the same version:

Windows Terminal Preview
Version: 1.18.1462.0
An update is available.
Version: 1.18.1462

However now Control + Space reports as ^@:

> showkey -a
Press any keys - Ctrl-D will terminate this program
         32 0040 0x20   # Space
'        39 0047 0x27   # Single quote/@ symbol
^@        0 0000 0x00   # Control + Space
^@        0 0000 0x00   # Control + Single quote/@ symbol

That's fine for me, but a little weird that this started working without any apparent change to the system.

Edit: Just to note I use a United Kingdom QWERTY layout, so I have a single quote/@ key instead of the US ANSI single/double quote key. I'm not sure how the keys map there.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Input Related to input processing (key presses, mouse, etc.) Area-VT Virtual Terminal sequence support Issue-Bug It either shouldn't be doing this or needs an investigation. Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something Product-Conpty For console issues specifically related to conpty Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Projects
None yet
Development

Successfully merging a pull request may close this issue.