diff --git a/Cargo.lock b/Cargo.lock index 9c00252..e0dff31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1983,6 +1983,63 @@ dependencies = [ "cc", ] +[[package]] +name = "glutin" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2491aa3090f682ddd920b184491844440fdd14379c7eef8f5bc10ef7fb3242fd" +dependencies = [ + "bitflags 2.6.0", + "cfg_aliases 0.2.1", + "cgl", + "core-foundation", + "dispatch", + "glutin_egl_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "libloading", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "once_cell", + "raw-window-handle", + "wayland-sys 0.31.4", + "windows-sys 0.52.0", + "x11-dl", +] + +[[package]] +name = "glutin-winit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" +dependencies = [ + "cfg_aliases 0.2.1", + "glutin", + "raw-window-handle", + "winit", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cae99fff4d2850dbe6fb8c1fa8e4fead5525bab715beaacfccf3fb994e01c827" +dependencies = [ + "gl_generator", + "windows-sys 0.52.0", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2b2d3918e76e18e08796b55eb64e8fe6ec67d5a6b2e2a7e2edce224ad24c63" +dependencies = [ + "gl_generator", + "x11-dl", +] + [[package]] name = "glutin_wgl_sys" version = "0.6.0" @@ -3360,9 +3417,7 @@ checksum = "b14af7d1a65278923835af94ac23d4c3662478001ac6e78075fe1210a7067e4b" dependencies = [ "bindgen", "cc", - "gl_generator", "lazy_static", - "libz-sys", "walkdir", ] @@ -6168,12 +6223,13 @@ dependencies = [ "fonts", "getopts", "gleam", + "glutin", + "glutin-winit", "ipc-channel", "keyboard-types", "layout_thread_2020", "log", "media", - "mozangle", "net", "objc2", "objc2-app-kit", @@ -6190,7 +6246,6 @@ dependencies = [ "sparkle", "style", "style_traits", - "surfman", "thiserror", "url", "webdriver_server", diff --git a/Cargo.toml b/Cargo.toml index 83a3862..4f94dfb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,12 +53,13 @@ env_logger = "0.10" euclid = "0.22" getopts = "0.2.17" gleam = "0.15" +glutin = "0.32.0" +glutin-winit = "0.5.0" ipc-channel = "0.18" keyboard-types = "0.7" log = "0.4" raw-window-handle = { version = "0.6", features = ["std"] } sparkle = "0.1.26" -surfman = { version = "0.9", features = ["chains", "sm-raw-window-handle-06"] } thiserror = "1.0" winit = { version = "0.30", features = ["rwh_06"] } # Servo repo crates @@ -99,10 +100,6 @@ cargo-packager-resource-resolver = { version = "0.1.1", features = [ ], optional = true } url = "2.5.2" -[target.'cfg(target_os = "windows")'.dependencies] -surfman = { version = "0.9", features = ["sm-angle-default"] } -mozangle = { version = "0.5.1", features = ["egl", "build_dlls"] } - [target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies] objc2 = "0.5" objc2-app-kit = {version = "0.2", features = ["NSView", "NSResponder", "NSWindow"]} @@ -117,4 +114,4 @@ lto = true # Tell clippy to allow e.g. #[cfg(macos)] [lints.clippy] -mismatched_target_os = "allow" \ No newline at end of file +mismatched_target_os = "allow" diff --git a/src/compositor.rs b/src/compositor.rs index 22b2ee7..00785b3 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -24,7 +24,6 @@ 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, @@ -39,11 +38,11 @@ use webrender_api::{ use webrender_traits::display_list::{HitTestInfo, ScrollTree}; use webrender_traits::{ CanvasToCompositorMsg, CompositorHitTestResult, FontToCompositorMsg, ImageUpdate, - NetToCompositorMsg, RenderingContext, ScriptToCompositorMsg, SerializedImageUpdate, - UntrustedNodeAddress, + NetToCompositorMsg, ScriptToCompositorMsg, SerializedImageUpdate, UntrustedNodeAddress, }; use winit::window::WindowId; +use crate::rendering::RenderingContext; use crate::touch::{TouchAction, TouchHandler}; use crate::window::Window; @@ -104,9 +103,6 @@ const MIN_ZOOM: f32 = 0.1; /// 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>, - /// The current window that Compositor is handling. pub current_window: WindowId, @@ -176,7 +172,7 @@ pub struct IOCompositor { /// The webrender interface, if enabled. pub webrender_api: RenderApi, - /// The surfman instance that webrender targets + /// The glutin instance that webrender targets pub rendering_context: RenderingContext, /// The GL bindings for webrender @@ -348,10 +344,7 @@ 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, @@ -394,15 +387,7 @@ impl IOCompositor { } /// Consume compositor itself and deinit webrender. - 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)); - } + pub fn deinit(self) { self.webrender.deinit(); } @@ -453,34 +438,6 @@ impl IOCompositor { self.shutdown_state = ShutdownState::FinishedShuttingDown; } - /// The underlying native surface can be lost during servo's lifetime. - /// On Android, for example, this happens when the app is sent to background. - /// We need to unbind the surface so that we don't try to use it again. - pub fn invalidate_native_surface(&mut self) { - debug!("Invalidating native surface in compositor"); - if let Err(e) = self.rendering_context.unbind_native_surface_from_context() { - warn!("Unbinding native surface from context failed ({:?})", e); - } - } - - /// On Android, this function will be called when the app moves to foreground - /// and the system creates a new native surface that needs to bound to the current - /// context. - #[allow(unsafe_code)] - #[allow(clippy::not_unsafe_ptr_arg_deref)] // It has an unsafe block inside - pub fn replace_native_surface(&mut self, native_widget: *mut c_void, coords: DeviceIntSize) { - debug!("Replacing native surface in compositor: {native_widget:?}"); - let connection = self.rendering_context.connection(); - let native_widget = - unsafe { connection.create_native_widget_from_ptr(native_widget, coords.to_untyped()) }; - if let Err(e) = self - .rendering_context - .bind_native_surface_to_context(native_widget) - { - warn!("Binding native surface to context failed ({:?})", e); - } - } - fn handle_browser_message( &mut self, msg: CompositorMsg, @@ -1282,23 +1239,16 @@ impl IOCompositor { self.current_window, window.id() ); - if let Some(Some(new_surface)) = self.surfaces.insert(window.id(), None) { - // Swap the surface - 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); - self.resize(window.size(), window); - } + self.current_window = window.id(); + self.scale_factor = Scale::new(window.scale_factor() as f32); + self.resize(window.size(), window); } } /// 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, window: &mut Window) -> bool { - let need_resize = self.on_resize_window_event(size); + let need_resize = self.on_resize_window_event(size, window); if let Some(panel) = &mut window.panel { let rect = DeviceIntRect::from_size(size); @@ -1319,12 +1269,14 @@ impl IOCompositor { /// 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 { + pub fn on_resize_window_event(&mut self, new_viewport: DeviceIntSize, window: &Window) -> bool { if self.shutdown_state != ShutdownState::NotShuttingDown { return false; } - let _ = self.rendering_context.resize(new_viewport.to_untyped()); + let _ = self + .rendering_context + .resize(&window.surface, new_viewport.to_untyped()); self.viewport = new_viewport; let mut transaction = Transaction::new(); transaction.set_document_view(DeviceIntRect::from_size(self.viewport)); @@ -1959,8 +1911,8 @@ impl IOCompositor { } /// Composite to the given target if any, or the current target otherwise. - pub fn composite(&mut self) { - match self.composite_specific_target() { + pub fn composite(&mut self, window: &Window) { + match self.composite_specific_target(window) { Ok(_) => { if self.exit_after_load { println!("Shutting down the Constellation after generating an output file or exit flag specified"); @@ -1974,8 +1926,11 @@ impl IOCompositor { } /// Composite to the given target if any, or the current target otherwise. - fn composite_specific_target(&mut self) -> Result<(), UnableToComposite> { - if let Err(err) = self.rendering_context.make_gl_context_current() { + fn composite_specific_target(&mut self, window: &Window) -> Result<(), UnableToComposite> { + if let Err(err) = self + .rendering_context + .make_gl_context_current(&window.surface) + { warn!("Failed to make GL context current: {:?}", err); } self.assert_no_gl_error(); @@ -1999,17 +1954,6 @@ impl IOCompositor { } } - // Bind the webrender framebuffer - let framebuffer_object = self - .rendering_context - .context_surface_info() - .unwrap_or(None) - .map(|info| info.framebuffer_object) - .unwrap_or(0); - self.webrender_gl - .bind_framebuffer(gl::FRAMEBUFFER, framebuffer_object); - self.assert_gl_framebuffer_complete(); - profile( ProfilerCategory::Compositing, None, @@ -2071,7 +2015,7 @@ impl IOCompositor { } } - if let Err(err) = self.rendering_context.present() { + if let Err(err) = self.rendering_context.present(&window.surface) { warn!("Failed to present surface: {:?}", err); } self.composition_request = CompositionRequest::NoCompositingNecessary; @@ -2147,19 +2091,21 @@ impl IOCompositor { self.zoom_action = false; } - match self.composition_request { - CompositionRequest::NoCompositingNecessary => {} - CompositionRequest::CompositeNow(_) => self.composite(), - } + if let Some(window) = windows.get(&self.current_window) { + match self.composition_request { + CompositionRequest::NoCompositingNecessary => {} + CompositionRequest::CompositeNow(_) => self.composite(window), + } - // Run the WebXR main thread - self.webxr_main_thread.run_one_frame(); + // Run the WebXR main thread + self.webxr_main_thread.run_one_frame(); - // The WebXR thread may make a different context current - let _ = self.rendering_context.make_gl_context_current(); + // The WebXR thread may make a different context current + let _ = self + .rendering_context + .make_gl_context_current(&window.surface); - if !self.pending_scroll_zoom_events.is_empty() { - if let Some(window) = windows.get(&self.current_window) { + if !self.pending_scroll_zoom_events.is_empty() { self.process_pending_scroll_events(window) } } @@ -2175,7 +2121,9 @@ impl IOCompositor { let need_recomposite = matches!(msg, CompositorMsg::NewWebRenderFrameReady(_)); let keep_going = self.handle_browser_message(msg, windows); if need_recomposite { - self.composite(); + if let Some(window) = windows.get(&self.current_window) { + self.composite(window); + } break; } if !keep_going { diff --git a/src/errors.rs b/src/errors.rs index 87e2773..248b404 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -11,4 +11,7 @@ pub enum Error { /// A general error that may occur while running the Winit event loop. #[error(transparent)] EventLoopError(#[from] winit::error::EventLoopError), + /// Glutin errors. + #[error(transparent)] + GlutinError(#[from] glutin::error::Error), } diff --git a/src/lib.rs b/src/lib.rs index 0925314..73c34cb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,6 +13,8 @@ pub mod config; pub mod errors; /// Utilities to handle keyboard inputs and states. pub mod keyboard; +/// Verso's rendering context. +pub mod rendering; /// Utilities to handle touch inputs and states. pub mod touch; /// Main entry types and functions. diff --git a/src/rendering.rs b/src/rendering.rs new file mode 100644 index 0000000..437e088 --- /dev/null +++ b/src/rendering.rs @@ -0,0 +1,182 @@ +use std::ffi::CString; +use std::num::NonZeroU32; +use std::rc::Rc; + +use euclid::default::Size2D; +use gleam::gl; +use glutin::config::GetGlConfig; +use glutin::context::PossiblyCurrentContext; +use glutin::prelude::{GlContext, PossiblyCurrentGlContext}; +use glutin::surface::{ + GlSurface, ResizeableSurface, Surface, SurfaceTypeTrait, SwapInterval, WindowSurface, +}; +use glutin::{ + config::{Config, ConfigTemplateBuilder, GlConfig}, + context::{ContextApi, ContextAttributesBuilder, Version}, + display::GetGlDisplay, + prelude::{GlDisplay, NotCurrentGlContext}, +}; +use glutin_winit::{DisplayBuilder, GlWindow}; +use raw_window_handle::HasWindowHandle; +use winit::event_loop::ActiveEventLoop; +use winit::window::Window; + +/// A Verso rendering context, which holds all of the information needed +/// to render Servo's layout, and bridges WebRender and glutin. +pub struct RenderingContext { + context: PossiblyCurrentContext, + pub(crate) gl: Rc, +} + +impl RenderingContext { + /// Create a rendering context instance. + pub fn create( + evl: &ActiveEventLoop, + window: &Window, + ) -> Result<(Self, Surface), Box> { + let template = ConfigTemplateBuilder::new() + .with_alpha_size(8) + .with_transparency(cfg!(macos)); + let (_, gl_config) = DisplayBuilder::new().build(evl, template, gl_config_picker)?; + + log::debug!("Picked a config with {} samples", gl_config.num_samples()); + + // XXX This will panic on Android, but we care about Desktop for now. + let raw_window_handle = window.window_handle().ok().map(|handle| handle.as_raw()); + // XXX The display could be obtained from any object created by it, so we can + // query it from the config. + let gl_display = gl_config.display(); + // The context creation part. + let context_attributes = ContextAttributesBuilder::new().build(raw_window_handle); + // Since glutin by default tries to create OpenGL core context, which may not be + // present we should try GLES. + let fallback_context_attributes = ContextAttributesBuilder::new() + .with_context_api(ContextApi::Gles(None)) + .build(raw_window_handle); + // There are also some old devices that support neither modern OpenGL nor GLES. + // To support these we can try and create a 2.1 context. + let legacy_context_attributes = ContextAttributesBuilder::new() + .with_context_api(ContextApi::OpenGl(Some(Version::new(2, 1)))) + .build(raw_window_handle); + let not_current_gl_context = unsafe { + gl_display + .create_context(&gl_config, &context_attributes) + .unwrap_or_else(|_| { + gl_display + .create_context(&gl_config, &fallback_context_attributes) + .unwrap_or_else(|_| { + gl_display + .create_context(&gl_config, &legacy_context_attributes) + .expect("failed to create context") + }) + }) + }; + + // Create surface + let attrs = window + .build_surface_attributes(Default::default()) + .expect("Failed to build surface attributes"); + let surface = unsafe { + gl_config + .display() + .create_window_surface(&gl_config, &attrs) + .unwrap() + }; + + // Make it current. + let context = not_current_gl_context.make_current(&surface).unwrap(); + + // Try setting vsync. + if let Err(res) = + surface.set_swap_interval(&context, SwapInterval::Wait(NonZeroU32::new(1).unwrap())) + { + log::error!("Error setting vsync: {res:?}"); + } + + let gl = match context.context_api() { + ContextApi::OpenGl(_) => unsafe { + gleam::gl::GlFns::load_with(|symbol| { + let symbol = CString::new(symbol).unwrap(); + gl_display.get_proc_address(symbol.as_c_str()) as *const _ + }) + }, + ContextApi::Gles(_) => unsafe { + gleam::gl::GlesFns::load_with(|symbol| { + let symbol = CString::new(symbol).unwrap(); + gl_display.get_proc_address(symbol.as_c_str()) as *const _ + }) + }, + }; + + println!("Running on {}", gl.get_string(gl::RENDERER)); + println!("OpenGL Version {}", gl.get_string(gl::VERSION)); + println!( + "Shaders version on {}", + gl.get_string(gl::SHADING_LANGUAGE_VERSION) + ); + + Ok((Self { context, gl }, surface)) + } + + /// Create a surface based on provided window. + pub fn create_surface( + &self, + window: &Window, + ) -> Result, crate::errors::Error> { + let attrs = window + .build_surface_attributes(Default::default()) + .expect("Failed to build surface attributes"); + let config = self.context.config(); + unsafe { Ok(config.display().create_window_surface(&config, &attrs)?) } + } + + /// Make GL context current. + pub fn make_gl_context_current( + &self, + surface: &Surface, + ) -> Result<(), crate::errors::Error> { + self.context.make_current(surface)?; + Ok(()) + } + + /// Resize the rendering context. + pub fn resize( + &self, + surface: &Surface, + size: Size2D, + ) { + surface.resize( + &self.context, + NonZeroU32::new(size.width as u32).unwrap(), + NonZeroU32::new(size.height as u32).unwrap(), + ); + self.gl.viewport(0, 0, size.width, size.height); + } + + /// Present the surface of the rendering context. + pub fn present( + &self, + surface: &Surface, + ) -> Result<(), crate::errors::Error> { + self.context.make_current(&surface)?; + surface.swap_buffers(&self.context)?; + Ok(()) + } +} + +/// Find the config with the maximum number of samples, so our triangle will be +/// smooth. +pub fn gl_config_picker(configs: Box + '_>) -> Config { + configs + .reduce(|accum, config| { + let transparency_check = config.supports_transparency().unwrap_or(false) + & !accum.supports_transparency().unwrap_or(false); + + if transparency_check || config.num_samples() > accum.num_samples() { + config + } else { + accum + } + }) + .unwrap() +} diff --git a/src/verso.rs b/src/verso.rs index 4262097..ab6c141 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -19,7 +19,6 @@ use devtools; use embedder_traits::{EmbedderMsg, EmbedderProxy, EmbedderReceiver, EventLoopWaker}; use euclid::Scale; use fonts::FontCacheThread; -use gleam::gl; use ipc_channel::ipc::{self, IpcSender}; use layout_thread_2020; use log::{Log, Metadata, Record}; @@ -31,7 +30,6 @@ use script_traits::WindowSizeData; 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}; @@ -101,24 +99,8 @@ impl Verso { // Initialize servo media with dummy backend servo_media::ServoMedia::init::(); - // Initialize surfman & get GL bindings - let webrender_gl = match rendering_context.connection().gl_api() { - GLApi::GL => unsafe { gl::GlFns::load_with(|s| rendering_context.get_proc_address(s)) }, - GLApi::GLES => unsafe { - 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); + // Get GL bindings + let webrender_gl = rendering_context.gl.clone(); // Create profiler threads let time_profiler_sender = profile::time::Profiler::create( diff --git a/src/window.rs b/src/window.rs index a3b95f2..a072f35 100644 --- a/src/window.rs +++ b/src/window.rs @@ -5,15 +5,13 @@ use compositing_traits::ConstellationMsg; use crossbeam_channel::Sender; use embedder_traits::{Cursor, EmbedderMsg}; use euclid::{Point2D, Size2D}; -use raw_window_handle::{HasDisplayHandle, HasWindowHandle}; +use glutin::surface::Surface; +use glutin::surface::WindowSurface; use script_traits::{TouchEventType, WheelDelta, WheelMode}; -use surfman::Connection; -use surfman::SurfaceType; use webrender_api::{ units::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePoint, LayoutVector2D}, ScrollLocation, }; -use webrender_traits::RenderingContext; use winit::{ dpi::PhysicalPosition, event::{ElementState, TouchPhase, WindowEvent}, @@ -25,6 +23,7 @@ use winit::{ use crate::{ compositor::{IOCompositor, MouseWindowEvent}, keyboard::keyboard_event_from_winit, + rendering::RenderingContext, verso::send_to_constellation, webview::WebView, }; @@ -35,6 +34,8 @@ use arboard::Clipboard; pub struct Window { /// Access to Winit window pub(crate) window: WinitWindow, + /// GL surface of the window + pub(crate) surface: Surface, /// The main control panel of this window. pub(crate) panel: Option, /// The WebView of this window. @@ -54,9 +55,9 @@ impl Window { // .with_decorations(false) .expect("Failed to create window."); - let rwh = window.window_handle().expect("Failed to get window handle"); #[cfg(macos)] unsafe { + let rwh = window.window_handle().expect("Failed to get window handle"); if let RawWindowHandle::AppKit(AppKitWindowHandle { ns_view, .. }) = rwh.as_ref() { decorate_window( ns_view.as_ptr() as *mut AnyObject, @@ -64,22 +65,8 @@ impl Window { ); } } - 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 - .display_handle() - .expect("Failed to get display handle"); - let connection = - Connection::from_display_handle(display_handle).expect("Failed to create connection"); - let adapter = connection - .create_adapter() - .expect("Failed to create adapter"); - let native_widget = connection - .create_native_widget_from_window_handle(rwh, window_size) - .expect("Failed to create native widget"); - let surface_type = SurfaceType::Widget { native_widget }; - let rendering_context = RenderingContext::create(&connection, &adapter, surface_type) - .expect("Failed to create rendering context"); + let (rendering_context, surface) = + RenderingContext::create(evl, &window).expect("Failed to create rendering context"); log::trace!("Created rendering context for window {:?}", window); let size = window.inner_size(); @@ -87,6 +74,7 @@ impl Window { ( Self { window, + surface, panel: Some(WebView::new_panel(DeviceIntRect::from_size(size))), webview: None, mouse_position: Cell::new(PhysicalPosition::default()), @@ -104,9 +92,9 @@ impl Window { // .with_decorations(false) .expect("Failed to create window."); - let rwh = window.window_handle().expect("Failed to get window handle"); #[cfg(macos)] unsafe { + let rwh = window.window_handle().expect("Failed to get window handle"); if let RawWindowHandle::AppKit(AppKitWindowHandle { ns_view, .. }) = rwh.as_ref() { decorate_window( ns_view.as_ptr() as *mut AnyObject, @@ -114,26 +102,20 @@ impl 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_window_handle(rwh, 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 { + .create_surface(&window) + .unwrap(); + let mut window = Self { window, + surface, panel: None, webview: None, mouse_position: Cell::new(PhysicalPosition::default()), modifiers_state: Cell::new(ModifiersState::default()), - } + }; + compositor.swap_current_window(&mut window); + window } /// Handle Winit window event and return a boolean to indicate if the compositor should repaint immediately. @@ -390,7 +372,7 @@ impl Window { #[cfg(macos)] use objc2::runtime::AnyObject; #[cfg(macos)] -use raw_window_handle::{AppKitWindowHandle, RawWindowHandle}; +use raw_window_handle::{AppKitWindowHandle, HasWindowHandle, RawWindowHandle}; #[cfg(macos)] use winit::dpi::LogicalPosition;