summaryrefslogtreecommitdiff
path: root/internal/tui/tui.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-09 11:11:01 +0300
committerPaul Buetow <paul@buetow.org>2026-05-09 11:11:01 +0300
commiteed407b0e252a0105619daf79b8bc236ff5f487d (patch)
treeec2b1e6feb79d1eb2e9b4f10b5463cdc01f552db /internal/tui/tui.go
parent8da473aed2c3e901615294df398b26db5aea6032 (diff)
refine auto-reset timer cycle and pause on blur
Two follow-up refinements to the auto-reset timer added in 8da473a. - Hotkey cycle now goes off -> 10s -> 30s -> 60s -> 2m -> 5m -> off, giving the user finer control between 60s and 5m and a quicker starting cadence. - The timer now pauses while the TUI is blurred. SetFocused returns a tea.Cmd that re-arms a fresh tick on focus regain, and bumps the generation counter on every focus change so any tick scheduled before blur is dropped on arrival. autoResetTickCmd and handleAutoResetTick also gate on m.focused as defense in depth. - Dashboard chrome shows 'auto-reset: 30s (paused)' while the timer is enabled but blurred, distinguishing it from the disabled 'off' state. Tests cover the full preset cycle (including custom-value passthrough) and the pause-on-blur lifecycle: stale ticks ignored, current-gen ticks ignored while blurred, focus regain re-arms and fires the reset, no-op focus calls don't churn the generation counter, and the chrome label flips to '(paused)' as expected. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Diffstat (limited to 'internal/tui/tui.go')
-rw-r--r--internal/tui/tui.go19
1 files changed, 15 insertions, 4 deletions
diff --git a/internal/tui/tui.go b/internal/tui/tui.go
index e1d5581..63321ac 100644
--- a/internal/tui/tui.go
+++ b/internal/tui/tui.go
@@ -481,13 +481,22 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, nil
case tea.FocusMsg:
m.focused = true
- m.dashboard.SetFocused(true)
+ // SetFocused returns a tea.Cmd that arms a fresh auto-reset tick
+ // when focus returns (or nil if the timer is disabled). It also
+ // bumps the dashboard's autoResetGen so any tick that was scheduled
+ // before the blur and is still in flight is dropped on arrival.
+ focusCmd := m.dashboard.SetFocused(true)
if m.screen == ScreenDashboard && !m.attaching {
+ // Init() arms its own auto-reset tick at the post-bump
+ // generation, so discard focusCmd here to avoid two
+ // concurrently-live ticks racing the cadence.
return m, tea.Batch(m.dashboard.Init(), m.dashboard.SnapshotCmd())
}
- return m, nil
+ return m, focusCmd
case tea.BlurMsg:
m.focused = false
+ // SetFocused returns nil on blur but still bumps autoResetGen so
+ // that any in-flight tick scheduled before the blur is ignored.
m.dashboard.SetFocused(false)
return m, nil
case tea.KeyPressMsg:
@@ -666,12 +675,14 @@ func (m Model) handleGlobalKeyPress(msg tea.KeyPressMsg) (tea.Model, tea.Cmd, bo
// autoResetCycle is the ordered set of cadences exposed via the `I`
// hotkey. The first entry (0) disables the timer; the rest are
// progressively longer to give users a quick way to slow auto-resets
-// down on long traces or turn them off entirely.
+// down on long traces or turn them off entirely. The cycle wraps so
+// pressing `I` past the last preset returns to off.
var autoResetCycle = []time.Duration{
0,
- 15 * time.Second,
+ 10 * time.Second,
30 * time.Second,
60 * time.Second,
+ 2 * time.Minute,
5 * time.Minute,
}