4.0 KiB
name, description
| name | description |
|---|---|
| niri-all-monitor-screenshot-fix | Fix flameshot screenshot failures on niri with 2+ outputs: confirm portal outputs.len()==1 census, retire flameshot binds for niri-native equivalents, absolute script paths (niri spawn-sh PATH lacks ~/.local/bin) |
Niri all-monitor screenshot fix (flameshot retirement)
Symptom fingerprints
- "Bunch of flameshot errors after a delay" when docked (2+ outputs); fine on one output.
- Journal census (ground truth):
journalctl --user -u niri --since today | grep -i screenshot- FAIL:
WARN niri::niri: error taking a screenshot: Condition failed: outputs.len() == 1 (2 vs 1)— one press of flameshot full emits 3 WARNs (composited screen + per-output portal requests). - SUCCESS:
DEBUG niri::niri: saving screenshot to ...— per-file lines.
- FAIL:
- Timeline: count WARNs before/after a config reload to attribute presses to config states.
Root cause
Flameshot 14 on Wayland captures via xdg-desktop-portal → xdg-desktop-portal-gnome → niri's GNOME-Screenshot compatibility D-Bus API → screenshot_all_outputs → ensure!(outputs.len() == 1) (FIXME upstream). Upstream: niri#4313 (closed duplicate, unfixed in 26.04/8ed0da4), flameshot#4449.
- NOT just
full: live-verified docked,flameshot fullANDflameshot screenboth hang ~15 s (exit 124 under timeout), write no file. Assume ALL flameshot capture modes dead with 2+ outputs.
Fix: retire flameshot binds; niri-native replacements (blankpad layout)
| Chord | Action |
|---|---|
| Print / Ctrl+Shift+1 / Mod+Shift+S | spawn-sh "/home/blank/.omp/scripts/screenshot-desk.sh" — per-monitor PNGs |
| Alt+Print / Ctrl+Shift+2 | screenshot-screen; — focused monitor → screenshot-path + clipboard |
| Ctrl+Print / Ctrl+Shift+3 | screenshot; — interactive UI (Space saves, Esc cancels; single-output selection by design) |
- Misc:
screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png"at CONFIG ROOT (it isconfig.screenshot_path; a KDLoutput { }block REQUIRES a name arg — bareoutput {}is a parse error). - KDL comments are
//, never#(parses as identifiers → cryptic "identifiers cannot be used as arguments"). - niri 26.04 screenshot UI: "allows only single-output selections for now" (src/ui/screenshot_ui.rs) — no built-in all-monitor composite; script needed.
All-monitor script (scripts/screenshot-desk.sh)
Per active output (niri msg --json outputs | jq -r .[].name): niri msg action focus-monitor <m> → sleep 0.15 → niri msg action screenshot-screen --path "<abs>/… <connector>.png" → restore prior focused monitor (niri msg --json focused-output | jq -r .name). No grim, no portal. --path must be absolute.
THE SPAWN-SH PATH TRAP
niri's spawn-sh PATH = system dirs only; ~/.local/bin ABSENT. Proof:
tr '\0' '\n' < /proc/$(pgrep -x niri | head -1)/environ | grep ^PATH
→ any bare user-script name in a keybind fails SILENTLY (no journal error, no file). Rule: keybinds use absolute script paths (/home/blank/.omp/scripts/...). Audit existing binds for bare names (desk.sh was dead too).
Verifying a keybind end-to-end without a keyboard
Reproduce niri's child env exactly:
env -i PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl HOME=$HOME USER=$USER LOGNAME=$LOGNAME XDG_RUNTIME_DIR=/run/user/$(id -u) WAYLAND_DISPLAY=wayland-1 NIRI_SOCKET=/run/user/$(id -u)/niri.$WAYLAND_DISPLAY.$(pgrep -x niri | head -1).sock sh -c "/abs/path/script"
NIRI_SOCKET is NOT in niri's own environ (it is set on niri's children); socket path convention: $XDG_RUNTIME_DIR/niri.<wl-display>.<niri-pid>.sock.
Deploy mechanics (blankpad command-center)
Live niri config = symlinks into the ~/.omp main checkout ("the checkout is the deployment"). Merge to main → niri auto-reloads (~1 s later journal DEBUG niri_config: loaded config from ...); verify that DEBUG line as the reload proof. Manual fallback: Mod+Shift+/. niri msg has NO keybinds subcommand — keybind proof = overlay (Mod+Shift+Escape) + journal census.