diff options
| author | caley <u65487754@gmail.com> | 2026-06-24 00:20:07 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-06-24 00:20:07 +0200 |
| commit | c28d0cf062d3a7cfb261f3ef9b3f8e30ab723961 (patch) | |
| tree | 395f29045b0cce8c42d645e869a6fdaf65d38cba /nixos | |
| parent | 4bd499ec6ec59ff1f87e6e3c42addce14d200096 (diff) | |
Update qksh.nix
Diffstat (limited to 'nixos')
| -rw-r--r-- | nixos/mdls/qksh.nix | 237 |
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 |
