Move current theme state to local state

This commit is contained in:
Ryan Hughes
2026-06-09 19:48:37 -04:00
parent 29c4a20a86
commit 0f5e81143e
45 changed files with 261 additions and 72 deletions
+2 -2
View File
@@ -8,7 +8,7 @@ omarchy-pkg-add helix
mkdir -p ~/.config/helix/themes
# Symlink the rendered Omarchy theme so Helix tracks the active theme
ln -sf ~/.config/omarchy/current/theme/helix.toml ~/.config/helix/themes/omarchy.toml
ln -sf "$HOME/.local/state/omarchy/current/theme/helix.toml" ~/.config/helix/themes/omarchy.toml
# Only seed a config.toml if the user does not already have one
if [[ ! -f ~/.config/helix/config.toml ]]; then
@@ -18,7 +18,7 @@ EOF
fi
# Ensure the symlink target exists for users whose current theme predates this template
if [[ ! -e ~/.config/omarchy/current/theme/helix.toml ]]; then
if [[ ! -e $HOME/.local/state/omarchy/current/theme/helix.toml ]]; then
omarchy-theme-refresh
fi
+1 -1
View File
@@ -2,7 +2,7 @@
# omarchy:summary=Preview a Plymouth boot screen with custom colors and logo
# omarchy:args=<background-hex> <text-hex> <path-to-logo.png> <output-path>
# omarchy:examples=omarchy plymouth preview '#1d2021' '#ebdbb2' ~/.config/omarchy/current/theme/plymouth/logo.png /tmp/plymouth-preview.png
# omarchy:examples=omarchy plymouth preview '#1d2021' '#ebdbb2' ~/.local/state/omarchy/current/theme/plymouth/logo.png /tmp/plymouth-preview.png
# Render a Plymouth login-screen preview PNG by compositing the staged omarchy
# theme assets (recolored with the given text color) onto the background.
+1 -1
View File
@@ -2,7 +2,7 @@
# omarchy:summary=Set the Plymouth boot theme colors and logo
# omarchy:args=<background-hex> <text-hex> <path-to-logo.png>
# omarchy:examples=omarchy plymouth set '#1d2021' '#ebdbb2' ~/.config/omarchy/current/theme/plymouth/logo.png
# omarchy:examples=omarchy plymouth set '#1d2021' '#ebdbb2' ~/.local/state/omarchy/current/theme/plymouth/logo.png
# omarchy:requires-sudo=true
# Configure the Plymouth boot theme with a custom background color, text color, and logo.
+1 -1
View File
@@ -75,7 +75,7 @@ valid_hex "$background_color" || fallback
omarchy-cmd-present magick || fallback
if [[ -z $background_path ]]; then
background_path=$(readlink -f "$HOME/.config/omarchy/current/background" 2>/dev/null || true)
background_path=$(readlink -f "$HOME/.local/state/omarchy/current/background" 2>/dev/null || true)
fi
[[ -f $background_path ]] || fallback
+2 -2
View File
@@ -2,9 +2,9 @@
# omarchy:summary=Cache background switcher thumbnails for the current theme
theme_name=$(cat "$HOME/.config/omarchy/current/theme.name" 2>/dev/null)
theme_name=$(cat "$HOME/.local/state/omarchy/current/theme.name" 2>/dev/null)
omarchy-menu-images \
--cache-only \
"$HOME/.config/omarchy/current/theme/backgrounds" \
"$HOME/.local/state/omarchy/current/theme/backgrounds" \
"$HOME/.config/omarchy/backgrounds/$theme_name"
+1 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Show current background
# omarchy:examples=omarchy theme bg current
BACKGROUND_PATH=$(readlink -f "$HOME/.config/omarchy/current/background" 2>/dev/null)
BACKGROUND_PATH=$(readlink -f "$HOME/.local/state/omarchy/current/background" 2>/dev/null)
if [[ -n $BACKGROUND_PATH ]]; then
basename -- "$BACKGROUND_PATH" | perl -pe 's/\.[^.]+$//; s/^\d+-//; s/-/ /g; s/\b(\w)/\U$1/g'
+1 -1
View File
@@ -2,7 +2,7 @@
# omarchy:summary=Open the current theme's user background folder
CURRENT_THEME_NAME=$(cat "$HOME/.config/omarchy/current/theme.name")
CURRENT_THEME_NAME=$(cat "$HOME/.local/state/omarchy/current/theme.name")
THEME_USER_BACKGROUNDS="$HOME/.config/omarchy/backgrounds/$CURRENT_THEME_NAME"
mkdir -p "$THEME_USER_BACKGROUNDS"
+3 -3
View File
@@ -3,10 +3,10 @@
# omarchy:summary=Cycle to the next background for the current theme
# omarchy:examples=omarchy theme bg next
THEME_NAME=$(cat "$HOME/.config/omarchy/current/theme.name" 2>/dev/null)
THEME_BACKGROUNDS_PATH="$HOME/.config/omarchy/current/theme/backgrounds/"
THEME_NAME=$(cat "$HOME/.local/state/omarchy/current/theme.name" 2>/dev/null)
THEME_BACKGROUNDS_PATH="$HOME/.local/state/omarchy/current/theme/backgrounds/"
USER_BACKGROUNDS_PATH="$HOME/.config/omarchy/backgrounds/$THEME_NAME/"
CURRENT_BACKGROUND_LINK="$HOME/.config/omarchy/current/background"
CURRENT_BACKGROUND_LINK="$HOME/.local/state/omarchy/current/background"
mapfile -d '' -t BACKGROUNDS < <(
find -L "$USER_BACKGROUNDS_PATH" "$THEME_BACKGROUNDS_PATH" -maxdepth 1 -type f \
+1 -1
View File
@@ -10,7 +10,7 @@ if [[ -z $1 ]]; then
fi
BACKGROUND="$(realpath "$1")"
CURRENT_BACKGROUND_LINK="$HOME/.config/omarchy/current/background"
CURRENT_BACKGROUND_LINK="$HOME/.local/state/omarchy/current/background"
if [[ ! -f $BACKGROUND ]]; then
echo "File does not exist: $BACKGROUND" >&2
+3 -3
View File
@@ -5,10 +5,10 @@
# omarchy:name=bg-switcher
# omarchy:aliases=omarchy background
theme_name=$(cat "$HOME/.config/omarchy/current/theme.name" 2>/dev/null)
current_background=$(readlink -f "$HOME/.config/omarchy/current/background" 2>/dev/null)
theme_name=$(cat "$HOME/.local/state/omarchy/current/theme.name" 2>/dev/null)
current_background=$(readlink -f "$HOME/.local/state/omarchy/current/background" 2>/dev/null)
omarchy-menu-images \
--selected "$current_background" \
"$HOME/.config/omarchy/current/theme/backgrounds" \
"$HOME/.local/state/omarchy/current/theme/backgrounds" \
"$HOME/.config/omarchy/backgrounds/$theme_name"
+1 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Show current theme
# omarchy:examples=omarchy theme current
THEME_NAME_PATH="$HOME/.config/omarchy/current/theme.name"
THEME_NAME_PATH="$HOME/.local/state/omarchy/current/theme.name"
if [[ -f $THEME_NAME_PATH ]]; then
cat $THEME_NAME_PATH | sed -E 's/(^|-)([a-z])/\1\u\2/g; s/-/ /g'
+1 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Print OSC sequences for an Omarchy color theme
# omarchy:hidden=true
theme="${1:-$HOME/.config/omarchy/current/theme/colors.toml}"
theme="${1:-$HOME/.local/state/omarchy/current/theme/colors.toml}"
[[ -f $theme ]] || exit 0
+1 -1
View File
@@ -2,7 +2,7 @@
# omarchy:summary=Refresh the current theme from its templates.
THEME_NAME_PATH="$HOME/.config/omarchy/current/theme.name"
THEME_NAME_PATH="$HOME/.local/state/omarchy/current/theme.name"
if [[ -f $THEME_NAME_PATH ]]; then
OMARCHY_THEME_SKIP_BACKGROUND=1 omarchy-theme-set "$(cat $THEME_NAME_PATH)"
-1
View File
@@ -19,7 +19,6 @@ else
fi
THEMES_DIR="$HOME/.config/omarchy/themes"
CURRENT_DIR="$HOME/.config/omarchy/current"
THEME_PATH="$THEMES_DIR/$THEME_NAME"
# Ensure a theme was set
+4 -4
View File
@@ -9,9 +9,9 @@ if [[ -z $1 ]]; then
exit 1
fi
CURRENT_THEME_PATH="$HOME/.config/omarchy/current/theme"
NEXT_THEME_PATH="$HOME/.config/omarchy/current/next-theme"
CURRENT_BACKGROUND_LINK="$HOME/.config/omarchy/current/background"
CURRENT_THEME_PATH="$HOME/.local/state/omarchy/current/theme"
NEXT_THEME_PATH="$HOME/.local/state/omarchy/current/next-theme"
CURRENT_BACKGROUND_LINK="$HOME/.local/state/omarchy/current/background"
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"
@@ -165,7 +165,7 @@ rm -rf "$CURRENT_THEME_PATH"
mv "$NEXT_THEME_PATH" "$CURRENT_THEME_PATH"
# Store theme name for reference
echo "$THEME_NAME" >"$HOME/.config/omarchy/current/theme.name"
echo "$THEME_NAME" >"$HOME/.local/state/omarchy/current/theme.name"
# Make the running shell pick up the new palette immediately while the rest of
# the theme hooks run.
+1 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Apply the current theme color to Chromium, Chrome, Edge, and Brave
# omarchy:hidden=true
CHROMIUM_THEME=~/.config/omarchy/current/theme/chromium.theme
CHROMIUM_THEME=$HOME/.local/state/omarchy/current/theme/chromium.theme
if [[ -f $CHROMIUM_THEME ]]; then
THEME_RGB_COLOR=$(<$CHROMIUM_THEME)
+1 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Apply current Omarchy theme colors to running Foot terminals
# omarchy:hidden=true
colors_toml=~/.config/omarchy/current/theme/colors.toml
colors_toml=$HOME/.local/state/omarchy/current/theme/colors.toml
if [[ ! -f $colors_toml ]] || ! pgrep -x foot >/dev/null; then
exit 0
+2 -2
View File
@@ -10,7 +10,7 @@ if [[ -z ${DBUS_SESSION_BUS_ADDRESS:-} ]]; then
exit 0
fi
THEME_DIR=~/.config/omarchy/current/theme
THEME_DIR=$HOME/.local/state/omarchy/current/theme
COLORS_FILE="$THEME_DIR/colors.toml"
# In-tree light themes now declare `mode = "light"` in colors.toml instead of
@@ -50,7 +50,7 @@ else
fi
# Change gnome icon theme color
GNOME_ICONS_THEME=~/.config/omarchy/current/theme/icons.theme
GNOME_ICONS_THEME=$HOME/.local/state/omarchy/current/theme/icons.theme
if [[ -f $GNOME_ICONS_THEME ]]; then
gsettings set org.gnome.desktop.interface icon-theme "$(<$GNOME_ICONS_THEME)"
else
+1 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Apply the current theme keyboard color to ASUS ROG keyboards
# omarchy:hidden=true
ASUSCTL_THEME=~/.config/omarchy/current/theme/keyboard.rgb
ASUSCTL_THEME=$HOME/.local/state/omarchy/current/theme/keyboard.rgb
if omarchy-cmd-present asusctl; then
asusctl aura effect static -c $(sed 's/^#//' $ASUSCTL_THEME)
+1 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Apply the current theme keyboard color to Framework Laptop 16 keyboards
# omarchy:hidden=true
FRAMEWORK16_THEME=~/.config/omarchy/current/theme/keyboard.rgb
FRAMEWORK16_THEME=$HOME/.local/state/omarchy/current/theme/keyboard.rgb
if omarchy-cmd-present qmk_hid && [[ -f $FRAMEWORK16_THEME ]]; then
hex=$(cat "$FRAMEWORK16_THEME")
+1 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Sync Omarchy theme to all Obsidian vaults
# omarchy:hidden=true
CURRENT_THEME_DIR="$HOME/.config/omarchy/current/theme"
CURRENT_THEME_DIR="$HOME/.local/state/omarchy/current/theme"
[[ -f $CURRENT_THEME_DIR/obsidian.css ]] || exit 0
+1 -1
View File
@@ -6,7 +6,7 @@
set -euo pipefail
CURRENT_THEME_PATH="$HOME/.config/omarchy/current/theme"
CURRENT_THEME_PATH="$HOME/.local/state/omarchy/current/theme"
PI_SOURCE_PATH="$CURRENT_THEME_PATH/pi.json"
PI_AGENT_DIR="$HOME/.pi/agent"
PI_THEME_DIR="$PI_AGENT_DIR/themes"
+1 -1
View File
@@ -5,7 +5,7 @@
TEMPLATES_DIR="$OMARCHY_PATH/default/themed"
USER_TEMPLATES_DIR="$HOME/.config/omarchy/themed"
NEXT_THEME_DIR="$HOME/.config/omarchy/current/next-theme"
NEXT_THEME_DIR="$HOME/.local/state/omarchy/current/next-theme"
COLORS_FILE="$NEXT_THEME_DIR/colors.toml"
declare -A THEME_COLORS
+1 -1
View File
@@ -3,7 +3,7 @@
# omarchy:summary=Sync current Omarchy theme environment into tmux
# omarchy:hidden=true
CURRENT_THEME_PATH="$HOME/.config/omarchy/current/theme"
CURRENT_THEME_PATH="$HOME/.local/state/omarchy/current/theme"
GUM_ENV="$CURRENT_THEME_PATH/gum_env.lua"
COLORS_TOML="$CURRENT_THEME_PATH/colors.toml"
+2 -2
View File
@@ -3,8 +3,8 @@
# omarchy:summary=Sync Omarchy theme to VS Code, VSCodium, and Cursor
# omarchy:hidden=true
VS_CODE_THEME_DESCRIPTOR="$HOME/.config/omarchy/current/theme/vscode.json"
GENERATED_THEME="$HOME/.config/omarchy/current/theme/vscode-theme.json"
VS_CODE_THEME_DESCRIPTOR="$HOME/.local/state/omarchy/current/theme/vscode.json"
GENERATED_THEME="$HOME/.local/state/omarchy/current/theme/vscode-theme.json"
GENERATED_EXTENSION_NAME="omarchy-theme"
GENERATED_EXTENSION_ID="local.$GENERATED_EXTENSION_NAME"
GENERATED_EXTENSION_VERSION="1.0.0"
+1 -1
View File
@@ -102,7 +102,7 @@ if [[ ! -f $fast_signature_file ]] || ! cmp -s "$fast_signature_file" <(printf '
printf '%s' "$fast_signature" >"$fast_signature_file"
fi
current_theme=$(cat "$HOME/.config/omarchy/current/theme.name" 2>/dev/null)
current_theme=$(cat "$HOME/.local/state/omarchy/current/theme.name" 2>/dev/null)
selected_preview=""
for extension in png jpg jpeg webp gif bmp; do
if [[ -e $preview_dir/$current_theme.$extension ]]; then
+68 -7
View File
@@ -1873,10 +1873,53 @@ EOF
fi
mkdir -p "$HOME/.config/omarchy/themes" "$HOME/.config/btop/themes"
ln -snf "$HOME/.config/omarchy/current/theme/btop.theme" "$HOME/.config/btop/themes/current.theme"
if [[ ! -e $HOME/.config/omarchy/current/background && -d $HOME/.config/omarchy/current/theme/backgrounds ]]; then
background=$(find "$HOME/.config/omarchy/current/theme/backgrounds" -maxdepth 1 -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' \) | sort | head -n1)
[[ -n ${background:-} ]] && ln -snf "$background" "$HOME/.config/omarchy/current/background"
legacy_current_dir="$HOME/.config/omarchy/current"
current_state_dir="$HOME/.local/state/omarchy/current"
if [[ -e $legacy_current_dir || -L $legacy_current_dir ]]; then
mkdir -p "$HOME/.local/state/omarchy"
if [[ ! -e $current_state_dir && ! -L $current_state_dir ]]; then
mv "$legacy_current_dir" "$current_state_dir"
else
if [[ -d $legacy_current_dir && -d $current_state_dir ]]; then
cp -an "$legacy_current_dir/." "$current_state_dir/" 2>/dev/null || true
fi
rm -rf "$legacy_current_dir"
fi
fi
replace_legacy_current_path() {
local file="$1"
[[ -f $file ]] || return 0
python3 - "$file" "$HOME" <<'PY'
from pathlib import Path
import sys
path = Path(sys.argv[1])
home = sys.argv[2]
text = path.read_text()
replacements = {
f"{home}/.config/omarchy/current": f"{home}/.local/state/omarchy/current",
"~/.config/omarchy/current": "~/.local/state/omarchy/current",
"../omarchy/current": "../../.local/state/omarchy/current",
}
for old, new in replacements.items():
text = text.replace(old, new)
path.write_text(text)
PY
}
for file in \
"$HOME/.config/alacritty/alacritty.toml" \
"$HOME/.config/foot/foot.ini" \
"$HOME/.config/ghostty/config" \
"$HOME/.config/hypr/hyprland.conf" \
"$HOME/.config/hyprland-preview-share-picker/config.yaml" \
"$HOME/.config/kitty/kitty.conf"; do
replace_legacy_current_path "$file"
done
ln -snf "$HOME/.local/state/omarchy/current/theme/btop.theme" "$HOME/.config/btop/themes/current.theme"
if [[ ! -e $HOME/.local/state/omarchy/current/background && -d $HOME/.local/state/omarchy/current/theme/backgrounds ]]; then
background=$(find "$HOME/.local/state/omarchy/current/theme/backgrounds" -maxdepth 1 -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' \) | sort | head -n1)
[[ -n ${background:-} ]] && ln -snf "$background" "$HOME/.local/state/omarchy/current/background"
fi
mkdir -p "$HOME/.config/wireplumber/wireplumber.conf.d"
@@ -2037,9 +2080,20 @@ write_legacy_theme_hyprland_conf() {
set -euo pipefail
hyprland_conf="$HOME/.config/hypr/hyprland.conf"
[[ -f $hyprland_conf ]] || exit 0
python3 - "$hyprland_conf" "$HOME" <<'PY'
from pathlib import Path
import sys
path = Path(sys.argv[1])
home = sys.argv[2]
text = path.read_text()
text = text.replace(f"{home}/.config/omarchy/current", f"{home}/.local/state/omarchy/current")
text = text.replace("~/.config/omarchy/current", "~/.local/state/omarchy/current")
path.write_text(text)
PY
grep -q 'current/theme/hyprland.conf' "$hyprland_conf" || exit 0
theme_dir="$HOME/.config/omarchy/current/theme"
theme_dir="$HOME/.local/state/omarchy/current/theme"
colors="$theme_dir/colors.toml"
target="$theme_dir/hyprland.conf"
mkdir -p "$theme_dir"
@@ -2068,14 +2122,21 @@ refresh_current_theme_after_upgrade() {
theme_name=$(run_as_user env HOME="$target_home" bash -c '
set -euo pipefail
theme_name_path="$HOME/.config/omarchy/current/theme.name"
current_theme_path="$HOME/.config/omarchy/current/theme"
theme_name_path="$HOME/.local/state/omarchy/current/theme.name"
current_theme_path="$HOME/.local/state/omarchy/current/theme"
legacy_theme_name_path="$HOME/.config/omarchy/current/theme.name"
legacy_current_theme_path="$HOME/.config/omarchy/current/theme"
if [[ -f $theme_name_path ]]; then
read -r theme_name <"$theme_name_path" || true
printf "%s" "${theme_name:-}"
elif [[ -f $legacy_theme_name_path ]]; then
read -r theme_name <"$legacy_theme_name_path" || true
printf "%s" "${theme_name:-}"
elif [[ -L $current_theme_path ]]; then
basename -- "$(readlink "$current_theme_path")"
elif [[ -L $legacy_current_theme_path ]]; then
basename -- "$(readlink "$legacy_current_theme_path")"
else
printf ""
fi
+1 -1
View File
@@ -1,4 +1,4 @@
general.import = [ "~/.config/omarchy/current/theme/alacritty.toml" ]
general.import = [ "~/.local/state/omarchy/current/theme/alacritty.toml" ]
[env]
TERM = "xterm-256color"
+1 -1
View File
@@ -1,5 +1,5 @@
[main]
include=~/.config/omarchy/current/theme/foot.ini
include=~/.local/state/omarchy/current/theme/foot.ini
term=xterm-256color
font=JetBrainsMono Nerd Font:size=9
pad=14x14
+1 -1
View File
@@ -1,5 +1,5 @@
# Dynamic theme colors
config-file = ?"~/.config/omarchy/current/theme/ghostty.conf"
config-file = ?"~/.local/state/omarchy/current/theme/ghostty.conf"
# Font
font-family = "JetBrainsMono Nerd Font"
@@ -1,7 +1,7 @@
# paths to stylesheets on the filesystem which should be applied to the application
#
# relative paths are resolved relative to the location of the config file
stylesheets: ["../omarchy/current/theme/hyprland-preview-share-picker.css"]
stylesheets: ["../../.local/state/omarchy/current/theme/hyprland-preview-share-picker.css"]
# default page selected when the picker is opened
default_page: outputs
+1 -1
View File
@@ -1,4 +1,4 @@
include ~/.config/omarchy/current/theme/kitty.conf
include ~/.local/state/omarchy/current/theme/kitty.conf
# Font
font_family JetBrainsMono Nerd Font
+7 -2
View File
@@ -1,7 +1,12 @@
-- Hyprland bootstrap for Omarchy's Lua module path.
-- Load user modules from ~/.config and Omarchy defaults from $OMARCHY_PATH.
package.path = os.getenv("HOME")
local home = os.getenv("HOME")
-- Load generated state from ~/.local/state, user modules from ~/.config, and
-- Omarchy defaults from $OMARCHY_PATH.
package.path = home
.. "/.local/state/?.lua;"
.. home
.. "/.config/?.lua;"
.. (os.getenv("OMARCHY_PATH") or "/usr/share/omarchy")
.. "/?.lua;"
+8 -1
View File
@@ -42,6 +42,11 @@ Three layers populate `$HOME`:
`/etc/skel` only fires at user creation. Existing users picking up new
defaults must use the resync command.
Current generated theme state lives under
`~/.local/state/omarchy/current/`. Keep `~/.config/omarchy/` for files a user
may intentionally version in a dotfile manager, such as user themes, hooks,
shell layout, plugin sources, and themed template overrides.
## Build-time map (repo → installed paths)
```
@@ -284,4 +289,6 @@ return to the packaged default.
| Noninteractive root fix for existing installs | `migrations/system/<unix-timestamp>.sh` |
| User/session fix for existing installs | `migrations/user/<unix-timestamp>.sh` |
| User-facing `omarchy-*` command | `bin/omarchy-<group>-<verb>` — see `GROUP_DESCRIPTIONS` in `bin/omarchy` |
| New theme | `themes/<name>/` (+ matching templates under `default/themed/` if they need theme colors) |
| New stock theme | `themes/<name>/` (+ matching templates under `default/themed/` if they need theme colors) |
| User-installed theme | `~/.config/omarchy/themes/<name>/` |
| Generated current theme/background state | `~/.local/state/omarchy/current/` |
+7 -6
View File
@@ -1,22 +1,23 @@
# Omarchy theming
Omarchy themes live under `themes/<name>/` in the source tree, with optional
user themes under `~/.config/omarchy/themes/<name>/`. A theme normally starts
with a `colors.toml`; Omarchy generates the rest of the theme files from
Omarchy themes live under `themes/<name>/` in the source tree (installed at
`/usr/share/omarchy/themes/<name>/`), with optional user themes under
`~/.config/omarchy/themes/<name>/`. A theme normally starts with a
`colors.toml`; Omarchy generates the active theme files from
`default/themed/*.tpl` when `omarchy-theme-set <name>` runs.
## Theme activation flow
`omarchy-theme-set <name>` builds a clean staging directory at
`~/.config/omarchy/current/next-theme`:
`~/.local/state/omarchy/current/next-theme`:
1. Copy the first-party theme from `themes/<name>/`.
2. Overlay any user theme files from `~/.config/omarchy/themes/<name>/`.
3. If needed, generate `colors.toml` from `alacritty.toml`.
4. Run `omarchy-theme-set-templates` to render templates into the staging
theme.
5. Move the staging theme into `~/.config/omarchy/current/theme` and notify the
running shell.
5. Move the staging theme into `~/.local/state/omarchy/current/theme`, write
`~/.local/state/omarchy/current/theme.name`, and notify the running shell.
Template rendering only happens when the staged theme has `colors.toml`.
Existing files are never overwritten by a template, so a hand-written
+1
View File
@@ -25,6 +25,7 @@ The design goal is:
| `${XDG_RUNTIME_DIR:-/tmp}/omarchy-update.lock` | user | Prevent overlapping update runs. Owned by `omarchy-update`; compatibility wrappers inherit/respect it. |
| `/tmp/omarchy-update.log` | user | Transcript of `omarchy update`, used by `omarchy-update-analyze-logs`. |
| `~/.local/state/omarchy/updates/` | user | Update-check state for the shell widget (`packages`, `aur`, `available`, `checked-at`, `error`). |
| `~/.local/state/omarchy/current/` | user | Generated active theme, selected theme name, and current background symlink. |
| `/var/lib/omarchy/migrations/system/` | root | System migration markers. |
| `~/.local/state/omarchy/migrations/user/` | user | User migration markers. |
| `~/.local/state/omarchy/reboot-required` | user | Optional reboot marker checked by `omarchy-update-restart`. |
+1 -1
View File
@@ -11,4 +11,4 @@ rm -rf ~/.config/chromium/SingletonLock
omarchy-theme-set-pi --activate
mkdir -p ~/.config/btop/themes
ln -snf ~/.config/omarchy/current/theme/btop.theme ~/.config/btop/themes/current.theme
ln -snf "$HOME/.local/state/omarchy/current/theme/btop.theme" ~/.config/btop/themes/current.theme
+86
View File
@@ -0,0 +1,86 @@
echo "Move current Omarchy theme state to ~/.local/state"
legacy_current_dir="$HOME/.config/omarchy/current"
current_state_dir="$HOME/.local/state/omarchy/current"
mkdir -p "$HOME/.local/state/omarchy"
if [[ -e $legacy_current_dir || -L $legacy_current_dir ]]; then
if [[ ! -e $current_state_dir && ! -L $current_state_dir ]]; then
mv "$legacy_current_dir" "$current_state_dir"
else
if [[ -d $legacy_current_dir && -d $current_state_dir ]]; then
cp -an "$legacy_current_dir/." "$current_state_dir/" 2>/dev/null || true
fi
rm -rf "$legacy_current_dir"
fi
fi
replace_current_path() {
local file="$1"
[[ -f $file ]] || return 0
if command -v python3 >/dev/null 2>&1; then
python3 - "$file" "$HOME" <<'PY'
from pathlib import Path
import sys
path = Path(sys.argv[1])
home = sys.argv[2]
text = path.read_text()
replacements = {
f"{home}/.config/omarchy/current": f"{home}/.local/state/omarchy/current",
"~/.config/omarchy/current": "~/.local/state/omarchy/current",
"../omarchy/current": "../../.local/state/omarchy/current",
}
for old, new in replacements.items():
text = text.replace(old, new)
path.write_text(text)
PY
else
sed -i \
-e 's|~/.config/omarchy/current|~/.local/state/omarchy/current|g' \
-e 's|\.\./omarchy/current|../../.local/state/omarchy/current|g' \
"$file"
fi
}
for file in \
"$HOME/.config/alacritty/alacritty.toml" \
"$HOME/.config/foot/foot.ini" \
"$HOME/.config/ghostty/config" \
"$HOME/.config/hypr/hyprland.conf" \
"$HOME/.config/hyprland-preview-share-picker/config.yaml" \
"$HOME/.config/kitty/kitty.conf"; do
replace_current_path "$file"
done
relink_current_symlink() {
local link="$1"
local target suffix
[[ -L $link ]] || return 0
target=$(readlink "$link") || return 0
case "$target" in
"$legacy_current_dir"/*)
suffix=${target#"$legacy_current_dir"/}
ln -sfn "$current_state_dir/$suffix" "$link"
;;
"~/.config/omarchy/current/"*)
suffix=${target#"~/.config/omarchy/current/"}
ln -sfn "~/.local/state/omarchy/current/$suffix" "$link"
;;
esac
}
for link in \
"$HOME/.config/btop/themes/current.theme" \
"$HOME/.config/helix/themes/omarchy.toml" \
"$HOME/.vscode/extensions/omarchy-theme/themes/omarchy-color-theme.json" \
"$HOME/.vscode-insiders/extensions/omarchy-theme/themes/omarchy-color-theme.json" \
"$HOME/.vscode-oss/extensions/omarchy-theme/themes/omarchy-color-theme.json" \
"$HOME/.cursor/extensions/omarchy-theme/themes/omarchy-color-theme.json"; do
relink_current_symlink "$link"
done
+6 -2
View File
@@ -12,6 +12,10 @@ import "BorderGeometry.js" as Geometry
QtObject {
id: root
readonly property string home: Quickshell.env("HOME")
readonly property string stateHome: home + "/.local/state"
readonly property string currentThemePath: stateHome + "/omarchy/current/theme"
property color foreground: "#cacccc"
property color background: "#101315"
property color accent: "#cacccc"
@@ -194,14 +198,14 @@ QtObject {
// through shell IPC.
property FileView colorsFile: FileView {
id: colorsFile
path: Quickshell.env("HOME") + "/.config/omarchy/current/theme/colors.toml"
path: root.currentThemePath + "/colors.toml"
watchChanges: false
printErrors: false
onLoaded: root.loadColors(text())
}
property FileView shellFile: FileView {
id: shellFile
path: Quickshell.env("HOME") + "/.config/omarchy/current/theme/shell.toml"
path: root.currentThemePath + "/shell.toml"
watchChanges: false
printErrors: false
onLoaded: root.loadShell(text())
+2 -1
View File
@@ -10,7 +10,8 @@ Item {
id: root
readonly property string home: Quickshell.env("HOME")
readonly property string currentBackgroundLink: home + "/.config/omarchy/current/background"
readonly property string stateHome: home + "/.local/state"
readonly property string currentBackgroundLink: stateHome + "/omarchy/current/background"
property string currentBackground: ""
property string displayedBackground: ""
+2 -1
View File
@@ -30,6 +30,7 @@ Item {
// FileView watcher further down.
property bool barHidden: false
property string home: Quickshell.env("HOME")
property string stateHome: home + "/.local/state"
property string omarchyConfigDir: home + "/.config/omarchy"
property var fallbackBarConfig: ({
position: "top",
@@ -661,7 +662,7 @@ Item {
}
FileView {
path: root.home + "/.config/omarchy/current"
path: root.stateHome + "/omarchy/current"
watchChanges: true
printErrors: false
onFileChanged: root.scheduleTransparentForegroundRefresh()
+2 -1
View File
@@ -12,7 +12,8 @@ Item {
// Injected by omarchy-shell; defaults to the session OMARCHY_PATH.
property string omarchyPath: Quickshell.env("OMARCHY_PATH")
property string imageDirs: Quickshell.env("OMARCHY_IMAGE_SELECTOR_DIRS") || Quickshell.env("OMARCHY_IMAGE_SELECTOR_DIR") || Quickshell.env("OMARCHY_STOCK_BACKGROUNDS_DIR") || (Quickshell.env("HOME") + "/.config/omarchy/current/theme/backgrounds")
property string stateHome: Quickshell.env("HOME") + "/.local/state"
property string imageDirs: Quickshell.env("OMARCHY_IMAGE_SELECTOR_DIRS") || Quickshell.env("OMARCHY_IMAGE_SELECTOR_DIR") || Quickshell.env("OMARCHY_STOCK_BACKGROUNDS_DIR") || (stateHome + "/omarchy/current/theme/backgrounds")
property string imageRows: ""
property string loadedImageRows: ""
property string selectionFile: Quickshell.env("OMARCHY_IMAGE_SELECTOR_SELECTION_FILE") || Quickshell.env("OMARCHY_BACKGROUND_SELECTION_FILE")
+2 -1
View File
@@ -12,8 +12,9 @@ Item {
property string omarchyPath: ""
readonly property string home: Quickshell.env("HOME")
readonly property string stateHome: home + "/.local/state"
readonly property string userName: Quickshell.env("USER") || Quickshell.env("LOGNAME")
readonly property string currentBackgroundLink: home + "/.config/omarchy/current/background"
readonly property string currentBackgroundLink: stateHome + "/omarchy/current/background"
property bool lockRequested: false
property bool authenticatingPassword: false
+25 -5
View File
@@ -211,8 +211,8 @@ pass "safe dispatch works for font list"
pass "safe dispatch works for font current"
PI_TMPDIR=$(mktemp -d)
NEXT_THEME="$PI_TMPDIR/.config/omarchy/current/next-theme"
CURRENT_THEME="$PI_TMPDIR/.config/omarchy/current/theme"
NEXT_THEME="$PI_TMPDIR/.local/state/omarchy/current/next-theme"
CURRENT_THEME="$PI_TMPDIR/.local/state/omarchy/current/theme"
USER_THEMED="$PI_TMPDIR/.config/omarchy/themed"
mkdir -p "$NEXT_THEME" "$CURRENT_THEME" "$USER_THEMED"
@@ -340,12 +340,32 @@ pass "pi theme activation preserves existing settings"
THEME_TMPDIR=$(mktemp -d)
OMARCHY_PATH="$ROOT" HOME="$THEME_TMPDIR" OMARCHY_THEME_HEADLESS=1 "$ROOT/bin/omarchy-theme-set" "Tokyo Night"
background_path=$(readlink -f "$THEME_TMPDIR/.config/omarchy/current/background" 2>/dev/null || true)
expected_background="$THEME_TMPDIR/.config/omarchy/current/theme/backgrounds/0-swirl-buck.jpg"
background_path=$(readlink -f "$THEME_TMPDIR/.local/state/omarchy/current/background" 2>/dev/null || true)
expected_background="$THEME_TMPDIR/.local/state/omarchy/current/theme/backgrounds/0-swirl-buck.jpg"
[[ $background_path == "$expected_background" ]] || fail "headless theme set creates current background symlink"
[[ -f $background_path ]] || fail "headless theme background target exists"
[[ ! -e $THEME_TMPDIR/.config/omarchy/current ]] || fail "headless theme set avoids config current state"
pass "headless theme set creates current background symlink"
MIGRATION_TMPDIR=$(mktemp -d)
mkdir -p \
"$MIGRATION_TMPDIR/.config/omarchy/current/theme" \
"$MIGRATION_TMPDIR/.config/alacritty" \
"$MIGRATION_TMPDIR/.config/hyprland-preview-share-picker" \
"$MIGRATION_TMPDIR/.config/btop/themes"
printf 'tokyo-night\n' >"$MIGRATION_TMPDIR/.config/omarchy/current/theme.name"
printf 'x\n' >"$MIGRATION_TMPDIR/.config/omarchy/current/theme/colors.toml"
printf 'general.import = [ "~/.config/omarchy/current/theme/alacritty.toml" ]\n' >"$MIGRATION_TMPDIR/.config/alacritty/alacritty.toml"
printf 'stylesheets: ["../omarchy/current/theme/hyprland-preview-share-picker.css"]\n' >"$MIGRATION_TMPDIR/.config/hyprland-preview-share-picker/config.yaml"
ln -s "$MIGRATION_TMPDIR/.config/omarchy/current/theme/btop.theme" "$MIGRATION_TMPDIR/.config/btop/themes/current.theme"
HOME="$MIGRATION_TMPDIR" bash -euo pipefail "$ROOT/migrations/user/1781043107.sh" >/dev/null
[[ -f $MIGRATION_TMPDIR/.local/state/omarchy/current/theme.name ]] || fail "current theme migration moves theme name"
[[ ! -e $MIGRATION_TMPDIR/.config/omarchy/current ]] || fail "current theme migration removes legacy config state"
grep -Fq '~/.local/state/omarchy/current/theme/alacritty.toml' "$MIGRATION_TMPDIR/.config/alacritty/alacritty.toml" || fail "current theme migration updates alacritty import"
grep -Fq '../../.local/state/omarchy/current/theme/hyprland-preview-share-picker.css' "$MIGRATION_TMPDIR/.config/hyprland-preview-share-picker/config.yaml" || fail "current theme migration updates relative stylesheet"
[[ $(readlink "$MIGRATION_TMPDIR/.config/btop/themes/current.theme") == "$MIGRATION_TMPDIR/.local/state/omarchy/current/theme/btop.theme" ]] || fail "current theme migration updates btop symlink"
pass "current theme migration moves state and rewrites shipped references"
cp "$NEXT_THEME/colors.toml" "$CURRENT_THEME/colors.toml"
cp "$NEXT_THEME/vscode-theme.json" "$CURRENT_THEME/vscode-theme.json"
@@ -405,7 +425,7 @@ PATH="$FAKE_BIN:$ROOT/bin:$PATH" HOME="$PI_TMPDIR" "$ROOT/bin/omarchy-theme-set-
jq -e '.contributes.themes[0].uiTheme == "vs"' "$PI_TMPDIR/.vscode/extensions/omarchy-theme/package.json" >/dev/null || fail "vscode generated light theme uses VS Code light uiTheme"
pass "vscode generated light theme uses VS Code light uiTheme"
[[ -L $PI_TMPDIR/.vscode/extensions/omarchy-theme/themes/omarchy-color-theme.json ]] || fail "vscode generated theme references current theme file"
[[ $(readlink "$PI_TMPDIR/.vscode/extensions/omarchy-theme/themes/omarchy-color-theme.json") == "$PI_TMPDIR/.config/omarchy/current/theme/vscode-theme.json" ]] || fail "vscode generated theme references current theme file"
[[ $(readlink "$PI_TMPDIR/.vscode/extensions/omarchy-theme/themes/omarchy-color-theme.json") == "$PI_TMPDIR/.local/state/omarchy/current/theme/vscode-theme.json" ]] || fail "vscode generated theme references current theme file"
pass "vscode generated theme references current theme file"
[[ ! -f $PI_TMPDIR/.vscode/extensions/.obsolete ]] || fail "vscode generated theme clears obsolete extension marker"
pass "vscode generated theme clears obsolete extension marker"
+3 -2
View File
@@ -148,8 +148,9 @@ pass "package-owned defaults live outside config"
grep -F 'dofile((os.getenv("OMARCHY_PATH") or "/usr/share/omarchy") .. "/default/hypr/bootstrap.lua")' "$ROOT/config/hypr/hyprland.lua" >/dev/null
grep -F 'require("default.hypr.omarchy")' "$ROOT/config/hypr/hyprland.lua" >/dev/null
grep -F 'package.path = os.getenv("HOME")' "$ROOT/default/hypr/bootstrap.lua" >/dev/null
pass "Hyprland user entrypoint keeps only package path bootstrap in defaults"
grep -F 'package.path = home' "$ROOT/default/hypr/bootstrap.lua" >/dev/null
grep -F '/.local/state/?.lua;' "$ROOT/default/hypr/bootstrap.lua" >/dev/null
pass "Hyprland user entrypoint keeps package and state path bootstrap in defaults"
TMPDIR=$(mktemp -d)
mkdir -p "$TMPDIR/home/.config/omarchy"