Skip to content

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

Closed

Description

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.

Activity

  1. ghost added
    Needs-TriageIt's a new issue that the core contributor team needs to triage at the next triage meeting
    on Sep 24, 2019
  2. ghost added
    Needs-Tag-FixDoesn't match tag requirements
    on Sep 24, 2019
  3. zadjii-msft commented on Sep 24, 2019

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

  4. christianparpart commented on Sep 24, 2019

    @christianparpart
    Author

    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.

  5. zadjii-msft commented on Sep 24, 2019

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

  6. christianparpart commented on Sep 24, 2019

    @christianparpart
    Author

    Hey Mike Griese (@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?

  7. zadjii-msft commented on Sep 24, 2019

    @zadjii-msft
    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".

  8. christianparpart commented on Sep 24, 2019

    @christianparpart
    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?

  9. zadjii-msft commented on Sep 25, 2019

    @zadjii-msft
    Member

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

  10. ghost removed
    Needs-Tag-FixDoesn't match tag requirements
    on Sep 25, 2019
  11. 46 remaining items

  12. mkq commented on Jul 27, 2022

    @mkq

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

  13. thammegowda commented on Nov 19, 2022

    @thammegowda
    Member

    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!

  14. michael-ts commented on Dec 2, 2022

    @michael-ts

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

    Thamme Gowda (@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.

  15. thammegowda commented on Dec 2, 2022

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

  16. michael-ts commented on Dec 2, 2022

    @michael-ts

    Thamme Gowda (@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.

  17. thammegowda commented on Dec 2, 2022

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

  18. DHowett commented on Dec 2, 2022

    @DHowett
    Member

    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

  19. michael-ts commented on Dec 7, 2022

    @michael-ts

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

  20. chiendo97 commented on Dec 7, 2022

    @chiendo97

    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
    
  21. fagg commented on Jun 2, 2023

    @fagg

    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.

  22. iHeadway commented on Jun 2, 2023

    @iHeadway

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

  23. ChildishhAlbino commented on Jun 5, 2023

    @ChildishhAlbino

    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

  24. brookst commented on Jun 9, 2023

    @brookst

    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.

  25. vinser commented on Oct 1, 2023

    @vinser
  26. brookst commented on Oct 1, 2023

    @brookst

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Area-InputRelated to input processing (key presses, mouse, etc.)Area-VTVirtual Terminal sequence supportIssue-BugIt either shouldn't be doing this or needs an investigation.Needs-Author-FeedbackThe original author of the issue/PR needs to come back and respond to somethingProduct-ConptyFor console issues specifically related to conptyResolution-Fix-CommittedFix is checked in, but it might be 3-4 weeks until a release.

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions