Bug 1087 - virtualize stage_queue_redraw
Add a ClutterStage::queue-redraw signal. The purpose of this signal is to allow combining the Clutter redraw idle with another redraw idle such as gtk's (or any other one really; this is desirable anytime Clutter is not the only thing drawing to a toplevel window). To override the default, you would connect to ::queue-redraw and then stop the signal emission.
This commit is contained in:
parent
f09b221ade
commit
be462b2ea8
@ -115,6 +115,8 @@ enum
|
||||
UNFULLSCREEN,
|
||||
ACTIVATE,
|
||||
DEACTIVATE,
|
||||
QUEUE_REDRAW,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@ -335,6 +337,42 @@ clutter_stage_real_fullscreen (ClutterStage *stage)
|
||||
clutter_actor_allocate (CLUTTER_ACTOR (stage), &box, FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
redraw_update_idle (gpointer user_data)
|
||||
{
|
||||
ClutterStage *stage = user_data;
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
|
||||
if (priv->update_idle)
|
||||
{
|
||||
g_source_remove (priv->update_idle);
|
||||
priv->update_idle = 0;
|
||||
}
|
||||
|
||||
CLUTTER_NOTE (MULTISTAGE, "redrawing via idle for stage:%p", stage);
|
||||
clutter_redraw (stage);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_real_queue_redraw (ClutterStage *stage)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
|
||||
if (priv->update_idle == 0)
|
||||
{
|
||||
CLUTTER_TIMESTAMP (SCHEDULER, "Adding idle source for stage: %p", stage);
|
||||
|
||||
/* FIXME: weak_ref self in case we dissapear before paint? */
|
||||
priv->update_idle =
|
||||
clutter_threads_add_idle_full (CLUTTER_PRIORITY_REDRAW,
|
||||
redraw_update_idle,
|
||||
stage,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@ -687,8 +725,58 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
||||
NULL, NULL,
|
||||
clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
/**
|
||||
* ClutterStage::queue-redraw:
|
||||
* @stage: the stage which was queued for redraw
|
||||
*
|
||||
* The ::queue-redraw signal is emitted each time a #ClutterStage
|
||||
* has been queued for a redraw. You can use this signal to know
|
||||
* when clutter_stage_queue_redraw() has been called.
|
||||
*
|
||||
* Toolkits embedding a #ClutterStage which require a redraw and
|
||||
* relayout cycle can stop the emission of this signal using the
|
||||
* GSignal API, redraw the UI and then call clutter_redraw()
|
||||
* themselves, like:
|
||||
*
|
||||
* |[
|
||||
* static void
|
||||
* on_redraw_complete (void)
|
||||
* {
|
||||
* /* execute the Clutter drawing pipeline */
|
||||
* clutter_redraw ();
|
||||
* }
|
||||
*
|
||||
* static void
|
||||
* on_stage_queue_redraw (ClutterStage *stage)
|
||||
* {
|
||||
* /* this prevents the default handler to run */
|
||||
* g_signal_stop_emission_by_name (stage, "queue-redraw");
|
||||
*
|
||||
* /* queue a redraw with the host toolkit and call
|
||||
* * a function when the redraw has been completed
|
||||
* */
|
||||
* queue_a_redraw (G_CALLBACK (on_redraw_complete));
|
||||
* }
|
||||
* ]|
|
||||
*
|
||||
* <note><para>This signal is emitted before the Clutter paint
|
||||
* pipeline is run. If you want to know when the pipeline has been
|
||||
* completed you should connect to the ::paint signal on the Stage
|
||||
* with g_signal_connect_after().</para></note>
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
stage_signals[QUEUE_REDRAW] =
|
||||
g_signal_new (I_("queue-redraw"),
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (ClutterStageClass, queue_redraw),
|
||||
NULL, NULL,
|
||||
clutter_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
klass->fullscreen = clutter_stage_real_fullscreen;
|
||||
klass->queue_redraw = clutter_stage_real_queue_redraw;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (ClutterStagePrivate));
|
||||
}
|
||||
@ -1826,24 +1914,6 @@ clutter_stage_ensure_viewport (ClutterStage *stage)
|
||||
clutter_stage_queue_redraw (stage);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
redraw_update_idle (gpointer user_data)
|
||||
{
|
||||
ClutterStage *stage = user_data;
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
|
||||
if (priv->update_idle)
|
||||
{
|
||||
g_source_remove (priv->update_idle);
|
||||
priv->update_idle = 0;
|
||||
}
|
||||
|
||||
CLUTTER_NOTE (MULTISTAGE, "redrawing via idle for stage:%p", stage);
|
||||
clutter_redraw (stage);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_stage_queue_redraw:
|
||||
* @stage: the #ClutterStage
|
||||
@ -1860,17 +1930,7 @@ clutter_stage_queue_redraw (ClutterStage *stage)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||
|
||||
if (!stage->priv->update_idle)
|
||||
{
|
||||
CLUTTER_TIMESTAMP (SCHEDULER, "Adding idle source for stage: %p", stage);
|
||||
|
||||
/* FIXME: weak_ref self in case we dissapear before paint? */
|
||||
stage->priv->update_idle =
|
||||
clutter_threads_add_idle_full (CLUTTER_PRIORITY_REDRAW,
|
||||
redraw_update_idle,
|
||||
stage,
|
||||
NULL);
|
||||
}
|
||||
g_signal_emit (stage, stage_signals[QUEUE_REDRAW], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,6 +106,8 @@ struct _ClutterStageClass
|
||||
void (* activate) (ClutterStage *stage);
|
||||
void (* deactivate) (ClutterStage *stage);
|
||||
|
||||
void (* queue_redraw) (ClutterStage *stage);
|
||||
|
||||
/*< private >*/
|
||||
/* padding for future expansion */
|
||||
gpointer _padding_dummy[32];
|
||||
|
Loading…
Reference in New Issue
Block a user