// Copyright (C) 2026 Danilo M. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. pragma Singleton import Quickshell import Quickshell.Services.Mpris import QtQuick // Which MPRIS player the OSD should describe. Singleton { id: root // playerctld proxies whatever is playing and publishes it under its own // name, so every real player shows up twice. Its own entry is skipped: // controlling the player directly works whether or not playerctld is up. readonly property var real: Mpris.players.values.filter(p => !p.dbusName.endsWith(".playerctld")) // Prefer something actually playing; otherwise keep the last one seen, so // pausing does not make the track row vanish mid-look. readonly property var current: real.find(p => p.playbackState === MprisPlaybackState.Playing) ?? real.find(p => p.playbackState === MprisPlaybackState.Paused) ?? real[0] ?? null readonly property bool active: current !== null readonly property bool playing: current?.playbackState === MprisPlaybackState.Playing readonly property string title: current?.trackTitle ?? "" readonly property string artist: current?.trackArtist ?? "" // Players that extract embedded art write it to a temp file they reuse // per track, so the path can repeat while the image behind it changes. // The cache buster makes Image reload instead of showing the last cover. readonly property string artUrl: (current?.trackArtUrl ?? "") === "" ? "" : current.trackArtUrl + "#" + encodeURIComponent(title) }