Include WebViewId into EmbedderMsg variants where possible (#35211)

`EmbedderMsg` was previously paired with an implicit
`Option<WebViewId>`, even though almost all variants were either always
`Some` or always `None`, depending on whether there was a `WebView
involved.

This patch adds the `WebViewId` to as many `EmbedderMsg` variants as
possible, so we can call their associated `WebView` delegate methods
without needing to check and unwrap the `Option`. In many cases, this
required more changes to plumb through the `WebViewId`.

Notably, all `Request`s now explicitly need a `WebView` or not, in order
to ensure that it is passed when appropriate.

Signed-off-by: Delan Azabani <dazabani@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Delan Azabani 2025-01-30 19:15:35 +08:00 committed by GitHub
parent 9eeb602f7a
commit 5e9de2cb61
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
70 changed files with 809 additions and 753 deletions

View file

@ -1232,9 +1232,9 @@ where
)]
fn handle_request_from_background_hang_monitor(&self, message: HangMonitorAlert) {
match message {
HangMonitorAlert::Profile(bytes) => self
.embedder_proxy
.send((None, EmbedderMsg::ReportProfile(bytes))),
HangMonitorAlert::Profile(bytes) => {
self.embedder_proxy.send(EmbedderMsg::ReportProfile(bytes))
},
HangMonitorAlert::Hang(hang) => {
// TODO: In case of a permanent hang being reported, add a "kill script" workflow,
// via the embedder?
@ -1271,8 +1271,8 @@ where
FromCompositorMsg::GetFocusTopLevelBrowsingContext(resp_chan) => {
let _ = resp_chan.send(self.webviews.focused_webview().map(|(id, _)| id));
},
FromCompositorMsg::Keyboard(key_event) => {
self.handle_key_msg(key_event);
FromCompositorMsg::Keyboard(webview_id, key_event) => {
self.handle_key_msg(webview_id, key_event);
},
FromCompositorMsg::IMECompositionEvent(ime_event) => {
self.handle_ime_msg(ime_event);
@ -1391,11 +1391,8 @@ where
// A top level browsing context is created and opened in both constellation and
// compositor.
FromCompositorMsg::WebViewOpened(top_level_browsing_context_id) => {
let msg = (
Some(top_level_browsing_context_id),
EmbedderMsg::WebViewOpened(top_level_browsing_context_id),
);
self.embedder_proxy.send(msg);
self.embedder_proxy
.send(EmbedderMsg::WebViewOpened(top_level_browsing_context_id));
},
// Close a top level browsing context.
FromCompositorMsg::CloseWebView(top_level_browsing_context_id) => {
@ -1414,8 +1411,7 @@ where
},
FromCompositorMsg::BlurWebView => {
self.webviews.unfocus();
self.embedder_proxy
.send((None, EmbedderMsg::WebViewBlurred));
self.embedder_proxy.send(EmbedderMsg::WebViewBlurred);
},
// Handle a forward or back request
FromCompositorMsg::TraverseHistory(top_level_browsing_context_id, direction) => {
@ -1442,7 +1438,9 @@ where
FromCompositorMsg::ForwardEvent(destination_pipeline_id, event) => {
self.forward_event(destination_pipeline_id, event);
},
FromCompositorMsg::SetCursor(cursor) => self.handle_set_cursor_msg(cursor),
FromCompositorMsg::SetCursor(webview_id, cursor) => {
self.handle_set_cursor_msg(webview_id, cursor)
},
FromCompositorMsg::ToggleProfiler(rate, max_duration) => {
for background_monitor_control_sender in &self.background_monitor_control_senders {
if let Err(e) = background_monitor_control_sender.send(
@ -1469,7 +1467,7 @@ where
)
.entered();
self.embedder_proxy
.send((None, EmbedderMsg::ReadyToPresent(webview_ids)));
.send(EmbedderMsg::ReadyToPresent(webview_ids));
},
FromCompositorMsg::Gamepad(gamepad_event) => {
self.handle_gamepad_msg(gamepad_event);
@ -1557,8 +1555,7 @@ where
self.handle_schedule_broadcast(source_pipeline_id, router_id, message);
},
FromScriptMsg::ForwardToEmbedder(embedder_msg) => {
self.embedder_proxy
.send((Some(source_top_ctx_id), embedder_msg));
self.embedder_proxy.send(embedder_msg);
},
FromScriptMsg::PipelineExited => {
self.handle_pipeline_exited(source_pipeline_id);
@ -1756,10 +1753,8 @@ where
};
}
self.active_media_session = Some(pipeline_id);
self.embedder_proxy.send((
Some(source_top_ctx_id),
EmbedderMsg::MediaSessionEvent(event),
));
self.embedder_proxy
.send(EmbedderMsg::MediaSessionEvent(source_top_ctx_id, event));
},
#[cfg(feature = "webgpu")]
FromScriptMsg::RequestAdapter(response_sender, options, ids) => self
@ -2793,9 +2788,10 @@ where
let browsing_context_id = BrowsingContextId::from(top_level_browsing_context_id);
self.embedder_proxy.send((
Some(top_level_browsing_context_id),
EmbedderMsg::Panic(reason.clone(), backtrace.clone()),
self.embedder_proxy.send(EmbedderMsg::Panic(
top_level_browsing_context_id,
reason.clone(),
backtrace.clone(),
));
let browsing_context = match self.browsing_contexts.get(&browsing_context_id) {
@ -2874,10 +2870,8 @@ where
return warn!("{top_level_browsing_context_id}: FocusWebView on unknown top-level browsing context");
}
self.webviews.focus(top_level_browsing_context_id);
self.embedder_proxy.send((
Some(top_level_browsing_context_id),
EmbedderMsg::WebViewFocused(top_level_browsing_context_id),
));
self.embedder_proxy
.send(EmbedderMsg::WebViewFocused(top_level_browsing_context_id));
}
#[cfg_attr(
@ -2950,9 +2944,9 @@ where
Some(pipeline) => pipeline,
};
self.embedder_proxy.send((
Some(pipeline.top_level_browsing_context_id),
EmbedderMsg::EventDelivered((&event).into()),
self.embedder_proxy.send(EmbedderMsg::EventDelivered(
pipeline.top_level_browsing_context_id,
(&event).into(),
));
if let Err(e) = pipeline.event_loop.send(ConstellationControlMsg::SendEvent(
@ -3052,16 +3046,13 @@ where
self.close_browsing_context(browsing_context_id, ExitPipelineMode::Normal);
if self.webviews.focused_webview().map(|(id, _)| id) == Some(top_level_browsing_context_id)
{
self.embedder_proxy
.send((None, EmbedderMsg::WebViewBlurred));
self.embedder_proxy.send(EmbedderMsg::WebViewBlurred);
}
self.webviews.remove(top_level_browsing_context_id);
self.compositor_proxy
.send(CompositorMsg::RemoveWebView(top_level_browsing_context_id));
self.embedder_proxy.send((
Some(top_level_browsing_context_id),
EmbedderMsg::WebViewClosed(top_level_browsing_context_id),
));
self.embedder_proxy
.send(EmbedderMsg::WebViewClosed(top_level_browsing_context_id));
let Some(browsing_context) = browsing_context else {
return;
@ -3431,9 +3422,9 @@ where
feature = "tracing",
tracing::instrument(skip_all, fields(servo_profiling = true), level = "trace")
)]
fn handle_set_cursor_msg(&mut self, cursor: Cursor) {
fn handle_set_cursor_msg(&mut self, webview_id: WebViewId, cursor: Cursor) {
self.embedder_proxy
.send((None, EmbedderMsg::SetCursor(cursor)))
.send(EmbedderMsg::SetCursor(webview_id, cursor));
}
#[cfg_attr(
@ -3499,11 +3490,12 @@ where
},
};
// Allow the embedder to handle the url itself
let msg = (
Some(top_level_browsing_context_id),
EmbedderMsg::AllowNavigationRequest(source_id, load_data.url.clone()),
);
self.embedder_proxy.send(msg);
self.embedder_proxy
.send(EmbedderMsg::AllowNavigationRequest(
top_level_browsing_context_id,
source_id,
load_data.url.clone(),
));
}
#[cfg_attr(
@ -4215,41 +4207,33 @@ where
feature = "tracing",
tracing::instrument(skip_all, fields(servo_profiling = true))
)]
fn handle_key_msg(&mut self, event: KeyboardEvent) {
fn handle_key_msg(&mut self, webview_id: WebViewId, event: KeyboardEvent) {
// Send to the focused browsing contexts' current pipeline. If it
// doesn't exist, fall back to sending to the compositor.
let focused_browsing_context_id = self
.webviews
.focused_webview()
.map(|(_, webview)| webview.focused_browsing_context_id);
match focused_browsing_context_id {
Some(browsing_context_id) => {
let event = CompositorEvent::KeyboardEvent(event);
let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
Some(ctx) => ctx.pipeline_id,
None => {
return warn!(
"{}: Got key event for nonexistent browsing context",
browsing_context_id,
);
},
};
let msg = ConstellationControlMsg::SendEvent(pipeline_id, event);
let result = match self.pipelines.get(&pipeline_id) {
Some(pipeline) => pipeline.event_loop.send(msg),
None => {
return debug!("{}: Got key event after closure", pipeline_id);
},
};
if let Err(e) = result {
self.handle_send_error(pipeline_id, e);
}
},
let Some(webview) = self.webviews.get(webview_id) else {
warn!("Handling keyboard event for unknown webview: {webview_id}");
return;
};
let browsing_context_id = webview.focused_browsing_context_id;
let event = CompositorEvent::KeyboardEvent(event);
let pipeline_id = match self.browsing_contexts.get(&browsing_context_id) {
Some(ctx) => ctx.pipeline_id,
None => {
warn!("No focused browsing context! Falling back to sending key to compositor");
let event = (None, EmbedderMsg::Keyboard(event));
self.embedder_proxy.send(event);
return warn!(
"{}: Got key event for nonexistent browsing context",
browsing_context_id,
);
},
};
let msg = ConstellationControlMsg::SendEvent(pipeline_id, event);
let result = match self.pipelines.get(&pipeline_id) {
Some(pipeline) => pipeline.event_loop.send(msg),
None => {
return debug!("{}: Got key event after closure", pipeline_id);
},
};
if let Err(e) = result {
self.handle_send_error(pipeline_id, e);
}
}
@ -4410,10 +4394,8 @@ where
// Focus the top-level browsing context.
self.webviews.focus(top_level_browsing_context_id);
self.embedder_proxy.send((
Some(top_level_browsing_context_id),
EmbedderMsg::WebViewFocused(top_level_browsing_context_id),
));
self.embedder_proxy
.send(EmbedderMsg::WebViewFocused(top_level_browsing_context_id));
// Update the webviews focused browsing context.
match self.webviews.get_mut(top_level_browsing_context_id) {
@ -4557,13 +4539,13 @@ where
WebDriverCommandMsg::CloseWebView(top_level_browsing_context_id) => {
self.handle_close_top_level_browsing_context(top_level_browsing_context_id);
},
WebDriverCommandMsg::NewWebView(sender, load_sender) => {
WebDriverCommandMsg::NewWebView(webview_id, sender, load_sender) => {
let (chan, port) = match ipc::channel() {
Ok(result) => result,
Err(error) => return warn!("Failed to create channel: {error:?}"),
};
self.embedder_proxy
.send((None, EmbedderMsg::AllowOpeningWebView(chan)));
.send(EmbedderMsg::AllowOpeningWebView(webview_id, chan));
let webview_id = match port.recv() {
Ok(Some(webview_id)) => webview_id,
Ok(None) => return warn!("Embedder refused to allow opening webview"),
@ -4588,10 +4570,8 @@ where
response_sender,
) => {
self.webdriver.resize_channel = Some(response_sender);
self.embedder_proxy.send((
Some(top_level_browsing_context_id),
EmbedderMsg::ResizeTo(size),
));
self.embedder_proxy
.send(EmbedderMsg::ResizeTo(top_level_browsing_context_id, size));
},
WebDriverCommandMsg::LoadUrl(
top_level_browsing_context_id,
@ -4833,11 +4813,11 @@ where
.rev()
.scan(current_url, &resolve_url_future),
);
let msg = (
Some(top_level_browsing_context_id),
EmbedderMsg::HistoryChanged(entries, current_index),
);
self.embedder_proxy.send(msg);
self.embedder_proxy.send(EmbedderMsg::HistoryChanged(
top_level_browsing_context_id,
entries,
current_index,
));
}
#[cfg_attr(