fix(servo): resize through WebView only, never the rendering context
Servo's reference embedder (\`examples/winit_minimal.rs\`) handles
resize with a single call: \`webview.resize(new_size)\`. The Servo
paint pipeline behind that call:
1. early-returns if \`rendering_context.size() == new_size\`,
2. otherwise calls \`rendering_context.resize\` itself,
3. updates \`webview_renderer.rect\` so the compositor relays out
the page at the new device viewport,
4. sends \`transaction.set_document_view(...)\` so WebRender's
document viewport matches the surface,
5. flags the painter \`needs_repaint(RepaintReason::Resize)\`.
Our \`runtime.rs::resize\` called \`webview.rendering_context.resize\`
*before* \`webview.webview.resize\`. surfman accepted the new size, so
the painter saw \`rendering_context.size() == new_size\` and took the
early-return path — steps 3, 4, and 5 never ran. The compositor
kept the original (creation-time) viewport rect while we presented
a much larger surface. The page ended up laid out for a tiny
viewport and either rendered into the top-left of a sea of cleared
background (StableLance) or never painted any pipeline at all
(google.com appeared totally blank).
Drop the direct \`rendering_context.resize\` call and route through
\`WebView::resize\` exactly as the reference embedder does. The
debounce in \`record_viewport_size\` still collapses a sidebar /
window-edge animation into a single trailing-edge resize, so we
also avoid hammering Servo with per-frame surface mutations.
This commit is contained in:
@@ -270,8 +270,24 @@ impl ServoHost for SoftwareServoHost {
|
||||
.get(&request.webview_id)
|
||||
.ok_or_else(|| ServoHostError::WebViewNotFound { id: request.webview_id.clone() })?;
|
||||
|
||||
// `WebView::resize` is the single entry point — it routes through
|
||||
// `paint().resize_rendering_context`, which:
|
||||
// 1. early-returns if `rendering_context.size() == new_size`;
|
||||
// 2. calls `rendering_context.resize` itself;
|
||||
// 3. calls `webview_renderer.set_rect(new_viewport_rect)` so the
|
||||
// compositor relays out the page at the new size; and
|
||||
// 4. sends `transaction.set_document_view(...)` so WebRender's
|
||||
// document viewport matches the surface.
|
||||
//
|
||||
// Calling `rendering_context.resize` *ourselves* before that path
|
||||
// is what produced the original bug: surfman saw the new size,
|
||||
// Servo's early-return then skipped steps 3 and 4, and the page
|
||||
// stayed laid out at the original size while we presented a
|
||||
// larger surface — content collapsed to the top-left of a giant
|
||||
// viewport (StableLance) or rendered nothing at all (Google).
|
||||
// The Servo `winit_minimal` reference embedder calls
|
||||
// `webview.resize` and nothing else; mirror that exactly.
|
||||
let size = PhysicalSize::new(request.width, request.height);
|
||||
webview.rendering_context.resize(size);
|
||||
webview.webview.resize(size);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user