Skip to content

Commit 7689435

Browse files
committed
feat: add dynamic background rotation with aww transitions
1 parent 9cf1852 commit 7689435

11 files changed

Lines changed: 316 additions & 2 deletions

bin/omarchy-dynamic-bg-rotate

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/bin/bash
2+
3+
# omarchy:summary=Rotate backgrounds dynamically with awww transitions
4+
# omarchy:group=theme
5+
# omarchy:name=dynamic-bg-rotate
6+
7+
OMARCHY_PATH=${OMARCHY_PATH:-$HOME/.local/share/omarchy}
8+
CONF="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf"
9+
10+
if [[ ! -f $CONF ]]; then
11+
echo "Dynamic background config not found: $CONF" >&2
12+
exit 1
13+
fi
14+
15+
source "$CONF"
16+
17+
if ! omarchy-cmd-present awww; then
18+
echo "awww is not installed. Install it to use dynamic backgrounds." >&2
19+
exit 1
20+
fi
21+
22+
# Skip rotation if any window is fullscreen and the setting is enabled
23+
if [[ $DYNAMIC_BG_STOP_ON_FULLSCREEN == "true" ]]; then
24+
fullscreen_count=$(hyprctl clients -j 2>/dev/null | jq -r '[.[] | select(.fullscreen != 0)] | length')
25+
if [[ $fullscreen_count -gt 0 ]]; then
26+
exit 0
27+
fi
28+
fi
29+
30+
# Collect backgrounds from theme and user directories
31+
theme_name=$(cat "$HOME/.config/omarchy/current/theme.name" 2>/dev/null)
32+
dirs=(
33+
"$HOME/.config/omarchy/current/theme/backgrounds"
34+
)
35+
36+
if [[ -n $theme_name ]]; then
37+
dirs+=("$HOME/.config/omarchy/backgrounds/$theme_name")
38+
dirs+=("$HOME/.local/share/omarchy/themes/$theme_name/backgrounds")
39+
fi
40+
41+
images=()
42+
for dir in "${dirs[@]}"; do
43+
if [[ -d $dir ]]; then
44+
while IFS= read -r -d '' img; do
45+
images+=("$img")
46+
done < <(find -L "$dir" -maxdepth 1 -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.gif' -o -iname '*.bmp' -o -iname '*.webp' \) -print0 2>/dev/null)
47+
fi
48+
done
49+
50+
if (( ${#images[@]} == 0 )); then
51+
echo "No background images found." >&2
52+
exit 1
53+
fi
54+
55+
# Kill static wallpaper engine
56+
pkill -x swaybg
57+
58+
# Ensure awww daemon is running
59+
if ! pgrep -x awww-daemon &>/dev/null; then
60+
setsid uwsm-app -- awww-daemon &>/dev/null &
61+
sleep 0.5
62+
fi
63+
64+
# Apply random background to each monitor
65+
while IFS= read -r monitor; do
66+
img=${images[RANDOM % ${#images[@]}]}
67+
awww img "$img" -o "$monitor" \
68+
--transition-type "$DYNAMIC_BG_TRANSITION_TYPE" \
69+
--transition-duration "$DYNAMIC_BG_TRANSITION_DURATION" \
70+
--transition-fps "$DYNAMIC_BG_TRANSITION_FPS"
71+
done < <(hyprctl monitors -j | jq -r '.[] | .name')
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/bin/bash
2+
3+
# omarchy:summary=Set dynamic background rotation interval
4+
# omarchy:group=theme
5+
# omarchy:name=dynamic-bg-set-interval
6+
# omarchy:args=<interval>
7+
8+
CONF="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf"
9+
TIMER="$HOME/.config/systemd/user/omarchy-dynamic-bg.timer"
10+
INTERVAL=$1
11+
12+
if [[ -z $INTERVAL ]]; then
13+
echo "Usage: omarchy-dynamic-bg-set-interval <interval>" >&2
14+
echo "Examples: 15sec, 30sec, 1min, 5min, 10min, 30min, 1h" >&2
15+
exit 1
16+
fi
17+
18+
if [[ ! -f $CONF ]]; then
19+
echo "Dynamic background config not found: $CONF" >&2
20+
exit 1
21+
fi
22+
23+
sed -i "s/^DYNAMIC_BG_INTERVAL=.*/DYNAMIC_BG_INTERVAL=$INTERVAL/" "$CONF"
24+
25+
if [[ -f $TIMER ]]; then
26+
sed -i "s/^OnUnitActiveSec=.*/OnUnitActiveSec=$INTERVAL/" "$TIMER"
27+
fi
28+
29+
systemctl --user daemon-reload
30+
systemctl --user restart omarchy-dynamic-bg.timer 2>/dev/null || true
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/bin/bash
2+
3+
# omarchy:summary=Set dynamic background transition type and duration
4+
# omarchy:group=theme
5+
# omarchy:name=dynamic-bg-set-transition
6+
# omarchy:args=<type> <duration>
7+
8+
CONF="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf"
9+
TYPE=$1
10+
DURATION=$2
11+
12+
if [[ -z $TYPE || -z $DURATION ]]; then
13+
echo "Usage: omarchy-dynamic-bg-set-transition <type> <duration>" >&2
14+
echo "Types: random, fade, wipe, grow, wave, outer" >&2
15+
echo "Duration: 0.5, 1, 2, 3, 5 (seconds)" >&2
16+
exit 1
17+
fi
18+
19+
if [[ ! -f $CONF ]]; then
20+
echo "Dynamic background config not found: $CONF" >&2
21+
exit 1
22+
fi
23+
24+
sed -i "s/^DYNAMIC_BG_TRANSITION_TYPE=.*/DYNAMIC_BG_TRANSITION_TYPE=$TYPE/" "$CONF"
25+
sed -i "s/^DYNAMIC_BG_TRANSITION_DURATION=.*/DYNAMIC_BG_TRANSITION_DURATION=$DURATION/" "$CONF"

bin/omarchy-dynamic-bg-toggle

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/bin/bash
2+
3+
# omarchy:summary=Toggle dynamic background rotation on/off
4+
# omarchy:group=theme
5+
# omarchy:name=dynamic-bg-toggle
6+
7+
CONF="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf"
8+
9+
if [[ ! -f $CONF ]]; then
10+
echo "Dynamic background config not found: $CONF" >&2
11+
exit 1
12+
fi
13+
14+
source "$CONF"
15+
16+
if [[ $DYNAMIC_BG_ENABLED == "true" ]]; then
17+
sed -i "s/^DYNAMIC_BG_ENABLED=.*/DYNAMIC_BG_ENABLED=false/" "$CONF"
18+
systemctl --user disable --now omarchy-dynamic-bg.timer
19+
else
20+
omarchy-cmd-present awww || {
21+
echo "awww is required for dynamic backgrounds." >&2
22+
exit 1
23+
}
24+
25+
# Ensure systemd units exist for existing installs
26+
OMARCHY_PATH=${OMARCHY_PATH:-$HOME/.local/share/omarchy}
27+
for unit in omarchy-dynamic-bg.service omarchy-dynamic-bg.timer; do
28+
if [[ ! -f $HOME/.config/systemd/user/$unit ]]; then
29+
cp "$OMARCHY_PATH/config/systemd/user/$unit" "$HOME/.config/systemd/user/$unit"
30+
fi
31+
done
32+
33+
# Ensure config file exists for existing installs
34+
if [[ ! -f $CONF ]]; then
35+
mkdir -p "$(dirname "$CONF")"
36+
cp "$OMARCHY_PATH/config/omarchy/dynamic-bg/dynamic-bg.conf" "$CONF"
37+
fi
38+
39+
systemctl --user daemon-reload
40+
sed -i "s/^DYNAMIC_BG_ENABLED=.*/DYNAMIC_BG_ENABLED=true/" "$CONF"
41+
systemctl --user enable --now omarchy-dynamic-bg.timer
42+
fi
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/bash
2+
3+
# omarchy:summary=Toggle dynamic background stop-on-fullscreen behavior
4+
# omarchy:group=theme
5+
# omarchy:name=dynamic-bg-toggle-fullscreen
6+
7+
CONF="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf"
8+
9+
if [[ ! -f $CONF ]]; then
10+
echo "Dynamic background config not found: $CONF" >&2
11+
exit 1
12+
fi
13+
14+
source "$CONF"
15+
16+
if [[ $DYNAMIC_BG_STOP_ON_FULLSCREEN == "true" ]]; then
17+
sed -i "s/^DYNAMIC_BG_STOP_ON_FULLSCREEN=.*/DYNAMIC_BG_STOP_ON_FULLSCREEN=false/" "$CONF"
18+
else
19+
sed -i "s/^DYNAMIC_BG_STOP_ON_FULLSCREEN=.*/DYNAMIC_BG_STOP_ON_FULLSCREEN=true/" "$CONF"
20+
fi

bin/omarchy-menu

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,93 @@ show_theme_menu() {
328328
}
329329

330330
show_background_menu() {
331-
background=$(omarchy-theme-bg-switcher)
332-
[[ -n $background ]] && omarchy-theme-bg-set "$background"
331+
case $(menu "Background" "󰐃 Static\n󰑓 Dynamic") in
332+
*Static*)
333+
background=$(omarchy-theme-bg-switcher)
334+
[[ -n $background ]] && omarchy-theme-bg-set "$background"
335+
;;
336+
*Dynamic*) show_dynamic_bg_menu ;;
337+
*) back_to show_style_menu ;;
338+
esac
339+
}
340+
341+
show_dynamic_bg_menu() {
342+
if ! command -v awww &>/dev/null; then
343+
omarchy-notification-send "awww is required for dynamic backgrounds" -u critical
344+
back_to show_style_menu
345+
return
346+
fi
347+
348+
local conf="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf"
349+
[[ -f $conf ]] && source "$conf"
350+
351+
local status="Disabled"
352+
[[ $DYNAMIC_BG_ENABLED == "true" ]] && status="Enabled"
353+
354+
local fullscreen="Off"
355+
[[ $DYNAMIC_BG_STOP_ON_FULLSCREEN == "true" ]] && fullscreen="On"
356+
357+
case $(menu "Dynamic Background" "󰐾 Status: $status\n󱦟 Interval: $DYNAMIC_BG_INTERVAL\n󰸌 Transition Effect: ${DYNAMIC_BG_TRANSITION_TYPE^}\n󰓅 Transition Speed: ${DYNAMIC_BG_TRANSITION_DURATION}s\n󰍺 Stop on Fullscreen: $fullscreen") in
358+
*Status*) omarchy-dynamic-bg-toggle ; show_dynamic_bg_menu ;;
359+
*Interval*) show_dynamic_bg_interval_menu ;;
360+
*Effect*) show_dynamic_bg_effect_menu ;;
361+
*Speed*) show_dynamic_bg_speed_menu ;;
362+
*Fullscreen*) omarchy-dynamic-bg-toggle-fullscreen ; show_dynamic_bg_menu ;;
363+
*) back_to show_style_menu ;;
364+
esac
365+
}
366+
367+
show_dynamic_bg_interval_menu() {
368+
case $(menu "Interval" "󱦟 15 seconds\n󱦟 30 seconds\n󱦟 1 minute\n󱦟 5 minutes\n󱦟 10 minutes\n󱦟 30 minutes\n󱦟 1 hour") in
369+
*"15 seconds"*) omarchy-dynamic-bg-set-interval 15sec ;;
370+
*"30 seconds"*) omarchy-dynamic-bg-set-interval 30sec ;;
371+
*"1 minute"*) omarchy-dynamic-bg-set-interval 1min ;;
372+
*"5 minutes"*) omarchy-dynamic-bg-set-interval 5min ;;
373+
*"10 minutes"*) omarchy-dynamic-bg-set-interval 10min ;;
374+
*"30 minutes"*) omarchy-dynamic-bg-set-interval 30min ;;
375+
*"1 hour"*) omarchy-dynamic-bg-set-interval 1h ;;
376+
*) show_dynamic_bg_menu ; return ;;
377+
esac
378+
show_dynamic_bg_menu
379+
}
380+
381+
show_dynamic_bg_effect_menu() {
382+
local conf="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf"
383+
[[ -f $conf ]] && source "$conf"
384+
385+
local choice
386+
choice=$(menu "Transition Effect" "󰸌 Random\n󰸌 Fade\n󰸌 Wipe\n󰸌 Grow\n󰸌 Wave\n󰸌 Outer")
387+
local text="${choice##* }"
388+
389+
case "$text" in
390+
Random) omarchy-dynamic-bg-set-transition random "$DYNAMIC_BG_TRANSITION_DURATION" ;;
391+
Fade) omarchy-dynamic-bg-set-transition fade "$DYNAMIC_BG_TRANSITION_DURATION" ;;
392+
Wipe) omarchy-dynamic-bg-set-transition wipe "$DYNAMIC_BG_TRANSITION_DURATION" ;;
393+
Grow) omarchy-dynamic-bg-set-transition grow "$DYNAMIC_BG_TRANSITION_DURATION" ;;
394+
Wave) omarchy-dynamic-bg-set-transition wave "$DYNAMIC_BG_TRANSITION_DURATION" ;;
395+
Outer) omarchy-dynamic-bg-set-transition outer "$DYNAMIC_BG_TRANSITION_DURATION" ;;
396+
*) show_dynamic_bg_menu ; return ;;
397+
esac
398+
show_dynamic_bg_menu
399+
}
400+
401+
show_dynamic_bg_speed_menu() {
402+
local conf="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf"
403+
[[ -f $conf ]] && source "$conf"
404+
405+
local choice
406+
choice=$(menu "Transition Speed" "󰓅 0.5s\n󰓅 1s\n󰓅 2s\n󰓅 3s\n󰓅 5s")
407+
local text="${choice##* }"
408+
409+
case "$text" in
410+
0.5s) omarchy-dynamic-bg-set-transition "$DYNAMIC_BG_TRANSITION_TYPE" 0.5 ;;
411+
1s) omarchy-dynamic-bg-set-transition "$DYNAMIC_BG_TRANSITION_TYPE" 1 ;;
412+
2s) omarchy-dynamic-bg-set-transition "$DYNAMIC_BG_TRANSITION_TYPE" 2 ;;
413+
3s) omarchy-dynamic-bg-set-transition "$DYNAMIC_BG_TRANSITION_TYPE" 3 ;;
414+
5s) omarchy-dynamic-bg-set-transition "$DYNAMIC_BG_TRANSITION_TYPE" 5 ;;
415+
*) show_dynamic_bg_menu ; return ;;
416+
esac
417+
show_dynamic_bg_menu
333418
}
334419

335420
show_font_menu() {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
DYNAMIC_BG_ENABLED=false
2+
DYNAMIC_BG_INTERVAL=10min
3+
DYNAMIC_BG_TRANSITION_TYPE=random
4+
DYNAMIC_BG_TRANSITION_DURATION=3
5+
DYNAMIC_BG_TRANSITION_FPS=120
6+
DYNAMIC_BG_STOP_ON_FULLSCREEN=true
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[Unit]
2+
Description=Dynamic background rotation with awww
3+
After=graphical-session.target
4+
5+
[Service]
6+
Type=oneshot
7+
ExecStart=%h/.local/share/omarchy/bin/omarchy-dynamic-bg-rotate
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[Unit]
2+
Description=Timer for dynamic background rotation
3+
Requires=omarchy-dynamic-bg.service
4+
5+
[Timer]
6+
OnBootSec=2min
7+
OnUnitActiveSec=10min
8+
AccuracySec=1s
9+
10+
[Install]
11+
WantedBy=timers.target

install/omarchy-base.packages

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
1password-beta
55
1password-cli
66
aether
7+
awww
78
alsa-utils
89
asdcontrol
910
avahi

0 commit comments

Comments
 (0)