#+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.