From f5fc91419850ee5f2652bdce0dcc214de18b4a22 Mon Sep 17 00:00:00 2001 From: Kris Yotam <75515498+krisyotam@users.noreply.github.com> Date: Thu, 2 Jul 2026 00:50:10 -0500 Subject: [PATCH] add wallpapermenu script (was untracked); auto-detect output so cw works on any machine --- .local/bin/wallpapermenu | 106 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100755 .local/bin/wallpapermenu diff --git a/.local/bin/wallpapermenu b/.local/bin/wallpapermenu new file mode 100755 index 0000000000000000000000000000000000000000..f711dd5419ebb6a9fcd3925a0f8a753f20d2bdb5 --- /dev/null +++ b/.local/bin/wallpapermenu @@ -0,0 +1,106 @@ +#!/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 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 "${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 "${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 -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" + 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[@]}" + 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