diff options
Diffstat (limited to 'libdbusmenu-gtk/parser.c')
-rw-r--r-- | libdbusmenu-gtk/parser.c | 119 |
1 files changed, 73 insertions, 46 deletions
diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c index f516dde..cf2003f 100644 --- a/libdbusmenu-gtk/parser.c +++ b/libdbusmenu-gtk/parser.c @@ -109,60 +109,74 @@ dbusmenu_gtk_parse_menu_structure (GtkWidget * widget) return recurse.parent; } -/* Called when the dbusmenu item that we're keeping around - is finalized */ static void -dbusmenu_cache_freed (gpointer data, GObject * obj) +parse_data_free (gpointer data) { - /* If the dbusmenu item is killed we don't need to remove - the weak ref as well. */ - g_object_steal_data(G_OBJECT(data), CACHED_MENUITEM); - - ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(obj), PARSER_DATA); + ParserData *pdata = (ParserData *)data; if (pdata != NULL && pdata->label != NULL) { - g_signal_handlers_disconnect_by_func(pdata->label, G_CALLBACK(label_notify_cb), obj); + 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) { - g_signal_handlers_disconnect_by_func(pdata->action, G_CALLBACK(action_notify_cb), obj); + 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) { - g_signal_handlers_disconnect_by_func(pdata->widget, G_CALLBACK(widget_notify_cb), obj); + 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(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); } if (pdata != NULL && pdata->shell != NULL) { - g_signal_handlers_disconnect_by_func(pdata->shell, G_CALLBACK(child_added_cb), obj); + g_signal_handlers_disconnect_matched(pdata->shell, (GSignalMatchType)G_SIGNAL_MATCH_FUNC, + 0, 0, NULL, G_CALLBACK(child_added_cb), NULL); g_object_remove_weak_pointer(G_OBJECT(pdata->shell), (gpointer*)&pdata->shell); } if (pdata != NULL && pdata->image != NULL) { - g_signal_handlers_disconnect_by_func(pdata->image, G_CALLBACK(image_notify_cb), obj); + 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); } + g_free(pdata); + return; } -/* Called if we replace the cache on the object with a new - dbusmenu menuitem */ static void -object_cache_freed (gpointer data) +widget_freed (gpointer data, GObject * obj) { - // TODO: make this have access to both data and obj so we can call these - //if (!G_IS_OBJECT(obj)) return; - //g_object_weak_unref(G_OBJECT(obj), dbusmenu_cache_freed, data); - //dbusmenu_cache_freed(data, obj); - - g_signal_handlers_disconnect_by_func(gtk_icon_theme_get_default(), G_CALLBACK(theme_changed_cb), data); + g_signal_handlers_disconnect_by_func(gtk_icon_theme_get_default(), G_CALLBACK(theme_changed_cb), obj); 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_signal_handlers_disconnect_by_func(gtk_icon_theme_get_default(), G_CALLBACK(theme_changed_cb), pdata->widget); + g_object_steal_data(G_OBJECT(pdata->widget), CACHED_MENUITEM); + g_object_weak_unref(G_OBJECT(pdata->widget), widget_freed, NULL); + } +} + /* 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 @@ -198,10 +212,13 @@ 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, g_free); + 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_weak_ref(G_OBJECT(widget), widget_freed, NULL); - g_object_set_data_full(G_OBJECT(widget), CACHED_MENUITEM, item, object_cache_freed); - g_object_weak_ref(G_OBJECT(item), dbusmenu_cache_freed, widget); + pdata->widget = widget; + g_object_add_weak_pointer(G_OBJECT (widget), (gpointer*)&pdata->widget); return item; } @@ -237,16 +254,16 @@ parse_menu_structure_helper (GtkWidget * widget, RecurseContext * recurse) if (recurse->parent == NULL) { recurse->parent = new_menuitem(widget); - } - ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(recurse->parent), PARSER_DATA); + ParserData *pdata = (ParserData *)g_object_get_data(G_OBJECT(recurse->parent), PARSER_DATA); - pdata->shell = widget; - g_signal_connect (G_OBJECT (widget), - "child-added", - G_CALLBACK (child_added_cb), - recurse->parent); - g_object_add_weak_pointer(G_OBJECT (widget), (gpointer*)&pdata->shell); + pdata->shell = widget; + g_signal_connect (G_OBJECT (widget), + "child-added", + G_CALLBACK (child_added_cb), + recurse->parent); + g_object_add_weak_pointer(G_OBJECT (widget), (gpointer*)&pdata->shell); + } gtk_container_foreach (GTK_CONTAINER (widget), (GtkCallback)parse_menu_structure_helper, @@ -294,10 +311,6 @@ parse_menu_structure_helper (GtkWidget * widget, RecurseContext * recurse) /* Oops, let's tell our parents about us */ if (peek == NULL) { - /* TODO: Should we set a weak ref on the parent? */ - g_object_set_data (G_OBJECT (thisitem), - "dbusmenu-parent", - recurse->parent); gint pos = get_child_position (widget); if (pos >= 0) dbusmenu_menuitem_child_add_position (recurse->parent, @@ -445,6 +458,17 @@ construct_dbusmenu_for_widget (GtkWidget * widget) } } + GtkWidget *submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(widget)); + if (submenu) + { + pdata->shell = submenu; + g_signal_connect (G_OBJECT (submenu), + "child-added", + G_CALLBACK (child_added_cb), + mi); + g_object_add_weak_pointer(G_OBJECT(submenu), (gpointer*)&pdata->shell); + } + if (!g_object_get_data (G_OBJECT (widget), "gtk-empty-menu-item") && !GTK_IS_TEAROFF_MENU_ITEM (widget)) { visible = gtk_widget_get_visible (widget); @@ -472,12 +496,10 @@ construct_dbusmenu_for_widget (GtkWidget * widget) DBUSMENU_MENUITEM_PROP_ENABLED, sensitive); - pdata->widget = widget; g_signal_connect (widget, "notify", G_CALLBACK (widget_notify_cb), mi); - g_object_add_weak_pointer(G_OBJECT (widget), (gpointer*)&pdata->widget); return mi; } @@ -750,30 +772,34 @@ widget_notify_cb (GtkWidget *widget, 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 ("sensitive")) { dbusmenu_menuitem_property_set_bool (child, DBUSMENU_MENUITEM_PROP_ENABLED, - gtk_widget_get_sensitive (widget)); + g_value_get_boolean (&prop_value)); } else if (pspec->name == g_intern_static_string ("label")) { dbusmenu_menuitem_property_set (child, DBUSMENU_MENUITEM_PROP_LABEL, - gtk_menu_item_get_label (GTK_MENU_ITEM (widget))); + g_value_get_string (&prop_value)); } else if (pspec->name == g_intern_static_string ("visible")) { dbusmenu_menuitem_property_set_bool (child, DBUSMENU_MENUITEM_PROP_VISIBLE, - gtk_widget_get_visible (widget)); + g_value_get_boolean (&prop_value)); } else if (pspec->name == g_intern_static_string ("image") || pspec->name == g_intern_static_string ("always-show-image")) { GtkWidget *image; - image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (widget)); + image = GTK_WIDGET (g_value_get_object (&prop_value)); update_icon (child, GTK_IMAGE (image)); } else if (pspec->name == g_intern_static_string ("parent")) @@ -782,13 +808,13 @@ widget_notify_cb (GtkWidget *widget, * We probably should have added a 'remove' method to the * UbuntuMenuProxy early on, but it's late in the cycle now. */ - if (gtk_widget_get_parent (widget) == NULL) + if (GTK_WIDGET (g_value_get_object (&prop_value)) == NULL) { g_signal_handlers_disconnect_by_func (widget, G_CALLBACK (widget_notify_cb), child); - DbusmenuMenuitem *parent = g_object_get_data (G_OBJECT (child), "dbusmenu-parent"); + DbusmenuMenuitem *parent = dbusmenu_menuitem_get_parent (child); if (DBUSMENU_IS_MENUITEM (parent) && DBUSMENU_IS_MENUITEM (child)) { @@ -818,7 +844,7 @@ widget_notify_cb (GtkWidget *widget, recurse.parent = item; if (item != NULL) { - GtkWidget * menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)); + GtkWidget * menu = GTK_WIDGET (g_value_get_object (&prop_value)); parse_menu_structure_helper(menu, &recurse); } else { /* Note: it would be really odd that we wouldn't have a cached @@ -827,6 +853,7 @@ widget_notify_cb (GtkWidget *widget, g_object_unref(G_OBJECT(recurse.parent)); } } + g_value_unset (&prop_value); } /* A child item was added to a menu we're watching. Let's try to integrate it. */ |