diff --git a/crates/op-host-web/src/canvaskit.rs b/crates/op-host-web/src/canvaskit.rs index f645be4f0..fb45d2a23 100644 --- a/crates/op-host-web/src/canvaskit.rs +++ b/crates/op-host-web/src/canvaskit.rs @@ -796,7 +796,11 @@ pub async fn mount_ck(canvas_id: String) -> Result<(), JsValue> { canvas: canvas.clone(), a11y, })); - inner.borrow_mut().repaint(); + { + let mut b = inner.borrow_mut(); + let _ = b.resize_to_window(&window)?; + b.repaint(); + } crate::web_fonts::drain_font_requests(&inner); // Populate the chat model picker from the daemon's `/api/ai/models` diff --git a/crates/op-host-web/tests/web_mount_event_wiring.rs b/crates/op-host-web/tests/web_mount_event_wiring.rs index ef0793b62..1f3d586e2 100644 --- a/crates/op-host-web/tests/web_mount_event_wiring.rs +++ b/crates/op-host-web/tests/web_mount_event_wiring.rs @@ -28,6 +28,25 @@ fn canvaskit_mount_listens_for_window_resize() { ); } +#[test] +fn canvaskit_mount_syncs_window_size_before_first_repaint() { + let source = std::fs::read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/src/canvaskit.rs")) + .expect("canvaskit source is readable"); + let start = source + .find("let inner = Rc::new(RefCell::new(CkInner") + .expect("mount creates CkInner"); + let first_repaint = source[start..] + .find("repaint();") + .map(|idx| start + idx) + .expect("mount performs an initial repaint"); + let initial_mount = &source[start..first_repaint]; + + assert!( + initial_mount.contains("resize_to_window(&window)"), + "CanvasKit mount must sync the backend to the current browser viewport before the first repaint" + ); +} + #[test] fn canvaskit_mount_does_not_panic_if_a11y_mirror_borrow_is_busy() { let source = std::fs::read_to_string(concat!(env!("CARGO_MANIFEST_DIR"), "/src/canvaskit.rs"))