@@ -76,6 +76,19 @@ void set_dnd_cursor(GdkWindow *w, bool p_okay, MCImage *p_image)
7676}
7777
7878
79+ struct dnd_modal_loop_context
80+ {
81+ GdkDragContext* drag_context;
82+ GdkDisplay* display;
83+ };
84+
85+ static void break_dnd_modal_loop (void * context)
86+ {
87+ dnd_modal_loop_context* t_context = (dnd_modal_loop_context*)context;
88+ gdk_drag_abort (t_context->drag_context , GDK_CURRENT_TIME);
89+ gdk_display_pointer_ungrab (t_context->display , GDK_CURRENT_TIME);
90+ }
91+
7992// SN-2014-07-11: [[ Bug 12769 ]] Update the signature - the non-implemented UIDC dodragdrop was called otherwise
8093MCDragAction MCScreenDC::dodragdrop (Window w, MCPasteboard *p_pasteboard, MCDragActionSet p_allowed_actions, MCImage *p_image, const MCPoint* p_image_offset)
8194{
@@ -141,10 +154,22 @@ MCDragAction MCScreenDC::dodragdrop(Window w, MCPasteboard *p_pasteboard, MCDrag
141154 // Whether the target accepted the drop or not
142155 bool t_accepted = true ;
143156
157+ // Context for breaking out of the modal loop, if required
158+ dnd_modal_loop_context t_loop_context;
159+ modal_loop t_modal_loop;
160+ t_loop_context.drag_context = t_context;
161+ t_loop_context.display = dpy;
162+ t_modal_loop.break_function = break_dnd_modal_loop;
163+ t_modal_loop.context = &t_loop_context;
164+ modalLoopStart (t_modal_loop);
165+
144166 // The drag-and-drop loop
145167 bool t_dnd_done = false ;
146168 while (!t_dnd_done)
147169 {
170+ if (t_modal_loop.broken )
171+ break ;
172+
148173 // Run the GLib event loop to exhaustion
149174 while (g_main_context_iteration (NULL , FALSE ))
150175 ;
@@ -350,6 +375,8 @@ MCDragAction MCScreenDC::dodragdrop(Window w, MCPasteboard *p_pasteboard, MCDrag
350375 siguser ();
351376 }
352377
378+ modalLoopEnd ();
379+
353380 // Other people can now use the pointer
354381 g_object_unref (t_context);
355382 gdk_display_pointer_ungrab (dpy, GDK_CURRENT_TIME);
0 commit comments