diff --git a/adapters/src/rendering/femtovg/main_window.rs b/adapters/src/rendering/femtovg/main_window.rs index f34ab25..2b8dc84 100644 --- a/adapters/src/rendering/femtovg/main_window.rs +++ b/adapters/src/rendering/femtovg/main_window.rs @@ -1,3 +1,4 @@ +use super::renderable_window::{RenderState, RenderableWindow}; use crate::errors::{RenderingError, Result}; use core::ops::Deref; use log::info; @@ -8,11 +9,6 @@ use slint::{ use std::cell::Cell; use std::rc::{Rc, Weak}; -pub enum RenderState { - Clean, - Dirty, -} - pub struct FemtoVGWindow { window: Window, renderer: FemtoVGRenderer, @@ -35,8 +31,10 @@ impl FemtoVGWindow { } }) } +} - pub fn render_frame_if_dirty(&self) -> Result<()> { +impl RenderableWindow for FemtoVGWindow { + fn render_frame_if_dirty(&self) -> Result<()> { if matches!( self.render_state.replace(RenderState::Clean), RenderState::Dirty @@ -50,16 +48,28 @@ impl FemtoVGWindow { Ok(()) } - pub fn set_scale_factor(&self, scale_factor: f32) { + fn set_scale_factor(&self, scale_factor: f32) { info!("Setting scale factor to {scale_factor}"); self.scale_factor.set(scale_factor); self.window() .dispatch_event(WindowEvent::ScaleFactorChanged { scale_factor }); } - pub fn scale_factor(&self) -> f32 { + fn scale_factor(&self) -> f32 { self.scale_factor.get() } + + fn render_state(&self) -> &Cell { + &self.render_state + } + + fn size_cell(&self) -> &Cell { + &self.size + } + + fn scale_factor_cell(&self) -> &Cell { + &self.scale_factor + } } impl WindowAdapter for FemtoVGWindow { @@ -72,18 +82,15 @@ impl WindowAdapter for FemtoVGWindow { } fn size(&self) -> PhysicalSize { - self.size.get() + self.size_impl() } fn set_size(&self, size: WindowSize) { - self.size.set(size.to_physical(self.scale_factor())); - self.window.dispatch_event(WindowEvent::Resized { - size: size.to_logical(self.scale_factor()), - }); + self.set_size_impl(size); } fn request_redraw(&self) { - self.render_state.set(RenderState::Dirty); + RenderableWindow::request_redraw(self); } } diff --git a/adapters/src/rendering/femtovg/mod.rs b/adapters/src/rendering/femtovg/mod.rs index 50d701a..782c585 100644 --- a/adapters/src/rendering/femtovg/mod.rs +++ b/adapters/src/rendering/femtovg/mod.rs @@ -1,2 +1,3 @@ pub mod main_window; pub mod popup_window; +pub mod renderable_window; diff --git a/adapters/src/rendering/femtovg/popup_window.rs b/adapters/src/rendering/femtovg/popup_window.rs index e913747..ffef184 100644 --- a/adapters/src/rendering/femtovg/popup_window.rs +++ b/adapters/src/rendering/femtovg/popup_window.rs @@ -1,3 +1,4 @@ +use super::renderable_window::{RenderState, RenderableWindow}; use crate::errors::{RenderingError, Result}; use crate::wayland::surfaces::popup_manager::{OnCloseCallback, PopupId}; use core::ops::Deref; @@ -10,8 +11,6 @@ use slint_interpreter::ComponentInstance; use std::cell::{Cell, OnceCell}; use std::rc::{Rc, Weak}; -use super::main_window::RenderState; - pub struct PopupWindow { window: Window, renderer: FemtoVGRenderer, @@ -73,7 +72,35 @@ impl PopupWindow { info!("Popup window cleanup complete"); } - pub fn render_frame_if_dirty(&self) -> Result<()> { + pub fn popup_key(&self) -> Option { + self.popup_id.get().map(PopupId::key) + } + + pub fn mark_configured(&self) { + info!("Popup window marked as configured"); + self.configured.set(true); + } + + pub fn is_configured(&self) -> bool { + self.configured.get() + } + + pub fn set_component_instance(&self, instance: ComponentInstance) { + info!("Setting component instance for popup window"); + if self.component_instance.set(instance).is_err() { + info!("Component instance already set for popup window"); + } + } + + pub fn request_resize(&self, width: f32, height: f32) { + info!("Requesting popup resize to {}x{}", width, height); + self.set_size(WindowSize::Logical(slint::LogicalSize::new(width, height))); + RenderableWindow::request_redraw(self); + } +} + +impl RenderableWindow for PopupWindow { + fn render_frame_if_dirty(&self) -> Result<()> { if !self.configured.get() { info!("Popup not yet configured, skipping render"); return Ok(()); @@ -98,41 +125,27 @@ impl PopupWindow { Ok(()) } - pub fn set_scale_factor(&self, scale_factor: f32) { + fn set_scale_factor(&self, scale_factor: f32) { info!("Setting popup scale factor to {scale_factor}"); self.scale_factor.set(scale_factor); self.window() .dispatch_event(WindowEvent::ScaleFactorChanged { scale_factor }); } - pub fn scale_factor(&self) -> f32 { + fn scale_factor(&self) -> f32 { self.scale_factor.get() } - pub fn popup_key(&self) -> Option { - self.popup_id.get().map(PopupId::key) + fn render_state(&self) -> &Cell { + &self.render_state } - pub fn mark_configured(&self) { - info!("Popup window marked as configured"); - self.configured.set(true); + fn size_cell(&self) -> &Cell { + &self.size } - pub fn is_configured(&self) -> bool { - self.configured.get() - } - - pub fn set_component_instance(&self, instance: ComponentInstance) { - info!("Setting component instance for popup window"); - if self.component_instance.set(instance).is_err() { - info!("Component instance already set for popup window"); - } - } - - pub fn request_resize(&self, width: f32, height: f32) { - info!("Requesting popup resize to {}x{}", width, height); - self.set_size(WindowSize::Logical(slint::LogicalSize::new(width, height))); - self.request_redraw(); + fn scale_factor_cell(&self) -> &Cell { + &self.scale_factor } } @@ -146,18 +159,15 @@ impl WindowAdapter for PopupWindow { } fn size(&self) -> PhysicalSize { - self.size.get() + self.size_impl() } fn set_size(&self, size: WindowSize) { - self.size.set(size.to_physical(self.scale_factor())); - self.window.dispatch_event(WindowEvent::Resized { - size: size.to_logical(self.scale_factor()), - }); + self.set_size_impl(size); } fn request_redraw(&self) { - self.render_state.set(RenderState::Dirty); + RenderableWindow::request_redraw(self); } } diff --git a/adapters/src/rendering/femtovg/renderable_window.rs b/adapters/src/rendering/femtovg/renderable_window.rs new file mode 100644 index 0000000..36173c9 --- /dev/null +++ b/adapters/src/rendering/femtovg/renderable_window.rs @@ -0,0 +1,35 @@ +use crate::errors::Result; +use slint::{ + PhysicalSize, WindowSize, + platform::{WindowAdapter, WindowEvent}, +}; +use std::cell::Cell; + +pub enum RenderState { + Clean, + Dirty, +} + +pub trait RenderableWindow: WindowAdapter { + fn render_frame_if_dirty(&self) -> Result<()>; + fn set_scale_factor(&self, scale_factor: f32); + fn scale_factor(&self) -> f32; + fn render_state(&self) -> &Cell; + fn size_cell(&self) -> &Cell; + fn scale_factor_cell(&self) -> &Cell; + + fn request_redraw(&self) { + self.render_state().set(RenderState::Dirty); + } + + fn size_impl(&self) -> PhysicalSize { + self.size_cell().get() + } + + fn set_size_impl(&self, size: WindowSize) { + self.size_cell().set(size.to_physical(self.scale_factor())); + self.window().dispatch_event(WindowEvent::Resized { + size: size.to_logical(self.scale_factor()), + }); + } +} diff --git a/adapters/src/wayland/shell_adapter.rs b/adapters/src/wayland/shell_adapter.rs index 6c92b65..1ff0e40 100644 --- a/adapters/src/wayland/shell_adapter.rs +++ b/adapters/src/wayland/shell_adapter.rs @@ -11,7 +11,8 @@ use crate::wayland::{ use crate::{ errors::{EventLoopError, LayerShikaError, RenderingError, Result}, rendering::{ - egl::context::EGLContext, femtovg::main_window::FemtoVGWindow, + egl::context::EGLContext, + femtovg::{main_window::FemtoVGWindow, renderable_window::RenderableWindow}, slint_integration::platform::CustomSlintPlatform, }, }; diff --git a/adapters/src/wayland/surfaces/popup_manager.rs b/adapters/src/wayland/surfaces/popup_manager.rs index a699ad4..5e1a6d6 100644 --- a/adapters/src/wayland/surfaces/popup_manager.rs +++ b/adapters/src/wayland/surfaces/popup_manager.rs @@ -1,6 +1,6 @@ use crate::errors::{LayerShikaError, Result}; use crate::rendering::egl::context::EGLContext; -use crate::rendering::femtovg::popup_window::PopupWindow; +use crate::rendering::femtovg::{popup_window::PopupWindow, renderable_window::RenderableWindow}; use crate::wayland::surfaces::display_metrics::SharedDisplayMetrics; use layer_shika_domain::value_objects::popup_config::PopupConfig; use layer_shika_domain::value_objects::popup_positioning_mode::PopupPositioningMode; diff --git a/adapters/src/wayland/surfaces/rendering_state.rs b/adapters/src/wayland/surfaces/rendering_state.rs index 91f9335..695b0c7 100644 --- a/adapters/src/wayland/surfaces/rendering_state.rs +++ b/adapters/src/wayland/surfaces/rendering_state.rs @@ -1,18 +1,18 @@ use std::rc::Rc; use crate::errors::Result; -use crate::rendering::femtovg::main_window::FemtoVGWindow; +use crate::rendering::femtovg::renderable_window::RenderableWindow; use crate::wayland::surfaces::window_renderer::{WindowRenderer, WindowRendererParams}; use slint::PhysicalSize; use smithay_client_toolkit::reexports::protocols_wlr::layer_shell::v1::client::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1; use crate::wayland::managed_proxies::ManagedWpFractionalScaleV1; -pub struct RenderingState { - renderer: WindowRenderer, +pub struct RenderingState { + renderer: WindowRenderer, } -impl RenderingState { +impl RenderingState { #[must_use] - pub fn new(params: WindowRendererParams) -> Self { + pub fn new(params: WindowRendererParams) -> Self { Self { renderer: WindowRenderer::new(params), } @@ -38,7 +38,7 @@ impl RenderingState { self.renderer.height() } - pub const fn window(&self) -> &Rc { + pub const fn window(&self) -> &Rc { self.renderer.window() } diff --git a/adapters/src/wayland/surfaces/surface_state.rs b/adapters/src/wayland/surfaces/surface_state.rs index 9ded320..add0d04 100644 --- a/adapters/src/wayland/surfaces/surface_state.rs +++ b/adapters/src/wayland/surfaces/surface_state.rs @@ -25,7 +25,7 @@ use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_v1: pub struct WindowState { component: ComponentState, - rendering: RenderingState, + rendering: RenderingState, event_context: EventContext, display_metrics: SharedDisplayMetrics, #[allow(dead_code)] diff --git a/adapters/src/wayland/surfaces/window_renderer.rs b/adapters/src/wayland/surfaces/window_renderer.rs index ed87616..95b0774 100644 --- a/adapters/src/wayland/surfaces/window_renderer.rs +++ b/adapters/src/wayland/surfaces/window_renderer.rs @@ -1,5 +1,5 @@ use crate::errors::Result; -use crate::rendering::femtovg::main_window::FemtoVGWindow; +use crate::rendering::femtovg::renderable_window::RenderableWindow; use crate::wayland::managed_proxies::{ ManagedWlSurface, ManagedZwlrLayerSurfaceV1, ManagedWpFractionalScaleV1, ManagedWpViewport, }; @@ -17,8 +17,8 @@ enum ScalingMode { Integer, } -pub struct WindowRendererParams { - pub window: Rc, +pub struct WindowRendererParams { + pub window: Rc, pub surface: ManagedWlSurface, pub layer_surface: ManagedZwlrLayerSurfaceV1, pub viewport: Option, @@ -28,8 +28,8 @@ pub struct WindowRendererParams { pub size: PhysicalSize, } -pub struct WindowRenderer { - window: Rc, +pub struct WindowRenderer { + window: Rc, surface: ManagedWlSurface, layer_surface: ManagedZwlrLayerSurfaceV1, viewport: Option, @@ -40,9 +40,9 @@ pub struct WindowRenderer { logical_size: PhysicalSize, } -impl WindowRenderer { +impl WindowRenderer { #[must_use] - pub fn new(params: WindowRendererParams) -> Self { + pub fn new(params: WindowRendererParams) -> Self { Self { window: params.window, surface: params.surface, @@ -60,7 +60,7 @@ impl WindowRenderer { self.window.render_frame_if_dirty() } - pub const fn window(&self) -> &Rc { + pub const fn window(&self) -> &Rc { &self.window } @@ -176,7 +176,7 @@ impl WindowRenderer { self.size = dimensions.to_slint_physical_size(); self.logical_size = dimensions.to_slint_logical_size(); - self.window.request_redraw(); + RenderableWindow::request_redraw(self.window.as_ref()); } pub const fn logical_size(&self) -> PhysicalSize {