From 3cef97f10d3125888ec7707944ecda02cd8abc20 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Sun, 7 Oct 2012 11:42:45 -0400 Subject: [PATCH] GdkFrameClock: Reverse order of resume-events and afterpaint Keeping events paused after the end of a frame put us in a weird state where we had to process and queue events - so that we would get the message from the compositor - but not deliver them. Instead resume events before ending the frame. https://bugzilla.gnome.org/show_bug.cgi?id=685460 --- gdk/gdkframeclock.h | 4 +- gdk/gdkframeclockidle.c | 116 +++++++++++++++++++--------------------- 2 files changed, 58 insertions(+), 62 deletions(-) diff --git a/gdk/gdkframeclock.h b/gdk/gdkframeclock.h index 624f6fef4c..d75fce984a 100644 --- a/gdk/gdkframeclock.h +++ b/gdk/gdkframeclock.h @@ -70,8 +70,8 @@ typedef enum { GDK_FRAME_CLOCK_PHASE_UPDATE = 1 << 2, GDK_FRAME_CLOCK_PHASE_LAYOUT = 1 << 3, GDK_FRAME_CLOCK_PHASE_PAINT = 1 << 4, - GDK_FRAME_CLOCK_PHASE_AFTER_PAINT = 1 << 5, - GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS = 1 << 6 + GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS = 1 << 5, + GDK_FRAME_CLOCK_PHASE_AFTER_PAINT = 1 << 6 } GdkFrameClockPhase; struct _GdkFrameClockInterface diff --git a/gdk/gdkframeclockidle.c b/gdk/gdkframeclockidle.c index ff4b479ae4..c8a90368ac 100644 --- a/gdk/gdkframeclockidle.c +++ b/gdk/gdkframeclockidle.c @@ -219,83 +219,79 @@ gdk_frame_clock_paint_idle (void *data) skip_to_resume_events = (priv->requested & ~(GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS | GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS)) == 0; - switch (priv->phase) + if (!skip_to_resume_events) { - case GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS: - break; - case GDK_FRAME_CLOCK_PHASE_NONE: - case GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT: - if (priv->freeze_count == 0) - { - priv->frame_time = compute_frame_time (clock_idle); - - priv->phase = GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT; - /* We always emit ::before-paint and ::after-paint if - * any of the intermediate phases are requested and - * they don't get repeated if you freeze/thaw while - * in them. */ - if (!skip_to_resume_events) + switch (priv->phase) + { + case GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS: + break; + case GDK_FRAME_CLOCK_PHASE_NONE: + case GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT: + if (priv->freeze_count == 0) { + priv->frame_time = compute_frame_time (clock_idle); + + priv->phase = GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT; + + /* We always emit ::before-paint and ::after-paint if + * any of the intermediate phases are requested and + * they don't get repeated if you freeze/thaw while + * in them. */ priv->requested &= ~GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT; g_signal_emit_by_name (G_OBJECT (clock), "before-paint"); + priv->phase = GDK_FRAME_CLOCK_PHASE_UPDATE; } - priv->phase = GDK_FRAME_CLOCK_PHASE_UPDATE; - } - case GDK_FRAME_CLOCK_PHASE_UPDATE: - if (priv->freeze_count == 0) - { - if (priv->requested & GDK_FRAME_CLOCK_PHASE_UPDATE) + case GDK_FRAME_CLOCK_PHASE_UPDATE: + if (priv->freeze_count == 0) { - priv->requested &= ~GDK_FRAME_CLOCK_PHASE_UPDATE; - g_signal_emit_by_name (G_OBJECT (clock), "update"); + if (priv->requested & GDK_FRAME_CLOCK_PHASE_UPDATE) + { + priv->requested &= ~GDK_FRAME_CLOCK_PHASE_UPDATE; + g_signal_emit_by_name (G_OBJECT (clock), "update"); + } } - } - case GDK_FRAME_CLOCK_PHASE_LAYOUT: - if (priv->freeze_count == 0) - { - priv->phase = GDK_FRAME_CLOCK_PHASE_LAYOUT; - if (priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT) + case GDK_FRAME_CLOCK_PHASE_LAYOUT: + if (priv->freeze_count == 0) { - priv->requested &= ~GDK_FRAME_CLOCK_PHASE_LAYOUT; - g_signal_emit_by_name (G_OBJECT (clock), "layout"); + priv->phase = GDK_FRAME_CLOCK_PHASE_LAYOUT; + if (priv->requested & GDK_FRAME_CLOCK_PHASE_LAYOUT) + { + priv->requested &= ~GDK_FRAME_CLOCK_PHASE_LAYOUT; + g_signal_emit_by_name (G_OBJECT (clock), "layout"); + } } - } - case GDK_FRAME_CLOCK_PHASE_PAINT: - if (priv->freeze_count == 0) - { - priv->phase = GDK_FRAME_CLOCK_PHASE_PAINT; - if (priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT) + case GDK_FRAME_CLOCK_PHASE_PAINT: + if (priv->freeze_count == 0) { - priv->requested &= ~GDK_FRAME_CLOCK_PHASE_PAINT; - g_signal_emit_by_name (G_OBJECT (clock), "paint"); + priv->phase = GDK_FRAME_CLOCK_PHASE_PAINT; + if (priv->requested & GDK_FRAME_CLOCK_PHASE_PAINT) + { + priv->requested &= ~GDK_FRAME_CLOCK_PHASE_PAINT; + g_signal_emit_by_name (G_OBJECT (clock), "paint"); + } } - } - case GDK_FRAME_CLOCK_PHASE_AFTER_PAINT: - if (priv->freeze_count == 0) - { - priv->phase = GDK_FRAME_CLOCK_PHASE_AFTER_PAINT; - if (!skip_to_resume_events) + case GDK_FRAME_CLOCK_PHASE_AFTER_PAINT: + if (priv->freeze_count == 0) { priv->requested &= ~GDK_FRAME_CLOCK_PHASE_AFTER_PAINT; g_signal_emit_by_name (G_OBJECT (clock), "after-paint"); + /* the ::after-paint phase doesn't get repeated on freeze/thaw, + */ + priv->phase = GDK_FRAME_CLOCK_PHASE_NONE; } - /* the ::after-paint phase doesn't get repeated on freeze/thaw, - */ - priv->phase = GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS; - } - case GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS: - if (priv->freeze_count == 0) - { - if (priv->requested & GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS) - { - priv->requested &= ~GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS; - g_signal_emit_by_name (G_OBJECT (clock), "resume-events"); - } - /* the ::resume-event phase doesn't get repeated on freeze/thaw */ - priv->phase = GDK_FRAME_CLOCK_PHASE_NONE; - } + case GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS: + ; + } } + if (priv->requested & GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS) + { + priv->requested &= ~GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS; + g_signal_emit_by_name (G_OBJECT (clock), "resume-events"); + } + + priv->phase = GDK_FRAME_CLOCK_PHASE_NONE; + if (priv->freeze_count == 0 && priv->requested != 0) { /* We need to start over again immediately - this implies that there is no