English | 简体中文
A libinput-based touchpad gesture handler and GUI settings panel for Linux. It talks directly to the libinput API instead of parsing debug output, and writes to /dev/uinput for low-latency dragging on Wayland (with X11 support).
Pre-compiled packages (.deb, Arch Linux PKGBUILD) and binaries are available on the releases page.
- Wayland & X11: Direct
/dev/uinputvirtual pointer on Wayland; directlibxdoon X11. Auto-detected at startup. - Three-Finger Drag: macOS-style drag with configurable
mouse-up-delay. - Graphical Settings Panel: Native GUI (
gestures-panel) with English and Chinese support for editing gestures and touchpad settings. - Desktop Autostart: Integrates via standard XDG desktop autostart (
~/.config/autostart). - Gesture Types: Swipe (8 directions + any), Pinch (in/out/rotate), Hold.
- Touchpad Acceleration: Optional process-level acceleration profile (
adaptive/flat) and speed setting. - Live Reload: Reload configuration on the fly via IPC (
gestures reload) without restarting.
Download the unified .deb package from Releases:
sudo dpkg -i gestures_1.1.0_amd64.debThis installs the daemon (gestures), the GUI (gestures-panel), desktop menu entry, and global autostart.
Use the provided PKGBUILD in packaging/arch:
cd packaging/arch
makepkg -siOr build directly from the git checkout:
./scripts/package-arch.sh
sudo pacman -U dist/gestures-*.pkg.tar.zst# flake.nix
{
inputs.gestures.url = "github:ferstar/gestures";
# Then add to packages:
# inputs.gestures.packages.${system}.gestures
}cargo install --git https://github.com/ferstar/gestures.gitgit clone https://github.com/ferstar/gestures
cd gestures
# Build Rust daemon engine
cargo build --release
sudo cp target/release/gestures /usr/bin/
# Build GUI panel (requires Go 1.24+)
cd apps/panel
go build -o build/gestures-panel .
sudo cp build/gestures-panel /usr/bin/Launch Gestures from your desktop application launcher, or run:
gestures-panelFrom the panel, you can configure gestures, adjust acceleration, and toggle Desktop Autostart on or off.
To start gestures automatically upon graphical desktop login:
# Install autostart desktop entry to ~/.config/autostart/gestures.desktop
gestures install-autostart# Start daemon in background or foreground
gestures start
# Reload configuration on the fly
gestures reload
# Generate default configuration (~/.config/gestures.kdl)
gestures generate-configNote: The display server is detected via the WAYLAND_DISPLAY and XDG_SESSION_TYPE environment variables. Manual override is rarely needed.
This fork includes several performance improvements:
- Zero-regex command rendering: template variables (
$delta_x,$delta_y,$scale,$delta_angle) are substituted with plainstr::replace— no regex engine and no precompilation - Thread pool: a 4-worker pool prevents PID exhaustion during fast gestures
- Input-driven dragging: direct mouse movement follows touchpad events without a fixed frame-rate limit, retaining fractional pixels for slow-drag precision. The worker coalesces queued movements when needed. Custom swipe update commands remain limited to 60 updates per second.
- Timer-based delays: non-blocking mouse-up delays for smooth dragging
- Event caching: 1-second cache for gesture configuration lookups
- Mouse command lifecycle: a dedicated worker owns a persistent uinput virtual pointer and writes movement/button events directly. If uinput initialization fails, it falls back to ydotool and waits for each child to exit. Its bounded queue coalesces adjacent movement events without crossing button events. On graceful shutdown, the worker drains queued commands, releases any held drag button, destroys its virtual device on exit, and is joined.
- Direct dragging has no fixed frame-rate limit; its bounded worker queue coalesces adjacent movement events.
- Custom swipe update commands are limited by
ThrottleState::new(60)incrates/gestures/src/event_handler.rs. - Check service CPU usage and logs while dragging; resource use depends on the touchpad event rate and command execution speed.
X11:
- Ensure the X11 session environment is correct (
DISPLAY/XAUTHORITY)
Wayland:
- The default backend writes directly to
/dev/uinput;ydotooldis not required. - Check logs for the selected backend. Failure to create the virtual pointer logs the reason and falls back to ydotool.
- Ensure the uinput module is loaded and your user can read/write
/dev/uinput. - If using the fallback, install
ydotool, runydotoold, and check its socket permissions.
Touchpad event access and virtual pointer creation both need appropriate permissions. On distributions using an input group:
# Load the kernel module if /dev/uinput is missing
sudo modprobe uinput
# Add your user to the group (log out and back in afterward)
sudo usermod -aG input "$USER"
# Inspect device ownership and permissions
ls -l /dev/uinput /dev/input/event*If /dev/uinput is not group-writable, create /etc/udev/rules.d/99-gestures-uinput.rules with:
KERNEL=="uinput", GROUP="input", MODE="0660"
Use your distribution's uinput group instead if applicable. Input-group membership also grants access to other input devices. Apply the rule and restart gestures after logging back in:
sudo udevadm control --reload-rules
sudo udevadm trigger --subsystem-match=misc --sysname-match=uinput
systemctl --user restart gestures.serviceOnly when using the ydotool fallback (or explicit ydotool custom commands):
systemctl --user enable --now ydotoold.service
systemctl --user status ydotoold.service
ls -la "$XDG_RUNTIME_DIR/.ydotool_socket"Keep gestures and ydotoold in the same user session for the fallback. Avoid world-writable device or socket permissions.
libxdo is loaded dynamically at runtime (libxdo.so.4, libxdo.so.3, or libxdo.so), so a system upgrade that changes the SONAME no longer breaks the binary, and no rebuild is needed.
If none of the libraries can be loaded (for example, xdotool is not installed), the daemon logs a warning and falls back to the uinput virtual pointer, then to ydotool — dragging keeps working. To use the libxdo backend, install your distribution's xdotool/libxdo package and restart the daemon.
Disable built-in gestures in your desktop environment (GNOME, KDE, etc.)
- libinput-gestures - Parses debug output
- gebaar - Swipe only
- fusuma - Ruby-based
