mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
servoshell: Move headless
setting to ServoShellPreferences (#35377)
This is only used in servoshell, even though it was plumbed through script previously. It's just about how the `RenderingContext` is set up, which is something managed entirely outside of servo itself. In addition, make the name of `servo_shell_preferences` in `app.rs` more consistent with the rest of the codebase. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
1ba5d0e093
commit
e227e0913b
11 changed files with 20 additions and 48 deletions
|
@ -48,8 +48,6 @@ pub struct Opts {
|
||||||
|
|
||||||
pub output_file: Option<String>,
|
pub output_file: Option<String>,
|
||||||
|
|
||||||
pub headless: bool,
|
|
||||||
|
|
||||||
/// True to exit on thread failure instead of displaying about:failure.
|
/// True to exit on thread failure instead of displaying about:failure.
|
||||||
pub hard_fail: bool,
|
pub hard_fail: bool,
|
||||||
|
|
||||||
|
@ -218,7 +216,6 @@ impl Default for Opts {
|
||||||
userscripts: None,
|
userscripts: None,
|
||||||
user_stylesheets: Vec::new(),
|
user_stylesheets: Vec::new(),
|
||||||
output_file: None,
|
output_file: None,
|
||||||
headless: false,
|
|
||||||
hard_fail: true,
|
hard_fail: true,
|
||||||
webdriver_port: None,
|
webdriver_port: None,
|
||||||
initial_window_size: Size2D::new(1024, 740),
|
initial_window_size: Size2D::new(1024, 740),
|
||||||
|
|
|
@ -64,7 +64,6 @@ impl DissimilarOriginWindow {
|
||||||
// FIXME(nox): The microtask queue is probably not important
|
// FIXME(nox): The microtask queue is probably not important
|
||||||
// here, but this whole DOM interface is a hack anyway.
|
// here, but this whole DOM interface is a hack anyway.
|
||||||
global_to_clone_from.microtask_queue().clone(),
|
global_to_clone_from.microtask_queue().clone(),
|
||||||
global_to_clone_from.is_headless(),
|
|
||||||
global_to_clone_from.get_user_agent(),
|
global_to_clone_from.get_user_agent(),
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
global_to_clone_from.wgpu_id_hub(),
|
global_to_clone_from.wgpu_id_hub(),
|
||||||
|
|
|
@ -316,9 +316,6 @@ pub(crate) struct GlobalScope {
|
||||||
#[allow(clippy::vec_box)]
|
#[allow(clippy::vec_box)]
|
||||||
consumed_rejections: DomRefCell<Vec<Box<Heap<*mut JSObject>>>>,
|
consumed_rejections: DomRefCell<Vec<Box<Heap<*mut JSObject>>>>,
|
||||||
|
|
||||||
/// True if headless mode.
|
|
||||||
is_headless: bool,
|
|
||||||
|
|
||||||
/// An optional string allowing the user agent to be set for testing.
|
/// An optional string allowing the user agent to be set for testing.
|
||||||
user_agent: Cow<'static, str>,
|
user_agent: Cow<'static, str>,
|
||||||
|
|
||||||
|
@ -716,7 +713,6 @@ impl GlobalScope {
|
||||||
origin: MutableOrigin,
|
origin: MutableOrigin,
|
||||||
creation_url: Option<ServoUrl>,
|
creation_url: Option<ServoUrl>,
|
||||||
microtask_queue: Rc<MicrotaskQueue>,
|
microtask_queue: Rc<MicrotaskQueue>,
|
||||||
is_headless: bool,
|
|
||||||
user_agent: Cow<'static, str>,
|
user_agent: Cow<'static, str>,
|
||||||
#[cfg(feature = "webgpu")] gpu_id_hub: Arc<IdentityHub>,
|
#[cfg(feature = "webgpu")] gpu_id_hub: Arc<IdentityHub>,
|
||||||
inherited_secure_context: Option<bool>,
|
inherited_secure_context: Option<bool>,
|
||||||
|
@ -751,7 +747,6 @@ impl GlobalScope {
|
||||||
event_source_tracker: DOMTracker::new(),
|
event_source_tracker: DOMTracker::new(),
|
||||||
uncaught_rejections: Default::default(),
|
uncaught_rejections: Default::default(),
|
||||||
consumed_rejections: Default::default(),
|
consumed_rejections: Default::default(),
|
||||||
is_headless,
|
|
||||||
user_agent,
|
user_agent,
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
gpu_id_hub,
|
gpu_id_hub,
|
||||||
|
@ -2911,10 +2906,6 @@ impl GlobalScope {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_headless(&self) -> bool {
|
|
||||||
self.is_headless
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn get_user_agent(&self) -> Cow<'static, str> {
|
pub(crate) fn get_user_agent(&self) -> Cow<'static, str> {
|
||||||
self.user_agent.clone()
|
self.user_agent.clone()
|
||||||
}
|
}
|
||||||
|
|
|
@ -2778,7 +2778,6 @@ impl Window {
|
||||||
unminify_css: bool,
|
unminify_css: bool,
|
||||||
local_script_source: Option<String>,
|
local_script_source: Option<String>,
|
||||||
userscripts_path: Option<String>,
|
userscripts_path: Option<String>,
|
||||||
is_headless: bool,
|
|
||||||
replace_surrogates: bool,
|
replace_surrogates: bool,
|
||||||
user_agent: Cow<'static, str>,
|
user_agent: Cow<'static, str>,
|
||||||
player_context: WindowGLContext,
|
player_context: WindowGLContext,
|
||||||
|
@ -2807,7 +2806,6 @@ impl Window {
|
||||||
origin,
|
origin,
|
||||||
Some(creator_url),
|
Some(creator_url),
|
||||||
microtask_queue,
|
microtask_queue,
|
||||||
is_headless,
|
|
||||||
user_agent,
|
user_agent,
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
gpu_id_hub,
|
gpu_id_hub,
|
||||||
|
|
|
@ -79,7 +79,6 @@ pub(crate) fn prepare_workerscope_init(
|
||||||
pipeline_id: global.pipeline_id(),
|
pipeline_id: global.pipeline_id(),
|
||||||
origin: global.origin().immutable().clone(),
|
origin: global.origin().immutable().clone(),
|
||||||
creation_url: global.creation_url().clone(),
|
creation_url: global.creation_url().clone(),
|
||||||
is_headless: global.is_headless(),
|
|
||||||
user_agent: global.get_user_agent(),
|
user_agent: global.get_user_agent(),
|
||||||
inherited_secure_context: Some(global.is_secure_context()),
|
inherited_secure_context: Some(global.is_secure_context()),
|
||||||
};
|
};
|
||||||
|
@ -165,7 +164,6 @@ impl WorkerGlobalScope {
|
||||||
MutableOrigin::new(init.origin),
|
MutableOrigin::new(init.origin),
|
||||||
init.creation_url,
|
init.creation_url,
|
||||||
runtime.microtask_queue.clone(),
|
runtime.microtask_queue.clone(),
|
||||||
init.is_headless,
|
|
||||||
init.user_agent,
|
init.user_agent,
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
gpu_id_hub,
|
gpu_id_hub,
|
||||||
|
|
|
@ -96,7 +96,6 @@ impl WorkletGlobalScope {
|
||||||
MutableOrigin::new(ImmutableOrigin::new_opaque()),
|
MutableOrigin::new(ImmutableOrigin::new_opaque()),
|
||||||
None,
|
None,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
init.is_headless,
|
|
||||||
init.user_agent.clone(),
|
init.user_agent.clone(),
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
init.gpu_id_hub.clone(),
|
init.gpu_id_hub.clone(),
|
||||||
|
@ -186,8 +185,6 @@ pub(crate) struct WorkletGlobalScopeInit {
|
||||||
pub(crate) to_constellation_sender: IpcSender<(PipelineId, ScriptMsg)>,
|
pub(crate) to_constellation_sender: IpcSender<(PipelineId, ScriptMsg)>,
|
||||||
/// The image cache
|
/// The image cache
|
||||||
pub(crate) image_cache: Arc<dyn ImageCache>,
|
pub(crate) image_cache: Arc<dyn ImageCache>,
|
||||||
/// True if in headless mode
|
|
||||||
pub(crate) is_headless: bool,
|
|
||||||
/// An optional string allowing the user agent to be set for testing
|
/// An optional string allowing the user agent to be set for testing
|
||||||
pub(crate) user_agent: Cow<'static, str>,
|
pub(crate) user_agent: Cow<'static, str>,
|
||||||
/// Identity manager for WebGPU resources
|
/// Identity manager for WebGPU resources
|
||||||
|
|
|
@ -318,9 +318,6 @@ pub struct ScriptThread {
|
||||||
/// won't be loaded
|
/// won't be loaded
|
||||||
userscripts_path: Option<String>,
|
userscripts_path: Option<String>,
|
||||||
|
|
||||||
/// True if headless mode.
|
|
||||||
headless: bool,
|
|
||||||
|
|
||||||
/// Replace unpaired surrogates in DOM strings with U+FFFD.
|
/// Replace unpaired surrogates in DOM strings with U+FFFD.
|
||||||
/// See <https://github.com/servo/servo/issues/6564>
|
/// See <https://github.com/servo/servo/issues/6564>
|
||||||
replace_surrogates: bool,
|
replace_surrogates: bool,
|
||||||
|
@ -753,7 +750,6 @@ impl ScriptThread {
|
||||||
.pipeline_to_constellation_sender
|
.pipeline_to_constellation_sender
|
||||||
.clone(),
|
.clone(),
|
||||||
image_cache: script_thread.image_cache.clone(),
|
image_cache: script_thread.image_cache.clone(),
|
||||||
is_headless: script_thread.headless,
|
|
||||||
user_agent: script_thread.user_agent.clone(),
|
user_agent: script_thread.user_agent.clone(),
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
gpu_id_hub: script_thread.gpu_id_hub.clone(),
|
gpu_id_hub: script_thread.gpu_id_hub.clone(),
|
||||||
|
@ -961,7 +957,6 @@ impl ScriptThread {
|
||||||
local_script_source: opts.local_script_source.clone(),
|
local_script_source: opts.local_script_source.clone(),
|
||||||
unminify_css: opts.unminify_css,
|
unminify_css: opts.unminify_css,
|
||||||
userscripts_path: opts.userscripts.clone(),
|
userscripts_path: opts.userscripts.clone(),
|
||||||
headless: opts.headless,
|
|
||||||
replace_surrogates: opts.debug.replace_surrogates,
|
replace_surrogates: opts.debug.replace_surrogates,
|
||||||
user_agent,
|
user_agent,
|
||||||
player_context: state.player_context,
|
player_context: state.player_context,
|
||||||
|
@ -3151,7 +3146,6 @@ impl ScriptThread {
|
||||||
self.unminify_css,
|
self.unminify_css,
|
||||||
self.local_script_source.clone(),
|
self.local_script_source.clone(),
|
||||||
self.userscripts_path.clone(),
|
self.userscripts_path.clone(),
|
||||||
self.headless,
|
|
||||||
self.replace_surrogates,
|
self.replace_surrogates,
|
||||||
self.user_agent.clone(),
|
self.user_agent.clone(),
|
||||||
self.player_context.clone(),
|
self.player_context.clone(),
|
||||||
|
|
|
@ -770,8 +770,6 @@ pub struct WorkerGlobalScopeInit {
|
||||||
pub origin: ImmutableOrigin,
|
pub origin: ImmutableOrigin,
|
||||||
/// The creation URL
|
/// The creation URL
|
||||||
pub creation_url: Option<ServoUrl>,
|
pub creation_url: Option<ServoUrl>,
|
||||||
/// True if headless mode
|
|
||||||
pub is_headless: bool,
|
|
||||||
/// An optional string allowing the user agnet to be set for testing.
|
/// An optional string allowing the user agnet to be set for testing.
|
||||||
pub user_agent: Cow<'static, str>,
|
pub user_agent: Cow<'static, str>,
|
||||||
/// True if secure context
|
/// True if secure context
|
||||||
|
|
|
@ -44,7 +44,7 @@ use crate::prefs::ServoShellPreferences;
|
||||||
pub struct App {
|
pub struct App {
|
||||||
opts: Opts,
|
opts: Opts,
|
||||||
preferences: Preferences,
|
preferences: Preferences,
|
||||||
servo_shell_preferences: ServoShellPreferences,
|
servoshell_preferences: ServoShellPreferences,
|
||||||
suspended: Cell<bool>,
|
suspended: Cell<bool>,
|
||||||
windows: HashMap<WindowId, Rc<dyn WindowPortsMethods>>,
|
windows: HashMap<WindowId, Rc<dyn WindowPortsMethods>>,
|
||||||
minibrowser: Option<Minibrowser>,
|
minibrowser: Option<Minibrowser>,
|
||||||
|
@ -88,7 +88,7 @@ impl App {
|
||||||
App {
|
App {
|
||||||
opts,
|
opts,
|
||||||
preferences,
|
preferences,
|
||||||
servo_shell_preferences,
|
servoshell_preferences: servo_shell_preferences,
|
||||||
suspended: Cell::new(false),
|
suspended: Cell::new(false),
|
||||||
windows: HashMap::new(),
|
windows: HashMap::new(),
|
||||||
minibrowser: None,
|
minibrowser: None,
|
||||||
|
@ -103,7 +103,7 @@ impl App {
|
||||||
/// Initialize Application once event loop start running.
|
/// Initialize Application once event loop start running.
|
||||||
pub fn init(&mut self, event_loop: Option<&ActiveEventLoop>) {
|
pub fn init(&mut self, event_loop: Option<&ActiveEventLoop>) {
|
||||||
// Create rendering context
|
// Create rendering context
|
||||||
let rendering_context = if self.opts.headless {
|
let rendering_context = if self.servoshell_preferences.headless {
|
||||||
let connection = Connection::new().expect("Failed to create connection");
|
let connection = Connection::new().expect("Failed to create connection");
|
||||||
let adapter = connection
|
let adapter = connection
|
||||||
.create_software_adapter()
|
.create_software_adapter()
|
||||||
|
@ -128,10 +128,11 @@ impl App {
|
||||||
.expect("Failed to create WR surfman")
|
.expect("Failed to create WR surfman")
|
||||||
};
|
};
|
||||||
|
|
||||||
let window = if self.opts.headless {
|
let headless = self.servoshell_preferences.headless;
|
||||||
|
let window = if headless {
|
||||||
headless_window::Window::new(
|
headless_window::Window::new(
|
||||||
self.opts.initial_window_size,
|
self.opts.initial_window_size,
|
||||||
self.servo_shell_preferences.device_pixel_ratio_override,
|
self.servoshell_preferences.device_pixel_ratio_override,
|
||||||
self.opts.screen_size_override,
|
self.opts.screen_size_override,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -140,8 +141,8 @@ impl App {
|
||||||
&rendering_context,
|
&rendering_context,
|
||||||
self.opts.initial_window_size,
|
self.opts.initial_window_size,
|
||||||
event_loop.unwrap(),
|
event_loop.unwrap(),
|
||||||
self.servo_shell_preferences.no_native_titlebar,
|
self.servoshell_preferences.no_native_titlebar,
|
||||||
self.servo_shell_preferences.device_pixel_ratio_override,
|
self.servoshell_preferences.device_pixel_ratio_override,
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -158,7 +159,7 @@ impl App {
|
||||||
self.suspended.set(false);
|
self.suspended.set(false);
|
||||||
let (_, window) = self.windows.iter().next().unwrap();
|
let (_, window) = self.windows.iter().next().unwrap();
|
||||||
|
|
||||||
let xr_discovery = if pref!(dom_webxr_openxr_enabled) && !self.opts.headless {
|
let xr_discovery = if pref!(dom_webxr_openxr_enabled) && !headless {
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
let openxr = {
|
let openxr = {
|
||||||
let app_info = AppInfo::new("Servoshell", 0, "Servo", 0);
|
let app_info = AppInfo::new("Servoshell", 0, "Servo", 0);
|
||||||
|
@ -168,7 +169,7 @@ impl App {
|
||||||
let openxr = None;
|
let openxr = None;
|
||||||
|
|
||||||
openxr
|
openxr
|
||||||
} else if pref!(dom_webxr_glwindow_enabled) && !self.opts.headless {
|
} else if pref!(dom_webxr_glwindow_enabled) && !headless {
|
||||||
let window = window.new_glwindow(event_loop.unwrap());
|
let window = window.new_glwindow(event_loop.unwrap());
|
||||||
Some(XrDiscovery::GlWindow(GlWindowDiscovery::new(window)))
|
Some(XrDiscovery::GlWindow(GlWindowDiscovery::new(window)))
|
||||||
} else {
|
} else {
|
||||||
|
@ -202,16 +203,12 @@ impl App {
|
||||||
Rc::new(rendering_context),
|
Rc::new(rendering_context),
|
||||||
embedder,
|
embedder,
|
||||||
Rc::new(UpcastedWindow(window.clone())),
|
Rc::new(UpcastedWindow(window.clone())),
|
||||||
self.servo_shell_preferences.user_agent.clone(),
|
self.servoshell_preferences.user_agent.clone(),
|
||||||
composite_target,
|
composite_target,
|
||||||
);
|
);
|
||||||
servo.setup_logging();
|
servo.setup_logging();
|
||||||
|
|
||||||
let running_state = Rc::new(RunningAppState::new(
|
let running_state = Rc::new(RunningAppState::new(servo, window.clone(), headless));
|
||||||
servo,
|
|
||||||
window.clone(),
|
|
||||||
self.opts.headless,
|
|
||||||
));
|
|
||||||
running_state.new_toplevel_webview(self.initial_url.clone().into_url());
|
running_state.new_toplevel_webview(self.initial_url.clone().into_url());
|
||||||
|
|
||||||
if let Some(ref mut minibrowser) = self.minibrowser {
|
if let Some(ref mut minibrowser) = self.minibrowser {
|
||||||
|
@ -332,7 +329,7 @@ impl App {
|
||||||
minibrowser.update_location_dirty(false);
|
minibrowser.update_location_dirty(false);
|
||||||
let Some(url) = location_bar_input_to_url(
|
let Some(url) = location_bar_input_to_url(
|
||||||
&location.clone(),
|
&location.clone(),
|
||||||
&self.servo_shell_preferences.searchpage,
|
&self.servoshell_preferences.searchpage,
|
||||||
) else {
|
) else {
|
||||||
warn!("failed to parse location");
|
warn!("failed to parse location");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -28,7 +28,7 @@ pub fn main() {
|
||||||
};
|
};
|
||||||
|
|
||||||
let clean_shutdown = servoshell_preferences.clean_shutdown;
|
let clean_shutdown = servoshell_preferences.clean_shutdown;
|
||||||
let event_loop = EventsLoop::new(opts.headless, opts.output_file.is_some())
|
let event_loop = EventsLoop::new(servoshell_preferences.headless, opts.output_file.is_some())
|
||||||
.expect("Failed to create events loop");
|
.expect("Failed to create events loop");
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,6 +34,9 @@ pub(crate) struct ServoShellPreferences {
|
||||||
/// URL string of the search engine page with '%s' standing in for the search term.
|
/// URL string of the search engine page with '%s' standing in for the search term.
|
||||||
/// For example <https://duckduckgo.com/html/?q=%s>.
|
/// For example <https://duckduckgo.com/html/?q=%s>.
|
||||||
pub searchpage: String,
|
pub searchpage: String,
|
||||||
|
/// Whether or not to run servoshell in headless mode. While running in headless
|
||||||
|
/// mode, image output is supported.
|
||||||
|
pub headless: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ServoShellPreferences {
|
impl Default for ServoShellPreferences {
|
||||||
|
@ -46,6 +49,7 @@ impl Default for ServoShellPreferences {
|
||||||
homepage: "https://servo.org".into(),
|
homepage: "https://servo.org".into(),
|
||||||
no_native_titlebar: true,
|
no_native_titlebar: true,
|
||||||
searchpage: "https://duckduckgo.com/html/?q=%s".into(),
|
searchpage: "https://duckduckgo.com/html/?q=%s".into(),
|
||||||
|
headless: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -539,11 +543,11 @@ pub(crate) fn parse_command_line_arguments(args: Vec<String>) -> ArgumentParsing
|
||||||
no_native_titlebar,
|
no_native_titlebar,
|
||||||
device_pixel_ratio_override,
|
device_pixel_ratio_override,
|
||||||
clean_shutdown: opt_match.opt_present("clean-shutdown"),
|
clean_shutdown: opt_match.opt_present("clean-shutdown"),
|
||||||
|
headless: opt_match.opt_present("z"),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let headless = opt_match.opt_present("z");
|
if servoshell_preferences.headless && preferences.media_glvideo_enabled {
|
||||||
if headless && preferences.media_glvideo_enabled {
|
|
||||||
warn!("GL video rendering is not supported on headless windows.");
|
warn!("GL video rendering is not supported on headless windows.");
|
||||||
preferences.media_glvideo_enabled = false;
|
preferences.media_glvideo_enabled = false;
|
||||||
}
|
}
|
||||||
|
@ -558,7 +562,6 @@ pub(crate) fn parse_command_line_arguments(args: Vec<String>) -> ArgumentParsing
|
||||||
userscripts: opt_match.opt_default("userscripts", ""),
|
userscripts: opt_match.opt_default("userscripts", ""),
|
||||||
user_stylesheets,
|
user_stylesheets,
|
||||||
output_file,
|
output_file,
|
||||||
headless,
|
|
||||||
hard_fail: opt_match.opt_present("f") && !opt_match.opt_present("F"),
|
hard_fail: opt_match.opt_present("f") && !opt_match.opt_present("F"),
|
||||||
webdriver_port,
|
webdriver_port,
|
||||||
initial_window_size,
|
initial_window_size,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue