Dotfiles/desktopenvs/niri/scripts/wallpaper-picker

89 lines
2.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# Wallpaper picker for niri using swaybg.
# Usage: wallpaper-picker [directory]
set -u
DIR="${1:-$HOME/Pictures}"
STATE_FILE="${HOME}/.config/niri-wallpaper"
IMAGES=()
while IFS= read -r -d '' f; do
IMAGES+=("$f")
done < <(find "$DIR" -maxdepth 1 -type f \
\( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' \
-o -iname '*.webp' -o -iname '*.bmp' -o -iname '*.avif' \) \
-print0 | sort -z)
[[ ${#IMAGES[@]} -eq 0 ]] && { echo "No images found in $DIR"; exit 1; }
INDEX=0
icat() { kitty +kitten icat --stdin=no --silent --transfer-mode=memory "$@" 2>/dev/null; }
clear_images() { icat --clear; }
draw() {
local cols rows
cols=$(tput cols); rows=$(tput lines)
local n=${#IMAGES[@]}
local prev=$(( (INDEX - 1 + n) % n ))
local next=$(( (INDEX + 1) % n ))
local header_h=2
local footer_h=4
local img_h=$(( rows - header_h - footer_h ))
(( img_h < 5 )) && img_h=5
local side_w=$(( cols * 18 / 100 ))
local center_w=$(( cols - 2 * (side_w + 2) ))
local center_x=$(( side_w + 2 ))
local next_x=$(( center_x + center_w + 2 ))
printf '\033[2J\033[H'
clear_images
tput cup 0 0
printf ' Wallpaper Picker (niri/swaybg) [%d/%d] %s' \
$(( INDEX + 1 )) "$n" "$(basename "${IMAGES[$INDEX]}")"
icat --place "${side_w}x${img_h}@0x${header_h}" "${IMAGES[$prev]}"
icat --place "${center_w}x${img_h}@${center_x}x${header_h}" "${IMAGES[$INDEX]}"
icat --place "${side_w}x${img_h}@${next_x}x${header_h}" "${IMAGES[$next]}"
local row=$(( header_h + img_h ))
tput cup "$row" 0
printf ' h/←: prev l/→: next Enter/Space: apply q: quit\n'
}
apply() {
local path="$1"
killall swaybg 2>/dev/null || true
swaybg -m fill -i "$path" &
printf '%s\n' "$path" > "$STATE_FILE"
tput cup $(( $(tput lines) - 1 )) 0
printf '\033[2K Applied: %s' "$(basename "$path")"
}
KEY=""
read_key() {
KEY=""
IFS= read -rsn1 KEY
if [[ $KEY == $'\x1b' ]]; then
local rest=""
IFS= read -rsn2 -t 0.1 rest || true
KEY+="$rest"
fi
}
old_stty=$(stty -g)
trap 'stty "$old_stty"; clear_images; tput cnorm; printf "\033[2J\033[H"' EXIT
stty -echo -icanon -icrnl min 1 time 0
tput civis
draw
while true; do
read_key
case "$KEY" in
h|$'\x1b[D') INDEX=$(( (INDEX - 1 + ${#IMAGES[@]}) % ${#IMAGES[@]} )); draw ;;
l|$'\x1b[C') INDEX=$(( (INDEX + 1) % ${#IMAGES[@]} )); draw ;;
$'\r'|$'\n'|' ') apply "${IMAGES[$INDEX]}" ;;
q|Q) break ;;
esac
done