Skip to content

Latest commit

 

History

History
83 lines (66 loc) · 3.05 KB

File metadata and controls

83 lines (66 loc) · 3.05 KB

Move Display

A tiny macOS menu-bar app that does exactly one thing: rearrange the position of your displays relative to each other — the same operation you'd otherwise do by dragging blue rectangles around in System Settings → Displays.

Inspired by BetterDisplay's "Easily move around displays relative to each other using the app menu" feature, but stripped down to just that.

Features

  • Lives in the menu bar (no Dock icon, no main window).
  • Click the menu bar icon to open a small popover with a visual arrangement canvas — each display is a rectangle scaled to its real pixel size.
  • Drag any display to reposition it. Edges snap to other displays' edges (left/right/top/bottom), and centers also snap, just like System Settings → Displays.
  • The main display gets a thin "menu bar" stripe at the top so it's easy to identify.
  • Auto-refreshes when you connect/disconnect a display.
  • Permanently saves the new arrangement (uses CGCompleteDisplayConfiguration(.permanently), the same API System Settings uses).

No DDC, no virtual screens, no brightness control, no resolution scaling — just visual display arrangement.

Build

Requires Swift 5.9+ and macOS 13+ (built and tested on macOS 26 / Tahoe).

./build-app.sh

This produces build/Move Display.app. To install:

cp -R "build/Move Display.app" /Applications/
open "/Applications/Move Display.app"

The first time it launches, macOS may ask you to allow it because it's ad-hoc signed. Right-click → Open the first time if Gatekeeper complains.

How it works

  • CGGetActiveDisplayList — enumerates connected displays.
  • IODisplayCreateInfoDictionary — pulls the localized product name.
  • CGBeginDisplayConfiguration / CGConfigureDisplayOrigin / CGCompleteDisplayConfiguration — moves displays atomically and persists the arrangement.
  • After every move, the layout is renormalized so that the main display sits at origin (0, 0), matching what System Settings does.

Project layout

MoveDisplay/
├── Package.swift
├── build-app.sh
├── Resources/
│   └── Info.plist            # LSUIElement = true (menu-bar only)
└── Sources/MoveDisplay/
    ├── MoveDisplayApp.swift   # @main entry point (accessory app)
    ├── AppDelegate.swift      # status item + popover wiring
    ├── ArrangementView.swift  # SwiftUI visual canvas + edge snapping
    └── DisplayManager.swift   # CoreGraphics + IOKit logic

Caveats

  • Only one display moves per drag. Drag each display in turn to build more complex arrangements — the layout updates after each drop.
  • After a drop, the layout is renormalized so the main display sits at (0, 0), matching macOS conventions. So if you drag the main display, what actually moves visually on the canvas is everything else (the main display always re-anchors at origin).
  • Requires macOS 13+. macOS doesn't require any special permission for display rearrangement, so no entitlements / TCC prompts.