diff --git a/.config/systemd/user/restore-gnome.service b/.config/systemd/user/restore-gnome.service index 08c5589..1651a82 100644 --- a/.config/systemd/user/restore-gnome.service +++ b/.config/systemd/user/restore-gnome.service @@ -4,6 +4,7 @@ Before=gnome-session-pre.target ConditionPathIsDirectory=%h/.config/gnome-settings [Service] +Environment=FRESH_SESSION=1 Type=oneshot ExecStart=%h/.local/bin/restore-gnome diff --git a/.local/bin/randomize-background b/.local/bin/randomize-background index 44880ce..6f67f23 100755 --- a/.local/bin/randomize-background +++ b/.local/bin/randomize-background @@ -8,13 +8,25 @@ # - Pairs => Both "-d.jpg" and "-l.jpg" exist # - Singles => Any other "*.jpg" not following the -d/-l scheme, # used as dark and light at the same time +# +# The live `gsettings` URIs point at uniquely named copies +# because `gnome-shell` caches background images by file URI; +# `restore-gnome` cleans up that temporary state during the next login set -eu +XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" +XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}" +XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}" + + SOURCE_DIR="$HOME/Cloud/Null-Tech/Backgrounds" -TARGET_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/backgrounds" -STATE_FILE="${XDG_STATE_HOME:-$HOME/.local/state}/current-background.txt" +TARGET_DIR="$XDG_DATA_HOME/backgrounds" + + +LOCAL_INI="$XDG_CONFIG_HOME/gnome-settings/local/temporary_background.ini" +STATE_FILE="$XDG_STATE_HOME/current-background.txt" [ -d "$SOURCE_DIR" ] || { echo "No such folder: $SOURCE_DIR" >&2; exit 1; } @@ -43,33 +55,87 @@ candidates=$( done ) - if [ -z "$candidates" ]; then echo "No usable *.jpg files in: $SOURCE_DIR" >&2 exit 1 fi - echo "Found $(printf '%s\n' "$candidates" | wc -l) candidate(s)" # The glob expands alphabetically => "$candidates" is already sorted # => Pick the first candidate sorting strictly after the last-used one, -# falling back to the first (e.g., for start, wrap-around, or missing state file) -last=$(cat "$STATE_FILE" 2>/dev/null || true) -chosen=$(printf '%s\n' "$candidates" | awk -F '\t' -v last="$last" '$1 > last { print; exit }') -[ -n "$chosen" ] || chosen=$(printf '%s\n' "$candidates" | head -n 1) +# falling back to the first one if necessary +# (e.g., for start, wrap-around, or missing state file) +last_background=$(cat "$STATE_FILE" 2>/dev/null || true) +next_background=$(printf '%s\n' "$candidates" | awk -F '\t' -v last_background="$last_background" '$1 > last_background { print; exit }') +[ -n "$next_background" ] || next_background=$(printf '%s\n' "$candidates" | head -n 1) -dark=$(printf '%s' "$chosen" | cut -f 1) -light=$(printf '%s' "$chosen" | cut -f 2) -echo "Chosen: $(basename "$dark")" +dark_source=$(printf '%s' "$next_background" | cut -f 1) +light_source=$(printf '%s' "$next_background" | cut -f 2) +echo "Chosen background: $(basename "$dark_source")" -mkdir -p "$TARGET_DIR" "$(dirname "$STATE_FILE")" -cp -- "$dark" "$TARGET_DIR/dark.jpg" -cp -- "$light" "$TARGET_DIR/light.jpg" -printf '%s\n' "$dark" > "$STATE_FILE" +dark_target="$TARGET_DIR/dark.jpg" +light_target="$TARGET_DIR/light.jpg" + +# Create a unique name per run +# so that the URIs below never repeat +timestamp=$(date +%s) + +dark_live_target="$TARGET_DIR/dark-tmp-$timestamp.jpg" +light_live_target="$TARGET_DIR/light-tmp-$timestamp.jpg" + + +mkdir -p \ + "$TARGET_DIR" \ + "$(dirname "$LOCAL_INI")" \ + "$(dirname "$STATE_FILE")" + + +# Fixed-name copies, referenced as login-time defaults in the *.ini files +cp -- "$dark_source" "$dark_target" +cp -- "$light_source" "$light_target" + + +# Uniquely named copies for the live `gsettings` URIs +# to ensure `gnome-shell` uses the correct files right away +cp -- "$dark_source" "$dark_live_target" +cp -- "$light_source" "$light_live_target" + + +printf '%s\n' "$dark_source" > "$STATE_FILE" + + +Background=org.gnome.desktop.background +Screensaver=org.gnome.desktop.screensaver + +gsettings set $Background picture-uri-dark "file://$dark_live_target" +gsettings set $Background picture-uri "file://$light_live_target" +gsettings set $Screensaver picture-uri "file://$dark_live_target" + + +# Persist the unique URIs for `restore-gnome`, +# which loads local/*.ini after the base *.ini files +cat > "$LOCAL_INI" < "$BACKUP_DIR/$(date +%Y%m%d-%H%M%S).ini" ls -1t "$BACKUP_DIR"/*.ini | tail -n +11 | xargs -r rm -- +# Remove temporary background image files +# created by ~/.local/bin/randomize-background +if [ "${FRESH_SESSION:-}" = "1" ]; then + echo "Removing session-scoped background image files" + rm -f "$XDG_CONFIG_HOME/gnome-settings/local/temporary_background.ini" + find "$XDG_DATA_HOME/backgrounds" -name '*-tmp-*.jpg' -delete 2>/dev/null || true +fi + echo "Resetting managed subtrees in dconf"