#!/bin/bash
# change wallpaper - rofi-based wallpaper picker
#
# cw browse folders, pick wallpaper, set primary monitor
# cw -a same but set all monitors
# cw dry <file> primary monitor only, no colorscheme
# cw -d restore Plan 9 default
# cw --random random wallpaper on primary monitor
WPFOLDER="$HOME/.local/share/wallpapers"
ROFI_THEME=(
-theme-str '* { bg: #ffffea; fg: #000000; cyan: #eaffff; olive: #99994c; }' \
-theme-str 'window { width: 40%; border: 3px solid; border-color: @olive; background-color: @bg; }' \
-theme-str 'mainbox { background-color: @bg; }' \
-theme-str 'inputbar { background-color: @cyan; text-color: @fg; padding: 8px; children: [entry]; }' \
-theme-str 'entry { text-color: @fg; placeholder: ""; }' \
-theme-str 'listview { columns: 1; lines: 8; spacing: 4px; background-color: @bg; padding: 8px; fixed-height: false; }' \
-theme-str 'element { background-color: @bg; text-color: @fg; border: 1px solid; border-color: @olive; padding: 4px; }' \
-theme-str 'element selected { background-color: @cyan; border-color: @olive; border: 2px solid; }' \
-theme-str 'element-icon { size: 6em; }' \
-theme-str 'element-text { vertical-align: 0.5; text-color: inherit; }'
)
ROFI_KEYS=(-kb-row-down 'Down,j' -kb-row-up 'Up,k' -kb-accept-entry 'Return,l' -kb-cancel 'Escape,q')
CATEGORIES=(film anime art photo tv)
# Primary connected output, falling back to the first connected one. Keeps this
# portable across machines (DisplayPort-4 on moirai, eDP-1 on the laptop).
primary_output() {
local out
out=$(xrandr --query | awk '/ connected primary/ {print $1; exit}')
[ -z "$out" ] && out=$(xrandr --query | awk '/ connected/ {print $1; exit}')
printf '%s\n' "$out"
}
pick_category() {
printf '%s\n' "${CATEGORIES[@]}" | rofi -dmenu -i -no-custom -no-config "${ROFI_KEYS[@]}" "${ROFI_THEME[@]}"
}
pick_folder() {
local dir="$1"
local entries=""
for d in "$dir"/*/; do
[ -d "$d" ] || continue
entries+="$(basename "$d")\n"
done
printf "$entries" | rofi -dmenu -i -no-custom -no-config "${ROFI_KEYS[@]}" "${ROFI_THEME[@]}"
}
pick_image() {
local dir="$1"
local entries=""
for f in "$dir"/*.{jpg,jpeg,png,webp}; do
[ -f "$f" ] || continue
entries+="$(basename "$f")\x00icon\x1f${f}\n"
done
printf "$entries" | rofi -dmenu -i -no-custom -no-config -show-icons "${ROFI_KEYS[@]}" "${ROFI_THEME[@]}"
}
browse() {
local category
category=$(pick_category) || return
[ -z "$category" ] && return
local title
title=$(pick_folder "$WPFOLDER/$category") || return
[ -z "$title" ] && return
local image
image=$(pick_image "$WPFOLDER/$category/$title") || return
[ -z "$image" ] && return
echo "$WPFOLDER/$category/$title/$image"
}
setwp() {
xwallpaper --output "$(primary_output)" --zoom "$1"
command -v CAPS >/dev/null 2>&1 && CAPS
}
setall() {
local args=() out
while read -r out; do
[ -n "$out" ] && args+=(--output "$out" --zoom "$1")
done < <(xrandr --query | awk '/ connected/ {print $1}')
xwallpaper "${args[@]}"
command -v CAPS >/dev/null 2>&1 && CAPS
}
case "$1" in
-d) setbg -d; CAPS ;;
-a)
chosen=$(browse)
[ -n "$chosen" ] && setall "$chosen"
;;
dry) [ -n "$2" ] && setwp "$2" ;;
--random) file=$(find "$WPFOLDER" -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' \) ! -name 'plan9*' ! -name 'winter*' ! -name 'd1e2f1*' | shuf -n1) && setwp "$file" ;;
"")
chosen=$(browse)
[ -n "$chosen" ] && setwp "$chosen"
;;
*) setwp "$1" ;;
esac