[gnome-globalmenu] Fix a crash in standalone.c.



commit 0faffd8b6df15d7efa615b0daf8da1a80d05c272
Author: Yu Feng <rainwoodman gmail com>
Date:   Wed Nov 11 12:20:22 2009 -0500

    Fix a crash in standalone.c.
    
    Due to some leakage in libserver.

 libserver/ccode/menushellutils-ccode.c |   14 +++++++++-----
 libserver/globalmenubar.vala           |    6 ++++++
 libserver/parser.vala                  |   23 ++++++++++++++---------
 libserver/widgets/menu.vala            |    4 ++++
 libserver/widgets/menubar.vala         |    2 ++
 libserver/widgets/menuitem.vala        |    1 +
 6 files changed, 36 insertions(+), 14 deletions(-)
---
diff --git a/libserver/ccode/menushellutils-ccode.c b/libserver/ccode/menushellutils-ccode.c
index 9e3e651..69af722 100644
--- a/libserver/ccode/menushellutils-ccode.c
+++ b/libserver/ccode/menushellutils-ccode.c
@@ -23,11 +23,15 @@ static void gtk_menu_shell_set_item_array(GtkMenuShell * menu_shell,
 }
 
 
+/**
+ * only removes the extra reference for later attached widgets.
+ */
 void gtk_menu_shell_remove_all(GtkMenuShell * menu_shell) {
-	GList * children = gtk_container_get_children(GTK_CONTAINER(menu_shell));
-	GList * iter;
-	for(iter = children; iter; iter = iter->next) {
-		gtk_container_remove(GTK_CONTAINER(menu_shell), iter->data);
+	int array_length = 0;
+	int i;
+	GnomenuMenuItem **array = gtk_menu_shell_get_item_array(menu_shell, &array_length);
+	for(i = 0; i < array_length; i++) {
+		g_object_unref(array[i]);
 	}
 	gtk_menu_shell_set_item_array(menu_shell, NULL, 0);
 }
@@ -57,7 +61,7 @@ void gtk_menu_shell_set_length(GtkMenuShell * menu_shell, gint length) {
            to the array, too.*/
 		for(i = array_length; i < length; i++) {
 			GnomenuMenuItem * item = gnomenu_menu_item_new();
-			new_array[i] = item;
+			new_array[i] = g_object_ref_sink(item);
 			gtk_menu_shell_append(menu_shell, GTK_WIDGET(item));
 		}
 		/* Recalculate the children list, pass through the next
diff --git a/libserver/globalmenubar.vala b/libserver/globalmenubar.vala
index d208de4..01c3351 100644
--- a/libserver/globalmenubar.vala
+++ b/libserver/globalmenubar.vala
@@ -62,6 +62,12 @@ public class Gnomenu.GlobalMenuBar : Gnomenu.MenuBar {
 		};
 	}
 
+	public override void dispose() {
+		this.active_window_monitor = null;
+		this.mnemonic_keys = null;
+		base.dispose();
+	}
+
 	private void emit_active_window_changed(Gnomenu.Window? prev_window) {
 		active_window_changed(prev_window);
 	}
diff --git a/libserver/parser.vala b/libserver/parser.vala
index 23ebf03..8d0898b 100644
--- a/libserver/parser.vala
+++ b/libserver/parser.vala
@@ -29,10 +29,8 @@ public class Gnomenu.Parser {
 		public void advance() {
 			_position++;
 		}
-		public Item item {
-			owned get {
-				return shell.get_item(position);
-			}
+		public Item get_item() {
+			return shell.get_item(position);
 		}
 
 		/* item_has_sub_shell is used to defer the removal of the
@@ -56,6 +54,12 @@ public class Gnomenu.Parser {
 		stack.push_tail(bootstrap);
 	}
 
+	~Parser() {
+		State s = null;
+		while((s = stack.pop_tail()) != null) {
+			continue;
+		}
+	}
 	static const MarkupParser parser_functions = {
 		start_element,
 		end_element,
@@ -80,17 +84,18 @@ public class Gnomenu.Parser {
 					/*if this is not the root <menu> entry
 					 * aka, we are at
 					 * <menu><item><MENU>*/
-					state.item.has_sub_shell = true;
-					state.item_has_sub_shell = true;
+					var item = state.get_item();
+					item.has_sub_shell = true;
 					/* nested the menu, change state*/
-					stack.push_tail(new State(state.item.sub_shell));
+					stack.push_tail(new State(item.sub_shell));
 				}
 			break;
 			case "item":
 				is_bootstrapping = false;
 				/*NOTE: after the first time we has(position) == false,
 				 * it should be false forever)*/
-				setup_item(state.item, attribute_names, attribute_values);
+				var item = state.get_item();
+				setup_item(item, attribute_names, attribute_values);
 				state.item_has_sub_shell = false;
 			break;
 			default:
@@ -175,7 +180,7 @@ public class Gnomenu.Parser {
 				break;
 			case "item":
 				if(!state.item_has_sub_shell) {
-					state.item.has_sub_shell = false;
+					state.get_item().has_sub_shell = false;
 				}
 				state.advance();
 			break;
diff --git a/libserver/widgets/menu.vala b/libserver/widgets/menu.vala
index 4148080..6c6c853 100644
--- a/libserver/widgets/menu.vala
+++ b/libserver/widgets/menu.vala
@@ -27,6 +27,10 @@ public class Gnomenu.Menu : Gtk.Menu, Gnomenu.Shell {
 
 		}
 	}
+	public override void destroy() {
+		gtk_menu_shell_remove_all(this);
+		base.destroy();
+	}
 	/******
 	 * Gnomenu.Shell interface
 	 ********* */
diff --git a/libserver/widgets/menubar.vala b/libserver/widgets/menubar.vala
index 889acdb..006c332 100644
--- a/libserver/widgets/menubar.vala
+++ b/libserver/widgets/menubar.vala
@@ -73,9 +73,11 @@ static const string EMPTY_OVERFLOWN_MENU =
 	public override void dispose() {
 		if(!disposed) {
 			disposed = true;
+			gtk_menu_shell_remove_all(this);
 		}
 		base.dispose();
 	}
+
 	private MenuItem resolve_item_maybe_from_overflown(MenuItem item) {
 		if(item.is_child_of(_overflown_arrow)) {
 			string path = overflown_path_to_path(item.item_path);
diff --git a/libserver/widgets/menuitem.vala b/libserver/widgets/menuitem.vala
index 2157033..b0436b8 100644
--- a/libserver/widgets/menuitem.vala
+++ b/libserver/widgets/menuitem.vala
@@ -50,6 +50,7 @@ public class Gnomenu.MenuItem : Gtk.MenuItem, Gnomenu.Item {
 				_image_widget.unparent();
 				_image_widget = null;
 			}
+			this._submenu_cache.destroy();
 		}
 		base.dispose();
 	}



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