feat(qt): theme Qt apps with Catppuccin via Kvantum
Qt apps (e.g. VLC) rendered in the default Fusion style — GTK theming
does not cover Qt. Add the Kvantum style engine + Catppuccin Mocha
Lavender theme, wired via QT_STYLE_OVERRIDE, which covers both Qt5 and
Qt6 (QT_QPA_PLATFORMTHEME can select only one plugin at a time).
Also move all GUI-toolkit env vars (QT_*/GDK/SDL/CLUTTER) from zshrc to
niri's environment{} block: niri is systemd-started, so zsh exports
never reached niri-spawned GUI apps (verified via /proc/environ), only
terminal-launched ones — the app launcher included.
- packages: kvantum, kvantum-qt5, qt6ct + kvantum-theme-catppuccin-git (AUR)
- niri config.kdl: environment{} block; zshrc: GUI-toolkit vars removed
- qt6ct.conf (style=kvantum, icon_theme=Colloid), Kvantum/kvantum.kvconfig
(theme=catppuccin-mocha-lavender, the Lavender accent)
- CLAUDE.md + DECISIONS.md
This commit is contained in:
@@ -114,6 +114,18 @@ System-wide generic-family defaults via `defaults/etc/fonts/conf.d/65-moonarch-f
|
||||
- Aliases need `binding="strong"` — a weak `<prefer>` (fontconfig default) ranks behind the effective generic fallback and does not take effect.
|
||||
- Only applies to apps that use generic families (e.g. Firefox web fallback). moonarch apps (Waybar, foot, GTK, walker, swaync) set the font explicitly.
|
||||
|
||||
## Qt Theming (Catppuccin via Kvantum)
|
||||
|
||||
Qt apps (e.g. VLC) get the Catppuccin Mocha look via the **Kvantum** style engine — GTK theming (Colloid) does not cover Qt, and the Qt5 GTK-follow path (`qt5-styleplugins`) is unmaintained and not in the official repos.
|
||||
|
||||
- **Style — `QT_STYLE_OVERRIDE=kvantum` is the workhorse.** A single value themes **both Qt5 (VLC 3) and Qt6**. `QT_QPA_PLATFORMTHEME` cannot: one value selects either the Qt5 `qt5ct` plugin or the Qt6 `qt6ct` plugin, never both. The style override sidesteps that, so we ship `kvantum` + `kvantum-qt5` (Qt6 + Qt5 style plugins) and **skip `qt5ct`**.
|
||||
- **Theme:** `kvantum-theme-catppuccin-git` (AUR) installs all flavors to `/usr/share/Kvantum/`; `defaults/xdg/Kvantum/kvantum.kvconfig` selects `catppuccin-mocha-lavender` (matches the ecosystem Lavender accent `#b4befe`).
|
||||
- **Qt6 icons/palette:** `QT_QPA_PLATFORMTHEME=qt6ct` + `defaults/xdg/qt6ct/qt6ct.conf` (`icon_theme=Colloid-Grey-Catppuccin-Dark`). Qt5/VLC relies on the style override alone (no platform theme).
|
||||
- **Env location — must be niri, not zshrc.** niri is started by systemd, so niri-spawned GUI apps (app launcher, `spawn`, `spawn-at-startup`) never inherit zsh exports — only terminal-launched apps would (verified via `/proc/<pid>/environ`). All GUI-toolkit vars therefore live in niri's `environment {}` block (`defaults/xdg/niri/config.kdl`), not `defaults/shell/zshrc`; zshrc keeps only shell-oriented (`TERMINAL`/`EDITOR`) + `XDG_*` session vars.
|
||||
- **Fonts** come from the fontconfig generic-family defaults (see below); qt6ct leaves fonts unset so they resolve through fontconfig.
|
||||
|
||||
Rationale + rejected alternatives: `DECISIONS.md` (2026-07-15).
|
||||
|
||||
## Browser Idle-Inhibit (xdg-desktop-portal)
|
||||
|
||||
So that windowed browser video (Firefox/Waterfox) keeps the screen awake, via `defaults/etc/xdg-desktop-portal/niri-portals.conf` (owned by moonarch-git, higher priority than niri's `/usr/share/xdg-desktop-portal/niri-portals.conf`):
|
||||
|
||||
@@ -242,3 +242,9 @@
|
||||
- **Why**: A popout action that triggers an external auth toplevel left focus stuck on quickshell — reproduced with the network popout: select a VPN → Enter → `nmcli connection up` fires nm-applet's secret agent → gnome-keyring/gcr shows a GTK unlock prompt, but keyboard focus stayed on the popout, so the prompt was untypeable. Same class for Wi-Fi PSK, polkit, any dialog spawned by any popout. Not VPN-specific — the cause is the popout's keyboard-focus grab.
|
||||
- **Tradeoffs**: Root cause is `PopoutHost`'s `WlrKeyboardFocus.Exclusive` while open. Per wlr-layer-shell, Exclusive on the overlay layer sits above all normal windows, so the compositor never focuses a newly-mapped toplevel while it holds. Empirically verified on niri 26.04 (`niri msg focused-window`): under **Exclusive**, a prompt maps with `is_focused=false` and `focused-window` stays `null` — no `WindowFocusChanged` fires, so a listen-and-close approach is impossible (there is no focus event to react to). Under **OnDemand**, a keybind-opened popout *still* grabs the keyboard on open (`focused-window: null` → Escape/Tab/arrow nav preserved) **and** an externally-mapped toplevel takes focus (`nm-connection-editor is_focused=true`). So OnDemand fixes it with no loss of the keyboard-nav feature and no per-action handler code. Rejected: closing the popout on the VPN toggle (symptom fix, per-action, doesn't generalise).
|
||||
- **How**: `PopoutHost.qml` — `keyboardFocus: root.wantOpen ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None` (was `Exclusive`), comment updated with the verified niri behaviour. One line; covers every popout and every prompt type.
|
||||
|
||||
## 2026-07-15 – Qt apps get the Catppuccin look via Kvantum; GUI-toolkit env moved to niri
|
||||
- **Who**: Dominik, ClaudeCode
|
||||
- **Why**: Qt apps (concretely VLC 3) ignored the system theme — they rendered in the default Fusion style while everything else is Catppuccin Mocha. moonarch themes GTK system-wide (Colloid) but had no Qt story. Diagnosis found the existing setup half-wired: `QT_QPA_PLATFORMTHEME=qt6ct` was exported but `qt6ct` was never installed, so the variable pointed at nothing.
|
||||
- **Tradeoffs**: (1) **Approach** — Qt-follows-GTK (`QT_QPA_PLATFORMTHEME=gtk3` / qgnomeplatform) vs. a native Qt Catppuccin theme. GTK-follow was rejected: it fails on the reported app — VLC is Qt5, and the Qt5 GTK-style plugin (`qt5-styleplugins`) is unmaintained and absent from the official repos; GTK-follow is also unreliable on non-GNOME Wayland. Picked **Kvantum** — a maintained Catppuccin theme, best visual match, covers Qt5 + Qt6. (2) **Style wiring** — `QT_QPA_PLATFORMTHEME` cannot theme both Qt versions at once (one value selects either the Qt5 `qt5ct` plugin or the Qt6 `qt6ct` plugin, never both). `QT_STYLE_OVERRIDE=kvantum` is honoured by **both** Qt5 and Qt6, so it is the primary mechanism; `qt6ct` is kept only as a Qt6 bonus for icons/palette, and `qt5ct` is skipped (the style override covers the Qt5 look; qt5ct would add only Qt5 icon control). (3) **Env location** — the Qt/GTK/SDL/Clutter vars lived in `defaults/shell/zshrc`. Verified empirically (`/proc/<pid>/environ` of niri and a niri-spawned quickshell) that **niri is systemd-started and its children never inherit zsh exports** — so those vars only ever reached terminal-launched apps, never the app launcher / `spawn`. Rejected keeping them in zshrc (would not fix VLC). Moved all GUI-toolkit vars to niri's `environment {}` block; `TERMINAL`/`EDITOR`/`XDG_*` stay in zshrc. (4) **Theme delivery** — vendor the one Mocha-Lavender theme into `defaults/` vs. the AUR package. Picked the AUR package `kvantum-theme-catppuccin-git` for consistency with how the GTK theme ships (`colloid-catppuccin-theme-git`); it installs to `/usr/share/Kvantum/`, a Kvantum search path.
|
||||
- **How**: `packages/official.txt` += `kvantum kvantum-qt5 qt6ct`; `packages/aur.txt` += `kvantum-theme-catppuccin-git`. New `environment {}` block in `defaults/xdg/niri/config.kdl` (QT_QPA_PLATFORM, QT_QPA_PLATFORMTHEME=qt6ct, QT_STYLE_OVERRIDE=kvantum, QT_AUTO_SCREEN_SCALE_FACTOR, QT_WAYLAND_DISABLE_WINDOWDECORATION, GDK_BACKEND, SDL_VIDEODRIVER, CLUTTER_BACKEND); the same GUI vars removed from `defaults/shell/zshrc`. New `defaults/xdg/qt6ct/qt6ct.conf` (style=kvantum, icon_theme=Colloid-Grey-Catppuccin-Dark) and `defaults/xdg/Kvantum/kvantum.kvconfig` (theme=catppuccin-mocha-lavender, matching the Lavender accent `#b4befe`). Both deploy to `/etc/xdg/` automatically via the moonarch-git PKGBUILD's `defaults/xdg` glob (no PKGBUILD change); not added to `moonarch-doctor` — like `niri/config.kdl` and the GTK `settings.ini`, owned `/etc/xdg` configs have no `/usr/share/moonarch` reference copy to compare against. Open item at commit time: verify Kvantum reads `kvantum.kvconfig` from `/etc/xdg/Kvantum/`; if not, seed `~/.config/Kvantum/` from post-install (as done for the GTK theme via gsettings).
|
||||
|
||||
@@ -125,14 +125,10 @@ if [[ -f /usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh ]];
|
||||
fi
|
||||
|
||||
# --- Wayland environment ---
|
||||
# GUI-toolkit vars (QT_*/GDK/SDL/CLUTTER) live in niri's environment {} block, not here:
|
||||
# niri is systemd-started, so a zsh export only reaches terminal-launched apps, never
|
||||
# niri-spawned GUI apps. Kept here: shell-oriented + XDG session identity.
|
||||
export TERMINAL="footclient"
|
||||
export GDK_BACKEND="wayland,x11,*"
|
||||
export QT_QPA_PLATFORM="wayland;xcb"
|
||||
export QT_QPA_PLATFORMTHEME="qt6ct"
|
||||
export QT_AUTO_SCREEN_SCALE_FACTOR="1"
|
||||
export QT_WAYLAND_DISABLE_WINDOWDECORATION="1"
|
||||
export SDL_VIDEODRIVER="wayland"
|
||||
export CLUTTER_BACKEND="wayland"
|
||||
export XDG_CURRENT_DESKTOP="niri"
|
||||
export XDG_SESSION_DESKTOP="niri"
|
||||
export XDG_SESSION_TYPE="wayland"
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# ABOUTME: System Kvantum config — selects the Catppuccin Mocha Lavender theme (moonarch accent).
|
||||
# ABOUTME: Deployed to /etc/xdg/Kvantum/kvantum.kvconfig; a user copy in ~/.config/Kvantum wins by XDG precedence.
|
||||
[General]
|
||||
theme=catppuccin-mocha-lavender
|
||||
@@ -1,6 +1,21 @@
|
||||
// ABOUTME: Moonarch default Niri compositor configuration.
|
||||
// ABOUTME: User overrides go in ~/.config/niri/config.kdl
|
||||
|
||||
// GUI-toolkit environment for every niri-spawned app (launcher, spawn, spawn-at-startup).
|
||||
// These must live here, not in zshrc: niri is started by systemd, so a zsh export only
|
||||
// reaches terminal-launched apps — niri's children never see it. QT_QPA_PLATFORMTHEME +
|
||||
// QT_STYLE_OVERRIDE give Qt apps (e.g. VLC) the Catppuccin look via qt6ct + Kvantum.
|
||||
environment {
|
||||
QT_QPA_PLATFORM "wayland;xcb"
|
||||
QT_QPA_PLATFORMTHEME "qt6ct"
|
||||
QT_STYLE_OVERRIDE "kvantum"
|
||||
QT_AUTO_SCREEN_SCALE_FACTOR "1"
|
||||
QT_WAYLAND_DISABLE_WINDOWDECORATION "1"
|
||||
GDK_BACKEND "wayland,x11,*"
|
||||
SDL_VIDEODRIVER "wayland"
|
||||
CLUTTER_BACKEND "wayland"
|
||||
}
|
||||
|
||||
cursor {
|
||||
xcursor-theme "Sweet-cursors"
|
||||
hide-when-typing
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# ABOUTME: System qt6ct config — Qt6 icon theme + Kvantum style for Catppuccin consistency.
|
||||
# ABOUTME: Deployed to /etc/xdg/qt6ct/qt6ct.conf; a user copy in ~/.config/qt6ct wins by XDG precedence.
|
||||
[Appearance]
|
||||
style=kvantum
|
||||
icon_theme=Colloid-Grey-Catppuccin-Dark
|
||||
standard_dialogs=default
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
# Theming
|
||||
colloid-catppuccin-theme-git
|
||||
kvantum-theme-catppuccin-git
|
||||
|
||||
# Fonts
|
||||
otf-openmoji
|
||||
|
||||
@@ -87,6 +87,11 @@ qt6-5compat
|
||||
# Themes & Fonts
|
||||
ttf-ubuntusans-nerd
|
||||
|
||||
# Qt Theming (Catppuccin via Kvantum — see CLAUDE.md "Qt Theming")
|
||||
kvantum
|
||||
kvantum-qt5
|
||||
qt6ct
|
||||
|
||||
# Applications
|
||||
viewnior
|
||||
|
||||
|
||||
Reference in New Issue
Block a user