From 0aa0aeae0b8ee6eeee48141556d1a8be5b8fc396 Mon Sep 17 00:00:00 2001 From: drendog Date: Sun, 7 Dec 2025 02:11:47 +0100 Subject: [PATCH] refactor: add more abstraction level of event loop integration --- crates/composition/src/event_loop.rs | 25 ++++++++++++++-- crates/composition/src/layer_shika.rs | 6 ++-- crates/composition/src/lib.rs | 17 +++++------ crates/composition/src/shell.rs | 14 ++++----- crates/composition/src/system.rs | 41 +++++++++++++++++++++++---- src/event.rs | 2 +- src/lib.rs | 4 +-- src/prelude.rs | 4 +-- src/shell.rs | 2 +- 9 files changed, 78 insertions(+), 37 deletions(-) diff --git a/crates/composition/src/event_loop.rs b/crates/composition/src/event_loop.rs index 7482658..adb3ba4 100644 --- a/crates/composition/src/event_loop.rs +++ b/crates/composition/src/event_loop.rs @@ -7,18 +7,37 @@ use layer_shika_adapters::platform::calloop::{ use layer_shika_adapters::{AppState, WaylandSystemOps}; use std::cell::RefCell; use std::os::unix::io::AsFd; -use std::rc::Weak; +use std::rc::{Rc, Weak}; use std::time::{Duration, Instant}; pub trait FromAppState<'a> { fn from_app_state(app_state: &'a mut AppState) -> Self; } -pub struct EventLoopHandleBase { +pub struct ShellEventLoop { + inner: Rc>, +} + +impl ShellEventLoop { + pub fn new(inner: Rc>) -> Self { + Self { inner } + } + + pub fn run(&mut self) -> Result<()> { + self.inner.borrow_mut().run()?; + Ok(()) + } + + pub fn get_handle(&self) -> EventLoopHandle { + EventLoopHandle::new(Rc::downgrade(&self.inner)) + } +} + +pub struct EventLoopHandle { system: Weak>, } -impl EventLoopHandleBase { +impl EventLoopHandle { pub fn new(system: Weak>) -> Self { Self { system } } diff --git a/crates/composition/src/layer_shika.rs b/crates/composition/src/layer_shika.rs index 3f3e511..67ba778 100644 --- a/crates/composition/src/layer_shika.rs +++ b/crates/composition/src/layer_shika.rs @@ -1,4 +1,4 @@ -use crate::event_loop::{EventLoopHandleBase, FromAppState}; +use crate::event_loop::{EventLoopHandle, FromAppState}; use crate::popup_builder::PopupBuilder; use crate::shell::LayerSurfaceHandle; use crate::shell_runtime::ShellRuntime; @@ -447,7 +447,7 @@ impl Runtime { loop_handle .insert_source(receiver, move |event, (), app_state| { if let channel::Event::Msg(command) = event { - let mut ctx = crate::system::EventContext::from_app_state(app_state); + let mut ctx = crate::system::EventDispatchContext::from_app_state(app_state); match command { PopupCommand::Show(request) => { @@ -815,8 +815,6 @@ impl ShellRuntime for Runtime { } } -pub type EventLoopHandle = EventLoopHandleBase; - pub struct EventContext<'a> { app_state: &'a mut AppState, } diff --git a/crates/composition/src/lib.rs b/crates/composition/src/lib.rs index 83dd4a0..aac65db 100644 --- a/crates/composition/src/lib.rs +++ b/crates/composition/src/lib.rs @@ -14,6 +14,7 @@ use layer_shika_adapters::errors::LayerShikaError; use layer_shika_domain::errors::DomainError; use std::result::Result as StdResult; +pub use event_loop::{EventLoopHandle, ShellEventLoop}; pub use layer_shika_adapters::PopupWindow; pub use layer_shika_adapters::platform::{slint, slint_interpreter}; pub use layer_shika_domain::entities::output_registry::OutputRegistry; @@ -29,16 +30,14 @@ pub use layer_shika_domain::value_objects::popup_positioning_mode::PopupPosition pub use layer_shika_domain::value_objects::popup_request::{ PopupHandle, PopupPlacement, PopupRequest, PopupSize, }; +pub use layer_surface::{LayerSurfaceHandle, ShellSurfaceConfigHandler}; pub use popup_builder::PopupBuilder; pub use shell_runtime::{DEFAULT_SURFACE_NAME, ShellRuntime}; -pub use system::{EventContext, EventLoopHandle, ShellControl}; +pub use system::{EventDispatchContext, ShellControl}; pub use value_conversion::IntoValue; -pub use layer_surface::{LayerSurfaceHandle, ShellSurfaceConfigHandler}; - pub use shell::{ - DEFAULT_COMPONENT_NAME, Shell, ShellBuilder, ShellEventContext, ShellEventLoopHandle, - SurfaceConfigBuilder, + DEFAULT_COMPONENT_NAME, Shell, ShellBuilder, ShellEventContext, SurfaceConfigBuilder, }; pub use surface_registry::{SurfaceDefinition, SurfaceEntry, SurfaceMetadata, SurfaceRegistry}; @@ -46,9 +45,7 @@ pub use surface_registry::{SurfaceDefinition, SurfaceEntry, SurfaceMetadata, Sur pub use shell_config::{CompiledUiSource, ShellConfig, SurfaceComponentConfig}; pub mod calloop { - pub use layer_shika_adapters::platform::calloop::{ - Generic, Interest, Mode, PostAction, RegistrationToken, TimeoutAction, Timer, channel, - }; + pub use layer_shika_adapters::platform::calloop::*; } pub type Result = StdResult; @@ -68,11 +65,11 @@ pub enum Error { pub mod prelude { pub use crate::{ AnchorEdges, AnchorStrategy, CompiledUiSource, DEFAULT_COMPONENT_NAME, - DEFAULT_SURFACE_NAME, EventContext, EventLoopHandle, Handle, IntoValue, + DEFAULT_SURFACE_NAME, EventDispatchContext, EventLoopHandle, Handle, IntoValue, KeyboardInteractivity, Layer, LayerSurfaceHandle, OutputGeometry, OutputHandle, OutputInfo, OutputPolicy, OutputRegistry, PopupBuilder, PopupHandle, PopupPlacement, PopupPositioningMode, PopupRequest, PopupSize, PopupWindow, Result, Shell, ShellBuilder, - ShellConfig, ShellControl, ShellEventContext, ShellEventLoopHandle, ShellRuntime, + ShellConfig, ShellControl, ShellEventContext, ShellEventLoop, ShellRuntime, ShellSurfaceConfigHandler, SurfaceComponentConfig, SurfaceConfigBuilder, SurfaceDefinition, SurfaceEntry, SurfaceHandle, SurfaceMetadata, SurfaceRegistry, }; diff --git a/crates/composition/src/shell.rs b/crates/composition/src/shell.rs index 6637eca..2ab0ee0 100644 --- a/crates/composition/src/shell.rs +++ b/crates/composition/src/shell.rs @@ -1,4 +1,4 @@ -use crate::event_loop::{EventLoopHandleBase, FromAppState}; +use crate::event_loop::{EventLoopHandle, FromAppState}; use crate::layer_surface::LayerSurfaceHandle; use crate::popup_builder::PopupBuilder; use crate::shell_config::{CompiledUiSource, ShellConfig}; @@ -485,7 +485,7 @@ impl Shell { loop_handle .insert_source(receiver, move |event, (), app_state| { if let channel::Event::Msg(command) = event { - let mut ctx = crate::system::EventContext::from_app_state(app_state); + let mut ctx = crate::system::EventDispatchContext::from_app_state(app_state); match command { PopupCommand::Show(request) => { @@ -535,8 +535,8 @@ impl Shell { self.registry.contains_name(name) } - pub fn event_loop_handle(&self) -> ShellEventLoopHandle { - ShellEventLoopHandle::new(Rc::downgrade(&self.inner)) + pub fn event_loop_handle(&self) -> EventLoopHandle { + EventLoopHandle::new(Rc::downgrade(&self.inner)) } pub fn run(&mut self) -> Result<()> { @@ -887,11 +887,11 @@ impl Shell { } impl ShellRuntime for Shell { - type LoopHandle = ShellEventLoopHandle; + type LoopHandle = EventLoopHandle; type Context<'a> = ShellEventContext<'a>; fn event_loop_handle(&self) -> Self::LoopHandle { - ShellEventLoopHandle::new(Rc::downgrade(&self.inner)) + EventLoopHandle::new(Rc::downgrade(&self.inner)) } fn with_component(&self, name: &str, mut f: F) @@ -926,8 +926,6 @@ impl ShellRuntime for Shell { } } -pub type ShellEventLoopHandle = EventLoopHandleBase; - pub struct ShellEventContext<'a> { app_state: &'a mut AppState, } diff --git a/crates/composition/src/system.rs b/crates/composition/src/system.rs index 34724b8..188862b 100644 --- a/crates/composition/src/system.rs +++ b/crates/composition/src/system.rs @@ -1,4 +1,4 @@ -use crate::event_loop::{EventLoopHandleBase, FromAppState}; +use crate::event_loop::FromAppState; use crate::{Error, Result}; use layer_shika_adapters::platform::calloop::channel; use layer_shika_adapters::platform::slint::ComponentHandle; @@ -98,13 +98,11 @@ impl ShellControl { } } -pub type EventLoopHandle = EventLoopHandleBase; - -pub struct EventContext<'a> { +pub struct EventDispatchContext<'a> { app_state: &'a mut AppState, } -impl<'a> FromAppState<'a> for EventContext<'a> { +impl<'a> FromAppState<'a> for EventDispatchContext<'a> { fn from_app_state(app_state: &'a mut AppState) -> Self { Self { app_state } } @@ -122,7 +120,38 @@ fn extract_dimensions_from_callback(args: &[Value]) -> PopupDimensions { ) } -impl EventContext<'_> { +impl EventDispatchContext<'_> { + pub fn with_surface(&self, name: &str, f: F) -> Result + where + F: FnOnce(&ComponentInstance) -> R, + { + let component = self.get_surface_component(name).ok_or_else(|| { + Error::Domain(DomainError::Configuration { + message: format!("Surface '{}' not found", name), + }) + })?; + Ok(f(component)) + } + + pub fn with_output(&self, handle: OutputHandle, f: F) -> Result + where + F: FnOnce(&ComponentInstance) -> R, + { + let component = self.get_output_component(handle).ok_or_else(|| { + Error::Domain(DomainError::Configuration { + message: format!("Output with handle {:?} not found", handle), + }) + })?; + Ok(f(component)) + } + + fn get_surface_component(&self, name: &str) -> Option<&ComponentInstance> { + self.app_state + .surfaces_by_name(name) + .next() + .map(SurfaceState::component_instance) + } + #[must_use] pub fn component_instance(&self) -> Option<&ComponentInstance> { self.app_state diff --git a/src/event.rs b/src/event.rs index fe696e5..90363e0 100644 --- a/src/event.rs +++ b/src/event.rs @@ -1 +1 @@ -pub use layer_shika_composition::{EventContext, EventLoopHandle}; +pub use layer_shika_composition::{EventDispatchContext, EventLoopHandle, ShellEventLoop}; diff --git a/src/lib.rs b/src/lib.rs index 00b12ce..0e64ba8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -122,7 +122,7 @@ pub use layer_shika_composition::{Error, Handle, Result, SurfaceHandle}; pub use shell::{ CompiledUiSource, DEFAULT_COMPONENT_NAME, DEFAULT_SURFACE_NAME, LayerSurfaceHandle, Shell, - ShellBuilder, ShellConfig, ShellControl, ShellEventContext, ShellEventLoopHandle, ShellRuntime, + ShellBuilder, ShellConfig, ShellControl, ShellEventContext, ShellRuntime, ShellSurfaceConfigHandler, SurfaceComponentConfig, SurfaceConfigBuilder, SurfaceDefinition, }; @@ -133,7 +133,7 @@ pub use window::{ pub use output::{OutputGeometry, OutputHandle, OutputInfo, OutputPolicy, OutputRegistry}; -pub use event::{EventContext, EventLoopHandle}; +pub use event::{EventDispatchContext, EventLoopHandle, ShellEventLoop}; pub use slint_integration::{PopupWindow, slint, slint_interpreter}; diff --git a/src/prelude.rs b/src/prelude.rs index da981af..89743a7 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -10,7 +10,7 @@ pub use crate::shell::{ CompiledUiSource, DEFAULT_COMPONENT_NAME, DEFAULT_SURFACE_NAME, LayerSurfaceHandle, Shell, - ShellBuilder, ShellConfig, ShellControl, ShellEventContext, ShellEventLoopHandle, ShellRuntime, + ShellBuilder, ShellConfig, ShellControl, ShellEventContext, ShellRuntime, ShellSurfaceConfigHandler, SurfaceComponentConfig, SurfaceConfigBuilder, SurfaceDefinition, }; @@ -21,7 +21,7 @@ pub use crate::window::{ pub use crate::output::{OutputGeometry, OutputHandle, OutputInfo, OutputPolicy, OutputRegistry}; -pub use crate::event::{EventContext, EventLoopHandle}; +pub use crate::event::{EventDispatchContext, EventLoopHandle, ShellEventLoop}; pub use crate::slint_integration::{PopupWindow, slint, slint_interpreter}; diff --git a/src/shell.rs b/src/shell.rs index a2c5cd1..1825a5c 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -1,5 +1,5 @@ pub use layer_shika_composition::{ CompiledUiSource, DEFAULT_COMPONENT_NAME, DEFAULT_SURFACE_NAME, LayerSurfaceHandle, Shell, - ShellBuilder, ShellConfig, ShellControl, ShellEventContext, ShellEventLoopHandle, ShellRuntime, + ShellBuilder, ShellConfig, ShellControl, ShellEventContext, ShellRuntime, ShellSurfaceConfigHandler, SurfaceComponentConfig, SurfaceConfigBuilder, SurfaceDefinition, };