Repository navigation
Gestures
Reference for every gesture the patchset adds, how recognition works, and which fallback applies when something is left unbound. For the config syntax itself, see Configuration.
The multi-finger swipes run through the same spring-physics pipeline as niri's touchpad gestures: rotation-proof logical coordinates, live follow, inertia. Touchpad behavior is untouched; everything on this page is touchscreen-only.
With fingers fingers (3 or 4; default 3) down and dragging:
- Vertical drag runs the workspace carousel, the same continuous animated switch as the touchpad swipe.
-
Horizontal drag moves the view across columns, or, with
horizontal-swipe "resize-column", resizes the focused window instead (next section).
While a drag is in progress the view tracks your fingers 1:1; on lift it settles with inertia.
touchscreen-swipe {
horizontal-swipe "resize-column"
}Instead of scrolling the view, the horizontal drag widens or narrows the focused window, tracking your fingers 1:1: drag right to widen, left to narrow; the width stops when you stop and stays where you lift.
It rides niri's own interactive-resize machinery, so the resize is smooth, respects window min/max sizes, and works on floating windows too. On a tiled layout it resizes the focused column; with a floating window focused, that window. With nothing focused, the drag falls back to moving the view.
The default remains "move-view" (the animated scroll), and that is also the
compiled default: with no gestures {} config at all, only the two animated
drags and the 3-finger tap do anything.
The discrete gestures fire once, on finger lift. fingers sets the base count
(3 or 4; default 3) and the *-more nodes sit at one finger more than that:
-
tap-fingersfingers down and up within ~250 ms, without the gesture's centroid crossing the 16 px swipe-recognition threshold (the same figure GNOME Shell uses). Compiled default:maximize-column. -
tap-more- taps with one finger more thanfingers(4 by default); overridestapfor those. -
swipe-more-down/swipe-more-up- a quick vertical flick with one finger more thanfingers(4 by default), direction as the name says. -
swipe-more-left/swipe-more-right- the horizontal counterparts, added after v26.04.18. Unbound (the shipped default), such flicks keep the horizontal drag's behavior (move-view or resize-column).
Renamed after v26.04.18: tap-4/swipe-4-up/swipe-4-down became
tap-more/swipe-more-up/swipe-more-down and now track fingers instead
of a fixed four. EasySetup reads the old names and writes the new ones on its
next save.
A "quick" flick is decided by how long your fingers lingered below the movement threshold before moving; see hold-swipes below for the other side of that decision.
Anything left unbound falls back to the animated gesture (or, for taps with
more fingers than fingers, to the regular tap action). Concretely: with
tap-more unset, a 4-finger tap runs tap's action; with swipe-more-up
unset, a 4-finger flick drives the workspace carousel; with swipe-more-left
or swipe-more-right unset, the flick resizes (or scrolls) like the
horizontal drag. So "my 4-finger
gestures act like 3-finger ones" means "the 4-finger binds are missing from
the config", not a bug: see Troubleshooting.
Rest three (or more) fingers still for a moment (~400ms), then swipe: instead of the animated view scroll, the dominant direction runs a discrete action. Quick swipes never trigger it; how long your fingers lingered below the movement threshold decides.
Each direction binds on its own (left, right, up, down); a direction
left unset falls back to the animated swipe. Remove the hold block (or a
single direction) and held swipes behave like quick ones again.
From the moment touchscreen-swipe.fingers fingers are down, the whole touch
sequence belongs to the compositor: apps never see it (touches they already
received are cancelled), and normal delivery resumes when the last finger
lifts. So a 3-finger swipe doesn't pinch-zoom a browser or drag-select
terminal text mid-gesture.
Single- and two-finger input, including app pinch-zoom, is untouched. If an
app genuinely needs 3-finger touches (some design tools use them), raise
fingers to 4.
A single finger swiping inward from a screen edge:
- the touch must start within ~48 logical pixels of an edge, and
- swipe inward past ~40 pixels, with the inward direction dominant.
Then the action bound to that edge runs. bottom means swiping up, top
swiping down, left swiping right, right swiping left.
Behavior details that matter in practice:
- Touches in an edge strip deliver to applications normally until the trigger distance is crossed: plain taps and short drags on shell bars and app content keep working. The compositor cancels the touch (and swallows the rest of the stroke) only when the gesture actually fires.
- A second finger landing cancels the gesture.
- The zones follow the output the touch lands on, including its transform, so edges stay in the visual orientation on rotated tablets and per-output on multi-monitor setups.
- Zones left unbound are inert.
- The trigger path doesn't check whether the overview is open (only the screenshot and window-MRU UIs are gated), so an edge swipe can fire with the overview up: a bound bottom edge toggles the overview closed mid-drag. Kept deliberately.
- Don't bind an edge covered by a swipe-driven shell surface (for example a pull-down notification panel along the top): the bound gesture would fire mid-drag.
Single-finger diagonal swipes out of a screen corner. The corner zones are the ~48 logical pixel squares where two edge strips meet, and the swipe must move inward by ~20 pixels on both axes: a genuinely diagonal stroke. A mostly-straight swipe starting in a corner zone deliberately triggers nothing, so the adjacent edges stay usable right up to the corner.
Corners win over edges when the touch starts within range of both. Unbound corners are inert; the shipped config leaves all four unbound on purpose.
show-touch-points renders translucent dots that follow your fingers, drawn
by the compositor itself: any screen recording captures them and input is
never touched. Off by default; meant for demo videos and for debugging
gestures.
gestures {
show-touch-points "gestures" // dots only while a multi-finger gesture is down
// show-touch-points "all" // every finger (debugging)
}In gestures mode dots appear only while enough fingers are down concurrently
for a gesture (touchscreen-swipe.fingers), so ordinary taps and scrolling
stay clean.