From 9fab3828698199718a3d2f2faf8826f77d9258f7 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Tue, 9 Sep 2025 21:40:07 +0200 Subject: ... --- accounts/gkleen@sif/niri/default.nix | 39 ++++++++------- accounts/gkleen@sif/shell/quickshell/UnixIPC.qml | 49 +++++++++++++++++++ accounts/gkleen@sif/shell/quickshell/VolumeOSD.qml | 55 ++++++++++++++++------ accounts/gkleen@sif/shell/quickshell/shell.qml | 2 + 4 files changed, 115 insertions(+), 30 deletions(-) create mode 100644 accounts/gkleen@sif/shell/quickshell/UnixIPC.qml (limited to 'accounts/gkleen@sif') diff --git a/accounts/gkleen@sif/niri/default.nix b/accounts/gkleen@sif/niri/default.nix index e1eca4c4..1ff149bc 100644 --- a/accounts/gkleen@sif/niri/default.nix +++ b/accounts/gkleen@sif/niri/default.nix @@ -947,22 +947,6 @@ in { action = spawn swayosd-client "--brightness" "lower"; allow-when-locked = true; }; - "XF86AudioRaiseVolume" = { - action = spawn swayosd-client "--output-volume" "raise"; - allow-when-locked = true; - }; - "XF86AudioLowerVolume" = { - action = spawn swayosd-client "--output-volume" "lower"; - allow-when-locked = true; - }; - "XF86AudioMute" = { - action = spawn swayosd-client "--output-volume" "mute-toggle"; - allow-when-locked = true; - }; - "XF86AudioMicMute" = { - action = spawn swayosd-client "--input-volume" "mute-toggle"; - allow-when-locked = true; - }; "Mod+Semicolon".action = spawn makoctl "dismiss" "--group"; "Mod+Shift+Semicolon".action = spawn makoctl "dismiss" "--all"; @@ -982,6 +966,29 @@ in { "Mod+K".action = spawn (lib.getExe' pkgs.worktime "worktime-ui"); "Mod+Shift+K".action = spawn (lib.getExe' pkgs.worktime "worktime-stop"); })) + (lib.mapAttrsToList (name: cfg: node name [(lib.removeAttrs cfg ["action"])] [cfg.action]) (let + shell = obj: leaf "send-unix" [ + { path = ''''${XDG_RUNTIME_DIR}/shell.sock''; } + (builtins.toJSON obj + "\n") + ]; + in { + "XF86AudioRaiseVolume" = { + allow-when-locked = true; + action = shell { Volume.volume = "up"; }; + }; + "XF86AudioLowerVolume" = { + allow-when-locked = true; + action = shell { Volume.volume = "down"; }; + }; + "XF86AudioMute" = { + allow-when-locked = true; + action = shell { Volume.muted = "toggle"; }; + }; + "XF86AudioMicMute" = { + allow-when-locked = true; + action = shell { Volume."mic-muted" = "toggle"; }; + }; + })) (map ({ name, selector, spawn, key, ...}: if key != null && selector != null && spawn != null then bind key { action = focus-or-spawn-action selector name spawn; } else null) cfg.scratchspaces) (map ({ name, moveKey, ...}: if moveKey != null then bind moveKey { action = kdl.magic-leaf "move-column-to-workspace" name; } else null) cfg.scratchspaces) ] diff --git a/accounts/gkleen@sif/shell/quickshell/UnixIPC.qml b/accounts/gkleen@sif/shell/quickshell/UnixIPC.qml new file mode 100644 index 00000000..7b308ec0 --- /dev/null +++ b/accounts/gkleen@sif/shell/quickshell/UnixIPC.qml @@ -0,0 +1,49 @@ +import Quickshell +import Quickshell.Io +import Quickshell.Services.Pipewire + +Scope { + id: root + + SocketServer { + active: true + path: `${Quickshell.env("XDG_RUNTIME_DIR")}/shell.sock` + handler: Socket { + parser: SplitParser { + onRead: line => { + try { + const command = JSON.parse(line); + + if (command.Volume) + root.onCommandVolume(command.Volume); + else + console.warn("UnixIPC: Command not handled:", JSON.stringify(command)); + } catch (e) { + console.warn("UnixIPC: Failed to parse command:", line, e); + } + } + } + + onError: e => { + if (e == 1) + return; + console.warn("QLocalSocket::LocalSocketError", e); + } + } + } + + PwObjectTracker { + objects: [ Pipewire.defaultAudioSink, Pipewire.defaultAudioSource ] + } + function onCommandVolume(command) { + if (command.muted === "toggle") + Pipewire.defaultAudioSink.audio.muted = !Pipewire.defaultAudioSink.audio.muted; + if (command.volume === "up") + Pipewire.defaultAudioSink.audio.volume += 0.02; + if (command.volume === "down") + Pipewire.defaultAudioSink.audio.volume -= 0.02; + + if (command["mic-muted"] === "toggle") + Pipewire.defaultAudioSource.audio.muted = !Pipewire.defaultAudioSource.audio.muted; + } +} diff --git a/accounts/gkleen@sif/shell/quickshell/VolumeOSD.qml b/accounts/gkleen@sif/shell/quickshell/VolumeOSD.qml index 02dcf227..16fb5dea 100644 --- a/accounts/gkleen@sif/shell/quickshell/VolumeOSD.qml +++ b/accounts/gkleen@sif/shell/quickshell/VolumeOSD.qml @@ -7,11 +7,11 @@ import Quickshell.Widgets Scope { id: root - property bool show: false + property string show: "" property bool inhibited: true PwObjectTracker { - objects: [ Pipewire.defaultAudioSink ] + objects: [ Pipewire.defaultAudioSink, Pipewire.defaultAudioSource ] } Connections { @@ -19,11 +19,25 @@ Scope { target: Pipewire.defaultAudioSink?.audio function onVolumeChanged() { - root.show = true; + root.show = "sink"; hideTimer.restart(); } function onMutedChanged() { - root.show = true; + root.show = "sink"; + hideTimer.restart(); + } + } + + Connections { + enabled: Pipewire.defaultAudioSource + target: Pipewire.defaultAudioSource?.audio + + function onVolumeChanged() { + root.show = "source"; + hideTimer.restart(); + } + function onMutedChanged() { + root.show = "source"; hideTimer.restart(); } } @@ -36,7 +50,7 @@ Scope { Timer { id: hideTimer interval: 1000 - onTriggered: root.show = false + onTriggered: root.show = "" } Timer { @@ -44,7 +58,7 @@ Scope { interval: 100 running: true onTriggered: { - root.show = false; + root.show = ""; root.inhibited = false; } } @@ -97,13 +111,20 @@ Scope { implicitHeight: parent.height icon: { - if (!Pipewire.defaultAudioSink || Pipewire.defaultAudioSink.audio.muted) - return "volume-off"; - if (Pipewire.defaultAudioSink.audio.volume <= 0.33) - return "volume-low"; - if (Pipewire.defaultAudioSink.audio.volume <= 0.67) - return "volume-medium"; - return "volume-high"; + if (root.show == "sink") { + if (!Pipewire.defaultAudioSink || Pipewire.defaultAudioSink.audio.muted) + return "volume-off"; + if (Pipewire.defaultAudioSink.audio.volume <= 0.33) + return "volume-low"; + if (Pipewire.defaultAudioSink.audio.volume <= 0.67) + return "volume-medium"; + return "volume-high"; + } else if (root.show == "source") { + if (!Pipewire.defaultAudioSource || Pipewire.defaultAudioSource.audio.muted) + return "microphone-off"; + return "microphone"; + } + return "volume-high"; } } @@ -123,7 +144,13 @@ Scope { color: Pipewire.defaultAudioSink?.audio.muted ? "#70ffffff" : "white" - implicitWidth: parent.width * (Pipewire.defaultAudioSink?.audio.volume ?? 0) + implicitWidth: { + if (root.show == "sink") + return parent.width * (Pipewire.defaultAudioSink?.audio.volume ?? 0); + else if (root.show == "source") + return parent.width * (Pipewire.defaultAudioSource?.audio.volume ?? 0); + return 0; + } } } } diff --git a/accounts/gkleen@sif/shell/quickshell/shell.qml b/accounts/gkleen@sif/shell/quickshell/shell.qml index 3657f77f..3bb2ae00 100644 --- a/accounts/gkleen@sif/shell/quickshell/shell.qml +++ b/accounts/gkleen@sif/shell/quickshell/shell.qml @@ -43,4 +43,6 @@ ShellRoot { Lockscreen {} VolumeOSD {} + + UnixIPC {} } -- cgit v1.2.3