diff --git a/ports/servoshell/desktop/app.rs b/ports/servoshell/desktop/app.rs index 7ee1f9713bd..7f548e894b1 100644 --- a/ports/servoshell/desktop/app.rs +++ b/ports/servoshell/desktop/app.rs @@ -11,10 +11,10 @@ use std::time::Instant; use std::{env, fs}; use gleam::gl; -use log::{info, trace}; +use log::{error, info, trace}; use servo::compositing::windowing::EmbedderEvent; use servo::compositing::CompositeTarget; -use servo::config::{opts, set_pref}; +use servo::config::opts; use servo::embedder_traits::EventLoopWaker; use servo::servo_config::pref; use servo::url::ServoUrl; @@ -31,7 +31,6 @@ use winit::window::WindowId; use super::events_loop::{EventLoopGuard, EventsLoop, WakerEvent}; use super::minibrowser::Minibrowser; use super::webview::WebViewManager; -use super::{headed_window, headless_window}; use crate::desktop::embedder::{EmbedderCallbacks, XrDiscovery}; use crate::desktop::events_loop::with_current_event_loop; use crate::desktop::tracing::trace_winit_event; @@ -71,28 +70,10 @@ enum PumpResult { impl App { pub fn new( events_loop: &EventsLoop, - no_native_titlebar: bool, - device_pixel_ratio_override: Option, + window: Rc, user_agent: Option, url: Option, ) -> Self { - // Implements window methods, used by compositor. - let window = if opts::get().headless { - // GL video rendering is not supported on headless windows. - set_pref!(media.glvideo.enabled, false); - headless_window::Window::new( - opts::get().initial_window_size, - device_pixel_ratio_override, - ) - } else { - Rc::new(headed_window::Window::new( - opts::get().initial_window_size, - events_loop.as_winit(), - no_native_titlebar, - device_pixel_ratio_override, - )) - }; - // Handle browser state. let webviews = WebViewManager::new(window.clone()); let initial_url = get_default_url(url.as_deref(), env::current_dir().unwrap(), |path| { @@ -304,6 +285,12 @@ impl App { match self.handle_events() { PumpResult::Shutdown => { event_loop.exit(); + if let Err(e) = window + .rendering_context() + .unbind_native_surface_from_context() + { + error!("Failed to unbind native surface: {e:?}"); + } self.servo.take().unwrap().deinit(); if let Some(mut minibrowser) = self.minibrowser() { minibrowser.context.destroy(); diff --git a/ports/servoshell/desktop/cli.rs b/ports/servoshell/desktop/cli.rs index f590f022bb7..a0364b85a5d 100644 --- a/ports/servoshell/desktop/cli.rs +++ b/ports/servoshell/desktop/cli.rs @@ -2,15 +2,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use std::rc::Rc; use std::{env, panic, process}; use getopts::Options; -use log::error; +use log::{error, warn}; use servo::config::opts::{self, ArgumentParsingResult}; +use servo::config::set_pref; use servo::servo_config::pref; -use super::events_loop::EventsLoop; use crate::desktop::app::App; +use crate::desktop::events_loop::EventsLoop; +use crate::desktop::{headed_window, headless_window}; use crate::panic_hook; pub fn main() { @@ -103,10 +106,27 @@ pub fn main() { let event_loop = EventsLoop::new(opts::get().headless, opts::get().output_file.is_some()) .expect("Failed to create events loop"); + // Implements window methods, used by compositor. + // FIXME: We keep the window until application exits. Otherwise, it will cause + // simthay-clipboard thread segfault on Wayland. + let window = if opts::get().headless { + if pref!(media.glvideo.enabled) { + warn!("GL video rendering is not supported on headless windows."); + set_pref!(media.glvideo.enabled, false); + } + headless_window::Window::new(opts::get().initial_window_size, device_pixel_ratio_override) + } else { + Rc::new(headed_window::Window::new( + opts::get().initial_window_size, + event_loop.as_winit(), + do_not_use_native_titlebar, + device_pixel_ratio_override, + )) + }; + let mut app = App::new( &event_loop, - do_not_use_native_titlebar, - device_pixel_ratio_override, + window.clone(), user_agent, url_opt.map(|s| s.to_string()), );