Add MPRIS blacklist
This commit is contained in:
parent
7bcb227d7b
commit
1533b2d3a1
5 changed files with 171 additions and 10 deletions
|
|
@ -218,6 +218,9 @@ Singleton {
|
|||
property string visualizerType: "linear"
|
||||
property int volumeStep: 5
|
||||
property int cavaFrameRate: 60
|
||||
// MPRIS controls
|
||||
property list<string> mprisBlacklist: []
|
||||
property string preferredPlayer: ""
|
||||
}
|
||||
|
||||
// ui
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ Row {
|
|||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
active: Settings.data.audio.showMiniplayerCava && Settings.data.audio.visualizerType == "linear"
|
||||
&& MediaService.isPlaying
|
||||
&& MediaService.isPlaying && MediaService.trackLength > 0
|
||||
z: 0
|
||||
|
||||
sourceComponent: LinearSpectrum {
|
||||
|
|
@ -65,7 +65,7 @@ Row {
|
|||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
active: Settings.data.audio.showMiniplayerCava && Settings.data.audio.visualizerType == "mirrored"
|
||||
&& MediaService.isPlaying
|
||||
&& MediaService.isPlaying && MediaService.trackLength > 0
|
||||
z: 0
|
||||
|
||||
sourceComponent: MirroredSpectrum {
|
||||
|
|
@ -81,7 +81,7 @@ Row {
|
|||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
active: Settings.data.audio.showMiniplayerCava && Settings.data.audio.visualizerType == "wave"
|
||||
&& MediaService.isPlaying
|
||||
&& MediaService.isPlaying && MediaService.trackLength > 0
|
||||
z: 0
|
||||
|
||||
sourceComponent: WaveSpectrum {
|
||||
|
|
|
|||
|
|
@ -227,6 +227,134 @@ ColumnLayout {
|
|||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
// MPRIS Player Preferences
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NText {
|
||||
text: "MPRIS Player Preferences"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.bottomMargin: Style.marginS * scaling
|
||||
}
|
||||
|
||||
// Preferred player (persistent)
|
||||
NTextInput {
|
||||
label: "Preferred Player"
|
||||
description: "Substring to match MPRIS player (identity/bus/desktop)."
|
||||
placeholderText: "e.g. spotify, vlc, mpv"
|
||||
text: Settings.data.audio.preferredPlayer
|
||||
onTextChanged: {
|
||||
Settings.data.audio.preferredPlayer = text
|
||||
MediaService.updateCurrentPlayer()
|
||||
}
|
||||
}
|
||||
|
||||
// Blacklist editor
|
||||
ColumnLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
RowLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NTextInput {
|
||||
id: blacklistInput
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignTop
|
||||
label: "Blacklist player"
|
||||
description: "Substring, e.g. plex, shim, mpv"
|
||||
placeholderText: "type substring and press +"
|
||||
}
|
||||
|
||||
// Button aligned to the center of the actual input field
|
||||
NIconButton {
|
||||
icon: "add"
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
Layout.bottomMargin: blacklistInput.description ? Style.marginS * scaling : 0
|
||||
onClicked: {
|
||||
const val = (blacklistInput.text || "").trim()
|
||||
if (val !== "") {
|
||||
const arr = (Settings.data.audio.mprisBlacklist || [])
|
||||
if (!arr.find(x => String(x).toLowerCase() === val.toLowerCase())) {
|
||||
Settings.data.audio.mprisBlacklist = [...arr, val]
|
||||
blacklistInput.text = ""
|
||||
MediaService.updateCurrentPlayer()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Current blacklist entries
|
||||
Flow {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.marginS * scaling
|
||||
spacing: Style.marginS * scaling
|
||||
|
||||
Repeater {
|
||||
model: Settings.data.audio.mprisBlacklist
|
||||
delegate: Rectangle {
|
||||
required property string modelData
|
||||
// Padding around the inner row
|
||||
property real pad: Style.marginS * scaling
|
||||
// Visuals
|
||||
color: Color.applyOpacity(Color.mOnSurface, "20")
|
||||
border.color: Color.applyOpacity(Color.mOnSurface, "50")
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
|
||||
// Content
|
||||
RowLayout {
|
||||
id: chipRow
|
||||
spacing: Style.marginXS * scaling
|
||||
anchors.fill: parent
|
||||
anchors.margins: pad
|
||||
|
||||
NText {
|
||||
text: modelData
|
||||
color: Color.mOnSurface
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.leftMargin: Style.marginS * scaling
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
icon: "close"
|
||||
sizeRatio: 0.8
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.rightMargin: Style.marginXS * scaling
|
||||
onClicked: {
|
||||
const arr = (Settings.data.audio.mprisBlacklist || [])
|
||||
const idx = arr.findIndex(x => String(x) === modelData)
|
||||
if (idx >= 0) {
|
||||
arr.splice(idx, 1)
|
||||
Settings.data.audio.mprisBlacklist = arr
|
||||
MediaService.updateCurrentPlayer()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Intrinsic size derived from inner row + padding
|
||||
implicitWidth: chipRow.implicitWidth + pad * 2
|
||||
implicitHeight: Math.max(chipRow.implicitHeight + pad * 2, Style.baseWidgetSize * 0.8 * scaling)
|
||||
radius: Style.radiusM * scaling
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Divider
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
// Bar Mini Media player
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ NBox {
|
|||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -330,7 +331,7 @@ NBox {
|
|||
}
|
||||
|
||||
Loader {
|
||||
active: Settings.data.audio.visualizerType == "linear"
|
||||
active: Settings.data.audio.visualizerType == "linear" && MediaService.isPlaying && MediaService.trackLength > 0
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
sourceComponent: LinearSpectrum {
|
||||
|
|
@ -343,7 +344,7 @@ NBox {
|
|||
}
|
||||
|
||||
Loader {
|
||||
active: Settings.data.audio.visualizerType == "mirrored"
|
||||
active: Settings.data.audio.visualizerType == "mirrored" && MediaService.isPlaying && MediaService.trackLength > 0
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
sourceComponent: MirroredSpectrum {
|
||||
|
|
@ -356,7 +357,7 @@ NBox {
|
|||
}
|
||||
|
||||
Loader {
|
||||
active: Settings.data.audio.visualizerType == "wave"
|
||||
active: Settings.data.audio.visualizerType == "wave" && MediaService.isPlaying && MediaService.trackLength > 0
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
sourceComponent: WaveSpectrum {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ Singleton {
|
|||
property var currentPlayer: null
|
||||
property real currentPosition: 0
|
||||
property int selectedPlayerIndex: 0
|
||||
property bool isPlaying: currentPlayer ? currentPlayer.isPlaying : false
|
||||
property bool isPlaying: currentPlayer ? (currentPlayer.playbackState === MprisPlaybackState.Playing || currentPlayer.isPlaying) : false
|
||||
property string trackTitle: currentPlayer ? (currentPlayer.trackTitle || "") : ""
|
||||
property string trackArtist: currentPlayer ? (currentPlayer.trackArtist || "") : ""
|
||||
property string trackAlbum: currentPlayer ? (currentPlayer.trackAlbum || "") : ""
|
||||
|
|
@ -37,12 +37,25 @@ Singleton {
|
|||
let allPlayers = Mpris.players.values
|
||||
let controllablePlayers = []
|
||||
|
||||
// Apply blacklist and controllable filter
|
||||
const blacklist = (Settings.data.audio && Settings.data.audio.mprisBlacklist) ? Settings.data.audio.mprisBlacklist : []
|
||||
for (var i = 0; i < allPlayers.length; i++) {
|
||||
let player = allPlayers[i]
|
||||
if (player && player.canControl) {
|
||||
if (!player)
|
||||
continue
|
||||
const identity = String(player.identity || "")
|
||||
const busName = String(player.busName || "")
|
||||
const desktop = String(player.desktopEntry || "")
|
||||
const idKey = identity.toLowerCase()
|
||||
const match = blacklist.find(b => {
|
||||
const s = String(b || "").toLowerCase()
|
||||
return s && (idKey.includes(s) || busName.toLowerCase().includes(s) || desktop.toLowerCase().includes(s))
|
||||
})
|
||||
if (match)
|
||||
continue
|
||||
if (player.canControl)
|
||||
controllablePlayers.push(player)
|
||||
}
|
||||
}
|
||||
|
||||
return controllablePlayers
|
||||
}
|
||||
|
|
@ -54,6 +67,22 @@ Singleton {
|
|||
return null
|
||||
}
|
||||
|
||||
// Preferred player logic (preferred > fallback)
|
||||
const preferred = (Settings.data.audio.preferredPlayer || "")
|
||||
if (preferred !== "") {
|
||||
for (var i = 0; i < availablePlayers.length; i++) {
|
||||
const p = availablePlayers[i]
|
||||
const identity = String(p.identity || "").toLowerCase()
|
||||
const busName = String(p.busName || "").toLowerCase()
|
||||
const desktop = String(p.desktopEntry || "").toLowerCase()
|
||||
const pref = preferred.toLowerCase()
|
||||
if (identity.includes(pref) || busName.includes(pref) || desktop.includes(pref)) {
|
||||
selectedPlayerIndex = i
|
||||
return p
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedPlayerIndex < availablePlayers.length) {
|
||||
return availablePlayers[selectedPlayerIndex]
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue