Skip to content

A cancelled shutdown suppresses autosave and records clean_shutdown: true anyway #230

Description

@arzafran

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:

  1. Autosave stays suppressed, because SessionAutosaveCoordinator gates every tick on isTerminatingApp (Sources/SessionAutosaveCoordinator.swift:76). Anything you rearrange after the cancelled shutdown is never persisted.
  2. 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

  1. Launch programa with a few workspaces open.
  2. Start a macOS restart or shut down, then cancel at the confirmation prompt.
  3. Add or rearrange a workspace.
  4. Force kill programa: killall -9 programa.
  5. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions