Replaces the flat pane list with a binary split tree, so a view can hold
layouts a single shared orientation could not express. Three panes in a row
with the rightmost dragged to the bottom now gives two on top and one
spanning the full width beneath them.
Each split node owns a GtkPaned, which brings draggable dividers. Positions
are stored as ratios and re-applied whenever the available space changes, so
proportions survive window resizes while user drags still update them.
Drop placement depends on proximity to the view's own border: near an edge
the pane is placed against the whole layout and spans it, anywhere else it
splits only the pane under the pointer.
Drags now rearrange live rather than on release, so the layout under the
cursor is always the result. Cancelling restores the original arrangement,
which works because only the dragged pane moves: the rest of the tree keeps
its shape, so re-inserting beside the original sibling is enough.
Fixes a latent ownership bug the tree exposed: panes did not hold a
reference to their own widget, so detaching one during a rebuild dropped the
last reference and finalized it, producing GTK_IS_WIDGET assertion failures.
Panes and split nodes now each own a reference to their widget.
A tab is now a view holding an ordered list of panes rather than a single
terminal. New panes open side by side; moving one against a top or bottom
edge restacks the view, and against a side edge returns it to a row.
Layout is a flat list with one orientation per view rather than a split
tree. That covers a shell beside an agent without the structure a tree
needs, and it can be replaced once mixed layouts actually matter.
Panes live in a GtkBox and are reordered in place, so rearranging never
unparents a terminal and running processes and scrollback survive the move.
Dragging a pane uses its header as the handle so it never competes with the
terminal's own mouse handling, and drops go through the same moveRelative
path as the Ctrl+Shift+arrow shortcuts.
Also fixes an ordering bug this surfaced: View.create used to add its first
pane immediately, firing the title callback into a Tab that had not been
initialized yet. The view is now created empty and the caller adds the pane
once it has finished wiring itself up.
Uses libghostty-vt (the API Ghostty documents for external embedders) for
the terminal core. Ghostty's other C API, ghostty.h, exposes a full terminal
surface but only supports macOS and iOS platform tags, so it cannot be
embedded on Linux.
We supply the layers libghostty-vt deliberately leaves out: PTY and process
management, a Cairo/Pango cell renderer, and a GTK4/libadwaita UI with a
Zen-style vertical tab sidebar.
Nix pins the whole toolchain (Zig 0.16 via zig-overlay, GTK 4.22, libadwaita)
so no host setup is needed.