fix: clear active window if popup

This commit is contained in:
drendog 2025-10-26 19:39:52 +01:00
parent b14cb51f86
commit 0615995e40
Signed by: dwenya
GPG key ID: 8DD77074645332D0
3 changed files with 44 additions and 4 deletions

View file

@ -185,4 +185,21 @@ impl PopupManager {
.get(index)
.map(|popup| Rc::clone(&popup.window))
}
pub fn destroy_popup(&self, index: usize) {
let mut popups = self.popups.borrow_mut();
if index < popups.len() {
info!("Destroying popup at index {index}");
popups.remove(index);
}
}
pub fn find_popup_index_by_xdg_popup_id(&self, xdg_popup_id: &ObjectId) -> Option<usize> {
for (index, popup) in self.popups.borrow().iter().enumerate() {
if popup.surface.xdg_popup.id() == *xdg_popup_id {
return Some(index);
}
}
None
}
}

View file

@ -187,7 +187,7 @@ impl Dispatch<WlPointer, ()> for WindowState {
wl_pointer::Event::Leave { .. } => {
state.dispatch_to_active_window(WindowEvent::PointerExited);
state.active_window = None;
state.clear_active_window();
}
wl_pointer::Event::Button {
@ -251,8 +251,8 @@ impl Dispatch<XdgWmBase, ()> for WindowState {
impl Dispatch<XdgPopup, ()> for WindowState {
fn event(
_state: &mut Self,
_xdg_popup: &XdgPopup,
state: &mut Self,
xdg_popup: &XdgPopup,
event: xdg_popup::Event,
_data: &(),
_conn: &Connection,
@ -268,7 +268,20 @@ impl Dispatch<XdgPopup, ()> for WindowState {
info!("XdgPopup Configure: position=({x}, {y}), size=({width}x{height})");
}
xdg_popup::Event::PopupDone => {
info!("XdgPopup dismissed");
info!("XdgPopup dismissed by compositor");
let popup_id = xdg_popup.id();
let popup_index = state
.popup_manager
.as_ref()
.and_then(|pm| pm.find_popup_index_by_xdg_popup_id(&popup_id));
if let Some(index) = popup_index {
info!("Destroying popup at index {index}");
state.clear_active_window_if_popup(index);
if let Some(popup_manager) = &state.popup_manager {
popup_manager.destroy_popup(index);
}
}
}
xdg_popup::Event::Repositioned { token } => {
info!("XdgPopup repositioned with token {token}");

View file

@ -358,4 +358,14 @@ impl WindowState {
}
}
}
pub(super) const fn clear_active_window(&mut self) {
self.active_window = None;
}
pub(super) fn clear_active_window_if_popup(&mut self, popup_index: usize) {
if self.active_window == Some(ActiveWindow::Popup(popup_index)) {
self.active_window = None;
}
}
}