diff options
-rw-r--r-- | libdbusmenu-glib/menuitem.c | 20 | ||||
-rw-r--r-- | libdbusmenu-glib/server.c | 6 | ||||
-rw-r--r-- | libdbusmenu-gtk/parser.c | 36 |
3 files changed, 48 insertions, 14 deletions
diff --git a/libdbusmenu-glib/menuitem.c b/libdbusmenu-glib/menuitem.c index f7867e4..2e5a345 100644 --- a/libdbusmenu-glib/menuitem.c +++ b/libdbusmenu-glib/menuitem.c @@ -1180,17 +1180,23 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro } } - gboolean replaced = FALSE; gboolean remove = FALSE; - gpointer currentval = g_hash_table_lookup(priv->properties, property); + gchar * hash_key = NULL; + GVariant * hash_variant = NULL; + gboolean inhash = g_hash_table_lookup_extended(priv->properties, property, (gpointer *)&hash_key, (gpointer *)&hash_variant); + + if (inhash && hash_variant == NULL) { + g_warning("The property '%s' is in the hash with a NULL variant", property); + inhash = FALSE; + } if (value != NULL) { /* NOTE: We're only marking this as replaced if this is true but we're actually replacing it no matter. This is so that the variant passed in sticks around which the caller may expect. They shouldn't, but it's low cost to remove bugs. */ - if (currentval == NULL || !g_variant_equal((GVariant*)currentval, value)) { + if (!inhash || !g_variant_equal(hash_variant, value)) { replaced = TRUE; } @@ -1204,7 +1210,7 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro bad value */ g_hash_table_insert(priv->properties, lprop, value); } else { - if (currentval != NULL) { + if (inhash) { /* So the question you should be asking if you're paying attention is "Why not just do the remove here?" It's a good question with an interesting answer. Bascially it's the same reason as above, @@ -1213,6 +1219,7 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro it) after the signal emition */ remove = TRUE; replaced = TRUE; + g_hash_table_steal(priv->properties, property); } } @@ -1220,7 +1227,7 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro becuse it has been unref'd when replaced in the hash table. But the fact that there was a value is the imporant part. */ - if (currentval == NULL || replaced) { + if (!inhash || replaced) { GVariant * signalval = value; if (signalval == NULL) { @@ -1233,7 +1240,8 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro } if (remove) { - g_hash_table_remove(priv->properties, property); + g_free(hash_key); + g_variant_unref(hash_variant); } return TRUE; diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index ca39ea3..a41e6ce 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -511,7 +511,7 @@ set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec) GVariantBuilder params; g_variant_builder_init(¶ms, G_VARIANT_TYPE_TUPLE); g_variant_builder_add_value(¶ms, g_variant_new_string(DBUSMENU_INTERFACE)); - GVariant * dict = g_variant_new_dict_entry(g_variant_new_string("TextDirection"), g_variant_new_string(dbusmenu_text_direction_get_nick(priv->text_direction))); + GVariant * dict = g_variant_new_dict_entry(g_variant_new_string("TextDirection"), g_variant_new_variant(g_variant_new_string(dbusmenu_text_direction_get_nick(priv->text_direction)))); g_variant_builder_add_value(¶ms, g_variant_new_array(NULL, &dict, 1)); g_variant_builder_add_value(¶ms, g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0)); GVariant * vparams = g_variant_builder_end(¶ms); @@ -535,7 +535,7 @@ set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec) GVariantBuilder params; g_variant_builder_init(¶ms, G_VARIANT_TYPE_TUPLE); g_variant_builder_add_value(¶ms, g_variant_new_string(DBUSMENU_INTERFACE)); - GVariant * dict = g_variant_new_dict_entry(g_variant_new_string("Status"), g_variant_new_string(dbusmenu_status_get_nick(instatus))); + GVariant * dict = g_variant_new_dict_entry(g_variant_new_string("Status"), g_variant_new_variant(g_variant_new_string(dbusmenu_status_get_nick(instatus)))); g_variant_builder_add_value(¶ms, g_variant_new_array(NULL, &dict, 1)); g_variant_builder_add_value(¶ms, g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0)); GVariant * vparams = g_variant_builder_end(¶ms); @@ -1773,7 +1773,7 @@ dbusmenu_server_set_icon_paths (DbusmenuServer * server, GStrv icon_paths) g_variant_builder_add_value(¶ms, g_variant_new_string(DBUSMENU_INTERFACE)); GVariant * items = NULL; if (priv->icon_dirs != NULL) { - GVariant * dict = g_variant_new_dict_entry(g_variant_new_string("IconThemePath"), g_variant_new_strv((const gchar * const *)priv->icon_dirs, -1)); + GVariant * dict = g_variant_new_dict_entry(g_variant_new_string("IconThemePath"), g_variant_new_variant(g_variant_new_strv((const gchar * const *)priv->icon_dirs, -1))); items = g_variant_new_array(NULL, &dict, 1); } else { items = g_variant_new_array(G_VARIANT_TYPE("{sv}"), NULL, 0); diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c index cf2003f..8954d64 100644 --- a/libdbusmenu-gtk/parser.c +++ b/libdbusmenu-gtk/parser.c @@ -219,6 +219,7 @@ new_menuitem (GtkWidget * widget) pdata->widget = widget; g_object_add_weak_pointer(G_OBJECT (widget), (gpointer*)&pdata->widget); + g_object_set_data(G_OBJECT(widget), CACHED_MENUITEM, item); return item; } @@ -311,6 +312,10 @@ parse_menu_structure_helper (GtkWidget * widget, RecurseContext * recurse) /* Oops, let's tell our parents about us */ if (peek == NULL) { + if (dbusmenu_menuitem_get_parent(thisitem) != NULL) { + dbusmenu_menuitem_unparent(thisitem); + } + gint pos = get_child_position (widget); if (pos >= 0) dbusmenu_menuitem_child_add_position (recurse->parent, @@ -340,6 +345,23 @@ parse_menu_structure_helper (GtkWidget * widget, RecurseContext * recurse) return; } +static gchar * +sanitize_label_text (const gchar * label) +{ + /* Label contains underscores, which we like, and pango markup, + which we don't. */ + gchar * sanitized = NULL; + GError * error = NULL; + if (pango_parse_markup (label, -1, 0, NULL, &sanitized, NULL, &error)) { + return sanitized; + } + else { + g_warning ("Could not parse '%s': %s", label, error->message); + g_error_free (error); + return g_strdup (label); + } +} + /* Turn a widget into a dbusmenu item depending on the type of GTK object that it is. */ static DbusmenuMenuitem * @@ -423,9 +445,9 @@ construct_dbusmenu_for_widget (GtkWidget * widget) { // Sometimes, an app will directly find and modify the label // (like empathy), so watch the label especially for that. - dbusmenu_menuitem_property_set (mi, - "label", - gtk_label_get_text (GTK_LABEL (label))); + gchar * text = sanitize_label_text (gtk_label_get_label (GTK_LABEL (label))); + dbusmenu_menuitem_property_set (mi, "label", text); + g_free (text); pdata->label = label; g_signal_connect (G_OBJECT (label), @@ -668,9 +690,11 @@ label_notify_cb (GtkWidget *widget, if (pspec->name == g_intern_static_string ("label")) { + gchar * text = sanitize_label_text (gtk_label_get_label (GTK_LABEL (widget))); dbusmenu_menuitem_property_set (child, DBUSMENU_MENUITEM_PROP_LABEL, - gtk_label_get_text (GTK_LABEL (widget))); + text); + g_free (text); } } @@ -724,9 +748,11 @@ action_notify_cb (GtkAction *action, } else if (pspec->name == g_intern_static_string ("label")) { + gchar * text = sanitize_label_text (gtk_action_get_label (action)); dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, - gtk_action_get_label (action)); + text); + g_free (text); } } |