refactor: add more abstraction level of event loop integration

This commit is contained in:
drendog 2025-12-07 02:11:47 +01:00
parent ebc630b6dc
commit 0aa0aeae0b
Signed by: dwenya
GPG key ID: 8DD77074645332D0
9 changed files with 78 additions and 37 deletions

View file

@ -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<RefCell<dyn WaylandSystemOps>>,
}
impl ShellEventLoop {
pub fn new(inner: Rc<RefCell<dyn WaylandSystemOps>>) -> 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<RefCell<dyn WaylandSystemOps>>,
}
impl EventLoopHandleBase {
impl EventLoopHandle {
pub fn new(system: Weak<RefCell<dyn WaylandSystemOps>>) -> Self {
Self { system }
}

View file

@ -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,
}

View file

@ -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<T> = StdResult<T, Error>;
@ -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,
};

View file

@ -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<F>(&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,
}

View file

@ -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<F, R>(&self, name: &str, f: F) -> Result<R>
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<F, R>(&self, handle: OutputHandle, f: F) -> Result<R>
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

View file

@ -1 +1 @@
pub use layer_shika_composition::{EventContext, EventLoopHandle};
pub use layer_shika_composition::{EventDispatchContext, EventLoopHandle, ShellEventLoop};

View file

@ -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};

View file

@ -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};

View file

@ -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,
};