more convenient wallpaper select/fetch
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
#!/usr/bin/env bash
|
||||
# /home/krosh/Documents/Github/nixos-config/home-manager/modules/zsh/next_wallpaper.sh
|
||||
# Pick next or random wallpaper from ~/Pictures/Wallpapers and update symlink ~/Pictures/wallpaper.png
|
||||
# Then call: swww img "$WALLPAPER"
|
||||
|
||||
set -euo pipefail
|
||||
# Handle -f <file> anywhere in argv: remove it from "$@" so getopts can still parse -r.
|
||||
FORCE_FILE=""
|
||||
_remaining=()
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-f)
|
||||
if [ -z "${2-}" ]; then
|
||||
echo "Option -f requires an argument" >&2
|
||||
exit 2
|
||||
fi
|
||||
FORCE_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
_remaining+=("$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# restore remaining args for subsequent getopts
|
||||
if [ "${#_remaining[@]}" -gt 0 ]; then
|
||||
set -- "${_remaining[@]}"
|
||||
else
|
||||
set --
|
||||
fi
|
||||
|
||||
# If -f was given, validate and immediately update the symlink & wallpaper, then exit.
|
||||
if [ -n "$FORCE_FILE" ]; then
|
||||
if [ ! -f "$FORCE_FILE" ]; then
|
||||
echo "Specified wallpaper not found: $FORCE_FILE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET="$(readlink -f "$FORCE_FILE")"
|
||||
SYMLINK_PATH="$HOME/Pictures/wallpaper.png"
|
||||
|
||||
TMP_LINK="$(mktemp -u "${SYMLINK_PATH}.tmp.XXXX")"
|
||||
ln -sfn -- "$TARGET" "$TMP_LINK"
|
||||
mv -f "$TMP_LINK" "$SYMLINK_PATH"
|
||||
|
||||
# export and trigger compositor/wallpaper tools
|
||||
WALLPAPER="$TARGET"
|
||||
swww img "$WALLPAPER" --transition-type fade
|
||||
hyprpanel -q ; hyprpanel & disown
|
||||
wal -c
|
||||
wal -n -i "$WALLPAPER"
|
||||
|
||||
exit 0
|
||||
fi
|
||||
RANDOM_MODE=0
|
||||
while getopts "r" opt; do
|
||||
case "$opt" in
|
||||
r) RANDOM_MODE=1 ;;
|
||||
*) echo "Usage: $0 [-r]" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
WALLPAPERS_DIR="$HOME/Pictures/Wallpapers"
|
||||
SYMLINK="$HOME/Pictures/wallpaper.png"
|
||||
|
||||
if [ ! -d "$WALLPAPERS_DIR" ]; then
|
||||
echo "Wallpapers directory not found: $WALLPAPERS_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Resolve current wallpaper (target of symlink). If not a symlink or missing, CUR will be empty.
|
||||
CUR="$(readlink -f "$SYMLINK" 2>/dev/null || true)"
|
||||
|
||||
# Collect png files; sort by timestamp ascending (oldest first) using ls -tr.
|
||||
# If there are spaces in names, ls handles them, but filenames with newlines are unsupported.
|
||||
mapfile -t FILES < <(find "$WALLPAPERS_DIR" -maxdepth 1 -type f -iname '*.png' -print0 | xargs -0 ls -1tr 2>/dev/null || true)
|
||||
|
||||
if [ "${#FILES[@]}" -eq 0 ]; then
|
||||
echo "No png wallpapers found in $WALLPAPERS_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
choose_random() {
|
||||
# pick random file different from CUR if possible
|
||||
candidates=()
|
||||
for f in "${FILES[@]}"; do
|
||||
[ "$(readlink -f "$f")" = "$CUR" ] && continue
|
||||
candidates+=("$f")
|
||||
done
|
||||
if [ "${#candidates[@]}" -eq 0 ]; then
|
||||
# only current exists
|
||||
echo "No other wallpaper to choose (only current exists)." >&2
|
||||
exit 1
|
||||
fi
|
||||
idx=$((RANDOM % ${#candidates[@]}))
|
||||
echo "${candidates[$idx]}"
|
||||
}
|
||||
|
||||
choose_next() {
|
||||
# find current in sorted list and pick next (wrap). If current not found, choose first.
|
||||
n=${#FILES[@]}
|
||||
if [ "$n" -eq 1 ]; then
|
||||
# only one file
|
||||
if [ "$(readlink -f "${FILES[0]}")" = "$CUR" ]; then
|
||||
echo "No other wallpaper to choose (only current exists)." >&2
|
||||
exit 1
|
||||
else
|
||||
echo "${FILES[0]}"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
# find index of current
|
||||
idx=-1
|
||||
for i in "${!FILES[@]}"; do
|
||||
if [ "$(readlink -f "${FILES[i]}")" = "$CUR" ]; then
|
||||
idx="$i"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$idx" -eq -1 ]; then
|
||||
# current not in list: choose first
|
||||
echo "${FILES[0]}"
|
||||
return
|
||||
fi
|
||||
|
||||
# next index with wrap
|
||||
next=$(( (idx + 1) % n ))
|
||||
# if next equals current (possible if only one), error handled above
|
||||
echo "${FILES[$next]}"
|
||||
}
|
||||
|
||||
if [ "$RANDOM_MODE" -eq 1 ]; then
|
||||
NEW="$(choose_random)"
|
||||
else
|
||||
NEW="$(choose_next)"
|
||||
fi
|
||||
|
||||
# Ensure absolute path
|
||||
NEW="$(readlink -f "$NEW")"
|
||||
|
||||
# Create symlink (atomic-ish): create temporary symlink and move
|
||||
TMP_SYMLINK="$(mktemp -u "${SYMLINK}.tmp.XXXX")"
|
||||
ln -sfn -- "$NEW" "$TMP_SYMLINK"
|
||||
mv -f "$TMP_SYMLINK" "$SYMLINK"
|
||||
|
||||
# Export for hyprctl command (and run it)
|
||||
WALLPAPER="$NEW"
|
||||
|
||||
swww img "$WALLPAPER" --transition-type fade
|
||||
hyprpanel -q ; hyprpanel & disown
|
||||
wal -c
|
||||
wal -n -i "$WALLPAPER"
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user