Repository navigation
Releases
v1.6.6
Contact and companion app
- Questions and bug reports go to info@simpledisplay.app (Settings → Contact, the website's footer and Contact button, and the README).
- Remote Display (remotedisplay.app), the remote desktop for macOS whose virtual monitors resize to your window, is linked from Settings and recommended wherever remote access comes up. SimpleDisplay prepares the displays; Remote Display streams them.
Housekeeping
- The Gatekeeper "Open Anyway" screenshot is gone from the repository and the website; builds have been notarized since v1.6.1.
Signed with a Developer ID and notarized.
Full Changelog: v1.6.5...v1.6.6
v1.6.5
A simpler virtual display editor
The editor no longer scrolls. It is a five-row form that fits the popover at a glance: Name, Preset (one popup button grouped by iPhone, iPad, Mac and TV & Others, with the current match checked), Panel size in pixels, Zoom (1x or 2x Retina, with the resulting "looks like" size next to it) and, when editing, the live mode. Picking a preset fills the size and, unless the display already has a custom name, the name.
The warning banner that still pointed at the removed "clean cached data" tool is gone; a single quiet line appears only when there are changes to apply.
Signed with a Developer ID and notarized.
Full Changelog: v1.6.4...v1.6.5
v1.6.4
Housekeeping: the ColorSync cleanup tool is gone
Settings no longer has Clean display cache. It killed colorsyncd, deleted the display .icc profiles and macOS's display preferences with an admin password, and existed only to recover from the ICC profile leak that random virtual display serials used to cause. Since v1.5.0 every virtual display keeps a stable identity, so nothing accumulates any more, and wiping the window server's display preferences would now also erase the per-display-set mode memory the app relies on (see v1.6.3). The sRGB profile that was pinned on every new virtual display is gone too.
Still in place: the fix for the ColorSync deadlock with two identical physical monitors (sRGB assigned to duplicates at launch). That is a different bug.
If you have profiles left over from builds older than v1.5.0 and want them gone:
sudo rm /Library/ColorSync/Profiles/Displays/*.icc
Signed with a Developer ID and notarized.
Full Changelog: v1.6.3...v1.6.4
v1.6.3
Resolution and zoom, from the menu bar
Every display row now has a resolution menu in place of its mode caption: Retina "looks like" sizes, native sizes and, per size, the refresh rates the display offers. It works for physical and virtual displays alike. A virtual display remembers the mode you pick and re-applies it after topology changes and on the next launch.
The virtual display editor starts from the display's saved panel size and zoom (not from whatever mode happens to be live), shows the live mode as "Active", and replaces the HiDPI switch with a 1x / 2x Retina zoom control that spells out the resulting "looks like" size.
Bug fix: the virtual main display no longer shrinks when you turn a monitor off
macOS remembers a mode per display identity and per set of connected displays. Turning your physical monitor off makes "virtual only" a different set, with its own remembered mode, so a 3440x1440 virtual display could fall back to 1720x720 the moment the monitor went dark. The configured (or picked) mode is now re-applied after every topology change the app makes, and committed permanently, so both sets end up remembering the right mode.
More fixes around modes and mirrors
- A display gets its own mode back when a mirror ends (a mirror slave runs at the master's mode and macOS did not reliably restore the previous one: 1920x1080 → 1280x720 → 800x600 over two cycles), and when it is turned back on from a row rebuilt after a relaunch. The mode a display had is now saved when it is turned off or mirrored, and restored by UUID afterwards, verified once the topology settled.
- Mode changes are written to macOS's display preferences only while no display is mirrored. A permanent commit made while a mirror was active baked the mirror set into the preferences, and macOS re-created the mirror on its own later.
Automation
simpledisplay://mode?id=N|name=S&width=W&height=H[&hidpi=true|false][&refresh=N]andsimpledisplayctl modeswitch any display to one of the modes it offers.
Also
- The DMG opens with its background and icon layout again; the Finder step of the build had been failing silently for a long time.
Signed with a Developer ID and notarized. Verified on a macOS 26 VM with 81 scripted checks (docs/real-disable-vm/).
Full Changelog: v1.6.2...v1.6.3
v1.6.2
Bug fix: virtual displays come up in their configured mode
A virtual display could come up in a mode macOS remembered for its identity instead of the one you configured (for example a 3440x1440 display appearing as 1720x720), because CGVirtualDisplay accepts the settings but the window server keeps the remembered mode, and it never switches the mode of the main display without a real configuration commit. SimpleDisplay now checks every virtual display after launch, creation and reconfiguration and re-applies the configured resolution and HiDPI setting through CGConfigureDisplayWithDisplayMode. The commit is permanent, so macOS remembers the right mode from then on.
Verified on the macOS 26 VM: a new HiDPI display created on a slot whose identity remembered 1280x720 comes up at 1600x900 HiDPI.
Signed with a Developer ID and notarized, like v1.6.1.
Full Changelog: v1.6.1...v1.6.2
v1.6.1
Opens without the Gatekeeper block
The DMG is now signed with a Developer ID certificate and notarized by Apple, with the notarization ticket stapled to both the app and the disk image. macOS opens it like any other app; no more System Settings → Privacy & Security → Open Anyway. (Notarization is an automated malware scan; the private APIs the app relies on are not an issue for it.)
Menu bar icon
- The menu bar glyph introduced in v1.6.0 has bolder resize marks: on a non-Retina menu bar (1x) the thin marks blurred into a plain monitor and the icon still read as generic. It stays a template image, so it adapts to light and dark menu bars.
For maintainers
make notarizeandmake release(see CONTRIBUTING.md) produce the notarized DMG and replace the ad-hoc one the Release workflow attaches; the signing identity is picked by team, never by name.
Everything else is v1.6.0: real display disable via CGSConfigureDisplayEnabled, mirroring as a separate action, the 15-second countdown when turning off the last visible display, simpledisplayctl enable/disable/mirror/unmirror, and persistent identities for virtual displays.
Full Changelog: v1.6.0...v1.6.1
v1.6.0
Disabling a display now turns it off for real
Until now, "disabling" a display mirrored it onto another one: the panel stayed lit showing a copy of your main screen and kept its place in the arrangement. SimpleDisplay now uses the private CGSConfigureDisplayEnabled API (the same mechanism displayplacer uses): the display goes dark and leaves the desktop while staying connected, and comes back with one click. Based on PR #1 by @zhigang1992, thank you.
- A disabled display drops out of macOS's display list, so SimpleDisplay keeps a greyed-out row for it (persisted across launches) with a working toggle. Rows are reconciled by display UUID, so a display that comes back with a different ID, or an ID that macOS reassigned to another monitor, can't be toggled by mistake.
- The HiDPI mode a display had before being turned off is restored when it comes back.
- Turning off your last visible display (only virtual displays would remain) is allowed but guarded: a banner counts down 15 seconds and turns it back on unless you click Keep off. Only a confirmed choice is re-applied on launch; if the app quits mid-countdown it brings the display back on the next start.
Mirroring is a separate action
Prefer to keep a monitor on? The new mirror button next to each physical display's toggle mirrors it onto the main display, and back. Mirrors are persisted, re-applied on launch and dissolved before sleep. Virtual displays can't be mirror sources: on macOS 26 that crashes the window server (verified, see docs/real-disable-vm), so the app refuses it. Mirroring a physical display onto a virtual one works and is the remote-desktop use case.
Automation
- New
simpledisplay://actions:mirror,unmirror, anddisable?…&headless=trueto confirm turning off the last visible display up front (remote sessions, scripts). simpledisplayctlgainsenable,disable [--headless],mirrorandunmirror.simpledisplay://statusJSON includesmirrorOf.
Bug fixes
- Virtual displays keep their identity across launches: the serial slot is now persisted per display, so removing one virtual display and relaunching no longer makes another inherit its identity and the mode macOS remembered for it (HiDPI lost).
- Persisted display state is applied only once the display topology has settled, so virtual displays restored at launch are no longer skipped.
- Removing a virtual display that was disabled no longer leaves a dead row or a stale persisted flag behind.
Look and feel
- The menu bar icon is now the app's own glyph (a template image that adapts to light and dark menu bars) instead of the generic system symbol; the popover and Settings show the real app icon.
Notes
CGSConfigureDisplayEnabledis undocumented; likeCGVirtualDisplay, it may change in future macOS versions.- Verified on a clean macOS 26.6.2 VM with 67 scripted checks (
docs/real-disable-vm/). Sleep/wake with real monitors could not be exercised in the VM; please report anything odd.
Full Changelog: v1.5.0...v1.6.0
v1.5.0
Bug Fixes
- ColorSync profile leak fixed at the root. Virtual displays now use a stable per-slot serial number instead of a random one, so macOS sees the same monitor every time and reuses its ICC profile. Previously every create/destroy left a new
.iccin/Library/ColorSync/Profiles/Displaysand keptcolorsyncd/displayservicesbusy. Verified on a clean macOS 26 VM: 100 create/remove cycles → 1 profile (was 96, growing by one per cycle). Details and measurements in docs/colorsync-serial-leak.md. - Removed the ColorSync workarounds that no longer make sense (deleting profiles on remove, device unregister, admin-password prompt). The Fix color profiles button in Settings stays as a recovery tool for machines that already accumulated profiles with older builds.
New Features
simpledisplayctl remove --name <name>removes a virtual display by name.- New
simpledisplay://actionsenable,disableandstatus(JSON snapshot written to/tmp/simpledisplay-status.json) for remote control and scripting.
Full Changelog: v1.4.0...v1.5.0