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.
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.
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).