#!/usr/bin/env bash # install-theme.sh — restore the NexusOS desktop theme wiring. # # The theme *assets* live in this repo (assets/themes/). # This script recreates everything OUTSIDE the repo that makes the desktop # actually use them: symlinks, xfconf (xsettings + xfwm4), and the canonical # lines in the GTK 3/4 settings.ini files. # # Idempotent and safe: re-running only fixes drift; any real file it would # replace with a symlink is backed up to .bak-YYYYMMDD first. # # Usage: ./assets/themes/install-theme.sh (apply + reload) # ./assets/themes/install-theme.sh --no-reload set -euo pipefail REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" RELOAD=1 [[ "${1:-}" == "--no-reload" ]] && RELOAD=0 STAMP="$(date +%Y%m%d)" # Canonical values — keep in sync with assets/themes/NexusOS/index.theme GTK_THEME="NexusOS" ICON_THEME="NexusOS" CURSOR_THEME="DMZ-White" CURSOR_SIZE="24" FONT_NAME="Ubuntu 10" say() { printf ' %s\n' "$*"; } # link : make linkname a symlink to target, backing up # any pre-existing real file/dir that isn't already the correct link. link() { local target="$1" linkname="$2" mkdir -p "$(dirname "$linkname")" if [[ -L "$linkname" && "$(readlink -f "$linkname")" == "$(readlink -f "$target")" ]]; then say "ok $linkname" return fi if [[ -e "$linkname" || -L "$linkname" ]]; then mv "$linkname" "$linkname.bak-$STAMP" say "backup $linkname -> $linkname.bak-$STAMP" fi ln -sfn "$target" "$linkname" say "link $linkname -> $target" } # set_ini : ensure key=value under [Settings], # creating the file/section/key as needed, replacing in place otherwise. set_ini() { local file="$1" key="$2" value="$3" if [[ ! -f "$file" ]]; then mkdir -p "$(dirname "$file")" printf '[Settings]\n%s=%s\n' "$key" "$value" > "$file" say "create $file ($key)" return fi if grep -qE "^${key}=" "$file"; then sed -i "s|^${key}=.*|${key}=${value}|" "$file" else sed -i "0,/^\[Settings\]/s//[Settings]\n${key}=${value}/" "$file" fi say "ini $file : $key=$value" } xset() { # xfconf set, creating the prop with the right type if absent local channel="$1" prop="$2" type="$3" val="$4" command -v xfconf-query >/dev/null || return 0 xfconf-query -c "$channel" -p "$prop" -n -t "$type" -s "$val" 2>/dev/null \ || xfconf-query -c "$channel" -p "$prop" -s "$val" 2>/dev/null || true say "xfconf $channel$prop = $val" } echo "NexusOS theme — restoring wiring from $REPO" echo "[1/4] Symlinks" link "$REPO/assets/themes/NexusOS" "$HOME/.themes/NexusOS" link "$REPO/assets/themes/NexusOS-icons" "$HOME/.icons/NexusOS" link "$REPO/assets/themes/gtk3-user-overrides.css" "$HOME/.config/gtk-3.0/gtk.css" echo "[2/4] xfconf (xsettings + xfwm4)" xset xsettings /Net/ThemeName string "$GTK_THEME" xset xsettings /Net/IconThemeName string "$ICON_THEME" xset xsettings /Gtk/CursorThemeName string "$CURSOR_THEME" xset xsettings /Gtk/CursorThemeSize int "$CURSOR_SIZE" xset xsettings /Gtk/FontName string "$FONT_NAME" xset xfwm4 /general/theme string "$GTK_THEME" echo "[3/4] GTK 3 / GTK 4 settings.ini" for f in "$HOME/.config/gtk-3.0/settings.ini" "$HOME/.config/gtk-4.0/settings.ini"; do set_ini "$f" gtk-theme-name "$GTK_THEME" set_ini "$f" gtk-icon-theme-name "$ICON_THEME" set_ini "$f" gtk-cursor-theme-name "$CURSOR_THEME" set_ini "$f" gtk-cursor-theme-size "$CURSOR_SIZE" set_ini "$f" gtk-font-name "$FONT_NAME" done echo "[4/4] Icon caches" gtk-update-icon-cache -f -t "$HOME/.icons/NexusOS" 2>/dev/null \ && say "ok NexusOS icon cache rebuilt" \ || say "WARN NexusOS icon cache rebuild failed" INH="$(grep -i '^Inherits=' "$REPO/assets/themes/NexusOS-icons/index.theme" 2>/dev/null | cut -d= -f2)" if [[ -n "$INH" ]]; then INH_OK=0 for dir in /usr/share/icons ~/.icons ~/.local/share/icons; do [[ -d "$dir/$INH" ]] && { INH_OK=1; INH_DIR="$dir/$INH"; break; } done if [[ "$INH_OK" == 1 ]]; then say "ok icon fallback '$INH' found" if sudo -n gtk-update-icon-cache -f -t "$INH_DIR" 2>/dev/null; then say "ok $INH icon cache rebuilt" else say "note $INH cache skipped (no passwordless sudo — run manually if needed)" fi else say "WARN icon fallback '$INH' not installed — icons may be missing" fi fi echo "[5/5] Sanity" for dir in /usr/share/icons ~/.icons ~/.local/share/icons; do [[ -d "$dir/$CURSOR_THEME" ]] && { say "ok cursor '$CURSOR_THEME' found"; CUR_OK=1; break; } done [[ "${CUR_OK:-0}" == 1 ]] || say "WARN cursor theme '$CURSOR_THEME' not installed — will fall back" if [[ "$RELOAD" == 1 ]] && command -v xfconf-query >/dev/null && [[ -n "${DISPLAY:-}" ]]; then xfconf-query -c xsettings -p /Net/ThemeName -s "Adwaita" 2>/dev/null || true xfconf-query -c xsettings -p /Net/ThemeName -s "$GTK_THEME" 2>/dev/null || true command -v xfdesktop >/dev/null && (xfdesktop --reload >/dev/null 2>&1 &) || true command -v xfce4-panel >/dev/null && (xfce4-panel -r >/dev/null 2>&1 &) || true echo "Reloaded. (some already-running apps may need a restart)" else echo "Done. Skipped live reload (no X session or --no-reload)." fi