import Quickshell // for PanelWindow import QtQuick // for Text import QtQuick.Controls import QtQuick.Layouts import Quickshell.Io import Quickshell.Widgets import Quickshell.Hyprland import Quickshell.Services.Pipewire ClippingWrapperRectangle { radius: 5 width: 100; height: 30 Button { id: button text: (Pipewire.defaultAudioSink?.audio?.muted ? " " : " ") + Math.floor(Pipewire.defaultAudioSink?.audio?.volume * 100) + "%" font.pointSize: 12 implicitHeight: parent.height PwObjectTracker { objects: [ Pipewire.defaultAudioSink ] } onClicked: { menu.visible = true grab.active = true } } required property var window required property real popupOffset id: root PopupWindow { id: menu anchor.window: window anchor.rect.x: popupOffset anchor.rect.y: 50 implicitWidth: 250 implicitHeight: 150 visible: false color: "transparent" ClippingWrapperRectangle { radius: 5 implicitHeight: parent.height - 20 implicitWidth: parent.width ScrollView { ColumnLayout { spacing: 0 Text { text: 'Output Devices' } ColumnLayout { Repeater { id: outputs model: { Pipewire.nodes.values.filter(n => n.isSink && n.audio && n.nickname != "") } Button { text: outputs.model[index].nickname onClicked: Pipewire.preferredDefaultAudioSink = outputs.model[index] } } } Text { text: 'Input Devices' } ColumnLayout { Repeater { id: inputs model: { Pipewire.nodes.values.filter(n => !n.isSink && n.audio && n.nickname != "") } Button { text: inputs.model[index].nickname onClicked: Pipewire.preferredDefaultAudioSource = inputs.model[index] } } } } } } HyprlandFocusGrab { id: grab windows: [ menu ] onCleared: menu.visible = false } } }