Skip to content

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.

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.

[layout]
default = "scrolling"
gaps_outer = 8
gaps_inner = 4
master_ratio = 0.55
master_count = 1
border_width = 2
border_focused = 0xFF88C0D0
border_normal = 0xFF3B4252
border_urgent = 0xFFBF616A
force_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 = true
show_borders = false
[layout.options.dwindle]
split_ratio = 0.5
start_axis = "vertical" # vertical | horizontal
[layout.options.reverse-dwindle]
split_ratio = 0.5
start_axis = "vertical"

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.

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 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-overlap
cascade_step = 32
move_step = 10
move_step_coarse = 50
resize_step = 10
snap_gap = 0
snap_threshold = 24
resistance = 12
top_edge_maximize = true

New 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.

  • 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_MOVERESIZE is 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.

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.0
y = 0.0
width = 0.6666667
height = 1.0
[layout.snap-layout.work.zone.terminal]
name = "Terminal"
x = 0.6666667
y = 0.0
width = 0.3333333
height = 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.

All stacking actions are built-ins but remain unbound unless configured. They include:

  • raise_window, lower_window, toggle_always_above, and toggle_always_below.
  • Fine and coarse nudge_floating_<direction> movement.
  • resize_floating_<direction> and shrink_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.

[layout.options.scrolling]
column_fraction = 0.5
center_focused = true
follow_new_windows = true
open_new_windows_to_right = false
prefer_vertical_on_portrait = false
snap_to_columns = false
allow_overscroll = true
focus_follows_mouse_delay_ms = 0

Each 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 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 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.

rules.toml
[game_mode]
remainder_layout = "grid"
fallback_layout = "tile"
gaps_inner = 8
[[window]]
app_id = "steam_app_*"
layout = "game-mode"
workspace = 9
anchor = "center"
size = "0.70x0.80"
scale = 1.0

The 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.

[[output]]
name = "DP-1"
layout = "scrolling"
[[workspace]]
workspace = 2
layout = "monocle"
[[workspace]]
output = "DP-1"
workspace = 4
layout = "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.

© 2026 Seafoam LabsShelly Chel