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 embedder_traits::user_contents::{
18    UserContentManagerId, UserScript, UserScriptId, UserStyleSheet, UserStyleSheetId,
19};
20use embedder_traits::{
21    EmbedderControlId, EmbedderControlResponse, InputEventAndId, JavaScriptEvaluationId,
22    MediaSessionActionType, NewWebViewDetails, PaintHitTestResult, Theme, TraversalId, UrlRequest,
23    ViewportDetails, WebDriverCommandMsg,
24};
25pub use from_script_message::*;
26use malloc_size_of_derive::MallocSizeOf;
27use paint_api::PinchZoomInfos;
28use paint_api::largest_contentful_paint_candidate::LCPCandidateID;
29use profile_traits::mem::MemoryReportResult;
30use rustc_hash::FxHashMap;
31use serde::{Deserialize, Serialize};
32use servo_base::cross_process_instant::CrossProcessInstant;
33use servo_base::generic_channel::GenericCallback;
34use servo_base::id::{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    /// Make a webview focused. [EmbedderMsg::WebViewFocused] will be sent with
76    /// the result of this operation.
77    FocusWebView(WebViewId),
78    /// Make none of the webviews focused.
79    BlurWebView,
80    /// Forward an input event to an appropriate ScriptTask.
81    ForwardInputEvent(WebViewId, InputEventAndId, Option<PaintHitTestResult>),
82    /// Request that the given pipeline refresh the cursor by doing a hit test at the most
83    /// recently hovered cursor position and resetting the cursor. This happens after a
84    /// display list update is rendered.
85    RefreshCursor(PipelineId),
86    /// Request to exit from fullscreen mode
87    ExitFullScreen(WebViewId),
88    /// Media session action.
89    MediaSessionAction(MediaSessionActionType),
90    /// Set whether to use less resources, by stopping animations and running timers at a heavily limited rate.
91    SetWebViewThrottled(WebViewId, bool),
92    /// The Servo renderer scrolled and is updating the scroll states of the nodes in the
93    /// given pipeline via the constellation.
94    SetScrollStates(PipelineId, ScrollStateUpdate),
95    /// Notify the constellation that a particular paint metric event has happened for the given pipeline.
96    PaintMetric(PipelineId, PaintMetricEvent),
97    /// Evaluate a JavaScript string in the context of a `WebView`. When execution is complete or an
98    /// error is encountered, a correpsonding message will be sent to the embedding layer.
99    EvaluateJavaScript(WebViewId, JavaScriptEvaluationId, String),
100    /// Create a memory report and return it via the [`GenericCallback`]
101    CreateMemoryReport(GenericCallback<MemoryReportResult>),
102    /// Sends the generated image key to the image cache associated with this pipeline.
103    SendImageKeysForPipeline(PipelineId, Vec<ImageKey>),
104    /// A set of preferences were updated with the given new values.
105    PreferencesUpdated(Vec<(&'static str, PrefValue)>),
106    /// Request preparation for a screenshot of the given WebView. The Constellation will
107    /// send a message to the Embedder when the screenshot is ready to be taken.
108    RequestScreenshotReadiness(WebViewId),
109    /// A response to a request to show an embedder user interface control.
110    EmbedderControlResponse(EmbedderControlId, EmbedderControlResponse),
111    /// An action to perform on the given `UserContentManagerId`.
112    UserContentManagerAction(UserContentManagerId, UserContentManagerAction),
113    /// Update pinch zoom details stored in the top level window
114    UpdatePinchZoomInfos(PipelineId, PinchZoomInfos),
115    /// Activate or deactivate accessibility features for the given `WebView`.
116    SetAccessibilityActive(WebViewId, bool),
117}
118
119pub enum UserContentManagerAction {
120    AddUserScript(UserScript),
121    DestroyUserContentManager,
122    RemoveUserScript(UserScriptId),
123    AddUserStyleSheet(UserStyleSheet),
124    RemoveUserStyleSheet(UserStyleSheetId),
125}
126
127/// A description of a paint metric that is sent from the Servo renderer to the
128/// constellation.
129pub enum PaintMetricEvent {
130    FirstPaint(CrossProcessInstant, bool /* first_reflow */),
131    FirstContentfulPaint(CrossProcessInstant, bool /* first_reflow */),
132    LargestContentfulPaint(
133        CrossProcessInstant,
134        usize, /* area */
135        Option<ServoUrl>,
136        LCPCandidateID,
137    ),
138}
139
140impl fmt::Debug for EmbedderToConstellationMessage {
141    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
142        let variant_string: &'static str = self.into();
143        write!(formatter, "ConstellationMsg::{variant_string}")
144    }
145}
146
147/// A log entry reported to the constellation
148/// We don't report all log entries, just serious ones.
149/// We need a separate type for this because `LogLevel` isn't serializable.
150#[derive(Clone, Debug, Deserialize, Serialize)]
151pub enum LogEntry {
152    /// Panic, with a reason and backtrace
153    Panic(String, String),
154    /// Error, with a reason
155    Error(String),
156    /// warning, with a reason
157    Warn(String),
158}
159
160/// The type of window size change.
161#[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
162pub enum WindowSizeType {
163    /// Initial load.
164    Initial,
165    /// Window resize.
166    Resize,
167}
168
169/// The direction of a history traversal
170#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
171pub enum TraversalDirection {
172    /// Travel forward the given number of documents.
173    Forward(usize),
174    /// Travel backward the given number of documents.
175    Back(usize),
176}
177
178/// The source of a [`HistoryTraversalRequest`].
179#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
180pub enum HistoryTraversalSource {
181    /// The traversal was triggered from the embedder, which means it is expecting
182    /// a notification when the request has completed.
183    Embedder,
184    /// The traversal was triggered from the script event loop.
185    Script,
186}
187
188/// A history traversal request.
189#[derive(Clone, Debug, Deserialize, Serialize)]
190pub struct SessionHistoryTraversalRequest {
191    /// An identifier that uniquely identifies this [`HistoryTraversalRequest`].
192    pub id: TraversalId,
193    /// The `WebView` that should be traversed.
194    pub webview_id: WebViewId,
195    /// The direction and number of steps that should be traversed.
196    pub direction: TraversalDirection,
197    /// The [`HistoryTraversalSource`] of this [`HistoryTraversalRequest`].
198    pub source: HistoryTraversalSource,
199}
200
201impl SessionHistoryTraversalRequest {
202    /// Create a new [`HistoryTraversalRequest`] either due to an embedder API call
203    /// or a script-initiated history traversal.
204    pub fn new(
205        webview_id: WebViewId,
206        direction: TraversalDirection,
207        source: HistoryTraversalSource,
208    ) -> Self {
209        Self {
210            id: TraversalId::new(),
211            webview_id,
212            direction,
213            source,
214        }
215    }
216}
217
218/// A task on the <https://html.spec.whatwg.org/multipage/#port-message-queue>
219#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
220pub struct PortMessageTask {
221    /// The origin of this task.
222    pub origin: ImmutableOrigin,
223    /// A data-holder for serialized data and transferred objects.
224    pub data: StructuredSerializedData,
225}
226
227/// The information needed by a global to process the transfer of a port.
228#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
229pub struct PortTransferInfo {
230    /// <https://html.spec.whatwg.org/multipage/#port-message-queue>
231    pub port_message_queue: VecDeque<PortMessageTask>,
232    /// A boolean indicating whether the port has been disentangled while in transfer,
233    /// if so, the disentanglement should be completed along with the transfer.
234    /// <https://html.spec.whatwg.org/multipage/#disentangle>
235    pub disentangled: bool,
236}
237
238/// Messages for communication between the constellation and a global managing ports.
239#[derive(Debug, Deserialize, Serialize)]
240#[expect(clippy::large_enum_variant)]
241pub enum MessagePortMsg {
242    /// Complete the transfer for a batch of ports.
243    CompleteTransfer(FxHashMap<MessagePortId, PortTransferInfo>),
244    /// Complete the transfer of a single port,
245    /// whose transfer was pending because it had been requested
246    /// while a previous failed transfer was being rolled-back.
247    CompletePendingTransfer(MessagePortId, PortTransferInfo),
248    /// <https://html.spec.whatwg.org/multipage/#disentangle>
249    CompleteDisentanglement(MessagePortId),
250    /// Handle a new port-message-task.
251    NewTask(MessagePortId, PortMessageTask),
252}
253
254/// A data structure which contains information for the pipeline after a scroll happens in the
255/// embedder-side `WebView`.
256#[derive(Debug, Deserialize, Serialize)]
257pub struct ScrollStateUpdate {
258    /// The [`ExternalScrollId`] of the node that that was scrolled.
259    pub scrolled_node: ExternalScrollId,
260    /// A map containing the scroll offsets of the entire scroll tree. This is necessary,
261    /// because scroll events can cause other nodes to scroll due to sticky positioning.
262    pub offsets: FxHashMap<ExternalScrollId, LayoutVector2D>,
263}