From 9252b931969eb088c1bd16ff540a461a78c4aa5e Mon Sep 17 00:00:00 2001 From: drendog Date: Sun, 2 Nov 2025 12:42:56 +0100 Subject: [PATCH] feat: add event loop ergonomic wrappers --- adapters/src/lib.rs | 4 ++- composition/src/lib.rs | 8 +++++- composition/src/system.rs | 53 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/adapters/src/lib.rs b/adapters/src/lib.rs index 7625487..62b4675 100644 --- a/adapters/src/lib.rs +++ b/adapters/src/lib.rs @@ -15,8 +15,10 @@ pub mod platform { pub mod calloop { pub use smithay_client_toolkit::reexports::calloop::channel; + pub use smithay_client_toolkit::reexports::calloop::generic::Generic; + pub use smithay_client_toolkit::reexports::calloop::timer::{TimeoutAction, Timer}; pub use smithay_client_toolkit::reexports::calloop::{ - EventSource, InsertError, PostAction, RegistrationToken, + EventSource, InsertError, Interest, Mode, PostAction, RegistrationToken, }; } } diff --git a/composition/src/lib.rs b/composition/src/lib.rs index d6432d3..6a4c4ca 100644 --- a/composition/src/lib.rs +++ b/composition/src/lib.rs @@ -10,11 +10,17 @@ use std::result::Result as StdResult; pub use builder::LayerShika; pub use layer_shika_adapters::PopupWindow; pub use layer_shika_adapters::close_current_popup; -pub use layer_shika_adapters::platform::{calloop, slint, slint_interpreter}; +pub use layer_shika_adapters::platform::{slint, slint_interpreter}; pub use layer_shika_adapters::{clear_popup_config, get_popup_config, set_popup_config}; pub use layer_shika_domain::value_objects::anchor::AnchorEdges; pub use layer_shika_domain::value_objects::popup_positioning_mode::PopupPositioningMode; +pub mod calloop { + pub use layer_shika_adapters::platform::calloop::{ + Generic, Interest, Mode, PostAction, RegistrationToken, TimeoutAction, Timer, channel, + }; +} + pub type Result = StdResult; #[derive(Debug, thiserror::Error)] diff --git a/composition/src/system.rs b/composition/src/system.rs index 81daa26..d071147 100644 --- a/composition/src/system.rs +++ b/composition/src/system.rs @@ -1,6 +1,9 @@ use crate::{Error, Result}; use layer_shika_adapters::errors::EventLoopError; -use layer_shika_adapters::platform::calloop::{EventSource, RegistrationToken}; +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::wayland::{ config::WaylandWindowConfig, shell_adapter::WaylandWindowingSystem, @@ -8,8 +11,10 @@ use layer_shika_adapters::wayland::{ }; use layer_shika_domain::config::WindowConfig; use std::cell::{Ref, RefCell}; +use std::os::unix::io::AsFd; use std::rc::{Rc, Weak}; use std::result::Result as StdResult; +use std::time::{Duration, Instant}; pub struct EventLoopHandle { system: Weak>, @@ -42,6 +47,52 @@ impl EventLoopHandle { ) }) } + + pub fn add_timer(&self, duration: Duration, mut callback: F) -> Result + where + F: FnMut(Instant, RuntimeState<'_>) -> TimeoutAction + 'static, + { + let timer = Timer::from_duration(duration); + self.insert_source(timer, move |deadline, (), runtime_state| { + callback(deadline, runtime_state) + }) + } + + pub fn add_timer_at(&self, deadline: Instant, mut callback: F) -> Result + where + F: FnMut(Instant, RuntimeState<'_>) -> TimeoutAction + 'static, + { + let timer = Timer::from_deadline(deadline); + self.insert_source(timer, move |deadline, (), runtime_state| { + callback(deadline, runtime_state) + }) + } + + pub fn add_channel(&self, mut callback: F) -> Result<(RegistrationToken, channel::Sender)> + where + T: 'static, + F: FnMut(T, RuntimeState<'_>) + 'static, + { + let (sender, receiver) = channel::channel(); + let token = self.insert_source(receiver, move |event, (), runtime_state| { + if let channel::Event::Msg(msg) = event { + callback(msg, runtime_state); + } + })?; + Ok((token, sender)) + } + + pub fn add_fd(&self, fd: T, interest: Interest, mode: Mode, mut callback: F) -> Result + where + T: AsFd + 'static, + F: FnMut(RuntimeState<'_>) + 'static, + { + let generic = Generic::new(fd, interest, mode); + self.insert_source(generic, move |_readiness, _fd, runtime_state| { + callback(runtime_state); + Ok(PostAction::Continue) + }) + } } pub struct RuntimeState<'a> {