Skip to content

Releases: GGEZUS/niri-tablet

v26.04.20

Choose a tag to compare

@GGEZUS GGEZUS released this 23 Sep 01:44

niri v26.04 + 20 patches (was 18). A breaking gesture rename, a new gesture pair, a GUI configurator, and a smarter auto-rotate helper.

Breaking: gesture nodes renamed

tap-4 / swipe-4-up / swipe-4-down are now tap-more / swipe-more-up / swipe-more-down, and they apply at one finger more than touchscreen-swipe.fingers (4 by default) instead of a hardcoded four. fingers itself is now restricted to 3 or 4, enforced at parse time.

Configs from v26.04.18 or earlier that still use the old names fail validation on this build. Run ./update-niri-tablet.sh and answer y when it offers the rename: one dated .bak per touched file, undone unless niri validate passes on the whole include chain. Or open EasySetup and save once. Either way, rename before your next login, or the session starts on niri's default config with an error notification until the file is fixed.

New

  • swipe-more-left / swipe-more-right: quick horizontal flicks with one finger more than the base count now run discrete actions, like the vertical ones. Unbound (the shipped default) they keep the horizontal drag's behavior (resize-column or move-view).
  • EasySetup, a GTK4/libadwaita configurator: pick actions from installed apps or a curated catalog, test-run them live, import/export schemes, and save only what niri validate accepts. cargo build --release in niri-tablet-easysetup/; details in the EasySetup wiki page.
  • Tablet-mode gate in niri-rotate.sh: on 2-in-1s the auto-rotate helper stays idle in laptop mode and catches up when folded into a tablet. ThinkPad and HP convertibles detected automatically; NIRI_ROTATE_TABLET_MODE_SYSFS for other vendors, NIRI_ROTATE_TABLET_MODE_ONLY=no to disable. Machines without a switch are untouched.
  • The shipped config/gestures.kdl is now the full scheme the author runs daily: hold-swipes move windows, the bottom edge toggles the OSK, a 4-finger flick up toggles fullscreen.

Changed

  • The updater detects old gesture names in ~/.config/niri after installing and offers the rename (--yes reports without editing).
  • New 60-second demo video.

The 20 patches

  1. feat(input): add touchscreen 3-finger swipe gestures
  2. feat(config): add touchscreen-swipe gesture configuration
  3. docs: document touchscreen swipe gestures
  4. feat(input): touchscreen tap and bottom-edge swipe gestures
  5. feat(input): discrete 4-finger vertical swipe gestures
  6. fix(input): count late-joining fingers and fix deadlock in discrete swipes
  7. test(config): refresh the parse insta snapshot for the touchscreen gesture fields
  8. feat(ui): show-touch-points: compositor-rendered touch point visualization
  9. feat(input): hold-swipe touchscreen gestures: move windows with a held swipe
  10. fix(input): own multi-finger touch sequences: gestures stop leaking to apps
  11. fix(input): latch gesture ownership through smithay's implicit touch grab
  12. fix(input): clear touch gesture state when a touch device is removed
  13. feat(input): gesture debug logging behind gestures debug-log
  14. feat(input): single-finger edge and corner swipe gestures
  15. docs: document touchscreen edge and corner swipe gestures
  16. fix(test): edge-swipe test helper rectangle construction
  17. feat(input): horizontal swipe column-resize mode
  18. docs: document the touchscreen-swipe action options
  19. feat(gestures): derive the tap/flick tier from fingers
  20. feat(gestures): swipe-more-left/right for extra-finger flicks

v26.04.18: edge & corner swipes and live width resize

Choose a tag to compare

@GGEZUS GGEZUS released this 08 Sep 11:30

niri v26.04 + 18 patches, installed as niri-tablet 26.04.18.

New since v26.04.13:

Edge and corner swipes (one finger). A finger swiping inward from a
screen edge, or diagonally out of a corner, runs any niri action. Four
edge zones and four corner zones, each bound on its own:

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

Edges trigger on a 40px perpendicular-dominant stroke starting within
48px of the edge; corners need a genuinely diagonal 20px stroke, so a
mostly-straight swipe near a corner still does nothing and the adjacent
edges stay usable. Taps and short drags in the strips keep reaching
apps, unbound zones are inert, and bindings apply live without a
re-login.

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

Live width resize on the 3-finger horizontal drag. New mode:

touchscreen-swipe {
    horizontal-swipe "resize-column"
}

Instead of scrolling the view, the horizontal drag now 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 (the same one
Mod+right-click uses), so the resize is smooth, respects window min/max
sizes, and works on floating windows too. The default remains
"move-view" (the animated scroll), and a drag with nothing focused falls
back to it.

Example config rewritten. config/gestures.kdl carried too much
comment noise; it now states only what earns its place (the
fingers/*-4 tier relationship, the nesting of the edge/corner blocks).
No semantic changes.

Also in this release: the wiki documents every touchscreen-swipe node
(previously only fingers/off were listed), and an edge-swipe test
helper that failed to compile in the test profile was fixed.

Verified on hardware on both a Microsoft Surface Go 2 and a ThinkPad
T480: the resize mode, all four edge zones, the fallbacks, and app
delivery in the edge strips.

The full niri test suite passes (236 tests, plus the config and
wiki-doc suites), and the 18-patch series applies cleanly over the
v26.04 tag.

Install

Arch Linux: easiest, with the bundled updater:

git clone https://github.com/GGEZUS/niri-tablet.git
cd niri-tablet
./update-niri-tablet.sh

Manual equivalent:

cd niri-tablet/pkg
makepkg -si        # builds upstream niri + patches; replaces stock niri

Upgrading: ./update-niri-tablet.sh (or git pull && makepkg -si), then
log out and back in. Other distros: the series is plain patch/git am

  • cargo build; see the
    README.

NixOS: bump rev in the fetchFromGitHub block to v26.04.18
(the hash will change with it; leave it empty once and Nix prints the
right one).

Patch series (changelog)

  1. feat(input): add touchscreen 3-finger swipe gestures
  2. feat(config): add touchscreen-swipe gesture configuration
  3. docs: document touchscreen swipe gestures
  4. feat(input): touchscreen tap and bottom-edge swipe gestures
  5. feat(input): discrete 4-finger vertical swipe gestures
  6. fix(input): count late-joining fingers and fix deadlock in discrete swipes
  7. test(config): refresh the parse insta snapshot for the touchscreen gesture fields
  8. feat(ui): show-touch-points — compositor-rendered touch point visualization
  9. feat(input): hold-swipe touchscreen gestures — move windows with a held swipe
  10. fix(input): own multi-finger touch sequences — gestures stop leaking to apps
  11. fix(input): latch gesture ownership through smithay's implicit touch grab
  12. fix(input): clear touch gesture state when a touch device is removed
  13. feat(input): gesture debug logging behind gestures debug-log
  14. feat(input): single-finger edge and corner swipe gestures
  15. docs: document touchscreen edge and corner swipe gestures
  16. fix(test): edge-swipe test helper rectangle construction
  17. feat(input): horizontal swipe column-resize mode
  18. docs: document the touchscreen-swipe action options

Each rebase onto a new niri release gets a new tag (v<niri-version>.<patch-count>,
matching the installed pkgver) and appends its changes here.

v26.04.13 — gesture debug logging (bug-report helper)

Choose a tag to compare

@GGEZUS GGEZUS released this 07 Sep 19:34

niri v26.04 + 13 patches, installed as niri-tablet 26.04.13.

New in this release: gestures { debug-log }, a bug-report helper.
If a gesture misbehaves, the flag turns on per-event logging of the
touchscreen gesture stack: every finger down/up/motion with slot ids,
positions and timestamps, the recognition decision (finger count,
direction, hold vs quick), and the action dispatched for taps, discrete
swipes and edge swipes. Every line is prefixed gesture-debug: and
written at info level, so a plain journalctl excerpt is enough to debug
a repro remotely:

journalctl --user -u niri.service --since -10m | grep gesture-debug

Off by default, no behavior change to the gestures themselves. Toggling
it works live: save the config and the flag applies from the next touch
(no re-login). Running niri from a terminal instead? The same lines go
to its stderr. Details in the README, section "Gesture debug logging".

Why it exists: the first external bug report (4-finger gestures acting
as 3-finger ones on some hardware) needs exactly this stream to
diagnose. If you hit a gesture bug, please enable the flag, reproduce
it a few times, and attach the collected lines to your issue; it makes
these fixable from a distance.

The full niri test suite passes (227 tests, plus the config and
wiki-doc suites), and the 13-patch series applies cleanly over the
v26.04 tag.

Install

Arch Linux: easiest, with the bundled updater:

git clone https://github.com/GGEZUS/niri-tablet.git
cd niri-tablet
./update-niri-tablet.sh

Manual equivalent:

cd niri-tablet/pkg
makepkg -si        # builds upstream niri + patches; replaces stock niri

Upgrading: ./update-niri-tablet.sh (or git pull && makepkg -si), then
log out and back in. Other distros: the series is plain patch/git am

  • cargo build; see the
    README.

NixOS: bump rev in the fetchFromGitHub block to v26.04.13
(the hash will change with it; leave it empty once and Nix prints the
right one).

Patch series (changelog)

  1. feat(input): add touchscreen 3-finger swipe gestures
  2. feat(config): add touchscreen-swipe gesture configuration
  3. docs: document touchscreen swipe gestures
  4. feat(input): touchscreen tap and bottom-edge swipe gestures
  5. feat(input): discrete 4-finger vertical swipe gestures
  6. fix(input): count late-joining fingers and fix deadlock in discrete swipes
  7. test(config): refresh the parse insta snapshot for the touchscreen gesture fields
  8. feat(ui): show-touch-points — compositor-rendered touch point visualization
  9. feat(input): hold-swipe touchscreen gestures — move windows with a held swipe
  10. fix(input): own multi-finger touch sequences — gestures stop leaking to apps
  11. fix(input): latch gesture ownership through smithay's implicit touch grab
  12. fix(input): clear touch gesture state when a touch device is removed
  13. feat(input): gesture debug logging behind gestures debug-log

Each rebase onto a new niri release gets a new tag (v<niri-version>.<patch-count>,
matching the installed pkgver) and appends its changes here.

v26.04.12 — touch-device removal no longer wedges the session

Choose a tag to compare

@GGEZUS GGEZUS released this 06 Sep 18:14

v26.04.12 — touch-device removal no longer wedges the session

niri v26.04 + 12 patches, installed as niri-tablet 26.04.12.

If a touchscreen vanished mid-gesture — a USB crash-loop, an unplug, any
hotplug hiccup — three wedges persisted until the next re-login:

  • touch_input_suspended never cleared (it only clears on the last
    finger's lift, which never came), so every touch of the re-enumerated
    device was swallowed: touch stayed dead for the rest of the session;
  • any installed gesture grab stayed on the touch handle, eating future
    touches;
  • touches already delivered to an app never got their lift — the same
    stuck-phantom-touch class v26.04.11 fixed (apps ignoring taps and
    clicks until restarted).

The fix (patch 0012): on_device_removed now runs the same teardown
on_touch_cancel performs — synthetic lifts + frame for client-visible
touches, grab release, both tracker resets, suspension cleared,
touch-point overlay dropped — before the seat's touch handle is
destroyed. The moment the device returns (a crash-looping touchscreen
usually re-enumerates within seconds), touch works again. No re-login,
no phantom touches.

Found in the wild: a T480 whose Raydium touchscreen entered a ~5.5 s USB
disconnect loop mid-session — touch dead for the whole session and apps
eating touchpad clicks until restarted. Post-fix, the full gesture set
verified on the same machine, and the full niri test suite (227 tests)
passes.

Install

Arch Linux — easiest, with the bundled updater (added right after this
release; git pull once if your clone predates it):

git clone https://github.com/GGEZUS/niri-tablet.git
cd niri-tablet
./update-niri-tablet.sh     # fetch → changelog → build → install → pin IgnorePkg

Manual equivalent:

cd niri-tablet/pkg
makepkg -si        # builds upstream niri + patches; replaces stock niri

Upgrading: ./update-niri-tablet.sh (or git pull && makepkg -si), then log
out and back in. Other distros: the series is plain patch/git am +
cargo build — see the
README.

Patch series (changelog)

  1. feat(input): add touchscreen 3-finger swipe gestures
  2. feat(config): add touchscreen-swipe gesture configuration
  3. docs: document touchscreen swipe gestures
  4. feat(input): touchscreen tap and bottom-edge swipe gestures
  5. feat(input): discrete 4-finger vertical swipe gestures
  6. fix(input): count late-joining fingers and fix deadlock in discrete swipes
  7. test(config): refresh the parse insta snapshot for the touchscreen gesture fields
  8. feat(ui): show-touch-points — compositor-rendered touch point visualization
  9. feat(input): hold-swipe touchscreen gestures — move windows with a held swipe
  10. fix(input): own multi-finger touch sequences — gestures stop leaking to apps
  11. fix(input): latch gesture ownership through smithay's implicit touch grab
  12. fix(input): clear touch gesture state when a touch device is removed

Each rebase onto a new niri release gets a new tag (v<niri-version>.<patch-count>,
matching the installed pkgver) and appends its changes here.

v26.04.11 — phantom-touch fix

Choose a tag to compare

@GGEZUS GGEZUS released this 24 Aug 21:36

v26.04.11 — phantom-touch fix

niri v26.04 + 11 patches, installed as niri-tablet 26.04.11.

This release fixes the phantom-touch bug introduced by the gesture-ownership
patch: after 3/4-finger gestures, apps (browsers especially) kept believing
extra fingers were still on screen — a single-finger scroll pinch-zoomed, taps
were ignored — until the app was restarted.

Root cause: smithay installs an implicit TouchDownGrab on every delivered
touch-down, so is_grabbed() is true from the first finger that lands on an
app window. The ownership latch required "not grabbed", so over app surfaces it
never fired: every finger of the gesture streamed to the app, and the gesture
grab then swallowed their lifts — stuck touches, with touch ids reused while
stuck (double-downs on the wire).

The fix (patch 0011): the latch treats the implicit grab as "no grab" and
drops it when the compositor takes over, ending the already-delivered touches
with synthetic lifts + a frame. A hardware touch-cancel now ends client-visible
touches the same way (smithay's TouchHandle::cancel() is a silent no-op for
frame-flushed slots), and the edge-swipe lift is frame-finalized.

Verified on a ThinkPad touchscreen (Raydium) and a Surface Go 2 (IPTS):
WAYLAND_DEBUG captures show every gesture ending app-visible touches cleanly
— zero double-downs, zero stuck touches, at most two app-visible fingers per
gesture (nine phantoms before the fix). Capture logs are in
bugreports/phantom-touch-20260824/.

Install

Arch Linux:

git clone https://github.com/GGEZUS/niri-tablet.git
cd niri-tablet/pkg
makepkg -si        # builds upstream niri + patches; replaces stock niri

Upgrading: git pull && makepkg -si, then log out and back in. Other distros:
the series is plain patch/git am + cargo build — see the
README.

Patch series (changelog)

  1. feat(input): add touchscreen 3-finger swipe gestures
  2. feat(config): add touchscreen-swipe gesture configuration
  3. docs: document touchscreen swipe gestures
  4. feat(input): touchscreen tap and bottom-edge swipe gestures
  5. feat(input): discrete 4-finger vertical swipe gestures
  6. fix(input): count late-joining fingers and fix deadlock in discrete swipes
  7. test(config): refresh the parse insta snapshot for the touchscreen gesture fields
  8. feat(ui): show-touch-points — compositor-rendered touch point visualization
  9. feat(input): hold-swipe touchscreen gestures — move windows with a held swipe
  10. fix(input): own multi-finger touch sequences — gestures stop leaking to apps
  11. fix(input): latch gesture ownership through smithay's implicit touch grab

Each rebase onto a new niri release gets a new tag (v<niri-version>.<patch-count>,
matching the installed pkgver) and appends its changes here.

v26.04.10 — first release

Choose a tag to compare

@GGEZUS GGEZUS released this 22 Aug 22:08

First release of the niri-tablet patchset: niri v26.04 + 10 patches, installed as niri-tablet 26.04.10.

Tablet/touchscreen support for niri: multi-finger
window-management gestures, an on-screen keyboard helper that adapts to screen
orientation, and automatic display rotation — everything needed to run a niri
session with the keyboard detached.

The gesture set

Gesture Action
3-finger drag, horizontal scroll the view across columns (animated)
3-finger drag, vertical workspace carousel (animated)
3-finger tap maximize / restore the focused column
3-finger hold + swipe move the focused window: left/right a column, up/down a workspace
4-finger tap window overview (built-in; any launcher binds in its place)
4-finger flick down close the focused window
4-finger flick up toggle the on-screen keyboard (needs the OSK script)

Every gesture is configurable — each node takes any niri action, same as
keybinds. Multi-finger gestures are owned by the compositor: apps never see
them, 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) and
touchpad behavior are untouched.

Install

Arch Linux:

git clone https://github.com/GGEZUS/niri-tablet.git
cd niri-tablet/pkg
makepkg -si        # builds upstream niri + patches; replaces stock niri

Other distros: the series is plain patch/git am + cargo build — see the
README.

Patch series (changelog)

  1. feat(input): add touchscreen 3-finger swipe gestures
  2. feat(config): add touchscreen-swipe gesture configuration
  3. docs: document touchscreen swipe gestures
  4. feat(input): touchscreen tap and bottom-edge swipe gestures
  5. feat(input): discrete 4-finger vertical swipe gestures
  6. fix(input): count late-joining fingers and fix deadlock in discrete swipes
  7. test(config): refresh the parse insta snapshot for the touchscreen gesture fields
  8. feat(ui): show-touch-points — compositor-rendered touch point visualization
  9. feat(input): hold-swipe touchscreen gestures — move windows with a held swipe
  10. fix(input): own multi-finger touch sequences — gestures stop leaking to apps

Each rebase onto a new niri release gets a new tag (v<niri-version>.<patch-count>,
matching the installed pkgver) and appends its changes here.