diff options
| author | Tim Keller <tjk@tjkeller.xyz> | 2024-10-18 21:49:17 -0500 | 
|---|---|---|
| committer | Tim Keller <tjk@tjkeller.xyz> | 2024-10-18 21:49:17 -0500 | 
| commit | 923eb46350b1102749eb05cd2120c96cc6a715d0 (patch) | |
| tree | 811da20b4195d4b5c65c8ac0090982a4a23f6a7d /widgets/pavolctld.lua | |
| download | awesome-923eb46350b1102749eb05cd2120c96cc6a715d0.tar.xz awesome-923eb46350b1102749eb05cd2120c96cc6a715d0.zip  | |
initial commit
Diffstat (limited to 'widgets/pavolctld.lua')
| -rw-r--r-- | widgets/pavolctld.lua | 104 | 
1 files changed, 104 insertions, 0 deletions
diff --git a/widgets/pavolctld.lua b/widgets/pavolctld.lua new file mode 100644 index 0000000..f59b27f --- /dev/null +++ b/widgets/pavolctld.lua @@ -0,0 +1,104 @@ +local awful = require("awful") +local wibox = require("wibox") +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 + +-- return table +local widget = { +	textbox = wibox.widget.textbox() +} + +-- 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 + +-- 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()) + +		if sink == sinks.default then +			widget.textbox:set_text(sink.vol) +		end +	-- 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) +		widget.textbox:set_text(sinks.default.vol) +		-- set command sink to default sink for now TODO change later +		pavolctld_cmd("s") +	-- sink removed +	elseif cmd == 'x' then +		local x = tonumber(s:sub(2)) +		table.remove(sinks.sinks, x) +	else +		naughty.notify({ +			preset = naughty.config.presets.critical, +			title = "pavolctld error", +			text = s +		}) +	end +end) + +-- pavolctld takes commands in using stdin +function pavolctld_cmd(cmd) +	local _, err = stdin:write_all(cmd .. "\n", nil) + +	if err then return nil end +	return true +end + +function widget.volume_inc(vol) return pavolctld_cmd("v+" .. vol) end +function widget.volume_dec(vol) return pavolctld_cmd("v-" .. vol) end +function widget.volume_set(vol) return pavolctld_cmd("v"  .. vol) end +function widget.mute_set(muted) return pavolctld_cmd("m" .. muted and 1 or 0) end +function widget.mute_toggle()   return pavolctld_cmd("m") end +function widget.default_sink_set(i) return pavolctld_cmd("f" .. i) end + +return widget  | 
