#!/usr/bin/env bash # scripts/panama-idle generates hypridle's configuration from Panama's settings. # # This is the one generator that can cost the user their automatic screen lock, # so the properties that matter are: zero means never (rather than "immediately", # which a naive template would produce), values are clamped even when the # settings file has been hand-edited, and a missing or corrupt file still yields # a working configuration rather than an empty one. set -euo pipefail repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" helper="$repo_dir/config/dot/quickshell/scripts/panama-idle" work="$(mktemp -d /tmp/panama-idle-contract.XXXXXX)" fail() { printf 'idle config contract: %s\n' "$1" >&2 exit 1 } cleanup() { rm -rf "$work"; } trap cleanup EXIT generated="$work/state/panama/hypridle.conf" run_with() { # Isolated config AND state, so this never touches the real generated file # and never restarts the user's hypridle: `apply` only restarts when the # systemd drop-in exists, and it cannot exist under this temporary root. mkdir -p "$work/config/panama" printf '%s' "$1" >"$work/config/panama/settings.json" XDG_CONFIG_HOME="$work/config" XDG_STATE_HOME="$work/state" "$helper" apply } # ── Shipped defaults ───────────────────────────────────────────────────────── run_with '{}' grep -q 'timeout = 300' "$generated" || fail 'default screen blank is not 5 minutes' grep -q 'timeout = 600' "$generated" || fail 'default lock is not 10 minutes' grep -q 'before_sleep_cmd' "$generated" || fail 'lock before sleep missing by default' grep -q 'systemctl suspend' "$generated" && fail 'automatic suspend is on by default' # ── Zero means never, not immediately ──────────────────────────────────────── run_with '{"screenBlankMinutes":0,"lockMinutes":0,"suspendMinutes":0}' grep -q 'timeout = 0' "$generated" && fail 'a zero timeout was written as an immediate trigger' # `dpms` also appears in general.after_sleep_cmd, which is correct and must # stay; what must not exist is any listener at all. grep -qE '^listener' "$generated" && fail 'a listener was written when everything is set to never' grep -q 'after_sleep_cmd' "$generated" || fail 'the general block was lost when all timers are off' # ── Values are honoured ────────────────────────────────────────────────────── run_with '{"screenBlankMinutes":2,"lockMinutes":7,"suspendMinutes":45}' grep -q 'timeout = 120' "$generated" || fail '2 minute blank not honoured' grep -q 'timeout = 420' "$generated" || fail '7 minute lock not honoured' grep -q 'timeout = 2700' "$generated" || fail '45 minute suspend not honoured' grep -q 'systemctl suspend' "$generated" || fail 'suspend listener missing when set' # ── lockOnSleep off removes the pre-sleep lock ─────────────────────────────── run_with '{"lockOnSleep":false}' grep -q 'before_sleep_cmd' "$generated" && fail 'pre-sleep lock present when disabled' # ── Hand-edited nonsense is clamped, not passed through ────────────────────── run_with '{"screenBlankMinutes":99999,"lockMinutes":-40,"suspendMinutes":"soon"}' grep -q 'timeout = 7200' "$generated" || fail 'an above-range blank was not clamped to the maximum' grep -q 'timeout = 0' "$generated" && fail 'a negative lock produced an immediate trigger' grep -q 'systemctl suspend' "$generated" && fail 'a non-numeric suspend produced a listener' # ── A corrupt or absent settings file still yields a working config ────────── run_with '{ not json at all' grep -q 'timeout = 300' "$generated" || fail 'a corrupt settings file did not fall back to defaults' rm -f "$work/config/panama/settings.json" XDG_CONFIG_HOME="$work/config" XDG_STATE_HOME="$work/state" "$helper" apply grep -q 'timeout = 300' "$generated" || fail 'an absent settings file did not fall back to defaults' # ── status reports what it generated ───────────────────────────────────────── status="$(XDG_CONFIG_HOME="$work/config" XDG_STATE_HOME="$work/state" "$helper" status)" jq -e '.managed == false and .blankMinutes == 5 and .lockMinutes == 10' <<<"$status" >/dev/null \ || fail "status did not report the generated values: $status" trap - EXIT cleanup printf 'idle config contract: PASS\n'