From d646306a7a433f7c34558811fd802ff991cc2565 Mon Sep 17 00:00:00 2001 From: drendog Date: Sat, 1 Nov 2025 15:40:55 +0100 Subject: [PATCH] feat: add popup sizing --- adapters/src/lib.rs | 3 +- .../rendering/slint_integration/platform.rs | 49 ++++++++++++++++++- .../src/wayland/surfaces/popup_manager.rs | 16 ++++-- composition/src/lib.rs | 1 + 4 files changed, 62 insertions(+), 7 deletions(-) diff --git a/adapters/src/lib.rs b/adapters/src/lib.rs index d8f4f8c..e1f2f7a 100644 --- a/adapters/src/lib.rs +++ b/adapters/src/lib.rs @@ -7,7 +7,8 @@ pub mod wayland; pub use rendering::femtovg::popup_window::PopupWindow; pub use rendering::slint_integration::platform::{ clear_popup_position_override, close_current_popup, get_popup_position_override, - set_popup_position_override, + set_popup_position_override, clear_popup_size_override, get_popup_size_override, + set_popup_size_override, }; pub mod platform { diff --git a/adapters/src/rendering/slint_integration/platform.rs b/adapters/src/rendering/slint_integration/platform.rs index b105573..8ab4abe 100644 --- a/adapters/src/rendering/slint_integration/platform.rs +++ b/adapters/src/rendering/slint_integration/platform.rs @@ -34,10 +34,11 @@ pub fn set_popup_position_override(x: f32, y: f32) { }); } -#[must_use] pub fn get_popup_position_override() -> Option<(f32, f32)> { CURRENT_PLATFORM.with(|platform| { - platform.borrow().as_ref() + platform + .borrow() + .as_ref() .and_then(Weak::upgrade) .and_then(|strong| strong.get_popup_position()) }) @@ -53,12 +54,43 @@ pub fn clear_popup_position_override() { }); } +pub fn set_popup_size_override(width: f32, height: f32) { + CURRENT_PLATFORM.with(|platform| { + if let Some(weak_platform) = platform.borrow().as_ref() { + if let Some(strong_platform) = weak_platform.upgrade() { + strong_platform.set_popup_size(width, height); + } + } + }); +} + +pub fn get_popup_size_override() -> Option<(f32, f32)> { + CURRENT_PLATFORM.with(|platform| { + platform + .borrow() + .as_ref() + .and_then(Weak::upgrade) + .and_then(|strong| strong.get_popup_size()) + }) +} + +pub fn clear_popup_size_override() { + CURRENT_PLATFORM.with(|platform| { + if let Some(weak_platform) = platform.borrow().as_ref() { + if let Some(strong_platform) = weak_platform.upgrade() { + strong_platform.clear_popup_size(); + } + } + }); +} + pub struct CustomSlintPlatform { main_window: Weak, popup_creator: RefCell>>, first_call: Cell, last_popup: RefCell>>, popup_position: RefCell>, + popup_size: RefCell>, } impl CustomSlintPlatform { @@ -70,6 +102,7 @@ impl CustomSlintPlatform { first_call: Cell::new(true), last_popup: RefCell::new(None), popup_position: RefCell::new(None), + popup_size: RefCell::new(None), }); CURRENT_PLATFORM.with(|current| { @@ -112,6 +145,18 @@ impl CustomSlintPlatform { pub fn clear_popup_position(&self) { *self.popup_position.borrow_mut() = None; } + + pub fn set_popup_size(&self, width: f32, height: f32) { + *self.popup_size.borrow_mut() = Some((width, height)); + } + + pub fn get_popup_size(&self) -> Option<(f32, f32)> { + *self.popup_size.borrow() + } + + pub fn clear_popup_size(&self) { + *self.popup_size.borrow_mut() = None; + } } impl Platform for CustomSlintPlatform { diff --git a/adapters/src/wayland/surfaces/popup_manager.rs b/adapters/src/wayland/surfaces/popup_manager.rs index ce5c95a..e031fa6 100644 --- a/adapters/src/wayland/surfaces/popup_manager.rs +++ b/adapters/src/wayland/surfaces/popup_manager.rs @@ -3,6 +3,7 @@ use crate::rendering::egl::context::EGLContext; use crate::rendering::femtovg::popup_window::PopupWindow; use crate::rendering::slint_integration::platform::{ clear_popup_position_override, get_popup_position_override, + clear_popup_size_override, get_popup_size_override, }; use log::info; use slab::Slab; @@ -112,10 +113,17 @@ impl PopupManager { ); #[allow(clippy::cast_precision_loss)] - let logical_size = slint::LogicalSize::new( - output_size.width as f32 / scale_factor, - output_size.height as f32 / scale_factor, - ); + let logical_size = if let Some((width, height)) = get_popup_size_override() { + info!("Using explicit popup size: ({}, {})", width, height); + clear_popup_size_override(); + slint::LogicalSize::new(width, height) + } else { + info!("No popup size override - using full output size"); + slint::LogicalSize::new( + output_size.width as f32 / scale_factor, + output_size.height as f32 / scale_factor, + ) + }; #[allow(clippy::cast_possible_truncation)] #[allow(clippy::cast_sign_loss)] let popup_size = PhysicalSize::new( diff --git a/composition/src/lib.rs b/composition/src/lib.rs index 12298f5..45e162d 100644 --- a/composition/src/lib.rs +++ b/composition/src/lib.rs @@ -13,6 +13,7 @@ pub use layer_shika_adapters::close_current_popup; pub use layer_shika_adapters::platform::{calloop, slint, slint_interpreter}; pub use layer_shika_adapters::{ clear_popup_position_override, get_popup_position_override, set_popup_position_override, + clear_popup_size_override, get_popup_size_override, set_popup_size_override, }; pub use layer_shika_domain::value_objects::anchor::AnchorEdges;