Skip to content
C.W.K.
Stream
Lesson 02 of 05 · published

The Pane Tree

~12 min · pane, split, tree, layout, focus

Level 0Spark
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

A Pane Is an Object, Not a Rectangle

A native split is a tree. Each node is either a split (horizontal or vertical, with a divider) or a leaf (a pane bound to one PTY and one terminal view). Nested splits are just deeper nodes. That sounds like window-manager trivia. It is the difference between "I can move this job" and "I can screenshot this job." An object has identity: title, color, focused descendant, the process attached to it. A rectangle in a byte stream has cells.

Because the pane is an object, the app can ask it questions without parsing the screen. Which pane has focus. Which process is in the foreground. What directory it was born in. A sibling that wants a new split to the right of this object asks the tree, not a multiplexer. Selection copies text from the view, not a scraped grid. The first track's seam was expensive because none of those questions had an object to land on.

Linked Dividers and Maximize

Dividers are part of the tree, not decorations. Adjacent splits that share an edge can share a divider, so dragging one does not leave a jagged gap. That is layout, owned, not a luck of pixel alignment. Maximize is also a tree operation: the focused leaf takes the tab's frame, the other leaves remember their ratios, restore puts the tree back. Maximize is not "hide the other PTYs." The jobs keep running. Only the projection of the sibling leaves is borrowed.

If maximize killed the unfocused jobs, it would be a close wearing a zoom icon. If maximize discarded the tree and rebuilt a single pane, restore would rematerialize instead of revealing. The tree has to survive being visually one leaf. That is the same lesson as detach: the drawing is allowed to change without the ownership changing.

Navigate the Objects

Keyboard navigation walks leaves: next, previous, and left/right/up/down by nearest rectangle that overlaps on the other axis. That directional pick is how Smolder actually moves focus — geometry on objects, not a parsed screen. Parent-split and swap-with-neighbor are not verbs here. The tree still owns the leaves, which is the tree you will drag in the next lesson.

Focus is singular inside a window. One leaf is the focused pane. Chrome can show that without painting the world orange — a rail, a mark, a word in the title. The next lessons will put identity in that chrome and let TUI colors stay standard. Here the only claim is: there is a focused object, the tree knows which, and navigation moves that knowledge, not a pixel highlight that forgot the model.

The pane is an object in a tree. Nested splits, linked dividers, maximize, and navigation are operations on that tree. If you have to parse cells to do them, you do not own the pane yet.

Code

A tab as a tree of objects, not a grid of cells·text
tab
 └─ split(vertical, ratio 0.5)
     ├─ split(horizontal, ratio 0.4)
     │   ├─ leaf { title: "zsh", pty: A, focused: true }
     │   └─ leaf { title: "lazygit", pty: B }
     └─ leaf { title: "ssh remote", pty: C }

# Operations that must be tree ops, not screenshot ops
  split focused leaf
  move divider (linked if a neighbor shares the edge)
  maximize focused leaf   -> other leaves keep ratios, PTYs stay alive
  restore from maximize   -> same tree, not a rematerialize
  focus next / previous   -> walk leaves in tree order

# Directional focus (Smolder does this)
  left/right/up/down = nearest overlapping rectangle
# Not a tree op
  "parse tmux status to guess which pane is active"

External links

Exercise

Sketch a tab with three leaves (two stacked on the left, one full-height on the right). Write the tree. Then write what maximize of the bottom-left leaf does to (a) pixels, (b) PTYs, (c) the stored ratios. If (b) is "the others die," maximize is misnamed. If (c) is "forgotten," restore will rematerialize instead of revealing.
Hint
The tree is the product. Pixels are a projection of the tree. PTYs belong to the daemon and do not care that you zoomed.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.