Parsing and suppressing event in Pynput

32 Views Asked by At

I'm using Pynput 1.7.6 on win10. I was hoping for a way to parse the raw event into some convenient structures - pynput definitely does this. I was also hoping for a way to prevent the event from propagating to the rest of the system - pynput also does this, technically. However, as far as I can tell, it is impossible to do both at the same time - if you use suppress_event() inside the w32_event_filter, the listener's event handler will not fire regardless of your hook's return value. As such, if you want to do anything with the event while also suppressing it, it seems like you have to use the raw message data inside w32_event_filter.

Am I missing anything that would let me conveniently do both? Or is there a really good reason as to why this isn't possible?

Minimal: (Forgive the contrived setup, I don't really know how else to call suppress_event())

from pynput import mouse
listener = None
def make_listener():
    global listener

    def on_scroll(x, y, dx, dy):
        # nicely parsed event data available here
        print("On scroll!")
        listener.suppress_event()

    def win32_event_filter(msg, data):
        # raw event msg available here
        listener.suppress_event()
        return True
    
    listener = mouse.Listener(on_scroll=on_scroll,
                       win32_event_filter=win32_event_filter, 
                       suppress=False)

    return listener

l = make_listener()
l.start()
l.join()

While running, this suppresses all scroll events, and on_scroll will never be called.

1

There are 1 best solutions below

0
user3896248 On

Explored source for a bit. Although the docs only reference suppress_event() in relation to the win32_event_filter callback, you're actually free to call suppress_event() at any time during the event handling, including after the on_scroll handler logic (bearing in mind suppress_event() seems to be win32-specific). Calling suppress_event() will throw, ending the handling logic, and the exception will be caught by the internal hook.

Given that, win32_event_filter may not be necessary at all unless you want to filter out events with maximum performance.

Not sure how this interacts with returning False to end the listener -- I didn't figure out where that happens in the source.