Skip to content

Latest commit

 

History

33 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OhMyDisplay app icon

OhMyDisplay

A macOS menu bar app for display profiles and daily controls.

The app can:

  • Show connected displays from the menu bar.
  • Change HiDPI, resolution, and refresh rate.
  • Change display mode, dithering, and ICC profile.
  • Save, rename, delete, and switch display profiles.
  • Keep the selected profile applied after wake, display changes, external changes, and periodic checks.

Risky resolution, display mode, and profile changes use a short Keep/Restore confirmation so you can return to the previous state.

The project also includes omd, a companion CLI for terminal use, scripts, and automation. The app and CLI use the same display control core.

Disclaimer

This software only sets display modes reported by the device. Even so, a display may report a mode that it does not actually support, which can cause unexpected behavior or other adverse effects. Use it at your own risk.

Some display properties are backed by public CoreGraphics, ColorSync, and IOKit APIs. Display mode control uses Quartz/CADisplay behavior that is not part of a stable public Apple API surface, so it may vary across macOS releases and display hardware.

omd CLI

Use omd when you want the same display control from a terminal, script, or .command file.

The CLI can:

  • List connected displays and stable selectors.
  • Read the current display state.
  • List available resolution modes.
  • List available display modes.
  • List installed ColorSync ICC profiles.
  • Set resolution modes by exact mode ID or by user-facing options.
  • Set display modes by exact mode ID or by user-facing options.
  • Set dithering on or off.
  • Set a display ICC profile.
  • Emit JSON for scripting and automation.

Requirements

  • macOS 14 or newer
  • Swift 6 toolchain

Build

Build the app bundle:

Packaging/package-app.sh

The app is written to:

dist/OhMyDisplay.app

Open the app:

open dist/OhMyDisplay.app

Build the CLI:

swift build -c release --product omd

The executable is written to:

.build/release/omd

Examples below assume omd is on your PATH. If not, replace omd with .build/release/omd or .build/debug/omd.

For development builds:

swift build --product omd
.build/debug/omd version

CLI Quick Start

List displays:

omd display list

Read the main display state:

omd display get

List available resolution modes for the main display:

omd display resolutions

List available display modes for the main display:

omd display modes

List installed ICC profiles:

omd icc list

All read commands support JSON output:

omd display get --json
omd display resolutions --json
omd display modes --json
omd icc list --json

CLI Display Selection

--display defaults to main for display-scoped commands:

omd display get
omd display set --dithering off

For scripts that target a specific display, copy a stable selector from:

omd display list

Then pass it explicitly:

omd display get --display 'uuid:...'
omd display set --display 'uuid:...' --dithering off

--display all is not supported for mutation.

CLI Setting Display State

Exact mode IDs are copied from the list commands.

Set an exact resolution mode:

omd display resolutions
omd display set --resolution-mode '<resolutionMode>' --yes

Set an exact display mode:

omd display modes
omd display set --display-mode '<displayMode>' --yes

You can also ask omd to resolve a mode from user-facing flags.

Set a resolution by logical size, HiDPI state, and refresh rate:

omd display set --resolution 1920x1080 --hidpi on --refresh 120 --yes

Set display-mode properties for the current timing:

omd display set --encoding rgb --bpc 10 --range full --hdr sdr --yes

Combine a resolution change with semantic display-mode properties:

omd display set \
  --resolution 1920x1080 \
  --hidpi on \
  --refresh 120 \
  --encoding rgb \
  --bpc 10 \
  --range full \
  --hdr sdr \
  --yes

Direct settings:

omd display set --dithering on
omd display set --dithering off
omd display set --icc ~/Library/ColorSync/Profiles/Display.icc

When a resolution or display mode may change, non-interactive use requires --yes. Interactive terminals prompt before applying the change.

Operations run in this order:

resolution -> displayMode -> dithering -> icc

If a later display-mode operation fails after a resolution change, omd attempts to restore the original resolution and display mode.

CLI Command Reference

omd display list [--json]
omd display get [--display <display>] [--json]
omd display resolutions [--display <display>] [--json]
omd display modes [--display <display>] [--json]
omd display set [--display <display>] [set options] [--json] [--yes]
omd icc list [--json]
omd version

display set options:

--resolution-mode <resolutionMode>
--resolution <width>x<height>
--hidpi on|off
--refresh <hz>
--display-mode <displayMode>
--encoding rgb|ycbcr
--bpc <bits-per-component>
--range full|limited
--chroma 444|422|420
--hdr sdr|hdr10|dolby-vision|dolby-vision-low-latency
--vrr on|off
--dithering on|off
--icc <path>

Rules:

  • --resolution-mode cannot be combined with --resolution, --hidpi, or --refresh.
  • --display-mode cannot be combined with semantic display-mode flags such as --bpc, --hdr, or --vrr.
  • --display-mode cannot be combined with a resolution change. Use semantic display-mode flags if the desired display mode should be resolved after the resolution changes.
  • Omit --encoding and --chroma for Dolby Vision modes; they report none in JSON and - in human tables.
  • Omit --chroma for RGB modes; use it for YCbCr 444, 422, or 420 modes.
  • Semantic display-mode selection defaults to --vrr off; pass --vrr on to select a VRR mode.

CLI Exit Codes

0   success
2   blocked before mutation
3   partial failure after a mutation was attempted
64  usage error
70  unexpected error

For automation, prefer --json; set commands include per-operation status and whether a mutation was attempted.

Swift Library

The package also exposes OMDCore as a thin Swift library.

import OMDCore

let displays = try listDisplays()
let display = displays.first { $0.isMain }!

let state = try readDisplayState(display.selector)
let resolutions = try listResolutionModes(display.selector)
let displayModes = try listDisplayModes(display.selector)

let result = try setDithering(display.selector, enabled: false)

Public functions:

listDisplays()
readDisplayState(_:)
listResolutionModes(_:)
setResolutionMode(_:modeID:)
listDisplayModes(_:)
setDisplayMode(_:modeID:)
setDithering(_:enabled:)
setICCProfile(_:profileURL:)

The core library intentionally stays thin. Higher-level features such as saved presets should live in a caller layer.

Testing

swift test

License

MIT. See LICENSE.

About

A macOS menu bar app for display profiles and daily controls

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages