From 04cc4221385a14a0aa9829640b1d945e2ad75346 Mon Sep 17 00:00:00 2001 From: Wu Yu Wei Date: Sat, 3 Aug 2024 16:06:31 +0900 Subject: [PATCH 01/22] Init window after event loop inited --- src/main.rs | 47 ++++++++++++++++++++++++++++------------------- src/verso.rs | 27 +++++++++++---------------- 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/src/main.rs b/src/main.rs index f96b87ce..a2c0afa5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ use verso::config::Config; use verso::{Result, Verso}; +use winit::event::{Event, StartCause}; use winit::event_loop::{ControlFlow, DeviceEvents}; use winit::{event_loop::EventLoop, window::WindowBuilder}; @@ -19,28 +20,36 @@ use winit::dpi::LogicalPosition; fn main() -> Result<()> { let event_loop = EventLoop::new()?; event_loop.listen_device_events(DeviceEvents::Never); - let window = WindowBuilder::new() - // .with_decorations(false) - .build(&event_loop)?; + let proxy = event_loop.create_proxy(); + let mut verso = None; + event_loop.run(move |event, evl| { + if let Event::NewEvents(StartCause::Init) = event { + let window = WindowBuilder::new() + // .with_decorations(false) + .build(&evl) + .expect("Failed to initialize Winit window"); - #[cfg(macos)] - unsafe { - let rwh = window.raw_window_handle(); - if let RawWindowHandle::AppKit(AppKitWindowHandle { ns_window, .. }) = rwh { - decorate_window(ns_window as *mut Object, LogicalPosition::new(8.0, 40.0)); - } - } + #[cfg(macos)] + unsafe { + let rwh = window.raw_window_handle(); + if let RawWindowHandle::AppKit(AppKitWindowHandle { ns_window, .. }) = rwh { + decorate_window(ns_window as *mut Object, LogicalPosition::new(8.0, 40.0)); + } + } - let config = Config::new(resources_dir_path().unwrap()); - let mut verso = Verso::new(window, event_loop.create_proxy(), config); - event_loop.run(move |event, evl| { - verso.run(event); - if verso.finished_shutting_down() { - evl.exit(); - } else if verso.is_animating() { - evl.set_control_flow(ControlFlow::Poll); + let config = Config::new(resources_dir_path().unwrap()); + verso = Some(Verso::new(window, proxy.clone(), config)); } else { - evl.set_control_flow(ControlFlow::Wait); + if let Some(v) = &mut verso { + v.run(event); + if v.finished_shutting_down() { + evl.exit(); + } else if v.is_animating() { + evl.set_control_flow(ControlFlow::Poll); + } else { + evl.set_control_flow(ControlFlow::Wait); + } + } } })?; diff --git a/src/verso.rs b/src/verso.rs index 2bc36b27..b3eeb009 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -37,11 +37,7 @@ use webgpu; use webrender::{create_webrender_instance, ShaderPrecacheFlags, WebRenderOptions}; use webrender_api::*; use webrender_traits::*; -use winit::{ - event::{Event, StartCause}, - event_loop::EventLoopProxy, - window::Window as WinitWindow, -}; +use winit::{event::Event, event_loop::EventLoopProxy, window::Window as WinitWindow}; use crate::{ compositor::{IOCompositor, InitialCompositorState, ShutdownState}, @@ -367,6 +363,15 @@ impl Verso { }; verso.setup_logging(); + // Send the constellation message to start Panel UI + // NB: Should become a window method + let panel_id = verso.window.panel.webview_id; + let path = verso.resource_dir.join("panel.html"); + let url = ServoUrl::from_file_path(path.to_str().unwrap()).unwrap(); + send_to_constellation( + &verso.constellation_sender, + ConstellationMsg::NewWebView(url, panel_id), + ); verso } @@ -383,17 +388,7 @@ impl Verso { fn handle_winit_event(&mut self, event: Event<()>) { log::trace!("Verso is handling Winit event: {event:?}"); match event { - Event::NewEvents(StartCause::Init) => { - // Send the constellation message to start Panel UI - let panel_id = self.window.panel.webview_id; - let path = self.resource_dir.join("panel.html"); - let url = ServoUrl::from_file_path(path.to_str().unwrap()).unwrap(); - send_to_constellation( - &self.constellation_sender, - ConstellationMsg::NewWebView(url, panel_id), - ); - } - Event::Suspended | Event::Resumed | Event::UserEvent(()) => {} + Event::NewEvents(_) | Event::Suspended | Event::Resumed | Event::UserEvent(()) => {} Event::WindowEvent { window_id: _, event, From b960945ca256c59fef8989bf89fe8eeefa1fd383 Mon Sep 17 00:00:00 2001 From: Wu Wayne Date: Sun, 4 Aug 2024 10:34:23 +0900 Subject: [PATCH 02/22] Fix typo --- src/compositor.rs | 2 +- src/window.rs | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index 5247e232..1e28e973 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -1486,7 +1486,7 @@ impl IOCompositor { self.dispatch_mouse_window_event_class(MouseWindowEvent::Click(button, p)); } - /// Hit test and foward the wheel event to constellation. + /// Hit test and forward the wheel event to constellation. pub fn on_wheel_event(&mut self, delta: WheelDelta, p: DevicePoint) { if self.shutdown_state != ShutdownState::NotShuttingDown { return; diff --git a/src/window.rs b/src/window.rs index 0a2095e9..13b7d5d2 100644 --- a/src/window.rs +++ b/src/window.rs @@ -271,22 +271,22 @@ impl Window { } } - /// Set the webview to this window. It won't be updated if the exisitng webview and pipeline ID + /// Set the webview to this window. It won't be updated if the existing webview and pipeline ID /// are the same. This will also set the painting order of the compositor and tell /// constellation to focus the webview. pub fn set_webview( &mut self, webview_id: WebViewId, - pipline_id: PipelineId, + pipeline_id: PipelineId, compositor: &mut IOCompositor, ) { if self.panel.webview_id == webview_id { - if self.panel.pipeline_id != Some(pipline_id) { - self.panel.pipeline_id = Some(pipline_id); + if self.panel.pipeline_id != Some(pipeline_id) { + self.panel.pipeline_id = Some(pipeline_id); } } else if let Some(webview) = &mut self.webview { - if webview.webview_id == webview_id && webview.pipeline_id != Some(pipline_id) { - webview.pipeline_id = Some(pipline_id); + if webview.webview_id == webview_id && webview.pipeline_id != Some(pipeline_id) { + webview.pipeline_id = Some(pipeline_id); } } else { let size = self.size(); @@ -295,7 +295,7 @@ impl Window { self.webview = Some(WebView::new(webview_id, rect)); } - compositor.set_painting_order(self.paiting_order()); + compositor.set_painting_order(self.painting_order()); self.resize(self.size(), compositor); send_to_constellation( @@ -327,7 +327,7 @@ impl Window { } /// Get the painting order of this window. - pub fn paiting_order(&self) -> Vec { + pub fn painting_order(&self) -> Vec { let mut order = vec![]; if let Some(webview) = &self.webview { order.push(webview.clone()); From 3277ddaafda9f380ec9d0767c128ef3543525a13 Mon Sep 17 00:00:00 2001 From: Wu Wayne Date: Sun, 4 Aug 2024 10:40:59 +0900 Subject: [PATCH 03/22] Fix resize event --- src/compositor.rs | 39 --------------------------------------- src/main.rs | 1 + src/window.rs | 7 +++++-- 3 files changed, 6 insertions(+), 41 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index 1e28e973..5535b23f 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -1934,7 +1934,6 @@ impl IOCompositor { trace!("Compositing"); // Paint the scene. // TODO(gw): Take notice of any errors the renderer returns! - self.clear_background(); self.webrender // TODO to untyped? .render(self.viewport, 0 /* buffer_age */) @@ -2020,44 +2019,6 @@ impl IOCompositor { self.composition_request = CompositionRequest::CompositeNow(reason) } - fn clear_background(&self) { - let gl = &self.webrender_gl; - self.assert_gl_framebuffer_complete(); - - // Set the viewport background based on prefs. - let color = servo_config::pref!(shell.background_color.rgba); - gl.clear_color( - color[0] as f32, - color[1] as f32, - color[2] as f32, - color[3] as f32, - ); - - let framebuffer_height = self.viewport.height; - // Clear the viewport rect of each top-level browsing context. - for webview in &self.painting_order { - // Flip the rectangle in the framebuffer - let origin = webview.rect.to_i32(); - let mut rect = origin.clone(); - let min_y = framebuffer_height - rect.max.y; - let max_y = framebuffer_height - rect.min.y; - rect.min.y = min_y; - rect.max.y = max_y; - - gl.scissor( - rect.min.x, - rect.min.y, - rect.size().width, - rect.size().height, - ); - gl.enable(gl::SCISSOR_TEST); - gl.clear(gl::COLOR_BUFFER_BIT); - gl.disable(gl::SCISSOR_TEST); - } - - self.assert_gl_framebuffer_complete(); - } - #[track_caller] fn assert_no_gl_error(&self) { debug_assert_eq!(self.webrender_gl.get_error(), gl::NO_ERROR); diff --git a/src/main.rs b/src/main.rs index a2c0afa5..952e3000 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,6 +26,7 @@ fn main() -> Result<()> { if let Event::NewEvents(StartCause::Init) = event { let window = WindowBuilder::new() // .with_decorations(false) + .with_transparent(true) .build(&evl) .expect("Failed to initialize Winit window"); diff --git a/src/window.rs b/src/window.rs index 13b7d5d2..432b149b 100644 --- a/src/window.rs +++ b/src/window.rs @@ -237,14 +237,18 @@ impl Window { let need_resize = compositor.on_resize_window_event(size); let rect = DeviceIntRect::from_size(size); + self.panel.rect = rect; compositor.on_resize_webview_event(self.panel.webview_id, rect); - if let Some(w) = &self.webview { + if let Some(w) = &mut self.webview { let mut rect = DeviceIntRect::from_size(size); rect.min.y = rect.max.y.min(76); + w.rect = rect; compositor.on_resize_webview_event(w.webview_id, rect); } + compositor.set_painting_order(self.painting_order()); + if need_resize { compositor.repaint_synchronously(self); compositor.present(); @@ -295,7 +299,6 @@ impl Window { self.webview = Some(WebView::new(webview_id, rect)); } - compositor.set_painting_order(self.painting_order()); self.resize(self.size(), compositor); send_to_constellation( From 276c0b9b3f2bb74160b1831e0100d10700655a26 Mon Sep 17 00:00:00 2001 From: Wu Wayne Date: Sun, 4 Aug 2024 11:45:28 +0900 Subject: [PATCH 04/22] Return boolean after resize --- src/compositor.rs | 5 ++++- src/verso.rs | 9 ++++++--- src/window.rs | 24 ++++++++++++++---------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index 5535b23f..2c9aafd1 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -98,7 +98,10 @@ pub enum MouseWindowEvent { const MAX_ZOOM: f32 = 8.0; const MIN_ZOOM: f32 = 0.1; -/// NB: Never block on the constellation, because sometimes the constellation blocks on us. +// NB: Never block on the constellation, because sometimes the constellation blocks on us. +/// Verso compositor contains a GL rendering context with a WebRender insrtance. +/// The compositor will communicate with Serv messages from the Constellation and then +/// composite to WebRender frames and present the surface to the window. pub struct IOCompositor { /// Size of current viewport that Compositor is handling. viewport: DeviceIntSize, diff --git a/src/verso.rs b/src/verso.rs index b3eeb009..6885abdf 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -158,7 +158,7 @@ impl Verso { debug_flags.set(DebugFlags::PROFILER_DBG, opts.debug.webrender_stats); let render_notifier = Box::new(RenderNotifier::new(compositor_sender.clone())); - let clear_color = ColorF::new(1., 1., 1., 0.); + let clear_color = ColorF::new(0., 0., 0., 0.); create_webrender_instance( webrender_gl.clone(), render_notifier, @@ -394,11 +394,14 @@ impl Verso { event, } => { if let Some(compositor) = &mut self.compositor { - self.window.handle_winit_window_event( + if self.window.handle_winit_window_event( &self.constellation_sender, compositor, &event, - ) + ) { + compositor.repaint_synchronously(&mut self.window); + compositor.present(); + } } } e => log::warn!("Verso isn't supporting this event yet: {e:?}"), diff --git a/src/window.rs b/src/window.rs index 432b149b..127ce266 100644 --- a/src/window.rs +++ b/src/window.rs @@ -78,20 +78,20 @@ impl Window { ) } - /// Handle Winit window event. + /// Handle Winit window event and return a boolean to indicate if the compositor should repaint immediately. pub fn handle_winit_window_event( &mut self, sender: &Sender, compositor: &mut IOCompositor, event: &winit::event::WindowEvent, - ) { + ) -> bool { match event { WindowEvent::RedrawRequested => { compositor.present(); } WindowEvent::Resized(size) => { let size = Size2D::new(size.width, size.height); - let _ = self.resize(size.to_i32(), compositor); + return self.resize(size.to_i32(), compositor); } WindowEvent::CursorMoved { position, .. } => { let cursor: DevicePoint = DevicePoint::new(position.x as f32, position.y as f32); @@ -107,7 +107,7 @@ impl Window { log::warn!( "Verso Window isn't supporting this mouse button yet: {button:?}" ); - return; + return false; } }; let position = Point2D::new( @@ -189,6 +189,7 @@ impl Window { } e => log::warn!("Verso Window isn't supporting this window event yet: {e:?}"), } + false } /// Handle servo messages. @@ -232,8 +233,13 @@ impl Window { self.window.request_redraw() } - /// Resize the rendering context and all web views. - pub fn resize(&mut self, size: Size2D, compositor: &mut IOCompositor) { + /// Resize the rendering context and all web views. Return true if the compositor should repaint and present + /// after this. + pub fn resize( + &mut self, + size: Size2D, + compositor: &mut IOCompositor, + ) -> bool { let need_resize = compositor.on_resize_window_event(size); let rect = DeviceIntRect::from_size(size); @@ -249,10 +255,7 @@ impl Window { compositor.set_painting_order(self.painting_order()); - if need_resize { - compositor.repaint_synchronously(self); - compositor.present(); - } + need_resize } /// Size of the window that's used by webrender. @@ -299,6 +302,7 @@ impl Window { self.webview = Some(WebView::new(webview_id, rect)); } + // Ignore the return boolean since the webview will present eventually. self.resize(self.size(), compositor); send_to_constellation( From 92b79d525d72777f826865a7cbd86ff0d52cd9b1 Mon Sep 17 00:00:00 2001 From: Wu Wayne Date: Sun, 4 Aug 2024 12:40:14 +0900 Subject: [PATCH 05/22] Update verso to hold hashmap of windows --- src/compositor.rs | 59 ++++++++++++++---------- src/verso.rs | 111 ++++++++++++++++++++++++++++++---------------- src/window.rs | 52 +++++++++------------- 3 files changed, 130 insertions(+), 92 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index 2c9aafd1..c4bf8b68 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -41,6 +41,7 @@ use webrender_traits::{ NetToCompositorMsg, RenderingContext, ScriptToCompositorMsg, SerializedImageUpdate, UntrustedNodeAddress, }; +use winit::window::WindowId; use crate::touch::{TouchAction, TouchHandler}; use crate::webview::WebView; @@ -469,7 +470,11 @@ impl IOCompositor { } } - fn handle_browser_message(&mut self, msg: CompositorMsg, window: &mut Window) -> bool { + fn handle_browser_message( + &mut self, + msg: CompositorMsg, + windows: &mut HashMap, + ) -> bool { match self.shutdown_state { ShutdownState::NotShuttingDown => {} ShutdownState::ShuttingDown => { @@ -493,12 +498,12 @@ impl IOCompositor { } CompositorMsg::CreateOrUpdateWebView(frame_tree) => { - self.create_or_update_webview(&frame_tree, window); + self.create_or_update_webview(&frame_tree, windows); self.send_scroll_positions_to_layout_for_pipeline(&frame_tree.pipeline.id); } CompositorMsg::RemoveWebView(top_level_browsing_context_id) => { - self.remove_webview(top_level_browsing_context_id, window); + self.remove_webview(top_level_browsing_context_id, windows); } CompositorMsg::MoveResizeWebView(_webview_id, _rect) => { @@ -1106,14 +1111,21 @@ impl IOCompositor { } } - fn create_or_update_webview(&mut self, frame_tree: &SendableFrameTree, window: &mut Window) { + fn create_or_update_webview( + &mut self, + frame_tree: &SendableFrameTree, + windows: &mut HashMap, + ) { debug!("{}: Setting frame tree for webview", frame_tree.pipeline.id); - window.set_webview( - frame_tree.pipeline.top_level_browsing_context_id, - frame_tree.pipeline.id, - self, - ); + for window in windows.values_mut() { + // TODO: should only set to one window + window.set_webview( + frame_tree.pipeline.top_level_browsing_context_id, + frame_tree.pipeline.id, + self, + ); + } self.send_root_pipeline_display_list(); self.create_or_update_pipeline_details_with_frame_tree(frame_tree, None); @@ -1125,20 +1137,21 @@ impl IOCompositor { fn remove_webview( &mut self, top_level_browsing_context_id: TopLevelBrowsingContextId, - window: &mut Window, + windows: &mut HashMap, ) { debug!("{}: Removing", top_level_browsing_context_id); - let Some(webview) = window.remove_webview(top_level_browsing_context_id, self) else { - warn!("{top_level_browsing_context_id}: Removing unknown webview"); - return; - }; + for window in windows.values_mut() { + if let Some(webview) = window.remove_webview(top_level_browsing_context_id, self) { + self.send_root_pipeline_display_list(); + if let Some(pipeline_id) = webview.pipeline_id { + self.remove_pipeline_details_recursively(pipeline_id); + } - self.send_root_pipeline_display_list(); - if let Some(pipeline_id) = webview.pipeline_id { - self.remove_pipeline_details_recursively(pipeline_id); + self.frame_tree_id.next(); + return; + } } - - self.frame_tree_id.next(); + warn!("{top_level_browsing_context_id}: Removing unknown webview"); } /// Notify compositor the provided webview is resized. The compositor will tell constellation and update the display list. @@ -2039,7 +2052,7 @@ impl IOCompositor { } /// Receive and handle compositor messages. - pub fn receive_messages(&mut self, window: &mut Window) -> bool { + pub fn receive_messages(&mut self, windows: &mut HashMap) -> bool { // Check for new messages coming from the other threads in the system. let mut compositor_messages = vec![]; let mut found_recomposite_msg = false; @@ -2058,7 +2071,7 @@ impl IOCompositor { } } for msg in compositor_messages { - if !self.handle_browser_message(msg, window) { + if !self.handle_browser_message(msg, windows) { return false; } } @@ -2100,11 +2113,11 @@ impl IOCompositor { /// paint is not scheduled the compositor will hang forever. /// /// This is used when resizing the window. - pub fn repaint_synchronously(&mut self, window: &mut Window) { + pub fn repaint_synchronously(&mut self, windows: &mut HashMap) { while self.shutdown_state != ShutdownState::ShuttingDown { let msg = self.port.recv_compositor_msg(); let need_recomposite = matches!(msg, CompositorMsg::NewWebRenderFrameReady(_)); - let keep_going = self.handle_browser_message(msg, window); + let keep_going = self.handle_browser_message(msg, windows); if need_recomposite { self.composite(); break; diff --git a/src/verso.rs b/src/verso.rs index 6885abdf..f43998d9 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -1,6 +1,6 @@ use std::{ borrow::Cow, - path::PathBuf, + collections::HashMap, sync::{atomic::Ordering, Arc}, }; @@ -17,7 +17,7 @@ use compositing_traits::{ use constellation::{Constellation, FromCompositorLogger, InitialConstellationState}; use crossbeam_channel::{unbounded, Sender}; use devtools; -use embedder_traits::{EmbedderProxy, EmbedderReceiver, EventLoopWaker}; +use embedder_traits::{EmbedderMsg, EmbedderProxy, EmbedderReceiver, EventLoopWaker}; use euclid::Scale; use fonts::FontCacheThread; use gleam::gl; @@ -37,7 +37,11 @@ use webgpu; use webrender::{create_webrender_instance, ShaderPrecacheFlags, WebRenderOptions}; use webrender_api::*; use webrender_traits::*; -use winit::{event::Event, event_loop::EventLoopProxy, window::Window as WinitWindow}; +use winit::{ + event::Event, + event_loop::EventLoopProxy, + window::{Window as WinitWindow, WindowId}, +}; use crate::{ compositor::{IOCompositor, InitialCompositorState, ShutdownState}, @@ -47,7 +51,7 @@ use crate::{ /// Main entry point of Verso browser. pub struct Verso { - window: Window, + windows: HashMap, compositor: Option, constellation_sender: Sender, embedder_receiver: EmbedderReceiver, @@ -57,7 +61,6 @@ pub struct Verso { _js_engine_setup: Option, /// FIXME: It's None on wayland in Flatpak. Find a way to support this. clipboard: Option, - resource_dir: PathBuf, } impl Verso { @@ -351,27 +354,30 @@ impl Verso { opts.debug.convert_mouse_to_touch, ); + // Send the constellation message to start Panel UI + // NB: Should become a window method + let panel_id = window.panel.webview_id; + let path = resource_dir.join("panel.html"); + let url = ServoUrl::from_file_path(path.to_str().unwrap()).unwrap(); + send_to_constellation( + &constellation_sender, + ConstellationMsg::NewWebView(url, panel_id), + ); + + let mut windows = HashMap::new(); + windows.insert(window.id(), window); + // Create Verso instance let verso = Verso { - window, + windows, compositor: Some(compositor), constellation_sender, embedder_receiver, _js_engine_setup: js_engine_setup, clipboard: Clipboard::new().ok(), - resource_dir, }; verso.setup_logging(); - // Send the constellation message to start Panel UI - // NB: Should become a window method - let panel_id = verso.window.panel.webview_id; - let path = verso.resource_dir.join("panel.html"); - let url = ServoUrl::from_file_path(path.to_str().unwrap()).unwrap(); - send_to_constellation( - &verso.constellation_sender, - ConstellationMsg::NewWebView(url, panel_id), - ); verso } @@ -389,17 +395,21 @@ impl Verso { log::trace!("Verso is handling Winit event: {event:?}"); match event { Event::NewEvents(_) | Event::Suspended | Event::Resumed | Event::UserEvent(()) => {} - Event::WindowEvent { - window_id: _, - event, - } => { + Event::WindowEvent { window_id, event } => { if let Some(compositor) = &mut self.compositor { - if self.window.handle_winit_window_event( - &self.constellation_sender, - compositor, - &event, - ) { - compositor.repaint_synchronously(&mut self.window); + let mut need_repaint = false; + for (id, window) in &mut self.windows { + if window_id == *id { + need_repaint = window.handle_winit_window_event( + &self.constellation_sender, + compositor, + &event, + ); + } + } + + if need_repaint { + compositor.repaint_synchronously(&mut self.windows); compositor.present(); } } @@ -414,25 +424,50 @@ impl Verso { if let Some(compositor) = &mut self.compositor { // Handle Compositor's messages first log::trace!("Verso is handling Compositor messages"); - if compositor.receive_messages(&mut self.window) { + if compositor.receive_messages(&mut self.windows) { // And then handle Embedder messages log::trace!( "Verso is handling Embedder messages when shutdown state is set to {:?}", compositor.shutdown_state ); - while let Some((top_level_browsing_context, msg)) = - self.embedder_receiver.try_recv_embedder_msg() - { + while let Some((webview_id, msg)) = self.embedder_receiver.try_recv_embedder_msg() { match compositor.shutdown_state { ShutdownState::NotShuttingDown => { - // TODO we need to worry about which window to handle message in - // multiwindow - self.window.handle_servo_message( - top_level_browsing_context, - msg, - &self.constellation_sender, - self.clipboard.as_mut(), - ); + if let Some(id) = webview_id { + for window in self.windows.values_mut() { + if window.has_webview(id) { + window.handle_servo_message( + id, + msg, + &self.constellation_sender, + self.clipboard.as_mut(), + ); + break; + } + } + } else { + // Handle message in Verso Window + log::trace!("Verso Window is handling Embedder message: {msg:?}"); + match msg { + EmbedderMsg::ReadyToPresent(_w) => { + // TODO: Should be done in compositor composite method + for window in self.windows.values() { + window.request_redraw(); + } + } + EmbedderMsg::SetCursor(cursor) => { + // TODO: Should set to the right window + self.windows + .values() + .last() + .map(|w| w.set_cursor_icon(cursor)); + } + EmbedderMsg::Shutdown => {} + e => { + log::warn!("Verso Window isn't supporting handling this message yet: {e:?}") + } + } + } } ShutdownState::FinishedShuttingDown => { log::error!("Verso shouldn't be handling messages after compositor has shut down"); diff --git a/src/window.rs b/src/window.rs index 127ce266..1525d3b6 100644 --- a/src/window.rs +++ b/src/window.rs @@ -19,7 +19,7 @@ use winit::{ dpi::PhysicalPosition, event::{ElementState, TouchPhase, WindowEvent}, keyboard::ModifiersState, - window::{CursorIcon, Window as WinitWindow}, + window::{CursorIcon, Window as WinitWindow, WindowId}, }; use crate::{ @@ -195,36 +195,18 @@ impl Window { /// Handle servo messages. pub fn handle_servo_message( &mut self, - webview_id: Option, + webview_id: WebViewId, message: EmbedderMsg, sender: &Sender, clipboard: Option<&mut Clipboard>, ) { - match webview_id { - // // Handle message in Verso Panel - Some(p) if p == self.panel.webview_id => { - self.handle_servo_messages_with_panel(p, message, sender, clipboard); - } - // Handle message in Verso WebView - Some(w) => { - self.handle_servo_messages_with_webview(w, message, sender, clipboard); - } - // Handle message in Verso Window - None => { - log::trace!("Verso Window is handling Embedder message: {message:?}"); - match message { - EmbedderMsg::ReadyToPresent(_w) => { - self.window.request_redraw(); - } - EmbedderMsg::SetCursor(cursor) => { - self.set_cursor_icon(cursor); - } - EmbedderMsg::Shutdown => {} - e => { - log::warn!("Verso Window isn't supporting handling this message yet: {e:?}") - } - } - } + // // Handle message in Verso Panel + if webview_id == self.panel.webview_id { + self.handle_servo_messages_with_panel(webview_id, message, sender, clipboard); + } + // Handle message in Verso WebView + else { + self.handle_servo_messages_with_webview(webview_id, message, sender, clipboard); } } @@ -264,17 +246,25 @@ impl Window { Size2D::new(size.width as i32, size.height as i32) } + /// Get Winit window ID of the window. + pub fn id(&self) -> WindowId { + self.window.id() + } + /// Scale factor of the window. This is also known as HIDPI. pub fn scale_factor(&self) -> f64 { self.window.scale_factor() } - /// Get the mutable reference of the webview in this window from provided webview ID. - pub fn get_webview(&mut self, id: WebViewId) -> Option<&mut WebView> { + /// Check if the window has such webview. + pub fn has_webview(&mut self, id: WebViewId) -> bool { if self.panel.webview_id == id { - Some(&mut self.panel) + true } else { - self.webview.as_mut().filter(|w| w.webview_id == id) + self.webview + .as_ref() + .filter(|w| w.webview_id == id) + .is_some() } } From ae0943c457e266974e53f4111183c07abb8c6b9a Mon Sep 17 00:00:00 2001 From: Wu Wayne Date: Sun, 4 Aug 2024 17:07:39 +0900 Subject: [PATCH 06/22] Improve shutdown logic --- src/compositor.rs | 17 ++++++++-- src/verso.rs | 37 +++++++++++++-------- src/window.rs | 85 +++++++++++++++++++++++++++-------------------- 3 files changed, 86 insertions(+), 53 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index c4bf8b68..3c89fe3f 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -1140,18 +1140,29 @@ impl IOCompositor { windows: &mut HashMap, ) { debug!("{}: Removing", top_level_browsing_context_id); + let mut window_id = None; for window in windows.values_mut() { - if let Some(webview) = window.remove_webview(top_level_browsing_context_id, self) { + let (webview, close_window) = + window.remove_webview(top_level_browsing_context_id, self); + if let Some(webview) = webview { + self.set_painting_order(window.painting_order()); self.send_root_pipeline_display_list(); if let Some(pipeline_id) = webview.pipeline_id { self.remove_pipeline_details_recursively(pipeline_id); } + if close_window { + window_id = Some(window.id()); + } + self.frame_tree_id.next(); - return; + break; } } - warn!("{top_level_browsing_context_id}: Removing unknown webview"); + + if let Some(id) = window_id { + windows.remove(&id); + } } /// Notify compositor the provided webview is resized. The compositor will tell constellation and update the display list. diff --git a/src/verso.rs b/src/verso.rs index f43998d9..4211f794 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -38,7 +38,7 @@ use webrender::{create_webrender_instance, ShaderPrecacheFlags, WebRenderOptions use webrender_api::*; use webrender_traits::*; use winit::{ - event::Event, + event::{Event, WindowEvent}, event_loop::EventLoopProxy, window::{Window as WinitWindow, WindowId}, }; @@ -356,7 +356,7 @@ impl Verso { // Send the constellation message to start Panel UI // NB: Should become a window method - let panel_id = window.panel.webview_id; + let panel_id = window.panel.as_ref().unwrap().webview_id; let path = resource_dir.join("panel.html"); let url = ServoUrl::from_file_path(path.to_str().unwrap()).unwrap(); send_to_constellation( @@ -388,6 +388,11 @@ impl Verso { pub fn run(&mut self, event: Event<()>) { self.handle_winit_event(event); self.handle_servo_messages(); + if self.windows.is_empty() { + self.compositor + .as_mut() + .map(IOCompositor::maybe_start_shutting_down); + } } /// Handle Winit events @@ -397,20 +402,24 @@ impl Verso { Event::NewEvents(_) | Event::Suspended | Event::Resumed | Event::UserEvent(()) => {} Event::WindowEvent { window_id, event } => { if let Some(compositor) = &mut self.compositor { - let mut need_repaint = false; - for (id, window) in &mut self.windows { - if window_id == *id { - need_repaint = window.handle_winit_window_event( - &self.constellation_sender, - compositor, - &event, - ); + if let WindowEvent::CloseRequested = event { + self.windows.remove(&window_id); + } else { + let mut need_repaint = false; + for (id, window) in &mut self.windows { + if window_id == *id { + need_repaint = window.handle_winit_window_event( + &self.constellation_sender, + compositor, + &event, + ); + } } - } - if need_repaint { - compositor.repaint_synchronously(&mut self.windows); - compositor.present(); + if need_repaint { + compositor.repaint_synchronously(&mut self.windows); + compositor.present(); + } } } } diff --git a/src/window.rs b/src/window.rs index 1525d3b6..f8b094c3 100644 --- a/src/window.rs +++ b/src/window.rs @@ -36,7 +36,7 @@ pub struct Window { /// Access to Winit window pub(crate) window: WinitWindow, /// The main control panel of this window. - pub(crate) panel: WebView, + pub(crate) panel: Option, /// The WebView of this window. pub(crate) webview: Option, /// The mouse physical position in the web view. @@ -69,7 +69,7 @@ impl Window { ( Self { window, - panel: WebView::new_panel(DeviceIntRect::from_size(size)), + panel: Some(WebView::new_panel(DeviceIntRect::from_size(size))), webview: None, mouse_position: Cell::new(PhysicalPosition::default()), modifiers_state: Cell::new(ModifiersState::default()), @@ -177,9 +177,6 @@ impl Window { phase, ); } - WindowEvent::CloseRequested => { - compositor.maybe_start_shutting_down(); - } WindowEvent::ModifiersChanged(modifier) => self.modifiers_state.set(modifier.state()), WindowEvent::KeyboardInput { event, .. } => { let event = keyboard_event_from_winit(&event, self.modifiers_state.get()); @@ -201,7 +198,12 @@ impl Window { clipboard: Option<&mut Clipboard>, ) { // // Handle message in Verso Panel - if webview_id == self.panel.webview_id { + if self + .panel + .as_ref() + .filter(|p| p.webview_id == webview_id) + .is_some() + { self.handle_servo_messages_with_panel(webview_id, message, sender, clipboard); } // Handle message in Verso WebView @@ -224,9 +226,11 @@ impl Window { ) -> bool { let need_resize = compositor.on_resize_window_event(size); - let rect = DeviceIntRect::from_size(size); - self.panel.rect = rect; - compositor.on_resize_webview_event(self.panel.webview_id, rect); + if let Some(panel) = &mut self.panel { + let rect = DeviceIntRect::from_size(size); + panel.rect = rect; + compositor.on_resize_webview_event(panel.webview_id, rect); + } if let Some(w) = &mut self.webview { let mut rect = DeviceIntRect::from_size(size); @@ -258,7 +262,7 @@ impl Window { /// Check if the window has such webview. pub fn has_webview(&mut self, id: WebViewId) -> bool { - if self.panel.webview_id == id { + if self.panel.as_ref().filter(|w| w.webview_id == id).is_some() { true } else { self.webview @@ -277,28 +281,30 @@ impl Window { pipeline_id: PipelineId, compositor: &mut IOCompositor, ) { - if self.panel.webview_id == webview_id { - if self.panel.pipeline_id != Some(pipeline_id) { - self.panel.pipeline_id = Some(pipeline_id); - } - } else if let Some(webview) = &mut self.webview { - if webview.webview_id == webview_id && webview.pipeline_id != Some(pipeline_id) { - webview.pipeline_id = Some(pipeline_id); + if let Some(panel) = &mut self.panel { + if panel.webview_id == webview_id { + if panel.pipeline_id != Some(pipeline_id) { + panel.pipeline_id = Some(pipeline_id); + } + } else if let Some(webview) = &mut self.webview { + if webview.webview_id == webview_id && webview.pipeline_id != Some(pipeline_id) { + webview.pipeline_id = Some(pipeline_id); + } + } else { + let size = self.size(); + let mut rect = DeviceIntRect::from_size(size); + rect.min.y = rect.max.y.min(76); + self.webview = Some(WebView::new(webview_id, rect)); } - } else { - let size = self.size(); - let mut rect = DeviceIntRect::from_size(size); - rect.min.y = rect.max.y.min(76); - self.webview = Some(WebView::new(webview_id, rect)); - } - // Ignore the return boolean since the webview will present eventually. - self.resize(self.size(), compositor); + // Ignore the return boolean since the webview will present eventually. + self.resize(self.size(), compositor); - send_to_constellation( - &compositor.constellation_chan, - ConstellationMsg::FocusWebView(webview_id), - ); + send_to_constellation( + &compositor.constellation_chan, + ConstellationMsg::FocusWebView(webview_id), + ); + } } /// Remove the webview in this window by provided webview ID. If this is the panel, it will @@ -307,19 +313,24 @@ impl Window { &mut self, id: WebViewId, compositor: &mut IOCompositor, - ) -> Option { - if id == self.panel.webview_id { - compositor.maybe_start_shutting_down(); - None + ) -> (Option, bool) { + if self.panel.as_ref().filter(|w| w.webview_id == id).is_some() { + self.webview.as_ref().map(|w| { + send_to_constellation( + &compositor.constellation_chan, + ConstellationMsg::CloseWebView(w.webview_id), + ) + }); + (self.panel.take(), false) } else if self .webview .as_ref() .filter(|w| w.webview_id == id) .is_some() { - self.webview.take() + (self.webview.take(), self.panel.is_none()) } else { - None + (None, false) } } @@ -329,7 +340,9 @@ impl Window { if let Some(webview) = &self.webview { order.push(webview.clone()); } - order.push(self.panel.clone()); + if let Some(panel) = &self.panel { + order.push(panel.clone()); + } order } From ee65d847a6445fa577f89fa9a65f61fa0c6ff503 Mon Sep 17 00:00:00 2001 From: Wu Yuwei Date: Sun, 4 Aug 2024 18:49:39 +0900 Subject: [PATCH 07/22] Fix scale factor on Linux --- src/compositor.rs | 13 +++++++++++++ src/window.rs | 3 +++ 2 files changed, 16 insertions(+) diff --git a/src/compositor.rs b/src/compositor.rs index 3c89fe3f..461dd89b 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -1275,6 +1275,19 @@ impl IOCompositor { true } + /// Handle the window resize event and return a boolean to tell embedder if it should further + /// handle the resize event. + pub fn on_scale_factor_event(&mut self, scale_factor: f32) -> bool { + if self.shutdown_state != ShutdownState::NotShuttingDown { + return false; + } + + self.scale_factor = Scale::new(scale_factor); + self.update_after_zoom_or_hidpi_change(); + self.composite_if_necessary(CompositingReason::Resize); + true + } + /// Handle the mouse event in the window. pub fn on_mouse_window_event_class(&mut self, mouse_window_event: MouseWindowEvent) { if self.shutdown_state != ShutdownState::NotShuttingDown { diff --git a/src/window.rs b/src/window.rs index f8b094c3..6a0fb10c 100644 --- a/src/window.rs +++ b/src/window.rs @@ -93,6 +93,9 @@ impl Window { let size = Size2D::new(size.width, size.height); return self.resize(size.to_i32(), compositor); } + WindowEvent::ScaleFactorChanged { scale_factor, .. } => { + compositor.on_scale_factor_event(*scale_factor as f32); + } WindowEvent::CursorMoved { position, .. } => { let cursor: DevicePoint = DevicePoint::new(position.x as f32, position.y as f32); self.mouse_position.set(*position); From 7e38b23996c1840b65f6c7e03cc37b3094f2da7e Mon Sep 17 00:00:00 2001 From: Wu Wayne Date: Sun, 4 Aug 2024 19:07:17 +0900 Subject: [PATCH 08/22] Present directly after composite --- src/compositor.rs | 29 ++--------------------------- src/verso.rs | 9 +-------- src/window.rs | 3 --- 3 files changed, 3 insertions(+), 38 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index 461dd89b..d21451c0 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -198,9 +198,6 @@ pub struct IOCompositor { /// The number of frames pending to receive from WebRender. pending_frames: usize, - /// Waiting for external code to call present. - waiting_on_present: bool, - /// The [`Instant`] of the last animation tick, used to avoid flooding the Constellation and /// ScriptThread with a deluge of animation ticks. last_animation_tick: Instant, @@ -375,7 +372,6 @@ impl IOCompositor { exit_after_load, convert_mouse_to_touch, pending_frames: 0, - waiting_on_present: false, last_animation_tick: Instant::now(), is_animating: false, painting_order: vec![], @@ -1924,13 +1920,6 @@ impl IOCompositor { /// Composite to the given target if any, or the current target otherwise. fn composite_specific_target(&mut self) -> Result<(), UnableToComposite> { - if self.waiting_on_present { - debug!("tried to composite while waiting on present"); - return Err(UnableToComposite::NotReadyToPaintImage( - NotReadyToPaint::WaitingOnConstellation, - )); - } - if let Err(err) = self.rendering_context.make_gl_context_current() { warn!("Failed to make GL context current: {:?}", err); } @@ -2027,15 +2016,9 @@ impl IOCompositor { } } - // Notify embedder that servo is ready to present. - // Embedder should call `present` to tell compositor to continue rendering. - self.waiting_on_present = true; - let webview_ids = self.painting_order.iter().map(|w| w.webview_id); - let msg = ConstellationMsg::ReadyToPresent(webview_ids.collect()); - if let Err(e) = self.constellation_chan.send(msg) { - warn!("Sending event to constellation failed ({:?}).", e); + if let Err(err) = self.rendering_context.present() { + warn!("Failed to present surface: {:?}", err); } - self.composition_request = CompositionRequest::NoCompositingNecessary; self.process_animations(true); @@ -2043,14 +2026,6 @@ impl IOCompositor { Ok(()) } - /// Displays the contents of the surface on screen. - pub fn present(&mut self) { - if let Err(err) = self.rendering_context.present() { - warn!("Failed to present surface: {:?}", err); - } - self.waiting_on_present = false; - } - fn composite_if_necessary(&mut self, reason: CompositingReason) { trace!( "Will schedule a composite {reason:?}. Previously was {:?}", diff --git a/src/verso.rs b/src/verso.rs index 4211f794..8f65c7b4 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -418,7 +418,6 @@ impl Verso { if need_repaint { compositor.repaint_synchronously(&mut self.windows); - compositor.present(); } } } @@ -458,12 +457,6 @@ impl Verso { // Handle message in Verso Window log::trace!("Verso Window is handling Embedder message: {msg:?}"); match msg { - EmbedderMsg::ReadyToPresent(_w) => { - // TODO: Should be done in compositor composite method - for window in self.windows.values() { - window.request_redraw(); - } - } EmbedderMsg::SetCursor(cursor) => { // TODO: Should set to the right window self.windows @@ -471,7 +464,7 @@ impl Verso { .last() .map(|w| w.set_cursor_icon(cursor)); } - EmbedderMsg::Shutdown => {} + EmbedderMsg::Shutdown | EmbedderMsg::ReadyToPresent(_) => {} e => { log::warn!("Verso Window isn't supporting handling this message yet: {e:?}") } diff --git a/src/window.rs b/src/window.rs index 6a0fb10c..291c385b 100644 --- a/src/window.rs +++ b/src/window.rs @@ -86,9 +86,6 @@ impl Window { event: &winit::event::WindowEvent, ) -> bool { match event { - WindowEvent::RedrawRequested => { - compositor.present(); - } WindowEvent::Resized(size) => { let size = Size2D::new(size.width, size.height); return self.resize(size.to_i32(), compositor); From 57923bfad423eb2baadef8b584ef652067c5391d Mon Sep 17 00:00:00 2001 From: Wu Yu Wei Date: Mon, 5 Aug 2024 15:25:17 +0900 Subject: [PATCH 09/22] Add some fields to prepare for multisurface --- src/compositor.rs | 33 +++++++++++++++++---------------- src/verso.rs | 14 +++----------- src/window.rs | 11 +++++++++-- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index d21451c0..19a14da6 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -104,18 +104,27 @@ const MIN_ZOOM: f32 = 0.1; /// The compositor will communicate with Serv messages from the Constellation and then /// composite to WebRender frames and present the surface to the window. pub struct IOCompositor { + /// The current window that Compositor is handling. + current_window: WindowId, + /// Size of current viewport that Compositor is handling. viewport: DeviceIntSize, + /// The pixel density of the display. + scale_factor: Scale, + + /// The order to paint webviews in, top most webview should be the last element. + painting_order: Vec, + + /// The active webrender document. + webrender_document: DocumentId, + /// The port on which we receive messages. port: CompositorReceiver, /// Tracks details about each active pipeline that the compositor knows about. pipeline_details: HashMap, - /// The pixel density of the display. - scale_factor: Scale, - /// "Mobile-style" zoom that does not reflow the page. viewport_zoom: PinchZoomFactor, @@ -161,9 +170,6 @@ pub struct IOCompositor { /// The webrender renderer. webrender: webrender::Renderer, - /// The active webrender document. - webrender_document: DocumentId, - /// The webrender interface, if enabled. webrender_api: RenderApi, @@ -207,9 +213,6 @@ pub struct IOCompositor { /// will want to avoid blocking on UI events, and just /// run the event loop at the vsync interval. pub is_animating: bool, - - /// The order to paint webviews in, top most webview should be the last element. - painting_order: Vec, } #[derive(Clone, Copy)] @@ -335,6 +338,7 @@ impl PipelineDetails { impl IOCompositor { /// Create a new compositor. pub fn new( + current_window: WindowId, viewport: DeviceIntSize, scale_factor: Scale, state: InitialCompositorState, @@ -342,6 +346,7 @@ impl IOCompositor { convert_mouse_to_touch: bool, ) -> Self { let compositor = IOCompositor { + current_window, viewport, port: state.receiver, pipeline_details: HashMap::new(), @@ -1271,8 +1276,8 @@ impl IOCompositor { true } - /// Handle the window resize event and return a boolean to tell embedder if it should further - /// handle the resize event. + /// Handle the window scale factor event and return a boolean to tell embedder if it should further + /// handle the scale factor event. pub fn on_scale_factor_event(&mut self, scale_factor: f32) -> bool { if self.shutdown_state != ShutdownState::NotShuttingDown { return false; @@ -1748,10 +1753,6 @@ impl IOCompositor { } } - fn scale_factor(&self) -> Scale { - self.scale_factor - } - fn device_pixels_per_page_pixel(&self) -> Scale { self.device_pixels_per_page_pixel_not_including_page_zoom() * self.pinch_zoom_level() } @@ -1759,7 +1760,7 @@ impl IOCompositor { fn device_pixels_per_page_pixel_not_including_page_zoom( &self, ) -> Scale { - self.page_zoom * self.scale_factor() + self.page_zoom * self.scale_factor } /// Handle zoom reset event diff --git a/src/verso.rs b/src/verso.rs index 8f65c7b4..a080a446 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -83,7 +83,7 @@ impl Verso { // Initialize configurations and Verso window let resource_dir = config.resource_dir.clone(); config.init(); - let (window, rendering_context) = Window::new(window); + let (mut window, rendering_context) = Window::new(window); let event_loop_waker = Box::new(Waker(proxy)); let opts = opts::get(); @@ -105,16 +105,6 @@ impl Verso { gl::GlesFns::load_with(|s| rendering_context.get_proc_address(s)) }, }; - // Make sure the gl context is made current. - rendering_context.make_gl_context_current().unwrap(); - debug_assert_eq!(webrender_gl.get_error(), gl::NO_ERROR,); - // Bind the webrender framebuffer - let framebuffer_object = rendering_context - .context_surface_info() - .unwrap_or(None) - .map(|info| info.framebuffer_object) - .unwrap_or(0); - webrender_gl.bind_framebuffer(gl::FRAMEBUFFER, framebuffer_object); // Create profiler threads let time_profiler_sender = profile::time::Profiler::create( @@ -191,6 +181,7 @@ impl Verso { }; let webrender_api = webrender_api_sender.create_api(); let webrender_document = webrender_api.add_document(window.size()); + window.document = webrender_document; // Initialize js engine if it's single process mode let js_engine_setup = if !opts.multiprocess { @@ -335,6 +326,7 @@ impl Verso { // The compositor coordinates with the client window to create the final // rendered page and display it somewhere. let compositor = IOCompositor::new( + window.id(), window.size(), Scale::new(window.scale_factor() as f32), InitialCompositorState { diff --git a/src/window.rs b/src/window.rs index 291c385b..293e641f 100644 --- a/src/window.rs +++ b/src/window.rs @@ -7,12 +7,12 @@ use embedder_traits::{Cursor, EmbedderMsg}; use euclid::{Point2D, Size2D}; use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; use script_traits::{TouchEventType, WheelDelta, WheelMode}; -use surfman::{Connection, SurfaceType}; +use surfman::{Connection, Surface, SurfaceType}; use webrender_api::{ units::{ DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePixel, DevicePoint, LayoutVector2D, }, - ScrollLocation, + DocumentId, ScrollLocation, }; use webrender_traits::RenderingContext; use winit::{ @@ -43,6 +43,11 @@ pub struct Window { mouse_position: Cell>, /// Modifiers state of the keyboard. modifiers_state: Cell, + /// Webrender document + pub(crate) document: DocumentId, + /// The surface of the window which isn't used by Compositor at the moment. + /// If this field is None, it means the compositor is currently rendering on this window. + pending_surface: Option, } impl Window { @@ -73,6 +78,8 @@ impl Window { webview: None, mouse_position: Cell::new(PhysicalPosition::default()), modifiers_state: Cell::new(ModifiersState::default()), + document: DocumentId::INVALID, + pending_surface: None, }, rendering_context, ) From 9289541146879cff22134fdaa2e3df62ff98a39b Mon Sep 17 00:00:00 2001 From: Wu Yu Wei Date: Mon, 5 Aug 2024 20:53:14 +0900 Subject: [PATCH 10/22] Add initial multi-surface support --- src/compositor.rs | 33 ++++++++++++++++-- src/main.rs | 44 ++---------------------- src/verso.rs | 24 ++++++++----- src/window.rs | 87 +++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 124 insertions(+), 64 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index 19a14da6..09141c2d 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -24,6 +24,7 @@ use script_traits::{ }; use servo_geometry::DeviceIndependentPixel; use style_traits::{CSSPixel, DevicePixel, PinchZoomFactor}; +use surfman::Surface; use webrender::{RenderApi, Transaction}; use webrender_api::units::{ DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePoint, LayoutPoint, LayoutRect, LayoutSize, @@ -104,6 +105,9 @@ const MIN_ZOOM: f32 = 0.1; /// The compositor will communicate with Serv messages from the Constellation and then /// composite to WebRender frames and present the surface to the window. pub struct IOCompositor { + /// All surfaces that Compositor currently owns. + pub surfaces: HashMap>, + /// The current window that Compositor is handling. current_window: WindowId, @@ -174,7 +178,7 @@ pub struct IOCompositor { webrender_api: RenderApi, /// The surfman instance that webrender targets - rendering_context: RenderingContext, + pub rendering_context: RenderingContext, /// The GL bindings for webrender webrender_gl: Rc, @@ -345,7 +349,10 @@ impl IOCompositor { exit_after_load: bool, convert_mouse_to_touch: bool, ) -> Self { + let mut surfaces = HashMap::new(); + surfaces.insert(current_window, None); let compositor = IOCompositor { + surfaces, current_window, viewport, port: state.receiver, @@ -388,11 +395,15 @@ impl IOCompositor { } /// Consume compositor itself and deinit webrender. - pub fn deinit(self) { - // TODO: can we do this in drop? + pub fn deinit(mut self) { if let Err(err) = self.rendering_context.make_gl_context_current() { warn!("Failed to make GL context current: {:?}", err); } + for surface in self.surfaces.values_mut() { + surface + .take() + .map(|s| self.rendering_context.destroy_surface(s)); + } self.webrender.deinit(); } @@ -1258,6 +1269,22 @@ impl IOCompositor { self.pipeline_details.remove(&pipeline_id); } + /// Change the current window of the compositor should display. + pub fn update_current_window(&mut self, window: &mut Window) { + if window.id() != self.current_window { + if let Some(Some(new_surface)) = self.surfaces.insert(window.id(), None) { + self.rendering_context.with_front_buffer(|_, old_surface| { + self.surfaces.insert(self.current_window, Some(old_surface)); + new_surface + }); + self.current_window = window.id(); + self.scale_factor = Scale::new(window.scale_factor() as f32); + window.resize(window.size(), self); + // TODO: Figure out why second screen may turn black + } + } + } + /// Handle the window resize event and return a boolean to tell embedder if it should further /// handle the resize event. pub fn on_resize_window_event(&mut self, new_viewport: DeviceIntSize) -> bool { diff --git a/src/main.rs b/src/main.rs index 952e3000..258f0971 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,18 +4,8 @@ use verso::config::Config; use verso::{Result, Verso}; use winit::event::{Event, StartCause}; +use winit::event_loop::EventLoop; use winit::event_loop::{ControlFlow, DeviceEvents}; -use winit::{event_loop::EventLoop, window::WindowBuilder}; - -/* window decoration */ -#[cfg(macos)] -use cocoa::appkit::{NSWindow, NSWindowStyleMask, NSWindowTitleVisibility}; -#[cfg(macos)] -use objc::runtime::Object; -#[cfg(macos)] -use raw_window_handle::{AppKitWindowHandle, HasRawWindowHandle, RawWindowHandle}; -#[cfg(macos)] -use winit::dpi::LogicalPosition; fn main() -> Result<()> { let event_loop = EventLoop::new()?; @@ -24,25 +14,11 @@ fn main() -> Result<()> { let mut verso = None; event_loop.run(move |event, evl| { if let Event::NewEvents(StartCause::Init) = event { - let window = WindowBuilder::new() - // .with_decorations(false) - .with_transparent(true) - .build(&evl) - .expect("Failed to initialize Winit window"); - - #[cfg(macos)] - unsafe { - let rwh = window.raw_window_handle(); - if let RawWindowHandle::AppKit(AppKitWindowHandle { ns_window, .. }) = rwh { - decorate_window(ns_window as *mut Object, LogicalPosition::new(8.0, 40.0)); - } - } - let config = Config::new(resources_dir_path().unwrap()); - verso = Some(Verso::new(window, proxy.clone(), config)); + verso = Some(Verso::new(evl, proxy.clone(), config)); } else { if let Some(v) = &mut verso { - v.run(event); + v.run(event, evl); if v.finished_shutting_down() { evl.exit(); } else if v.is_animating() { @@ -57,20 +33,6 @@ fn main() -> Result<()> { Ok(()) } -#[cfg(macos)] -pub unsafe fn decorate_window(window: *mut Object, _position: LogicalPosition) { - NSWindow::setTitlebarAppearsTransparent_(window, cocoa::base::YES); - NSWindow::setTitleVisibility_(window, NSWindowTitleVisibility::NSWindowTitleHidden); - NSWindow::setStyleMask_( - window, - NSWindowStyleMask::NSTitledWindowMask - | NSWindowStyleMask::NSFullSizeContentViewWindowMask - | NSWindowStyleMask::NSClosableWindowMask - | NSWindowStyleMask::NSResizableWindowMask - | NSWindowStyleMask::NSMiniaturizableWindowMask, - ); -} - fn resources_dir_path() -> Option { #[cfg(feature = "packager")] let root_dir = { diff --git a/src/verso.rs b/src/verso.rs index a080a446..d28860d1 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -39,8 +39,8 @@ use webrender_api::*; use webrender_traits::*; use winit::{ event::{Event, WindowEvent}, - event_loop::EventLoopProxy, - window::{Window as WinitWindow, WindowId}, + event_loop::{EventLoopProxy, EventLoopWindowTarget}, + window::WindowId, }; use crate::{ @@ -79,11 +79,11 @@ impl Verso { /// - Font cache /// - Canvas /// - Constellation - pub fn new(window: WinitWindow, proxy: EventLoopProxy<()>, config: Config) -> Self { + pub fn new(evl: &EventLoopWindowTarget<()>, proxy: EventLoopProxy<()>, config: Config) -> Self { // Initialize configurations and Verso window let resource_dir = config.resource_dir.clone(); config.init(); - let (mut window, rendering_context) = Window::new(window); + let (window, rendering_context) = Window::new(evl); let event_loop_waker = Box::new(Waker(proxy)); let opts = opts::get(); @@ -151,7 +151,7 @@ impl Verso { debug_flags.set(DebugFlags::PROFILER_DBG, opts.debug.webrender_stats); let render_notifier = Box::new(RenderNotifier::new(compositor_sender.clone())); - let clear_color = ColorF::new(0., 0., 0., 0.); + let clear_color = ColorF::new(0., 1., 0., 0.); create_webrender_instance( webrender_gl.clone(), render_notifier, @@ -180,8 +180,9 @@ impl Verso { .expect("Unable to initialize webrender!") }; let webrender_api = webrender_api_sender.create_api(); - let webrender_document = webrender_api.add_document(window.size()); - window.document = webrender_document; + let document_id: u64 = window.id().into(); + let webrender_document = + webrender_api.add_document_with_id(window.size(), document_id as u32); // Initialize js engine if it's single process mode let js_engine_setup = if !opts.multiprocess { @@ -377,7 +378,11 @@ impl Verso { /// /// - Handle Winit's event, updating Compositor and sending messages to Constellation. /// - Handle Servo's messages and updating Compositor again. - pub fn run(&mut self, event: Event<()>) { + pub fn run(&mut self, event: Event<()>, evl: &EventLoopWindowTarget<()>) { + if self.windows.len() == 1 { + let window = Window::new_with_compositor(evl, self.compositor.as_mut().unwrap()); + self.windows.insert(window.id(), window); + } self.handle_winit_event(event); self.handle_servo_messages(); if self.windows.is_empty() { @@ -395,7 +400,8 @@ impl Verso { Event::WindowEvent { window_id, event } => { if let Some(compositor) = &mut self.compositor { if let WindowEvent::CloseRequested = event { - self.windows.remove(&window_id); + // self.windows.remove(&window_id); + compositor.maybe_start_shutting_down(); } else { let mut need_repaint = false; for (id, window) in &mut self.windows { diff --git a/src/window.rs b/src/window.rs index 293e641f..1929894c 100644 --- a/src/window.rs +++ b/src/window.rs @@ -7,19 +7,21 @@ use embedder_traits::{Cursor, EmbedderMsg}; use euclid::{Point2D, Size2D}; use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; use script_traits::{TouchEventType, WheelDelta, WheelMode}; -use surfman::{Connection, Surface, SurfaceType}; +use surfman::Connection; +use surfman::SurfaceType; use webrender_api::{ units::{ DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePixel, DevicePoint, LayoutVector2D, }, - DocumentId, ScrollLocation, + ScrollLocation, }; use webrender_traits::RenderingContext; use winit::{ dpi::PhysicalPosition, event::{ElementState, TouchPhase, WindowEvent}, + event_loop::EventLoopWindowTarget, keyboard::ModifiersState, - window::{CursorIcon, Window as WinitWindow, WindowId}, + window::{CursorIcon, Window as WinitWindow, WindowBuilder, WindowId}, }; use crate::{ @@ -43,16 +45,21 @@ pub struct Window { mouse_position: Cell>, /// Modifiers state of the keyboard. modifiers_state: Cell, - /// Webrender document - pub(crate) document: DocumentId, - /// The surface of the window which isn't used by Compositor at the moment. - /// If this field is None, it means the compositor is currently rendering on this window. - pending_surface: Option, } impl Window { /// Create a Verso window from Winit window and return the rendering context. - pub fn new(window: WinitWindow) -> (Self, RenderingContext) { + pub fn new(evl: &EventLoopWindowTarget<()>) -> (Self, RenderingContext) { + let window = WindowBuilder::new() + .build(evl) + .expect("Failed to create window."); + #[cfg(macos)] + unsafe { + let rwh = window.raw_window_handle(); + if let RawWindowHandle::AppKit(AppKitWindowHandle { ns_window, .. }) = rwh { + decorate_window(ns_window as *mut Object, LogicalPosition::new(8.0, 40.0)); + } + } let window_size = window.inner_size(); let window_size = Size2D::new(window_size.width as i32, window_size.height as i32); let display_handle = window.raw_display_handle(); @@ -78,13 +85,41 @@ impl Window { webview: None, mouse_position: Cell::new(PhysicalPosition::default()), modifiers_state: Cell::new(ModifiersState::default()), - document: DocumentId::INVALID, - pending_surface: None, }, rendering_context, ) } + /// Create a Verso window with the rendering context. + pub fn new_with_compositor( + evl: &EventLoopWindowTarget<()>, + compositor: &mut IOCompositor, + ) -> Self { + let window = WindowBuilder::new() + .build(evl) + .expect("Failed to create window."); + let window_size = window.inner_size(); + let window_size = Size2D::new(window_size.width as i32, window_size.height as i32); + let native_widget = compositor + .rendering_context + .connection() + .create_native_widget_from_raw_window_handle(window.raw_window_handle(), window_size) + .expect("Failed to create native widget"); + let surface_type = SurfaceType::Widget { native_widget }; + let surface = compositor + .rendering_context + .create_surface(surface_type) + .ok(); + compositor.surfaces.insert(window.id(), surface); + Self { + window, + panel: None, + webview: None, + mouse_position: Cell::new(PhysicalPosition::default()), + modifiers_state: Cell::new(ModifiersState::default()), + } + } + /// Handle Winit window event and return a boolean to indicate if the compositor should repaint immediately. pub fn handle_winit_window_event( &mut self, @@ -93,6 +128,11 @@ impl Window { event: &winit::event::WindowEvent, ) -> bool { match event { + WindowEvent::Focused(focused) => { + if *focused { + compositor.update_current_window(self); + } + } WindowEvent::Resized(size) => { let size = Size2D::new(size.width, size.height); return self.resize(size.to_i32(), compositor); @@ -101,6 +141,7 @@ impl Window { compositor.on_scale_factor_event(*scale_factor as f32); } WindowEvent::CursorMoved { position, .. } => { + compositor.update_current_window(self); let cursor: DevicePoint = DevicePoint::new(position.x as f32, position.y as f32); self.mouse_position.set(*position); compositor.on_mouse_window_move_event_class(cursor); @@ -395,3 +436,27 @@ impl Window { self.window.set_cursor_icon(winit_cursor); } } + +/* window decoration */ +#[cfg(macos)] +use cocoa::appkit::{NSWindow, NSWindowStyleMask, NSWindowTitleVisibility}; +#[cfg(macos)] +use objc::runtime::Object; +#[cfg(macos)] +use raw_window_handle::{AppKitWindowHandle, HasRawWindowHandle, RawWindowHandle}; +#[cfg(macos)] +use winit::dpi::LogicalPosition; + +#[cfg(macos)] +pub unsafe fn decorate_window(window: *mut Object, _position: LogicalPosition) { + NSWindow::setTitlebarAppearsTransparent_(window, cocoa::base::YES); + NSWindow::setTitleVisibility_(window, NSWindowTitleVisibility::NSWindowTitleHidden); + NSWindow::setStyleMask_( + window, + NSWindowStyleMask::NSTitledWindowMask + | NSWindowStyleMask::NSFullSizeContentViewWindowMask + | NSWindowStyleMask::NSClosableWindowMask + | NSWindowStyleMask::NSResizableWindowMask + | NSWindowStyleMask::NSMiniaturizableWindowMask, + ); +} From 20c6c58a829f44bb09a2c5de19bae3532cef1951 Mon Sep 17 00:00:00 2001 From: Wu Wayne Date: Tue, 6 Aug 2024 14:04:02 +0900 Subject: [PATCH 11/22] Add document ID field in window --- src/compositor.rs | 2 +- src/verso.rs | 17 ++++++++++++++--- src/window.rs | 24 +++++++++++++++++++++++- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index 09141c2d..27fb0460 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -1278,9 +1278,9 @@ impl IOCompositor { new_surface }); self.current_window = window.id(); + // self.webrender_document = window.document_id; self.scale_factor = Scale::new(window.scale_factor() as f32); window.resize(window.size(), self); - // TODO: Figure out why second screen may turn black } } } diff --git a/src/verso.rs b/src/verso.rs index d28860d1..71a1c19a 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -83,7 +83,7 @@ impl Verso { // Initialize configurations and Verso window let resource_dir = config.resource_dir.clone(); config.init(); - let (window, rendering_context) = Window::new(evl); + let (mut window, rendering_context) = Window::new(evl); let event_loop_waker = Box::new(Waker(proxy)); let opts = opts::get(); @@ -106,6 +106,17 @@ impl Verso { }, }; + // Make sure the gl context is made current. + rendering_context.make_gl_context_current().unwrap(); + debug_assert_eq!(webrender_gl.get_error(), gl::NO_ERROR,); + // Bind the webrender framebuffer + let framebuffer_object = rendering_context + .context_surface_info() + .unwrap_or(None) + .map(|info| info.framebuffer_object) + .unwrap_or(0); + webrender_gl.bind_framebuffer(gl::FRAMEBUFFER, framebuffer_object); + // Create profiler threads let time_profiler_sender = profile::time::Profiler::create( &opts.time_profiling, @@ -180,9 +191,9 @@ impl Verso { .expect("Unable to initialize webrender!") }; let webrender_api = webrender_api_sender.create_api(); - let document_id: u64 = window.id().into(); let webrender_document = - webrender_api.add_document_with_id(window.size(), document_id as u32); + webrender_api.add_document_with_id(window.size(), u64::from(window.id()) as u32); + window.document_id = webrender_document; // Initialize js engine if it's single process mode let js_engine_setup = if !opts.multiprocess { diff --git a/src/window.rs b/src/window.rs index 1929894c..e99f0bf9 100644 --- a/src/window.rs +++ b/src/window.rs @@ -9,6 +9,7 @@ use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; use script_traits::{TouchEventType, WheelDelta, WheelMode}; use surfman::Connection; use surfman::SurfaceType; +use webrender_api::DocumentId; use webrender_api::{ units::{ DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePixel, DevicePoint, LayoutVector2D, @@ -45,6 +46,7 @@ pub struct Window { mouse_position: Cell>, /// Modifiers state of the keyboard. modifiers_state: Cell, + pub(crate) document_id: DocumentId, } impl Window { @@ -85,6 +87,7 @@ impl Window { webview: None, mouse_position: Cell::new(PhysicalPosition::default()), modifiers_state: Cell::new(ModifiersState::default()), + document_id: DocumentId::INVALID, }, rendering_context, ) @@ -111,12 +114,18 @@ impl Window { .create_surface(surface_type) .ok(); compositor.surfaces.insert(window.id(), surface); + // let window_size = window.inner_size(); + // let window_size = Size2D::new(window_size.width as i32, window_size.height as i32); + // let document_id = compositor + // .webrender_api + // .add_document_with_id(window_size, u64::from(window.id()) as u32); Self { window, panel: None, webview: None, mouse_position: Cell::new(PhysicalPosition::default()), modifiers_state: Cell::new(ModifiersState::default()), + document_id: DocumentId::INVALID, } } @@ -348,6 +357,18 @@ impl Window { // Ignore the return boolean since the webview will present eventually. self.resize(self.size(), compositor); + send_to_constellation( + &compositor.constellation_chan, + ConstellationMsg::FocusWebView(webview_id), + ); + } else { + let size = self.size(); + let rect = DeviceIntRect::from_size(size); + self.panel = Some(WebView::new(webview_id, rect)); + + // Ignore the return boolean since the webview will present eventually. + self.resize(self.size(), compositor); + send_to_constellation( &compositor.constellation_chan, ConstellationMsg::FocusWebView(webview_id), @@ -443,10 +464,11 @@ use cocoa::appkit::{NSWindow, NSWindowStyleMask, NSWindowTitleVisibility}; #[cfg(macos)] use objc::runtime::Object; #[cfg(macos)] -use raw_window_handle::{AppKitWindowHandle, HasRawWindowHandle, RawWindowHandle}; +use raw_window_handle::{AppKitWindowHandle, RawWindowHandle}; #[cfg(macos)] use winit::dpi::LogicalPosition; +/// Window decoration for macOS. #[cfg(macos)] pub unsafe fn decorate_window(window: *mut Object, _position: LogicalPosition) { NSWindow::setTitlebarAppearsTransparent_(window, cocoa::base::YES); From 1e7f842a8ab2e3d8690c24b638515dd7cf5d0826 Mon Sep 17 00:00:00 2001 From: Wu Wayne Date: Tue, 6 Aug 2024 20:13:11 +0900 Subject: [PATCH 12/22] Update to latest servo --- Cargo.lock | 162 ++++++++++++++++++++++++++--------------------------- Cargo.toml | 49 ++++++++-------- 2 files changed, 105 insertions(+), 106 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5675de93..6beb4090 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,7 +239,7 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "background_hang_monitor" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "background_hang_monitor_api", "backtrace", @@ -257,7 +257,7 @@ dependencies = [ [[package]] name = "background_hang_monitor_api" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "base", "ipc-channel", @@ -288,7 +288,7 @@ dependencies = [ [[package]] name = "base" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "crossbeam-channel", "ipc-channel", @@ -419,7 +419,7 @@ dependencies = [ [[package]] name = "bluetooth" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "bitflags 2.6.0", "bluetooth_traits", @@ -435,7 +435,7 @@ dependencies = [ [[package]] name = "bluetooth_traits" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "embedder_traits", "ipc-channel", @@ -559,7 +559,7 @@ dependencies = [ [[package]] name = "canvas" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "app_units", "bitflags 2.6.0", @@ -598,7 +598,7 @@ dependencies = [ [[package]] name = "canvas_traits" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "base", "crossbeam-channel", @@ -793,7 +793,7 @@ dependencies = [ [[package]] name = "compositing_traits" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "base", "crossbeam-channel", @@ -823,7 +823,7 @@ dependencies = [ [[package]] name = "constellation" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "background_hang_monitor", "background_hang_monitor_api", @@ -1139,7 +1139,7 @@ dependencies = [ [[package]] name = "deny_public_fields" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "syn 2.0.72", "synstructure", @@ -1158,7 +1158,7 @@ dependencies = [ [[package]] name = "derive_common" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-07-16#ed09e046c8cc7654eb3a0c2e3ec789503f64ed74" +source = "git+https://github.com/servo/stylo?branch=2024-07-16#e7ea820c1aaee5a40f95552477c22b48b04c21b4" dependencies = [ "darling", "proc-macro2", @@ -1181,7 +1181,7 @@ dependencies = [ [[package]] name = "devtools" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "base", "chrono", @@ -1203,7 +1203,7 @@ dependencies = [ [[package]] name = "devtools_traits" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "base", "bitflags 2.6.0", @@ -1322,7 +1322,7 @@ dependencies = [ [[package]] name = "dom" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-07-16#ed09e046c8cc7654eb3a0c2e3ec789503f64ed74" +source = "git+https://github.com/servo/stylo?branch=2024-07-16#e7ea820c1aaee5a40f95552477c22b48b04c21b4" dependencies = [ "bitflags 2.6.0", ] @@ -1330,7 +1330,7 @@ dependencies = [ [[package]] name = "dom_struct" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "quote", "syn 2.0.72", @@ -1339,7 +1339,7 @@ dependencies = [ [[package]] name = "domobject_derive" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "proc-macro2", "quote", @@ -1390,7 +1390,7 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "embedder_traits" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "base", "cfg-if", @@ -1573,9 +1573,9 @@ checksum = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" [[package]] name = "flate2" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" dependencies = [ "crc32fast", "miniz_oxide", @@ -1630,7 +1630,7 @@ dependencies = [ [[package]] name = "fonts" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "app_units", "atomic_refcell", @@ -1682,7 +1682,7 @@ dependencies = [ [[package]] name = "fonts_traits" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "ipc-channel", "malloc_size_of", @@ -2258,7 +2258,7 @@ dependencies = [ [[package]] name = "hyper_serde" version = "0.13.2" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "cookie 0.18.1", "headers", @@ -2906,7 +2906,7 @@ dependencies = [ [[package]] name = "jstraceable_derive" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "proc-macro2", "syn 2.0.72", @@ -2944,7 +2944,7 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "layout_2020" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "app_units", "atomic_refcell", @@ -2989,7 +2989,7 @@ dependencies = [ [[package]] name = "layout_thread_2020" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "app_units", "base", @@ -3185,7 +3185,7 @@ dependencies = [ [[package]] name = "malloc_size_of" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-07-16#ed09e046c8cc7654eb3a0c2e3ec789503f64ed74" +source = "git+https://github.com/servo/stylo?branch=2024-07-16#e7ea820c1aaee5a40f95552477c22b48b04c21b4" dependencies = [ "accountable-refcell", "app_units", @@ -3248,7 +3248,7 @@ checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "media" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "euclid", "fnv", @@ -3309,7 +3309,7 @@ dependencies = [ [[package]] name = "metrics" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "base", "fonts_traits", @@ -3477,7 +3477,7 @@ dependencies = [ [[package]] name = "net" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "async-recursion", "async-tungstenite", @@ -3539,7 +3539,7 @@ dependencies = [ [[package]] name = "net_traits" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "base", "content-security-policy", @@ -3949,7 +3949,7 @@ dependencies = [ [[package]] name = "peek-poke" version = "0.3.0" -source = "git+https://github.com/servo/webrender?branch=0.64#9d354adf8955b1390dd56db89e6d5a9ea7880391" +source = "git+https://github.com/servo/webrender?branch=0.65#c0bcdd024adac1297ceb2f34a2de46731243c970" dependencies = [ "euclid", "peek-poke-derive", @@ -3958,7 +3958,7 @@ dependencies = [ [[package]] name = "peek-poke-derive" version = "0.3.0" -source = "git+https://github.com/servo/webrender?branch=0.64#9d354adf8955b1390dd56db89e6d5a9ea7880391" +source = "git+https://github.com/servo/webrender?branch=0.65#c0bcdd024adac1297ceb2f34a2de46731243c970" dependencies = [ "proc-macro2", "quote", @@ -4098,7 +4098,7 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pixels" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "euclid", "image 0.24.9", @@ -4163,12 +4163,11 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.19" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2288c0e17cc8d342c712bb43a257a80ebffce59cdb33d5000d8348f3ec02528b" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ "zerocopy", - "zerocopy-derive", ] [[package]] @@ -4198,7 +4197,7 @@ dependencies = [ [[package]] name = "profile" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "ipc-channel", "libc", @@ -4214,7 +4213,7 @@ dependencies = [ [[package]] name = "profile_traits" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "crossbeam-channel", "ipc-channel", @@ -4300,7 +4299,7 @@ dependencies = [ [[package]] name = "range" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "malloc_size_of", "malloc_size_of_derive", @@ -4567,9 +4566,9 @@ dependencies = [ [[package]] name = "scc" -version = "2.1.7" +version = "2.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a870e34715d5d59c8536040d4d4e7a41af44d527dc50237036ba4090db7996fc" +checksum = "8d777f59627453628a9a5be1ee8d948745b94b1dfc2d0c3099cbd9e08ab89e7c" dependencies = [ "sdd", ] @@ -4589,7 +4588,7 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "script" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "app_units", "arrayvec", @@ -4692,7 +4691,7 @@ dependencies = [ [[package]] name = "script_layout_interface" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "app_units", "atomic_refcell", @@ -4727,7 +4726,7 @@ dependencies = [ [[package]] name = "script_traits" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "background_hang_monitor_api", "base", @@ -4798,7 +4797,7 @@ checksum = "177258b64c0faaa9ffd3c65cd3262c2bc7e2588dbbd9c1641d0346145c1bbda8" [[package]] name = "selectors" version = "0.24.0" -source = "git+https://github.com/servo/stylo?branch=2024-07-16#ed09e046c8cc7654eb3a0c2e3ec789503f64ed74" +source = "git+https://github.com/servo/stylo?branch=2024-07-16#e7ea820c1aaee5a40f95552477c22b48b04c21b4" dependencies = [ "bitflags 2.6.0", "cssparser", @@ -5011,7 +5010,7 @@ dependencies = [ [[package]] name = "servo_allocator" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "libc", "tikv-jemalloc-sys", @@ -5022,7 +5021,7 @@ dependencies = [ [[package]] name = "servo_arc" version = "0.2.0" -source = "git+https://github.com/servo/stylo?branch=2024-07-16#ed09e046c8cc7654eb3a0c2e3ec789503f64ed74" +source = "git+https://github.com/servo/stylo?branch=2024-07-16#e7ea820c1aaee5a40f95552477c22b48b04c21b4" dependencies = [ "serde", "stable_deref_trait", @@ -5031,7 +5030,7 @@ dependencies = [ [[package]] name = "servo_atoms" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-07-16#ed09e046c8cc7654eb3a0c2e3ec789503f64ed74" +source = "git+https://github.com/servo/stylo?branch=2024-07-16#e7ea820c1aaee5a40f95552477c22b48b04c21b4" dependencies = [ "string_cache", "string_cache_codegen", @@ -5040,7 +5039,7 @@ dependencies = [ [[package]] name = "servo_config" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "dirs-next", "embedder_traits", @@ -5061,7 +5060,7 @@ dependencies = [ [[package]] name = "servo_config_plugins" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "itertools 0.13.0", "proc-macro2", @@ -5072,7 +5071,7 @@ dependencies = [ [[package]] name = "servo_geometry" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "app_units", "euclid", @@ -5084,7 +5083,7 @@ dependencies = [ [[package]] name = "servo_rand" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "lazy_static", "log", @@ -5097,7 +5096,7 @@ dependencies = [ [[package]] name = "servo_url" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "malloc_size_of", "malloc_size_of_derive", @@ -5169,7 +5168,7 @@ checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "size_of_test" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-07-16#ed09e046c8cc7654eb3a0c2e3ec789503f64ed74" +source = "git+https://github.com/servo/stylo?branch=2024-07-16#e7ea820c1aaee5a40f95552477c22b48b04c21b4" dependencies = [ "static_assertions", ] @@ -5299,7 +5298,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "static_prefs" version = "0.1.0" -source = "git+https://github.com/servo/stylo?branch=2024-07-16#ed09e046c8cc7654eb3a0c2e3ec789503f64ed74" +source = "git+https://github.com/servo/stylo?branch=2024-07-16#e7ea820c1aaee5a40f95552477c22b48b04c21b4" [[package]] name = "strck" @@ -5352,7 +5351,7 @@ dependencies = [ [[package]] name = "style" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-07-16#ed09e046c8cc7654eb3a0c2e3ec789503f64ed74" +source = "git+https://github.com/servo/stylo?branch=2024-07-16#e7ea820c1aaee5a40f95552477c22b48b04c21b4" dependencies = [ "app_units", "arrayvec", @@ -5411,7 +5410,7 @@ dependencies = [ [[package]] name = "style_config" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-07-16#ed09e046c8cc7654eb3a0c2e3ec789503f64ed74" +source = "git+https://github.com/servo/stylo?branch=2024-07-16#e7ea820c1aaee5a40f95552477c22b48b04c21b4" dependencies = [ "lazy_static", ] @@ -5419,7 +5418,7 @@ dependencies = [ [[package]] name = "style_derive" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-07-16#ed09e046c8cc7654eb3a0c2e3ec789503f64ed74" +source = "git+https://github.com/servo/stylo?branch=2024-07-16#e7ea820c1aaee5a40f95552477c22b48b04c21b4" dependencies = [ "darling", "derive_common", @@ -5432,7 +5431,7 @@ dependencies = [ [[package]] name = "style_traits" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-07-16#ed09e046c8cc7654eb3a0c2e3ec789503f64ed74" +source = "git+https://github.com/servo/stylo?branch=2024-07-16#e7ea820c1aaee5a40f95552477c22b48b04c21b4" dependencies = [ "app_units", "bitflags 2.6.0", @@ -5557,19 +5556,20 @@ dependencies = [ [[package]] name = "task_info" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "cc", ] [[package]] name = "tempfile" -version = "3.10.1" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53" dependencies = [ "cfg-if", "fastrand", + "once_cell", "rustix", "windows-sys 0.52.0", ] @@ -5740,7 +5740,7 @@ dependencies = [ [[package]] name = "to_shmem" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-07-16#ed09e046c8cc7654eb3a0c2e3ec789503f64ed74" +source = "git+https://github.com/servo/stylo?branch=2024-07-16#e7ea820c1aaee5a40f95552477c22b48b04c21b4" dependencies = [ "cssparser", "servo_arc", @@ -5753,7 +5753,7 @@ dependencies = [ [[package]] name = "to_shmem_derive" version = "0.0.1" -source = "git+https://github.com/servo/stylo?branch=2024-07-16#ed09e046c8cc7654eb3a0c2e3ec789503f64ed74" +source = "git+https://github.com/servo/stylo?branch=2024-07-16#e7ea820c1aaee5a40f95552477c22b48b04c21b4" dependencies = [ "darling", "derive_common", @@ -5896,9 +5896,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "ttf-parser" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8686b91785aff82828ed725225925b33b4fde44c4bb15876e5f7c832724c420a" +checksum = "5be21190ff5d38e8b4a2d3b6a3ae57f612cc39c96e83cedeaf7abc338a8bac4a" [[package]] name = "tungstenite" @@ -6422,7 +6422,7 @@ dependencies = [ [[package]] name = "webdriver_server" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "base", "base64", @@ -6450,7 +6450,7 @@ dependencies = [ [[package]] name = "webgpu" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "arrayvec", "base", @@ -6476,8 +6476,8 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webrender" -version = "0.64.0" -source = "git+https://github.com/servo/webrender?branch=0.64#9d354adf8955b1390dd56db89e6d5a9ea7880391" +version = "0.65.0" +source = "git+https://github.com/servo/webrender?branch=0.65#c0bcdd024adac1297ceb2f34a2de46731243c970" dependencies = [ "bincode", "bitflags 2.6.0", @@ -6511,8 +6511,8 @@ dependencies = [ [[package]] name = "webrender_api" -version = "0.64.0" -source = "git+https://github.com/servo/webrender?branch=0.64#9d354adf8955b1390dd56db89e6d5a9ea7880391" +version = "0.65.0" +source = "git+https://github.com/servo/webrender?branch=0.65#c0bcdd024adac1297ceb2f34a2de46731243c970" dependencies = [ "app_units", "bitflags 2.6.0", @@ -6531,7 +6531,7 @@ dependencies = [ [[package]] name = "webrender_build" version = "0.0.2" -source = "git+https://github.com/servo/webrender?branch=0.64#9d354adf8955b1390dd56db89e6d5a9ea7880391" +source = "git+https://github.com/servo/webrender?branch=0.65#c0bcdd024adac1297ceb2f34a2de46731243c970" dependencies = [ "bitflags 2.6.0", "lazy_static", @@ -6540,7 +6540,7 @@ dependencies = [ [[package]] name = "webrender_traits" version = "0.0.1" -source = "git+https://github.com/servo/servo.git?rev=5e59988#5e59988c87c40e84b0228021798455175699e824" +source = "git+https://github.com/servo/servo.git?rev=28430ba#28430bad0e7a4d4c11710d61fbaf1c598bffa87d" dependencies = [ "base", "crossbeam-channel", @@ -6693,9 +6693,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ "windows-sys 0.52.0", ] @@ -7063,7 +7063,7 @@ dependencies = [ [[package]] name = "wr_glyph_rasterizer" version = "0.1.0" -source = "git+https://github.com/servo/webrender?branch=0.64#9d354adf8955b1390dd56db89e6d5a9ea7880391" +source = "git+https://github.com/servo/webrender?branch=0.65#c0bcdd024adac1297ceb2f34a2de46731243c970" dependencies = [ "core-foundation", "core-graphics", @@ -7087,8 +7087,8 @@ dependencies = [ [[package]] name = "wr_malloc_size_of" -version = "0.0.2" -source = "git+https://github.com/servo/webrender?branch=0.64#9d354adf8955b1390dd56db89e6d5a9ea7880391" +version = "0.0.3" +source = "git+https://github.com/servo/webrender?branch=0.65#c0bcdd024adac1297ceb2f34a2de46731243c970" dependencies = [ "app_units", "euclid", @@ -7195,9 +7195,9 @@ checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] name = "xml-rs" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" +checksum = "539a77ee7c0de333dcc6da69b177380a0b81e0dacfa4f7344c465a36871ee601" [[package]] name = "xml5ever" diff --git a/Cargo.toml b/Cargo.toml index d91d6b59..58de82fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,36 +62,35 @@ surfman = { version = "0.9", features = ["chains", "sm-raw-window-handle-05"] } thiserror = "1.0" winit = { version = "0.29", features = ["rwh_05"] } # Servo repo crates -# libservo = { git = "https://github.com/servo/servo.git", rev = "5e59988", features = ["max_log_level", "native-bluetooth", "webdriver"] } -base = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -bluetooth = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -bluetooth_traits = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -canvas = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -compositing_traits = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -constellation = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -devtools = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -embedder_traits = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -fonts = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -layout_thread_2020 = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -media = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -net = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -profile = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -profile_traits = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -script = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -script_traits = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -servo_config = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -servo_geometry = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -servo_url = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -webdriver_server = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -webrender_traits = { git = "https://github.com/servo/servo.git", rev = "5e59988" } -webgpu = { git = "https://github.com/servo/servo.git", rev = "5e59988" } +base = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +bluetooth = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +bluetooth_traits = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +canvas = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +compositing_traits = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +constellation = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +devtools = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +embedder_traits = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +fonts = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +layout_thread_2020 = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +media = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +net = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +profile = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +profile_traits = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +script = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +script_traits = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +servo_config = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +servo_geometry = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +servo_url = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +webdriver_server = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +webrender_traits = { git = "https://github.com/servo/servo.git", rev = "28430ba" } +webgpu = { git = "https://github.com/servo/servo.git", rev = "28430ba" } # Servo org crates servo-media = { git = "https://github.com/servo/media" } servo-media-dummy = { git = "https://github.com/servo/media" } style = { git = "https://github.com/servo/stylo", branch = "2024-07-16", features = ["servo"] } style_traits = { git = "https://github.com/servo/stylo", branch = "2024-07-16", features = ["servo"] } -webrender = { git = "https://github.com/servo/webrender", branch = "0.64", features = ["capture"] } -webrender_api = { git = "https://github.com/servo/webrender", branch = "0.64" } +webrender = { git = "https://github.com/servo/webrender", branch = "0.65", features = ["capture"] } +webrender_api = { git = "https://github.com/servo/webrender", branch = "0.65" } webxr = { git = "https://github.com/servo/webxr", features = ["headless"] } # Packager feature cargo-packager-resource-resolver = { version = "0.1.1", features = [ From 465af4e6ef4ff149b029d6e1be0b669500924ee2 Mon Sep 17 00:00:00 2001 From: Wu Wayne Date: Tue, 6 Aug 2024 21:20:19 +0900 Subject: [PATCH 13/22] Create correct window spawning order --- src/compositor.rs | 9 +++++---- src/verso.rs | 46 ++++++++++++++++++++++++++++++++-------------- src/webview.rs | 14 ++++++++++---- src/window.rs | 30 +++++++++--------------------- 4 files changed, 56 insertions(+), 43 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index 27fb0460..b4a45218 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -109,7 +109,7 @@ pub struct IOCompositor { pub surfaces: HashMap>, /// The current window that Compositor is handling. - current_window: WindowId, + pub current_window: WindowId, /// Size of current viewport that Compositor is handling. viewport: DeviceIntSize, @@ -1131,12 +1131,13 @@ impl IOCompositor { debug!("{}: Setting frame tree for webview", frame_tree.pipeline.id); for window in windows.values_mut() { - // TODO: should only set to one window - window.set_webview( + if window.set_webview( frame_tree.pipeline.top_level_browsing_context_id, frame_tree.pipeline.id, self, - ); + ) { + break; + } } self.send_root_pipeline_display_list(); diff --git a/src/verso.rs b/src/verso.rs index 71a1c19a..12aa76db 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -1,10 +1,12 @@ use std::{ borrow::Cow, collections::HashMap, + path::PathBuf, sync::{atomic::Ordering, Arc}, }; use arboard::Clipboard; +use base::id::WebViewId; use bluetooth::BluetoothThreadFactory; use bluetooth_traits::BluetoothRequest; use canvas::{ @@ -33,6 +35,7 @@ use servo_config::{opts, pref}; use servo_url::ServoUrl; use style; use surfman::GLApi; +use units::DeviceIntRect; use webgpu; use webrender::{create_webrender_instance, ShaderPrecacheFlags, WebRenderOptions}; use webrender_api::*; @@ -46,6 +49,7 @@ use winit::{ use crate::{ compositor::{IOCompositor, InitialCompositorState, ShutdownState}, config::Config, + webview::WebView, window::Window, }; @@ -61,6 +65,7 @@ pub struct Verso { _js_engine_setup: Option, /// FIXME: It's None on wayland in Flatpak. Find a way to support this. clipboard: Option, + resource_dir: PathBuf, } impl Verso { @@ -359,7 +364,7 @@ impl Verso { ); // Send the constellation message to start Panel UI - // NB: Should become a window method + // TODO: Should become a window method let panel_id = window.panel.as_ref().unwrap().webview_id; let path = resource_dir.join("panel.html"); let url = ServoUrl::from_file_path(path.to_str().unwrap()).unwrap(); @@ -379,6 +384,7 @@ impl Verso { embedder_receiver, _js_engine_setup: js_engine_setup, clipboard: Clipboard::new().ok(), + resource_dir, }; verso.setup_logging(); @@ -390,12 +396,8 @@ impl Verso { /// - Handle Winit's event, updating Compositor and sending messages to Constellation. /// - Handle Servo's messages and updating Compositor again. pub fn run(&mut self, event: Event<()>, evl: &EventLoopWindowTarget<()>) { - if self.windows.len() == 1 { - let window = Window::new_with_compositor(evl, self.compositor.as_mut().unwrap()); - self.windows.insert(window.id(), window); - } self.handle_winit_event(event); - self.handle_servo_messages(); + self.handle_servo_messages(evl); if self.windows.is_empty() { self.compositor .as_mut() @@ -436,7 +438,7 @@ impl Verso { } /// Handle message came from Servo. - fn handle_servo_messages(&mut self) { + fn handle_servo_messages(&mut self, evl: &EventLoopWindowTarget<()>) { let mut shutdown = false; if let Some(compositor) = &mut self.compositor { // Handle Compositor's messages first @@ -453,12 +455,27 @@ impl Verso { if let Some(id) = webview_id { for window in self.windows.values_mut() { if window.has_webview(id) { - window.handle_servo_message( + if window.handle_servo_message( id, msg, &self.constellation_sender, self.clipboard.as_mut(), - ); + ) { + let mut window = + Window::new_with_compositor(evl, compositor); + let panel_id = WebViewId::new(); + let path = self.resource_dir.join("panel.html"); + let url = + ServoUrl::from_file_path(path.to_str().unwrap()) + .unwrap(); + send_to_constellation( + &self.constellation_sender, + ConstellationMsg::NewWebView(url, panel_id), + ); + let rect = DeviceIntRect::from_size(window.size()); + window.panel = Some(WebView::new(panel_id, rect)); + self.windows.insert(window.id(), window); + } break; } } @@ -467,11 +484,12 @@ impl Verso { log::trace!("Verso Window is handling Embedder message: {msg:?}"); match msg { EmbedderMsg::SetCursor(cursor) => { - // TODO: Should set to the right window - self.windows - .values() - .last() - .map(|w| w.set_cursor_icon(cursor)); + // TODO: This should move to compositor + if let Some(window) = + self.windows.get(&compositor.current_window) + { + window.set_cursor_icon(cursor); + } } EmbedderMsg::Shutdown | EmbedderMsg::ReadyToPresent(_) => {} e => { diff --git a/src/webview.rs b/src/webview.rs index ffb34109..430c9dbf 100644 --- a/src/webview.rs +++ b/src/webview.rs @@ -119,14 +119,14 @@ impl Window { } } - /// Handle servo messages with main panel. + /// Handle servo messages with main panel. Return true it requests a new window. pub fn handle_servo_messages_with_panel( &mut self, panel_id: WebViewId, message: EmbedderMsg, sender: &Sender, clipboard: Option<&mut Clipboard>, - ) { + ) -> bool { log::trace!("Verso Panel {panel_id:?} is handling Embedder message: {message:?}",); match message { EmbedderMsg::LoadStart @@ -142,6 +142,10 @@ impl Window { // let demo_url = ServoUrl::parse("https://demo.versotile.org").unwrap(); let demo_url = ServoUrl::parse("https://keyboard-test.space").unwrap(); let demo_id = WebViewId::new(); + let size = self.size(); + let mut rect = DeviceIntRect::from_size(size); + rect.min.y = rect.max.y.min(76); + self.webview = Some(WebView::new(demo_id, rect)); send_to_constellation(sender, ConstellationMsg::NewWebView(demo_url, demo_id)); } EmbedderMsg::AllowNavigationRequest(id, _url) => { @@ -154,6 +158,7 @@ impl Window { EmbedderMsg::Prompt(definition, _origin) => { match definition { PromptDefinition::Input(msg, _, prompt_sender) => { + let _ = prompt_sender.send(None); if let Some(webview) = &self.webview { let id = webview.webview_id; @@ -185,7 +190,8 @@ impl Window { // TODO Set EmbedderMsg::Status to None } "REFRESH" => { - send_to_constellation(sender, ConstellationMsg::Reload(id)); + // send_to_constellation(sender, ConstellationMsg::Reload(id)); + return true; } "MINIMIZE" => { self.window.set_minimized(true); @@ -200,7 +206,6 @@ impl Window { } } } - let _ = prompt_sender.send(None); } _ => log::warn!("Verso Panel isn't supporting this prompt yet"), } @@ -229,5 +234,6 @@ impl Window { log::warn!("Verso Panel isn't supporting this message yet: {e:?}") } } + false } } diff --git a/src/window.rs b/src/window.rs index e99f0bf9..de2dc737 100644 --- a/src/window.rs +++ b/src/window.rs @@ -246,14 +246,14 @@ impl Window { false } - /// Handle servo messages. + /// Handle servo messages. Return true if it requests a new window pub fn handle_servo_message( &mut self, webview_id: WebViewId, message: EmbedderMsg, sender: &Sender, clipboard: Option<&mut Clipboard>, - ) { + ) -> bool { // // Handle message in Verso Panel if self .panel @@ -261,11 +261,12 @@ impl Window { .filter(|p| p.webview_id == webview_id) .is_some() { - self.handle_servo_messages_with_panel(webview_id, message, sender, clipboard); + self.handle_servo_messages_with_panel(webview_id, message, sender, clipboard) } // Handle message in Verso WebView else { self.handle_servo_messages_with_webview(webview_id, message, sender, clipboard); + false } } @@ -331,13 +332,13 @@ impl Window { /// Set the webview to this window. It won't be updated if the existing webview and pipeline ID /// are the same. This will also set the painting order of the compositor and tell - /// constellation to focus the webview. + /// constellation to focus the webview. Return true if the webview is set to this window. pub fn set_webview( &mut self, webview_id: WebViewId, pipeline_id: PipelineId, compositor: &mut IOCompositor, - ) { + ) -> bool { if let Some(panel) = &mut self.panel { if panel.webview_id == webview_id { if panel.pipeline_id != Some(pipeline_id) { @@ -348,10 +349,7 @@ impl Window { webview.pipeline_id = Some(pipeline_id); } } else { - let size = self.size(); - let mut rect = DeviceIntRect::from_size(size); - rect.min.y = rect.max.y.min(76); - self.webview = Some(WebView::new(webview_id, rect)); + return false; } // Ignore the return boolean since the webview will present eventually. @@ -361,19 +359,9 @@ impl Window { &compositor.constellation_chan, ConstellationMsg::FocusWebView(webview_id), ); - } else { - let size = self.size(); - let rect = DeviceIntRect::from_size(size); - self.panel = Some(WebView::new(webview_id, rect)); - - // Ignore the return boolean since the webview will present eventually. - self.resize(self.size(), compositor); - - send_to_constellation( - &compositor.constellation_chan, - ConstellationMsg::FocusWebView(webview_id), - ); + return true; } + false } /// Remove the webview in this window by provided webview ID. If this is the panel, it will From 045490b91e2be3cb7d42bfee71d27c13a407d737 Mon Sep 17 00:00:00 2001 From: Wu Wayne Date: Wed, 7 Aug 2024 11:05:23 +0900 Subject: [PATCH 14/22] Create separate display list for different surface --- src/compositor.rs | 38 ++++++++++++++++++++++++++------------ src/verso.rs | 3 +-- src/webview.rs | 15 ++++----------- src/window.rs | 45 +-------------------------------------------- 4 files changed, 32 insertions(+), 69 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index b4a45218..a8176693 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -45,6 +45,7 @@ use webrender_traits::{ use winit::window::WindowId; use crate::touch::{TouchAction, TouchHandler}; +use crate::verso::send_to_constellation; use crate::webview::WebView; use crate::window::Window; @@ -126,6 +127,9 @@ pub struct IOCompositor { /// The port on which we receive messages. port: CompositorReceiver, + /// Tracks each webview and its current pipeline + webviews: HashMap, + /// Tracks details about each active pipeline that the compositor knows about. pipeline_details: HashMap, @@ -175,7 +179,7 @@ pub struct IOCompositor { webrender: webrender::Renderer, /// The webrender interface, if enabled. - webrender_api: RenderApi, + pub webrender_api: RenderApi, /// The surfman instance that webrender targets pub rendering_context: RenderingContext, @@ -356,6 +360,7 @@ impl IOCompositor { current_window, viewport, port: state.receiver, + webviews: HashMap::new(), pipeline_details: HashMap::new(), scale_factor, composition_request: CompositionRequest::NoCompositingNecessary, @@ -1044,7 +1049,7 @@ impl IOCompositor { // Every display list needs a pipeline, but we'd like to choose one that is unlikely // to conflict with our content pipelines, which start at (1, 1). (0, 0) is WebRender's // dummy pipeline, so we choose (0, 1). - let root_pipeline = WebRenderPipelineId(0, 1); + let root_pipeline = WebRenderPipelineId(u64::from(self.current_window) as u32, 1); transaction.set_root_pipeline(root_pipeline); let mut builder = webrender::api::DisplayListBuilder::new(root_pipeline); @@ -1072,7 +1077,7 @@ impl IOCompositor { let root_clip_id = builder.define_clip_rect(zoom_reference_frame, scaled_viewport_rect); let clip_chain_id = builder.define_clip_chain(None, [root_clip_id]); for webview in &self.painting_order { - if let Some(pipeline_id) = webview.pipeline_id { + if let Some(pipeline_id) = self.webviews.get(&webview.webview_id) { let scaled_webview_rect = webview.rect.to_f32() / zoom_factor; builder.push_iframe( LayoutRect::from_untyped(&scaled_webview_rect.to_untyped()), @@ -1130,16 +1135,24 @@ impl IOCompositor { ) { debug!("{}: Setting frame tree for webview", frame_tree.pipeline.id); + let pipeline_id = frame_tree.pipeline.id; + let webview_id = frame_tree.pipeline.top_level_browsing_context_id; + if let Some(old_pipeline) = self.webviews.insert(webview_id, pipeline_id) { + debug!("{webview_id}'s pipeline has changed from {old_pipeline} to {pipeline_id}"); + } + + // Resize window and focus webview if the window has this webview for window in windows.values_mut() { - if window.set_webview( - frame_tree.pipeline.top_level_browsing_context_id, - frame_tree.pipeline.id, - self, - ) { + if window.has_webview(webview_id) { + window.resize(window.size(), self); + + send_to_constellation( + &self.constellation_chan, + ConstellationMsg::FocusWebView(webview_id), + ); break; } } - self.send_root_pipeline_display_list(); self.create_or_update_pipeline_details_with_frame_tree(frame_tree, None); self.reset_scroll_tree_for_unattached_pipelines(frame_tree); @@ -1160,7 +1173,7 @@ impl IOCompositor { if let Some(webview) = webview { self.set_painting_order(window.painting_order()); self.send_root_pipeline_display_list(); - if let Some(pipeline_id) = webview.pipeline_id { + if let Some(pipeline_id) = self.webviews.remove(&webview.webview_id) { self.remove_pipeline_details_recursively(pipeline_id); } @@ -1279,9 +1292,10 @@ impl IOCompositor { new_surface }); self.current_window = window.id(); - // self.webrender_document = window.document_id; self.scale_factor = Scale::new(window.scale_factor() as f32); + self.painting_order.clear(); window.resize(window.size(), self); + self.send_root_pipeline_display_list(); } } } @@ -1994,7 +2008,7 @@ impl IOCompositor { // TODO(gw): Take notice of any errors the renderer returns! self.webrender // TODO to untyped? - .render(self.viewport, 0 /* buffer_age */) + .render(self.viewport, 0) .ok(); }, ); diff --git a/src/verso.rs b/src/verso.rs index 12aa76db..28ac9eb8 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -88,7 +88,7 @@ impl Verso { // Initialize configurations and Verso window let resource_dir = config.resource_dir.clone(); config.init(); - let (mut window, rendering_context) = Window::new(evl); + let (window, rendering_context) = Window::new(evl); let event_loop_waker = Box::new(Waker(proxy)); let opts = opts::get(); @@ -198,7 +198,6 @@ impl Verso { let webrender_api = webrender_api_sender.create_api(); let webrender_document = webrender_api.add_document_with_id(window.size(), u64::from(window.id()) as u32); - window.document_id = webrender_document; // Initialize js engine if it's single process mode let js_engine_setup = if !opts.multiprocess { diff --git a/src/webview.rs b/src/webview.rs index 430c9dbf..38696d3a 100644 --- a/src/webview.rs +++ b/src/webview.rs @@ -1,5 +1,5 @@ use arboard::Clipboard; -use base::id::{PipelineId, PipelineNamespace, PipelineNamespaceId, WebViewId}; +use base::id::{PipelineNamespace, PipelineNamespaceId, WebViewId}; use compositing_traits::ConstellationMsg; use crossbeam_channel::Sender; use embedder_traits::{CompositorEventVariant, EmbedderMsg, PromptDefinition}; @@ -14,8 +14,6 @@ use crate::{verso::send_to_constellation, window::Window}; pub struct WebView { /// Webview ID pub webview_id: WebViewId, - /// Pipeline ID for webrender usage. - pub pipeline_id: Option, /// The position and size of the webview. pub rect: DeviceIntRect, } @@ -23,11 +21,7 @@ pub struct WebView { impl WebView { /// Create a web view from Winit window. pub fn new(webview_id: WebViewId, rect: DeviceIntRect) -> Self { - Self { - webview_id, - pipeline_id: None, - rect, - } + Self { webview_id, rect } } /// Create a panel view from Winit window. A panel is a special web view that focus on controlling states around window. @@ -47,7 +41,6 @@ impl WebView { let id = WebViewId::new(); Self { webview_id: id, - pipeline_id: None, rect, } } @@ -139,8 +132,8 @@ impl Window { } EmbedderMsg::LoadComplete => { self.window.request_redraw(); - // let demo_url = ServoUrl::parse("https://demo.versotile.org").unwrap(); - let demo_url = ServoUrl::parse("https://keyboard-test.space").unwrap(); + let demo_url = ServoUrl::parse("https://servo.org").unwrap(); + // let demo_url = ServoUrl::parse("https://keyboard-test.space").unwrap(); let demo_id = WebViewId::new(); let size = self.size(); let mut rect = DeviceIntRect::from_size(size); diff --git a/src/window.rs b/src/window.rs index de2dc737..25562b0e 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,6 +1,6 @@ use std::cell::Cell; -use base::id::{PipelineId, WebViewId}; +use base::id::WebViewId; use compositing_traits::ConstellationMsg; use crossbeam_channel::Sender; use embedder_traits::{Cursor, EmbedderMsg}; @@ -9,7 +9,6 @@ use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; use script_traits::{TouchEventType, WheelDelta, WheelMode}; use surfman::Connection; use surfman::SurfaceType; -use webrender_api::DocumentId; use webrender_api::{ units::{ DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePixel, DevicePoint, LayoutVector2D, @@ -46,7 +45,6 @@ pub struct Window { mouse_position: Cell>, /// Modifiers state of the keyboard. modifiers_state: Cell, - pub(crate) document_id: DocumentId, } impl Window { @@ -87,7 +85,6 @@ impl Window { webview: None, mouse_position: Cell::new(PhysicalPosition::default()), modifiers_state: Cell::new(ModifiersState::default()), - document_id: DocumentId::INVALID, }, rendering_context, ) @@ -114,18 +111,12 @@ impl Window { .create_surface(surface_type) .ok(); compositor.surfaces.insert(window.id(), surface); - // let window_size = window.inner_size(); - // let window_size = Size2D::new(window_size.width as i32, window_size.height as i32); - // let document_id = compositor - // .webrender_api - // .add_document_with_id(window_size, u64::from(window.id()) as u32); Self { window, panel: None, webview: None, mouse_position: Cell::new(PhysicalPosition::default()), modifiers_state: Cell::new(ModifiersState::default()), - document_id: DocumentId::INVALID, } } @@ -330,40 +321,6 @@ impl Window { } } - /// Set the webview to this window. It won't be updated if the existing webview and pipeline ID - /// are the same. This will also set the painting order of the compositor and tell - /// constellation to focus the webview. Return true if the webview is set to this window. - pub fn set_webview( - &mut self, - webview_id: WebViewId, - pipeline_id: PipelineId, - compositor: &mut IOCompositor, - ) -> bool { - if let Some(panel) = &mut self.panel { - if panel.webview_id == webview_id { - if panel.pipeline_id != Some(pipeline_id) { - panel.pipeline_id = Some(pipeline_id); - } - } else if let Some(webview) = &mut self.webview { - if webview.webview_id == webview_id && webview.pipeline_id != Some(pipeline_id) { - webview.pipeline_id = Some(pipeline_id); - } - } else { - return false; - } - - // Ignore the return boolean since the webview will present eventually. - self.resize(self.size(), compositor); - - send_to_constellation( - &compositor.constellation_chan, - ConstellationMsg::FocusWebView(webview_id), - ); - return true; - } - false - } - /// Remove the webview in this window by provided webview ID. If this is the panel, it will /// shut down the compositor and then close whole application. pub fn remove_webview( From cea58a1312bbc926eef3572ecbb2ab39b6753352 Mon Sep 17 00:00:00 2001 From: Wu Wayne Date: Wed, 7 Aug 2024 13:32:04 +0900 Subject: [PATCH 15/22] Fix flashing --- src/compositor.rs | 10 ++++++++-- src/verso.rs | 2 +- src/webview.rs | 2 +- src/window.rs | 15 +++++++++++++-- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index a8176693..e641045a 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -1284,9 +1284,14 @@ impl IOCompositor { } /// Change the current window of the compositor should display. - pub fn update_current_window(&mut self, window: &mut Window) { + pub fn swap_current_window(&mut self, window: &mut Window) { if window.id() != self.current_window { if let Some(Some(new_surface)) = self.surfaces.insert(window.id(), None) { + // Present current surface first + if let Err(err) = self.rendering_context.present() { + warn!("Failed to present surface: {:?}", err); + } + // Swap the surface self.rendering_context.with_front_buffer(|_, old_surface| { self.surfaces.insert(self.current_window, Some(old_surface)); new_surface @@ -1294,7 +1299,8 @@ impl IOCompositor { self.current_window = window.id(); self.scale_factor = Scale::new(window.scale_factor() as f32); self.painting_order.clear(); - window.resize(window.size(), self); + self.viewport = window.size(); + self.set_painting_order(window.painting_order()); self.send_root_pipeline_display_list(); } } diff --git a/src/verso.rs b/src/verso.rs index 28ac9eb8..fa70750b 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -167,7 +167,7 @@ impl Verso { debug_flags.set(DebugFlags::PROFILER_DBG, opts.debug.webrender_stats); let render_notifier = Box::new(RenderNotifier::new(compositor_sender.clone())); - let clear_color = ColorF::new(0., 1., 0., 0.); + let clear_color = ColorF::new(0., 0., 0., 0.); create_webrender_instance( webrender_gl.clone(), render_notifier, diff --git a/src/webview.rs b/src/webview.rs index 38696d3a..260944c5 100644 --- a/src/webview.rs +++ b/src/webview.rs @@ -132,7 +132,7 @@ impl Window { } EmbedderMsg::LoadComplete => { self.window.request_redraw(); - let demo_url = ServoUrl::parse("https://servo.org").unwrap(); + let demo_url = ServoUrl::parse("https://wusyong.github.io/").unwrap(); // let demo_url = ServoUrl::parse("https://keyboard-test.space").unwrap(); let demo_id = WebViewId::new(); let size = self.size(); diff --git a/src/window.rs b/src/window.rs index 25562b0e..acadb73f 100644 --- a/src/window.rs +++ b/src/window.rs @@ -51,6 +51,8 @@ impl Window { /// Create a Verso window from Winit window and return the rendering context. pub fn new(evl: &EventLoopWindowTarget<()>) -> (Self, RenderingContext) { let window = WindowBuilder::new() + .with_transparent(true) + .with_decorations(false) .build(evl) .expect("Failed to create window."); #[cfg(macos)] @@ -96,8 +98,17 @@ impl Window { compositor: &mut IOCompositor, ) -> Self { let window = WindowBuilder::new() + .with_transparent(true) + .with_decorations(false) .build(evl) .expect("Failed to create window."); + #[cfg(macos)] + unsafe { + let rwh = window.raw_window_handle(); + if let RawWindowHandle::AppKit(AppKitWindowHandle { ns_window, .. }) = rwh { + decorate_window(ns_window as *mut Object, LogicalPosition::new(8.0, 40.0)); + } + } let window_size = window.inner_size(); let window_size = Size2D::new(window_size.width as i32, window_size.height as i32); let native_widget = compositor @@ -130,7 +141,7 @@ impl Window { match event { WindowEvent::Focused(focused) => { if *focused { - compositor.update_current_window(self); + compositor.swap_current_window(self); } } WindowEvent::Resized(size) => { @@ -141,7 +152,7 @@ impl Window { compositor.on_scale_factor_event(*scale_factor as f32); } WindowEvent::CursorMoved { position, .. } => { - compositor.update_current_window(self); + compositor.swap_current_window(self); let cursor: DevicePoint = DevicePoint::new(position.x as f32, position.y as f32); self.mouse_position.set(*position); compositor.on_mouse_window_move_event_class(cursor); From c3f0211a9d2b69aaadd914060ffbe1bfaffcd1ac Mon Sep 17 00:00:00 2001 From: Wu Yuwei Date: Thu, 8 Aug 2024 01:06:35 +0900 Subject: [PATCH 16/22] Improve set_painting_order safety --- src/compositor.rs | 21 +++++++++++++-------- src/webview.rs | 3 +-- src/window.rs | 10 +++++----- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index e641045a..db5c4a3c 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -1171,8 +1171,7 @@ impl IOCompositor { let (webview, close_window) = window.remove_webview(top_level_browsing_context_id, self); if let Some(webview) = webview { - self.set_painting_order(window.painting_order()); - self.send_root_pipeline_display_list(); + self.set_painting_order(window); if let Some(pipeline_id) = self.webviews.remove(&webview.webview_id) { self.remove_pipeline_details_recursively(pipeline_id); } @@ -1198,7 +1197,6 @@ impl IOCompositor { rect: DeviceIntRect, ) { self.send_window_size_message_for_top_level_browser_context(rect, webview_id); - self.send_root_pipeline_display_list(); } fn send_window_size_message_for_top_level_browser_context( @@ -1300,8 +1298,7 @@ impl IOCompositor { self.scale_factor = Scale::new(window.scale_factor() as f32); self.painting_order.clear(); self.viewport = window.size(); - self.set_painting_order(window.painting_order()); - self.send_root_pipeline_display_list(); + self.set_painting_order(window); } } } @@ -1319,7 +1316,6 @@ impl IOCompositor { transaction.set_document_view(DeviceIntRect::from_size(self.viewport)); self.webrender_api .send_transaction(self.webrender_document, transaction); - self.update_after_zoom_or_hidpi_change(); self.composite_if_necessary(CompositingReason::Resize); true } @@ -2214,8 +2210,17 @@ impl IOCompositor { } /// Update the painting order of the compositor. - pub fn set_painting_order(&mut self, painting_order: Vec) { - self.painting_order = painting_order; + pub fn set_painting_order(&mut self, window: &Window) { + if self.current_window == window.id() { + let painting_order = window.painting_order(); + self.painting_order = painting_order; + self.send_root_pipeline_display_list(); + } else { + warn!( + "Failed to set painting order due to {:?} is not the current window", + window.id() + ); + } } } diff --git a/src/webview.rs b/src/webview.rs index 260944c5..7f918c41 100644 --- a/src/webview.rs +++ b/src/webview.rs @@ -132,8 +132,7 @@ impl Window { } EmbedderMsg::LoadComplete => { self.window.request_redraw(); - let demo_url = ServoUrl::parse("https://wusyong.github.io/").unwrap(); - // let demo_url = ServoUrl::parse("https://keyboard-test.space").unwrap(); + let demo_url = ServoUrl::parse("https://example.com").unwrap(); let demo_id = WebViewId::new(); let size = self.size(); let mut rect = DeviceIntRect::from_size(size); diff --git a/src/window.rs b/src/window.rs index acadb73f..f9e3120c 100644 --- a/src/window.rs +++ b/src/window.rs @@ -51,8 +51,8 @@ impl Window { /// Create a Verso window from Winit window and return the rendering context. pub fn new(evl: &EventLoopWindowTarget<()>) -> (Self, RenderingContext) { let window = WindowBuilder::new() - .with_transparent(true) - .with_decorations(false) + // .with_transparent(true) + // .with_decorations(false) .build(evl) .expect("Failed to create window."); #[cfg(macos)] @@ -98,8 +98,8 @@ impl Window { compositor: &mut IOCompositor, ) -> Self { let window = WindowBuilder::new() - .with_transparent(true) - .with_decorations(false) + // .with_transparent(true) + // .with_decorations(false) .build(evl) .expect("Failed to create window."); #[cfg(macos)] @@ -299,7 +299,7 @@ impl Window { compositor.on_resize_webview_event(w.webview_id, rect); } - compositor.set_painting_order(self.painting_order()); + compositor.set_painting_order(self); need_resize } From 33c9b996a28b32ae8ff24f455d86da55e8246ec1 Mon Sep 17 00:00:00 2001 From: Wu Yu Wei Date: Thu, 8 Aug 2024 13:38:50 +0900 Subject: [PATCH 17/22] Improve webview creation flow --- src/compositor.rs | 51 ++++++++++++++++++++++++++--------------------- src/verso.rs | 1 + src/webview.rs | 21 ++++++++++++++----- src/window.rs | 9 +++++++-- 4 files changed, 52 insertions(+), 30 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index db5c4a3c..45407563 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -45,7 +45,6 @@ use webrender_traits::{ use winit::window::WindowId; use crate::touch::{TouchAction, TouchHandler}; -use crate::verso::send_to_constellation; use crate::webview::WebView; use crate::window::Window; @@ -128,7 +127,7 @@ pub struct IOCompositor { port: CompositorReceiver, /// Tracks each webview and its current pipeline - webviews: HashMap, + webviews: HashMap, /// Tracks details about each active pipeline that the compositor knows about. pipeline_details: HashMap, @@ -515,7 +514,7 @@ impl IOCompositor { } CompositorMsg::CreateOrUpdateWebView(frame_tree) => { - self.create_or_update_webview(&frame_tree, windows); + self.create_or_update_webview(&frame_tree); self.send_scroll_positions_to_layout_for_pipeline(&frame_tree.pipeline.id); } @@ -1077,7 +1076,7 @@ impl IOCompositor { let root_clip_id = builder.define_clip_rect(zoom_reference_frame, scaled_viewport_rect); let clip_chain_id = builder.define_clip_chain(None, [root_clip_id]); for webview in &self.painting_order { - if let Some(pipeline_id) = self.webviews.get(&webview.webview_id) { + if let Some((pipeline_id, true)) = self.webviews.get(&webview.webview_id) { let scaled_webview_rect = webview.rect.to_f32() / zoom_factor; builder.push_iframe( LayoutRect::from_untyped(&scaled_webview_rect.to_untyped()), @@ -1128,31 +1127,37 @@ impl IOCompositor { } } - fn create_or_update_webview( - &mut self, - frame_tree: &SendableFrameTree, - windows: &mut HashMap, - ) { + /// Set the webview of the compositor to completely loaded, and hence it could add to display + /// list. + pub fn set_webview_loaded(&mut self, webview_id: &TopLevelBrowsingContextId) { + if let Some((_, loaded)) = self.webviews.get_mut(webview_id) { + *loaded = true; + } else { + warn!("The compositor doesn't have {webview_id} to set its loaded state"); + } + } + + fn create_or_update_webview(&mut self, frame_tree: &SendableFrameTree) { debug!("{}: Setting frame tree for webview", frame_tree.pipeline.id); let pipeline_id = frame_tree.pipeline.id; let webview_id = frame_tree.pipeline.top_level_browsing_context_id; - if let Some(old_pipeline) = self.webviews.insert(webview_id, pipeline_id) { + if let Some((old_pipeline, _)) = self.webviews.insert(webview_id, (pipeline_id, false)) { debug!("{webview_id}'s pipeline has changed from {old_pipeline} to {pipeline_id}"); } - // Resize window and focus webview if the window has this webview - for window in windows.values_mut() { - if window.has_webview(webview_id) { - window.resize(window.size(), self); - - send_to_constellation( - &self.constellation_chan, - ConstellationMsg::FocusWebView(webview_id), - ); - break; - } - } + // // Resize window and focus webview if the window has this webview + // for window in windows.values_mut() { + // if window.has_webview(webview_id) { + // window.resize(window.size(), self); + // + // send_to_constellation( + // &self.constellation_chan, + // ConstellationMsg::FocusWebView(webview_id), + // ); + // break; + // } + // } self.send_root_pipeline_display_list(); self.create_or_update_pipeline_details_with_frame_tree(frame_tree, None); self.reset_scroll_tree_for_unattached_pipelines(frame_tree); @@ -1172,7 +1177,7 @@ impl IOCompositor { window.remove_webview(top_level_browsing_context_id, self); if let Some(webview) = webview { self.set_painting_order(window); - if let Some(pipeline_id) = self.webviews.remove(&webview.webview_id) { + if let Some((pipeline_id, _)) = self.webviews.remove(&webview.webview_id) { self.remove_pipeline_details_recursively(pipeline_id); } diff --git a/src/verso.rs b/src/verso.rs index fa70750b..ba80b6c8 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -459,6 +459,7 @@ impl Verso { msg, &self.constellation_sender, self.clipboard.as_mut(), + compositor, ) { let mut window = Window::new_with_compositor(evl, compositor); diff --git a/src/webview.rs b/src/webview.rs index 7f918c41..b30d4149 100644 --- a/src/webview.rs +++ b/src/webview.rs @@ -7,7 +7,7 @@ use script_traits::TraversalDirection; use servo_url::ServoUrl; use webrender_api::units::DeviceIntRect; -use crate::{verso::send_to_constellation, window::Window}; +use crate::{compositor::IOCompositor, verso::send_to_constellation, window::Window}; /// A web view is an area to display web browsing context. It's what user will treat as a "web page". #[derive(Debug, Clone)] @@ -54,19 +54,24 @@ impl Window { message: EmbedderMsg, sender: &Sender, clipboard: Option<&mut Clipboard>, + compositor: &mut IOCompositor, ) { log::trace!("Verso WebView {webview_id:?} is handling Embedder message: {message:?}",); match message { EmbedderMsg::LoadStart | EmbedderMsg::HeadParsed | EmbedderMsg::WebViewOpened(_) - | EmbedderMsg::WebViewClosed(_) - | EmbedderMsg::WebViewFocused(_) => { + | EmbedderMsg::WebViewClosed(_) => { // Most WebView messages are ignored because it's done by compositor. log::trace!("Verso WebView {webview_id:?} ignores this message: {message:?}") } + EmbedderMsg::WebViewFocused(w) => { + compositor.set_webview_loaded(&w); + compositor.set_painting_order(self); + } EmbedderMsg::LoadComplete => { self.window.request_redraw(); + send_to_constellation(sender, ConstellationMsg::FocusWebView(webview_id)); } EmbedderMsg::AllowNavigationRequest(id, _url) => { // TODO should provide a API for users to check url @@ -119,19 +124,25 @@ impl Window { message: EmbedderMsg, sender: &Sender, clipboard: Option<&mut Clipboard>, + compositor: &mut IOCompositor, ) -> bool { log::trace!("Verso Panel {panel_id:?} is handling Embedder message: {message:?}",); match message { EmbedderMsg::LoadStart | EmbedderMsg::HeadParsed | EmbedderMsg::WebViewOpened(_) - | EmbedderMsg::WebViewClosed(_) - | EmbedderMsg::WebViewFocused(_) => { + | EmbedderMsg::WebViewClosed(_) => { // Most WebView messages are ignored because it's done by compositor. log::trace!("Verso Panel ignores this message: {message:?}") } + EmbedderMsg::WebViewFocused(w) => { + compositor.set_webview_loaded(&w); + compositor.set_painting_order(self); + } EmbedderMsg::LoadComplete => { self.window.request_redraw(); + send_to_constellation(sender, ConstellationMsg::FocusWebView(panel_id)); + let demo_url = ServoUrl::parse("https://example.com").unwrap(); let demo_id = WebViewId::new(); let size = self.size(); diff --git a/src/window.rs b/src/window.rs index f9e3120c..726f07c1 100644 --- a/src/window.rs +++ b/src/window.rs @@ -255,6 +255,7 @@ impl Window { message: EmbedderMsg, sender: &Sender, clipboard: Option<&mut Clipboard>, + compositor: &mut IOCompositor, ) -> bool { // // Handle message in Verso Panel if self @@ -263,11 +264,15 @@ impl Window { .filter(|p| p.webview_id == webview_id) .is_some() { - self.handle_servo_messages_with_panel(webview_id, message, sender, clipboard) + self.handle_servo_messages_with_panel( + webview_id, message, sender, clipboard, compositor, + ) } // Handle message in Verso WebView else { - self.handle_servo_messages_with_webview(webview_id, message, sender, clipboard); + self.handle_servo_messages_with_webview( + webview_id, message, sender, clipboard, compositor, + ); false } } From 5ae8d6594195a89c760898bca1dde0a0b331791d Mon Sep 17 00:00:00 2001 From: Wu Yuwei Date: Thu, 8 Aug 2024 14:25:33 +0900 Subject: [PATCH 18/22] Update unsupported log to trace --- src/verso.rs | 4 ++-- src/webview.rs | 8 ++++---- src/window.rs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/verso.rs b/src/verso.rs index ba80b6c8..c1cd3614 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -432,7 +432,7 @@ impl Verso { } } } - e => log::warn!("Verso isn't supporting this event yet: {e:?}"), + e => log::trace!("Verso isn't supporting this event yet: {e:?}"), } } @@ -493,7 +493,7 @@ impl Verso { } EmbedderMsg::Shutdown | EmbedderMsg::ReadyToPresent(_) => {} e => { - log::warn!("Verso Window isn't supporting handling this message yet: {e:?}") + log::trace!("Verso Window isn't supporting handling this message yet: {e:?}") } } } diff --git a/src/webview.rs b/src/webview.rs index b30d4149..a78e5932 100644 --- a/src/webview.rs +++ b/src/webview.rs @@ -112,7 +112,7 @@ impl Window { } } e => { - log::warn!("Verso WebView isn't supporting this message yet: {e:?}") + log::trace!("Verso WebView isn't supporting this message yet: {e:?}") } } } @@ -203,14 +203,14 @@ impl Window { let is_maximized = self.window.is_maximized(); self.window.set_maximized(!is_maximized); } - e => log::warn!( + e => log::trace!( "Verso Panel isn't supporting this prompt message yet: {e}" ), } } } } - _ => log::warn!("Verso Panel isn't supporting this prompt yet"), + _ => log::trace!("Verso Panel isn't supporting this prompt yet"), } } EmbedderMsg::GetClipboardContents(sender) => { @@ -234,7 +234,7 @@ impl Window { }); } e => { - log::warn!("Verso Panel isn't supporting this message yet: {e:?}") + log::trace!("Verso Panel isn't supporting this message yet: {e:?}") } } false diff --git a/src/window.rs b/src/window.rs index 726f07c1..59ab6eed 100644 --- a/src/window.rs +++ b/src/window.rs @@ -163,7 +163,7 @@ impl Window { winit::event::MouseButton::Right => script_traits::MouseButton::Right, winit::event::MouseButton::Middle => script_traits::MouseButton::Middle, _ => { - log::warn!( + log::trace!( "Verso Window isn't supporting this mouse button yet: {button:?}" ); return false; @@ -243,7 +243,7 @@ impl Window { let msg = ConstellationMsg::Keyboard(event); send_to_constellation(sender, msg); } - e => log::warn!("Verso Window isn't supporting this window event yet: {e:?}"), + e => log::trace!("Verso Window isn't supporting this window event yet: {e:?}"), } false } From 30ba3c8b5e41f8678b36aa70f59f964c80605c6f Mon Sep 17 00:00:00 2001 From: Wu Yuwei Date: Thu, 8 Aug 2024 16:18:56 +0900 Subject: [PATCH 19/22] Fix resize and add more debug logs --- src/compositor.rs | 39 ++++++++++++++++++++++----------------- src/webview.rs | 11 +++++++++++ src/window.rs | 4 +++- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index 45407563..5b00c09e 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -1138,26 +1138,16 @@ impl IOCompositor { } fn create_or_update_webview(&mut self, frame_tree: &SendableFrameTree) { - debug!("{}: Setting frame tree for webview", frame_tree.pipeline.id); - let pipeline_id = frame_tree.pipeline.id; let webview_id = frame_tree.pipeline.top_level_browsing_context_id; + debug!( + "Verso Compositor is setting frame tree with pipeline {} for webview {}", + pipeline_id, webview_id + ); if let Some((old_pipeline, _)) = self.webviews.insert(webview_id, (pipeline_id, false)) { debug!("{webview_id}'s pipeline has changed from {old_pipeline} to {pipeline_id}"); } - // // Resize window and focus webview if the window has this webview - // for window in windows.values_mut() { - // if window.has_webview(webview_id) { - // window.resize(window.size(), self); - // - // send_to_constellation( - // &self.constellation_chan, - // ConstellationMsg::FocusWebView(webview_id), - // ); - // break; - // } - // } self.send_root_pipeline_display_list(); self.create_or_update_pipeline_details_with_frame_tree(frame_tree, None); self.reset_scroll_tree_for_unattached_pipelines(frame_tree); @@ -1170,7 +1160,10 @@ impl IOCompositor { top_level_browsing_context_id: TopLevelBrowsingContextId, windows: &mut HashMap, ) { - debug!("{}: Removing", top_level_browsing_context_id); + debug!( + "Verso Compositor is removing webview {}", + top_level_browsing_context_id + ); let mut window_id = None; for window in windows.values_mut() { let (webview, close_window) = @@ -1289,6 +1282,11 @@ impl IOCompositor { /// Change the current window of the compositor should display. pub fn swap_current_window(&mut self, window: &mut Window) { if window.id() != self.current_window { + debug!( + "Verso Compositor swap current window from {:?} to {:?}", + self.current_window, + window.id() + ); if let Some(Some(new_surface)) = self.surfaces.insert(window.id(), None) { // Present current surface first if let Err(err) = self.rendering_context.present() { @@ -1302,8 +1300,7 @@ impl IOCompositor { self.current_window = window.id(); self.scale_factor = Scale::new(window.scale_factor() as f32); self.painting_order.clear(); - self.viewport = window.size(); - self.set_painting_order(window); + window.resize(window.size(), self); } } } @@ -2220,6 +2217,14 @@ impl IOCompositor { let painting_order = window.painting_order(); self.painting_order = painting_order; self.send_root_pipeline_display_list(); + debug!( + "Verso Compositor sets painting order to {:?}'s painting order {:?}", + window.id(), + self.painting_order + .iter() + .map(|w| w.webview_id) + .collect::>() + ); } else { warn!( "Failed to set painting order due to {:?} is not the current window", diff --git a/src/webview.rs b/src/webview.rs index a78e5932..de7a1b34 100644 --- a/src/webview.rs +++ b/src/webview.rs @@ -66,6 +66,11 @@ impl Window { log::trace!("Verso WebView {webview_id:?} ignores this message: {message:?}") } EmbedderMsg::WebViewFocused(w) => { + log::debug!( + "Verso Window {:?}'s webview {} has loaded completely.", + self.id(), + w + ); compositor.set_webview_loaded(&w); compositor.set_painting_order(self); } @@ -136,6 +141,11 @@ impl Window { log::trace!("Verso Panel ignores this message: {message:?}") } EmbedderMsg::WebViewFocused(w) => { + log::debug!( + "Verso Window {:?}'s panel {} has loaded completely.", + self.id(), + w + ); compositor.set_webview_loaded(&w); compositor.set_painting_order(self); } @@ -150,6 +160,7 @@ impl Window { rect.min.y = rect.max.y.min(76); self.webview = Some(WebView::new(demo_id, rect)); send_to_constellation(sender, ConstellationMsg::NewWebView(demo_url, demo_id)); + log::debug!("Verso Window {:?} adds webview {}", self.id(), demo_id); } EmbedderMsg::AllowNavigationRequest(id, _url) => { // The panel shouldn't navigate to other pages. diff --git a/src/window.rs b/src/window.rs index 59ab6eed..8252cb3c 100644 --- a/src/window.rs +++ b/src/window.rs @@ -151,8 +151,10 @@ impl Window { WindowEvent::ScaleFactorChanged { scale_factor, .. } => { compositor.on_scale_factor_event(*scale_factor as f32); } - WindowEvent::CursorMoved { position, .. } => { + WindowEvent::CursorEntered { .. } => { compositor.swap_current_window(self); + } + WindowEvent::CursorMoved { position, .. } => { let cursor: DevicePoint = DevicePoint::new(position.x as f32, position.y as f32); self.mouse_position.set(*position); compositor.on_mouse_window_move_event_class(cursor); From dd6b75961031c19f28056521f892bfdf237b241d Mon Sep 17 00:00:00 2001 From: Wu Wayne Date: Thu, 8 Aug 2024 18:11:57 +0900 Subject: [PATCH 20/22] Remove unecessary step --- src/compositor.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index 5b00c09e..e2e5abaf 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -1288,10 +1288,6 @@ impl IOCompositor { window.id() ); if let Some(Some(new_surface)) = self.surfaces.insert(window.id(), None) { - // Present current surface first - if let Err(err) = self.rendering_context.present() { - warn!("Failed to present surface: {:?}", err); - } // Swap the surface self.rendering_context.with_front_buffer(|_, old_surface| { self.surfaces.insert(self.current_window, Some(old_surface)); From 5bb2a461460f736f032964a6ad1aa4d7db77842d Mon Sep 17 00:00:00 2001 From: Wu Yu Wei Date: Thu, 8 Aug 2024 20:43:27 +0900 Subject: [PATCH 21/22] Address review changes --- src/window.rs | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/src/window.rs b/src/window.rs index 8252cb3c..5a837d2a 100644 --- a/src/window.rs +++ b/src/window.rs @@ -260,23 +260,16 @@ impl Window { compositor: &mut IOCompositor, ) -> bool { // // Handle message in Verso Panel - if self - .panel - .as_ref() - .filter(|p| p.webview_id == webview_id) - .is_some() - { - self.handle_servo_messages_with_panel( - webview_id, message, sender, clipboard, compositor, - ) + if let Some(panel) = &self.panel { + if panel.webview_id == webview_id { + return self.handle_servo_messages_with_panel( + webview_id, message, sender, clipboard, compositor, + ); + } } // Handle message in Verso WebView - else { - self.handle_servo_messages_with_webview( - webview_id, message, sender, clipboard, compositor, - ); - false - } + self.handle_servo_messages_with_webview(webview_id, message, sender, clipboard, compositor); + false } /// Queues a Winit `WindowEvent::RedrawRequested` event to be emitted that aligns with the windowing system drawing loop. @@ -328,15 +321,9 @@ impl Window { } /// Check if the window has such webview. - pub fn has_webview(&mut self, id: WebViewId) -> bool { - if self.panel.as_ref().filter(|w| w.webview_id == id).is_some() { - true - } else { - self.webview - .as_ref() - .filter(|w| w.webview_id == id) - .is_some() - } + pub fn has_webview(&self, id: WebViewId) -> bool { + self.panel.as_ref().map_or(false, |w| w.webview_id == id) + || self.webview.as_ref().map_or(false, |w| w.webview_id == id) } /// Remove the webview in this window by provided webview ID. If this is the panel, it will From 2a465434a410145cc3f2cbbdccc1bd2dea0dcfaf Mon Sep 17 00:00:00 2001 From: Wu Yu Wei Date: Fri, 9 Aug 2024 17:54:57 +0900 Subject: [PATCH 22/22] Update compositor document --- src/compositor.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index e2e5abaf..577bda46 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -100,10 +100,10 @@ pub enum MouseWindowEvent { const MAX_ZOOM: f32 = 8.0; const MIN_ZOOM: f32 = 0.1; -// NB: Never block on the constellation, because sometimes the constellation blocks on us. -/// Verso compositor contains a GL rendering context with a WebRender insrtance. -/// The compositor will communicate with Serv messages from the Constellation and then -/// composite to WebRender frames and present the surface to the window. +// NB: Never block on the Constellation, because sometimes the Constellation blocks on us. +/// The Verso compositor contains a GL rendering context with a WebRender instance. +/// The compositor will communicate with Servo using messages from the Constellation, +/// then composite the WebRender frames and present the surface to the window. pub struct IOCompositor { /// All surfaces that Compositor currently owns. pub surfaces: HashMap>,