fix: nested popup destruction

This commit is contained in:
Ashley Wulber 2025-06-10 10:36:50 -04:00
parent 78153e6240
commit 9668aeba1f
No known key found for this signature in database
GPG key ID: 5216D4F46A90A820
2 changed files with 24 additions and 17 deletions

View file

@ -1133,19 +1133,25 @@ impl SctkState {
SctkEvent::PopupEvent { variant: crate::sctk_event::PopupEventVariant::Size(size.0, size.1), toplevel_id: existing.data.parent.wl_surface().clone(), parent_id: existing.data.parent.wl_surface().clone(), id: existing.popup.wl_surface().clone() }); SctkEvent::PopupEvent { variant: crate::sctk_event::PopupEventVariant::Size(size.0, size.1), toplevel_id: existing.data.parent.wl_surface().clone(), parent_id: existing.data.parent.wl_surface().clone(), id: existing.popup.wl_surface().clone() });
return Ok(()); return Ok(());
} }
let parent_mismatch = self.popups.iter().rev().find(|p| { let mut found = false;
self.id_map.get(&p.popup.wl_surface().id()).map_or(true, |p_id|{ let mut parent_mismatch = false;
*p_id != settings.parent && p.data.grab && settings.grab}) for p in &self.popups {
}); found |= p.data.id == settings.parent;
if !self.destroyed.is_empty() || parent_mismatch.is_some() { parent_mismatch |= found && p.data.id != settings.parent;
if parent_mismatch.is_some() { }
for i in 0..self.popups.len() { parent_mismatch |= !found;
let id = self.id_map.get(&self.popups[i].popup.wl_surface().id()); if !self.destroyed.is_empty() || parent_mismatch {
if let Some(id) = id { if parent_mismatch {
if *id != settings.parent { let mut found = false;
_ = self.handle_action(Action::Popup(platform_specific::wayland::popup::Action::Destroy{id: *id})); for p in std::mem::take(&mut self.popups).into_iter().rev() {
} let id = p.data.id;
self.popups.insert(0, p);
found |= id == settings.parent;
if !found {
_ = self.handle_action(Action::Popup(platform_specific::wayland::popup::Action::Destroy{id}));
} }
} }
} }
if self.pending_popup.replace((settings, 0)).is_none() { if self.pending_popup.replace((settings, 0)).is_none() {

View file

@ -65,13 +65,14 @@ impl PopupHandler for SctkState {
break; break;
} }
state::PopupParent::Popup(popup_to_destroy_first) => { state::PopupParent::Popup(popup_to_destroy_first) => {
let popup_to_destroy_first = self let Some(popup_to_destroy_first) =
.popups self.popups.iter().position(|p| {
.iter()
.position(|p| {
p.popup.wl_surface() == &popup_to_destroy_first p.popup.wl_surface() == &popup_to_destroy_first
}) })
.unwrap(); else {
log::warn!("could not find popup to destroy first.");
return;
};
let popup_to_destroy_first = let popup_to_destroy_first =
self.popups.remove(popup_to_destroy_first); self.popups.remove(popup_to_destroy_first);
to_destroy.push(popup_to_destroy_first); to_destroy.push(popup_to_destroy_first);