Open giladbarnea opened 6 years ago
Hi
Wow, that's a very thorough bug report. Thank you.
Suppressing the first key but not the others is a feature; it actually simulates the suppressed event as soon as a new event that is incompatible with the hotkey comes. If you press "shift+2" you'll see both events being sent at the same time, when you press the "2", but nothing until then (unless you hold it too long, which makes the second shift also look like an unrelated key).
This is the only way to completely suppress a hotkey. I see how this could be a problem, but I'm not sure what's the best solution.
Not suppressing the modifier means that other applications will see it, even if it's later on used as part of the "suppressed" hotkey. In this case, if you are suppressing "shift+1" and type "shift+1" twice, the application would see two "shift"s in a row with nothing else. In IntelliJ IDEA that would open the "search anywhere" box, for example, which is unwanted.
A possible solution is to have the library also listen for mouse events, and treat them like unrelated keys. In this case, shift would still be suppressed at the beginning, but a fake shift event will be sent as soon as you press the mouse button. However this would significantly complicate the library and lead to strange situations (e.g. what happens if the keyboard hooking works, but not the mouse hooking? The user is going to be unpleasantly surprised either way).
I'm kinda stumped on this one. Open to suggestions.
Alright, thanks for sharing. I feel like my reply would be more on point if I had a better grasp on the inner workings of the library, so I apologize if it has a somewhat ignorant tint to it - Let me make sure I understood everything:
Suppressing the first key but not the others is a feature; it actually simulates the suppressed event as soon as a new event that is incompatible with the hotkey comes.
I see how this is the only way to suppress a key, the 'search everywhere' example was spot on. So first shift is suppressed, and as soon as a new event comes, a fake shift is sent in tandem with the new event.
A possible solution is to have the library also listen for mouse events, and treat them like unrelated keys. In this case, shift would still be suppressed at the beginning, but a fake shift event will be sent as soon as you press the mouse button. However this would significantly complicate the library and lead to strange situations
I understand that it would make everything a lot more complicated. But I feel like:
(e.g. what happens if the keyboard hooking works, but not the mouse hooking? The user is going to be unpleasantly surprised either way).
Maybe misses some additional arguments? Right now, the keyboard hooking works wonderfully, but the mouse hooking suffers when a keyboard modifier comes into play. So that scenario you mentioned isn't very different than what's going on now, and also, I think that making it work is not out of scope (if you're ok with including mouse hooking in the scope of the lib).
keyboard
is really important to me, because I'm currently developing my first real product which is relying heavily on it :)
Could you maybe direct me to where the 'suppress first press; on incompatible event, send original press + event' mechanism? I'll try to see if I can help in any way, but I've never done this (kinda scary) and I won't be having a lot of free time until mid-June. I'll try though.
Thanks again.
Hi,
This is a pretty simple bug to reproduce. The following sample code:
keyboard.add_hotkey('shift+1', callback=print, suppress=True)
Literally suppresses shift when holding shift and clicking the mouse, but only within a narrow time period.
In standard Windows behavior (not sure about other OSs), when one holds a key down, there's about a second where it's registered as a single press, and only after this second is over will it start "looping" key presses rapidly, as long as the key is held.
Within that second, before the looping starts, the modifier is suppressed and the mouse clicks are registered like normal, non-modified clicks. The moment the press starts looping due do the key being held down, the modifier IS registered when clicking the mouse.
I created a short video that shows the behavior: https://photos.app.goo.gl/jBpwcyoJQq76rcp78
And attached the code and the video in a zip in case the link doesn't work. reproduce00.txt keyboard_bug_video.zip
Thanks, Gilad