diff --git a/adapters/src/wayland/config.rs b/adapters/src/wayland/config.rs index 4c8448f..f9e418b 100644 --- a/adapters/src/wayland/config.rs +++ b/adapters/src/wayland/config.rs @@ -2,11 +2,12 @@ use layer_shika_domain::prelude::{ AnchorEdges, KeyboardInteractivity as DomainKeyboardInteractivity, Layer, Margins, WindowConfig as DomainWindowConfig, }; -use slint_interpreter::ComponentDefinition; +use slint_interpreter::{ComponentDefinition, CompilationResult}; use smithay_client_toolkit::reexports::protocols_wlr::layer_shell::v1::client::{ zwlr_layer_shell_v1::{self}, zwlr_layer_surface_v1::{Anchor, KeyboardInteractivity as WaylandKeyboardInteractivity}, }; +use std::rc::Rc; #[derive(Debug, Clone, Copy)] pub(crate) struct LayerSurfaceParams { @@ -28,12 +29,14 @@ pub struct WaylandWindowConfig { pub scale_factor: f32, pub namespace: String, pub component_definition: ComponentDefinition, + pub compilation_result: Option>, } impl WaylandWindowConfig { #[must_use] pub fn from_domain_config( component_definition: ComponentDefinition, + compilation_result: Option>, domain_config: DomainWindowConfig, ) -> Self { Self { @@ -48,6 +51,7 @@ impl WaylandWindowConfig { scale_factor: domain_config.scale_factor, namespace: domain_config.namespace, component_definition, + compilation_result, } } } diff --git a/adapters/src/wayland/shell_adapter.rs b/adapters/src/wayland/shell_adapter.rs index bd8f239..4f0199c 100644 --- a/adapters/src/wayland/shell_adapter.rs +++ b/adapters/src/wayland/shell_adapter.rs @@ -129,6 +129,7 @@ impl WaylandWindowingSystem { let mut builder = WindowStateBuilder::new() .with_component_definition(config.component_definition) + .with_compilation_result(config.compilation_result) .with_surface(Rc::clone(&surface_ctx.surface)) .with_layer_surface(Rc::clone(&surface_ctx.layer_surface)) .with_scale_factor(config.scale_factor) diff --git a/adapters/src/wayland/surfaces/surface_builder.rs b/adapters/src/wayland/surfaces/surface_builder.rs index 26e13e6..e623f45 100644 --- a/adapters/src/wayland/surfaces/surface_builder.rs +++ b/adapters/src/wayland/surfaces/surface_builder.rs @@ -4,7 +4,7 @@ use slint::{ platform::{set_platform, Platform, WindowAdapter}, PhysicalSize, PlatformError, }; -use slint_interpreter::ComponentDefinition; +use slint_interpreter::{ComponentDefinition, CompilationResult}; use smithay_client_toolkit::reexports::protocols_wlr::layer_shell::v1::client::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1; use wayland_client::{protocol::{wl_pointer::WlPointer, wl_surface::WlSurface}, Connection}; use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1; @@ -25,6 +25,7 @@ impl Platform for PlatformWrapper { pub struct WindowStateBuilder { pub component_definition: Option, + pub compilation_result: Option>, pub surface: Option>, pub layer_surface: Option>, pub fractional_scale: Option>, @@ -105,6 +106,12 @@ impl WindowStateBuilder { self } + #[must_use] + pub fn with_compilation_result(mut self, compilation_result: Option>) -> Self { + self.compilation_result = compilation_result; + self + } + #[must_use] pub fn with_fractional_scale(mut self, fractional_scale: Rc) -> Self { self.fractional_scale = Some(fractional_scale); @@ -141,6 +148,7 @@ impl Default for WindowStateBuilder { fn default() -> Self { Self { component_definition: None, + compilation_result: None, surface: None, layer_surface: None, fractional_scale: None, diff --git a/adapters/src/wayland/surfaces/surface_state.rs b/adapters/src/wayland/surfaces/surface_state.rs index 1e04930..4f4351b 100644 --- a/adapters/src/wayland/surfaces/surface_state.rs +++ b/adapters/src/wayland/surfaces/surface_state.rs @@ -16,7 +16,7 @@ use layer_shika_domain::surface_dimensions::SurfaceDimensions; use log::info; use slint::{LogicalPosition, PhysicalSize, ComponentHandle}; use slint::platform::{WindowAdapter, WindowEvent}; -use slint_interpreter::ComponentInstance; +use slint_interpreter::{ComponentInstance, CompilationResult}; use smithay_client_toolkit::reexports::protocols_wlr::layer_shell::v1::client::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1; use wayland_client::{protocol::wl_surface::WlSurface, Proxy}; use wayland_protocols::wp::fractional_scale::v1::client::wp_fractional_scale_v1::WpFractionalScaleV1; @@ -89,6 +89,7 @@ impl MutableWindowState { pub struct WindowState { component_instance: ComponentInstance, + compilation_result: Option>, viewport: Option, fractional_scale: Option, layer_surface: ManagedZwlrLayerSurfaceV1, @@ -160,6 +161,7 @@ impl WindowState { Ok(Self { component_instance, + compilation_result: builder.compilation_result, viewport, fractional_scale, layer_surface, @@ -317,6 +319,11 @@ impl WindowState { &self.component_instance } + #[must_use] + pub fn compilation_result(&self) -> Option> { + self.compilation_result.as_ref().map(Rc::clone) + } + pub fn render_frame_if_dirty(&self) -> Result<()> { self.window.render_frame_if_dirty() } diff --git a/composition/src/builder.rs b/composition/src/builder.rs index 45f5d62..641af42 100644 --- a/composition/src/builder.rs +++ b/composition/src/builder.rs @@ -1,16 +1,20 @@ use crate::Result; use crate::system::WindowingSystem; -use layer_shika_adapters::platform::slint_interpreter::{Compiler, ComponentDefinition}; +use layer_shika_adapters::platform::slint_interpreter::{ + CompilationResult, Compiler, ComponentDefinition, +}; use layer_shika_domain::errors::DomainError; use layer_shika_domain::prelude::{ AnchorEdges, KeyboardInteractivity, Layer, Margins, WindowConfig, }; use spin_on::spin_on; use std::path::{Path, PathBuf}; +use std::rc::Rc; pub struct NeedsComponent; pub struct HasComponent { component_definition: ComponentDefinition, + compilation_result: Option>, } pub struct LayerShika { @@ -24,6 +28,7 @@ impl LayerShika { LayerShika { state: HasComponent { component_definition, + compilation_result: None, }, config: WindowConfig::default(), } @@ -59,17 +64,23 @@ impl LayerShika { .into()); } - let definition = compilation_result.component(component_name).ok_or_else(|| { - DomainError::Configuration { + let definition = compilation_result + .component(component_name) + .ok_or_else(|| DomainError::Configuration { message: format!( "Component '{}' not found in Slint file '{}'", component_name, path.as_ref().display() ), - } - })?; + })?; - Ok(Self::new(definition)) + Ok(LayerShika { + state: HasComponent { + component_definition: definition, + compilation_result: Some(Rc::new(compilation_result)), + }, + config: WindowConfig::default(), + }) } pub fn from_source( @@ -103,17 +114,32 @@ impl LayerShika { .into()); } - let definition = compilation_result.component(component_name).ok_or_else(|| { - DomainError::Configuration { - message: format!("Component '{}' not found in Slint source code", component_name), - } - })?; + let definition = compilation_result + .component(component_name) + .ok_or_else(|| DomainError::Configuration { + message: format!( + "Component '{}' not found in Slint source code", + component_name + ), + })?; - Ok(Self::new(definition)) + Ok(LayerShika { + state: HasComponent { + component_definition: definition, + compilation_result: Some(Rc::new(compilation_result)), + }, + config: WindowConfig::default(), + }) } } impl LayerShika { + #[must_use] + pub fn with_compilation_result(mut self, compilation_result: Rc) -> Self { + self.state.compilation_result = Some(compilation_result); + self + } + #[must_use] pub const fn with_height(mut self, height: u32) -> Self { self.config.height = height; @@ -168,6 +194,10 @@ impl LayerShika { } pub fn build(self) -> Result { - WindowingSystem::new(self.state.component_definition, self.config) + WindowingSystem::new( + self.state.component_definition, + self.state.compilation_result, + self.config, + ) } } diff --git a/composition/src/system.rs b/composition/src/system.rs index d071147..cb5d7ef 100644 --- a/composition/src/system.rs +++ b/composition/src/system.rs @@ -4,7 +4,9 @@ use layer_shika_adapters::platform::calloop::{ EventSource, Generic, Interest, Mode, PostAction, RegistrationToken, TimeoutAction, Timer, channel, }; -use layer_shika_adapters::platform::slint_interpreter::{ComponentDefinition, ComponentInstance}; +use layer_shika_adapters::platform::slint_interpreter::{ + CompilationResult, ComponentDefinition, ComponentInstance, +}; use layer_shika_adapters::wayland::{ config::WaylandWindowConfig, shell_adapter::WaylandWindowingSystem, surfaces::surface_state::WindowState, @@ -68,7 +70,10 @@ impl EventLoopHandle { }) } - pub fn add_channel(&self, mut callback: F) -> Result<(RegistrationToken, channel::Sender)> + pub fn add_channel( + &self, + mut callback: F, + ) -> Result<(RegistrationToken, channel::Sender)> where T: 'static, F: FnMut(T, RuntimeState<'_>) + 'static, @@ -82,7 +87,13 @@ impl EventLoopHandle { Ok((token, sender)) } - pub fn add_fd(&self, fd: T, interest: Interest, mode: Mode, mut callback: F) -> Result + pub fn add_fd( + &self, + fd: T, + interest: Interest, + mode: Mode, + mut callback: F, + ) -> Result where T: AsFd + 'static, F: FnMut(RuntimeState<'_>) + 'static, @@ -108,6 +119,11 @@ impl RuntimeState<'_> { pub fn render_frame_if_dirty(&mut self) -> Result<()> { Ok(self.window_state.render_frame_if_dirty()?) } + + #[must_use] + pub fn compilation_result(&self) -> Option> { + self.window_state.compilation_result() + } } pub struct WindowingSystem { @@ -117,9 +133,14 @@ pub struct WindowingSystem { impl WindowingSystem { pub(crate) fn new( component_definition: ComponentDefinition, + compilation_result: Option>, config: WindowConfig, ) -> Result { - let wayland_config = WaylandWindowConfig::from_domain_config(component_definition, config); + let wayland_config = WaylandWindowConfig::from_domain_config( + component_definition, + compilation_result, + config, + ); let inner = WaylandWindowingSystem::new(wayland_config)?; Ok(Self {