diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-11 16:46:20 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-11 16:46:20 +0200 |
| commit | 4c4ed4e3ce3dd25395866cb0bb71a8187f359dbe (patch) | |
| tree | b34dc7585d31f2b8002b3d8edf4af9117e9f31f8 /volume-osd/Player.qml | |
| parent | 4f01824832da8455a40446dc2ee949545f470ec5 (diff) | |
| download | quickshell-4c4ed4e3ce3dd25395866cb0bb71a8187f359dbe.tar.gz quickshell-4c4ed4e3ce3dd25395866cb0bb71a8187f359dbe.zip | |
feat(volume-osd): show what is playing
The OSD gains a track row above the volume bar when an MPRIS player is
running: album art, title, artist, and prev/play/next. With no player it
is the volume OSD it was, at the same size. A track change or a
play/pause shows the panel as well, so the row is not something you only
see by happening to touch the volume.
Hovering freezes the fade so the buttons can be clicked and leaving
restarts it, which keeps the passive behaviour intact for anyone not
reaching for the mouse. The panel still takes no keyboard focus.
playerctld proxies whichever player is active and republishes it under
its own bus name, so every player is enumerated twice. Player.qml drops
that name rather than deduplicating by identity, and controls the real
player, which works whether or not playerctld is running.
Album art is loaded with cache off and a per-track suffix on the URL.
Audacious extracts embedded art into one temp file in its cache and
rewrites that same path for each track, so the URL repeats while the
image changes, and a cached Image would keep showing the last cover.
Theme gains overlay, used by the art placeholder.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G7NRsGyF9jGfPYS4zPqpN7
Diffstat (limited to 'volume-osd/Player.qml')
| -rw-r--r-- | volume-osd/Player.qml | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/volume-osd/Player.qml b/volume-osd/Player.qml new file mode 100644 index 0000000..73f86af --- /dev/null +++ b/volume-osd/Player.qml @@ -0,0 +1,48 @@ +// 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 + + // 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) +} |
