#!/usr/bin/env bash set -euo pipefail fail() { printf 'settings pages contract: %s\n' "$1" >&2 exit 1 } cleanup() { qs ipc call settings close >/dev/null 2>&1 || true } trap cleanup EXIT # Start from a clean slate. Closing the Settings window is asynchronous: the # shell reports it closed as soon as it drops its own state, while the toplevel # survives until the compositor destroys it. Without this wait, running straight # after settings-window-contract sees the outgoing window and reads it as a # duplicate. qs ipc call settings close >/dev/null 2>&1 || true for _ in $(seq 1 40); do hyprctl -j clients | jq -e '[.[] | select(.title == "Panama Settings")] | length == 0' >/dev/null && break sleep 0.1 done hyprctl -j clients | jq -e '[.[] | select(.title == "Panama Settings")] | length == 0' >/dev/null \ || fail 'a Settings window was still open when the contract started' pages=(home appearance displays connectivity desktop sound notifications screen-intelligence shortcuts services about) for page in "${pages[@]}"; do qs ipc call settings page "$page" >/dev/null for _ in $(seq 1 20); do [[ "$(qs ipc call settings status | jq -r .page)" == "$page" ]] && break sleep 0.1 done [[ "$(qs ipc call settings status | jq -r .page)" == "$page" ]] || fail "$page did not route" hyprctl -j clients | jq -e '[.[] | select(.title == "Panama Settings")] | length == 1' >/dev/null \ || fail "$page created a missing or duplicate Settings window" done qs ipc call settings page '__unsupported__' >/dev/null [[ "$(qs ipc call settings status | jq -r .page)" == "home" ]] || fail 'unsupported page did not fall back to Home' hyprctl -j binds | jq -e '.[] | select(.description == "Panama Settings" and .key == "I" and .modmask == 64)' >/dev/null \ || fail 'Super+I is not registered as Panama Settings' hyprctl -j binds | jq -e '.[] | select(.description == "Screen Intelligence" and .key == "S" and .modmask == 65)' >/dev/null \ || fail 'Super+Shift+S is not registered as Screen Intelligence' desktop_file="$HOME/.local/share/applications/panama-settings.desktop" [[ -L "$desktop_file" || -f "$desktop_file" ]] || fail 'searchable desktop entry is not installed' desktop-file-validate "$desktop_file" >/dev/null || fail 'desktop entry is invalid' gnome_desktop_file="$HOME/.local/share/applications/gnome-settings-hyprland.desktop" [[ -L "$gnome_desktop_file" || -f "$gnome_desktop_file" ]] || fail 'searchable GNOME Settings fallback is not installed' desktop-file-validate "$gnome_desktop_file" >/dev/null || fail 'GNOME Settings fallback entry is invalid' intelligence_desktop_file="$HOME/.local/share/applications/panama-screen-intelligence.desktop" [[ -L "$intelligence_desktop_file" || -f "$intelligence_desktop_file" ]] || fail 'Screen Intelligence desktop entry is not installed' desktop-file-validate "$intelligence_desktop_file" >/dev/null || fail 'Screen Intelligence desktop entry is invalid' trap - EXIT cleanup printf 'settings pages contract: PASS\n'