summaryrefslogtreecommitdiff
path: root/.config/niri/theme-switcher.sh
diff options
context:
space:
mode:
authorseraphim <18ycm9tx@anonaddy.me>2026-08-23 18:07:29 +0700
committerseraphim <18ycm9tx@anonaddy.me>2026-08-23 18:07:29 +0700
commited3e8f6ec6929327ab19e512ffb0d8ece12ed5a8 (patch)
treef1a783af87d29b8d78ce20df5a485f92b8c32d5d /.config/niri/theme-switcher.sh
parent3c71645d355910b6998e97a1efca6f5a7c7608bc (diff)
reorganize directories, so everything in .config
Diffstat (limited to '.config/niri/theme-switcher.sh')
-rwxr-xr-x.config/niri/theme-switcher.sh135
1 files changed, 135 insertions, 0 deletions
diff --git a/.config/niri/theme-switcher.sh b/.config/niri/theme-switcher.sh
new file mode 100755
index 0000000..6d1f548
--- /dev/null
+++ b/.config/niri/theme-switcher.sh
@@ -0,0 +1,135 @@
+#!/bin/bash
+
+# Day/night theme switcher + wallpaper/color applier.
+# Two wallpapers: day.jpg (9:00-18:00) and night.jpg (18:00-9:00).
+#
+# Usage:
+# ./theme-switcher.sh one-shot: apply based on current time, then exit
+# ./theme-switcher.sh day|light force light theme, then exit
+# ./theme-switcher.sh night|dark force dark theme, then exit
+# ./theme-switcher.sh --daemon continuous time-based loop (used at login)
+
+WALLPAPERS="$HOME/Pictures/wallpapers"
+STATE_FILE="/tmp/current_theme_state"
+WALLPAPER_STATE_FILE="/tmp/current_wallpaper_state"
+BACKDROP_STATE_FILE="/tmp/current_backdrop_state"
+PID_FILE="/tmp/theme-switcher.daemon.pid"
+LOG="/tmp/theme-switcher.log"
+SCRIPT_DIR="$(cd "$(dirname "$(realpath "$0")")" && pwd)"
+SET_BACKDROP="$SCRIPT_DIR/set-backdrop.sh"
+
+log() {
+ printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >>"$LOG"
+}
+
+# Resolve TARGET_STATE / MODE / WALLPAPER. Optional $1 forces day|night.
+resolve_target() {
+ local force="${1:-}"
+ if [ "$force" = "day" ] || [ "$force" = "light" ]; then
+ TARGET_STATE="light"
+ MODE="light"
+ WALLPAPER="$WALLPAPERS/day.jpg"
+ elif [ "$force" = "night" ] || [ "$force" = "dark" ]; then
+ TARGET_STATE="dark"
+ MODE="dark"
+ WALLPAPER="$WALLPAPERS/night.jpg"
+ else
+ local HOUR
+ HOUR=$(date +%H)
+ HOUR=$((10#$HOUR))
+ if [ "$HOUR" -ge 9 ] && [ "$HOUR" -lt 18 ]; then
+ TARGET_STATE="light"
+ MODE="light"
+ WALLPAPER="$WALLPAPERS/day.jpg"
+ else
+ TARGET_STATE="dark"
+ MODE="dark"
+ WALLPAPER="$WALLPAPERS/night.jpg"
+ fi
+ fi
+}
+
+# Apply the resolved target once. Returns 0 on success.
+apply_target() {
+ if [ ! -f "$WALLPAPER" ]; then
+ log "wallpaper missing: $WALLPAPER"
+ return 1
+ fi
+
+ local CURRENT_THEME CURRENT_WALLPAPER EXPECTED_BACKDROP ACTUAL_BACKDROP
+
+ CURRENT_THEME=$(cat "$STATE_FILE" 2>/dev/null || true)
+ # Already in the correct theme: don't re-run wallust/matugen every loop tick.
+ # Still self-heal a drifted backdrop below, then bail out.
+ if [ "$CURRENT_THEME" = "$TARGET_STATE" ]; then
+ EXPECTED_BACKDROP=$(cat "$BACKDROP_STATE_FILE" 2>/dev/null || true)
+ ACTUAL_BACKDROP=$(awww query -n backdrop -j 2>/dev/null | jq -r '.["backdrop"][0].displaying.image // empty')
+ if [ -n "$EXPECTED_BACKDROP" ] && [ "$ACTUAL_BACKDROP" != "$EXPECTED_BACKDROP" ]; then
+ "$SET_BACKDROP" "$WALLPAPER"
+ fi
+ return 0
+ fi
+ CURRENT_WALLPAPER=$(cat "$WALLPAPER_STATE_FILE" 2>/dev/null || true)
+
+ # Self-heal the Overview backdrop if it drifted from the expected image.
+ EXPECTED_BACKDROP=$(cat "$BACKDROP_STATE_FILE" 2>/dev/null || true)
+ ACTUAL_BACKDROP=$(awww query -n backdrop -j 2>/dev/null | jq -r '.["backdrop"][0].displaying.image // empty')
+ if [ -n "$EXPECTED_BACKDROP" ] && [ "$ACTUAL_BACKDROP" != "$EXPECTED_BACKDROP" ]; then
+ "$SET_BACKDROP" "$WALLPAPER"
+ fi
+
+ log "switching to $TARGET_STATE ($WALLPAPER)"
+ if sh "$SCRIPT_DIR/apply-colors.sh" "$WALLPAPER" "$MODE"; then
+ if [ "$CURRENT_THEME" != "$TARGET_STATE" ]; then
+ darkman set "$TARGET_STATE"
+ fi
+
+ ln -sf \
+ "theme-${TARGET_STATE}.css" \
+ "$HOME/dotfiles-gentoo/waybar/.config/waybar/theme.css"
+
+ ln -sf \
+ "settings-${TARGET_STATE}.ini" \
+ "$HOME/dotfiles-gentoo/gtk/.config/gtk-3.0/settings.ini"
+
+ echo "$TARGET_STATE" >"$STATE_FILE"
+ echo "$WALLPAPER" >"$WALLPAPER_STATE_FILE"
+ log "switched to $TARGET_STATE ($WALLPAPER)"
+ return 0
+ else
+ log "FAILED to apply $TARGET_STATE ($WALLPAPER)"
+ return 1
+ fi
+}
+
+daemon_loop() {
+ # Refuse to run a second daemon instance (e.g. manual run while one is alive).
+ if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE" 2>/dev/null)" 2>/dev/null; then
+ log "daemon already running (pid $(cat "$PID_FILE")), exiting"
+ exit 0
+ fi
+ echo $$ >"$PID_FILE"
+
+ while true; do
+ resolve_target
+ apply_target || true # failure is retried on the next loop, state is left untouched
+ sleep 60
+ done
+}
+
+case "${1:-}" in
+--daemon | -d) daemon_loop ;;
+"" | day | light | night | dark)
+ resolve_target "${1:-}"
+ apply_target
+ exit $?
+ ;;
+-h | --help)
+ echo "usage: $0 [day|night|--daemon]" >&2
+ exit 0
+ ;;
+*)
+ echo "usage: $0 [day|night|--daemon]" >&2
+ exit 1
+ ;;
+esac