Skip to content

Layouts

Shoji ships with several built-in layouts and supports custom layouts. This page provides layout guidance and examples. For the complete list of configuration options, see Configuration overview.

Built-in layouts

LayoutDescription
tallMain window on left, stack on right
wideMain window on top, stack below
bspBinary space partitioning (recursive splits)
gridDynamic grid arrangement
columnEqual-width columns
three_columnsMain center, stacks on sides
monocleAll windows stacked full-size
floatingNo automatic tiling

Default layout

New macOS Spaces start with the default_layout:

spoon.Shoji:configure({
default_layout = "tall",
})

Enabled layouts

Control which layouts are available when cycling (Ctrl+Alt+Space):

spoon.Shoji:configure({
enabled_layouts = { "tall", "wide", "monocle" },
})

The cycle_layout_forward action moves through this list in order. Layouts not in this list cannot be cycled to but can still be set directly via set_layout_* hotkeys.

Main area configuration

The tall and wide layouts split the screen into a main area and a stack. Two settings control this split:

Main ratio

The proportion of screen space for the main area:

spoon.Shoji:configure({
main_ratio = 0.5, -- Default: 50% main, 50% stack
})

Valid range: 0.1 to 0.9. Adjust at runtime with increase_main_ratio and decrease_main_ratio hotkeys (5% step).

main_ratio = 0.5:

┌─────────────────────────────┬─────────────────────────────┐
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ Main │ Stack │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
└─────────────────────────────┴─────────────────────────────┘

main_ratio = 0.7:

┌─────────────────────────────────────────┬─────────────────┐
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ Main │ Stack │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
│ │ │
└─────────────────────────────────────────┴─────────────────┘

Main window count

The number of windows in the main area:

spoon.Shoji:configure({
main_count = 1, -- Default: 1 main window
})

Minimum: 1. Adjust at runtime with increase_main_count and decrease_main_count hotkeys.

main_count = 1:

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

main_count = 2:

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

Custom layouts

Register custom layout implementations with the layouts option:

local MyLayout = require("my_custom_layout")
spoon.Shoji:configure({
layouts = { MyLayout },
enabled_layouts = { "tall", "mylayout" },
})

See Creating custom layouts for implementation details.

Layout modifiers

Modify built-in layouts with modifiers. For example, mirror a layout:

local Modifiers = require("layouts.modifiers")
local Mirror = require("layouts.modifiers.mirror")
local Tall = require("layouts.tall")
local tallRight = Modifiers.wrap(Tall, Mirror.horizontal(), {
name = "tall-right",
displayName = "Tall (Right)",
})
spoon.Shoji:configure({
layouts = { tallRight },
enabled_layouts = { "tall", "tall-right", "wide" },
})

This creates a tall layout with the main area on the right instead of left. See Layout modifiers for all available modifiers.

Per-macOS Space layouts

Each macOS Space maintains its own layout. Changing layouts affects only the current macOS Space.

Bind hotkeys to switch directly to specific layouts:

spoon.Shoji:bindHotkeys({
set_layout_tall = { { "ctrl", "alt" }, "1" },
set_layout_wide = { { "ctrl", "alt" }, "2" },
set_layout_bsp = { { "ctrl", "alt" }, "3" },
})