summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2013-04-24 22:21:06 +0200
committerAlexander Larsson <alexl@redhat.com>2013-04-24 22:21:06 +0200
commit0d9b189a6420c89627d08c5e3ec1b2f2f07b1385 (patch)
tree666996034f5722ecbe95da8474dab0073007cf7f
parentfe70c2db55d5aad47ebc856b2296753557d7bc2a (diff)
downloadgtk+-wip/simple-draw.tar.gz
gdkframeclock: Loop the layout phase if neededwip/simple-draw
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.
-rw-r--r--gdk/gdkframeclockidle.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/gdk/gdkframeclockidle.c b/gdk/gdkframeclockidle.c
index 5901c7f6ca..922af8715e 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)