Problem
After you cancel a restart or shut down, programa stops saving your layout for the rest of the run, and the last snapshot it did save claims the session ended cleanly. Both bite at the same moment: programa snapshot list shows the newest archive as clean while it is actually stale.
The NSWorkspace.willPowerOffNotification handler (Sources/AppDelegate.swift:2152-2163) sets isTerminatingApp = true and saves with cleanShutdown: true. Nothing resets the flag when the shutdown does not happen. The only reset is Sources/AppDelegate.swift:1513, which covers the Cmd+Q warning being declined, not power off.
Two consequences:
- Autosave stays suppressed, because
SessionAutosaveCoordinator gates every tick on isTerminatingApp (Sources/SessionAutosaveCoordinator.swift:76). Anything you rearrange after the cancelled shutdown is never persisted.
- The newest snapshot is labelled a clean shutdown even if the app is later force killed.
The suppressed autosave predates #228. The misleading label is new, because cleanShutdown now surfaces in snapshot list and is the field you use to judge which archive is trustworthy.
Repro
- Launch programa with a few workspaces open.
- Start a macOS restart or shut down, then cancel at the confirmation prompt.
- Add or rearrange a workspace.
- Force kill programa:
killall -9 programa.
- Relaunch. The restored layout predates step 3, and
programa snapshot list reports the newest archive as clean.
Fix sketch
Clear isTerminatingApp when the power off does not proceed. macOS sends no "power off cancelled" notification, so the options are a short timer that clears the flag if termination never arrives, or clearing it on the next applicationDidBecomeActive. Whichever lands, cleanShutdown should only be written by a path that actually reaches termination.
Found while reviewing #228.
Problem
After you cancel a restart or shut down, programa stops saving your layout for the rest of the run, and the last snapshot it did save claims the session ended cleanly. Both bite at the same moment:
programa snapshot listshows the newest archive ascleanwhile it is actually stale.The
NSWorkspace.willPowerOffNotificationhandler (Sources/AppDelegate.swift:2152-2163) setsisTerminatingApp = trueand saves withcleanShutdown: true. Nothing resets the flag when the shutdown does not happen. The only reset isSources/AppDelegate.swift:1513, which covers the Cmd+Q warning being declined, not power off.Two consequences:
SessionAutosaveCoordinatorgates every tick onisTerminatingApp(Sources/SessionAutosaveCoordinator.swift:76). Anything you rearrange after the cancelled shutdown is never persisted.The suppressed autosave predates #228. The misleading label is new, because
cleanShutdownnow surfaces insnapshot listand is the field you use to judge which archive is trustworthy.Repro
killall -9 programa.programa snapshot listreports the newest archive asclean.Fix sketch
Clear
isTerminatingAppwhen the power off does not proceed. macOS sends no "power off cancelled" notification, so the options are a short timer that clears the flag if termination never arrives, or clearing it on the nextapplicationDidBecomeActive. Whichever lands,cleanShutdownshould only be written by a path that actually reaches termination.Found while reviewing #228.