summaryrefslogtreecommitdiff
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
parent25013359a29e76693e908af1395ae31b0cf15c26 (diff)
downloadawesome-1ad1e4120700148359b271566ca70aed7ae79321.tar.xz
awesome-1ad1e4120700148359b271566ca70aed7ae79321.zip
pavolctld refactor and audio dropdown initial
-rw-r--r--buttons.lua10
-rw-r--r--keybindings.lua54
-rw-r--r--lib/pavolctld.lua107
-rw-r--r--theme.lua16
-rw-r--r--widgets/audio.lua21
-rw-r--r--widgets/pavolctld.lua212
6 files changed, 285 insertions, 135 deletions
diff --git a/buttons.lua b/buttons.lua
index 8b4a867..ff87aae 100644
--- a/buttons.lua
+++ b/buttons.lua
@@ -1,6 +1,6 @@
local awful = require("awful")
local gears = require("gears")
-local volume_control = require("widgets.pavolctld")
+local pavolctld = require("lib.pavolctld")
local super = "Mod4"
local alt = "Mod1"
@@ -22,7 +22,8 @@ client_buttons = gears.table.join(
-- wibar widgets
layout_buttons = gears.table.join(
- awful.button({ }, 1, function() awful.layout.inc(1, awful.screen.focused().tags[0]) end)
+ awful.button({ }, 1, function() awful.layout.inc(1, awful.screen.focused().tags[0]) end),
+ awful.button({ }, 2, function() if client.focus and not client.focus.prevent_kill then client.focus:kill() end end)
)
taglist_buttons = gears.table.join(
@@ -42,7 +43,6 @@ tasklist_buttons = gears.table.join(
)
volume_buttons = gears.table.join(
- awful.button({ }, 4, function() volume_control.volume_inc(5) end),
- awful.button({ }, 5, function() volume_control.volume_dec(5) end)
+ awful.button({ }, 4, function() pavolctld.volume_inc(5) end),
+ awful.button({ }, 5, function() pavolctld.volume_dec(5) end)
)
-
diff --git a/keybindings.lua b/keybindings.lua
index 9800bbd..e731788 100644
--- a/keybindings.lua
+++ b/keybindings.lua
@@ -2,6 +2,7 @@ local awful = require("awful")
local gears = require("gears")
local hotkeys_popup = require("awful.hotkeys_popup")
local menubar = require("menubar")
+local pavolctld = require("lib.pavolctld")
-- Enable hotkeys help widget for VIM and other apps
-- when client with a matching name is opened:
-- require("awful.hotkeys_popup.keys")
@@ -45,7 +46,7 @@ globalkeys = gears.table.join(
key(w , "F10", awesome.restart , { group = "awesome" , description = "reload awesome" }),
key(ws, "F10", awesome.quit , { group = "awesome" , description = "quit awesome" }),
key(w , "Tab", awful.tag.history.restore , { group = "tag" , description = "go back" }),
- --
+ -- Window Management
key(w , "j", function () awful.client.focus.byidx( 1) end, { group = "client" , description = "focus next by index" }),
key(w , "k", function () awful.client.focus.byidx(-1) end, { group = "client" , description = "focus previous by index" }),
key(ws, "j", function () awful.client.swap.byidx( 1) end, { group = "client" , description = "swap with next client by index" }),
@@ -73,24 +74,23 @@ globalkeys = gears.table.join(
key(w , "F12", function () awful.spawn("shutdownprompt Shutdown") end, { group = "system" , description = "shutdown system" }),
key(a , "m", function () awful.spawn("mounter -m") end, { group = "system" , description = "mount drive prompt" }),
key(as, "m", function () awful.spawn("mounter -u") end, { group = "system" , description = "unmount drive prompt" }),
- key(w , "F5", function () awful.spawn("bl set 0") end, { group = "system" , description = "set brightness to 0%" }),
- key(w , "F6", function () awful.spawn("bl set 25") end, { group = "system" , description = "set brightness to 25%" }),
- key(w , "F7", function () awful.spawn("bl set 50") end, { group = "system" , description = "set brightness to 50%" }),
- key(w , "F8", function () awful.spawn("bl set 100") end, { group = "system" , description = "set brightness to 100%" }),
-- Screenshots
key({}, "Print", function () awful.spawn("screenshot -x") end, { group = "misc" , description = "screenshot, copy to clipboard" }),
key(a , "Print", function () awful.spawn("screenshot -xc") end, { group = "misc" , description = "screenshot, crop, copy to clipboard" }),
key(w , "Print", function () awful.spawn("screenshot") end, { group = "misc" , description = "screenshot, save to screenshots dir" }),
- key(wa, "Print", function () awful.spawn("screenshot -c") end, { group = "misc" , description = "screenshot, crop, save to screenshots dir" })
+ key(wa, "Print", function () awful.spawn("screenshot -c") end, { group = "misc" , description = "screenshot, crop, save to screenshots dir" }),
+ -- Monitor Controls
+ key(w , "F5", function () awful.spawn("bl set 0") end, { group = "monitor" , description = "set monitor brightness to 0%" }),
+ key(w , "F6", function () awful.spawn("bl set 25") end, { group = "monitor" , description = "set monitor brightness to 25%" }),
+ key(w , "F7", function () awful.spawn("bl set 50") end, { group = "monitor" , description = "set monitor brightness to 50%" }),
+ key(w , "F8", function () awful.spawn("bl set 100") end, { group = "monitor" , description = "set monitor brightness to 100%" }),
+ key({}, "XF86MonBrightnessUp", function () awful.spawn("bl inc 10") end, { group = "monitor" , description = "increase monitor brightness by 10%" }),
+ key({}, "XF86MonBrightnessDown", function () awful.spawn("bl dec 10") end, { group = "monitor" , description = "decrease monitor brightness by 10%" }),
+ -- Volume Controls
+ key({}, "XF86AudioRaiseVolume", function () pavolctld.volume_inc(5) end, { group = "volume" , description = "increase volume by 5%" }),
+ key({}, "XF86AudioLowerVolume", function () pavolctld.volume_dec(5) end, { group = "volume" , description = "decrease volume by 5%" }),
+ key({}, "XF86AudioMute", pavolctld.mute_toggle , { group = "volume" , description = "toggle audio mute" })
)
---Audio Raise Volume Increase volume
---Audio Lower Volume Decrease volume
---Audio Mute Toggle mute
---Backlight Controls:
---Mon Brightness Up Increase brightness
---Mon Brightness Down Decrease brightness
---Alt + Mon Brightness Up Increase brightness by half-step
---Alt + Mon Brightness Down Decrease brightness by half-step
-- Client protection
@@ -104,20 +104,30 @@ local function unProtectClient(c)
c.screen:emit_signal("arrange")
end
local function killClient(c)
- if c.prevent_kill == nil or not c.prevent_kill then
+ if not c.prevent_kill then
c:kill()
end
end
+-- Client swap with master (more similar to dwm)
+local function masterswap(c)
+ local m = awful.client.getmaster()
+ if m ~= c then
+ c:swap(awful.client.getmaster())
+ else
+ c:swap(awful.client.next(1, c))
+ end
+end
+
-- Client keys
clientkeys = gears.table.join(
- key(w , "q", killClient , { description = "close", group = "client" }),
- key(w , "x", protectClient , { description = "close", group = "client" }),
- key(ws, "x", unProtectClient , { description = "close", group = "client" }),
- key(wc, "space", awful.client.floating.toggle , { description = "toggle floating", group = "client" }),
- key(w , "Return", function (c) c:swap(awful.client.getmaster()) end, { description = "move to master", group = "client" }),
- key(ws, ",", function (c) c:move_to_screen(c.screen.index - 1) end, { description = "move to previous screen", group = "client" }),
- key(ws, ",", function (c) c:move_to_screen(c.screen.index + 1) end, { description = "move to next screen", group = "client" })
+ key(w , "q", killClient , { description = "close", group = "client" }),
+ key(w , "x", protectClient , { description = "prevent closing", group = "client" }),
+ key(ws, "x", unProtectClient , { description = "allow closing", group = "client" }),
+ key(wc, "space", awful.client.floating.toggle , { description = "toggle floating", group = "client" }),
+ key(w , "Return", masterswap , { description = "move to master", group = "client" }),
+ key(ws, ",", function (c) c:move_to_screen(c.screen.index - 1) end, { description = "move to left screen", group = "client" }),
+ key(ws, ".", function (c) c:move_to_screen() end, { description = "move to right screen", group = "client" })
)
-- Bind all key numbers to tags.
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
diff --git a/theme.lua b/theme.lua
index 9393030..6df5649 100644
--- a/theme.lua
+++ b/theme.lua
@@ -16,14 +16,14 @@ beautiful.gap_single_client = false
-- overrides
beautiful.tasklist_font_focus = beautiful.font -- prevent bold
-beautiful.wibar_height = math.floor(beautiful.get_font_height(beautiful.font) * 1.1)
+beautiful.wibar_height = math.floor(beautiful.get_font_height(beautiful.font) * 1.15)
beautiful.wibar_bg = darkgray
--beautiful.layoutlist_font = "Monospace 8"
--beautiful.font = "Tamzen 10"
--beautiful.tasklist_align = "center" -- does nothing?
beautiful.font_sans = beautiful.font
-beautiful.font_mono = "CommitMono 10"
+beautiful.font_mono = "monospace 10"
beautiful.font = beautiful.font_mono
--beautiful.layoutlist_font = beautiful.font_mono
@@ -41,6 +41,18 @@ beautiful.hotkeys_label_fg = white
beautiful.hotkeys_modifiers_fg = lightgray
beautiful.hotkeys_label_bg = darkgray -- ???
+-- slider
+beautiful.slider_bar_height = 5
+beautiful.slider_bar_shape = gears.shape.rounded_rect
+beautiful.slider_handle_width = 17.5
+beautiful.slider_handle_shape = gears.shape.circle
+beautiful.slider_handle_color = beautiful.border_color
+beautiful.slider_handle_border_color = "#333333"
+beautiful.slider_handle_border_width = 1
+
+-- progressbar
+beautiful.progressbar_fg = beautiful.border_focus
+
-- set border on clients
client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
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