Skip to content

Commit 973917c

Browse files
authored
Close active sibling popups before creating a new one (#9178)
Fixes #8891
1 parent be2b653 commit 973917c

File tree

2 files changed

+114
-132
lines changed

2 files changed

+114
-132
lines changed

internal/core/window.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,7 @@ impl WindowInner {
12011201
Some(x) => item_tree = x.item_tree().clone(),
12021202
}
12031203
};
1204+
12041205
let parent_root_item_tree = root_of(parent_item.item_tree().clone());
12051206
let (parent_window_adapter, position) = if let Some(parent_popup) = self
12061207
.active_popups
@@ -1257,6 +1258,19 @@ impl WindowInner {
12571258
let popup_id = self.next_popup_id.get();
12581259
self.next_popup_id.set(self.next_popup_id.get().checked_add(1).unwrap());
12591260

1261+
// Close active popups before creating a new one.
1262+
let siblings: Vec<_> = self
1263+
.active_popups
1264+
.borrow()
1265+
.iter()
1266+
.filter(|p| p.parent_item == parent_item.downgrade())
1267+
.map(|p| p.popup_id)
1268+
.collect();
1269+
1270+
for sibling in siblings {
1271+
self.close_popup(sibling);
1272+
}
1273+
12601274
let location = match parent_window_adapter
12611275
.internal(crate::InternalToken)
12621276
.and_then(|x| x.create_popup(LogicalRect::new(position, size)))

tests/cases/elements/popupwindow_nested.slint

Lines changed: 100 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,6 @@ export component TestCase inherits Window {
105105
popup2.show();
106106
}
107107
}
108-
Button {
109-
text: "Open two popups";
110-
clicked => {
111-
popup1.show();
112-
popup2.show();
113-
}
114-
}
115108
}
116109
}
117110

