# Screen recording (menu › Tools › Capture). One helper owns the whole # lifecycle: `start` launches wl-screenrec (VAAPI hardware encode) and # falls back to wf-recorder (software x264) if it dies on the spot — # e.g. no usable VAAPI device; `status` feeds the self-gating Waybar # indicator (waybar.nix, signal 8), whose click is the ONE stop surface # (`stop` SIGINTs the recorder so it finalizes the file cleanly). State # is a runtime pidfile — nothing persists across sessions. { config, lib, pkgs, ... }: lib.mkIf config.nomarchy.rofi.enable { home.packages = [ pkgs.wl-screenrec pkgs.wf-recorder (pkgs.writeShellScriptBin "nomarchy-record" '' run="''${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" pidfile="$run/nomarchy-record.pid" filefile="$run/nomarchy-record.file" alive() { [ -f "$pidfile" ] && kill -0 "$(cat "$pidfile")" 2>/dev/null; } # -x, both comm names: nixpkgs wraps the binary as `.waybar-wrapped`, # and an unanchored `waybar` also matches (and kills) the # nomarchy-waybar supervisor, whose bash dies on an unhandled RTMIN. poke_bar() { pkill -RTMIN+8 -x 'waybar|\.waybar-wrapped' 2>/dev/null || true; } case "''${1:-}" in start) if alive; then notify-send "Screen recording" "Already recording — stop it via the ⏺ in the bar." exit 1 fi target="''${2:-screen}"; audio="''${3:-}" geo="" if [ "$target" = region ]; then geo=$(slurp) || exit 0 # Esc in slurp = cancel, silently fi dir="$HOME/Videos/Recordings" mkdir -p "$dir" file="$dir/$(date +%Y%m%d-%H%M%S).mp4" launch() { # launch -> 0 if it survived startup case "$1" in wl-screenrec) setsid wl-screenrec ''${geo:+-g "$geo"} \ ''${audio:+--audio} -f "$file" >/dev/null 2>&1 & ;; wf-recorder) setsid wf-recorder ''${geo:+-g "$geo"} \ ''${audio:+-a} -f "$file" >/dev/null 2>&1 & ;; esac echo $! > "$pidfile" sleep 0.7 alive } started="" if command -v wl-screenrec >/dev/null 2>&1 && launch wl-screenrec; then started=wl-screenrec elif command -v wf-recorder >/dev/null 2>&1 && launch wf-recorder; then started=wf-recorder # software fallback (no VAAPI device) fi if [ -z "$started" ]; then rm -f "$pidfile" notify-send "Screen recording" "Recorder failed to start (no wl-screenrec/wf-recorder able to run)." exit 1 fi printf '%s' "$file" > "$filefile" poke_bar notify-send "Screen recording" "Recording ($started)''${audio:+ with audio} — click the ⏺ in the bar to stop." ;; stop) if ! alive; then rm -f "$pidfile" "$filefile"; poke_bar notify-send "Screen recording" "No recording is running." exit 0 fi pid=$(cat "$pidfile") kill -INT "$pid" 2>/dev/null # graceful: both recorders finalize on INT for _ in $(seq 1 50); do kill -0 "$pid" 2>/dev/null || break; sleep 0.1; done kill -0 "$pid" 2>/dev/null && kill "$pid" 2>/dev/null file=$(cat "$filefile" 2>/dev/null || echo "?") rm -f "$pidfile" "$filefile" poke_bar notify-send "Screen recording saved" "$file" ;; active) alive ;; status) # Waybar JSON while recording; nothing => module hidden. if alive; then file=$(cat "$filefile" 2>/dev/null || echo "") printf '{"text":"⏺ REC","class":"recording","tooltip":"Recording to %s — click to stop"}\n' "''${file##*/}" fi exit 0 ;; *) echo "usage: nomarchy-record start [region|screen] [audio] | stop | active | status" >&2 exit 2 ;; esac '') ]; }