refactor: minor popup types

This commit is contained in:
drendog 2025-11-14 23:16:35 +01:00
parent 911f801ece
commit 65a4ff41f7
Signed by: dwenya
GPG key ID: 8DD77074645332D0
5 changed files with 66 additions and 48 deletions

View file

@ -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 {

View file

@ -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<RenderState>,
size: Cell<PhysicalSize>,
scale_factor: Cell<f32>,
popup_id: Cell<Option<PopupId>>,
popup_handle: Cell<Option<PopupHandle>>,
on_close: OnceCell<OnCloseCallback>,
configured: Cell<bool>,
component_instance: OnceCell<ComponentInstance>,
@ -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<usize> {
self.popup_id.get().map(PopupId::key)
self.popup_handle.get().map(PopupHandle::key)
}
pub fn mark_configured(&self) {

View file

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

View file

@ -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<dyn Fn(PopupId)>;
pub type OnCloseCallback = Box<dyn Fn(PopupHandle)>;
#[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

View file

@ -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(|| {
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<channel::Sender<PopupCommand>>,
@ -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()),