BSP (binary space partitioning)
Recursively splits the screen in half, creating a balanced tree of windows. Each split alternates direction: vertical, then horizontal, then vertical again. Unlike Tall and Wide, BSP has no main window. Every window can be resized individually.
Layout
Section titled “Layout”1 window
Section titled “1 window”┌───────────────────────────────────────────────────────────┐│ ││ ││ ││ ││ ││ ││ ││ ││ 1 ││ ││ ││ ││ ││ ││ ││ ││ │└───────────────────────────────────────────────────────────┘2 windows
Section titled “2 windows”┌─────────────────────────────┬─────────────────────────────┐│ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ 1 │ 2 ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ │└─────────────────────────────┴─────────────────────────────┘3 windows
Section titled “3 windows”┌─────────────────────────────┬─────────────────────────────┐│ │ ││ │ ││ │ ││ 1 │ ││ │ ││ │ ││ │ ││ │ 3 │├─────────────────────────────┤ ││ │ ││ │ ││ │ ││ 2 │ ││ │ ││ │ ││ │ ││ │ │└─────────────────────────────┴─────────────────────────────┘4 windows
Section titled “4 windows”┌─────────────────────────────┬─────────────────────────────┐│ │ ││ │ ││ │ ││ 1 │ 3 ││ │ ││ │ ││ │ ││ │ │├─────────────────────────────┼─────────────────────────────┤│ │ ││ │ ││ │ ││ 2 │ 4 ││ │ ││ │ ││ │ ││ │ │└─────────────────────────────┴─────────────────────────────┘5 windows
Section titled “5 windows”┌──────────────┬──────────────┬─────────────────────────────┐│ │ │ ││ │ │ ││ │ │ ││ 1 │ 2 │ 4 ││ │ │ ││ │ │ ││ │ │ ││ │ │ │├──────────────┴──────────────┼─────────────────────────────┤│ │ ││ │ ││ │ ││ 3 │ 5 ││ │ ││ │ ││ │ ││ │ │└─────────────────────────────┴─────────────────────────────┘Each new window splits an existing space in half, alternating direction at each tree level.
Capabilities
Section titled “Capabilities”- Adjustable ratio: No (use per-window resize instead)
- Adjustable main count: No (no main area concept)
- Per-window resize: Yes
- Stateful: Yes - remembers custom ratios
Resizing windows
Section titled “Resizing windows”BSP provides resize actions that adjust individual splits:
spoon.Shoji:bindHotkeys({ bsp_shrink_horizontal = { { "ctrl", "cmd" }, "h" }, bsp_expand_horizontal = { { "ctrl", "cmd" }, "l" }, bsp_shrink_vertical = { { "ctrl", "cmd" }, "k" }, bsp_expand_vertical = { { "ctrl", "cmd" }, "j" }, bsp_rotate = { { "ctrl", "cmd" }, "r" },})Expand/shrink example
Section titled “Expand/shrink example”Resize the split containing the focused window:
Before (window 1 focused):
┌─────────────────────────────┬─────────────────────────────┐│ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ 1 │ 2 ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ │└─────────────────────────────┴─────────────────────────────┘After expand_horizontal:
┌─────────────────────────────────────────┬─────────────────┐│ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ 1 │ 2 ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ │└─────────────────────────────────────────┴─────────────────┘Rotate
Section titled “Rotate”Flip all splits 90 degrees:
Before:
┌─────────────────────────────┬─────────────────────────────┐│ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ 1 │ 2 ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ │└─────────────────────────────┴─────────────────────────────┘After:
┌───────────────────────────────────────────────────────────┐│ ││ ││ ││ 1 ││ ││ ││ ││ │├───────────────────────────────────────────────────────────┤│ ││ ││ ││ 2 ││ ││ ││ ││ │└───────────────────────────────────────────────────────────┘Split-ratio model
Section titled “Split-ratio model”Each split in the BSP tree has an independent ratio (default 0.5, meaning equal halves). The resize actions adjust the nearest split in the specified direction:
| Action | Effect |
|---|---|
bsp_expand_horizontal |
Increase width of focused window’s vertical split by 0.05 |
bsp_shrink_horizontal |
Decrease width of focused window’s vertical split by 0.05 |
bsp_expand_vertical |
Increase height of focused window’s horizontal split by 0.05 |
bsp_shrink_vertical |
Decrease height of focused window’s horizontal split by 0.05 |
bsp_rotate |
Swap all horizontal splits to vertical and vice versa |
To reset all split ratios to 0.5, use reset_space
(Ctrl+Alt+Shift+0).
This clears the BSP tree state and rebuilds it from scratch.
See BSP layout actions for hotkey bindings.
State persistence
Section titled “State persistence”BSP remembers custom split ratios. This state persists:
- Across retiles within the same macOS Space
- When switching away and back to the macOS Space
- When cycling to other layouts and returning
How BSP splits work
Section titled “How BSP splits work”The algorithm builds a binary tree:
- First split (depth 0): Left-right (vertical divider)
- Second split (depth 1): Top-bottom (horizontal divider)
- Third split (depth 2): Left-right again
- And so on…
Windows distribute evenly between subtrees, creating balanced layouts regardless of window count.
When to use
Section titled “When to use”BSP shines when:
- Managing many windows (5+) that all need visibility
- Window importance shifts during work (no fixed main window)
- Fine-grained control over individual window sizes is needed
- A symmetric, balanced layout is preferred
BSP vs Tall
Section titled “BSP vs Tall”| Aspect | BSP | Tall |
|---|---|---|
| Main window | None | Yes (left side) |
| Resize scope | Individual splits | Global ratio |
| State | Per-window ratios | Stateless |
| Best for | Many equal windows | Primary + supporting |