Rewrote battery widget

master
Mark 2022-04-24 09:42:45 -07:00
parent 3a70262d04
commit 38293246e3
Signed by: Mark
GPG Key ID: AD62BB059C2AAEE4
9 changed files with 402 additions and 230 deletions

View File

@ -24,16 +24,6 @@ return {
end, end,
}, },
battery = {
watch = function(timeout, callback, widget)
awful.widget.watch(script_dir .. "battery", timeout, callback, widget)
end,
status = function(callback)
awful.spawn.easy_async(script_dir .. "battery", callback)
end,
},
rofi = { rofi = {
launcher = function() launcher = function()
awful.spawn("rofi -show drun -theme \"" .. bin_dir .. "/rofi/launcher.rasi\"") awful.spawn("rofi -show drun -theme \"" .. bin_dir .. "/rofi/launcher.rasi\"")

View File

@ -0,0 +1,158 @@
local P = {}
function P:set_value(value)
-- Set widget value. (0 - 100)
self.arc.value = value
--[[
if batpec > 60 then
self.progressbar.color = beautiful.color.battery.good
elseif batpec > 40 then
self.progressbar.color = beautiful.color.battery.low
elseif batpec <= 40 then
self.progressbar.color = beautiful.color.battery.danger
end
if (self.state == "discharging") then
self.rotator.direction = "east"
else
self.rotator.direction = "west"
end
if (self.state == "charging") and (value > 90) then
self.progressbar.border_color = beautiful.color.battery.good
elseif (self.state == "discharging") and (value <= 25) then
self.progressbar.border_color = beautiful.color.battery.danger
else
self.rogressbar.border_color = beautiful.color.bar.active
end
--]]
-- Set current battery icon
if (self.state == "charging") then
if value > 80 then self.icon.image = beautiful.icons.battery.charging.full
elseif value > 60 then self.icon.image = beautiful.icons.battery.charging.good
elseif value > 40 then self.icon.image = beautiful.icons.battery.charging.low
elseif value > 20 then self.icon.image = beautiful.icons.battery.charging.caution
elseif value <= 20 then self.icon.image = beautiful.icons.battery.charging.empty end
elseif (self.state == "discharging") then
if value > 80 then self.icon.image = beautiful.icons.battery.full
elseif value > 60 then self.icon.image = beautiful.icons.battery.good
elseif value > 40 then self.icon.image = beautiful.icons.battery.low
elseif value > 20 then self.icon.image = beautiful.icons.battery.caution
elseif value <= 20 then self.icon.image = beautiful.icons.battery.empty end
else
self.icon.image = beautiful.icons.battery.missing
end
end
function P:set_state(state)
if (state == "discharging") then
self.state = "discharging"
elseif (state == "charging") then
self.state = "charging"
elseif (state == "error") then
self.state = "error"
else
error("Invalid state " .. state)
end
end
function P:set_tooltip(text)
-- Set widget value. (0 - 100)
self.tooltip.text = text
end
function P:new()
widget = {
state = "error"
}
setmetatable(widget, self)
self.__index = self
widget.icon = wibox.widget {
image = beautiful.icons.battery.missing,
resize = true,
widget = wibox.widget.imagebox,
}
--[[
widget.progressbar = wibox.widget {
max_value = 100,
widget = wibox.widget.progressbar,
paddings = beautiful.dpi(2),
color = beautiful.color.bar.active,
background_color = beautiful.color.transparent,
border_color = beautiful.color.bar.active,
border_width = beautiful.dpi(1),
margins = beautiful.dpi(3)
}
widget.rotator = wibox.widget {
widget.progressbar,
forced_width = beautiful.dpi(15),
direction = "east",
layout = wibox.container.rotate,
}
--]]
widget.arc = wibox.widget {
{
widget.icon,
top = beautiful.dpi(1),
bottom = beautiful.dpi(1),
layout = wibox.container.margin,
},
max_value = 100,
thickness = beautiful.dpi(4),
start_angle = 4.71238898, -- 2pi*3/4
--forced_height = beautiful.dpi(16),
--forced_width = beautiful.dpi(16),
colors = {"#27D4CC", "#00446B"},
bg = "#FFFFFF30",
paddings = beautiful.dpi(2),
widget = wibox.container.arcchart
}
widget.widget = wibox.widget {
{
{ -- Right space
widget = wibox.widget.separator,
color = beautiful.color.transparent,
forced_width = beautiful.dpi(3)
},
{
widget.arc,
top = beautiful.dpi(2),
bottom = beautiful.dpi(2),
layout = wibox.container.margin,
},
{ -- Left space
widget = wibox.widget.separator,
color = beautiful.color.transparent,
forced_width = beautiful.dpi(3)
},
layout = wibox.layout.align.horizontal,
},
layout = wibox.container.background,
}
widget.tooltip = awful.tooltip {
objects = { widget.widget },
text = ""
}
widget.widget:connect_signal("mouse::enter", function(result)
widget.widget.bg = beautiful.color.bar.hover_bg
end)
widget.widget:connect_signal("mouse::leave", function(result)
widget.widget.bg = beautiful.color.transparent
end)
return widget
end
return P

120
classes/battery/battery.lua Normal file
View File

@ -0,0 +1,120 @@
local widget_types = {
arc = require("classes/battery/arc_widget"),
prog = require("classes/battery/prog_widget")
}
local P = {}
---
-- Internal methods
---
function P:_get_status()
awful.spawn.easy_async(
script_dir .. "battery",
function(stdout, stderr, exitreason, exitcode)
local bat = string.match(stdout, "(%d?%d?%d)%%")
bat = tonumber(string.format("% 3d", bat))
local discharging = string.match(stdout, "discharging") or false
self._ready = true
self.battery_percent = bat
self.charging = not discharging
self:_update_widget()
self:_check_notification()
end
)
return true
end
function P:_update_widget()
if (not self._ready) then
self.widget:set_state("error")
self.widget:set_value(100);
self.widget:set_tooltip("Battery error");
return
end
if (self.charging) then
self.widget:set_state("charging")
else
self.widget:set_state("discharging")
end
self.widget:set_value(self.battery_percent);
self.widget:set_tooltip("Battery " .. math.floor(self.battery_percent) .. "%");
end
function P:_check_notification()
if not self.charging then
for i=1, #self.warnings do
v = self.warnings[i]
if (self.battery_percent <= v) and (not self._warning_log[i]) then
self._warning_log[i] = true
naughty.notify({
title = "Low power",
text = "Battery is at " .. tostring(self.battery_percent) .. "%",
icon = beautiful.icons.battery.caution,
timeout = 5,
ignore_suspend = true,
border_color = beautiful.color.battery.danger,
preset = beautiful.notification_templates.bottom_right
})
break
end
end
else
for i=1, #self.warnings do
if (self.battery_percent >= self.warnings[i]) then
self._warning_log[i] = false
end
end
end
end
---
-- Create new
---
function P:new(args)
-- Arguments
b = {
update_interval = args.update_interal or 5,
widget_type = args.widget_type or "arc",
warnings = {5, 10, 25, 50}, -- Percentages to warn at (must be in order)
_warning_log = {},
_ready = false, -- is all the information in this class up-to-date?
-- if this is false, ui will show an error and most methods will
-- do nothing. Updated in _get_status()
}
-- Initialize warning log
for i=1, #b.warnings do
b._warning_log[i] = false
end
b.widget = widget_types[b.widget_type]:new()
setmetatable(b, self)
self.__index = self
-- This timer keeps mute and volume status up-to-date.
b.timer = gears.timer {
timeout = b.update_interval,
call_now = true,
autostart = true,
callback = function()
b:_get_status()
end
}
return b
end
return P

7
classes/battery/init.lua Normal file
View File

@ -0,0 +1,7 @@
local P = require("classes/battery/battery")
local F = function(args)
return P:new(args)
end
return F

View File

@ -0,0 +1,113 @@
local P = {}
function P:set_value(value)
-- Set widget value. (0 - 100)
self.progressbar.value = value
if value > 60 then
self.progressbar.color = beautiful.color.battery.good
elseif value > 40 then
self.progressbar.color = beautiful.color.battery.low
elseif value <= 40 then
self.progressbar.color = beautiful.color.battery.danger
end
if (self.state == "discharging") then
self.rotator.direction = "east"
else
self.rotator.direction = "west"
end
if (self.state == "charging") and (value > 90) then
self.progressbar.border_color = beautiful.color.battery.good
elseif (self.state == "discharging") and (value <= 25) then
self.progressbar.border_color = beautiful.color.battery.danger
else
self.progressbar.border_color = beautiful.color.bar.active
end
end
function P:set_state(state)
if (state == "discharging") then
self.state = "discharging"
elseif (state == "charging") then
self.state = "charging"
elseif (state == "error") then
self.state = "error"
else
error("Invalid state " .. state)
end
end
function P:set_tooltip(text)
-- Set widget value. (0 - 100)
self.tooltip.text = text
end
function P:new()
widget = {
state = "error"
}
setmetatable(widget, self)
self.__index = self
widget.progressbar = wibox.widget {
max_value = 100,
widget = wibox.widget.progressbar,
paddings = beautiful.dpi(2),
color = beautiful.color.bar.active,
background_color = beautiful.color.transparent,
border_color = beautiful.color.bar.active,
border_width = beautiful.dpi(1),
margins = beautiful.dpi(3)
}
widget.rotator = wibox.widget {
widget.progressbar,
forced_width = beautiful.dpi(15),
direction = "east",
layout = wibox.container.rotate,
}
widget.widget = wibox.widget {
{
{ -- Right space
widget = wibox.widget.separator,
color = beautiful.color.transparent,
forced_width = beautiful.dpi(3)
},
{
widget.rotator,
top = beautiful.dpi(2),
bottom = beautiful.dpi(2),
layout = wibox.container.margin,
},
{ -- Left space
widget = wibox.widget.separator,
color = beautiful.color.transparent,
forced_width = beautiful.dpi(3)
},
layout = wibox.layout.align.horizontal,
},
layout = wibox.container.background,
}
widget.tooltip = awful.tooltip {
objects = { widget.widget },
text = ""
}
widget.widget:connect_signal("mouse::enter", function(result)
widget.widget.bg = beautiful.color.bar.hover_bg
end)
widget.widget:connect_signal("mouse::leave", function(result)
widget.widget.bg = beautiful.color.transparent
end)
return widget
end
return P

View File

@ -1,4 +1,5 @@
return { return {
Backlight = require("classes/backlight"), Backlight = require("classes/backlight"),
Volume = require("classes/volume") Volume = require("classes/volume"),
Battery = require("classes/battery"),
} }

View File

@ -46,10 +46,6 @@ local desktop = {
} }
} }
if conf.battery_enabled then
desktop.widgets.battery = require("desktop.widgets.battery")
end
if conf.mpc_enabled then if conf.mpc_enabled then
desktop.widgets.mpc = require("desktop.widgets.mpc") desktop.widgets.mpc = require("desktop.widgets.mpc")
end end
@ -178,7 +174,7 @@ awful.screen.connect_for_each_screen(
desktop.widgets.textclock, desktop.widgets.textclock,
desktop.widgets.space(8), desktop.widgets.space(8),
desktop.widgets.battery, batt.widget.widget,
bck.widget.widget, bck.widget.widget,
vol.widget.widget, vol.widget.widget,
desktop.widgets.space(8), desktop.widgets.space(8),

View File

@ -1,214 +0,0 @@
local battery = {}
-- Percentages to warn at
-- (must be in order least -> greatest)
battery.warnings = {
5, 10, 25, 50
}
battery.warninglog = {}
for i=1, #battery.warnings do
battery.warninglog[i] = false
end
battery.image_path = beautiful.icons.battery.missing
battery.icon = wibox.widget {
image = beautiful.icons.battery.missing,
resize = true,
widget = wibox.widget.imagebox,
}
battery.progressbar = wibox.widget {
max_value = 100,
widget = wibox.widget.progressbar,
paddings = beautiful.dpi(2),
color = beautiful.color.bar.active,
background_color = beautiful.color.transparent,
border_color = beautiful.color.bar.active,
border_width = beautiful.dpi(1),
margins = beautiful.dpi(3)
}
battery.arc = wibox.widget {
{
battery.icon,
top = beautiful.dpi(1),
bottom = beautiful.dpi(1),
layout = wibox.container.margin,
},
max_value = 100,
thickness = beautiful.dpi(4),
start_angle = 4.71238898, -- 2pi*3/4
--forced_height = beautiful.dpi(16),
--forced_width = beautiful.dpi(16),
colors = {"#27D4CC", "#00446B"},
bg = "#FFFFFF30",
paddings = beautiful.dpi(2),
widget = wibox.container.arcchart
}
battery.rotator = wibox.widget {
battery.progressbar,
forced_width = beautiful.dpi(15),
direction = "east",
layout = wibox.container.rotate,
}
battery.widget = wibox.widget {
{
{ -- Right space
widget = wibox.widget.separator,
color = beautiful.color.transparent,
forced_width = beautiful.dpi(3)
},
{
battery.arc,
top = beautiful.dpi(2),
bottom = beautiful.dpi(2),
layout = wibox.container.margin,
},
{ -- Left space
widget = wibox.widget.separator,
color = beautiful.color.transparent,
forced_width = beautiful.dpi(3)
},
layout = wibox.layout.align.horizontal,
},
layout = wibox.container.background,
}
battery.widget:connect_signal("mouse::enter", function(result)
battery.widget.bg = beautiful.color.bar.hover_bg
end)
battery.widget:connect_signal("mouse::leave", function(result)
battery.widget.bg = beautiful.color.transparent
end)
battery.update = function(stdout)
local batpec = string.match(stdout, "(%d?%d?%d)%%")
batpec = tonumber(string.format("% 3d", batpec))
local discharging = string.match(stdout, "discharging") or false
-- Handle low power notifications
if discharging then
for i=1, #battery.warnings do
v = battery.warnings[i]
if (batpec <= v) and (not battery.warninglog[i]) then
battery.warninglog[i] = true
naughty.notify({
title = "Low power",
text = "Battery is at " .. tostring(batpec) .. "%",
icon = beautiful.icons.battery.caution,
timeout = 5,
ignore_suspend = true,
border_color = beautiful.color.battery.danger,
preset = beautiful.notification_templates.bottom_right
})
break
end
end
else
for i=1, #battery.warnings do
if (batpec >= battery.warnings[i]) then
battery.warninglog[i] = false
end
end
end
battery.progressbar.value = batpec
battery.arc.value = batpec
if batpec > 60 then
battery.progressbar.color = beautiful.color.battery.good
elseif batpec > 40 then
battery.progressbar.color = beautiful.color.battery.low
elseif batpec <= 40 then
battery.progressbar.color = beautiful.color.battery.danger
end
battery.image_path = beautiful.icons.battery.missing
-- Set current battery icon
if (not discharging) then
if batpec > 80 then battery.image_path = beautiful.icons.battery.charging.full
elseif batpec > 60 then battery.image_path = beautiful.icons.battery.charging.good
elseif batpec > 40 then battery.image_path = beautiful.icons.battery.charging.low
elseif batpec > 20 then battery.image_path = beautiful.icons.battery.charging.caution
elseif batpec <= 20 then battery.image_path = beautiful.icons.battery.charging.empty end
else
if batpec > 80 then battery.image_path = beautiful.icons.battery.full
elseif batpec > 60 then battery.image_path = beautiful.icons.battery.good
elseif batpec > 40 then battery.image_path = beautiful.icons.battery.low
elseif batpec > 20 then battery.image_path = beautiful.icons.battery.caution
elseif batpec <= 20 then battery.image_path = beautiful.icons.battery.empty end
end
battery.icon.image = battery.image_path
if (not discharging) and (batpec > 90) then
battery.progressbar.border_color = beautiful.color.battery.good
elseif (discharging) and (batpec <= 25) then
battery.progressbar.border_color = beautiful.color.battery.danger
else
battery.progressbar.border_color = beautiful.color.bar.active
end
if discharging then
battery.rotator.direction = "east"
else
battery.rotator.direction = "west"
end
end
battery.readupdate = function()
bin.battery.status(
function(stdout, stderr, exitreason, exitcode)
battery.update(stdout)
end
)
end
battery.widget:connect_signal("button::press",
function(_, _, _, button, mods)
if (button == 1) then
bin.battery.status(
function(stdout, stderr, exitreason, exitcode)
local batpec = string.match(stdout, "(%d?%d?%d)%%") -- (\d?\d?\d)\%)
local batstat = string.match(stdout, "discharging") or false
if batstat then
batstat = "Discharging, "
else
batstat = "Charging, "
end
local out = naughty.notify({
title = "Battery:",
text = batstat .. batpec .. "%",
icon = battery.image_path,
replaces_id = battery.notid,
ignore_suspend = true,
preset = beautiful.notification_templates.bottom_right
})
battery.notid = out.id
end
)
end
end
)
bin.battery.watch(10, function(_, stdout) battery.update(stdout) end, battery.widget)
return battery.widget

1
rc.lua
View File

@ -40,6 +40,7 @@ beautiful.init(require("theme"))
classes = require("classes") classes = require("classes")
vol = classes.Volume{pa_sink = conf.pamixer_sink} vol = classes.Volume{pa_sink = conf.pamixer_sink}
bck = classes.Backlight{} bck = classes.Backlight{}
batt = classes.Battery{}
desktop = require("desktop") desktop = require("desktop")