[mutter/wip/frame-synchronization: 2/8] Implement freezing of updates during resize
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/frame-synchronization: 2/8] Implement freezing of updates during resize
- Date: Thu, 4 Oct 2012 03:29:40 +0000 (UTC)
commit 293e04dd1a06bf97e4ca7430183da8703e909e63
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.
src/compositor/compositor.c | 14 +++++++--
src/compositor/meta-window-actor-private.h | 2 +
src/compositor/meta-window-actor.c | 46 +++++++++++++++++++++++----
src/core/window-private.h | 5 +++
src/core/window.c | 40 ++++++++++++++++++++----
src/meta/compositor.h | 4 +-
6 files changed, 93 insertions(+), 18 deletions(-)
---
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index e0e9b71..7f6d43e 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -688,10 +688,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 371233f..1339f54 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;
@@ -953,10 +954,16 @@ meta_window_actor_thaw (MetaWindowActor *self)
if (self->priv->freeze_count)
return;
+ /* We ignores 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);
}
@@ -1299,6 +1306,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)
{
@@ -1307,6 +1320,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)
{
@@ -1503,6 +1519,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 */
@@ -1955,12 +1974,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)
@@ -1989,6 +2002,7 @@ meta_window_actor_process_damage (MetaWindowActor *self,
* any drawing done to the window is always immediately reflected in the
* texture regardless of damage event handling.
*/
+
priv->needs_damage_all = TRUE;
return;
}
@@ -2399,3 +2413,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 1db735e..d07c14b 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;
@@ -648,4 +651,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 4c754b6..c95e78a 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -4421,6 +4421,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)
@@ -4918,8 +4949,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);
}
@@ -9043,8 +9073,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)
@@ -9301,8 +9330,7 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
event->xbutton.x_root,
event->xbutton.y_root,
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 c65267b..ab5070b 100644
--- a/src/meta/compositor.h
+++ b/src/meta/compositor.h
@@ -149,9 +149,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]