fix(qt): rename on-prefixed QML properties and gate the pattern

A property named `on<Upper>` is filed as a signal handler as soon as a
sibling member `<upper>` exists: its initializer never binds, it sits at
the type default, and nothing warns. `PurchasesView.qml` declared
`onAlbums` next to `albums`, so the Albums tab bound `[]` once and never
re-evaluated, which blanked Purchases for every account with real
purchases. Reproduced standalone with the `qml` runtime: the identical
expression under another name reads `true`.

Rename it to `albumsTab` and the four other `on<Upper>` properties
(`collectionsTab`, `surfaceTint`, `accentFloor`, `litColor`) so the rule
can be exact, and add `qml_on_prefixed_property_audit.py` to the four
QML audit sites (qt-run, cargo-test, test-crates, qt-gate-windows).

cc
This commit is contained in:
vicrodh committed 2026-09-01 23:40:33 -06:00
1 parent 7627ac7a36
commit 1cb988954e
10 files changed
+128 -35

No files matched your search

+4 -4
View File
@@ -198,7 +198,7 @@ QtObject {
// answer is a SELECTOR, not a constant.
//
// THE RULE — theme intent first, floor-guarded:
// 1. `accentText`, whenever it clears `onAccentFloor` against the LIVE
// 1. `accentText`, whenever it clears `accentFloor` against the LIVE
// accent. It is the theme author's own on-accent colour, and — via
// `accentGlyphColor` — it is what the sibling LABELS across the app
// resolve to on 34 of the 35 rows (FilterChip, CastPicker,
@@ -259,7 +259,7 @@ QtObject {
/// The non-text contrast floor (WCAG 1.4.11). Read the note above before
/// raising it: 4.5 moves the three DEFAULT themes.
readonly property real onAccentFloor: 3.0
readonly property real accentFloor: 3.0
/// The QbzIcon tint NAME for a glyph drawn on an accent fill.
///
@@ -289,7 +289,7 @@ QtObject {
readonly property string accentGlyphTint: {
const la = _relLum(accent) + 0.05
const lt = _relLum(accentText) + 0.05
if ((la > lt ? la / lt : lt / la) >= onAccentFloor)
if ((la > lt ? la / lt : lt / la) >= accentFloor)
return "accentText"
// Accent-text is not legible on this accent. Pick the extreme that
// holds on BOTH fills a control paints (rest + hover) — see the
@@ -298,7 +298,7 @@ QtObject {
// white: (1.0 + 0.05) / (Lfill + 0.05); black: (Lfill + 0.05) / 0.05
const white = Math.min(1.05 / la, 1.05 / lh)
const black = Math.min(la, lh) / 0.05
if (Math.max(white, black) >= onAccentFloor)
if (Math.max(white, black) >= accentFloor)
return white >= black ? "white" : "black"
// LAST RESORT — neither extreme survives BOTH fills. Scoring the two
// fills jointly takes a `min()`, and a `min()` has no floor of its