#!/usr/bin/env bash DAY_HOUR=7 NIGHT_HOUR=20 DAY_WALL="$HOME/.config/hypr/paper/day.jpg" NIGHT_WALL="$HOME/.config/hypr/paper/night.jpg" STATE_FILE="/tmp/wallpaper-mode" # tracks: day / night / auto MONITORS=( $(hyprctl monitors -j | jq -r '.[].name') ) apply_day() { for mon in "${MONITORS[@]}"; do hyprctl hyprpaper wallpaper "$mon,$DAY_WALL" &>/dev/null done } apply_night() { for mon in "${MONITORS[@]}"; do hyprctl hyprpaper wallpaper "$mon,$NIGHT_WALL" &>/dev/null done } wait_for_hyprpaper() { local retries=20 local sock="$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.hyprpaper.sock" [[ -S "$sock" ]] || sock="/tmp/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.hyprpaper.sock" while ((retries-- > 0)); do [[ -S "$sock" ]] && return 0 sleep 0.3 done return 1 } get_state() { cat "$STATE_FILE" 2>/dev/null || echo "auto" } set_state() { echo "$1" > "$STATE_FILE" } # --- ARGUMENT HANDLING --- case "$1" in day) set_state "day" wait_for_hyprpaper || { echo "hyprpaper not ready"; exit 1; } apply_day exit 0 ;; night) set_state "night" wait_for_hyprpaper || { echo "hyprpaper not ready"; exit 1; } apply_night exit 0 ;; auto) set_state "auto" exit 0 ;; # Waybar left-click: cycle day -> night -> auto -> day next) cur=$(get_state) case "$cur" in day) "$0" night; exit 0 ;; night) "$0" auto; exit 0 ;; auto) "$0" day; exit 0 ;; esac ;; # Waybar polls this for the button label status) cur=$(get_state) case "$cur" in day) echo '{"text":"󰖙 day", "tooltip":"Wallpaper: day (click to → night)","class":"day"}' ;; night) echo '{"text":"󰖔 night","tooltip":"Wallpaper: night (click to → auto)","class":"night"}' ;; auto) echo '{"text":"󰃝 auto", "tooltip":"Wallpaper: auto (click to → day)","class":"auto"}' ;; esac exit 0 ;; "") # No arg — fall through to cycle loop ;; *) echo "Usage: $0 [day|night|auto|next|status]" exit 1 ;; esac # --- CYCLE LOOP --- current_mode="none" while true; do hour=$(date +%H | sed 's/^0*//') state=$(get_state) if [[ "$current_mode" == "none" ]]; then if wait_for_hyprpaper; then current_mode="waiting" fi sleep 1 continue fi # If pinned to day or night, just wait and recheck if [[ "$state" == "day" && "$current_mode" != "day" ]]; then apply_day; current_mode="day" elif [[ "$state" == "night" && "$current_mode" != "night" ]]; then apply_night; current_mode="night" elif [[ "$state" == "auto" ]]; then if (( hour >= DAY_HOUR && hour < NIGHT_HOUR )) && [[ "$current_mode" != "day" ]]; then apply_day; current_mode="day" elif (( hour < DAY_HOUR || hour >= NIGHT_HOUR )) && [[ "$current_mode" != "night" ]]; then apply_night; current_mode="night" fi fi sleep $(( 60 - $(date +%S) )) done