From cccd3fc83553dd525d620f069c7cacbe89e3f322 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 24 Mar 2011 10:58:04 -0500 Subject: Put in some more protections on the types for property variants and generate some errors --- libdbusmenu-glib/client.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 24d5c5d..049cc91 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -1333,8 +1333,16 @@ menuitem_get_properties_cb (GVariant * properties, GError * error, gpointer data if (error != NULL) { g_warning("Error getting properties on a menuitem: %s", error->message); - g_object_unref(data); - return; + goto out; + } + + if (properties == NULL) { + goto out; + } + + if (!g_variant_is_of_type(properties, G_VARIANT_TYPE("a{sv}"))) { + g_warning("Properties are of type '%s' instead of type '%s'", g_variant_get_type_string(properties), "a{sv}"); + goto out; } GVariantIter iter; @@ -1347,6 +1355,7 @@ menuitem_get_properties_cb (GVariant * properties, GError * error, gpointer data dbusmenu_menuitem_property_set_variant(item, key, value); } +out: g_object_unref(data); return; @@ -1365,12 +1374,16 @@ menuitem_get_properties_replace_cb (GVariant * properties, GError * error, gpoin g_warning("Unable to replace properties on %d: %s", dbusmenu_menuitem_get_id(DBUSMENU_MENUITEM(data)), error->message); have_error = TRUE; } + + if (properties == NULL) { + have_error = TRUE; + } /* Get the list of the current properties */ GList * current_props = dbusmenu_menuitem_properties_list(DBUSMENU_MENUITEM(data)); GList * tmp = NULL; - if (properties != NULL) { + if (!have_error && g_variant_is_of_type(properties, G_VARIANT_TYPE("a{sv}"))) { GVariantIter iter; g_variant_iter_init(&iter, properties); gchar * name; GVariant * value; @@ -1414,8 +1427,12 @@ menuitem_get_properties_new_cb (GVariant * properties, GError * error, gpointer if (error != NULL) { g_warning("Error getting properties on a new menuitem: %s", error->message); - g_object_unref(propdata->item); - return; + goto out; + } + + if (properties == NULL) { + g_warning("Not realizing new item as properties for it were unavailable"); + goto out; } DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(propdata->client); @@ -1449,6 +1466,7 @@ menuitem_get_properties_new_cb (GVariant * properties, GError * error, gpointer g_signal_emit(G_OBJECT(propdata->client), signals[NEW_MENUITEM], 0, propdata->item, TRUE); } +out: g_object_unref(propdata->item); g_free(propdata); -- cgit v1.2.3 -- cgit v1.2.3 From 3473a33b499be4d6c2bf7762bf836e1139353970 Mon Sep 17 00:00:00 2001 From: Michael Terry Date: Fri, 25 Mar 2011 11:46:41 -0400 Subject: fix some potential memory issues in hopes of fixing a reported crash --- libdbusmenu-glib/client.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 24d5c5d..49dc2d5 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -598,10 +598,10 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data) } /* Callback all the folks we can find */ - GVariant * child = g_variant_get_child_value(params, 0); + GVariant * parent = g_variant_get_child_value(params, 0); GVariantIter iter; - g_variant_iter_init(&iter, child); - g_variant_unref(child); + g_variant_iter_init(&iter, parent); + GVariant * child; while ((child = g_variant_iter_next_value(&iter)) != NULL) { if (g_strcmp0(g_variant_get_type_string(child), "(ia{sv})") != 0) { g_warning("Properties return signature is not '(ia{sv})' it is '%s'", g_variant_get_type_string(child)); @@ -632,6 +632,7 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data) g_variant_unref(properties); g_variant_unref(child); } + g_variant_unref(parent); g_variant_unref(params); /* Provide errors for those who we can't */ @@ -1370,7 +1371,7 @@ menuitem_get_properties_replace_cb (GVariant * properties, GError * error, gpoin GList * current_props = dbusmenu_menuitem_properties_list(DBUSMENU_MENUITEM(data)); GList * tmp = NULL; - if (properties != NULL) { + if (properties != NULL && have_error == FALSE) { GVariantIter iter; g_variant_iter_init(&iter, properties); gchar * name; GVariant * value; @@ -1378,7 +1379,7 @@ menuitem_get_properties_replace_cb (GVariant * properties, GError * error, gpoin /* Remove the entries from the current list that we have new values for. This way we don't create signals of them being removed with the duplication of the value being changed. */ - while (g_variant_iter_loop(&iter, "{sv}", &name, &value) && have_error == FALSE) { + while (g_variant_iter_loop(&iter, "{sv}", &name, &value)) { for (tmp = current_props; tmp != NULL; tmp = g_list_next(tmp)) { if (g_strcmp0((gchar *)tmp->data, name) == 0) { current_props = g_list_delete_link(current_props, tmp); -- cgit v1.2.3 From e8dcac5e5e1da9eb69210cffde00f896858793ef Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 28 Mar 2011 21:54:55 -0500 Subject: Don't unref a variant we didn't have a ref to on error --- libdbusmenu-gtk/menuitem.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libdbusmenu-gtk/menuitem.c b/libdbusmenu-gtk/menuitem.c index ca2bc3e..f02e171 100644 --- a/libdbusmenu-gtk/menuitem.c +++ b/libdbusmenu-gtk/menuitem.c @@ -287,7 +287,6 @@ dbusmenu_menuitem_property_get_shortcut (DbusmenuMenuitem * menuitem, guint * ke if (g_variant_n_children(wrapper) != 1) { g_warning("Unable to parse shortcut, too many keys"); - g_variant_unref(wrapper); return; } -- cgit v1.2.3 From 980cc3a10a166cd99f9369712489f849732a63e0 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 28 Mar 2011 22:06:44 -0500 Subject: Putting in some protections from NULL parameters. --- libdbusmenu-gtk/menuitem.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libdbusmenu-gtk/menuitem.c b/libdbusmenu-gtk/menuitem.c index f02e171..f6c50b6 100644 --- a/libdbusmenu-gtk/menuitem.c +++ b/libdbusmenu-gtk/menuitem.c @@ -275,6 +275,17 @@ dbusmenu_menuitem_property_set_shortcut_menuitem (DbusmenuMenuitem * menuitem, c void dbusmenu_menuitem_property_get_shortcut (DbusmenuMenuitem * menuitem, guint * key, GdkModifierType * modifier) { + guint dummykey; + GdkModifierType dummymodifier; + + if (key == NULL) { + key = &dummykey; + } + + if (modifier == NULL) { + modifier = &dummymodifier; + } + *key = 0; *modifier = 0; -- cgit v1.2.3 From de83592f2bb7a825b4164b68e9a70499416aeb4b Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 28 Mar 2011 22:11:25 -0500 Subject: Use loop instead of next --- libdbusmenu-gtk/menuitem.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libdbusmenu-gtk/menuitem.c b/libdbusmenu-gtk/menuitem.c index f6c50b6..9987cef 100644 --- a/libdbusmenu-gtk/menuitem.c +++ b/libdbusmenu-gtk/menuitem.c @@ -305,7 +305,7 @@ dbusmenu_menuitem_property_get_shortcut (DbusmenuMenuitem * menuitem, guint * ke g_variant_iter_init(&iter, g_variant_get_child_value(wrapper, 0)); gchar * string; - while(g_variant_iter_next(&iter, "s", &string)) { + while(g_variant_iter_loop(&iter, "s", &string)) { if (g_strcmp0(string, DBUSMENU_MENUITEM_SHORTCUT_CONTROL) == 0) { *modifier |= GDK_CONTROL_MASK; } else if (g_strcmp0(string, DBUSMENU_MENUITEM_SHORTCUT_ALT) == 0) { @@ -318,8 +318,6 @@ dbusmenu_menuitem_property_get_shortcut (DbusmenuMenuitem * menuitem, guint * ke GdkModifierType tempmod; gtk_accelerator_parse(string, key, &tempmod); } - - g_free(string); } return; -- cgit v1.2.3 From ad638a2aed595ae3695c0068e3447c811fa91207 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 29 Mar 2011 08:46:45 -0500 Subject: Split out into another variable --- libdbusmenu-gtk/menuitem.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libdbusmenu-gtk/menuitem.c b/libdbusmenu-gtk/menuitem.c index 9987cef..0f511bc 100644 --- a/libdbusmenu-gtk/menuitem.c +++ b/libdbusmenu-gtk/menuitem.c @@ -302,7 +302,8 @@ dbusmenu_menuitem_property_get_shortcut (DbusmenuMenuitem * menuitem, guint * ke } GVariantIter iter; - g_variant_iter_init(&iter, g_variant_get_child_value(wrapper, 0)); + GVariant * child = g_variant_get_child_value(wrapper, 0); + g_variant_iter_init(&iter, child); gchar * string; while(g_variant_iter_loop(&iter, "s", &string)) { @@ -320,6 +321,8 @@ dbusmenu_menuitem_property_get_shortcut (DbusmenuMenuitem * menuitem, guint * ke } } + g_variant_unref(child); + return; } -- cgit v1.2.3 From 6c9761c9c66a51d6a00a59f14048267beb7ca7f1 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 29 Mar 2011 08:46:56 -0500 Subject: Be more specific about the shortcut type --- libdbusmenu-glib/defaults.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libdbusmenu-glib/defaults.c b/libdbusmenu-glib/defaults.c index 9eaf9e5..ec70da6 100644 --- a/libdbusmenu-glib/defaults.c +++ b/libdbusmenu-glib/defaults.c @@ -85,7 +85,7 @@ dbusmenu_defaults_init (DbusmenuDefaults *self) dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_ICON_NAME, G_VARIANT_TYPE_STRING, NULL); dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, G_VARIANT_TYPE_STRING, NULL); dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, G_VARIANT_TYPE_INT32, NULL); - dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_SHORTCUT, G_VARIANT_TYPE_ARRAY, NULL); + dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_SHORTCUT, G_VARIANT_TYPE("aas"), NULL); dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY, G_VARIANT_TYPE_STRING, NULL); /* Separator defaults */ -- cgit v1.2.3 From 5c87bba0ab605353ca44063b30765470b069c599 Mon Sep 17 00:00:00 2001 From: Chris Coulson Date: Tue, 29 Mar 2011 19:05:15 +0100 Subject: Don't set a default label for menuitems. Some applications (eg, xchat and pidgin) do silly things like creating GtkMenuItems's without a label for separators (rather than using the GtkSeparatorMenuItem class). GTK correctly renders these as separators, so we need to handle it too by not setting a default label on these --- libdbusmenu-glib/defaults.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libdbusmenu-glib/defaults.c b/libdbusmenu-glib/defaults.c index 9eaf9e5..1666efc 100644 --- a/libdbusmenu-glib/defaults.c +++ b/libdbusmenu-glib/defaults.c @@ -81,7 +81,6 @@ dbusmenu_defaults_init (DbusmenuDefaults *self) /* Standard defaults */ dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_VISIBLE, G_VARIANT_TYPE_BOOLEAN, g_variant_new_boolean(TRUE)); dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_ENABLED, G_VARIANT_TYPE_BOOLEAN, g_variant_new_boolean(TRUE)); - dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_LABEL, G_VARIANT_TYPE_STRING, g_variant_new_string(_("Label Empty"))); dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_ICON_NAME, G_VARIANT_TYPE_STRING, NULL); dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, G_VARIANT_TYPE_STRING, NULL); dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, G_VARIANT_TYPE_INT32, NULL); -- cgit v1.2.3 From ccf2e684c6a2f8115dbe9544f43412986acaee79 Mon Sep 17 00:00:00 2001 From: Chris Coulson Date: Wed, 30 Mar 2011 13:20:52 +0100 Subject: Revert the last commit and handle the same problem in the parser instead --- libdbusmenu-glib/defaults.c | 1 + libdbusmenu-gtk/parser.c | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/libdbusmenu-glib/defaults.c b/libdbusmenu-glib/defaults.c index 1666efc..2387c06 100644 --- a/libdbusmenu-glib/defaults.c +++ b/libdbusmenu-glib/defaults.c @@ -81,6 +81,7 @@ dbusmenu_defaults_init (DbusmenuDefaults *self) /* Standard defaults */ dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_VISIBLE, G_VARIANT_TYPE_BOOLEAN, g_variant_new_boolean(TRUE)); dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_ENABLED, G_VARIANT_TYPE_BOOLEAN, g_variant_new_boolean(TRUE)); + dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_LABEL, G_VARIANT_TYPE_STRING, g_variant_new_string(_("Label Empty"))); dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_ICON_NAME, G_VARIANT_TYPE_STRING, NULL); dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, G_VARIANT_TYPE_STRING, NULL); dbusmenu_defaults_default_set(self, DBUSMENU_CLIENT_TYPES_DEFAULT, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, G_VARIANT_TYPE_INT32, NULL); diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c index a7f90a2..9fc8f53 100644 --- a/libdbusmenu-gtk/parser.c +++ b/libdbusmenu-gtk/parser.c @@ -454,7 +454,7 @@ construct_dbusmenu_for_widget (GtkWidget * widget) gboolean visible = FALSE; gboolean sensitive = FALSE; - if (GTK_IS_SEPARATOR_MENU_ITEM (widget)) + if (GTK_IS_SEPARATOR_MENU_ITEM (widget) || !find_menu_label (widget)) { dbusmenu_menuitem_property_set (mi, "type", @@ -891,6 +891,26 @@ widget_notify_cb (GtkWidget *widget, } else if (pspec->name == g_intern_static_string ("label")) { + if (!g_strcmp0 (dbusmenu_menuitem_property_get (child, DBUSMENU_MENUITEM_PROP_TYPE), "separator")) + { + /* GtkMenuItem's can start life as a separator if they have no child + * GtkLabel. In this case, we need to convert the DbusmenuMenuitem from + * a separator to a normal menuitem if the application adds a label + */ + GtkWidget *label = find_menu_label (widget); + /* This should never fail */ + g_return_if_fail (label != NULL); + + dbusmenu_menuitem_property_remove (child, DBUSMENU_MENUITEM_PROP_TYPE); + ParserData *pdata = g_object_get_data (G_OBJECT (widget), PARSER_DATA); + pdata->label = label; + g_signal_connect (G_OBJECT (label), + "notify", + G_CALLBACK (label_notify_cb), + child); + g_object_add_weak_pointer(G_OBJECT (label), (gpointer*)&pdata->label); + } + dbusmenu_menuitem_property_set (child, DBUSMENU_MENUITEM_PROP_LABEL, g_value_get_string (&prop_value)); -- cgit v1.2.3 From f4bfda45834ee6f3983be3e3d7fd9c0e8fb7512e Mon Sep 17 00:00:00 2001 From: Chris Coulson Date: Wed, 30 Mar 2011 13:31:33 +0100 Subject: Remove the now unneeded null pointer check on label in construct_dbusmenu_for_widget. Also, don't use a strcmp in widget_notify_cb for checking if the menuitem is a separator. Just do a null pointer check on pdata->label instead --- libdbusmenu-gtk/parser.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c index 9fc8f53..fc9a3fe 100644 --- a/libdbusmenu-gtk/parser.c +++ b/libdbusmenu-gtk/parser.c @@ -512,21 +512,18 @@ construct_dbusmenu_for_widget (GtkWidget * widget) GtkWidget *label = find_menu_label (widget); - if (label) - { - // Sometimes, an app will directly find and modify the label - // (like empathy), so watch the label especially for that. - gchar * text = sanitize_label (GTK_LABEL (label)); - dbusmenu_menuitem_property_set (mi, "label", text); - g_free (text); - - pdata->label = label; - g_signal_connect (G_OBJECT (label), - "notify", - G_CALLBACK (label_notify_cb), - mi); - g_object_add_weak_pointer(G_OBJECT (label), (gpointer*)&pdata->label); - } + // Sometimes, an app will directly find and modify the label + // (like empathy), so watch the label especially for that. + gchar * text = sanitize_label (GTK_LABEL (label)); + dbusmenu_menuitem_property_set (mi, "label", text); + g_free (text); + + pdata->label = label; + g_signal_connect (G_OBJECT (label), + "notify", + G_CALLBACK (label_notify_cb), + mi); + g_object_add_weak_pointer(G_OBJECT (label), (gpointer*)&pdata->label); if (GTK_IS_ACTIVATABLE (widget)) { @@ -891,7 +888,8 @@ widget_notify_cb (GtkWidget *widget, } else if (pspec->name == g_intern_static_string ("label")) { - if (!g_strcmp0 (dbusmenu_menuitem_property_get (child, DBUSMENU_MENUITEM_PROP_TYPE), "separator")) + ParserData *pdata = g_object_get_data (G_OBJECT (widget), PARSER_DATA); + if (!pdata->label) { /* GtkMenuItem's can start life as a separator if they have no child * GtkLabel. In this case, we need to convert the DbusmenuMenuitem from @@ -902,7 +900,6 @@ widget_notify_cb (GtkWidget *widget, g_return_if_fail (label != NULL); dbusmenu_menuitem_property_remove (child, DBUSMENU_MENUITEM_PROP_TYPE); - ParserData *pdata = g_object_get_data (G_OBJECT (widget), PARSER_DATA); pdata->label = label; g_signal_connect (G_OBJECT (label), "notify", -- cgit v1.2.3 From 25b78133a2075185fe2d94925f446927c1b85b9a Mon Sep 17 00:00:00 2001 From: Chris Coulson Date: Wed, 30 Mar 2011 19:43:02 +0100 Subject: - Don't change the type of existing menu items in the server. This isn't handled in the client too well - Handle a GtkMenuItem's GtkLabel being removed too --- libdbusmenu-gtk/parser.c | 74 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c index fc9a3fe..037c362 100644 --- a/libdbusmenu-gtk/parser.c +++ b/libdbusmenu-gtk/parser.c @@ -756,12 +756,43 @@ find_menu_label (GtkWidget *widget) return label; } +static gboolean +recreate_menu_item_in_idle_cb (gpointer data) +{ + DbusmenuMenuitem * child = (DbusmenuMenuitem *)data; + DbusmenuMenuitem * parent = dbusmenu_menuitem_get_parent (child); + g_object_unref (child); + if (parent == NULL) + { + return FALSE; + } + ParserData * pdata = g_object_get_data (G_OBJECT (child), PARSER_DATA); + /* Keep a pointer to the GtkMenuItem, as pdata->widget might be + * invalidated when we delete the DbusmenuMenuitem + */ + GtkWidget * menuitem = pdata->widget; + + dbusmenu_menuitem_child_delete (parent, child); + + RecurseContext recurse = {0}; + recurse.toplevel = gtk_widget_get_toplevel(menuitem); + recurse.parent = parent; + + parse_menu_structure_helper(menuitem, &recurse); + + return FALSE; +} + static void label_notify_cb (GtkWidget *widget, GParamSpec *pspec, gpointer data) { DbusmenuMenuitem *child = (DbusmenuMenuitem *)data; + GValue prop_value = {0}; + + 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")) { @@ -771,6 +802,24 @@ label_notify_cb (GtkWidget *widget, text); g_free (text); } + else if (pspec->name == g_intern_static_string ("parent")) + { + if (GTK_WIDGET (g_value_get_object (&prop_value)) == NULL) + { + /* This label is being removed from its GtkMenuItem. The + * menuitem becomes a separator now. As the client doesn't handle + * changing types so well, we remove the current DbusmenuMenuitem + * and add a new one. + * + * Note, we have to defer this to idle, as we are called before + * bin->child member of our old parent is invalidated. If we go ahead + * and call parse_menu_structure_helper now, the GtkMenuItem will + * still appear to have a label and we never convert it to a separator + */ + g_object_ref (child); + g_idle_add ((GSourceFunc)recreate_menu_item_in_idle_cb, child); + } + } } static void @@ -888,24 +937,25 @@ widget_notify_cb (GtkWidget *widget, } else if (pspec->name == g_intern_static_string ("label")) { - ParserData *pdata = g_object_get_data (G_OBJECT (widget), PARSER_DATA); + ParserData *pdata = g_object_get_data (G_OBJECT (child), PARSER_DATA); if (!pdata->label) { /* GtkMenuItem's can start life as a separator if they have no child * GtkLabel. In this case, we need to convert the DbusmenuMenuitem from - * a separator to a normal menuitem if the application adds a label + * a separator to a normal menuitem if the application adds a label. + * As changing types isn't handled too well by the client, we delete + * this menuitem for now and then recreate it */ - GtkWidget *label = find_menu_label (widget); - /* This should never fail */ - g_return_if_fail (label != NULL); + DbusmenuMenuitem * parent = dbusmenu_menuitem_get_parent (child); + dbusmenu_menuitem_child_delete (parent, child); - dbusmenu_menuitem_property_remove (child, DBUSMENU_MENUITEM_PROP_TYPE); - pdata->label = label; - g_signal_connect (G_OBJECT (label), - "notify", - G_CALLBACK (label_notify_cb), - child); - g_object_add_weak_pointer(G_OBJECT (label), (gpointer*)&pdata->label); + RecurseContext recurse = {0}; + recurse.toplevel = gtk_widget_get_toplevel(widget); + recurse.parent = parent; + + parse_menu_structure_helper(widget, &recurse); + + return; } dbusmenu_menuitem_property_set (child, -- cgit v1.2.3 From 44fb71ec9b70ad3d2dc7bcb6d35e3f6c7e69370e Mon Sep 17 00:00:00 2001 From: Chris Coulson Date: Wed, 30 Mar 2011 19:58:47 +0100 Subject: Remove some code duplication introduced in this branch --- libdbusmenu-gtk/parser.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c index 037c362..e68c286 100644 --- a/libdbusmenu-gtk/parser.c +++ b/libdbusmenu-gtk/parser.c @@ -756,15 +756,13 @@ find_menu_label (GtkWidget *widget) return label; } -static gboolean -recreate_menu_item_in_idle_cb (gpointer data) +static void +recreate_menu_item (DbusmenuMenuitem * parent, DbusmenuMenuitem * child) { - DbusmenuMenuitem * child = (DbusmenuMenuitem *)data; - DbusmenuMenuitem * parent = dbusmenu_menuitem_get_parent (child); - g_object_unref (child); if (parent == NULL) { - return FALSE; + /* We need a parent */ + return; } ParserData * pdata = g_object_get_data (G_OBJECT (child), PARSER_DATA); /* Keep a pointer to the GtkMenuItem, as pdata->widget might be @@ -779,7 +777,15 @@ recreate_menu_item_in_idle_cb (gpointer data) recurse.parent = parent; parse_menu_structure_helper(menuitem, &recurse); +} +static gboolean +recreate_menu_item_in_idle_cb (gpointer data) +{ + DbusmenuMenuitem * child = (DbusmenuMenuitem *)data; + DbusmenuMenuitem * parent = dbusmenu_menuitem_get_parent (child); + g_object_unref (child); + recreate_menu_item (parent, child); return FALSE; } @@ -947,14 +953,7 @@ widget_notify_cb (GtkWidget *widget, * this menuitem for now and then recreate it */ DbusmenuMenuitem * parent = dbusmenu_menuitem_get_parent (child); - dbusmenu_menuitem_child_delete (parent, child); - - RecurseContext recurse = {0}; - recurse.toplevel = gtk_widget_get_toplevel(widget); - recurse.parent = parent; - - parse_menu_structure_helper(widget, &recurse); - + recreate_menu_item (parent, child); return; } -- cgit v1.2.3 From f90465d8892aff9002874ae40656b3c67a2542af Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 31 Mar 2011 12:58:34 -0500 Subject: 0.4.1 --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index a400680..e94e795 100644 --- a/configure.ac +++ b/configure.ac @@ -1,11 +1,11 @@ -AC_INIT(libdbusmenu, 0.4.0, ted@canonical.com) +AC_INIT(libdbusmenu, 0.4.1, ted@canonical.com) AC_COPYRIGHT([Copyright 2009,2010 Canonical]) AC_PREREQ(2.62) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(libdbusmenu, 0.4.0, [-Wno-portability]) +AM_INIT_AUTOMAKE(libdbusmenu, 0.4.1, [-Wno-portability]) AM_MAINTAINER_MODE @@ -134,7 +134,7 @@ AC_PATH_PROG([XSLT_PROC], [xsltproc]) ########################### LIBDBUSMENU_CURRENT=3 -LIBDBUSMENU_REVISION=11 +LIBDBUSMENU_REVISION=12 LIBDBUSMENU_AGE=0 AC_SUBST(LIBDBUSMENU_CURRENT) -- cgit v1.2.3