From c7cd757c79d3a78ae5e16cf828badf825d36d016 Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 12 Nov 2024 15:16:18 +0800 Subject: [PATCH 1/5] Allow setting initial window size from cli --- src/config.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ src/verso.rs | 3 ++- src/window.rs | 18 +++++++++++++++--- 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/config.rs b/src/config.rs index 4c731cf6..b9361ba7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -9,6 +9,9 @@ use net_traits::{ ResourceFetchTiming, }; use servo_config::opts::{default_opts, set_options, Opts}; +use winit::dpi; + +use crate::window::WindowSettings; /// Command line arguments. #[derive(Clone, Debug, Default)] @@ -19,6 +22,8 @@ pub struct CliArgs { pub ipc_channel: Option, /// Should launch without control panel pub no_panel: bool, + /// Window settings for the initial winit window + pub window_settings: WindowSettings, } /// Configuration of Verso instance. @@ -44,6 +49,16 @@ fn parse_cli_args() -> Result { "", ); opts.optflag("", "no-panel", "Launch Verso without control panel"); + opts.optflag( + "", + "width", + "Initial window's width in physical unit, the height command line arg much also be set", + ); + opts.optflag( + "", + "height", + "Initial window's height in physical unit, the width command line arg much also be set", + ); let matches: getopts::Matches = opts.parse(&args[1..])?; let url = matches @@ -63,10 +78,37 @@ fn parse_cli_args() -> Result { let ipc_channel = matches.opt_str("ipc-channel"); let no_panel = matches.opt_present("no-panel"); + let width: Option = matches.opt_get("width").unwrap_or_else(|e| { + log::error!("Failed to parse width command line argument: {e}"); + None + }); + let height: Option = matches.opt_get("height").unwrap_or_else(|e| { + log::error!("Failed to parse height command line argument: {e}"); + None + }); + + let size = match (width, height) { + (None, Some(_height)) => { + log::error!("Invalid size command line argument, height is present but not width"); + None + } + (Some(_width), None) => { + log::error!("Invalid size command line argument, width is present but not height"); + None + } + (Some(width), Some(height)) => Some(dpi::PhysicalSize::new(width, height)), + _ => None, + }; + let window_settings = WindowSettings { + size, + ..Default::default() + }; + Ok(CliArgs { url, ipc_channel, no_panel, + window_settings, }) } diff --git a/src/verso.rs b/src/verso.rs index d4182b35..7d9ae498 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -108,11 +108,12 @@ impl Verso { let protocols = config.create_protocols(); let initial_url = config.args.url.clone(); let with_panel = !config.args.no_panel; + let window_settings = config.args.window_settings.clone(); config.init(); // Reserving a namespace to create TopLevelBrowsingContextId. PipelineNamespace::install(PipelineNamespaceId(0)); - let (mut window, rendering_context) = Window::new(evl); + let (mut window, rendering_context) = Window::new(evl, window_settings); let event_loop_waker = Box::new(Waker(proxy)); let opts = opts::get(); diff --git a/src/window.rs b/src/window.rs index cb679c1f..83f9ebfc 100644 --- a/src/window.rs +++ b/src/window.rs @@ -19,7 +19,7 @@ use webrender_api::{ #[cfg(any(linux, target_os = "windows"))] use winit::window::ResizeDirection; use winit::{ - dpi::PhysicalPosition, + dpi::{self, PhysicalPosition}, event::{ElementState, TouchPhase, WindowEvent}, event_loop::ActiveEventLoop, keyboard::ModifiersState, @@ -54,13 +54,25 @@ pub struct Window { pub(crate) resizing: bool, } +/// Window settings to init the winit window +#[derive(Debug, Default, Clone)] +#[non_exhaustive] +pub struct WindowSettings { + /// Size + pub(crate) size: Option>, +} + impl Window { /// Create a Verso window from Winit window and return the rendering context. - pub fn new(evl: &ActiveEventLoop) -> (Self, RenderingContext) { - let window_attributes = WinitWindow::default_attributes() + pub fn new(evl: &ActiveEventLoop, settings: WindowSettings) -> (Self, RenderingContext) { + let mut window_attributes = WinitWindow::default_attributes() .with_transparent(true) .with_decorations(false); + if let Some(size) = settings.size { + window_attributes = window_attributes.with_inner_size(size); + } + let template = ConfigTemplateBuilder::new() .with_alpha_size(8) .with_transparency(cfg!(macos)); From 7bcd9bfafb8cd332e53a56c4deca14723d188727 Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 12 Nov 2024 15:22:11 +0800 Subject: [PATCH 2/5] Should be optopt --- src/config.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/config.rs b/src/config.rs index b9361ba7..a2f34911 100644 --- a/src/config.rs +++ b/src/config.rs @@ -49,15 +49,17 @@ fn parse_cli_args() -> Result { "", ); opts.optflag("", "no-panel", "Launch Verso without control panel"); - opts.optflag( + opts.optopt( "", "width", "Initial window's width in physical unit, the height command line arg much also be set", + "", ); - opts.optflag( + opts.optopt( "", "height", "Initial window's height in physical unit, the width command line arg much also be set", + "", ); let matches: getopts::Matches = opts.parse(&args[1..])?; From 0b07edcf3390c5918a8948bb0075aec53af1548e Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 12 Nov 2024 15:33:34 +0800 Subject: [PATCH 3/5] Clean up --- src/config.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/config.rs b/src/config.rs index a2f34911..ccc2b85b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -49,6 +49,7 @@ fn parse_cli_args() -> Result { "", ); opts.optflag("", "no-panel", "Launch Verso without control panel"); + opts.optopt( "", "width", @@ -80,11 +81,11 @@ fn parse_cli_args() -> Result { let ipc_channel = matches.opt_str("ipc-channel"); let no_panel = matches.opt_present("no-panel"); - let width: Option = matches.opt_get("width").unwrap_or_else(|e| { + let width = matches.opt_get::("width").unwrap_or_else(|e| { log::error!("Failed to parse width command line argument: {e}"); None }); - let height: Option = matches.opt_get("height").unwrap_or_else(|e| { + let height = matches.opt_get::("height").unwrap_or_else(|e| { log::error!("Failed to parse height command line argument: {e}"); None }); From f0359490928419ee8a1b2e949cfa3aae08c78bd5 Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 12 Nov 2024 16:09:15 +0800 Subject: [PATCH 4/5] Add short name for width and height --- src/config.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config.rs b/src/config.rs index ccc2b85b..0f4d9f21 100644 --- a/src/config.rs +++ b/src/config.rs @@ -51,13 +51,13 @@ fn parse_cli_args() -> Result { opts.optflag("", "no-panel", "Launch Verso without control panel"); opts.optopt( - "", + "w", "width", "Initial window's width in physical unit, the height command line arg much also be set", "", ); opts.optopt( - "", + "h", "height", "Initial window's height in physical unit, the width command line arg much also be set", "", From c41e2b4554c06c4d0fe7cfe9a2603ab85b69b27e Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 12 Nov 2024 16:13:27 +0800 Subject: [PATCH 5/5] Store winit WindowAttributes instead --- src/config.rs | 17 ++++++++--------- src/verso.rs | 2 +- src/window.rs | 23 +++++++---------------- 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/src/config.rs b/src/config.rs index 0f4d9f21..43a8ddf7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -9,9 +9,7 @@ use net_traits::{ ResourceFetchTiming, }; use servo_config::opts::{default_opts, set_options, Opts}; -use winit::dpi; - -use crate::window::WindowSettings; +use winit::{dpi, window::WindowAttributes}; /// Command line arguments. #[derive(Clone, Debug, Default)] @@ -23,7 +21,7 @@ pub struct CliArgs { /// Should launch without control panel pub no_panel: bool, /// Window settings for the initial winit window - pub window_settings: WindowSettings, + pub window_attributes: WindowAttributes, } /// Configuration of Verso instance. @@ -102,16 +100,17 @@ fn parse_cli_args() -> Result { (Some(width), Some(height)) => Some(dpi::PhysicalSize::new(width, height)), _ => None, }; - let window_settings = WindowSettings { - size, - ..Default::default() - }; + let mut window_attributes = winit::window::Window::default_attributes(); + + if let Some(size) = size { + window_attributes = window_attributes.with_inner_size(size); + } Ok(CliArgs { url, ipc_channel, no_panel, - window_settings, + window_attributes, }) } diff --git a/src/verso.rs b/src/verso.rs index 7d9ae498..595497ea 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -108,7 +108,7 @@ impl Verso { let protocols = config.create_protocols(); let initial_url = config.args.url.clone(); let with_panel = !config.args.no_panel; - let window_settings = config.args.window_settings.clone(); + let window_settings = config.args.window_attributes.clone(); config.init(); // Reserving a namespace to create TopLevelBrowsingContextId. diff --git a/src/window.rs b/src/window.rs index 83f9ebfc..a76c17c3 100644 --- a/src/window.rs +++ b/src/window.rs @@ -19,11 +19,11 @@ use webrender_api::{ #[cfg(any(linux, target_os = "windows"))] use winit::window::ResizeDirection; use winit::{ - dpi::{self, PhysicalPosition}, + dpi::PhysicalPosition, event::{ElementState, TouchPhase, WindowEvent}, event_loop::ActiveEventLoop, keyboard::ModifiersState, - window::{CursorIcon, Window as WinitWindow, WindowId}, + window::{CursorIcon, Window as WinitWindow, WindowAttributes, WindowId}, }; use crate::{ @@ -54,25 +54,16 @@ pub struct Window { pub(crate) resizing: bool, } -/// Window settings to init the winit window -#[derive(Debug, Default, Clone)] -#[non_exhaustive] -pub struct WindowSettings { - /// Size - pub(crate) size: Option>, -} - impl Window { /// Create a Verso window from Winit window and return the rendering context. - pub fn new(evl: &ActiveEventLoop, settings: WindowSettings) -> (Self, RenderingContext) { - let mut window_attributes = WinitWindow::default_attributes() + pub fn new( + evl: &ActiveEventLoop, + window_attributes: WindowAttributes, + ) -> (Self, RenderingContext) { + let window_attributes = window_attributes .with_transparent(true) .with_decorations(false); - if let Some(size) = settings.size { - window_attributes = window_attributes.with_inner_size(size); - } - let template = ConfigTemplateBuilder::new() .with_alpha_size(8) .with_transparency(cfg!(macos));