From 1ad1e4120700148359b271566ca70aed7ae79321 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Sun, 17 Nov 2024 22:48:47 -0600 Subject: pavolctld refactor and audio dropdown initial --- widgets/audio.lua | 21 ----- widgets/pavolctld.lua | 212 ++++++++++++++++++++++++++++++-------------------- 2 files changed, 127 insertions(+), 106 deletions(-) delete mode 100644 widgets/audio.lua (limited to 'widgets') diff --git a/widgets/audio.lua b/widgets/audio.lua deleted file mode 100644 index 002c556..0000000 --- a/widgets/audio.lua +++ /dev/null @@ -1,21 +0,0 @@ -local awful = require("awful") -local wibox = require("wibox") -local gears = require("gears") - -local audio_dropdown = awful.popup { - widget = { - margins = 10, - widget = wibox.container.margin, - { - layout = wibox.layout.fixed.horizontal, - wibox.widget.textbox "AUDIO", - }, - }, - ontop = true, - placement = awful.placement.centered, - border_width = 1, - border_color = "#ff0000", - visible = true, -} - -return audio_dropdown 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 -- cgit v1.2.3