Merge pull request #7718 from OldJobobo/feature/remember-theme-wallpapers

Remember the selected wallpaper for each theme
This commit is contained in:
bjarneo authored and GitHub committed 2026-09-23 20:39:46 +02:00
commit 28ceaae70e
3 files changed
+187 -18

No files matched your search

+56 -18
View File
@@ -10,8 +10,10 @@ if [[ -z $1 ]]; then
fi
CURRENT_THEME_PATH="$HOME/.local/state/omarchy/current/theme"
CURRENT_THEME_NAME_PATH="$HOME/.local/state/omarchy/current/theme.name"
NEXT_THEME_PATH="$HOME/.local/state/omarchy/current/next-theme"
CURRENT_BACKGROUND_LINK="$HOME/.local/state/omarchy/current/background"
THEME_BACKGROUND_STATE_PATH="$HOME/.local/state/omarchy/theme-backgrounds"
BACKGROUND_TRANSITION_CACHE="$HOME/.cache/omarchy/background-transitions"
THEME_SET_LOCK="${XDG_RUNTIME_DIR:-/tmp}/omarchy-theme-set.lock"
USER_THEMES_PATH="$HOME/.config/omarchy/themes"
@@ -74,6 +76,24 @@ snapshot_current_background() {
snapshot_background_path "$current_background" "previous"
}
theme_background_state_file() {
local theme="$1"
[[ -n $theme && ${theme##*/} == $theme && $theme != "." && $theme != ".." ]] || return 1
printf '%s/%s\n' "$THEME_BACKGROUND_STATE_PATH" "$theme"
}
remember_current_theme_background() {
local current_background state_file
state_file=$(theme_background_state_file "$PREVIOUS_THEME_NAME") || return
current_background=$(readlink -f "$CURRENT_BACKGROUND_LINK" 2>/dev/null || true)
[[ -f $current_background ]] || return
mkdir -p "$THEME_BACKGROUND_STATE_PATH"
printf '%s\n' "$current_background" >"$state_file"
}
background_transition_uses_snapshots() {
local next_background="$1"
local current_background
@@ -86,7 +106,7 @@ choose_theme_background() {
local theme_path="${1:-$CURRENT_THEME_PATH}"
local current_theme_backgrounds="$CURRENT_THEME_PATH/backgrounds"
local backgrounds=()
local current_background index next_index i
local current_background remembered_background state_file index next_index i
CHOSEN_THEME_BACKGROUND=""
mapfile -d '' -t backgrounds < <(
@@ -98,25 +118,40 @@ choose_theme_background() {
(( ${#backgrounds[@]} > 0 )) || return 1
current_background=$(readlink "$CURRENT_BACKGROUND_LINK" 2>/dev/null || true)
if [[ $theme_path != $CURRENT_THEME_PATH && ${current_background%/*} == $current_theme_backgrounds ]]; then
current_background="$theme_path/backgrounds/${current_background##*/}"
fi
index=-1
for i in "${!backgrounds[@]}"; do
if [[ ${backgrounds[$i]} == $current_background ]]; then
index=$i
break
if [[ $PREVIOUS_THEME_NAME == "$THEME_NAME" ]]; then
current_background=$(readlink "$CURRENT_BACKGROUND_LINK" 2>/dev/null || true)
if [[ $theme_path != $CURRENT_THEME_PATH && ${current_background%/*} == $current_theme_backgrounds ]]; then
current_background="$theme_path/backgrounds/${current_background##*/}"
fi
done
if (( index == -1 )); then
CHOSEN_THEME_BACKGROUND="${backgrounds[0]}"
else
next_index=$(((index + 1) % ${#backgrounds[@]}))
CHOSEN_THEME_BACKGROUND="${backgrounds[$next_index]}"
index=-1
for i in "${!backgrounds[@]}"; do
if [[ ${backgrounds[$i]} == $current_background ]]; then
index=$i
break
fi
done
if (( index != -1 )); then
next_index=$(((index + 1) % ${#backgrounds[@]}))
CHOSEN_THEME_BACKGROUND="${backgrounds[$next_index]}"
else
CHOSEN_THEME_BACKGROUND="${backgrounds[0]}"
fi
return
fi
state_file=$(theme_background_state_file "$THEME_NAME" 2>/dev/null || true)
remembered_background=$(cat "$state_file" 2>/dev/null || true)
if [[ $theme_path != $CURRENT_THEME_PATH && ${remembered_background%/*} == $current_theme_backgrounds ]]; then
remembered_background="$theme_path/backgrounds/${remembered_background##*/}"
fi
if [[ -f $remembered_background ]]; then
CHOSEN_THEME_BACKGROUND="$remembered_background"
return
fi
CHOSEN_THEME_BACKGROUND="${backgrounds[0]}"
}
choose_staged_theme_background() {
@@ -296,6 +331,9 @@ fi
exec 9>"$THEME_SET_LOCK"
flock 9
PREVIOUS_THEME_NAME=$(cat "$CURRENT_THEME_NAME_PATH" 2>/dev/null || true)
remember_current_theme_background
# Setup clean next theme directory (for atomic theme config swapping)
rm -rf "$NEXT_THEME_PATH"
mkdir -p "$NEXT_THEME_PATH"
@@ -338,7 +376,7 @@ rm -rf "$CURRENT_THEME_PATH"
mv "$NEXT_THEME_PATH" "$CURRENT_THEME_PATH"
# Store theme name for reference
echo "$THEME_NAME" >"$HOME/.local/state/omarchy/current/theme.name"
echo "$THEME_NAME" >"$CURRENT_THEME_NAME_PATH"
# Make the running shell pick up the new palette immediately while the rest of
# the theme hooks run.
@@ -0,0 +1,130 @@
#!/bin/bash
set -euo pipefail
source "$(dirname "$0")/base-test.sh"
test_tmp=$(mktemp -d)
trap 'rm -rf "$test_tmp"' EXIT
test_home="$test_tmp/home"
runtime_dir="$test_tmp/runtime"
current_state="$test_home/.local/state/omarchy/current"
background_state="$test_home/.local/state/omarchy/theme-backgrounds"
mkdir -p "$test_home" "$runtime_dir"
set_theme() {
HOME="$test_home" XDG_RUNTIME_DIR="$runtime_dir" OMARCHY_PATH="$ROOT" PATH="$ROOT/bin:$PATH" \
OMARCHY_THEME_HEADLESS=1 "$ROOT/bin/omarchy-theme-set" "$1" >/dev/null
}
current_background_name() {
basename "$(readlink "$current_state/background")"
}
theme_a="tokyo-night"
theme_b="catppuccin"
set_theme "$theme_a"
mapfile -t theme_a_backgrounds < <(find "$current_state/theme/backgrounds" -maxdepth 1 -type f -print | sort)
(( ${#theme_a_backgrounds[@]} > 1 )) || fail "test theme has multiple backgrounds"
theme_a_first=${theme_a_backgrounds[0]##*/}
theme_a_selected_path=${theme_a_backgrounds[1]}
theme_a_selected=${theme_a_selected_path##*/}
ln -nsf "$theme_a_selected_path" "$current_state/background"
set_theme "$theme_b"
mapfile -t theme_b_backgrounds < <(find "$current_state/theme/backgrounds" -maxdepth 1 -type f -print | sort)
(( ${#theme_b_backgrounds[@]} > 1 )) || fail "second test theme has multiple backgrounds"
theme_b_first=${theme_b_backgrounds[0]##*/}
common_background=$(comm -12 \
<(find "$ROOT/themes/$theme_a/backgrounds" -maxdepth 1 -type f -printf '%f\n' | sort) \
<(find "$current_state/theme/backgrounds" -maxdepth 1 -type f -printf '%f\n' | sort) | head -n 1)
[[ -n $common_background ]] || fail "test themes share a background filename"
theme_b_common_path=$(find "$current_state/theme/backgrounds" -maxdepth 1 -type f -name "$common_background" -print -quit)
ln -nsf "$theme_b_common_path" "$current_state/background"
[[ $(<"$background_state/$theme_a") == "$theme_a_selected_path" ]] || fail "theme switch remembers the outgoing background path"
pass "theme switch remembers the outgoing background path"
set_theme "$theme_a"
[[ $(current_background_name) == "$theme_a_selected" ]] || fail "shared filenames do not override the remembered background"
pass "shared filenames do not override the remembered background"
set_theme "$theme_b"
[[ $(current_background_name) == "$common_background" ]] || fail "themes remember backgrounds independently"
pass "themes remember backgrounds independently"
external_background="$test_tmp/external-background.webp"
cp "$(readlink -f "$current_state/background")" "$external_background"
ln -nsf "$external_background" "$current_state/background"
set_theme "$theme_a"
set_theme "$theme_b"
[[ $(readlink -f "$current_state/background") == "$external_background" ]] || fail "theme switch restores an external background path"
pass "theme switch restores an external background path"
set_theme "$theme_b"
[[ $(current_background_name) == "$theme_b_first" ]] || fail "reapplying a theme with an external background falls back to the first image"
pass "reapplying a theme with an external background falls back to the first image"
set_theme "$theme_a"
user_background_dir="$test_home/.config/omarchy/backgrounds/$theme_a"
user_background="$user_background_dir/$theme_a_first"
mkdir -p "$user_background_dir"
cp "${theme_a_backgrounds[0]}" "$user_background"
ln -nsf "$user_background" "$current_state/background"
set_theme "$theme_b"
set_theme "$theme_a"
[[ $(readlink -f "$current_state/background") == "$user_background" ]] || fail "theme switch distinguishes duplicate background filenames"
pass "theme switch distinguishes duplicate background filenames"
set_theme "$theme_b"
rm -f "$user_background"
printf '%s\n' "$test_tmp/missing-background.webp" >"$background_state/$theme_a"
set_theme "$theme_a"
[[ $(current_background_name) == "$theme_a_first" ]] || fail "missing remembered background falls back to the first image"
pass "missing remembered background falls back to the first image"
set_theme "$theme_a"
[[ $(current_background_name) == "$theme_a_selected" ]] || fail "reapplying the active theme still cycles backgrounds"
pass "reapplying the active theme still cycles backgrounds"
printf '%s\n' "../escaped" >"$current_state/theme.name"
set_theme "$theme_b"
[[ ! -e $test_home/.local/state/omarchy/escaped ]] || fail "invalid theme names cannot escape the background state directory"
pass "invalid theme names cannot escape the background state directory"
# Interactive switches choose before swapping the staged theme into place.
source <(awk '
/^(theme_background_state_file|choose_theme_background|choose_staged_theme_background)\(\) \{/ { copying=1 }
copying { print }
copying && /^}$/ { copying=0 }
' "$ROOT/bin/omarchy-theme-set")
HOME="$test_home"
CURRENT_THEME_PATH="$current_state/theme"
NEXT_THEME_PATH="$current_state/next-theme"
CURRENT_BACKGROUND_LINK="$current_state/background"
THEME_BACKGROUND_STATE_PATH="$background_state"
THEME_NAME="staged-test"
PREVIOUS_THEME_NAME="$theme_b"
mkdir -p "$NEXT_THEME_PATH/backgrounds"
printf 'first\n' >"$NEXT_THEME_PATH/backgrounds/first.png"
printf 'selected\n' >"$NEXT_THEME_PATH/backgrounds/selected.mp4"
printf '%s\n' "$CURRENT_THEME_PATH/backgrounds/selected.mp4" >"$background_state/$THEME_NAME"
choose_staged_theme_background
[[ $CHOSEN_THEME_BACKGROUND == "$CURRENT_THEME_PATH/backgrounds/selected.mp4" ]] || fail "staged selection restores a remembered file absent from the outgoing theme"
pass "staged selection restores a remembered file absent from the outgoing theme"
printf 'outgoing only\n' >"$CURRENT_THEME_PATH/backgrounds/outgoing-only.png"
printf '%s\n' "$CURRENT_THEME_PATH/backgrounds/outgoing-only.png" >"$background_state/$THEME_NAME"
choose_staged_theme_background
[[ $CHOSEN_THEME_BACKGROUND == "$CURRENT_THEME_PATH/backgrounds/first.png" ]] || fail "staged selection rejects remembered files absent from the incoming theme"
pass "staged selection rejects remembered files absent from the incoming theme"
PREVIOUS_THEME_NAME="$THEME_NAME"
ln -nsf "$CURRENT_THEME_PATH/backgrounds/first.png" "$CURRENT_BACKGROUND_LINK"
choose_staged_theme_background
[[ $CHOSEN_THEME_BACKGROUND == "$CURRENT_THEME_PATH/backgrounds/selected.mp4" ]] || fail "staged same-theme selection still cycles backgrounds"
pass "staged same-theme selection still cycles backgrounds"
+1
View File
@@ -299,6 +299,7 @@ NEXT_THEME_PATH="$transition_home/.local/state/omarchy/current/next-theme"
CURRENT_BACKGROUND_LINK="$transition_home/.local/state/omarchy/current/background"
BACKGROUND_TRANSITION_CACHE="$transition_home/.cache/omarchy/background-transitions"
THEME_NAME="video-test"
PREVIOUS_THEME_NAME="$THEME_NAME"
HOME="$transition_home"
mkdir -p "$CURRENT_THEME_PATH/backgrounds" "$NEXT_THEME_PATH/backgrounds" "$HOME/.config/omarchy/backgrounds/$THEME_NAME"
printf 'old image\n' >"$CURRENT_THEME_PATH/backgrounds/old.png"