@@ -148,6 +141,7 @@ export component TestCase inherits Window {
148141
border-color: pink;
149142
background: orange;
150143
}
144+
151145
VerticalLayout {
152146
padding: 3px;
153147
ComboBox {
@@ -156,6 +150,7 @@ export component TestCase inherits Window {
156150
result += value;
157151
}
158152
}
153+
159154
HorizontalLayout {
160155
Button {
161156
text: "close this";
@@ -164,13 +159,7 @@ export component TestCase inherits Window {
164159
popup2.close();
165160
}
166161
}
167-
Button {
168-
text: "close popup1";
169-
clicked => {
170-
result += "C1";
171-
popup1.close();
172-
}
173-
}
162+
174163
Button {
175164
text: "open popup1";
176165
clicked => {
@@ -180,6 +169,7 @@ export component TestCase inherits Window {
180169
}
181170
}
182171
}
172+
183173
close-policy: no-auto-close;
184174
}
185175
}
@@ -190,14 +180,24 @@ export component TestCase inherits Window {
190180
use slint::{platform::WindowEvent, platform::PointerEventButton, LogicalPosition};
191181
let instance = TestCase::new().unwrap();
192182
193-
// open both popups
194-
slint_testing::send_mouse_click(&instance, 380., 10.);
183+
// open popup1
184+
slint_testing::send_mouse_click(&instance, 10., 10.);
195185
196-
// clicking in P1 doesn nothing
186+
// check P1 is open
197187
slint_testing::send_mouse_click(&instance, 210., 90.);
188+
assert_eq!(instance.get_result(), "P1");
189+
instance.set_result("".into());
190+
191+
// click outside
192+
slint_testing::send_mouse_click(&instance, 20., 310.);
198193
assert_eq!(instance.get_result(), "");
194+
slint_testing::send_mouse_click(&instance, 20., 310.);
195+
assert_eq!(instance.get_result(), "Root");
196+
instance.set_result("".into());
199197
200-
// go in the popup1 combobox
198+
// open popup2
199+
slint_testing::send_mouse_click(&instance, 210., 10.);
200+
// go in the popup2 combobox
201201
slint_testing::send_mouse_click(&instance, 40., 210.);
202202
slint_testing::send_mouse_click(&instance, 40., 210. + 40.);
203203
assert_eq!(instance.get_result(), "Aaaa");
@@ -207,39 +207,23 @@ instance.set_result("".into());
207207
slint_testing::send_mouse_click(&instance, 40., 210. + 40.);
208208
assert_eq!(instance.get_result(), "C2");
209209
instance.set_result("".into());
210-
// clicking in P1
211-
slint_testing::send_mouse_click(&instance, 210., 90.);
212-
assert_eq!(instance.get_result(), "P1");
213-
instance.set_result("".into());
214-
// open P1 combobox
210+
211+
// open popup1
212+
slint_testing::send_mouse_click(&instance, 10., 10.);
213+
214+
// open P1 combobox and select first
215215
slint_testing::send_mouse_click(&instance, 210., 60.);
216216
slint_testing::send_mouse_click(&instance, 210., 60. + 40.);
217217
assert_eq!(instance.get_result(), "First");
218218
instance.set_result("".into());
219-
slint_testing::send_mouse_click(&instance, 210., 90.);
220-
assert_eq!(instance.get_result(), "P1");
221-
instance.set_result("".into());
222219
223-
// click outside
224-
slint_testing::send_mouse_click(&instance, 20., 310.);
225-
assert_eq!(instance.get_result(), "");
226-
slint_testing::send_mouse_click(&instance, 20., 310.);
227-
assert_eq!(instance.get_result(), "Root");
228-
instance.set_result("".into());
229-
230-
// open popup2
231-
slint_testing::send_mouse_click(&instance, 200., 10.);
232-
assert_eq!(instance.get_result(), "");
233-
// open popup1 from popup2
234-
slint_testing::send_mouse_click(&instance, 300., 210. + 40.);
235-
assert_eq!(instance.get_result(), "O1");
236-
instance.set_result("".into());
237-
238-
// open P1 combobox
220+
// open it again
239221
slint_testing::send_mouse_click(&instance, 210., 60.);
222+
240223
// click outside closes the combobox
241224
slint_testing::send_mouse_click(&instance, 20., 310.);
242225
assert_eq!(instance.get_result(), "");
226+
243227
// but P1 is still open
244228
slint_testing::send_mouse_click(&instance, 210., 90.);
245229
assert_eq!(instance.get_result(), "P1");
@@ -249,76 +233,74 @@ instance.set_result("".into());
249233
slint_testing::send_mouse_click(&instance, 20., 310.);
250234
assert_eq!(instance.get_result(), "");
251235
252-
// but p2 is still open
253-
// Open its combobox
254-
slint_testing::send_mouse_click(&instance, 40., 210.);
255-
// but click outside closes it
256-
slint_testing::send_mouse_click(&instance, 210., 90.);
236+
// open popup2
237+
slint_testing::send_mouse_click(&instance, 210., 10.);
257238
assert_eq!(instance.get_result(), "");
258239
259-
// "close this" closes p2
260-
slint_testing::send_mouse_click(&instance, 40., 210. + 40.);
261-
assert_eq!(instance.get_result(), "C2");
262-
instance.set_result("".into());
263-
264-
slint_testing::send_mouse_click(&instance, 20., 310.);
265-
assert_eq!(instance.get_result(), "Root");
266-
instance.set_result("".into());
267-
268-
// open both popups
269-
slint_testing::send_mouse_click(&instance, 380., 10.);
240+
// open its combobox
241+
slint_testing::send_mouse_click(&instance, 40., 210.);
270242
271-
// close popup1
272-
slint_testing::send_mouse_click(&instance, 150., 210. + 40.);
273-
assert_eq!(instance.get_result(), "C1");
274-
instance.set_result("".into());
243+
// click outside closes it
244+
slint_testing::send_mouse_click(&instance, 210., 90.);
245+
assert_eq!(instance.get_result(), "");
275246
276-
// popup2 is still open and can be closed
247+
// but P2 is still open, so open its combobox again
248+
slint_testing::send_mouse_click(&instance, 40., 210.);
277249
slint_testing::send_mouse_click(&instance, 40., 210. + 40.);
278-
assert_eq!(instance.get_result(), "C2");
250+
assert_eq!(instance.get_result(), "Aaaa");
279251
instance.set_result("".into());
280252
281-
// open both popups
282-
slint_testing::send_mouse_click(&instance, 380., 10.);
283-
284-
// close popup2
285-
slint_testing::send_mouse_click(&instance, 40., 210. + 40.);
286-
assert_eq!(instance.get_result(), "C2");
253+
// open popup1 from popup2
254+
slint_testing::send_mouse_click(&instance, 300., 210. + 40.);
255+
assert_eq!(instance.get_result(), "O1");
287256
instance.set_result("".into());
288257
289-
// popup1 is still open
258+
// check P1 is open
290259
slint_testing::send_mouse_click(&instance, 210., 90.);
291260
assert_eq!(instance.get_result(), "P1");
292261
instance.set_result("".into());
293262
294-
// close popup1
295-
slint_testing::send_mouse_click(&instance, 150., 210. + 40.);
263+
// by opening P1, P2 should be automatically closed
264+
slint_testing::send_mouse_click(&instance, 40., 210.);
265+
assert_eq!(instance.get_result(), "");
266+
slint_testing::send_mouse_click(&instance, 40., 210.);
267+
assert_eq!(instance.get_result(), "Root");
268+
instance.set_result("".into());
296269
297-
// open both popups
298-
slint_testing::send_mouse_click(&instance, 380., 10.);
270+
// open popup1
271+
slint_testing::send_mouse_click(&instance, 10., 10.);
299272
300273
// close popup1 by esc
301274
slint_testing::send_keyboard_string_sequence(&instance, "\u{001b}");
302275
303-
// popup2 is still open
304-
slint_testing::send_mouse_click(&instance, 40., 210. + 40.);
305-
assert_eq!(instance.get_result(), "C2");
276+
// check P1 is closed
277+
slint_testing::send_mouse_click(&instance, 210., 90.);
278+
assert_eq!(instance.get_result(), "Root");
306279
instance.set_result("".into());
307-
308280
```
309281
310282
```cpp
311283
auto handle = TestCase::create();
312284
TestCase &instance = *handle;
313285
314-
// open both popups
315-
slint_testing::send_mouse_click(&instance, 380., 10.);
286+
// open popup1
287+
slint_testing::send_mouse_click(&instance, 10., 10.);
316288
317-
// clicking in P1 doesn nothing
289+
// check P1 is open
318290
slint_testing::send_mouse_click(&instance, 210., 90.);
291+
assert_eq(instance.get_result(), "P1");
292+
instance.set_result("");
293+
294+
// click outside
295+
slint_testing::send_mouse_click(&instance, 20., 310.);
319296
assert_eq(instance.get_result(), "");
297+
slint_testing::send_mouse_click(&instance, 20., 310.);
298+
assert_eq(instance.get_result(), "Root");
299+
instance.set_result("");
320300
321-
// go in the popup1 combobox
301+
// open popup2
302+
slint_testing::send_mouse_click(&instance, 210., 10.);
303+
// go in the popup2 combobox
322304
slint_testing::send_mouse_click(&instance, 40., 210.);
323305
slint_testing::send_mouse_click(&instance, 40., 210. + 40.);
324306
assert_eq(instance.get_result(), "Aaaa");
@@ -328,40 +310,23 @@ instance.set_result("");
328310
slint_testing::send_mouse_click(&instance, 40., 210. + 40.);
329311
assert_eq(instance.get_result(), "C2");
330312
instance.set_result("");
331-
// clicking in P1
332-
slint_testing::send_mouse_click(&instance, 210., 90.);
333-
assert_eq(instance.get_result(), "P1");
334-
instance.set_result("");
335-
// open P1 combobox
313+
314+
// open popup1
315+
slint_testing::send_mouse_click(&instance, 10., 10.);
316+
317+
// open P1 combobox and select first
336318
slint_testing::send_mouse_click(&instance, 210., 60.);
337319
slint_testing::send_mouse_click(&instance, 210., 60. + 40.);
338320
assert_eq(instance.get_result(), "First");
339321
instance.set_result("");
340-
slint_testing::send_mouse_click(&instance, 210., 90.);
341-
assert_eq(instance.get_result(), "P1");
342-
instance.set_result("");
343-
344-
// click outside
345-
slint_testing::send_mouse_click(&instance, 20., 310.);
346-
assert_eq(instance.get_result(), "");
347-
slint_testing::send_mouse_click(&instance, 20., 310.);
348-
assert_eq(instance.get_result(), "Root");
349-
instance.set_result("");
350-
351-
// open popup2
352-
slint_testing::send_mouse_click(&instance, 200., 10.);
353-
assert_eq(instance.get_result(), "");
354-
// open popup1 from popup2
355-
slint_testing::send_mouse_click(&instance, 20., 310.);
356-
slint_testing::send_mouse_click(&instance, 300., 210. + 35.);
357-
assert_eq(instance.get_result(), "O1");
358-
instance.set_result("");
359322
360-
// open P1 combobox
323+
// open it again
361324
slint_testing::send_mouse_click(&instance, 210., 60.);
325+
362326
// click outside closes the combobox
363327
slint_testing::send_mouse_click(&instance, 20., 310.);
364328
assert_eq(instance.get_result(), "");
329+
365330
// but P1 is still open
366331
slint_testing::send_mouse_click(&instance, 210., 90.);
367332
assert_eq(instance.get_result(), "P1");
@@ -371,46 +336,49 @@ instance.set_result("");
371336
slint_testing::send_mouse_click(&instance, 20., 310.);
372337
assert_eq(instance.get_result(), "");
373338
374-
// but p2 is still open
375-
// Open its combobox
339+
// open popup2
340+
slint_testing::send_mouse_click(&instance, 210., 10.);
341+
assert_eq(instance.get_result(), "");
342+
343+
// open its combobox
376344
slint_testing::send_mouse_click(&instance, 40., 210.);
377-
// but click outside closes it
345+
346+
// click outside closes it
378347
slint_testing::send_mouse_click(&instance, 210., 90.);
379348
assert_eq(instance.get_result(), "");
380349
381-
// "close this" closes p2
350+
// but P2 is still open, so open its combobox again
351+
slint_testing::send_mouse_click(&instance, 40., 210.);
382352
slint_testing::send_mouse_click(&instance, 40., 210. + 40.);
383-
assert_eq(instance.get_result(), "C2");
353+
assert_eq(instance.get_result(), "Aaaa");
384354
instance.set_result("");
385355
386-
slint_testing::send_mouse_click(&instance, 20., 310.);
387-
assert_eq(instance.get_result(), "Root");
356+
// open popup1 from popup2
357+
slint_testing::send_mouse_click(&instance, 300., 210. + 40.);
358+
assert_eq(instance.get_result(), "O1");
388359
instance.set_result("");
389360
390-
// open both popups
391-
slint_testing::send_mouse_click(&instance, 380., 10.);
392-
393-
// close popup1
394-
slint_testing::send_mouse_click(&instance, 150., 210. + 40.);
395-
assert_eq(instance.get_result(), "C1");
361+
// check P1 is open
362+
slint_testing::send_mouse_click(&instance, 210., 90.);
363+
assert_eq(instance.get_result(), "P1");
396364
instance.set_result("");
397365
398-
// popup2 is still open and can be closed
399-
slint_testing::send_mouse_click(&instance, 40., 210. + 40.);
400-
assert_eq(instance.get_result(), "C2");
366+
// by opening P1, P2 should be automatically closed
367+
slint_testing::send_mouse_click(&instance, 40., 210.);
368+
assert_eq(instance.get_result(), "");
369+
slint_testing::send_mouse_click(&instance, 40., 210.);
370+
assert_eq(instance.get_result(), "Root");
401371
instance.set_result("");
402372
403-
// open both popups
404-
slint_testing::send_mouse_click(&instance, 380., 10.);
373+
// open popup1
374+
slint_testing::send_mouse_click(&instance, 10., 10.);
405375
406-
// close popup2
407-
slint_testing::send_mouse_click(&instance, 40., 210. + 40.);
408-
assert_eq(instance.get_result(), "C2");
409-
instance.set_result("");
376+
// close popup1 by esc
377+
slint_testing::send_keyboard_string_sequence(&instance, slint::platform::key_codes::Escape);
410378
411-
// popup1 is still open
379+
// check P1 is closed
412380
slint_testing::send_mouse_click(&instance, 210., 90.);
413-
assert_eq(instance.get_result(), "P1");
381+
assert_eq(instance.get_result(), "Root");
414382
instance.set_result("");
415383
```
416384

0 commit comments

Comments
 (0)