diff --git a/adapters/src/rendering/femtovg/popup_window.rs b/adapters/src/rendering/femtovg/popup_window.rs index 050076e..2e16a5b 100644 --- a/adapters/src/rendering/femtovg/popup_window.rs +++ b/adapters/src/rendering/femtovg/popup_window.rs @@ -3,9 +3,10 @@ use crate::wayland::surfaces::popup_manager::PopupManager; use core::ops::Deref; use log::info; use slint::{ - PhysicalSize, Window, WindowSize, + ComponentHandle, PhysicalSize, Window, WindowSize, platform::{Renderer, WindowAdapter, WindowEvent, femtovg_renderer::FemtoVGRenderer}, }; +use slint_interpreter::ComponentInstance; use std::cell::{Cell, RefCell}; use std::rc::{Rc, Weak}; @@ -20,6 +21,7 @@ pub struct PopupWindow { scale_factor: Cell, popup_manager: RefCell>, popup_key: Cell>, + component_instance: RefCell>, } #[allow(dead_code)] @@ -36,10 +38,15 @@ impl PopupWindow { scale_factor: Cell::new(1.), popup_manager: RefCell::new(Weak::new()), popup_key: Cell::new(None), + component_instance: RefCell::new(None), } }) } + pub fn set_component_instance(&self, instance: ComponentInstance) { + *self.component_instance.borrow_mut() = Some(instance); + } + pub fn set_popup_manager(&self, popup_manager: Weak, key: usize) { *self.popup_manager.borrow_mut() = popup_manager; self.popup_key.set(Some(key)); @@ -48,6 +55,13 @@ impl PopupWindow { pub fn close_popup(&self) { info!("Closing popup window - cleaning up resources"); + if let Some(instance) = self.component_instance.borrow_mut().take() { + info!("Hiding ComponentInstance to release strong reference from show()"); + if let Err(e) = instance.hide() { + info!("Failed to hide component instance: {e}"); + } + } + if let Err(e) = self.window.hide() { info!("Failed to hide popup window: {e}"); } diff --git a/adapters/src/wayland/surfaces/popup_builder.rs b/adapters/src/wayland/surfaces/popup_builder.rs index 282e7c5..64a5a7f 100644 --- a/adapters/src/wayland/surfaces/popup_builder.rs +++ b/adapters/src/wayland/surfaces/popup_builder.rs @@ -134,6 +134,14 @@ impl<'a> PopupBuilder<'a> { width, height ); + temp_instance + .hide() + .map_err(|e| LayerShikaError::WindowConfiguration { + message: format!("Failed to hide temporary instance: {}", e), + })?; + + debug!("Hidden temporary instance to release strong reference"); + Ok(PopupDimensions::new(width, height)) } diff --git a/composition/src/system.rs b/composition/src/system.rs index 9d52161..a3806f0 100644 --- a/composition/src/system.rs +++ b/composition/src/system.rs @@ -188,15 +188,23 @@ impl RuntimeState<'_> { popup_manager.set_pending_popup(req, width, height); - Self::create_popup_instance(&definition, &popup_manager)?; + let instance = Self::create_popup_instance(&definition, &popup_manager)?; - Ok(PopupHandle::new( - popup_manager.current_popup_key().ok_or_else(|| { - Error::Domain(DomainError::Configuration { - message: "No popup key available after creation".to_string(), - }) - })?, - )) + let popup_key = popup_manager.current_popup_key().ok_or_else(|| { + Error::Domain(DomainError::Configuration { + message: "No popup key available after creation".to_string(), + }) + })?; + + if let Some(popup_window) = popup_manager.get_popup_window(popup_key) { + popup_window.set_component_instance(instance); + } else { + return Err(Error::Domain(DomainError::Configuration { + message: "Popup window not found after creation".to_string(), + })); + } + + Ok(PopupHandle::new(popup_key)) } pub fn close_popup(&mut self, handle: PopupHandle) -> Result<()> { @@ -259,10 +267,12 @@ impl RuntimeState<'_> { }) })?; - let popup_manager_for_callback = Rc::clone(popup_manager); + let popup_manager_weak = Rc::downgrade(popup_manager); instance .set_callback("closed", move |_| { - popup_manager_for_callback.close_current_popup(); + if let Some(popup_manager) = popup_manager_weak.upgrade() { + popup_manager.close_current_popup(); + } Value::Void }) .map_err(|e| {