local awful = require("awful") local beautiful = require("beautiful") local gears = require("gears") local naughty = require("naughty") local wibox = require("wibox") local config = require("config").widgets.system_resources local inspect = require("simple/debug/inspect") local bar = { { { max_value = 1, value = 0, widget = wibox.widget.progressbar, color = beautiful.system_resources_widget_bar_color, background_color = beautiful.system_resources_widget_bar_bg, shape = beautiful.system_resources_widget_bar_shape, border_color = beautiful.system_resources_widget_border_color, border_width = beautiful.system_resources_widget_border_width, }, forced_width = beautiful.system_resources_widget_bar_width, direction = "east", layout = wibox.container.rotate, }, margins = beautiful.system_resources_widget_bar_margin, widget = wibox.container.margin, } local bars = wibox.widget { bar, bar, bar, layout = wibox.layout.flex.horizontal } function fileExists(name) local f = io.open(name, "r") if f ~= nil then io.close(f) return true end return false end function readCommand(command) local handle = io.popen(command, "r") local r = handle:read("*a") handle:close() return r end function readFile(file) local handle = io.open(file, "r") local r = handle:read("*a") handle:close() return r end local cpuBar = bars:get_children()[1]:get_children()[1]:get_children()[1] function getCpuData() local raw = readCommand("cat /proc/stat | head -n 1") local data = {raw:match((raw:gsub("[^ ]* ", "([^ ]*) ")))} return { user = data[3], nice = data[4], system = data[5], idle = data[6], iowait = data[7], irq = data[8], softirq = data[9], steal = data[10], } end local lastCpuTime = -1 local lastCpuIdle = -1 gears.timer { timeout = config.bars.refresh_interval, call_now = true, autostart = true, callback = function() local data = getCpuData() local currentCpuTime = data.user + data.nice + data.system + data.idle + data.iowait + data.irq + data.softirq + data.steal local currentCpuIdle = data.idle + data.iowait if(lastCpuTime >= 0) then cpuBar.value = 1 - (currentCpuIdle - lastCpuIdle) / (currentCpuTime - lastCpuTime) end lastCpuTime = currentCpuTime lastCpuIdle = currentCpuIdle end } local memoryBar = bars:get_children()[2]:get_children()[1]:get_children()[1] function getTotalMemory() return readCommand("cat /proc/meminfo | grep MemTotal | awk '{print $2}'") end function getAvailableMemory() return readCommand("cat /proc/meminfo | grep MemAvailable | awk '{print $2}'") end function getFreeMemory() return readCommand("cat /proc/meminfo | grep MemFree | awk '{print $2}'") end gears.timer { timeout = config.bars.refresh_interval, call_now = true, autostart = true, callback = function() memoryBar.value = 1 - getAvailableMemory() / getTotalMemory() end } local swapBar = bars:get_children()[3]:get_children()[1]:get_children()[1] function getTotalSwap() return readCommand("cat /proc/meminfo | grep SwapTotal | awk '{print $2}'") end function getFreeSwap() return readCommand("cat /proc/meminfo | grep SwapFree | awk '{print $2}'") end gears.timer { timeout = config.bars.refresh_interval, call_now = true, autostart = true, callback = function() swapBar.value = 1 - getFreeSwap() / getTotalSwap() end } --- --- Batteries --- rawBatteries = {} function refreshRawBatteries() rawBatteries = readCommand("ls -A1 /sys/class/power_supply") end function getBatteryLevel(battery) local charge = 0 local capacity = 0 if fileExists(battery .. "/energy_now") then charge = charge + readFile(battery .. "/energy_now") capacity = capacity + readFile(battery .. "/energy_full") elseif fileExists(battery .. "/charge_now") then charge = charge + readFile(battery .. "/charge_now") capacity = capacity + readFile(battery .. "/charge_full") elseif fileExists(battery .. "/capacity_level") then return readFile(battery .. "/capacity_level") else return "Unsupported" end return string.format("%." .. config.battery.precision .. "f", (charge / capacity) * 100) .. "%" end function isCharging(battery) return readFile(battery .. "/status") == "Charging\n" end local batteryContainer = wibox.widget { layout = wibox.layout.fixed.horizontal } local timers = {} function refreshBatteries() -- refresh raw batteries and check for change local oldBatteries = rawBatteries refreshRawBatteries() if rawBatteries == oldBatteries then return end -- clear timers for i,v in ipairs(timers) do v:stop() end timers = {}; -- clear layout batteryContainer:set_children({}) for battery in rawBatteries:gmatch("([^\n]+)") do local path = "/sys/class/power_supply/" .. battery if readFile(path .. "/type"):match("Battery") then -- widget local widget = wibox.widget { { markup = "-- %", align = "center", valign = "center", widget = wibox.widget.textbox, }, margins = beautiful.system_resources_widget_battery_margin, widget = wibox.container.margin, } -- tooltip local name = readFile(path .. "/model_name") local tooltip = awful.tooltip { text = name } tooltip:add_to_object(widget) -- update battery level local batteryText = widget:get_children()[1] local timer = gears.timer { timeout = config.battery.refresh_interval, call_now = true, autostart = true, callback = function() batteryText.markup = (isCharging(path) and "+" or "") .. getBatteryLevel(path) end } table.insert(timers, timer) batteryContainer:add(widget) end end end gears.timer { timeout = config.battery.list_refresh_interval, call_now = true, autostart = true, callback = function() refreshBatteries() end } return { bars = bars, battery = batteryContainer, }