textual icon indicating copy to clipboard operation
textual copied to clipboard

ctrl+space interpreted as ctrl+@ or \x00 in VSCode terminal (and many others)

Open RedBeard0531 opened this issue 5 months ago • 5 comments

Have you checked closed issues? (https://github.com/Textualize/textual/issues?q=is%3Aissue+is%3Aclosed) yes

Have you checked against the most recent version of Textual? (https://pypi.org/search/?q=textual) yes

The ask / suggested fix

Interpret ctrl+@ as ctrl+space since that is what most terminals send when you hit ctrl+space.

The bug

Run textual keys in kitty and vscode terminal and press space and ctrl+space. In kitty you correctly get:

Key(key='space', character=' ', name='space', is_printable=True)                                                                                                                                                                                      
Key(key='ctrl+space', character=None, name='ctrl_space', is_printable=False) 

but VSCode shows

Image

(Screenshot since vscode doesn't support shift+highlight to bypass mouse interception)

I think ctrl+space is much more likely to be a useful mapping than ctrl+@, so it is probably best to just interpret the latter as the former. Interestingly if I hit ctrl+shift+2 (@ is shift+2 on my keyboard), vscode outputs the same line as ctrl+space, while kitty outputs nothing. Kitty defaults to mapping that to go to window 2, so it is intercepted before reaching textual (ctrl+shift is the default "kitty_mod" to send commands to kitty). If I remove that mapping it will send the following, so there is no way to generate ctrl+@ unless you have a dedicated @ key (or make a weird custom mapping...):

Key(key='ctrl+shift+2', character=None, name='ctrl_shift_2', is_printable=False)  

After typing most of this bug up, I also tried xterm, Apple's terminal.app, wezterm and ghostTTY (all on a mac but sshed into linux). ghostTTY behaved identically to kitty (although it sends ctrl+shift+2 by default since it is unmapped), but the rest send ctrl+@ like vscode. If I had to guess, kitty and ghost support the fancy kitty input protocol but the others don't.

Textual Diagnostics

Versions

Name Value
Textual 3.5.0
Rich 14.0.0

Python

Name Value
Version 3.13.5
Implementation CPython
Compiler GCC 6.3.0 20170516
Executable /home/mstearn/.local/share/uv/tools/textual-dev/bin/python

Operating System

Name Value
System Linux
Release 6.14.10
Version #1 SMP Sat Jun 7 02:45:18 UTC 2025

Terminal

Name Value
Terminal Application vscode (1.101.2)
TERM xterm-256color
COLORTERM truecolor
FORCE_COLOR Not set
NO_COLOR Not set

Rich Console options

Name Value
size width=214, height=31
legacy_windows False
min_width 1
max_width 214
is_terminal True
encoding utf-8
max_height 31
justify None
overflow None
no_wrap False
highlight None
markup None
height None

RedBeard0531 avatar Jun 27 '25 08:06 RedBeard0531

We found the following entries in the FAQ which you may find helpful:

Feel free to close this issue if you found an answer in the FAQ. Otherwise, please give us a little time to review.

This project is developed and maintained by Will McGugan. Consider sponsoring Will's work on this project (and others).

This is an automated reply, generated by FAQtory

github-actions[bot] avatar Jun 27 '25 08:06 github-actions[bot]

Update: I got curious and tried alt+space and the results were far more interesting and varied! Again, kitty and ghostTTY were the only ones that handled it correctly as:

Key(key='alt+space', character=None, name='alt_space', is_printable=False)  

xterm crashed terminal keys with UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe5 in position 0: invalid continuation byte (it may be misconfigured since I never use it)

vscode and terminal.app output: Image

wezterm outputs:

Key(key='escape', character='\x1b', name='escape', is_printable=False, aliases=['escape', 'ctrl+left_square_brace'])
Key(key='space', character=' ', name='space', is_printable=True)

Fun!

RedBeard0531 avatar Jun 27 '25 09:06 RedBeard0531

@Guevaraxxx

Guevaraxxx avatar Jun 27 '25 09:06 Guevaraxxx

ctrl+alt+space is even more of a lost cause. ghostTTY is the only one that correctly handles it. Kitty outputs the same as plain space, VSCode outputs nothing, and I'm not going to bother looking into everyone else...

RedBeard0531 avatar Jun 27 '25 09:06 RedBeard0531

Please check #6074 as it enables more of the Kitty protocol. I guess for VSCode we need to implement the Kitty protocol in Javascript, but it's a VS code feature not a Textual bug/feature

adamritter avatar Aug 26 '25 11:08 adamritter