swiftmacosapplescriptautomatorapple-developer

Is it possible to programmatically change the XDR Display Reference Mode (aka Preset) on macOS?


Apple's XDR Displays like the Pro Display XDR and the Liquid Retina Display XDR support Display Reference Modes, also known as Presets. These can be changed from within System Preferences > Displays > Display Settings > Presets (After selecting an XDR Display).

Is there a way to get the list of available Presets and change the current Preset programmatically? Whether it's through a script or through an API? It seems like ColorSync is used to change/set a color profile but I don't see any reference for setting a preset within ColorSync.

Documentation for Reference Modes: https://support.apple.com/en-us/HT210435


Solution

  • Yes, it can be done by compiling against the private MonitorPanel.framework which is what System Settings uses to change resolutions and presets.

    Here is a simple Swift file that can list and change presets along with the required headers to compile it. I also provide a compiled binary and Apple Shortcuts support in lunar.fyi for convenience.

    And here's some sample code to list displays with their active preset, then activating the "Design & Print (P3-D50)" preset for the first display.

    presets.swift

    guard let mgr = MPDisplayMgr(), let display = mgr.displays.first(where: \.hasPresets) else {
        exit(1)
    }
    
    print("\(display.displayName!): \"\(display.activePreset!.presetName!)\"")
    
    if let preset = display.presets.first(where: { $0.presetName == "Design & Print (P3-D50)" }) {
        print("Activating preset \"Design & Print (P3-D50)\" for \(display.displayName!)")
        display.setActivePreset(preset)
    }
    

    Bridging-Header.h

    #import <MonitorPanel/MPDisplayPreset.h>
    #import <MonitorPanel/MPDisplay.h>
    #import <MonitorPanel/MPDisplayMgr.h>
    #import <MonitorPanel/MPDisplayMode.h>
    

    Compiler command:

    swiftc -F$PWD/Headers \
        -F/System/Library/PrivateFrameworks \
        -framework MonitorPanel \
        -import-objc-header Bridging-Header.h \
        presets.swift -o presets
    ./presets