aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Schanzenbacher <ryan@rschanz.org>2026-07-09 23:28:49 -0400
committerRyan Schanzenbacher <ryan@rschanz.org>2026-07-09 23:28:49 -0400
commit36e5025868cfd674ef4f8a0ae0529371d6581572 (patch)
tree207eab51f636a157e562afca623668eec0f35630
parent8c57a511a35702ddf354f3cb52e04228a36bee82 (diff)
hammerspoon listener pt 1
-rw-r--r--hosts/RyanMac/configuration.nix1
-rw-r--r--users/ryan/hammerspoon/init.lua35
-rw-r--r--users/ryan/home.nix3
-rwxr-xr-xusers/ryan/modules/simple-bar/simple-bar-source/lib/components/data/sound.jsx2
4 files changed, 40 insertions, 1 deletions
diff --git a/hosts/RyanMac/configuration.nix b/hosts/RyanMac/configuration.nix
index 088b774..19ffeec 100644
--- a/hosts/RyanMac/configuration.nix
+++ b/hosts/RyanMac/configuration.nix
@@ -179,6 +179,7 @@ in {
179 "tailscale-app" 179 "tailscale-app"
180 "netbird-ui" 180 "netbird-ui"
181 "ubersicht" 181 "ubersicht"
182 "hammerspoon"
182 ]; 183 ];
183 }; 184 };
184 185
diff --git a/users/ryan/hammerspoon/init.lua b/users/ryan/hammerspoon/init.lua
new file mode 100644
index 0000000..1245a09
--- /dev/null
+++ b/users/ryan/hammerspoon/init.lua
@@ -0,0 +1,35 @@
1-- ~/.hammerspoon/init.lua
2
3local function refreshWidget()
4 hs.http.asyncGet("http://127.0.0.1:7776/widget/sound/refresh", nil, function(status, body, headers)
5 -- optional: log failures
6 if status ~= 200 then
7 print("Widget refresh failed with status: " .. tostring(status))
8 end
9 end)
10end
11
12local function audioWatcherCallback(uid, eventName, scope, element)
13 -- "vmvc" = volume changed, "mute" = mute toggled
14 if eventName == "vmvc" or eventName == "mute" then
15 refreshWidget()
16 end
17end
18
19local function setupAudioWatcher()
20 local device = hs.audiodevice.defaultOutputDevice()
21 if device then
22 device:watcherCallback(audioWatcherCallback)
23 device:watcherStart()
24 end
25end
26
27setupAudioWatcher()
28
29-- Re-attach the watcher if the default output device changes (e.g. plugging in headphones)
30hs.audiodevice.watcher.setCallback(function(event)
31 if event == "dOut " then -- note: the trailing space is intentional, it's part of the event name
32 setupAudioWatcher()
33 end
34end)
35hs.audiodevice.watcher.start()
diff --git a/users/ryan/home.nix b/users/ryan/home.nix
index f1c1b32..2aaacb3 100644
--- a/users/ryan/home.nix
+++ b/users/ryan/home.nix
@@ -106,6 +106,9 @@
106 ''; 106 '';
107 }; 107 };
108 108
109 # Add hammerspoon if on mac
110 home.file.".hammerspoon".source = lib.mkIf pkgs.stdenv.isDarwin ./hammerspoon;
111
109 programs.zsh = { 112 programs.zsh = {
110 enable = true; 113 enable = true;
111 initContent = let 114 initContent = let
diff --git a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/sound.jsx b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/sound.jsx
index a3c5cab..3b39594 100755
--- a/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/sound.jsx
+++ b/users/ryan/modules/simple-bar/simple-bar-source/lib/components/data/sound.jsx
@@ -56,7 +56,7 @@ export const Widget = React.memo(() => {
56 if (!visible) return; 56 if (!visible) return;
57 const output = await Utils.cachedRun( 57 const output = await Utils.cachedRun(
58 `osascript -e 'set v to get volume settings' -e 'output volume of v & output muted of v'`, 58 `osascript -e 'set v to get volume settings' -e 'output volume of v & output muted of v'`,
59 refresh, 59 500,
60 ); 60 );
61 const parts = Utils.cleanupOutput(output).split(", "); 61 const parts = Utils.cleanupOutput(output).split(", ");
62 setState({ 62 setState({