GtkStyleContext: Stop animations if the window is gone.

This commit is contained in:
Carlos Garnacho 2010-11-24 22:53:36 +01:00
parent cc18d65986
commit ad6da0cdb8

View File

@ -536,14 +536,50 @@ animation_info_free (AnimationInfo *info)
g_slice_free (AnimationInfo, info); g_slice_free (AnimationInfo, info);
} }
static AnimationInfo *
animation_info_lookup_by_timeline (GtkStyleContext *context,
GtkTimeline *timeline)
{
GtkStyleContextPrivate *priv;
AnimationInfo *info;
GSList *l;
priv = context->priv;
for (l = priv->animations; l; l = l->next)
{
info = l->data;
if (info->timeline == timeline)
return info;
}
return NULL;
}
static void static void
timeline_frame_cb (GtkTimeline *timeline, timeline_frame_cb (GtkTimeline *timeline,
gdouble progress, gdouble progress,
gpointer user_data) gpointer user_data)
{ {
GtkStyleContextPrivate *priv;
GtkStyleContext *context;
AnimationInfo *info; AnimationInfo *info;
info = user_data; context = user_data;
priv = context->priv;
info = animation_info_lookup_by_timeline (context, timeline);
g_assert (info != NULL);
/* Cancel transition if window is gone */
if (gdk_window_is_destroyed (info->window) ||
!gdk_window_is_visible (info->window))
{
priv->animations = g_slist_remove (priv->animations, info);
animation_info_free (info);
return;
}
if (info->invalidation_region && if (info->invalidation_region &&
!cairo_region_is_empty (info->invalidation_region)) !cairo_region_is_empty (info->invalidation_region))
@ -559,30 +595,23 @@ timeline_finished_cb (GtkTimeline *timeline,
GtkStyleContextPrivate *priv; GtkStyleContextPrivate *priv;
GtkStyleContext *context; GtkStyleContext *context;
AnimationInfo *info; AnimationInfo *info;
GSList *l;
context = user_data; context = user_data;
priv = context->priv; priv = context->priv;
info = animation_info_lookup_by_timeline (context, timeline);
for (l = priv->animations; l; l = l->next) g_assert (info != NULL);
{
info = l->data;
if (info->timeline == timeline) priv->animations = g_slist_remove (priv->animations, info);
{
priv->animations = g_slist_delete_link (priv->animations, l);
/* Invalidate one last time the area, so the final content is painted */ /* Invalidate one last time the area, so the final content is painted */
if (info->invalidation_region && if (info->invalidation_region &&
!cairo_region_is_empty (info->invalidation_region)) !cairo_region_is_empty (info->invalidation_region))
gdk_window_invalidate_region (info->window, info->invalidation_region, TRUE); gdk_window_invalidate_region (info->window, info->invalidation_region, TRUE);
else else
gdk_window_invalidate_rect (info->window, NULL, TRUE); gdk_window_invalidate_rect (info->window, NULL, TRUE);
animation_info_free (info); animation_info_free (info);
break;
}
}
} }
static AnimationInfo * static AnimationInfo *
@ -616,7 +645,7 @@ animation_info_new (GtkStyleContext *context,
} }
g_signal_connect (info->timeline, "frame", g_signal_connect (info->timeline, "frame",
G_CALLBACK (timeline_frame_cb), info); G_CALLBACK (timeline_frame_cb), context);
g_signal_connect (info->timeline, "finished", g_signal_connect (info->timeline, "finished",
G_CALLBACK (timeline_finished_cb), context); G_CALLBACK (timeline_finished_cb), context);