Files
Panama/setup/scripts/change-settings
T
Gabriel Brown cb7c09d208 Give the desktop real themes, video wallpapers, and honest titlebars
Appearance now opens on Themes: light and dark side by side, each
remembering its own choice, over galleries of ten shipped themes —
Tokyo Moon and Day joined by Moon Rose, Catppuccin, Nord, Gruvbox and
Everforest in both modes. A theme is a complete palette: the catalog
lives in themes.json, Theme.qml reads every color token from the
active record, and one render pipeline carries it to kitty, tmux,
btop, GTK, Vicinae, Firefox's chrome, and the lock screen. The Theme
editor builds new ones from four wells — wheel, hex, or eyedropper —
with derived surfaces, a saturation slider, debounced fine-tune, and
effects that save with the theme. Custom edits finally keep GNOME's
accent, kitty's border, and hyprlock in sync.

Wallpapers can be video: mpvpaper per output, hardware-decoded, muted
and looped, supervised and respawned. Panama owns the pausing — games,
battery, and a bar pill for right now — because the compositor
rebuilds full-screen blur for every frame a video wallpaper draws.
The lock screen gets a still frame.

Titlebars stop lying. GNOME apps get close-only on your chosen side,
the maximize and double-click settings are gone, the Settings window
obeys the same rules, and its titlebar can be turned off entirely.
Typography becomes five labeled dropdowns instead of a wall of
samples.

Contracts updated and written throughout (165 now); per the redesign
workflow none were executed — the full sweep runs once at the end.

Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
2026-08-23 23:39:04 -04:00

