Description
When using keyboard.Listener on Windows, if you provide a win32_event_filter and return False to suppress a specific key from reaching the OS, that key is ALSO incorrectly hidden from the Listener's own
on_press and
on_release callbacks.
This makes it impossible to implement "selective key suppression" (e.g., intercepting a specific physical key to use as a macro trigger while allowing all normal typing to pass through, and then handling the macro logically inside
on_press).
To work around this currently, developers are forced to fire their custom logic directly inside the win32_event_filter thread, which is dangerous as it risks stalling the global Windows keyboard hook.
Minimal Reproducible Example
from pynput import keyboard
# For this example, we want to suppress the "Right Arrow" key from the OS,
# but still want to detect it in Python to trigger some application logic.
TARGET_VK = 0x27 # VK_RIGHT
def win32_event_filter(msg, data):
if data.vkCode == TARGET_VK:
# Return False to suppress this key from being sent to the OS/other apps (Works)
return False
return True
def on_press(key):
# BUG: If the key was suppressed in win32_event_filter,
# this callback is NEVER fired for it!
print(f"Python on_press received: {key}")
def on_release(key):
# This also never fires for the suppressed key.
if key == keyboard.Key.esc:
return False
print("Press the Right Arrow key. Notice how it is suppressed from the OS, but also disappears from on_press.")
with keyboard.Listener(
on_press=on_press,
on_release=on_release,
win32_event_filter=win32_event_filter) as listener:
listener.join()
Expected behavior
When win32_event_filter returns False, it should suppress the event from propagating to the operating system/other applications (i.e., return 1 from the Windows Hook), BUT it should still dispatch the event to the
on_press and
on_release callbacks so the Python application can handle the key it intentionally intercepted.
Actual behavior
The key is suppressed from the OS successfully, but
on_press and
on_release are never triggered for that key.
Environment
- OS: Windows 10/11
- pynput version: (You can fill in your actual version here, usually
1.7.6 or latest)
Description
When using
keyboard.Listeneron Windows, if you provide awin32_event_filterand returnFalseto suppress a specific key from reaching the OS, that key is ALSO incorrectly hidden from the Listener's ownon_press and
on_release callbacks.
This makes it impossible to implement "selective key suppression" (e.g., intercepting a specific physical key to use as a macro trigger while allowing all normal typing to pass through, and then handling the macro logically inside
on_press).
To work around this currently, developers are forced to fire their custom logic directly inside the
win32_event_filterthread, which is dangerous as it risks stalling the global Windows keyboard hook.Minimal Reproducible Example
Expected behavior
When
win32_event_filterreturnsFalse, it should suppress the event from propagating to the operating system/other applications (i.e., return1from the Windows Hook), BUT it should still dispatch the event to theon_press and
on_release callbacks so the Python application can handle the key it intentionally intercepted.
Actual behavior
The key is suppressed from the OS successfully, but
on_press and
on_release are never triggered for that key.
Environment
1.7.6or latest)