boppreh / keyboard

Hook and simulate global keyboard events on Windows and Linux.
MIT License
3.8k stars 433 forks source link

Not all key events are caught if they are done in a CPU-intensive window #534

Open josephernest opened 2 years ago

josephernest commented 2 years ago

This adds the KEY_DOWN events in a list, and removes them when the key is up.

import keyboard
keys = []
while True:
    event = keyboard.read_event()
    if event.event_type == keyboard.KEY_DOWN:
        if event.name not in keys:
            keys.append(event.name)
    else:
        if event.name in keys:
            keys.remove(event.name)
    print(event.name, event.event_type, keys)

Normal behaviour when typing hello (quite fast):

h down ['h']
e down ['h', 'e']
h up ['e']
e up []
l down ['l']
l up []
l down ['l']
l up []
o down ['o']
o up []

Unexpected behaviour when typing hello fast in another window which is CPU-intensive (example: a process that does autocompletion on each keystroke and perform searches on the fly):

h down ['h']
e down ['h', 'e']
h up ['e']
l down ['e', 'l']
l up ['e']
l down ['e', 'l']
l up ['e']
o down ['e', 'o']
o up ['e']              # the "e up"  event has not been caught

Any idea how to avoid this corner case, where the keystrokes were too fast, and the Python interpreter didn't get the time to intercept 100% of them?

Note: I tried with pynput.keyboard and here this issue does not appear. (I'm on Windows + Python 3.7).