aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-17 09:16:58 +0200
committerDanilo M. <danix@danix.xyz>2026-09-17 09:16:58 +0200
commitaf64aed9b49c727d6b4050f3534115cead314f1d (patch)
treef085ad2769bd1583e85b941c43dd13d362f0b89c
parent2bdb74a1cbd4b33216d94713de1f1b3c81f631e2 (diff)
downloadconky-theme-udt-af64aed9b49c727d6b4050f3534115cead314f1d.tar.gz
conky-theme-udt-af64aed9b49c727d6b4050f3534115cead314f1d.zip
fix: size the weather card to its content
The first draft placed every band at a fixed pixel offset and let the arc absorb whatever height was left. In a 1x2 cell on this monitor that is 794px of arc: a cathedral arch under a fifth of a card of content, nothing like the mockup it was shaped after. Three changes, all visible in an offscreen render of the real widget: - Type sizes and band offsets scale with the rect, within clamps, so the proportions hold on the 1920 monitor as well as this one. - The arc gets a bounded band that follows the stats instead of being pinned to the bottom, so no dead strip opens between them. - The layout gives the widget a 1x1 cell. Its content is about 350px tall and a full-height cell cannot be filled without inventing data. Found before restarting conky by loading conky's own cairo bindings standalone and rendering the widget to a PNG, which is a far tighter loop than install, restart, switch workspace, screenshot. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
-rw-r--r--dashboard.lua5
-rw-r--r--docs/superpowers/plans/2026-09-17-weather-widget.md11
-rw-r--r--widgets/weather.lua62
3 files changed, 57 insertions, 21 deletions
diff --git a/dashboard.lua b/dashboard.lua
index dfd19ff..f5e74f3 100644
--- a/dashboard.lua
+++ b/dashboard.lua
@@ -20,7 +20,10 @@ local COLS, ROWS = 4, 2
local layout = {
{ widget = 'clock', col = 1, row = 1, w = 1, h = 2 },
- { widget = 'weather', col = 2, row = 1, w = 1, h = 2 },
+ -- 1x1, not 1x2: the card's content is about 350px tall, so a full-height
+ -- cell left a dead band down its middle. A single-row cell is as tall as
+ -- what it holds.
+ { widget = 'weather', col = 2, row = 1, w = 1, h = 1 },
}
-- ==========================================================================
diff --git a/docs/superpowers/plans/2026-09-17-weather-widget.md b/docs/superpowers/plans/2026-09-17-weather-widget.md
index 01cd767..14bf11f 100644
--- a/docs/superpowers/plans/2026-09-17-weather-widget.md
+++ b/docs/superpowers/plans/2026-09-17-weather-widget.md
@@ -1065,7 +1065,10 @@ In `dashboard.lua`, replace the `layout` table:
```lua
local layout = {
{ widget = 'clock', col = 1, row = 1, w = 1, h = 2 },
- { widget = 'weather', col = 2, row = 1, w = 1, h = 2 },
+ -- 1x1, not 1x2: the card's content is about 350px tall, so a full-height
+ -- cell left a dead band down its middle. A single-row cell is as tall as
+ -- what it holds.
+ { widget = 'weather', col = 2, row = 1, w = 1, h = 1 },
}
```
@@ -1182,7 +1185,11 @@ with a dot between the two times.
Compare against `idea1.png`. Likely first-pass problems, each fixed in
`widgets/weather.lua` and re-screenshotted:
- Text overflowing the card's right edge: reduce the font size or shorten the label.
-- The arc cramped or overlapping the stats: adjust the `ry2 + 10` offset.
+- The arc cramped or overlapping the stats: adjust the offsets in `draw()`.
+- Proportions wrong in the other direction, which is what actually happened:
+ the first draft let the arc absorb all leftover height and drew a 794px
+ arch. The widget now scales its type to the rect and bounds the arc band,
+ and the layout gives it a 1x1 cell.
- The sun dot off the curve: the Bezier evaluation and the drawn curve have
diverged, which means the control points differ between them.
diff --git a/widgets/weather.lua b/widgets/weather.lua
index 8a3b72d..9431b0c 100644
--- a/widgets/weather.lua
+++ b/widgets/weather.lua
@@ -106,36 +106,54 @@ function M.draw(cr, rect, colors)
return
end
+ -- The card is much taller than idea1's, so the bands are placed against the
+ -- rect rather than at fixed offsets: content sits in a block at the top, the
+ -- arc gets a bounded band pinned to the bottom, and the slack falls between
+ -- them. Letting the arc take all the leftover height instead drew a 794px
+ -- cathedral arch on this monitor, with the content crammed into the top
+ -- fifth. Scaled, not fixed, so the 1920 monitor gets the same proportions.
local y = inner.y
+ -- Type sizes scale with the card, within limits that keep them legible on a
+ -- small cell and stop them ballooning on a tall one.
+ local function clamp(v, lo, hi) return math.max(lo, math.min(hi, v)) end
+ local temp_size = clamp(inner.h * 0.075, 34, 60)
+ local glyph_size = clamp(temp_size * 0.80, 26, 46)
+ local label_size = clamp(inner.h * 0.014, 10, 14)
+ local desc_size = clamp(inner.h * 0.017, 12, 17)
+ local row_size = clamp(inner.h * 0.016, 11, 15)
+ local row_step = row_size * 1.9
+
-- Header: condition glyph, then the temperature with the city beneath it.
local glyph = weather.icon(w.id, now, w.sunrise, w.sunset)
- card.font(cr, card.FONT_MONO, 36, false)
+ card.font(cr, card.FONT_MONO, glyph_size, false)
card.rgba(cr, colors.highlight)
- card.text(cr, inner.x, y + 34, glyph)
- local gx = inner.x + card.advance(cr, glyph) + 14
+ local gy = y + glyph_size * 0.95
+ card.text(cr, inner.x, gy, glyph)
+ local gx = inner.x + card.advance(cr, glyph) + glyph_size * 0.4
- card.font(cr, card.FONT_HEAVY, 44, false)
+ card.font(cr, card.FONT_HEAVY, temp_size, false)
card.rgba(cr, colors.body)
- card.text(cr, gx, y + 38, string.format('%d\u{00B0}', math.floor(w.temp + 0.5)))
+ card.text(cr, gx, y + temp_size * 0.86, string.format('%d\u{00B0}', math.floor(w.temp + 0.5)))
- card.font(cr, card.FONT_MONO, 11, false)
+ card.font(cr, card.FONT_MONO, label_size, false)
card.rgba(cr, colors.label)
local city = (w.city or ''):upper()
if weather.is_stale(w.dt, now) then
city = city .. ' stale ' .. weather.age_str(w.dt, now)
end
- card.text(cr, gx, y + 56, city)
+ card.text(cr, gx, y + temp_size * 1.28, city)
-- Condition, in OWM's own words, first letter capitalised.
- card.font(cr, card.FONT_UI, 13, false)
+ card.font(cr, card.FONT_UI, desc_size, false)
card.rgba(cr, colors.body)
local desc = w.description or ''
desc = desc:sub(1, 1):upper() .. desc:sub(2)
- card.text(cr, inner.x, y + 84, desc)
+ local dy = y + temp_size * 1.95
+ card.text(cr, inner.x, dy, desc)
-- Rule.
- local ry = y + 100
+ local ry = dy + desc_size * 1.4
card.rgba(cr, colors.rule, 0.8)
cairo_set_line_width(cr, 1)
cairo_move_to(cr, inner.x, ry)
@@ -152,26 +170,34 @@ function M.draw(cr, rect, colors)
{ 'HUMIDITY', w.humidity and (w.humidity .. '%') or '--' },
{ 'WIND', wind_txt },
}
- local sy = ry + 22
+ local sy = ry + row_step
for _, row in ipairs(rows) do
- card.font(cr, card.FONT_MONO, 11, false)
+ card.font(cr, card.FONT_MONO, row_size, false)
card.rgba(cr, colors.label)
card.text(cr, inner.x, sy, row[1])
card.rgba(cr, colors.value)
card.text_right(cr, inner.x + inner.w, sy, row[2])
- sy = sy + 20
+ sy = sy + row_step
end
- -- Rule.
- local ry2 = sy + 2
+ -- The arc follows the stats rather than being pinned to the bottom, and
+ -- takes the smaller of its natural height and whatever remains. Pinning it
+ -- low left a dead band between the stats and the curve; the layout gives
+ -- this widget a cell sized to its content, so the drawing should end where
+ -- the content does.
+ local bottom = inner.y + inner.h
+ local arc_h = clamp(inner.h * 0.30, 90, 190)
+ local arc_y = math.min(sy + row_step * 0.6, bottom - arc_h)
+
+ -- Rule above the arc, riding with it rather than with the stats: it reads as
+ -- the arc band's top edge, and the gap left by a tall card falls here.
+ local ry2 = arc_y - 14
card.rgba(cr, colors.rule, 0.8)
cairo_move_to(cr, inner.x, ry2)
cairo_line_to(cr, inner.x + inner.w, ry2)
cairo_stroke(cr)
- -- The arc fills whatever height is left.
- draw_arc(cr, inner.x, ry2 + 10, inner.w, (inner.y + inner.h) - (ry2 + 10),
- colors, w, now)
+ draw_arc(cr, inner.x, arc_y, inner.w, arc_h, colors, w, now)
end
return M