Skip to content

Add optional reliable window stacking restoration #35

Description

@olerida

Problem

Settle captures the relative front-to-back order correctly, but macOS does not always apply the same order during restore. The current quiet, single-pass approach activates application groups and raises their windows without waiting for each activation to become effective. App activation is asynchronous, so lower layers can be reordered differently from the saved layout.

Observed case

Layout: 20 Jun 2026, 22:06

Saved stackingIndex values (smaller means closer to the front):

  1. Finder — 15
  2. Notes — 16
  3. Safari — 17

Expected front-to-back order: Finder → Notes → Safari.

Observed after restore: Finder → Safari → Notes. The frontmost window is correct, but the two lower application layers are swapped. The composite snapshot and persisted layout data retain the expected order, so the defect is in restoration rather than capture.

macOS constraints investigated

  • AXRaise on a background application may return success without changing its global WindowServer order.
  • Sending all AXRaise calls immediately does not reliably order windows across applications.
  • Setting AXFocused alone has the same limitation.
  • Direct SLSOrderWindow / CGSOrderWindow calls are rejected for windows owned by other processes with kCGErrorFailure (1000).
  • Repeated raise-and-verify passes add visible noise and still do not guarantee application-layer order.
  • Activating applications back-to-front works when each activation is allowed to complete before continuing.

Proposed setting

Add an optional Settings preference such as Reliable window ordering.

Default: off, preserving the current quieter best-effort restoration.

When enabled:

  1. Group matched windows by application.
  2. Determine application group order from the smallest saved stackingIndex in each group.
  3. Process application groups from back to front.
  4. Activate each application once.
  5. Wait until NSWorkspace.shared.frontmostApplication confirms the expected process, with a short timeout.
  6. Raise that application's windows from back to front.
  7. Finish by focusing the saved frontmost window.

The setting description must clearly warn that reliable ordering briefly changes application focus during restoration.

Acceptance criteria

  • The preference is persisted and defaults to disabled.
  • UI copy is localized in English, Spanish, Catalan, French, and German.
  • Disabled mode preserves the current quiet behavior.
  • Enabled mode synchronizes each application activation before processing the next group.
  • Timeouts prevent a non-activatable application from blocking the full restore.
  • Unit tests cover preference persistence, group ordering, activation timeout/continuation, and enabled/disabled behavior.
  • Manual validation covers at least three overlapping apps and confirms the saved application-layer order.
  • README and CHANGELOG document the optional behavior and its focus-change tradeoff.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:appNative macOS app workbacklogPlanned work not started yetbugSomething isn't workingenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions