-- cgit v1.2.3 From 042406a84a19568ab4e417e51eac9a632970c25e Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 4 Apr 2012 23:06:45 -0500 Subject: Protect from the cases where we might get NULL in the data segment --- libdbusmenu-glib/client.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 34f8b8d..78537f8 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1834,6 +1834,8 @@ struct _about_to_show_t { static void about_to_show_finish (about_to_show_t * data, gboolean need_update) { + g_return_if_fail(data != NULL); + /* If we need to update, do that first. */ if (need_update) { update_layout(data->client); @@ -1938,6 +1940,8 @@ about_to_show_idle (gpointer user_data) GQueue * showers = priv->about_to_show_to_go; priv->about_to_show_to_go = NULL; + g_return_val_if_fail(showers != NULL, FALSE); + /* Figure out if we've got any callbacks */ gboolean got_callbacks = FALSE; g_queue_foreach(showers, about_to_show_idle_callbacks, &got_callbacks); @@ -1995,7 +1999,10 @@ about_to_show_cb (GObject * proxy, GAsyncResult * res, gpointer userdata) g_variant_unref(params); } - about_to_show_finish(data, need_update); + if (data != NULL) { + about_to_show_finish(data, need_update); + } + return; } -- cgit v1.2.3 From 9e5453bb93db68695d5fd4c1e8de8003a400f7d6 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 4 Apr 2012 23:07:16 -0500 Subject: Make sure that if the callback is NULL we're not trying to get a callback --- libdbusmenu-glib/client.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 78537f8..ed89d86 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -2035,11 +2035,15 @@ dbusmenu_client_send_about_to_show(DbusmenuClient * client, gint id, void (*cb)( priv->about_to_show_idle = g_idle_add(about_to_show_idle, client); } } else { + GAsyncReadyCallback dbuscb = NULL; + /* If there's no callback we don't need this data, let's clean it up in a consistent way */ if (cb == NULL) { about_to_show_finish(data, FALSE); data = NULL; + } else { + dbuscb = about_to_show_cb; } g_dbus_proxy_call(priv->menuproxy, @@ -2048,7 +2052,7 @@ dbusmenu_client_send_about_to_show(DbusmenuClient * client, gint id, void (*cb)( G_DBUS_CALL_FLAGS_NONE, -1, /* timeout */ NULL, /* cancellable */ - about_to_show_cb, + dbuscb, data); } -- cgit v1.2.3 From 02a14f6b93bec06f7dc73dd6e93e691e0d254ca1 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 5 Apr 2012 10:35:53 -0500 Subject: 0.5.98 --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 2d51716..a1f269b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,11 +1,11 @@ -AC_INIT(libdbusmenu, 0.5.97, ted@canonical.com) +AC_INIT(libdbusmenu, 0.5.98, ted@canonical.com) AC_COPYRIGHT([Copyright 2009,2010 Canonical]) AC_PREREQ(2.62) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(libdbusmenu, 0.5.97, [-Wno-portability]) +AM_INIT_AUTOMAKE(libdbusmenu, 0.5.98, [-Wno-portability]) AM_MAINTAINER_MODE -- cgit v1.2.3 From d3a9dcd2d4afb609c0201573fb8463242d0e9aba Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 5 Apr 2012 13:35:49 -0500 Subject: make event_data_find() and session_bus_cb() private instead of public --- libdbusmenu-glib/client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index ed89d86..b6e7204 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1023,7 +1023,7 @@ proxy_destroyed (GObject * gobj_proxy, gpointer userdata) /* Respond to us getting the session bus (hopefully) or handle the error if not */ -void +static void session_bus_cb (GObject * object, GAsyncResult * res, gpointer user_data) { GError * error = NULL; @@ -1634,7 +1634,7 @@ menuitem_call_cb (GObject * proxy, GAsyncResult * res, gpointer userdata) } /* Looks at event_data_t structs to match an ID */ -gint +static gint event_data_find (gconstpointer data, gconstpointer user_data) { event_data_t * edata = (event_data_t *)data; -- cgit v1.2.3 From 62d50f5b58529493bf1029ef90d264e0f16bf0bb Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 5 Apr 2012 13:58:03 -0500 Subject: 0.5.99 --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index a1f269b..9a55549 100644 --- a/configure.ac +++ b/configure.ac @@ -1,11 +1,11 @@ -AC_INIT(libdbusmenu, 0.5.98, ted@canonical.com) +AC_INIT(libdbusmenu, 0.5.99, ted@canonical.com) AC_COPYRIGHT([Copyright 2009,2010 Canonical]) AC_PREREQ(2.62) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(libdbusmenu, 0.5.98, [-Wno-portability]) +AM_INIT_AUTOMAKE(libdbusmenu, 0.5.99, [-Wno-portability]) AM_MAINTAINER_MODE -- cgit v1.2.3 From 202e61a48003989bec69f68f24f41a3bb20e8e55 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 6 Apr 2012 13:23:22 -0500 Subject: fix dbusmenu_item_freed(), it called g_object_get_data() on a finalized GObject --- libdbusmenu-gtk/parser.c | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c index b98f34b..c56e28f 100644 --- a/libdbusmenu-gtk/parser.c +++ b/libdbusmenu-gtk/parser.c @@ -163,23 +163,23 @@ dbusmenu_gtk_parse_get_cached_item (GtkWidget * widget) } static void -parse_data_free (gpointer data) +parse_data_free (ParserData * pdata) { - ParserData *pdata = (ParserData *)data; + g_return_if_fail (pdata != NULL); - if (pdata != NULL && pdata->label != NULL) { + if (pdata->label != NULL) { g_signal_handlers_disconnect_matched(pdata->label, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK(label_notify_cb), NULL); g_object_remove_weak_pointer(G_OBJECT(pdata->label), (gpointer*)&pdata->label); } - if (pdata != NULL && pdata->action != NULL) { + if (pdata->action != NULL) { g_signal_handlers_disconnect_matched(pdata->action, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK(action_notify_cb), NULL); g_object_remove_weak_pointer(G_OBJECT(pdata->action), (gpointer*)&pdata->action); } - if (pdata != NULL && pdata->widget != NULL) { + if (pdata->widget != NULL) { g_signal_handlers_disconnect_matched(pdata->widget, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK(widget_notify_cb), NULL); g_signal_handlers_disconnect_matched(pdata->widget, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, @@ -191,9 +191,11 @@ parse_data_free (gpointer data) g_signal_handlers_disconnect_matched(pdata->widget, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK(menuitem_notify_cb), NULL); g_object_remove_weak_pointer(G_OBJECT(pdata->widget), (gpointer*)&pdata->widget); + /* since the DbusmenuMenuitem is being destroyed, uncache it from the GtkWidget */ + g_object_steal_data(G_OBJECT(pdata->widget), CACHED_MENUITEM); } - if (pdata != NULL && pdata->shell != NULL) { + if (pdata->shell != NULL) { g_signal_handlers_disconnect_matched(pdata->shell, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK(item_inserted_cb), NULL); g_signal_handlers_disconnect_matched(pdata->shell, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, @@ -201,13 +203,13 @@ parse_data_free (gpointer data) g_object_remove_weak_pointer(G_OBJECT(pdata->shell), (gpointer*)&pdata->shell); } - if (pdata != NULL && pdata->image != NULL) { + if (pdata->image != NULL) { g_signal_handlers_disconnect_matched(pdata->image, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK(image_notify_cb), NULL); g_object_remove_weak_pointer(G_OBJECT(pdata->image), (gpointer*)&pdata->image); } - if (pdata != NULL && pdata->accessible != NULL) { + if (pdata->accessible != NULL) { g_signal_handlers_disconnect_matched(pdata->accessible, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK(a11y_name_notify_cb), NULL); g_object_remove_weak_pointer(G_OBJECT(pdata->accessible), (gpointer*)&pdata->accessible); @@ -218,18 +220,6 @@ parse_data_free (gpointer data) return; } -/* Called when the dbusmenu item that we're keeping around - is finalized */ -static void -dbusmenu_item_freed (gpointer data, GObject * obj) -{ - ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(obj), PARSER_DATA); - - if (pdata != NULL && pdata->widget != NULL) { - g_object_steal_data(G_OBJECT(pdata->widget), CACHED_MENUITEM); - } -} - /* Gets the positon of the child with its' parent if it has one. Returns -1 if the position is unable to be calculated. */ static gint @@ -265,9 +255,7 @@ new_menuitem (GtkWidget * widget) DbusmenuMenuitem * item = dbusmenu_menuitem_new(); ParserData *pdata = g_new0 (ParserData, 1); - g_object_set_data_full(G_OBJECT(item), PARSER_DATA, pdata, parse_data_free); - - g_object_weak_ref(G_OBJECT(item), dbusmenu_item_freed, NULL); + g_object_set_data_full(G_OBJECT(item), PARSER_DATA, pdata, (GDestroyNotify)parse_data_free); pdata->widget = widget; g_object_add_weak_pointer(G_OBJECT (widget), (gpointer*)&pdata->widget); -- cgit v1.2.3 From c9b182f4571ee7973288e9ab1075f4b002aef45b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 6 Apr 2012 13:24:57 -0500 Subject: remove convoluted & unnecessary branch in update_icon() --- libdbusmenu-gtk/parser.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c index c56e28f..4492d01 100644 --- a/libdbusmenu-gtk/parser.c +++ b/libdbusmenu-gtk/parser.c @@ -61,7 +61,6 @@ static void checkbox_toggled (GtkWidget * widget, DbusmenuMenuitem * mi); static void update_icon (DbusmenuMenuitem * menuitem, ParserData * pdata, - GtkImageMenuItem * gmenuitem, GtkImage * image); static GtkWidget * find_menu_label (GtkWidget * widget); static void label_notify_cb (GtkWidget * widget, @@ -546,7 +545,7 @@ construct_dbusmenu_for_widget (GtkWidget * widget) if (GTK_IS_IMAGE (image)) { - update_icon (mi, pdata, GTK_IMAGE_MENU_ITEM(widget), GTK_IMAGE (image)); + update_icon (mi, pdata, GTK_IMAGE (image)); } } @@ -703,7 +702,7 @@ checkbox_toggled (GtkWidget *widget, DbusmenuMenuitem *mi) } static void -update_icon (DbusmenuMenuitem *menuitem, ParserData * pdata, GtkImageMenuItem * gmenuitem, GtkImage *image) +update_icon (DbusmenuMenuitem *menuitem, ParserData * pdata, GtkImage *image) { GdkPixbuf * pixbuf = NULL; const gchar * icon_name = NULL; @@ -712,12 +711,8 @@ update_icon (DbusmenuMenuitem *menuitem, ParserData * pdata, GtkImageMenuItem * GtkIconInfo * info; gint width; - /* Check to see if we're changing the image. If so, we need to track - that little bugger */ - /* Why check for gmenuitem being NULL? Because there are some cases where - we can't get it easily, and those mean it's not changed just the icon - underneith, so we can ignore these larger impacts */ - if (image != GTK_IMAGE(pdata->image) && gmenuitem != NULL) { + /* Check to see if we're changing the image. If so, we need to track that little bugger */ + if (image != GTK_IMAGE(pdata->image)) { if (pdata->image != NULL) { g_signal_handlers_disconnect_by_func(pdata->image, G_CALLBACK(image_notify_cb), menuitem); @@ -936,7 +931,7 @@ image_notify_cb (GtkWidget *widget, pspec->name == g_intern_static_string ("storage-type")) { ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(mi), PARSER_DATA); - update_icon (mi, pdata, NULL, GTK_IMAGE (widget)); + update_icon (mi, pdata, GTK_IMAGE (widget)); } } @@ -1125,14 +1120,14 @@ widget_notify_cb (GtkWidget *widget, GtkWidget *image = NULL; g_object_get(widget, "image", &image, NULL); ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(child), PARSER_DATA); - update_icon (child, pdata, GTK_IMAGE_MENU_ITEM(widget), GTK_IMAGE(image)); + update_icon (child, pdata, GTK_IMAGE(image)); } else if (pspec->name == g_intern_static_string ("image")) { GtkWidget *image; image = GTK_WIDGET (g_value_get_object (&prop_value)); ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(child), PARSER_DATA); - update_icon (child, pdata, GTK_IMAGE_MENU_ITEM(widget), GTK_IMAGE (image)); + update_icon (child, pdata, GTK_IMAGE (image)); } else if (pspec->name == g_intern_static_string ("parent")) { -- cgit v1.2.3 From edb01a80ec933d3dbd8a2588a553d2158b799509 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 6 Apr 2012 13:25:49 -0500 Subject: fix prop_value leak in widget_notify_cb() when a widget's label changes --- libdbusmenu-gtk/parser.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c index 4492d01..a396d8f 100644 --- a/libdbusmenu-gtk/parser.c +++ b/libdbusmenu-gtk/parser.c @@ -1100,14 +1100,13 @@ widget_notify_cb (GtkWidget *widget, } else if (pspec->name == g_intern_static_string ("label")) { - if (handle_first_label (child)) + if (!handle_first_label (child)) { - return; + dbusmenu_menuitem_property_set (child, + DBUSMENU_MENUITEM_PROP_LABEL, + g_value_get_string (&prop_value)); } - dbusmenu_menuitem_property_set (child, - DBUSMENU_MENUITEM_PROP_LABEL, - g_value_get_string (&prop_value)); } else if (pspec->name == g_intern_static_string ("visible")) { -- cgit v1.2.3 From 26789718d12a11f67d7b856d5019de4a472f496e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 6 Apr 2012 13:32:12 -0500 Subject: don't use g_intern_static_string() as a drop-in replacement for strcmp() --- libdbusmenu-gtk/parser.c | 158 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 107 insertions(+), 51 deletions(-) diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c index a396d8f..717efbd 100644 --- a/libdbusmenu-gtk/parser.c +++ b/libdbusmenu-gtk/parser.c @@ -105,6 +105,61 @@ static void menuitem_notify_cb (GtkWidget * widget, GParamSpec * pspec, gpointer data); +/*** +**** +***/ + +static const char * interned_str_accessible_name = NULL; +static const char * interned_str_active = NULL; +static const char * interned_str_always_show_image = NULL; +static const char * interned_str_file = NULL; +static const char * interned_str_gicon = NULL; +static const char * interned_str_icon_name = NULL; +static const char * interned_str_icon_set = NULL; +static const char * interned_str_image = NULL; +static const char * interned_str_label = NULL; +static const char * interned_str_mask = NULL; +static const char * interned_str_parent = NULL; +static const char * interned_str_pixbuf_animation = NULL; +static const char * interned_str_pixbuf = NULL; +static const char * interned_str_pixmap = NULL; +static const char * interned_str_sensitive = NULL; +static const char * interned_str_stock = NULL; +static const char * interned_str_storage_type = NULL; +static const char * interned_str_submenu = NULL; +static const char * interned_str_visible = NULL; + +static void +ensure_interned_strings_loaded (void) +{ + if (G_UNLIKELY(interned_str_file == NULL)) + { + interned_str_accessible_name = g_intern_static_string ("accessible-name"); + interned_str_active = g_intern_static_string ("active"); + interned_str_always_show_image = g_intern_static_string ("always-show-image"); + interned_str_file = g_intern_static_string ("file"); + interned_str_gicon = g_intern_static_string ("gicon"); + interned_str_icon_name = g_intern_static_string ("icon-name"); + interned_str_icon_set = g_intern_static_string ("icon-set"); + interned_str_image = g_intern_static_string ("image"); + interned_str_label = g_intern_static_string ("label"); + interned_str_mask = g_intern_static_string ("mask"); + interned_str_parent = g_intern_static_string ("parent"); + interned_str_pixbuf_animation = g_intern_static_string ("pixbuf-animation"); + interned_str_pixbuf = g_intern_static_string ("pixbuf"); + interned_str_pixmap = g_intern_static_string ("pixmap"); + interned_str_sensitive = g_intern_static_string ("sensitive"); + interned_str_stock = g_intern_static_string ("stock"); + interned_str_storage_type = g_intern_static_string ("storage-type"); + interned_str_submenu = g_intern_static_string ("submenu"); + interned_str_visible = g_intern_static_string ("visible"); + } +} + +/*** +**** +***/ + /** * dbusmenu_gtk_parse_menu_structure: * @widget: A #GtkMenuItem or #GtkMenuShell to turn into a #DbusmenuMenuitem @@ -669,7 +724,9 @@ menuitem_notify_cb (GtkWidget *widget, GParamSpec *pspec, gpointer data) { - if (pspec->name == g_intern_static_string ("visible")) + ensure_interned_strings_loaded (); + + if (pspec->name == interned_str_visible) { GtkWidget * new_toplevel = gtk_widget_get_toplevel (widget); GtkWidget * old_toplevel = GTK_WIDGET(data); @@ -877,10 +934,12 @@ label_notify_cb (GtkWidget *widget, DbusmenuMenuitem *child = (DbusmenuMenuitem *)data; GValue prop_value = {0}; + ensure_interned_strings_loaded (); + g_value_init (&prop_value, pspec->value_type); g_object_get_property (G_OBJECT (widget), pspec->name, &prop_value); - if (pspec->name == g_intern_static_string ("label")) + if (pspec->name == interned_str_label) { gchar * text = sanitize_label (GTK_LABEL (widget)); dbusmenu_menuitem_property_set (child, @@ -888,7 +947,7 @@ label_notify_cb (GtkWidget *widget, text); g_free (text); } - else if (pspec->name == g_intern_static_string ("parent")) + else if (pspec->name == interned_str_parent) { if (GTK_WIDGET (g_value_get_object (&prop_value)) == NULL) { @@ -912,55 +971,53 @@ label_notify_cb (GtkWidget *widget, } static void -image_notify_cb (GtkWidget *widget, - GParamSpec *pspec, - gpointer data) +image_notify_cb (GtkWidget * image, GParamSpec * pspec, gpointer data) { - DbusmenuMenuitem *mi = (DbusmenuMenuitem *)data; - - if (pspec->name == g_intern_static_string ("file") || - pspec->name == g_intern_static_string ("gicon") || - pspec->name == g_intern_static_string ("icon-name") || - pspec->name == g_intern_static_string ("icon-set") || - pspec->name == g_intern_static_string ("image") || - pspec->name == g_intern_static_string ("mask") || - pspec->name == g_intern_static_string ("pixbuf") || - pspec->name == g_intern_static_string ("pixbuf-animation") || - pspec->name == g_intern_static_string ("pixmap") || - pspec->name == g_intern_static_string ("stock") || - pspec->name == g_intern_static_string ("storage-type")) + ensure_interned_strings_loaded(); + + if (pspec->name == interned_str_file || + pspec->name == interned_str_gicon || + pspec->name == interned_str_icon_name || + pspec->name == interned_str_icon_set || + pspec->name == interned_str_image || + pspec->name == interned_str_mask || + pspec->name == interned_str_pixbuf || + pspec->name == interned_str_pixbuf_animation || + pspec->name == interned_str_pixmap || + pspec->name == interned_str_stock || + pspec->name == interned_str_storage_type) { + DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(data); ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(mi), PARSER_DATA); - update_icon (mi, pdata, GTK_IMAGE (widget)); + update_icon (mi, pdata, GTK_IMAGE (image)); } } static void -action_notify_cb (GtkAction *action, - GParamSpec *pspec, - gpointer data) +action_notify_cb (GtkAction *action, GParamSpec * pspec, gpointer data) { - DbusmenuMenuitem *mi = (DbusmenuMenuitem *)data; + DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(data); + ensure_interned_strings_loaded (); - if (pspec->name == g_intern_static_string ("sensitive")) + if (pspec->name == interned_str_sensitive) { dbusmenu_menuitem_property_set_bool (mi, DBUSMENU_MENUITEM_PROP_ENABLED, gtk_action_is_sensitive (action)); } - else if (pspec->name == g_intern_static_string ("visible")) + else if (pspec->name == interned_str_visible) { dbusmenu_menuitem_property_set_bool (mi, DBUSMENU_MENUITEM_PROP_VISIBLE, gtk_action_is_visible (action)); } - else if (pspec->name == g_intern_static_string ("active")) + else if (pspec->name == interned_str_active) { dbusmenu_menuitem_property_set_int (mi, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)) ? DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED : DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED); } - else if (pspec->name == g_intern_static_string ("label")) + else if (pspec->name == interned_str_label) { gchar * text = sanitize_label_text (gtk_action_get_label (action)); dbusmenu_menuitem_property_set (mi, @@ -971,23 +1028,23 @@ action_notify_cb (GtkAction *action, } static void -a11y_name_notify_cb (AtkObject *accessible, - GParamSpec *pspec, - gpointer data) +a11y_name_notify_cb (AtkObject * accessible, GParamSpec * pspec, gpointer data) { - DbusmenuMenuitem *item = (DbusmenuMenuitem *)data; - GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible)); - GtkWidget *label = find_menu_label (widget); - const gchar *label_text = gtk_label_get_text (GTK_LABEL (label)); - const gchar *name = atk_object_get_name (accessible); + ensure_interned_strings_loaded (); /* If an application sets the accessible name to NULL, then a subsequent * call to get the accessible name from the Atk object should return the same * string as the text of the menu item label, in which case, we want to clear * the accessible description property of the dbusmenu item. */ - if (pspec->name == g_intern_static_string ("accessible-name")) + if (pspec->name == interned_str_accessible_name) { + DbusmenuMenuitem * item = DBUSMENU_MENUITEM(data); + GtkWidget *widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible)); + GtkWidget *label = find_menu_label (widget); + const gchar *label_text = gtk_label_get_text (GTK_LABEL (label)); + const gchar *name = atk_object_get_name (accessible); + if (!g_strcmp0 (name, label_text)) dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_ACCESSIBLE_DESC, NULL); else @@ -1082,23 +1139,24 @@ handle_first_label (DbusmenuMenuitem *mi) } static void -widget_notify_cb (GtkWidget *widget, - GParamSpec *pspec, - gpointer data) +widget_notify_cb (GtkWidget * widget, GParamSpec * pspec, gpointer data) { - DbusmenuMenuitem *child = (DbusmenuMenuitem *)data; GValue prop_value = {0}; + DbusmenuMenuitem * child = DBUSMENU_MENUITEM(data); + g_return_if_fail (child != NULL); + + ensure_interned_strings_loaded (); g_value_init (&prop_value, pspec->value_type); g_object_get_property (G_OBJECT (widget), pspec->name, &prop_value); - if (pspec->name == g_intern_static_string ("sensitive")) + if (pspec->name == interned_str_sensitive) { dbusmenu_menuitem_property_set_bool (child, DBUSMENU_MENUITEM_PROP_ENABLED, g_value_get_boolean (&prop_value)); } - else if (pspec->name == g_intern_static_string ("label")) + else if (pspec->name == interned_str_label) { if (!handle_first_label (child)) { @@ -1106,29 +1164,27 @@ widget_notify_cb (GtkWidget *widget, DBUSMENU_MENUITEM_PROP_LABEL, g_value_get_string (&prop_value)); } - } - else if (pspec->name == g_intern_static_string ("visible")) + else if (pspec->name == interned_str_visible) { dbusmenu_menuitem_property_set_bool (child, DBUSMENU_MENUITEM_PROP_VISIBLE, g_value_get_boolean (&prop_value)); } - else if (pspec->name == g_intern_static_string ("always-show-image")) + else if (pspec->name == interned_str_always_show_image) { GtkWidget *image = NULL; g_object_get(widget, "image", &image, NULL); ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(child), PARSER_DATA); update_icon (child, pdata, GTK_IMAGE(image)); } - else if (pspec->name == g_intern_static_string ("image")) + else if (pspec->name == interned_str_image) { - GtkWidget *image; - image = GTK_WIDGET (g_value_get_object (&prop_value)); + GtkWidget * image = GTK_WIDGET (g_value_get_object (&prop_value)); ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(child), PARSER_DATA); update_icon (child, pdata, GTK_IMAGE (image)); } - else if (pspec->name == g_intern_static_string ("parent")) + else if (pspec->name == interned_str_parent) { /* * We probably should have added a 'remove' method to the @@ -1148,7 +1204,7 @@ widget_notify_cb (GtkWidget *widget, } } } - else if (pspec->name == g_intern_static_string ("submenu")) + else if (pspec->name == interned_str_submenu) { /* The underlying submenu got swapped out. Let's see what it is now. */ /* First, delete any children that may exist currently. */ -- cgit v1.2.3 From 29097ccb25899f33f62a65a85ffdbd9250945e00 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 9 Apr 2012 10:08:06 -0500 Subject: Pull the items out of the tuple --- libdbusmenu-glib/server.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index 091b243..9e5b714 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -1831,8 +1831,9 @@ bus_about_to_show_group (DbusmenuServer * server, GVariant * params, GDBusMethod gint32 id; GVariantIter iter; GVariantBuilder builder; - - g_variant_iter_init(&iter, params); + + GVariant * items = g_variant_get_child_value(params, 0); + g_variant_iter_init(&iter, items); g_variant_builder_init(&builder, G_VARIANT_TYPE("ai")); gboolean gotone = FALSE; @@ -1872,6 +1873,7 @@ bus_about_to_show_group (DbusmenuServer * server, GVariant * params, GDBusMethod } g_variant_unref(errors); + g_variant_unref(items); return; } -- cgit v1.2.3 From fcbbfff1269c3a923358c31587319239d183508a Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 9 Apr 2012 10:09:41 -0500 Subject: Apparently this type is wrong, if only this language supported some way to communicate to programmers the types that variables were. Oh, we can dream. --- libdbusmenu-glib/server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index 9e5b714..ebe0082 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -1837,7 +1837,7 @@ bus_about_to_show_group (DbusmenuServer * server, GVariant * params, GDBusMethod g_variant_builder_init(&builder, G_VARIANT_TYPE("ai")); gboolean gotone = FALSE; - while (g_variant_iter_loop(&iter, "(i)", &id)) { + while (g_variant_iter_loop(&iter, "i", &id)) { DbusmenuMenuitem * mi = lookup_menuitem_by_id(server, id); if (mi != NULL) { g_timeout_add(0, bus_about_to_show_idle, g_object_ref(mi)); -- cgit v1.2.3 From 13b7ca65308a08f7c981ccae80ca4e994369e7aa Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 9 Apr 2012 11:16:07 -0500 Subject: warn if we're not able to disconnect from the signals that we're monitoring --- libdbusmenu-gtk/parser.c | 71 ++++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c index 717efbd..5ef6f3b 100644 --- a/libdbusmenu-gtk/parser.c +++ b/libdbusmenu-gtk/parser.c @@ -217,57 +217,70 @@ dbusmenu_gtk_parse_get_cached_item (GtkWidget * widget) } static void -parse_data_free (ParserData * pdata) +parser_data_free (ParserData * pdata) { g_return_if_fail (pdata != NULL); if (pdata->label != NULL) { - g_signal_handlers_disconnect_matched(pdata->label, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(label_notify_cb), 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); } if (pdata->action != NULL) { - g_signal_handlers_disconnect_matched(pdata->action, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(action_notify_cb), 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); } if (pdata->widget != NULL) { - g_signal_handlers_disconnect_matched(pdata->widget, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(widget_notify_cb), NULL); - g_signal_handlers_disconnect_matched(pdata->widget, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(widget_add_cb), NULL); - g_signal_handlers_disconnect_matched(pdata->widget, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(accel_changed), NULL); - g_signal_handlers_disconnect_matched(pdata->widget, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(checkbox_toggled), NULL); - g_signal_handlers_disconnect_matched(pdata->widget, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(menuitem_notify_cb), NULL); - g_object_remove_weak_pointer(G_OBJECT(pdata->widget), (gpointer*)&pdata->widget); + 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); + g_object_remove_weak_pointer(o, (gpointer*)&pdata->widget); /* since the DbusmenuMenuitem is being destroyed, uncache it from the GtkWidget */ - g_object_steal_data(G_OBJECT(pdata->widget), CACHED_MENUITEM); + g_object_steal_data(o, CACHED_MENUITEM); } if (pdata->shell != NULL) { - g_signal_handlers_disconnect_matched(pdata->shell, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(item_inserted_cb), NULL); - g_signal_handlers_disconnect_matched(pdata->shell, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(item_removed_cb), 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); } if (pdata->image != NULL) { - g_signal_handlers_disconnect_matched(pdata->image, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(image_notify_cb), 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); } - if (pdata->accessible != NULL) { - g_signal_handlers_disconnect_matched(pdata->accessible, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, G_CALLBACK(a11y_name_notify_cb), NULL); - g_object_remove_weak_pointer(G_OBJECT(pdata->accessible), (gpointer*)&pdata->accessible); - } + 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); + } g_free(pdata); @@ -309,7 +322,7 @@ new_menuitem (GtkWidget * widget) DbusmenuMenuitem * item = dbusmenu_menuitem_new(); ParserData *pdata = g_new0 (ParserData, 1); - g_object_set_data_full(G_OBJECT(item), PARSER_DATA, pdata, (GDestroyNotify)parse_data_free); + g_object_set_data_full(G_OBJECT(item), PARSER_DATA, pdata, (GDestroyNotify)parser_data_free); pdata->widget = widget; g_object_add_weak_pointer(G_OBJECT (widget), (gpointer*)&pdata->widget); -- cgit v1.2.3 From ef2f1b8d2e827050e91b2bcdaf75ebc2cdae69a4 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 9 Apr 2012 12:02:05 -0500 Subject: Check the string for mnemonic support when setting the value --- libdbusmenu-gtk/genericmenuitem.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index e9c8367..09e509f 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -216,6 +216,31 @@ get_text_color (GenericmenuitemDisposition disposition, GtkWidget * widget) return g_strdup(values[disposition].default_color); } +/* Check to see if we've got mnemonic stuff goin' on */ +static gboolean +has_mnemonic (const gchar * string, gboolean previous_underscore) +{ + if (string == NULL || string[0] == '\0') { + return FALSE; + } + + if (g_utf8_get_char(string) == '_') { + if (previous_underscore) { + return has_mnemonic(g_utf8_next_char(string), FALSE); + } else { + return has_mnemonic(g_utf8_next_char(string), TRUE); + } + } else { + if (previous_underscore) { + return TRUE; + } else { + return has_mnemonic(g_utf8_next_char(string), FALSE); + } + } + + return FALSE; +} + /* Set the label on the item */ static void set_label (GtkMenuItem * menu_item, const gchar * in_label) @@ -287,11 +312,15 @@ set_label (GtkMenuItem * menu_item, const gchar * in_label) if (labelw == NULL) { /* Build it */ labelw = GTK_LABEL(gtk_accel_label_new(local_label)); - gtk_label_set_use_underline(GTK_LABEL(labelw), TRUE); gtk_label_set_use_markup(GTK_LABEL(labelw), TRUE); gtk_misc_set_alignment(GTK_MISC(labelw), 0.0, 0.5); - gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(labelw), GTK_WIDGET(menu_item)); - gtk_label_set_markup_with_mnemonic(labelw, local_label); + + if (has_mnemonic(in_label, FALSE)) { + gtk_label_set_use_underline(GTK_LABEL(labelw), TRUE); + gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(labelw), GTK_WIDGET(menu_item)); + gtk_label_set_markup_with_mnemonic(labelw, local_label); + } + gtk_widget_show(GTK_WIDGET(labelw)); /* Check to see if it needs to be in the bin for this -- cgit v1.2.3 From 1a2b0942da2b73c6338516144f0b77ac5696db74 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 9 Apr 2012 12:07:32 -0500 Subject: Handle mnemonic stuff on updates as well --- libdbusmenu-gtk/genericmenuitem.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libdbusmenu-gtk/genericmenuitem.c b/libdbusmenu-gtk/genericmenuitem.c index 09e509f..9effd82 100644 --- a/libdbusmenu-gtk/genericmenuitem.c +++ b/libdbusmenu-gtk/genericmenuitem.c @@ -338,7 +338,13 @@ set_label (GtkMenuItem * menu_item, const gchar * in_label) getting in. */ suppress_update = TRUE; } else { - gtk_label_set_markup_with_mnemonic(labelw, local_label); + if (has_mnemonic(in_label, FALSE)) { + gtk_label_set_use_underline(GTK_LABEL(labelw), TRUE); + gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(labelw), GTK_WIDGET(menu_item)); + gtk_label_set_markup_with_mnemonic(labelw, local_label); + } else { + gtk_label_set_markup(labelw, local_label); + } } } -- cgit v1.2.3 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