From da221d4045e52edcf95c34d58ed01c91f1d0395b Mon Sep 17 00:00:00 2001 From: webbeef Date: Wed, 24 Sep 2025 08:31:13 -0700 Subject: [PATCH] constellation: Store pending viewport changes (#39447) It is possible for viewport changes to be received before the constellation adds a browsing context to its managed set when navigating. When that happens, the viewport change is ignored, and eg. the hidpi will keep the default 1.0 value. On later page navigation, this value is not updated and leads to incorrect display zooming. The initial page load is fine in the current embedders because they update the compositor and webview renderer even if the constellation is not fully ready. Testing: Testing is difficult because it's device dependent, but I reproduce 100% of the time running winit_minimal on a Pinephone Pro. Signed-off-by: webbeef --- components/constellation/constellation.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 63abab36d8f..5a8bc4c0b08 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -490,6 +490,10 @@ pub struct Constellation { /// The image cache for the single-process mode image_cache: Box, + + /// Pending viewport changes for browsing contexts that are not + /// yet known to the constellation. + pending_viewport_changes: HashMap, } /// State needed to construct a constellation. @@ -743,6 +747,7 @@ where state.compositor_proxy.cross_process_compositor_api, rippy_data, )), + pending_viewport_changes: Default::default(), }; constellation.run(); @@ -1164,6 +1169,12 @@ where return; }, }; + + // Override the viewport details if we have a pending change for that browsing context. + let viewport_details = self + .pending_viewport_changes + .remove(&browsing_context_id) + .unwrap_or(viewport_details); let browsing_context = BrowsingContext::new( bc_group_id, browsing_context_id, @@ -5036,7 +5047,7 @@ where ) { debug!( "handle_change_viewport_details_msg: {:?}", - new_viewport_details.size.to_untyped() + new_viewport_details ); let browsing_context_id = BrowsingContextId::from(webview_id); @@ -5222,6 +5233,9 @@ where )); } } + } else { + self.pending_viewport_changes + .insert(browsing_context_id, new_viewport_details); } // Send resize message to any pending pipelines that aren't loaded yet. @@ -5306,6 +5320,8 @@ where exit_mode, ); + let _ = self.pending_viewport_changes.remove(&browsing_context_id); + let browsing_context = match self.browsing_contexts.remove(&browsing_context_id) { Some(ctx) => ctx, None => {