From eee824d43799faa05bd3414675f6b7987d430d42 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 10 Apr 2012 10:46:44 -0500 Subject: make the signal disconnect warnings in dbusmenu-gtk more fine-grained. --- libdbusmenu-gtk/parser.c | 206 ++++++++++++++++++++++++++--------------------- 1 file changed, 113 insertions(+), 93 deletions(-) diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c index 5ef6f3b..7c4aeb5 100644 --- a/libdbusmenu-gtk/parser.c +++ b/libdbusmenu-gtk/parser.c @@ -39,11 +39,27 @@ License version 3 and version 2.1 along with this program. If not, see typedef struct _ParserData { GtkWidget *label; + gulong label_notify_handler_id; + GtkAction *action; - GtkWidget *widget; + gulong action_notify_handler_id; + GtkWidget *shell; + gulong item_inserted_handler_id; + gulong item_removed_handler_id; + GtkWidget *image; + gulong image_notify_handler_id; + AtkObject *accessible; + gulong a11y_handler_id; + + GtkWidget *widget; + gulong widget_notify_handler_id; + gulong widget_add_handler_id; + gulong widget_accel_handler_id; + gulong widget_toggle_handler_id; + gulong widget_visible_handler_id; } ParserData; @@ -160,6 +176,40 @@ ensure_interned_strings_loaded (void) **** ***/ +static void +dbusmenu_gtk_clear_signal_handler (gpointer instance, gulong *handler_id) +{ + if (handler_id && *handler_id) + { + /* complain if we thought we were connected but aren't */ + g_return_if_fail (g_signal_handler_is_connected (instance, *handler_id)); + + g_signal_handler_disconnect (instance, *handler_id); + *handler_id = 0; + } +} + +/* get the ParserData associated with the specified DbusmenuMenuitem */ +static ParserData* +parser_data_get_from_menuitem (DbusmenuMenuitem * item) +{ + return (ParserData *) g_object_get_data(G_OBJECT(item), PARSER_DATA); +} + +/* get the ParserData associated with the specified widget */ +static ParserData* +parser_data_get_from_widget (GtkWidget * widget) +{ + DbusmenuMenuitem * item = dbusmenu_gtk_parse_get_cached_item (widget); + if (item != NULL) + return parser_data_get_from_menuitem (item); + return NULL; +} + +/*** +**** +***/ + /** * dbusmenu_gtk_parse_menu_structure: * @widget: A #GtkMenuItem or #GtkMenuShell to turn into a #DbusmenuMenuitem @@ -222,64 +272,47 @@ parser_data_free (ParserData * pdata) g_return_if_fail (pdata != NULL); if (pdata->label != NULL) { - gint i = 0; - i += g_signal_handlers_disconnect_matched(pdata->label, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(label_notify_cb), NULL); - g_warn_if_fail (i != 1); - g_object_remove_weak_pointer(G_OBJECT(pdata->label), (gpointer*)&pdata->label); + GObject * o = G_OBJECT(pdata->label); + dbusmenu_gtk_clear_signal_handler (o, &pdata->label_notify_handler_id); + g_object_remove_weak_pointer(o, (gpointer*)&pdata->label); } if (pdata->action != NULL) { - gint i = 0; - i += g_signal_handlers_disconnect_matched(pdata->action, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(action_notify_cb), NULL); - g_warn_if_fail (i != 1); - g_object_remove_weak_pointer(G_OBJECT(pdata->action), (gpointer*)&pdata->action); + GObject * o = G_OBJECT(pdata->action); + dbusmenu_gtk_clear_signal_handler (o, &pdata->action_notify_handler_id); + g_object_remove_weak_pointer(o, (gpointer*)&pdata->action); } if (pdata->widget != NULL) { GObject * o = G_OBJECT(pdata->widget); - gint i = 0; - i += g_signal_handlers_disconnect_matched(o, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(widget_notify_cb), NULL); - i += g_signal_handlers_disconnect_matched(o, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(widget_add_cb), NULL); - i += g_signal_handlers_disconnect_matched(o, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(accel_changed), NULL); - i += g_signal_handlers_disconnect_matched(o, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(checkbox_toggled), NULL); - i += g_signal_handlers_disconnect_matched(o, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(menuitem_notify_cb), NULL); - g_warn_if_fail (i != 5); + 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); 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); } if (pdata->shell != NULL) { - gint i = 0; - i += g_signal_handlers_disconnect_matched(pdata->shell, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(item_inserted_cb), NULL); - i += g_signal_handlers_disconnect_matched(pdata->shell, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(item_removed_cb), NULL); - g_warn_if_fail (i != 2); - g_object_remove_weak_pointer(G_OBJECT(pdata->shell), (gpointer*)&pdata->shell); + GObject * o = G_OBJECT(pdata->shell); + dbusmenu_gtk_clear_signal_handler (o, &pdata->item_inserted_handler_id); + dbusmenu_gtk_clear_signal_handler (o, &pdata->item_removed_handler_id); + g_object_remove_weak_pointer(o, (gpointer*)&pdata->shell); } if (pdata->image != NULL) { - gint i = 0; - i += g_signal_handlers_disconnect_matched(pdata->image, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(image_notify_cb), NULL); - g_warn_if_fail (i != 1); - g_object_remove_weak_pointer(G_OBJECT(pdata->image), (gpointer*)&pdata->image); + GObject * o = G_OBJECT(pdata->image); + dbusmenu_gtk_clear_signal_handler (o, &pdata->image_notify_handler_id); + g_object_remove_weak_pointer(o, (gpointer*)&pdata->image); } if (pdata->accessible != NULL) { - gint i = 0; - i += g_signal_handlers_disconnect_matched(pdata->accessible, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(a11y_name_notify_cb), NULL); - g_warn_if_fail (i != 1); - g_object_remove_weak_pointer(G_OBJECT(pdata->accessible), (gpointer*)&pdata->accessible); + GObject * o = G_OBJECT(pdata->accessible); + dbusmenu_gtk_clear_signal_handler (o, &pdata->a11y_handler_id); + g_object_remove_weak_pointer(o, (gpointer*)&pdata->accessible); } g_free(pdata); @@ -347,10 +380,10 @@ watch_submenu(DbusmenuMenuitem * mi, GtkWidget * menu) g_return_if_fail(DBUSMENU_IS_MENUITEM(mi)); g_return_if_fail(GTK_IS_MENU_SHELL(menu)); - ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(mi), PARSER_DATA); + ParserData *pdata = parser_data_get_from_menuitem (mi); pdata->shell = menu; - g_signal_connect (G_OBJECT (menu), + pdata->item_inserted_handler_id = g_signal_connect (G_OBJECT (menu), #ifdef HAVE_GTK3 "insert", #else @@ -358,10 +391,10 @@ watch_submenu(DbusmenuMenuitem * mi, GtkWidget * menu) #endif G_CALLBACK (item_inserted_cb), mi); - g_signal_connect (G_OBJECT (menu), - "remove", - G_CALLBACK (item_removed_cb), - mi); + pdata->item_removed_handler_id = g_signal_connect (G_OBJECT (menu), + "remove", + G_CALLBACK (item_removed_cb), + mi); g_object_add_weak_pointer(G_OBJECT (menu), (gpointer*)&pdata->shell); /* Some apps (notably Eclipse RCP apps) don't fill contents of submenus @@ -447,17 +480,18 @@ parse_menu_structure_helper (GtkWidget * widget, RecurseContext * recurse) thisitem = construct_dbusmenu_for_widget (widget); if (!gtk_widget_get_visible (widget)) { - g_signal_connect (G_OBJECT (widget), - "notify::visible", - G_CALLBACK (menuitem_notify_cb), - recurse->toplevel); - } + ParserData *pdata = parser_data_get_from_menuitem (thisitem); + pdata->widget_visible_handler_id = g_signal_connect (G_OBJECT (widget), + "notify::visible", + G_CALLBACK (menuitem_notify_cb), + recurse->toplevel); + } if (GTK_IS_TEAROFF_MENU_ITEM (widget)) { dbusmenu_menuitem_property_set_bool (thisitem, DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE); - } + } } /* Check to see if we're in our parents list of children, if we have @@ -584,10 +618,8 @@ construct_dbusmenu_for_widget (GtkWidget * widget) } else { - g_signal_connect (widget, - "accel-closures-changed", - G_CALLBACK (accel_changed), - mi); + pdata->widget_accel_handler_id = g_signal_connect (widget, "accel-closures-changed", + G_CALLBACK (accel_changed), mi); if (GTK_IS_CHECK_MENU_ITEM (widget)) { @@ -599,10 +631,7 @@ construct_dbusmenu_for_widget (GtkWidget * widget) DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (widget)) ? DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED : DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED); - g_signal_connect (widget, - "activate", - G_CALLBACK (checkbox_toggled), - mi); + pdata->widget_toggle_handler_id = g_signal_connect (widget, "activate", G_CALLBACK (checkbox_toggled), mi); } if (GTK_IS_IMAGE_MENU_ITEM (widget)) @@ -626,10 +655,7 @@ construct_dbusmenu_for_widget (GtkWidget * widget) g_free (text); pdata->label = label; - g_signal_connect (G_OBJECT (label), - "notify", - G_CALLBACK (label_notify_cb), - mi); + pdata->label_notify_handler_id = g_signal_connect (G_OBJECT (label), "notify", G_CALLBACK(label_notify_cb), mi); g_object_add_weak_pointer(G_OBJECT (label), (gpointer*)&pdata->label); AtkObject *accessible = gtk_widget_get_accessible (widget); @@ -646,10 +672,10 @@ construct_dbusmenu_for_widget (GtkWidget * widget) // An application may set an alternate accessible name in the future, // so we had better watch out for it. pdata->accessible = accessible; - g_signal_connect (G_OBJECT (accessible), - "notify::accessible-name", - G_CALLBACK (a11y_name_notify_cb), - mi); + pdata->a11y_handler_id = g_signal_connect (G_OBJECT (accessible), + "notify::accessible-name", + G_CALLBACK (a11y_name_notify_cb), + mi); g_object_add_weak_pointer(G_OBJECT (accessible), (gpointer*)&pdata->accessible); } @@ -667,10 +693,9 @@ construct_dbusmenu_for_widget (GtkWidget * widget) sensitive = gtk_action_is_sensitive (action); pdata->action = action; - g_signal_connect_object (action, "notify", - G_CALLBACK (action_notify_cb), - mi, - G_CONNECT_AFTER); + pdata->action_notify_handler_id = g_signal_connect_object (action, "notify", + G_CALLBACK (action_notify_cb), mi, + G_CONNECT_AFTER); g_object_add_weak_pointer(G_OBJECT (action), (gpointer*)&pdata->action); } } @@ -714,15 +739,11 @@ construct_dbusmenu_for_widget (GtkWidget * widget) DBUSMENU_MENUITEM_PROP_ENABLED, sensitive); - g_signal_connect (widget, - "notify", - G_CALLBACK (widget_notify_cb), - mi); + pdata->widget_notify_handler_id = g_signal_connect (widget, "notify", + G_CALLBACK (widget_notify_cb), mi); - g_signal_connect (widget, - "add", - G_CALLBACK (widget_add_cb), - mi); + pdata->widget_add_handler_id = g_signal_connect (widget, "add", + G_CALLBACK (widget_add_cb), mi); return mi; } @@ -742,16 +763,15 @@ menuitem_notify_cb (GtkWidget *widget, if (pspec->name == interned_str_visible) { GtkWidget * new_toplevel = gtk_widget_get_toplevel (widget); - GtkWidget * old_toplevel = GTK_WIDGET(data); + GtkWidget * old_toplevel = GTK_WIDGET(data); if (new_toplevel == old_toplevel) { /* TODO: Figure this out -> rebuild (context->bridge, window); */ } /* We only care about this once, so let's disconnect now. */ - g_signal_handlers_disconnect_by_func (widget, - G_CALLBACK (menuitem_notify_cb), - data); + ParserData * pdata = parser_data_get_from_widget (widget); + dbusmenu_gtk_clear_signal_handler (widget, &pdata->widget_visible_handler_id); } } @@ -785,17 +805,18 @@ update_icon (DbusmenuMenuitem *menuitem, ParserData * pdata, GtkImage *image) if (image != GTK_IMAGE(pdata->image)) { if (pdata->image != NULL) { - g_signal_handlers_disconnect_by_func(pdata->image, G_CALLBACK(image_notify_cb), menuitem); - g_object_remove_weak_pointer(G_OBJECT(pdata->image), (gpointer*)&pdata->image); + GObject * o = G_OBJECT(pdata->image); + dbusmenu_gtk_clear_signal_handler (o, &pdata->image_notify_handler_id); + g_object_remove_weak_pointer(o, (gpointer*)&pdata->image); } pdata->image = GTK_WIDGET(image); if (pdata->image != NULL) { - g_signal_connect (G_OBJECT (pdata->image), - "notify", - G_CALLBACK (image_notify_cb), - menuitem); + pdata->image_notify_handler_id = g_signal_connect (G_OBJECT (pdata->image), + "notify", + G_CALLBACK (image_notify_cb), + menuitem); g_object_add_weak_pointer(G_OBJECT (pdata->image), (gpointer*)&pdata->image); } } @@ -1205,9 +1226,8 @@ widget_notify_cb (GtkWidget * widget, GParamSpec * pspec, gpointer data) */ if (GTK_WIDGET (g_value_get_object (&prop_value)) == NULL) { - g_signal_handlers_disconnect_by_func (widget, - G_CALLBACK (widget_notify_cb), - child); + ParserData *pdata = parser_data_get_from_menuitem (child); + dbusmenu_gtk_clear_signal_handler (widget, &pdata->widget_notify_handler_id); DbusmenuMenuitem *parent = dbusmenu_menuitem_get_parent (child); -- cgit v1.2.3 From 4b0ee3d54ebf03ba125144217fb6d8e3325b942f Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 10 Apr 2012 11:05:52 -0500 Subject: switch the smoke test to a g_debug statement --- libdbusmenu-gtk/parser.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c index 7c4aeb5..2f7277c 100644 --- a/libdbusmenu-gtk/parser.c +++ b/libdbusmenu-gtk/parser.c @@ -179,13 +179,14 @@ ensure_interned_strings_loaded (void) static void dbusmenu_gtk_clear_signal_handler (gpointer instance, gulong *handler_id) { - if (handler_id && *handler_id) - { + if (handler_id && *handler_id) { /* complain if we thought we were connected but aren't */ - g_return_if_fail (g_signal_handler_is_connected (instance, *handler_id)); - - g_signal_handler_disconnect (instance, *handler_id); - *handler_id = 0; + if (!g_signal_handler_is_connected (instance, *handler_id)) { + g_debug ("%s tried to disconnect signal handler %lu from disconnected %p", G_STRLOC, *handler_id, instance); + } else { + g_signal_handler_disconnect (instance, *handler_id); + *handler_id = 0; + } } } -- cgit v1.2.3 From 514253caa8b99331f11bf91b15fffe0fe44f5e0c Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 10 Apr 2012 17:54:52 -0500 Subject: In menuitem_signals_remove(), disconnect the DBUSMENU_MENUITEM_SIGNAL_SHOW_TO_USER event that we connected to in menuitem_signals_create(). It looks like this non-disconnected signal goes all the way back to July 2010 so I'd like ted's eyes on this to confirm there's not some nuance that I'm missing... --- libdbusmenu-glib/server.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index ebe0082..9e5ef0c 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -1288,6 +1288,7 @@ menuitem_signals_remove (DbusmenuMenuitem * mi, gpointer data) g_signal_handlers_disconnect_by_func(G_OBJECT(mi), G_CALLBACK(menuitem_child_removed), data); g_signal_handlers_disconnect_by_func(G_OBJECT(mi), G_CALLBACK(menuitem_child_moved), data); g_signal_handlers_disconnect_by_func(G_OBJECT(mi), G_CALLBACK(menuitem_property_changed), data); + g_signal_handlers_disconnect_by_func(G_OBJECT(mi), G_CALLBACK(menuitem_shown), data); return; } -- cgit v1.2.3 From a217d86f8ad6f83b5604ef36a71f7752199f8d04 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 11 Apr 2012 11:13:37 -0500 Subject: 0.6.0 --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 9a55549..50f14ef 100644 --- a/configure.ac +++ b/configure.ac @@ -1,11 +1,11 @@ -AC_INIT(libdbusmenu, 0.5.99, ted@canonical.com) +AC_INIT(libdbusmenu, 0.6.0, ted@canonical.com) AC_COPYRIGHT([Copyright 2009,2010 Canonical]) AC_PREREQ(2.62) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(libdbusmenu, 0.5.99, [-Wno-portability]) +AM_INIT_AUTOMAKE(libdbusmenu, 0.6.0, [-Wno-portability]) AM_MAINTAINER_MODE -- cgit v1.2.3 From 2421f72a9f0acb6afb3e5209a434c409bf3a409d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 11 Apr 2012 11:42:40 -0500 Subject: 0.6.1 --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 50f14ef..94bba0c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,11 +1,11 @@ -AC_INIT(libdbusmenu, 0.6.0, ted@canonical.com) +AC_INIT(libdbusmenu, 0.6.1, ted@canonical.com) AC_COPYRIGHT([Copyright 2009,2010 Canonical]) AC_PREREQ(2.62) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(libdbusmenu, 0.6.0, [-Wno-portability]) +AM_INIT_AUTOMAKE(libdbusmenu, 0.6.1, [-Wno-portability]) AM_MAINTAINER_MODE -- cgit v1.2.3