feat: add facade for wayland adapter

This commit is contained in:
drendog 2025-11-14 21:50:41 +01:00
parent f7bf0c9b12
commit cc385fde3b
Signed by: dwenya
GPG key ID: 8DD77074645332D0
6 changed files with 181 additions and 93 deletions

View file

@ -6,14 +6,11 @@ pub(crate) mod wayland;
pub use rendering::femtovg::popup_window::PopupWindow; pub use rendering::femtovg::popup_window::PopupWindow;
pub use wayland::{ pub use wayland::config::WaylandWindowConfig;
config::WaylandWindowConfig, pub use wayland::facade::{PopupManagerFacade, RuntimeStateFacade, WindowingSystemFacade};
shell_adapter::WaylandWindowingSystem, pub use wayland::shell_adapter::WaylandWindowingSystem;
surfaces::{ pub use wayland::surfaces::popup_manager::{PopupId, PopupManager};
popup_manager::{PopupId, PopupManager}, pub use wayland::surfaces::surface_state::WindowState;
surface_state::WindowState,
},
};
pub mod platform { pub mod platform {
pub use slint; pub use slint;

View file

@ -0,0 +1,85 @@
use crate::errors::Result;
use crate::wayland::shell_adapter::WaylandWindowingSystem;
use crate::wayland::surfaces::popup_manager::PopupManager;
use crate::wayland::surfaces::surface_state::WindowState;
use layer_shika_domain::errors::DomainError;
use layer_shika_domain::ports::windowing::RuntimeStatePort;
use slint_interpreter::ComponentInstance;
use std::rc::Rc;
use std::result::Result as StdResult;
pub struct WindowingSystemFacade {
inner: WaylandWindowingSystem,
}
impl WindowingSystemFacade {
pub fn new(inner: WaylandWindowingSystem) -> Self {
Self { inner }
}
pub fn inner_ref(&self) -> &WaylandWindowingSystem {
&self.inner
}
pub fn inner_mut(&mut self) -> &mut WaylandWindowingSystem {
&mut self.inner
}
pub fn component_instance(&self) -> &ComponentInstance {
self.inner.component_instance()
}
pub fn run(&mut self) -> Result<()> {
self.inner.run()
}
}
pub struct RuntimeStateFacade<'a> {
window_state: &'a mut WindowState,
}
impl<'a> RuntimeStateFacade<'a> {
pub fn new(window_state: &'a mut WindowState) -> Self {
Self { window_state }
}
pub fn popup_manager(&self) -> Option<Rc<PopupManager>> {
self.window_state.popup_manager().cloned()
}
pub fn component_instance(&self) -> &ComponentInstance {
self.window_state.component_instance()
}
pub fn window_state(&self) -> &WindowState {
self.window_state
}
pub fn window_state_mut(&mut self) -> &mut WindowState {
self.window_state
}
}
impl RuntimeStatePort for RuntimeStateFacade<'_> {
fn render_frame_if_dirty(&mut self) -> StdResult<(), DomainError> {
self.window_state
.render_frame_if_dirty()
.map_err(|e| DomainError::Adapter {
source: Box::new(e),
})
}
}
pub struct PopupManagerFacade {
inner: Rc<PopupManager>,
}
impl PopupManagerFacade {
pub fn new(inner: Rc<PopupManager>) -> Self {
Self { inner }
}
pub fn inner(&self) -> &Rc<PopupManager> {
&self.inner
}
}

View file

@ -1,5 +1,6 @@
pub(crate) mod config; pub(crate) mod config;
pub(crate) mod event_handling; pub(crate) mod event_handling;
pub(crate) mod facade;
pub(crate) mod globals; pub(crate) mod globals;
pub(crate) mod managed_proxies; pub(crate) mod managed_proxies;
pub(crate) mod shell_adapter; pub(crate) mod shell_adapter;

View file

