diff options
author | Martin Robinson <mrobinson@igalia.com> | 2025-05-26 14:05:38 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-26 12:05:38 +0000 |
commit | d3e57a513c79f61f619f8ff667ae4152714ff2c9 (patch) | |
tree | 98f1115a23c8f12311b129645ed588d1c5834d0b /components/script | |
parent | c96de69e80362546e8557afbcb1c5eb92a59c0d3 (diff) | |
download | servo-d3e57a513c79f61f619f8ff667ae4152714ff2c9.tar.gz servo-d3e57a513c79f61f619f8ff667ae4152714ff2c9.zip |
constellation: Pass system theme to new Pipelines (#37132)
Previously, when the theme was set it was only set on currently active
`Window`s. This change makes setting the `Theme` stateful. Now the
`Constellation` tracks what theme is applied to a `WebView` and properly
passes that value to new `Pipeline`s when they are constructed. In
addition, the value is passed to layout when that is constructed as
well.
Testing: this change adds a unit test.
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/htmliframeelement.rs | 3 | ||||
-rw-r--r-- | components/script/dom/window.rs | 16 | ||||
-rw-r--r-- | components/script/dom/windowproxy.rs | 3 | ||||
-rw-r--r-- | components/script/navigation.rs | 7 | ||||
-rw-r--r-- | components/script/script_thread.rs | 35 |
5 files changed, 37 insertions, 27 deletions
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 7de3d4977b1..0ccf0e93b11 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -223,6 +223,7 @@ impl HTMLIFrameElement { old_pipeline_id, sandbox: sandboxed, viewport_details, + theme: window.theme(), }; window .as_global_scope() @@ -238,6 +239,7 @@ impl HTMLIFrameElement { opener: None, load_data, viewport_details, + theme: window.theme(), }; self.pipeline_id.set(Some(new_pipeline_id)); @@ -250,6 +252,7 @@ impl HTMLIFrameElement { old_pipeline_id, sandbox: sandboxed, viewport_details, + theme: window.theme(), }; window .as_global_scope() diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 24e694b4f06..f75ae4b4cb3 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -80,7 +80,6 @@ use style::dom::OpaqueNode; use style::error_reporting::{ContextualParseError, ParseErrorReporter}; use style::properties::PropertyId; use style::properties::style_structs::Font; -use style::queries::values::PrefersColorScheme; use style::selector_parser::PseudoElement; use style::str::HTML_SPACE_CHARACTERS; use style::stylesheets::UrlExtraData; @@ -269,7 +268,7 @@ pub(crate) struct Window { /// Platform theme. #[no_trace] - theme: Cell<PrefersColorScheme>, + theme: Cell<Theme>, /// Parent id associated with this page, if any. #[no_trace] @@ -2739,13 +2738,13 @@ impl Window { self.viewport_details.get() } + /// Get the theme of this [`Window`]. + pub(crate) fn theme(&self) -> Theme { + self.theme.get() + } + /// Handle a theme change request, triggering a reflow is any actual change occured. pub(crate) fn handle_theme_change(&self, new_theme: Theme) { - let new_theme = match new_theme { - Theme::Light => PrefersColorScheme::Light, - Theme::Dark => PrefersColorScheme::Dark, - }; - if self.theme.get() == new_theme { return; } @@ -3033,6 +3032,7 @@ impl Window { player_context: WindowGLContext, #[cfg(feature = "webgpu")] gpu_id_hub: Arc<IdentityHub>, inherited_secure_context: Option<bool>, + theme: Theme, ) -> DomRoot<Self> { let error_reporter = CSSErrorReporter { pipelineid: pipeline_id, @@ -3118,7 +3118,7 @@ impl Window { throttled: Cell::new(false), layout_marker: DomRefCell::new(Rc::new(Cell::new(true))), current_event: DomRefCell::new(None), - theme: Cell::new(PrefersColorScheme::Light), + theme: Cell::new(theme), trusted_types: Default::default(), }); diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index dc02f9feb49..a8decee24ed 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -329,6 +329,9 @@ impl WindowProxy { opener: Some(self.browsing_context_id), load_data, viewport_details: window.viewport_details(), + // Use the current `WebView`'s theme initially, but the embedder may + // change this later. + theme: window.theme(), }; ScriptThread::process_attach_layout(new_layout_info, document.origin().clone()); // TODO: if noopener is false, copy the sessionStorage storage area of the creator origin. diff --git a/components/script/navigation.rs b/components/script/navigation.rs index 17cff5bab4a..54f2db77d48 100644 --- a/components/script/navigation.rs +++ b/components/script/navigation.rs @@ -12,7 +12,7 @@ use base::cross_process_instant::CrossProcessInstant; use base::id::{BrowsingContextId, PipelineId, WebViewId}; use constellation_traits::LoadData; use crossbeam_channel::Sender; -use embedder_traits::ViewportDetails; +use embedder_traits::{Theme, ViewportDetails}; use http::header; use net_traits::request::{ CredentialsMode, InsecureRequestsPolicy, RedirectMode, RequestBuilder, RequestMode, @@ -159,6 +159,9 @@ pub(crate) struct InProgressLoad { /// this load. #[no_trace] pub(crate) url_list: Vec<ServoUrl>, + /// The [`Theme`] to use for this page, once it loads. + #[no_trace] + pub(crate) theme: Theme, } impl InProgressLoad { @@ -171,6 +174,7 @@ impl InProgressLoad { parent_info: Option<PipelineId>, opener: Option<BrowsingContextId>, viewport_details: ViewportDetails, + theme: Theme, origin: MutableOrigin, load_data: LoadData, ) -> InProgressLoad { @@ -189,6 +193,7 @@ impl InProgressLoad { canceller: Default::default(), load_data, url_list: vec![url], + theme, } } diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index e0309298f3d..4565c02dcb9 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -403,14 +403,20 @@ impl ScriptThreadFactory for ScriptThread { WebViewId::install(state.webview_id); let roots = RootCollection::new(); let _stack_roots = ThreadLocalStackRoots::new(&roots); - let id = state.id; - let browsing_context_id = state.browsing_context_id; - let webview_id = state.webview_id; - let parent_info = state.parent_info; - let opener = state.opener; let memory_profiler_sender = state.memory_profiler_sender.clone(); - let viewport_details = state.viewport_details; + let in_progress_load = InProgressLoad::new( + state.id, + state.browsing_context_id, + state.webview_id, + state.parent_info, + state.opener, + state.viewport_details, + state.theme, + MutableOrigin::new(load_data.url.origin()), + load_data, + ); + let reporter_name = format!("script-reporter-{:?}", state.id); let script_thread = ScriptThread::new(state, layout_factory, system_font_service); SCRIPT_THREAD_ROOT.with(|root| { @@ -419,19 +425,8 @@ impl ScriptThreadFactory for ScriptThread { let mut failsafe = ScriptMemoryFailsafe::new(&script_thread); - let origin = MutableOrigin::new(load_data.url.origin()); - script_thread.pre_page_load(InProgressLoad::new( - id, - browsing_context_id, - webview_id, - parent_info, - opener, - viewport_details, - origin, - load_data, - )); + script_thread.pre_page_load(in_progress_load); - let reporter_name = format!("script-reporter-{:?}", id); memory_profiler_sender.run_with_memory_reporting( || { script_thread.start(CanGc::note()); @@ -2435,6 +2430,7 @@ impl ScriptThread { opener, load_data, viewport_details, + theme, } = new_layout_info; // Kick off the fetch for the new resource. @@ -2446,6 +2442,7 @@ impl ScriptThread { parent_info, opener, viewport_details, + theme, origin, load_data, ); @@ -3189,6 +3186,7 @@ impl ScriptThread { time_profiler_chan: self.senders.time_profiler_sender.clone(), compositor_api: self.compositor_api.clone(), viewport_details: incomplete.viewport_details, + theme: incomplete.theme, }; // Create the window and document objects. @@ -3228,6 +3226,7 @@ impl ScriptThread { #[cfg(feature = "webgpu")] self.gpu_id_hub.clone(), incomplete.load_data.inherited_secure_context, + incomplete.theme, ); let _realm = enter_realm(&*window); |