winit: Cleanup, move the winit window out of the individual renderers

This commit is contained in:
Simon Hausmann 2023-05-09 17:59:42 +02:00 committed by Simon Hausmann
parent d0cdc462c7
commit a3a13c727a
5 changed files with 36 additions and 49 deletions

View file

@ -37,12 +37,10 @@ mod renderer {
window_adapter_weak: &Weak<dyn WindowAdapter>,
window_builder: winit::window::WindowBuilder,
#[cfg(target_arch = "wasm32")] canvas_id: &str,
) -> Result<Self, PlatformError>
) -> Result<(Self, Rc<winit::window::Window>), PlatformError>
where
Self: Sized;
fn window(&self) -> Rc<winit::window::Window>;
fn show(&self) -> Result<(), PlatformError>;
fn hide(&self) -> Result<(), PlatformError>;

View file

@ -20,7 +20,6 @@ mod glcontext;
pub struct GlutinFemtoVGRenderer {
rendering_notifier: RefCell<Option<Box<dyn RenderingNotifier>>>,
renderer: FemtoVGRenderer,
winit_window: Rc<winit::window::Window>,
// 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<dyn WindowAdapter>,
window_builder: winit::window::WindowBuilder,
#[cfg(target_arch = "wasm32")] canvas_id: &str,
) -> Result<Self, PlatformError> {
) -> Result<(Self, Rc<winit::window::Window>), 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<winit::window::Window> {
self.winit_window.clone()
Ok((
Self { rendering_notifier: Default::default(), renderer, opengl_context },
Rc::new(winit_window),
))
}
fn show(&self) -> Result<(), PlatformError> {

View file

@ -8,7 +8,6 @@ use i_slint_core::platform::PlatformError;
use i_slint_core::window::WindowAdapter;
pub struct SkiaRenderer {
winit_window: Rc<winit::window::Window>,
renderer: i_slint_renderer_skia::SkiaRenderer<Rc<winit::window::Window>>,
}
@ -18,7 +17,7 @@ impl super::WinitCompatibleRenderer for SkiaRenderer {
fn new(
window_adapter_weak: &Weak<dyn WindowAdapter>,
window_builder: winit::window::WindowBuilder,
) -> Result<Self, PlatformError> {
) -> Result<(Self, Rc<winit::window::Window>), 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<winit::window::Window> {
self.winit_window.clone()
Ok((Self { renderer }, winit_window))
}
fn show(&self) -> Result<(), PlatformError> {

View file

@ -13,7 +13,6 @@ use std::cell::RefCell;
use std::rc::{Rc, Weak};
pub struct WinitSoftwareRenderer {
winit_window: Rc<winit::window::Window>,
renderer: SoftwareRenderer,
canvas: RefCell<softbuffer::GraphicsContext>,
}
@ -24,7 +23,7 @@ impl super::WinitCompatibleRenderer for WinitSoftwareRenderer {
fn new(
window_adapter_weak: &Weak<dyn WindowAdapter>,
window_builder: winit::window::WindowBuilder,
) -> Result<Self, PlatformError> {
) -> Result<(Self, Rc<winit::window::Window>), 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<winit::window::Window> {
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> {

View file

@ -112,6 +112,7 @@ pub(crate) struct WinitWindowAdapter<Renderer: WinitCompatibleRenderer + 'static
constraints: Cell<(corelib::layout::LayoutInfo, corelib::layout::LayoutInfo)>,
shown: Cell<bool>,
winit_window: Option<Rc<winit::window::Window>>,
renderer: OnceCell<Renderer>,
#[cfg(target_arch = "wasm32")]
@ -130,6 +131,7 @@ impl<Renderer: WinitCompatibleRenderer + 'static> 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<Renderer: WinitCompatibleRenderer + 'static> WinitWindowAdapter<Renderer> {
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<Renderer: WinitCompatibleRenderer + 'static> WinitWindowAdapter<Renderer> {
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<Renderer: WinitCompatibleRenderer + 'static> 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<winit::window::Window> {
self.renderer().window()
self.winit_window.as_ref().unwrap().clone()
}
fn is_shown(&self) -> bool {
@ -503,7 +508,7 @@ impl<Renderer: WinitCompatibleRenderer + 'static> 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<Renderer: WinitCompatibleRenderer + 'static> 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<Renderer: WinitCompatibleRenderer + 'static> 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<Renderer: WinitCompatibleRenderer + 'static> 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<Renderer: WinitCompatibleRenderer + 'static> Drop for WinitWindowAdapter<Re
fn drop(&mut self) {
if let Some(renderer) = self.renderer.get() {
renderer.hide().ok(); // ignore errors here, we're going away anyway
crate::event_loop::unregister_window(renderer.window().id());
crate::event_loop::unregister_window(self.winit_window().id());
}
}
}