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 adoptWidgetLayout → WidgetLayoutListFull → 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.
Symptom
A production three-pane desktop app built on the SDK hits
WidgetLayoutListFullon 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):
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 isadoptWidgetLayout→WidgetLayoutListFull→ 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_viewin lockstep; the existing lockstep test incanvas_widget_layout_tests.zigkeeps 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.