#!/usr/bin/env bash # One stable command boundary for launcher actions. Vicinae scripts stay tiny, # while the actual mapping to Quickshell IPC remains testable in one place. set -euo pipefail script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" action="${1:-}" helper_dir="${PANAMA_ACTION_HELPER_DIR:-$script_dir}" confirm_attempts="${PANAMA_ACTION_CONFIRM_ATTEMPTS:-20}" confirm_delay="${PANAMA_ACTION_CONFIRM_DELAY:-0.1}" kill_command="${PANAMA_ACTION_KILL_COMMAND:-/usr/bin/kill}" osd_command=("$helper_dir/panama-osd") gallery_command=("$helper_dir/panama-prism-gallery") report_failure() { local status=$? trap - EXIT if (( status != 0 )) && command -v notify-send >/dev/null 2>&1; then notify-send -a Panama -i dialog-error-symbolic \ "Panama action failed" \ "The “${action//-/ }” action could not be completed." || true fi exit "$status" } trap report_failure EXIT show_state() { local state="$1" on_icon="$2" off_icon="$3" label="$4" case "$state" in true) PANAMA_OSD_STRICT=1 "${osd_command[@]}" message "$on_icon" "$label On" ;; false) PANAMA_OSD_STRICT=1 "${osd_command[@]}" message "$off_icon" "$label Off" ;; *) printf 'Panama action returned an invalid state: %s\n' "$state" >&2 return 1 ;; esac } state_is_active() { local target="$1" case "$target" in caffeine) systemd-inhibit --list --no-pager --no-legend 2>/dev/null \ | awk '$1 == "Panama" && $(NF - 1) == "Caffeine" && $NF == "block" { found = 1 } END { exit !found }' ;; night-light) pgrep -u "$(id -u)" -x hyprsunset >/dev/null 2>&1 ;; *) return 2 ;; esac } release_caffeine_inhibitors() { local inhibitors pid uid uid="$(id -u)" inhibitors="$(systemd-inhibit --list --no-pager --no-legend 2>/dev/null \ | awk -v uid="$uid" '$1 == "Panama" && $2 == uid && $(NF - 1) == "Caffeine" && $NF == "block" { print $4 }')" while IFS= read -r pid; do [[ $pid =~ ^[0-9]+$ ]] || continue "$kill_command" "$pid" 2>/dev/null || true done <<<"$inhibitors" } wait_for_confirmed_state() { local target="$1" expected="$2" attempt for ((attempt = 0; attempt < confirm_attempts; attempt++)); do if [[ $expected == true ]] && state_is_active "$target"; then return 0 fi if [[ $expected == false ]] && ! state_is_active "$target"; then return 0 fi sleep "$confirm_delay" done printf 'Panama action could not confirm %s reached state %s\n' "$target" "$expected" >&2 return 1 } toggle_state() { local target="$1" on_icon="$2" off_icon="$3" label="$4" state state="$(qs ipc call "$target" toggle)" case "$state" in true|false) ;; *) show_state "$state" "$on_icon" "$off_icon" "$label"; return ;; esac if [[ $target == caffeine && $state == false ]]; then release_caffeine_inhibitors fi wait_for_confirmed_state "$target" "$state" show_state "$state" "$on_icon" "$off_icon" "$label" } wait_for_shell() { local attempt for ((attempt = 0; attempt < confirm_attempts; attempt++)); do if qs ipc show >/dev/null 2>&1; then return 0 fi sleep "$confirm_delay" done printf 'Panama shell did not become ready after restart\n' >&2 return 1 } case "$action" in control-center) qs ipc call quicksettings open ;; notifications) qs ipc call notifications open ;; calendar) qs ipc call calendar-agenda open ;; clipboard) qs ipc call clipboard open ;; overview) qs ipc call overview open ;; settings) qs ipc call settings open ;; health) qs ipc call health open ;; dnd) state="$(qs ipc call notifications dnd)" show_state "$state" notifications-disabled-symbolic notifications-symbolic "Do Not Disturb" ;; caffeine) toggle_state caffeine weather-clear-symbolic weather-clear-night-symbolic Caffeine ;; night-light) toggle_state night-light night-light-symbolic night-light-disabled-symbolic "Night Light" ;; focus-start) state="$(qs ipc call focus start)" [[ $state == true ]] PANAMA_OSD_STRICT=1 "${osd_command[@]}" message preferences-system-time-symbolic "Focus Session Started" ;; focus-end) state="$(qs ipc call focus end)" if [[ $state == true ]]; then PANAMA_OSD_STRICT=1 "${osd_command[@]}" message media-playback-stop-symbolic "Focus Session Ended" else PANAMA_OSD_STRICT=1 "${osd_command[@]}" message dialog-information-symbolic "No Focus Session Running" fi ;; capture) qs ipc call capture open ;; intelligence) qs ipc call screen-intelligence open ;; screenshot) qs ipc call capture screenNow ;; microphone) PANAMA_OSD_STRICT=1 "${osd_command[@]}" microphone toggle ;; gallery) "${gallery_command[@]}" ;; restart-shell) qs kill >/dev/null 2>&1 || true quickshell --daemonize wait_for_shell PANAMA_OSD_STRICT=1 "${osd_command[@]}" message view-refresh-symbolic "Panama Restarted" ;; *) printf 'Usage: panama-action {%s}\n' \ 'control-center|notifications|calendar|clipboard|overview|settings|health|dnd|caffeine|night-light|focus-start|focus-end|capture|intelligence|screenshot|microphone|gallery|restart-shell' >&2 exit 2 ;; esac