aboutsummaryrefslogtreecommitdiff
path: root/libdbusmenu-glib/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdbusmenu-glib/server.c')
-rw-r--r--libdbusmenu-glib/server.c126
1 files changed, 106 insertions, 20 deletions
diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c
index 4da8ae0..aa39991 100644
--- a/libdbusmenu-glib/server.c
+++ b/libdbusmenu-glib/server.c
@@ -438,7 +438,7 @@ set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec)
GList * iter;
for (iter = properties; iter != NULL; iter = g_list_next(iter)) {
gchar * property = (gchar *)iter->data;
- menuitem_property_changed(priv->root, property, g_variant_new_string("deadvalue"), DBUSMENU_SERVER(obj));
+ menuitem_property_changed(priv->root, property, NULL, DBUSMENU_SERVER(obj));
}
g_list_free(properties);
@@ -680,7 +680,10 @@ prop_array_teardown (GArray * prop_array)
prop_idle_prop_t * iprop = &g_array_index(iitem->array, prop_idle_prop_t, j);
g_free(iprop->property);
- g_variant_unref(iprop->variant);
+
+ if (iprop->variant != NULL) {
+ g_variant_unref(iprop->variant);
+ }
}
g_array_free(iitem->array, TRUE);
@@ -708,34 +711,105 @@ menuitem_property_idle (gpointer user_data)
int i, j;
GVariantBuilder itembuilder;
- g_variant_builder_init(&itembuilder, G_VARIANT_TYPE_ARRAY);
+ gboolean item_init = FALSE;
+
+ GVariantBuilder removeitembuilder;
+ gboolean removeitem_init = FALSE;
for (i = 0; i < priv->prop_array->len; i++) {
prop_idle_item_t * iitem = &g_array_index(priv->prop_array, prop_idle_item_t, i);
- GVariantBuilder tuplebuilder;
- g_variant_builder_init(&tuplebuilder, G_VARIANT_TYPE_TUPLE);
-
- g_variant_builder_add_value(&tuplebuilder, g_variant_new_int32(iitem->id));
-
GVariantBuilder dictbuilder;
- g_variant_builder_init(&dictbuilder, G_VARIANT_TYPE_DICTIONARY);
+ gboolean dictinit = FALSE;
+
+ GVariantBuilder removedictbuilder;
+ gboolean removedictinit = FALSE;
+ /* Go throught each item and see if it should go in the removal list
+ or the additive list. */
for (j = 0; j < iitem->array->len; j++) {
prop_idle_prop_t * iprop = &g_array_index(iitem->array, prop_idle_prop_t, j);
- GVariant * entry = g_variant_new_dict_entry(g_variant_new_string(iprop->property),
- g_variant_new_variant(iprop->variant));
+ if (iprop->variant != NULL) {
+ if (!dictinit) {
+ g_variant_builder_init(&dictbuilder, G_VARIANT_TYPE_DICTIONARY);
+ dictinit = TRUE;
+ }
+
+ GVariant * entry = g_variant_new_dict_entry(g_variant_new_string(iprop->property),
+ g_variant_new_variant(iprop->variant));
+
+ g_variant_builder_add_value(&dictbuilder, entry);
+ } else {
+ if (!removedictinit) {
+ g_variant_builder_init(&removedictbuilder, G_VARIANT_TYPE_ARRAY);
+ removedictinit = TRUE;
+ }
+
+ g_variant_builder_add_value(&removedictbuilder, g_variant_new_string(iprop->property));
+ }
+ }
+
+ /* If we've got new values that are real values we need to add that
+ to the list of items to send the value of */
+ if (dictinit) {
+ GVariantBuilder tuplebuilder;
+ g_variant_builder_init(&tuplebuilder, G_VARIANT_TYPE_TUPLE);
+
+ g_variant_builder_add_value(&tuplebuilder, g_variant_new_int32(iitem->id));
+ g_variant_builder_add_value(&tuplebuilder, g_variant_builder_end(&dictbuilder));
+
+ if (!item_init) {
+ g_variant_builder_init(&itembuilder, G_VARIANT_TYPE_ARRAY);
+ item_init = TRUE;
+ }
- g_variant_builder_add_value(&dictbuilder, entry);
+ g_variant_builder_add_value(&itembuilder, g_variant_builder_end(&tuplebuilder));
}
- g_variant_builder_add_value(&tuplebuilder, g_variant_builder_end(&dictbuilder));
+ /* If we've got properties that have been removed then we need to add
+ them to the list of removed items */
+ if (removedictinit) {
+ GVariantBuilder tuplebuilder;
+ g_variant_builder_init(&tuplebuilder, G_VARIANT_TYPE_TUPLE);
+
+ g_variant_builder_add_value(&tuplebuilder, g_variant_new_int32(iitem->id));
+ g_variant_builder_add_value(&tuplebuilder, g_variant_builder_end(&removedictbuilder));
- g_variant_builder_add_value(&itembuilder, g_variant_builder_end(&tuplebuilder));
+ if (!removeitem_init) {
+ g_variant_builder_init(&removeitembuilder, G_VARIANT_TYPE_ARRAY);
+ removeitem_init = TRUE;
+ }
+
+ g_variant_builder_add_value(&removeitembuilder, g_variant_builder_end(&tuplebuilder));
+ }
}
- GVariant * megadata = g_variant_builder_end(&itembuilder);
+ GVariant * megadata[2];
+
+ if (item_init) {
+ megadata[0] = g_variant_builder_end(&itembuilder);
+ } else {
+ GError * error = NULL;
+ megadata[0] = g_variant_parse(G_VARIANT_TYPE("a(ia{sv})"), "[ ]", NULL, NULL, &error);
+
+ if (error != NULL) {
+ g_warning("Unable to parse '[ ]' as a 'a(ia{sv})': %s", error->message);
+ g_error_free(error);
+ }
+ }
+
+ if (removeitem_init) {
+ megadata[1] = g_variant_builder_end(&removeitembuilder);
+ } else {
+ GError * error = NULL;
+ megadata[1] = g_variant_parse(G_VARIANT_TYPE("a(ia(s))"), "[ ]", NULL, NULL, &error);
+
+ if (error != NULL) {
+ g_warning("Unable to parse '[ ]' as a 'a(ia(s))': %s", error->message);
+ g_error_free(error);
+ }
+ }
if (priv->dbusobject != NULL && priv->bus != NULL) {
g_dbus_connection_emit_signal(priv->bus,
@@ -743,10 +817,11 @@ menuitem_property_idle (gpointer user_data)
priv->dbusobject,
DBUSMENU_INTERFACE,
"ItemPropertiesUpdated",
- g_variant_new_tuple(&megadata, 1),
+ g_variant_new_tuple(megadata, 2),
NULL);
} else {
- g_variant_unref(megadata);
+ g_variant_unref(megadata[0]);
+ g_variant_unref(megadata[1]);
}
/* Clean everything up */
@@ -808,6 +883,13 @@ menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GVariant * v
}
}
+ /* If it's the default value we want to treat it like a clearing
+ of the value so that it doesn't get sent over dbus and waste
+ bandwidth */
+ if (dbusmenu_menuitem_property_is_default(mi, property)) {
+ variant = NULL;
+ }
+
/* If so, we need to swap the value */
if (prop != NULL) {
g_variant_unref(prop->variant);
@@ -820,7 +902,9 @@ menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GVariant * v
g_array_append_val(properties, myprop);
}
- g_variant_ref(variant);
+ if (variant != NULL) {
+ g_variant_ref_sink(variant);
+ }
/* Check to see if the idle is already queued, and queue it
if not. */
@@ -974,8 +1058,10 @@ bus_get_layout (DbusmenuServer * server, GVariant * params, GDBusMethodInvocatio
g_variant_builder_add_value(&tuplebuilder, g_variant_new_uint32(revision));
g_variant_builder_add_value(&tuplebuilder, items);
+ GVariant * retval = g_variant_builder_end(&tuplebuilder);
+ // g_debug("Sending layout type: %s", g_variant_get_type_string(retval));
g_dbus_method_invocation_return_value(invocation,
- g_variant_builder_end(&tuplebuilder));
+ retval);
return;
}
@@ -1280,7 +1366,7 @@ bus_event (DbusmenuServer * server, GVariant * params, GDBusMethodInvocation * i
event_data->variant = g_variant_get_variant(event_data->variant);
}
- g_variant_ref(event_data->variant);
+ g_variant_ref_sink(event_data->variant);
g_timeout_add(0, event_local_handler, event_data);