import Quickshell.Services.Pipewire import QtQuick import QtQuick.Layouts import "../components" Item { id: root implicitWidth: chip.implicitWidth + 10 implicitHeight: 24 signal clickedLeft PwObjectTracker { objects: Pipewire.nodes.values } function safeVolume(node) { if (!node || !node.ready || !node.audio) return 0 const v = node.audio.volume return (v !== undefined && !isNaN(v)) ? v : 0 } function setVolume(node, v) { if (!node || !node.ready || !node.audio) return node.audio.volume = Math.max(0, Math.min(1, v)) } function volIcon(vol, muted) { if (muted) return "\uf6a9" if (vol > 0.6) return "\uf028" if (vol > 0.2) return "\uf027" return "\uf026" } readonly property var defaultSink: Pipewire.defaultAudioSink readonly property real defaultVolume: safeVolume(defaultSink) readonly property bool defaultMuted: defaultSink?.audio?.muted ?? false Row { id: chip anchors.centerIn: parent spacing: 5 Text { anchors.verticalCenter: parent.verticalCenter text: root.volIcon(root.defaultVolume, root.defaultMuted) font.family: "JetBrainsMono Nerd Font Mono" font.pixelSize: 14 color: root.defaultMuted ? Theme.textDim : Theme.text } Text { anchors.verticalCenter: parent.verticalCenter text: root.defaultMuted ? "mute" : Math.round(root.defaultVolume * 100) + "%" font.pixelSize: 11 color: Theme.textDim } } MouseArea { anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton cursorShape: Qt.PointingHandCursor onClicked: mouse => { if (mouse.button === Qt.RightButton) { if (root.defaultSink?.ready && root.defaultSink?.audio) root.defaultSink.audio.muted = !root.defaultSink.audio.muted } else { root.clickedLeft() } } onWheel: wheel => { if (!root.defaultSink?.ready) return root.setVolume(root.defaultSink, root.defaultVolume + wheel.angleDelta.y / 120 * 0.05) } } }