From c44ffae7515679bcdc3a80786624b779b0a08b49 Mon Sep 17 00:00:00 2001 From: bbedward Date: Thu, 9 Jul 2026 19:39:15 -0400 Subject: [PATCH] fix(media): resolve monochrome album art accents port: 1.5 --- quickshell/Services/MediaAccentService.qml | 49 ++++++++++++++++++---- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/quickshell/Services/MediaAccentService.qml b/quickshell/Services/MediaAccentService.qml index 9212503ff..0cbfad38f 100644 --- a/quickshell/Services/MediaAccentService.qml +++ b/quickshell/Services/MediaAccentService.qml @@ -26,7 +26,20 @@ Singleton { readonly property color accentTrack: Theme.withAlpha(accent, 0.28) readonly property color accentSubtle: Theme.withAlpha(accent, 0.55) - readonly property string artUrl: TrackArtService.resolvedArtUrl + // Prefer the validated url, but fall back to the live mpris art so quantization + // starts as soon as the cover exists instead of waiting on the commit pipeline. + readonly property string artUrl: { + const resolved = TrackArtService.resolvedArtUrl; + if (resolved !== "") + return resolved; + const p = MprisController.activePlayer; + if (!p) + return ""; + if (p.trackArtUrl) + return p.trackArtUrl; + const m = p.metadata; + return m && m["mpris:artUrl"] ? m["mpris:artUrl"].toString() : ""; + } // Hold the last accent across the brief artUrl blank between tracks; never reset to primary. property var _accent: null @@ -37,9 +50,10 @@ Singleton { depth: 4 rescaleSize: 64 onColorsChanged: { - const a = root._pickAccent(colors); - if (a !== null) - root._accent = a; + // Hold last accent only across the blank-art gap; else always recompute. + if (!colors || colors.length === 0) + return; + root._accent = root._pickAccent(colors); } } @@ -62,9 +76,30 @@ Singleton { } } - if (!best) - return null; - return _normalize(best); + if (best) + return _normalize(best); + + // Monochrome art: pick a neutral tone instead of keeping the last accent. + return _pickNeutral(colors); + } + + function _pickNeutral(colors) { + let best = null; + let bestScore = -1; + for (let i = 0; i < colors.length; i++) { + const c = colors[i]; + const v = c.hsvValue; + const score = (1 - Math.abs(v - 0.6)) + c.hsvSaturation * 0.5; + if (score > bestScore) { + bestScore = score; + best = c; + } + } + + const hue = best.hsvHue < 0 ? 0 : best.hsvHue; + const s = Math.min(best.hsvSaturation, 0.18); + const v = Math.min(Math.max(best.hsvValue, 0.6), 0.82); + return Qt.hsva(hue, s, v, 1); } function _normalize(c) {