From ce94bd1b6add09fe1e5aee336da1b7108b5298ff Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Mon, 26 May 2025 10:17:16 +0200 Subject: [PATCH] media controls: filter redundant players --- .../modules/mediaControls/MediaControls.qml | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/.config/quickshell/modules/mediaControls/MediaControls.qml b/.config/quickshell/modules/mediaControls/MediaControls.qml index 0983562b..def25936 100644 --- a/.config/quickshell/modules/mediaControls/MediaControls.qml +++ b/.config/quickshell/modules/mediaControls/MediaControls.qml @@ -20,6 +20,7 @@ Scope { property bool visible: false readonly property MprisPlayer activePlayer: MprisController.activePlayer readonly property var realPlayers: Mpris.players.values.filter(player => isRealPlayer(player)) + readonly property var meaningfulPlayers: filterDuplicatePlayers(realPlayers) readonly property real osdWidth: Appearance.sizes.osdWidth readonly property real widgetWidth: Appearance.sizes.mediaControlsWidth readonly property real widgetHeight: Appearance.sizes.mediaControlsHeight @@ -41,6 +42,33 @@ Scope { !(player.dbusName?.endsWith('.mpd') && !player.dbusName.endsWith('MediaPlayer2.mpd')) ); } + function filterDuplicatePlayers(players) { + let filtered = []; + let used = new Set(); + + for (let i = 0; i < players.length; ++i) { + if (used.has(i)) continue; + let p1 = players[i]; + let group = [i]; + + // Find duplicates by trackTitle prefix + for (let j = i + 1; j < players.length; ++j) { + let p2 = players[j]; + if (p1.trackTitle && p2.trackTitle && + (p1.trackTitle.startsWith(p2.trackTitle) || p2.trackTitle.startsWith(p1.trackTitle))) { + group.push(j); + } + } + + // Pick the one with non-empty trackArtUrl, or fallback to the first + let chosenIdx = group.find(idx => players[idx].trackArtUrl && players[idx].trackArtUrl.length > 0); + if (chosenIdx === undefined) chosenIdx = group[0]; + + filtered.push(players[chosenIdx]); + group.forEach(idx => used.add(idx)); + } + return filtered; + } Component.onCompleted: { Hyprland.dispatch(`exec rm -rf ${baseCoverArtDir} && mkdir -p ${baseCoverArtDir}`) @@ -84,7 +112,7 @@ Scope { Repeater { model: ScriptModel { - values: root.realPlayers + values: root.meaningfulPlayers } delegate: PlayerControl { required property MprisPlayer modelData