From 6ecbf2db8a31484fe88b8faa399b9832da6c8a6a Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sun, 27 Oct 2024 22:54:26 +0300 Subject: Deny toplevel move from DnD grabs Work around https://gitlab.gnome.org/GNOME/gtk/-/issues/7113 --- src/handlers/xdg_shell.rs | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/handlers/xdg_shell.rs b/src/handlers/xdg_shell.rs index 8cccfd9e..922250ba 100644 --- a/src/handlers/xdg_shell.rs +++ b/src/handlers/xdg_shell.rs @@ -23,6 +23,7 @@ use smithay::wayland::compositor::{ }; use smithay::wayland::dmabuf::get_dmabuf; use smithay::wayland::input_method::InputMethodSeat; +use smithay::wayland::selection::data_device::DnDGrab; use smithay::wayland::shell::kde::decoration::{KdeDecorationHandler, KdeDecorationState}; use smithay::wayland::shell::wlr_layer::{self, Layer}; use smithay::wayland::shell::xdg::decoration::XdgDecorationHandler; @@ -75,27 +76,44 @@ impl XdgShellHandler for State { // See if this comes from a pointer grab. let pointer = self.niri.seat.get_pointer().unwrap(); - if pointer.has_grab(serial) { - if let Some(start_data) = pointer.grab_start_data() { + pointer.with_grab(|grab_serial, grab| { + if grab_serial == serial { + let start_data = grab.start_data(); if let Some((focus, _)) = &start_data.focus { if focus.id().same_client_as(&wl_surface.id()) { - grab_start_data = Some(PointerOrTouchStartData::Pointer(start_data)); + // Deny move requests from DnD grabs to work around + // https://gitlab.gnome.org/GNOME/gtk/-/issues/7113 + let is_dnd_grab = grab.as_any().downcast_ref::>().is_some(); + + if !is_dnd_grab { + grab_start_data = + Some(PointerOrTouchStartData::Pointer(start_data.clone())); + } } } } - } + }); // See if this comes from a touch grab. if let Some(touch) = self.niri.seat.get_touch() { - if touch.has_grab(serial) { - if let Some(start_data) = touch.grab_start_data() { + touch.with_grab(|grab_serial, grab| { + if grab_serial == serial { + let start_data = grab.start_data(); if let Some((focus, _)) = &start_data.focus { if focus.id().same_client_as(&wl_surface.id()) { - grab_start_data = Some(PointerOrTouchStartData::Touch(start_data)); + // Deny move requests from DnD grabs to work around + // https://gitlab.gnome.org/GNOME/gtk/-/issues/7113 + let is_dnd_grab = + grab.as_any().downcast_ref::>().is_some(); + + if !is_dnd_grab { + grab_start_data = + Some(PointerOrTouchStartData::Touch(start_data.clone())); + } } } } - } + }); } let Some(start_data) = grab_start_data else { -- cgit