GNOME Bugzilla – Bug 709340
Hang in DND due to clock frozen
Last modified: 2013-10-15 20:42:17 UTC
We're having this issue in gtk 3.10 where DnD hangs. Its easy to reproduce in gedit, just open a file, select some text and start DNDing it. Sometimes it works, but sometimes it "hangs", i.e. the dnd window gets stuck at the initial position. If it works the first time it will continue working, if it hangs the first time it will continue hanging. I can also reproduce this with the textview in gtk3-demo, so its not gedit related. I've tracked this down a bit. It turns out that the motion events that are supposed to reach the drag source just never arrive in the hanged case. The reason for this is that whenever we get a motion events from the lower layers these get in "pending" mode in _gdk_event_queue_handle_motion_compression() (called from _gdk_windowing_got_event), and then we request a GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS phase to make sure that we eventually handle this. The gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS) call ends up in gdkframeclockidle.c:maybe_start_idle(), and in the "hanged" situation this doesn't queue an idle, because the clock is frozen. The clock is frozen because we just completed a frame, and gdk_x11_window_end_frame() did: if (impl->frame_sync_enabled && gdk_x11_screen_supports_net_wm_hint (gdk_window_get_screen (window), gdk_atom_intern_static_string ("_NET_WM_FRAME_DRAWN"))) { impl->toplevel->frame_pending = TRUE; _gdk_frame_clock_freeze (gdk_window_get_frame_clock (window)); timings->cookie = impl->toplevel->current_counter_value; } And it seems that in this case we never get a _NET_WM_FRAME_DRAWN message... I don't know why though...
Maybe this is a gnome-shell/mutter issue, for the record i'm running version 3.10.0.1 of both gnome-shell and mutter, on F20.
The window in question is the GTK_WINDOW_POPUP toplevel created in gtk_drag_get_ipc_widget_for_screen(). It is positioned outside the screen, maybe that is why we don't get a FRAME_DRAWN?
(In reply to comment #2) > The window in question is the GTK_WINDOW_POPUP toplevel created in > gtk_drag_get_ipc_widget_for_screen(). It is positioned outside the screen, > maybe that is why we don't get a FRAME_DRAWN? If the problem is not getting any FRAME_DRAWN messages for a window that is not visible at all it might be caused by the optimization from bug 703332 ... but the code (is supposed to) ensure that it gets the frame_drawn at least every 100ms in that case.
I cannot reproduce the bug though ... the drag window follows the mouse like it should (testing with gtk3-demo).
I managed to reproduce this once out of several dozen tries - so if you can get it more reliably, I'd certainly appreciate help. In general, outside screen vs. not shouldn't matter. I'm curious why if (impl->toplevel->current_counter_value % 2 == 1) Is it because: A) GTK+ drew something to the window B) Because of the special-casing for newly created window we added with bug 702196 (Did this just start happening?)
I don't know when this happened. I just got told by nacho about it. Anyway, some points: If i change gtk_drag_get_ipc_widget_for_screen to make the window onscreen then I'm unable to reproduce. gtk_window_draw() *is* called on the ipc_widget GtkWindow, so we *do* draw something.
This seem related to bug 703332, because I was unable to reproduce with this mutter patch applied: diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c index 505232f..603f3ed 100644 --- a/src/compositor/meta-shaped-texture.c +++ b/src/compositor/meta-shaped-texture.c @@ -552,7 +552,7 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, meta_texture_tower_update_area (priv->paint_tower, x, y, width, height); - if (unobscured_region) + if (0&&unobscured_region) { cairo_region_t *intersection;
(In reply to comment #7) > This seem related to bug 703332, because I was unable to reproduce with this > mutter patch applied: > > diff --git a/src/compositor/meta-shaped-texture.c > b/src/compositor/meta-shaped-texture.c > index 505232f..603f3ed 100644 > --- a/src/compositor/meta-shaped-texture.c > +++ b/src/compositor/meta-shaped-texture.c > @@ -552,7 +552,7 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex, > > meta_texture_tower_update_area (priv->paint_tower, x, y, width, height); > > - if (unobscured_region) > + if (0&&unobscured_region) > { > cairo_region_t *intersection; meta_window_actor_queue_frame_drawn should be still sending FRAME_DRAWN message though https://git.gnome.org/browse/mutter/tree/src/compositor/meta-window-actor.c#n1060 Can you add some debug prints there to find out whats going on?
Or does something like this: git diff diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-act index 63c12c0..5b8c55a 100644 --- a/src/compositor/meta-window-actor.c +++ b/src/compositor/meta-window-actor.c @@ -2080,6 +2080,9 @@ meta_window_actor_process_damage (MetaWindowActor *self priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued; + if (!priv->repaint_scheduled) + meta_window_actor_queue_frame_drawn (self, TRUE); + } void help?
That doesn't seem to help, don't have time to debug more atm.
Created attachment 256639 [details] [review] meta-window-actor: Make sure we have a correct offset in queue_send_frame_messages_timeout When the window is always obscured (or initially) obscured we never get to set the last frame_drawn_time so it ends up being 0. Fix that case by just using a 0 offset when this happens. --- OK as said on IRC this should fix it, can you test it?
Created attachment 256645 [details] [review] meta-window-actor: Fix offset calculation The current math is wrong the offset should become smaller when the current time is bigger (the last drawn time is further in the past).
That fixes it for me.
Pushed with improved commit message.
*** Bug 710082 has been marked as a duplicate of this bug. ***
*** Bug 710213 has been marked as a duplicate of this bug. ***