From 55759e5bb79f84277ccf198f529af04184912874 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Mon, 11 Dec 2023 14:38:24 -0800 Subject: [PATCH] dnd_listener: Fix behavior when there are multiple listeners (#87) A `dnd_listener` widget shouldn't handle a DnD event when the dnd drag isn't within the widget's bounds. So add a few more checks for this. Enter/leave events generated by `DndOfferEvent::Motion` also don't behave as one might expect, since the enter may occur before the leave depending on the order it calls `on_event` on the widget. Not sure how to address that, but cosmic-workspaces can just ignore the leave events for now. Otherwise, this seems to be working fine, after these changes. --- widget/src/dnd_listener.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/widget/src/dnd_listener.rs b/widget/src/dnd_listener.rs index 0bc310607d..eac05a4d99 100644 --- a/widget/src/dnd_listener.rs +++ b/widget/src/dnd_listener.rs @@ -414,6 +414,10 @@ fn update( Event::PlatformSpecific(PlatformSpecific::Wayland( event::wayland::Event::DndOffer(DndOfferEvent::Leave), )) => { + if matches!(state.dnd, DndState::None | DndState::External(..)) { + return event::Status::Ignored; + } + if !matches!(state.dnd, DndState::Dropped) { state.dnd = DndState::None; } @@ -428,10 +432,10 @@ fn update( )) => { if matches!(state.dnd, DndState::Hovered(..)) { state.dnd = DndState::Dropped; - } - if let Some(message) = widget.on_drop.clone() { - shell.publish(message); - return event::Status::Captured; + if let Some(message) = widget.on_drop.clone() { + shell.publish(message); + return event::Status::Captured; + } } } Event::PlatformSpecific(PlatformSpecific::Wayland( @@ -479,6 +483,10 @@ fn update( action, )), )) => { + if matches!(state.dnd, DndState::None | DndState::External(..)) { + return event::Status::Ignored; + } + if let Some(message) = widget.on_selected_action.as_ref() { shell.publish(message(*action)); return event::Status::Captured;