diff --git a/crates/adapters/src/rendering/femtovg/popup_window.rs b/crates/adapters/src/rendering/femtovg/popup_window.rs index 0b3f1ce..d3c0a33 100644 --- a/crates/adapters/src/rendering/femtovg/popup_window.rs +++ b/crates/adapters/src/rendering/femtovg/popup_window.rs @@ -2,6 +2,7 @@ use super::renderable_window::{RenderState, RenderableWindow}; use crate::errors::{RenderingError, Result}; use crate::wayland::surfaces::popup_manager::OnCloseCallback; use core::ops::Deref; +use layer_shika_domain::dimensions::LogicalSize; use layer_shika_domain::value_objects::handle::PopupHandle; use log::info; use slint::{ @@ -37,6 +38,7 @@ pub struct PopupWindow { on_close: OnceCell, popup_render_state: Cell, component_instance: RefCell>, + logical_size: Cell, } impl PopupWindow { @@ -54,6 +56,7 @@ impl PopupWindow { on_close: OnceCell::new(), popup_render_state: Cell::new(PopupRenderState::Unconfigured), component_instance: RefCell::new(None), + logical_size: Cell::new(LogicalSize::default()), } }) } @@ -141,10 +144,21 @@ impl PopupWindow { .dispatch_event(WindowEvent::WindowActiveChanged(true)); } - pub fn request_resize(&self, width: f32, height: f32) { - info!("Requesting popup resize to {}x{}", width, height); + pub fn request_resize(&self, width: f32, height: f32) -> bool { + let new_size = LogicalSize::from_raw(width, height); + let current_size = self.logical_size.get(); + + if current_size == new_size { + info!("Popup resize skipped - size unchanged: {}x{}", width, height); + return false; + } + + info!("Requesting popup resize from {}x{} to {}x{}", + current_size.width(), current_size.height(), width, height); + self.logical_size.set(new_size); self.set_size(WindowSize::Logical(slint::LogicalSize::new(width, height))); RenderableWindow::request_redraw(self); + true } pub fn begin_repositioning(&self) { diff --git a/crates/composition/src/system.rs b/crates/composition/src/system.rs index 1ceaa78..63b5361 100644 --- a/crates/composition/src/system.rs +++ b/crates/composition/src/system.rs @@ -903,24 +903,26 @@ impl EventDispatchContext<'_> { })?; if let Some(popup_surface) = popup_manager.get_popup_window(handle.key()) { - popup_surface.request_resize(width, height); + let size_changed = popup_surface.request_resize(width, height); - #[allow(clippy::cast_possible_truncation)] - #[allow(clippy::cast_possible_wrap)] - let logical_width = width as i32; - #[allow(clippy::cast_possible_truncation)] - #[allow(clippy::cast_possible_wrap)] - let logical_height = height as i32; + if size_changed { + #[allow(clippy::cast_possible_truncation)] + #[allow(clippy::cast_possible_wrap)] + let logical_width = width as i32; + #[allow(clippy::cast_possible_truncation)] + #[allow(clippy::cast_possible_wrap)] + let logical_height = height as i32; - popup_manager.update_popup_viewport(handle.key(), logical_width, logical_height); - popup_manager.commit_popup_surface(handle.key()); - log::debug!( - "Updated popup viewport to logical size: {}x{} (from resize to {}x{})", - logical_width, - logical_height, - width, - height - ); + popup_manager.update_popup_viewport(handle.key(), logical_width, logical_height); + popup_manager.commit_popup_surface(handle.key()); + log::debug!( + "Updated popup viewport to logical size: {}x{} (from resize to {}x{})", + logical_width, + logical_height, + width, + height + ); + } } Ok(()) @@ -1022,27 +1024,29 @@ impl EventDispatchContext<'_> { if let Some(popup_manager) = popup_manager_weak.upgrade() { if let Some(popup_surface) = popup_manager.get_popup_window(popup_key) { - popup_surface.request_resize(dimensions.width, dimensions.height); + let size_changed = popup_surface.request_resize(dimensions.width, dimensions.height); - #[allow(clippy::cast_possible_truncation)] - #[allow(clippy::cast_possible_wrap)] - let logical_width = dimensions.width as i32; - #[allow(clippy::cast_possible_truncation)] - #[allow(clippy::cast_possible_wrap)] - let logical_height = dimensions.height as i32; + if size_changed { + #[allow(clippy::cast_possible_truncation)] + #[allow(clippy::cast_possible_wrap)] + let logical_width = dimensions.width as i32; + #[allow(clippy::cast_possible_truncation)] + #[allow(clippy::cast_possible_wrap)] + let logical_height = dimensions.height as i32; - popup_manager.update_popup_viewport( - popup_key, - logical_width, - logical_height, - ); - log::debug!( - "Updated popup viewport to logical size: {}x{} (from direct resize to {}x{})", - logical_width, - logical_height, - dimensions.width, - dimensions.height - ); + popup_manager.update_popup_viewport( + popup_key, + logical_width, + logical_height, + ); + log::debug!( + "Updated popup viewport to logical size: {}x{} (from direct resize to {}x{})", + logical_width, + logical_height, + dimensions.width, + dimensions.height + ); + } } } Value::Void diff --git a/examples/simple-popup/ui/ui.slint b/examples/simple-popup/ui/ui.slint index a3cc41e..1d4b5c2 100644 --- a/examples/simple-popup/ui/ui.slint +++ b/examples/simple-popup/ui/ui.slint @@ -52,6 +52,7 @@ export component ExamplePopup inherits Window { interval: 1ms; running: true; triggered => { + resize_timer.running = false; root.resize_popup(root.preferred-width, root.preferred-height); } }