diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c index fc090c34d6..29dbe8ef9d 100644 --- a/gtk/gtkbuilder.c +++ b/gtk/gtkbuilder.c @@ -260,7 +260,7 @@ typedef struct char *domain; GHashTable *objects; GSList *delayed_properties; - GSList *signals; + GPtrArray *signals; GSList *bindings; char *filename; char *resource_prefix; @@ -375,8 +375,8 @@ gtk_builder_finalize (GObject *object) #endif g_hash_table_destroy (priv->objects); - - g_slist_free_full (priv->signals, (GDestroyNotify)_free_signal_info); + if (priv->signals) + g_ptr_array_free (priv->signals, TRUE); G_OBJECT_CLASS (gtk_builder_parent_class)->finalize (object); } @@ -1020,12 +1020,14 @@ _gtk_builder_add (GtkBuilder *builder, void _gtk_builder_add_signals (GtkBuilder *builder, - GSList *signals) + GPtrArray *signals) { GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder); - priv->signals = g_slist_concat (priv->signals, - g_slist_copy (signals)); + if (G_UNLIKELY (!priv->signals)) + priv->signals = g_ptr_array_new_with_free_func ((GDestroyNotify)_free_signal_info); + + g_ptr_array_extend_and_steal (priv->signals, signals); } static gboolean @@ -1853,18 +1855,17 @@ gtk_builder_connect_signals (GtkBuilder *builder, GError **error) { GtkBuilderPrivate *priv = gtk_builder_get_instance_private (builder); - GSList *l; GObject *object; GObject *connect_object; - gboolean result = FALSE; + gboolean result = TRUE; - if (!priv->signals) + if (!priv->signals || + priv->signals->len == 0) return TRUE; - priv->signals = g_slist_reverse (priv->signals); - for (l = priv->signals; l; l = l->next) + for (guint i = 0; i < priv->signals->len; i++) { - SignalInfo *signal = (SignalInfo*)l->data; + SignalInfo *signal = g_ptr_array_index (priv->signals, i); GClosure *closure; g_assert (signal != NULL); @@ -1897,7 +1898,10 @@ gtk_builder_connect_signals (GtkBuilder *builder, error); if (closure == NULL) - break; + { + result = false; + break; + } g_signal_connect_closure_by_id (object, signal->id, @@ -1905,10 +1909,8 @@ gtk_builder_connect_signals (GtkBuilder *builder, closure, signal->flags & G_CONNECT_AFTER ? TRUE : FALSE); } - if (l == NULL) - result = TRUE; - g_slist_free_full (priv->signals, (GDestroyNotify)_free_signal_info); + g_ptr_array_free (priv->signals, TRUE); priv->signals = NULL; return result; diff --git a/gtk/gtkbuilderparser.c b/gtk/gtkbuilderparser.c index 4009307af7..5008b4b7dd 100644 --- a/gtk/gtkbuilderparser.c +++ b/gtk/gtkbuilderparser.c @@ -797,7 +797,8 @@ free_object_info (ObjectInfo *info) { /* Do not free the signal items, which GtkBuilder takes ownership of */ g_type_class_unref (info->oclass); - g_slist_free (info->signals); + if (info->signals) + g_ptr_array_free (info->signals, TRUE); if (info->properties) g_ptr_array_free (info->properties, TRUE); g_free (info->constructor); @@ -1955,7 +1956,12 @@ end_element (GtkBuildableParseContext *context, if (GTK_IS_BUILDABLE (object_info->object) && GTK_BUILDABLE_GET_IFACE (object_info->object)->parser_finished) data->finalizers = g_slist_prepend (data->finalizers, object_info->object); - _gtk_builder_add_signals (data->builder, object_info->signals); + + if (object_info->signals) + { + _gtk_builder_add_signals (data->builder, object_info->signals); + object_info->signals = NULL; + } free_object_info (object_info); } @@ -1973,7 +1979,11 @@ end_element (GtkBuildableParseContext *context, ObjectInfo *object_info = (ObjectInfo*)state_peek_info (data, CommonInfo); g_assert (object_info != NULL); signal_info->object_name = g_strdup (object_info->id); - object_info->signals = g_slist_prepend (object_info->signals, signal_info); + + if (G_UNLIKELY (!object_info->signals)) + object_info->signals = g_ptr_array_new (); + + g_ptr_array_add (object_info->signals, signal_info); } else if (strcmp (element_name, "constant") == 0 || strcmp (element_name, "closure") == 0 || diff --git a/gtk/gtkbuilderprivate.h b/gtk/gtkbuilderprivate.h index f86aaea629..3b5568fa97 100644 --- a/gtk/gtkbuilderprivate.h +++ b/gtk/gtkbuilderprivate.h @@ -48,7 +48,7 @@ typedef struct { char *constructor; GPtrArray *properties; - GSList *signals; + GPtrArray *signals; GSList *bindings; GObject *object; @@ -220,7 +220,7 @@ void _gtk_builder_add_object (GtkBuilder *builder, void _gtk_builder_add (GtkBuilder *builder, ChildInfo *child_info); void _gtk_builder_add_signals (GtkBuilder *builder, - GSList *signals); + GPtrArray *signals); gboolean _gtk_builder_finish (GtkBuilder *builder, GError **error); void _free_signal_info (SignalInfo *info,