diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-29 13:33:03 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-29 13:33:03 +0200 |
| commit | 0da34c765da9b9c831befdab659c9eb0c79c9079 (patch) | |
| tree | 8746369fb1e6f78da04fa1d9ab5c4300c9c45774 | |
| parent | b33c7f5ec094469becd4f842e2bed37efb85dcfb (diff) | |
| download | quickshell-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.qml | 13 |
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; } |
