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 wayland::{
config::WaylandWindowConfig,
shell_adapter::WaylandWindowingSystem,
surfaces::{
popup_manager::{PopupId, PopupManager},
surface_state::WindowState,
},
};
pub use wayland::config::WaylandWindowConfig;
pub use wayland::facade::{PopupManagerFacade, RuntimeStateFacade, WindowingSystemFacade};
pub use wayland::shell_adapter::WaylandWindowingSystem;
pub use wayland::surfaces::popup_manager::{PopupId, PopupManager};
pub use wayland::surfaces::surface_state::WindowState;
pub mod platform {
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 event_handling;
pub(crate) mod facade;
pub(crate) mod globals;
pub(crate) mod managed_proxies;
pub(crate) mod shell_adapter;

View file

@ -267,7 +267,7 @@ impl 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 {
source: Box::new(e),
})

View file

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

View file

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