diff --git a/crates/adapters/src/lib.rs b/crates/adapters/src/lib.rs index 4159a8c..4d224e6 100644 --- a/crates/adapters/src/lib.rs +++ b/crates/adapters/src/lib.rs @@ -9,7 +9,7 @@ pub use rendering::femtovg::popup_window::PopupWindow; 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::popup_manager::PopupManager; pub use wayland::surfaces::surface_state::WindowState; pub mod platform { diff --git a/crates/adapters/src/rendering/femtovg/popup_window.rs b/crates/adapters/src/rendering/femtovg/popup_window.rs index 7a2445c..a4720b8 100644 --- a/crates/adapters/src/rendering/femtovg/popup_window.rs +++ b/crates/adapters/src/rendering/femtovg/popup_window.rs @@ -1,7 +1,8 @@ use super::renderable_window::{RenderState, RenderableWindow}; use crate::errors::{RenderingError, Result}; -use crate::wayland::surfaces::popup_manager::{OnCloseCallback, PopupId}; +use crate::wayland::surfaces::popup_manager::OnCloseCallback; use core::ops::Deref; +use layer_shika_domain::value_objects::popup_request::PopupHandle; use log::info; use slint::{ PhysicalSize, Window, WindowSize, @@ -17,7 +18,7 @@ pub struct PopupWindow { render_state: Cell, size: Cell, scale_factor: Cell, - popup_id: Cell>, + popup_handle: Cell>, on_close: OnceCell, configured: Cell, component_instance: OnceCell, @@ -34,7 +35,7 @@ impl PopupWindow { render_state: Cell::new(RenderState::Clean), size: Cell::new(PhysicalSize::default()), scale_factor: Cell::new(1.), - popup_id: Cell::new(None), + popup_handle: Cell::new(None), on_close: OnceCell::new(), configured: Cell::new(false), component_instance: OnceCell::new(), @@ -49,8 +50,8 @@ impl PopupWindow { window } - pub fn set_popup_id(&self, id: PopupId) { - self.popup_id.set(Some(id)); + pub fn set_popup_id(&self, handle: PopupHandle) { + self.popup_handle.set(Some(handle)); } pub fn close_popup(&self) { @@ -60,20 +61,20 @@ impl PopupWindow { info!("Failed to hide popup window: {e}"); } - if let Some(id) = self.popup_id.get() { - info!("Destroying popup with id {:?}", id); + if let Some(handle) = self.popup_handle.get() { + info!("Destroying popup with handle {:?}", handle); if let Some(on_close) = self.on_close.get() { - on_close(id); + on_close(handle); } } - self.popup_id.set(None); + self.popup_handle.set(None); info!("Popup window cleanup complete"); } pub fn popup_key(&self) -> Option { - self.popup_id.get().map(PopupId::key) + self.popup_handle.get().map(PopupHandle::key) } pub fn mark_configured(&self) { diff --git a/crates/adapters/src/wayland/surfaces/event_context.rs b/crates/adapters/src/wayland/surfaces/event_context.rs index 10acd54..35fe88a 100644 --- a/crates/adapters/src/wayland/surfaces/event_context.rs +++ b/crates/adapters/src/wayland/surfaces/event_context.rs @@ -130,8 +130,8 @@ impl EventContext { ActiveWindow::Main => { self.main_window.window().dispatch_event(event); } - ActiveWindow::Popup(index) => { - if let Some(popup_window) = popup_manager.get_popup_window(index) { + ActiveWindow::Popup(handle) => { + if let Some(popup_window) = popup_manager.get_popup_window(handle.key()) { popup_window.dispatch_event(event); } } diff --git a/crates/adapters/src/wayland/surfaces/popup_manager.rs b/crates/adapters/src/wayland/surfaces/popup_manager.rs index 9f8d102..92c12df 100644 --- a/crates/adapters/src/wayland/surfaces/popup_manager.rs +++ b/crates/adapters/src/wayland/surfaces/popup_manager.rs @@ -29,26 +29,31 @@ use super::surface_state::WindowState; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ActiveWindow { Main, - Popup(usize), + Popup(PopupHandle), None, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct PopupId(pub(crate) usize); +struct PopupId(usize); impl PopupId { #[must_use] - pub const fn key(self) -> usize { + const fn key(self) -> usize { self.0 } #[must_use] - pub const fn from_key(key: usize) -> Self { - Self(key) + const fn from_handle(handle: PopupHandle) -> Self { + Self(handle.key()) + } + + #[must_use] + const fn to_handle(self) -> PopupHandle { + PopupHandle::new(self.0) } } -pub type OnCloseCallback = Box; +pub type OnCloseCallback = Box; #[derive(Debug, Clone, Copy)] pub struct CreatePopupParams { @@ -291,15 +296,16 @@ impl PopupManager { let on_close: OnCloseCallback = { let weak_self = Rc::downgrade(self); - Box::new(move |id: PopupId| { + Box::new(move |handle: PopupHandle| { if let Some(manager) = weak_self.upgrade() { + let id = PopupId::from_handle(handle); manager.destroy_popup(id); } }) }; let popup_window = PopupWindow::new_with_callback(renderer, on_close); - popup_window.set_popup_id(popup_id); + popup_window.set_popup_id(popup_id.to_handle()); popup_window.set_scale_factor(scale_factor); popup_window.set_size(WindowSize::Logical(slint::LogicalSize::new( params.width, @@ -373,7 +379,7 @@ impl PopupManager { .map(|popup| Rc::clone(&popup.window)) } - pub fn destroy_popup(&self, id: PopupId) { + fn destroy_popup(&self, id: PopupId) { if let Some(popup) = self.state.borrow_mut().popups.remove(&id) { info!("Destroying popup with id {:?}", id); @@ -423,7 +429,7 @@ impl PopupManager { } pub fn close(&self, handle: PopupHandle) -> Result<()> { - let id = PopupId::from_key(handle.key()); + let id = PopupId::from_handle(handle); self.destroy_popup(id); Ok(()) } @@ -464,8 +470,11 @@ impl PopupManager { return ActiveWindow::Main; } - if let Some(popup_key) = self.find_popup_key_by_surface_id(&surface_id) { - return ActiveWindow::Popup(popup_key); + if let Some(popup_handle) = self + .find_popup_key_by_surface_id(&surface_id) + .map(PopupHandle::new) + { + return ActiveWindow::Popup(popup_handle); } ActiveWindow::None diff --git a/crates/composition/src/system.rs b/crates/composition/src/system.rs index fcb90a6..6948ef3 100644 --- a/crates/composition/src/system.rs +++ b/crates/composition/src/system.rs @@ -8,9 +8,7 @@ use layer_shika_adapters::platform::slint::{ComponentHandle, SharedString}; use layer_shika_adapters::platform::slint_interpreter::{ CompilationResult, ComponentDefinition, ComponentInstance, Value, }; -use layer_shika_adapters::{ - PopupId, PopupManager, WaylandWindowConfig, WindowState, WindowingSystemFacade, -}; +use layer_shika_adapters::{PopupManager, WaylandWindowConfig, WindowState, WindowingSystemFacade}; use layer_shika_domain::config::WindowConfig; use layer_shika_domain::errors::DomainError; use layer_shika_domain::value_objects::popup_positioning_mode::PopupPositioningMode; @@ -27,7 +25,11 @@ use std::time::{Duration, Instant}; pub enum PopupCommand { Show(PopupRequest), Close(PopupHandle), - Resize { key: usize, width: f32, height: f32 }, + Resize { + handle: PopupHandle, + width: f32, + height: f32, + }, } pub struct EventLoopHandle { @@ -197,15 +199,18 @@ impl RuntimeState<'_> { let (instance, popup_key_cell) = Self::create_popup_instance(&definition, &popup_manager, resize_sender)?; - let popup_key = popup_manager.current_popup_key().ok_or_else(|| { - Error::Domain(DomainError::Configuration { - message: "No popup key available after creation".to_string(), - }) - })?; + let popup_handle = popup_manager + .current_popup_key() + .map(PopupHandle::new) + .ok_or_else(|| { + Error::Domain(DomainError::Configuration { + message: "No popup key available after creation".to_string(), + }) + })?; - popup_key_cell.set(popup_key); + popup_key_cell.set(popup_handle.key()); - if let Some(popup_window) = popup_manager.get_popup_window(popup_key) { + if let Some(popup_window) = popup_manager.get_popup_window(popup_handle.key()) { popup_window.set_component_instance(instance); } else { return Err(Error::Domain(DomainError::Configuration { @@ -213,13 +218,12 @@ impl RuntimeState<'_> { })); } - Ok(PopupHandle::new(popup_key)) + Ok(popup_handle) } pub fn close_popup(&mut self, handle: PopupHandle) -> Result<()> { if let Some(popup_manager) = self.window_state.popup_manager() { - let id = PopupId::from_key(handle.key()); - popup_manager.destroy_popup(id); + popup_manager.close(handle)?; } Ok(()) } @@ -233,7 +237,7 @@ impl RuntimeState<'_> { pub fn resize_popup( &mut self, - key: usize, + handle: PopupHandle, width: f32, height: f32, resize_sender: Option>, @@ -248,10 +252,10 @@ impl RuntimeState<'_> { }) .cloned()?; - let Some((request, _serial)) = popup_manager.get_popup_info(key) else { + let Some((request, _serial)) = popup_manager.get_popup_info(handle.key()) else { log::debug!( - "Ignoring resize request for non-existent popup with key {}", - key + "Ignoring resize request for non-existent popup with handle {:?}", + handle ); return Ok(()); }; @@ -270,7 +274,7 @@ impl RuntimeState<'_> { height ); - self.close_popup(PopupHandle::new(key))?; + self.close_popup(handle)?; let new_request = PopupRequest::builder(request.component) .at(request.at) @@ -280,7 +284,7 @@ impl RuntimeState<'_> { self.show_popup(new_request, resize_sender)?; } else if size_changed { - if let Some(popup_window) = popup_manager.get_popup_window(key) { + if let Some(popup_window) = popup_manager.get_popup_window(handle.key()) { popup_window.request_resize(width, height); } } @@ -337,7 +341,7 @@ impl RuntimeState<'_> { if sender .send(PopupCommand::Resize { - key: popup_key, + handle: PopupHandle::new(popup_key), width, height, }) @@ -451,9 +455,13 @@ impl WindowingSystem { log::error!("Failed to close popup: {}", e); } } - PopupCommand::Resize { key, width, height } => { + PopupCommand::Resize { + handle, + width, + height, + } => { if let Err(e) = runtime_state.resize_popup( - key, + handle, width, height, Some(sender_for_handler.clone()),