Gtk4 win32: drag not finalized, icon stays visible

Hi,

There is an annoying bug with gtk4 on Windows:
I start a drag with the mouse, when I reach the DnD drag threshold the drag icon becomes visible, but if I immediately release the mouse button without any further move, then the drag icon stays visible forever.

Here an example with gtk4-widget-factory:
The purple button is draggable, the corresponding drag icon stays visible:

dnd4-bug

I checked some traces for the good and bad cases, in both cases gdk_win32_drag_cancel() gets called, but in the bad case if no cursor moves are done then I don’t see the expected DRAGDROP_S_CANCEL from idropsource_querycontinuedrag(), and consequently gdk_win32_drag_finalize() isn’t called!

  • Good case, with cursor movement after drag threshold:
gdk_win32_drag_init 0000022051731d30
_gdk_win32_surface_drag_begin
gdk_win32_surface_register_dnd: 0000000000ac3346
drag_context_grab: 0x0000022051731d30 with grab surface 0x000002204edc2350
source_context_new: 000002205e9c2fd0 (drag 0000022051731d30)
data_object_new: 000002205eaf9490
gdk_drag_set_hotspot: 0x0000022051731d30 -2:-2
gdk_dnd_handle_motion_event: 0x0000022051731d30
Post WM_MOUSEMOVE keystate=1
idataobject_querygetdata 000002205eaf9490 0x0000000f fmt, 0000000000000000 ptd, 1 aspect, -1 lindex, 1 tymed - CF_HDROP, return 0x80040064 (DV_E_FORMATETC)
idropsource_querycontinuedrag 000002205e9c2fd0 esc=0 keystate=0x1 with state 1
idropsource_querycontinuedrag state 1
S_OK
idropsourcenotify_dragentertarget 000002205e9c2fd8 (SDC 000002205e9c2fd0) 0x0000000001e905d0
idroptarget_dragenter 00000220518aeec0 @ 624 : 154 for dest window 0x000002204edc2350. dwOKEffects = 3
gdk_win32_drop_init 000002205ec05110
gdk_win32_drop_status:
 context=000002205ec05110:{source_actions=COPY|MOVE, preferred=}
idroptarget_dragenter returns S_OK with actions  and drop effect 0
idropsource_givefeedback 000002205e9c2fd0 with drop effect 0 S_OK
idropsource_givefeedback 000002205e9c2fd0 returns
gdk_dnd_handle_drag_status: 0x0000022051731d30
idroptarget_dragover 00000220518aeec0 @ 624 : 154 (raw 624 : 154), dwOKEffects = 3, suggests 3 action
idroptarget_dragover returns S_OK with actions  and effect 0
idropsource_givefeedback 000002205e9c2fd0 with drop effect 0 S_OK
idropsource_givefeedback 000002205e9c2fd0 returns
gdk_dnd_handle_drag_status: 0x0000022051731d30
gdk_dnd_handle_motion_event: 0x0000022051731d30
Post WM_MOUSEMOVE keystate=1
gdk_dnd_handle_button_event: 0x0000022051731d30
gdk_win32_drag_drop_done: 0x0000022051731d30 dropped unsuccessfully
gdk_win32_drag_drop_done: animate the drag window from 625 : 154 to 651 : 167
idropsource_querycontinuedrag 000002205e9c2fd0 esc=0 keystate=0x1 with state 1
gdk_win32_drag_cancel: 0x0000022051731d30 no target
gdk_win32_drag_set_cursor: 0x0000022051731d30 0x0000000000000000
drag_context_ungrab: 0x0000022051731d30 0x000002204ef880e0
DRAGDROP_S_CANCEL
idroptarget_dragleave 00000220518aeec0 S_OK
gdk_win32_drop_finalize 000002205ec05110
idropsourcenotify_dragleavetarget 000002205e9c2fd8 (SDC 000002205e9c2fd0) 0x0000000001e905d0
DoDragDrop returned DRAGDROP_S_CANCEL with effect 0
gdk_dnd_handle_drop_finished: 0x0000022051731d30
gdk_win32_drag_finalize 0000022051731d30
gdk_win32_drag_set_cursor: 0x0000022051731d30 0x0000000000000000
  • Bad case, with immediate mouse button release after drag threshold:
gdk_win32_drag_init 000001ebdea28e60
_gdk_win32_surface_drag_begin
gdk_win32_surface_register_dnd: 00000000004126fe
drag_context_grab: 0x000001ebdea28e60 with grab surface 0x000001ebc930b460
source_context_new: 000001ebdebe9b90 (drag 000001ebdea28e60)
data_object_new: 000001ebdea54060
gdk_drag_set_hotspot: 0x000001ebdea28e60 -2:-2
gdk_dnd_handle_button_event: 0x000001ebdea28e60
gdk_win32_drag_drop_done: 0x000001ebdea28e60 dropped unsuccessfully
gdk_win32_drag_drop_done: animate the drag window from 598 : 125 to 598 : 125
gdk_win32_drag_cancel: 0x000001ebdea28e60 no target
gdk_win32_drag_set_cursor: 0x000001ebdea28e60 0x0000000000000000
drag_context_ungrab: 0x000001ebdea28e60 0x000001ebc6ce7850

It looks like we can’t rely on idropsource_querycontinuedrag() being reported by Win32.

Anyone has some hints on how to manage this situation?

My setup: Windows10, msys2 ucrt64, gtk-4.15.2

Hi @gwillems! Could you open an issue in GTK?

Thanks!

Hi,

Well yes, I could of course, but I prefer to come to gitlab with solutions, not problems :slightly_smiling_face:

I just need to better understand the synchro between the drag part and the drop part (though it seems to me that the drop is fairly independent, maybe it’s on drag side only…).

I let me around one week to think about this, if no progress I will create the issue.