Skip to content

Expose touchpad "hold" gesture to stop kinetic scrolling #8223

@jondkinney

Description

@jondkinney

Problem

On a touchpad the platform convention (macOS, GNOME, …) is that resting two
fingers on the trackpad stops an in-progress kinetic / momentum scroll
— the
"touch to stop" behavior. egui can't react to this today: a stationary
finger-rest produces no pointer or scroll event, so a ScrollArea's kinetic
coast (its vel) — or any app-synthesized momentum — can't be halted by touch.

Enabling upstream change

winit is adding WindowEvent::HoldGesture { device_id, phase }, which surfaces
the Wayland hold gesture (zwp_pointer_gestures_v1 — whose protocol explicitly
names "cancel kinetic scrolling" as its purpose): rust-windowing/winit#4585.
Started when fingers rest, Ended on lift, Cancelled when the rest turns
into a scroll.

Once that lands (and egui bumps to a winit that has it), egui-winit is the
natural place to translate it.

Design question

egui core has no gesture/hold event today, and egui-winit already translates
platform gestures into semantic egui events rather than mirroring winit's
variants — e.g. winit PinchGestureegui::Event::Zoom. Following that
pattern, how would you want the hold gesture exposed?

  1. A semantic egui::Event (e.g. a pointer-gesture / scroll-control event)
    that widgets and apps can read.
  2. Direct ScrollArea integration — egui-winit sets an internal flag that
    ScrollArea reads to zero its kinetic vel on hold, with no public event.
  3. Both — a public event plus ScrollArea consuming it.

No strong opinion on the surface here; happy to implement whichever you prefer.

Platform note

Wayland-only in winit for now. macOS already stops OS-provided momentum on
touch, so it doesn't strictly need this for that path — but the event would
still let egui's own drag-kinetic vel (and other platforms) honor touch-to-stop
consistently.

Motivation / prior art

We hit this building macOS-style kinetic + rubber-band scrolling for Linux
touchpads (libinput doesn't synthesize trackpad momentum, so we synthesize it
ourselves). To get touch-to-stop we currently bridge winit's hold event through
a forked egui-winit into a private egui-memory flag our scroll code reads — it
works, but a first-class egui signal would drop the fork and let ScrollArea
itself benefit.

Scope / gating

Forward-looking: needs winit#4585 merged and egui on a winit with HoldGesture.
Filing now to settle the API direction so the egui-winit + ScrollArea wiring
can follow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions