gtkmenu.c - attachment issues ...



Hi guys,

	So - the libbonoboui code relies pretty heavily on the
gtk_container_get_children list (with some caveats) being in-sync with
the visual list of widgets.

	There is a particularly pernicious bug in nautilus whereby your items
and particularly / separators get horribly jumbled up. After some
extremely time-consuming debugging this was found to be down to the new
gtkmenu.c 'attachment' child properties which were getting pretty
mangled; eg. walking the gtk_container_get_child list in order I was
getting ~20 items with attach properties of ~30 or so, and a totally
jumbled list.

	The attached patch shifts items down to fill voids created on removal -
effectively the converse of the insertion process; this fixes all the
nautilus problems I could see, and would appear to make some sense. I
also eliminated one _container_get_child_properties in the equivalent
insert at least to make it slightly more efficient.

	Comments or may I commit ?

	Regards,

		Michael.

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/ChangeLog,v
retrieving revision 1.4797
diff -u -p -u -r1.4797 ChangeLog
--- ChangeLog	14 Jan 2004 13:08:39 -0000	1.4797
+++ ChangeLog	14 Jan 2004 18:05:55 -0000
@@ -1,3 +1,9 @@
+2004-01-14  Michael Meeks  <michael ximian com>
+
+	* gtk/gtkmenu.c (gtk_menu_do_insert): accelerate a little.
+	(gtk_menu_do_remove): implement to keep the attach ordering sane.
+	(gtk_menu_remove): call it.
+
 Wed Jan 14 13:07:30 GMT 2004  Tony Gale <gale gtk org>
 
 	* docs/faq/gtk-faq.sgml: Updates to Section 5
Index: gtk/gtkmenu.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmenu.c,v
retrieving revision 1.153
diff -u -p -u -r1.153 gtkmenu.c
--- gtk/gtkmenu.c	21 Dec 2003 00:59:44 -0000	1.153
+++ gtk/gtkmenu.c	14 Jan 2004 18:05:58 -0000
@@ -935,6 +935,26 @@ gtk_menu_detach (GtkMenu *menu)
   g_object_unref (menu);
 }
 
+static void
+gtk_menu_do_remove (GtkMenuShell *menu_shell,
+		    GtkWidget    *child)
+{
+  AttachInfo *ai = get_attach_info (G_OBJECT (child));
+  GList *children;
+  int delta = ai->bottom_attach - ai->top_attach;
+  
+  for (children = menu_shell->children; children; children =
children->next)
+    {
+      AttachInfo *child_ai = get_attach_info (children->data);
+      
+      if (child_ai->bottom_attach > ai->bottom_attach)
+        gtk_container_child_set (GTK_CONTAINER (menu_shell),
children->data,
+                                 "top_attach", child_ai->top_attach -
delta,
+                                 "bottom_attach",
child_ai->bottom_attach - delta,
+                                 NULL);
+    }
+}
+
 static void 
 gtk_menu_remove (GtkContainer *container,
 		 GtkWidget    *widget)
@@ -954,6 +974,7 @@ gtk_menu_remove (GtkContainer *container
       menu->old_active_menu_item = NULL;
     }
 
+  gtk_menu_do_remove (GTK_MENU_SHELL (container), widget);
   g_object_set_data (G_OBJECT (widget), ATTACH_INFO_KEY, NULL);
 
   GTK_CONTAINER_CLASS (parent_class)->remove (container, widget);
@@ -993,17 +1014,12 @@ gtk_menu_do_insert (GtkMenuShell *menu_s
    */
   for (children = menu_shell->children; children; children =
children->next)
     {
-      guint top, bottom;
-
-      gtk_container_child_get (GTK_CONTAINER (menu_shell),
children->data,
-                               "top_attach", &top,
-                               "bottom_attach", &bottom,
-                               NULL);
+      AttachInfo *child_ai = get_attach_info (children->data);
 
-      if (top >= position)
+      if (child_ai->top_attach >= position)
         gtk_container_child_set (GTK_CONTAINER (menu_shell),
children->data,
-                                 "top_attach", top + 1,
-                                 "bottom_attach", bottom + 1,
+                                 "top_attach", child_ai->top_attach +
1,
+                                 "bottom_attach",
child_ai->bottom_attach + 1,
                                  NULL);
     }
 


-- 
 michael ximian com  <><, Pseudo Engineer, itinerant idiot




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]