[gtk+/wip/simple-draw3: 15/23] gdkframeclock: Loop the layout phase if needed
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/simple-draw3: 15/23] gdkframeclock: Loop the layout phase if needed
- Date: Mon, 29 Apr 2013 19:52:04 +0000 (UTC)
commit 08df83daec67da8bf2958024cf9d03e571bf9afc
Author: Alexander Larsson <alexl redhat com>
Date: Wed Apr 24 22:21:06 2013 +0200
gdkframeclock: Loop the layout phase if needed
In the case where the layout phase queued a layout we don't
want to progress to the paint phase with invalid allocations, so
we loop the layout. This shouldn't normally happen, but it may
happen in some edge cases like if user/wm resizes clash with
natural window size changes from a gtk widget. This should not
generally loop though, so we detect this after 4 cycles and
print a warning.
This was detected because of an issue in GtkWindow where it
seems to incorrectly handle the case of a user interactive resize.
It seems gtk_window_move_resize() believes that configure_request_size_changed
changed due to hitting some corner case so it calls
gtk_widget_queue_resize_no_redraw(), marking the window as need_alloc
after the layout phase. This commit fixes the issue, but we should
also look into if we can fix that.
gdk/gdkframeclockidle.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
---
diff --git a/gdk/gdkframeclockidle.c b/gdk/gdkframeclockidle.c
index 5901c7f..922af87 100644
--- a/gdk/gdkframeclockidle.c
+++ b/gdk/gdkframeclockidle.c
@@ -384,6 +384,7 @@ gdk_frame_clock_paint_idle (void *data)
case GDK_FRAME_CLOCK_PHASE_LAYOUT:
if (priv->freeze_count == 0)
{
+ int iter;
#ifdef G_ENABLE_DEBUG
if ((_gdk_debug_flags & GDK_DEBUG_FRAMES) != 0)
{
@@ -394,11 +395,20 @@ gdk_frame_clock_paint_idle (void *data)
#endif /* G_ENABLE_DEBUG */
priv->phase = GDK_FRAME_CLOCK_PHASE_LAYOUT;
- if (priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT)
+ /* We loop in the layout phase, because we don't want to progress
+ * into the paint phase with invalid size allocations. This may
+ * happen in some situation like races between user window
+ * resizes and natural size changes.
+ */
+ iter = 0;
+ while ((priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT) &&
+ priv->freeze_count == 0 && iter++ < 4)
{
priv->requested &= ~GDK_FRAME_CLOCK_PHASE_LAYOUT;
g_signal_emit_by_name (G_OBJECT (clock), "layout");
}
+ if (iter == 4)
+ g_warning ("gdk-frame-clock: layout continuously requested, giving up after 4 tries");
}
case GDK_FRAME_CLOCK_PHASE_PAINT:
if (priv->freeze_count == 0)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]