#!/bin/bash # omarchy:summary=Apply an Omarchy theme # omarchy:args= # omarchy:examples=omarchy theme list | omarchy theme set "Tokyo Night" if [[ -z $1 ]]; then echo "Usage: omarchy-theme-set " 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" BACKGROUND_TRANSITION_CACHE="$HOME/.cache/omarchy/background-transitions" USER_THEMES_PATH="$HOME/.config/omarchy/themes" OMARCHY_THEMES_PATH="$OMARCHY_PATH/themes" run_parallel() { local pid local pids=() for command in "$@"; do bash -lc "$command" & pids+=("$!") done for pid in "${pids[@]}"; do wait "$pid" done } snapshot_current_background() { local current_background snapshot extension current_background=$(readlink -f "$CURRENT_BACKGROUND_LINK" 2>/dev/null || true) [[ -f $current_background ]] || return mkdir -p "$BACKGROUND_TRANSITION_CACHE" extension=${current_background##*.} snapshot="$BACKGROUND_TRANSITION_CACHE/previous-$$.$extension" ln "$current_background" "$snapshot" 2>/dev/null || cp "$current_background" "$snapshot" echo "$snapshot" } set_theme_background() { local backgrounds=() local current_background index new_background next_index mapfile -d '' -t backgrounds < <( find -L "$HOME/.config/omarchy/backgrounds/$THEME_NAME/" "$CURRENT_THEME_PATH/backgrounds/" -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 | sort -z ) if (( ${#backgrounds[@]} == 0 )); then omarchy-notification-send "No background was found for theme" -t 2000 omarchy-shell-ipc-fast shell applyTheme "$colors_payload" "$shell_payload" >/dev/null 2>&1 || true return fi current_background=$(readlink "$CURRENT_BACKGROUND_LINK" 2>/dev/null || true) index=-1 for i in "${!backgrounds[@]}"; do if [[ ${backgrounds[$i]} == $current_background ]]; then index=$i break fi done if (( index == -1 )); then new_background="${backgrounds[0]}" else next_index=$(((index + 1) % ${#backgrounds[@]})) new_background="${backgrounds[$next_index]}" fi ln -nsf "$new_background" "$CURRENT_BACKGROUND_LINK" if [[ -f $OLD_BACKGROUND_SNAPSHOT ]]; then omarchy-shell-ipc-fast background themeTransition "$OLD_BACKGROUND_SNAPSHOT" "$new_background" "$colors_payload" "$shell_payload" >/dev/null 2>&1 || \ omarchy-shell-ipc-fast shell applyTheme "$colors_payload" "$shell_payload" >/dev/null 2>&1 || true (sleep 3; rm -f "$OLD_BACKGROUND_SNAPSHOT") & else omarchy-shell-ipc-fast background themeTransition "" "$new_background" "$colors_payload" "$shell_payload" >/dev/null 2>&1 || \ omarchy-shell-ipc-fast shell applyTheme "$colors_payload" "$shell_payload" >/dev/null 2>&1 || true fi } THEME_NAME=$(echo "$1" | sed -E 's/<[^>]+>//g' | tr '[:upper:]' '[:lower:]' | tr ' ' '-') if [[ ! -d $OMARCHY_THEMES_PATH/$THEME_NAME ]] && [[ ! -d $USER_THEMES_PATH/$THEME_NAME ]]; then echo "Theme '$THEME_NAME' does not exist" exit 1 fi # Prevent file-watch reloads from changing shell colors before the background # reveal is ready. The theme IPC below resumes reloads as it applies colors. omarchy-shell-ipc --if-running shell suspendThemeReloads >/dev/null 2>&1 || true # Setup clean next theme directory (for atomic theme config swapping) rm -rf "$NEXT_THEME_PATH" mkdir -p "$NEXT_THEME_PATH" # Copy official theme first, then overlay user customizations on top cp -r "$OMARCHY_THEMES_PATH/$THEME_NAME/"* "$NEXT_THEME_PATH/" 2>/dev/null cp -r "$USER_THEMES_PATH/$THEME_NAME/"* "$NEXT_THEME_PATH/" 2>/dev/null # Generate colors.toml from alacritty.toml if theme is missing colors.toml if [[ ! -f $NEXT_THEME_PATH/colors.toml && -f $NEXT_THEME_PATH/alacritty.toml ]]; then omarchy-theme-colors-from-alacritty "$NEXT_THEME_PATH" fi # Generate dynamic configs omarchy-theme-set-templates OLD_BACKGROUND_SNAPSHOT="" if [[ $OMARCHY_THEME_SKIP_BACKGROUND != "1" ]]; then OLD_BACKGROUND_SNAPSHOT=$(snapshot_current_background) fi # Swap next theme in as current 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" # Make the running shell pick up the new palette immediately instead of waiting # for file-watch debounce while the rest of the theme hooks run. colors_payload=$([[ -f $CURRENT_THEME_PATH/colors.toml ]] && base64 -w 0 "$CURRENT_THEME_PATH/colors.toml") shell_payload=$([[ -f $CURRENT_THEME_PATH/shell.toml ]] && base64 -w 0 "$CURRENT_THEME_PATH/shell.toml") if [[ $OMARCHY_THEME_SKIP_BACKGROUND == "1" ]]; then omarchy-shell-ipc-fast shell applyTheme "$colors_payload" "$shell_payload" >/dev/null 2>&1 || true else set_theme_background fi post_theme_commands=( omarchy-restart-terminal omarchy-restart-hyprctl omarchy-restart-btop omarchy-restart-opencode omarchy-restart-helix omarchy-theme-set-foot omarchy-theme-set-gnome omarchy-theme-set-browser omarchy-theme-set-vscode omarchy-theme-set-obsidian omarchy-theme-set-keyboard ) run_parallel "${post_theme_commands[@]}" # Call hook on theme set omarchy-hook theme-set "$THEME_NAME" >/dev/null # Warm selector caches after the theme is applied. The shell hot-reloads theme # colors/backgrounds, so keep the running instance alive and preload the picker # rows/selection to avoid first-open carousel settling after a theme change. omarchy-theme-switcher --preload >/dev/null 2>&1 omarchy-theme-bg-cache >/dev/null 2>&1 &