pynput Documentation

repository·master·Indexed 24 days ago

https://github.com/moses-palmer/pynput

A library for controlling and monitoring input devices, specifically supporting mouse and keyboard input. It provides Controller classes to simulate input and Listener classes to monitor events across multiple platforms, including macOS, Windows, and Linux (Xorg, uinput, and Wayland). Features include global hotkey registration, synchronous event polling via the Events class, and platform-specific event suppression.

Tokens
7.1K
Snippets
13
Records
49
Agent score
79%

What's inside pynput

  1. Control and monitor the mouse with pynput.mouse

    master

    The pynput.mouse module provides tools to both control the mouse (simulating movement and clicks) and monitor it (listening to mouse events).

    To control the mouse, use the pynput.mouse.Controller class. To monitor mouse activity, use the pynput.mouse.Listener class.

  2. How HotKey works for custom state management

    master

    The pynput.keyboard.HotKey class is a lower-level abstraction used to manage the state of a multi-key combination. Because a Listener is stateless, you must use HotKey.press and HotKey.release within your listener callbacks to track which keys are currently held down.

    To ensure compatibility, keys should be passed through Listener.canonical() before being sent to the HotKey instance to normalize modifiers.

    from pynput import keyboard
    
    def on_activate():
        print('Global hotkey activated!')
    
    def for_canonical(f):
        return lambda k: f(l.canonical(k))
    
    hotkey = keyboard.HotKey(
        keyboard.HotKey.parse('<ctrl>+<alt>+h'),
        on_activate)
    
    with keyboard.Listener(
            on_press=for_canonical(hotkey.press),
            on_release=for_canonical(hotkey.release)) as l:
        l.join()
  3. Import pynput subpackages

    master

    To control or monitor input devices, import the mouse or keyboard subpackages directly from the main pynput package. All device-specific modules are automatically imported into the top-level package.

    from pynput import mouse, keyboard
  4. Handle errors in mouse listener callbacks

    master

    If a callback handler raises an exception, the listener will stop. Because callbacks run in a dedicated thread, exceptions are not automatically reraised in your main thread.

    To catch exceptions raised within a callback, you must call listener.join() within a try...except block in your main thread.

    from pynput import mouse
    
    class MyException(Exception): pass
    
    def on_click(x, y, button, pressed):
        if button == mouse.Button.left:
            raise MyException(button)
    
    with mouse.Listener(on_click=on_click) as listener:
        try:
            listener.join()
        except MyException as e:
            print(f'Caught exception from callback: {e.args[0]}')
  5. Monitor mouse events with Listener

    master

    Use pynput.mouse.Listener to monitor mouse activity. The listener runs in a dedicated threading.Thread.

    Callback Signatures

    • on_move(x, y, injected)
    • on_click(x, y, button, pressed, injected)
    • on_scroll(x, y, dx, dy, injected)

    Note: injected is a boolean indicating if the event was generated by a controller rather than a physical device.

    Usage Modes

    1. Blocking: Use a with statement and call listener.join(). This blocks the current thread until the listener stops.
    2. Non-blocking: Call listener.start(). This allows the current thread to continue executing. This is useful for GUI integration but will cause a standalone script to exit immediately if not managed.

    Stopping the Listener

    To stop the listener, you can:

    • Return False from any callback function.
    • Call pynput.mouse.Listener.stop() from anywhere.
    • Raise StopException from a callback.
  6. Configure pynput for Linux (X11)

    master

    When running on Linux using the X server, ensure that an X server is active and the $DISPLAY environment variable is correctly set. If running over SSH, you must manually set the $DISPLAY variable to point to the local X session to allow pynput to interface with the display.

    To find your current $DISPLAY value, run echo $DISPLAY in a terminal within your desktop environment.

    $ DISPLAY=:0 python -c 'import pynput'
  7. Configure pynput for macOS (Keyboard Permissions)

    master

    Recent versions of macOS restrict keyboard monitoring for security. To monitor the keyboard, you must satisfy one of the following:

    1. Run the process as root.
    2. Whitelist your application under Enable access for assistive devices in System Settings. (Note: If running as a script, you may need to whitelist your entire Python installation or package your application).
    3. On macOS versions after Mojave, you may also need to whitelist your terminal application if running the script from a terminal.

    Note: These restrictions do not apply to monitoring the mouse or trackpad.

  8. Suppress specific events on Windows

    master

    On Windows, you can suppress specific events by passing a win32_event_filter callable to the listener constructor. This function receives (msg, data), where data is a MSLLHOOKSTRUCT (for mouse) or a KBDLLHOOKSTRUCT (for keyboard).

    To suppress the event, call listener.suppress_event() within the filter function. Returning False from the filter function will also hide the event from other listener callbacks.

    # Values for MSLLHOOKSTRUCT.vkCode can be found here:
    # https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
    def win32_event_filter(msg, data):
        if data.vkCode == 0x58:
            # Suppress x
            listener.suppress_event()
    
    # Use it in the listener constructor
    # listener = keyboard.Listener(win32_event_filter=win32_event_filter)
  9. Suppress specific events on macOS

    master

    On macOS, you can suppress specific events by passing a darwin_intercept callable to the listener constructor. This function receives (event_type, event), where event is a CGEventRef.

    To suppress an event, return None. To allow the event (or a modified version of it) to pass through, return the event object. You can use the Quartz module to inspect or modify the event.

    def darwin_intercept(event_type, event):
        import Quartz
        length, chars = Quartz.CGEventKeyboardGetUnicodeString(
            event, 100, None, None)
        if length > 0 and chars == 'x':
            # Suppress x
            return None
        elif length > 0 and chars == 'a':
            # Transform a to b
            Quartz.CGEventKeyboardSetUnicodeString(event, 1, 'b')
        else:
            return event
    
    # Use it in the listener constructor
    # listener = keyboard.Listener(darwin_intercept=darwin_intercept)