Back to buildsBUILD RECORD

MonitorMate / Native macOS utility / 2026

Bringing a saved display setup back after reconnecting.

MonitorMate saves macOS display arrangements and checks wake and reconnect events before restoring a matching layout, with separate controls for trying and keeping manual changes.

THE WORK

The project.

MonitorMate keeps saved display arrangements available when a Mac wakes or monitors reconnect. It identifies the connected displays, finds an exact matching profile and checks whether their positions have drifted before applying the saved geometry. A deliberate rearrangement in System Settings is treated differently from a wake or reconnect event, so differing from a profile is not enough on its own to trigger restoration.

That distinction depends on remembering how the displays changed. Core Graphics can emit several callbacks while a setup settles, and a quick unplug and reconnect can finish with the same display identities it started with. MonitorMate accumulates wake and topology flags through a 1.5-second debounce, preserving the reason to check the layout even when the final list looks unchanged.

Manual editing uses a separate draft. Apply changes the live arrangement, Keep saves it to the profile and Revert reapplies the captured previous arrangement without saving the draft. The ten-second countdown defaults to Keep. SwiftUI and AppKit present these controls while the underlying state keeps a preview, a live arrangement and a saved preference distinct.

ATTEMPTS & CORRECTIONS

What changed along the way.

  1. Waiting for Keep before saving a display draft
    At first
    Apply originally saved the draft into the active profile as soon as it changed the displays, before the ten-second confirmation window ended.
    What needed to change
    Choosing Revert could restore the previous live positions while leaving the rejected draft in the saved profile. A later restoration could therefore use an arrangement the user had just declined.
    The change
    The August 10 fix moved persistence from Apply to Keep. Apply captures the previous live state, Revert reapplies it without saving the draft, and a failed initial apply clears the pending revert snapshot.
    The result
    Revert now leaves the saved profile unchanged, while Keep saves the draft. The timer still chooses Keep on expiry. This behavior is supported by the recorded diff and current state transitions, not a fresh hardware exercise.

IMPLEMENTATION

Design choices.

  1. Remember event causes as well as the settled display list. A quick unplug and reconnect can restore the same identities while disturbing their positions, so final-snapshot comparison alone is insufficient.
  2. Require an exact display-set match before selecting a saved profile. This avoids applying geometry for a different combination of monitors, at the cost of needing a matching profile for each setup.
  3. Restore only after an eligible wake or topology event and only when geometry differs. A geometry-only change in System Settings is not treated as a fault simply because it differs from the saved arrangement.
  4. Save manual changes on Keep, not on Apply. Revert can then restore the previous live arrangement without preserving the rejected draft, while the countdown's default remains explicitly Keep rather than automatic rollback.
  5. Hold a re-entry guard through configuration and the follow-up refresh. Callbacks produced by the app's own apply operation should not immediately start another restoration; physical wake, dock and rapid-reconnect cases still need hardware coverage.

HOW IT FITS TOGETHER

Architecture.

  • Core Graphics callbacks enter a 1.5-second debounce window. Replacing pending work does not discard its accumulated wake or topology flags; the settled callback receives that context alongside a fresh display snapshot.
  • Stable display fingerprints connect a saved JSON profile to the current setup. Matching requires the same complete display set, and applying a profile resolves the active Core Graphics display identifiers again.
  • AutoFixPipeline checks the event context, global setting, matching profile, re-entry state and geometry drift before applying. A delayed refresh after success updates the remembered topology and releases the guard.
  • DisplayService translates the arrangement so the main display is at the origin, then submits it through Core Graphics configuration calls. Missing displays and configuration errors return failure instead of being treated as a successful arrangement.
  • The app holds the editable draft, previous live snapshot and saved profile separately. Apply captures and changes the live state; Keep persists the draft; Revert reapplies the snapshot; timer expiry follows the Keep path.
Explore the architecture map8 components · 10 connections

MonitorMate state and operating-system boundaries

Automatic correction and manual drafts share the display service but have different persistence rules.

Direct callAsync taskResponse / return
macOS
Application state
Profile state

Scroll or drag the background to move. Use the zoom buttons to resize.Arrow keys move between components. Enter selects.

Choose a component to explore

Select a numbered component on the map or use the component menu. Its details and connections will appear here.

No component selected.

All connections (10)
  1. 01 · Callbacks and wake02 · Display servicecallbacks · Async task
  2. 02 · Display service03 · Auto-fix pipelinesnapshot and context · Direct call
  3. 04 · Profile store03 · Auto-fix pipelinematching profile · Direct call
  4. 03 · Auto-fix pipeline07 · Core Graphics transactioneligible drift · Direct call
  5. 05 · Editable layout draft07 · Core Graphics transactionmanual Apply · Direct call
  6. 07 · Core Graphics transaction08 · Live display arrangementconfigure displays · Direct call
  7. 07 · Core Graphics transaction06 · Keep/Revert decisionmanual apply succeeded · Response / return
  8. 06 · Keep/Revert decision04 · Profile storeKeep or timeout · Direct call
  9. 06 · Keep/Revert decision07 · Core Graphics transactionRevert captured layout · Direct call
  10. 08 · Live display arrangement02 · Display servicerefresh · Response / return

MADE WITH

Swift · SwiftUI · AppKit · Combine · CoreGraphics · JSON · XcodeGen

SELECTED DEVELOPMENT RECORD

Engineering changes.

Implementation dates come from project records. “Recorded” is the date this portfolio entry was written.

  1. Retaining the cause of a display-event burstfixedRecorded

    The debounce now carries wake and topology flags into the settled check, including rapid reconnects that finish with the original display set.

    Source observedChanged

  2. Keeping a preview out of the saved profilechangedRecorded

    Apply changes the live arrangement; Keep persists it. Revert uses the captured previous layout without saving the draft, and the countdown still selects Keep.

    Source observedChanged

CHECKS & RESULTS

What was checked.

A source review shows what the code does. It is not a fresh test of the running app.

  1. Code and development records reviewedReviewed

    The code, tests and available development records were checked. Reported test results keep their original scope. No fresh app or live deployment check was run for this write-up.

    Scope of this check
    Code review, not a fresh run of the app

NEXT

Still to work through.

The implementation connects event handling to a restrained restore decision and separates a manual preview from profile persistence. Source inspection establishes those state transitions, not their behavior across every dock or display. A physical matrix covering wake, rapid reconnects, missing displays and deliberate rearrangement remains the next verification step.