[mutter/wip/frame-synchronization: 108/121] Implement freezing of updates during resize



commit 8b57ecebdaff4958114a6d103e13a6100221f5db
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Mon Jun 13 17:53:23 2011 -0400

    Implement freezing of updates during resize
    
    Replace the unused meta_compositor_set_updates() with
    a reversed-meaning meta_compositor_set_updates_frozen(), and use
    it to implement freezing application window updates during
    interactive resizing. This avoids drawing new areas of the window
    with blank content before the application has a chance to repaint.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=685463

 src/compositor/compositor.c                |   14 +++++++--
 src/compositor/meta-window-actor-private.h |    2 +
 src/compositor/meta-window-actor.c         |   45 +++++++++++++++++++++++----
 src/core/window-private.h                  |    5 +++
 src/core/window.c                          |   40 +++++++++++++++++++++----
 src/meta/compositor.h                      |    4 +-
 6 files changed, 92 insertions(+), 18 deletions(-)
---
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 105464f..3c4972d 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -716,10 +716,18 @@ meta_compositor_remove_window (MetaCompositor *compositor,
 }
 
 void
-meta_compositor_set_updates (MetaCompositor *compositor,
-                             MetaWindow     *window,
-                             gboolean        updates)
+meta_compositor_set_updates_frozen (MetaCompositor *compositor,
+                                    MetaWindow     *window,
+                                    gboolean        updates_frozen)
 {
+  MetaWindowActor *window_actor;
+
+  DEBUG_TRACE ("meta_compositor_set_updates_frozen\n");
+  window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
+  if (!window_actor)
+    return;
+
+  meta_window_actor_set_updates_frozen (window_actor, updates_frozen);
 }
 
 static gboolean
diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h
index 97e3140..0d653ec 100644
--- a/src/compositor/meta-window-actor-private.h
+++ b/src/compositor/meta-window-actor-private.h
@@ -45,6 +45,8 @@ void     meta_window_actor_update_shape        (MetaWindowActor *self);
 void     meta_window_actor_update_opacity      (MetaWindowActor *self);
 void     meta_window_actor_mapped              (MetaWindowActor *self);
 void     meta_window_actor_unmapped            (MetaWindowActor *self);
+void     meta_window_actor_set_updates_frozen  (MetaWindowActor *self,
+                                                gboolean         updates_frozen);
 
 cairo_region_t *meta_window_actor_get_obscured_region (MetaWindowActor *self);
 
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 180cfdc..4f6ccba 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -111,6 +111,7 @@ struct _MetaWindowActorPrivate
   guint             recompute_focused_shadow   : 1;
   guint             recompute_unfocused_shadow : 1;
   guint		    size_changed           : 1;
+  guint             updates_frozen         : 1;
 
   guint		    needs_destroy	   : 1;
 
@@ -925,10 +926,16 @@ meta_window_actor_thaw (MetaWindowActor *self)
   if (self->priv->freeze_count)
     return;
 
+  /* We ignore moves and resizes on frozen windows */
+  meta_window_actor_sync_actor_position (self);
+
+  /* We do this now since we might be going right back into the
+   * frozen state */
+  meta_window_actor_pre_paint (self);
+
   /* Since we ignore damage events while a window is frozen for certain effects
    * we may need to issue an update_area() covering the whole pixmap if we
    * don't know what real damage has happened. */
-
   if (self->priv->needs_damage_all)
     meta_window_actor_damage_all (self);
 }
@@ -1279,6 +1286,12 @@ meta_window_actor_destroy (MetaWindowActor *self)
     clutter_actor_destroy (CLUTTER_ACTOR (self));
 }
 
+static gboolean
+is_frozen (MetaWindowActor *self)
+{
+  return self->priv->freeze_count ? TRUE : FALSE;
+}
+
 void
 meta_window_actor_sync_actor_position (MetaWindowActor *self)
 {
@@ -1287,6 +1300,9 @@ meta_window_actor_sync_actor_position (MetaWindowActor *self)
 
   meta_window_get_input_rect (priv->window, &window_rect);
 
+  if (is_frozen (self))
+    return;
+
   if (priv->last_width != window_rect.width ||
       priv->last_height != window_rect.height)
     {
@@ -1483,6 +1499,9 @@ meta_window_actor_new (MetaWindow *window)
   if (priv->mapped)
     meta_window_actor_queue_create_pixmap (self);
 
+  meta_window_actor_set_updates_frozen (self,
+                                        meta_window_updates_are_frozen (priv->window));
+
   meta_window_actor_sync_actor_position (self);
 
   /* Hang our compositor window state off the MetaWindow for fast retrieval */
@@ -1872,12 +1891,6 @@ check_needs_shadow (MetaWindowActor *self)
     meta_shadow_unref (old_shadow);
 }
 
-static gboolean
-is_frozen (MetaWindowActor *self)
-{
-  return self->priv->freeze_count ? TRUE : FALSE;
-}
-
 void
 meta_window_actor_process_damage (MetaWindowActor    *self,
                                   XDamageNotifyEvent *event)
@@ -2329,3 +2342,21 @@ meta_window_actor_update_opacity (MetaWindowActor *self)
   self->priv->opacity = opacity;
   clutter_actor_set_opacity (self->priv->actor, opacity);
 }
