This commit is contained in:
2026-03-15 20:08:48 -05:00
parent 9871af127a
commit 6ea4782a80
15 changed files with 610 additions and 491 deletions

View File

@@ -7,101 +7,118 @@ 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
}
ScrollView {
anchors.fill: parent
ColumnLayout {
anchors.fill: parent
}
spacing: 0
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 {
color: Pywal.colors.color11
radius: 5
Layout.margins: 5
Layout.alignment: Qt.AlignVCenter | Qt.AlignTop
implicitWidth: parent.width - 2 * Layout.margins
implicitHeight: parent.height - 20
implicitWidth: parent.width
RowLayout {
width: parent.width
Text {
color: Pywal.colors.color0
Layout.margins: 5
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
text: 'Output'
}
ScrollView {
ColumnLayout {
Slider {
from: 0
to: 2
spacing: 0
orientation: Qt.Horizontal
Text {
text: 'Output Devices'
}
implicitWidth: 500
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]
}
}
}
value: Pipewire.defaultAudioSink.audio.volume
onValueChanged: Pipewire.defaultAudioSink.audio.volume = value
}
}
}
HyprlandFocusGrab {
id: grab
windows: [ menu ]
onCleared: menu.visible = false
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]
}
PwObjectTracker {
objects: [ outputs.model[index] ]
}
}
}
}
ClippingWrapperRectangle {
color: Pywal.colors.color11
radius: 5
Layout.margins: 5
Layout.alignment: Qt.AlignVCenter | Qt.AlignTop
implicitWidth: parent.width - 2 * Layout.margins
RowLayout {
width: parent.width
Text {
color: Pywal.colors.color0
Layout.margins: 5
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
text: 'Input'
}
Slider {
from: 0
to: 2
visible: false
orientation: Qt.Horizontal
implicitWidth: 500
value: Pipewire.defaultAudioSource.audio.volume
onValueChanged: Pipewire.defaultAudioSource.audio.volume = value
}
}
}
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]
}
}
}
}
}
}