-- Sum each logical CPU's interval utilization. Unlike the built-in average, -- this follows Unix tools by allowing the value to exceed 100%. local command = [[awk ' /^cpu[0-9]+ / { total = 0 for (i = 2; i <= NF; i++) total += $i idle = $5 + $6 printf "%s %.0f %.0f\n", $1, total, idle }' /proc/stat]] local previous = {} local request_in_flight = false local function colorForUsage(percent) if percent >= 85 then return "#ff453a" -- red end if percent >= 70 then return "#ff8800" -- orange end if percent >= 50 then return "#ffd60a" -- yellow end return "#ffffff" -- white end local function renderStatus(text, color) barWidget.render(ui.row({ gap = 4, align = "center" }, { ui.glyph({ name = "cpu", size = 14, color = color }), ui.label({ text = text, color = color }), })) end function update() noctalia.setUpdateInterval(2000) if request_in_flight then return end request_in_flight = true noctalia.runAsync(command, function(result) request_in_flight = false if result.exitCode ~= 0 then renderStatus("CPU —", "#fff1e6") barWidget.setTooltip("Unable to read CPU utilization") return end local utilization = 0 local sampled = 0 for line in string.gmatch(result.stdout, "[^\r\n]+") do local name, total, idle = string.match(line, "^(cpu%d+) (%d+) (%d+)$") total = tonumber(total) idle = tonumber(idle) local prior = previous[name] if prior ~= nil then local total_delta = total - prior.total local idle_delta = idle - prior.idle if total_delta > 0 then utilization = utilization + (100 * (total_delta - idle_delta) / total_delta) sampled = sampled + 1 end end previous[name] = { total = total, idle = idle } end if sampled > 0 then -- Keep the aggregate display, but base its heat color on average -- utilization per logical CPU so multicore systems do not stay red. local per_cpu_utilization = utilization / sampled renderStatus(string.format("%.0f%%", utilization), colorForUsage(per_cpu_utilization)) barWidget.setTooltip( string.format( "Aggregate CPU utilization (100%% per logical CPU) · %.0f%% average per CPU", per_cpu_utilization ) ) else renderStatus("—", "#fff1e6") barWidget.setTooltip("Sampling CPU utilization…") end end) end