i3wm Cheatsheet

Super is the Mod key (Windows/Command key) — referred to as $mod below

Essentials

$mod + ReturnOpen terminal (WezTerm)
$mod + dApp launcher (Rofi)
$mod + TabWindow switcher (Rofi)
$mod + Shift + qKill focused window
$mod + EscapeLock screen

Focus Windows

$mod + h / Focus left
$mod + j / Focus down
$mod + k / Focus up
$mod + l / Focus right
$mod + aFocus parent container
$mod + zFocus child container
$mod + spaceToggle focus tiling/floating

Move Windows

$mod + Shift + h / Move left
$mod + Shift + j / Move down
$mod + Shift + k / Move up
$mod + Shift + l / Move right
$mod + Shift + 1-0Move to workspace 1-10

Workspaces

$mod + 10Switch to workspace 1-10
$mod + Ctrl + / hPrevious workspace (same monitor)
$mod + Ctrl + / lNext workspace (same monitor)
Tip: Workspaces live on whichever monitor they were first opened on. Focus a monitor first, then switch to a workspace to place it there.

Layout

$mod + bNext new window opens to the right (no visual change)
$mod + vNext new window opens below (no visual change)
$mod + fToggle fullscreen
$mod + sStacking layout
$mod + wTabbed layout
$mod + eToggle H/V — also untabs/unstacks
$mod + Shift + spaceToggle floating
$mod + Shift + fFlatten workspace (fix nesting)
Confused? See the Containers tab for visual explanations of how layouts work.

Resize Mode

$mod + rEnter resize mode
h / Shrink width
l / Grow width
k / Shrink height
j / Grow height
Escape / ReturnExit resize mode

Gaps

$mod + gIncrease inner gaps
$mod + Shift + gDecrease inner gaps
$mod + Ctrl + gRemove all gaps

Layout commands change how a container arranges its children. If a command doesn't work, press $mod+a first to select the parent container.

Layout modes

A B A B A B A (active) B (hidden) $mod+e split (toggle H/V) $mod+e split (toggle H/V) $mod+w tabbed $mod+s stacked

Switch vertical ↔ horizontal

BEFORE A B $mod+a $mod+e AFTER A B
Focus A or B, press $mod+a (parent), then $mod+e (toggle split).

Move windows together

BEFORE A B ← focused $mod+Shift+h AFTER (split) A B $mod+a, $mod+w TABBED A B
Focus B, move it left into A's space, then optionally $mod+a + $mod+w to tab them. Undo: $mod+a, $mod+e.

Navigate: parent ↔ child

Workspace Window A Container [tabbed] $mod+a ↑ ↓ $mod+z Window B Window C
$mod+a zooms out to the parent container. $mod+z zooms back into the child.

Recommended: Dev workspace

Claude Code terminal Browser nvim gh-dash (active tab content)
Terminal on the left, tabbed apps on the right. Set up once, leave it.
Steps:
1. $mod+Return — open terminal for Claude Code
2. $mod+Return — second terminal opens right
3. $mod+v on right terminal — set vertical split
4. $mod+Return × 2 — two more terminals below
5. Focus any right terminal, $mod+a, $mod+w — tabs
6. Launch browser/nvim/gh-dash from each tab

Nesting — the hidden trap

Every tab/untab cycle ($mod+w then $mod+e) adds a container level. Repeat a few times and $mod+a needs many presses.

Avoid: Don't toggle tab/split repeatedly. Set up once and leave it.
Fix: $mod+Shift+f flattens the workspace — resets all nesting.

The core rule

Layout commands ($mod+e/w/s) always operate on the parent of the focused node.

Focus a window inside a group → command changes the group's layout. Correct.
Focus a container via $mod+a → command changes the container's parent. One level too high.

$mod+v / $mod+b are different — they set where the next new window opens. No visual change.

Container quick reference

$mod+aFocus parent (zoom out)
$mod+zFocus child (zoom in)
Change existing layout (focus a window, press directly)
$mod+eToggle H/V — also untabs/unstacks
$mod+wTab siblings
$mod+sStack siblings
Set direction for next new window
$mod+bNext new window → right
$mod+vNext new window → below
Fix
$mod+Shift+fFlatten workspace (fix nesting)
$mod+oMove workspace to other monitor
$mod+Shift+oGather all workspaces here

