# Canvas Initial Render & Continuous Repaint Fix ## Problem Analysis ### Issue 1: Canvas not visible on first image open When a file is opened via `pending_load` in `HcieApp::logic()` (line 2897), the document is pushed to the dock using `self.dock_state.push_to_focused_leaf()`. This pushes the tab to whatever leaf is currently focused — which may be a utility panel (Tools, Layers, etc.) rather than the document center area. The document tab exists but is hidden behind a narrow utility panel, requiring the user to click the tab title to see the canvas. The `FileOpenRequested` event handler (line 1573, 1604) correctly uses `push_document_to_center()` which finds the document leaf and focuses it before pushing. But the `pending_load` path in `logic()` uses the raw `push_to_focused_leaf()`. ### Issue 2: Continuous repaint In `logic()` (line 2996-2998): ```rust if self.stable_frames < 5 { ctx.request_repaint(); } ``` `stable_frames` is incremented in `ui_main_assembly()` (line 2370) only when `(self.last_window_width - avail_w).abs() < 0.1`. The `layout_solver::adjust_pixel_widths()` changes dock split fractions on startup (when `stable_frames < 3`), which can cause the available width to fluctuate slightly between frames, resetting `stable_frames` to 0 repeatedly. This creates an infinite loop of repaint requests. Additionally, the `enforce_constraints` function runs every frame and may move document tabs around, which also triggers repaints. ## Changes ### 1. `hcie-egui-app/crates/hcie-gui-egui/src/app/mod.rs` — `logic()` function **a) Use `push_document_to_center()` in `pending_load` handler** Replace both `self.dock_state.push_to_focused_leaf(...)` calls in the `pending_load` block (lines 2918 and 2944) with `self.push_document_to_center(dock::HciePane::Document(self.active_doc))`. This ensures the document tab goes to the center document area and is focused immediately. **b) Fix continuous repaint — replace `stable_frames < 5` with targeted approach** Replace the `stable_frames < 5` check (lines 2995-2998) with a single `ctx.request_repaint()` call that runs only on the very first frame after app start. Use a new boolean field `first_frame` on `HcieApp` that is set to `true` in `new()` and set to `false` after the first repaint request. This prevents the layout solver's width fluctuations from causing infinite repaint loops. **c) Ensure composite texture is created immediately after loading** After the `pending_load` block, explicitly call `doc.engine.mark_composite_dirty()` and ensure the composite buffer is allocated. This is already done by `open_image()` which sets `composite_dirty = true`, but we should also ensure the buffer is pre-allocated to the correct size so `render_composition()` can create the texture on the very first frame. ### 2. `hcie-egui-app/crates/hcie-gui-egui/src/app/mod.rs` — `HcieApp` struct Add `first_frame: bool` field, initialized to `true` in `new()`. ### 3. `hcie-egui-app/crates/hcie-gui-egui/src/app/mod.rs` — `ui_main_assembly()` Ensure that after `enforce_constraints` moves document tabs, the composite is marked dirty so the canvas re-renders with the correct content. ## Files to modify | File | Change | |------|--------| | `hcie-egui-app/crates/hcie-gui-egui/src/app/mod.rs` | Fix `pending_load` to use `push_document_to_center()`, fix continuous repaint, add `first_frame` field | ## Files NOT to modify (regression protection) - `hcie-engine-api/src/lib.rs` — locked, no changes needed - `hcie-egui-app/crates/hcie-gui-egui/src/canvas/mod.rs` — no changes needed - `hcie-egui-app/crates/hcie-gui-egui/src/canvas/render.rs` — no changes needed - `hcie-egui-app/crates/hcie-gui-egui/src/app/layout_solver.rs` — no changes needed - `hcie-egui-app/crates/hcie-gui-egui/src/event_bus.rs` — no changes needed