Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Multikey-press behaves strangely depending on key up/down sequence #22

Open
AlexEshoo opened this issue Oct 11, 2016 · 8 comments
Open
Milestone

Comments

@AlexEshoo
Copy link

Consider the following code which prints the event type, key, and list of currently pressed keys for a keyboard event.

from pyhooked import Hook, KeyboardEvent

def handle_events(args):
    if isinstance(args, KeyboardEvent):
        print args.event_type, args.current_key, args.pressed_key

hk = Hook()  # make a new instance of PyHooked
hk.handler = handle_events  # add a new shortcut ctrl+a, or triggered on mouseover of (300,400)
hk.hook()  # hook into the events, and listen to the presses

When a key, 'a' for example, is held down, the output is: key down A ['A'] and it is repeated until the key is released, which then yields a single output of: key up A [] .

Now consider pressing the 'A' and 'S' Keys simultaneously. For the first example, consider holding 'A' first, then 'S', then letting go of 'A', then 'S'. The output is (in order, repeated if dots follow):

key down A ['A']
...
key down S ['A', 'S']
...
key up A['S']
key down S ['S']
...
key up S []

Now consider the case of releasing 'S' first instead. The output is (in order, repeated if dots follow):

key down A ['A']
...
key down S['A', 'S']
...
key up S ['A']
key up A []

Notice that the difference is that the key down event does not repeat for 'A' after 'S' has been released as was the case for 'S' in the first example. This can be generalized for the case when more than two buttons are pressed as well. In every case, if the last button that was pressed is released, the output stops repeating.

This behavior is inconsistent, however I'm not sure what the intended behavior is. Do we define a keyboard event as a triggered event? Then holding a key down should not repeat output. Or do we define it as the state of the key? In that case the output should repeat for the key(s) being held and when one is released the other(s) should continue to repeat.

Do you have thoughts on what should be the proper output?

@emmatyping
Copy link
Owner

If I understand your explanation correctly, then I believe the first example is correct. Because if you lift up 'S' first, A is still down so, it should be received as such.

@AlexEshoo
Copy link
Author

I'm not very familiar with the windows API unfortunately, so I can't seem to find where the code is going wrong with this. Do you have any ideas?

@emmatyping
Copy link
Owner

No ideas off the top of my head. I can't promise I'll have time to look at this soon, but I will try to get to it when I can.

@emmatyping emmatyping added the bug label Oct 12, 2016
@emmatyping emmatyping modified the milestones: 0.9, 0.8 Oct 12, 2016
@KeineLimonade
Copy link

Don´t worry, I found myself a workaround.

@AlexEshoo
Copy link
Author

What is the workaround that you found?

@AlexEshoo
Copy link
Author

I did a little digging and I found this example also exhibits the same behavior. (Not surprisingly since this repository is a spitting image of the example).
http://stackoverflow.com/questions/9817531/applying-low-level-keyboard-hooks-with-python-and-setwindowshookexa

Something else that perhaps I do not fully understand, and therefore found confusing is that TranslateMessage(byref(message)) and DispatchMessageW(byref(message)) never seemed to be called. It seems that msg = GetMessageW(byref(message), 0, 0, 0) gets called once in the while loop, but never again. Is this to be expected? The WinAPI documentation seems to indicate otherwise.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms644928(v=vs.85).aspx

@KeineLimonade
Copy link

I created a daemon thread and an function which would wait till this thread outputs something

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants