IfMax
IfMax switches between two layouts depending on how many windows are open. Use it to apply a focused layout for a few windows and a more structured one when the count grows.
At a glance
- Switches between two layouts based on window count
- Threshold is the max count for the below layout
- Capabilities and state inherited from both children
- State persists independently per child
Basic usage
local IfMax = require("layouts.combinators.if_max")local Monocle = require("layouts.monocle")local Tall = require("layouts.tall")
local dev = IfMax.create(2, Monocle, Tall, { name = "dev", displayName = "Dev",})With 1–2 windows the Monocle layout is used:
┌───────────────────────────────────────────────────────────┐│ ││ ││ ││ ││ ││ ││ ││ 1 or 2 ││ (Monocle) ││ ││ ││ ││ ││ ││ ││ ││ │└───────────────────────────────────────────────────────────┘With 3 or more windows, Tall takes over:
┌─────────────────────────────┬─────────────────────────────┐│ │ ││ │ 2 ││ │ ││ ├─────────────────────────────┤│ │ ││ │ 3 ││ │ ││ 1 ├─────────────────────────────┤│ │ ││ (Tall) │ 4 ││ │ ││ ├─────────────────────────────┤│ │ ││ │ 5 ││ │ ││ │ ││ │ │└─────────────────────────────┴─────────────────────────────┘Threshold semantics
The threshold is the maximum window count for belowLayout:
#windows <= threshold→belowLayout#windows > threshold→aboveLayout
With threshold = 2: 1 or 2 windows use belowLayout; 3 or more use
aboveLayout.
Error handling
IfMax.create returns nil and an error string on invalid input:
-- threshold must be a positive integerlocal layout, err = IfMax.create(0, Monocle, Tall)-- err = "threshold must be a positive integer"
-- both layouts must be validlocal layout, err = IfMax.create(2, nil, Tall)-- err = "belowLayout is invalid"State management
IfMax maintains state for both child layouts. Each child’s state is preserved independently, so switching back to a layout resumes exactly where it left off. State persists across layout cycles and Hammerspoon restarts.
Common mistakes
Off-by-one on threshold:
IfMax.create(2, ...) means 1–2 windows use belowLayout
and 3+ use aboveLayout. The threshold is the maximum
count for the below layout, not the minimum for above.
Using IfMax when Partition with count would be
simpler:
If you want a fixed split (e.g., 1 window left, rest
right), Partition with count = 1 is more direct. IfMax
is for layouts that change structure entirely based on
window count.
Common errors
“threshold must be a positive integer”: Passed 0 or a non-integer. The threshold must be 1 or greater.
“belowLayout is invalid” / “aboveLayout is
invalid”: A child layout is missing required fields.
Every layout must have at least name and arrange.