aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-29 13:33:03 +0200
committerDanilo M. <danix@danix.xyz>2026-09-29 13:33:03 +0200
commit0da34c765da9b9c831befdab659c9eb0c79c9079 (patch)
tree8746369fb1e6f78da04fa1d9ab5c4300c9c45774
parentb33c7f5ec094469becd4f842e2bed37efb85dcfb (diff)
downloadquickshell-0da34c765da9b9c831befdab659c9eb0c79c9079.tar.gz
quickshell-0da34c765da9b9c831befdab659c9eb0c79c9079.zip
fix(sound): swap background cover when the track changes
The crossfade only brought a loaded cover to the front when the image's source compared equal to the wanted URL. It never did for a title with spaces or brackets: the URL carries the title as a percent-encoded fragment cache buster, and QUrl reads it back decoded, so "#Foo%20Bar" came back as "#Foo Bar". The load finished, loaded() bailed, and the old cover stayed. Confirmed with a standalone qml test. The slot being loaded is now tracked by index instead. Stale status changes cannot match: only the back image is ever reloaded, and a newer want resets it before assigning. Seen working on screen by the user. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-rw-r--r--desktop/modules/sound/Osd.qml13
1 files changed, 9 insertions, 4 deletions
diff --git a/desktop/modules/sound/Osd.qml b/desktop/modules/sound/Osd.qml
index ede8cf1..8f7b477 100644
--- a/desktop/modules/sound/Osd.qml
+++ b/desktop/modules/sound/Osd.qml
@@ -101,11 +101,16 @@ Scope {
readonly property string want: Player.active ? Player.artUrl : ""
property int front: 0
+ // The slot loading the wanted cover, -1 when none. Tracked by
+ // index because a url does not compare back to the string it
+ // was set from: QUrl decodes the %20s of the cache buster.
+ property int loading: -1
property bool artOn: false
onWantChanged: {
- if (want === "") { artOn = false; return; }
- const back = front === 0 ? artB : artA;
+ if (want === "") { loading = -1; artOn = false; return; }
+ loading = front === 0 ? 1 : 0;
+ const back = loading === 0 ? artA : artB;
// Cleared first so a URL the back image already holds
// still loads and reports a status.
back.source = "";
@@ -115,8 +120,8 @@ Scope {
Component.onCompleted: wantChanged()
function loaded(img, idx) {
- if (img.source != want) return;
- if (img.status === Image.Ready) { front = idx; artOn = true; }
+ if (idx !== loading) return;
+ if (img.status === Image.Ready) { front = idx; loading = -1; artOn = true; }
else if (img.status === Image.Error) artOn = false;
}