Single-script builder (nosignal.sh) that turns a stock Arch Linux ISO into a fully-offline installer for a themed Hyprland + caelestia (Quickshell) desktop: matching SDDM greeter, Btrfs/Limine bootable snapshots, chwd-style GPU detection, and a curated "os updates" layer (keybind cheatsheet, settings panels, system polish, on-box management skill). See README.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
67 lines
3.2 KiB
Markdown
Executable file
67 lines
3.2 KiB
Markdown
Executable file
# app-theme-awareness
|
|
|
|
User-level, no root.
|
|
|
|
## Goal
|
|
Make external apps (Chrome/Chromium, Electron, Firefox, GTK, Qt) **follow
|
|
Caelestia's light/dark mode** automatically — dark when Caelestia is dark.
|
|
|
|
## Why they don't today
|
|
Modern apps read one signal: `org.freedesktop.appearance` → `color-scheme`,
|
|
published by **xdg-desktop-portal**. By default that value is **0
|
|
("no preference")** because nothing sets it — `gsettings
|
|
org.gnome.desktop.interface color-scheme` is `'default'`. So every app defaults
|
|
to light. All portal pieces are already installed (`xdg-desktop-portal`,
|
|
`-gtk`, `-hyprland`); `libadwaita` is present.
|
|
|
|
## How this works
|
|
- **`nosignal-app-theme-sync`**: reads `caelestia scheme get` ("Mode: dark|
|
|
light") and sets:
|
|
- `gsettings org.gnome.desktop.interface color-scheme` → `prefer-dark` /
|
|
`prefer-light`. xdg-desktop-portal-gtk republishes this as the freedesktop
|
|
appearance `color-scheme`, which **Chrome, Electron, Firefox, GTK4/libadwaita
|
|
and Qt6 honor** (UI + web `prefer-color-scheme`).
|
|
- `gtk-application-prefer-dark-theme` in `gtk-3.0`/`gtk-4.0` `settings.ini`
|
|
for legacy GTK3 apps that ignore the portal.
|
|
- **`nosignal-app-theme.path` + `.service`** (user units, mirroring NoSignal's
|
|
`hyprmoncfgd-rescan.path`): watch `~/.local/state/caelestia/scheme.json` and
|
|
re-run the sync on every scheme change, and run it once at login. So flipping
|
|
Caelestia light↔dark flips the apps live.
|
|
- **`portals.conf`**: pins the Settings portal backend to `gtk` (keeping
|
|
Hyprland's portal default for screencast), so the appearance value is served
|
|
reliably. Installed only if the user has no `portals.conf`.
|
|
|
|
`install-app-theme-awareness.sh` does all of it idempotently — entirely
|
|
user-level (no root, no pacman hook).
|
|
|
|
## Per-app notes
|
|
- **Chrome/Chromium (Wayland):** follows the portal automatically. If the UI
|
|
stays light, set `chrome://settings` → Appearance → **GTK / "Use system"**.
|
|
- **Qt:** `QT_QPA_PLATFORMTHEME=qtengine` is already set; Qt6 honors the portal.
|
|
Old Qt5 apps may need a dark qt5ct/Kvantum style (out of scope).
|
|
- **GTK3 dark fidelity:** prefer-dark uses Adwaita's built-in dark rendering. For
|
|
a fuller dark GTK3 theme the builder can add `gnome-themes-extra` (ships
|
|
`Adwaita-dark`) — optional.
|
|
|
|
## Builder integration
|
|
Ship the sync script in the layer bin, the two user units (enabled by default,
|
|
like the other NoSignal user units), and seed `portals.conf`. Ideally Caelestia
|
|
itself could set `color-scheme` when its scheme flips; until then these units
|
|
bridge it. Mode is read from `caelestia scheme get`, so it tracks the dynamic
|
|
Material scheme.
|
|
|
|
## Verify (after install)
|
|
```
|
|
caelestia scheme set -m light # or via the Caelestia UI
|
|
gsettings get org.gnome.desktop.interface color-scheme # -> 'prefer-light'
|
|
caelestia scheme set -m dark
|
|
gsettings get org.gnome.desktop.interface color-scheme # -> 'prefer-dark'
|
|
# Chrome/GTK apps follow within a moment.
|
|
```
|
|
|
|
## Files
|
|
- `nosignal-app-theme-sync` — mode → portal/GTK sync.
|
|
- `nosignal-app-theme.service` / `.path` — login run + watch-on-change.
|
|
- `portals.conf` — Settings backend = gtk.
|
|
- `install-app-theme-awareness.sh` — idempotent user-level installer.
|
|
- `migrations/1781442000-app-theme-awareness.sh` — delegates to it.
|