@ -267,7 +267,7 @@ impl WindowState {
} }
impl RuntimeStatePort for WindowState { impl RuntimeStatePort for WindowState {
fn render_frame_if_dirty(&self) -> CoreResult<(), DomainError> { fn render_frame_if_dirty(&mut self) -> CoreResult<(), DomainError> {
WindowState::render_frame_if_dirty(self).map_err(|e| DomainError::Adapter { WindowState::render_frame_if_dirty(self).map_err(|e| DomainError::Adapter {
source: Box::new(e), source: Box::new(e),
}) })

View file

@ -9,7 +9,7 @@ use layer_shika_adapters::platform::slint_interpreter::{
CompilationResult, ComponentDefinition, ComponentInstance, Value, CompilationResult, ComponentDefinition, ComponentInstance, Value,
}; };
use layer_shika_adapters::{ use layer_shika_adapters::{
PopupId, PopupManager, WaylandWindowConfig, WaylandWindowingSystem, WindowState, PopupId, PopupManager, WaylandWindowConfig, WindowState, WindowingSystemFacade,
}; };
use layer_shika_domain::config::WindowConfig; use layer_shika_domain::config::WindowConfig;
use layer_shika_domain::errors::DomainError; use layer_shika_domain::errors::DomainError;
@ -18,7 +18,7 @@ use layer_shika_domain::value_objects::popup_request::{
PopupAt, PopupHandle, PopupRequest, PopupSize, PopupAt, PopupHandle, PopupRequest, PopupSize,
}; };
use std::cell::Cell; use std::cell::Cell;
use std::cell::{Ref, RefCell}; use std::cell::RefCell;
use std::os::unix::io::AsFd; use std::os::unix::io::AsFd;
use std::rc::{Rc, Weak}; use std::rc::{Rc, Weak};
use std::result::Result as StdResult; use std::result::Result as StdResult;
@ -31,7 +31,7 @@ pub enum PopupCommand {
} }
pub struct EventLoopHandle { pub struct EventLoopHandle {
system: Weak<RefCell<WaylandWindowingSystem>>, system: Weak<RefCell<WindowingSystemFacade>>,
} }
impl EventLoopHandle { impl EventLoopHandle {
@ -45,7 +45,7 @@ impl EventLoopHandle {
F: FnMut(S::Event, &mut S::Metadata, RuntimeState<'_>) -> R + 'static, F: FnMut(S::Event, &mut S::Metadata, RuntimeState<'_>) -> R + 'static,
{ {
let system = self.system.upgrade().ok_or(Error::SystemDropped)?; let system = self.system.upgrade().ok_or(Error::SystemDropped)?;
let loop_handle = system.borrow().event_loop_handle(); let loop_handle = system.borrow().inner_ref().event_loop_handle();
loop_handle loop_handle
.insert_source(source, move |event, metadata, window_state| { .insert_source(source, move |event, metadata, window_state| {
@ -395,7 +395,7 @@ impl RuntimeState<'_> {
} }
pub struct WindowingSystem { pub struct WindowingSystem {
inner: Rc<RefCell<WaylandWindowingSystem>>, inner: Rc<RefCell<WindowingSystemFacade>>,
popup_positioning_mode: Rc<RefCell<PopupPositioningMode>>, popup_positioning_mode: Rc<RefCell<PopupPositioningMode>>,
popup_command_sender: channel::Sender<PopupCommand>, popup_command_sender: channel::Sender<PopupCommand>,
} }
@ -411,8 +411,9 @@ impl WindowingSystem {
compilation_result, compilation_result,
config, config,
); );
let inner = WaylandWindowingSystem::new(wayland_config)?; let inner = layer_shika_adapters::WaylandWindowingSystem::new(wayland_config)?;
let inner_rc = Rc::new(RefCell::new(inner)); let facade = WindowingSystemFacade::new(inner);
let inner_rc = Rc::new(RefCell::new(facade));
let (sender, receiver) = channel::channel(); let (sender, receiver) = channel::channel();
@ -429,7 +430,7 @@ impl WindowingSystem {
} }
fn setup_popup_command_handler(&self, receiver: channel::Channel<PopupCommand>) -> Result<()> { fn setup_popup_command_handler(&self, receiver: channel::Channel<PopupCommand>) -> Result<()> {
let loop_handle = self.inner.borrow().event_loop_handle(); let loop_handle = self.inner.borrow().inner_ref().event_loop_handle();
let sender_for_handler = self.popup_command_sender.clone(); let sender_for_handler = self.popup_command_sender.clone();
loop_handle loop_handle
@ -476,8 +477,7 @@ impl WindowingSystem {
} }
fn register_popup_callbacks(&self) -> Result<()> { fn register_popup_callbacks(&self) -> Result<()> {
let component_instance = self.component_instance(); self.with_component_instance(|component_instance| {
let popup_mode_clone = Rc::clone(&self.popup_positioning_mode); let popup_mode_clone = Rc::clone(&self.popup_positioning_mode);
component_instance component_instance
.set_callback("set_popup_positioning_mode", move |args| { .set_callback("set_popup_positioning_mode", move |args| {
@ -507,8 +507,10 @@ impl WindowingSystem {
e e
), ),
}) })
})
})?; })?;
self.with_component_instance(|component_instance| {
let sender = self.popup_command_sender.clone(); let sender = self.popup_command_sender.clone();
let popup_mode_for_callback = Rc::clone(&self.popup_positioning_mode); let popup_mode_for_callback = Rc::clone(&self.popup_positioning_mode);
@ -550,6 +552,7 @@ impl WindowingSystem {
Error::Domain(DomainError::Configuration { Error::Domain(DomainError::Configuration {
message: format!("Failed to register show_popup callback: {}", e), message: format!("Failed to register show_popup callback: {}", e),
}) })
})
})?; })?;
Ok(()) Ok(())
@ -587,8 +590,10 @@ impl WindowingSystem {
Ok(()) Ok(())
} }
#[must_use] pub fn with_component_instance<F, R>(&self, f: F) -> R
pub fn component_instance(&self) -> Ref<'_, ComponentInstance> { where
Ref::map(self.inner.borrow(), |system| system.component_instance()) F: FnOnce(&ComponentInstance) -> R,
{
f(self.inner.borrow().component_instance())
} }
} }

View file

@ -5,5 +5,5 @@ pub trait WindowingSystemPort {
} }
pub trait RuntimeStatePort { pub trait RuntimeStatePort {
fn render_frame_if_dirty(&self) -> Result<(), DomainError>; fn render_frame_if_dirty(&mut self) -> Result<(), DomainError>;
} }