SIGN IN SIGN UP

dock: Add `DockItem::is_empty` (#2683)

## Description

Hosts that want to render something when a layout holds no panel — a
placeholder, a different background — currently have no way to ask.

`DockItem::items` looks like the answer, but it is stale in both
directions: `add_panel` only pushes into them, `remove_panel` takes
`&self` so it cannot remove, and splitting never touches them. `dump`
does walk the live tree, but it builds the whole serialisable state, and
a panel's `dump` may read host state the caller is already holding.

So `DockItem::is_empty` walks the live panels and answers only that one
question. A container is empty when every child is (`all` over no
children is `true`, so a fresh one is empty). A leaf is empty while it
is hidden, which is what rendering already assumes: `StackPanel` draws
each child as `.visible(panel.visible(cx))` and `TabPanel::visible`
counts only visible panels, so a group holding nothing but hidden panels
draws nothing and should not read as full.

`Tiles` recurses for the same reason its children outlive their
contents: a `TabPanel` in a tile has no parent `StackPanel` to remove
itself from, so emptying it leaves the tile behind.

The method lives on `DockItem`, so a dock can be asked the same question
through `Dock::panel()`. `DockArea::is_center_empty` wraps it for the
centre — named that way because a `DockArea` also has three docks, and
an inherent `is_empty` would shadow the extension traits downstream
already define under that name.

## How to Test

```sh
cargo test -p gpui-component dock::   # 34 passed
cargo check --workspace
cargo clippy -p gpui-component --all-targets
cargo fmt --check
```

Six of those tests cover the walk:

- a fresh `DockArea` reports empty
- a centre holding a tab group does not
- after removing every panel it reports empty again — the `DockItem`
tree still lists the tab group here, so anything reading `items` would
get this wrong
- adding a panel to an empty tab group flips it back
- a centre whose panels are all hidden reports empty
- a centre holding a single emptied tile reports empty

The last two also assert that the panels and the tile are still in
place, so they cannot quietly become no-ops if `TabPanel` or `Tiles`
later learns to drop its empty children. Both fail if the matching arm
stops recursing.

`cargo check --workspace --all-targets` does not run here: upstream
`gpui`'s test target fails to build with `can't find crate for
sum_tree`, which `cargo check -p gpui --all-targets` reproduces on its
own.

## 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.
- [x] Passed `cargo run` for story tests related to the changes — see
Screenshot above.
- [x] Tested macOS, Windows and Linux platforms performance (if the
change is platform-specific)

AI assistance: written with Claude Code. The empty/hidden semantics and
the API placement were reviewed and adjusted by hand.

---------

Co-authored-by: Floyd Wang <gassnake999@gmail.com>
C
Cookie committed
8bb7f4708b9934bc0bc5afb2e9dc63f20b38b61d
Parent: 3c2769e
Committed by GitHub <noreply@github.com> on 8/12/2026, 2:41:28 AM