Skip to content

Configuration

GGEZUS edited this page Sep 23, 2026 · 8 revisions

The patchset adds one new gestures {} block to the niri config. niri reloads the config on save, and every option below applies live, without a re-login (the debug-log flag takes effect from the next touch).

Every action node takes any niri action, same as keybinds. If you can bind it to a key, you can bind it to a gesture. The niri wiki's actions list is the menu.

Using the shipped config

config/gestures.kdl in the repo is the scheme the project ships and its author runs daily. Either paste its gestures block into your config.kdl, or include the file:

include "~/.config/niri/cfg/gestures.kdl"

and copy it there:

mkdir -p ~/.config/niri/cfg
cp niri-tablet/config/gestures.kdl ~/.config/niri/cfg/

Prefer not to hand-edit KDL at all? EasySetup is a GUI that does the above for you and then some.

What follows is the full node reference.

touchscreen-swipe

Multi-finger gestures: the two animated drags, taps, flicks, and hold-swipes. On top of the animated swipes, discrete actions can be bound to taps and specific swipe shapes, and the horizontal swipe can be switched to resize the focused window. Anything left unbound falls back to the animated gesture (or, for taps with more fingers than fingers, to the regular tap action).

Renamed after v26.04.18: tap-4/swipe-4-up/swipe-4-down became tap-more/swipe-more-up/swipe-more-down and apply at one finger more than fingers instead of a fixed four.

  • fingers - number of fingers required for everything in this block that has no "more" in its name (the drags and tap). Must be 3 or 4; default 3. The *-more nodes below override their gesture at one finger more than this (4 by default).
  • off - disable touchscreen swipe gestures entirely.
  • horizontal-swipe - what a quick horizontal swipe does. Default: "move-view" (scroll the view across columns). "resize-column" makes the swipe resize the focused window's width, tracking the fingers 1:1: dragging right widens it, dragging left narrows it, and the width stays where the fingers leave it. Tiled: the focused column; floating: the focused window. Without a focused window the swipe falls back to moving the view.
  • tap - action for a quick tap with fingers fingers. Default: maximize-column. All fingers down and up within a short window, without enough movement to become a swipe.
  • tap-more - action for taps with one finger more than fingers (4 by default); overrides tap for those.
  • swipe-more-down / swipe-more-up - discrete action for a quick vertical swipe with one finger more than fingers (4 by default). Unset, such swipes drive the workspace carousel.
  • swipe-more-left / swipe-more-right - discrete action for a quick horizontal swipe with one finger more than fingers (4 by default), added after v26.04.18. Unset, such swipes keep the horizontal-swipe behavior (move the view, or resize the focused column).
  • hold { left/right/up/down { ... } } - discrete actions for held swipes: fingers resting still for ~400ms before swiping. A direction left unset falls back to the animated swipe.
gestures {
    touchscreen-swipe {
        fingers 3
        // off
        horizontal-swipe "resize-column"
        tap             { maximize-column; }
        tap-more        { toggle-overview; }
        swipe-more-down { close-window; }
        swipe-more-up   { fullscreen-window; }
        // swipe-more-left { focus-column-left; }
        // swipe-more-right { focus-column-right; }

        hold {
            left  { move-column-left; }
            right { move-column-right; }
            up    { move-window-to-workspace-up; }
            down  { move-window-to-workspace-down; }
        }
    }
}
gestures {
    // Disable touchscreen swipe gestures.
    touchscreen-swipe {
        off
    }
}

The recognition rules (hold vs quick, tap vs swipe, fallbacks) are described on Gestures.

touchscreen-edge-swipe

Single-finger swipes that start at a screen edge. A finger starting within ~48 logical pixels of an edge and swiping inward past ~40 pixels (with the inward direction dominant) runs the action bound to that edge. Each of bottom (swipe up), top (swipe down), left (swipe right) and right (swipe left) takes any niri action:

gestures {
    touchscreen-edge-swipe {
        bottom { spawn-sh "~/.local/bin/niri-osk.sh"; }
        top    { toggle-overview; }
        left   { focus-column-left; }
        right  { focus-column-right; }
    }
}

Touches in an edge strip deliver to applications normally until the trigger distance is crossed, unbound zones are inert, and the zones follow the output's transform (details on Gestures). Avoid binding edges occupied by swipe-driven shell surfaces (e.g. a pull-down notification panel along the top): the bound gesture would fire mid-drag.

Breaking change in v26.04.18: the old touchscreen-edge-swipe { spawn ...; } form no longer parses (it never worked on hardware); use the per-zone children shown above.

touchscreen-corner-swipe

Single-finger diagonal swipes that start at 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. Each of top-left, top-right, bottom-left and bottom-right takes any niri action; unbound corners are inert.

gestures {
    touchscreen-corner-swipe {
        top-left     { maximize-column; }
        top-right    { toggle-overview; }
        bottom-left  { spawn "foot"; }
        bottom-right { close-window; }
    }
}

Corners win over edges when the touch starts within range of both.

show-touch-points

Translucent dots that follow your fingers, drawn by the compositor. For demo videos and gesture debugging; off by default.

gestures {
    show-touch-points "gestures"   // only while a multi-finger gesture is down
    // show-touch-points "all"     // every finger (debugging)
}

The values are quoted strings. A bare unquoted show-touch-points gestures passes the unit-test parser but niri's strict file loader rejects it, so niri validate is the only check that catches it before a re-login.

debug-log

Per-event logging of the touchscreen gesture stack, for bug reports. Every line is prefixed gesture-debug:. Off by default, toggles live (applies from the next touch). See Troubleshooting for how to collect a reproduction.

gestures {
    debug-log
}

A note on non-US layouts and the OSK

If you use the on-screen keyboard with a non-US system layout, the two-group xkb setup that keeps the OSK typing US while the physical keyboard stays native belongs in your input config, not in the gestures block: OSK and auto-rotation.

Clone this wiki locally