libservo: Port desktop servoshell to use the new WebView API (#35183)

This removes all uses of `EmbedderEvent` in the desktop servoshell to
use the new `WebView` API -- filling it out when necessary.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Delan Azabani <dazabani@igalia.com>
This commit is contained in:
Martin Robinson 2025-01-28 15:57:57 +01:00 committed by GitHub
parent a1cf0cbf86
commit 9dbc942bee
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 826 additions and 798 deletions

View file

@ -427,19 +427,19 @@ impl BackgroundHangMonitorWorker {
},
recv(self.control_port) -> event => {
match event {
Ok(BackgroundHangMonitorControlMsg::EnableSampler(rate, max_duration)) => {
println!("Enabling profiler.");
self.sampling_duration = Some(rate);
self.sampling_max_duration = Some(max_duration);
self.sampling_baseline = Instant::now();
Ok(BackgroundHangMonitorControlMsg::ToggleSampler(rate, max_duration)) => {
if self.sampling_duration.is_some() {
println!("Enabling profiler.");
self.finish_sampled_profile();
self.sampling_duration = None;
} else {
println!("Disabling profiler.");
self.sampling_duration = Some(rate);
self.sampling_max_duration = Some(max_duration);
self.sampling_baseline = Instant::now();
}
None
},
Ok(BackgroundHangMonitorControlMsg::DisableSampler) => {
println!("Disabling profiler.");
self.finish_sampled_profile();
self.sampling_duration = None;
return true;
},
Ok(BackgroundHangMonitorControlMsg::Exit(sender)) => {
for component in self.monitored_components.values_mut() {
component.exit_signal.signal_to_exit();

View file

@ -1318,7 +1318,7 @@ impl IOCompositor {
self.pipeline_details.remove(&pipeline_id);
}
pub fn on_resize_window_event(&mut self) -> bool {
pub fn on_rendering_context_resized(&mut self) -> bool {
if self.shutdown_state != ShutdownState::NotShuttingDown {
return false;
}

View file

@ -1443,24 +1443,15 @@ where
self.forward_event(destination_pipeline_id, event);
},
FromCompositorMsg::SetCursor(cursor) => self.handle_set_cursor_msg(cursor),
FromCompositorMsg::EnableProfiler(rate, max_duration) => {
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(
BackgroundHangMonitorControlMsg::EnableSampler(rate, max_duration),
BackgroundHangMonitorControlMsg::ToggleSampler(rate, max_duration),
) {
warn!("error communicating with sampling profiler: {}", e);
}
}
},
FromCompositorMsg::DisableProfiler => {
for background_monitor_control_sender in &self.background_monitor_control_senders {
if let Err(e) = background_monitor_control_sender
.send(BackgroundHangMonitorControlMsg::DisableSampler)
{
warn!("error communicating with sampling profiler: {}", e);
}
}
},
FromCompositorMsg::ExitFullScreen(top_level_browsing_context_id) => {
self.handle_exit_fullscreen_msg(top_level_browsing_context_id);
},

View file

@ -85,8 +85,7 @@ mod from_compositor {
Self::BlurWebView => target!("BlurWebView"),
Self::ForwardEvent(_, event) => event.log_target(),
Self::SetCursor(..) => target!("SetCursor"),
Self::EnableProfiler(..) => target!("EnableProfiler"),
Self::DisableProfiler => target!("DisableProfiler"),
Self::ToggleProfiler(..) => target!("EnableProfiler"),
Self::ExitFullScreen(_) => target!("ExitFullScreen"),
Self::MediaSessionAction(_) => target!("MediaSessionAction"),
Self::SetWebViewThrottled(_, _) => target!("SetWebViewThrottled"),

View file

@ -30,7 +30,7 @@ use std::thread;
use std::vec::Drain;
pub use base::id::TopLevelBrowsingContextId;
use base::id::{PipelineNamespace, PipelineNamespaceId};
use base::id::{PipelineId, PipelineNamespace, PipelineNamespaceId};
use bluetooth::BluetoothThreadFactory;
use bluetooth_traits::BluetoothRequest;
use canvas::canvas_paint_thread::CanvasPaintThread;
@ -189,7 +189,6 @@ pub struct Servo {
constellation_proxy: ConstellationProxy,
embedder_receiver: EmbedderReceiver,
messages_for_embedder: Vec<(Option<TopLevelBrowsingContextId>, EmbedderMsg)>,
profiler_enabled: bool,
/// For single-process Servo instances, this field controls the initialization
/// and deinitialization of the JS Engine. Multiprocess Servo instances have their
/// own instance that exists in the content process instead.
@ -530,7 +529,6 @@ impl Servo {
constellation_proxy: ConstellationProxy::new(constellation_chan),
embedder_receiver,
messages_for_embedder: Vec::new(),
profiler_enabled: false,
_js_engine_setup: js_engine_setup,
}
}
@ -652,7 +650,7 @@ impl Servo {
},
EmbedderEvent::WindowResize => {
return self.compositor.borrow_mut().on_resize_window_event();
return self.compositor.borrow_mut().on_rendering_context_resized();
},
EmbedderEvent::ThemeChange(theme) => {
let msg = ConstellationMsg::ThemeChange(theme);
@ -798,13 +796,10 @@ impl Servo {
},
EmbedderEvent::ToggleSamplingProfiler(rate, max_duration) => {
self.profiler_enabled = !self.profiler_enabled;
let msg = if self.profiler_enabled {
ConstellationMsg::EnableProfiler(rate, max_duration)
} else {
ConstellationMsg::DisableProfiler
};
if let Err(e) = self.constellation_proxy.try_send(msg) {
if let Err(e) = self
.constellation_proxy
.try_send(ConstellationMsg::ToggleProfiler(rate, max_duration))
{
warn!("Sending profiler toggle to constellation failed ({:?}).", e);
}
},
@ -1003,6 +998,20 @@ impl Servo {
log::set_max_level(filter);
}
pub fn start_shutting_down(&self) {
self.compositor.borrow_mut().maybe_start_shutting_down();
}
pub fn allow_navigation_response(&self, pipeline_id: PipelineId, allow: bool) {
let msg = ConstellationMsg::AllowNavigationResponse(pipeline_id, allow);
if let Err(e) = self.constellation_proxy.try_send(msg) {
warn!(
"Sending allow navigation to constellation failed ({:?}).",
e
);
}
}
pub fn deinit(self) {
self.compositor.borrow_mut().deinit();
}

View file

@ -3,15 +3,26 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::cell::RefCell;
use std::ffi::c_void;
use std::rc::Rc;
use std::time::Duration;
use base::id::WebViewId;
use compositing::windowing::{MouseWindowEvent, WebRenderDebugOption};
use compositing::IOCompositor;
use compositing_traits::ConstellationMsg;
use webrender_api::units::DeviceRect;
use embedder_traits::{
ClipboardEventType, GamepadEvent, MediaSessionActionType, Theme, TouchEventType, TouchId,
TraversalDirection, WheelDelta,
};
use keyboard_types::{CompositionEvent, KeyboardEvent};
use url::Url;
use webrender_api::units::{DeviceIntPoint, DeviceIntSize, DevicePoint, DeviceRect};
use webrender_api::ScrollLocation;
use crate::ConstellationProxy;
#[derive(Clone)]
pub struct WebView(Rc<WebViewInner>);
struct WebViewInner {
@ -38,7 +49,7 @@ impl WebView {
pub(crate) fn new(
constellation_proxy: &ConstellationProxy,
compositor: Rc<RefCell<IOCompositor>>,
url: url::Url,
url: Url,
) -> Self {
let webview_id = WebViewId::new();
constellation_proxy.send(ConstellationMsg::NewWebView(url.into(), webview_id));
@ -114,4 +125,188 @@ impl WebView {
.raise_webview_to_top(self.id(), hide_others)
.expect("BUG: invalid WebView instance");
}
pub fn notify_theme_change(&self, theme: Theme) {
self.0
.constellation_proxy
.send(ConstellationMsg::ThemeChange(theme))
}
pub fn load(&self, url: Url) {
self.0
.constellation_proxy
.send(ConstellationMsg::LoadUrl(self.id(), url.into()))
}
pub fn reload(&self) {
self.0
.constellation_proxy
.send(ConstellationMsg::Reload(self.id()))
}
pub fn go_back(&self, amount: usize) {
self.0
.constellation_proxy
.send(ConstellationMsg::TraverseHistory(
self.id(),
TraversalDirection::Back(amount),
))
}
pub fn go_forward(&self, amount: usize) {
self.0
.constellation_proxy
.send(ConstellationMsg::TraverseHistory(
self.id(),
TraversalDirection::Forward(amount),
))
}
pub fn notify_pointer_button_event(&self, event: MouseWindowEvent) {
self.0
.compositor
.borrow_mut()
.on_mouse_window_event_class(event);
}
pub fn notify_pointer_move_event(&self, event: DevicePoint) {
self.0
.compositor
.borrow_mut()
.on_mouse_window_move_event_class(event);
}
pub fn notify_touch_event(&self, event_type: TouchEventType, id: TouchId, point: DevicePoint) {
self.0
.compositor
.borrow_mut()
.on_touch_event(event_type, id, point);
}
pub fn notify_wheel_event(&self, delta: WheelDelta, point: DevicePoint) {
self.0.compositor.borrow_mut().on_wheel_event(delta, point);
}
pub fn notify_scroll_event(
&self,
location: ScrollLocation,
point: DeviceIntPoint,
touch_event_type: TouchEventType,
) {
self.0
.compositor
.borrow_mut()
.on_scroll_event(location, point, touch_event_type);
}
pub fn notify_keyboard_event(&self, event: KeyboardEvent) {
self.0
.constellation_proxy
.send(ConstellationMsg::Keyboard(event))
}
pub fn notify_ime_event(&self, event: CompositionEvent) {
self.0
.constellation_proxy
.send(ConstellationMsg::IMECompositionEvent(event))
}
pub fn notify_ime_dismissed_event(&self) {
self.0
.constellation_proxy
.send(ConstellationMsg::IMEDismissed);
}
pub fn notify_gamepad_event(&self, event: GamepadEvent) {
self.0
.constellation_proxy
.send(ConstellationMsg::Gamepad(event));
}
pub fn notify_media_session_action_event(&self, event: MediaSessionActionType) {
self.0
.constellation_proxy
.send(ConstellationMsg::MediaSessionAction(event));
}
pub fn notify_clipboard_event(&self, event: ClipboardEventType) {
self.0
.constellation_proxy
.send(ConstellationMsg::Clipboard(event));
}
pub fn notify_vsync(&self) {
self.0.compositor.borrow_mut().on_vsync();
}
pub fn notify_rendering_context_resized(&self) {
self.0
.compositor
.borrow_mut()
.on_rendering_context_resized();
}
pub fn set_zoom(&self, new_zoom: f32) {
self.0
.compositor
.borrow_mut()
.on_zoom_window_event(new_zoom);
}
pub fn reset_zoom(&self) {
self.0.compositor.borrow_mut().on_zoom_reset_window_event();
}
pub fn set_pinch_zoom(&self, new_pinch_zoom: f32) {
self.0
.compositor
.borrow_mut()
.on_pinch_zoom_window_event(new_pinch_zoom);
}
pub fn exit_fullscreen(&self) {
self.0
.constellation_proxy
.send(ConstellationMsg::ExitFullScreen(self.id()));
}
pub fn set_throttled(&self, throttled: bool) {
self.0
.constellation_proxy
.send(ConstellationMsg::SetWebViewThrottled(self.id(), throttled));
}
pub fn toggle_webrender_debugging(&self, debugging: WebRenderDebugOption) {
self.0
.compositor
.borrow_mut()
.toggle_webrender_debug(debugging);
}
pub fn capture_webrender(&self) {
self.0.compositor.borrow_mut().capture_webrender();
}
pub fn invalidate_native_surface(&self) {
self.0.compositor.borrow_mut().invalidate_native_surface();
}
pub fn replace_native_surface(&self, native_widget: *mut c_void, size: DeviceIntSize) {
self.0
.compositor
.borrow_mut()
.replace_native_surface(native_widget, size);
}
pub fn toggle_sampling_profiler(&self, rate: Duration, max_duration: Duration) {
self.0
.constellation_proxy
.send(ConstellationMsg::ToggleProfiler(rate, max_duration));
}
pub fn send_error(&self, message: String) {
self.0
.constellation_proxy
.send(ConstellationMsg::SendError(Some(self.id()), message));
}
}

View file

@ -205,9 +205,8 @@ pub trait BackgroundHangMonitorExitSignal: Send {
/// Messages to control the sampling profiler.
#[derive(Deserialize, Serialize)]
pub enum BackgroundHangMonitorControlMsg {
/// Enable the sampler, with a given sampling rate and max total sampling duration.
EnableSampler(Duration, Duration),
DisableSampler,
/// Toggle the sampler, with a given sampling rate and max total sampling duration.
ToggleSampler(Duration, Duration),
/// Exit, and propagate the signal to monitored components.
Exit(IpcSender<()>),
}

View file

@ -75,9 +75,7 @@ pub enum ConstellationMsg {
/// Requesting a change to the onscreen cursor.
SetCursor(Cursor),
/// Enable the sampling profiler, with a given sampling rate and max total sampling duration.
EnableProfiler(Duration, Duration),
/// Disable the sampling profiler.
DisableProfiler,
ToggleProfiler(Duration, Duration),
/// Request to exit from fullscreen mode
ExitFullScreen(TopLevelBrowsingContextId),
/// Media session action.
@ -129,8 +127,7 @@ impl ConstellationMsg {
SendError(..) => "SendError",
ForwardEvent(..) => "ForwardEvent",
SetCursor(..) => "SetCursor",
EnableProfiler(..) => "EnableProfiler",
DisableProfiler => "DisableProfiler",
ToggleProfiler(..) => "EnableProfiler",
ExitFullScreen(..) => "ExitFullScreen",
MediaSessionAction(..) => "MediaSessionAction",
SetWebViewThrottled(..) => "SetWebViewThrottled",