dock: Keep an empty StackPanel a stack when dumped (#2686)
## Description
`StackPanel::dump` assigned `state.info` **inside** the loop over its
children, so a StackPanel holding no panel never ran it and kept
`PanelState`'s default, `PanelInfo::Panel(Null)`:
```json
{ "panel_name": "StackPanel", "children": [], "info": { "panel": null } }
```
Restoring that takes the `PanelInfo::Panel` arm, which looks
`StackPanel` up in `PanelRegistry` — a container is never registered
there — so the whole tab renders *"The `StackPanel` panel type is not
registered in PanelRegistry."* instead of the layout.
Only reachable once a layout can be empty, which is why it went
unnoticed: a split layout built from a template always ships with
panels, and an empty canvas centre is `Tiles`, not `StackPanel`.
Downstream it shows up as a saved-but-empty split layout coming back
broken after a restart.
Assigning the info once before the loop also stops it being recomputed
on every iteration.
## Break Changes
None.
## How to Test
```
cargo test -p gpui-component dock::tab_panel # 22 passed
cargo check --workspace --all-targets
cargo fmt --check
```
`empty_center_round_trips_as_a_stack` is new: it dumps a fresh
`DockArea` and asserts the centre comes back as `PanelInfo::Stack`. It
fails on `main`.
## Checklist
- [x] I have read the [CONTRIBUTING](../CONTRIBUTING.md) document and
followed the guidelines.
- [x] Reviewed the changes in this PR and confirmed AI generated code
(If any) is accurate.
- [ ] Passed `cargo run` for story tests related to the changes — no
story starts from an empty split layout.
- [ ] Tested macOS, Windows and Linux platforms performance (if the
change is platform-specific)
AI assistance: written with Claude Code, reviewed by hand. C
Cookie committed
6e3f241136ed9a60d0f38d53ac3bdf285a3a13f7
Parent: 8bb7f47
Committed by GitHub <noreply@github.com>
on 8/12/2026, 3:28:04 AM