-- Battery status widget -- -- Based on Battery Arc Widget by Pavel Makhov -- https://github.com/streetturtle/awesome-wm-widgets/tree/master/batteryarc-widget -- @copyright 2020 Pavel Makhov -- The MIT License (MIT) -- -- Copyright (c) 2017 -- -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and associated documentation files (the "Software"), to deal -- in the Software without restriction, including without limitation the rights -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -- copies of the Software, and to permit persons to whom the Software is -- furnished to do so, subject to the following conditions: -- -- The above copyright notice and this permission notice shall be included in all -- copies or substantial portions of the Software. -- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -- SOFTWARE. local awful = require("awful") local beautiful = require("beautiful") -- local menubar_it = require("menubar.icon_theme") -- local menubar_utils = require("menubar.utils") local naughty = require("naughty") local wibox = require("wibox") local BatteryWidget = {} BatteryWidget.__index = BatteryWidget setmetatable(BatteryWidget, { __call = function (cls, ...) return cls.new(...) end, }) local COLORS = { MAIN_FG = beautiful.fg_color, MAIN_BG = '#ffffff11', CHARGING = "#43a047", CHARGE_MEDIUM = "#c0ca33", CHARGE_LOW = "#e53935", CHARGE_UNKNOWN = "#990099", NOTIFY_LOW_FG = "#EEE9EF", NOTIFY_LOW_BG = "#F06060", } function BatteryWidget:_show_battery_warning(charge_percent) naughty.notify({ -- icon = warning_msg_icon, -- icon_size = 100, title = 'Low battery', text = string.format('battery at %d%%', charge_percent), timeout = 25, -- show the warning for a longer time hover_timeout = 0.5, bg = COLORS.NOTIFY_LOW_BG, fg = COLORS.NOTIFY_LOW_FG, width = 300, }) end function BatteryWidget:_update() local capacity = self._bat.capacity if not capacity then local cl = self._bat.capacity_level if cl == 'Full' then capacity = 100 elseif cl == 'High' then capacity = 75 elseif cl == 'Normal' then capacity = 50 elseif cl == 'Low' then capacity = 25 elseif cl == 'Critical' then capacity = 5 end end -- hide the widget if the battery is full if self._bat.status == self._bat.STATUS.FULL then self._placeholder:set_children({}) return end -- show the widget if it was previously hidden if next(self._placeholder.children) == nil then self._placeholder:set_children({self._arc}) end if self._level_text ~= nil then --- if battery is fully charged (100) there is not enough place for three digits, so we don't show any text self._level_text.text = (capacirty and capacity >= 100) and '' or string.format('%d', capacity // 1) end if self._bat.status == self._bat.STATUS.CHARGING then self._arc.bg = COLORS.CHARGING else self._arc.bg = COLORS.MAIN_BG end if capacity then self._arc.value = capacity if capacity < 15 then self._arc.colors = { COLORS.CHARGE_LOW } if self._bat.status == self._bat.STATUS.DISCHARGING and os.difftime(os.time(), self._last_battery_check) > 300 then self:_show_battery_warning(capacity) self._last_battery_check = os.time() end elseif capacity < 40 then self._arc.colors = { COLORS.CHARGE_MEDIUM } else self._arc.colors = { COLORS.MAIN_FG } end else -- capacity level unavailable self._arc.colors = { COLORS.CHARGE_UNKNOWN } self._arc.value = self._bat.status == self._bat.STATUS.CHARGING and 50 or 100 end -- build tooltip text -- start with name + description local tooltip_text = self._bat.name if self._bat.desc then tooltip_text = string.format('%s (%s)', tooltip_text, self._bat.desc) end -- percentage/capacity level if self._bat.capacity then tooltip_text = string.format('%s: %d%%', tooltip_text, self._bat.capacity) elseif self._bat.capacity_level then tooltip_text = string.format('%s: %s', tooltip_text, self._bat.capacity_level) end -- status + power (if available) tooltip_text = string.format('%s; %s', tooltip_text, self._bat.status) if self._bat.power then tooltip_text = string.format('%s at %.3gW', tooltip_text, self._bat.power) end if self._bat.remaining_seconds then local sec = self._bat.remaining_seconds local h = sec // 3600 sec = sec - 3600 * h local m = sec // 60 sec = sec - 60 * m local s = sec // 1 local endstate = self._bat.status == self._bat.STATUS.DISCHARGING and 'empty' or 'full' tooltip_text = string.format('%s; %02d:%02d:%02d until %s', tooltip_text, h, m, s, endstate) end self._tooltip.text = tooltip_text end function BatteryWidget.new(battery, user_args) local self = setmetatable({}, BatteryWidget) local args = user_args or {} self._bat = battery -- optional textbox showing battery charge percentage local show_current_level = args.show_current_level or false if show_current_level then self._level_text = wibox.widget.textbox() end -- arc indicating battery charge level self._arc = wibox.widget { self._level_text, max_value = 100, rounded_edge = true, thickness = args.arc_thickness or 4, start_angle = 4.71238898, -- 2pi*3/4 bg = COLORS.MAIN_BG, paddings = 2, widget = wibox.container.arcchart } -- placeholder layout used to hide the widget on full battery self._placeholder = wibox.layout.flex.horizontal() -- the actually returned widget, showing the battery only on the primary screen local ret_widget = awful.widget.only_on_screen(self._placeholder, "primary") -- tooltip showing extended battery status self._tooltip = awful.tooltip({}) self._tooltip:add_to_object(ret_widget) self._last_battery_check = os.time() -- wibox.widget.imagebox -- local it = menubar_it() -- print(it:find_icon_path('battery-full', 32)) battery:connect_signal('updated', function () self:_update() end) return ret_widget end return BatteryWidget