diff --git a/internal/compiler/generator/rust.rs b/internal/compiler/generator/rust.rs index ee9169a2922..21856e1bc0e 100644 --- a/internal/compiler/generator/rust.rs +++ b/internal/compiler/generator/rust.rs @@ -530,9 +530,7 @@ fn generate_sub_component( let mut extra_components = component .popup_windows .iter() - .map(|c| { - generate_item_tree(c, root, Some(ParentCtx::new(&ctx, None)), quote!(), index_property) - }) + .map(|c| generate_item_tree(c, root, Some(ParentCtx::new(&ctx, None)), quote!(), None)) .collect::>(); let mut declared_property_vars = vec![]; @@ -766,17 +764,15 @@ fn generate_sub_component( let visibility = core::ptr::eq(&root.item_tree.root as *const _, component as *const _).then(|| quote!(pub)); - let access_prop = |&property_index| { - access_member( + let subtree_index_function = if let Some(property_index) = index_property { + let prop = access_member( &llr::PropertyReference::Local { sub_component_path: vec![], property_index }, &ctx, - ) + ); + quote!(#prop.get() as usize) + } else { + quote!(core::usize::MAX) }; - let prop = index_property.iter().map(access_prop); - let mut subtree_index_function = quote!(#(#prop.get() as usize)*); - if subtree_index_function.is_empty() { - subtree_index_function = quote!(core::usize::MAX); - } quote!( #[derive(slint::re_exports::FieldOffsets, Default)] diff --git a/internal/compiler/object_tree.rs b/internal/compiler/object_tree.rs index c0ef0433124..f227f09c6b3 100644 --- a/internal/compiler/object_tree.rs +++ b/internal/compiler/object_tree.rs @@ -173,7 +173,7 @@ impl Document { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct PopupWindow { pub component: Rc, pub x: NamedReference, diff --git a/internal/compiler/passes/repeater_component.rs b/internal/compiler/passes/repeater_component.rs index 3a89eb4a12d..db3ac99c15c 100644 --- a/internal/compiler/passes/repeater_component.rs +++ b/internal/compiler/passes/repeater_component.rs @@ -14,6 +14,7 @@ use std::rc::Rc; pub fn process_repeater_components(component: &Rc) { create_repeater_components(component); adjust_references(component); + adjust_popups(component); } fn create_repeater_components(component: &Rc) { @@ -113,3 +114,22 @@ fn adjust_references(comp: &Rc) { }) }); } + +fn adjust_popups(component: &Rc) { + component.popup_windows.borrow_mut().retain(|popup| { + let parent = popup + .component + .parent_element + .upgrade() + .unwrap() + .borrow() + .enclosing_component + .upgrade() + .unwrap(); + if Rc::ptr_eq(&parent, component) { + return true; + } + parent.popup_windows.borrow_mut().push(popup.clone()); + false + }); +} diff --git a/tests/cases/crashes/issue1113_popup_in_repeater.slint b/tests/cases/crashes/issue1113_popup_in_repeater.slint new file mode 100644 index 00000000000..ee19bf7ff90 --- /dev/null +++ b/tests/cases/crashes/issue1113_popup_in_repeater.slint @@ -0,0 +1,16 @@ +// Copyright © SixtyFPS GmbH +// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial + +App := Window { + for menu-item in [{children: ["hello"]}] : VerticalLayout { + Rectangle { + popup := PopupWindow { + Rectangle { + for child in menu-item.children : Rectangle { + } + } + } + } + } +} +