Seconds per clock, and type that scales with the bar height

Seconds move from one bar-wide switch to a per-clock setting. A clock's own
`showSeconds` wins, the top-level one is the default for clocks with no
opinion, and the centre clock gets `local.showSeconds` since it has no entry in
`clocks[]`. An explicit false on a clock beats a true default, so the check is
for the property's presence rather than its truthiness.

The tick rate follows what is actually displayed: `anyShowsSeconds()` decides
between a per-second and a per-minute SystemClock, so a bar showing no seconds
does not wake the shell sixty times as often to redraw an identical minute.

`barSize` is now editable from the popup, and everything drawn on the bar is
sized against the theme's own bar height rather than pinned to the theme's
12px type. A taller bar carries proportionally larger text, gaps and rule; at
the theme's own height the scale is exactly 1, so nothing moves. Heights are
clamped to 12-120 rather than rejected, so a value the editor can produce can
never be one the config layer silently discards.

Fixes a latent bug this surfaced: updateRow() rebuilt a draft row from a fixed
pair of fields, so editing a clock's label would have thrown away its own
seconds setting. It now copies every key the row had.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MhxtL7WzL5XmuTd8GHbcTY
This commit is contained in:
2026-09-04 18:02:36 +02:00
co-authored by Claude Opus 5
parent 602a6db274
commit b3123ecb3b
6 changed files with 249 additions and 29 deletions
+30 -3
View File
@@ -84,6 +84,29 @@ function isWorkingHours(wall, hours) {
return hour >= start || hour < end
}
// Seconds are decided per clock, falling back to the config-wide default.
// An explicit `false` on a clock has to beat a `true` default, so the check is
// for the property's presence, not its truthiness.
function showsSeconds(entry, fallback) {
if (entry && typeof entry.showSeconds === "boolean") return entry.showSeconds
return fallback === true
}
// Whether anything on the bar is showing seconds, which is what decides
// between a per-second and a per-minute tick. Ticking every second when
// nothing displays them wakes the whole shell sixty times as often for no
// visible change.
function anyShowsSeconds(config) {
var cfg = config || {}
var fallback = cfg.showSeconds === true
if (showsSeconds(cfg.local, fallback)) return true
var entries = Array.isArray(cfg.clocks) ? cfg.clocks : []
for (var i = 0; i < entries.length; i++) {
if (showsSeconds(entries[i], fallback)) return true
}
return false
}
function isValidLabel(label) {
return typeof label === "string" && label.replace(/^\s+|\s+$/g, "").length > 0
}
@@ -93,6 +116,7 @@ function isValidLabel(label) {
// show the label struck through instead of quietly lying about the time.
function buildClock(entry, offsets, utcMs, localOffset, options) {
var opts = options || {}
var withSeconds = showsSeconds(entry, opts.showSeconds)
var timezone = String(entry && entry.timezone ? entry.timezone : "")
var label = isValidLabel(entry && entry.label) ? String(entry.label).replace(/^\s+|\s+$/g, "") : timezone
var offset = parseOffset(offsets ? offsets[timezone] : null)
@@ -100,7 +124,8 @@ function buildClock(entry, offsets, utcMs, localOffset, options) {
if (offset === null) {
return {
label: label, timezone: timezone, known: false,
time: "--:--", marker: "", delta: 0, relativeMinutes: 0, working: false
time: withSeconds ? "--:--:--" : "--:--",
marker: "", delta: 0, relativeMinutes: 0, working: false
}
}
@@ -112,7 +137,7 @@ function buildClock(entry, offsets, utcMs, localOffset, options) {
label: label,
timezone: timezone,
known: true,
time: formatTime(wall, opts.showSeconds === true),
time: formatTime(wall, withSeconds),
marker: dayMarker(delta),
delta: delta,
relativeMinutes: offset - localOffset,
@@ -165,7 +190,7 @@ function buildBar(config, offsets, utcMs, localOffsetRaw) {
// of the trailing group where they are visible but never mis-ordered.
right: right.concat(unknown),
center: {
time: formatTime(localWall, options.showSeconds),
time: formatTime(localWall, showsSeconds(cfg.local, options.showSeconds)),
date: localWall.getUTCFullYear() + "-" + pad2(localWall.getUTCMonth() + 1) + "-" + pad2(localWall.getUTCDate()),
offsetMinutes: localOffset
}
@@ -211,6 +236,8 @@ if (typeof module !== "undefined" && module.exports) {
dayDelta: dayDelta,
dayMarker: dayMarker,
isWorkingHours: isWorkingHours,
showsSeconds: showsSeconds,
anyShowsSeconds: anyShowsSeconds,
buildClock: buildClock,
buildBar: buildBar,
zonesToProbe: zonesToProbe,