diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-14 12:24:13 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-14 12:24:13 +0200 |
| commit | d203d938f005d7542bf13e217ac51917866a8ace (patch) | |
| tree | c4a6d8728461099638a3fc3378ba7fb34a2b5874 /desktop/modules/sound/Player.qml | |
| parent | 55619e7dc830697d2929b0bd5cf1c6dc7435720c (diff) | |
| download | quickshell-d203d938f005d7542bf13e217ac51917866a8ace.tar.gz quickshell-d203d938f005d7542bf13e217ac51917866a8ace.zip | |
feat(desktop): move volume-osd in as the sound module
VolumeOsd.qml did three jobs in one file: PipeWire tracking, the OSD
surface and the player transport. They become Service, Osd and the page.
The OSD keeps its namespace so the existing Hyprland blur rule still
matches, and the service stays always-active because the OSD has to
answer a keypress with no drawer open.
Diffstat (limited to 'desktop/modules/sound/Player.qml')
| -rw-r--r-- | desktop/modules/sound/Player.qml | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/desktop/modules/sound/Player.qml b/desktop/modules/sound/Player.qml new file mode 100644 index 0000000..fab8083 --- /dev/null +++ b/desktop/modules/sound/Player.qml @@ -0,0 +1,56 @@ +// Copyright (C) 2026 Danilo M. <danix@danix.xyz> +// +// 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 + + // Two things proxy a real player and republish it under their own name, so + // one track can appear on three buses at once: a playing Navidrome tab + // showed up as firefox.instance_*, as plasma-browser-integration and as + // playerctld. Both proxies are skipped and the OSD talks to the browser's + // own entry, which is safe because none of the three exists until playback + // starts, and the browser's entry appeared whenever the plasma one did. An + // open but silent tab publishes nothing, so there is no row to lose. The + // plasma name is browser-only: Feishin on the same server publishes just + // its own entry and playerctld, so a native player loses nothing here. + readonly property var proxyNames: [".playerctld", ".plasma-browser-integration"] + + readonly property var real: + Mpris.players.values.filter(p => !root.proxyNames.some(n => p.dbusName.endsWith(n))) + + // 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) +} |
