|
2 | 2 | # theme-switch.sh — Cycle or set desktop theme |
3 | 3 | # Usage: theme-switch.sh [vantablack|white|tokyonight|next] |
4 | 4 |
|
5 | | -HYPR_THEMES="$HOME/.config/hypr/themes" |
6 | | -WAYBAR_THEMES="$HOME/.config/waybar/themes" |
7 | | -KITTY_THEMES="$HOME/.config/kitty/themes" |
8 | | -ROFI_COLORS="$HOME/.config/rofi/colors" |
9 | | -TMUX_THEMES="$HOME/.config/tmux/themes" |
10 | | -FZF_THEMES="$HOME/.config/fzf/themes" |
11 | | -ZSH_THEMES="$HOME/.config/zsh/themes" |
12 | | -KVANTUM_THEMES="$HOME/.config/Kvantum/themes" |
13 | | -BAT_THEMES="$HOME/.config/bat/themes" |
14 | | -GIT_THEMES="$HOME/.config/git/themes" |
15 | | -CURRENT_FILE="$HOME/.config/hypr/current-theme" |
16 | | -BG_DIR="$HOME/.config/backgrounds" |
| 5 | +set -euo pipefail |
17 | 6 |
|
18 | | -THEMES=(vantablack white tokyonight) |
| 7 | +SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd) |
| 8 | +DOTFILES_ROOT="${DOTFILES:-${DOTFILES_PATH:-$HOME/Projects/dotfiles}}" |
19 | 9 |
|
20 | | -# Determine target theme |
21 | | -if [[ "$1" == "next" || "$1" == "toggle" ]]; then |
22 | | - current=$(cat "$CURRENT_FILE" 2>/dev/null || echo "vantablack") |
23 | | - for i in "${!THEMES[@]}"; do |
24 | | - if [[ "${THEMES[$i]}" == "$current" ]]; then |
25 | | - THEME="${THEMES[$(( (i + 1) % ${#THEMES[@]} ))]}" |
26 | | - break |
27 | | - fi |
28 | | - done |
29 | | - THEME="${THEME:-vantablack}" |
30 | | -elif [[ "$1" == "vantablack" || "$1" == "white" || "$1" == "tokyonight" ]]; then |
31 | | - THEME="$1" |
| 10 | +if [[ -f "$DOTFILES_ROOT/setup/lib/theme_orchestrator.sh" ]]; then |
| 11 | + source "$DOTFILES_ROOT/setup/lib/theme_orchestrator.sh" |
| 12 | +elif [[ -f "$SCRIPT_DIR/../../../setup/lib/theme_orchestrator.sh" ]]; then |
| 13 | + source "$SCRIPT_DIR/../../../setup/lib/theme_orchestrator.sh" |
32 | 14 | else |
33 | | - echo "Usage: theme-switch.sh [vantablack|white|tokyonight|next]" |
| 15 | + echo "theme_orchestrator.sh not found. Set DOTFILES or DOTFILES_PATH." >&2 |
34 | 16 | exit 1 |
35 | 17 | fi |
36 | 18 |
|
37 | | -# Hyprland + Hyprlock colors |
38 | | -ln -sf "$HYPR_THEMES/$THEME.conf" "$HOME/.config/hypr/colors.conf" |
39 | | - |
40 | | -# Waybar CSS |
41 | | -ln -sf "$WAYBAR_THEMES/$THEME.css" "$HOME/.config/waybar/themes/current.css" |
42 | | - |
43 | | -# Kitty — symlink must match the include name in kitty.conf |
44 | | -ln -sf "$KITTY_THEMES/$THEME.conf" "$HOME/.config/kitty/current-theme.conf" |
45 | | -kill -SIGUSR1 $(pgrep -x kitty) 2>/dev/null |
46 | | - |
47 | | -# Rofi (kept as fallback) |
48 | | -ln -sf "$ROFI_COLORS/$THEME.rasi" "$HOME/.config/rofi/colors/current.rasi" |
49 | | - |
50 | | -# Walker — update theme and restart service so it reloads config |
51 | | -WALKER_CFG="$HOME/.config/walker/config.toml" |
52 | | -if [[ -f "$WALKER_CFG" ]]; then |
53 | | - sed -i "s/^theme = .*/theme = \"$THEME\"/" "$WALKER_CFG" |
54 | | - pkill -x walker 2>/dev/null |
55 | | - sleep 0.2 |
56 | | - walker --gapplication-service & |
57 | | -fi |
58 | | - |
59 | | -# Tmux |
60 | | -ln -sf "$TMUX_THEMES/$THEME.conf" "$HOME/.config/tmux/current-theme.conf" |
61 | | -tmux source-file ~/.tmux.conf 2>/dev/null |
62 | | - |
63 | | -# fzf — new shells will pick up the theme via .zshrc sourcing current-theme.sh |
64 | | -mkdir -p "$HOME/.config/fzf" |
65 | | -ln -sf "$FZF_THEMES/$THEME.sh" "$HOME/.config/fzf/current-theme.sh" |
66 | | - |
67 | | -# Update FZF_DEFAULT_OPTS in running tmux instances and send SIGUSR1 to shells if possible |
68 | | -if command -v tmux &>/dev/null && tmux info &>/dev/null; then |
69 | | - # We evaluate the script in a clean subshell to get the final FZF_DEFAULT_OPTS |
70 | | - # We pass the current FZF_DEFAULT_OPTS to avoid losing other configuration |
71 | | - CURRENT_FZF=$(tmux show-environment FZF_DEFAULT_OPTS 2>/dev/null | sed 's/^FZF_DEFAULT_OPTS=//' || echo "") |
72 | | - NEW_FZF_OPTS=$(env -i bash -c "export FZF_DEFAULT_OPTS='$CURRENT_FZF'; source $HOME/.config/fzf/current-theme.sh && echo \"\$FZF_DEFAULT_OPTS\"") |
73 | | - if [[ -n "$NEW_FZF_OPTS" ]]; then |
74 | | - tmux set-environment -g FZF_DEFAULT_OPTS "$NEW_FZF_OPTS" |
75 | | - fi |
76 | | -fi |
77 | | - |
78 | | -# Send SIGUSR1 to zsh instances to ask them to reload fzf config if they trap it |
79 | | -# Not all shells trap SIGUSR1 by default, but we can update tmux for now |
80 | | -killall -SIGUSR1 zsh 2>/dev/null || true |
81 | | - |
82 | | - |
83 | | -# ZSH — p10k + autosuggestions colors (new shells pick up via .zshrc) |
84 | | -mkdir -p "$HOME/.config/zsh/themes" |
85 | | -ln -sf "$ZSH_THEMES/$THEME.zsh" "$HOME/.config/zsh/current-theme.zsh" |
86 | | - |
87 | | -# Kvantum / Qt apps — keep Qt in the same theme flow |
88 | | -if [[ -d "$KVANTUM_THEMES" ]]; then |
89 | | - mkdir -p "$HOME/.config/Kvantum" |
90 | | - ln -sf "$KVANTUM_THEMES/$THEME.kvconfig" "$HOME/.config/Kvantum/kvantum.kvconfig" |
91 | | -fi |
92 | | - |
93 | | -# bat — theme selected via symlinked config file |
94 | | -if [[ -d "$BAT_THEMES" ]]; then |
95 | | - mkdir -p "$HOME/.config/bat" |
96 | | - ln -sf "$BAT_THEMES/$THEME.conf" "$HOME/.config/bat/config" |
97 | | -fi |
98 | | - |
99 | | -# git-delta — include a theme-specific gitconfig fragment |
100 | | -if [[ -d "$GIT_THEMES" ]]; then |
101 | | - mkdir -p "$HOME/.config/git" |
102 | | - ln -sf "$GIT_THEMES/$THEME.gitconfig" "$HOME/.config/git/current-theme.gitconfig" |
103 | | -fi |
104 | | - |
105 | | -# Wallpaper via wpaperd — generate config with per-output rotation workaround |
106 | | -if [[ -d "$BG_DIR/$THEME" ]]; then |
107 | | - "$HOME/.config/hypr/scripts/wpaperd-set.sh" "$BG_DIR/$THEME" |
108 | | -fi |
109 | | - |
110 | | -# Reload Hyprland (picks up colors.conf) |
111 | | -hyprctl reload |
112 | | - |
113 | | -# Reload Waybar |
114 | | -sleep 0.3 |
115 | | -if ! pkill -SIGUSR2 waybar 2>/dev/null; then |
116 | | - pkill waybar 2>/dev/null |
117 | | - sleep 0.2 |
118 | | - waybar & |
119 | | -fi |
120 | | - |
121 | | -# GTK + icon + cursor theme sync |
122 | | -# gsettings → propagates to running GTK4/libadwaita apps via xdg-desktop-portal-gtk |
123 | | -# settings.ini → applies at launch for GTK3 apps without a settings daemon |
124 | | -if [[ "$THEME" == "white" ]]; then |
125 | | - GTK_THEME_NAME="Adwaita" |
126 | | - GTK_DARK="0" |
127 | | - GTK_COLOR_SCHEME="prefer-light" |
128 | | - GTK_ICONS="Papirus-Light" |
129 | | - GTK_CURSOR="Bibata-Modern-Ice" |
130 | | -else |
131 | | - GTK_THEME_NAME="Adwaita-dark" |
132 | | - GTK_DARK="1" |
133 | | - GTK_COLOR_SCHEME="prefer-dark" |
134 | | - GTK_ICONS="Papirus-Dark" |
135 | | - GTK_CURSOR="Bibata-Modern-Classic" |
136 | | -fi |
137 | | - |
138 | | -# Write GTK3 settings.ini (read at app launch; no daemon needed) |
139 | | -mkdir -p "$HOME/.config/gtk-3.0" |
140 | | -cat > "$HOME/.config/gtk-3.0/settings.ini" <<EOF |
141 | | -[Settings] |
142 | | -gtk-theme-name=$GTK_THEME_NAME |
143 | | -gtk-icon-theme-name=$GTK_ICONS |
144 | | -gtk-cursor-theme-name=$GTK_CURSOR |
145 | | -gtk-cursor-theme-size=24 |
146 | | -gtk-font-name=Adwaita Sans 11 |
147 | | -gtk-application-prefer-dark-theme=$GTK_DARK |
148 | | -EOF |
149 | | - |
150 | | -# Write GTK4 settings.ini (libadwaita dark/light toggle) |
151 | | -mkdir -p "$HOME/.config/gtk-4.0" |
152 | | -cat > "$HOME/.config/gtk-4.0/settings.ini" <<EOF |
153 | | -[Settings] |
154 | | -gtk-application-prefer-dark-theme=$GTK_DARK |
155 | | -gtk-icon-theme-name=$GTK_ICONS |
156 | | -gtk-cursor-theme-name=$GTK_CURSOR |
157 | | -gtk-cursor-theme-size=24 |
158 | | -EOF |
159 | | - |
160 | | -# Write GTK2 gtkrc for older apps |
161 | | -cat > "$HOME/.gtkrc-2.0" <<EOF |
162 | | -# Managed by ~/.config/hypr/scripts/theme-switch.sh |
163 | | -gtk-theme-name="$GTK_THEME_NAME" |
164 | | -gtk-icon-theme-name="$GTK_ICONS" |
165 | | -gtk-font-name="Adwaita Sans 11" |
166 | | -gtk-cursor-theme-name="$GTK_CURSOR" |
167 | | -gtk-cursor-theme-size=24 |
168 | | -gtk-toolbar-style=GTK_TOOLBAR_ICONS |
169 | | -gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR |
170 | | -gtk-button-images=0 |
171 | | -gtk-menu-images=0 |
172 | | -gtk-enable-event-sounds=1 |
173 | | -gtk-enable-input-feedback-sounds=0 |
174 | | -gtk-xft-antialias=1 |
175 | | -gtk-xft-hinting=1 |
176 | | -gtk-xft-hintstyle="hintslight" |
177 | | -gtk-xft-rgba="rgb" |
178 | | -EOF |
179 | | - |
180 | | -# Keep ~/.icons/default aligned for apps that still read index.theme |
181 | | -mkdir -p "$HOME/.icons/default" |
182 | | -cat > "$HOME/.icons/default/index.theme" <<EOF |
183 | | -[Icon Theme] |
184 | | -Inherits=$GTK_CURSOR |
185 | | -EOF |
186 | | - |
187 | | -# Notify running GTK apps via dconf/xdg-desktop-portal-gtk |
188 | | -gsettings set org.gnome.desktop.interface color-scheme "$GTK_COLOR_SCHEME" |
189 | | -gsettings set org.gnome.desktop.interface gtk-theme "$GTK_THEME_NAME" |
190 | | -gsettings set org.gnome.desktop.interface icon-theme "$GTK_ICONS" |
191 | | -gsettings set org.gnome.desktop.interface cursor-theme "$GTK_CURSOR" |
192 | | -gsettings set org.gnome.desktop.interface cursor-size 24 |
193 | | - |
194 | | -# Apply cursor live in Hyprland (compositor + all new X/Wayland clients) |
195 | | -hyprctl setcursor "$GTK_CURSOR" 24 |
196 | | - |
197 | | -# Quit Nautilus completely (including daemon) so it reloads icon theme on next open |
198 | | -nautilus -q 2>/dev/null |
199 | | - |
200 | | -# Mako — update colors and reload (Omarchy pattern: text/border/background from theme) |
201 | | -if command -v mako &>/dev/null; then |
202 | | - MAKO_CFG="$HOME/.config/mako/config" |
203 | | - if [[ "$THEME" == "white" ]]; then |
204 | | - MAKO_TEXT="#000000"; MAKO_BORDER="#6e6e6e"; MAKO_BG="#ffffff" |
205 | | - elif [[ "$THEME" == "tokyonight" ]]; then |
206 | | - MAKO_TEXT="#c0caf5"; MAKO_BORDER="#7aa2f7"; MAKO_BG="#1a1b26" |
207 | | - else |
208 | | - MAKO_TEXT="#ffffff"; MAKO_BORDER="#8d8d8d"; MAKO_BG="#000000" |
209 | | - fi |
210 | | - sed -i "s/^text-color=.*/text-color=$MAKO_TEXT/" "$MAKO_CFG" |
211 | | - sed -i "s/^border-color=.*/border-color=$MAKO_BORDER/" "$MAKO_CFG" |
212 | | - sed -i "s/^background-color=.*/background-color=$MAKO_BG/" "$MAKO_CFG" |
213 | | - makoctl reload 2>/dev/null |
214 | | -fi |
215 | | - |
216 | | -# Pi coding agent — use named theme if installed, fallback to dark/light |
217 | | -PI_SETTINGS="$HOME/.pi/agent/settings.json" |
218 | | -if [[ -f "$PI_SETTINGS" ]]; then |
219 | | - if [[ -f "$HOME/.pi/agent/themes/$THEME.json" ]]; then |
220 | | - PI_THEME="$THEME" |
221 | | - else |
222 | | - PI_THEME=$([[ "$THEME" == "white" ]] && echo "light" || echo "dark") |
223 | | - fi |
224 | | - if command -v jq &>/dev/null; then |
225 | | - tmp=$(mktemp) |
226 | | - jq --arg t "$PI_THEME" '.theme = $t' "$PI_SETTINGS" > "$tmp" && mv "$tmp" "$PI_SETTINGS" |
227 | | - else |
228 | | - sed -i "s/\"theme\": \"[^\"]*\"/\"theme\": \"$PI_THEME\"/" "$PI_SETTINGS" |
229 | | - fi |
230 | | -fi |
231 | | - |
232 | | -# Persist current theme |
233 | | -echo "$THEME" > "$CURRENT_FILE" |
234 | | - |
235 | | -notify-send "Theme" "Switched to: $THEME" --icon=preferences-desktop-theme -t 2000 |
| 19 | +theme_apply "${1:-}" |
0 commit comments