From 22cf6cc53e2bc55504cadd785f96d5d56eb42423 Mon Sep 17 00:00:00 2001 From: Benjamin Palko Date: Sat, 13 Sep 2025 22:53:37 -0400 Subject: [PATCH] basic audio configurations --- modules/configuration/AudioView.qml | 71 +++++++++++++++++++++++++ modules/configuration/Configuration.qml | 11 ++-- services/Pipewire.qml | 15 ++++++ 3 files changed, 90 insertions(+), 7 deletions(-) create mode 100644 modules/configuration/AudioView.qml diff --git a/modules/configuration/AudioView.qml b/modules/configuration/AudioView.qml new file mode 100644 index 0000000..9f0e6af --- /dev/null +++ b/modules/configuration/AudioView.qml @@ -0,0 +1,71 @@ +import qs.components +import qs.config +import qs.services +import QtQuick +import QtQuick.Layouts + +ColumnLayout { + anchors.fill: parent + + spacing: Styling.layout.spacing.xl + + StyledText { + text: "Speaker Settings" + } + StyledPane { + Layout.fillWidth: true + padding: 24 + GridLayout { + Layout.fillWidth: true + + columnSpacing: Styling.layout.spacing.xl + + StyledText { + Layout.column: 1 + Layout.row: 1 + text: "Speakers" + } + + StyledComboBox { + Layout.column: 2 + Layout.row: 1 + Layout.fillWidth: true + currentIndex: Pipewire.sinks.indexOf(Pipewire.sink) + model: Pipewire.sinks.map(sink => sink.nickname ?? sink.name) + onActivated: index => { + Pipewire.setSink(Pipewire.sinks[index]); + } + } + } + } + + StyledText { + text: "Microphone Settings" + } + StyledPane { + Layout.fillWidth: true + padding: 24 + GridLayout { + Layout.fillWidth: true + + columnSpacing: Styling.layout.spacing.xl + + StyledText { + Layout.column: 1 + Layout.row: 2 + text: "Microphones" + } + + StyledComboBox { + Layout.column: 2 + Layout.row: 2 + Layout.fillWidth: true + currentIndex: Pipewire.sources.indexOf(Pipewire.source) + model: Pipewire.sources.map(source => source.nickname ?? source.name) + onActivated: index => { + Pipewire.setSource(Pipewire.sinks[index]); + } + } + } + } +} diff --git a/modules/configuration/Configuration.qml b/modules/configuration/Configuration.qml index 5684f30..1e1871e 100644 --- a/modules/configuration/Configuration.qml +++ b/modules/configuration/Configuration.qml @@ -26,7 +26,7 @@ StyledPanelWindow { anchors.left: parent.left anchors.right: parent.right - text: "General" + text: "Audio" } StyledTabButton { anchors.left: parent.left @@ -49,14 +49,11 @@ StyledPanelWindow { currentIndex: tabs.currentIndex ScrollView { - padding: 36 - StyledPane { - anchors.left: parent.left - anchors.right: parent.right - } + padding: 24 + AudioView {} } ScrollView { - padding: 36 + padding: 24 StylingView {} } } diff --git a/services/Pipewire.qml b/services/Pipewire.qml index 53cc141..4cdd60b 100644 --- a/services/Pipewire.qml +++ b/services/Pipewire.qml @@ -10,6 +10,9 @@ Singleton { readonly property PwNode sink: Pipewire.defaultAudioSink readonly property PwNode source: Pipewire.defaultAudioSource + readonly property list sinks: Pipewire.nodes.values.filter(node => node.audio != null && node.isSink && !node.isStream) + readonly property list sources: Pipewire.nodes.values.filter(node => node.audio != null && !node.isSink && !node.isStream) + readonly property bool muted: sink?.audio?.muted ?? false readonly property real volume: sink?.audio?.volume ?? 0 @@ -42,6 +45,18 @@ Singleton { sink.audio.muted = !sink.audio.muted; } + function setSink(node: PwNode) { + if (node.audio != null && node.isSink && !node.isStream) { + Pipewire.preferredDefaultAudioSink = node; + } + } + + function setSource(node: PwNode) { + if (node.audio != null && !node.isSink && !node.isStream) { + Pipewire.preferredDefaultAudioSource = node; + } + } + PwObjectTracker { objects: [Pipewire.defaultAudioSink, Pipewire.defaultAudioSource] }