From e92ed982034f17d41319064d2dd0f1ea1f1f01d7 Mon Sep 17 00:00:00 2001 From: Kayshen-X Date: Sun, 10 May 2026 17:57:07 +0800 Subject: [PATCH] docs(shell): note canvas_region invariant for collapsed sidebar Recent codex stop-hook iterations exposed three sites where input hit-test hardcoded LAYER_PANEL_WIDTH while paint followed canvas_region (which collapses to 0 when sidebar is closed): over_canvas, apply_wheel cursor offset, toolbar hit rect. Document the invariant so future widgets don't re-introduce the drift. --- crates/CLAUDE.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/CLAUDE.md b/crates/CLAUDE.md index bb118d230..7b78bfd2e 100644 --- a/crates/CLAUDE.md +++ b/crates/CLAUDE.md @@ -98,9 +98,13 @@ Hit-test runs in REVERSE paint order so the topmost overlay always wins: 1. TopBar (sidebar toggle button) — also eats other top-bar gaps 2. AI chat panel (DragHandle starts drag; FocusInput / Send / Example / ToggleCollapse defer to apply_click) 3. Toolbar (button hits dispatch tools; gaps inside the bounding rect eat clicks) -4. apply_click → LayerPanel rows / Page rows + chat-defocus +4. apply_click → LayerPanel rows / Page rows + chat-defocus (skipped when sidebar collapsed) 5. Empty canvas press → clear `selected` (collapses RightPanel) + start pan-drag +### Coordinate invariant + +Every input path that reasons about the canvas region MUST derive its rects from `canvas_region(viewport_w, viewport_h)`. Never reuse `LAYER_PANEL_WIDTH` for hit-test — paint follows `canvas_region`, which collapses to `canvas_left = 0` when `Document.ui.sidebar_open == false`. Sites that proved this rule by violating it: `over_canvas`, `apply_wheel` cursor offset, toolbar hit rect in `apply_press` / `apply_click`. Web `apply_wheel` zoom anchor + `toolbar_rect()` helper follow the same rule. + ## Performance gotchas - Native chrome paint: ~30 text draws × jian-skia textlayout's per-call `FontCollection::new()` = ~600ms/frame. Fix is the cached typeface path described above. Don't add new draw_text calls without cache awareness.