-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Fix SendInput handling #7900
Fix SendInput handling #7900
Conversation
While not explicitly permitted, a wide range of software, including Windows' own touch keyboard, sets the wScan member of the KEYBDINPUT structure to 0, resulting in scanCode being 0 as well. In these situations we'll now use the vkey to get a scanCode.
VERIFY_IS_FALSE(term.SendKeyEvent(0, 123, {}, true)); | ||
VERIFY_IS_FALSE(term.SendKeyEvent(255, 123, {}, true)); | ||
VERIFY_IS_FALSE(term.SendKeyEvent(123, 0, {}, true)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The already minimal test coverage for this particular method is being reduced even further. 😕
Unfortunately I don't believe there's any valid vkey
on "regular" computers that maps to a zero scanCode using MapVirtualKeyW
.
// --> Alternatively get the scanCode from the vkey if possible. | ||
// GH#7495 | ||
const auto sc = scanCode ? scanCode : _ScanCodeFromVirtualKey(vkey); | ||
if (sc == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been thinking for a while whether we should allow sc
to be 0 or not in the code that follows after this line.
I've decided for the latter, because we can still remove this if-condition later on if it turns out that some vkey
s cannot be mapped to scanCode
s on some platforms. Until then this is something of a "defensive programming style" of sorts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's important I mention the reason we need scanCode
s here again (because this topic is kinda complicated)...
When we receive a key event we must decide whether we consume the event or not. If we do consume it we'll not receive a follow-up character event no matter what. We'd like to only consume non-character key events, because the character events contain proper unicode characters and the key events don't.
In order to decide this we use ToUnicodeEx
which translates a vkey
and some modifier keys to one or more characters. If it spits out characters we ignore the key and wait for an appropriate character event.
Unfortunately there can be multiple meanings to a single vkey
depending on the keyboard state and depending on the key in question that was pressed. Two or more keys might map to the same vkey
but have different scanCode
s.
Due to this ToUnicodeEx
asks for a scanCode
allowing it to correctly map unicode characters. Ergo we need scanCode
s in the key event handler. But apparently even official applications don't set it in the KEYBDINPUT
structure, if input doesn't originate from a physical keyboard (but for instance a software/touch keyboard instead).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an excellent description. Thanks!
If anyone has any suggestions which corner cases I should additionally test, please let me know. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great and very well-reasoned to me,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, so after enough coffee, this doesn't actually look all that scary. I quite like the clever fallback of looking up the scan code from the vkey, since that's likely been set correctly.
Sorry for the delay in reviewing!
I'm gonna check to see if I can repro #8045, and see if this fixes that. Turns out my dev box is still on, despite no one being in the office for the last 8 months 😆 |
Hello @zadjii-msft! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
I couldn't repro #8045, so I'm just gonna merge this, and hope we figure out the root cause of that issue separately. |
While not explicitly permitted, a wide range of software (including Windows' own touch keyboard) sets the `wScan` member of the `KEYBDINPUT` structure to 0, resulting in `scanCode` being 0 as well. In these situations we'll now use the `vkey` to get a `scanCode`. Validation ---------- * AutoHotkey * Use a keyboard layout with `AltGr` key * Execute the following script: ```ahk #NoEnv #Warn SendMode Input SetWorkingDir %A_ScriptDir% <^>!8::SendInput {Raw}» ``` * Press `AltGr+8` while the Terminal is in the foreground * Ensure » is being echoed ✔️ * PowerToys * Add a `Ctrl+I -> ↑ (up arrow)` keyboard shortcut * Press `Ctrl+I` while the Terminal is in the foreground * Ensure the shell history is being navigated backwards ✔️ * Windows Touch Keyboard * Right-click or tap and hold the taskbar and select "Show touch keyboard" button * Open touch keyboard * Ensure keyboard works like a regular keyboard ✔️ * Ensure unicode characters are echoed on the Terminal as well (except for Emojis) ✔️ Closes #7438 Closes #7495 Closes #7843 (cherry picked from commit d51d8dc)
🎉 Handy links: |
🎉 Handy links: |
Hi, has this been reintroduced with a later release of terminal by any chance? just I'm experiencing the same issues, enabled the service though initially it wasn't even listed, had to enable a few options withing settings accessibility for the service to show in the list of services, but even after enabling the service still now luck. AltGr+8 seems to work, along with other AltGr+ (random keys). I'm running this on: Test Terminal Version: 1.15.2713.0 and preview release 1.16.2642.0 Thanks |
@D3nbot Which service are you talking about? None of the 3 issues this PR closed mention anything related to "service". From what I can tell, this PR also still seems to work for me. |
Hi @lhecker, One of the many threads mentioned "Touch Keyboard and Handwriting Panel Service" once I'd rebooted after installing terminal pre, it seems to have started working in both variants, not entirely sure what caused the issue. Sorry if I wasted anyone's time with this one, was highly frustrating at the time. Thanks |
While not explicitly permitted, a wide range of software (including
Windows' own touch keyboard) sets the
wScan
member of theKEYBDINPUT
structure to 0, resulting in
scanCode
being 0 as well. In thesesituations we'll now use the
vkey
to get ascanCode
.Validation
AltGr
keyAltGr+8
while the Terminal is in the foregroundCtrl+I -> ↑ (up arrow)
keyboard shortcutCtrl+I
while the Terminal is in the foregroundkeyboard" button
for Emojis) ✔️
Closes #7438
Closes #7495
Closes #7843