Michael Terry has proposed merging 
lp:~mterry/indicator-appmenu/fix-empathy-contact-crash into 
lp:indicator-appmenu.

Requested reviews:
  Indicator Applet Developers (indicator-applet-developers)
Related bugs:
  #696897 clicking on 'contact' menu in empathy chat window reloads the menubar 
in Unity
  https://bugs.launchpad.net/bugs/696897

For more details, see:
https://code.launchpad.net/~mterry/indicator-appmenu/fix-empathy-contact-crash/+merge/47579

Empathy swaps out the menu for the Contact toplevel entry whenever a contact 
window gets focus.  Since indicator-appmenu isn't well prepared for that, it 
kept a pointer around to the old menu.  Then it crashed when the user tried to 
use it.

To fully fix this, I'd ideally like to add support for using the new menu, but 
for now, I'm interested in just stopping us from crashing.  So here's a patch 
to NULL out the entry's menu when it is destroyed by libdbusmenu.

With this patch alone, the empty menu stops scrubbing motions.  There's a 
separate patch I'm filing against unity to fix that.
-- 
https://code.launchpad.net/~mterry/indicator-appmenu/fix-empathy-contact-crash/+merge/47579
Your team ayatana-commits is subscribed to branch lp:indicator-appmenu.
=== modified file 'src/window-menus.c'
--- src/window-menus.c	2011-01-25 18:21:55 +0000
+++ src/window-menus.c	2011-01-26 19:52:40 +0000
@@ -207,6 +207,28 @@
 	return;
 }
 
+static void
+entry_free(IndicatorObjectEntry * entry)
+{
+	g_return_if_fail(entry != NULL);
+
+	if (entry->label != NULL) {
+		g_object_unref(entry->label);
+		entry->label = NULL;
+	}
+	if (entry->image != NULL) {
+		g_object_unref(entry->image);
+		entry->image = NULL;
+	}
+	if (entry->menu != NULL) {
+		g_signal_handlers_disconnect_by_func(entry->menu, G_CALLBACK(gtk_widget_destroyed), &entry->menu);
+		g_object_unref(entry->menu);
+		entry->menu = NULL;
+	}
+
+	g_free(entry);
+}
+
 /* Free memory */
 static void
 window_menus_finalize (GObject *object)
@@ -220,15 +242,9 @@
 		for (i = 0; i < priv->entries->len; i++) {
 			IndicatorObjectEntry * entry;
 			entry = g_array_index(priv->entries, IndicatorObjectEntry *, i);
-			
-			if (entry->label != NULL) {
-				g_object_unref(entry->label);
-			}
-			if (entry->menu != NULL) {
-				g_object_unref(entry->menu);
-			}
+			entry_free(entry);
 		}
-		g_array_free(priv->entries, TRUE);
+		g_array_free(priv->entries, FALSE);
 		priv->entries = NULL;
 	}
 
@@ -659,6 +675,7 @@
 	} else {
 		g_object_ref(entry->menu);
 		gtk_menu_detach(entry->menu);
+		g_signal_connect(entry->menu, "destroy", G_CALLBACK(gtk_widget_destroyed), &entry->menu);
 	}
 
 	g_signal_connect(G_OBJECT(newentry), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(menu_prop_changed), entry);
@@ -704,7 +721,7 @@
 
 	g_signal_emit(G_OBJECT(user_data), signals[ENTRY_REMOVED], 0, entry, TRUE);
 
-	g_free(entry);
+	entry_free(entry);
 
 	return;
 }

_______________________________________________
Mailing list: https://launchpad.net/~ayatana-commits
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~ayatana-commits
More help   : https://help.launchpad.net/ListHelp

Reply via email to