aboutsummaryrefslogtreecommitdiff
path: root/docs/specs/2026-07-02-timer-panel-spec.org
blob: 6368d313d4a1ba77800c90f16d51063328e253b0 (plain)
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
114
115
116
117
118
119
120
121
122
123
#+TITLE: Timer GTK Panel
#+AUTHOR: Craig Jennings
#+DATE: 2026-07-02
#+TODO: TODO | DONE
#+TODO: DRAFT READY DOING | IMPLEMENTED SUPERSEDED CANCELLED

* DRAFT Timer GTK Panel
:PROPERTIES:
:ID:       25ed5321-f035-42b3-b115-69364d775f41
:END:
- 2026-07-04 Sat @ 12:36:56 -0500 — retrofitted by spec-sort; status set to DRAFT (evidence-based, human-confirmed)

* DRAFT Status
:PROPERTIES:
:ID:       1770af2e-b093-4024-a512-ae4324a2869f
:END:
- [2026-07-04 Sat] DRAFT — all four decisions resolved by Craig (standalone; retire fuzzel once the panel lands; timer chips gain 10m/30m/2h; wtimer watch mode over polling). Decision-complete; ready for a spec-review to flip it READY before build.
- [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. Live state comes
  from a new wtimer watch/subscribe mode (decision D), which the panel
  subscribes to for push updates instead of polling =render= on a timer.
  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
  (timer 5m / 10m / 15m / 25m / 30m / 60m / 2h; alarm +30m / top-of-hour /
  07:00; pomodoro default cycle; stopwatch none — decision C), 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

Decision B (below) resolved this: the fuzzel chain retires once the panel
lands. The panel becomes the single creation surface, replacing both the
click-driven bar path and the keybind/fuzzel path. Until the panel ships the
fuzzel flow stays (it's styled and tested); phase 4 removes it after the
panel proves out.

* Decisions (Craig)

** DONE Panel scope: standalone timer panel, or a page in the desktop-settings panel?
CLOSED: [2026-07-04 Sat]
Resolved (Craig, 2026-07-04): standalone, sharing the palette/css asset. Matches the net panel's one-domain-one-panel shape and keeps the timer dropdown small.

** DONE Fuzzel flow: keep as keyboard fast lane, or retire once the panel lands?
CLOSED: [2026-07-04 Sat]
Resolved (Craig, 2026-07-04): retire the fuzzel flow once the panel lands. The panel becomes the single creation surface; the keybind chain goes away rather than staying as a parallel path. (Implementation phase 4's "decide the fuzzel flow's future" is now decided — retire, don't keep.)

** DONE Presets: which chips per type?
CLOSED: [2026-07-04 Sat]
Resolved (Craig, 2026-07-04): timer chips are 5m / 10m / 15m / 25m / 30m / 60m / 2h (the strawman plus 10m, 30m, 2h). Alarm +30m / top-of-hour / 07:00, pomodoro default cycle only, stopwatch none — as the strawman.

** DONE Live updates: poll render (1s, like the bar) or a wtimer "watch" mode?
CLOSED: [2026-07-04 Sat]
Resolved (Craig, 2026-07-04): a wtimer watch/subscribe mode, not 1s polling. This grows wtimer with a new watch capability that the panel (and potentially the bar) subscribes to for live state, rather than reusing the poll cadence — cleaner at the cost of a wtimer addition. Fold the watch mode into the phase 1 CLI-backing seam.

* Implementation phases

1. PanelModel presenter + CLI-backing seam (TDD, GTK-free, 100% like the net
   PanelModel), plus the wtimer watch/subscribe mode (decision D) the presenter
   subscribes to for live state.
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); the panel and bar both track state via the
   wtimer watch subscription.
4. AT-SPI smoke + manual-testing checklist; retire the fuzzel flow (decision B)
   after the panel proves out over a week of real use.