From 3deaf1e079b821ce3ea12d17fa8f241faee5f999 Mon Sep 17 00:00:00 2001 From: Tony Date: Mon, 14 Oct 2024 17:26:19 +0800 Subject: [PATCH 1/4] Support no control panel --- src/compositor.rs | 21 +++++++++++---------- src/verso.rs | 12 ++++++------ src/webview.rs | 10 +++------- src/window.rs | 24 +++++++++++++++++++++--- 4 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index 7ef71210..039723bf 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -41,7 +41,7 @@ use webrender_api::{ }; use webrender_traits::display_list::{HitTestInfo, ScrollTree}; use webrender_traits::{ - CompositorHitTestResult, CrossProcessCompositorMessage, ImageUpdate, UntrustedNodeAddress + CompositorHitTestResult, CrossProcessCompositorMessage, ImageUpdate, UntrustedNodeAddress, }; use winit::window::WindowId; @@ -572,7 +572,7 @@ impl IOCompositor { CompositorMsg::CrossProcess(cross_proces_message) => { self.handle_cross_process_message(cross_proces_message); - }, + } } true @@ -707,11 +707,11 @@ impl IOCompositor { match update { ImageUpdate::AddImage(key, desc, data) => { txn.add_image(key, desc, data.into(), None) - }, + } ImageUpdate::DeleteImage(key) => txn.delete_image(key), ImageUpdate::UpdateImage(key, desc, data) => { txn.update_image(key, desc, data.into(), &DirtyRect::All) - }, + } } } self.webrender_api @@ -727,7 +727,7 @@ impl IOCompositor { transaction.add_native_font(font_key, native_handle); self.webrender_api .send_transaction(self.webrender_document, transaction); - }, + } CrossProcessCompositorMessage::AddFontInstance( font_instance_key, @@ -777,13 +777,13 @@ impl IOCompositor { if let Err(e) = req.send(self.viewport.into()) { warn!("Sending response to get client window failed ({:?}).", e); } - }, + } CrossProcessCompositorMessage::GetScreenSize(req) => { if let Err(e) = req.send(self.viewport) { warn!("Sending response to get screen size failed ({:?}).", e); } - }, + } CrossProcessCompositorMessage::GetAvailableScreenSize(req) => { if let Err(e) = req.send(self.viewport) { @@ -833,7 +833,7 @@ impl IOCompositor { .map(|_| self.webrender_api.generate_font_instance_key()) .collect(); let _ = result_sender.send((font_keys, font_instance_keys)); - }, + } CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GetClientWindowRect( req, )) => { @@ -1240,9 +1240,10 @@ impl IOCompositor { self.on_resize_webview_event(panel.webview_id, rect); } + let rect = DeviceIntRect::from_size(size); + let content_size = window.get_content_rect(rect); if let Some(w) = &mut window.webview { - let rect = DeviceIntRect::from_size(size); - w.set_size(rect); + w.set_size(content_size); self.on_resize_webview_event(w.webview_id, w.rect); } diff --git a/src/verso.rs b/src/verso.rs index ff349078..b92a6be1 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -10,9 +10,7 @@ use base::id::WebViewId; use bluetooth::BluetoothThreadFactory; use bluetooth_traits::BluetoothRequest; use canvas::canvas_paint_thread::CanvasPaintThread; -use compositing_traits::{ - CompositorMsg, CompositorProxy, CompositorReceiver, ConstellationMsg, -}; +use compositing_traits::{CompositorMsg, CompositorProxy, CompositorReceiver, ConstellationMsg}; use constellation::{Constellation, FromCompositorLogger, InitialConstellationState}; use crossbeam_channel::{unbounded, Sender}; use devtools; @@ -86,7 +84,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(); @@ -282,7 +280,8 @@ impl Verso { // Create font cache thread let system_font_service = Arc::new( - SystemFontService::spawn(compositor_sender.cross_process_compositor_api.clone()).to_proxy(), + SystemFontService::spawn(compositor_sender.cross_process_compositor_api.clone()) + .to_proxy(), ); // Create canvas thread @@ -368,7 +367,8 @@ impl Verso { // Send the constellation message to start Panel UI // TODO: Should become a window method - let panel_id = window.panel.as_ref().unwrap().webview_id; + let panel = window.add_control_panel(); + let panel_id = panel.webview_id; let path = resource_dir.join("panel.html"); let url = ServoUrl::from_file_path(path.to_str().unwrap()).unwrap(); send_to_constellation( diff --git a/src/webview.rs b/src/webview.rs index 6c559fa4..e2fec741 100644 --- a/src/webview.rs +++ b/src/webview.rs @@ -50,12 +50,8 @@ impl WebView { } } - /// Set the webview size corresponding to the window size. - pub fn set_size(&mut self, mut rect: DeviceIntRect) { - rect.min.y = rect.max.y.min(100); - rect.min.x += 10; - rect.max.y -= 10; - rect.max.x -= 10; + /// Set the webview size. + pub fn set_size(&mut self, rect: DeviceIntRect) { self.rect = rect; } } @@ -185,7 +181,7 @@ impl Window { let size = self.size(); let rect = DeviceIntRect::from_size(size); let mut webview = WebView::new(demo_id, rect); - webview.set_size(rect); + webview.set_size(self.get_content_rect(rect)); self.webview = Some(webview); send_to_constellation(sender, ConstellationMsg::NewWebView(demo_url, demo_id)); log::debug!("Verso Window {:?} adds webview {}", self.id(), demo_id); diff --git a/src/window.rs b/src/window.rs index 3fa20ad4..d034742d 100644 --- a/src/window.rs +++ b/src/window.rs @@ -83,13 +83,11 @@ impl Window { .expect("Failed to create rendering context"); log::trace!("Created rendering context for window {:?}", window); - let size = window.inner_size(); - let size = Size2D::new(size.width as i32, size.height as i32); ( Self { window, surface, - panel: Some(WebView::new_panel(DeviceIntRect::from_size(size))), + panel: None, webview: None, mouse_position: Cell::new(PhysicalPosition::default()), modifiers_state: Cell::new(ModifiersState::default()), @@ -132,6 +130,26 @@ impl Window { window } + /// Create the control panel + pub fn add_control_panel(&mut self) -> &WebView { + let size = self.window.inner_size(); + let size = Size2D::new(size.width as i32, size.height as i32); + self.panel + .replace(WebView::new_panel(DeviceIntRect::from_size(size))); + self.panel.as_ref().unwrap() + } + + /// Get the content area size for the webview to draw on + pub fn get_content_rect(&self, mut size: DeviceIntRect) -> DeviceIntRect { + if self.panel.is_some() { + size.min.y = size.max.y.min(100); + size.min.x += 10; + size.max.y -= 10; + size.max.x -= 10; + } + size + } + /// Handle Winit window event and return a boolean to indicate if the compositor should repaint immediately. pub fn handle_winit_window_event( &mut self, From 26973685b2d8887b5fd0d3966b706c9fbcb63055 Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 15 Oct 2024 10:10:08 +0800 Subject: [PATCH 2/4] Put things in new --- src/verso.rs | 30 +++++------------------------- src/window.rs | 51 +++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/src/verso.rs b/src/verso.rs index b92a6be1..6b68cc77 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -6,7 +6,6 @@ use std::{ }; use arboard::Clipboard; -use base::id::WebViewId; use bluetooth::BluetoothThreadFactory; use bluetooth_traits::BluetoothRequest; use canvas::canvas_paint_thread::CanvasPaintThread; @@ -27,9 +26,7 @@ use profile; use script::{self, JSEngineSetup}; use script_traits::WindowSizeData; use servo_config::{opts, pref}; -use servo_url::ServoUrl; use style; -use units::DeviceIntRect; use webgpu; use webrender::{create_webrender_instance, ShaderPrecacheFlags, WebRenderOptions}; use webrender_api::*; @@ -44,7 +41,6 @@ use winit::{ use crate::{ compositor::{IOCompositor, InitialCompositorState, ShutdownState}, config::Config, - webview::WebView, window::Window, }; @@ -84,7 +80,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 (mut window, rendering_context) = Window::new(evl, true); let event_loop_waker = Box::new(Waker(proxy)); let opts = opts::get(); @@ -365,16 +361,7 @@ impl Verso { opts.debug.convert_mouse_to_touch, ); - // Send the constellation message to start Panel UI - // TODO: Should become a window method - let panel = window.add_control_panel(); - let panel_id = 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), - ); + window.init_panel_webview(&resource_dir, &constellation_sender); let mut windows = HashMap::new(); windows.insert(window.id(), (window, webrender_document)); @@ -443,18 +430,11 @@ impl Verso { compositor, ) { 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( + Window::new_with_compositor(evl, compositor, true); + window.init_panel_webview( + &self.resource_dir, &self.constellation_sender, - ConstellationMsg::NewWebView(url, panel_id), ); - let rect = DeviceIntRect::from_size(window.size()); - window.panel = Some(WebView::new(panel_id, rect)); let webrender_document = document.clone(); self.windows .insert(window.id(), (window, webrender_document)); diff --git a/src/window.rs b/src/window.rs index d034742d..faf9db92 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,4 +1,4 @@ -use std::cell::Cell; +use std::{cell::Cell, path::Path}; use base::id::WebViewId; use compositing_traits::ConstellationMsg; @@ -11,6 +11,7 @@ use glutin::{ }; use glutin_winit::DisplayBuilder; use script_traits::{TouchEventType, WheelDelta, WheelMode}; +use servo_url::ServoUrl; use webrender_api::{ units::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePoint, LayoutVector2D}, ScrollLocation, @@ -51,7 +52,7 @@ pub struct Window { impl Window { /// Create a Verso window from Winit window and return the rendering context. - pub fn new(evl: &ActiveEventLoop) -> (Self, RenderingContext) { + pub fn new(evl: &ActiveEventLoop, with_panel: bool) -> (Self, RenderingContext) { let window_attributes = WinitWindow::default_attributes() .with_transparent(true) .with_decorations(false); @@ -83,11 +84,17 @@ impl Window { .expect("Failed to create rendering context"); log::trace!("Created rendering context for window {:?}", window); + let panel = if with_panel { + Some(Self::create_control_panel(&window)) + } else { + None + }; + ( Self { window, surface, - panel: None, + panel, webview: None, mouse_position: Cell::new(PhysicalPosition::default()), modifiers_state: Cell::new(ModifiersState::default()), @@ -97,7 +104,11 @@ impl Window { } /// Create a Verso window with the rendering context. - pub fn new_with_compositor(evl: &ActiveEventLoop, compositor: &mut IOCompositor) -> Self { + pub fn new_with_compositor( + evl: &ActiveEventLoop, + compositor: &mut IOCompositor, + with_panel: bool, + ) -> Self { let window = evl .create_window(WinitWindow::default_attributes()) // .with_transparent(true) @@ -118,10 +129,15 @@ impl Window { .rendering_context .create_surface(&window) .unwrap(); + let panel = if with_panel { + Some(Self::create_control_panel(&window)) + } else { + None + }; let mut window = Self { window, surface, - panel: None, + panel, webview: None, mouse_position: Cell::new(PhysicalPosition::default()), modifiers_state: Cell::new(ModifiersState::default()), @@ -131,12 +147,10 @@ impl Window { } /// Create the control panel - pub fn add_control_panel(&mut self) -> &WebView { - let size = self.window.inner_size(); + fn create_control_panel(window: &winit::window::Window) -> WebView { + let size = window.inner_size(); let size = Size2D::new(size.width as i32, size.height as i32); - self.panel - .replace(WebView::new_panel(DeviceIntRect::from_size(size))); - self.panel.as_ref().unwrap() + WebView::new_panel(DeviceIntRect::from_size(size)) } /// Get the content area size for the webview to draw on @@ -150,6 +164,23 @@ impl Window { size } + /// Send the constellation message to start Panel UI + pub fn init_panel_webview( + &mut self, + resource_dir: &Path, + constellation_sender: &Sender, + ) { + if let Some(panel) = &self.panel { + let panel_id = 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), + ); + } + } + /// Handle Winit window event and return a boolean to indicate if the compositor should repaint immediately. pub fn handle_winit_window_event( &mut self, From b17f53606c29dc1fd55b2edea1ef5b4ed44fb880 Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 15 Oct 2024 10:14:12 +0800 Subject: [PATCH 3/4] Fix second window fails to start --- src/window.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/window.rs b/src/window.rs index faf9db92..4f4be105 100644 --- a/src/window.rs +++ b/src/window.rs @@ -85,7 +85,7 @@ impl Window { log::trace!("Created rendering context for window {:?}", window); let panel = if with_panel { - Some(Self::create_control_panel(&window)) + Some(Self::create_control_panel(&window, None)) } else { None }; @@ -130,7 +130,7 @@ impl Window { .create_surface(&window) .unwrap(); let panel = if with_panel { - Some(Self::create_control_panel(&window)) + Some(Self::create_control_panel(&window, Some(WebViewId::new()))) } else { None }; @@ -147,10 +147,17 @@ impl Window { } /// Create the control panel - fn create_control_panel(window: &winit::window::Window) -> WebView { + fn create_control_panel( + window: &winit::window::Window, + webview_id: Option, + ) -> WebView { let size = window.inner_size(); let size = Size2D::new(size.width as i32, size.height as i32); - WebView::new_panel(DeviceIntRect::from_size(size)) + if let Some(webview_id) = webview_id { + WebView::new(webview_id, DeviceIntRect::from_size(size)) + } else { + WebView::new_panel(DeviceIntRect::from_size(size)) + } } /// Get the content area size for the webview to draw on From f9ccc46549de71192725f69cd1a4327597498bc5 Mon Sep 17 00:00:00 2001 From: Wu Yu Wei Date: Wed, 16 Oct 2024 12:22:32 +0900 Subject: [PATCH 4/4] Rename method names and signatures --- src/compositor.rs | 2 +- src/verso.rs | 8 +++---- src/webview.rs | 2 +- src/window.rs | 53 +++++++++++++++-------------------------------- 4 files changed, 23 insertions(+), 42 deletions(-) diff --git a/src/compositor.rs b/src/compositor.rs index 039723bf..98500071 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -1241,7 +1241,7 @@ impl IOCompositor { } let rect = DeviceIntRect::from_size(size); - let content_size = window.get_content_rect(rect); + let content_size = window.get_content_size(rect); if let Some(w) = &mut window.webview { w.set_size(content_size); self.on_resize_webview_event(w.webview_id, w.rect); diff --git a/src/verso.rs b/src/verso.rs index fcdd0602..305c0464 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -81,7 +81,7 @@ impl Verso { config.init(); // Reserving a namespace to create TopLevelBrowsingContextId. PipelineNamespace::install(PipelineNamespaceId(0)); - let (mut window, rendering_context) = Window::new(evl, true); + let (mut window, rendering_context) = Window::new(evl); let event_loop_waker = Box::new(Waker(proxy)); let opts = opts::get(); @@ -359,7 +359,7 @@ impl Verso { opts.debug.convert_mouse_to_touch, ); - window.init_panel_webview(&constellation_sender); + window.create_panel(&constellation_sender); let mut windows = HashMap::new(); windows.insert(window.id(), (window, webrender_document)); @@ -427,8 +427,8 @@ impl Verso { compositor, ) { let mut window = - Window::new_with_compositor(evl, compositor, true); - window.init_panel_webview(&self.constellation_sender); + Window::new_with_compositor(evl, compositor); + window.create_panel(&self.constellation_sender); let webrender_document = document.clone(); self.windows .insert(window.id(), (window, webrender_document)); diff --git a/src/webview.rs b/src/webview.rs index f4ff0420..7331d28a 100644 --- a/src/webview.rs +++ b/src/webview.rs @@ -160,7 +160,7 @@ impl Window { let size = self.size(); let rect = DeviceIntRect::from_size(size); let mut webview = WebView::new(demo_id, rect); - webview.set_size(self.get_content_rect(rect)); + webview.set_size(self.get_content_size(rect)); self.webview = Some(webview); send_to_constellation(sender, ConstellationMsg::NewWebView(demo_url, demo_id)); log::debug!("Verso Window {:?} adds webview {}", self.id(), demo_id); diff --git a/src/window.rs b/src/window.rs index 961f7577..d5813615 100644 --- a/src/window.rs +++ b/src/window.rs @@ -62,7 +62,7 @@ pub struct Window { impl Window { /// Create a Verso window from Winit window and return the rendering context. - pub fn new(evl: &ActiveEventLoop, with_panel: bool) -> (Self, RenderingContext) { + pub fn new(evl: &ActiveEventLoop) -> (Self, RenderingContext) { let window_attributes = WinitWindow::default_attributes() .with_transparent(true) .with_decorations(false); @@ -94,17 +94,11 @@ impl Window { .expect("Failed to create rendering context"); log::trace!("Created rendering context for window {:?}", window); - let panel = if with_panel { - Some(Self::create_control_panel(&window)) - } else { - None - }; - ( Self { window, surface, - panel, + panel: None, webview: None, mouse_position: Cell::new(PhysicalPosition::default()), modifiers_state: Cell::new(ModifiersState::default()), @@ -114,11 +108,7 @@ impl Window { } /// Create a Verso window with the rendering context. - pub fn new_with_compositor( - evl: &ActiveEventLoop, - compositor: &mut IOCompositor, - with_panel: bool, - ) -> Self { + pub fn new_with_compositor(evl: &ActiveEventLoop, compositor: &mut IOCompositor) -> Self { let window = evl .create_window(WinitWindow::default_attributes()) // .with_transparent(true) @@ -139,15 +129,11 @@ impl Window { .rendering_context .create_surface(&window) .unwrap(); - let panel = if with_panel { - Some(Self::create_control_panel(&window)) - } else { - None - }; + let mut window = Self { window, surface, - panel, + panel: None, webview: None, mouse_position: Cell::new(PhysicalPosition::default()), modifiers_state: Cell::new(ModifiersState::default()), @@ -156,15 +142,8 @@ impl Window { window } - /// Create the control panel - fn create_control_panel(window: &winit::window::Window) -> WebView { - let size = window.inner_size(); - let size = Size2D::new(size.width as i32, size.height as i32); - WebView::new(WebViewId::new(), DeviceIntRect::from_size(size)) - } - /// Get the content area size for the webview to draw on - pub fn get_content_rect(&self, mut size: DeviceIntRect) -> DeviceIntRect { + pub fn get_content_size(&self, mut size: DeviceIntRect) -> DeviceIntRect { if self.panel.is_some() { size.min.y = size.max.y.min(100); size.min.x += 10; @@ -175,15 +154,17 @@ impl Window { } /// Send the constellation message to start Panel UI - pub fn init_panel_webview(&mut self, constellation_sender: &Sender) { - if let Some(panel) = &self.panel { - let panel_id = panel.webview_id; - let url = ServoUrl::parse("verso://panel.html").unwrap(); - send_to_constellation( - constellation_sender, - ConstellationMsg::NewWebView(url, panel_id), - ); - } + pub fn create_panel(&mut self, constellation_sender: &Sender) { + let size = self.window.inner_size(); + let size = Size2D::new(size.width as i32, size.height as i32); + let panel_id = WebViewId::new(); + self.panel = Some(WebView::new(panel_id, DeviceIntRect::from_size(size))); + + let url = ServoUrl::parse("verso://panel.html").unwrap(); + send_to_constellation( + constellation_sender, + ConstellationMsg::NewWebView(url, panel_id), + ); } /// Handle Winit window event and return a boolean to indicate if the compositor should repaint immediately.