aboutsummaryrefslogtreecommitdiff
path: root/libdbusmenu-gtk
diff options
context:
space:
mode:
authorCharles Kerr <charles.kerr@canonical.com>2013-03-13 17:16:48 +0000
committerCharles Kerr <charles.kerr@canonical.com>2013-03-13 17:16:48 +0000
commit9b75358ca14e1ad8a41c364195df748a1a1bbf5d (patch)
treebaf1e3f7051216f46da49a8a1d82dde3d4ca20e9 /libdbusmenu-gtk
parent7453a4ef0ecd0e44b8296899f3021587e8110f4e (diff)
downloadlibdbusmenu-9b75358ca14e1ad8a41c364195df748a1a1bbf5d.tar.gz
libdbusmenu-9b75358ca14e1ad8a41c364195df748a1a1bbf5d.tar.bz2
libdbusmenu-9b75358ca14e1ad8a41c364195df748a1a1bbf5d.zip
stop listening to a widget's signals when it's removed from the menu tree that we're mirroring. This condition was detected by a flood of g_warnings, so add a regression test to confirm that the warning messages no longer appear.
Diffstat (limited to 'libdbusmenu-gtk')
-rw-r--r--libdbusmenu-gtk/parser.c80
1 files changed, 51 insertions, 29 deletions
diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c
index 6244b07..9d1b034 100644
--- a/libdbusmenu-gtk/parser.c
+++ b/libdbusmenu-gtk/parser.c
@@ -273,10 +273,47 @@ dbusmenu_gtk_parse_menu_structure (GtkWidget * widget)
DbusmenuMenuitem *
dbusmenu_gtk_parse_get_cached_item (GtkWidget * widget)
{
- if (!GTK_IS_MENU_ITEM(widget)) {
- return NULL;
- }
- return DBUSMENU_MENUITEM(g_object_get_data(G_OBJECT(widget), CACHED_MENUITEM));
+ GObject * o = NULL;
+ DbusmenuMenuitem * ret = NULL;
+
+ if (GTK_IS_MENU_ITEM (widget))
+ o = g_object_get_data (G_OBJECT(widget), CACHED_MENUITEM);
+
+ if (o && DBUSMENU_IS_MENUITEM(o))
+ ret = DBUSMENU_MENUITEM (o);
+
+ return ret;
+}
+
+/* remove our dbusmenuitem's hooks to a GtkWidget,
+ such as when either of them are being destroyed */
+static void
+disconnect_from_widget (GtkWidget * widget)
+{
+ ParserData * pdata = parser_data_get_from_widget (widget);
+
+ if (pdata && pdata->widget)
+ {
+ GObject * o;
+
+ g_assert (pdata->widget == widget);
+
+ /* stop listening to signals from the widget */
+ o = G_OBJECT (pdata->widget);
+ dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_notify_handler_id);
+ dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_add_handler_id);
+ dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_accel_handler_id);
+ dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_toggle_handler_id);
+ dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_visible_handler_id);
+ dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_screen_changed_handler_id);
+
+ /* clear the menuitem's widget pointer */
+ g_object_remove_weak_pointer (o, (gpointer*)&pdata->widget);
+ pdata->widget = NULL;
+
+ /* clear the widget's menuitem pointer */
+ g_object_steal_data(o, CACHED_MENUITEM);
+ }
}
static void
@@ -297,17 +334,7 @@ parser_data_free (ParserData * pdata)
}
if (pdata->widget != NULL) {
- GObject * o = G_OBJECT(pdata->widget);
- dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_notify_handler_id);
- dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_add_handler_id);
- dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_accel_handler_id);
- dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_toggle_handler_id);
- dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_visible_handler_id);
- dbusmenu_gtk_clear_signal_handler (o, &pdata->widget_screen_changed_handler_id);
- g_object_remove_weak_pointer(o, (gpointer*)&pdata->widget);
-
- /* since the DbusmenuMenuitem is being destroyed, uncache it from the GtkWidget */
- g_object_steal_data(o, CACHED_MENUITEM);
+ disconnect_from_widget (pdata->widget);
}
if (pdata->settings != NULL) {
@@ -1387,24 +1414,19 @@ item_inserted_cb (GtkContainer *menu,
/* A child item was removed from a menu we're watching. */
static void
-item_removed_cb (GtkContainer *menu, GtkWidget *widget, gpointer data)
+item_removed_cb (GtkContainer *parent_w, GtkWidget *child_w, gpointer data)
{
- gpointer pmi = g_object_get_data(G_OBJECT(widget), CACHED_MENUITEM);
- if (pmi == NULL) {
- return;
- }
+ DbusmenuMenuitem * child_mi;
- DbusmenuMenuitem * child = DBUSMENU_MENUITEM(pmi);
-
- pmi = g_object_get_data(G_OBJECT(menu), CACHED_MENUITEM);
- if (pmi == NULL) {
- return;
- }
+ if ((child_mi = dbusmenu_gtk_parse_get_cached_item (child_w)))
+ {
+ DbusmenuMenuitem * parent_mi;
- DbusmenuMenuitem * parent = DBUSMENU_MENUITEM(pmi);
+ if ((parent_mi = dbusmenu_gtk_parse_get_cached_item (GTK_WIDGET(parent_w))))
+ dbusmenu_menuitem_child_delete (parent_mi, child_mi);
- dbusmenu_menuitem_child_delete(parent, child);
- return;
+ disconnect_from_widget (child_w);
+ }
}
static gboolean