aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac4
-rw-r--r--libdbusmenu-glib/client.c19
-rw-r--r--libdbusmenu-glib/server.c9
-rw-r--r--libdbusmenu-gtk/parser.c418
4 files changed, 268 insertions, 182 deletions
diff --git a/configure.ac b/configure.ac
index 2d51716..50f14ef 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,11 +1,11 @@
-AC_INIT(libdbusmenu, 0.5.97, 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.97, [-Wno-portability])
+AM_INIT_AUTOMAKE(libdbusmenu, 0.6.0, [-Wno-portability])
AM_MAINTAINER_MODE
diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c
index 34f8b8d..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;
@@ -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;
}
@@ -2028,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,
@@ -2041,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);
}
diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c
index 091b243..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;
}
@@ -1831,12 +1832,13 @@ 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;
- 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));
@@ -1872,6 +1874,7 @@ bus_about_to_show_group (DbusmenuServer * server, GVariant * params, GDBusMethod
}
g_variant_unref(errors);
+ g_variant_unref(items);
return;
}
diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c
index b98f34b..2f7277c 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;
@@ -61,7 +77,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,
@@ -106,6 +121,96 @@ 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");
+ }
+}
+
+/***
+****
+***/
+
+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 */
+ 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;
+ }
+ }
+}
+
+/* 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
@@ -163,73 +268,59 @@ dbusmenu_gtk_parse_get_cached_item (GtkWidget * widget)
}
static void
-parse_data_free (gpointer data)
+parser_data_free (ParserData * pdata)
{
- ParserData *pdata = (ParserData *)data;
+ g_return_if_fail (pdata != NULL);
- if (pdata != NULL && 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->label != NULL) {
+ 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 != NULL && 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->action != NULL) {
+ 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 != NULL && 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);
+ if (pdata->widget != NULL) {
+ GObject * o = G_OBJECT(pdata->widget);
+ 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 != NULL && 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);
- g_object_remove_weak_pointer(G_OBJECT(pdata->shell), (gpointer*)&pdata->shell);
+ if (pdata->shell != NULL) {
+ 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 != NULL && 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->image != NULL) {
+ 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 != NULL && 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) {
+ 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);
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 +356,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)parser_data_free);
pdata->widget = widget;
g_object_add_weak_pointer(G_OBJECT (widget), (gpointer*)&pdata->widget);
@@ -292,10 +381,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
@@ -303,10 +392,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
@@ -392,17 +481,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
@@ -529,10 +619,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))
{
@@ -544,10 +632,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))
@@ -558,7 +643,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));
}
}
@@ -571,10 +656,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);
@@ -591,10 +673,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);
}
@@ -612,10 +694,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);
}
}
@@ -659,15 +740,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;
}
@@ -682,19 +759,20 @@ 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);
+ 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);
}
}
@@ -715,7 +793,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;
@@ -724,25 +802,22 @@ 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);
- 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);
}
}
@@ -894,10 +969,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,
@@ -905,7 +982,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)
{
@@ -929,55 +1006,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, NULL, 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,
@@ -988,23 +1063,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
@@ -1099,54 +1174,52 @@ 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))
+ 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"))
+ 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_MENU_ITEM(widget), GTK_IMAGE(image));
+ 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_MENU_ITEM(widget), GTK_IMAGE (image));
+ 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
@@ -1154,9 +1227,8 @@ widget_notify_cb (GtkWidget *widget,
*/
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);
@@ -1166,7 +1238,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. */