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

Fix SendInput handling #7900

Merged
1 commit merged into from
Oct 27, 2020
Merged

Fix SendInput handling #7900

1 commit merged into from
Oct 27, 2020

Conversation

lhecker
Copy link
Member

@lhecker lhecker commented Oct 12, 2020

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:
      #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

@ghost ghost added Area-Input Related to input processing (key presses, mouse, etc.) Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-1 A description (P1) Product-Terminal The new Windows Terminal. labels Oct 12, 2020
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));
Copy link
Member Author

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)
Copy link
Member Author

@lhecker lhecker Oct 12, 2020

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 vkeys cannot be mapped to scanCodes on some platforms. Until then this is something of a "defensive programming style" of sorts.

Copy link
Member Author

@lhecker lhecker Oct 12, 2020

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

Due to this ToUnicodeEx asks for a scanCode allowing it to correctly map unicode characters. Ergo we need scanCodes 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).

Copy link
Member

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!

@lhecker
Copy link
Member Author

lhecker commented Oct 12, 2020

If anyone has any suggestions which corner cases I should additionally test, please let me know.
I don't like breaking stuff and I'd really like to "unbreak" all the corner cases now. 😅

@ghost ghost added Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) Priority-2 A description (P2) labels Oct 12, 2020
@zadjii-msft zadjii-msft self-assigned this Oct 15, 2020
Copy link
Member

@DHowett DHowett left a 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,

Copy link
Member

@zadjii-msft zadjii-msft left a 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!

@zadjii-msft zadjii-msft removed their assignment Oct 27, 2020
@zadjii-msft
Copy link
Member

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 😆

@zadjii-msft zadjii-msft added the AutoMerge Marked for automatic merge by the bot when requirements are met label Oct 27, 2020
@ghost
Copy link

ghost commented Oct 27, 2020

Hello @zadjii-msft!

Because this pull request has the AutoMerge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

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 (@msftbot) and give me an instruction to get started! Learn more here.

@ghost ghost merged commit d51d8dc into microsoft:main Oct 27, 2020
@zadjii-msft
Copy link
Member

I couldn't repro #8045, so I'm just gonna merge this, and hope we figure out the root cause of that issue separately.

DHowett pushed a commit that referenced this pull request Oct 28, 2020
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)
@ghost
Copy link

ghost commented Nov 11, 2020

🎉Windows Terminal v1.4.3141.0 has been released which incorporates this pull request.:tada:

Handy links:

@ghost
Copy link

ghost commented Nov 11, 2020

🎉Windows Terminal Preview v1.5.3142.0 has been released which incorporates this pull request.:tada:

Handy links:

@D3nbot
Copy link

D3nbot commented Oct 10, 2022

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:
Windows 11 Pro - 21H2 - 22000.978
Windows Feature Experience Pack 1000.22000.978.0

Test Terminal Version: 1.15.2713.0 and preview release 1.16.2642.0

Thanks

@lhecker
Copy link
Member Author

lhecker commented Oct 10, 2022

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

@D3nbot
Copy link

D3nbot commented Oct 10, 2022

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

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Input Related to input processing (key presses, mouse, etc.) Area-TerminalControl Issues pertaining to the terminal control (input, selection, keybindings, mouse interaction, etc.) AutoMerge Marked for automatic merge by the bot when requirements are met hacktoberfest-accepted Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-1 A description (P1) Priority-2 A description (P2) Product-Terminal The new Windows Terminal.
Projects
None yet
4 participants