mirror of
https://github.com/Nexoniarz/nexoniarz-config-nixos.git
synced 2026-11-03 20:44:27 +00:00
Add Qt/GTK2 theming, default apps, LibreOffice; fix display.conf race
- Add qt-theme-set: a working Qt theming pipeline via qt6ct (the QT_QPA_PLATFORMTHEME=qt6ct env var was pointing at a platform theme plugin that wasn't even installed, so every Qt app fell back to its own default style). Also regenerates kdeglobals' KColorScheme groups and sets QT_QUICK_CONTROLS_STYLE=org.kde.desktop for Kirigami-based KDE apps, whose QML-drawn chrome ignores QPalette/qt6ct entirely. Gwenview's dialogs/content now follow the theme; its toolbar/statusbar chrome is a known remaining gap tied to Kirigami's platform-theme detection outside a full Plasma session - Add GTK2 compat (~/.gtkrc-2.0: icon theme + font follow the theme; no dark variant exists for GTK2's Adwaita engine) - Add modules/default-apps.nix: Gwenview/Ark as system-default image viewer/archive manager via /etc/xdg/mimeapps.list, LibreOffice (Qt6 build), and a working Thunar "Open Terminal Here" (it shipped calling exo-open, which isn't installed and never resolved) - Fix display-set.sh: mktemp defaulted to /tmp, a different filesystem than ~/.config/hypr here, making the mv into display.conf a non-atomic copy+unlink. Hyprland's file watcher could catch it mid-replace and throw "source= globbing error: found no match" on any monitor mode/orientation change. Stress-tested with 60 concurrent write+reload cycles after the fix with zero errors
This commit is contained in:
parent
1f5f9795bc
commit
d1ff0a11e0
9 changed files with 224 additions and 2 deletions
|
|
@ -25,7 +25,15 @@ touch "$conf"
|
|||
|
||||
line="monitor = $descriptor"
|
||||
if grep -q "^monitor = $mon," "$conf" 2>/dev/null; then
|
||||
tmp=$(mktemp)
|
||||
# mktemp in the same directory as $conf, not the default /tmp: /tmp is
|
||||
# a different filesystem here, which makes `mv` below a non-atomic
|
||||
# copy+unlink instead of a rename — Hyprland's file watcher (it
|
||||
# watches every `source=`d file, including this one) could catch the
|
||||
# destination mid-replace and its `source=` glob would find nothing,
|
||||
# throwing "globbing error: found no match" (observed live after an
|
||||
# orientation change, which always hits this branch since DP-1
|
||||
# already has an existing line by then).
|
||||
tmp=$(mktemp "$conf.XXXXXX")
|
||||
awk -v prefix="monitor = $mon," -v newline="$line" '
|
||||
index($0, prefix) == 1 { print newline; next } { print }
|
||||
' "$conf" > "$tmp"
|
||||
|
|
|
|||
|
|
@ -117,3 +117,16 @@ if command -v dconf >/dev/null 2>&1; then
|
|||
dconf write /org/gnome/desktop/interface/icon-theme "'$icon_theme'"
|
||||
dconf write /org/gnome/desktop/interface/color-scheme "'$color_scheme'"
|
||||
fi
|
||||
|
||||
# GTK2 compat: separate config format (~/.gtkrc-2.0, not settings.ini),
|
||||
# and no live theme-switching mechanism at all — GTK2 apps only read this
|
||||
# at their own startup. Only icon theme and font actually follow the
|
||||
# current theme; gnome-themes-extra's bundled GTK2 Adwaita engine has no
|
||||
# dark variant to switch to (GTK2 predates that concept), so gtk-theme-
|
||||
# name here is always the one real option, not a broken attempt at dark
|
||||
# mode.
|
||||
cat > "$HOME/.gtkrc-2.0" <<EOF
|
||||
gtk-theme-name="Adwaita"
|
||||
gtk-icon-theme-name="$icon_theme"
|
||||
gtk-font-name="Noto Sans 10"
|
||||
EOF
|
||||
|
|
|
|||
105
modules/scripts/qt-theme-set.sh
Normal file
105
modules/scripts/qt-theme-set.sh
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#!/usr/bin/env bash
|
||||
# Regenerates qt6ct's config + color scheme to match the current Quickshell
|
||||
# theme, the Qt-side equivalent of gtk-theme-set. Qt apps (Gwenview, Ark,
|
||||
# Kate, ...) had no working platform theme plugin at all before this — the
|
||||
# QT_QPA_PLATFORMTHEME=qt6ct env var (hyprland.conf) was pointing at a
|
||||
# plugin that wasn't even installed, so every Qt app fell back to
|
||||
# whatever default style/palette it shipped with, ignoring the rest of
|
||||
# the desktop entirely. style=Fusion (not a KDE/Breeze style) matters
|
||||
# specifically: Fusion paints straight from QPalette, so a custom color
|
||||
# scheme here is guaranteed to actually show — Breeze-family styles
|
||||
# prefer reading colors from kdeglobals instead, which is a separate,
|
||||
# static, unrelated leftover file on this machine.
|
||||
set -euo pipefail
|
||||
|
||||
accent="${1:?usage: qt-theme-set <accent> <bg> <bgAlt> <fg> <fgDim> <border> <dark:1|0>}"
|
||||
bg="${2:?bg required}"
|
||||
bg_alt="${3:?bgAlt required}"
|
||||
fg="${4:?fg required}"
|
||||
fg_dim="${5:?fgDim required}"
|
||||
border="${6:?border required}"
|
||||
dark="${7:?dark required}"
|
||||
|
||||
dir="$HOME/.config/qt6ct"
|
||||
mkdir -p "$dir/colors"
|
||||
|
||||
# qt6ct color scheme files store QPalette::ColorRole values as a fixed-
|
||||
# order, comma-separated #aarrggbb list — order and format verified
|
||||
# against the example schemes qt6ct itself ships
|
||||
# (share/qt6ct/colors/darker.conf etc.), not guessed: WindowText, Button,
|
||||
# Light, Midlight, Dark, Mid, Text, BrightText, ButtonText, Base, Window,
|
||||
# Shadow, Highlight, HighlightedText, Link, LinkVisited, AlternateBase,
|
||||
# NoRole, ToolTipBase, ToolTipText, PlaceholderText.
|
||||
a() { printf '#ff%s' "${1#\#}"; } # opaque
|
||||
t() { printf '#80%s' "${1#\#}"; } # translucent, for PlaceholderText
|
||||
|
||||
active="$(a "$fg"), $(a "$bg_alt"), $(a "$border"), $(a "$bg_alt"), $(a "$bg"), $(a "$border"), $(a "$fg"), $(a "$fg"), $(a "$fg"), $(a "$bg"), $(a "$bg"), $(a "$border"), $(a "$accent"), $(a "$bg"), $(a "$accent"), $(a "$accent"), $(a "$bg_alt"), $(a "$bg"), $(a "$bg_alt"), $(a "$fg"), $(t "$fg_dim")"
|
||||
disabled="$(a "$fg_dim"), $(a "$bg_alt"), $(a "$border"), $(a "$bg_alt"), $(a "$bg"), $(a "$border"), $(a "$fg_dim"), $(a "$fg_dim"), $(a "$fg_dim"), $(a "$bg"), $(a "$bg"), $(a "$border"), $(a "$accent"), $(a "$fg_dim"), $(a "$accent"), $(a "$accent"), $(a "$bg_alt"), $(a "$bg"), $(a "$bg_alt"), $(a "$fg_dim"), $(t "$fg_dim")"
|
||||
|
||||
color_file="$dir/colors/quickshell-theme.conf"
|
||||
cat > "$color_file" <<EOF
|
||||
[ColorScheme]
|
||||
active_colors=$active
|
||||
disabled_colors=$disabled
|
||||
inactive_colors=$active
|
||||
EOF
|
||||
|
||||
icon_theme="Gruvbox-Plus-Light"
|
||||
[ "$dark" = "1" ] && icon_theme="Gruvbox-Plus-Dark"
|
||||
|
||||
cat > "$dir/qt6ct.conf" <<EOF
|
||||
[Appearance]
|
||||
style=Fusion
|
||||
icon_theme=$icon_theme
|
||||
custom_palette=true
|
||||
color_scheme_path=$color_file
|
||||
standard_dialogs=default
|
||||
EOF
|
||||
|
||||
# qt6ct's palette only reaches classic QWidget UI. Modern KDE apps
|
||||
# (confirmed live: Gwenview) draw their toolbar/chrome with Kirigami/QML
|
||||
# instead, which ignores QPalette entirely and reads kdeglobals' color
|
||||
# groups directly via KColorScheme — so without this, qt6ct alone left
|
||||
# exactly that chrome stuck on whatever this machine's stale leftover
|
||||
# kdeglobals had (unrelated purple KDE colors from some earlier install),
|
||||
# while everything else (dialogs, the actual image viewport, ...)
|
||||
# correctly followed the theme.
|
||||
rgb() {
|
||||
local hex="${1#\#}"
|
||||
printf '%d,%d,%d' "0x${hex:0:2}" "0x${hex:2:2}" "0x${hex:4:2}"
|
||||
}
|
||||
|
||||
cat > "$HOME/.config/kdeglobals" <<EOF
|
||||
[General]
|
||||
ColorScheme=QuickshellTheme
|
||||
widgetStyle=Fusion
|
||||
|
||||
[KDE]
|
||||
widgetStyle=Fusion
|
||||
|
||||
[Colors:Window]
|
||||
BackgroundNormal=$(rgb "$bg_alt")
|
||||
ForegroundNormal=$(rgb "$fg")
|
||||
|
||||
[Colors:View]
|
||||
BackgroundNormal=$(rgb "$bg")
|
||||
ForegroundNormal=$(rgb "$fg")
|
||||
|
||||
[Colors:Button]
|
||||
BackgroundNormal=$(rgb "$bg_alt")
|
||||
ForegroundNormal=$(rgb "$fg")
|
||||
|
||||
[Colors:Selection]
|
||||
BackgroundNormal=$(rgb "$accent")
|
||||
ForegroundNormal=$(rgb "$bg")
|
||||
DecorationFocus=$(rgb "$accent")
|
||||
DecorationHover=$(rgb "$accent")
|
||||
|
||||
[Colors:Tooltip]
|
||||
BackgroundNormal=$(rgb "$bg_alt")
|
||||
ForegroundNormal=$(rgb "$fg")
|
||||
|
||||
[Colors:Header]
|
||||
BackgroundNormal=$(rgb "$bg_alt")
|
||||
ForegroundNormal=$(rgb "$fg")
|
||||
EOF
|
||||
Loading…
Reference in a new issue