forked from AuroraMiddleware/gtk
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
This commit is contained in:
parent
7753883add
commit
c4545cc5d4
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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->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;
|
||||
|
||||
priv->in_paint = FALSE;
|
||||
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;
|
||||
GdkFrameClockIdle *clock_idle = GDK_FRAME_CLOCK_IDLE (clock);
|
||||
GdkFrameClockIdlePrivate *priv = clock_idle->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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user