From bf4a4a302a6a7dba5f03834f7f05079d49a7fbe8 Mon Sep 17 00:00:00 2001 From: Nydragon Date: Mon, 26 Aug 2024 03:08:25 +0200 Subject: [PATCH] feat: first iteration off a working audio volumen manager - default sink - mute it - change volume - streams - change volume --- .qmllint.ini | 33 ++++++++++++++ .qmlls.ini | 2 + assets/audio-volume-high.svg | 13 ++++++ assets/folder-music.svg | 13 ++++++ assets/mute.png | Bin 0 -> 7996 bytes {src => assets}/speaker.png | Bin 2549 -> 2550 bytes assets/volume-mute.png | Bin 0 -> 7963 bytes src/AudioOutput.qml | 13 ++++-- src/Bar.qml | 6 ++- src/windows/AudioEntry.qml | 84 +++++++++++++++++++++++++++++++++++ src/windows/AudioManager.qml | 61 ++++++++++++++++++++----- 11 files changed, 211 insertions(+), 14 deletions(-) create mode 100644 .qmllint.ini create mode 100644 .qmlls.ini create mode 100644 assets/audio-volume-high.svg create mode 100644 assets/folder-music.svg create mode 100644 assets/mute.png rename {src => assets}/speaker.png (98%) create mode 100644 assets/volume-mute.png create mode 100644 src/windows/AudioEntry.qml diff --git a/.qmllint.ini b/.qmllint.ini new file mode 100644 index 0000000..07b81e9 --- /dev/null +++ b/.qmllint.ini @@ -0,0 +1,33 @@ +[General] +DisableDefaultImports=false + +[Warnings] +AccessSingletonViaObject=warning +AttachedPropertyReuse=disable +BadSignalHandlerParameters=warning +CompilerWarnings=disable +Deprecated=warning +DuplicatePropertyBinding=warning +DuplicatedName=warning +ImportFailure=warning +IncompatibleType=warning +InheritanceCycle=warning +InvalidLintDirective=warning +LintPluginWarnings=disable +MissingProperty=warning +MissingType=warning +MultilineStrings=info +NonListProperty=warning +PrefixedImportType=warning +PropertyAliasCycles=warning +ReadOnlyProperty=warning +RequiredProperty=warning +RestrictedType=warning +TopLevelComponent=warning +UncreatableType=warning +UnqualifiedAccess=warning +UnresolvedType=warning +UnusedImports=info +UseProperFunction=warning +VarUsedBeforeDeclaration=warning +WithStatement=warning diff --git a/.qmlls.ini b/.qmlls.ini new file mode 100644 index 0000000..780b83a --- /dev/null +++ b/.qmlls.ini @@ -0,0 +1,2 @@ +[General] +no-cmake-calls=false diff --git a/assets/audio-volume-high.svg b/assets/audio-volume-high.svg new file mode 100644 index 0000000..05720a8 --- /dev/null +++ b/assets/audio-volume-high.svg @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/assets/folder-music.svg b/assets/folder-music.svg new file mode 100644 index 0000000..7a0bb78 --- /dev/null +++ b/assets/folder-music.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/assets/mute.png b/assets/mute.png new file mode 100644 index 0000000000000000000000000000000000000000..d34d1e1af0d524c494009b46f3efc2057a095600 GIT binary patch literal 7996 zcmZ{pcUV(r*zoTYgM^|;pcNGm!9iOQP?RCd0a7Z8gQXzEqM&7J1T+wG>`^Op~6aU>7Hh{iZ^GEFS54A<%%zd6g z`!>f#>`U6dcPAtzC0Xx|jbevykKbt>w>L7o+hrEO>`HHsm45qkx?V>$+}ypb<*nF+ zHF@R+7VM1Jn6^N zIQOBN=45ZLB+rC!MT^{A#Laj1PbzfVq}-|S5@i>N3*V$3Q%{9NnOweG)a;*mqv&Q) ze)k5Yr$Qx<5p}e^Dp&7lSaK%6I4?DSl$FrIZ0{1e?>5u{lg9FZ;ykyu!J*FJ^-8fz zW!0zNwGrPJ-ApYKdhR(nO;sZMS(NEl?%df=1jsrH#N9j4vd!f&xAS0gqlZhu=q^ja zk;a_t{ElfO77*~RUmlitN6;5%=e}**0jl}liqiq^t+6&2>|~ck)3MsvAQig%Oly6JtWl82{P zX1VA<%bR5)V`H|!%~f176!`ew-8;98PB5UN!Yh#XqGe2RGp5lb9i zbsGV)q1B?uS-fI5SNFT()Ai8?&lA@*Nyhsoz3? z{F%M@zoibR18wqh7jw+vQE!EOk*HZORC{6K?(C!S8SA}Btgp3oo@%3_L*zQSSgYz{ zUuNd|DpQF!*d_$}yNidDuPuUDY33{*ac+mn6#BJJH&L)LulP$yd2{u;Y9R7Z(Yybw zqu77Ez)Jm?`%im4cRcvOf{#U_N3+6yw=``dD8G;J4bJs z!m&hu#qB!rG%X0Oyu?YC+FaRo%#xtKZVrr#8s~0+_<7Tc+**f^deedZ=}NmoA*YdT z`+pozt(V(9N`!dE^`Wu2-Q!$eh_~RCzYqC4mkwk5uFK!23z~Hxv3)FfJsmr}^8q)w zvGp5*ia7!#JNbLX+d6UEHCr0%q6bh$gxW226d2wg! z8RS<61oh12^5}kPk2iZ3!QX`DKh@{U{Le>?*X)X&3jsdZu*7nCX}Un&kU*!NqyZ~q z_STx~eM9G*GGPTBO8RR=ma}+*Gh+<+mI*%M_c4QGUgGdmOK4=1A@=OHZ8b%GL#O7a zgT&qgY?nwS?ZZmFvF)+Z)}9A|*u zN2Vy*m?sE&fKB_J4u^XSZ~+Lj(OI~sWt>(|^JT2tFM^vkjgkbLI> z{DqnMs=~gZpGuMc_JH_JO+{|6hm)zZUJ#G{%ai@t-hYX5+wr$*U+iuA;C3y zeLb7mcbL%mCxhHseQR`uRD8bu1IBk|Lj4W_@6B9rWZ>(bor+6!0wdw$H4txW0qs3i zav_#=_5}9b1rKOwmgc+1jVCvCM$kdqlEwAb(5~X&b9+myDr(JkN#+oA+=8yl-%tsBn;fVvv1B`KcHC zdd%5b$cGr@o}yw^pj7PK9zPedzGTATp)2y$>Aa?_2N}TH>j5T*l&S>mi$6S|v-w

9zzpk}8F>V*5ez;>+# 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 CoLUC} literal 0 HcmV?d00001 diff --git a/src/AudioOutput.qml b/src/AudioOutput.qml index 6379cdf..c63b2f9 100644 --- a/src/AudioOutput.qml +++ b/src/AudioOutput.qml @@ -13,7 +13,7 @@ import "windows" // BUG: When controlling audio from outside of QS, the change is reflected, but if audio in pavucontrol is not 100% // QS can only change from 0 to whatever is set in pavucontrol Rectangle { - id: test + id: aoutput width: parent.width height: (icon.height + slider.height) * 1.5 anchors.bottomMargin: 5 @@ -28,13 +28,20 @@ Rectangle { objects: [sink] } + required property var popupAnchor + + AudioManager { + id: audioman + anchor.window: popupAnchor + } + MouseArea { id: audio_area anchors.fill: parent onClicked: { - AudioManager.visible = !AudioManager.visible; + audioman.visible = !audioman.visible; } onWheel: wheel => { @@ -52,7 +59,7 @@ Rectangle { // TODO: Make icon depend on sink type and volume level Image { id: icon - source: "speaker.png" + source: "root:/../assets/speaker.png" width: parent.width * (2 / 3) anchors.horizontalCenter: parent.horizontalCenter diff --git a/src/Bar.qml b/src/Bar.qml index 63aa0b5..e08cc15 100644 --- a/src/Bar.qml +++ b/src/Bar.qml @@ -1,14 +1,17 @@ import Quickshell // for ShellRoot and PanelWindow import QtQuick // for Text import Quickshell.Io // for process +import "windows" Scope { Variants { model: Quickshell.screens // the screen from the screens list will be injected into this property PanelWindow { + id: root property var modelData screen: modelData + anchors { top: true left: true @@ -17,7 +20,7 @@ Scope { margins.left: 2 width: 30 - color: "#00000000" + color: "transparent" // the ClockWidget type we just created // TODO: on click open a calendar view @@ -27,6 +30,7 @@ Scope { } AudioOutput { + popupAnchor: root anchors.top: clock.bottom anchors.horizontalCenter: parent.horizontalCenter } diff --git a/src/windows/AudioEntry.qml b/src/windows/AudioEntry.qml new file mode 100644 index 0000000..6d63155 --- /dev/null +++ b/src/windows/AudioEntry.qml @@ -0,0 +1,84 @@ +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls +import Quickshell.Services.Pipewire + +RowLayout { + required property PwNode node + + // bind the node so we can read its properties + PwObjectTracker { + objects: [node] + } + + //Component.onCompleted: console.log(JSON.stringify(node.properties, null, 2)) + + Image { + source: { + const hasIcon = !!node.properties["application.icon-name"] ?? false; + console.log(hasIcon); + const getFallback = () => node.isStream ? "root:/../assets/folder-music.svg" : "root:/../assets/audio-volume-high.svg"; + const icon = hasIcon ? `image://icon/${node.properties["application.icon-name"]}` : getFallback(); + icon; + } + + //sourceSize.width: 40 + //sourceSize.height: 40 + fillMode: Image.PreserveAspectFit + + Layout.fillHeight: true + Layout.fillWidth: true + Layout.maximumWidth: 40 + Layout.maximumHeight: parent.height + + sourceSize.width: 40 + sourceSize.height: 40 + //width: 40 + //height: 40 + Component.onCompleted: console.log(`width: ${paintedWidth}, height: ${paintedHeight}`) + } + + ColumnLayout { + RowLayout { + id: b + spacing: 6 + Layout.preferredHeight: 30 + + Text { + text: node.properties["media.name"] ?? node.description + } + + Button { + visible: node.isSink + width: 10 + checkable: true + Image { + source: node.audio.muted ? "root:/../assets/mute.png" : "root:/../assets/speaker.png" + height: parent.height * (2 / 3) + + anchors.centerIn: parent + + fillMode: Image.PreserveAspectFit + } + onClicked: node.audio.muted = !node.audio.muted + } + + Button { + visible: node.isSink + text: "default" + } + } + RowLayout { + Label { + Layout.preferredWidth: 50 + text: `${Math.floor(node.audio.volume * 100)}%` + } + + Slider { + Layout.fillWidth: true + value: node.audio.volume + onValueChanged: node.audio.volume = value + } + } + } +} diff --git a/src/windows/AudioManager.qml b/src/windows/AudioManager.qml index f443b6e..4948da3 100644 --- a/src/windows/AudioManager.qml +++ b/src/windows/AudioManager.qml @@ -1,19 +1,60 @@ -pragma Singleton - import Quickshell +import Quickshell.Services.Pipewire import QtQuick +import QtQuick.Layouts +import QtQuick.Controls -Singleton { - FloatingWindow { - color: "transparent" - height: 300 - width: 600 +PopupWindow { + anchor { + rect.x: 30 + rect.y: 20 + } - Rectangle { + color: "transparent" + width: 500 + height: 300 + visible: false + + Rectangle { + anchors.fill: parent + border.color: "black" + border.width: 2 + radius: 5 + color: "white" + ScrollView { anchors.fill: parent - color: "#20ffffff" + contentWidth: availableWidth - // your content here + ColumnLayout { + anchors.fill: parent + anchors.margins: 10 + + PwNodeLinkTracker { + id: linkTracker + node: Pipewire.defaultAudioSink + } + + AudioEntry { + node: Pipewire.defaultAudioSink + } + + Rectangle { + height: 2 + color: "black" + Layout.fillWidth: true + radius: 10 + } + + Repeater { + // Show all sources, regardless of what sink they are assigned to + model: Pipewire.linkGroups + + AudioEntry { + required property PwLinkGroup modelData + node: modelData.source + } + } + } } } }