From 3b1d8fd26256a7c2d6ad91ae4e5e6035c824882e Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Sat, 8 Nov 2025 16:48:00 +0100 Subject: [PATCH] make volume device selection use a combobox --- .../modules/common/widgets/StyledComboBox.qml | 15 ++++ .../sidebarRight/volumeMixer/VolumeDialog.qml | 12 +-- .../volumeMixer/VolumeDialogContent.qml | 77 +++++++------------ 3 files changed, 49 insertions(+), 55 deletions(-) create mode 100644 dots/.config/quickshell/ii/modules/common/widgets/StyledComboBox.qml diff --git a/dots/.config/quickshell/ii/modules/common/widgets/StyledComboBox.qml b/dots/.config/quickshell/ii/modules/common/widgets/StyledComboBox.qml new file mode 100644 index 000000000..2f391dd1f --- /dev/null +++ b/dots/.config/quickshell/ii/modules/common/widgets/StyledComboBox.qml @@ -0,0 +1,15 @@ +import QtQuick +import QtQuick.Controls.Material +import QtQuick.Controls +import qs.modules.common + +ComboBox { + id: root + + Material.theme: Material.System + Material.accent: Appearance.m3colors.m3primary + Material.primary: Appearance.m3colors.m3primary + Material.background: Appearance.m3colors.m3surface + Material.foreground: Appearance.m3colors.m3onSurface + Material.containerStyle: Material.Outlined +} diff --git a/dots/.config/quickshell/ii/modules/sidebarRight/volumeMixer/VolumeDialog.qml b/dots/.config/quickshell/ii/modules/sidebarRight/volumeMixer/VolumeDialog.qml index 004440b25..82bce9750 100644 --- a/dots/.config/quickshell/ii/modules/sidebarRight/volumeMixer/VolumeDialog.qml +++ b/dots/.config/quickshell/ii/modules/sidebarRight/volumeMixer/VolumeDialog.qml @@ -11,21 +11,23 @@ import Quickshell.Services.Pipewire WindowDialog { id: root property bool isSink: true - backgroundHeight: 700 + backgroundHeight: 600 WindowDialogTitle { text: root.isSink ? Translation.tr("Audio output") : Translation.tr("Audio input") } - VolumeDialogContent { - isSink: root.isSink - } - WindowDialogSeparator { + visible: root.hasApps + Layout.topMargin: -22 Layout.leftMargin: 0 Layout.rightMargin: 0 } + VolumeDialogContent { + isSink: root.isSink + } + WindowDialogButtonRow { DialogButton { buttonText: Translation.tr("Details") diff --git a/dots/.config/quickshell/ii/modules/sidebarRight/volumeMixer/VolumeDialogContent.qml b/dots/.config/quickshell/ii/modules/sidebarRight/volumeMixer/VolumeDialogContent.qml index a276128d9..bb1e036e6 100644 --- a/dots/.config/quickshell/ii/modules/sidebarRight/volumeMixer/VolumeDialogContent.qml +++ b/dots/.config/quickshell/ii/modules/sidebarRight/volumeMixer/VolumeDialogContent.qml @@ -16,25 +16,16 @@ ColumnLayout { readonly property list appPwNodes: Pipewire.nodes.values.filter((node) => { // Should be list but it breaks ScriptModel return root.correctType(node) && node.isStream }) + readonly property list devices: Pipewire.nodes.values.filter(node => { + return root.correctType(node) && !node.isStream + }) readonly property bool hasApps: appPwNodes.length > 0 spacing: 16 - WindowDialogSectionHeader { - visible: root.hasApps - text: Translation.tr("Applications") - } - - WindowDialogSeparator { - visible: root.hasApps - Layout.topMargin: -22 - Layout.leftMargin: 0 - Layout.rightMargin: 0 - color: Appearance.colors.colOutlineVariant - } - DialogSectionListView { visible: root.hasApps Layout.fillHeight: true + topMargin: 14 model: ScriptModel { values: root.appPwNodes @@ -49,44 +40,25 @@ ColumnLayout { } } - WindowDialogSectionHeader { - text: Translation.tr("Devices") - } - - WindowDialogSeparator { - Layout.topMargin: -22 - Layout.leftMargin: 0 - Layout.rightMargin: 0 - color: Appearance.colors.colOutlineVariant - } - - DialogSectionListView { - Layout.fillHeight: !root.hasApps - Layout.preferredHeight: 180 - - model: ScriptModel { - values: Pipewire.nodes.values.filter(node => { - return root.correctType(node) && !node.isStream - }) - } - delegate: StyledRadioButton { - id: radioButton - required property var modelData - anchors { - left: parent?.left - right: parent?.right + StyledComboBox { + id: deviceSelector + Layout.fillWidth: true + Layout.bottomMargin: 6 + model: root.devices.map(node => node.description) + currentIndex: root.devices.findIndex(item => { + if (root.isSink) { + return item.id === Pipewire.preferredDefaultAudioSink?.id + } else { + return item.id === Pipewire.preferredDefaultAudioSource?.id } - - description: modelData.description - checked: modelData.id === (root.isSink ? Pipewire.preferredDefaultAudioSink?.id : Pipewire.preferredDefaultAudioSource?.id) - - onCheckedChanged: { - if (!checked) return; - if (root.isSink) { - Pipewire.preferredDefaultAudioSink = modelData - } else { - Pipewire.preferredDefaultAudioSource = modelData - } + }) + onActivated: (index) => { + print(index) + const item = root.devices[index] + if (root.isSink) { + Pipewire.preferredDefaultAudioSink = item + } else { + Pipewire.preferredDefaultAudioSource = item } } } @@ -106,4 +78,9 @@ ColumnLayout { spacing: 4 animateAppearance: false } + + Component { + id: listElementComp + ListElement {} + } }