diff options
| author | seraphim <18ycm9tx@anonaddy.me> | 2026-08-23 13:48:20 +0700 |
|---|---|---|
| committer | seraphim <18ycm9tx@anonaddy.me> | 2026-08-23 13:48:20 +0700 |
| commit | 9f12ea8a648fa6483b392dc9ba1d7dbf4e61057c (patch) | |
| tree | 35ec7c12203114c9e47cebbdb634c174094913c8 /niri/.config | |
| parent | b57f994aa7c74d1b4e17e3df31ddf94702a8f6de (diff) | |
-
Diffstat (limited to 'niri/.config')
| -rwxr-xr-x | niri/.config/niri/apply-colors.sh | 61 | ||||
| -rw-r--r-- | niri/.config/niri/config.kdl | 5 | ||||
| -rwxr-xr-x | niri/.config/niri/theme-switcher.sh | 125 |
3 files changed, 133 insertions, 58 deletions
diff --git a/niri/.config/niri/apply-colors.sh b/niri/.config/niri/apply-colors.sh index 339e134..505578c 100755 --- a/niri/.config/niri/apply-colors.sh +++ b/niri/.config/niri/apply-colors.sh @@ -22,46 +22,59 @@ if [ -z "$IMG" ] || [ ! -f "$IMG" ]; then exit 1 fi +# wait for the awww daemon to be ready (it is spawned next to this script at login) +log "awww img $IMG" +for _ in $(seq 1 10); do + if awww query >/dev/null 2>&1; then + break + fi + sleep 1 +done + +# set the wallpaper FIRST and unconditionally — this is the critical, must-work +# step. Color generation below is best-effort: a failure there must never block +# the wallpaper from changing (that coupling is what froze the wallpaper before). +awww img "$IMG" || { log "awww img FAILED ($IMG)"; exit 1; } + +# blurred copy for the Overview backdrop (sibling or on-the-fly generation) +"$SCRIPT_DIR/set-backdrop.sh" "$IMG" || log "set-backdrop FAILED ($IMG)" + # wallust: classic 16-color palette (foot, btop, ...) # fastresize (the config default) is flaky on some images — always use resized. -# A single attempt with honest error handling: the old retry loop swallowed -# failures (case && break defeats set -e) and kept the stale light theme. +# Best-effort: a wallust failure must not prevent the wallpaper from sticking. log "wallust palette=$MODE $IMG" case "$MODE" in light|dark) WALLUST_PALETTE=("--palette" "$MODE") ;; *) WALLUST_PALETTE=() ;; esac -if ! wallust run -b resized "${WALLUST_PALETTE[@]}" "$IMG"; then - log "wallust FAILED ($IMG, mode=$MODE)" - exit 1 +# wallust's `resized` backend is intermittently flaky on some images; retry a +# few times, but ultimately tolerate failure. +ok=0 +for attempt in 1 2 3; do + if wallust run -b resized "${WALLUST_PALETTE[@]}" "$IMG"; then + ok=1 + break + fi + log "wallust attempt $attempt FAILED ($IMG, mode=$MODE)" + [ "$attempt" -lt 3 ] && sleep 2 +done +if [ "$ok" -ne 1 ]; then + log "wallust FAILED after 3 attempts ($IMG, mode=$MODE) — continuing without wallust colors" +else + # foot needs bare RRGGBB, not #RRGGBB — strip the leading '#' + sed -i 's/#\([0-9a-fA-F]\)/\1/g' ~/.cache/wallust/foot-theme.ini 2>/dev/null || true fi -# foot needs bare RRGGBB, not #RRGGBB — strip the leading '#' -sed -i 's/#\([0-9a-fA-F]\)/\1/g' ~/.cache/wallust/foot-theme.ini 2>/dev/null || true - # matugen: Material You / M3 colors (niri focus ring, ...) # --prefer is required for non-interactive runs (multiple source colors). +# Best-effort: a matugen failure (e.g. bad config after an upgrade) must not +# block the wallpaper. log "matugen mode=$MODE $IMG" case "$MODE" in light) matugen image "$IMG" -m "light" --prefer saturation ;; dark) matugen image "$IMG" -m "dark" --prefer saturation ;; *) matugen image "$IMG" --prefer saturation ;; -esac - -# wait for the awww daemon to be ready (it is spawned next to this script at login) -log "awww img $IMG" -for _ in $(seq 1 10); do - if awww query >/dev/null 2>&1; then - break - fi - sleep 1 -done - -# set the wallpaper -awww img "$IMG" - -# blurred copy for the Overview backdrop (sibling or on-the-fly generation) -"$SCRIPT_DIR/set-backdrop.sh" "$IMG" +esac || log "matugen FAILED ($IMG, mode=$MODE) — continuing without matugen colors" # reload consumers killall -SIGUSR2 waybar 2>/dev/null || true diff --git a/niri/.config/niri/config.kdl b/niri/.config/niri/config.kdl index 05b2240..24b0896 100644 --- a/niri/.config/niri/config.kdl +++ b/niri/.config/niri/config.kdl @@ -1,4 +1,3 @@ -// Material You / Material Design 3 colors, generated by matugen (see theme-switcher.sh / apply-colors.sh) include optional=true "/home/seraphim/.cache/matugen/theme.kdl" spawn-at-startup "mako" spawn-at-startup "xrdb" "-merge" "/home/seraphim/.Xresources" @@ -11,7 +10,7 @@ spawn-at-startup "awww-daemon" "--namespace" "backdrop" spawn-at-startup "/usr/libexec/hyprpolkitagent" spawn-at-startup "dbus-update-activation-environment" "WAYLAND_DISPLAY" "DISPLAY" "XDG_CURRENT_DESKTOP" spawn-at-startup "darkman" "run" -spawn-at-startup "/home/seraphim/dotfiles-gentoo/niri/.config/niri/theme-switcher.sh" +spawn-at-startup "/home/seraphim/dotfiles-gentoo/niri/.config/niri/theme-switcher.sh" "--daemon" spawn-at-startup "sh" "-c" "NO_AT_BRIDGE=1 waybar" spawn-at-startup "/usr/bin/Throne" spawn-at-startup "mpd" @@ -37,7 +36,7 @@ layer-rule { place-within-backdrop true } input { -// focus-follows-mouse max-scroll-amount="30%" + focus-follows-mouse max-scroll-amount="100%" keyboard { xkb { diff --git a/niri/.config/niri/theme-switcher.sh b/niri/.config/niri/theme-switcher.sh index 6b3b6e9..6d1f548 100755 --- a/niri/.config/niri/theme-switcher.sh +++ b/niri/.config/niri/theme-switcher.sh @@ -1,12 +1,19 @@ #!/bin/bash +# Day/night theme switcher + wallpaper/color applier. # Two wallpapers: day.jpg (9:00-18:00) and night.jpg (18:00-9:00). -# To switch, just rename the files in ~/Pictures/wallpapers/. +# +# 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" @@ -15,58 +22,114 @@ log() { printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >>"$LOG" } -while true; do - HOUR=$(date +%H) - HOUR=$((10#$HOUR)) - - if [ "$HOUR" -ge 9 ] && [ "$HOUR" -lt 18 ]; then +# 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" - else + 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 - sleep 60 - continue + 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 + # 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 - if [ "$CURRENT_WALLPAPER" != "$WALLPAPER" ] || [ "$CURRENT_THEME" != "$TARGET_STATE" ]; then - 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 + 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 \ + "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" + 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)" - else - # State is intentionally NOT written so the next loop iteration retries. - log "FAILED to apply $TARGET_STATE ($WALLPAPER), will retry" - fi + 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 +} - 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 |
