summaryrefslogtreecommitdiff
path: root/widgets/pavolctld.lua
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 /widgets/pavolctld.lua
parent25013359a29e76693e908af1395ae31b0cf15c26 (diff)
downloadawesome-1ad1e4120700148359b271566ca70aed7ae79321.tar.xz
awesome-1ad1e4120700148359b271566ca70aed7ae79321.zip
pavolctld refactor and audio dropdown initial
Diffstat (limited to 'widgets/pavolctld.lua')
-rw-r--r--widgets/pavolctld.lua212
1 files changed, 127 insertions, 85 deletions
diff --git a/widgets/pavolctld.lua b/widgets/pavolctld.lua
index 1c57bb9..3697465 100644
--- a/widgets/pavolctld.lua
+++ b/widgets/pavolctld.lua
@@ -1,105 +1,147 @@
local awful = require("awful")
+local gears = require("gears")
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
+local beautiful = require("beautiful")
+local menubar = require("menubar")
+local pavolctld = require("lib.pavolctld")
-- return table
local widget = {}
widget.textbox = wibox.widget.textbox()
+widget.dbmeter = wibox.widget.textbox()
+widget.vslider = wibox.widget {
+ {
+ {
+ {
+ value = 50,
+ max_value = 150,
+ shape = beautiful.slider_bar_shape,
+ bg = beautiful.slider_handle_color,
+ widget = wibox.widget.progressbar,
+ },
+ height = 5,
+ widget = wibox.container.constraint
+ },
+ halign = "center",
+ widget = wibox.container.place,
+ },
+ {
+ bar_height = 0,
+ widget = wibox.widget.slider,
+ },
+ layout = wibox.layout.stack,
+}
+widget.defsink = wibox.widget.textbox()
widget.tooltip = awful.tooltip { objects = {widget.textbox}, delay_show = 1 }
--- start subprocess
-local p = Gio.Subprocess.new({ "pavolctld" }, Gio.SubprocessFlags.STDIN_PIPE + Gio.SubprocessFlags.STDOUT_PIPE)
+-- widget callbacks
+pavolctld.set_volume_change_callback(function()
+ widget.vslider.value = pavolctld.sinks.default.vol
+ widget.textbox:set_text(pavolctld.sinks.default.vol)
+ widget.dbmeter:set_text(pavolctld.sinks.default.db .. " dB")
+end)
-local stdout = p:get_stdout_pipe()
-local stdin = p:get_stdin_pipe()
+pavolctld.set_sink_change_callback(function()
+ widget.tooltip:set_text(pavolctld.sinks.default.desc)
+end)
--- state vars
-local sinks = {
- default = nil,
- command = nil, -- sink being modified by commands
- sinks = {},
-}
+pavolctld.set_default_sink_change_callback(function()
+ widget.vslider.value = pavolctld.sinks.default.vol
+ widget.textbox:set_text(pavolctld.sinks.default.vol)
+ widget.dbmeter:set_text(pavolctld.sinks.default.db .. " dB")
+ widget.tooltip:set_text(pavolctld.sinks.default.desc)
+ widget.defsink:set_text(pavolctld.sinks.default.desc)
+end)
-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
+-- slider
+widget.vslider.maximum = 150 -- max in pavolctld
+widget.vslider:buttons(volume_buttons)
+widget.vslider:connect_signal("property::value", function()
+ if pavolctld.sinks.default.vol == widget.vslider.value then return end -- help prevent overloading daemon
+ pavolctld.volume_set(widget.vslider.value)
+end)
--- parse output
-function parse_csv(csv)
- return (csv .. ","):gmatch("(.-),")
-end
+-- scrollbox for default sink select
+local default_sink_scrollbox = wibox.widget {
+ widget.defsink,
+ step_function = wibox.container.scroll.step_functions.linear_increase,
+ speed = 25,
+ extra_space = 25, -- space between repetition
+ pause = true, -- start paused
+ widget = wibox.container.scroll.horizontal,
+}
-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())
+-- scroll when hovering
+default_sink_scrollbox:connect_signal("mouse::enter", function()
+ default_sink_scrollbox:continue()
+end)
- 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)
- widget.tooltip:set_text(sinks.default.desc)
- -- 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
+default_sink_scrollbox:connect_signal("mouse::leave", function()
+ default_sink_scrollbox:pause()
+ default_sink_scrollbox:reset_scrolling()
end)
--- pavolctld takes commands in using stdin
-function pavolctld_cmd(cmd)
- local _, err = stdin:write_all(cmd .. "\n", nil)
+-- widget dropdown
+local volume_dropdown = wibox.widget {
+ {
+ {
+ {
+ default_sink_scrollbox,
+ margins = 5,
+ widget = wibox.container.margin,
+ },
+ bg = "#333333",
+ widget = wibox.container.background,
+ },
+ margins = beautiful.border_width,
+ color = "#222222",
+ widget = wibox.container.margin,
+ },
+ {
+ {
+ text = "M",
+ widget = wibox.widget.textbox,
+ },
+ {
+ widget.vslider,
+ left = 10,
+ right = 10,
+ widget = wibox.container.margin,
+ layout = wibox.layout.stack,
+ },
+ {
+ widget.dbmeter,
+ forced_width = 125,
+ halign = "right",
+ widget = wibox.container.place,
+ },
+ layout = wibox.layout.align.horizontal,
+ },
+ forced_num_cols = 1,
+ forced_num_rows = 2,
+ expand = true,
+ forced_width = 500,
+ forced_height = 100,
+ layout = wibox.layout.grid,
+}
+widget.dropdown = awful.popup {
+ widget = {
+ volume_dropdown,
+ margins = 15,
+ widget = wibox.container.margin,
+ },
+ border_color = beautiful.border_focus,
+ border_width = beautiful.border_width,
+ shape = gears.shape.rounded_rect,
+ ontop = true,
+ hide_on_right_click = true,
+ preferred_positions = "bottom",
+ preferred_anchors = 'back',
+ visible = false,
+ offset = { y = 5 },
+}
- if err then return nil end
- return true
-end
+widget.dropdown:bind_to_widget(widget.textbox)
-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