133 lines
7.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Strict: the copy over / below is the one thing this stage exists to do, and
# without set -e its failure fell through to guarded no-ops and exited 0 --
# a failed stage the installer's summary could never see.
set -euo pipefail
# --- Helper functions ---
log() { echo -e "\033[1;34m[INFO]\033[0m $*"; }
exists() { command -v "$1" >/dev/null 2>&1; }
# --- Defined Paths ---
# The default, not an assignment: an exported PANAMA_PATH from a clone at
# another location must win, or the copy over / below reads the wrong tree.
PANAMA_PATH="${PANAMA_PATH:-$HOME/.local/share/Panama}"
echo -e "\n--- Copying System & User files ---"
# dnf options are applied as individual keys rather than shipped as a file.
# config/copy once carried a whole /etc/dnf/dnf.conf, which clobbered proxies
# and mirrors a machine already had -- and set defaultyes=True system-wide, so
# every `dnf remove` for every user treated a bare Enter as yes. These two are
# performance knobs with no behavior change; anything else stays the machine's
# own business. (fastestmirror and deltarpm were dnf4-era keys dnf5 ignores,
# so they simply stop being written.)
log "Setting dnf performance options (max_parallel_downloads, keepcache)"
sudo dnf config-manager setopt max_parallel_downloads=10 keepcache=True 2>/dev/null \
|| log "Could not set dnf options; defaults apply"
log "Copying system files (udev rules, systemd drop-ins)"
sudo cp -r "$PANAMA_PATH/config/copy/." "/"
# The GPU symlink rules land via the copy above. Apply them without a reboot so
# AQ_DRM_DEVICES resolves on the first Hyprland login rather than the second.
if [[ -f /etc/udev/rules.d/99-panama-gpu.rules ]]; then
log "Reloading udev rules for stable GPU symlinks"
sudo udevadm control --reload
sudo udevadm trigger --subsystem-match=drm
fi
# The power-key drop-in lands via the same copy; logind reads its config only
# at start, so without this the button keeps hard-powering-off until the next
# boot. Restarting logind is what Fedora's own updates do and current systemd
# preserves sessions across it.
if [[ -f /etc/systemd/logind.conf.d/panama-power-key.conf ]]; then
log "Reloading logind so the power button opens the menu instead of powering off"
sudo systemctl try-restart systemd-logind 2>/dev/null \
|| log "Could not restart logind; the power-button change applies at next boot"
fi
# The document-portal drop-in lands via the same copy. A user unit's drop-ins
# are read at daemon-reload, so without this the guard applies from the next
# login rather than from now -- and the failure it guards against is one you
# only find days later, when you next open a flatpak you had not opened yet.
if [[ -f /etc/systemd/user/xdg-document-portal.service.d/panama-stale-mount.conf ]]; then
log "Reloading the user manager so the document-portal drop-in applies"
systemctl --user daemon-reload || log "Could not reload the user manager"
fi
echo -e "\n--- Desktop appearance ---"
# GTK and Qt apps read these directly from gsettings; there is no settings
# daemon outside GNOME, so they must be correct rather than merely overridden.
# These match config/dot/gtk-3.0/settings.ini and quickshell's Theme.qml.
if exists gsettings; then
log "Applying interface settings"
gsettings set org.gnome.desktop.interface gtk-theme 'adw-gtk3-dark'
gsettings set org.gnome.desktop.interface icon-theme 'Adwaita'
gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark'
gsettings set org.gnome.desktop.interface font-name 'Adwaita Sans 11'
gsettings set org.gnome.desktop.interface monospace-font-name 'VictorMono Nerd Font 10'
gsettings set org.gnome.desktop.interface cursor-theme 'oreo_blue_cursors'
# Deliberately NOT setting cursor-size. GNOME here is on 16 (smaller than
# GNOME's own default of 24) and changing it would visibly alter the working
# GNOME session. Hyprland uses XCURSOR_SIZE=24 from uwsm/env; if the cursor
# feels too large there, change that one value rather than this one.
fi
echo -e "\n--- Hyprland session services ---"
# Deliberately NOT enabling these.
#
# hyprpaper / hypridle / hyprpolkitagent / vicinae all ship units that are
# WantedBy=graphical-session.target -- and that target is active under GNOME
# too. Enabling them would start hypridle alongside GNOME's own idle handling
# (two daemons blanking and locking the screen on different timers) and start
# hyprpaper where there is no layer shell for it to draw on.
#
# Instead hypr/autostart.lua runs `systemctl --user start ...` on
# hyprland.start, which scopes them to the Hyprland session. They still get the
# correct uwsm activation environment and still stop in order, because they are
# PartOf=graphical-session.target.
log "Hyprland services are started per-session by hypr/autostart.lua, not enabled globally"
# espanso is the exception to the rule above: text expansion is wanted under
# any compositor and conflicts with nothing GNOME runs, and upstream's own
# mechanism is a registered user unit. The RPM ships no unit -- without this,
# the package installs, the config links, and no trigger ever fires.
# `service register` writes and enables the unit and is idempotent on re-runs;
# autostart.lua also starts it so the first Hyprland login after a fresh
# install expands text without waiting for the next one.
if exists espanso && ! systemctl --user cat espanso.service >/dev/null 2>&1; then
log "Registering the espanso text-expansion service"
espanso service register >/dev/null 2>&1 || log "Could not register espanso"
fi
# Notification daemons must NOT be installed: mako, dunst and swaync all
# register Name=org.freedesktop.Notifications for D-Bus activation, which races
# Quickshell's own notification server at login. Whoever wins keeps the name.
for pkg in mako dunst SwayNotificationCenter; do
if rpm -q "$pkg" >/dev/null 2>&1; then
log "WARNING: $pkg is installed and will fight Quickshell for the notification D-Bus name."
log " Fix with: systemctl --user mask ${pkg,,}.service"
fi
done
# The launcher theme is NOT set here any more. vicinae.json selects one theme
# per system appearance -- panama-dark and panama-light, both rendered from the
# active Panama theme by quickshell/scripts/panama-theme-apps -- and
# `vicinae theme set` replaces that pair with a single fixed name. It would pin
# the launcher to one palette for good, and it would do it by rewriting
# vicinae.json, which is symlinked out of this repository.
# A machine with a battery gets managed idle timings from the start. The
# shipped hypridle.conf deliberately never suspends -- correct for a desktop,
# and exactly wrong for a laptop in a bag. panama-idle generates the
# power-source-aware config and points hypridle at it with a drop-in; it does
# not start hypridle here (the Hyprland session does that), so running it
# under GNOME during install is safe. A desktop skips this entirely and keeps
# the shipped file, as before.
if "${PANAMA_PATH:-$HOME/.local/share/Panama}/bin/panama-hw" battery 2>/dev/null; then
log "Battery detected: enabling managed idle timings (suspend on battery works out of the box)"
"${PANAMA_PATH:-$HOME/.local/share/Panama}/config/dot/quickshell/scripts/panama-idle" install \
|| log "Could not enable managed idle timings; the Power page can turn them on later"
fi