fix: always recalculate DnD rectangle on offer motion in case it changes

Sometimes DnD targets can be nested inside other containers which are also DnD targets.
This commit is contained in:
Ashley Wulber 2024-07-23 19:56:01 -04:00 committed by Ashley Wulber
parent d099e82a4c
commit 5a3007def4

View file

@ -119,14 +119,37 @@ where
} }
return (s.clone(), None); return (s.clone(), None);
}; };
if let (Some((action, preferred_action)), Some(mime_type), Some(dnd_state)) = if !had_dest.is_some_and(|old_id| old_id == dest.id) {
(actions, mime, dnd_state.as_ref()) if let (Some((action, preferred_action)), Some(mime_type), Some(dnd_state)) =
{ (actions, mime, dnd_state.as_ref())
dnd_state.set_actions(action, preferred_action); {
self.dnd_state.selected_mime = Some(mime_type.clone()); if let Some((tx, old_id)) = self.dnd_state.sender.as_ref().zip(had_dest) {
dnd_state _ = tx.send(DndEvent::Offer(
.accept_mime_type(self.dnd_state.accept_ctr, Some(mime_type.to_string())); Some(old_id),
self.dnd_state.accept_ctr = self.dnd_state.accept_ctr.wrapping_add(1); super::OfferEvent::LeaveDestination,
));
}
if let Some(tx) = self.dnd_state.sender.as_ref() {
_ = tx.send(DndEvent::Offer(Some(dest.id), OfferEvent::Enter {
x,
y,
surface: s.s.clone(),
mime_types: dest.mime_types.clone(),
}));
_ = tx.send(DndEvent::Offer(
Some(dest.id),
OfferEvent::SelectedAction(self.dnd_state.selected_action),
));
}
dnd_state.set_actions(action, preferred_action);
self.dnd_state.selected_mime = Some(mime_type.clone());
dnd_state.accept_mime_type(
self.dnd_state.accept_ctr,
Some(mime_type.to_string()),
);
self.dnd_state.accept_ctr = self.dnd_state.accept_ctr.wrapping_add(1);
}
} }
(s.clone(), Some(dest)) (s.clone(), Some(dest))
}); });
@ -218,12 +241,7 @@ where
} }
pub(crate) fn offer_motion(&mut self, x: f64, y: f64, wl_data_device: &WlDataDevice) { pub(crate) fn offer_motion(&mut self, x: f64, y: f64, wl_data_device: &WlDataDevice) {
let Some((surface, dest)) = self let Some(surface) = self.dnd_state.active_surface.clone().map(|(s, _)| s) else {
.dnd_state
.active_surface
.clone()
.map(|(s, dest)| (s, dest.filter(|d| d.rectangle.contains(x, y))))
else {
return; return;
}; };
let Some(data_device) = self let Some(data_device) = self
@ -238,9 +256,7 @@ where
// Ignore cancelled internal DnD // Ignore cancelled internal DnD
return; return;
} }
if dest.is_none() { self.update_active_surface(&surface.surface, x, y, drag_offer.as_ref());
self.update_active_surface(&surface.surface, x, y, drag_offer.as_ref());
}
let id = self.cur_id(); let id = self.cur_id();
if let Some(tx) = self.dnd_state.sender.as_ref() { if let Some(tx) = self.dnd_state.sender.as_ref() {
_ = tx.send(DndEvent::Offer(id, super::OfferEvent::Motion { x, y })); _ = tx.send(DndEvent::Offer(id, super::OfferEvent::Motion { x, y }));
@ -368,7 +384,6 @@ where
surface.attach(Some(wl_buffer), 0, 0); surface.attach(Some(wl_buffer), 0, 0);
surface.commit(); surface.commit();
dbg!("attached buffer, damaged surface.");
self.dnd_state.icon_surface = Some(surface); self.dnd_state.icon_surface = Some(surface);
} }