aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-18 19:09:23 +0200
committerDanilo M. <danix@danix.xyz>2026-09-18 19:09:23 +0200
commitd975c14645554cfbe9ba1d8c9279f51bd8407673 (patch)
treee5b60d21939ea02b4e2cb50a4342d071763083b1
parent7fddddcd39bb250cd2653e130c8f7899d2d3f19c (diff)
downloadconky-theme-udt-d975c14645554cfbe9ba1d8c9279f51bd8407673.tar.gz
conky-theme-udt-d975c14645554cfbe9ba1d8c9279f51bd8407673.zip
feat: add a title icon to every labelled card
Add card.ICON and a card.title helper that draws the glyph in the highlight colour before the label, at the label's own size. The eight labelled cards use it, in both the fit_unit width measurement and the draw, so the icon cannot overrun a narrow cell. Clock (no label) and weather (condition glyph already) are unchanged, and the no-data notice titles stay text-only. Codepoints were chosen against a rendered contact sheet, not fontconfig alone, since a wrong codepoint draws a plausible neighbour.
-rw-r--r--DESIGN.md7
-rw-r--r--README.md3
-rw-r--r--lib/card.lua34
-rw-r--r--widgets/breaktimer.lua6
-rw-r--r--widgets/cache.lua6
-rw-r--r--widgets/calendar.lua3
-rw-r--r--widgets/disks.lua3
-rw-r--r--widgets/gpu.lua6
-rw-r--r--widgets/network.lua6
-rw-r--r--widgets/slackware.lua7
-rw-r--r--widgets/system.lua6
11 files changed, 62 insertions, 25 deletions
diff --git a/DESIGN.md b/DESIGN.md
index 34e8d95..b463c1f 100644
--- a/DESIGN.md
+++ b/DESIGN.md
@@ -73,6 +73,7 @@ One language for every measured quantity, so state is read rather than decoded:
Nerd Font glyphs stand in for labels where an icon reads faster than a word:
the disks rings put a distro / house / disk / network glyph at each ring's
-centre, weather puts the condition glyph in its header. A wrong-but-present
-codepoint draws a plausible neighbour rather than failing, so render a new
-glyph and look at it before trusting it.
+centre, weather puts the condition glyph in its header, and every card title
+carries one in `highlight` before its label (the codepoints live in
+`card.ICON`). A wrong-but-present codepoint draws a plausible neighbour rather
+than failing, so render a new glyph and look at it before trusting it.
diff --git a/README.md b/README.md
index 2269a70..4956896 100644
--- a/README.md
+++ b/README.md
@@ -264,6 +264,9 @@ carries the primitives it should use rather than reaching for Cairo directly:
to a right edge.
- `notice(cr, inner, colors, title, note, hint)` draws the no-data face every
cached card shares when its sampler has not run.
+- `title(cr, x, y, icon, text, colors)` draws a card title: the icon in
+ `highlight`, the text in `label`. `title_str(icon, text)` returns the same run
+ as a string, for `fit_unit` to measure. The glyphs live in `card.ICON`.
- `measure(cr, s)` returns the **ink** size, what the glyphs actually cover. Use
it to centre or right-align.
- `advance(cr, s)` returns the **x_advance**, how far the cursor moves after
diff --git a/lib/card.lua b/lib/card.lua
index 3c520b9..e3cb11e 100644
--- a/lib/card.lua
+++ b/lib/card.lua
@@ -118,6 +118,40 @@ function M.card(cr, rect, colors, pad)
w = rect.w - pad * 2, h = rect.h - pad * 2 }
end
+-- Card title glyphs, all present in FONT_MONO (Inconsolata Nerd Font).
+--
+-- Verified by rendering a contact sheet and looking at each one, not by
+-- fontconfig alone: a missing glyph draws as an invisible blank and a wrong
+-- codepoint as a plausible neighbour, so neither fails visibly.
+M.ICON = {
+ system = '\u{F0EE0}', -- cpu-64-bit
+ gpu = '\u{F083E}', -- video-4k-box (no GPU glyph exists)
+ disks = '\u{F02CA}', -- harddisk
+ cache = '\u{F0ABA}', -- folder-clock
+ network = '\u{F0317}', -- lan
+ slackware = '\u{F318}', -- linux-slackware
+ breaktimer = '\u{F13AB}', -- timer
+ calendar = '\u{F0E17}', -- calendar-month
+}
+
+-- The gap between a title's icon and its text. One constant so the measured
+-- width and the drawn width cannot drift apart.
+local TITLE_GAP = ' '
+
+-- The full run a title occupies, for fit_unit to measure. Colour does not
+-- affect width, so measuring icon and text as one string is exact.
+function M.title_str(icon, text) return icon .. TITLE_GAP .. text end
+
+-- Draw a card title: the icon in `highlight`, the text in `label`, both at the
+-- caller's current font. x is the left edge, y the baseline.
+function M.title(cr, x, y, icon, text, colors)
+ M.rgba(cr, colors.highlight)
+ M.text(cr, x, y, icon)
+ x = x + M.advance(cr, icon .. TITLE_GAP)
+ M.rgba(cr, colors.label)
+ M.text(cr, x, y, text)
+end
+
-- The no-data face: the card chrome with a named message in it.
--
-- Every cached card draws this when its sampler has not run, so the board keeps
diff --git a/widgets/breaktimer.lua b/widgets/breaktimer.lua
index e6487b8..6fed30e 100644
--- a/widgets/breaktimer.lua
+++ b/widgets/breaktimer.lua
@@ -43,7 +43,7 @@ function M.draw(cr, rect, colors)
-- Fluid type: the height budget grows the content to fill the cell, the
-- measured width fit pulls it back where the phase label would overrun.
local groups = {
- { { 'BREAKTIMER', card.FONT_MONO, LABEL_F },
+ { { card.title_str(card.ICON.breaktimer, 'BREAKTIMER'), card.FONT_MONO, LABEL_F },
{ bt.countdown, card.FONT_HEAVY, BIG_F } },
}
for _, r in ipairs(rows) do
@@ -60,8 +60,8 @@ function M.draw(cr, rect, colors)
card.text_right(cr, inner.x + inner.w, inner.y + S * BIG_F, bt.countdown)
card.font(cr, card.FONT_MONO, label_size, false)
- card.rgba(cr, colors.label)
- card.text(cr, inner.x, inner.y + label_size, 'BREAKTIMER')
+ card.title(cr, inner.x, inner.y + label_size, card.ICON.breaktimer,
+ 'BREAKTIMER', colors)
local ey = inner.y + S * BIG_F + row_size * 1.6
local step = row_size * 2.0
diff --git a/widgets/cache.lua b/widgets/cache.lua
index 3772458..c6391ca 100644
--- a/widgets/cache.lua
+++ b/widgets/cache.lua
@@ -37,7 +37,8 @@ function M.draw(cr, rect, colors)
local row_n = #items
local S_h = inner.h * 0.94 / (1.78 + row_n * 0.64)
local groups = {
- { { 'CACHE', card.FONT_MONO, LABEL_F }, { c.total.label, card.FONT_HEAVY, 1.0 } },
+ { { card.title_str(card.ICON.cache, 'CACHE'), card.FONT_MONO, LABEL_F },
+ { c.total.label, card.FONT_HEAVY, 1.0 } },
}
for i = 1, row_n do
groups[#groups + 1] = { { names[i], card.FONT_MONO, ROW_F },
@@ -48,8 +49,7 @@ function M.draw(cr, rect, colors)
local row_size = S * ROW_F
card.font(cr, card.FONT_MONO, label_size, false)
- card.rgba(cr, colors.label)
- card.text(cr, inner.x, inner.y + label_size, 'CACHE')
+ card.title(cr, inner.x, inner.y + label_size, card.ICON.cache, 'CACHE', colors)
-- The total shares the header line with the label, set on the same baseline
-- and right-aligned: the width carries the number instead of an otherwise
diff --git a/widgets/calendar.lua b/widgets/calendar.lua
index b31e3b2..da173c9 100644
--- a/widgets/calendar.lua
+++ b/widgets/calendar.lua
@@ -122,8 +122,7 @@ function M.draw(cr, rect, colors)
card.text_right(cr, inner.x + inner.w, inner.y + big_size, title)
card.font(cr, card.FONT_MONO, label_size, false)
- card.rgba(cr, colors.label)
- card.text(cr, inner.x, inner.y + label_size, 'CALENDAR')
+ card.title(cr, inner.x, inner.y + label_size, card.ICON.calendar, 'CALENDAR', colors)
-- === Month grid =========================================================
-- 2.3, not 1.5: the weekday row sat close enough to the header that the
diff --git a/widgets/disks.lua b/widgets/disks.lua
index fa97b50..3922188 100644
--- a/widgets/disks.lua
+++ b/widgets/disks.lua
@@ -50,8 +50,7 @@ function M.draw(cr, rect, colors)
end
card.font(cr, card.FONT_MONO, label_size, false)
- card.rgba(cr, colors.label)
- card.text(cr, inner.x, inner.y + label_size, 'DISKS')
+ card.title(cr, inner.x, inner.y + label_size, card.ICON.disks, 'DISKS', colors)
local top = inner.y + label_size * 2.2
local avail_h = (inner.y + inner.h) - top
diff --git a/widgets/gpu.lua b/widgets/gpu.lua
index cd6cc2f..7d5f2ed 100644
--- a/widgets/gpu.lua
+++ b/widgets/gpu.lua
@@ -35,7 +35,8 @@ function M.draw(cr, rect, colors)
local row_n = #TEMPS + 1 -- VRAM + FAN
local S_h = inner.h * 0.94 / (2.088 + row_n * 0.646)
local groups = {
- { { 'GPU', card.FONT_MONO, LABEL_F }, { big_txt, card.FONT_HEAVY, 1.0 } },
+ { { card.title_str(card.ICON.gpu, 'GPU'), card.FONT_MONO, LABEL_F },
+ { big_txt, card.FONT_HEAVY, 1.0 } },
{ { 'ARC B580', card.FONT_MONO, LABEL_F } },
}
for _, t in ipairs(TEMPS) do
@@ -59,8 +60,7 @@ function M.draw(cr, rect, colors)
card.text_right(cr, inner.x + inner.w, y + S, big_txt)
card.font(cr, card.FONT_MONO, label_size, false)
- card.rgba(cr, colors.label)
- card.text(cr, inner.x, y + label_size, 'GPU')
+ card.title(cr, inner.x, y + label_size, card.ICON.gpu, 'GPU', colors)
card.rgba(cr, colors.value)
card.text(cr, inner.x, y + S + label_size * 1.7, 'ARC B580')
diff --git a/widgets/network.lua b/widgets/network.lua
index 5d1a8ca..3a11521 100644
--- a/widgets/network.lua
+++ b/widgets/network.lua
@@ -80,7 +80,8 @@ function M.draw(cr, rect, colors)
-- taken as the smaller of a height budget and a measured width fit.
local LABEL_F, BIG_F, ROW_F = 0.30, 1.0, 0.30
local groups = {
- { { 'NET', card.FONT_MONO, LABEL_F }, { '888.8M/s', card.FONT_HEAVY, BIG_F } },
+ { { card.title_str(card.ICON.network, 'NET'), card.FONT_MONO, LABEL_F },
+ { '888.8M/s', card.FONT_HEAVY, BIG_F } },
{ { '\u{F0318} 192.000.000.000', card.FONT_MONO, ROW_F } },
{ { '\u{F01DA} 888.8M/s', card.FONT_MONO, ROW_F },
{ '\u{F0552} 888.8M/s', card.FONT_MONO, ROW_F } },
@@ -98,8 +99,7 @@ function M.draw(cr, rect, colors)
card.text_right(cr, inner.x + inner.w, inner.y + S * BIG_F, rate_str(down))
card.font(cr, card.FONT_MONO, label_size, false)
- card.rgba(cr, colors.label)
- card.text(cr, inner.x, inner.y + label_size, 'NET')
+ card.title(cr, inner.x, inner.y + label_size, card.ICON.network, 'NET', colors)
local ey = inner.y + S * BIG_F + row_size * 1.4
local step = row_size * 2.2
diff --git a/widgets/slackware.lua b/widgets/slackware.lua
index f9afb70..9686f8a 100644
--- a/widgets/slackware.lua
+++ b/widgets/slackware.lua
@@ -74,7 +74,8 @@ function M.draw(cr, rect, colors)
-- Fluid type: the height budget grows the content to fill the cell, the
-- measured width fit pulls it back where a row would overrun.
local groups = {
- { { 'SLACKWARE', card.FONT_MONO, LABEL_F }, { age_txt, card.FONT_HEAVY, BIG_F } },
+ { { card.title_str(card.ICON.slackware, 'SLACKWARE'), card.FONT_MONO, LABEL_F },
+ { age_txt, card.FONT_HEAVY, BIG_F } },
}
for _, r in ipairs(rows) do
groups[#groups + 1] = { { r[1], card.FONT_MONO, ROW_F },
@@ -90,8 +91,8 @@ function M.draw(cr, rect, colors)
card.text_right(cr, inner.x + inner.w, inner.y + S * BIG_F, age_txt)
card.font(cr, card.FONT_MONO, label_size, false)
- card.rgba(cr, colors.label)
- card.text(cr, inner.x, inner.y + label_size, 'SLACKWARE')
+ card.title(cr, inner.x, inner.y + label_size, card.ICON.slackware,
+ 'SLACKWARE', colors)
local ey = inner.y + S * BIG_F + row_size * 1.6
local step = row_size * 2.0
diff --git a/widgets/system.lua b/widgets/system.lua
index d4f6188..98e0ae1 100644
--- a/widgets/system.lua
+++ b/widgets/system.lua
@@ -65,7 +65,8 @@ function M.draw(cr, rect, colors)
-- 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 } },
+ { { card.title_str(card.ICON.system, 'CPU'), card.FONT_MONO, LABEL_F },
+ { load_txt, card.FONT_HEAVY, BIG_F } },
{ { cpu_txt or '', card.FONT_MONO, ROW_F } },
{ { board_txt or '', card.FONT_MONO, ROW_F } },
{ { 'RAM', card.FONT_MONO, ROW_F }, { '999.9G / 999.9G', card.FONT_MONO, ROW_F } },
@@ -96,8 +97,7 @@ function M.draw(cr, rect, colors)
card.text_right(cr, inner.x + inner.w, y + big_size, load_txt)
card.font(cr, card.FONT_MONO, label_size, false)
- card.rgba(cr, colors.label)
- card.text(cr, inner.x, y + label_size, 'CPU')
+ card.title(cr, inner.x, y + label_size, card.ICON.system, 'CPU', colors)
-- The hardware this card is about, under the header. Truncated by character,
-- never by byte: a model string can carry a multi-byte character and half of