diff --git a/internal/backends/winit/lib.rs b/internal/backends/winit/lib.rs index 4daa6985b..e4acaaa5b 100644 --- a/internal/backends/winit/lib.rs +++ b/internal/backends/winit/lib.rs @@ -37,12 +37,10 @@ mod renderer { window_adapter_weak: &Weak, window_builder: winit::window::WindowBuilder, #[cfg(target_arch = "wasm32")] canvas_id: &str, - ) -> Result + ) -> Result<(Self, Rc), PlatformError> where Self: Sized; - fn window(&self) -> Rc; - fn show(&self) -> Result<(), PlatformError>; fn hide(&self) -> Result<(), PlatformError>; diff --git a/internal/backends/winit/renderer/femtovg.rs b/internal/backends/winit/renderer/femtovg.rs index e64758484..945e2e24b 100644 --- a/internal/backends/winit/renderer/femtovg.rs +++ b/internal/backends/winit/renderer/femtovg.rs @@ -20,7 +20,6 @@ mod glcontext; pub struct GlutinFemtoVGRenderer { rendering_notifier: RefCell>>, renderer: FemtoVGRenderer, - winit_window: Rc, // Last field, so that it's dropped last and context exists and is current when destroying the FemtoVG canvas opengl_context: glcontext::OpenGLContext, } @@ -61,7 +60,7 @@ impl super::WinitCompatibleRenderer for GlutinFemtoVGRenderer { window_adapter_weak: &Weak, window_builder: winit::window::WindowBuilder, #[cfg(target_arch = "wasm32")] canvas_id: &str, - ) -> Result { + ) -> Result<(Self, Rc), PlatformError> { let (winit_window, opengl_context) = crate::event_loop::with_window_target(|event_loop| { glcontext::OpenGLContext::new_context( window_builder, @@ -79,16 +78,10 @@ impl super::WinitCompatibleRenderer for GlutinFemtoVGRenderer { &opengl_context.html_canvas_element(), )?; - Ok(Self { - rendering_notifier: Default::default(), - renderer, - winit_window: Rc::new(winit_window), - opengl_context, - }) - } - - fn window(&self) -> Rc { - self.winit_window.clone() + Ok(( + Self { rendering_notifier: Default::default(), renderer, opengl_context }, + Rc::new(winit_window), + )) } fn show(&self) -> Result<(), PlatformError> { diff --git a/internal/backends/winit/renderer/skia.rs b/internal/backends/winit/renderer/skia.rs index 16ca1e437..f6fdd5ae4 100644 --- a/internal/backends/winit/renderer/skia.rs +++ b/internal/backends/winit/renderer/skia.rs @@ -8,7 +8,6 @@ use i_slint_core::platform::PlatformError; use i_slint_core::window::WindowAdapter; pub struct SkiaRenderer { - winit_window: Rc, renderer: i_slint_renderer_skia::SkiaRenderer>, } @@ -18,7 +17,7 @@ impl super::WinitCompatibleRenderer for SkiaRenderer { fn new( window_adapter_weak: &Weak, window_builder: winit::window::WindowBuilder, - ) -> Result { + ) -> Result<(Self, Rc), PlatformError> { let winit_window = Rc::new(crate::event_loop::with_window_target(|event_loop| { window_builder.build(event_loop.event_loop_target()).map_err(|winit_os_error| { format!("Error creating native window for Skia rendering: {}", winit_os_error) @@ -46,11 +45,7 @@ impl super::WinitCompatibleRenderer for SkiaRenderer { PhysicalWindowSize::new(width, height), )?; - Ok(Self { winit_window, renderer }) - } - - fn window(&self) -> Rc { - self.winit_window.clone() + Ok((Self { renderer }, winit_window)) } fn show(&self) -> Result<(), PlatformError> { diff --git a/internal/backends/winit/renderer/sw.rs b/internal/backends/winit/renderer/sw.rs index 769c98625..0bab10772 100644 --- a/internal/backends/winit/renderer/sw.rs +++ b/internal/backends/winit/renderer/sw.rs @@ -13,7 +13,6 @@ use std::cell::RefCell; use std::rc::{Rc, Weak}; pub struct WinitSoftwareRenderer { - winit_window: Rc, renderer: SoftwareRenderer, canvas: RefCell, } @@ -24,7 +23,7 @@ impl super::WinitCompatibleRenderer for WinitSoftwareRenderer { fn new( window_adapter_weak: &Weak, window_builder: winit::window::WindowBuilder, - ) -> Result { + ) -> Result<(Self, Rc), PlatformError> { let winit_window = crate::event_loop::with_window_target(|event_loop| { window_builder.build(event_loop.event_loop_target()).map_err(|winit_os_error| { format!("Error creating native window for software rendering: {}", winit_os_error) @@ -36,18 +35,16 @@ impl super::WinitCompatibleRenderer for WinitSoftwareRenderer { format!("Error creating softbuffer graphics context: {}", softbuffer_error) })?; - Ok(Self { - winit_window: Rc::new(winit_window), - renderer: SoftwareRenderer::new( - i_slint_core::software_renderer::RepaintBufferType::NewBuffer, - window_adapter_weak.clone(), - ), - canvas: RefCell::new(canvas), - }) - } - - fn window(&self) -> Rc { - self.winit_window.clone() + Ok(( + Self { + renderer: SoftwareRenderer::new( + i_slint_core::software_renderer::RepaintBufferType::NewBuffer, + window_adapter_weak.clone(), + ), + canvas: RefCell::new(canvas), + }, + Rc::new(winit_window), + )) } fn show(&self) -> Result<(), PlatformError> { diff --git a/internal/backends/winit/winitwindowadapter.rs b/internal/backends/winit/winitwindowadapter.rs index 7c027e13a..5db6f936c 100644 --- a/internal/backends/winit/winitwindowadapter.rs +++ b/internal/backends/winit/winitwindowadapter.rs @@ -112,6 +112,7 @@ pub(crate) struct WinitWindowAdapter, shown: Cell, + winit_window: Option>, renderer: OnceCell, #[cfg(target_arch = "wasm32")] @@ -130,6 +131,7 @@ impl Default for WinitWindowAdapter dark_color_scheme: Default::default(), constraints: Default::default(), shown: Default::default(), + winit_window: Default::default(), renderer: Default::default(), #[cfg(target_arch = "wasm32")] virtual_keyboard_helper: Default::default(), @@ -160,7 +162,10 @@ impl WinitWindowAdapter { canvas_id, ) }) { - Ok(new_renderer) => result.renderer = OnceCell::with_value(new_renderer), + Ok((new_renderer, winit_window)) => { + result.renderer = OnceCell::with_value(new_renderer); + result.winit_window = Some(winit_window); + } Err(err) => { platform_error = Some(err); return Self::default(); @@ -177,7 +182,7 @@ impl WinitWindowAdapter { if let Some(err) = platform_error.take() { Err(err) } else { - let id = self_rc.renderer().window().id(); + let id = self_rc.winit_window().id(); crate::event_loop::register_window(id, (self_rc.clone()) as _); Ok(self_rc as _) } @@ -273,17 +278,17 @@ impl WinitWindow for WinitWindowAda self.pending_redraw.set(false); let renderer = self.renderer(); - renderer.render(physical_size_to_slint(&renderer.window().inner_size()))?; + renderer.render(physical_size_to_slint(&self.winit_window().inner_size()))?; Ok(self.pending_redraw.get()) } fn with_window_handle(&self, callback: &mut dyn FnMut(&winit::window::Window)) { - callback(&self.renderer().window()); + callback(&self.winit_window()); } fn winit_window(&self) -> Rc { - self.renderer().window() + self.winit_window.as_ref().unwrap().clone() } fn is_shown(&self) -> bool { @@ -503,7 +508,7 @@ impl WindowAdapterSealed self.call_with_event_loop(|self_| { self_.shown.set(true); - let winit_window = self_.renderer().window(); + let winit_window = self_.winit_window(); let runtime_window = WindowInner::from_pub(&self_.window()); @@ -686,7 +691,7 @@ impl WindowAdapterSealed } fn position(&self) -> corelib::api::PhysicalPosition { - match self.renderer().window().outer_position() { + match self.winit_window().outer_position() { Ok(outer_position) => { corelib::api::PhysicalPosition::new(outer_position.x, outer_position.y) } @@ -695,22 +700,21 @@ impl WindowAdapterSealed } fn set_position(&self, position: corelib::api::WindowPosition) { - self.renderer().window().set_outer_position(position_to_winit(&position)) + self.winit_window().set_outer_position(position_to_winit(&position)) } fn set_size(&self, size: corelib::api::WindowSize) { if self.in_resize_event.get() { return; } - self.renderer().window().set_inner_size(window_size_to_slint(&size)) + self.winit_window().set_inner_size(window_size_to_slint(&size)) } fn dark_color_scheme(&self) -> bool { self.dark_color_scheme .get_or_init(|| { Box::pin(Property::new({ - self.renderer() - .window() + self.winit_window() .theme() .map_or(false, |theme| theme == winit::window::Theme::Dark) })) @@ -720,7 +724,7 @@ impl WindowAdapterSealed } fn is_visible(&self) -> bool { - self.renderer().window().is_visible().unwrap_or(true) + self.winit_window().is_visible().unwrap_or(true) } } @@ -728,7 +732,7 @@ impl Drop for WinitWindowAdapter