Fix sleep/wake handling, midnight schedules, and improve settings UI#26
Merged
Conversation
Cancel break timers and dismiss overlay on system sleep to prevent rapid-fire auto-completions when Mac wakes. Replace native TabView with a custom tab bar to eliminate icon size jitter caused by frequent @EnvironmentObject re-renders.
Listen for com.apple.screenIsLocked/screenIsUnlocked via DistributedNotificationCenter. Cancel the break timer and dismiss any active overlay when the screen locks; reschedule the next break through the scheduling engine on unlock so time-window and daily-cap checks are preserved.
.buttonStyle(.plain) on macOS limits the clickable region to the natural content size, ignoring padding. Adding contentShape makes the entire padded frame tappable.
Negative tracking at -0.04 caused edge glyphs to be clipped at large serif font sizes. Reducing to -0.02 gives enough breathing room.
TimeWindow.contains() returned false for windows spanning midnight (e.g. 23:00-00:00) because end < start made the AND check impossible. Use OR logic when the window wraps past midnight.
Screen lock and system sleep during an active break dismissed the overlay but never emitted a CoordinatorEvent, leaving isBreakActive stuck at true. Now emits .breakSkipped so AppCoordinator resets state correctly. Also restarts the progress timer when a scheduled break enters the countdown threshold, preventing a ~10s stale display on first appearance.
System sleep or screen lock during a user-initiated pause destroyed the pause-resume timer and left isPaused=true permanently, blocking all future break scheduling. Wake/unlock handlers now check isPaused and call resume() instead of scheduleNextBreak(). Also extract duplicate handler logic into cancelAndDismissIfShowing() and add tests for all four system event handlers including the pause+sleep interaction.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Handle system sleep/wake and screen lock events to properly pause and resume break timers, fix schedule evaluation for time windows that cross midnight, and replace the native TabView with a custom tab bar for better control and hit areas.
BreakCoordinator.swift— added sleep/wake and screen lock/unlock handlers that cancel timers, dismiss active overlays, and reschedule breaks on resumeAppCoordinator.swift— observesNSWorkspacesleep/wake andDistributedNotificationCenterscreen lock/unlock notifications, restarts progress timer after break schedulingSchedule.swift—TimeWindow.containsnow handles midnight-crossing windows (e.g. 22:00–06:00)SettingsView.swift— replacedTabViewwith customSettingsTabBarusing rounded highlight buttons and expanded hit areas viacontentShapeAboutView.swift— replacedNSApplicationDelegateAdaptorwith parameter injection forSPUUpdater, added social links and copyrightTimerNumerals.swift— reduced tracking multiplier from -0.04 to -0.02 to prevent glyph clippingSchedulingTests.swiftHow it works
AppCoordinator.observeSystemSleep()registers for four system notifications:willSleep,didWake,screenIsLocked,screenIsUnlockedBreakCoordinatorcancels the pending break timer and dismisses any active break overlay (marking it as skipped)BreakCoordinator.scheduleNextBreak()recalculates and sets a fresh timerTimeWindow.containsdetects midnight crossover whenstart > endand usestime >= start || time < endinstead of a simple range checkDesign decisions
SettingsTabBarwith manual buttonscontentShapefor hit area expansion or custom highlight stylingNSApplicationDelegateAdaptorTest plan