mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-07 05:55:37 -05:00
Merge remote changes with CPU/RAM monitor widgets
This commit is contained in:
@@ -11,6 +11,11 @@ Singleton {
|
||||
property var audioSinks: []
|
||||
property string currentAudioSink: ""
|
||||
|
||||
// Microphone properties
|
||||
property int micLevel: 50
|
||||
property var audioSources: []
|
||||
property string currentAudioSource: ""
|
||||
|
||||
// Real Audio Control
|
||||
Process {
|
||||
id: volumeChecker
|
||||
@@ -27,6 +32,22 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
// Microphone level checker
|
||||
Process {
|
||||
id: micLevelChecker
|
||||
command: ["bash", "-c", "pactl get-source-volume @DEFAULT_SOURCE@ | grep -o '[0-9]*%' | head -1 | tr -d '%'"]
|
||||
running: true
|
||||
|
||||
stdout: SplitParser {
|
||||
splitMarker: "\n"
|
||||
onRead: (data) => {
|
||||
if (data.trim()) {
|
||||
root.micLevel = Math.min(100, parseInt(data.trim()) || 50)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: audioSinkLister
|
||||
command: ["pactl", "list", "sinks"]
|
||||
@@ -35,7 +56,6 @@ Singleton {
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
if (text.trim()) {
|
||||
console.log("Parsing pactl sink output...")
|
||||
let sinks = []
|
||||
let lines = text.trim().split('\n')
|
||||
|
||||
@@ -88,7 +108,6 @@ Singleton {
|
||||
sink.displayName = displayName
|
||||
}
|
||||
|
||||
console.log("Final audio sinks:", JSON.stringify(sinks, null, 2))
|
||||
root.audioSinks = sinks
|
||||
defaultSinkChecker.running = true
|
||||
}
|
||||
@@ -96,6 +115,61 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
// Audio source (microphone) lister
|
||||
Process {
|
||||
id: audioSourceLister
|
||||
command: ["pactl", "list", "sources"]
|
||||
running: true
|
||||
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
if (text.trim()) {
|
||||
let sources = []
|
||||
let lines = text.trim().split('\n')
|
||||
|
||||
let currentSource = null
|
||||
|
||||
for (let line of lines) {
|
||||
line = line.trim()
|
||||
|
||||
// New source starts
|
||||
if (line.startsWith('Source #')) {
|
||||
if (currentSource && currentSource.name && currentSource.id) {
|
||||
sources.push(currentSource)
|
||||
}
|
||||
currentSource = {
|
||||
id: line.replace('Source #', '').replace(':', ''),
|
||||
name: '',
|
||||
displayName: '',
|
||||
active: false
|
||||
}
|
||||
}
|
||||
// Source name
|
||||
else if (line.startsWith('Name: ') && currentSource) {
|
||||
currentSource.name = line.replace('Name: ', '')
|
||||
}
|
||||
// Description (display name)
|
||||
else if (line.startsWith('Description: ') && currentSource) {
|
||||
let desc = line.replace('Description: ', '')
|
||||
currentSource.displayName = desc
|
||||
}
|
||||
}
|
||||
|
||||
// Add the last source
|
||||
if (currentSource && currentSource.name && currentSource.id) {
|
||||
sources.push(currentSource)
|
||||
}
|
||||
|
||||
// Filter out monitor sources (we want actual input devices)
|
||||
sources = sources.filter(source => !source.name.includes('.monitor'))
|
||||
|
||||
root.audioSources = sources
|
||||
defaultSourceChecker.running = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: defaultSinkChecker
|
||||
command: ["pactl", "get-default-sink"]
|
||||
@@ -106,7 +180,6 @@ Singleton {
|
||||
onRead: (data) => {
|
||||
if (data.trim()) {
|
||||
root.currentAudioSink = data.trim()
|
||||
console.log("Default audio sink:", root.currentAudioSink)
|
||||
|
||||
// Update active status in audioSinks
|
||||
let updatedSinks = []
|
||||
@@ -124,6 +197,34 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
// Default source (microphone) checker
|
||||
Process {
|
||||
id: defaultSourceChecker
|
||||
command: ["pactl", "get-default-source"]
|
||||
running: false
|
||||
|
||||
stdout: SplitParser {
|
||||
splitMarker: "\n"
|
||||
onRead: (data) => {
|
||||
if (data.trim()) {
|
||||
root.currentAudioSource = data.trim()
|
||||
|
||||
// Update active status in audioSources
|
||||
let updatedSources = []
|
||||
for (let source of root.audioSources) {
|
||||
updatedSources.push({
|
||||
id: source.id,
|
||||
name: source.name,
|
||||
displayName: source.displayName,
|
||||
active: source.name === root.currentAudioSource
|
||||
})
|
||||
}
|
||||
root.audioSources = updatedSources
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setVolume(percentage) {
|
||||
let volumeSetProcess = Qt.createQmlObject('
|
||||
import Quickshell.Io
|
||||
@@ -135,6 +236,17 @@ Singleton {
|
||||
', root)
|
||||
}
|
||||
|
||||
function setMicLevel(percentage) {
|
||||
let micSetProcess = Qt.createQmlObject('
|
||||
import Quickshell.Io
|
||||
Process {
|
||||
command: ["pactl", "set-source-volume", "@DEFAULT_SOURCE@", "' + percentage + '%"]
|
||||
running: true
|
||||
onExited: micLevelChecker.running = true
|
||||
}
|
||||
', root)
|
||||
}
|
||||
|
||||
function setAudioSink(sinkName) {
|
||||
console.log("Setting audio sink to:", sinkName)
|
||||
|
||||
@@ -160,4 +272,39 @@ Singleton {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setAudioSource(sourceName) {
|
||||
console.log("Setting audio source to:", sourceName)
|
||||
|
||||
sourceSetProcess.command = ["pactl", "set-default-source", sourceName]
|
||||
sourceSetProcess.running = true
|
||||
}
|
||||
|
||||
// Dedicated process for setting audio source
|
||||
Process {
|
||||
id: sourceSetProcess
|
||||
running: false
|
||||
|
||||
onExited: (exitCode) => {
|
||||
console.log("Audio source change exit code:", exitCode)
|
||||
if (exitCode === 0) {
|
||||
console.log("Audio source changed successfully")
|
||||
// Refresh current source and list
|
||||
defaultSourceChecker.running = true
|
||||
audioSourceLister.running = true
|
||||
} else {
|
||||
console.error("Failed to change audio source")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Timer to refresh audio devices regularly (catches new Bluetooth devices)
|
||||
Timer {
|
||||
interval: 4000 // 4s refresh to catch new BT devices
|
||||
running: true; repeat: true
|
||||
onTriggered: {
|
||||
audioSinkLister.running = true
|
||||
audioSourceLister.running = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,14 +17,13 @@ Singleton {
|
||||
// Real Bluetooth Management
|
||||
Process {
|
||||
id: bluetoothStatusChecker
|
||||
command: ["bluetoothctl", "show"]
|
||||
command: ["bluetoothctl", "show"] // Use default controller
|
||||
running: true
|
||||
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
root.bluetoothAvailable = text.trim() !== "" && !text.includes("No default controller")
|
||||
root.bluetoothEnabled = text.includes("Powered: yes")
|
||||
console.log("Bluetooth available:", root.bluetoothAvailable, "enabled:", root.bluetoothEnabled)
|
||||
|
||||
if (root.bluetoothEnabled && root.bluetoothAvailable) {
|
||||
bluetoothDeviceScanner.running = true
|
||||
@@ -37,7 +36,7 @@ Singleton {
|
||||
|
||||
Process {
|
||||
id: bluetoothDeviceScanner
|
||||
command: ["bash", "-c", "bluetoothctl devices | while read -r line; do if [[ $line =~ Device\\ ([0-9A-F:]+)\\ (.+) ]]; then mac=\"${BASH_REMATCH[1]}\"; name=\"${BASH_REMATCH[2]}\"; if [[ ! $name =~ ^/org/bluez ]]; then info=$(bluetoothctl info $mac); connected=$(echo \"$info\" | grep 'Connected:' | grep -q 'yes' && echo 'true' || echo 'false'); battery=$(echo \"$info\" | grep 'Battery Percentage' | grep -o '([0-9]*)' | tr -d '()'); echo \"$mac|$name|$connected|${battery:-}\"; fi; fi; done"]
|
||||
command: ["bash", "-c", "bluetoothctl devices | while read -r line; do if [[ $line =~ Device\\ ([0-9A-F:]+)\\ (.+) ]]; then mac=\"${BASH_REMATCH[1]}\"; name=\"${BASH_REMATCH[2]}\"; if [[ ! $name =~ ^/org/bluez ]]; then info=$(bluetoothctl info $mac); connected=$(echo \"$info\" | grep -m1 'Connected:' | awk '{print $2}'); battery=$(echo \"$info\" | grep -m1 'Battery Percentage:' | grep -o '[0-9]\\+'); echo \"$mac|$name|$connected|${battery:-}\"; fi; fi; done"]
|
||||
running: false
|
||||
|
||||
stdout: StdioCollector {
|
||||
@@ -52,7 +51,7 @@ Singleton {
|
||||
if (parts.length >= 3) {
|
||||
let mac = parts[0].trim()
|
||||
let name = parts[1].trim()
|
||||
let connected = parts[2].trim() === 'true'
|
||||
let connected = parts[2].trim() === 'yes'
|
||||
let battery = parts[3] ? parseInt(parts[3]) : -1
|
||||
|
||||
// Skip if name is still a technical path
|
||||
@@ -82,7 +81,6 @@ Singleton {
|
||||
}
|
||||
|
||||
root.bluetoothDevices = devices
|
||||
console.log("Found", devices.length, "Bluetooth devices")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -95,23 +93,12 @@ Singleton {
|
||||
}
|
||||
|
||||
function startDiscovery() {
|
||||
console.log("Starting Bluetooth discovery...")
|
||||
let discoveryProcess = Qt.createQmlObject('
|
||||
import Quickshell.Io
|
||||
Process {
|
||||
command: ["bluetoothctl", "scan", "on"]
|
||||
running: true
|
||||
onExited: {
|
||||
root.scanning = true
|
||||
// Scan for 10 seconds then get discovered devices
|
||||
discoveryScanTimer.start()
|
||||
}
|
||||
}
|
||||
', root)
|
||||
root.scanning = true
|
||||
// Run comprehensive scan that gets all devices
|
||||
discoveryScanner.running = true
|
||||
}
|
||||
|
||||
function stopDiscovery() {
|
||||
console.log("Stopping Bluetooth discovery...")
|
||||
let stopDiscoveryProcess = Qt.createQmlObject('
|
||||
import Quickshell.Io
|
||||
Process {
|
||||
@@ -180,7 +167,6 @@ Singleton {
|
||||
}
|
||||
|
||||
function toggleBluetoothDevice(mac) {
|
||||
console.log("Toggling Bluetooth device:", mac)
|
||||
let device = root.bluetoothDevices.find(d => d.mac === mac)
|
||||
if (device) {
|
||||
let action = device.connected ? "disconnect" : "connect"
|
||||
@@ -207,26 +193,68 @@ Singleton {
|
||||
', root)
|
||||
}
|
||||
|
||||
// Timer for discovery scanning
|
||||
// Timer to refresh adapter & device state
|
||||
Timer {
|
||||
id: discoveryScanTimer
|
||||
interval: 8000 // 8 seconds
|
||||
repeat: false
|
||||
interval: 3000 // 3s refresh for more responsive updates
|
||||
running: true; repeat: true
|
||||
onTriggered: {
|
||||
availableDeviceScanner.running = true
|
||||
bluetoothStatusChecker.running = true
|
||||
if (root.bluetoothEnabled) {
|
||||
bluetoothDeviceScanner.running = true
|
||||
// Also refresh paired devices to get current connection status
|
||||
pairedDeviceChecker.discoveredToMerge = []
|
||||
pairedDeviceChecker.running = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Scan for available/discoverable devices
|
||||
property var discoveredDevices: []
|
||||
|
||||
// Handle discovered devices
|
||||
function _handleDiscovered(found) {
|
||||
|
||||
let discoveredDevices = []
|
||||
for (let device of found) {
|
||||
let type = "bluetooth"
|
||||
let nameLower = device.name.toLowerCase()
|
||||
if (nameLower.includes("headphone") || nameLower.includes("airpod") || nameLower.includes("headset") || nameLower.includes("arctis") || nameLower.includes("audio")) type = "headset"
|
||||
else if (nameLower.includes("mouse")) type = "mouse"
|
||||
else if (nameLower.includes("keyboard")) type = "keyboard"
|
||||
else if (nameLower.includes("phone") || nameLower.includes("iphone") || nameLower.includes("samsung") || nameLower.includes("android")) type = "phone"
|
||||
else if (nameLower.includes("watch")) type = "watch"
|
||||
else if (nameLower.includes("speaker")) type = "speaker"
|
||||
else if (nameLower.includes("tv") || nameLower.includes("display")) type = "tv"
|
||||
|
||||
discoveredDevices.push({
|
||||
mac: device.mac,
|
||||
name: device.name,
|
||||
type: type,
|
||||
paired: false,
|
||||
connected: false,
|
||||
rssi: -70,
|
||||
signalStrength: "fair",
|
||||
canPair: true
|
||||
})
|
||||
|
||||
console.log(" -", device.name, "(", device.mac, ")")
|
||||
}
|
||||
|
||||
// Get paired devices first, then merge with discovered
|
||||
pairedDeviceChecker.discoveredToMerge = discoveredDevices
|
||||
pairedDeviceChecker.running = true
|
||||
}
|
||||
|
||||
// Get only currently connected/paired devices that matter
|
||||
Process {
|
||||
id: availableDeviceScanner
|
||||
command: ["bash", "-c", "timeout 5 bluetoothctl devices | grep -v 'Device.*/' | while read -r line; do if [[ $line =~ Device\ ([0-9A-F:]+)\ (.+) ]]; then mac=\"${BASH_REMATCH[1]}\"; name=\"${BASH_REMATCH[2]}\"; if [[ ! $name =~ ^/org/bluez ]] && [[ ! $name =~ hci0 ]]; then info=$(timeout 3 bluetoothctl info $mac 2>/dev/null); paired=$(echo \"$info\" | grep 'Paired:' | grep -q 'yes' && echo 'true' || echo 'false'); connected=$(echo \"$info\" | grep 'Connected:' | grep -q 'yes' && echo 'true' || echo 'false'); rssi=$(echo \"$info\" | grep 'RSSI:' | awk '{print $2}' | head -n1); echo \"$mac|$name|$paired|$connected|${rssi:-}\"; fi; fi; done"]
|
||||
command: ["bash", "-c", "bluetoothctl devices | while read -r line; do if [[ $line =~ Device\\ ([A-F0-9:]+)\\ (.+) ]]; then mac=\"${BASH_REMATCH[1]}\"; name=\"${BASH_REMATCH[2]}\"; info=$(bluetoothctl info \"$mac\" 2>/dev/null); paired=$(echo \"$info\" | grep -m1 'Paired:' | awk '{print $2}'); connected=$(echo \"$info\" | grep -m1 'Connected:' | awk '{print $2}'); if [[ \"$paired\" == \"yes\" ]] || [[ \"$connected\" == \"yes\" ]]; then echo \"$mac|$name|$paired|$connected\"; fi; fi; done"]
|
||||
running: false
|
||||
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
|
||||
let devices = []
|
||||
if (text.trim()) {
|
||||
let devices = []
|
||||
let lines = text.trim().split('\n')
|
||||
|
||||
for (let line of lines) {
|
||||
@@ -235,16 +263,15 @@ Singleton {
|
||||
if (parts.length >= 4) {
|
||||
let mac = parts[0].trim()
|
||||
let name = parts[1].trim()
|
||||
let paired = parts[2].trim() === 'true'
|
||||
let connected = parts[3].trim() === 'true'
|
||||
let rssi = parts[4] ? parseInt(parts[4]) : 0
|
||||
let paired = parts[2].trim() === 'yes'
|
||||
let connected = parts[3].trim() === 'yes'
|
||||
|
||||
// Skip if name is still a technical path
|
||||
if (name.startsWith('/org/bluez') || name.includes('hci0')) {
|
||||
// Skip technical names
|
||||
if (name.startsWith('/org/bluez') || name.includes('hci0') || name.length < 3) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Determine device type from name
|
||||
// Determine device type
|
||||
let type = "bluetooth"
|
||||
let nameLower = name.toLowerCase()
|
||||
if (nameLower.includes("headphone") || nameLower.includes("airpod") || nameLower.includes("headset") || nameLower.includes("arctis") || nameLower.includes("audio")) type = "headset"
|
||||
@@ -255,32 +282,128 @@ Singleton {
|
||||
else if (nameLower.includes("speaker")) type = "speaker"
|
||||
else if (nameLower.includes("tv") || nameLower.includes("display")) type = "tv"
|
||||
|
||||
// Signal strength assessment
|
||||
let signalStrength = "unknown"
|
||||
if (rssi !== 0) {
|
||||
if (rssi >= -50) signalStrength = "excellent"
|
||||
else if (rssi >= -60) signalStrength = "good"
|
||||
else if (rssi >= -70) signalStrength = "fair"
|
||||
else signalStrength = "weak"
|
||||
}
|
||||
|
||||
devices.push({
|
||||
mac: mac,
|
||||
name: name,
|
||||
type: type,
|
||||
paired: paired,
|
||||
connected: connected,
|
||||
rssi: rssi,
|
||||
signalStrength: signalStrength,
|
||||
canPair: !paired
|
||||
rssi: 0,
|
||||
signalStrength: "unknown",
|
||||
canPair: false // Already paired
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
root.availableDevices = devices
|
||||
console.log("Found", devices.length, "available Bluetooth devices")
|
||||
}
|
||||
|
||||
root.availableDevices = devices
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Discovery scanner using bluetoothctl --timeout
|
||||
Process {
|
||||
id: discoveryScanner
|
||||
// Discover for 8 s in non-interactive mode, then auto-exit
|
||||
command: ["bluetoothctl",
|
||||
"--timeout", "8",
|
||||
"--monitor", // keeps stdout unbuffered
|
||||
"scan", "on"]
|
||||
running: false
|
||||
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
/*
|
||||
* bluetoothctl prints lines like:
|
||||
* [NEW] Device 12:34:56:78:9A:BC My-Headphones
|
||||
*/
|
||||
const rx = /^\[NEW\] Device ([0-9A-F:]+)\s+(.+)$/i;
|
||||
const found = text.split('\n')
|
||||
.filter(l => rx.test(l))
|
||||
.map(l => {
|
||||
const [,mac,name] = l.match(rx);
|
||||
return { mac, name };
|
||||
});
|
||||
root._handleDiscovered(found);
|
||||
}
|
||||
}
|
||||
|
||||
onExited: {
|
||||
root.scanning = false
|
||||
}
|
||||
}
|
||||
|
||||
// Get paired devices and merge with discovered ones
|
||||
Process {
|
||||
id: pairedDeviceChecker
|
||||
command: ["bash", "-c", "bluetoothctl devices | while read -r line; do if [[ $line =~ Device\\ ([A-F0-9:]+)\\ (.+) ]]; then mac=\"${BASH_REMATCH[1]}\"; name=\"${BASH_REMATCH[2]}\"; if [[ ${#name} -gt 3 ]] && [[ ! $name =~ ^/org/bluez ]] && [[ ! $name =~ hci0 ]]; then info=$(bluetoothctl info \"$mac\" 2>/dev/null); paired=$(echo \"$info\" | grep -m1 'Paired:' | awk '{print $2}'); connected=$(echo \"$info\" | grep -m1 'Connected:' | awk '{print $2}'); echo \"$mac|$name|$paired|$connected\"; fi; fi; done"]
|
||||
running: false
|
||||
property var discoveredToMerge: []
|
||||
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
// Start with discovered devices (unpaired, available to pair)
|
||||
let allDevices = [...pairedDeviceChecker.discoveredToMerge]
|
||||
let seenMacs = new Set(allDevices.map(d => d.mac))
|
||||
|
||||
// Add only actually paired devices from bluetoothctl
|
||||
if (text.trim()) {
|
||||
let lines = text.trim().split('\n')
|
||||
|
||||
for (let line of lines) {
|
||||
if (line.trim()) {
|
||||
let parts = line.split('|')
|
||||
if (parts.length >= 4) {
|
||||
let mac = parts[0].trim()
|
||||
let name = parts[1].trim()
|
||||
let paired = parts[2].trim() === 'yes'
|
||||
let connected = parts[3].trim() === 'yes'
|
||||
|
||||
// Only include if actually paired
|
||||
if (!paired) continue
|
||||
|
||||
// Check if already in discovered list
|
||||
if (seenMacs.has(mac)) {
|
||||
// Update existing device to show it's paired
|
||||
let existing = allDevices.find(d => d.mac === mac)
|
||||
if (existing) {
|
||||
existing.paired = true
|
||||
existing.connected = connected
|
||||
existing.canPair = false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Add paired device not found during scan
|
||||
let type = "bluetooth"
|
||||
let nameLower = name.toLowerCase()
|
||||
if (nameLower.includes("headphone") || nameLower.includes("airpod") || nameLower.includes("headset") || nameLower.includes("arctis") || nameLower.includes("audio")) type = "headset"
|
||||
else if (nameLower.includes("mouse")) type = "mouse"
|
||||
else if (nameLower.includes("keyboard")) type = "keyboard"
|
||||
else if (nameLower.includes("phone") || nameLower.includes("iphone") || nameLower.includes("samsung") || nameLower.includes("android")) type = "phone"
|
||||
else if (nameLower.includes("watch")) type = "watch"
|
||||
else if (nameLower.includes("speaker")) type = "speaker"
|
||||
else if (nameLower.includes("tv") || nameLower.includes("display")) type = "tv"
|
||||
|
||||
allDevices.push({
|
||||
mac: mac,
|
||||
name: name,
|
||||
type: type,
|
||||
paired: true,
|
||||
connected: connected,
|
||||
rssi: -100,
|
||||
signalStrength: "unknown",
|
||||
canPair: false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
root.availableDevices = allDevices
|
||||
root.scanning = false
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,16 +27,15 @@ Singleton {
|
||||
target: modelData
|
||||
|
||||
Component.onCompleted: {
|
||||
console.log("MPRIS Player connected:", modelData.identity)
|
||||
if (root.trackedPlayer == null || modelData.isPlaying) {
|
||||
root.trackedPlayer = modelData
|
||||
}
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
if (root.trackedPlayer == null || !root.trackedPlayer.isPlaying) {
|
||||
if (root.trackedPlayer == null || root.trackedPlayer.playbackState !== MprisPlaybackState.Playing) {
|
||||
for (const player of Mpris.players.values) {
|
||||
if (player.playbackState.isPlaying) {
|
||||
if (player.playbackState === MprisPlaybackState.Playing) {
|
||||
root.trackedPlayer = player
|
||||
break
|
||||
}
|
||||
@@ -73,7 +72,6 @@ Singleton {
|
||||
onActivePlayerChanged: this.updateTrack()
|
||||
|
||||
function updateTrack() {
|
||||
console.log(`MPRIS Track Update: ${this.activePlayer?.trackTitle ?? ""} : ${this.activePlayer?.trackArtist}`)
|
||||
this.activeTrack = {
|
||||
uniqueId: this.activePlayer?.uniqueId ?? 0,
|
||||
artUrl: this.activePlayer?.trackArtUrl ?? "",
|
||||
@@ -86,7 +84,7 @@ Singleton {
|
||||
this.__reverse = false
|
||||
}
|
||||
|
||||
property bool isPlaying: this.activePlayer && this.activePlayer.isPlaying
|
||||
property bool isPlaying: this.activePlayer && this.activePlayer.playbackState === MprisPlaybackState.Playing
|
||||
property bool canTogglePlaying: this.activePlayer?.canTogglePlaying ?? false
|
||||
function togglePlaying() {
|
||||
if (this.canTogglePlaying) this.activePlayer.togglePlaying()
|
||||
@@ -128,7 +126,6 @@ Singleton {
|
||||
|
||||
function setActivePlayer(player) {
|
||||
const targetPlayer = player ?? Mpris.players[0]
|
||||
console.log(`[Mpris] Active player ${targetPlayer} << ${activePlayer}`)
|
||||
|
||||
if (targetPlayer && this.activePlayer) {
|
||||
this.__reverse = Mpris.players.indexOf(targetPlayer) < Mpris.players.indexOf(this.activePlayer)
|
||||
@@ -139,22 +136,4 @@ Singleton {
|
||||
this.trackedPlayer = targetPlayer
|
||||
}
|
||||
|
||||
// Debug timer
|
||||
Timer {
|
||||
interval: 3000
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
if (activePlayer) {
|
||||
console.log(` Track: ${activePlayer.trackTitle || 'Unknown'} by ${activePlayer.trackArtist || 'Unknown'}`)
|
||||
console.log(` State: ${activePlayer.playbackState}`)
|
||||
} else if (Mpris.players.length === 0) {
|
||||
console.log(" No MPRIS players detected. Try:")
|
||||
console.log(" - mpv --script-opts=mpris-title='{{media-title}}' file.mp3")
|
||||
console.log(" - firefox/chromium (YouTube, Spotify Web)")
|
||||
console.log(" - vlc file.mp3")
|
||||
console.log(" Check available players: busctl --user list | grep mpris")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user