ClutterStage: Replace clutter_stage_set_paint_callback() with ::after-paint signal

clutter_stage_set_paint_callback() has the disadvantage that it only
works for a single caller, and subsequent callers will overwrite and
break previous callers. Replace it with an ::after-paint signal that is
emitted at the same point - after all painting for the stage is
completed but before the drawing is presented to the screen.

https://bugzilla.gnome.org/show_bug.cgi?id=732342
This commit is contained in:
Owen W. Taylor 2014-06-05 15:21:05 -04:00
parent 9c74b98310
commit ec911dc8b9
5 changed files with 23 additions and 60 deletions

View File

@ -146,7 +146,6 @@ struct _ClutterStagePrivate
ClutterStageState current_state;
ClutterStagePaintFunc paint_callback;
gpointer paint_data;
GDestroyNotify paint_notify;
@ -192,6 +191,7 @@ enum
ACTIVATE,
DEACTIVATE,
DELETE_EVENT,
AFTER_PAINT,
LAST_SIGNAL
};
@ -202,7 +202,6 @@ static const ClutterColor default_stage_color = { 255, 255, 255, 255 };
static void clutter_stage_maybe_finish_queue_redraws (ClutterStage *stage);
static void free_queue_redraw_entry (ClutterStageQueueRedrawEntry *entry);
static void clutter_stage_invoke_paint_callback (ClutterStage *stage);
static void clutter_container_iface_init (ClutterContainerIface *iface);
@ -688,7 +687,7 @@ _clutter_stage_do_paint (ClutterStage *stage,
_clutter_stage_update_active_framebuffer (stage);
clutter_actor_paint (CLUTTER_ACTOR (stage));
clutter_stage_invoke_paint_callback (stage);
g_signal_emit (stage, stage_signals[AFTER_PAINT], 0);
}
/* If we don't implement this here, we get the paint function
@ -2211,6 +2210,23 @@ clutter_stage_class_init (ClutterStageClass *klass)
G_TYPE_BOOLEAN, 1,
CLUTTER_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
/**
* ClutterStage::after-paint:
* @stage: the stage that received the event
*
* The ::after-paint signal is emitted after the stage is painted,
* but before the results are displayed on the screen.
*
* Since: 1.20
*/
stage_signals[AFTER_PAINT] =
g_signal_new (I_("after-paint"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
0, /* no corresponding vfunc */
NULL, NULL, NULL,
G_TYPE_NONE, 0);
klass->fullscreen = clutter_stage_real_fullscreen;
klass->activate = clutter_stage_real_activate;
klass->deactivate = clutter_stage_real_deactivate;
@ -4593,45 +4609,6 @@ clutter_stage_skip_sync_delay (ClutterStage *stage)
_clutter_stage_window_schedule_update (stage_window, -1);
}
/**
* clutter_stage_set_paint_callback:
* @stage: a #ClutterStage
* @callback: (allow-none): a callback
* @data: (allow-none): data to be passed to @callback
* @notify: (allow-none): function to be called when the callback is removed
*
* Sets a callback function to be invoked after the @stage has been
* painted.
*
* Since: 1.14
*/
void
clutter_stage_set_paint_callback (ClutterStage *stage,
ClutterStagePaintFunc callback,
gpointer data,
GDestroyNotify notify)
{
ClutterStagePrivate *priv;
g_return_if_fail (CLUTTER_IS_STAGE (stage));
priv = stage->priv;
if (priv->paint_notify != NULL)
priv->paint_notify (priv->paint_data);
priv->paint_callback = callback;
priv->paint_data = data;
priv->paint_notify = notify;
}
static void
clutter_stage_invoke_paint_callback (ClutterStage *stage)
{
if (stage->priv->paint_callback != NULL)
stage->priv->paint_callback (stage, stage->priv->paint_data);
}
void
_clutter_stage_set_scale_factor (ClutterStage *stage,
int factor)

View File

@ -243,15 +243,6 @@ void clutter_stage_set_sync_delay (ClutterStage
gint sync_delay);
CLUTTER_AVAILABLE_IN_1_14
void clutter_stage_skip_sync_delay (ClutterStage *stage);
typedef void (* ClutterStagePaintFunc) (ClutterStage *stage,
gpointer data);
CLUTTER_AVAILABLE_IN_1_14
void clutter_stage_set_paint_callback (ClutterStage *stage,
ClutterStagePaintFunc callback,
gpointer data,
GDestroyNotify notify);
#endif
G_END_DECLS

View File

@ -669,7 +669,6 @@ clutter_stage_get_accept_focus
<SUBSECTION>
ClutterStagePaintFunc
clutter_stage_set_paint_callback
clutter_stage_set_sync_delay
clutter_stage_skip_sync_delay

View File

@ -75,10 +75,8 @@ actor_offscreen_limit_max_size (void)
return;
data.stage = clutter_test_get_stage ();
clutter_stage_set_paint_callback (CLUTTER_STAGE (data.stage),
check_results,
&data,
NULL);
g_signal_connect (data.stage, "after-paint",
G_CALLBACK (check_results), &data);
clutter_actor_set_size (data.stage, STAGE_WIDTH, STAGE_HEIGHT);
data.actor_group1 = clutter_actor_new ();

View File

@ -271,10 +271,8 @@ actor_shader_effect (void)
clutter_actor_show (stage);
was_painted = FALSE;
clutter_stage_set_paint_callback (CLUTTER_STAGE (stage),
paint_cb,
&was_painted,
NULL);
g_signal_connect (stage, "after-paint",
G_CALLBACK (paint_cb), NULL);
while (!was_painted)
g_main_context_iteration (NULL, FALSE);