Layouts
Layout policy belongs in layout.toml, although the same sections remain
accepted in wm.toml. The sidecar overlays recognized values one key at a time.
Layout engines
Section titled “Layout engines”| Engine | Behavior |
|---|---|
tile |
Master area beside a vertically divided stack. |
monocle |
One full-area window, or a full-area z-stack. |
grid |
Balanced rows and columns. |
rows |
Full-width horizontal rows. |
dwindle |
Alternating recursive splits. |
reverse-dwindle |
Horizontally mirrored recursive splits. |
scrolling |
PaperWM-style columns with independent vertical stacks and viewports. |
stacking |
Full freeform/stacking desktop with persistent geometry and z-order. |
game-mode |
One anchor with companion layouts in the remaining side columns. |
composable |
As many as four independent leaf layouts in fixed normalized regions. |
float, floating, and stack are compatibility aliases for stacking;
reverse_dwindle and game_mode are accepted aliases for their dashed IDs.
Shared defaults and slots
Section titled “Shared defaults and slots”[layout]default = "scrolling"gaps_outer = 8gaps_inner = 4master_ratio = 0.55master_count = 1border_width = 2border_focused = 0xFF88C0D0border_normal = 0xFF3B4252border_urgent = 0xFFBF616Aforce_ssd = false
[layout.slots]primary = "tile"secondary = "scrolling"tertiary = "monocle"quaternary = "grid"Every leaf [layout.options.<id>] can override the common geometry and border
fields for that engine. The four slots are targets for the corresponding
set_layout_* actions and can contain any top-level layout ID.
[layout.options.monocle]hide_others = trueshow_borders = false
[layout.options.dwindle]split_ratio = 0.5start_axis = "vertical" # vertical | horizontal
[layout.options.reverse-dwindle]split_ratio = 0.5start_axis = "vertical"Moving tiles between outputs
Section titled “Moving tiles between outputs”Hold Super and left-drag a tiled window onto another enabled output. It joins
that output’s active workspace and adopts the destination layout’s placement
policy. Fixed-position and fullscreen windows cannot use this tiled move path.
Floating windows retain their separate cross-output move behavior.
Tile resizing
Section titled “Tile resizing”Super+right-drag on a tile member resizes it without making it floating.
Horizontal motion changes the shared master/stack split; vertical motion
changes the selected member’s height within its column while the other members
share the remainder. The split persists as layout state.
Stacking layout
Section titled “Stacking layout”Stacking is a workspace-wide freeform layout, not merely a tiled layout with every window toggled floating. Ordinary members retain stacking-owned geometry across focus changes and temporary layout switches. A per-window floating toggle promotes a member to a persistent floating overlay; toggling again returns ownership to the workspace layout at the latest rectangle.
[layout.options.stacking]placement = "minimal-overlap" # cascade | center | under-pointer | minimal-overlapcascade_step = 32move_step = 10move_step_coarse = 50resize_step = 10snap_gap = 0snap_threshold = 24resistance = 12top_edge_maximize = trueNew windows use native/rule geometry when provided, otherwise the configured
placement policy. minimal-overlap evaluates candidate positions against
existing stacking members. Geometry is constrained by client minimum/maximum
size hints and recovered after output mode, scale, transform, strut, or hotplug
changes so a reachable portion remains available.
Focus maintains workspace-local MRU order. raise_on_focus and its delay are
configured under [input]. Windows can be raised/lowered explicitly or placed
in below, normal, and above semantic layers through a rule or toggle.
Transient dialogs remain associated with their parent; fullscreen remains
above the ordinary stack.
Pointer movement and snapping
Section titled “Pointer movement and snapping”Super+left-drag moves a stacking member or persistent floating overlay.Super+right-drag resizes from the chosen edge/corner.- A validated XDG title-bar move/resize request uses the same path. XWayland
_NET_WM_MOVERESIZEis accepted only during a focused pointer press. - Edge resistance attracts the moving rectangle to output and other window edges.
- Reaching an output edge previews the active named snap layout. Releasing
while a zone is selected commits its padded geometry. When no named zone is
selected, the ordinary half/quarter edge action remains available. The top
edge maximizes to the usable area when
top_edge_maximize = true; otherwise it selects the top half. - Crossing another output transfers ownership to that output’s active workspace while preserving logical size and pointer offset.
Named stacking snap layouts
Section titled “Named stacking snap layouts”Aqueous can define up to eight named layouts with sixteen normalized zones in each layout. A layout has a stable ID used by actions, a display name, and padding applied inside each resolved zone:
[layout]snap_layout = "work"
[layout.snap-layout.work]name = "Work"padding = 8
[layout.snap-layout.work.zone.editor]name = "Editor"x = 0.0y = 0.0width = 0.6666667height = 1.0
[layout.snap-layout.work.zone.terminal]name = "Terminal"x = 0.6666667y = 0.0width = 0.3333333height = 1.0
[keybinds.custom]"Super+Alt+1" = "builtin:snap_zone:work/editor""Super+Alt+2" = "builtin:snap_zone:work/terminal""Super+Alt+W" = "builtin:set_snap_layout:work""Super+Alt+Space" = "builtin:cycle_snap_layout"Coordinates and dimensions must be finite and normalized within the usable
area. Layout and zone IDs contain at most 32 letters, digits, hyphens, or
underscores. The active layout is selected independently per output at runtime;
snap_layout supplies the initial/default selection.
While moving a stacking-owned window, entering the configured snap_threshold
at any output edge displays all zones in the active layout and highlights the
zone under the pointer. Release commits only the highlighted zone. A zone that
does not touch any activation edge remains available through its direct
keyboard action. Leaving the stacking output or cancelling the drag removes
the preview without changing geometry.
Named layout selection, preview, cycling, and zone actions are intentionally
available only when that output’s workspace is using stacking. They do not
operate on persistent floating overlays in another layout or inside a
composable child. This keeps snap-zone policy owned by the full stacking
desktop rather than by the general floating presentation state.
The legacy [layout.snap-zone.a] through d,
builtin:snap_zone:<a-d>, and builtin:cycle_snap_zone forms remain accepted
for existing configurations. The configuration helper supports named snap-layout
editing for compatible frontends.
Keyboard freeform actions
Section titled “Keyboard freeform actions”All stacking actions are built-ins but remain unbound unless configured. They include:
raise_window,lower_window,toggle_always_above, andtoggle_always_below.- Fine and coarse
nudge_floating_<direction>movement. resize_floating_<direction>andshrink_floating_<direction>.- Halves, quarters, top, bottom, center, named stacking zones, layout/zone
cycling, and
unsnap. - Horizontal/vertical partial maximize and full fit-to-output.
- Move-to-edge and grow-to-edge actions in all four directions.
General geometry actions also operate on a persistent floating overlay while another workspace layout is active. Named layout and named-zone actions are the exception: they require the workspace itself to use stacking.
Scrolling columns
Section titled “Scrolling columns”[layout.options.scrolling]column_fraction = 0.5center_focused = truefollow_new_windows = trueopen_new_windows_to_right = falseprefer_vertical_on_portrait = falsesnap_to_columns = falseallow_overscroll = truefocus_follows_mouse_delay_ms = 0Each column owns its width and an independent vertical member viewport. New windows normally create columns; portrait-aware mode appends them to the active column when that scrolling instance is taller than wide. This works inside composable regions and Game Mode remainders as well as on a full output.
Set open_new_windows_to_right = true to insert each new column immediately
after the focused column: opening D with B focused changes A B C to
A B D C. This takes precedence over portrait stacking and also applies to
windows entering a workspace or composable region. Reloading it leaves existing
columns in place. focus_new_windows controls keyboard focus independently;
follow_new_windows controls viewport following.
Focus left/right crosses columns and up/down crosses members. The built-ins can consume the first window from the right, expel a member into a new column, move a whole column, toggle one column to full viewport width, or pan without changing keyboard focus. Clipped focused members are revealed automatically.
A window rule can set scrolling_width = 0.65 for a 65% base column width,
or scrolling_full_width = true to start at full viewport width. Full width
temporarily takes precedence over a custom base width. Manual toggles and horizontal resizing override the preset;
see Scrolling width rules.
With the primary modifier held, vertical wheel steps pan by column; adding Alt moves within the focused column. On portrait-arranged instances the axes swap. Natural scrolling is respected, high-resolution motion is accumulated, and a captured navigation step does not leak into the client.
The wheel_scroll_* actions can be rebound or disabled independently of arrow
shortcuts. Explicit scroll_viewport_* actions retain their named direction
instead of swapping axes. See Keybindings.
Super+left-drag uses top/bottom insertion zones to stack a window within a
column and middle-left/right zones to form an adjacent column.
Super+right-drag changes the column width horizontally and the selected member
height vertically. Super+double-left-click restores configured width and
default full-viewport member height.
Composable regions
Section titled “Composable regions”Composable mode divides the strut-adjusted usable area into one to four regions
named a through d:
[layout]default = "composable"
[layout.composable.a]layout = "tile"p1 = [0.0, 0.0]p2 = [0.5, 0.0]p3 = [0.5, 1.0]p4 = [0.0, 1.0]
[layout.composable.b]layout = "scrolling"p1 = [0.5, 0.0]p2 = [1.0, 0.0]p3 = [1.0, 1.0]p4 = [0.5, 1.0]Points are normalized clockwise corners of a nonzero axis-aligned rectangle. Regions may touch or leave gaps but cannot overlap. An invalid configured region makes composable mode fall back to full-area tile.
Children may use any leaf layout, including stacking, but cannot nest Game Mode or composable. Each region keeps independent order, viewport, and floating state. New windows enter the active region; pointer and layout actions route to the member’s child. Cross-region drops exchange membership.
[keybinds.custom]"Super+Alt+1" = "builtin:focus_composable:a""Super+Alt+Shift+1" = "builtin:move_to_composable:a"Region arguments accept a–d or 1–4.
Game Mode
Section titled “Game Mode”Game Mode chooses one matched anchor and exposes the remaining full-height left and right columns to independent companion-layout instances. An edge anchor collapses that side; top/bottom strips around a shorter centered anchor remain unused.
To select Game Mode and establish an anchor with a window rule, set
layout = "game-mode" (or "game_mode") explicitly. Rules with no layout
preserve the workspace layout, even when they include anchor, size, or scale.
[game_mode]remainder_layout = "grid"fallback_layout = "tile"gaps_inner = 8
[[window]]app_id = "steam_app_*"layout = "game-mode"workspace = 9anchor = "center"size = "0.70x0.80"scale = 1.0The remainder and fallback accept every leaf layout. Game Mode delegates
rearrangement and scrolling actions to an active remainder while keeping the
anchor fixed. If no matching anchor is present, the fallback fills the usable
area. After a rule claims the workspace for Game Mode, closing its anchor or
removing the rule’s layout on reload keeps that workspace in Game Mode using
the fallback. Select a layout manually to release the existing claim.
Per-output and workspace selection
Section titled “Per-output and workspace selection”[[output]]name = "DP-1"layout = "scrolling"
[[workspace]]workspace = 2layout = "monocle"
[[workspace]]output = "DP-1"workspace = 4layout = "stacking"Workspace numbers are 1-based. The layout can also be changed live with
aqueousctl layout --output NAME --set LAYOUT --json or a layout binding.
