| Age | Commit message (Collapse) | Author | Files | Lines |
|
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
phase * 28 wrapped for math.maxinteger; multiply as a float so the
result goes through the non-finite check.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
deg, num, duration and moon_icon now return their missing-value
placeholder for NaN, inf and out-of-range input instead of raising from
%d or utf8.char. sun_t clamps NaN to 0 and age_str returns ? for a NaN
age. Drops the dead -0 fold in deg and fixes a mislabelled assertion.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
card.standard() draws the DESIGN.md card (title left, big value right,
label/value rows) from one fluid size and returns where it stopped, so
the forecast cards share it instead of copying breaktimer's layout five
times.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
Forecast and air quality from Open-Meteo, flattened by jq into the
tab-separated cache lib/weather.lua parses. The city is geocoded once
and cached; a failed air-quality call drops one line, not the cache.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
WMO codes to glyphs and words, moon phase, UV and AQI roles, and a
parser for the tab-separated cache the fetcher will write. Groundwork
for the Mirage-derived forecast cards.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Five weather cards (now, hourly, week, details, sky) adapted from the
Conky-Mirage theme and drawn in this repo's design language, with the
data source moving from OpenWeatherMap to Open-Meteo.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Both cards are now drawn by quickshell, so the conky copies go: the two
widgets, their samplers and texeci lines, their fixtures and icons, and
du_parse with human_bytes, which only the cache card used. kv_parse stays
for breaktimer; its test now runs on an inline string. README gains a
Samplers section listing what conky still schedules, and DESIGN.md's
examples point at the cards that remain. Their slots in the layout are
left open.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The reasons lived as comments in hypr-theme's autostart.lua. That file is
now edited by the quickshell settings window and carries no comments, so
they move here, beside the line they explain: the explicit -c config and
the [workspace special:dash silent] prefix, which the window rule cannot
replace because hl.window_rule rejects silent.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The card was a copy of nvtable's table, where installed-behind and
repo-behind share a row and are told apart by colour, and it read
"shipped" from the .info rather than the binary repo. The drawer's
updates page replaces it: one row per package under the action it needs
next, Slackware included. Removed: the card, its sampler and the
nvchecker run it started every 30 minutes (the drawer runs nvchecker
when its result is older than that), nvtable_parse with its test and
fixture, and the package-up icon. The card's slot in the layout is left
open; rearranging the board is a separate decision.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The quickshell island's performance panel now shows CPU, RAM,
temperatures, the GPU, disks and network, and warns from the status
pill when something runs hot, fills up, or the public IP drifts from
the pinned one. Two dashboards drawing the same numbers would drift
apart, so the four widgets go, with the disks and public IP samplers.
The island keeps writing ~/.cache/udt/pubip.txt in the same format.
The freed space is left empty for the user to rearrange.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
|
Cairo's toy text API binds one face with no per-glyph fallback, so an
emoji in a calendar event title rendered as a box in Noto Sans.
text/measure/advance now split strings into runs and draw emoji runs
(U+1F000-1FAFF, U+2600-27BF) in monochrome Noto Emoji, restoring the
caller's face afterwards. Nerd Font PUA icons stay in FONT_MONO.
Plain strings and invalid UTF-8 take the old single-call path.
No shaping: ZWJ sequences and flags draw as their parts. Pango via
lgi (built for Lua 5.4) is the upgrade path.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
At 0.1s the per-frame readings (temperatures, RAM, fan RPM) changed
ten times a second and read as jitter. 0.5s keeps the wheel scroll
responsive enough while settling the numbers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Sum drm-resident-vram0 from DRM fdinfo, the same per-client counters
gputop reads, counting each drm-client-id once since a client repeats
its totals on every fd it holds. One grep over /proc/*/fdinfo, about
10ms warm, sampled through new_gate every ~2s.
The 12 GiB total is hardcoded: xe exposes no VRAM capacity in sysfs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Conky gives Lua no way to request one redraw, so a scroll showed up to
2s late. Pointer enter and leave, which Hyprland sends on every toggle
of the special workspace, now switch conky_set_update_interval between
0.1s and the config's 2s.
At that rate the CPU and network counters would sample over 0.1s
windows and the chart would fill 20x faster, so both now sample through
data.new_gate on the /proc/uptime clock, about every 2s, and redraw
their last values in between. The samplers move to texeci: execi runs
in the main loop and a 0.7s nvtable or an Immich download stalled the
scroll.
Measured: about 12% of one core while visible, 0.5% while hidden.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Moves the nvchecker/nvtable table the login shell printed onto the
dashboard, as a wide card at the bottom centre. bin/updates-sample.sh
caches `nvtable -C -E` every ten minutes and starts nvchecker, fully
detached, at most every 30 minutes. The widget parses the cache and
colours it in the board's language: installed behind upstream is
critical, a shipped .info behind is a warning, with nvtable's status
dots per row and a legend on the bottom line. The mouse wheel scrolls
rows that do not fit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
A day with no memories left the card showing only a notice. When today
has none, immich-fetch.sh now merges the memories of each of the past
six days, skipping a day whose request fails, and marks the index with
a scope week line. The subtitle names where the photos come from,
Today or This week, before the i/n counter, and the empty notice reads
no memories this week.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The years-ago count read as a bare number unless you read the subtitle.
It now carries a small Y at its top-right, where a degree sign sits on a
temperature, and ago under it on the baseline. The subtitle drops its
now redundant "years ago" and keeps only the i/n counter.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
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>
|
|
With khal uninstalled the sampler still wrote a cache with a generated
key and no events, because khal's stderr is discarded. The card then
read "nothing this week" while an event was scheduled. Removing the
cache instead shows the card's "no calendar data" face.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The quickshell keybind reminder lists hyprctl binds -j, which reports
Lua actions as an opaque handle, so a bind shows what it does only
through its description. This was the one bind left undescribed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
The Slackware card's big value gave no hint it was the slackpkg ChangeLog
age. Add a small line under the title naming it.
The calendar's weekday initials were English. Use the Italian single-letter
form, matching the card's already-Italian breaktimer labels.
|
|
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.
|
|
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.
|
|
Replaces the Waybar module that used to show breaktimer.sh with a card
on the dashboard. The card's big value is the phase countdown, coloured
by phase with the same language the Waybar module used, and two rows
name the phase and what the countdown leads to.
Data comes from bin/breaktimer-sample.sh, run by conky at execi 5, which
reads the daemon's runtime files into a cache. The sampler owns the
kill -0 liveness check, because conky's Lua cannot run a process and a
dead daemon must read as 'fermo' rather than a stale 'running'.
Drops outside the work-hours window freeze the countdown while the phase
stays 'working'. The sampler detects this from the remain file's age and
the card reads it as 'outside working hours', which also covers a hung
daemon. The phase words and colour roles live in data.breaktimer_parse
so they are unit-tested; the card only draws the result.
|
|
|
|
The workspace rule pinning special:dash to DP-1 does not work: special
workspaces ignore a workspace_rule's `monitor` and open on whichever
monitor has focus. Verified on 0.56.2; upstream hyprwm/Hyprland#7990 and
#5570, both closed in the issues-to-discussions migration rather than
fixed.
The comment claimed the opposite, which was convincing because the rule
does register and `hyprctl workspacerules` reports it enabled. The rule
stays, so the intent is recorded and the line is ready if upstream fixes
it, and the bind now names the manual step: focus DP-1 first.
Also notes that the window stays on DP-3 once opened there, so a later
toggle is cropped until it is moved back, the conky surface being a
fixed 2560x1080.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Calendar to the middle column, with the clock and weather shifted down
and right to make room for it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Three changes to the calendar card:
The month grid drops further below the header. The weekday initials sat
close enough to read as part of the header rather than as the top of the
grid.
Event rows carry the date before the time, day/month with no year: the
window is a week and the grid above already names the month, so a year
would spend three characters on the one field that cannot vary.
A legend of the calendar colours is pinned along the card's bottom, and
the event rows now end above it rather than at the card's inner edge. It
lists every calendar khal declared a colour for, in name order so it
does not reshuffle between frames, since pairs() walks a hash.
The row budget also counted one row more than the drawing loop would
draw, which suppressed the '+N more' line exactly when it was needed:
the loop cut the row the count had already spent. Both now test the same
condition.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
The month grid with the week's appointments below it, colour-coded by
calendar. Events come from a cache file rather than a live call: khal
costs about 200ms of Python startup, which is two orders of magnitude
over the 2-second draw budget, so bin/calendar-sample.sh writes the
cache on a 5-minute execi and the widget only parses.
Calendar colours are read out of khal's own config by the sampler and
mapped onto the board's palette roles, so the card follows a scheme
change instead of pinning three literal hues.
khal will not emit an ISO date: {start-date} uses the user's dateformat,
which carries no year here, and a strftime spec inside the field raises.
The sampler asks for {start-date-long} and data.calendar_date recovers
the numbers by position, resolving day/month by magnitude and reading a
genuinely ambiguous pair day-first. A 2-digit year is refused rather
than guessed at.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
The two rows name two different pieces of hardware and read as one block in a
single colour. heading and highlight are the palette roles that carry no state
meaning, so they can stand for an identity; ok/warning/critical could not,
since those say how something is doing and these strings never change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Notes the two things a reader would otherwise get wrong: br0 is a bridge, so
local VM traffic shows up in the chart, and the disks card reads df's
available column rather than computing size minus used, which would overstate
free space by the root-reserved blocks.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Placement is provisional: there is no settled arrangement yet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Replaces the percentage, which the ring already draws as an angle. A number
repeating it costs a row in a column about 75px wide.
Free carries the threshold colour because it is the measured quantity; the
total is fixed and stays in the plain value colour, so each column has one
coloured number.
The cache card adopts card.truncate in the same pass: it was slicing names by
byte, which halves a multi-byte character.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Both read once: neither changes without a reboot, and /proc/cpuinfo repeats
its model-name line once per thread.
The two rows come out of the equaliser's height budget, since it is the
card's designated slack absorber. Its floor drops from 18px to zero: with
rows above it the band can genuinely run out of room, and a fixed floor
meant it kept height it did not have and the temperatures drew over it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
The big value is the time since slackpkg's ChangeLog changed, coloured green
under a day, amber to a week, red past it.
A cache with no changelog key is a different failure from no cache at all:
the sampler ran and the ChangeLog is what was missing, so the rows still draw
and only the age reads '--'. Collapsing the two would send the reader to the
wrong problem.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
GNU ls follows a symlink to a directory with or without a trailing slash, so
both forms count the packages correctly. Only -d lists the link itself.
The original claim came from a count taken where the path did not resolve at
all, and it reached the spec, the plan and two commit messages. The count was
always right; the reason given for it was not, and a comment that teaches the
next reader something false is worse than no comment.
Records the real trap in its place: ls aliased to a long format counts its
"total" header as a package.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Conky's Lua has no lfs, so it cannot stat a file, and counting 2800 package
files per draw would be a directory walk every two seconds.
Writes epochs rather than formatted dates. The shell function this replaces
rebuilds a date from ls -l output with the year hardcoded, which breaks every
January and on any file older than six months.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Two lines on one chart against a shared ceiling, one sample per pixel column
so nothing is interpolated. The history is module state sized from the card's
width, so moving the card reframes the window rather than clearing it.
The public address is refused once stale: an address that may no longer be
yours, displayed with confidence, is worse than a dash.
The fixture uses TEST-NET-1. This repository is public.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
The draw hook must never make a network call: a hung request blocks the
Cairo draw and freezes the dashboard. Thirty minutes, not the old config's
five, because a residential address is stable for days.
Validates the response before writing. A captive portal and a rate-limit
message both arrive with a 200 and would otherwise be drawn as an address.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Free space is read rather than derived: size - used overstates it by the
root-reserved blocks, tens of gigabytes on a large filesystem, none of it
available to anyone but root.
Also asserts fs[3], the row whose device name ends in a digit. It sits next
to a numeric column and is the row most likely to break a parser counting
fields, and nothing covered it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
The pattern required a literal CPU token immediately before the @, which the
one Intel fixture happens to carry. A Xeon reads 'E5-2680 v4 @ 2.40GHz' and a
Tiger Lake 'i7-1165G7 @ 2.80GHz', so both kept their clock on the card.
A generation prefix hid the vendor word from its anchor for the same reason:
'11th Gen Intel Core i7-1165G7' kept 'Intel'.
Three more forms added as tests. The Intel fixture was meant to keep the
stripping a rule, and one fixture was not enough to do it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Stripping by rule rather than by a table of known parts: a leading vendor
word, trademark noise, a trailing core count or clock. The Intel fixture
exists to keep it a rule.
DMI placeholders read as no board at all. 'To Be Filled By O.E.M.' on the
dashboard is worse than a blank row.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Only the first space separates, so a value keeps its own spaces. Values stay
strings: the sampler writes epochs and the widget decides whether an age
reads as hours or days.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
The widget passes conky's update_interval rather than letting it default, so
the argument path is the one that ships and nothing exercised it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Mirrors new_cpu_counter: cumulative counters need two samples to yield a
rate, and each direction carries its own previous reading.
Clamps a negative delta to zero rather than letting a 32-bit wrap or an
interface reset produce a spike. One bogus sample sets the shared autoscale
and flattens the entire window.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
|
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>
|