Skip to content

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

1 window

┌───────────────────────────────────────────────────────────┐
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ 1 │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
└───────────────────────────────────────────────────────────┘

2 windows

┌─────────────────────────────┬─────────────────────────────┐
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ 1 │ 2 │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
└─────────────────────────────┴─────────────────────────────┘

3 windows

┌─────────────────────────────┬─────────────────────────────┐
│ │ │
│ │ │
│ │ │
│ 1 │ 2 │
│ │ │
│ │ │
│ │ │
│ │ │
├─────────────────────────────┴─────────────────────────────┤
│ │
│ │
│ │
│ 3 │
│ │
│ │
│ │
│ │
└───────────────────────────────────────────────────────────┘

4 windows

┌─────────────────────────────┬─────────────────────────────┐
│ │ │
│ │ │
│ │ │
│ 1 │ 2 │
│ │ │
│ │ │
│ │ │
│ │ │
├─────────────────────────────┼─────────────────────────────┤
│ │ │
│ │ │
│ │ │
│ 3 │ 4 │
│ │ │
│ │ │
│ │ │
│ │ │
└─────────────────────────────┴─────────────────────────────┘

5 windows

┌─────────────────────────────┬─────────────────────────────┐
│ │ │
│ │ │
│ │ │
│ 1 │ 2 │
│ │ │
│ │ │
│ │ │
│ │ │
├─────────────────────────────┼──────────────┬──────────────┤
│ │ │ │
│ │ │ │
│ │ │ │
│ 3 │ 4 │ 5 │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
└─────────────────────────────┴──────────────┴──────────────┘

Each new window splits an existing space in half, alternating direction at each tree level.

Capabilities

  • Adjustable ratio: No (use per-window resize instead)
  • Adjustable nmaster: No (no main area concept)
  • Per-window resize: Yes
  • Stateful: Yes - remembers custom ratios

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

Resize the split containing the focused window:

Before (window 1 focused):

┌─────────────────────────────┬─────────────────────────────┐
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ 1 │ 2 │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
└─────────────────────────────┴─────────────────────────────┘

After expand_horizontal:

┌─────────────────────────────────────────┬─────────────────┐
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ 1 │ 2 │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
└─────────────────────────────────────────┴─────────────────┘

Rotate

Flip all splits 90 degrees:

Before:

┌─────────────────────────────┬─────────────────────────────┐
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ 1 │ 2 │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
└─────────────────────────────┴─────────────────────────────┘

After:

┌───────────────────────────────────────────────────────────┐
│ │
│ │
│ │
│ 1 │
│ │
│ │
│ │
│ │
├───────────────────────────────────────────────────────────┤
│ │
│ │
│ │
│ 2 │
│ │
│ │
│ │
│ │
└───────────────────────────────────────────────────────────┘

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

State resets when calling the retile_space action or spoon.Shoji:retile().

How BSP splits work

The algorithm builds a binary tree:

  1. First split (depth 0): Vertical (left-right)
  2. Second split (depth 1): Horizontal (top-bottom)
  3. Third split (depth 2): Vertical again
  4. And so on…

Windows distribute evenly between subtrees, creating balanced layouts regardless of window count.

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

AspectBSPTall
Main windowNoneYes (left side)
Resize scopeIndividual splitsGlobal ratio
StatePer-window ratiosStateless
Best forMany equal windowsPrimary + supporting