From 9268cb02202c1ece0cca1d022773b5101b04c7bd Mon Sep 17 00:00:00 2001 From: IoIxD Date: Tue, 7 Jul 2026 16:32:06 -0700 Subject: [PATCH] fix popup --- src/handlers/xdg_shell.rs | 44 +++++++++++++++++++++++++++++++++++---- src/render.rs | 2 +- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs index 6c909bc..1741669 100644 --- a/src/handlers/xdg_shell.rs +++ b/src/handlers/xdg_shell.rs @@ -1,6 +1,8 @@ use smithay::{ desktop::{ - find_popup_root_surface, get_popup_toplevel_coords, PopupKind, PopupManager, Space, Window, + find_popup_root_surface, get_popup_toplevel_coords, layer_map_for_output, + PopupKeyboardGrab, PopupKind, PopupManager, PopupPointerGrab, PopupUngrabStrategy, Space, + Window, WindowSurfaceType, }, input::{ pointer::{Focus, GrabStartData as PointerGrabStartData}, @@ -42,7 +44,12 @@ impl XdgShellHandler for State { fn new_popup(&mut self, surface: PopupSurface, _positioner: PositionerState) { self.unconstrain_popup(&surface); - let _ = self.popups.track_popup(PopupKind::Xdg(surface)); + if let Err(err) = self.popups.track_popup(PopupKind::Xdg(surface.clone())) { + println!("Failed to track popup: {err}"); + }; + if let Err(err) = surface.send_pending_configure() { + println!("Failed to configure popup: {err}"); + } } fn reposition_request( @@ -128,8 +135,37 @@ impl XdgShellHandler for State { } } - fn grab(&mut self, _surface: PopupSurface, _seat: wl_seat::WlSeat, _serial: Serial) { - // TODO popup grabs + fn grab(&mut self, surface: PopupSurface, seat: wl_seat::WlSeat, serial: Serial) { + let seat = Seat::from_resource(&seat).unwrap(); + let kind = PopupKind::Xdg(surface); + if let Ok(root) = find_popup_root_surface(&kind) { + let ret = self.popups.grab_popup(root, kind, &seat, serial); + + if let Ok(mut grab) = ret { + if let Some(keyboard) = seat.get_keyboard() { + if keyboard.is_grabbed() + && !(keyboard.has_grab(serial) + || keyboard.has_grab(grab.previous_serial().unwrap_or(serial))) + { + grab.ungrab(PopupUngrabStrategy::All); + return; + } + keyboard.set_focus(self, grab.current_grab(), serial); + keyboard.set_grab(self, PopupKeyboardGrab::new(&grab), serial); + } + if let Some(pointer) = seat.get_pointer() { + if pointer.is_grabbed() + && !(pointer.has_grab(serial) + || pointer + .has_grab(grab.previous_serial().unwrap_or_else(|| grab.serial()))) + { + grab.ungrab(PopupUngrabStrategy::All); + return; + } + pointer.set_grab(self, PopupPointerGrab::new(&grab), serial, Focus::Keep); + } + } + } } fn title_changed(&mut self, surface: ToplevelSurface) { diff --git a/src/render.rs b/src/render.rs index 85cb091..286b9d1 100644 --- a/src/render.rs +++ b/src/render.rs @@ -259,7 +259,7 @@ impl DecoratedWindow { impl SpaceElement for DecoratedWindow { fn bbox(&self) -> smithay::utils::Rectangle { - let mut bbox = self.window.bbox(); + let mut bbox = self.window.bbox_with_popups(); if self.decorated() { bbox.loc.x -= 5;