Everything is a tree

i3 represents your entire screen as a single tree. Every node in that tree is called a container. Containers with children arrange those children on screen according to a layout rule. Containers without children — the leaves — hold actual application windows. That's the whole model.

The top of the tree is always the same fixed structure. The root node sits at the very top. Below it, one node per physical monitor (i3 calls these outputs). Below each output, the workspaces you switch between with $mod+1, $mod+2, and so on. Below the active workspace is where you work.

root HDMI-1 physical monitor (output) workspace 1 virtual desktop · $mod+1 con [splith] layout node · arranges children Terminal window (leaf node) Firefox window (leaf node)
The full i3 container tree for one monitor, one workspace, two open apps. Gray = infrastructure, purple = workspace, blue = container, green = leaf windows.
The word "window" in i3 just means a leaf container. There is no separate "window" concept distinct from containers — a window is simply a container node that happens to have no children and therefore holds an application process.

Layouts

A container's only job is to declare a layout — a rule that controls how its children are positioned and sized. There are four layouts in i3:

splith
Children are tiled left to right, each taking equal width. The default when you open windows.
splitv
Children are tiled top to bottom, each taking equal height. Triggered with $mod+v before opening.
tabbed
All children share the same space. A horizontal tab bar shows their titles; only the focused one is visible. Toggle with $mod+w.
stacked
Same as tabbed but the title list is a vertical stack instead of a horizontal bar. Toggle with $mod+s.
A B A B A B A (active) B (hidden) splith side by side splitv top & bottom tabbed one visible at a time stacked vertical tabs
The same two windows rendered with each layout. Blue = focused window. The layout attribute lives on the parent container, not on the windows themselves.

The layout attribute lives on the container, not on the windows inside it. When you press $mod+w to switch to tabbed, you are changing the layout property of whichever container is the parent of the focused window. Every sibling in that container immediately becomes a tab. Switch back to $mod+e (splith/splitv toggle) and they tile again — the same tree, different rendering.

Splitting

Pressing $mod+v or $mod+b does not immediately change anything visible. It marks the focused window so that the next window you open will land inside a newly created container that wraps the current one. Split and open are two separate actions.

Suppose Terminal is the only window in your workspace. You press $mod+v, then open Neovim. i3 creates a new splitv container, moves Terminal inside it, then places Neovim as a sibling in that container.

BEFORE workspace Terminal $mod+v + open Neovim AFTER workspace con [splitv] new node Terminal Neovim one new container node inserted
Splitting inserts exactly one new container node between the focused window and its parent.

This is why trees can grow arbitrarily deep. Every split adds exactly one level of nesting. You can have a splitv container inside a splith container inside a tabbed container — each with its own independent layout.

The workspace is just another container. When you first open a window on an empty workspace, that window becomes a direct child of the workspace node — the workspace is the first container. Split once and a new container is inserted below the workspace.

Focus

The focused window is always a leaf. i3 tracks a focused path — a chain of nodes from the root down to exactly one leaf. Every container along this path also has focus, in the sense that it knows which of its children is in the focused chain.

When you navigate with $mod+h/j/k/l or $mod+Arrow, you move focus to an adjacent leaf within the same parent container. If you reach the edge of the container, focus crosses into the nearest container in that direction. This is why navigation in i3 feels spatial: the tree's structure determines the neighborhood of any given window.

For tabbed and stacked containers, focus controls more than highlighting — it determines which child is rendered. All other children are hidden. Changing focus within a tabbed container is equivalent to switching tabs.

Each internal container remembers which of its children was last focused. If focus moves into a container from outside, i3 restores that container's remembered focus rather than defaulting to the first child. This makes workspace switching and tab navigation feel consistent — returning to a workspace always lands you on the window you were last using.

Nesting — the hidden trap

Every time you tab ($mod+w) then untab ($mod+e), i3 creates a new container level. Repeat this a few times and your windows are buried many levels deep. Then $mod+a needs many presses to reach the right parent.

