Compare commits

..
2 changed files with 79 additions and 53 deletions

View file

@ -306,50 +306,58 @@ Column {
// Player switcher // Player switcher
Item { Item {
width: root.width width: root.width
height: root.players.length > 1 ? _playerFlow.implicitHeight + 6 : 0 height: root.players.length > 1 ? 28 : 0
visible: root.players.length > 1 visible: root.players.length > 1
Flow { Flickable {
id: _playerFlow id: _switcher
anchors.horizontalCenter: parent.horizontalCenter anchors.centerIn: parent
anchors.verticalCenter: parent.verticalCenter width: Math.min(_playerRow.implicitWidth, parent.width - 16)
width: parent.width - 16 height: 22
spacing: 6 contentWidth: _playerRow.implicitWidth
clip: true
Repeater { Row {
model: root.players id: _playerRow
height: 22
spacing: 6
delegate: Rectangle { Repeater {
required property var modelData model: root.players
required property int index
readonly property bool _active: index === root.playerIdx delegate: Rectangle {
required property var modelData
required property int index
width: _pLabel.implicitWidth + 12 readonly property bool _active: index === root.playerIdx
height: 18
radius: 9
color: _active ? S.Theme.base02 : (pHover.hovered ? S.Theme.base02 : "transparent")
border.color: _active ? root.accentColor : S.Theme.base03
border.width: _active ? 1 : 0
Text { width: _pLabel.implicitWidth + 12
id: _pLabel height: 18
anchors.centerIn: parent radius: 9
text: modelData.identity ?? "Player" color: _active ? S.Theme.base02 : (pHover.hovered ? S.Theme.base02 : "transparent")
color: _active ? root.accentColor : S.Theme.base04 border.color: _active ? root.accentColor : S.Theme.base03
font.pixelSize: S.Theme.fontSize - 2 border.width: _active ? 1 : 0
font.family: S.Theme.fontFamily anchors.verticalCenter: parent.verticalCenter
font.bold: _active
}
HoverHandler { Text {
id: pHover id: _pLabel
cursorShape: Qt.PointingHandCursor anchors.centerIn: parent
} text: modelData.identity ?? "Player"
color: _active ? root.accentColor : S.Theme.base04
font.pixelSize: S.Theme.fontSize - 2
font.family: S.Theme.fontFamily
font.bold: _active
}
TapHandler { HoverHandler {
onTapped: { id: pHover
root.playerSwitched(index); cursorShape: Qt.PointingHandCursor
}
TapHandler {
onTapped: {
root.playerSwitched(index);
}
} }
} }
} }

View file

@ -1,7 +1,6 @@
pragma Singleton pragma Singleton
import QtQuick import QtQuick
import QtQml.Models
import Quickshell.Services.Mpris import Quickshell.Services.Mpris
QtObject { QtObject {
@ -14,6 +13,7 @@ QtObject {
property string _selectedIdentity: "" property string _selectedIdentity: ""
property var _lastPlayedTime: ({}) property var _lastPlayedTime: ({})
property var _watchers: []
onPlayerChanged: { onPlayerChanged: {
if (player) if (player)
@ -33,18 +33,33 @@ QtObject {
} }
} }
// Watch all raw players for state changes via Instantiator - // Watch raw Mpris.players for add/remove - this does NOT fire on state changes
// delegates persist across state changes since the model only property Connections _mprisConn: Connections {
// changes on player add/remove, not property changes target: Mpris
property Instantiator _stateWatchers: Instantiator { function onPlayersChanged() {
model: Mpris.players root._reconnectWatchers();
delegate: QtObject { }
required property MprisPlayer modelData }
property Connections _conn: Connections {
target: modelData function _reconnectWatchers() {
function onPlaybackStateChanged() { for (const w of _watchers)
root._onPlaybackStateChanged(modelData); w.destroy();
}
const raw = Mpris.players.values ?? [];
const newWatchers = [];
for (const p of raw) {
const conn = _watcherComp.createObject(root, {
target: p
});
newWatchers.push(conn);
}
_watchers = newWatchers;
}
property Component _watcherComp: Component {
Connections {
function onPlaybackStateChanged() {
root._onPlaybackStateChanged(target);
} }
} }
} }
@ -69,6 +84,7 @@ QtObject {
} }
} }
} else if (p.playbackState === MprisPlaybackState.Paused && p === player) { } else if (p.playbackState === MprisPlaybackState.Paused && p === player) {
// Current player paused - switch to a playing one if available
_switchToPlaying(); _switchToPlaying();
} }
} }
@ -123,4 +139,6 @@ QtObject {
if (players[idx]) if (players[idx])
_selectedIdentity = players[idx].identity ?? ""; _selectedIdentity = players[idx].identity ?? "";
} }
Component.onCompleted: _reconnectWatchers()
} }