fix(mediacontrols): answer "no artwork" instead of saying nothing
CI / check (push) Skipped
CI / e2e (push) Skipped
CI / check (pull_request) Successful in 2m30s
CI / e2e (pull_request) Canceled after 0s

A track with no cover art omitted mpris:artUrl entirely, and KDE's
media controller keeps showing the last image it was handed -- so the
taskbar preview for an untagged track displayed the cover of whichever
earlier album happened to have one, where the user has no way to tell
it is stale.

The key is now always published, empty when there is nothing. Omitting
a field is what an absent value naturally reads as, and artwork is the
one field where that is wrong.

The dictionary build is extracted so it can be asserted on without a
bus. Every other field stays absent when empty -- a title of "" would
make players show a blank line where they would otherwise fall back to
the filename.

Refs #41
This commit is contained in:
2026-08-18 11:25:57 -04:00
parent 3bf27e3fd5
commit 128fa85a65
2 changed files with 99 additions and 4 deletions
+26 -4
View File
@@ -286,12 +286,36 @@ func (h *MPRISHandler) UpdateMetadata(meta Metadata) {
tid := h.trackID
h.mu.Unlock()
m := metadataMap(meta, tid)
h.enqueue(func() {
h.props.SetMust(playerIf, "Metadata", m)
})
}
// metadataMap is the org.mpris.MediaPlayer2.Player Metadata dictionary
// for one track.
//
// Absent fields are omitted, with one deliberate exception: a track
// with **no cover art still publishes mpris:artUrl**, empty. Omitting
// it is what a missing value naturally reads as, and it is wrong here
// -- KDE's media controller keeps showing the last artwork it was
// given, so playing an untagged track under a Plasma taskbar preview
// displayed the cover of whichever earlier album happened to have one.
// An empty string is our answer to "what is the artwork" rather than
// no answer at all.
//
// A generated placeholder image would be the stronger fix and needs an
// app icon to point at; this is the version that costs nothing and can
// be checked with busctl.
func metadataMap(meta Metadata, trackID uint64) map[string]interface{} {
m := map[string]interface{}{
"mpris:trackid": dbus.ObjectPath(
fmt.Sprintf(
"/org/yellowjacket/Track/%d", tid,
"/org/yellowjacket/Track/%d", trackID,
),
),
"mpris:artUrl": "",
}
if meta.Title != "" {
@@ -316,9 +340,7 @@ func (h *MPRISHandler) UpdateMetadata(meta Metadata) {
) * usPerSec
}
h.enqueue(func() {
h.props.SetMust(playerIf, "Metadata", m)
})
return m
}
// UpdatePlaybackState pushes the playback state and position