Hyprland Trackpad Gesture Configuration: Complete Technical Guide
TLDR: Hyprland configures trackpad gestures through a layered architecture that exposes the Wayland zwp_pointer_gestures_v1 protocol, processes swipe/pinch events in TrackpadGestures.cpp, and applies user-defined settings from gestures: namespace options in hyprland.conf.
Hyprland implements sophisticated trackpad gesture support through a modular input architecture that translates raw Wayland pointer events into configurable workspace and window actions. This guide examines the complete gesture pipeline from protocol implementation to configuration syntax, based on the actual source code in the hyprwm/Hyprland repository. Understanding these internals allows you to fine-tune sensitivity thresholds, direction behavior, and custom callbacks beyond basic defaults.
Gesture Architecture Overview
The implementation spans five distinct layers that transform hardware signals into desktop actions.
PointerGestures Protocol
At the lowest level, the compositor exposes the Wayland zwp_pointer_gestures_v1 interface through /src/protocols/PointerGestures.cpp. This file forwards raw swipe and pinch events from the Wayland backend to the compositor's internal input system.
TrackpadGestures Manager
The central coordinator lives in /src/managers/input/trackpad/TrackpadGestures.cpp. This manager maintains a registry of active gesture objects and matches incoming events to the appropriate handler based on finger count, direction, and modifier masks. It drives the gesture lifecycle through distinct phases: begin, update, and end.
Concrete Gesture Classes
Individual gesture behaviors reside in /src/managers/input/trackpad/gestures/. Each class implements the ITrackpadGesture interface:
- WorkspaceSwipeGesture.cpp: Handles horizontal swipes to switch between workspaces.
- UnifiedWorkspaceSwipeGesture.cpp: Provides unified handling for both touchpad and touchscreen swipe gestures.
These classes contain the actual logic for workspace changes, window movements, and other desktop actions.
InputManager Bridge
The /src/managers/input/InputManager.cpp file receives raw swipe and pinch events from the PointerGestures protocol and forwards them to the global g_pTrackpadGestures instance. This layer also emits Hyprland-wide gesture signals that external scripts can consume.
Configuration System
All gesture options are declared in /src/config/values/ConfigValues.cpp under the gestures: namespace. The parser loads these as CConfigValue objects, making them available throughout the gesture codebase without requiring restarts when values change.
Configuration Options Reference
The following options control trackpad gesture behavior in hyprland.conf. Values are read dynamically from CConfigValue objects, allowing runtime updates.
gestures:workspace_swipe_distance(Int, default:300): Minimum swipe distance in pixels to trigger a workspace change.gestures:workspace_swipe_touch(Bool, default:false): Enable workspace swiping from the edge of a touchscreen.gestures:workspace_swipe_invert(Bool, default:true): Invert swipe direction interpretation for touchpad input.gestures:workspace_swipe_touch_invert(Bool, default:false): Invert swipe direction for touchscreen input only.gestures:workspace_swipe_min_speed_to_force(Int, default:30): Minimum speed in pixels per timepoint required to force a swipe completion, ignoring the cancel ratio.gestures:workspace_swipe_cancel_ratio(Float, default:0.5): Fraction of the gesture distance that must be completed before it registers as valid.gestures:workspace_swipe_create_new(Bool, default:true): Automatically create a new workspace when swiping right from the last workspace.gestures:workspace_swipe_direction_lock(Bool, default:true): Lock the swipe direction after passing a threshold.gestures:workspace_swipe_direction_lock_threshold(Int, default:10): Pixels to travel before direction lock activates.gestures:workspace_swipe_forever(Bool, default:false): Allow continuous swiping through multiple workspaces beyond the immediate neighbor.gestures:workspace_swipe_use_r(Bool, default:false): Use therprefix instead ofmwhen resolving workspace names during swipes.gestures:close_max_timeout(Int, default:1000): Maximum duration in milliseconds for close-gesture detection before abort.gestures:scrolling:move_snap_to_grid(Bool, default:true): Snap windows to the tiling grid after a scroll-move gesture ends.gestures:scrolling:move_snap_cursor(Bool, default:true): Snap cursor focus to the newly active window after scroll-move completion.
Practical Configuration Examples
Basic Workspace Swipe Setup
Configure horizontal workspace switching with custom sensitivity in hyprland.conf:
# Basic gesture configuration
gestures:workspace_swipe_distance = 250
gestures:workspace_swipe_invert = false
gestures:workspace_swipe_create_new = true
gestures:workspace_swipe_direction_lock = true
gestures:workspace_swipe_direction_lock_threshold = 15
gestures:close_max_timeout = 800
gestures:scrolling:move_snap_to_grid = true
Advanced Direction and Speed Tuning
Fine-tune for high-precision trackpads:
# Require deliberate gestures
gestures:workspace_swipe_cancel_ratio = 0.7
gestures:workspace_swipe_min_speed_to_force = 50
gestures:workspace_swipe_direction_lock_threshold = 20
# Enable infinite workspace scrolling
gestures:workspace_swipe_forever = true
Runtime Configuration Reload
Changes to gesture settings take effect immediately without restarting the compositor. Apply updates using:
hyprctl reload
Alternatively, send SIGUSR1 to the Hyprland process to trigger a configuration reload. The gesture manager reads directly from CConfigValue objects, ensuring subsequent gestures use the new parameters.
Custom Gesture Callbacks
According to the source code in InputManager.cpp, Hyprland emits gesture signals that external consumers can intercept. Load custom Lua scripts via exec directives to extend behavior:
-- ~/.config/hypr/scripts/gesture.lua
hyprland = ...
hyprland:connect_gesture("swipe", function(e)
if e.direction == "right" then
hyprland:dispatch("workspace", "+1")
elseif e.direction == "left" then
hyprland:dispatch("workspace", "-1")
end
end)
Summary
- Protocol Layer:
/src/protocols/PointerGestures.cppexposes Waylandzwp_pointer_gestures_v1events. - Management Layer:
/src/managers/input/trackpad/TrackpadGestures.cpporchestrates gesture lifecycles and matching. - Implementation Layer: Concrete classes in
/src/managers/input/trackpad/gestures/define specific actions like workspace switching. - Configuration: All options reside under the
gestures:namespace inhyprland.conf, parsed intoCConfigValueobjects from/src/config/values/ConfigValues.cpp. - Runtime Updates: Use
hyprctl reloadto apply changes without session interruption.
Frequently Asked Questions
How do I enable workspace swiping on my laptop's touchpad?
Set gestures:workspace_swipe_distance to a comfortable pixel threshold, typically between 200 and 400. Ensure your trackpad supports the required finger count (usually three or four fingers) as detected by the PointerGestures protocol in /src/protocols/PointerGestures.cpp.
Why does my workspace swipe direction feel inverted?
Check the gestures:workspace_swipe_invert option, which defaults to true. Setting it to false makes the swipe direction match the physical finger movement exactly. For touchscreen-specific inversion, adjust gestures:workspace_swipe_touch_invert separately.
Can I use trackpad gestures to move windows instead of switching workspaces?
Yes. The gestures:scrolling:move_snap_to_grid and gestures:scrolling:move_snap_cursor options control scroll-move gestures implemented in the gesture classes. These allow you to reposition windows within the tiling layout using trackpad scroll actions rather than swipe gestures.
How do I apply configuration changes without restarting Hyprland?
Execute hyprctl reload from a terminal or add it to a keybinding in hyprland.conf. This sends the appropriate signal to reload CConfigValue objects, immediately updating gesture sensitivity and behavior parameters for all subsequent input events.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →