CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pynput

Monitor and control user input devices across multiple operating systems

Overview
Eval results
Files

mouse.mddocs/

Mouse Control and Monitoring

Comprehensive mouse input simulation and monitoring functionality for controlling mouse cursor position, generating button clicks, scroll events, and listening to real-time mouse interactions across multiple operating systems.

Capabilities

Mouse Controller

The Controller class provides programmatic control over mouse cursor position and button interactions, enabling automation of mouse-based operations.

class Controller:
    """A controller for sending virtual mouse events to the system."""

    def __init__(self):
        """Initialize the mouse controller."""
        ...

    @property
    def position(self) -> tuple[int, int]:
        """
        The current position of the mouse pointer.

        Returns:
            tuple[int, int]: The (x, y) coordinates of the mouse pointer
        """
        ...

    @position.setter
    def position(self, pos: tuple[int, int]):
        """
        Set the mouse pointer position.

        Args:
            pos (tuple[int, int]): The (x, y) coordinates to move the pointer to
        """
        ...

    def move(self, dx: int, dy: int):
        """
        Move the mouse pointer relative to its current position.

        Args:
            dx (int): Horizontal offset in pixels
            dy (int): Vertical offset in pixels

        Raises:
            ValueError: If the values are invalid (e.g., out of bounds)
        """
        ...

    def click(self, button: Button, count: int = 1):
        """
        Emit button click event(s) at the current position.

        Args:
            button (Button): The button to click
            count (int): Number of clicks to perform (default: 1)
        """
        ...

    def press(self, button: Button):
        """
        Emit a button press event at the current position.

        Args:
            button (Button): The button to press
        """
        ...

    def release(self, button: Button):
        """
        Emit a button release event at the current position.

        Args:
            button (Button): The button to release
        """
        ...

    def scroll(self, dx: int, dy: int):
        """
        Send scroll events.

        Args:
            dx (int): Horizontal scroll amount (units undefined, platform-dependent)
            dy (int): Vertical scroll amount (units undefined, platform-dependent)

        Raises:
            ValueError: If the values are invalid (e.g., out of bounds)
        """
        ...

Usage Examples

from pynput.mouse import Button, Controller

# Create controller
mouse = Controller()

# Get current position
current_pos = mouse.position
print(f"Mouse is at {current_pos}")

# Move to absolute position
mouse.position = (500, 300)

# Move relatively
mouse.move(50, -25)

# Single click
mouse.click(Button.left)

# Double click
mouse.click(Button.left, 2)

# Right click
mouse.click(Button.right)

# Press and hold, then release
mouse.press(Button.left)
# ... do something while button is pressed
mouse.release(Button.left)

# Scroll down 3 units
mouse.scroll(0, 3)

# Scroll horizontally
mouse.scroll(2, 0)

Mouse Event Listener

The Listener class monitors mouse events in real-time, providing callbacks for mouse movements, clicks, and scroll events.

class Listener:
    """A listener for mouse events."""

    def __init__(
        self,
        on_move: callable = None,
        on_click: callable = None,
        on_scroll: callable = None,
        suppress: bool = False,
        **kwargs
    ):
        """
        Initialize the mouse event listener.

        Args:
            on_move (callable): Callback for mouse move events (x, y, injected)
            on_click (callable): Callback for mouse click events (x, y, button, pressed, injected)
            on_scroll (callable): Callback for scroll events (x, y, dx, dy, injected)
            suppress (bool): Whether to suppress events system-wide
            **kwargs: Platform-specific options (darwin_*, win32_*, xorg_*)
        """
        ...

    def start(self):
        """Start the listener thread."""
        ...

    def stop(self):
        """Stop the listener. Cannot be restarted once stopped."""
        ...

    def wait(self):
        """Wait for the listener to become ready."""
        ...

    def join(self, timeout: float = None):
        """
        Wait for the listener thread to complete.

        Args:
            timeout (float): Maximum time to wait in seconds
        """
        ...

    @property
    def running(self) -> bool:
        """Whether the listener is currently running."""
        ...

    @property
    def suppress(self) -> bool:
        """Whether events are being suppressed system-wide."""
        ...

Usage Examples

from pynput import mouse

def on_move(x, y, injected):
    """Handle mouse move events."""
    if not injected:  # Ignore synthetic events
        print(f'Mouse moved to ({x}, {y})')

def on_click(x, y, button, pressed, injected):
    """Handle mouse click events."""
    action = 'Pressed' if pressed else 'Released'
    print(f'{action} {button} at ({x}, {y})')

    # Stop listener on right button release
    if button == mouse.Button.right and not pressed:
        return False

def on_scroll(x, y, dx, dy, injected):
    """Handle mouse scroll events."""
    direction = 'up' if dy > 0 else 'down'
    print(f'Scrolled {direction} at ({x}, {y})')

# Context manager usage (recommended)
with mouse.Listener(
    on_move=on_move,
    on_click=on_click,
    on_scroll=on_scroll
) as listener:
    listener.join()

# Manual control
listener = mouse.Listener(
    on_move=on_move,
    on_click=on_click,
    on_scroll=on_scroll
)
listener.start()
listener.join()  # Wait for listener to finish

# Non-blocking usage
listener = mouse.Listener(on_click=on_click)
listener.start()
# ... do other work
listener.stop()

Mouse Events Iterator

The Events class provides synchronous iteration over mouse events, useful for processing events in sequence.

class Events:
    """A mouse event listener supporting synchronous iteration over events."""

    def __init__(self):
        """Initialize the events iterator."""
        ...

    def __enter__(self):
        """Start the event listener."""
        ...

    def __exit__(self, *args):
        """Stop the event listener."""
        ...

    def __iter__(self):
        """Return iterator interface."""
        ...

    def __next__(self):
        """Get the next event."""
        ...

    def get(self, timeout: float = None):
        """
        Get the next event with optional timeout.

        Args:
            timeout (float): Maximum time to wait for an event

        Returns:
            Event or None: The next event, or None if timeout or stopped
        """
        ...

    class Move:
        """A mouse move event."""
        def __init__(self, x: int, y: int, injected: bool):
            self.x = x
            self.y = y
            self.injected = injected

    class Click:
        """A mouse click event."""
        def __init__(self, x: int, y: int, button: Button, pressed: bool, injected: bool):
            self.x = x
            self.y = y
            self.button = button
            self.pressed = pressed
            self.injected = injected

    class Scroll:
        """A mouse scroll event."""
        def __init__(self, x: int, y: int, dx: int, dy: int, injected: bool):
            self.x = x
            self.y = y
            self.dx = dx
            self.dy = dy
            self.injected = injected

Usage Examples

from pynput.mouse import Events

# Process events synchronously
with Events() as events:
    for event in events:
        if isinstance(event, Events.Move):
            print(f'Mouse moved to ({event.x}, {event.y})')
        elif isinstance(event, Events.Click):
            if event.pressed:
                print(f'Button {event.button} pressed at ({event.x}, {event.y})')
            else:
                print(f'Button {event.button} released')
                break  # Exit on button release
        elif isinstance(event, Events.Scroll):
            print(f'Scrolled ({event.dx}, {event.dy}) at ({event.x}, {event.y})')

# Get events with timeout
with Events() as events:
    while True:
        event = events.get(timeout=1.0)
        if event is None:
            print("No event received within timeout")
            break
        print(f"Received event: {event}")

Types

Button Enumeration

class Button(enum.Enum):
    """Mouse button identifiers."""

    left = 1      # Left mouse button
    middle = 2    # Middle mouse button (scroll wheel)
    right = 3     # Right mouse button
    unknown = 0   # Unknown button

Platform-Specific Features

Windows (win32)

# Event filtering
def win32_filter(msg, data):
    """Filter Windows mouse events."""
    # Return False to suppress event from reaching listener
    return True

listener = mouse.Listener(
    on_click=on_click,
    win32_event_filter=win32_filter
)

macOS (darwin)

# Event intercepting and modification
def darwin_intercept(event_type, event):
    """Intercept and modify macOS mouse events."""
    # Modify event using Quartz functions
    # Return None to suppress event system-wide
    return event

listener = mouse.Listener(
    on_click=on_click,
    darwin_intercept=darwin_intercept
)

Linux (xorg)

Platform-specific options are available for X11/Xorg systems, though specific parameters may vary based on system configuration.

Error Handling

Common Issues

  • ImportError: Missing platform dependencies

    • Windows: Ensure win32 libraries are available
    • macOS: Requires PyObjC framework bindings
    • Linux: Requires python-xlib and X11 development libraries
  • Permission Issues: Some operations may require elevated privileges

  • Display Issues: Linux requires DISPLAY environment variable to be set

Exception Handling

from pynput import mouse

try:
    controller = mouse.Controller()
    controller.position = (100, 100)
except Exception as e:
    print(f"Mouse control error: {e}")

try:
    with mouse.Listener(on_click=lambda *args: None) as listener:
        listener.join()
except Exception as e:
    print(f"Mouse listener error: {e}")

Install with Tessl CLI

npx tessl i tessl/pypi-pynput

docs

index.md

keyboard.md

mouse.md

tile.json