diff options
Diffstat (limited to 'libdbusmenu-glib/server.c')
-rw-r--r-- | libdbusmenu-glib/server.c | 126 |
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); |