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

Improper GetAsyncKeyState usage #114

Open
p120ph37 opened this issue Nov 27, 2018 · 1 comment · May be fixed by #115
Open

Improper GetAsyncKeyState usage #114

p120ph37 opened this issue Nov 27, 2018 · 1 comment · May be fixed by #115
Labels
Bug An error or incorrect implementation
Milestone

Comments

@p120ph37
Copy link

Contrary to superficial appearances, GetKeyState and GetAsyncKeyState actually have significantly different behavior, aside from skipping the input buffer queue.

GetKeyState: docs

If the high-order bit is 1, the key is down; otherwise, it is up.
If the low-order bit is 1, the key is toggled.

  • Allows detection of lock-key toggle state (e.g. "is CapsLock on?")
  • Allows detection of currently-pressed state (e.g. "is CapsLock being pressed?")

GetAsyncKeyState: docs

If the most significant bit is set, the key is down
If the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState. However, you should not rely on this last behavior

  • Does not detect toggle state (try it! Note, this is different from the way Robot works on OSX)
  • Allows detection of "recent" keypresses (almost useless since this can get reset by other processes, and is different from the way Robot works on OSX)
  • Allows detection of currently-pressed state (e.g. "is CapsLock being pressed?")

I think Robot should probably be using GetKeyState rather than GetAsyncKeyState. The reasoning for using GetAsyncKeyState is that it allows you to check the current realtime keyboard state regardless of queued input to your process, however it is your process so you could just as well drain your input before calling GetKeyState to get the same result, with the added benefit that you can obtain lock-key toggle information, and can also obtain input-buffer key information if you want.

One still-missing feature would be the ability to distinguish between CapsLock-on-and-down, CapsLock-on-and-up, and CapsLock-off-and-down. Unfortunately, sorting this out would probably require a new method signature other than bool Keyboard::GetState (Key keycode), and it's fairly rare to need to know if CapsLock (or ScrollLock or NumLock) is actually being pressed at the moment.

@p120ph37
Copy link
Author

I wrote:

One still-missing feature would be the ability to distinguish between CapsLock-on-and-down, CapsLock-on-and-up, and CapsLock-off-and-down. Unfortunately, sorting this out would probably require a new method signature other than bool Keyboard::GetState (Key keycode), and it's fairly rare to need to know if CapsLock (or ScrollLock or NumLock) is actually being pressed at the moment.

But upon further testing, it seems that the GetKeyState function only returns lock-state for lock type virtual keys, so this conflation is actually not really present anyway -- if you are testing VK_CAPITAL, you get lock-state only, not lock-state | down-state. And if you are testing some other non-lock key, you only get down-state.

@p120ph37 p120ph37 linked a pull request Nov 27, 2018 that will close this issue
@dkrutsko dkrutsko added the Bug An error or incorrect implementation label Mar 25, 2022
@dkrutsko dkrutsko added this to the Robot 2.1.0 milestone Mar 25, 2022
@dkrutsko dkrutsko linked a pull request Mar 25, 2022 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug An error or incorrect implementation
Development

Successfully merging a pull request may close this issue.

2 participants