1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-06-07 19:59:14 -04:00

Hide MPRIS players that have nothing to play (#2509)

* fix(Mpris): exclude idle players from active-player selection

Add MprisController.isIdle() (player Stopped with empty title and
artist). _resolveActivePlayer excludes idle players from every
selection path, and re-resolves when the active player itself goes
idle. Existing triggers (availablePlayers change, isPlaying becoming
true) do not fire for a player merely stopping.

The fallback now gates on !isIdle(p) instead of p.canPlay. canPlay
describes whether Play() would succeed; !isIdle describes whether
there is anything to surface. canControl unchanged.

When no eligible player remains, activePlayer becomes null and
consumers that gate on it unload (the bar media widget via
WidgetHost; the dash via the companion fix).

* fix(DankDash): show no-player state when active player resolves to null

showNoPlayerNow gated on _noneAvailable (player count === 0) or
activePlayer being idle. Neither covers activePlayer being null
while players remain registered, which is now possible (an
always-on player sitting stopped with empty metadata).

Key showNoPlayerNow on !activePlayer; drop the unreachable
_trulyIdle.

* add(MprisController): add track artist change handling to active player resolution

---------
This commit is contained in:
Connor Welsh
2026-05-28 00:19:34 -04:00
committed by GitHub
parent af097d0f33
commit 8a4be4936a
2 changed files with 21 additions and 5 deletions
@@ -65,8 +65,7 @@ Item {
// Derived "no players" state: always correct, no timers. // Derived "no players" state: always correct, no timers.
readonly property int _playerCount: allPlayers ? allPlayers.length : 0 readonly property int _playerCount: allPlayers ? allPlayers.length : 0
readonly property bool _noneAvailable: _playerCount === 0 readonly property bool _noneAvailable: _playerCount === 0
readonly property bool _trulyIdle: activePlayer && activePlayer.playbackState === MprisPlaybackState.Stopped && !activePlayer.trackTitle && !activePlayer.trackArtist readonly property bool showNoPlayerNow: (!_switchHold) && (_noneAvailable || !activePlayer)
readonly property bool showNoPlayerNow: (!_switchHold) && (_noneAvailable || _trulyIdle)
property bool _switchHold: false property bool _switchHold: false
Timer { Timer {
+20 -3
View File
@@ -17,12 +17,22 @@ Singleton {
target: root.activePlayer target: root.activePlayer
function onTrackTitleChanged() { function onTrackTitleChanged() {
root.activePlayerStableLength = (root.activePlayer && root.activePlayer.lengthSupported && root.activePlayer.length > 1) ? root.activePlayer.length : 0; root.activePlayerStableLength = (root.activePlayer && root.activePlayer.lengthSupported && root.activePlayer.length > 1) ? root.activePlayer.length : 0;
if (root.isIdle(root.activePlayer))
root._resolveActivePlayer();
}
function onTrackArtistChanged() {
if (root.isIdle(root.activePlayer))
root._resolveActivePlayer();
} }
function onLengthChanged() { function onLengthChanged() {
if (root.activePlayer && root.activePlayer.lengthSupported && root.activePlayer.length > 1) { if (root.activePlayer && root.activePlayer.lengthSupported && root.activePlayer.length > 1) {
root.activePlayerStableLength = root.activePlayer.length; root.activePlayerStableLength = root.activePlayer.length;
} }
} }
function onPlaybackStateChanged() {
if (root.isIdle(root.activePlayer))
root._resolveActivePlayer();
}
} }
onActivePlayerChanged: { onActivePlayerChanged: {
@@ -44,6 +54,13 @@ Singleton {
} }
} }
function isIdle(player: MprisPlayer): bool {
return player
&& player.playbackState === MprisPlaybackState.Stopped
&& !player.trackTitle
&& !player.trackArtist;
}
function _resolveActivePlayer(): void { function _resolveActivePlayer(): void {
const playing = availablePlayers.find(p => p.isPlaying); const playing = availablePlayers.find(p => p.isPlaying);
if (playing) { if (playing) {
@@ -51,17 +68,17 @@ Singleton {
_persistIdentity(playing.identity); _persistIdentity(playing.identity);
return; return;
} }
if (activePlayer && availablePlayers.indexOf(activePlayer) >= 0) if (activePlayer && availablePlayers.indexOf(activePlayer) >= 0 && !isIdle(activePlayer))
return; return;
const savedId = SessionData.lastPlayerIdentity; const savedId = SessionData.lastPlayerIdentity;
if (savedId) { if (savedId) {
const match = availablePlayers.find(p => p.identity === savedId); const match = availablePlayers.find(p => p.identity === savedId);
if (match) { if (match && !isIdle(match)) {
activePlayer = match; activePlayer = match;
return; return;
} }
} }
activePlayer = availablePlayers.find(p => p.canControl && p.canPlay) ?? null; activePlayer = availablePlayers.find(p => p.canControl && !isIdle(p)) ?? null;
if (activePlayer) if (activePlayer)
_persistIdentity(activePlayer.identity); _persistIdentity(activePlayer.identity);
} }