Lock-then-snapshot helper: settings first (cloned and released),
then timers (read and released). Never holds two scheduler mutex
guards across an .await, so two concurrent callers can’t deadlock
even if the rest of the codebase locks them in the opposite order.
Conclude the currently-active break. reason distinguishes
"completed" (taken in full), "dismissed" (user closed it
early), and "postponed" (countdown wasn’t honoured). Updates the
session counters, fires break_end hooks, hides every overlay
window, and emits break:end.
The (duration_secs, enforceable, manual_finish, hints) a break of
kind fires with. Single source for the scheduled-fire, resume, and
CLI-trigger paths, which each used to repeat this per-kind match.
Enforceability goes through test_break_enforceable so every path
shares one rule; duration / manual-finish / hints come from the
matching Settings accessors.
Called by the break overlay the moment it has rendered a break — any
successful IPC from the overlay proves its webview is alive and executing.
Acks the render-readiness watchdog (#196 / #226) so a healthy break is
never torn down. No scheduler state: just the process-wide ack.
Pause the scheduler. duration_secs = None pauses indefinitely;
Some(n) pauses for n seconds. Fires pause_start hooks and
emits the pause:changed event. Idempotent — a pause-while-paused
updates the deadline but doesn’t re-fire hooks.
Pause-state mutation core: updates the in-memory state, persists,
logs the event, and fires pause_start hooks on a true running→paused
edge. AppHandle-free so unit tests can drive it.
Push the active break out by the configured postpone interval
(with optional escalation by previous postpone count). Errors when
strict_mode / postpone_enabled = false block postpone or when
the per-break postpone cap is reached. Side-effects: bumps the
per-kind postpone counter, fires break_postponed hooks, hides
overlays.
Re-fire the most recently skipped/postponed break with the current
profile’s full settings (duration, hints, enforceability). Shared
by the renderer command and the tray menu handler. Errors with
"no break to resume" when the slot is empty.
Reset the next-break timer for kind so the user “skips” the
upcoming break. Shared by the renderer command and the CLI’s
skip subcommand. Errors when strict_mode is on.
Fire a long break right now and restart the rotation, exactly as if the
scheduled long break had come due (#258). Lets a user take their long
break early — a chore timer went off, the washing machine finished —
without waiting for it and without it doubling up later:
fire_scheduled_break re-anchors both interval clocks (a long break
swallows the pending micro). Bypasses suppression, matching the other
explicit manual triggers. Shared by the renderer command and the tray.
Mirrors the enforceability rule used by the scheduler’s normal
break-firing paths in run_loop.rs: micro/long obey their own
*_enforceable flag OR strict_mode, while sleep is always
enforceable.
Fire a one-off break of the given kind right now. Shared by the
renderer-facing trigger_test_break and the CLI’s trigger
command. Bypasses suppression checks (the user asked explicitly).