Window management
Window management actions change window positions, floating state, and zoom. This page focuses on behavior and examples. For the full action list and defaults, see Actions reference.
Swap actions
Section titled “Swap actions”Swap the focused window’s position with another window. Focus follows the window being moved.
Directional swap
Section titled “Directional swap”spoon.Shoji:bindHotkeys({ swap_left = { { "ctrl", "alt", "shift" }, "h" }, swap_down = { { "ctrl", "alt", "shift" }, "j" }, swap_up = { { "ctrl", "alt", "shift" }, "k" }, swap_right = { { "ctrl", "alt", "shift" }, "l" },})Example with swap_right (asterisk marks focus):
Before:
┌─────────────────────────────┬─────────────────────────────┐│ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ 1* │ 2 ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ │└─────────────────────────────┴─────────────────────────────┘After:
┌─────────────────────────────┬─────────────────────────────┐│ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ 2 │ 1* ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ ││ │ │└─────────────────────────────┴─────────────────────────────┘The focused window trades places with the target. Focus stays with window 1.
Order-based swap
Section titled “Order-based swap”spoon.Shoji:bindHotkeys({ swap_next = { { "ctrl", "alt", "shift" }, "n" }, swap_prev = { { "ctrl", "alt", "shift" }, "p" },})Swaps with the adjacent window in stack order. Good for reordering windows without worrying about screen positions. The order wraps around.
Swap with main
Section titled “Swap with main”spoon.Shoji:bindHotkeys({ swap_main = { { "ctrl", "alt", "shift" }, "return" },})Promotes the focused window to the main (first) position:
Before (focus on 3):
┌─────────────────────────────┬─────────────────────────────┐│ │ ││ │ ││ │ ││ │ ││ │ 2 ││ │ ││ │ ││ │ ││ 1 ├─────────────────────────────┤│ │ ││ │ ││ │ ││ │ 3* ││ │ ││ │ ││ │ ││ │ │└─────────────────────────────┴─────────────────────────────┘After:
┌─────────────────────────────┬─────────────────────────────┐│ │ ││ │ ││ │ ││ │ ││ │ 2 ││ │ ││ │ ││ │ ││ 3* ├─────────────────────────────┤│ │ ││ │ ││ │ ││ │ 1 ││ │ ││ │ ││ │ ││ │ │└─────────────────────────────┴─────────────────────────────┘If the focused window is already in main position, nothing happens.
Toggle floating
Section titled “Toggle floating”spoon.Shoji:bindHotkeys({ toggle_float = { { "ctrl", "alt", "shift" }, "t" },})Switches the focused window between tiling and floating modes:
- Tiling to floating: The window leaves the tiled layout. Remaining windows expand to fill the gap.
- Floating to tiling: The window rejoins the layout as a new entry, typically at the end of the tile order.
An on-screen alert confirms the new state (“Window floating” or “Window tiled”).
Float state persistence
Section titled “Float state persistence”- Persists across retiles and layout changes
- Cleared when the window closes
- Per-window, not per-macOS Space (a window stays floating on all macOS Spaces)
Floating window behavior
Section titled “Floating window behavior”Floating windows:
- Ignore all tiling operations
- Can be freely moved and resized
- Sit above tiled windows (standard macOS z-order)
- Are skipped by focus navigation actions
Toggle zoom
Section titled “Toggle zoom”spoon.Shoji:bindHotkeys({ toggle_zoom = { { "ctrl", "alt" }, "f" },})Temporarily maximizes the focused window to fill the entire screen work area. The window floats above the tiled layout while zoomed, and remaining tiled windows rearrange to fill the gap.
Press again to unzoom and restore the window to its tiled position.
How zoom differs from floating
Section titled “How zoom differs from floating”- Floating removes a window from tiling so you can position it freely. The window keeps its current size and position.
- Zoom floats and maximizes the window in one step. Unzooming restores it to tiling automatically.
Floating state preservation
Section titled “Floating state preservation”If a window is already floating when you zoom it, unzooming keeps it floating (rather than forcing it back into tiling). This prevents accidentally losing a deliberate floating state.
Zoom state persistence
Section titled “Zoom state persistence”- Persists across retiles and layout changes (same as floating)
- Cleared when the window closes
Retile space
Section titled “Retile space”spoon.Shoji:bindHotkeys({ retile_space = { { "ctrl", "alt", "shift" }, "r" },})Reapplies the current layout using existing parameters. Useful when windows get misaligned or after manual moves.
To reset main_ratio, main_count, and layout-specific state, use
reset_space in Layout control.