fix(shell-web): Step 3 stop-hook — read canvas size from backend
Codex Step 3 stop-hook flagged: "web repaint ignores actual canvas size". The prior fix `9cf0f865` hardcoded `960.0` to match the smoke HTML's `<canvas id="op" width="960">`, but that's brittle — any host that mounts onto a differently-sized canvas (responsive HTML, programmatic mount, future smoke fixture changes) gets the wrong layout viewport. Fix: WebBackend gains `canvas_width(&self) -> u32` + `canvas_height(&self) -> u32` accessors. The `width` / `height` fields are already refreshed at construction (`canvas.width()`) and on `RenderBackend::resize`, so reading them per-paint reflects whatever the host's `<canvas>` width attribute currently is. `paint_inspector` now: - Reads `viewport_w` + `viewport_h` from the backend at the start of each frame. - Uses them for the white-background clear AND for the WidgetHost::paint viewport_width arg. This also resolves the prior "web smoke paints only the toolbar" issue since the smoke canvas is 960×640 — the first frame still receives 960 as viewport_width, but now via the backend instead of a hardcode. Verification: - `cargo build -p openpencil-shell-web --target wasm32-unknown-unknown --features skia --release` — green - `wasm-bindgen --target web` — produces ../pkg/* - `bash tools/check-wasm-bundle.sh` — PASS, 0 env.*, 907 031 bytes gzip = 86% of 1 MiB ceiling (negligible delta — two small accessor methods).
This commit is contained in:
parent
01c5baf8f5
commit
7e1fbcabf0
|
|
@ -85,6 +85,21 @@ impl WebBackend {
|
|||
self.last_present_error.take()
|
||||
}
|
||||
|
||||
/// Current physical width of the host `<canvas>` element, refreshed
|
||||
/// at construction + on every `resize` call. Hosts use this so a
|
||||
/// repaint after the canvas DOM attribute changes pulls the new
|
||||
/// width through the WidgetHost layout (codex Step 3 stop-hook
|
||||
/// "web repaint ignores actual canvas size").
|
||||
pub fn canvas_width(&self) -> u32 {
|
||||
self.width
|
||||
}
|
||||
|
||||
/// Current physical height of the host `<canvas>` element. Same
|
||||
/// refresh contract as `canvas_width`.
|
||||
pub fn canvas_height(&self) -> u32 {
|
||||
self.height
|
||||
}
|
||||
|
||||
/// Snapshot the raster surface and `put_image_data` it onto the host
|
||||
/// `<canvas>`'s 2D context. Spec §5.3 raster-fallback contract:
|
||||
/// N32_PREMUL surface, RGBA8888 + Unpremul read, full-frame copy each
|
||||
|
|
|
|||
|
|
@ -109,26 +109,29 @@ impl Inner {
|
|||
fn repaint(&mut self) -> Result<(), JsValue> {
|
||||
use openpencil_shell_core::{Color, Point2D, Rect, RenderBackend};
|
||||
|
||||
// Pull the actual canvas dimensions from the backend
|
||||
// every frame so a host that swaps the `<canvas>` width
|
||||
// attribute (responsive layouts, devtool resizing,
|
||||
// future programmatic mount with a different size)
|
||||
// gets a layout that matches reality. Codex Step 3
|
||||
// stop-hook "web repaint ignores actual canvas size"
|
||||
// caught the prior hardcoded `960.0` — this swap also
|
||||
// resolves the "web smoke paints only the toolbar"
|
||||
// regression since the smoke canvas is 960×640 and the
|
||||
// first frame still gets the full width.
|
||||
let viewport_w = self.backend.canvas_width() as f32;
|
||||
let viewport_h = self.backend.canvas_height() as f32;
|
||||
|
||||
self.backend.begin_frame();
|
||||
// Clear to white so widget paints sit on a clean background.
|
||||
self.backend.fill_rect(
|
||||
Rect {
|
||||
origin: Point2D::new(0.0, 0.0),
|
||||
size: Point2D::new(960.0, 640.0),
|
||||
size: Point2D::new(viewport_w, viewport_h),
|
||||
},
|
||||
Color::WHITE,
|
||||
);
|
||||
// Step 3: pass the FULL canvas width (matches the smoke
|
||||
// HTML's `<canvas id="op" width="960">`). The host's
|
||||
// `paint(&self, backend, viewport_width)` lays out
|
||||
// Toolbar-top + LayerPanel-left + CanvasViewport-center
|
||||
// + PropertyPanel-right; viewport_width below the
|
||||
// MIN_RAIL_WIDTH cutoff would silently skip everything
|
||||
// except the toolbar — codex stop-hook
|
||||
// "web smoke paints only the toolbar" caught this when
|
||||
// the leftover Step 1b 280-px hardcode was still in
|
||||
// place.
|
||||
self.host.paint(&mut self.backend, 960.0);
|
||||
self.host.paint(&mut self.backend, viewport_w);
|
||||
self.backend.end_frame();
|
||||
if let Some(err) = self.backend.take_present_error() {
|
||||
return Err(err);
|
||||
|
|
|
|||
Loading…
Reference in a new issue