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

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.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 24
  • Comments: 54 (19 by maintainers)

Commits related to this issue

Most upvoted comments

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 https://github.com/PowerShell/openssh-portable/pull/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.

I came across this as dup of #4317 (https://github.com/microsoft/terminal/issues/4317)

In Windows Terminal Preview Version: 1.2.2381.0 the bug highlight in #4137 (ie CTRL+SPACE is not passing to ssh/tmux sessions) still exists. Can you please not close this as the other was closed as a dup and this should not be closed until also resolve this problem.

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 <kbd>Ctrl+Space</kbd>

image

For emacs, I finally resolve this issue by remapping C-SPC to C-z using PowerToys. You also have to bind C-z to set-mark-command as follows. (global-set-key (kbd "C-z") 'set-mark-command)

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

@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.

Similar to this https://github.com/microsoft/terminal/issues/2865#issuecomment-869087333 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 ^@

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!

To fix this, you can install this fixed version of the PowerShell openssh-portable project: https://github.com/PowerShell/openssh-portable/pull/569#issuecomment-1130048955

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.

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

🎉This issue was addressed in #6309, which has now been successfully released as Windows Terminal Preview v1.1.1671.0.🎉

Handy links:

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 <kbd>Ctrl+H</kbd>, 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 <kbd>Ctrl+Space</kbd> or <kbd>Ctrl+@</kbd> 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 <kbd>Ctrl+@</kbd> in the Terminal powershell thinks I pressed <kbd>Ctrl+Space</kbd>”.