Skip to content

Outputs

Output sections configure monitors by connector name, such as DP-1, or by monitor identity:

[output.DP-1]
mode = "3840x2160@165"
position = [0, 0]
scale = 1.25

Run umbriel outputs inside a session to list names and available modes. The Config name value is a copyable monitor identity in "<make> <model> <serial>" form:

[output."Microstep MSI G2712F CD6T084401192"]
mode = "1920x1080@180"

Use a monitor identity when settings should follow one display between ports. Use a connector when settings belong to a physical port. If both match, the monitor section wins. Matching is case-insensitive.

Without a matching output section, Umbriel enables outputs that advertise a preferred mode, a display identity, or no fixed mode list. A connector that advertises modes but provides neither a preferred mode nor an identity stays disabled. This avoids activating stale connector state reported by some DRM drivers. Add a matching output section with enabled = true to enable such a display explicitly.

When an output disconnects or is disabled, Umbriel temporarily moves its workspaces and windows to another enabled output. They return with their layout and positions when the output becomes available again.

KeyTypeDefaultDescription
enabledbooltrueTurn the monitor on or off.
modestringpreferredResolution and optional refresh rate, such as "2560x1440@165".
position[x, y]automaticTop-left position in logical coordinates.
scalefloat1.0Output scale from 0.25 to 4.0.
transformstring"normal"Rotation or reflection.
vrrstring"disabled"Variable refresh rate policy.
tearingboolfalseAllow eligible fullscreen windows to use asynchronous page flips.
direct_scanoutbooltrueAllow eligible fullscreen buffers to bypass composition.
hdrstring"off"HDR activation policy.
sdr_whitefloat203SDR reference white in cd/m² while HDR is active.
bit_depthint8Render bit depth for SDR output: 8 or 10.
workspacesint, string array, or "dynamic""dynamic"Workspace inventory for this output.
min_workspacesint1Minimum count for a dynamic output.
cyclic_workspacesboolfalseWrap a workspace step around the ends of the inventory.
workspace_axisstring"vertical"Workspace arrangement axis.
layout.scrolling.default_extent_fractionfloatinheritedInitial scrolling-column extent on this output.
screen_effectstringinheritedReplace effects.screen with a screen preset or pool, or "off" to disable it on this output.

Umbriel tries an unadvertised resolution as a custom mode. If it cannot apply the configured mode, it uses the preferred advertised mode and logs a warning.

workspaces accepts:

  • "dynamic" or an omitted value for workspaces that grow and shrink
  • An integer for a fixed number of anonymous workspaces
  • A string array for a fixed ordered list of names

min_workspaces sets a floor for a dynamic output:

[output.DP-1]
min_workspaces = 3

Do not combine min_workspaces with a fixed workspace inventory. See Workspaces for naming, lifecycle, and workspace rules.

With cyclic_workspaces = true, a workspace step past either end of the inventory wraps to the other end:

[output.DP-1]
workspaces = 3
cyclic_workspaces = true

This applies to workspace-next/previous, window-move-to-workspace-next/previous, window-move-to-workspace-silent-next/previous, window-move-or-workspace-up/down at the column edge, and column-move-to-workspace-next/previous.

On a dynamic output, the trailing empty workspace is the last one. Stepping forward from the last populated workspace enters it, and one more step wraps to the first. A static inventory wraps directly at both ends.

Override the global starting width for new scrolling columns on one output:

[output.DP-1.layout.scrolling]
default_extent_fraction = 0.4

A matching workspace rule can override this value. Reloading affects new columns only; existing columns keep their current width. See Scrolling behavior.

[output."HDMI-A-1"]
screen_effect = "off"

screen_effect names an [effects.preset.<name>] or [effects.pool.<name>] of kind screen, or "off" to disable effects.screen on this output. See Effects.

Positions use logical coordinates after scale and transform. A 3840x2160 output at scale 1.25 occupies 3072x1728 logical units. An output immediately to its right therefore starts at x = 3072.

Omit position to place outputs automatically from left to right. Explicitly positioned outputs must touch or overlap for the pointer to move between them.

Accepted values are normal, 90, 180, 270, flipped, flipped-90, flipped-180, and flipped-270.

Direct scanout can reduce composition work for eligible fullscreen applications. Disable it if fullscreen content causes corruption, black frames, or flicker:

[output.DP-1]
direct_scanout = false

The change applies on reload. Disabling direct scanout can increase GPU use and power consumption.

Set WLR_SCENE_DISABLE_DIRECT_SCANOUT=1 before starting Umbriel to disable direct scanout on every output.

vrr accepts:

ValueBehavior
"disabled"Never enable adaptive sync.
"always"Keep adaptive sync enabled when supported.
"fullscreen"Enable it while the active workspace has a fullscreen window.
[output.DP-1]
vrr = "fullscreen"

A focused window can override this policy through a window rule. Unsupported outputs remain at fixed refresh and produce a warning.

Tearing requires an output-level opt-in:

[output.DP-1]
tearing = true

Umbriel uses asynchronous presentation only for an eligible fullscreen window that requests it or matches a tearing = true window rule. A window rule can also veto a client request. Run umbriel tearing to inspect eligibility and fallback reasons.

hdr accepts:

ValueBehavior
"off"Keep the output in SDR.
"on"Keep the output in HDR.
"auto"Enable HDR for fullscreen content with supported HDR metadata.
"fullscreen"Enable HDR for any fullscreen content.
[output.DP-1]
hdr = "auto"
sdr_white = 203

Automatic HDR depends on metadata supplied by the application. Untagged XWayland content cannot be detected; use a native Wayland HDR path or hdr = "on" when necessary. Many monitors briefly go black while switching between SDR and HDR.

