Repository navigation
app: workspaces carry an old panes.zon over into the layout - #464
Conversation
With FIZZY_WORKSPACES=1, each workbench pane is a view the app places: fizzy.workspace.<grouping>, titled by the document it shows. Main shows the first by its keywords; a pane opened beside another (a tab dropped on a pane's edge, Open to the Side) is an app split of the place holding it, and an emptied pane closes its place as any emptied view's does, the half beside it taking its room. The workbench's own split tree and panes.zon are not used while the flag is on; layout.zon keeps the places and what each holds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With FIZZY_WORKSPACES=1, a document carried in the view drag is taken by the edges of any place, not only by the document panes: the place splits on that side and the app gives the new half a workspace holding the document (State.documents, which fizzy's Workspaces fills in). A plain place's middle is no target for a document. The app, not the workbench, now seats a document no pane holds, into the workspace it was opened toward, grouping 0 meaning the active one once the first has gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With FIZZY_WORKSPACES=1, the first frame the layout has drawn squares last session's layout with the panes that came back. An arrangement the workbench saved before the app placed its panes (panes.zon) becomes the app's splits of Main, split for split with each pane's share, and the file is deleted. A place whose workspace did not come back (it held no document at quit) closes instead of standing empty. Region.splitOnSized splits a place that has not been drawn yet, which a nested tree needs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The 1:3 in the follow-up comes from this PR's carry-over, not from the I reproduced it on this head (f927a7f) with the recipe above: a
With the Panel there, Main is 472 pt tall inside, and its half would be 231 pt. So Why it isn't the shared name. The kept origin is always the leftover half of its own branch ( The uneven split by hand was a separate, smaller bug: every split of a carded place came out short by the card padding on both sides (494 / 462 px). #465 fixes it: a place's recorded size is now its border box, and Suggested fix here: carry over once the layout under Main has settled, for example on a later frame, or once the Panel has registered its size. Another option is to store each new half's share of the place and turn it into an extent when the half is first drawn. Measuring on the first frame 🤖 Generated with Claude Code |
With FIZZY_WORKSPACES=1, a document carried onto a plain place lands there inside a new workspace, the way a view would: its middle adds the workspace to a place of tabs and takes a place of one (the view it replaces going where its keywords show it), its chooser takes it where it was let go, and an edge splits as before. State.documents now hands back the new workspace's view for the layout to place. A pane's only tab dropped on its own edge moves there with room opening on the other side, as a view alone in its place does (Workbench.Places.open). A minted place closed in the frame it was made, never drawn, is dropped outright instead of standing empty. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A document carried alone out of a workspace it is the only tab of takes the workspace along: dropped on a plain place, the workspace itself lands there (State.Documents.alone), as a drag of it would, rather than a new workspace being made round the document and the old one closing behind it. That round trip drew the document anew twice, and it blinked. A view joined with an empty half stays the one view, not a place of tabs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Found while chasing the uneven nested split reported in #464's follow-ups. ## What changes A split of a carded place now opens two even halves. Before, the new half was short by the card's padding on both sides. That covers fizzy's Main and Panel, and every split of their halves. At 2× on macOS: | | before | after | |---|---|---| | Main → Split → Vertical | Main 886 px, Main/r1 854 px | 870, 870 | | then Main/r1 → Split → Horizontal | Main/r1 494 px, Main/r1/b1 462 px | 478, 478 | **Why.** A split's extent is the new half's whole reach, border to border, padding included (`Region.init`). `splitOn` halved the place's recorded `size`, which was its *content* rect. `State.setPlaceMetrics` now records the border box, and it takes the box's `WidgetData`, so all three call sites measure it the same way. A split is the only thing that reads `size` (`placeSize`, and a drag's frozen `Target.size`). **The suspected cause was not it.** #464 suspected the `.branch` arm: it sizes the branch by `extent(b.origin)`, the same name the kept leaf has. But the kept origin is always the leftover half of its own branch (`resize = false`), so it never writes an extent under that name. Inside one tree, `extent(name)` always means the minted leaf's reach along its parent's axis, before and after that leaf is split again. Persistence round-trips too: the nested split came back at the same sizes after a restart. **The 1:3 in #464 comes from its own carry-over.** I reproduced it on #464's head (f927a7f) with its recipe: a `panes.zon` of `Pane 0` | (`Pane 4` over `Pane 5`), relaunched with `FIZZY_WORKSPACES=1`. Main/r1 came out 248 px over Main/r1/b1 708 px. The stored extent for Main/r1/b1 was 354 pt, which is exactly (718 − 10) × 0.5. 718 pt is Main's content height *without* the 236 pt Panel under it. So `settle` measures Main on a frame before the Panel has its room, and hands that height to `splitOnSized`. That fix belongs in #464. ## SDK impact - [x] None (`test-sdk-version` passes; `app/` only) ## Verified - [x] macOS: - new integration test `a split of a carded place, and of its new half, opens even halves`. It uses fizzy's shape: a carded Main with `pane_cards`, in a column, and compares the halves' drawn rects, not the `size` this PR redefines. Before the fix it failed at 187 vs 171. - sandbox fizzy (`--profile`, driven through the agent plugin): Main → Split → Vertical, then Main/r1 → Split → Horizontal, measured as in the table. - `scripts/check-fmt.sh`, `zig build`, `zig build test` (91/91 steps), `zig build test-integration` (53/53 steps), `zig build check-tests-reached`, `zig build check-web`, `zig build test-sdk-version`. - [ ] Windows: - [ ] Linux: - [ ] Web: builds ## Follow-ups - #464: measure Main once the layout under it has settled (or from the window), not on the first frame `settle` runs. Its `splitOnSized` gets the reach fix from this PR for free. - Removing a half that was split again: fixed in #467, stacked on this one. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Part of fizzyedit/work#21 (step 4 of
plans/WORKSPACES_PLAN.md). Stacked on #462, which is stacked on #461.What changes
Behind
FIZZY_WORKSPACES=1, a saved layout comes back whole.panes.zonbecomes the app's splits. The first time fizzy runs with the flag, the workbench's saved tree is laid out split for split from the place the first workspace is in (Main). Each pane's workspace goes in its half, at the share it had. Thenpanes.zonis deleted: the arrangement islayout.zon's from then on. A subtree whose panes didn't come back is skipped, so its sibling takes the room.Region.splitOnSized:splitOnfor a place that hasn't been drawn yet, with a share for the new half. A nested tree splits a half made in the same frame.splitOnnow calls it with the drawn size and half.What's already kept and needed no change: which place holds which workspace and each workspace's documents in order (
layout.zon, since #461), and each workspace's selected tab (the session,KeptDocuments.applySelections).Older fizzy reads the same
layout.zonit always did; nothing new is written. With the flag off, nothing changes. (The workbench still readspanes.zonas it did; only the carry-over deletes it.)SDK impact
test-sdk-versionpasses).Verified
Pane 0 | Pane 4);panes.zoninto a nested tree (horizontal 0.6:Pane 0| vertical 0.5 ofPane 4,Pane 5) and gavePane 5a document inlayout.zon;FIZZY_WORKSPACES=1: Main came back asMain| (Main/r1overMain/r1/b1), each half showing its workspace's document, the horizontal share 60/40, andpanes.zongone.zig build,zig build test,zig build test-integration(53/53 steps),zig build check-web,zig build test-sdk-version,scripts/check-fmt.sh.panes.zonthere, and the flag is never on.Follow-ups
Region,.branch), the same name its kept half reads its own size from along the other axis. That's the app's split code with or without this flag, so it's a separate fix.State.documentswith a float), and back.🤖 Generated with Claude Code