#!/usr/bin/env bash # Sunshine global_prep_cmd `undo` hook for the Sway-based headless path. # Cheaper than the Hyprland undo: there's no workspace shuffling to reverse on # a true headless box. We just keep the headless output alive for the next # connect (creating one is ~free, removing it forces sway to renegotiate # focused output every cycle). set -uo pipefail HEADLESS_NAME="${OMARCHY_VIRTUAL_OUTPUT:-HEADLESS-1}" STATE_DIR="${XDG_RUNTIME_DIR:-/tmp}/sunshine-headless" HOOK_LOG="$STATE_DIR/hook.log" log() { local msg msg="$(date +%H:%M:%S.%3N) [sunshine-undo-sway] $*" printf '%s\n' "$msg" >&2 printf '%s\n' "$msg" >> "$HOOK_LOG" 2>/dev/null || true } log "undo-hook start" if ! command -v swaymsg >/dev/null 2>&1; then log "swaymsg not found; nothing to undo." exit 0 fi if [[ -z "${SWAYSOCK:-}" ]]; then for sock in "${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"/sway-ipc.*.sock; do [[ -S "$sock" ]] || continue export SWAYSOCK="$sock" break done if [[ -z "${SWAYSOCK:-}" ]]; then log "sway not running; nothing to undo." exit 0 fi fi # Remember the headless name across the connect cycle if we adopted a # different output name in the do-hook. if [[ -f "$STATE_DIR/headless-name" ]]; then HEADLESS_NAME="$(cat "$STATE_DIR/headless-name" 2>/dev/null || echo "$HEADLESS_NAME")" fi # On a server with no real outputs, removing HEADLESS-1 leaves sway with zero # outputs and any future create_output starts numbering at -2, -3, etc. # Cheaper to keep it alive. log "Keeping $HEADLESS_NAME alive for the next stream" rm -f "$STATE_DIR/prev-outputs.json" "$STATE_DIR/headless-name" log "Stream teardown complete"