1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
#+TITLE: Timer GTK Panel
#+AUTHOR: Craig Jennings
#+DATE: 2026-07-02
#+TODO: TODO | DONE
#+TODO: DRAFT READY DOING | IMPLEMENTED SUPERSEDED CANCELLED
* DRAFT Status
:PROPERTIES:
:ID: 1770af2e-b093-4024-a512-ae4324a2869f
:END:
- [2026-07-02 Thu] DRAFT — initial spec from Craig's roam capture "give the
timer a gtk UI/UX like the network panel. spec this out."
* Metadata
| Field | Value |
|--------+---------------------------------------------------|
| Status | draft |
|--------+---------------------------------------------------|
| Owner | Craig Jennings |
|--------+---------------------------------------------------|
| Repo | dotfiles |
|--------+---------------------------------------------------|
| Kin | net panel (architecture donor), wtimer (backing), |
| | desktop-settings panel spec (sibling) |
|--------+---------------------------------------------------|
* Problem
The timer's whole UI is a chain of three fuzzel prompts (type, value, label)
plus a fourth for cancel. That flow can't show what's already running while
you create, can't offer one-tap presets, gives no feedback on a typo until
the add silently fails, and pomodoro state (phase, cycle) is only visible in
a tooltip. The 2026-07-02 styling pass made the dialogs presentable, but the
shape is still four blind modals for what is really one small control
surface.
* Goals
1. One panel, opened from the bar's timer module, that shows everything
running (live countdowns, pomodoro phase/cycle, paused state) and creates
new items without leaving it.
2. One-tap presets for the common cases (tea, pomodoro, quick alarm) next to
freeform entry, with inline validation before the add.
3. Per-item controls: pause/resume, cancel, promote to primary (the bar
glyph slot).
4. wtimer stays the single owner of timer state and the notification path;
the panel is a view over it, never a second engine.
* Design sketch
** Architecture — clone the net panel's proven stack
- GTK4 + gtk4-layer-shell dropdown anchored under the timer module, Blueprint
.blp compiled to committed .ui (=make ui=; compiler is dev-only).
- Humble-object split: GTK-free PanelModel presenter, unit-tested to 100%,
with thin widget bindings; one gated AT-SPI smoke via the
run-panel-smoke.sh pattern.
- Backing: shell out to the existing wtimer CLI (=add=, =toggle=, =cancel=,
=cycle=, =render=). =render= already emits a JSON payload; the panel polls
it (or subscribes to the same RTMIN+14 refresh signal) for live state.
wtimer's 89-case suite keeps owning the logic; panel tests fake the CLI
like every dotfiles suite fakes binaries.
- Dupre WIP palette CSS shared with the net panel (same factoring the
desktop-settings spec calls for — one palette asset, three panels).
** Layout sketch
- Header row: running-item count + a Clear All button (maps to cancel-all).
- Item list: one row per item — type glyph, label, live countdown / clock
time / phase+cycle for pomodoro, pause and cancel buttons, click-to-promote.
- Create strip: four type buttons (the wtimer glyphs), preset chips per type
(e.g. 5m / 15m / 25m / 60m for timers), a freeform entry validated with
wtimer's own parsers, an optional label field.
- Empty state: the create strip alone, centered.
** What happens to the fuzzel flow
The keybind/fuzzel path stays as the keyboard-fast lane (it's now styled and
tested); the panel replaces the click-driven path on the bar module. Whether
the fuzzel chain eventually retires is a decision below.
* Decisions (Craig)
** TODO Panel scope: standalone timer panel, or a page in the desktop-settings panel?
The desktop-settings spec (sibling DRAFT) could host timers as a page.
Standalone matches the net panel's one-domain-one-panel shape and keeps the
timer dropdown small; folding in means one panel binary fewer. Recommend
standalone, sharing the palette/css asset.
** TODO Fuzzel flow: keep as keyboard fast lane, or retire once the panel lands?
Keeping both costs two creation paths to maintain (though the fuzzel chain is
small and freshly tested). Recommend keep until the panel proves itself, then
revisit.
** TODO Presets: which chips per type?
Strawman: timer 5m/15m/25m/60m; alarm +30m/top-of-hour/07:00; pomodoro
default cycle only; stopwatch needs none. Adjust to taste.
** TODO Live updates: poll render (1s, like the bar) or a wtimer "watch" mode?
Polling reuses what exists and matches the bar's cadence; a watch/subscribe
mode is cleaner but grows wtimer. Recommend polling first.
* Implementation phases
1. PanelModel presenter + CLI-backing seam (TDD, GTK-free, 100% like the net
PanelModel).
2. Blueprint UI: item list + create strip, wired to the presenter; palette
css factored to the shared asset.
3. Bar integration: timer module left-click opens the panel (replacing the
fuzzel menu binding there), RTMIN+14 refresh keeps bar and panel in step.
4. AT-SPI smoke + manual-testing checklist; decide the fuzzel flow's future
after a week of real use.
|