@@ -13,16 +13,16 @@ use smithay::backend::allocator::dmabuf::Dmabuf;
1313use smithay:: backend:: drm:: DrmNode ;
1414use smithay:: backend:: input:: { InputEvent , TabletToolDescriptor } ;
1515use smithay:: desktop:: { PopupKind , PopupManager } ;
16- use smithay:: input:: pointer:: { CursorIcon , CursorImageStatus , PointerHandle } ;
16+ use smithay:: input:: dnd:: { self , DnDGrab , DndGrabHandler , DndTarget } ;
17+ use smithay:: input:: pointer:: { CursorIcon , CursorImageStatus , Focus , PointerHandle } ;
1718use smithay:: input:: { keyboard, Seat , SeatHandler , SeatState } ;
1819use smithay:: output:: Output ;
1920use smithay:: reexports:: rustix:: fs:: { fcntl_setfl, OFlags } ;
2021use smithay:: reexports:: wayland_protocols_wlr:: screencopy:: v1:: server:: zwlr_screencopy_manager_v1:: ZwlrScreencopyManagerV1 ;
21- use smithay:: reexports:: wayland_server:: protocol:: wl_data_source:: WlDataSource ;
2222use smithay:: reexports:: wayland_server:: protocol:: wl_output:: WlOutput ;
2323use smithay:: reexports:: wayland_server:: protocol:: wl_surface:: WlSurface ;
2424use smithay:: reexports:: wayland_server:: Resource ;
25- use smithay:: utils:: { Logical , Point , Rectangle } ;
25+ use smithay:: utils:: { Logical , Point , Rectangle , Serial } ;
2626use smithay:: wayland:: compositor:: { get_parent, with_states} ;
2727use smithay:: wayland:: dmabuf:: { DmabufGlobal , DmabufHandler , DmabufState , ImportNotifier } ;
2828use smithay:: wayland:: drm_lease:: {
@@ -41,8 +41,7 @@ use smithay::wayland::security_context::{
4141 SecurityContext , SecurityContextHandler , SecurityContextListenerSource ,
4242} ;
4343use smithay:: wayland:: selection:: data_device:: {
44- set_data_device_focus, ClientDndGrabHandler , DataDeviceHandler , DataDeviceState ,
45- ServerDndGrabHandler ,
44+ set_data_device_focus, DataDeviceHandler , DataDeviceState , WaylandDndGrabHandler ,
4645} ;
4746use smithay:: wayland:: selection:: ext_data_control:: {
4847 DataControlHandler as ExtDataControlHandler , DataControlState as ExtDataControlState ,
@@ -314,23 +313,51 @@ impl DataDeviceHandler for State {
314313 }
315314}
316315
317- impl ClientDndGrabHandler for State {
318- fn started (
316+ impl WaylandDndGrabHandler for State {
317+ fn dnd_requested < S : dnd :: Source > (
319318 & mut self ,
320- _source : Option < WlDataSource > ,
319+ source : S ,
321320 icon : Option < WlSurface > ,
322- _seat : Seat < Self > ,
321+ seat : Seat < Self > ,
322+ serial : Serial ,
323+ type_ : dnd:: GrabType ,
323324 ) {
324325 self . niri . dnd_icon = icon. map ( |surface| DndIcon {
325326 surface,
326327 offset : Point :: new ( 0 , 0 ) ,
327328 } ) ;
329+
330+ match type_ {
331+ dnd:: GrabType :: Pointer => {
332+ let pointer = seat. get_pointer ( ) . unwrap ( ) ;
333+ let start_data = pointer. grab_start_data ( ) . unwrap ( ) ;
334+ let grab =
335+ DnDGrab :: new_pointer ( & self . niri . display_handle , start_data, source, seat) ;
336+ pointer. set_grab ( self , grab, serial, Focus :: Keep ) ;
337+ }
338+ dnd:: GrabType :: Touch => {
339+ let touch = seat. get_touch ( ) . unwrap ( ) ;
340+ let start_data = touch. grab_start_data ( ) . unwrap ( ) ;
341+ let grab = DnDGrab :: new_touch ( & self . niri . display_handle , start_data, source, seat) ;
342+ touch. set_grab ( self , grab, serial) ;
343+ }
344+ }
345+
328346 // FIXME: more granular
329347 self . niri . queue_redraw_all ( ) ;
330348 }
349+ }
331350
332- fn dropped ( & mut self , target : Option < WlSurface > , validated : bool , _seat : Seat < Self > ) {
333- trace ! ( "client dropped, target: {target:?}, validated: {validated}" ) ;
351+ impl DndGrabHandler for State {
352+ fn dropped (
353+ & mut self ,
354+ target : Option < DndTarget < ' _ , Self > > ,
355+ validated : bool ,
356+ _seat : Seat < Self > ,
357+ location : Point < f64 , Logical > ,
358+ ) {
359+ let target: Option < & WlSurface > = target. map ( DndTarget :: into_inner) ;
360+ trace ! ( "dnd dropped, target: {target:?}, validated: {validated}" ) ;
334361
335362 // End DnD before activating a specific window below so that it takes precedence.
336363 self . niri . layout . dnd_end ( ) ;
@@ -349,19 +376,10 @@ impl ClientDndGrabHandler for State {
349376 }
350377
351378 if activate_output {
352- // Find the output from cursor coordinates.
353- //
354- // FIXME: uhhh, we can't actually properly tell if the DnD comes from pointer or touch,
355- // and if it comes from touch, then what the coordinates are. Need to pass more
356- // parameters from Smithay I guess.
357- //
358- // Assume that hidden pointer means touch DnD.
359- if self . niri . pointer_visibility . is_visible ( ) {
360- // We can't even get the current pointer location because it's locked (we're deep
361- // in the grab call stack here). So use the last known one.
362- if let Some ( output) = & self . niri . pointer_contents . output {
363- self . niri . layout . focus_output ( output) ;
364- }
379+ // Find the output from drop coordinates.
380+ if let Some ( ( output, _) ) = self . niri . output_under ( location) {
381+ let output = output. clone ( ) ;
382+ self . niri . layout . focus_output ( & output) ;
365383 }
366384 }
367385
@@ -371,8 +389,6 @@ impl ClientDndGrabHandler for State {
371389 }
372390}
373391
374- impl ServerDndGrabHandler for State { }
375-
376392delegate_data_device ! ( State ) ;
377393
378394impl PrimarySelectionHandler for State {
0 commit comments