From 236ddb030b31aa78842c81fef0cd107a6b615124 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 20 Aug 2009 12:54:53 -0500 Subject: Switching the new signal to be after the properties are gotten and adding a hashtable for type handlers. --- libdbusmenu-glib/client.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 212071b..9eb8b55 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -68,6 +68,8 @@ struct _DbusmenuClientPrivate DBusGProxyCall * layoutcall; DBusGProxy * dbusproxy; + + GHashTable * type_handlers; }; #define DBUSMENU_CLIENT_GET_PRIVATE(o) \ @@ -187,6 +189,9 @@ dbusmenu_client_init (DbusmenuClient *self) priv->dbusproxy = NULL; + priv->type_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, NULL); + return; } @@ -230,6 +235,10 @@ dbusmenu_client_finalize (GObject *object) g_free(priv->dbus_name); g_free(priv->dbus_object); + if (priv->type_handlers != NULL) { + g_hash_table_destroy(priv->type_handlers); + } + G_OBJECT_CLASS (dbusmenu_client_parent_class)->finalize (object); return; } @@ -515,6 +524,22 @@ menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError return; } +/* This is a different get properites call back that also sends + new signals. It basically is a small wrapper around the original. */ +static void +menuitem_get_properties_new_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data) +{ + gpointer * unpackarray = (gpointer *)data; + + menuitem_get_properties_cb (proxy, properties, error, unpackarray[1]); + + g_signal_emit(G_OBJECT(unpackarray[0]), signals[NEW_MENUITEM], 0, unpackarray[1], TRUE); + + g_free(unpackarray); + + return; +} + static void menuitem_call_cb (DBusGProxy * proxy, GError * error, gpointer userdata) { @@ -562,9 +587,14 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it dbusmenu_menuitem_set_root(item, TRUE); } g_signal_connect(G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(menuitem_activate), client); - g_signal_emit(G_OBJECT(client), signals[NEW_MENUITEM], 0, item, TRUE); + /* Get the properties queued up for this item */ - org_freedesktop_dbusmenu_get_properties_async(proxy, id, menuitem_get_properties_cb, item); + /* Not happy about this, but I need both of these :( */ + gpointer * packarray = g_new0(gpointer, 2); + packarray[0] = client; + packarray[1] = item; + + org_freedesktop_dbusmenu_get_properties_async(proxy, id, menuitem_get_properties_new_cb, packarray); } xmlNodePtr children; -- cgit v1.2.3 From 69fe6b5ac33dfd64163d5b41f9a0719b23912e40 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 20 Aug 2009 13:05:24 -0500 Subject: Makin' it so that if we have a type handler we use that, otherwise we pass things up. Also making it so that type handlers can report an error. --- libdbusmenu-glib/client.c | 22 ++++++++++++++++++++-- libdbusmenu-glib/client.h | 2 +- 2 files changed, 21 insertions(+), 3 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 9eb8b55..a4e4f72 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -530,10 +530,27 @@ static void menuitem_get_properties_new_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data) { gpointer * unpackarray = (gpointer *)data; + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(unpackarray[0]); menuitem_get_properties_cb (proxy, properties, error, unpackarray[1]); - g_signal_emit(G_OBJECT(unpackarray[0]), signals[NEW_MENUITEM], 0, unpackarray[1], TRUE); + gboolean handled = FALSE; + + const gchar * type; + DbusmenuClientTypeHandler newfunc = NULL; + + type = dbusmenu_menuitem_property_get(DBUSMENU_MENUITEM(unpackarray[1]), "type"); + if (type != NULL) { + newfunc = g_hash_table_lookup(priv->type_handlers, type); + } + + if (newfunc != NULL) { + handled = newfunc(DBUSMENU_MENUITEM(unpackarray[1]), DBUSMENU_MENUITEM(unpackarray[2])); + } + + if (!handled) { + g_signal_emit(G_OBJECT(unpackarray[0]), signals[NEW_MENUITEM], 0, unpackarray[1], TRUE); + } g_free(unpackarray); @@ -590,9 +607,10 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it /* Get the properties queued up for this item */ /* Not happy about this, but I need both of these :( */ - gpointer * packarray = g_new0(gpointer, 2); + gpointer * packarray = g_new0(gpointer, 3); packarray[0] = client; packarray[1] = item; + packarray[2] = parent; org_freedesktop_dbusmenu_get_properties_async(proxy, id, menuitem_get_properties_new_cb, packarray); } diff --git a/libdbusmenu-glib/client.h b/libdbusmenu-glib/client.h index 20156d8..9298d4e 100644 --- a/libdbusmenu-glib/client.h +++ b/libdbusmenu-glib/client.h @@ -90,7 +90,7 @@ struct _DbusmenuClient { GObject parent; }; -typedef void (*DbusmenuClientTypeHandler) (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent); +typedef gboolean (*DbusmenuClientTypeHandler) (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent); GType dbusmenu_client_get_type (void); DbusmenuClient * dbusmenu_client_new (const gchar * name, -- cgit v1.2.3 From 2a110cf96860653b68d1a165c7e3b7ddb1f993f8 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Thu, 20 Aug 2009 13:20:54 -0500 Subject: Making things a little more type safe. Only one evil cast. --- libdbusmenu-glib/client.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index a4e4f72..5809e1e 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -72,6 +72,14 @@ struct _DbusmenuClientPrivate GHashTable * type_handlers; }; +typedef struct _newItemPropData newItemPropData; +struct _newItemPropData +{ + DbusmenuClient * client; + DbusmenuMenuitem * item; + DbusmenuMenuitem * parent; +}; + #define DBUSMENU_CLIENT_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_TYPE_CLIENT, DbusmenuClientPrivate)) @@ -529,30 +537,30 @@ menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError static void menuitem_get_properties_new_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data) { - gpointer * unpackarray = (gpointer *)data; - DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(unpackarray[0]); + newItemPropData * propdata = (newItemPropData *)data; + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(propdata->client); - menuitem_get_properties_cb (proxy, properties, error, unpackarray[1]); + menuitem_get_properties_cb (proxy, properties, error, propdata->item); gboolean handled = FALSE; const gchar * type; DbusmenuClientTypeHandler newfunc = NULL; - type = dbusmenu_menuitem_property_get(DBUSMENU_MENUITEM(unpackarray[1]), "type"); + type = dbusmenu_menuitem_property_get(propdata->item, "type"); if (type != NULL) { newfunc = g_hash_table_lookup(priv->type_handlers, type); } if (newfunc != NULL) { - handled = newfunc(DBUSMENU_MENUITEM(unpackarray[1]), DBUSMENU_MENUITEM(unpackarray[2])); + handled = newfunc(propdata->item, propdata->parent); } if (!handled) { - g_signal_emit(G_OBJECT(unpackarray[0]), signals[NEW_MENUITEM], 0, unpackarray[1], TRUE); + g_signal_emit(G_OBJECT(propdata->client), signals[NEW_MENUITEM], 0, propdata->item, TRUE); } - g_free(unpackarray); + g_free(propdata); return; } @@ -606,13 +614,13 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it g_signal_connect(G_OBJECT(item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(menuitem_activate), client); /* Get the properties queued up for this item */ - /* Not happy about this, but I need both of these :( */ - gpointer * packarray = g_new0(gpointer, 3); - packarray[0] = client; - packarray[1] = item; - packarray[2] = parent; + /* Not happy about this, but I need these :( */ + newItemPropData * propdata = g_new0(newItemPropData, 1); + propdata->client = client; + propdata->item = item; + propdata->parent = parent; - org_freedesktop_dbusmenu_get_properties_async(proxy, id, menuitem_get_properties_new_cb, packarray); + org_freedesktop_dbusmenu_get_properties_async(proxy, id, menuitem_get_properties_new_cb, propdata); } xmlNodePtr children; -- cgit v1.2.3 From 3136e45a9b1aa56ba8d136df34310ab0891e1a84 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 25 Aug 2009 11:28:13 -0500 Subject: Signaling the realized event after it has all it's parameters. --- libdbusmenu-glib/client.c | 2 ++ libdbusmenu-glib/menuitem.h | 1 + 2 files changed, 3 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 5809e1e..4f5922d 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -556,6 +556,8 @@ menuitem_get_properties_new_cb (DBusGProxy * proxy, GHashTable * properties, GEr handled = newfunc(propdata->item, propdata->parent); } + g_signal_emit(G_OBJECT(propdata->item), DBUSMENU_MENUITEM_SIGNAL_REALIZED_ID, 0, TRUE); + if (!handled) { g_signal_emit(G_OBJECT(propdata->client), signals[NEW_MENUITEM], 0, propdata->item, TRUE); } diff --git a/libdbusmenu-glib/menuitem.h b/libdbusmenu-glib/menuitem.h index 7704b4a..0a92153 100644 --- a/libdbusmenu-glib/menuitem.h +++ b/libdbusmenu-glib/menuitem.h @@ -48,6 +48,7 @@ G_BEGIN_DECLS #define DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED "child-removed" #define DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED "child-moved" #define DBUSMENU_MENUITEM_SIGNAL_REALIZED "realized" +#define DBUSMENU_MENUITEM_SIGNAL_REALIZED_ID (g_signal_lookup(DBUSMENU_MENUITEM_SIGNAL_REALIZED, DBUSMENU_TYPE_MENUITEM)) /** DbusmenuMenuitem: -- cgit v1.2.3 From 0d23ee0ce837c23750bdeef3e01c4f117d1250fc Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 25 Aug 2009 14:13:34 -0500 Subject: Switching the prototype for type handlers so that it passes the client as well. --- libdbusmenu-glib/client.c | 2 +- libdbusmenu-glib/client.h | 2 +- libdbusmenu-gtk/client.c | 15 +++++++-------- 3 files changed, 9 insertions(+), 10 deletions(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 4f5922d..9ac880b 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -553,7 +553,7 @@ menuitem_get_properties_new_cb (DBusGProxy * proxy, GHashTable * properties, GEr } if (newfunc != NULL) { - handled = newfunc(propdata->item, propdata->parent); + handled = newfunc(propdata->item, propdata->parent, propdata->client); } g_signal_emit(G_OBJECT(propdata->item), DBUSMENU_MENUITEM_SIGNAL_REALIZED_ID, 0, TRUE); diff --git a/libdbusmenu-glib/client.h b/libdbusmenu-glib/client.h index c30f318..b4d214f 100644 --- a/libdbusmenu-glib/client.h +++ b/libdbusmenu-glib/client.h @@ -94,7 +94,7 @@ struct _DbusmenuClient { GObject parent; }; -typedef gboolean (*DbusmenuClientTypeHandler) (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent); +typedef gboolean (*DbusmenuClientTypeHandler) (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); GType dbusmenu_client_get_type (void); DbusmenuClient * dbusmenu_client_new (const gchar * name, diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index 0f24c39..bc4a72a 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -44,9 +44,9 @@ static void new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint po static void delete_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, DbusmenuGtkClient * gtkclient); static void move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint old, DbusmenuGtkClient * gtkclient); -static gboolean new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent); -static gboolean new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent); -static gboolean new_item_image (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent); +static gboolean new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); +static gboolean new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); +static gboolean new_item_image (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); /* GObject Stuff */ G_DEFINE_TYPE (DbusmenuGtkClient, dbusmenu_gtkclient, DBUSMENU_TYPE_CLIENT); @@ -266,7 +266,7 @@ dbusmenu_gtkclient_menuitem_get (DbusmenuGtkClient * client, DbusmenuMenuitem * } static gboolean -new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent) +new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) { gpointer ann_mi = g_object_get_data(G_OBJECT(newitem), data_menuitem); GtkMenuItem * gmi = GTK_MENU_ITEM(ann_mi); @@ -279,21 +279,20 @@ new_item_normal (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent) gmi = GTK_MENU_ITEM(gtk_menu_item_new()); - // Need client - base_new_menuitem(newitem, gmi, NULL); + base_new_menuitem(newitem, gmi, DBUSMENU_GTKCLIENT(client)); return TRUE; } static gboolean -new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent) +new_item_seperator (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) { return TRUE; } static gboolean -new_item_image (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent) +new_item_image (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) { return TRUE; -- cgit v1.2.3 From d5e159567d782bfd8568d9075bea32264f326dff Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 25 Aug 2009 14:47:43 -0500 Subject: It turns out that when you define functions in a header file, they don't just write themselves from your thoughts. Who's supposed to tell me these things? Anyway, now we have a way to register type handlers, like the header file said we should. --- libdbusmenu-glib/client.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index 9ac880b..c89b44b 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -802,3 +802,46 @@ dbusmenu_client_get_root (DbusmenuClient * client) return priv->root; } + +/** + dbusmenu_client_add_type_handler: + @client: Client where we're getting types coming in + @type: A text string that will be matched with the 'type' + property on incoming menu items + @newfunc: The function that will be executed with those new + items when they come in. + + This function connects into the type handling of the #DbusmenuClient. + Every new menuitem that comes in immediately gets asked for it's + properties. When we get those properties we check the 'type' + property and look to see if it matches a handler that is known + by the client. If so, the @newfunc function is executed on that + #DbusmenuMenuitem. If not, then the DbusmenuClient::new-menuitem + signal is sent. + + In the future the known types will be sent to the server so that it + can make choices about the menu item types availble. + + Return value: If registering the new type was successful. +*/ +gboolean +dbusmenu_client_add_type_handler (DbusmenuClient * client, const gchar * type, DbusmenuClientTypeHandler newfunc) +{ + g_return_val_if_fail(DBUSMENU_IS_CLIENT(client), FALSE); + + DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); + + if (priv->type_handlers) { + g_warning("Type handlers hashtable not built"); + return FALSE; + } + + gpointer value = g_hash_table_lookup(priv->type_handlers, type); + if (value != NULL) { + g_warning("Type '%s' already had a registered handler.", type); + return FALSE; + } + + g_hash_table_insert(priv->type_handlers, g_strdup(type), newfunc); + return TRUE; +} -- cgit v1.2.3 From 7e5458a267bc02c113c082a8185adf325cf5780d Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Tue, 25 Aug 2009 15:47:37 -0500 Subject: Ah, bother. Check NULL. Brain fart. --- libdbusmenu-glib/client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libdbusmenu-glib/client.c') diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index c89b44b..0a80c6e 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -831,7 +831,7 @@ dbusmenu_client_add_type_handler (DbusmenuClient * client, const gchar * type, D DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); - if (priv->type_handlers) { + if (priv->type_handlers == NULL) { g_warning("Type handlers hashtable not built"); return FALSE; } -- cgit v1.2.3