Skip to content

Add continuous three-finger drag gesture for text selection on Wayland#384

Open
philipbalinov wants to merge 6 commits intobulletmark:masterfrom
philipbalinov:three-finger-drag
Open

Add continuous three-finger drag gesture for text selection on Wayland#384
philipbalinov wants to merge 6 commits intobulletmark:masterfrom
philipbalinov:three-finger-drag

Conversation

@philipbalinov
Copy link
Copy Markdown

@philipbalinov philipbalinov commented Apr 18, 2026

Summary

  • Adds a DRAG gesture handler and _drag internal command that simulate a held mouse button while tracking finger movement via a persistent uinput virtual device
  • Enables three-finger drag-to-select text and drag-and-drop on Wayland (and Xorg)
  • The uinput device is created once at startup rather than per-gesture, so the Wayland compositor has time to discover it before the first event arrives

Motivation

Three-finger drag for text selection has been broken on GNOME Wayland because the compositor intercepts swipe gestures before any userspace tool can act on them continuously. This has been a frustrating limitation for many users — personally, a pet peeve for over 10 years.

The approach here works around it entirely via uinput, injecting BTN_LEFT + REL_X/REL_Y events from a virtual device that the compositor treats like a real mouse.

Configuration

Enable by adding to libinput-gestures.conf:

gesture drag drag 3 _drag

Requires python3-evdev and the user in the input group:

sudo usermod -aG input $USER
echo 'KERNEL=="uinput", MODE="0660", GROUP="input"' | sudo tee /etc/udev/rules.d/99-uinput.rules

Test plan

  • Three-finger drag selects text in a native Wayland app (e.g. gedit)
  • Three-finger drag works in XWayland apps
  • Cancelling a gesture mid-drag releases BTN_LEFT cleanly
  • No interference with existing swipe gestures on other finger counts

🤖 Generated with Claude Code

Philip Balinov and others added 6 commits April 18, 2026 09:27
Adds a new DRAG gesture handler and _drag internal command that simulate
a held mouse button while tracking finger movement via a persistent uinput
virtual device. This enables three-finger drag-to-select text and
drag-and-drop on both Wayland and Xorg.

Key implementation details:
- COMMAND_drag creates a uinput device at startup (not per-gesture) so
  Wayland's compositor has time to discover it before the first event
- DRAG gesture handler intercepts GESTURE_SWIPE events (since libinput has
  no GESTURE_DRAG type) when a drag config matches the finger count
- Handles gesture cancellation mid-drag to ensure BTN_LEFT is released
- Requires python3-evdev and user in the 'input' group

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a delay is specified (e.g. `_drag 500`), BTN_LEFT is held for that
many milliseconds after fingers are lifted. A new three-finger gesture
within the window cancels the timer and resumes dragging seamlessly,
allowing the user to reposition fingers at the touchpad edge without
losing the selection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Return cls from add_internal_command decorator so isinstance(cmd,
  COMMAND_drag) works correctly instead of type().__name__ string check
- Add threading.Lock to COMMAND_drag to guard shared state accessed from
  both the main thread and the release timer thread
- Initialize self._ecodes = None explicitly before the try block
- Wrap bad delay arg in try/except ValueError with a clear warning
- Make evdev an optional dependency ([project.optional-dependencies] uinput)
  so users of the xdotool backend don't need it
- Initialize _cmd = None as a class-level attribute, removing the hasattr()
  guard in cancel()
- Comment out the drag gesture in the default conf; users opt in via their
  personal ~/.config/libinput-gestures.conf

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Any BEGIN event during the lift-and-continue window that is not a
matching three-finger drag will now immediately release BTN_LEFT rather
than waiting for the timer to expire.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…setup

End the release grace period immediately when a POINTER_MOTION event is
seen, so moving a single finger after lifting three does not continue
text selection for the duration of the delay.

Also document the modprobe / modules-load.d steps needed to ensure
/dev/uinput exists before applying the udev rule.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant