[gtk+] GdkFrameClock: Make the phase explicit when requesting the frame
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] GdkFrameClock: Make the phase explicit when requesting the frame
- Date: Thu, 14 Feb 2013 22:23:17 +0000 (UTC)
commit c4545cc5d47364b66b7ecd7bb482210fb8c8655a
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Wed Oct 3 19:38:40 2012 -0400
GdkFrameClock: Make the phase explicit when requesting the frame
Instead of having gdk_frame_clock_request_frame() have
gdk_frame_clock_request_phase() where we can say what phase we need.
This allows us to know if we get a frame-request during layout whether
it's just a request for drawing from the layout, or whether another
layout phase is needed.
https://bugzilla.gnome.org/show_bug.cgi?id=685460
gdk/gdkframeclock.c | 43 ++++++-------------------
gdk/gdkframeclock.h | 23 ++++++++++---
gdk/gdkframeclockidle.c | 79 ++++++++++++++++++++++++++++++++++-------------
gdk/gdkwindow.c | 3 +-
gtk/gtkcontainer.c | 6 ++-
gtk/gtkwidget.c | 2 +-
6 files changed, 91 insertions(+), 65 deletions(-)
---
diff --git a/gdk/gdkframeclock.c b/gdk/gdkframeclock.c
index ca54840..9fcf642 100644
--- a/gdk/gdkframeclock.c
+++ b/gdk/gdkframeclock.c
@@ -47,7 +47,7 @@
* for example.
*
* A frame clock is idle until someone requests a frame with
- * gdk_frame_clock_request_frame(). At that time, the frame clock
+ * gdk_frame_clock_request_phase(). At that time, the frame clock
* emits its GdkFrameClock:frame-requested signal if no frame was
* already pending.
*
@@ -203,7 +203,7 @@ gdk_frame_clock_get_frame_time (GdkFrameClock *clock)
}
/**
- * gdk_frame_clock_request_frame:
+ * gdk_frame_clock_request_phase:
* @clock: the clock
*
* Asks the frame clock to paint a frame. The frame
@@ -217,15 +217,17 @@ gdk_frame_clock_get_frame_time (GdkFrameClock *clock)
* Since: 3.0
*/
void
-gdk_frame_clock_request_frame (GdkFrameClock *clock)
+gdk_frame_clock_request_phase (GdkFrameClock *clock,
+ GdkFrameClockPhase phase)
{
g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
- GDK_FRAME_CLOCK_GET_IFACE (clock)->request_frame (clock);
+ GDK_FRAME_CLOCK_GET_IFACE (clock)->request_phase (clock, phase);
}
+
/**
- * gdk_frame_clock_get_frame_requested:
+ * gdk_frame_clock_get_requested:
* @clock: the clock
*
* Gets whether a frame paint has been requested but has not been
@@ -235,12 +237,12 @@ gdk_frame_clock_request_frame (GdkFrameClock *clock)
* Since: 3.0
* Return value: TRUE if a frame paint is pending
*/
-gboolean
-gdk_frame_clock_get_frame_requested (GdkFrameClock *clock)
+GdkFrameClockPhase
+gdk_frame_clock_get_requested (GdkFrameClock *clock)
{
g_return_val_if_fail (GDK_IS_FRAME_CLOCK (clock), FALSE);
- return GDK_FRAME_CLOCK_GET_IFACE (clock)->get_frame_requested (clock);
+ return GDK_FRAME_CLOCK_GET_IFACE (clock)->get_requested (clock);
}
/**
@@ -281,28 +283,3 @@ gdk_frame_clock_frame_requested (GdkFrameClock *clock)
g_signal_emit (G_OBJECT (clock),
signals[FRAME_REQUESTED], 0);
}
-
-/**
- * gdk_frame_clock_paint:
- * @clock: the clock
- *
- * Emits the before-paint, paint, and after-paint signals. Used in
- * implementations of the #GdkFrameClock interface.
- */
-void
-gdk_frame_clock_paint (GdkFrameClock *clock)
-{
- g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
-
- g_signal_emit (G_OBJECT (clock),
- signals[BEFORE_PAINT], 0);
-
- g_signal_emit (G_OBJECT (clock),
- signals[LAYOUT], 0);
-
- g_signal_emit (G_OBJECT (clock),
- signals[PAINT], 0);
-
- g_signal_emit (G_OBJECT (clock),
- signals[AFTER_PAINT], 0);
-}
diff --git a/gdk/gdkframeclock.h b/gdk/gdkframeclock.h
index 043a890..fe0ea58 100644
--- a/gdk/gdkframeclock.h
+++ b/gdk/gdkframeclock.h
@@ -43,18 +43,28 @@ G_BEGIN_DECLS
typedef struct _GdkFrameClock GdkFrameClock;
typedef struct _GdkFrameClockInterface GdkFrameClockInterface;
+typedef enum {
+ GDK_FRAME_CLOCK_PHASE_NONE = 0,
+ GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT = 1 << 0,
+ GDK_FRAME_CLOCK_PHASE_LAYOUT = 1 << 1,
+ GDK_FRAME_CLOCK_PHASE_PAINT = 1 << 2,
+ GDK_FRAME_CLOCK_PHASE_AFTER_PAINT = 1 << 3
+} GdkFrameClockPhase;
+
struct _GdkFrameClockInterface
{
GTypeInterface base_iface;
guint64 (* get_frame_time) (GdkFrameClock *clock);
- void (* request_frame) (GdkFrameClock *clock);
- gboolean (* get_frame_requested) (GdkFrameClock *clock);
+
+ void (* request_phase) (GdkFrameClock *clock,
+ GdkFrameClockPhase phase);
+ GdkFrameClockPhase (* get_requested) (GdkFrameClock *clock);
/* signals */
/* void (* frame_requested) (GdkFrameClock *clock); */
/* void (* before_paint) (GdkFrameClock *clock); */
- /* void (* layout) 1(GdkFrameClock *clock); */
+ /* void (* layout) (GdkFrameClock *clock); */
/* void (* paint) (GdkFrameClock *clock); */
/* void (* after_paint) (GdkFrameClock *clock); */
};
@@ -62,8 +72,10 @@ struct _GdkFrameClockInterface
GType gdk_frame_clock_get_type (void) G_GNUC_CONST;
guint64 gdk_frame_clock_get_frame_time (GdkFrameClock *clock);
-void gdk_frame_clock_request_frame (GdkFrameClock *clock);
-gboolean gdk_frame_clock_get_frame_requested (GdkFrameClock *clock);
+
+void gdk_frame_clock_request_phase (GdkFrameClock *clock,
+ GdkFrameClockPhase phase);
+GdkFrameClockPhase gdk_frame_clock_get_requested (GdkFrameClock *clock);
/* Convenience API */
void gdk_frame_clock_get_frame_time_val (GdkFrameClock *clock,
@@ -71,7 +83,6 @@ void gdk_frame_clock_get_frame_time_val (GdkFrameClock *clock,
/* Signal emitters (used in frame clock implementations) */
void gdk_frame_clock_frame_requested (GdkFrameClock *clock);
-void gdk_frame_clock_paint (GdkFrameClock *clock);
G_END_DECLS
diff --git a/gdk/gdkframeclockidle.c b/gdk/gdkframeclockidle.c
index ff20632..bdcb16a 100644
--- a/gdk/gdkframeclockidle.c
+++ b/gdk/gdkframeclockidle.c
@@ -38,9 +38,12 @@ struct _GdkFrameClockIdlePrivate
guint idle_id;
- unsigned int in_paint : 1;
+ GdkFrameClockPhase requested;
+ GdkFrameClockPhase phase;
};
+static gboolean gdk_frame_clock_paint_idle (void *data);
+
static void gdk_frame_clock_idle_finalize (GObject *object);
static void gdk_frame_clock_idle_interface_init (GdkFrameClockInterface *iface);
@@ -113,7 +116,7 @@ gdk_frame_clock_idle_get_frame_time (GdkFrameClock *clock)
guint64 computed_frame_time;
/* can't change frame time during a paint */
- if (priv->in_paint)
+ if (priv->phase != GDK_FRAME_CLOCK_PHASE_NONE)
return priv->frame_time;
/* Outside a paint, pick something close to "now" */
@@ -130,6 +133,22 @@ gdk_frame_clock_idle_get_frame_time (GdkFrameClock *clock)
return priv->frame_time;
}
+static void
+maybe_start_idle (GdkFrameClockIdle *clock_idle)
+{
+ GdkFrameClockIdlePrivate *priv = clock_idle->priv;
+
+ if (priv->idle_id == 0 && priv->requested != 0)
+ {
+ priv->idle_id = gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
+ gdk_frame_clock_paint_idle,
+ g_object_ref (clock_idle),
+ (GDestroyNotify) g_object_unref);
+
+ gdk_frame_clock_frame_requested (GDK_FRAME_CLOCK (clock_idle));
+ }
+}
+
static gboolean
gdk_frame_clock_paint_idle (void *data)
{
@@ -139,44 +158,60 @@ gdk_frame_clock_paint_idle (void *data)
priv->idle_id = 0;
- priv->in_paint = TRUE;
priv->frame_time = compute_frame_time (clock_idle);
- gdk_frame_clock_paint (clock);
-
- priv->in_paint = FALSE;
+ priv->phase = GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT;
+ priv->requested &= ~GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT;
+ g_signal_emit_by_name (G_OBJECT (clock), "before-paint");
+ priv->phase = GDK_FRAME_CLOCK_PHASE_LAYOUT;
+ priv->requested &= ~GDK_FRAME_CLOCK_PHASE_LAYOUT;
+ g_signal_emit_by_name (G_OBJECT (clock), "layout");
+ priv->phase = GDK_FRAME_CLOCK_PHASE_PAINT;
+ priv->requested &= ~GDK_FRAME_CLOCK_PHASE_PAINT;
+ g_signal_emit_by_name (G_OBJECT (clock), "paint");
+ priv->phase = GDK_FRAME_CLOCK_PHASE_AFTER_PAINT;
+ priv->requested &= ~GDK_FRAME_CLOCK_PHASE_AFTER_PAINT;
+ g_signal_emit_by_name (G_OBJECT (clock), "after-paint");
+ priv->phase = GDK_FRAME_CLOCK_PHASE_NONE;
+
+ maybe_start_idle (clock_idle);
return FALSE;
}
static void
-gdk_frame_clock_idle_request_frame (GdkFrameClock *clock)
+gdk_frame_clock_idle_request_phase (GdkFrameClock *clock,
+ GdkFrameClockPhase phase)
{
- GdkFrameClockIdlePrivate *priv = GDK_FRAME_CLOCK_IDLE (clock)->priv;
-
- if (priv->idle_id == 0)
- {
- priv->idle_id = gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
- gdk_frame_clock_paint_idle,
- g_object_ref (clock),
- (GDestroyNotify) g_object_unref);
+ GdkFrameClockIdle *clock_idle = GDK_FRAME_CLOCK_IDLE (clock);
+ GdkFrameClockIdlePrivate *priv = clock_idle->priv;
- gdk_frame_clock_frame_requested (clock);
- }
+ priv->requested |= phase;
+ maybe_start_idle (clock_idle);
}
-static gboolean
-gdk_frame_clock_idle_get_frame_requested (GdkFrameClock *clock)
+static GdkFrameClockPhase
+gdk_frame_clock_idle_get_requested (GdkFrameClock *clock)
{
GdkFrameClockIdlePrivate *priv = GDK_FRAME_CLOCK_IDLE (clock)->priv;
- return priv->idle_id != 0;
+ return priv->requested;
}
static void
gdk_frame_clock_idle_interface_init (GdkFrameClockInterface *iface)
{
iface->get_frame_time = gdk_frame_clock_idle_get_frame_time;
- iface->request_frame = gdk_frame_clock_idle_request_frame;
- iface->get_frame_requested = gdk_frame_clock_idle_get_frame_requested;
+ iface->request_phase = gdk_frame_clock_idle_request_phase;
+ iface->get_requested = gdk_frame_clock_idle_get_requested;
+}
+
+GdkFrameClock *
+_gdk_frame_clock_idle_new (void)
+{
+ GdkFrameClockIdle *clock;
+
+ clock = g_object_new (GDK_TYPE_FRAME_CLOCK_IDLE, NULL);
+
+ return GDK_FRAME_CLOCK (clock);
}
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index f82ad16..e3b5026 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -3947,7 +3947,8 @@ gdk_window_schedule_update (GdkWindow *window)
gdk_window_is_toplevel_frozen (window)))
return;
- gdk_frame_clock_request_frame (gdk_window_get_frame_clock (window));
+ gdk_frame_clock_request_phase (gdk_window_get_frame_clock (window),
+ GDK_FRAME_CLOCK_PHASE_PAINT);
}
void
diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c
index 938887e..e73ef2a 100644
--- a/gtk/gtkcontainer.c
+++ b/gtk/gtkcontainer.c
@@ -1686,7 +1686,8 @@ gtk_container_idle_sizer (GdkFrameClock *clock,
}
else
{
- gdk_frame_clock_request_frame (clock);
+ gdk_frame_clock_request_phase (clock,
+ GDK_FRAME_CLOCK_PHASE_LAYOUT);
}
}
@@ -1705,7 +1706,8 @@ gtk_container_start_idle_sizer (GtkContainer *container)
container->priv->resize_clock = clock;
container->priv->resize_handler = g_signal_connect (clock, "layout",
G_CALLBACK (gtk_container_idle_sizer), container);
- gdk_frame_clock_request_frame (clock);
+ gdk_frame_clock_request_phase (clock,
+ GDK_FRAME_CLOCK_PHASE_LAYOUT);
}
static void
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index e1cf124..63fbcae 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -4793,7 +4793,7 @@ gtk_widget_queue_resize_no_redraw (GtkWidget *widget)
* then update the animation by calling
* gdk_frame_clock_get_frame_time() again during each repaint.
*
- * gdk_frame_clock_request_frame() will result in a new frame on the
+ * gdk_frame_clock_request_phase() will result in a new frame on the
* clock, but won't necessarily repaint any widgets. To repaint a
* widget, you have to use gtk_widget_queue_draw() which invalidates
* the widget (thus scheduling it to receive a draw on the next
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]