servo_constellation_traits/lib.rs
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! The interface to the `Constellation`, which prevents other crates from depending directly on
6//! the `constellation` crate itself. In addition to all messages to the `Constellation`, this
7//! crate is responsible for defining types that cross the process boundary from the
8//! embedding/rendering layer all the way to script, thus it should have very minimal dependencies
9//! on other parts of Servo.
10
11mod from_script_message;
12mod structured_data;
13
14use std::collections::VecDeque;
15use std::fmt;
16
17use accesskit::ActionRequest;
18use embedder_traits::user_contents::{
19 UserContentManagerId, UserScript, UserScriptId, UserStyleSheet, UserStyleSheetId,
20};
21use embedder_traits::{
22 EmbedderControlId, EmbedderControlResponse, InputEventAndId, JavaScriptEvaluationId,
23 MediaSessionActionType, NewWebViewDetails, PaintHitTestResult, Theme, TraversalId, UrlRequest,
24 ViewportDetails, WebDriverCommandMsg,
25};
26pub use from_script_message::*;
27use malloc_size_of_derive::MallocSizeOf;
28use paint_api::PinchZoomInfos;
29use paint_api::display_list::PaintTimingInfo;
30use profile_traits::mem::MemoryReportResult;
31use rustc_hash::FxHashMap;
32use serde::{Deserialize, Serialize};
33use servo_base::generic_channel::GenericCallback;
34use servo_base::id::{LCPCandidateID, MessagePortId, PipelineId, ScriptEventLoopId, WebViewId};
35use servo_config::prefs::PrefValue;
36use servo_url::{ImmutableOrigin, ServoUrl};
37pub use structured_data::*;
38use strum::IntoStaticStr;
39use webrender_api::units::LayoutVector2D;
40use webrender_api::{ExternalScrollId, ImageKey};
41
42/// Messages to the Constellation from the embedding layer, whether from `ServoRenderer` or
43/// from `libservo` itself.
44#[derive(IntoStaticStr)]
45pub enum EmbedderToConstellationMessage {
46 /// Exit the constellation.
47 Exit,
48 /// Whether to allow script to navigate.
49 AllowNavigationResponse(PipelineId, bool),
50 /// Request to load a page, with optionally additional data in [`URLRequest`].
51 LoadUrl(WebViewId, UrlRequest),
52 /// Request to traverse the joint session history of the provided browsing context.
53 TraverseHistory(SessionHistoryTraversalRequest),
54 /// Inform the Constellation that a `WebView`'s [`ViewportDetails`] have changed.
55 ChangeViewportDetails(WebViewId, ViewportDetails, WindowSizeType),
56 /// Inform the constellation of a theme change.
57 ThemeChange(WebViewId, Theme),
58 /// Requests that the constellation instruct script/layout to try to layout again and tick
59 /// animations.
60 TickAnimation(Vec<WebViewId>),
61 /// Notify the `ScriptThread` that the Servo renderer is no longer waiting on
62 /// asynchronous image uploads for the given `Pipeline`. These are mainly used
63 /// by canvas to perform uploads while the display list is being built.
64 NoLongerWaitingOnAsynchronousImageUpdates(Vec<PipelineId>),
65 /// Dispatch a webdriver command
66 WebDriverCommand(WebDriverCommandMsg),
67 /// Reload a top-level browsing context.
68 Reload(WebViewId),
69 /// A log entry, with the top-level browsing context id and thread name
70 LogEntry(Option<ScriptEventLoopId>, Option<String>, LogEntry),
71 /// Create a new top level browsing context.
72 NewWebView(ServoUrl, NewWebViewDetails),
73 /// Close a top level browsing context.
74 CloseWebView(WebViewId),
75 /// Set whether a WebView has system focus. This corresponds to the [HTML
76 /// specification's] concept of "system focus" and is distinct from the browsing
77 /// context or element that has focus within the WebView.
78 SetWebViewHasSystemFocus(WebViewId, bool),
79 /// Forward an input event to an appropriate ScriptTask.
80 ForwardInputEvent(WebViewId, InputEventAndId, Option<PaintHitTestResult>),
81 /// Request that the given pipeline refresh the cursor by doing a hit test at the most
82 /// recently hovered cursor position and resetting the cursor. This happens after a
83 /// display list update is rendered.
84 RefreshCursor(PipelineId),
85 /// Request to exit from fullscreen mode
86 ExitFullScreen(WebViewId),
87 /// Media session action.
88 MediaSessionAction(MediaSessionActionType),
89 /// Notify the Constellation that a WebView has been hidden. Hidden `WebView`s are throttled,
90 /// which means they use less resources, by stopping animations and running timers at a
91 /// heavily limited rate.
92 SetWebViewHidden(WebViewId, bool),
93 /// The Servo renderer scrolled and is updating the scroll states of the nodes in the
94 /// given pipeline via the constellation.
95 SetScrollStates(PipelineId, ScrollStateUpdate),
96 /// Notify the constellation that a particular paint metric event has happened for the given pipeline.
97 PaintMetric(PipelineId, PaintMetricEvent),
98 /// Evaluate a JavaScript string in the context of a `WebView`. When execution is complete or an
99 /// error is encountered, a correpsonding message will be sent to the embedding layer.
100 EvaluateJavaScript(WebViewId, JavaScriptEvaluationId, String),
101 /// Create a memory report and return it via the [`GenericCallback`]
102 CreateMemoryReport(GenericCallback<MemoryReportResult>),
103 /// Sends the generated image key to the image cache associated with this pipeline.
104 SendImageKeysForPipeline(PipelineId, Vec<ImageKey>),
105 /// A set of preferences were updated with the given new values.
106 PreferencesUpdated(Vec<(&'static str, PrefValue)>),
107 /// Request preparation for a screenshot of the given WebView. The Constellation will
108 /// send a message to the Embedder when the screenshot is ready to be taken.
109 RequestScreenshotReadiness(WebViewId),
110 /// A response to a request to show an embedder user interface control.
111 EmbedderControlResponse(EmbedderControlId, EmbedderControlResponse),
112 /// An action to perform on the given `UserContentManagerId`.
113 UserContentManagerAction(UserContentManagerId, UserContentManagerAction),
114 /// Update pinch zoom details stored in the top level window
115 UpdatePinchZoomInfos(PipelineId, PinchZoomInfos),
116 /// Activate or deactivate accessibility features for the given `WebView`.
117 SetAccessibilityActive(WebViewId, bool),
118 /// Forward an incoming [`accesskit::ActionRequest`] to the correct pipeline.
119 ForwardAccessibilityAction(ActionRequest),
120 /// Clears the session history for the `WebView` with the given `WebViewId`, leaving
121 /// the `WebView` with only the current URL in its session history.
122 ClearSessionHistory(WebViewId),
123}
124
125pub enum UserContentManagerAction {
126 AddUserScript(UserScript),
127 DestroyUserContentManager,
128 RemoveUserScript(UserScriptId),
129 AddUserStyleSheet(UserStyleSheet),
130 RemoveUserStyleSheet(UserStyleSheetId),
131}
132
133/// A description of a paint metric that is sent from the Servo renderer to the
134/// constellation and then forwarded to the script thread.
135#[derive(Clone, Debug, Deserialize, Serialize)]
136pub enum PaintMetricEvent {
137 FirstPaint(PaintTimingInfo, bool /* first_reflow */),
138 FirstContentfulPaint(PaintTimingInfo, bool /* first_reflow */),
139 LargestContentfulPaint(PaintTimingInfo, LCPCandidateID),
140}
141
142impl fmt::Debug for EmbedderToConstellationMessage {
143 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
144 let variant_string: &'static str = self.into();
145 write!(formatter, "ConstellationMsg::{variant_string}")
146 }
147}
148
149/// A log entry reported to the constellation
150/// We don't report all log entries, just serious ones.
151/// We need a separate type for this because `LogLevel` isn't serializable.
152#[derive(Clone, Debug, Deserialize, Serialize)]
153pub enum LogEntry {
154 /// Panic, with a reason and backtrace
155 Panic(String, String),
156 /// Error, with a reason
157 Error(String),
158 /// warning, with a reason
159 Warn(String),
160}
161
162/// The type of window size change.
163#[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
164pub enum WindowSizeType {
165 /// Initial load.
166 Initial,
167 /// Window resize.
168 Resize,
169}
170
171/// The direction of a history traversal
172#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
173pub enum TraversalDirection {
174 /// Travel forward the given number of documents.
175 Forward(usize),
176 /// Travel backward the given number of documents.
177 Back(usize),
178}
179
180/// The source of a [`HistoryTraversalRequest`].
181#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
182pub enum HistoryTraversalSource {
183 /// The traversal was triggered from the embedder, which means it is expecting
184 /// a notification when the request has completed.
185 Embedder,
186 /// The traversal was triggered from the script event loop.
187 Script,
188}
189
190/// A history traversal request.
191#[derive(Clone, Debug, Deserialize, Serialize)]
192pub struct SessionHistoryTraversalRequest {
193 /// An identifier that uniquely identifies this [`HistoryTraversalRequest`].
194 pub id: TraversalId,
195 /// The `WebView` that should be traversed.
196 pub webview_id: WebViewId,
197 /// The direction and number of steps that should be traversed.
198 pub direction: TraversalDirection,
199 /// The [`HistoryTraversalSource`] of this [`HistoryTraversalRequest`].
200 pub source: HistoryTraversalSource,
201}
202
203impl SessionHistoryTraversalRequest {
204 /// Create a new [`HistoryTraversalRequest`] either due to an embedder API call
205 /// or a script-initiated history traversal.
206 pub fn new(
207 webview_id: WebViewId,
208 direction: TraversalDirection,
209 source: HistoryTraversalSource,
210 ) -> Self {
211 Self {
212 id: TraversalId::new(),
213 webview_id,
214 direction,
215 source,
216 }
217 }
218}
219
220/// A task on the <https://html.spec.whatwg.org/multipage/#port-message-queue>
221#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
222pub struct PortMessageTask {
223 /// The origin of this task.
224 pub origin: ImmutableOrigin,
225 /// A data-holder for serialized data and transferred objects.
226 pub data: StructuredSerializedData,
227}
228
229/// The information needed by a global to process the transfer of a port.
230#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
231pub struct PortTransferInfo {
232 /// <https://html.spec.whatwg.org/multipage/#port-message-queue>
233 pub port_message_queue: VecDeque<PortMessageTask>,
234 /// A boolean indicating whether the port has been disentangled while in transfer,
235 /// if so, the disentanglement should be completed along with the transfer.
236 /// <https://html.spec.whatwg.org/multipage/#disentangle>
237 pub disentangled: bool,
238}
239
240/// Messages for communication between the constellation and a global managing ports.
241#[derive(Debug, Deserialize, Serialize)]
242#[expect(clippy::large_enum_variant)]
243pub enum MessagePortMsg {
244 /// Complete the transfer for a batch of ports.
245 CompleteTransfer(FxHashMap<MessagePortId, PortTransferInfo>),
246 /// Complete the transfer of a single port,
247 /// whose transfer was pending because it had been requested
248 /// while a previous failed transfer was being rolled-back.
249 CompletePendingTransfer(MessagePortId, PortTransferInfo),
250 /// <https://html.spec.whatwg.org/multipage/#disentangle>
251 CompleteDisentanglement(MessagePortId),
252 /// Handle a new port-message-task.
253 NewTask(MessagePortId, PortMessageTask),
254}
255
256/// A data structure which contains information for the pipeline after a scroll happens in the
257/// embedder-side `WebView`.
258#[derive(Debug, Deserialize, Serialize)]
259pub struct ScrollStateUpdate {
260 /// The [`ExternalScrollId`] of the node that that was scrolled.
261 pub scrolled_node: ExternalScrollId,
262 /// A map containing the scroll offsets of the entire scroll tree. This is necessary,
263 /// because scroll events can cause other nodes to scroll due to sticky positioning.
264 pub offsets: FxHashMap<ExternalScrollId, LayoutVector2D>,
265}