diff options
Diffstat (limited to '.config/niri/apply-colors.sh')
| -rwxr-xr-x | .config/niri/apply-colors.sh | 134 |
1 files changed, 60 insertions, 74 deletions
diff --git a/.config/niri/apply-colors.sh b/.config/niri/apply-colors.sh index aebf509..3d3b433 100755 --- a/.config/niri/apply-colors.sh +++ b/.config/niri/apply-colors.sh @@ -1,85 +1,71 @@ -#!/bin/bash -# Apply a wallpaper and generate colors with wallust (16-color palette) + matugen (Material You / M3). -# Usage: apply-colors.sh <image> [light|dark] -# Called by theme-switcher.sh and the waybar random-wallpaper click. +#!/bin/sh +# Regenerate wallust colors from the current wallpaper and reload running apps. +# Also keeps the niri backdrop in sync with the wallpaper. +# +# This is the single startup entry point: it derives the last used wallpaper +# from awww's own cache (so "main = last used wallpaper"), reads the saved +# palette/threshold from the runtime state file, runs `wallust run` (which +# regenerates EVERY template -> adding a new app only needs a wallust.toml +# template, never a new autostart line), and reloads live apps. -set -euo pipefail +CACHE="${XDG_CACHE_HOME:-$HOME/.cache}" +STATE="$CACHE/wallust_runtime" +WP_DIR="$HOME/Pictures/wallpapers" -SCRIPT_DIR="$(cd "$(dirname "$(realpath "$0")")" && pwd)" -IMG="${1:-}" -MODE="${2:-auto}" -LOG="${THEME_LOG:-/tmp/theme-switcher.log}" - -log() { - printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >>"$LOG" +# Determine the current wallpaper. +# Primary: the marker file written by theme-switcher.sh (last used wallpaper). +# Fallback: parse awww's cache (the last image set via `awww img`), excluding +# the blurred backdrop layer. awww stores the cache as one concatenated line, +# so we grep for the first absolute image path that is not a backdrop blur. +get_wp() { + marker="$CACHE/current_wallpaper" + if [ -f "$marker" ]; then + wp="$(cat "$marker" 2>/dev/null)" + [ -n "$wp" ] && [ -f "$wp" ] && { echo "$wp"; return 0; } + fi + for f in "$CACHE"/awww/*/*; do + [ -f "$f" ] || continue + # awww stores the cache as one concatenated line; the main-namespace + # image is everything before the first "backdrop" delimiter. Cut there + # so the greedy path match can't swallow the (blurred) backdrop path. + wp=$(sed 's/backdrop.*//' "$f" \ + | tr '\0' '\n' \ + | grep -oE '/[^[:space:]]+\.(png|jpg|jpeg|webp|gif)' \ + | head -1) + [ -n "$wp" ] && [ -f "$wp" ] && { echo "$wp"; return 0; } + done + return 1 } -# Record the exact failing command + line on any error. -trap 'log "apply-colors FAILED (exit $?) in ${BASH_SOURCE[0]}:$LINENO: $BASH_COMMAND"' ERR - -if [ -z "$IMG" ] || [ ! -f "$IMG" ]; then - echo "usage: $0 <image> [light|dark]" >&2 - exit 1 +# Read saved palette/threshold/saturation/colorspace from the runtime state. +palette=""; threshold=""; sat=""; cs="" +if [ -f "$STATE" ]; then + while IFS='=' read -r k v; do + case "$k" in + palette) palette="$v" ;; + threshold) threshold="$v" ;; + saturation) sat="$v" ;; + colorspace) cs="$v" ;; + esac + done < "$STATE" 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; } +WP="$(get_wp)" || WP="$(ls -1 "$WP_DIR"/*.* 2>/dev/null | head -1)" || true -# 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. -# 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 -# 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 +if [ -n "$WP" ] && [ -f "$WP" ]; then + args="" + [ -n "$palette" ] && args="$args -p $palette" + [ -n "$threshold" ] && args="$args -t $threshold" + [ -n "$sat" ] && args="$args --saturation $sat" + [ -n "$cs" ] && args="$args -c $cs" + # shellcheck disable=SC2086 + wallust run $args "$WP" || true + "$HOME/.config/niri/set-backdrop.sh" "$WP" || true fi -# 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 || log "matugen FAILED ($IMG, mode=$MODE) — continuing without matugen colors" - -# reload consumers -killall -SIGUSR2 waybar 2>/dev/null || true -killall -USR1 foot 2>/dev/null || true -niri msg action load-config-file 2>/dev/null || true +# Reload apps that support live reload. makoctl reload 2>/dev/null || true -log "apply-colors OK ($IMG, $MODE)" +# Refresh niri's own theme (focus ring, etc.) from the freshly generated +# wallust niri template. Optional because niri may still be starting up. +niri msg action reload-config 2>/dev/null || true |
