From a0c9af1ee74bda764a60859d5c5c255eec7151a7 Mon Sep 17 00:00:00 2001 From: Andrey Yugai Date: Thu, 9 Apr 2026 22:30:04 +0700 Subject: [PATCH] feature: persist last active player (#2184) --- quickshell/Common/SessionData.qml | 2 + quickshell/Common/settings/SessionSpec.js | 2 + .../Modules/DankDash/DankDashPopout.qml | 2 +- quickshell/Services/MprisController.qml | 51 ++++++++++++++++++- 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/quickshell/Common/SessionData.qml b/quickshell/Common/SessionData.qml index a71c5124..e3a07f5a 100644 --- a/quickshell/Common/SessionData.qml +++ b/quickshell/Common/SessionData.qml @@ -124,6 +124,8 @@ Singleton { property string vpnLastConnected: "" + property string lastPlayerIdentity: "" + property var deviceMaxVolumes: ({}) property var hiddenOutputDeviceNames: [] property var hiddenInputDeviceNames: [] diff --git a/quickshell/Common/settings/SessionSpec.js b/quickshell/Common/settings/SessionSpec.js index 3f5d91cf..e2bb4fe8 100644 --- a/quickshell/Common/settings/SessionSpec.js +++ b/quickshell/Common/settings/SessionSpec.js @@ -75,6 +75,8 @@ var SPEC = { vpnLastConnected: { def: "" }, + lastPlayerIdentity: { def: "" }, + deviceMaxVolumes: { def: {} }, hiddenOutputDeviceNames: { def: [] }, hiddenInputDeviceNames: { def: [] }, diff --git a/quickshell/Modules/DankDash/DankDashPopout.qml b/quickshell/Modules/DankDash/DankDashPopout.qml index 97a86554..34b324cf 100644 --- a/quickshell/Modules/DankDash/DankDashPopout.qml +++ b/quickshell/Modules/DankDash/DankDashPopout.qml @@ -100,7 +100,7 @@ DankPopout { if (currentPlayer && currentPlayer !== player && currentPlayer.canPause) { currentPlayer.pause(); } - MprisController.activePlayer = player; + MprisController.setActivePlayer(player); root.__hideDropdowns(); } onDeviceSelected: device => { diff --git a/quickshell/Services/MprisController.qml b/quickshell/Services/MprisController.qml index 48b99461..44ad1358 100644 --- a/quickshell/Services/MprisController.qml +++ b/quickshell/Services/MprisController.qml @@ -4,12 +4,61 @@ pragma ComponentBehavior: Bound import QtQuick import Quickshell import Quickshell.Services.Mpris +import qs.Common Singleton { id: root readonly property list availablePlayers: Mpris.players.values - property MprisPlayer activePlayer: availablePlayers.find(p => p.isPlaying) ?? availablePlayers.find(p => p.canControl && p.canPlay) ?? null + property MprisPlayer activePlayer: null + + onAvailablePlayersChanged: _resolveActivePlayer() + Component.onCompleted: _resolveActivePlayer() + + Instantiator { + model: root.availablePlayers + delegate: Connections { + required property MprisPlayer modelData + target: modelData + function onIsPlayingChanged() { + if (modelData.isPlaying) + root._resolveActivePlayer(); + } + } + } + + function _resolveActivePlayer(): void { + const playing = availablePlayers.find(p => p.isPlaying); + if (playing) { + activePlayer = playing; + _persistIdentity(playing.identity); + return; + } + if (activePlayer && availablePlayers.indexOf(activePlayer) >= 0) + return; + const savedId = SessionData.lastPlayerIdentity; + if (savedId) { + const match = availablePlayers.find(p => p.identity === savedId); + if (match) { + activePlayer = match; + return; + } + } + activePlayer = availablePlayers.find(p => p.canControl && p.canPlay) ?? null; + if (activePlayer) + _persistIdentity(activePlayer.identity); + } + + function setActivePlayer(player: MprisPlayer): void { + activePlayer = player; + if (player) + _persistIdentity(player.identity); + } + + function _persistIdentity(identity: string): void { + if (identity && SessionData.lastPlayerIdentity !== identity) + SessionData.set("lastPlayerIdentity", identity); + } Timer { interval: 1000