fix(qt): glyph colours follow the theme, on light palettes and on accent fills
Two defects with one cause: a tint name that means a frozen hex. "primary" is the legacy alias of literal #ffffff, not Theme.text-primary, so every control passing it drew a white glyph. On the eleven light themes that is white-on-light -- the header back/forward chevrons, the sidebar toggle and the carousel arrows the owner marked. They now pass the theme-following names, which icon_tint_qt bakes at runtime. The stale `hslLightness > 0.5 ? "primary" : "black"` workarounds that predate the runtime tinter collapse into those names, and the qrc floor underneath them becomes polarity-aware: dir_for() returns "" whenever the cache dir is unavailable, a bake fails or the theme document has not been published, and that path used to resolve textPrimary straight back to the white bake -- reproducing the bug it was fixing, app-wide, in the degraded state. On accent fills the fix is a deviation from Slint, approved by the owner after measurement. A fixed white glyph on Theme.accent falls under 2.6:1 on 16 of the 35 shipped palettes, including high-contrast at 1.70:1 and wcag-dark at 1.82:1 -- the two themes whose reason to exist is contrast. Slint hardcodes #ffffff there (CircleAction.slint:72 and three others), so the bug is upstream. accentText alone is not the answer either: it is picked for the theme's text ramp and gives 2.56:1 on Rose Pine Dawn, worse than the black it replaces. So QbzTheme picks the best-contrast tint by real sRGB luminance against the live accent, and the labels beside those glyphs use its colour twin -- BrowseGenreButton and LibraryView were drawing a white glyph next to an accentText label inside the same pill. Rounds out the two parity items the same files owe: QbzNavButton gains the ambient arm from Carousel.slint (wired at the six carousel sites, not left dead), and QbzCircleAction rounds its glyph to whole pixels the way CircleAction.slint does. cc
This commit is contained in:
52 files changed
+841
-153
No files matched your search
@@ -176,7 +176,7 @@ Rectangle {
|
||||
width: 18
|
||||
height: 18
|
||||
anchors.centerIn: parent
|
||||
tintName: moreArea.containsMouse ? "primary" : "muted"
|
||||
tintName: moreArea.containsMouse ? "textPrimary" : "muted"
|
||||
}
|
||||
MouseArea {
|
||||
id: moreArea
|
||||
|
||||
@@ -242,7 +242,9 @@ Rectangle {
|
||||
width: 13
|
||||
height: 13
|
||||
anchors.centerIn: parent
|
||||
tintName: "primary"
|
||||
// On the card's fixed brand gradient disc (indigo/violet
|
||||
// or amber), never on a theme surface.
|
||||
tintName: "white"
|
||||
}
|
||||
}
|
||||
Text {
|
||||
|
||||
@@ -132,13 +132,13 @@ Rectangle {
|
||||
readonly property color hdrStrong: headerLight ? "#ffffff" : theme.textPrimary
|
||||
readonly property color hdrBody: headerLight ? "#e0ffffff" : theme.textSecondary
|
||||
readonly property bool hdrOverlay: headerLight
|
||||
/// Slint's `Theme.text-primary` as an ICON tint. Icon tints in this port
|
||||
/// are pre-baked SVG variants (QbzIcon.qml) and the "primary" bake is a
|
||||
/// literal `fill="#ffffff"` — it is not the theme token. Every hover that
|
||||
/// raises a muted glyph to text-primary therefore has to pick the "black"
|
||||
/// bake on a light theme, or the glyph disappears at the moment it is
|
||||
/// supposed to light up. Same #638 class as the track-row play glyph.
|
||||
readonly property string tintOnSurface: theme.isDark ? "primary" : "black"
|
||||
/// Slint's `Theme.text-primary` as an ICON tint, for the hovers that raise
|
||||
/// a muted glyph on a THEME surface (every consumer sits on
|
||||
/// `surface-elevated`/transparent, never on the artwork header — that one
|
||||
/// uses `hdrStrong` above). Runtime-tinted via src/icon_tint_qt.rs, so it
|
||||
/// is the live token; it used to be `isDark ? "primary" : "black"`, a
|
||||
/// two-value stand-in from when only fixed bakes existed.
|
||||
readonly property string tintOnSurface: "textPrimary"
|
||||
/// TrackRow.slint:123-125 — the row hover uses the polarity-baked alpha
|
||||
/// ramp "so the hover state is visible on light themes too (the old
|
||||
/// #ffffff16 was invisible white-on-white there)". The zebra stripe is
|
||||
@@ -504,7 +504,9 @@ Rectangle {
|
||||
name: isActive && QbzPlayer.npPlaying ? "pause" : "play-fill"
|
||||
width: 16
|
||||
height: 16
|
||||
tintName: "primary"
|
||||
// On the #000000 @ 0.6 artwork scrim above — dark under
|
||||
// every theme.
|
||||
tintName: "white"
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -906,7 +906,7 @@ Rectangle {
|
||||
width: 20
|
||||
height: 20
|
||||
anchors.centerIn: parent
|
||||
tintName: gearArea.containsMouse ? "primary" : "muted"
|
||||
tintName: gearArea.containsMouse ? "textPrimary" : "muted"
|
||||
}
|
||||
MouseArea {
|
||||
id: gearArea
|
||||
|
||||
@@ -353,7 +353,7 @@ Rectangle {
|
||||
height: 16
|
||||
anchors.centerIn: parent
|
||||
tintName: parent.active ? "accent"
|
||||
: ttArea.containsMouse ? "primary" : "secondary"
|
||||
: ttArea.containsMouse ? "textPrimary" : "secondary"
|
||||
}
|
||||
MouseArea {
|
||||
id: ttArea
|
||||
@@ -385,7 +385,16 @@ Rectangle {
|
||||
width: 13
|
||||
height: 13
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
tintName: gtb.active ? "primary" : "secondary"
|
||||
// Same pair-of-halves fix as controls/BrowseGenreButton.qml:
|
||||
// the glyph said "primary" (legacy alias of a literal
|
||||
// #ffffff) next to an accent-text label, i.e. a white glyph
|
||||
// beside a black label on the pale-accent themes.
|
||||
// favorites/FavoritesView.slint:301 + :309 are consistently
|
||||
// #ffffff, but that white is 1.70:1 on high-contrast, 1.74
|
||||
// on ikari, 1.82 on wcag-dark and under 2.6:1 on 16 of the
|
||||
// 35 palettes — deliberate divergence from both lines.
|
||||
// theme/QbzTheme.qml, "ON AN ACCENT FILL".
|
||||
tintName: gtb.active ? theme.accentGlyphTint : "secondary"
|
||||
}
|
||||
Text {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
@@ -395,7 +404,9 @@ Rectangle {
|
||||
? QbzSession.tr("1 genre", QbzSession.trRev)
|
||||
: QbzSession.tr("{} genres", QbzSession.trRev)
|
||||
.replace("{}", root.genreCount)
|
||||
color: gtb.active ? theme.accentText : theme.textSecondary
|
||||
// The colour twin of the glyph's tint above — accent-text on
|
||||
// 34 of the 35 palettes.
|
||||
color: gtb.active ? theme.accentGlyphColor : theme.textSecondary
|
||||
font.pixelSize: 12
|
||||
}
|
||||
}
|
||||
@@ -532,7 +543,8 @@ Rectangle {
|
||||
color: "#a6000000"
|
||||
opacity: lrPlayArea.containsMouse ? 1.0 : 0.0
|
||||
Behavior on opacity { NumberAnimation { duration: 150 } }
|
||||
QbzIcon { name: "play-fill"; width: 16; height: 16; anchors.centerIn: parent; tintName: "primary" }
|
||||
// On the #a6000000 artwork scrim — dark under every theme.
|
||||
QbzIcon { name: "play-fill"; width: 16; height: 16; anchors.centerIn: parent; tintName: "white" }
|
||||
MouseArea {
|
||||
id: lrPlayArea
|
||||
anchors.fill: parent
|
||||
@@ -638,7 +650,10 @@ Rectangle {
|
||||
width: 14
|
||||
height: 14
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
tintName: item.source === "plex" ? "accent" : "primary"
|
||||
// Host is a transparent column over the theme row (NOT an
|
||||
// artwork scrim), so this matches its siblings
|
||||
// local/LocalAlbumRow.qml and local/LocalTrackRow.qml.
|
||||
tintName: item.source === "plex" ? "accent" : "muted"
|
||||
}
|
||||
}
|
||||
// Col — quality (albums + tracks).
|
||||
|
||||
@@ -369,7 +369,7 @@ Rectangle {
|
||||
width: 16
|
||||
height: 16
|
||||
anchors.centerIn: parent
|
||||
tintName: discArea.containsMouse ? "primary" : "muted"
|
||||
tintName: discArea.containsMouse ? "textPrimary" : "muted"
|
||||
}
|
||||
MouseArea {
|
||||
id: discArea
|
||||
|
||||
@@ -126,7 +126,7 @@ Rectangle {
|
||||
width: 16
|
||||
height: 16
|
||||
anchors.centerIn: parent
|
||||
tintName: root.rowHovered ? "primary" : "muted"
|
||||
tintName: root.rowHovered ? "textPrimary" : "muted"
|
||||
}
|
||||
MouseArea {
|
||||
id: playArea
|
||||
@@ -144,7 +144,7 @@ Rectangle {
|
||||
width: 16
|
||||
height: 16
|
||||
anchors.centerIn: parent
|
||||
tintName: moreArea.containsMouse ? "primary" : "secondary"
|
||||
tintName: moreArea.containsMouse ? "textPrimary" : "secondary"
|
||||
}
|
||||
MouseArea {
|
||||
id: moreArea
|
||||
|
||||
@@ -680,7 +680,15 @@ Rectangle {
|
||||
id: saveText
|
||||
anchors.centerIn: parent
|
||||
text: QbzSession.tr("Save", QbzSession.trRev)
|
||||
color: "#ffffff"
|
||||
// Was a literal #ffffff, 1:1 with
|
||||
// primitives/EditPlaylistModal.slint:171 — and that
|
||||
// white is 1.70:1 on high-contrast, 1.74 on ikari,
|
||||
// 1.82 on wcag-dark, under 2.6:1 on 16 of the 35
|
||||
// palettes, on the SAME accent fill every other
|
||||
// on-accent site was just fixed against. The colour
|
||||
// twin of the glyph selector; see
|
||||
// theme/QbzTheme.qml, "ON AN ACCENT FILL".
|
||||
color: theme.accentGlyphColor
|
||||
font.pixelSize: 13
|
||||
font.weight: theme.weightMedium
|
||||
}
|
||||
|
||||
@@ -361,7 +361,7 @@ Rectangle {
|
||||
radius: 12
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: clrArea.containsMouse ? theme.surfaceHover : theme.surfaceElevated
|
||||
QbzIcon { name: "x"; width: 13; height: 13; anchors.centerIn: parent; tintName: clrArea.containsMouse ? "primary" : "muted" }
|
||||
QbzIcon { name: "x"; width: 13; height: 13; anchors.centerIn: parent; tintName: clrArea.containsMouse ? "textPrimary" : "muted" }
|
||||
MouseArea {
|
||||
id: clrArea
|
||||
anchors.fill: parent
|
||||
|
||||
@@ -28,7 +28,14 @@ Rectangle {
|
||||
id: lbl
|
||||
anchors.centerIn: parent
|
||||
text: root.label
|
||||
color: root.active ? theme.accentText : theme.textSecondary
|
||||
// On the accent fill. NOT a departure from
|
||||
// locallibrary/LocalLibraryView.slint:690 (`Theme.accent-text`) —
|
||||
// `accentGlyphColor` RETURNS accent-text on 34 of the 35 palettes.
|
||||
// It is a floor under it: rose-pine-dawn's accent-text #575279 on
|
||||
// accent #d7827e is 2.56:1, and the twin hands back black at 7.38:1.
|
||||
// Reading it here instead of accent-text is also what keeps this chip
|
||||
// agreeing with the genre pills, which had to diverge outright.
|
||||
color: root.active ? theme.accentGlyphColor : theme.textSecondary
|
||||
font.pixelSize: theme.fontLegal
|
||||
font.weight: root.active ? theme.weightSemibold : theme.weightRegular
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ Rectangle {
|
||||
width: 18
|
||||
height: 18
|
||||
anchors.centerIn: parent
|
||||
tintName: moreArea.containsMouse ? "primary" : "muted"
|
||||
tintName: moreArea.containsMouse ? "textPrimary" : "muted"
|
||||
}
|
||||
MouseArea {
|
||||
id: moreArea
|
||||
|
||||
@@ -80,7 +80,13 @@ Rectangle {
|
||||
Text {
|
||||
width: parent.width
|
||||
text: root.item.displayName || root.item.name || ""
|
||||
color: root.selected ? theme.accentText : theme.textPrimary
|
||||
// Both labels sit on the selected row's `theme.accent` fill.
|
||||
// Same story as views/local/FilterChip.qml: NOT a departure
|
||||
// from locallibrary/LocalLibraryView.slint:653 + :660
|
||||
// (`Theme.accent-text`), which is what the twin returns on 34
|
||||
// of the 35 palettes — only a floor for rose-pine-dawn, where
|
||||
// accent-text measures 2.56:1 on this accent.
|
||||
color: root.selected ? theme.accentGlyphColor : theme.textPrimary
|
||||
font.pixelSize: theme.fontBody
|
||||
font.weight: root.selected ? theme.weightSemibold : theme.weightMedium
|
||||
elide: Text.ElideRight
|
||||
@@ -91,7 +97,7 @@ Rectangle {
|
||||
+ QbzSession.tr("albums", QbzSession.trRev) + " · "
|
||||
+ (root.item.trackCount || 0) + " "
|
||||
+ QbzSession.tr("tracks", QbzSession.trRev)
|
||||
color: root.selected ? theme.accentText : theme.textMuted
|
||||
color: root.selected ? theme.accentGlyphColor : theme.textMuted
|
||||
font.pixelSize: theme.fontLegal
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ Rectangle {
|
||||
height: 16
|
||||
anchors.centerIn: parent
|
||||
tintName: btn.modelData.danger ? "warning"
|
||||
: btnArea.containsMouse ? "primary" : "secondary"
|
||||
: btnArea.containsMouse ? "textPrimary" : "secondary"
|
||||
}
|
||||
MouseArea {
|
||||
id: btnArea
|
||||
|
||||
@@ -165,7 +165,13 @@ Row {
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: root.view.filterCount
|
||||
color: theme.accentText
|
||||
// 9px bold on a 15px accent dot — the smallest on-accent
|
||||
// text in the app, so the floor matters most here. NOT a
|
||||
// departure from locallibrary/LocalLibraryView.slint:887
|
||||
// (`Theme.accent-text`); the twin returns accent-text on
|
||||
// 34 of the 35 palettes and only overrides rose-pine-dawn
|
||||
// (2.56:1 -> 7.38:1).
|
||||
color: theme.accentGlyphColor
|
||||
font.pixelSize: 9
|
||||
font.weight: theme.weightBold
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ Item {
|
||||
width: 16
|
||||
height: 16
|
||||
anchors.centerIn: parent
|
||||
tintName: moreArea.containsMouse ? "primary" : "muted"
|
||||
tintName: moreArea.containsMouse ? "textPrimary" : "muted"
|
||||
}
|
||||
MouseArea {
|
||||
id: moreArea
|
||||
|
||||
@@ -33,7 +33,19 @@ Rectangle {
|
||||
width: Math.round(root.diameter * 0.62)
|
||||
height: Math.round(root.diameter * 0.62)
|
||||
anchors.centerIn: parent
|
||||
tintName: "primary"
|
||||
// DELIBERATE DIVERGENCE from primitives/SelectionCheckbox.slint:37,
|
||||
// which hardcodes `tint: #ffffff` on this same accent fill. That
|
||||
// white is under 2.6:1 on 16 of the 35 palettes, worst on
|
||||
// high-contrast at 1.70:1, then ikari 1.74 and wcag-dark 1.82 —
|
||||
// i.e. the two ACCESSIBILITY themes bracket the top of the list.
|
||||
// (This site used to claim ikari 1.74 was "the worst case in the
|
||||
// app"; it is second. The 8px glyph here does make it the smallest
|
||||
// thing painted at those ratios, which is a different argument and
|
||||
// the one worth keeping.) Slint's own QbzCheckbox.slint:24 uses
|
||||
// accent-text for the equivalent glyph, so upstream contradicts
|
||||
// ITSELF here; the selector settles it by measurement instead of by
|
||||
// picking a side. See theme/QbzTheme.qml, "ON AN ACCENT FILL".
|
||||
tintName: theme.accentGlyphTint
|
||||
}
|
||||
MouseArea {
|
||||
id: checkArea
|
||||
|
||||
Reference in new issue
Block a user