Skip to content

Window management

Window management actions change window positions and floating state. This page focuses on behavior and examples. For the full action list and defaults, see Actions reference.

Swap actions

Swap the focused window’s position with another window. Focus follows the window being moved.

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

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

spoon.Shoji:bindHotkeys({
swap_main = { { "ctrl", "alt" }, "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

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 (“Floating: On” or “Floating: Off”).

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

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

Retile space

spoon.Shoji:bindHotkeys({
retile_space = { { "ctrl", "alt", "shift" }, "r" },
})

Reapplies the current layout and resets all parameters to defaults:

  • main_ratio returns to 0.5 (or configured default)
  • nmaster returns to 1 (or configured default)
  • Layout-specific state clears (BSP split ratios, etc.)

Useful for resetting a macOS Space after tweaking parameters or when windows get misaligned.