Reported symptom: Electron applications and a Chromium-based browser, all set to follow the system, went light when the desktop went light and never came back. Nothing reported an error, and the portal was serving the correct value the whole time. Cause: ColorScheme set gtk-theme to "Adwaita-dark" for dark and "Adwaita" for light. Neither is installed on Fedora 44 -- only adw-gtk3 and adw-gtk3-dark are. GTK responds to an unknown theme name by falling back to its built-in default, which is LIGHT. So asking for light worked by accident, asking for dark silently produced light, and anything that takes its cue from the GTK theme rather than the portal stayed light no matter what org.freedesktop.appearance said. Verified: the portal emits correctly in both directions, so this was never the portal's fault. Second cause, the mirror of the first: gtk-3.0/settings.ini and gtk-4.0/settings.ini were pinned to adw-gtk3-dark and prefer-dark=1 and never regenerated. Under GNOME that file is ignored because gnome-settings-daemon publishes over XSETTINGS; under Hyprland nothing does, so for GTK3 it is authoritative -- and it contradicted the scheme in light mode. They are now generated from a template on every switch, gitignored as machine state, and seeded by link-dotfiles, the same shape kitty's current-theme.conf already uses. These directories are symlinked into the repository, so writing the live file directly would dirty the working tree on every theme switch. The failure was silent by construction, so it gets a test rather than a comment: gtk-theme-contract asserts every theme name Panama sets is actually installed, and that the generated GTK config agrees with the scheme in both directions. Verified it catches both original bugs. Claude-Session: https://claude.ai/code/session_01BRvzt4H8XXLPVH5MyYdk9L
89 lines
4.0 KiB
Bash
Executable File
89 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# Every GTK theme name Panama sets must be a theme that is actually installed.
|
|
#
|
|
# This exists because of a bug that was invisible for weeks. ColorScheme set
|
|
# gtk-theme to "Adwaita-dark" for dark and "Adwaita" for light. Neither is
|
|
# installed on Fedora 44 -- only adw-gtk3 and adw-gtk3-dark are -- and GTK
|
|
# responds to an unknown theme name by silently falling back to its built-in
|
|
# default, which is LIGHT.
|
|
#
|
|
# So light mode appeared to work, dark mode produced light windows, and nothing
|
|
# anywhere reported an error. Applications that take their cue from the GTK
|
|
# theme rather than the portal -- Chromium and Electron among them -- were stuck
|
|
# light with no way to diagnose it from inside the application.
|
|
#
|
|
# The failure is silent by construction, so it needs a test rather than a
|
|
# comment. Checks the compositor-facing setting and the generated GTK config
|
|
# agree, and that both name something real.
|
|
|
|
set -uo pipefail
|
|
|
|
repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
color_scheme="$repo_dir/config/dot/quickshell/services/ColorScheme.qml"
|
|
theme_apps="$repo_dir/config/dot/quickshell/scripts/panama-theme-apps"
|
|
|
|
fail() {
|
|
printf 'gtk theme contract: %s\n' "$1" >&2
|
|
exit 1
|
|
}
|
|
|
|
theme_installed() {
|
|
local name="$1" dir
|
|
for dir in /usr/share/themes "$HOME/.themes" "$HOME/.local/share/themes"; do
|
|
[[ -d "$dir/$name/gtk-3.0" ]] && return 0
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# ── The names ColorScheme sets must exist ────────────────────────────────────
|
|
names="$(grep -oE 'root\.dark \? "[a-zA-Z0-9-]+" : "[a-zA-Z0-9-]+"' "$color_scheme" \
|
|
| grep -oE '"[a-zA-Z0-9-]+"' | tr -d '"' | grep -E '^adw-|^Adwaita' | sort -u)"
|
|
[[ -n "$names" ]] || fail 'could not find the GTK theme names in ColorScheme.qml -- this contract is not reading it correctly'
|
|
|
|
while read -r name; do
|
|
[[ -n "$name" ]] || continue
|
|
theme_installed "$name" \
|
|
|| fail "ColorScheme sets gtk-theme to \"$name\", which is not installed. GTK falls back to its light default when a theme is missing, so this produces light windows in dark mode with no error anywhere."
|
|
done <<<"$names"
|
|
|
|
# ── The generated GTK config must agree, in both directions ──────────────────
|
|
# Generated into a fixture rather than the live config, so running this cannot
|
|
# retheme the desktop it is running on.
|
|
fixture="$(mktemp -d /tmp/panama-gtk-theme.XXXXXX)"
|
|
trap 'rm -rf "$fixture"' EXIT
|
|
|
|
for version in 3.0 4.0; do
|
|
mkdir -p "$fixture/gtk-$version"
|
|
cp "$repo_dir/config/dot/gtk-$version/settings.ini.template" "$fixture/gtk-$version/" \
|
|
|| fail "gtk-$version has no settings.ini.template -- the generated file would never be produced"
|
|
done
|
|
|
|
for scheme in dark light; do
|
|
XDG_CONFIG_HOME="$fixture" "$theme_apps" "$scheme" >/dev/null 2>&1
|
|
|
|
for version in 3.0 4.0; do
|
|
generated="$fixture/gtk-$version/settings.ini"
|
|
[[ -r "$generated" ]] || fail "gtk-$version settings.ini was not generated for $scheme"
|
|
|
|
grep -q '@GTK_THEME@\|@PREFER_DARK@' "$generated" \
|
|
&& fail "gtk-$version settings.ini still contains an unsubstituted placeholder for $scheme"
|
|
|
|
theme="$(sed -n 's/^gtk-theme-name=//p' "$generated")"
|
|
prefer="$(sed -n 's/^gtk-application-prefer-dark-theme=//p' "$generated")"
|
|
|
|
theme_installed "$theme" \
|
|
|| fail "gtk-$version settings.ini names \"$theme\" for $scheme, which is not installed"
|
|
|
|
if [[ "$scheme" == "dark" ]]; then
|
|
[[ "$prefer" == "1" ]] || fail "gtk-$version asks for prefer-dark=$prefer in dark mode"
|
|
[[ "$theme" == *dark* ]] || fail "gtk-$version uses \"$theme\" in dark mode, which is not a dark theme"
|
|
else
|
|
[[ "$prefer" == "0" ]] || fail "gtk-$version asks for prefer-dark=$prefer in light mode"
|
|
[[ "$theme" != *dark* ]] || fail "gtk-$version uses \"$theme\" in light mode, which is a dark theme"
|
|
fi
|
|
done
|
|
done
|
|
|
|
printf 'gtk theme contract: PASS\n'
|