From 8f70b7343b8958bd48aca92f0b1b933170fdbc0a Mon Sep 17 00:00:00 2001 From: pochitalinuxera Date: Tue, 23 Jun 2026 18:11:10 -0300 Subject: [PATCH 1/2] feat: add dynamic background rotation with aww transitions --- bin/omarchy-dynamic-bg-fullscreen-watcher | 22 +++++ bin/omarchy-dynamic-bg-rotate | 71 +++++++++++++++ bin/omarchy-dynamic-bg-set-interval | 30 +++++++ bin/omarchy-dynamic-bg-set-transition | 25 ++++++ bin/omarchy-dynamic-bg-toggle | 42 +++++++++ bin/omarchy-dynamic-bg-toggle-fullscreen | 20 +++++ bin/omarchy-menu | 89 ++++++++++++++++++- config/omarchy/dynamic-bg/dynamic-bg.conf | 6 ++ ...rchy-dynamic-bg-fullscreen-watcher.service | 13 +++ .../systemd/user/omarchy-dynamic-bg.service | 7 ++ config/systemd/user/omarchy-dynamic-bg.timer | 11 +++ install/omarchy-base.packages | 1 + migrations/1780929365.sh | 16 ++++ 13 files changed, 351 insertions(+), 2 deletions(-) create mode 100755 bin/omarchy-dynamic-bg-fullscreen-watcher create mode 100755 bin/omarchy-dynamic-bg-rotate create mode 100755 bin/omarchy-dynamic-bg-set-interval create mode 100755 bin/omarchy-dynamic-bg-set-transition create mode 100755 bin/omarchy-dynamic-bg-toggle create mode 100755 bin/omarchy-dynamic-bg-toggle-fullscreen create mode 100644 config/omarchy/dynamic-bg/dynamic-bg.conf create mode 100644 config/systemd/user/omarchy-dynamic-bg-fullscreen-watcher.service create mode 100644 config/systemd/user/omarchy-dynamic-bg.service create mode 100644 config/systemd/user/omarchy-dynamic-bg.timer create mode 100644 migrations/1780929365.sh diff --git a/bin/omarchy-dynamic-bg-fullscreen-watcher b/bin/omarchy-dynamic-bg-fullscreen-watcher new file mode 100755 index 0000000000..9df8dca49c --- /dev/null +++ b/bin/omarchy-dynamic-bg-fullscreen-watcher @@ -0,0 +1,22 @@ +#!/bin/bash + +# omarchy:summary=Watch fullscreen state to pause dynamic background rotation +# omarchy:group=theme +# omarchy:name=dynamic-bg-fullscreen-watcher + +OMARCHY_PATH=${OMARCHY_PATH:-$HOME/.local/share/omarchy} +CONF="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf" + +socat -u UNIX-CONNECT:"$XDG_RUNTIME_DIR/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock" - | while read -r line; do + [[ -f $CONF ]] && source "$CONF" + [[ $DYNAMIC_BG_ENABLED == "true" && $DYNAMIC_BG_STOP_ON_FULLSCREEN == "true" ]] || continue + + case "$line" in + fullscreen\>\>1*) + systemctl --user stop omarchy-dynamic-bg.timer + ;; + fullscreen\>\>0*) + systemctl --user start omarchy-dynamic-bg.timer + ;; + esac +done diff --git a/bin/omarchy-dynamic-bg-rotate b/bin/omarchy-dynamic-bg-rotate new file mode 100755 index 0000000000..39c2710723 --- /dev/null +++ b/bin/omarchy-dynamic-bg-rotate @@ -0,0 +1,71 @@ +#!/bin/bash + +# omarchy:summary=Rotate backgrounds dynamically with awww transitions +# omarchy:group=theme +# omarchy:name=dynamic-bg-rotate + +OMARCHY_PATH=${OMARCHY_PATH:-$HOME/.local/share/omarchy} +CONF="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf" + +if [[ ! -f $CONF ]]; then + echo "Dynamic background config not found: $CONF" >&2 + exit 1 +fi + +source "$CONF" + +if ! omarchy-cmd-present awww; then + echo "awww is not installed. Install it to use dynamic backgrounds." >&2 + exit 1 +fi + +# Skip rotation if any window is fullscreen and the setting is enabled +if [[ $DYNAMIC_BG_STOP_ON_FULLSCREEN == "true" ]]; then + fullscreen_count=$(hyprctl clients -j 2>/dev/null | jq -r '[.[] | select(.fullscreen != 0)] | length') + if [[ $fullscreen_count -gt 0 ]]; then + exit 0 + fi +fi + +# Collect backgrounds from theme and user directories +theme_name=$(cat "$HOME/.config/omarchy/current/theme.name" 2>/dev/null) +dirs=( + "$HOME/.config/omarchy/current/theme/backgrounds" +) + +if [[ -n $theme_name ]]; then + dirs+=("$HOME/.config/omarchy/backgrounds/$theme_name") + dirs+=("$HOME/.local/share/omarchy/themes/$theme_name/backgrounds") +fi + +images=() +for dir in "${dirs[@]}"; do + if [[ -d $dir ]]; then + while IFS= read -r -d '' img; do + images+=("$img") + 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) + fi +done + +if (( ${#images[@]} == 0 )); then + echo "No background images found." >&2 + exit 1 +fi + +# Kill static wallpaper engine +pkill -x swaybg + +# Ensure awww daemon is running +if ! pgrep -x awww-daemon &>/dev/null; then + setsid uwsm-app -- awww-daemon &>/dev/null & + sleep 0.5 +fi + +# Apply random background to each monitor +while IFS= read -r monitor; do + img=${images[RANDOM % ${#images[@]}]} + awww img "$img" -o "$monitor" \ + --transition-type "$DYNAMIC_BG_TRANSITION_TYPE" \ + --transition-duration "$DYNAMIC_BG_TRANSITION_DURATION" \ + --transition-fps "$DYNAMIC_BG_TRANSITION_FPS" +done < <(hyprctl monitors -j | jq -r '.[] | .name') diff --git a/bin/omarchy-dynamic-bg-set-interval b/bin/omarchy-dynamic-bg-set-interval new file mode 100755 index 0000000000..006cd2cf6a --- /dev/null +++ b/bin/omarchy-dynamic-bg-set-interval @@ -0,0 +1,30 @@ +#!/bin/bash + +# omarchy:summary=Set dynamic background rotation interval +# omarchy:group=theme +# omarchy:name=dynamic-bg-set-interval +# omarchy:args= + +CONF="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf" +TIMER="$HOME/.config/systemd/user/omarchy-dynamic-bg.timer" +INTERVAL=$1 + +if [[ -z $INTERVAL ]]; then + echo "Usage: omarchy-dynamic-bg-set-interval " >&2 + echo "Examples: 15sec, 30sec, 1min, 5min, 10min, 30min, 1h" >&2 + exit 1 +fi + +if [[ ! -f $CONF ]]; then + echo "Dynamic background config not found: $CONF" >&2 + exit 1 +fi + +sed -i "s/^DYNAMIC_BG_INTERVAL=.*/DYNAMIC_BG_INTERVAL=$INTERVAL/" "$CONF" + +if [[ -f $TIMER ]]; then + sed -i "s/^OnUnitActiveSec=.*/OnUnitActiveSec=$INTERVAL/" "$TIMER" +fi + +systemctl --user daemon-reload +systemctl --user restart omarchy-dynamic-bg.timer 2>/dev/null || true diff --git a/bin/omarchy-dynamic-bg-set-transition b/bin/omarchy-dynamic-bg-set-transition new file mode 100755 index 0000000000..40c5fba23b --- /dev/null +++ b/bin/omarchy-dynamic-bg-set-transition @@ -0,0 +1,25 @@ +#!/bin/bash + +# omarchy:summary=Set dynamic background transition type and duration +# omarchy:group=theme +# omarchy:name=dynamic-bg-set-transition +# omarchy:args= + +CONF="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf" +TYPE=$1 +DURATION=$2 + +if [[ -z $TYPE || -z $DURATION ]]; then + echo "Usage: omarchy-dynamic-bg-set-transition " >&2 + echo "Types: random, fade, wipe, grow, wave, outer" >&2 + echo "Duration: 0.5, 1, 2, 3, 5 (seconds)" >&2 + exit 1 +fi + +if [[ ! -f $CONF ]]; then + echo "Dynamic background config not found: $CONF" >&2 + exit 1 +fi + +sed -i "s/^DYNAMIC_BG_TRANSITION_TYPE=.*/DYNAMIC_BG_TRANSITION_TYPE=$TYPE/" "$CONF" +sed -i "s/^DYNAMIC_BG_TRANSITION_DURATION=.*/DYNAMIC_BG_TRANSITION_DURATION=$DURATION/" "$CONF" diff --git a/bin/omarchy-dynamic-bg-toggle b/bin/omarchy-dynamic-bg-toggle new file mode 100755 index 0000000000..b80354b220 --- /dev/null +++ b/bin/omarchy-dynamic-bg-toggle @@ -0,0 +1,42 @@ +#!/bin/bash + +# omarchy:summary=Toggle dynamic background rotation on/off +# omarchy:group=theme +# omarchy:name=dynamic-bg-toggle + +CONF="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf" + +if [[ ! -f $CONF ]]; then + echo "Dynamic background config not found: $CONF" >&2 + exit 1 +fi + +source "$CONF" + +if [[ $DYNAMIC_BG_ENABLED == "true" ]]; then + sed -i "s/^DYNAMIC_BG_ENABLED=.*/DYNAMIC_BG_ENABLED=false/" "$CONF" + systemctl --user disable --now omarchy-dynamic-bg.timer +else + omarchy-cmd-present awww || { + echo "awww is required for dynamic backgrounds." >&2 + exit 1 + } + + # Ensure systemd units exist for existing installs + OMARCHY_PATH=${OMARCHY_PATH:-$HOME/.local/share/omarchy} + for unit in omarchy-dynamic-bg.service omarchy-dynamic-bg.timer; do + if [[ ! -f $HOME/.config/systemd/user/$unit ]]; then + cp "$OMARCHY_PATH/config/systemd/user/$unit" "$HOME/.config/systemd/user/$unit" + fi + done + + # Ensure config file exists for existing installs + if [[ ! -f $CONF ]]; then + mkdir -p "$(dirname "$CONF")" + cp "$OMARCHY_PATH/config/omarchy/dynamic-bg/dynamic-bg.conf" "$CONF" + fi + + systemctl --user daemon-reload + sed -i "s/^DYNAMIC_BG_ENABLED=.*/DYNAMIC_BG_ENABLED=true/" "$CONF" + systemctl --user enable --now omarchy-dynamic-bg.timer +fi diff --git a/bin/omarchy-dynamic-bg-toggle-fullscreen b/bin/omarchy-dynamic-bg-toggle-fullscreen new file mode 100755 index 0000000000..d8ed981372 --- /dev/null +++ b/bin/omarchy-dynamic-bg-toggle-fullscreen @@ -0,0 +1,20 @@ +#!/bin/bash + +# omarchy:summary=Toggle dynamic background stop-on-fullscreen behavior +# omarchy:group=theme +# omarchy:name=dynamic-bg-toggle-fullscreen + +CONF="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf" + +if [[ ! -f $CONF ]]; then + echo "Dynamic background config not found: $CONF" >&2 + exit 1 +fi + +source "$CONF" + +if [[ $DYNAMIC_BG_STOP_ON_FULLSCREEN == "true" ]]; then + sed -i "s/^DYNAMIC_BG_STOP_ON_FULLSCREEN=.*/DYNAMIC_BG_STOP_ON_FULLSCREEN=false/" "$CONF" +else + sed -i "s/^DYNAMIC_BG_STOP_ON_FULLSCREEN=.*/DYNAMIC_BG_STOP_ON_FULLSCREEN=true/" "$CONF" +fi diff --git a/bin/omarchy-menu b/bin/omarchy-menu index 8627ab132c..6197854130 100755 --- a/bin/omarchy-menu +++ b/bin/omarchy-menu @@ -328,8 +328,93 @@ show_theme_menu() { } show_background_menu() { - background=$(omarchy-theme-bg-switcher) - [[ -n $background ]] && omarchy-theme-bg-set "$background" + case $(menu "Background" "󰐃 Static\n󰑓 Dynamic") in + *Static*) + background=$(omarchy-theme-bg-switcher) + [[ -n $background ]] && omarchy-theme-bg-set "$background" + ;; + *Dynamic*) show_dynamic_bg_menu ;; + *) back_to show_style_menu ;; + esac +} + +show_dynamic_bg_menu() { + if ! command -v awww &>/dev/null; then + omarchy-notification-send "awww is required for dynamic backgrounds" -u critical + back_to show_style_menu + return + fi + + local conf="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf" + [[ -f $conf ]] && source "$conf" + + local status="Disabled" + [[ $DYNAMIC_BG_ENABLED == "true" ]] && status="Enabled" + + local fullscreen="Off" + [[ $DYNAMIC_BG_STOP_ON_FULLSCREEN == "true" ]] && fullscreen="On" + + 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 + *Status*) omarchy-dynamic-bg-toggle ; show_dynamic_bg_menu ;; + *Interval*) show_dynamic_bg_interval_menu ;; + *Effect*) show_dynamic_bg_effect_menu ;; + *Speed*) show_dynamic_bg_speed_menu ;; + *Fullscreen*) omarchy-dynamic-bg-toggle-fullscreen ; show_dynamic_bg_menu ;; + *) back_to show_style_menu ;; + esac +} + +show_dynamic_bg_interval_menu() { + case $(menu "Interval" "󱦟 15 seconds\n󱦟 30 seconds\n󱦟 1 minute\n󱦟 5 minutes\n󱦟 10 minutes\n󱦟 30 minutes\n󱦟 1 hour") in + *"15 seconds"*) omarchy-dynamic-bg-set-interval 15sec ;; + *"30 seconds"*) omarchy-dynamic-bg-set-interval 30sec ;; + *"1 minute"*) omarchy-dynamic-bg-set-interval 1min ;; + *"5 minutes"*) omarchy-dynamic-bg-set-interval 5min ;; + *"10 minutes"*) omarchy-dynamic-bg-set-interval 10min ;; + *"30 minutes"*) omarchy-dynamic-bg-set-interval 30min ;; + *"1 hour"*) omarchy-dynamic-bg-set-interval 1h ;; + *) show_dynamic_bg_menu ; return ;; + esac + show_dynamic_bg_menu +} + +show_dynamic_bg_effect_menu() { + local conf="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf" + [[ -f $conf ]] && source "$conf" + + local choice + choice=$(menu "Transition Effect" "󰸌 Random\n󰸌 Fade\n󰸌 Wipe\n󰸌 Grow\n󰸌 Wave\n󰸌 Outer") + local text="${choice##* }" + + case "$text" in + Random) omarchy-dynamic-bg-set-transition random "$DYNAMIC_BG_TRANSITION_DURATION" ;; + Fade) omarchy-dynamic-bg-set-transition fade "$DYNAMIC_BG_TRANSITION_DURATION" ;; + Wipe) omarchy-dynamic-bg-set-transition wipe "$DYNAMIC_BG_TRANSITION_DURATION" ;; + Grow) omarchy-dynamic-bg-set-transition grow "$DYNAMIC_BG_TRANSITION_DURATION" ;; + Wave) omarchy-dynamic-bg-set-transition wave "$DYNAMIC_BG_TRANSITION_DURATION" ;; + Outer) omarchy-dynamic-bg-set-transition outer "$DYNAMIC_BG_TRANSITION_DURATION" ;; + *) show_dynamic_bg_menu ; return ;; + esac + show_dynamic_bg_menu +} + +show_dynamic_bg_speed_menu() { + local conf="$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf" + [[ -f $conf ]] && source "$conf" + + local choice + choice=$(menu "Transition Speed" "󰓅 0.5s\n󰓅 1s\n󰓅 2s\n󰓅 3s\n󰓅 5s") + local text="${choice##* }" + + case "$text" in + 0.5s) omarchy-dynamic-bg-set-transition "$DYNAMIC_BG_TRANSITION_TYPE" 0.5 ;; + 1s) omarchy-dynamic-bg-set-transition "$DYNAMIC_BG_TRANSITION_TYPE" 1 ;; + 2s) omarchy-dynamic-bg-set-transition "$DYNAMIC_BG_TRANSITION_TYPE" 2 ;; + 3s) omarchy-dynamic-bg-set-transition "$DYNAMIC_BG_TRANSITION_TYPE" 3 ;; + 5s) omarchy-dynamic-bg-set-transition "$DYNAMIC_BG_TRANSITION_TYPE" 5 ;; + *) show_dynamic_bg_menu ; return ;; + esac + show_dynamic_bg_menu } show_font_menu() { diff --git a/config/omarchy/dynamic-bg/dynamic-bg.conf b/config/omarchy/dynamic-bg/dynamic-bg.conf new file mode 100644 index 0000000000..4133c1f438 --- /dev/null +++ b/config/omarchy/dynamic-bg/dynamic-bg.conf @@ -0,0 +1,6 @@ +DYNAMIC_BG_ENABLED=false +DYNAMIC_BG_INTERVAL=10min +DYNAMIC_BG_TRANSITION_TYPE=random +DYNAMIC_BG_TRANSITION_DURATION=3 +DYNAMIC_BG_TRANSITION_FPS=120 +DYNAMIC_BG_STOP_ON_FULLSCREEN=true diff --git a/config/systemd/user/omarchy-dynamic-bg-fullscreen-watcher.service b/config/systemd/user/omarchy-dynamic-bg-fullscreen-watcher.service new file mode 100644 index 0000000000..9f9de8945d --- /dev/null +++ b/config/systemd/user/omarchy-dynamic-bg-fullscreen-watcher.service @@ -0,0 +1,13 @@ +[Unit] +Description=Pause dynamic background rotation and daemon during fullscreen +After=graphical-session.target + +[Service] +Type=simple +ExecStartPre=/bin/sleep 5 +ExecStart=%h/.local/share/omarchy/bin/omarchy-dynamic-bg-fullscreen-watcher +Restart=on-failure +RestartSec=10 + +[Install] +WantedBy=default.target diff --git a/config/systemd/user/omarchy-dynamic-bg.service b/config/systemd/user/omarchy-dynamic-bg.service new file mode 100644 index 0000000000..adb5361a58 --- /dev/null +++ b/config/systemd/user/omarchy-dynamic-bg.service @@ -0,0 +1,7 @@ +[Unit] +Description=Dynamic background rotation with awww +After=graphical-session.target + +[Service] +Type=oneshot +ExecStart=%h/.local/share/omarchy/bin/omarchy-dynamic-bg-rotate diff --git a/config/systemd/user/omarchy-dynamic-bg.timer b/config/systemd/user/omarchy-dynamic-bg.timer new file mode 100644 index 0000000000..a61a64a58d --- /dev/null +++ b/config/systemd/user/omarchy-dynamic-bg.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Timer for dynamic background rotation +Requires=omarchy-dynamic-bg.service + +[Timer] +OnBootSec=2min +OnUnitActiveSec=10min +AccuracySec=1s + +[Install] +WantedBy=timers.target diff --git a/install/omarchy-base.packages b/install/omarchy-base.packages index e471fcf50f..09b609b5c5 100644 --- a/install/omarchy-base.packages +++ b/install/omarchy-base.packages @@ -4,6 +4,7 @@ 1password-beta 1password-cli aether +awww alsa-utils asdcontrol avahi diff --git a/migrations/1780929365.sh b/migrations/1780929365.sh new file mode 100644 index 0000000000..1fd0015a35 --- /dev/null +++ b/migrations/1780929365.sh @@ -0,0 +1,16 @@ +echo "Install dynamic background config and systemd units" + +if [[ ! -f $HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf ]]; then + mkdir -p "$HOME/.config/omarchy/dynamic-bg" + cp "$OMARCHY_PATH/config/omarchy/dynamic-bg/dynamic-bg.conf" "$HOME/.config/omarchy/dynamic-bg/dynamic-bg.conf" +fi + +mkdir -p "$HOME/.config/systemd/user" + +for unit in omarchy-dynamic-bg.service omarchy-dynamic-bg.timer; do + if [[ ! -f $HOME/.config/systemd/user/$unit ]]; then + cp "$OMARCHY_PATH/config/systemd/user/$unit" "$HOME/.config/systemd/user/$unit" + fi +done + +systemctl --user daemon-reload From 600a07fab6eabe3d8c0b76695e93d4b098b75a5a Mon Sep 17 00:00:00 2001 From: pochitalinuxera Date: Fri, 3 Jul 2026 18:09:15 -0300 Subject: [PATCH 2/2] fix: show abbreviated interval in display, keep full names in submenu --- bin/omarchy-menu | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/omarchy-menu b/bin/omarchy-menu index 6197854130..8061094dbe 100755 --- a/bin/omarchy-menu +++ b/bin/omarchy-menu @@ -354,7 +354,11 @@ show_dynamic_bg_menu() { local fullscreen="Off" [[ $DYNAMIC_BG_STOP_ON_FULLSCREEN == "true" ]] && fullscreen="On" - 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 + local display_interval="$DYNAMIC_BG_INTERVAL" + display_interval="${display_interval/sec/s}" + display_interval="${display_interval/min/m}" + + case $(menu "Dynamic Background" "󰐾 Status: $status\n󱦟 Interval: $display_interval\n󰸌 Transition Effect: ${DYNAMIC_BG_TRANSITION_TYPE^}\n󰓅 Transition Speed: ${DYNAMIC_BG_TRANSITION_DURATION}s\n󰍺 Stop on Fullscreen: $fullscreen") in *Status*) omarchy-dynamic-bg-toggle ; show_dynamic_bg_menu ;; *Interval*) show_dynamic_bg_interval_menu ;; *Effect*) show_dynamic_bg_effect_menu ;;