#!/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'