Skip to main content

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