Avoid toggling tab/split repeatedly. Set up your layout once and leave it. If nesting gets out of hand, press $mod+Shift+f to flatten the workspace — it moves all windows out and back to reset the tree to a single level.

Best practice: Open all your windows first, arrange them with splits, then tab the group you want. Don't keep switching between tabbed and split on the same container — that's what causes deep nesting.

The core rule

Layout commands always operate on the parent of the focused node.

Focus on a window → command changes the container holding that window (correct).
Focus on a container (via $mod+a) → command changes that container's parent (one level too high).

To change a group's layout: focus a window inside the group, press $mod+w/e/s directly.

Don't press $mod+a before layout commands — it moves focus up, so the command operates one level higher than intended.

The mental model

You start with a blank workspace: one container. Every window you open becomes a child of the container that currently holds focus. $mod+v or $mod+b followed by opening a window inserts a new container node, creating a sub-region with its own layout.

$mod+v
Next new window opens below (no visual change).
$mod+b
Next new window opens to the right (no visual change).
$mod+w
Tabs siblings. Focus a window in the group, press directly.
$mod+s
Stacks siblings. Focus a window in the group, press directly.
$mod+e
Toggles siblings H/V. Focus a window in the group, press directly.
$mod+a / $mod+z
Move focus up/down the tree. For moving windows, not layout changes.
$mod+Shift+f
Flatten workspace — reset all nesting.
$mod+o
Move current workspace to the other monitor (toggles between outputs).
$mod+Shift+o
Gather all workspaces to current monitor.
auto-pin
i3 config pins ws 2–6 to the external (HDMI-1 / DP-1), ws 1 to the laptop. Connect the dock at home or office and they migrate automatically; undock and they fall back to eDP-1.
$mod+Shift+v
Toggle the AWS VPN window between sticky-visible (follows you across all workspaces) and hidden in scratchpad. Same gesture in both directions. Polybar's VPN icon is the click-to-toggle equivalent.
VPN status
Polybar indicator color reflects state: green = connected, gray = disconnected, red = AWS VPN service is down. Detection: acvc-openvpn process active means connected.
i3tree
Terminal command — shows the container tree for debugging.
$mod+Shift+p
Relaunch polybar (if missing on a monitor).
$mod+Ctrl+k
Re-apply keyboard layout (if Alt+Shift stops working).

When confused, run i3tree to see the tree, and $mod+Shift+f to reset. Every action is a tree operation.

Monitors

External monitor is managed by autorandr — plug/unplug is automatic.
$mod + Shift + Move window to monitor above
$mod + Shift + Move window to monitor below
Profiles: mobile (laptop only) • docked (external + laptop)
Save: autorandr --save <name> --force

Screenshots

PrintScreenshot selection (Flameshot)
$mod + PrintFull screenshot
$mod + Shift + PrintCurrent screen screenshot

Audio

Volume Up keyRaise volume +5%
Volume Down keyLower volume -5%
Mute keyToggle mute
Mic Mute keyToggle mic mute

Keyboard

Alt + ShiftToggle BR / US layout
Current layout is shown in the polybar (top-right area).

Notifications

dunstctl closeClose one notification
dunstctl close-allClose all notifications
dunstctl set-paused toggleDo not disturb toggle
Right-click notificationClose all

Scratchpad

$mod + Shift + -Send window to scratchpad
$mod + -Show/cycle scratchpad windows
Scratchpad is a hidden workspace. Send windows there to hide them, then recall them as floating windows.

i3 Management

$mod + Shift + cReload config
$mod + Shift + rRestart i3 in-place
$mod + Shift + pRelaunch polybar (fix missing bar)
$mod + Ctrl + kRe-apply keyboard layout (fix Alt+Shift)
$mod + Shift + eExit i3 (logout)

Tips

Floating: Some dialogs auto-float. Toggle any window with $mod+Shift+space. Hold $mod and drag to move floating windows.

Wallpaper: feh --bg-fill ~/Pictures/Wallpapers/<name>

Compositor: Using xcompmgr for shadows. Restart with: pkill xcompmgr && xcompmgr -c -r 6 -o 0.4 -l -5 -t -5 &