aboutsummaryrefslogtreecommitdiffstats
path: root/lib/card.lua
AgeCommit message (Collapse)AuthorFilesLines
10 daysfeat: add an Immich memories card with click and scrollDanilo M.1-0/+1
A centred card showing today's "N years ago" photos from Immich, one at a time on a 30-second rotation, with when each was taken and where. bin/immich-fetch.sh runs from conky's execi every 30 minutes: it asks /api/memories for today, converts each preview to PNG (Cairo loads nothing else) and writes an index with the year, local capture time and place. The place needs the key's asset.read permission and reads '--' without it. The key lives in ~/.config/udt/immich.env, like the weather key, because a GPG-backed store would raise a pinentry unattended. The dashboard now registers lua_mouse_hook and hands pointer events to the widget under the pointer. On this card, scrolling steps through the photos and a left click opens the photo in Immich's web UI and hides the dashboard so the browser is not stuck beneath it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-18feat: add a title icon to every labelled cardDanilo M.1-0/+34
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.
2026-09-18refactor: unify card no-data face and fluid sizingDanilo M.1-4/+24
Extract card.notice so every cached card's no-data state is one fluid, theme-consistent face instead of a copy per widget, and delete the fixed-size card.label it replaces. Derive weather's arc geometry from its band (pad, curve room, sun dot, time labels) instead of fixed pixels, and cap the arc at a proportion of the card's width rather than 240px. Derive disks' bar-fallback height and its address type from the card's own label scale. Standardise the big-value factor to 1.0 across the fit_unit cards and document the big-value colour rule and the disks headline exception.
2026-09-17feat: add card.plot, a shared-scale line chartDanilo M.1-0/+54
Several series on one baseline and one ceiling. The shared ceiling is the point: scaled independently, a 200kB/s upload draws the same height as a 40MB/s download, which is a lie about a link's shape. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17fix: restore the line width card.ring sets, add card.truncateDanilo M.1-2/+26
A ring left its line width behind, so the next stroke on the card inherited a hairline several pixels thick. It already restored the cap for the same reason. card.truncate replaces byte slicing, which cuts a multi-byte character in half and emits an invalid sequence Cairo draws as a box. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17feat: fluid type for the gpu and cache cardsDanilo M.1-0/+28
The big value moves to the right of the heading, on the same baseline, so the card's width carries it instead of leaving the right half empty. Type now scales to fill the cell: card.fit_unit measures the rows and returns the largest size that fits the width, and the widget takes the smaller of that and its height budget, shrinking only where a row would collide.
2026-09-17fix: stop the widgets from stalling or raising the drawDanilo M.1-1/+1
Memoize hwmon_dir by chip name so sensor reads no longer popen grep on every frame, cache misses included. Floor fractional byte counts in card.human so it cannot raise. Drop the GPU package-temperature row, which duplicated the headline. Set umask before mkdir in both samplers so a fresh cache directory is not world-readable. Make render.lua exit non-zero on a draw error and tolerate an unset HOME.
2026-09-17feat: add the disks and cache cardsDanilo M.1-0/+4
disks draws a ring per filesystem from the df sample, with the NFS server address read from the device field and a labelled-bar fallback when the rings would be too small to read. cache shows the ~/.cache total and its four largest children from the du sample. card.ring now resets the cairo path first: a preceding card.text() leaves a current point, and cairo_arc() joins to it with a straight line, so the disks rings were drawn with stray chords. The ring primitive had no caller until now, which is why it went unnoticed.
2026-09-17feat: add bar, vbar, ring and threshold primitivesDanilo M.1-0/+91
2026-09-17feat: give the clock its own fontDanilo M.1-0/+12
Installs Oswald (OFL-1.1, from googlefonts/OswaldFont) under ~/.fonts/o/Oswald with its license, and points the clock numerals at it for the squared look the rounded Noto Sans Black did not have. Per-widget fonts needed no new machinery: card.font() already takes any family string, so FONT_* are shared defaults rather than a restriction. FONT_CLOCK joins them, and the weather card keeps FONT_HEAVY, so the two no longer have to agree. Cairo still cannot ask for a weight above bold, so a heavier cut is selected by family name as FONT_HEAVY already did. Worth knowing that fontconfig substitutes a default for a family it does not recognise, which is indistinguishable from the font not applying; fc-match tells you which happened. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16fix: step text cursors by advance, not ink widthDanilo M.1-0/+15
The date rendered as "16 /SEP /2026", each slash jammed against the next glyph. measure() returns the ink width, which ignores leading and trailing spaces because a space carries no ink, and clock.lua was using it to advance a cursor. Measured: " / " covers 6px of ink but advances 14px, so every separator lost 8px. Splits the two uses that were conflated in one function. measure() is for centring and right-aligning, where ink width is what you want; advance() returns x_advance and is for laying out runs of text left to right. The clock's date now uses advance() and reads "16 / SEP / 2026" with even gaps, verified by screenshot. Worth the split rather than changing measure() in place: text_right is a correct caller of the ink width, so one function cannot serve both and silently returning the advance would have broken alignment instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16fix: read the palette from the config file, and stop leaking extentsDanilo M.1-3/+16
Two defects, both found by review of the Cairo work and both confirmed by experiment rather than reasoning. The palette mechanism could not have worked. conky_parse('${color3}') returns an empty string: conky's colour variables emit renderer escape codes into conky.text, they never evaluate to a hex string, and ${default_shade_color} is not a variable at all, so conky_parse hands the literal text back. conky.config is not exposed to Lua either (_G.conky is nil) and conky_info carries only cpu_count and update_interval. What Lua does get is conky_config, the config file's path, so the colours are now parsed out of that file, where UDT has already substituted real hex. The pattern needs [%w_]+ rather than %w+ or it misses default_color and default_shade_color. The card fill also duplicated the border colour, both being color3, so filling at 0.55 alpha and stroking the hairline at 0.9 in one hue made the border invisible and the cards read as blobs rather than the mockup's thin outlines. The fill is default_shade_color now, a role every scheme already defines. card.measure allocated a cairo_text_extents_t per call, which leaks: 5000 allocations grow Lua's heap by 182KB that GC never reclaims, and :destroy() on each does not help, measured at the same 182KB. One reused module-level struct costs 0KB. A draw hook running every 2s would have bled memory for as long as conky stayed up, which no screenshot would ever reveal. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16feat: add Cairo card primitivesDanilo M.1-0/+86
Rounded-rect card with a hairline border, text helpers with measured alignment, and font selection. Cairo's font API stops at BOLD, so the Black face is reached by family name instead of weight: at size 90, '13' measures 100px as Noto Sans Black against 94px as Bold, confirming the heavier face is selected. The card radius is clamped to half the shorter side, because a larger radius makes the corner arcs overlap into a bowtie. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>