GNOME Bugzilla – Bug 501588
Quartz version of gtk_drag_begin blocks until drag is over
Last modified: 2009-09-25 16:30:37 UTC
Both the C and ObjC APIs for drag and drop on the mac runs an internal modal mainloop under the cover when triggering a drag and drop. The current code does that in gtk_drag_begin, which doesn't work well, since that function is supposed to return the drag context immediately. The current code returns after the operation is completed which obviously doesn't work. I haven't looked very closely at how it could be fixed, it will need some investigation.
gtk_drag_begin should return NULL instead of freed object. It saves from a crash in treeview.
How about running dnd session in idle? It'd be ugly, it wouldn't be 100% right (the while (gtk_event_pending()) .. wouldn't work), but it would do normal cases at least.
The two options I have been thinking about: to run the dnd stuff in a thread and if that doesn't work out, use an idle to at least get something that works a bit better. We could always start with something simplistic that just prevents the crash (I'd try the idle before just returning NULL since treeview dnd should work that way).
Can a separate thread work at all? Two threads would need to talk using a pipe or something similar? Scary. Returning NULL is very good as a temporary workaround. Just returning NULL *is* better than segfault. E.g. I regularly get crash in filechooser - accidental DND with trackpad is easy. Though then I am actually using a Gtk application on mac, so it's actually important for me to have non-crashing Gtk right now, even if DND doesn't work ;)
It would need some kind of synchronization, yes. But it might not help anyway since the mac API runs the mainloop in a special tracking mode under the covers, which is why I say above that it might not work. It simply needs trying out. I don't think returning NULL is going to work because most code doesn't expect that to happen, if I remember correctly. Feel free to play around with this to find some other solution.
Returning NULL *does* work in the sense that GtkFileChooser doesn't crash anymore, and no it is not a solution, it is a workaround for a crash...
I am not saying it's supposed to be a solution. I'm just pointing out that it might not be a very effective workaround. If we do something like not unreffing the context when the drag is over but in an idle after the drag is over, we will have a real context to return. Or something similar, it should be quite quick to try out. I'm not saying this -will- work but I prefer at least trying something along those lines since it should cover all the crashes with dnd, no just one.
Deferring the unref to an idle works nicely, so I think that's the "least bad" choice for a work-around. I will look a bit more at it and then commit the workaround unless any issues turn up.
I've committed a workaround that fixes the crash for me, to trunk.
I think pushing the entire drag operation to a (high priority) idle is right. If you use an idle, then gtk_drag_set_icon_pixbuf(), etc, will work on the returned context until the idle fires ... if you use a thread, then you are racing. The thread makes fixing repainting during the dargmore complicated. And otherwise, I don't see much of a difference. The thread might not get scheduled until later anyways.
Bug 588449 indeed pushes the drag operation to an idle handler. Resolving as duplicate. *** This bug has been marked as a duplicate of bug 588449 ***