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

Look at Windows key handling #872

Open
willmcgugan opened this issue Oct 11, 2022 · 14 comments
Open

Look at Windows key handling #872

willmcgugan opened this issue Oct 11, 2022 · 14 comments
Labels
enhancement New feature or request Task

Comments

@willmcgugan
Copy link
Collaborator

Holding down shift creates ctrl-at keys.

@davep davep added Task enhancement New feature or request labels Jan 11, 2023
@sandos
Copy link

sandos commented Apr 14, 2023

Yes, please!

I believe this issue is prohibiting using anything with shift in windows, where, for example, ctrl+o works fine, shift+ctrl+o creates as you say ctrl-at sequences instead. With Windows Terminal also allocating a lot of shortcuts for itself it would be nice to expand the possible list of keys used, considering windows terminal is almost a prerequisite for performance. Every line after the ctrl+@ was really a shift+ctrl+o: (its the same in "cmd.exe" as windows terminal)

Key(key='ctrl+o', character='\x0f', name='ctrl_o', is_printable=False)
Key(key='ctrl+@', character='\x00', name='ctrl_@', is_printable=False)
Key(key='ctrl+o', character='\x0f', name='ctrl_o', is_printable=False)
Key(key='ctrl+o', character='\x0f', name='ctrl_o', is_printable=False)

@sandos
Copy link

sandos commented Apr 14, 2023

Oh, I noticed another thing as well, which is maybe even worse: pressing a ctrl+alt-key combo delays / blocks combos that do work, until some class of event happens. For example the lone binding

Binding("ctrl+o", "switch", "Hide hosts", show=True, priority=True),

will be delayed after pressing ctrl+alt+r.

This is also easily observable in "textual keys": initially, pressing ctrl+o gets immediate responses. Pressing ctrl+alt+r once, and then ctrl+o shows nothing happening.. until for example the mouse is hovered over the console.

@davep
Copy link
Contributor

davep commented Sep 7, 2023

Dragging this into "in progress" and using this as a place to log some other issues with keys and Windows. See also the problem with the default binding for the command palette on Windows and also #3178.

@davep davep self-assigned this Sep 7, 2023
@darrenburns
Copy link
Member

Just as a note - TextArea uses shift for a few of its bindings (shift+arrow keys, ctrl+shift+arrow keys), and they seemed to work fine when testing on Windows.

@davep
Copy link
Contributor

davep commented Sep 8, 2023

"Native" Windows, or under Parallels? I was able to recreate the shift issue yesterday with the latest Textual.

@davep
Copy link
Contributor

davep commented Sep 11, 2023

Just tested under "native" Windows and I'm seeing the exact same effects as I do when on my Mac under Parallels.

@davep
Copy link
Contributor

davep commented Sep 11, 2023

After experimenting while printing out the low-level values coming in via win32.EventMonitor.run, I'm noticing a couple or so things (this isn't a coherent set of facts yet, just observations to make sense of):

Pressing Shift on its own

When Shift is depressed, nothing happens. However, when it is released, two events occur:

Field Value
UnicodeChar '\x00'
AsciiChar b'\x00'
bKeyDown 1
wRepeatCount 1
wVirtualKeyCode 16
wVirtualScanCode 42
dwControlKeyState 16 (SHIFT_PRESSED)

followed immediately by:

Field Value
UnicodeChar '\x00'
AsciiChar b'\x00'
bKeyDown 0
wRepeatCount 1
wVirtualKeyCode 16
wVirtualScanCode 42
dwControlKeyState 0

Pressing Shift as a modifier key

If Shift is pressed to modify another key, there seems to be a key-down event for it, plus a down and up event for the modified version of the other key. For example, if you press Shift and 1, the following events occur:

Field Value
UnicodeChar '\x00'
AsciiChar b'\x00'
bKeyDown 1
wRepeatCount 1
wVirtualKeyCode 16
wVirtualScanCode 42
dwControlKeyState 16 (SHIFT_PRESSED)
Field Value
UnicodeChar '!'
AsciiChar b'!'
bKeyDown 1
wRepeatCount 1
wVirtualKeyCode 0
wVirtualScanCode 0
dwControlKeyState 0
Field Value
UnicodeChar '!'
AsciiChar b'!'
bKeyDown 0
wRepeatCount 1
wVirtualKeyCode 49
wVirtualScanCode 2
dwControlKeyState 16 (SHIFT_PRESSED)

@davep
Copy link
Contributor

davep commented Sep 11, 2023

Following on from this, in the heart of the Win32 driver is this bit of code:

if (
    key_event.dwControlKeyState
    and key_event.wVirtualKeyCode == 0
):
    continue

If I'm reading this correctly this looks to be the start of an approach to filtering some keys out, but it doesn't go all the way. It may be that more filtering is needed here. However, this will need to be done in a way that we can be 100% confident that we're not affecting the collection of sequences for valid keys.

@davep
Copy link
Contributor

davep commented Sep 11, 2023

If the above bit of code is extended with this:

or (key == "\x00" and key_event.wVirtualKeyCode != 50)

this appears to solve the problem1. That is, it appears to filter out all of the spurious NUL characters, while allowing for Ctrl+space to make it through. I'm not including this here as the solution just yet, but I am including it here as a solution (or at the very least possibly acceptable workaround).

This also does raise the side-issue of why ctrl+space isn't seen as an alias for ctrl+@.

Footnotes

  1. Albeit with a magic number; and I'm not a fan of magic numbers. I need to figure out why the virtual key code is 50 here, because I believe VK_SPACE in Windows is 32.2

  2. After more digging and testing, this makes more sense. This is really Ctrl+2, so the virtual key code is 50 (aka 0x32).

@davep
Copy link
Contributor

davep commented Sep 13, 2023

Moving this back to "in progress", as the scope for this has wandered a wee bit, and also there's some variation in how Windows behaves, it seems, that means any fix here can land differently depending on the environment that Windows is in.

So: I think a reset of this issue, and the associated PR, is in order. Filtering out the spurious NULs is easy enough; the question is how to we do that without filtering out a "genuine" NUL (which is often Ctrl+Space); and do we even want to care about that?

There's a cost/benefit decision to make here.

@davep
Copy link
Contributor

davep commented Sep 28, 2023

Bumping this over to "Blocked" for now; but something to keep in mind when we review #3411.

@willmcgugan
Copy link
Collaborator Author

@davep is this covered by the work you are doing on keys?

@davep
Copy link
Contributor

davep commented Nov 22, 2023

Not really; as this one is more about how the Windows driver can cope with the spurious NULs -- unrelated to unknown escape sequences and possibly-incorrect key names.

@tconbeer
Copy link
Contributor

This just bit me for the second time. I also just noticed (for the first time) that naked ctrl presses also trigger a ctrl+@ /NUL key.

Windows 11, Windows Terminal, Powershell

Textual Diagnostics

Versions

Name Value
Textual 0.45.1
Rich 13.7.0

Python

Name Value
Version 3.9.13
Implementation CPython
Compiler MSC v.1929 64 bit (AMD64)
Executable C:\Users\tedco\AppData\Local...\pypoetry\Cache\virtualenvs\harlequin-XIn5tjID-py3.9\Scripts\python.exe

Operating System

Name Value
System Windows
Release 10
Version 10.0.22621

Terminal

Name Value
Terminal Application Windows Terminal
TERM Not set
COLORTERM Not set
FORCE_COLOR Not set
NO_COLOR Not set

Rich Console options

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request Task
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants