Skip to content

feat: restore saved display arrangements - #11

Open
ai-eks wants to merge 1 commit into
mainfrom
aix-apply-display-layout
Open

ai-eks wants to merge 1 commit into
mainfrom
aix-apply-display-layout

Conversation

@ai-eks

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

Copy link
Copy Markdown
Owner

When display positions change unexpectedly, MousePortal detects a new arrangement and only previews the saved one. For example, shifting all three external displays 38 points to the left prevents the saved Camp portals from becoming active.

Add an Apply Arrangement button for saved arrangements that are not currently active. Restore all display origins in one CoreGraphics transaction, verify the resulting coordinates, and refresh the active arrangement and portals. Resolution, rotation, and the main display remain unchanged. Missing displays, incompatible sizes, mirroring, and ambiguous matches disable the action with an explanation.

New snapshots store ColorSync display UUIDs; legacy snapshots acquire them when their arrangement matches exactly. Restoration never relies on old display IDs, which macOS can reassign. Legacy snapshots use unique size matches; identical-size external displays require a uniquely matching uniform translation. The new UI strings cover all 20 languages, and the English and Chinese usage guides are updated.

Validation:

  • swift test: all 241 tests passed, including 15 new regression tests covering the Camp shift with reassigned IDs, swapped identical-size displays, snapshot migration, rejected matches, system failures, and result verification.
  • swift build -c release: passed.
  • All 20 localization files passed plutil -lint; git diff --check passed.
  • Inspected the actual ContentView in an isolated preview with a separate bundle ID, simulated shifted displays, and permission prompts disabled. Camp showed an enabled action; Home showed a disabled action and a display-count explanation. The preview did not move the physical displays.

This branch has not been installed in /Applications. The new button has not been used to move the user's current display arrangement.

@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: e225130fa7

ℹ️ 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 on lines +239 to +240
} else if selectedLayout != nil {
Button(action: applySelectedDisplayLayout) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Allow applying when physical displays are swapped

When two identified displays with the same dimensions exchange positions, DisplayLayout.matches still marks the saved layout current because it compares only geometry and isMain. This branch consequently hides the Apply button, even though DisplayArrangementPlan uses UUIDs and can correctly restore exactly this scenario (as covered by testUUIDsRestoreIdenticalDisplaysEvenWhenTheirPositionsAreSwapped). Determine whether the plan already matches the active display IDs/frames instead of using only currentLayoutID to decide whether the action is available.

Useful? React with 👍 / 👎.

@ai-eks ai-eks changed the title feat: 一键恢复保存的显示器排列 feat: restore saved display arrangements Sep 17, 2026
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