]> Pileus Git - ~andy/gtk/commitdiff
Position new ui nodes correctly when existing dirty dead nodes exist
authorAlexander Larsson <alexl@redhat.com>
Sun, 29 Nov 2009 01:49:37 +0000 (20:49 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Sun, 29 Nov 2009 01:49:37 +0000 (20:49 -0500)
If you add a new ui node that was recently removed it will still be
in the tree, but marked dirty. In this case we previously just used
the old node, which meant it wouldn't get the same position as if
the dirty nodes had been processed first (and deleted) before the
new node was added.

We handle this by detecting this case and reposition the node as if
it was new.

https://bugzilla.gnome.org/show_bug.cgi?id=603128

gtk/gtkuimanager.c

index dff908550998b1776d6dbdd7a7449b99c1cb1f2c..9ebaa92f41f7370d4fab93982adec615dd92a766 100644 (file)
@@ -943,6 +943,23 @@ gtk_ui_manager_get_action (GtkUIManager *self,
   return GTK_UI_MANAGER_GET_CLASS (self)->get_action (self, path);
 }
 
+static gboolean
+node_is_dead (GNode *node)
+{
+  GNode *child;
+
+  if (NODE_INFO (node)->uifiles != NULL)
+    return FALSE;
+
+  for (child = node->children; child != NULL; child = child->next)
+    {
+      if (!node_is_dead (child))
+       return FALSE;
+    }
+
+  return TRUE;
+}
+
 static GNode *
 get_child_node (GtkUIManager *self, 
                GNode        *parent,
@@ -977,7 +994,18 @@ get_child_node (GtkUIManager *self,
                               node_type, 
                               NODE_INFO (child)->name,
                               NODE_INFO (child)->type);
-                 
+
+                    if (node_is_dead (child))
+                      {
+                        /* This node was removed but is still dirty so
+                         * it is still in the tree. We want to treat this
+                         * as if it didn't exist, which means we move it
+                         * to the position it would have been created at.
+                         */
+                        g_node_unlink (child);
+                        goto insert_child;
+                      }
+
                  return child;
                }
            }
@@ -990,21 +1018,21 @@ get_child_node (GtkUIManager *self,
          mnode->type = node_type;
          mnode->name = g_strndup (childname, childname_length);
 
+         child = g_node_new (mnode);
+       insert_child:
          if (sibling)
            {
              if (top)
-               child = g_node_insert_before (parent, sibling, 
-                                             g_node_new (mnode));
+               g_node_insert_before (parent, sibling, child);
              else
-               child = g_node_insert_after (parent, sibling, 
-                                            g_node_new (mnode));
+               g_node_insert_after (parent, sibling, child);
            }
          else
            {
              if (top)
-               child = g_node_prepend_data (parent, mnode);
+               g_node_prepend (parent, child);
              else
-               child = g_node_append_data (parent, mnode);
+               g_node_append (parent, child);
            }
 
          mark_node_dirty (child);