From 0ce649e965560863d585393f70c7212a4f9cffbc Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 20 Aug 2010 01:16:40 +0200 Subject: [PATCH] Plug a bunch of leaks. --- gtk/gtkstyle.c | 2 +- gtk/gtkstylecontext.c | 257 ++++++++++++++++++++++------------------- gtk/gtkstyleset.c | 1 + gtk/gtksymboliccolor.c | 25 ++++ gtk/gtkthemingengine.c | 6 + gtk/gtkwidget.c | 1 + gtk/gtkwidgetpath.c | 3 + 7 files changed, 175 insertions(+), 120 deletions(-) diff --git a/gtk/gtkstyle.c b/gtk/gtkstyle.c index 55a2fa7ab9..82d05dd2ce 100644 --- a/gtk/gtkstyle.c +++ b/gtk/gtkstyle.c @@ -696,7 +696,7 @@ gtk_style_update_from_context (GtkStyle *style) set_color (style, priv->context, state, GTK_RC_TEXT); } - /* FIXME: thickness */ + /* FIXME: thickness, font_desc */ } static void diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index d34bc4103c..f7f236d262 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -204,7 +204,7 @@ gtk_style_context_init (GtkStyleContext *style_context) GtkStyleContextPrivate); priv->store = gtk_style_set_new (); - priv->theming_engine = (GtkThemingEngine *) gtk_theming_engine_load (NULL); + priv->theming_engine = g_object_ref ((gpointer) gtk_theming_engine_load (NULL)); priv->direction = GTK_TEXT_DIR_RTL; @@ -257,15 +257,139 @@ clear_property_cache (GtkStyleContext *context) } } +static void +animation_info_free (AnimationInfo *info) +{ + g_object_unref (info->timeline); + g_object_unref (info->window); + + if (info->invalidation_region) + gdk_region_destroy (info->invalidation_region); + + g_array_free (info->rectangles, TRUE); + g_slice_free (AnimationInfo, info); +} + +static void +timeline_frame_cb (GtkTimeline *timeline, + gdouble progress, + gpointer user_data) +{ + AnimationInfo *info; + + info = user_data; + + if (info->invalidation_region && + !gdk_region_empty (info->invalidation_region)) + gdk_window_invalidate_region (info->window, info->invalidation_region, TRUE); +} + +static void +timeline_finished_cb (GtkTimeline *timeline, + gpointer user_data) +{ + GtkStyleContextPrivate *priv; + GtkStyleContext *context; + AnimationInfo *info; + GSList *l; + + context = user_data; + priv = context->priv; + + for (l = priv->animations; l; l = l->next) + { + info = l->data; + + if (info->timeline == timeline) + { + priv->animations = g_slist_delete_link (priv->animations, l); + + /* Invalidate one last time the area, so the final content is painted */ + if (info->invalidation_region && + !gdk_region_empty (info->invalidation_region)) + gdk_window_invalidate_region (info->window, info->invalidation_region, TRUE); + + animation_info_free (info); + break; + } + } +} + +static AnimationInfo * +animation_info_new (GtkStyleContext *context, + gdouble duration, + GtkTimelineProgressType progress_type, + GtkStateType state, + gboolean target_value, + GdkWindow *window) +{ + AnimationInfo *info; + + info = g_slice_new0 (AnimationInfo); + + info->rectangles = g_array_new (FALSE, FALSE, sizeof (GdkRectangle)); + info->timeline = gtk_timeline_new (duration); + info->window = g_object_ref (window); + info->state = state; + info->target_value = target_value; + + gtk_timeline_set_progress_type (info->timeline, progress_type); + + if (!target_value) + { + gtk_timeline_set_direction (info->timeline, GTK_TIMELINE_DIRECTION_BACKWARD); + gtk_timeline_rewind (info->timeline); + } + + g_signal_connect (info->timeline, "frame", + G_CALLBACK (timeline_frame_cb), info); + g_signal_connect (info->timeline, "finished", + G_CALLBACK (timeline_finished_cb), context); + + gtk_timeline_start (info->timeline); + + return info; +} + +static AnimationInfo * +animation_info_lookup (GtkStyleContext *context, + gpointer region_id, + GtkStateType state) +{ + GtkStyleContextPrivate *priv; + GSList *l; + + priv = context->priv; + + for (l = priv->animations; l; l = l->next) + { + AnimationInfo *info; + + info = l->data; + + if (info->state == state && + info->region_id == region_id) + return info; + } + + return NULL; +} + static void gtk_style_context_finalize (GObject *object) { GtkStyleContextPrivate *priv; GtkStyleContext *style_context; + GSList *l; style_context = GTK_STYLE_CONTEXT (object); priv = style_context->priv; + if (priv->widget_path) + gtk_widget_path_free (priv->widget_path); + + g_object_unref (priv->store); + g_list_foreach (priv->providers, (GFunc) style_provider_data_free, NULL); g_list_free (priv->providers); @@ -277,6 +401,16 @@ gtk_style_context_finalize (GObject *object) g_slist_foreach (priv->icon_factories, (GFunc) g_object_unref, NULL); g_slist_free (priv->icon_factories); + g_slist_free (priv->animation_regions); + + for (l = priv->animations; l; l = l->next) + animation_info_free ((AnimationInfo *) l->data); + + g_slist_free (priv->animations); + + if (priv->theming_engine) + g_object_unref (priv->theming_engine); + G_OBJECT_CLASS (gtk_style_context_parent_class)->finalize (object); } @@ -363,6 +497,9 @@ rebuild_properties (GtkStyleContext *context) } } + if (priv->theming_engine) + g_object_unref (priv->theming_engine); + gtk_style_set_get (priv->store, 0, "engine", &priv->theming_engine, NULL); @@ -1437,124 +1574,6 @@ gtk_style_context_lookup_color (GtkStyleContext *context, return gtk_symbolic_color_resolve (sym_color, priv->store, color); } -static void -timeline_frame_cb (GtkTimeline *timeline, - gdouble progress, - gpointer user_data) -{ - AnimationInfo *info; - - info = user_data; - - if (info->invalidation_region && - !gdk_region_empty (info->invalidation_region)) - gdk_window_invalidate_region (info->window, info->invalidation_region, TRUE); -} - -static void -animation_info_free (AnimationInfo *info) -{ - g_object_unref (info->timeline); - g_object_unref (info->window); - - if (info->invalidation_region) - gdk_region_destroy (info->invalidation_region); - - g_array_free (info->rectangles, TRUE); - g_slice_free (AnimationInfo, info); -} - -static void -timeline_finished_cb (GtkTimeline *timeline, - gpointer user_data) -{ - GtkStyleContextPrivate *priv; - GtkStyleContext *context; - AnimationInfo *info; - GSList *l; - - context = user_data; - priv = context->priv; - - for (l = priv->animations; l; l = l->next) - { - info = l->data; - - if (info->timeline == timeline) - { - priv->animations = g_slist_delete_link (priv->animations, l); - - /* Invalidate one last time the area, so the final content is painted */ - if (info->invalidation_region && - !gdk_region_empty (info->invalidation_region)) - gdk_window_invalidate_region (info->window, info->invalidation_region, TRUE); - - animation_info_free (info); - break; - } - } -} - -static AnimationInfo * -animation_info_new (GtkStyleContext *context, - gdouble duration, - GtkTimelineProgressType progress_type, - GtkStateType state, - gboolean target_value, - GdkWindow *window) -{ - AnimationInfo *info; - - info = g_slice_new0 (AnimationInfo); - - info->rectangles = g_array_new (FALSE, FALSE, sizeof (GdkRectangle)); - info->timeline = gtk_timeline_new (duration); - info->window = g_object_ref (window); - info->state = state; - info->target_value = target_value; - - gtk_timeline_set_progress_type (info->timeline, progress_type); - - if (!target_value) - { - gtk_timeline_set_direction (info->timeline, GTK_TIMELINE_DIRECTION_BACKWARD); - gtk_timeline_rewind (info->timeline); - } - - g_signal_connect (info->timeline, "frame", - G_CALLBACK (timeline_frame_cb), info); - g_signal_connect (info->timeline, "finished", - G_CALLBACK (timeline_finished_cb), context); - - gtk_timeline_start (info->timeline); - - return info; -} - -static AnimationInfo * -animation_info_lookup (GtkStyleContext *context, - gpointer region_id, - GtkStateType state) -{ - GtkStyleContextPrivate *priv; - GSList *l; - - priv = context->priv; - - for (l = priv->animations; l; l = l->next) - { - AnimationInfo *info; - - info = l->data; - - if (info->state == state && - info->region_id == region_id) - return info; - } - - return NULL; -} - void gtk_style_context_notify_state_change (GtkStyleContext *context, GdkWindow *window, diff --git a/gtk/gtkstyleset.c b/gtk/gtkstyleset.c index 315846536e..a9df3a1201 100644 --- a/gtk/gtkstyleset.c +++ b/gtk/gtkstyleset.c @@ -129,6 +129,7 @@ property_data_free (PropertyData *data) g_value_unset (&value_data->value); } + g_array_free (data->values, TRUE); g_slice_free (PropertyData, data); } diff --git a/gtk/gtksymboliccolor.c b/gtk/gtksymboliccolor.c index bd33efaf6c..569f3066f0 100644 --- a/gtk/gtksymboliccolor.c +++ b/gtk/gtksymboliccolor.c @@ -65,6 +65,7 @@ gtk_symbolic_color_new_literal (GdkColor *color) symbolic_color = g_slice_new0 (GtkSymbolicColor); symbolic_color->type = COLOR_TYPE_LITERAL; symbolic_color->color = *color; + symbolic_color->ref_count = 1; return symbolic_color; } @@ -79,6 +80,7 @@ gtk_symbolic_color_new_name (const gchar *name) symbolic_color = g_slice_new0 (GtkSymbolicColor); symbolic_color->type = COLOR_TYPE_NAME; symbolic_color->name = g_strdup (name); + symbolic_color->ref_count = 1; return symbolic_color; } @@ -95,6 +97,7 @@ gtk_symbolic_color_new_shade (GtkSymbolicColor *color, symbolic_color->type = COLOR_TYPE_SHADE; symbolic_color->shade.color = gtk_symbolic_color_ref (color); symbolic_color->shade.factor = CLAMP (factor, 0, 1); + symbolic_color->ref_count = 1; return symbolic_color; } @@ -114,6 +117,7 @@ gtk_symbolic_color_new_mix (GtkSymbolicColor *color1, symbolic_color->mix.color1 = gtk_symbolic_color_ref (color1); symbolic_color->mix.color2 = gtk_symbolic_color_ref (color2); symbolic_color->mix.factor = CLAMP (factor, 0, 1); + symbolic_color->ref_count = 1; return symbolic_color; } @@ -134,6 +138,27 @@ gtk_symbolic_color_unref (GtkSymbolicColor *color) g_return_if_fail (color != NULL); color->ref_count--; + + if (color->ref_count == 0) + { + switch (color->type) + { + case COLOR_TYPE_NAME: + g_free (color->name); + break; + case COLOR_TYPE_SHADE: + gtk_symbolic_color_unref (color->shade.color); + break; + case COLOR_TYPE_MIX: + gtk_symbolic_color_unref (color->mix.color1); + gtk_symbolic_color_unref (color->mix.color2); + break; + default: + break; + } + + g_slice_free (GtkSymbolicColor, color); + } } gboolean diff --git a/gtk/gtkthemingengine.c b/gtk/gtkthemingengine.c index cbf57bd1d5..ef7a863cb5 100644 --- a/gtk/gtkthemingengine.c +++ b/gtk/gtkthemingengine.c @@ -724,6 +724,10 @@ gtk_theming_engine_render_option (GtkThemingEngine *engine, } cairo_restore (cr); + + gdk_color_free (fg_color); + gdk_color_free (base_color); + gdk_color_free (text_color); } static void @@ -1337,6 +1341,8 @@ gtk_theming_engine_render_line (GtkThemingEngine *engine, } cairo_restore (cr); + + gdk_color_free (bg_color); } typedef struct _ByteRange ByteRange; diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 22f3bf2fee..cb053fad6b 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -7442,6 +7442,7 @@ gtk_widget_ensure_style (GtkWidget *widget) NULL); gtk_widget_set_style_internal (widget, style, TRUE); + g_object_unref (style); } #if 0 diff --git a/gtk/gtkwidgetpath.c b/gtk/gtkwidgetpath.c index 6fe08f558a..0f5e420a41 100644 --- a/gtk/gtkwidgetpath.c +++ b/gtk/gtkwidgetpath.c @@ -102,6 +102,9 @@ gtk_widget_path_free (GtkWidgetPath *path) if (elem->regions) g_hash_table_destroy (elem->regions); + + if (elem->classes) + g_array_free (elem->classes, TRUE); } g_array_free (path->elems, TRUE);