Update(procmon-plugin): Add keyboard navigation and reduce CPU sampling (#321)
* Add procmon plugin with live process panel New Noctalia plugin: bar widget shows CPU/RAM usage and process count; floating panel has a sortable, searchable process table with per-process kill. Background service samples ps and /proc stats and publishes via plugin state. * Throttle data-driven panel renders Rebuild table at most every 500ms to stay within the panel update CPU budget. User interactions still render immediately; only state watches and the tick go through maybeRender(). * Update procmon deps and fix timestamp precision Document head, grep, and cat as required commands. Correct refresh interval default to 1000 ms. Sample refreshedAtMs in milliseconds. * Add keyboard navigation and reduce CPU sampling - Panel: arrow keys move cursor, Ctrl+D kills selected, Ctrl+F focuses filter - Service: sample /proc stats every 1s, ps every 2s; 2s render floor - Widget: handle vertical bars, truncate text, use valid theme color - Bump version to 0.4.0, plugin_api 13
This commit is contained in:
+36
-21
@@ -1,7 +1,12 @@
|
||||
--!nonstrict
|
||||
-- Process Monitor — bar widget. Full mode shows "CPU% RAM% · count" text; icon-only
|
||||
-- mode shows just a CPU icon colored by load, with the details in the tooltip so the
|
||||
-- bar stays tiny. Clicking opens the panel.
|
||||
-- Process Monitor — bar widget. Horizontal bars show "CPU% RAM%" text (truncated
|
||||
-- to fit); vertical bars are too narrow for text, so they show only a CPU icon
|
||||
-- colored by load. Clicking opens the panel.
|
||||
|
||||
-- Read the bar orientation once at load (pomodoro pattern) so the widget renders
|
||||
-- consistently instead of flickering between icon and text when isVertical() is
|
||||
-- polled on every update.
|
||||
local isVertical = barWidget.isVertical()
|
||||
|
||||
local function cfg(key)
|
||||
return noctalia.getConfig(key)
|
||||
@@ -15,6 +20,14 @@ local function tr(key, subst)
|
||||
return noctalia.tr(key, subst)
|
||||
end
|
||||
|
||||
-- Cap the text so it fits the bar instead of spilling out the right edge.
|
||||
local function trunc(s, n)
|
||||
if #s <= n then
|
||||
return s
|
||||
end
|
||||
return s:sub(1, n - 1) .. "…"
|
||||
end
|
||||
|
||||
function update()
|
||||
local stats = st("stats")
|
||||
local cpu = stats and stats.cpu and stats.cpu.usagePercent
|
||||
@@ -23,28 +36,30 @@ function update()
|
||||
local cpuInt = math.floor(cpu or 0)
|
||||
local tooltip = tr("widget.tooltip", { cpu = cpuInt, ram = math.floor(ram or 0), n = count })
|
||||
|
||||
barWidget.setGlyph(cfg("glyph") or "cpu")
|
||||
barWidget.setTooltip(tooltip)
|
||||
-- Color the icon by CPU load so a glance reads the machine state.
|
||||
-- Only real theme tokens (error/secondary/on_surface) — the runtime rejects
|
||||
-- unknown names like "warning" and logs a warning per glyph per frame.
|
||||
local color = "on_surface"
|
||||
if cpuInt >= 80 then
|
||||
color = "error"
|
||||
elseif cpuInt >= 50 then
|
||||
color = "secondary"
|
||||
end
|
||||
|
||||
if cfg("icon_only") then
|
||||
barWidget.setText("")
|
||||
-- color the icon by CPU load so a glance reads the machine state
|
||||
if cpuInt >= 80 then
|
||||
barWidget.setGlyphColor("error")
|
||||
elseif cpuInt >= 50 then
|
||||
barWidget.setGlyphColor("warning")
|
||||
else
|
||||
barWidget.setGlyphColor("on_surface")
|
||||
local children = { ui.glyph({ name = cfg("glyph") or "cpu", size = 14, color = color }) }
|
||||
|
||||
-- Vertical bars are too narrow for text; show only the icon so it fits.
|
||||
if not isVertical and not cfg("icon_only") then
|
||||
local text = string.format("CPU %d%% RAM %d%%", cpuInt, math.floor(ram or 0))
|
||||
if cfg("show_count") then
|
||||
text = text .. " · " .. count
|
||||
end
|
||||
return
|
||||
table.insert(children, ui.label({ text = text, fontSize = 11 }))
|
||||
end
|
||||
|
||||
barWidget.setGlyphColor("on_surface")
|
||||
local text = string.format("CPU %d%% RAM %d%%", cpuInt, math.floor(ram or 0))
|
||||
if cfg("show_count") then
|
||||
text = text .. " · " .. count
|
||||
end
|
||||
barWidget.setText(text)
|
||||
local container = isVertical and ui.column or ui.row
|
||||
barWidget.render(container({ gap = 6, align = "center" }, children))
|
||||
barWidget.setTooltip(tooltip)
|
||||
end
|
||||
|
||||
noctalia.state.watch("stats", update)
|
||||
|
||||
Reference in New Issue
Block a user