diff options
author | Juan Pablo Ugarte <juanpablougarte@gmail.com> | 2013-11-15 22:45:17 -0300 |
---|---|---|
committer | Juan Pablo Ugarte <juanpablougarte@gmail.com> | 2013-11-15 23:44:47 -0300 |
commit | 2bc40ad87be072aac2759755df63707d43f8415c (patch) | |
tree | d2aef65c7f35a6fcfd1b7be4f77e29d7d785bb77 | |
parent | af72b2dad1f4fa153a7449312841eec4d0a1e1dc (diff) | |
download | glade-2bc40ad87be072aac2759755df63707d43f8415c.tar.gz |
Sort object dependancy before saving using a topological
sorting algorithm _glade_tsort() instead of g_list_sort() with
glade_widget_depends() which is not a transitive property.
Closes Bug 709609 "[PATCH] Change way of sorting before writing XML output."
Fixes Bug 711858 "editing glade project results in long CPU usage spikes after upgrading to 3.16 and GTK+3.10"
-rw-r--r-- | gladeui/Makefile.am | 5 | ||||
-rw-r--r-- | gladeui/glade-project.c | 189 | ||||
-rw-r--r-- | gladeui/glade-tsort.c | 177 | ||||
-rw-r--r-- | gladeui/glade-tsort.h | 51 | ||||
-rw-r--r-- | gladeui/glade-widget-adaptor.c | 26 | ||||
-rw-r--r-- | gladeui/glade-widget-private.h | 36 | ||||
-rw-r--r-- | gladeui/glade-widget.c | 66 | ||||
-rw-r--r-- | plugins/gtk+/glade-gtk-entry.c | 11 | ||||
-rw-r--r-- | plugins/gtk+/glade-gtk-size-group.c | 10 | ||||
-rw-r--r-- | plugins/gtk+/glade-gtk-tree-view.c | 10 | ||||
-rw-r--r-- | plugins/gtk+/glade-gtk-widget.c | 8 | ||||
-rw-r--r-- | plugins/gtk+/gtk+.xml.in | 3 |
12 files changed, 474 insertions, 118 deletions
diff --git a/gladeui/Makefile.am b/gladeui/Makefile.am index 7e78bcb4..87d610cc 100644 --- a/gladeui/Makefile.am +++ b/gladeui/Makefile.am @@ -119,6 +119,7 @@ libgladeui_2_la_SOURCES = \ glade-signal-class.c \ glade-signal-editor.c \ glade-signal-model.c \ + glade-tsort.c \ glade-utils.c \ glade-widget.c \ glade-widget-action.c \ @@ -196,9 +197,11 @@ noinst_HEADERS = \ glade-preview-template.h \ glade-private.h \ glade-project-properties.h \ + glade-tsort.h \ gladeui-resources.h \ glade-drag.h \ - glade-dnd.h + glade-dnd.h \ + glade-widget-private.h if PLATFORM_WIN32 libgladeui_2_la_LDFLAGS += -no-undefined diff --git a/gladeui/glade-project.c b/gladeui/glade-project.c index e1acd14d..b6570f17 100644 --- a/gladeui/glade-project.c +++ b/gladeui/glade-project.c @@ -56,6 +56,9 @@ #include "glade-dnd.h" #include "glade-private.h" +#include "glade-widget-private.h" +#include "glade-tsort.h" + static void glade_project_target_version_for_adaptor (GladeProject *project, GladeWidgetAdaptor *adaptor, @@ -2582,19 +2585,171 @@ glade_project_write_css_provider_path (GladeProject *project, } static gint -sort_project_dependancies (GObject *a, GObject *b) +glade_widgets_name_cmp (gconstpointer ga, gconstpointer gb) { - GladeWidget *ga, *gb; + return g_strcmp0 (glade_widget_get_name ((gpointer)ga), glade_widget_get_name ((gpointer)gb)); +} - ga = glade_widget_get_from_gobject (a); - gb = glade_widget_get_from_gobject (b); +static inline gboolean +glade_project_widget_hard_depends (GladeWidget *widget, GladeWidget *another) +{ + GList *l; - if (glade_widget_depends (ga, gb)) - return 1; - else if (glade_widget_depends (gb, ga)) - return -1; - else - return strcmp (glade_widget_get_name (ga), glade_widget_get_name (gb)); + for (l = _glade_widget_peek_prop_refs (another); l; l = g_list_next (l)) + { + GladePropertyClass *klass; + + /* If one of the properties that reference @another is + * owned by @widget then @widget depends on @another + */ + if (glade_property_get_widget (l->data) == widget && + (klass = glade_property_get_class (l->data)) && + glade_property_class_get_construct_only (klass)) + return TRUE; + } + + return FALSE; +} + +static _NodeEdge * +glade_project_get_graph_deps (GladeProject *project) +{ + GladeProjectPrivate *priv = project->priv; + GList *l, *objects = NULL; + _NodeEdge *edges = NULL; + + /* Create list of GladeWidgets */ + for (l = priv->objects; l; l = g_list_next (l)) + objects = g_list_prepend (objects, glade_widget_get_from_gobject (l->data)); + + /* Sort objects alphabetically */ + objects = g_list_sort (objects, glade_widgets_name_cmp); + + /* Create edges of the directed graph */ + for (l = objects; l; l = g_list_next (l)) + { + GladeWidget *predecessor = l->data; + GladeWidget *predecessor_top; + GList *ll; + + predecessor_top = glade_widget_get_toplevel (predecessor); + + for (ll = objects; ll; ll = g_list_next (ll)) + { + GladeWidget *successor = ll->data; + GladeWidget *successor_top; + + successor_top = glade_widget_get_toplevel (successor); + + /* Ignore object within the same toplevel */ + if (predecessor_top == successor_top) + continue; + + /* Check if succesor depends on predecessor and add a corresponding + * edge to the dependency graph. + * Note that we add the implicit dependency on their respective + * toplevels because that is what we care! + */ + if (glade_widget_depends (successor, predecessor)) + edges = _node_edge_prepend (edges, predecessor_top, successor_top); + } + } + + g_list_free (objects); + + return edges; +} + +static GList * +glade_project_get_nodes_from_edges (GladeProject *project, _NodeEdge *edges) +{ + _NodeEdge *edge, *hard_edges = NULL; + GList *cycles = NULL; + + /* Collect widgets with circular dependencies */ + for (edge = edges; edge; edge = edge->next) + { + if (glade_widget_get_parent (edge->successor) == edge->predecessor || + glade_project_widget_hard_depends (edge->predecessor, edge->successor)) + hard_edges = _node_edge_prepend (hard_edges, edge->predecessor, edge->successor); + + /* Just toplevels */ + if (glade_widget_get_parent (edge->successor)) + continue; + + if (!g_list_find (cycles, edge->successor)) + cycles = g_list_prepend (cycles, edge->successor); + } + + /* Sort them alphabetically */ + cycles = g_list_sort (cycles, glade_widgets_name_cmp); + + if (!hard_edges) + return cycles; + + /* Sort them by hard deps */ + cycles = _glade_tsort (&cycles, &hard_edges); + + if (hard_edges) + { + GList *hard_cycles = NULL; + + /* Collect widgets with hard circular dependencies */ + for (edge = hard_edges; edge; edge = edge->next) + { + /* Just toplevels */ + if (glade_widget_get_parent (edge->successor)) + continue; + + if (!g_list_find (hard_cycles, edge->successor)) + hard_cycles = g_list_prepend (hard_cycles, edge->successor); + } + + /* And append to the end of the cycles list */ + cycles = g_list_concat (cycles, g_list_sort (hard_cycles, glade_widgets_name_cmp)); + + /* Opps! there is at least one hard circular dependency, + * GtkBuilder will fail to set one of the properties that create the cycle + */ + + _node_edge_free (hard_edges); + } + + return cycles; +} + +static GList * +glade_project_get_ordered_toplevels (GladeProject *project) +{ + GladeProjectPrivate *priv = project->priv; + GList *l, *sorted_tree, *tree = NULL; + _NodeEdge *edges; + + /* Create list of toplevels GladeWidgets */ + for (l = priv->tree; l; l = g_list_next (l)) + tree = g_list_prepend (tree, glade_widget_get_from_gobject (l->data)); + + /* Sort toplevels alphabetically */ + tree = g_list_sort (tree, glade_widgets_name_cmp); + + edges = glade_project_get_graph_deps (project); + + /* Sort tree */ + sorted_tree = _glade_tsort (&tree, &edges); + + if (edges) + { + GList *cycles = glade_project_get_nodes_from_edges (project, edges); + + /* And append to the end of the sorted list */ + sorted_tree = g_list_concat (sorted_tree, cycles); + + _node_edge_free (edges); + } + + /* No need to free tree as tsort will consume the list */ + + return sorted_tree; } static inline void @@ -2654,15 +2809,12 @@ glade_project_write (GladeProject *project) glade_project_write_css_provider_path (project, context, root); - /* Sort the toplevels */ - toplevels = g_list_copy (project->priv->tree); - toplevels = g_list_sort (toplevels, (GCompareFunc)sort_project_dependancies); + /* Get sorted toplevels */ + toplevels = glade_project_get_ordered_toplevels (project); - for (list = toplevels; list; list = list->next) + for (list = toplevels; list; list = g_list_next (list)) { - GladeWidget *widget; - - widget = glade_widget_get_from_gobject (list->data); + GladeWidget *widget = list->data; /* * Append toplevel widgets. Each widget then takes @@ -2670,6 +2822,9 @@ glade_project_write (GladeProject *project) */ if (!glade_widget_get_parent (widget)) glade_widget_write (widget, context, root); + else + g_warning ("Tried to save a non toplevel object '%s' at xml root", + glade_widget_get_name (widget)); } g_list_free (toplevels); diff --git a/gladeui/glade-tsort.c b/gladeui/glade-tsort.c new file mode 100644 index 00000000..439da33e --- /dev/null +++ b/gladeui/glade-tsort.c @@ -0,0 +1,177 @@ +/* + * glade-tsort.c: a topological sorting algorithm implementation + * + * Copyright (C) 2013 Juan Pablo Ugarte. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Authors: + * Juan Pablo Ugarte <juanpablougarte@gmail.com> + */ + +#include "glade-tsort.h" + +/** + * _node_edge_prepend: + * @node: a _NodeEdge pointer or NULL + * @predecessor: + * @successor: + * + * Adds a new node with the values @predecessor and @successor to the start of + * @node list. + * + * Returns: the new start of the node list. + */ +_NodeEdge * +_node_edge_prepend (_NodeEdge *node, + gpointer predecessor, + gpointer successor) +{ + _NodeEdge *edge = g_slice_new (_NodeEdge); + + edge->predecessor = predecessor; + edge->successor = successor; + edge->next = node; + + return edge; +} + +void +_node_edge_free (_NodeEdge *node) +{ + g_slice_free_chain (_NodeEdge, node, next); +} + +static inline void +tsort_remove_non_start_nodes (GList **nodes, _NodeEdge *edges) +{ + _NodeEdge *edge; + + for (edge = edges; edge; edge = edge->next) + *nodes = g_list_remove (*nodes, edge->successor); +} + + +static inline gboolean +tsort_node_has_no_incoming_edge (gpointer node, _NodeEdge *edges) +{ + _NodeEdge *edge; + + for (edge = edges; edge; edge = edge->next) + { + if (node == edge->successor) + return FALSE; + } + + return TRUE; +} + +/** + * _glade_tsort: + * @nodes: list of pointers to sort + * @edges: pointer to the list of #_NodeEdge that conform the dependency + * graph of @nodes. + * + * Topological sorting implementation. + * After calling this funtion only graph cycles (circular dependencies) are left + * in @edges list. So if @edges is NULL it means the returned list has all the + * elements topologically sorted if not it means there are at least one + * circular dependency. + * + * L ← Empty list that will contain the sorted elements + * S ← Set of all nodes with no incoming edges + * while S is non-empty do + * remove a node n from S + * insert n into L + * for each node m with an edge e from n to m do + * remove edge e from the graph + * if m has no other incoming edges then + * insert m into S + * return L (a topologically sorted order if graph has no edges) + * + * see: http://en.wikipedia.org/wiki/Topological_sorting + * + * Returns: a new list sorted by dependency including nodes only present in @edges + */ +GList * +_glade_tsort (GList **nodes, _NodeEdge **edges) +{ + GList *sorted_nodes; + + /* L ← Empty list that will contain the sorted elements */ + sorted_nodes = NULL; + + /* S ← Set of all nodes with no incoming edges */ + tsort_remove_non_start_nodes (nodes, *edges); + + /* while S is non-empty do */ + while (*nodes) + { + _NodeEdge *edge, *next, *prev = NULL; + gpointer n; + + /* remove a node n from S */ + n = (*nodes)->data; + *nodes = g_list_delete_link (*nodes, *nodes); + + /* insert n into L */ + /*if (!glade_widget_get_parent (n)) this would be a specific optimization */ + sorted_nodes = g_list_prepend (sorted_nodes, n); + + /* for each node m ... */ + for (edge = *edges; edge; edge = next) + { + next = edge->next; + + /* ... with an edge e from n to m do */ + if (edge->predecessor == n) + { + /* remove edge e from the graph */ + if (prev) + prev->next = (prev->next) ? prev->next->next : NULL; + else + /* edge is the first element in the list so we only need to + * change the start of the list */ + *edges = next; + + /* if m has no other incoming edges then */ + if (tsort_node_has_no_incoming_edge (edge->successor, *edges)) + /* insert m into S */ + *nodes = g_list_prepend (*nodes, edge->successor); + + g_slice_free (_NodeEdge, edge); + } + else + /* Keep a pointer to the previous node in the iteration to make + * things easier when removing a node + */ + prev = edge; + } + } + + /* if graph has edges then return error (graph has at least one cycle) */ +#if 0 /* We rather not return NULL, caller must check if edge */ + if (*edges) + { + g_list_free (sorted_nodes); + g_slice_free_chain (_NodeEdge, *edges, next); + *edges = NULL; + return NULL; + } +#endif + + /* return L (a topologically sorted order if edge is NULL) */ + return g_list_reverse (sorted_nodes); +} diff --git a/gladeui/glade-tsort.h b/gladeui/glade-tsort.h new file mode 100644 index 00000000..3026e2d5 --- /dev/null +++ b/gladeui/glade-tsort.h @@ -0,0 +1,51 @@ +/* + * glade-tsort.h: a topological sorting algorithm implementation + * + * Copyright (C) 2013 Juan Pablo Ugarte. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Authors: + * Juan Pablo Ugarte <juanpablougarte@gmail.com> + */ + +#ifndef __GLADE_TSORT_H__ +#define __GLADE_TSORT_H__ + +#include <glib.h> + +G_BEGIN_DECLS + +typedef struct __NodeEdge _NodeEdge; + +struct __NodeEdge +{ + gpointer predecessor; + gpointer successor; + _NodeEdge *next; +}; + +_NodeEdge *_node_edge_prepend (_NodeEdge *node, + gpointer predecessor, + gpointer successor); + +void _node_edge_free (_NodeEdge *node); + +GList *_glade_tsort (GList **nodes, + _NodeEdge **edges); + +G_END_DECLS + +#endif /* __GLADE_TSORT_H__ */ diff --git a/gladeui/glade-widget-adaptor.c b/gladeui/glade-widget-adaptor.c index 1acc8d9d..c40e3c99 100644 --- a/gladeui/glade-widget-adaptor.c +++ b/gladeui/glade-widget-adaptor.c @@ -42,6 +42,7 @@ #include "glade-displayable-values.h" #include "glade-editor-table.h" #include "glade-cursor.h" +#include "glade-widget-private.h" /* For g_file_exists */ #include <sys/types.h> @@ -978,33 +979,18 @@ glade_widget_adaptor_object_depends (GladeWidgetAdaptor *adaptor, GladeWidget *widget, GladeWidget *another) { - GList *prop_refs, *l; - gboolean depends = FALSE; - - prop_refs = glade_widget_list_prop_refs (another); + GList *l; - for (l = prop_refs; !depends && l; l = l->next) + for (l = _glade_widget_peek_prop_refs (another); l; l = g_list_next (l)) { - GladeProperty *property = l->data; - GladeWidget *prop_widget = glade_property_get_widget (property); - /* If one of the properties that reference @another is * owned by @widget then @widget depends on @another */ - if (prop_widget == widget) - depends = TRUE; - - /* Or if the widget that owns a property which references - * @another is somewhere inside @widget... then @widget - * also depends on @another. - */ - else if (glade_widget_is_ancestor (prop_widget, widget)) - depends = TRUE; + if (glade_property_get_widget (l->data) == widget) + return TRUE; } - g_list_free (prop_refs); - - return depends; + return FALSE; } static void diff --git a/gladeui/glade-widget-private.h b/gladeui/glade-widget-private.h new file mode 100644 index 00000000..12869f47 --- /dev/null +++ b/gladeui/glade-widget-private.h @@ -0,0 +1,36 @@ +/* + * glade-widget-private.h + * + * Copyright (C) 2013 Juan Pablo Ugarte + * + * Authors: + * Juan Pablo Ugarte <juanpablougarte@gmail.com> + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef __GLADE_WIDGET_PRIVATE_H__ +#define __GLADE_WIDGET_PRIVATE_H__ + +#include "glade-widget.h" + +G_BEGIN_DECLS + +GList *_glade_widget_peek_prop_refs (GladeWidget *widget); + +G_END_DECLS + +#endif /* __GLADE_WIDGET_PRIVATE_H__ */ diff --git a/gladeui/glade-widget.c b/gladeui/glade-widget.c index 2ea24573..df3a965f 100644 --- a/gladeui/glade-widget.c +++ b/gladeui/glade-widget.c @@ -44,7 +44,7 @@ #include "glade-accumulators.h" #include "glade-project.h" #include "glade-widget-adaptor.h" -#include "glade-widget.h" +#include "glade-widget-private.h" #include "glade-marshallers.h" #include "glade-property.h" #include "glade-property-class.h" @@ -148,7 +148,9 @@ struct _GladeWidgetPrivate { */ GtkTreeModel *signal_model; /* Signal model (or NULL if not yet requested) */ - + + GladeWidget *cached_toplevel; /* Used to speed up glade_widget_get_toplevel */ + /* Construct parameters: */ GladeWidget *construct_template; GladeCreateReason construct_reason; @@ -2045,6 +2047,14 @@ glade_widget_create_packing_properties (GladeWidget * container, return g_list_reverse (packing_props); } +/* Private API */ + +GList * +_glade_widget_peek_prop_refs (GladeWidget *widget) +{ + return widget->priv->prop_refs; +} + /******************************************************************************* API *******************************************************************************/ @@ -3633,6 +3643,9 @@ glade_widget_set_parent (GladeWidget * widget, GladeWidget * parent) old_parent = widget->priv->parent; widget->priv->parent = parent; + /* unset toplevel cache used in glade_widget_get_toplevel() */ + widget->priv->cached_toplevel = NULL; + /* Set packing props only if the object is actually parented by 'parent' * (a subsequent call should come from glade_command after parenting). */ @@ -3744,9 +3757,14 @@ glade_widget_get_toplevel (GladeWidget * widget) GladeWidget *toplevel = widget; g_return_val_if_fail (GLADE_IS_WIDGET (widget), NULL); + if (widget->priv->cached_toplevel) + return widget->priv->cached_toplevel; + while (toplevel->priv->parent) toplevel = toplevel->priv->parent; + widget->priv->cached_toplevel = toplevel; + return toplevel; } @@ -4343,11 +4361,8 @@ glade_widget_is_ancestor (GladeWidget * widget, GladeWidget * ancestor) * Determines whether @widget is somehow dependent on @other, in * which case it should be serialized after @other. * - * A widget is dependent on another widget if @widget or any - * of @widget's children depends on @other or any of @other's children. - * - * <note><para>This is a very recursive operation, it is used once when - * saving the project to ensure proper order at save time.</para></note> + * A widget is dependent on another widget. + * It does not take into account for children dependencies. * * Return value: %TRUE if @widget depends on @other. **/ @@ -4358,42 +4373,7 @@ glade_widget_depends (GladeWidget *widget, g_return_val_if_fail (GLADE_IS_WIDGET (widget), FALSE); g_return_val_if_fail (GLADE_IS_WIDGET (other), FALSE); - if (!glade_widget_adaptor_depends (widget->priv->adaptor, widget, other)) - { - gboolean depends; - GList *children, *l; - - /* Recurse into 'other' */ - children = glade_widget_get_children (other); - for (depends = FALSE, l = children; - depends == FALSE && l != NULL; - l = l->next) - { - GladeWidget *child = glade_widget_get_from_gobject (l->data); - - depends = glade_widget_depends (widget, child); - } - - g_list_free (children); - if (depends) - return TRUE; - - /* Recurse into 'widget' */ - children = glade_widget_get_children (widget); - for (depends = FALSE, l = children; - depends == FALSE && l != NULL; - l = l->next) - { - GladeWidget *child = glade_widget_get_from_gobject (l->data); - - depends = glade_widget_depends (child, other); - } - g_list_free (children); - - return depends; - } - - return TRUE; + return glade_widget_adaptor_depends (widget->priv->adaptor, widget, other); } /** diff --git a/plugins/gtk+/glade-gtk-entry.c b/plugins/gtk+/glade-gtk-entry.c index 2704afc2..cd8acfd8 100644 --- a/plugins/gtk+/glade-gtk-entry.c +++ b/plugins/gtk+/glade-gtk-entry.c @@ -28,17 +28,6 @@ #include "glade-image-editor.h" /* For the icon modes */ #include "glade-gtk.h" -gboolean -glade_gtk_entry_depends (GladeWidgetAdaptor * adaptor, - GladeWidget * widget, GladeWidget * another) -{ - if (GTK_IS_ENTRY_BUFFER (glade_widget_get_object (another))) - return TRUE; - - return GWA_GET_CLASS (GTK_TYPE_WIDGET)->depends (adaptor, widget, another); -} - - static void glade_gtk_entry_changed (GtkEditable * editable, GladeWidget * gentry) { diff --git a/plugins/gtk+/glade-gtk-size-group.c b/plugins/gtk+/glade-gtk-size-group.c index 94d4725b..3ca480ae 100644 --- a/plugins/gtk+/glade-gtk-size-group.c +++ b/plugins/gtk+/glade-gtk-size-group.c @@ -28,16 +28,6 @@ #define GLADE_TAG_SIZEGROUP_WIDGETS "widgets" #define GLADE_TAG_SIZEGROUP_WIDGET "widget" -gboolean -glade_gtk_size_group_depends (GladeWidgetAdaptor * adaptor, - GladeWidget * widget, GladeWidget * another) -{ - if (GTK_IS_WIDGET (glade_widget_get_object (another))) - return TRUE; - - return GWA_GET_CLASS (G_TYPE_OBJECT)->depends (adaptor, widget, another); -} - static void glade_gtk_size_group_read_widgets (GladeWidget * widget, GladeXmlNode * node) { diff --git a/plugins/gtk+/glade-gtk-tree-view.c b/plugins/gtk+/glade-gtk-tree-view.c index 704cabda..eb5bef5a 100644 --- a/plugins/gtk+/glade-gtk-tree-view.c +++ b/plugins/gtk+/glade-gtk-tree-view.c @@ -278,16 +278,6 @@ glade_gtk_treeview_replace_child (GladeWidgetAdaptor * adaptor, glade_gtk_cell_layout_sync_attributes (G_OBJECT (column)); } -gboolean -glade_gtk_treeview_depends (GladeWidgetAdaptor * adaptor, - GladeWidget * widget, GladeWidget * another) -{ - if (GTK_IS_TREE_MODEL (glade_widget_get_object (another))) - return TRUE; - - return GWA_GET_CLASS (GTK_TYPE_CONTAINER)->depends (adaptor, widget, another); -} - void glade_gtk_treeview_set_property (GladeWidgetAdaptor * adaptor, GObject * object, diff --git a/plugins/gtk+/glade-gtk-widget.c b/plugins/gtk+/glade-gtk-widget.c index dba1d2b7..7806986c 100644 --- a/plugins/gtk+/glade-gtk-widget.c +++ b/plugins/gtk+/glade-gtk-widget.c @@ -87,9 +87,11 @@ gboolean glade_gtk_widget_depends (GladeWidgetAdaptor * adaptor, GladeWidget * widget, GladeWidget * another) { - if (GTK_IS_ICON_FACTORY (glade_widget_get_object (another)) || - GTK_IS_ACTION (glade_widget_get_object (another)) || - GTK_IS_ACTION_GROUP (glade_widget_get_object (another))) + /* We want GtkIconFactory to be before any toplevels, just in case one of + * the stock items defined in it are used. + */ + if (!glade_widget_get_parent (widget) && + GTK_IS_ICON_FACTORY (glade_widget_get_object (another))) return TRUE; return GWA_GET_CLASS (G_TYPE_OBJECT)->depends (adaptor, widget, another); diff --git a/plugins/gtk+/gtk+.xml.in b/plugins/gtk+/gtk+.xml.in index 4ec5ad81..2754302a 100644 --- a/plugins/gtk+/gtk+.xml.in +++ b/plugins/gtk+/gtk+.xml.in @@ -1359,7 +1359,6 @@ <create-editable-function>glade_gtk_entry_create_editable</create-editable-function> <set-property-function>glade_gtk_entry_set_property</set-property-function> <read-widget-function>glade_gtk_entry_read_widget</read-widget-function> - <depends-function>glade_gtk_entry_depends</depends-function> <signals> <signal id="icon-press" since="2.16"/> @@ -3139,7 +3138,6 @@ </glade-widget-class> <glade-widget-class name="GtkSizeGroup" generic-name="sizegroup" _title="Size Group" toplevel="True"> - <depends-function>glade_gtk_size_group_depends</depends-function> <read-widget-function>glade_gtk_size_group_read_widget</read-widget-function> <write-widget-function>glade_gtk_size_group_write_widget</write-widget-function> <set-property-function>glade_gtk_size_group_set_property</set-property-function> @@ -3381,7 +3379,6 @@ <replace-child-function>glade_gtk_treeview_replace_child</replace-child-function> <remove-child-function>glade_gtk_treeview_remove_child</remove-child-function> <action-activate-function>glade_gtk_treeview_action_activate</action-activate-function> - <depends-function>glade_gtk_treeview_depends</depends-function> <actions> <action id="launch_editor" _name="Edit…" stock="gtk-edit" important="True"/> |