Displays

Resolution, brightness, rotation and input source for every display

palupdated 2026-09-29SystemComes with pal󱔓Menu bar: Brightness󰌹7 deep links

Open in pal

Comes with pal, so a new install already has it; the button finds it in pal again if you removed it. This page can't see what your pal has installed.

Displays: Every display with its mode and brightness; Night Shift, Sleep displays and the saved arrangements below
Every display with its mode and brightness; Night Shift, Sleep displays and the saved arrangements below
Displays: Enter on a monitor: brightness, contrast and volume over DDC, the input source, modes, mirroring and rotation
Enter on a monitor: brightness, contrast and volume over DDC, the input source, modes, mirroring and rotation
Displays: A control opens as a slider: the arrows move it by the step, the digits jump to 10 to 100%
A control opens as a slider: the arrows move it by the step, the digits jump to 10 to 100%
Displays: Every mode the monitor takes, HiDPI first and the current one tagged; a change keeps Undo one row away
Every mode the monitor takes, HiDPI first and the current one tagged; a change keeps Undo one row away
Displays: Set the brightness from the bar's text, make a display main or copy its id for a link
Set the brightness from the bar's text, make a display main or copy its id for a link
1 of 5

What it does

Every display with its mode and brightness: change resolution, scaling, rotation and mirroring, set an external monitor's brightness and input source, and save arrangements to switch between.

  • One row per display with its resolution, refresh rate, rotation and brightness
  • Brightness, contrast and volume as sliders, for external monitors too (over DDC)
  • Switch the input source of an external monitor
  • Change the resolution with an easy undo, rotate, mirror or make a display the main one
  • Save the arrangement under a name and apply it again from the list, the bar or a link
  • Each tool it uses is optional; a row says what to install when one is missing

Palettes 1

  • Displaysdisplayslive

    Every display with its mode and brightness, the arrangement presets, Night Shift and Sleep displays; Enter drills into a display's controls.

    • ↵Open the display, apply a preset, run a row
    • ⌘BSet the brightness to the percent typed in the bar
    • ⌘⇧MMake the display the main one
    • ⌘CCopy the display's id, for links
    • ⌘RRename a preset
    • ⌘⌫Delete a preset

Actions

  • OpenDrills into the display: its controls, modes and arrangement.↵
  • Set brightnessThe percent typed in the bar (or +10 / -10).⌘B
  • Make mainMoves the arrangement so this display is at (0,0).⌘⇧M

Settings

Extension, [extensions.displays]

step
5% number

What one press of the arrow keys, a scroll on the bar item or a `+10`-style link moves a level by, in percent. Shift with an arrow always moves 1%.

input_alt
Off boolean

Most monitors take the standard VCP 60 codes for their inputs (DisplayPort 1 is 15, HDMI 1 is 17). LG's take 208 and 144 instead; turn this on if switching the input does nothing.

Defaults shown. Change them in pal's settings window or in the config file.

The README

Everything Displays does, key by key, from the extension's own README.md

Displays

Every display with its mode and brightness; Enter drills into one for its controls (brightness, contrast, volume as sliders, the input source), its modes (resolution, refresh rate, HiDPI scaling), rotation, mirroring and Make main; arrangement presets; a bar item with a slider per display (mark several cards, cmd-click or shift+↓, and the brightness keys move them all). The palette's full description, keys and settings are in docs/palettes.md ("Displays").

What runs where

Nothing is built in: every fact comes from a tool, each optional, and a Setup row says what to install for the displays that are connected (Enter copies the command). The listing itself needs no tool on macOS.

macOS Linux
the displays, names, current mode, main, mirror system_profiler SPDisplaysDataType -json (~150 ms) hyprctl monitors -j, else wlr-randr --json, else xrandr --query
modes, rotation, mirroring, main, presets displayplacer (brew install displayplacer, ~300 ms a listing) the same compositor tool
built-in brightness brightness CLI, the HEAD build (brew install --HEAD brightness) brightnessctl
external brightness, contrast, volume, input m1ddc on Apple Silicon, ddcctl on Intel, over DDC/CI ddcutil
Night Shift nightlight (brew install smudge/smudge/nightlight) not offered

The displays are joined on the CoreGraphics display id on macOS, which is what windows.displays() in the SDK reports, displayplacer calls the "contextual" id and m1ddc the "Display ID"; on Linux on the output name (DP-1). Routes take that id, or main / external / builtin / a name.

Notes per tool:

  • The brightness on PATH is validated (-l must list displays) and Homebrew's prefixes are tried when it is something else by that name. The bottled 1.2 cannot read or set an Apple Silicon panel (it answers kIOReturnUnsupported); the HEAD build goes through DisplayServices and can. It also reads Apple displays (Studio Display) the same way.
  • m1ddc sets the input source but cannot read which is active, so the Input row carries no current tag with it; ddcctl and ddcutil read it. Volume is offered only when the monitor answers a volume read.
  • displayplacer's reproduce line (the last line of list) is what a preset stores and what Undo restores; every change is that line with one field moved, so a mode change never touches the other displays. Rotating the built-in screen asks first, with displayplacer's own warning.
  • The built-in panel never goes below 5 % from pal (BUILTIN_FLOOR in tools.ts): a screen you cannot see is one you cannot fix from.
  • On Linux, Make main exists only under xrandr (--primary); Wayland compositors have no primary output.

Caching

displayplacer list plus system_profiler cost a few hundred ms, so one snapshot of the displays stands for 20 s (SNAPSHOT_TTL_MS), and a level reading for 3 s (brightness moves under the keyboard's keys too). ⌘R, a write and the bar item's wake refresh drop both. Tools are re-detected every minute, so a brew install lands without a restart.

Files

model.ts is pure: the parsers of every tool's output and the placement maths (a mode, the main display, a mirror set, a rotation as the next displayplacer command), fixture-tested in host/test/extensions/displays.test.ts. tools.ts runs the tools and keeps the caches. view.ts draws the slider level and the bar popover. index.ts is the palette, the picks, the bar item and the routes.