1#!/usr/bin/env bash
2
3set -euo pipefail
4
5WALLDIR="${HOME}/.assets/wallpapers"
6
7# ── helpers ──────────────────────────────────────────────────────────────────
8
9die() { echo "error: $*" >&2; exit 1; }
10
11rofi_pick() {
12 local title="$1"; shift
13 rofi -dmenu -mesg "$title" -theme $HOME/.wraith/theme/scripts.rofi.rasi -theme-str 'listview {lines:5;}' -theme-str 'element-icon { margin: 0px 8px 0px 10px; }' "$@"
14}
15
16make_swatch() {
17 local color="$1"
18 local svg="/tmp/matugen-swatch-${color#'#'}.svg"
19 printf '<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32"><rect width="32" height="32" fill="%s"/></svg>' \
20 "$color" > "$svg"
21 echo "$svg"
22}
23
24# ── wallpaper ─────────────────────────────────────────────────────────────────
25
26img_input=""
27while IFS= read -r file; do
28 img_input+="${file}\0icon\x1f${WALLDIR}/${file}\n"
29done < <(find "$WALLDIR" -type f \( -iname "*.jpg" -o -iname "*.png" -o -iname "*.jpeg" \) -printf "%f\n" | sort)
30
31img=$(printf "%b" "$img_input" | rofi_pick "Choose a wallpaper" -show-icons -theme-str 'listview {orientation: horizontal;columns:2;lines:2;}' -theme-str 'element-icon { size: 200px; margin:0px 10px; padding:0px;}' -theme-str 'element {margin:0px;padding:0px;}' )
32img="${WALLDIR}/${img}"
33
34[[ -f "$img" ]] || die "file not found: $img"
35
36# ── scheme ────────────────────────────────────────────────────────────────────
37
38scheme=$(printf '%s\n' \
39 tonal-spot expressive fidelity content \
40 monochrome neutral rainbow fruit-salad \
41 | rofi_pick "Choose a color scheme")
42[[ -z "$scheme" ]] && exit 0
43
44# ── seed color ────────────────────────────────────────────────────────────────
45
46RAW=$(echo | script -q -c "matugen image '$img' --dry-run" /dev/stdout 2>/dev/null)
47mapfile -t COLORS < <(echo "$RAW" | grep -oP '#[0-9a-fA-F]{6}' | awk '!seen[$0]++')
48
49case "${#COLORS[@]}" in
50 0) die "matugen returned no colors" ;;
51 1) source_index=0 ;;
52 *)
53 rofi_input=""
54 for color in "${COLORS[@]}"; do
55 swatch=$(make_swatch "$color")
56 rofi_input+="${color}\0icon\x1f${swatch}\n"
57 done
58
59 selected=$(printf "%b" "$rofi_input" | rofi_pick "Pick a seed color" -show-icons)
60 [[ -z "$selected" ]] && exit 0
61
62 # find 0-based index
63 for i in "${!COLORS[@]}"; do
64 [[ "${COLORS[$i]}" == "$selected" ]] && source_index=$i && break
65 done
66 ;;
67esac
68
69# triple monitor setup
70CACHE="$HOME/.cache/awww-blend"
71mkdir -p "$CACHE"
72
73TOTAL_W=4080
74TOTAL_H=1920
75CENTER_Y=420
76
77TRANS="--transition-type wipe --transition-angle 0 --transition-fps 60 --transition-step 20"
78
79# Check source resolution before processing
80SRC_W=$(magick identify -format "%w" "$img")
81SRC_H=$(magick identify -format "%h" "$img")
82echo "Source: ${SRC_W}×${SRC_H} → Canvas: ${TOTAL_W}×${TOTAL_H}"
83
84if (( SRC_W < TOTAL_W || SRC_H < TOTAL_H )); then
85 echo "⚠ Image smaller than canvas — will be upscaled, expect some softness"
86fi
87
88# Lanczos = best quality filter for upscaling/downscaling
89magick "$img" \
90 -filter Lanczos \
91 -resize "${TOTAL_W}x${TOTAL_H}^" \
92 -gravity Center \
93 -extent "${TOTAL_W}x${TOTAL_H}" \
94 "$CACHE/base.png"
95
96magick "$CACHE/base.png" -crop "1080x1920+0+0" +repage "$CACHE/left.png"
97magick "$CACHE/base.png" -crop "1920x1080+1080+${CENTER_Y}" +repage "$CACHE/center.png"
98magick "$CACHE/base.png" -crop "1080x1920+3000+0" +repage "$CACHE/right.png"
99
100# ── apply ─────────────────────────────────────────────────────────────────────
101awww img -o HDMI-A-2 $TRANS "$CACHE/left.png" &
102awww img -o DP-1 $TRANS "$CACHE/center.png" &
103awww img -o HDMI-A-1 $TRANS "$CACHE/right.png" &
104wait
105
106matugen image "$img" \
107 --type "scheme-${scheme}" \
108 --source-color-index "$source_index"