Make the lock screen follow the colour scheme
hyprlock.conf shipped with Tokyo Night Moon hardcoded in six places, so choosing light mode left the lock screen dark. Every other surface had been taught to follow the scheme this week -- kitty, GTK, the launcher, btop, tmux, neovim -- and this was the one left, which is unfortunate, because it is the screen a user sees most often and the worst possible place to find a theming bug: you discover it while locked out of the machine and cannot fix it from there. It is now generated from a template on every scheme change, the same shape kitty, GTK, tmux and btop already use, and seeded by link-dotfiles so the first lock of a fresh install is themed rather than falling back to hyprlock's bare grey default. hyprlock is launched fresh on each lock (`pidof hyprlock || hyprlock`), so it picks the file up with no restart. The dark output is byte-identical to the file it replaces, ignoring comments -- verified by diff -- so nothing changes for anyone already in dark mode. One detail worth recording: hyprlock takes rgba(r, g, b, a) in DECIMAL, not hex, so the template carries "R, G, B" triples where every other theme file in this repository uses hex. Two values are the exception, sitting inside Pango markup where hyprlock wants ##rrggbb. Getting either wrong is not a parse error -- hyprlock ignores the value and uses its own default, silently. Which is why this has a contract. It generates both schemes into a fixture, never the live config, and checks that no placeholder survives substitution, that every colour is a well-formed decimal triple, that the Pango values are well-formed hex, that a light lock screen is actually light, and that the two schemes differ at all. Verified it catches a hardcoded colour left in the template and a light mode built from the dark palette, which is the original bug exactly. Claude-Session: https://claude.ai/code/session_01BRvzt4H8XXLPVH5MyYdk9L
This commit is contained in:
+93
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# The lock screen follows the colour scheme.
|
||||
#
|
||||
# It did not. hyprlock.conf shipped with Tokyo Night Moon hardcoded in six
|
||||
# places, so choosing light mode left the one screen a user sees most often
|
||||
# stubbornly dark. Every other surface -- kitty, GTK, the launcher, btop, tmux,
|
||||
# neovim -- had been taught to follow the scheme; this was the last one.
|
||||
#
|
||||
# It is also the worst place to discover a theming bug, because you find out
|
||||
# while locked out of the machine and cannot fix it from there. Hence a test.
|
||||
#
|
||||
# Generated into a fixture, never the live config: this contract must not
|
||||
# retheme the lock screen of the desktop it is running on.
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
template="$repo_dir/config/dot/hypr/hyprlock.conf.template"
|
||||
theme_apps="$repo_dir/config/dot/quickshell/scripts/panama-theme-apps"
|
||||
|
||||
fail() {
|
||||
printf 'lock screen theme contract: %s\n' "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
[[ -r "$template" ]] || fail 'hyprlock.conf.template is missing, so nothing generates the lock screen'
|
||||
|
||||
# The committed template must carry no literal colours. One left behind is a
|
||||
# colour that silently stays dark in light mode -- exactly the original bug.
|
||||
literal="$(grep -vE '^\s*#' "$template" | grep -oE 'rgba\([0-9]+, *[0-9]+, *[0-9]+' || true)"
|
||||
[[ -z "$literal" ]] \
|
||||
|| fail "the template still contains hardcoded colours, which will not follow the scheme: $literal"
|
||||
|
||||
fixture="$(mktemp -d /tmp/panama-lockscreen.XXXXXX)"
|
||||
trap 'rm -rf "$fixture"' EXIT
|
||||
mkdir -p "$fixture/hypr"
|
||||
cp "$template" "$fixture/hypr/"
|
||||
|
||||
for scheme in dark light; do
|
||||
XDG_CONFIG_HOME="$fixture" "$theme_apps" "$scheme" >/dev/null 2>&1
|
||||
generated="$fixture/hypr/hyprlock.conf"
|
||||
|
||||
[[ -r "$generated" ]] || fail "no hyprlock.conf was generated for $scheme"
|
||||
|
||||
# An unsubstituted placeholder is not a parse error to hyprlock; it is an
|
||||
# invalid colour it quietly ignores, falling back to its own default.
|
||||
leftover="$(grep -oE '@[A-Z_]+@' "$generated" || true)"
|
||||
[[ -z "$leftover" ]] \
|
||||
|| fail "$scheme left placeholders unsubstituted: $leftover"
|
||||
|
||||
# Every colour hyprlock is given must be a complete decimal triple. It
|
||||
# takes rgba(r, g, b, a), NOT hex, and a hex value here is silently ignored.
|
||||
while read -r colour; do
|
||||
[[ -n "$colour" ]] || continue
|
||||
grep -qE '^rgba\([0-9]{1,3}, [0-9]{1,3}, [0-9]{1,3}$' <<<"$colour" \
|
||||
|| fail "$scheme produced a malformed colour: $colour"
|
||||
done < <(grep -vE '^\s*#' "$generated" | grep -oE 'rgba\([^)]*' | sed 's/,[^,]*$//')
|
||||
|
||||
# The Pango markup values are hex, and hyprlock wants them doubled-hashed.
|
||||
while read -r pango; do
|
||||
[[ -n "$pango" ]] || continue
|
||||
grep -qE '^##[0-9a-f]{6}$' <<<"$pango" \
|
||||
|| fail "$scheme produced malformed Pango markup colour: $pango"
|
||||
done < <(grep -vE '^\s*#' "$generated" | grep -oE '##[0-9a-fA-F]{6}')
|
||||
|
||||
# The whole background block, not a fixed number of lines after it: the
|
||||
# colour sits near the end, after the blur and noise settings.
|
||||
background="$(awk '/^background \{/,/^\}/' "$generated" \
|
||||
| grep -vE '^\s*#' | grep -oE 'color = rgba\([0-9]+' | grep -oE '[0-9]+$' | head -1)"
|
||||
[[ -n "$background" ]] || fail "$scheme produced no background colour"
|
||||
|
||||
# The point of the whole exercise: a light lock screen must actually be
|
||||
# light. 128 splits the two cleanly for these palettes.
|
||||
if [[ "$scheme" == "light" ]]; then
|
||||
(( background > 128 )) \
|
||||
|| fail "light mode produced a DARK lock screen background (red channel $background) -- the original bug"
|
||||
else
|
||||
(( background < 128 )) \
|
||||
|| fail "dark mode produced a LIGHT lock screen background (red channel $background)"
|
||||
fi
|
||||
done
|
||||
|
||||
# The two schemes must actually differ, or the substitution is a no-op that
|
||||
# passes every check above.
|
||||
XDG_CONFIG_HOME="$fixture" "$theme_apps" dark >/dev/null 2>&1
|
||||
dark_hash="$(sha256sum "$fixture/hypr/hyprlock.conf" | cut -d' ' -f1)"
|
||||
XDG_CONFIG_HOME="$fixture" "$theme_apps" light >/dev/null 2>&1
|
||||
light_hash="$(sha256sum "$fixture/hypr/hyprlock.conf" | cut -d' ' -f1)"
|
||||
[[ "$dark_hash" != "$light_hash" ]] \
|
||||
|| fail 'the light and dark lock screens are byte-identical, so the scheme is not being applied'
|
||||
|
||||
printf 'lock screen theme contract: PASS\n'
|
||||
Reference in New Issue
Block a user