summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTim Keller <tjkeller.xyz>2024-11-17 22:48:47 -0600
committerTim Keller <tjkeller.xyz>2024-11-17 22:48:47 -0600
commit1ad1e4120700148359b271566ca70aed7ae79321 (patch)
tree8a7955e5d40bcaf51a2ca2044637532dcf850341 /lib
parent25013359a29e76693e908af1395ae31b0cf15c26 (diff)
downloadawesome-1ad1e4120700148359b271566ca70aed7ae79321.tar.xz
awesome-1ad1e4120700148359b271566ca70aed7ae79321.zip
pavolctld refactor and audio dropdown initial
Diffstat (limited to 'lib')
-rw-r--r--lib/pavolctld.lua107
1 files changed, 107 insertions, 0 deletions
diff --git a/lib/pavolctld.lua b/lib/pavolctld.lua
new file mode 100644
index 0000000..b6b6237
--- /dev/null
+++ b/lib/pavolctld.lua
@@ -0,0 +1,107 @@
+local awful = require("awful")
+local naughty = require("naughty")
+
+-- Gio is used to handle the subprocess instead of awful.spawn.
+-- Gio is more flexible and allows writing to stdin.
+-- also, awful.spawn.with_line_callback does not play nicely with pavolctld, as
+-- it seems to feed the stdout back into its stdin and kill performance.
+local lgi = require("lgi")
+local Gio = lgi.Gio
+
+-- start subprocess
+local p = Gio.Subprocess.new({ "pavolctld" }, Gio.SubprocessFlags.STDIN_PIPE + Gio.SubprocessFlags.STDOUT_PIPE)
+
+local stdout = p:get_stdout_pipe()
+local stdin = p:get_stdin_pipe()
+
+-- state vars
+local sinks = {
+ default = nil,
+ command = nil, -- sink being modified by commands
+ sinks = {},
+}
+
+function sinks.get(i)
+ if sinks.sinks[i] == nil then
+ sinks.sinks[i] = {
+ vol = 0,
+ db = 0.0,
+ mute = 0,
+ name = "",
+ desc = "",
+ }
+ end
+ return sinks.sinks[i]
+end
+
+-- return table
+local pavolctld = { _cb = {}, sinks = sinks }
+
+-- callbacks
+function pavolctld.set_volume_change_callback(cb) pavolctld._cb['v'] = cb end
+function pavolctld.set_sink_change_callback(cb) pavolctld._cb['s'] = cb end
+function pavolctld.set_default_sink_change_callback(cb) pavolctld._cb['f'] = cb end
+function pavolctld.set_sink_remove_callback(cb) pavolctld._cb['x'] = cb end
+
+-- parse output
+function parse_csv(csv)
+ return (csv .. ","):gmatch("(.-),")
+end
+
+awful.spawn.read_lines(stdout, function(s)
+ local cmd = s:sub(1, 1) -- first char of output
+ -- volume change
+ if cmd == 'v' then
+ local v = parse_csv(s:sub(2))
+ local i = tonumber(v())
+ local sink = sinks.get(i)
+ sink.vol = tonumber(v())
+ sink.db = tonumber(v())
+ sink.mute = tonumber(v())
+ -- sink description change
+ elseif cmd == 's' then
+ local v = parse_csv(s:sub(2))
+ local i = tonumber(v())
+ local sink = sinks.get(i)
+ sink.name = v()
+ sink.desc = v()
+ -- default sink change
+ elseif cmd == 'f' then
+ local f = tonumber(s:sub(2))
+ sinks.default = sinks.get(f)
+ -- set command sink to default sink for now TODO change later
+ send_cmd("s")
+ -- sink removed
+ elseif cmd == 'x' then
+ local x = tonumber(s:sub(2))
+ table.remove(sinks.sinks, x)
+ -- unrecognized cmd
+ else
+ naughty.notify({
+ preset = naughty.config.presets.critical,
+ title = "pavolctld error",
+ text = s
+ })
+ end
+ -- run command callback
+ if pavolctld._cb[cmd] then
+ pavolctld._cb[cmd]()
+ end
+end)
+
+-- pavolctld takes commands in using stdin
+function send_cmd(cmd)
+ local _, err = stdin:write_all(cmd .. "\n", nil)
+
+ if err then return nil end
+ return true
+end
+
+function pavolctld.volume_inc(vol) return send_cmd("v+" .. vol) end
+function pavolctld.volume_dec(vol) return send_cmd("v-" .. vol) end
+function pavolctld.volume_set(vol) return send_cmd("v" .. vol) end
+function pavolctld.mute_set(muted) return send_cmd("m" .. muted and 1 or 0) end
+function pavolctld.mute_toggle() return send_cmd("m") end
+function pavolctld.default_sink_set(i) return send_cmd("f" .. i) end
+
+return pavolctld