GNOME Bugzilla – Bug 347277
gtk_drag_get_ipc_widget() and window groups
Last modified: 2011-02-04 16:10:31 UTC
Please describe the problem: If a program calls gtk_drag_begin around the same time (shortly before) a button release, the button release event will not hit the button release handler created by gtk and the drag will be stuck until the user hits escape or clicks. Steps to reproduce: Quickly drag and release any tab other than the current tab in Firefox. The drag distance should be very slight, as if by accident. Often times, gtk_drag_begin will be called around the same time that the button release event is sent. Actual results: GTK starts dragging the tab. Expected results: Nothing. Switch to that tab. Does this happen every time? No, it is a bit of a race. Other information: https://bugzilla.mozilla.org/show_bug.cgi?id=307184 This is the Firefox bug. It would be better to fix this in gtk+, though there is a workaround for applications.
I'm wondering if this has to do with the use of window groups in mozilla; it doesn't look like gtkdnd.c tries to get the ipc widget into the same window group as the source widget where the drag was begun. The quick experiment you could try is to comment out the use of window groups in firefox and see if you can still reproduce the problem.
(In reply to comment #1) > The quick experiment you could try is to comment out the use of window > groups in firefox and see if you can still reproduce the problem. > Nope, drags don't seem to get stuck anymore once the window group code is eliminated.
Thanks for testing. I think it's fairly easy to fix up; gtk_dnd_get_ipc_widget() needs to check to see if the window is part of a non-default window group, and if so, use a per-window-group IPC widget rather than a per-screen IPC widget. [ The interaction of window groups with multi-head is a bit unclear; I suspect that the default window group from gtk_window_get_group() should likely be per-display, but it isn't currently, so you can't use gtk_window_get_group() directly from gtk_dnd_get_ipc_widget() ]
hmm, not quite clear if this will work. In almost all cases, we call gtk_drag_get_ipc_widget (gtk_widget_get_screen (foo)) so we can just replace the screen parameter by the widget, and then do smart things for window groups, but in gtk_drag_finish, we call it like this: gtk_drag_get_ipc_widget (gdk_drawable_get_screen (context->source_window)) so we just have a GdkWindow here, no GtkWindow
Or is the window group stuff only relevant on the source side ?
That sounds likely because thats where we do the grabs...
The window group stuff is indeed relevant only on the source side. Though note that there is context->dest_window that can be used to figure out the toplevel GtkWindow and thus the window group on the destination side.
Created attachment 69087 [details] [review] a patch
Owen, does this patch look right ? I had to make the ipc widgets GtkWindows, since GtkInvisibles cannot be direct members of window groups. I tested it a bit with testnotebookdnd and testdnd, and dnd seems to work as before. I haven't done any testing involving window groups. Michael, maybe you can test if this patch fixes the issue ?
hmm, owen pointed out that we may want to avoid adding the ipc widgets to the default window group, and that we have to be careful about not removing the widget from window group unless it has been added to it (maybe use window->group directly instead of gtk_window_get_group())
2006-07-18 Matthias Clasen <mclasen@redhat.com> * gtk/gtkdnd.c: Make the ipc widgets GtkWindows instead of GtkInvisibles, and put them in the same window group as the drag source, to avoid interactions between DND and window groups. (#347277, Michael Wu, analysis by Owen Taylor)