#!/usr/bin/env bash # --------------------------------------------------------------------------- # Apply a wallpaper with feh and remember the choice. # # set-wallpaper # restore the remembered wallpaper # set-wallpaper /path/img.png # set a specific image # set-wallpaper --random # pick a random one from the wallpaper dir # set-wallpaper --cache # (re)build the betterlockscreen cache # # The current selection is stored in $XDG_STATE_HOME/current-wallpaper. # --------------------------------------------------------------------------- set -uo pipefail WALLPAPER_DIR="${WALLPAPER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/wallpapers}" STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}" STATE_FILE="$STATE_DIR/current-wallpaper" MODE="${FEH_MODE:---bg-fill}" mkdir -p "$STATE_DIR" "$WALLPAPER_DIR" pick_random() { find -L "$WALLPAPER_DIR" -type f \ \( -iname '*.png' -o -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.webp' \) \ | shuf -n1 } first_available() { find -L "$WALLPAPER_DIR" -type f \ \( -iname '*.png' -o -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.webp' \) \ | sort | head -n1 } cache_lockscreen=0 target="" case "${1:-}" in --random) target="$(pick_random)" ;; --cache) cache_lockscreen=1 ;; "") target="$(cat "$STATE_FILE" 2>/dev/null || true)" ;; -*) echo "unknown option: $1" >&2; exit 2 ;; *) target="$1"; cache_lockscreen=1 ;; esac # Fall back through: remembered -> anything in the dir -> a flat Macchiato base if [[ -z "$target" || ! -f "$target" ]]; then target="$(first_available)" fi if [[ -z "$target" || ! -f "$target" ]]; then echo "set-wallpaper: no image found in $WALLPAPER_DIR — using a flat colour" >&2 command -v xsetroot >/dev/null && xsetroot -solid "#24273a" exit 0 fi command -v feh >/dev/null || { echo "set-wallpaper: feh is not installed" >&2; exit 1; } feh --no-fehbg "$MODE" "$target" printf '%s\n' "$target" > "$STATE_FILE" # Keep the lock screen in sync with the desktop. Caching is slow (imagemagick # blurs the image at every resolution), so only do it when the image changed. if [[ "$cache_lockscreen" == "1" ]] && command -v betterlockscreen >/dev/null; then ( betterlockscreen --update "$target" --blur 0.5 >/dev/null 2>&1 & disown ) 2>/dev/null || true fi