summaryrefslogtreecommitdiff
path: root/nixos/mdls/qksh.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/mdls/qksh.nix')
-rw-r--r--nixos/mdls/qksh.nix237
1 files changed, 209 insertions, 28 deletions
diff --git a/nixos/mdls/qksh.nix b/nixos/mdls/qksh.nix
index 3d521eb..87f57fc 100644
--- a/nixos/mdls/qksh.nix
+++ b/nixos/mdls/qksh.nix
@@ -46,6 +46,7 @@
}
ListModel { id: notifModel }
+ ListModel { id: mixerModel }
PanelWindow {
id: root
@@ -61,7 +62,9 @@
property var launcherTopApp: null
property string sysStats: "cpu --% | mem --%"
- property string audioVol: "vol: --%"
+ property string audioVol: "󰕿"
+ property string micState: "󰍬"
+ property string mixerBuf: ""
function removeNotif(nid) {
for (let i = 0; i < notifModel.count; i++) {
@@ -154,7 +157,7 @@
]
property var masterBarItems: [{ label: "position", sub: "barPosition" }, { label: "layout", sub: "barLayout" }, { label: "mode", sub: "barMode" }, { label: "look", sub: "barLook" }]
property var masterBarPositionItems: [{ label: "top", barPos: "top" }, { label: "bottom", barPos: "bottom" }]
- property var masterBarLayoutItems: [{ label: "minimal", barLyt: "minimal" }, { label: "full", barLyt: "full" }]
+ property var masterBarLayoutItems: [{ label: "minimal", barLyt: "minimal" }]
property var masterBarModeItems: [{ label: "performance", centerLyt: "performance" }, { label: "default", centerLyt: "default" }]
property var masterBarLookItems: [{ label: "float", barLook: "float" }, { label: "fill", barLook: "fill" }]
property var masterWpItems: []
@@ -243,13 +246,17 @@
}
onActiveModeChanged: {
- if (activeMode !== "none" && activeMode !== "calendar" && typeof barInput !== "undefined") {
+ if (activeMode !== "none" && activeMode !== "calendar" && activeMode !== "mixer" && typeof barInput !== "undefined") {
barInput.text = ""
barInput.forceActiveFocus()
}
+ if (activeMode === "mixer") {
+ root.mixerBuf = ""
+ mixerListProc.running = true
+ }
}
- WlrLayershell.keyboardFocus: activeMode !== "none" && activeMode !== "calendar" ? WlrLayershell.Exclusive : WlrLayershell.None
+ WlrLayershell.keyboardFocus: activeMode !== "none" && activeMode !== "calendar" && activeMode !== "mixer" ? WlrLayershell.Exclusive : WlrLayershell.None
anchors.top: position === "top"
anchors.bottom: position === "bottom"
@@ -329,6 +336,8 @@
onTriggered: {
if (barSettings.centerMode === "performance" && !sysProc.running) sysProc.running = true
if (!audioProc.running) audioProc.running = true
+ if (!micProc.running) micProc.running = true
+ if (root.activeMode === "mixer" && !mixerListProc.running) mixerListProc.running = true
}
}
@@ -343,10 +352,52 @@
Process {
id: audioProc
- command: ["sh", "-c", "wpctl get-volume @DEFAULT_AUDIO_SINK@ | awk '{print int($2*100)\"%\" ($3==\"[MUTED]\"?\" (m)\":\"\")}'"]
+ command: ["sh", "-c", "${pkgs.wireplumber}/bin/wpctl get-volume @DEFAULT_AUDIO_SINK@ | awk '{v=int($2*100); if(v>100)v=100; if($3==\"[MUTED]\") print \"󰕿\"; else if(v<=33) print \"󰕿\"; else if(v<=66) print \"󰖀\"; else print \"󰕾\"}'"]
+ running: false
+ stdout: SplitParser {
+ onRead: data => { root.audioVol = data.trim() }
+ }
+ }
+
+ Process {
+ id: micProc
+ command: ["sh", "-c", "${pkgs.wireplumber}/bin/wpctl get-volume @DEFAULT_AUDIO_SOURCE@ | awk '{print ($3==\"[MUTED]\"?\"󰍭\":\"󰍬\")}'"]
running: false
stdout: SplitParser {
- onRead: data => { root.audioVol = "vol: " + data.trim() }
+ onRead: data => { root.micState = data.trim() }
+ }
+ }
+
+ Process {
+ id: mixerListProc
+ command: ["${pkgs.pulseaudio}/bin/pactl", "-f", "json", "list", "sink-inputs"]
+ running: false
+ stdout: SplitParser {
+ splitMarker: ""
+ onRead: data => { root.mixerBuf += data }
+ }
+ onRunningChanged: {
+ if (!running && root.mixerBuf !== "") {
+ try {
+ let apps = JSON.parse(root.mixerBuf)
+ mixerModel.clear()
+ if (Array.isArray(apps)) {
+ apps.forEach(app => {
+ let name = app.properties["application.name"] || app.properties["media.name"] || "unknown"
+ let vol = "0%"
+ if (app.volume && app.volume["front-left"]) {
+ vol = app.volume["front-left"].value_percent
+ }
+ mixerModel.append({
+ idx: app.index,
+ name: name.toLowerCase(),
+ volume: vol
+ })
+ })
+ }
+ } catch(e) {}
+ root.mixerBuf = ""
+ }
}
}
@@ -356,6 +407,18 @@
onRunningChanged: if (!running) audioProc.running = true
}
+ Process {
+ id: micActProc
+ running: false
+ onRunningChanged: if (!running) micProc.running = true
+ }
+
+ Process {
+ id: mixerActProc
+ running: false
+ onRunningChanged: if (!running) mixerListProc.running = true
+ }
+
FontMetrics {
id: fm
font.family: "JetBrainsMono Nerd Font"
@@ -369,7 +432,7 @@
Text {
anchors.centerIn: parent
- visible: root.activeMode === "none" || root.activeMode === "calendar"
+ visible: root.activeMode === "none" || root.activeMode === "calendar" || root.activeMode === "mixer"
font.family: "JetBrainsMono Nerd Font"
font.pixelSize: 12
font.weight: Font.Normal
@@ -501,29 +564,70 @@
Item {
Layout.fillHeight: true
- implicitWidth: audioText.implicitWidth + 20
- Text {
- id: audioText
+ implicitWidth: 46
+
+ Row {
anchors.centerIn: parent
- font.family: "JetBrainsMono Nerd Font"
- font.pixelSize: 12
- renderType: Text.NativeRendering
- color: "#aaaaaa"
- text: root.audioVol
- }
- MouseArea {
- anchors.fill: parent
- onClicked: {
- volActProc.command = ["wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "toggle"]
- volActProc.running = true
+ spacing: 2
+
+ Item {
+ width: 20
+ height: 22
+
+ Text {
+ id: audioText
+ anchors.centerIn: parent
+ font.family: "JetBrainsMono Nerd Font"
+ font.pixelSize: 12
+ renderType: Text.NativeRendering
+ color: "#aaaaaa"
+ text: root.audioVol
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+ onClicked: (mouse) => {
+ if (mouse.button === Qt.RightButton) {
+ volActProc.command = ["${pkgs.wireplumber}/bin/wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "toggle"]
+ volActProc.running = true
+ } else {
+ if (root.activeMode === "mixer") root.activeMode = "none"
+ else root.activeMode = "mixer"
+ }
+ }
+ onWheel: (wheel) => {
+ if (wheel.angleDelta.y > 0) {
+ volActProc.command = ["${pkgs.wireplumber}/bin/wpctl", "set-volume", "-l", "1.0", "@DEFAULT_AUDIO_SINK@", "5%+"]
+ } else {
+ volActProc.command = ["${pkgs.wireplumber}/bin/wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "5%-"]
+ }
+ volActProc.running = true
+ }
+ }
}
- onWheel: (wheel) => {
- if (wheel.angleDelta.y > 0) {
- volActProc.command = ["wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "5%+"]
- } else {
- volActProc.command = ["wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "5%-"]
+
+ Item {
+ width: 20
+ height: 22
+
+ Text {
+ id: micText
+ anchors.centerIn: parent
+ font.family: "JetBrainsMono Nerd Font"
+ font.pixelSize: 12
+ renderType: Text.NativeRendering
+ color: "#aaaaaa"
+ text: root.micState
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ micActProc.command = ["${pkgs.wireplumber}/bin/wpctl", "set-mute", "@DEFAULT_AUDIO_SOURCE@", "toggle"]
+ micActProc.running = true
+ }
}
- volActProc.running = true
}
}
}
@@ -566,6 +670,83 @@
}
PanelWindow {
+ id: mixerOverlay
+ visible: root.activeMode === "mixer"
+
+ screen: Quickshell.screens.find(s => s.name === "HDMI-A-1") ?? Quickshell.screens[0]
+
+ anchors.top: root.position === "top"
+ anchors.bottom: root.position === "bottom"
+ anchors.right: true
+
+ margins.top: root.position === "top" ? (root.look === "fill" ? 0 : 6) : 0
+ margins.bottom: root.position === "bottom" ? (root.look === "fill" ? 0 : 6) : 0
+ margins.right: root.look === "fill" ? 0 : root.layout === "full" ? 6 : Math.round(((root.screen?.width ?? 1920) - 820) / 2) + 46
+
+ implicitWidth: 200
+ implicitHeight: Math.max(22, mixerModel.count * 22)
+ color: "transparent"
+
+ WlrLayershell.layer: WlrLayershell.Overlay
+
+ Rectangle {
+ anchors.fill: parent
+ color: "#1c1c1c"
+ border.color: "#3c3c3c"
+ border.width: 1
+
+ Column {
+ width: parent.width
+
+ Repeater {
+ model: mixerModel
+
+ Rectangle {
+ width: parent.width
+ height: 22
+ color: "transparent"
+
+ Text {
+ anchors.left: parent.left
+ anchors.leftMargin: 8
+ anchors.verticalCenter: parent.verticalCenter
+ width: 130
+ elide: Text.ElideRight
+ text: model.name
+ font.family: "JetBrainsMono Nerd Font"
+ font.pixelSize: 12
+ color: "#aaaaaa"
+ }
+
+ Text {
+ anchors.right: parent.right
+ anchors.rightMargin: 8
+ anchors.verticalCenter: parent.verticalCenter
+ text: model.volume
+ font.family: "JetBrainsMono Nerd Font"
+ font.pixelSize: 12
+ color: "#c0c0c0"
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onWheel: (wheel) => {
+ let cur = parseInt(model.volume)
+ if (wheel.angleDelta.y > 0) {
+ mixerActProc.command = ["${pkgs.pulseaudio}/bin/pactl", "set-sink-input-volume", model.idx, Math.min(100, cur + 5) + "%"]
+ } else {
+ mixerActProc.command = ["${pkgs.pulseaudio}/bin/pactl", "set-sink-input-volume", model.idx, Math.max(0, cur - 5) + "%"]
+ }
+ mixerActProc.running = true
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ PanelWindow {
id: masterOverlay
visible: root.activeMode === "master" && root.masterFiltered.length > 0
@@ -677,7 +858,7 @@
margins.top: root.position === "top" ? (root.look === "fill" ? 0 : 6) : 0
margins.bottom: root.position === "bottom" ? (root.look === "fill" ? 0 : 6) : 0
- implicitWidth: Math.round(root.implicitWidth / 3)
+ implicitWidth: Make.round(root.implicitWidth / 3)
implicitHeight: notifModel.count * 34
exclusiveZone: 0