Skip to content

Add Display::Contents support#944

Open
rlch wants to merge 6 commits into
DioxusLabs:mainfrom
rlch:display-contents
Open

Add Display::Contents support#944
rlch wants to merge 6 commits into
DioxusLabs:mainfrom
rlch:display-contents

Conversation

@rlch
Copy link
Copy Markdown

@rlch rlch commented Apr 1, 2026

Implements CSS display: contents for TaffyTree. A contents node generates no box — its children get promoted to the parent's child list during layout.

Picks up where #534 left off, but avoids the RefCell cache thrashing that caused the perf regression.

Changes

  • Display::Contents variant on the enum
  • Contents nodes get zero layout, children are not hidden
  • child_ids() / child_count() / get_child_id() flatten through contents nodes recursively
  • Flattened children pre-computed once per layout pass in a SecondaryMap
  • contents_dirty flag skips the resolve walk when no contents nodes exist

Performance

Scenario Before After (no contents) After (20% contents)
relayout 100 nodes 11.4 µs 11.4 µs 16.6 µs (+46%)
relayout 1000 nodes 119.6 µs 119.6 µs 167.9 µs (+40%)

Zero overhead when no contents nodes exist. ~40% when they're present (resolve walk + extra nodes).

Criterion benchmarks in benches/benches/display_contents.rs.

Tests

  • Flex promotion (5 items, 2 via contents wrapper)
  • Nested contents (recursive flattening)
  • Contents vs None behavior
  • Style roundtrip
  • Zero-overhead fast path

Closes #533

rlch added 6 commits April 1, 2026 13:19
Adds Display::Contents to the Display enum. Contents nodes generate no
box — they are invisible to layout, and their children should be laid
out as if they were direct children of the node's parent (CSS
`display: contents` semantics).

The layout dispatch treats Contents like hidden (zero layout, clear
cache) but does NOT recursively hide children. Child flattening is
the responsibility of the TraversePartialTree implementation.
Tests verify:
- Contents nodes get zero layout (no box generated)
- Contents children are not recursively hidden like Display::None
- Style roundtrip (set/get Display::Contents)

Note: child flattening tests belong in the consumer's
TraversePartialTree implementation, not here.
When a node's direct children include Display::Contents nodes, their
children are recursively promoted into the parent's child list. This
is resolved once before each layout pass (not on every child_ids call).

Performance: O(0) when no contents nodes exist (tracked by counter).
When contents nodes are present, O(n) walk to pre-compute flattened
children stored in a SecondaryMap. No RefCell, no per-call allocation,
no cache thrashing — addresses the performance concerns from PR DioxusLabs#534.

Tests verify: basic promotion, nested contents, contents vs none
behavior, style roundtrip, and zero-overhead fast path.
Criterion benchmarks comparing layout performance with and without
Display::Contents nodes across flat trees (10/100/1000), deep trees
(4^6 = 4096 nodes), and relayout scenarios.

Results: zero overhead when no contents nodes exist (counter skip).
With 20% contents nodes at 1000 items: ~186µs relayout vs ~123µs
baseline — well within frame budget for typical UI trees.
Simpler and less error-prone than maintaining a counter across every
mutation method. The flag is set whenever a Display::Contents-related
mutation occurs, and cleared after resolve if no contents nodes exist.

Benchmarks show equal or slightly better performance vs the counter.
6 browser-verified test cases:
- basic (5 items, 2 via contents wrapper)
- nested (contents within contents)
- deeply nested (3 levels of contents)
- single child (GestureDetector use case)
- flex-grow through contents
- contents vs none side-by-side

All expected values verified against Chrome's computed layout.
Also adds "contents" to the FromStr parser for Display.
@alice-i-cecile alice-i-cecile added the enhancement New feature or request label Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Display::Contents

2 participants