aboutsummaryrefslogtreecommitdiff
path: root/libdbusmenu-glib/server.c
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2011-02-07 17:07:23 -0600
committerTed Gould <ted@gould.cx>2011-02-07 17:07:23 -0600
commit880714ebc6850a2383c4caebfa6aeda66a422937 (patch)
treecf582d0787ad6a366706c593c917dc1590e4d1ab /libdbusmenu-glib/server.c
parent3fab4873c00572044ddc8447d5aa0f3d2d9f8cd1 (diff)
downloadlibdbusmenu-880714ebc6850a2383c4caebfa6aeda66a422937.tar.gz
libdbusmenu-880714ebc6850a2383c4caebfa6aeda66a422937.tar.bz2
libdbusmenu-880714ebc6850a2383c4caebfa6aeda66a422937.zip
Basic outline of the function mapped out, no compile.
Diffstat (limited to 'libdbusmenu-glib/server.c')
-rw-r--r--libdbusmenu-glib/server.c97
1 files changed, 93 insertions, 4 deletions
diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c
index 777e4ef..b54f4a3 100644
--- a/libdbusmenu-glib/server.c
+++ b/libdbusmenu-glib/server.c
@@ -633,12 +633,25 @@ layout_update_signal (DbusmenuServer * server)
return;
}
-static void
-menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GVariant * variant, DbusmenuServer * server)
+typedef struct _prop_idle_item_t prop_idle_item_t;
+struct _prop_idle_item_t {
+ guint id;
+ GArray * array;
+};
+
+typedef struct _prop_idle_prop_t prop_idle_prop_t;
+struct _prop_idle_prop_t {
+ gchar * property;
+ GVariant * variant;
+};
+
+/* Works in the idle to send a set of property updates so that they'll
+ all update in a single dbus message. */
+static gboolean
+menuitem_property_idle (gpointer user_data)
{
- DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
+ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(user_data);
- g_signal_emit(G_OBJECT(server), signals[ID_PROP_UPDATE], 0, dbusmenu_menuitem_get_id(mi), property, variant, TRUE);
if (priv->dbusobject != NULL && priv->bus != NULL) {
g_dbus_connection_emit_signal(priv->bus,
@@ -649,6 +662,82 @@ menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GVariant * v
g_variant_new("(isv)", dbusmenu_menuitem_get_id(mi), property, variant),
NULL);
}
+
+ return FALSE;
+}
+
+static void
+menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GVariant * variant, DbusmenuServer * server)
+{
+ int i;
+ guint item_id;
+
+ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
+
+ item_id = dbusmenu_menuitem_get_id(mi);
+
+ g_signal_emit(G_OBJECT(server), signals[ID_PROP_UPDATE], 0, item_id, property, variant, TRUE);
+
+ /* See if we have a property array, if not, we need to
+ build one of these suckers */
+ if (priv->prop_array == NULL) {
+ priv->prop_array = g_array_new();
+ }
+
+ /* Look to see if we already have this item in the list
+ and use it if so */
+ prop_idle_item_t * item = NULL;
+ for (i = 0; i < priv->prop_array->len; i++) {
+ prop_idle_item_t * iitem = &g_array_index(prop_idle_item_t, i);
+ if (iitem->id == item_id) {
+ item = iitem;
+ break;
+ }
+ }
+
+ GArray * properties = NULL;
+ /* If not, we'll need to build ourselves one */
+ if (item == NULL) {
+ prop_idle_item_t myitem;
+ myitem.id = item_id;
+ myitem.array = g_array_new();
+
+ g_array_append(priv->prop_array, myitem);
+ properties = myitem.array;
+ } else {
+ properties = item->array;
+ }
+
+ /* Check to see if this property is in the list */
+ prop_idle_prop_t * prop = NULL;
+ for (i = 0; i < properties->len; i++) {
+ prop_idle_prop_t * iprop = &g_array_index(properties, prop_idle_prop_t, i);
+ if (g_strcmp0(iprop->name, property)) {
+ prop = iprop;
+ break;
+ }
+ }
+
+ /* If so, we need to swap the value */
+ if (prop != NULL) {
+ g_variant_unref(prop->variant);
+ prop->variant = variant;
+ } else {
+ /* else we need to add it */
+ prop_idle_prop_t myprop;
+ myprop.property = g_strdup(property);
+ myprop.variant = variant;
+
+ g_array_append(properties, myprop);
+ }
+ g_variant_ref(variant);
+
+ /* Check to see if the idle is already queued, and queue it
+ if not. */
+ if (priv->property_idle == 0) {
+ priv->property_idle = g_idle_add(menuitem_property_idle, server);
+ }
+
return;
}