local ipairs = ipairs local mfloor = math.floor local setmetatable = setmetatable -- Awesome Libs local aspawn = require('awful.spawn') local atooltip = require('awful.tooltip') local beautiful = require('beautiful') local dpi = beautiful.xresources.apply_dpi local gcolor = require('gears.color') local gfilesystem = require('gears.filesystem') local gsurface = require('gears.surface') local gtimer = require('gears.timer') local lgi = require('lgi') local nnotification = require('naughty.notification') local upower_glib = lgi.require('UPowerGlib') local wibox = require('wibox') -- Local libs local hover = require('src.tools.hover') local capi = { awesome = awesome, } -- Icon directory path local icondir = gfilesystem.get_configuration_dir() .. 'src/assets/icons/battery/' local instance = nil if not instance then instance = setmetatable({}, { __call = function(_, battery_kind) local battery_widget = wibox.widget { { { { { { id = 'icon', image = gcolor.recolor_image(icondir .. 'battery-unknown.svg', beautiful.colorscheme.fg_dark), widget = wibox.widget.imagebox, valign = 'center', halign = 'center', resize = false, }, id = 'icon_layout', widget = wibox.container.place, }, id = 'icon_margin', top = dpi(2), widget = wibox.container.margin, }, spacing = dpi(10), { visible = false, align = 'center', valign = 'center', id = 'label', widget = wibox.widget.textbox, }, id = 'battery_layout', layout = wibox.layout.fixed.horizontal, }, id = 'container', left = dpi(8), right = dpi(8), widget = wibox.container.margin, }, bg = beautiful.colorscheme.bg_purple, fg = beautiful.colorscheme.fg_dark, shape = beautiful.shape[6], widget = wibox.container.background, } hover.bg_hover { widget = battery_widget } battery_widget:connect_signal('button::press', function() aspawn(beautiful.user_config.energy_manager) end) local function get_device_path() local paths = upower_glib.Client():get_devices() local path_table = {} for _, path in ipairs(paths) do table.insert(path_table, path:get_object_path()) end return path_table end local function get_device_from_path(path) local devices = upower_glib.Client():get_devices() for _, device in ipairs(devices) do if device:get_object_path() == path then return device end end return nil end local tooltip = atooltip { objects = { battery_widget }, mode = 'inside', preferred_alignments = 'middle', margins = dpi(10), } ---Sets the battery information for the widget ---@param device UPowerGlib.Device battery local function set_battery(device) local battery_percentage = mfloor(device.percentage + 0.5) local battery_status = upower_glib.DeviceState[device.state]:lower() local battery_temp = device.temperature local battery_time = 1 if device.time_to_empty ~= 0 then battery_time = device.time_to_empty else battery_time = device.time_to_full end local battery_string = mfloor(battery_time / 3600) .. 'h, ' .. mfloor((battery_time / 60) % 60) .. 'm' if battery_temp == 0.0 then battery_temp = 'NaN' else battery_temp = mfloor(battery_temp + 0.5) .. '°C' end if not battery_percentage then return end battery_widget:get_children_by_id('battery_layout')[1].spacing = dpi(5) battery_widget:get_children_by_id('label')[1].visible = true battery_widget:get_children_by_id('label')[1].text = battery_percentage .. '%' tooltip.markup = "Battery Status: " .. battery_status .. "\nRemaining time: " .. battery_string .. "\nTemperature: " .. battery_temp .. '' local icon = 'battery' if battery_status == 'fully-charged' or battery_status == 'charging' and battery_percentage == 100 then icon = icon .. '-' .. 'charging.svg' nnotification { title = 'Battery notification', message = 'Battery is fully charged', icon = icondir .. icon, timeout = 5, } battery_widget:get_children_by_id('icon')[1].image = gsurface.load_uncached(gcolor.recolor_image(icondir .. icon, beautiful.colorscheme.fg_dark)) return elseif battery_percentage > 0 and battery_percentage < 10 and battery_status == 'discharging' then icon = icon .. '-' .. 'alert.svg' nnotification { title = 'Battery warning', message = 'Battery is running low!\n' .. battery_percentage .. '% left', urgency = 'critical', icon = icondir .. icon, timeout = 60, } battery_widget:get_children_by_id('icon')[1].image = gsurface.load_uncached(gcolor.recolor_image(icondir .. icon, beautiful.colorscheme.fg_dark)) return end if battery_percentage > 0 and battery_percentage < 10 then icon = icon .. '-' .. battery_status .. '-' .. 'outline' elseif battery_percentage >= 10 and battery_percentage < 20 then icon = icon .. '-' .. battery_status .. '-' .. '10' elseif battery_percentage >= 20 and battery_percentage < 30 then icon = icon .. '-' .. battery_status .. '-' .. '20' elseif battery_percentage >= 30 and battery_percentage < 40 then icon = icon .. '-' .. battery_status .. '-' .. '30' elseif battery_percentage >= 40 and battery_percentage < 50 then icon = icon .. '-' .. battery_status .. '-' .. '40' elseif battery_percentage >= 50 and battery_percentage < 60 then icon = icon .. '-' .. battery_status .. '-' .. '50' elseif battery_percentage >= 60 and battery_percentage < 70 then icon = icon .. '-' .. battery_status .. '-' .. '60' elseif battery_percentage >= 70 and battery_percentage < 80 then icon = icon .. '-' .. battery_status .. '-' .. '70' elseif battery_percentage >= 80 and battery_percentage < 90 then icon = icon .. '-' .. battery_status .. '-' .. '80' elseif battery_percentage >= 90 and battery_percentage < 100 then icon = icon .. '-' .. battery_status .. '-' .. '90' end battery_widget:get_children_by_id('icon')[1].image = gsurface.load_uncached(gcolor.recolor_image(icondir .. icon .. '.svg', beautiful.colorscheme.fg_dark)) capi.awesome.emit_signal('update::battery_widget', battery_percentage, icondir .. icon .. '.svg') end local function attach_to_device(path) local device_path = beautiful.user_config.battery_path or path or '' battery_widget.device = get_device_from_path(device_path) or upower_glib.Client():get_display_device() battery_widget.device.on_notify = function(device) battery_widget:emit_signal('upower::update', device) end if upower_glib.DeviceKind[battery_widget.device.kind] == battery_kind then set_battery(battery_widget.device) end gtimer.delayed_call(battery_widget.emit_signal, battery_widget, 'upower::update', battery_widget.device) end for _, device in ipairs(get_device_path()) do attach_to_device(device) end battery_widget:connect_signal('upower::update', function(_, device) if upower_glib.DeviceKind[battery_widget.device.kind] == battery_kind then set_battery(device) end end) return battery_widget end, }) end return instance