Skip to content

fix: preserve layout identity and apply portals across display changes - #8

Merged
ai-eks merged 5 commits into
ai-eks:mainfrom
JaeHyeon-KAIST:pr/portal-layout-transitions
Sep 9, 2026
Merged

fix: preserve layout identity and apply portals across display changes#8
ai-eks merged 5 commits into
ai-eks:mainfrom
JaeHyeon-KAIST:pr/portal-layout-transitions

Conversation

@JaeHyeon-KAIST

Copy link
Copy Markdown
Contributor

Summary

Fix two layout/portal issues affecting multi-monitor setups, including operation with the main window closed.

1. Preserve matched layout identity after pruning

The matching path previously retained an array index across pruneLayouts. Removing an earlier unused layout could either cause an out-of-bounds crash or return a different retained layout. Resolve the result by its stable ID after pruning, while preserving the existing cleanup policy.

2. Apply saved portals when the display configuration changes

Move display-change coordination to an app-lifetime DisplayConfigurationCoordinator:

  • Match the active layout and apply its saved portals at startup and after display changes, independently of the main window.
  • Use a trailing 0.5-second debounce and query the current displays when it fires.
  • Apply portal geometry and display-resolution caches together for the event callback.
  • Preserve the last valid configuration when display enumeration is temporarily empty.
  • Cancel pending work on stop and reject stale scheduled callbacks.

Route Settings portal deletion/toggling through the current saved layout so changes survive configuration switches and reloads. Remove the unused reverse synchronization path. Preserve existing window-snapshot protection, migrate legacy portal lines using saved display snapshots, and retain a one-time local backup of previous global portal data before authoritative layout application.

Supporting changes

  • Regression tests for pruning, configuration transitions, scheduling/lifecycle, Settings edits, persistence, and legacy migration.
  • A local ad-hoc app-packaging script and README instructions; no Developer ID credentials or notarization upload required.
  • Implementation/review notes and a resource baseline/follow-up checklist in docs/.

Validation

  • swift test: 181 tests passed, 0 failures (2026-09-09).
  • swift build -c release: passed.
  • git diff --check origin/main...HEAD: passed.
  • Local packaged app launched and basic portal use was reported working.
  • Comprehensive physical monitor reconnect/sleep-wake testing.
  • Multi-day resource/leak and battery-impact validation.

The short background resource observation is only a baseline, not evidence of long-term stability. Regression tests use injected display providers and isolated preferences without starting global input taps.

Scope

This does not change portal crossing algorithms, layout retention policy, window-restoration behavior, or the separate shortcut-reset/global-enable persistence issues.

@ai-eks
ai-eks merged commit 8b93d88 into ai-eks:main Sep 9, 2026
1 check passed

ai-eks commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Thanks @JaeHyeon-KAIST for the fixes and regression coverage! We tested a real monitor disconnect/reconnect locally and confirmed that the saved portals restore correctly with the main window closed. Merged!

We'll address the legacy Settings upgrade-compatibility edge case and the relative output-path check in the local packaging script in follow-up changes before the next release.

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.

2 participants