Window RulesπŸ”—

Window rules tell Triad how to handle a window the moment it opens. Rules are declarative and reload on save β€” no restart needed.

Every rule begins with a window-rule block containing at least one match or exclude clause, followed by the properties to apply.

MatchingπŸ”—

Rules match on app-id and title using regular expressions. You can combine matchers; all must match for the rule to apply.

MatcherTypeDescription
app-idRegexMatch the application ID (Wayland class).
titleRegexMatch the window title.
is-focusedBoolMatch only when the window has focus.
is-floatingBoolMatch only floating windows.

To find a window's app-id, run:

triad msg state | grep app-id

Use exclude to carve out exceptions from a broader rule:

window-rule {
  match app-id="^org\."
  exclude title=".*β€”Private Browsing.*"
  open-workspace 2
}

Placement & BehaviorπŸ”—

PropertyValuesDescription
open-floatingBoolOpen the window floating instead of tiled.
open-focusedBoolGive focus to the window when it opens.
open-fullscreenBoolOpen in fullscreen mode.
open-maximizedBoolOpen as a full-width column in scroller layouts.
maximize-policy"edge", "column", "ignore"How the maximize command behaves for this window.
default-workspaceIntSend the window to a specific workspace number.
open-on-outputStringPin the window to a specific monitor by connector name.
open-on-all-workspacesBoolMake the window sticky β€” visible on every workspace.
idle-inhibit"none", "focused", "visible"Prevent the screen from sleeping while this window is visible or focused.
presentation-mode"default", "vsync", "async"Output presentation policy.

SizingπŸ”—

PropertyValuesDescription
min-width / max-widthPixelsHard size boundaries.
scroller-proportion0.05..1.0Initial column width in scroller layouts.
center-floatingBoolCenter the window on screen when floating.

ExamplesπŸ”—

Send KeePassXC to workspace 2, floating and centered:

window-rule {
  match app-id="^org\.keepassxc\.KeePassXC$"
  open-floating #true
  center-floating #true
  default-workspace 2
}

Fullscreen Steam games and inhibit idle:

window-rule {
  match app-id="^steam_app_"
  open-fullscreen #true
  idle-inhibit "visible"
}

Pin a browser to the web workspace and monitor:

window-rule {
  match app-id="^firefox$"
  default-workspace 2
  open-on-output "DP-1"
}

Float all dialog windows:

window-rule {
  match title=".*β€” Open File$"
  open-floating #true
  center-floating #true
}

Sticky a chat app across all workspaces:

window-rule {
  match app-id="^vesktop$"
  open-on-all-workspaces #true
}

For event-driven placement that KDL rules cannot express β€” "open next to an existing terminal if one is present, otherwise claim a new tag" β€” see Janet Scripting.