vercel-labs / vercel-labs/native

Per-view widget layout budget (1024 nodes) drops whole frames on real multi-pane app views

Open Beginner friendly
#408 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Zig
Stars
7.7k
Forks
314
Avg merge
5h
Merged PRs (30d)
13

Description

Symptom

A production three-pane desktop app built on the SDK hits WidgetLayoutListFull on ordinary interactions. The layout-retention failure drops the whole frame: opening a dialog, or clicking controls in a large view, leaves the UI visually unchanged — buttons appear dead. Once a view is over budget, the error fires on every invalidated frame, wedging the view's interactions entirely.

Evidence

View composition (real app, nothing exotic):

  • a session rail enumerating ~50 session rows,
  • a detail timeline retaining the full transcript,
  • a model-picker dialog listing ~60 model rows with provider-group headers.

Automation snapshot of the dialog frame: 1008 widgets. The retained node count runs ≈1.8 nodes per widget (each row widget carries inner rows/columns/text), so the frame needs ~1800 nodes — well past the 1024 cap in canvas_limits.max_canvas_widget_nodes_per_view. The error path is adoptWidgetLayoutWidgetLayoutListFull → the rebuild never lands and the whole frame is discarded.

The current comment sizes 1024 against "the measured worst realistic three-pane view is ~500 nodes". That estimate predates list-dense surfaces: any app whose rails/dialogs enumerate unbounded collections (sessions, models, files) crosses 1024 with a single dialog open on top of the base chrome. The failure mode is much worse than the budget's "fail loudly" intent — it doesn't reject an operation, it silently kills every subsequent frame for the view.

Proposed fix

Raise the budget 1024 → 4096 (and automation.snapshot.max_widgets_per_view in lockstep; the existing lockstep test in canvas_widget_layout_tests.zig keeps them equal). These are validation bounds over fixed-capacity address space — pages are only touched as views use capacity — so the raise costs address space, not committed memory. PR to follow.

Longer term, apps retaining unbounded collections will outgrow any fixed cap; windowed/virtualized retention for list widgets would remove the cliff entirely. Happy to file a separate issue for that discussion if useful.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with canvas_limits.max_canvas_widget_nodes_per_view and the automation.snapshot.max_widgets_per_view definitions, then read the lockstep test in canvas_widget_layout_tests.zig. Reproduce or inspect the existing capacity validation and update both bounds consistently. Done means the test still verifies equality and a three-pane view needing roughly 1800 retained nodes no longer hits WidgetLayoutListFull.

Written by the indexing model from the issue text.

Assessment

Tech stack
zig
Domain
desktop
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.