Some native Wayland Proton builds require PROTON_ENABLE_WAYLAND=1 and DXVK_HDR=1 before they publish HDR metadata. Proton variants differ, so follow the selected runtime’s documentation and fully restart Steam after changing session environment values.

Screenshots from normal screencopy clients receive an SDR view while HDR is active.

Set bit_depth = 10 to request a 10-bit SDR compositor render format:

[output.DP-1]
bit_depth = 10

Umbriel selects XR30 (DRM_FORMAT_XRGB2101010) or XB30 (DRM_FORMAT_XBGR2101010) when the backend accepts it. XB30 is tried first if it is already active. Otherwise, XR30 is tried first. If no 10-bit format commits, the output falls back to 8-bit. HDR uses 10-bit independently of this setting.

While a 10-bit format is active, blur and effects intermediate buffers are upgraded to FP16 precision, provided the renderer supports FP16 render targets and linear filtering of half-float textures. Otherwise, they remain 8-bit.

bit_depth = 10 controls the compositor render format only. It does not guarantee that the physical display link runs at 10 bits per channel. The number of bits delivered to the panel depends on the display’s EDID, cable, and driver. Run umbriel color to confirm the active render format that the compositor committed.

In umbriel color --json, bit_depth is the configured value and bit_depth_active reports whether an enabled SDR output is currently using XR30 or XB30. bit_depth_fallback_reason explains a failed 10-bit request. It is empty while HDR is active.

When VRR is also requested and the output supports adaptive sync, Umbriel tests the formats with VRR first, in the order described above. If neither passes, it tests them without VRR in the same order. Once a format passes its test, Umbriel attempts to commit it. If that commit fails with VRR, it retries the same format without VRR, without another test. A failed commit does not try the other format. If no 10-bit format commits, it falls back to 8-bit. HDR follows the same retry rule before falling back to SDR.

Direct scanout remains enabled by the direct_scanout setting, but it may be less likely to engage while 10-bit rendering is active. Direct scanout requires the client buffer format to exactly match what KMS accepts for the plane. Set direct_scanout = false to disable direct scanout for an output entirely.

Screencopy clients such as grim and Noctalia receive raw buffers in the output’s active 10-bit render format (XR30 or XB30) when 10-bit SDR is active. Unlike HDR capture, the pixels are not converted to an 8-bit SDR format first. Tools that do not handle 10-bit formats may produce undesired output.

A virtual output is a monitor with no display behind it. It has workspaces, takes windows, and can be captured like any other output, which makes it a target for remote desktop and game streaming. See Game streaming for a Sunshine setup.

Terminal window
umbriel output-create stream 2560x1440@120
umbriel output-destroy stream

The name uses ASCII letters, digits, -, _, and ., and must not match an existing output, ignoring case. output-create prints the new output’s name. The optional mode takes the same WIDTHxHEIGHT[@HZ] form as the mode setting below and sets the size and frame pacing at creation; without it, a virtual output starts at 1280x720. An output section or an output-management tool such as wlr-randr changes the mode afterwards:

[output.stream]
mode = "1920x1080@60"
Terminal window
wlr-randr --output stream --custom-mode 2560x1440@120Hz

output-destroy accepts only virtual outputs. Its windows move to another output, as when a monitor is unplugged.

Set enabled = false for a persistent disabled state:

[output.HDMI-A-1]
enabled = false

The output leaves the desktop, but its workspaces and windows are retained and return when it is enabled again. Output-management tools can temporarily override this state until a later output-policy change in the configuration reapplies the file. Reloading identical content or changing an unrelated setting leaves the temporary state intact.

Use the logical output actions for the same temporary change without an external output-management tool:

Terminal window
umbriel msg output-disable:eDP-1
umbriel msg output-enable:eDP-1
umbriel msg output-toggle:eDP-1

These actions remove and restore the output as part of the desktop layout. Windows move to another enabled output while their home is unavailable, then return when it is enabled again. A disabled output is also absent from whole-desktop screenshots. The actions can be used directly by lid event commands.

A temporary enable or disable choice survives the output disappearing and returning during the same compositor session. For a monitor with display identity, the choice follows that monitor if it returns on another connector; a different identified monitor on the old connector does not inherit it. Outputs without display identity remain associated with their connector name.

Use DPMS actions to power monitors off without removing their workspaces:

Terminal window
umbriel msg dpms-off
umbriel msg dpms-off:DP-1
umbriel msg dpms-on:DP-1

The bare actions target every configured output. Input wakes all monitors when every output is powered off. Outputs disabled with enabled = false are not affected. DPMS does not remove an output from the logical desktop, move its windows, or exclude it from a whole-desktop capture.

Tools such as wlr-randr, kanshi, and wdisplays can change enabled state, mode, position, scale, transform, and adaptive sync while Umbriel is running. Those changes last until another tool request or a changed output-state policy in the configuration replaces them. An identical or unrelated reload is inert.

[output.DP-1]
mode = "3840x2160@165"
position = [0, 0]
scale = 1.25
workspaces = 5
[output.DP-2]
mode = "2560x1440@144"
position = [1300, -1440]
scale = 1.0
workspaces = ["VIDEO"]
[output.HDMI-A-1]
mode = "1920x1080@60"
position = [3072, 0]
scale = 1.0
workspaces = ["CHAT", "STATS"]

The primary output is 3072 logical units wide, so the HDMI output begins at x = 3072.

Keep output configuration in a machine-specific include when sharing one base configuration between systems:

[include]
files = [
"src/general.toml",
"src/keybinds.toml",
"machines/monolith.toml",
]

Each output keeps its screen pool assignment while disabled. Disconnecting releases it; reconnecting starts from configuration. Inspect assignments with umbriel effects --json; outputs --json remains output-management data. The cursor has one session-wide selection shared by all outputs.