A tool for automating Wayland tasks using system packages wtype and wayland-info
Project description
Wayland Automation
A Python library for mouse and keyboard automation on Wayland compositors. Works out of the box on Hyprland, Sway, and other wlroots-based compositors.
Features
- Mouse — click, move, swipe (drag), and auto-click at any screen coordinate
- Keyboard — type text, press individual keys, and trigger hotkeys (e.g.
Ctrl+S) - Cursor Tracking — real-time cursor position via multiple backends (Hyprland → wl-find-cursor → xdotool → evdev)
- Convenience API — top-level functions so you can
import wayland_automation as waand go - Resilient — automatic reconnection logic for Wayland socket resets
Installation
1. Install the package
pip install wayland-automation
2. Install system dependencies
| Dependency | What it does | Install command |
|---|---|---|
wtype |
Required — keyboard automation | sudo pacman -S wtype (Arch) / sudo apt install wtype (Debian) / sudo dnf install wtype (Fedora) |
wayland-utils |
Screen resolution detection | sudo pacman -S wayland-utils (Arch) / sudo apt install wayland-utils (Debian) |
Mouse-tracking backends (pick the one for your compositor)
The library auto-detects the best backend. You only need to install the one that matches your setup:
| Backend | Compositor | Install |
|---|---|---|
hyprctl |
Hyprland | Pre-installed with Hyprland |
wl-find-cursor |
Sway / wlroots | See build from source below |
xdotool |
XWayland apps | sudo pacman -S xdotool / sudo apt install xdotool |
evdev (fallback) |
Any | pip install evdev + add user to input group (see below) |
Building wl-find-cursor from source
git clone https://github.com/cjacker/wl-find-cursor.git
cd wl-find-cursor
make
sudo cp wl-find-cursor /usr/local/bin/
Setting up evdev fallback
sudo usermod -aG input $USER
# Log out and back in for the group change to take effect
Quick Start
Top-level convenience API
The simplest way to use the library — no class instantiation needed:
import wayland_automation as wa
# Mouse
wa.click(250, 300, "left") # left-click at (250, 300)
wa.click(400, 500, "right") # right-click
wa.swipe(100, 200, 800, 200) # drag from point A to B
wa.auto_click(initial_delay=2, interval=0.1, duration=5) # auto-clicker
# Keyboard
wa.typewrite("Hello Wayland!", interval=0.05) # type text character by character
wa.press("enter") # press a single key
wa.hotkey("ctrl", "s") # key combination
Using the classes directly
For more control, instantiate Mouse or Keyboard:
from wayland_automation import Mouse, Keyboard
mouse = Mouse()
mouse.click(250, 300, "left") # left-click at (250, 300)
mouse.click(600, 400, "nothing") # move cursor without clicking
mouse.swipe(0, 500, 1000, 500, speed=0.5) # fast swipe (0.5 s)
kb = Keyboard()
kb.typewrite("Hello!", interval=0.05)
kb.press("enter")
kb.hotkey("ctrl", "a") # select all
kb.keyDown("shift") # hold shift
kb.keyUp("shift") # release shift
Cursor Tracking
Stream real-time cursor coordinates:
from wayland_automation import mouse_position_generator
for x, y in mouse_position_generator(interval=0.1):
print(f"Cursor at: ({x}, {y})")
# break whenever you want to stop
CLI Usage
After installing the package, a wayland-automation command is available:
wayland-automation # prints status
You can also run the individual modules directly:
# Mouse — click at (x, y)
python -m wayland_automation.mouse_controller click 250 300 left
# Mouse — swipe
python -m wayland_automation.mouse_controller swipe 100 200 800 200
# Mouse — auto-click (delay interval duration button)
python -m wayland_automation.mouse_controller autoclick 3 0.1 10 left
# Mouse — run built-in test
python -m wayland_automation.mouse_controller test
# Cursor position watcher
python -m wayland_automation.mouse_position
API Reference
wayland_automation.click(x, y, button=None)
Move the pointer to (x, y). If button is given ("left", "right", or "nothing"), perform a click.
wayland_automation.swipe(start_x, start_y, end_x, end_y, speed="normal")
Drag from one point to another. speed is duration in seconds ("normal" = 1.0 s).
wayland_automation.auto_click(initial_delay, interval, duration, button)
Wait initial_delay seconds, then click every interval seconds for duration seconds.
wayland_automation.typewrite(text, interval=0)
Type text one character at a time with an optional delay between characters.
wayland_automation.press(key)
Press and release a single key (e.g. "enter", "tab", "backspace", "space").
wayland_automation.hotkey(*keys)
Press a key combination (e.g. hotkey("ctrl", "shift", "t")). Modifier keys: ctrl, alt, shift, super.
wayland_automation.mouse_position_generator(interval=0.2, print_output=False)
Generator yielding (x, y) tuples of the current cursor position.
Compositor Compatibility
| Compositor | Mouse | Keyboard | Cursor Tracking | Notes |
|---|---|---|---|---|
| Hyprland | ✅ | ✅ | ✅ hyprctl |
Full support (wlroots-based) |
| Sway | ✅ | ✅ | ✅ wl-find-cursor |
Full support (wlroots-based) |
| KDE Plasma | ❌ | ✅ via wtype |
❌ | Mouse planned for KDE 6.5 (pointer-warp-v1) |
| GNOME | ❌ | ✅ via wtype |
❌ | Requires future protocol support |
Troubleshooting
| Problem | Likely cause | Fix |
|---|---|---|
BrokenPipeError / SIGPIPE |
Compositor disconnected the client | Ensure you are on a supported compositor and the protocol is available |
WaylandProtocolError |
zwlr_virtual_pointer_manager_v1 not supported |
Switch to a wlroots-based compositor (Hyprland / Sway) |
wtype not found |
System dependency missing | Install wtype (see Installation) |
| Cursor tracking returns nothing | No backend available | Install the backend matching your compositor (see table above) |
Architecture
wayland_automation/
├── __init__.py # Public API & convenience functions
├── __main__.py # CLI entry point, dependency checks
├── mouse_controller.py # Wayland socket communication for virtual pointer
├── keyboard_controller.py # Keyboard automation via wtype
├── mouse_position.py # Multi-backend cursor position tracking
└── utils/
└── screen_resolution.py # Screen resolution detection
Roadmap
- KDE Plasma 6.5+
pointer-warp-v1protocol support - Improved error messages for unsupported compositors
- Scroll wheel support
Contributing
Contributions welcome! See CONTRIBUTING.md for guidelines.
License
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wayland_automation-0.2.7.tar.gz.
File metadata
- Download URL: wayland_automation-0.2.7.tar.gz
- Upload date:
- Size: 17.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a0261cac5325251768f59024ad17fe72cc7777db922eaa0699f1c0fde7dd0858
|
|
| MD5 |
2d669e8aad0ceb11040f1b1f8e15b00d
|
|
| BLAKE2b-256 |
35f6164eefd7d1c9e8733137038779c1c7818efcedc5055b57e1985c7559566f
|
File details
Details for the file wayland_automation-0.2.7-py3-none-any.whl.
File metadata
- Download URL: wayland_automation-0.2.7-py3-none-any.whl
- Upload date:
- Size: 17.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb066885e686479311a109188252d95e107f343adfed58be225233b912688694
|
|
| MD5 |
259874633450f033378fecbb93e695ac
|
|
| BLAKE2b-256 |
c8da4981dcfd44a6b8055b9ef53a38260ba75a8ab15e8736362d7f9aa4559511
|