@@ -23,12 +23,22 @@ use crate::{
2323
2424use super :: { DndFocus , Source } ;
2525
26+ /// Type of interaction that started a DnD grab
27+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
28+ pub enum GrabType {
29+ /// Pointer input was validated for the requested grab
30+ Pointer ,
31+ /// Touch input was validated for the requested grab
32+ Touch ,
33+ }
34+
2635/// Grab during a client-initiated DnD operation.
2736pub struct DnDGrab < D : SeatHandler , S : Source , F : DndFocus < D > + ' static > {
2837 #[ cfg( feature = "wayland_frontend" ) ]
2938 dh : DisplayHandle ,
3039 pointer_start_data : Option < PointerGrabStartData < D > > ,
3140 touch_start_data : Option < TouchGrabStartData < D > > ,
41+ last_position : Point < f64 , Logical > ,
3242 data_source : Arc < S > ,
3343 current_focus : Option < F > ,
3444 offer_data : Option < F :: OfferData < S > > ,
5262
5363 f. field ( "pointer_start_data" , & self . pointer_start_data )
5464 . field ( "touch_start_data" , & self . touch_start_data )
65+ . field ( "last_position" , & self . last_position )
5566 . field ( "data_source" , & self . data_source )
5667 . field ( "current_focus" , & self . current_focus )
5768 . field ( "offer_data" , & self . offer_data )
@@ -71,11 +82,13 @@ where
7182 source : S ,
7283 seat : Seat < D > ,
7384 ) -> Self {
85+ let last_position = start_data. location ;
7486 Self {
7587 #[ cfg( feature = "wayland_frontend" ) ]
7688 dh : dh. clone ( ) ,
7789 pointer_start_data : Some ( start_data) ,
7890 touch_start_data : None ,
91+ last_position,
7992 data_source : Arc :: new ( source) ,
8093 current_focus : None ,
8194 offer_data : None ,
@@ -95,11 +108,13 @@ where
95108 source : S ,
96109 seat : Seat < D > ,
97110 ) -> Self {
111+ let last_position = start_data. location ;
98112 Self {
99113 #[ cfg( feature = "wayland_frontend" ) ]
100114 dh : dh. clone ( ) ,
101115 pointer_start_data : None ,
102116 touch_start_data : Some ( start_data) ,
117+ last_position,
103118 data_source : Arc :: new ( source) ,
104119 current_focus : None ,
105120 offer_data : None ,
@@ -118,8 +133,17 @@ pub trait DndGrabHandler: SeatHandler + Sized {
118133 /// * `validated` - Whether the drop offer was negotiated and accepted. If `false`, the drop
119134 /// was cancelled or otherwise not successful.
120135 /// * `seat` - The seat on which the DnD action was finished.
121- fn dropped < T : DndFocus < Self > > ( & mut self , target : Option < & T > , validated : bool , seat : Seat < Self > ) {
122- let _ = ( target, validated, seat) ;
136+ /// * `type_` - Type of grab that initiated the DnD operation
137+ /// * `location` - The location the drop was finished at
138+ fn dropped < T : DndFocus < Self > > (
139+ & mut self ,
140+ target : Option < & T > ,
141+ validated : bool ,
142+ seat : Seat < Self > ,
143+ type_ : GrabType ,
144+ location : Point < f64 , Logical > ,
145+ ) {
146+ let _ = ( target, validated, seat, type_, location) ;
123147 }
124148}
125149
@@ -214,7 +238,18 @@ where
214238 self . data_source . drop_performed ( ) ;
215239 }
216240
217- DndGrabHandler :: dropped ( data, self . current_focus . as_ref ( ) , validated, self . seat . clone ( ) ) ;
241+ DndGrabHandler :: dropped (
242+ data,
243+ self . current_focus . as_ref ( ) ,
244+ validated,
245+ self . seat . clone ( ) ,
246+ if self . pointer_start_data . is_some ( ) {
247+ GrabType :: Pointer
248+ } else {
249+ GrabType :: Touch
250+ } ,
251+ self . last_position ,
252+ ) ;
218253 // in all cases abandon the drop
219254 // no more buttons are pressed, release the grab
220255 if let Some ( ref focus) = self . current_focus {
@@ -245,6 +280,8 @@ where
245280 event,
246281 ) ;
247282
283+ self . last_position = event. location ;
284+
248285 self . update_focus ( data, focus, event. location , event. serial , event. time ) ;
249286 }
250287
@@ -400,6 +437,8 @@ where
400437 return ;
401438 }
402439
440+ self . last_position = event. location ;
441+
403442 self . update_focus (
404443 data,
405444 focus,
0 commit comments