89 lines
2.5 KiB
Bash
Executable File
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
|