ed063ab1fe
Capture desktop-specific system, session, Noctalia, and Pi integration alongside shared laptop support. Retire obsolete X11 configuration and make package ownership explicit for repeatable Decman deployments.
83 lines
2.3 KiB
Lua
83 lines
2.3 KiB
Lua
-- Read the tiny kernel meminfo pseudo-file every five seconds. This avoids a
|
|
-- resident helper process and reuses Noctalia's lightweight widget lifecycle.
|
|
local command = [[awk '
|
|
$1 == "MemTotal:" { total = $2 }
|
|
$1 == "MemAvailable:" { available = $2 }
|
|
$1 == "SwapTotal:" { swap_total = $2 }
|
|
$1 == "SwapFree:" { swap_free = $2 }
|
|
END {
|
|
if (!total || !available) exit 1
|
|
used = total - available
|
|
memory_used = used * 100 / total
|
|
if (swap_total > 0) {
|
|
swap_used = (swap_total - swap_free) * 100 / swap_total
|
|
printf "%.1f/%.1f GiB S %.0f%%\t%.0f\t%.0f\n", used / 1048576, total / 1048576, swap_used, memory_used, swap_used
|
|
} else {
|
|
printf "%.1f/%.1f GiB S —\t%.0f\t0\n", used / 1048576, total / 1048576, memory_used
|
|
}
|
|
}' /proc/meminfo]]
|
|
|
|
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 = "memory", size = 14, color = color }),
|
|
ui.label({ text = text, color = color }),
|
|
}))
|
|
end
|
|
|
|
function update()
|
|
noctalia.setUpdateInterval(5000)
|
|
|
|
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("RAM —", "#fff1e6")
|
|
barWidget.setTooltip("Unable to read /proc/meminfo")
|
|
return
|
|
end
|
|
|
|
local text, memory_percent, swap_percent = string.match(
|
|
result.stdout,
|
|
"^([^\t]+)\t([%d.]+)\t([%d.]+)"
|
|
)
|
|
memory_percent = tonumber(memory_percent)
|
|
swap_percent = tonumber(swap_percent)
|
|
|
|
if text == nil or memory_percent == nil or swap_percent == nil then
|
|
renderStatus("RAM —", "#fff1e6")
|
|
barWidget.setTooltip("Unable to parse memory utilization")
|
|
return
|
|
end
|
|
|
|
local highest_usage = math.max(memory_percent, swap_percent)
|
|
renderStatus(text, colorForUsage(highest_usage))
|
|
barWidget.setTooltip(
|
|
string.format(
|
|
"RAM used / total · %.0f%% RAM · %.0f%% swap",
|
|
memory_percent,
|
|
swap_percent
|
|
)
|
|
)
|
|
end)
|
|
end
|