Skip to content

fix: preserve window layout identities across restarts and screen lock - #7

Merged
ai-eks merged 6 commits into
mainfrom
fix/edge-window-layout-restore
Sep 14, 2026
Merged

ai-eks merged 6 commits into
mainfrom
fix/edge-window-layout-restore

Conversation

@ai-eks

@ai-eks ai-eks commented Sep 4, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Preserve exact AX window references separately for every saved layout; prune only deleted or replaced snapshots.
  • Persist a verifiable runtime identity with layout JSON: bundle ID, PID, process launch date, boot/login session, and CGWindowID.
  • After MousePortal restarts, re-enumerate windows and verify the persisted identity before falling back to metadata and then the same window index.
  • Reserve exact identities first, then use a maximum-cardinality, maximum-total-score metadata assignment (Hungarian algorithm) before the index fallback. Empty fields are not evidence, and titles/documents remain clues rather than proof of identity.
  • Capture through AX on sleep/session/lock notifications. On an actual screen lock, reconcile WindowServer records even when AX is only partially available, and supplement any already-frozen snapshot. Preserve existing AX geometry, snapshot ID, and retained-reference indexing; append only missing complete runtime identities.
  • Use CGWindowList only for enumeration/metadata and SLSGetWindowBounds for original position and size, avoiding transient lock-animation geometry. Do not label CG-only records as AX standard windows: persist unknown role/subrole plus requiresExactIdentity, and restore them only after exact identity and current AX standard-window type are verified.
  • Empty automatic captures and failed lock-supplement queries do not overwrite existing layouts. Distinguish an empty successful CG list from query/bounds failures, and preserve frozen snapshots on supplementation failure. No continuous geometry observer, guessed scale factor, or inverse-transform path is used.
  • Keep deletion behavior unchanged: deleting an automatic layout does not immediately recreate it, and startup does not auto-create a missing layout.
  • Require a snapshot ID for every AX capture; remove the unused optional-ID path while retaining per-layout identity caches.

Compatibility

  • Dynamically resolves the maintainer-approved private _AXUIElementGetWindow identity interface and the private SLSMainConnectionID / SLSGetWindowBounds geometry interfaces. Private-API compatibility and App Store distribution risks remain.
  • For AX-confirmed records, unavailable persisted identity data still permits retained-object matching and metadata/index fallback. CG-only records never use metadata/index fallback; records without a verifiable identity are omitted. When an existing AX record has no runtime identity, do not guess same-application deduplication during lock supplementation.
  • Existing layouts still decode with the new optional safety marker absent. Save a layout again to include current identity/type provenance. Restarting the target app or system invalidates exact identity: AX-confirmed records can use fallback matching, while CG-only records are skipped.
  • Mouse movement changes are deliberately excluded and published separately.

Verification

  • swift test: 210 tests passed on this branch.
  • swift build -c release: passed.
  • git diff --check: passed.
  • Regression coverage includes the review's greedy counterexample, equal-cardinality score optimization, and 200 small graph assignments compared with exhaustive enumeration; partial AX and frozen capture supplementation; complete-identity deduplication; repeated lock/failure behavior; and exact-only restoration of unknown window types after JSON reload. Existing identity, original-geometry, deletion, and sleep/manual capture regressions also pass.
  • Read-only native probe: 9 window identities were identical across two separate diagnostic processes; all 9 CGWindowIDs had the expected owner PID.
  • Read-only lock/unlock probe: on one display with three Edge windows, SLS bounds stayed at (0, 33, 1512, 884) while CG bounds shrank to (75, 78, 1362, 797). This does not establish compatibility for every application, display topology, or macOS version.
  • Before this optional-ID cleanup, the combined local build containing the geometry fix plus PR8 and the separate mouse fix passed 215 tests; the signed app was installed and its event tap verified enabled. The installed build has not been replaced for this cleanup or the subsequent review fixes. Full physical restore acceptance and a lock/unlock regression of the installed fix remain manual.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3aa96a3d1a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread MousePortal/Services/WindowLayoutEngine.swift
Comment thread MousePortal/Services/WindowLayoutService.swift Outdated
@ai-eks ai-eks changed the title fix: restore browser windows after tab changes fix: preserve window layout identities across restarts and screen lock Sep 12, 2026
@ai-eks

ai-eks commented Sep 12, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 99b9c23f95

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread MousePortal/Services/WindowLayoutEngine.swift Outdated
Comment thread MousePortal/Services/WindowLayoutService.swift Outdated
Comment thread MousePortal/Services/WindowLayoutService.swift Outdated

ai-eks commented Sep 13, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

Reviewed commit: 7b34caa3d6

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@ai-eks
ai-eks merged commit b761b53 into main Sep 14, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant