45 lines
4.0 KiB
Markdown
45 lines
4.0 KiB
Markdown
---
|
|
name: niri-all-monitor-screenshot-fix
|
|
description: "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.
|
|
- 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 full` AND `flameshot screen` both 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 is `config.screenshot_path`; a KDL `output { }` block REQUIRES a name arg — bare `output {}` 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.
|