Files
command-center/scripts/screenshot-desk.sh
Frank 8da6cdc9cd niri: fix screenshots on 2+ outputs — Mod+Shift+S captures all monitors
flameshot full dies docked: its portal path hits niri's
screenshot_all_outputs ensure!(outputs.len()==1) (upstream niri#4313,
niri 26.04), so every Print press on the home desk produces error
bubbles. niri's built-in screenshot UI selects only one output, so add
scripts/screenshot-desk.sh: per-monitor focus + screenshot-screen with
explicit --path, focus restored, one PNG per monitor in
~/Pictures/Screenshots. Bind Mod+Shift+S (Frank's call); noctalia
settings moves to Mod+Shift+O. Restore screenshot-path (was null, now
root-level as config.screenshot_path requires) for UI saves. Live-
verified docked: valid 1920x1080 PNGs for eDP-1 + DP-2, focus restored;
bats 27/27 incl. niri validate on both desk profiles.
2026-10-14 17:21:10 -07:00

46 lines
1.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# screenshot-desk.sh — capture EVERY connected monitor to disk, one PNG each.
#
# niri 26.04 has no single "screenshot all outputs" action (the screenshot
# UI selects a single output only, and the GNOME-compat D-Bus screenshot
# that flameshot 14 uses is hard-limited to one output — niri#4313).
# This script drives niri's own per-output primitives:
# focus-monitor + screenshot-screen, once per connected output,
# then restores the previously focused monitor.
#
# Usage: screenshot-desk.sh # bound to Mod+Shift+S in keybinds.kdl
# SCREENSHOT_DIR=/tmp screenshot-desk.sh
#
# Output naming mirrors niri's screenshot-path default:
# "$SCREENSHOT_DIR/Screenshot from YYYY-MM-DD HH-MM-SS <connector>.png"
# Files land in ~/Pictures/Screenshots by default (same dir as niri's
# screenshot-path in cfg/misc.kdl).
set -euo pipefail
out_dir="${SCREENSHOT_DIR:-$HOME/Pictures/Screenshots}"
mkdir -p "$out_dir"
ts="$(date +'%Y-%m-%d %H-%M-%S')"
focused() { niri msg --json focused-output | jq -r .name; }
prev="$(focused)"
count=0
# niri msg --json outputs: active outputs only (disabled/lid-closed absent).
while IFS= read -r mon; do
[ "$mon" != "$prev" ] && niri msg action focus-monitor "$mon"
# Let the compositor settle a frame after focus move (focus-driven
# highlights/animations are rendered async).
sleep 0.15
file="$out_dir/Screenshot from $ts $mon.png"
niri msg action screenshot-screen --path "$file"
echo "$file"
count=$((count + 1))
done < <(niri msg --json outputs | jq -r '.[].name')
# Restore the original focus (no-op if it's where we ended up).
now="$(focused)"
[ "$now" != "$prev" ] && niri msg action focus-monitor "$prev"
[ "$count" -gt 0 ] || { echo "no active outputs" >&2; exit 1; }