+
+void
+meta_window_actor_set_updates_frozen (MetaWindowActor *self,
+                                      gboolean         updates_frozen)
+{
+  MetaWindowActorPrivate *priv = self->priv;
+
+  updates_frozen = updates_frozen != FALSE;
+
+  if (priv->updates_frozen != updates_frozen)
+    {
+      priv->updates_frozen = updates_frozen;
+      if (updates_frozen)
+        meta_window_actor_freeze (self);
+      else
+        meta_window_actor_thaw (self);
+    }
+}
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 9b7987d..9059f6f 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -336,6 +336,9 @@ struct _MetaWindow
   /* if non-NULL, the bounds of the window frame */
   cairo_region_t *frame_bounds;
 
+  /* if TRUE, we are freezing updates during a resize */
+  guint updates_frozen_for_resize : 1;
+
   /* Note: can be NULL */
   GSList *struts;
 
@@ -655,4 +658,6 @@ gboolean meta_window_can_tile_side_by_side   (MetaWindow *window);
 
 void meta_window_compute_tile_match (MetaWindow *window);
 
+gboolean meta_window_updates_are_frozen (MetaWindow *window);
+
 #endif
diff --git a/src/core/window.c b/src/core/window.c
index 83255e0..f190c74 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -4466,6 +4466,37 @@ send_sync_request (MetaWindow *window)
 }
 #endif
 
+/**
+ * meta_window_updates_are_frozen:
+ * @window: a #MetaWindow
+ *
+ * Gets whether the compositor should be updating the window contents;
+ * window content updates may be frozen at client request by setting
+ * an odd value in the extended _NET_WM_SYNC_REQUEST_COUNTER counter r
+ * by the window manager during a resize operation while waiting for
+ * the client to redraw.
+ *
+ * Return value: %TRUE if updates are currently frozen
+ */
+gboolean
+meta_window_updates_are_frozen (MetaWindow *window)
+{
+  return window->updates_frozen_for_resize;
+}
+
+static void
+meta_window_set_updates_frozen_for_resize (MetaWindow *window,
+                                           gboolean    updates_frozen)
+{
+  if (updates_frozen != window->updates_frozen_for_resize)
+    {
+      window->updates_frozen_for_resize = updates_frozen;
+      if (window->display->compositor)
+        meta_compositor_set_updates_frozen (window->display->compositor, window,
+                                            meta_window_updates_are_frozen (window));
+    }
+}
+
 static gboolean
 maybe_move_attached_dialog (MetaWindow *window,
                             void       *data)
@@ -4966,8 +4997,7 @@ meta_window_move_resize_internal (MetaWindow          *window,
 	  window->sync_request_time.tv_sec == 0)
 	{
 	  /* turn off updating */
-	  if (window->display->compositor)
-	    meta_compositor_set_updates (window->display->compositor, window, FALSE);
+          meta_window_set_updates_frozen_for_resize (window, TRUE);
 
 	  send_sync_request (window);
 	}
@@ -9097,8 +9127,7 @@ update_resize (MetaWindow *window,
     }
 
   /* If we get here, it means the client should have redrawn itself */
-  if (window->display->compositor)
-    meta_compositor_set_updates (window->display->compositor, window, TRUE);
+  meta_window_set_updates_frozen_for_resize (window, FALSE);
 
   /* Remove any scheduled compensation events */
   if (window->display->grab_resize_timeout_id)
@@ -9380,8 +9409,7 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
                                xev->root_x,
                                xev->root_y,
                                TRUE);
-	      if (window->display->compositor)
-		meta_compositor_set_updates (window->display->compositor, window, TRUE);
+              meta_window_set_updates_frozen_for_resize (window, FALSE);
 
               /* If a tiled window has been dragged free with a
                * mouse resize without snapping back to the tiled
diff --git a/src/meta/compositor.h b/src/meta/compositor.h
index 8ccd46d..e36f30b 100644
--- a/src/meta/compositor.h
+++ b/src/meta/compositor.h
@@ -153,9 +153,9 @@ void meta_compositor_window_unmapped      (MetaCompositor *compositor,
                                            MetaWindow     *window);
 void meta_compositor_sync_window_geometry (MetaCompositor *compositor,
                                            MetaWindow     *window);
-void meta_compositor_set_updates          (MetaCompositor *compositor,
+void meta_compositor_set_updates_frozen   (MetaCompositor *compositor,
                                            MetaWindow     *window,
-                                           gboolean        updates);
+                                           gboolean        updates_frozen);
 
 void meta_compositor_sync_stack                (MetaCompositor *compositor,
                                                 MetaScreen     *screen,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]