From 6cce5006709cb2271494f7c012c56e326924e8e5 Mon Sep 17 00:00:00 2001 From: voidarc Date: Sun, 9 Aug 2026 17:02:40 +0100 Subject: [PATCH] mpris popup working --- Bar/Time.qml | 141 ++++++++++++++++++++++++++++++++++++++ Services/MprisManager.qml | 52 +++++++++++++- 2 files changed, 191 insertions(+), 2 deletions(-) diff --git a/Bar/Time.qml b/Bar/Time.qml index 9e33d52..56c569d 100644 --- a/Bar/Time.qml +++ b/Bar/Time.qml @@ -16,6 +16,9 @@ Container { property Notification latestNotif required property HyprlandMonitor monitor + property bool mpris: false + property double mprisHeight: 60 + property double mprisWidth: 350 property double notificationHeight: 100 property double notificationWidth: 350 property bool notified: false @@ -80,6 +83,24 @@ Container { notificationTimer.restart(); } } + }, + State { + name: "mpris" + when: root.mpris == true + + PropertyChanges { + root.boxHeight: root.mprisHeight + root.boxRadius: 12 + root.boxWidth: root.mprisWidth + root.visibleTopMargin: 5 + } + + StateChangeScript { + script: { + root.stack.replace(mprisToast); + mprisTimer.restart(); + } + } } ] @@ -97,6 +118,16 @@ Container { target: NotificationManager } + Connections { + function onTrackChanged() { + root.overriden = true; + root.mpris = true; + console.log("track changed"); + } + + target: MprisManager.defaultPlayer + } + Timer { id: notificationTimer @@ -110,6 +141,19 @@ Container { } } + Timer { + id: mprisTimer + + interval: 2000 + repeat: false + running: false + + onTriggered: { + root.mpris = false; + root.overriden = false; + } + } + Component { id: time @@ -192,4 +236,101 @@ Container { } } } + + Component { + id: mprisToast + + Item { + id: mprisToastRoot + + property double innerMargin: 4 + property double outerMargin: 4 + property var trackInfo: MprisManager.getTrackInfo() + + function getInnerHeight() { + let fullHeight = root.mprisHeight; + let fullMargin = mprisToastRoot.innerMargin + mprisToastRoot.outerMargin; + + return fullHeight - (fullMargin * 2); + } + + Rectangle { + color: Colors.surface1 + radius: 9 + + anchors { + fill: parent + margins: mprisToastRoot.outerMargin + } + + RowLayout { + Rectangle { + Layout.margins: mprisToastRoot.innerMargin + color: Colors.mauve + implicitHeight: mprisToastRoot.getInnerHeight() + implicitWidth: mprisToastRoot.getInnerHeight() + radius: 5 + + IconImage { + anchors.fill: parent + source: mprisToastRoot.trackInfo["albumArt"] + } + } + + ColumnLayout { + property double textMargin: 1 + + Layout.alignment: Qt.AlignVCenter + Layout.fillWidth: true + Layout.leftMargin: 0 + Layout.margins: mprisToastRoot.innerMargin + textMargin + + StyledText { + Layout.maximumWidth: root.mprisWidth - ((mprisToastRoot.outerMargin * 2) + ( + mprisToastRoot.innerMargin * 5) + mprisToastRoot.getInnerHeight()) + color: Colors.text + fontSize: 14 + text: mprisToastRoot.trackInfo["name"] + " - " + mprisToastRoot.trackInfo["artist"] + } + + Item { + Layout.fillHeight: true + Layout.fillWidth: true + Layout.maximumWidth: root.mprisWidth - ((mprisToastRoot.outerMargin * 2) + ( + mprisToastRoot.innerMargin * 5) + mprisToastRoot.getInnerHeight()) + Layout.preferredWidth: root.mprisWidth - ((mprisToastRoot.outerMargin * 2) + ( + mprisToastRoot.innerMargin * 5) + mprisToastRoot.getInnerHeight()) + + Rectangle { + anchors.fill: parent + color: Colors.overlay0 + radius: 100 + + Rectangle { + color: Colors.mauve + implicitWidth: parent.width * mprisToastRoot.trackInfo["lengthPercent"] + radius: 100 + + anchors { + bottom: parent.bottom + left: parent.left + top: parent.top + } + } + + StyledText { + text: MprisManager.getTimeString() + + anchors { + horizontalCenter: parent.horizontalCenter + verticalCenter: parent.verticalCenter + } + } + } + } + } + } + } + } + } } diff --git a/Services/MprisManager.qml b/Services/MprisManager.qml index 95cf458..089bb50 100644 --- a/Services/MprisManager.qml +++ b/Services/MprisManager.qml @@ -6,8 +6,7 @@ import Quickshell.Services.Mpris Singleton { id: root - property MprisPlayer defaultPlayer: Mpris.players.values[0] - property real pos: defaultPlayer.position / defaultPlayer.length + property MprisPlayer defaultPlayer: Mpris.players.values[0] || null function getPlaying() { if (!defaultPlayer) { @@ -17,6 +16,55 @@ Singleton { } } + function getTimeString() { + let trackInfo = getTrackInfo(); + let position = trackInfo["position"]; + let length = trackInfo["length"]; + if (length.hours > 0) { + return position.hours + ":" + position.minutes + ":" + position.seconds + "/" + length.hours + + ":" + length.minutes + ":" + length.seconds; + } else { + return position.minutes + ":" + position.seconds + "/" + length.minutes + ":" + length.seconds; + } + } + + function getTrackInfo() { + let trackName = root.defaultPlayer.trackTitle; + let trackArtist = root.defaultPlayer.trackArtist; + let trackAlbum = root.defaultPlayer.trackAlbum; + let trackPosition = root.defaultPlayer.position; + let trackLength = root.defaultPlayer.length; + let trackArt = root.defaultPlayer.trackArtUrl; + return { + "name": trackName, + "artist": trackArtist, + "album": trackAlbum, + "position": msToArray(trackPosition), + "length": msToArray(trackLength), + "lengthRemaining": msToArray(trackLength - trackPosition), + "lengthPercent": trackPosition / trackLength, + "albumArt": trackArt + }; + } + + function msToArray(time) { + time = Math.max(0, Number(time)); + + const inthours = Math.floor(time / 3600000); + const intminutes = Math.floor((time % 60000) / 60); + const intseconds = Math.floor((time % 1000) % 60); + + const hours = String(inthours).padStart(2, "0"); + const minutes = String(intminutes).padStart(2, "0"); + const seconds = String(intseconds).padStart(2, "0"); + + return { + hours, + minutes, + seconds + }; + } + function prev() { defaultPlayer.previous(); }