vincentbernat.i3wm-configur.../rc/widgets.lua
Vincent Bernat 853760b466 widgets: let clock update every two seconds
Most widgets are updated every two seconds. This is stupid to not
update the clock too. It would be better to update it at the next
minute but we would need to handle the timers ourselves.
2021-04-07 08:48:58 +02:00

322 lines
11 KiB
Lua

-- Widgets
require("vicious")
local icons = loadrc("icons", "vbe/icons")
-- Separators
local sepopen = widget({ type = "imagebox" })
sepopen.image = image(beautiful.icons .. "/widgets/left.png")
local sepclose = widget({ type = "imagebox" })
sepclose.image = image(beautiful.icons .. "/widgets/right.png")
local spacer = widget({ type = "imagebox" })
spacer.image = image(beautiful.icons .. "/widgets/spacer.png")
-- Date
local datewidget = widget({ type = "textbox" })
local dateformat = "%a %d/%m, %H:%M"
vicious.register(datewidget, vicious.widgets.date,
'<span color="' .. beautiful.fg_widget_clock .. '">' ..
dateformat .. '</span>')
local dateicon = widget({ type = "imagebox" })
dateicon.image = image(beautiful.icons .. "/widgets/clock.png")
local cal = (
function()
local calendar = nil
local offset = 0
local remove_calendar = function()
if calendar ~= nil then
naughty.destroy(calendar)
calendar = nil
offset = 0
end
end
local add_calendar = function(inc_offset)
local save_offset = offset
remove_calendar()
offset = save_offset + inc_offset
local curdate = os.date("*t")
local datespec = curdate.year * 12 + curdate.month - 1 + offset
datespec = (datespec % 12 + 1) .. " " .. math.floor(datespec / 12)
local cal = awful.util.pread("ncal -h -w -m " .. datespec)
-- Highlight the current date and month
if offset == 0 then
cal, n = cal:gsub(string.format("( %d)([ \n])", curdate.day),
string.format('<span color="%s">%%1</span>%%2',
beautiful.fg_widget_clock),
1)
end
-- Month and year
cal = cal:gsub("^( +[^ ]+ [0-9]+) *",
string.format('<span color="%s">%%1</span>',
beautiful.fg_widget_clock))
-- Turn anything other than days in labels
cal = cal:gsub("(\n[^%d ]+)",
string.format('<span color="%s">%%1</span>',
beautiful.fg_widget_label))
cal = cal:gsub("([%d ]+)\n?$",
string.format('<span color="%s">%%1</span>',
beautiful.fg_widget_label))
calendar = naughty.notify(
{
text = string.format('<span font="%s">%s</span>',
theme.font,
cal:gsub(" +\n","\n")),
timeout = 0, hover_timeout = 0.5,
width = 160 * theme.scale,
screen = mouse.screen,
})
end
return { add = add_calendar,
rem = remove_calendar }
end)()
datewidget:add_signal("mouse::enter", function() cal.add(0) end)
datewidget:add_signal("mouse::leave", cal.rem)
datewidget:buttons(awful.util.table.join(
awful.button({ }, 3, function() cal.add(-1) end),
awful.button({ }, 1, function() cal.add(1) end)))
-- CPU usage
local cpuwidget = widget({ type = "textbox" })
vicious.register(cpuwidget, vicious.widgets.cpu,
function (widget, args)
return string.format('<span color="' .. beautiful.fg_widget_value .. '">%2d%%</span>',
args[1])
end, 7)
local cpuicon = widget({ type = "imagebox" })
cpuicon.image = image(beautiful.icons .. "/widgets/cpu.png")
-- Battery
local batwidget = { widget = "" }
if awful.util.table.hasitem({"guybrush", "zoro"}, config.hostname) then
local bat = "BAT0"
batwidget.widget = widget({ type = "textbox" })
vicious.register(batwidget.widget, vicious.widgets.bat,
function (widget, args)
local color = beautiful.fg_widget_value
local current = args[2]
if current < 10 and args[1] == "-" then
color = beautiful.fg_widget_value_important
-- Maybe we want to display a small warning?
if current ~= batwidget.lastwarn then
batwidget.lastid = naughty.notify(
{ title = "Battery low!",
preset = naughty.config.presets.critical,
timeout = 20,
text = "Battery level is currently " ..
current .. "%.\n" .. args[3] ..
" left before running out of power.",
icon = icons.lookup({name = "battery-caution",
type = "status"}),
replaces_id = batwidget.lastid }).id
batwidget.lastwarn = current
end
end
return string.format('<span color="' .. color ..
'">%s%d%%</span>', args[1], current)
end,
59, bat)
end
local baticon = widget({ type = "imagebox" })
baticon.image = image(beautiful.icons .. "/widgets/bat.png")
-- Network
local netup = widget({ type = "textbox" })
local netdown = widget({ type = "textbox" })
local netupicon = widget({ type = "imagebox" })
netupicon.image = image(beautiful.icons .. "/widgets/up.png")
local netdownicon = widget({ type = "imagebox" })
netdownicon.image = image(beautiful.icons .. "/widgets/down.png")
local netgraph = awful.widget.graph()
netgraph:set_width(80 * theme.scale):set_height(16 * theme.scale)
netgraph:set_stack(true):set_scale(true)
netgraph:set_border_color(beautiful.fg_widget_border)
netgraph:set_stack_colors({ "#EF8171", "#cfefb3" })
netgraph:set_background_color("#00000033")
vicious.register(netup, vicious.widgets.net,
function (widget, args)
-- We sum up/down value for all interfaces
local up = 0
local down = 0
local iface
for name, value in pairs(args) do
iface = name:match("^{(%S+) down_b}$")
if iface and iface ~= "lo" then down = down + value end
iface = name:match("^{(%S+) up_b}$")
if iface and iface ~= "lo" then up = up + value end
end
-- Update the graph
netgraph:add_value(up, 1)
netgraph:add_value(down, 2)
-- Format the string representation
local format = function(val)
if val > 500000 then
return string.format("%.1f MB", val/1000000.)
elseif val > 500 then
return string.format("%.1f KB", val/1000.)
end
return string.format("%d B", val)
end
-- Down
netdown.text = string.format('<span color="' .. beautiful.fg_widget_value ..
'">%08s</span>', format(down))
-- Up
return string.format('<span color="' .. beautiful.fg_widget_value ..
'">%08s</span>', format(up))
end, 3)
-- Memory usage
local memwidget = widget({ type = "textbox" })
vicious.register(memwidget, vicious.widgets.mem,
'<span color="' .. beautiful.fg_widget_value .. '">$1%</span>',
19)
local memicon = widget({ type = "imagebox" })
memicon.image = image(beautiful.icons .. "/widgets/mem.png")
-- Volume level
local volwidget = widget({ type = "textbox" })
vicious.register(volwidget, vicious.widgets.volume,
'<span color="' .. beautiful.fg_widget_value .. '">$2 $1%</span>',
17, "-D pulse Master")
volume = loadrc("volume", "vbe/volume")
volwidget:buttons(awful.util.table.join(
awful.button({ }, 1, volume.mixer),
awful.button({ }, 3, function() volume.toggle("Master") end),
awful.button({ }, 4, function() volume.increase("Master") end),
awful.button({ }, 5, function() volume.decrease("Master") end)))
-- File systems
local fs = { "/",
"/home",
"/var",
"/usr",
"/tmp",
"/var/lib/systems" }
local fsicon = widget({ type = "imagebox" })
fsicon.image = image(beautiful.icons .. "/widgets/disk.png")
local fswidget = widget({ type = "textbox" })
vicious.register(fswidget, vicious.widgets.fs,
function (widget, args)
local result = ""
for _, path in pairs(fs) do
local used = args["{" .. path .. " used_p}"]
local color = beautiful.fg_widget_value
if used then
if used > 90 then
color = beautiful.fg_widget_value_important
end
local name = string.gsub(path, "[%w/]*/(%w+)", "%1")
if name == "/" then name = "root" end
result = string.format(
'%s%s<span color="' .. beautiful.fg_widget_label .. '">%s: </span>' ..
'<span color="' .. color .. '">%2d%%</span>',
result, #result > 0 and " " or "", name, used)
end
end
return result
end, 53, "-lx fuse -x aufs")
local notifications = widget({ type = "imagebox" })
notifications.image = image(beautiful.icons .. "/widgets/notifications-enabled.png")
notifications:buttons(awful.util.table.join(
awful.button({ }, 1,
function()
local state = "enabled"
naughty.toggle()
if naughty.is_suspended() then
state = "disabled"
end
notifications.image = image(beautiful.icons .. "/widgets/notifications-" .. state .. ".png")
end)))
local systray = widget({ type = "systray" })
-- Wibox initialisation
local wibox = {}
local promptbox = {}
local layoutbox = {}
local taglist = {}
local tasklist = {}
tasklist.buttons = awful.util.table.join(
awful.button({ }, 1, function (c)
if c == client.focus then
c.minimized = true
else
if not c:isvisible() then
awful.tag.viewonly(c:tags()[1])
end
-- This will also un-minimize
-- the client, if needed
client.focus = c
c:raise()
end
end))
for s = 1, screen.count() do
promptbox[s] = awful.widget.prompt({ layout = awful.widget.layout.horizontal.leftright })
layoutbox[s] = awful.widget.layoutbox(s)
tasklist[s] = awful.widget.tasklist(
function(c)
local title, color, _, icon = awful.widget.tasklist.label.currenttags(c, s)
return title, color, nil, icon
end, tasklist.buttons)
-- Create the taglist
taglist[s] = awful.widget.taglist.new(s,
awful.widget.taglist.label.all)
-- Create the wibox
wibox[s] = awful.wibox({ screen = s,
fg = beautiful.fg_normal,
bg = beautiful.bg_widget,
position = "top",
height = 16 * theme.scale,
})
-- Add widgets to the wibox
local on = function(n, what)
if s == n or n > screen.count() then return what end
return ""
end
wibox[s].widgets = {
{
screen.count() > 1 and sepopen or "",
taglist[s],
screen.count() > 1 and spacer or "",
layoutbox[s],
screen.count() > 1 and sepclose or "",
promptbox[s],
layout = awful.widget.layout.horizontal.leftright
},
on(1, systray),
on(1, notifications),
sepclose, datewidget, screen.count() > 1 and dateicon or "", spacer,
on(2, volwidget), on(2, spacer),
on(2, batwidget.widget),
on(2, batwidget.widget ~= "" and baticon or ""),
on(2, batwidget.widget ~= "" and spacer or ""),
on(2, fswidget), screen.count() > 1 and on(2, fsicon) or "",
screen.count() > 1 and on(2, sepopen) or on(2, spacer),
screen.count() > 1 and on(1, netgraph.widget) or "",
on(1, netdownicon), on(1, netdown),
on(1, netupicon), on(1, netup), on(1, spacer),
on(1, memwidget), on(1, memicon), on(1, spacer),
on(1, cpuwidget), on(1, cpuicon), on(1, sepopen),
tasklist[s],
layout = awful.widget.layout.horizontal.rightleft }
end
config.keys.global = awful.util.table.join(
config.keys.global,
awful.key({ modkey }, "r", function () promptbox[mouse.screen]:run() end,
"Prompt for a command"))
config.taglist = taglist