Read-only, pure functions over a state. They never mutate their input. Every query that is “per output” defaults to state.focusedOutput, so single-output code never passes an output. Sources: src/state/queries.mjs, src/state/rules.mjs, src/state/derive.mjs (presentationContext).
true when the window record, or any ancestor, has sticky: true: a dialog or popover of a sticky window is shown wherever its parent is.
isVisible(state, id)
true when the window exists; its status is not "minimized" or "popped-out"; it is not a hidden scratchpad window (workspace: null); its workspace is the active workspace of that workspace’s own output (or the window is sticky, itself or through an ancestor); and its parent, if any, is visible (recursively). Which output has focus does not matter.
Visible window records on that output: its active workspace’s windows in workspace order, then sticky windows living on other workspaces of the same output.
focusable(state, outputId = state.focusedOutput)
Ids of presentedWindows that are not blocked by a modal, in the same order. focus/next cycles these.
isPoppedOut(state, id)
status === "popped-out".
isScratchpadHidden(state, id)
A scratchpad window that is currently hidden (scratchpad: true and workspace: null).
Direct children (records whose parent === id). Backed by a parent → children index built once per state.windows object, so the window-tree queries (modalTarget, isBlocked, descendantsOf) and derive/presentationContext are linear in the number of windows. The returned list is shared: do not mutate it.
descendantsOf(state, id)
Ids of every descendant, in pre-order (child, its descendants, next child, …).
modalTarget(state, id)
The deepest open modal descendant reached by following modal children (not minimized, not popped out), or id itself when there is none. This is where focus goes when id is focused.
isBlocked(state, id)
modalTarget(state, id) !== id: an open modal descendant blocks input to this window.
Every window id, bottom to top, across all layers and workspaces: the logical stack (LAYERS order, then state.stack[layer] order).
paintOrder(state, outputId = state.focusedOutput)
The visual order of the output’s visible windows, bottom to top, exactly as derive paints them: background-layer windows, then the tiled base (in workspace order), then every other visible window by stacking order. If a visible window is fullscreen, just that window followed by its descendants.
The visible fullscreen window record on an output, or undefined. window/fullscreen keeps one per output; if a workspace switch brings two into view, the one covering the focused window (itself or an ancestor) wins, else the topmost.
isDescendantOf(state, id, ancestor)
Is id a child, grandchild, … of ancestor?
inTiledBase(state, win)
Takes a window record. It is true when the window is laid out by the workspace layout: role: "window", mode: "tiled", not sticky, not maximized, not hidden in the scratchpad (workspace: null), and the workspace layout is not floating. Tiled windows paint above the background layer and beneath everything else, whatever their position in state.stack.
Declarative window rules, in the spirit of xmonad ManageHooks, i3 for_window and EWMH window types. config.rules is an ordered array of { match?, set? }. The rules are applied by window/create and replaced by rules/set or config/set { rules }.
{ set:{ constraints:{ minWidth:200}}},// no match: applies to every window
]
match (every present field must agree; absent or empty matches everything):
Field
Matches when
role
win.role === role (must be one of ROLES)
id
win.id === id
idPrefix
win.id starts with it
title
win.title === title
titleRegex
new RegExp(titleRegex).test(win.title). It is a regex source string, compiled on every check so rules stay JSON-serializable.
app
win.app === app
parent
win.parent === parent
String fields must be strings. titleRegex must compile.
set: the fields a rule may fill in, the same ones a create command can set:
Field
Constraint
mode
"tiled" or "floating"
layer
one of LAYERS
workspace
a string. An unknown workspace makes the window/create itself reject (unknown-workspace).
placement
plain object, merged one level deep
status
one of STATUSES
draggable
boolean (false pins; true clears a pin)
constraints
plain object, merged one level deep; the placement is re-clamped
anchor
plain object or null
A rule with any other top-level key, or unknown match/set keys, is invalid.
Export
Description
matchRules(state, win)
Indices of state.config.rules whose match accepts win (a record or any window-shaped object), in rule order. Applies nothing, and never throws: an uncompilable titleRegex simply fails to match.
Precedence at window/create: the role defaults come first, then the matched rules in order (a later rule wins field by field), then the command’s own explicitly set fields, which always win.