aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-17 13:09:36 +0200
committerDanilo M. <danix@danix.xyz>2026-09-17 13:09:36 +0200
commit5b210415759bf0fbd605a5cee84a10450866530c (patch)
tree6996d4dbc6c9f556bbd018989d5891d95b989451
parentbc2bb5892eda1bbaf1409e2a260f8de5019a9d0d (diff)
downloadconky-theme-udt-5b210415759bf0fbd605a5cee84a10450866530c.tar.gz
conky-theme-udt-5b210415759bf0fbd605a5cee84a10450866530c.zip
feat: make the system card type fluid
The label, headline, RAM and temperature rows now derive from one base size, chosen from the cell height and a measured width fit, and the per-core equaliser absorbs the height left over. Bigger cell, bigger type instead of empty space; the size shrinks only on a width clash.
-rw-r--r--widgets/system.lua58
1 files changed, 40 insertions, 18 deletions
diff --git a/widgets/system.lua b/widgets/system.lua
index 752f61a..231192c 100644
--- a/widgets/system.lua
+++ b/widgets/system.lua
@@ -31,13 +31,34 @@ function M.draw(cr, rect, colors)
local inner = card.card(cr, rect, colors)
local function clamp(v, lo, hi) return math.max(lo, math.min(hi, v)) end
- local label_size = clamp(inner.w * 0.030, 11, 18)
- local big_size = clamp(inner.w * 0.085, 26, 56)
- local row_size = clamp(inner.w * 0.030, 11, 17)
-
local stat = data.slurp('/proc/stat')
local agg_total, agg_idle = data.cpu_times(stat or '')
local load = total_counter:sample(agg_total, agg_idle)
+ local load_txt = load and string.format('%d%%', math.floor(load + 0.5)) or '--'
+ local cores = data.per_cpu_times(stat or '')
+ local temp_n = #TEMPS
+
+ -- Fluid type. One base size S drives the label, headline, RAM and every
+ -- temperature row; the equaliser then absorbs the vertical room left over,
+ -- so the card fills its cell and S shrinks only where a row would overrun
+ -- the width. card.fit_unit supplies the width side of that.
+ local LABEL_F, BIG_F, ROW_F = 0.30, 1.0, 0.32
+ local groups = {
+ { { 'CPU', card.FONT_MONO, LABEL_F }, { load_txt, card.FONT_HEAVY, BIG_F } },
+ { { 'RAM', card.FONT_MONO, ROW_F }, { '999.9G / 999.9G', card.FONT_MONO, ROW_F } },
+ }
+ for _, t in ipairs(TEMPS) do
+ groups[#groups + 1] = { { t[3], card.FONT_MONO, ROW_F },
+ { '888\u{00B0}', card.FONT_MONO, ROW_F } }
+ end
+ -- Height the non-equaliser content needs, in units of S, plus a reserve for
+ -- the equaliser band. The smaller of that budget and the width fit is S.
+ local fixed_units = 1.30 + 1.13 + temp_n * ROW_F * 1.8 + 0.10
+ local S = clamp(math.min(inner.h * 0.96 / (fixed_units + 1.7),
+ card.fit_unit(cr, inner.w * 0.96, groups, 100)), 10, 72)
+ local label_size = S * LABEL_F
+ local big_size = S * BIG_F
+ local row_size = S * ROW_F
local y = inner.y
@@ -48,33 +69,35 @@ function M.draw(cr, rect, colors)
card.font(cr, card.FONT_HEAVY, big_size, false)
card.rgba(cr, load and card.threshold(load, 25, 75, colors) or colors.label)
- card.text(cr, inner.x, y + label_size + big_size,
- load and string.format('%d%%', math.floor(load + 0.5)) or '--')
-
- local ey = y + label_size + big_size + 14
+ card.text(cr, inner.x, y + label_size + big_size, load_txt)
- -- The equaliser: one bar per core, rising from a common baseline.
- local cores = data.per_cpu_times(stat or '')
+ -- The equaliser: one bar per core, rising from a common baseline. It takes
+ -- the room left between the header and the RAM/temperature block, so it is
+ -- the card's slack absorber.
+ local eq_top = y + label_size + big_size + S * 0.30
+ local bar_h = S * 0.18
+ local step = row_size * 1.8
+ local eh = clamp((inner.y + inner.h) - eq_top - (S * 1.13 + temp_n * step),
+ 18, math.huge)
local n = #cores
if n > 0 then
local gap = math.max(2, inner.w * 0.006)
local bw = (inner.w - gap * (n - 1)) / n
- local eh = clamp(inner.h * 0.315, 18, 165)
-- Below about 3px a row of sixteen bars is an illegible smear; drop to the
-- aggregate bar instead of drawing one.
if bw >= 3 then
for i, c in ipairs(cores) do
counters[i] = counters[i] or data.new_cpu_counter()
local pct = counters[i]:sample(c.total, c.idle) or 0
- card.vbar(cr, inner.x + (i - 1) * (bw + gap), ey + eh, bw, eh,
+ card.vbar(cr, inner.x + (i - 1) * (bw + gap), eq_top + eh, bw, eh,
pct / 100, card.threshold(pct, 25, 75, colors), colors)
end
else
- card.bar(cr, inner.x, ey + eh - 8, inner.w, 8, (load or 0) / 100,
+ card.bar(cr, inner.x, eq_top + eh - bar_h, inner.w, bar_h, (load or 0) / 100,
card.threshold(load or 0, 25, 75, colors), colors)
end
- ey = ey + eh + 16
end
+ local ey = eq_top + eh + S * 0.30
-- Memory. MemAvailable, not free: it already excludes reclaimable cache, so
-- it is the figure a person recognises as "used".
@@ -87,15 +110,14 @@ function M.draw(cr, rect, colors)
card.rgba(cr, colors.value)
card.text_right(cr, inner.x + inner.w, ey,
string.format('%s / %s', card.human(mem.used * 1024), card.human(mem.total * 1024)))
- ey = ey + 8
- card.bar(cr, inner.x, ey, inner.w, 8, frac,
+ ey = ey + S * 0.30
+ card.bar(cr, inner.x, ey, inner.w, bar_h, frac,
card.threshold(frac * 100, 25, 75, colors), colors)
- ey = ey + 22
+ ey = ey + bar_h + S * 0.35
end
-- Temperatures, each against its own ceiling.
card.font(cr, card.FONT_MONO, row_size, false)
- local step = row_size * 1.8
for _, t in ipairs(TEMPS) do
if ey + step > inner.y + inner.h then break end -- out of room: stop
local v = data.sensor(t[1], t[2])