After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 709340 - Hang in DND due to clock frozen
Hang in DND due to clock frozen
Status: RESOLVED FIXED
Product: mutter
Classification: Core
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: mutter-maint
mutter-maint
: 710082 710213 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2013-10-03 08:40 UTC by Alexander Larsson
Modified: 2013-10-15 20:42 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
meta-window-actor: Make sure we have a correct offset in queue_send_frame_messages_timeout (1.31 KB, patch)
2013-10-07 15:55 UTC, drago01
none Details | Review
meta-window-actor: Fix offset calculation (1.14 KB, patch)
2013-10-07 16:14 UTC, drago01
committed Details | Review

Description Alexander Larsson 2013-10-03 08:40:45 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...
Comment 1 Alexander Larsson 2013-10-03 08:58:31 UTC
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.
Comment 2 Alexander Larsson 2013-10-03 09:14:54 UTC
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?
Comment 3 drago01 2013-10-03 14:16:29 UTC
(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.
Comment 4 drago01 2013-10-03 14:20:09 UTC
I cannot reproduce the bug though ... the drag window follows the mouse like it should (testing with gtk3-demo).
Comment 5 Owen Taylor 2013-10-03 14:24:39 UTC
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?)
Comment 6 Alexander Larsson 2013-10-04 08:21:22 UTC
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.
Comment 7 Alexander Larsson 2013-10-04 08:42:19 UTC
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;
Comment 8 drago01 2013-10-04 10:33:08 UTC
(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?
Comment 9 drago01 2013-10-04 10:56:23 UTC
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?
Comment 10 Alexander Larsson 2013-10-04 13:23:17 UTC
That doesn't seem to help, don't have time to debug more atm.
Comment 11 drago01 2013-10-07 15:55:59 UTC
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?
Comment 12 drago01 2013-10-07 16:14:37 UTC
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).
Comment 13 Alexander Larsson 2013-10-07 17:56:16 UTC
That fixes it for me.
Comment 14 drago01 2013-10-07 18:23:44 UTC
Pushed with improved commit message.
Comment 15 Jasper St. Pierre (not reading bugmail) 2013-10-15 07:38:05 UTC
*** Bug 710082 has been marked as a duplicate of this bug. ***
Comment 16 Jasper St. Pierre (not reading bugmail) 2013-10-15 20:42:17 UTC
*** Bug 710213 has been marked as a duplicate of this bug. ***