aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2025-05-26 14:05:38 +0200
committerGitHub <noreply@github.com>2025-05-26 12:05:38 +0000
commitd3e57a513c79f61f619f8ff667ae4152714ff2c9 (patch)
tree98f1115a23c8f12311b129645ed588d1c5834d0b /components/script
parentc96de69e80362546e8557afbcb1c5eb92a59c0d3 (diff)
downloadservo-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.rs3
-rw-r--r--components/script/dom/window.rs16
-rw-r--r--components/script/dom/windowproxy.rs3
-rw-r--r--components/script/navigation.rs7
-rw-r--r--components/script/script_thread.rs35
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);