aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2011-02-15 11:54:43 -0600
committerTed Gould <ted@gould.cx>2011-02-15 11:54:43 -0600
commitd96e8ddcadc023ab9ac5bb9ff932011cd6788b5a (patch)
treeb557d324cadaf66a63b7f2220da364640c1fcc88
parent931994f499108dec95c7e6c9022848667b69848f (diff)
parente1094452eda0314065bb1b02d616d573c0367a74 (diff)
downloadlibdbusmenu-d96e8ddcadc023ab9ac5bb9ff932011cd6788b5a.tar.gz
libdbusmenu-d96e8ddcadc023ab9ac5bb9ff932011cd6788b5a.tar.bz2
libdbusmenu-d96e8ddcadc023ab9ac5bb9ff932011cd6788b5a.zip
Syncing up to the group properties branch so our tests pass
-rw-r--r--libdbusmenu-glib/client.c30
-rw-r--r--libdbusmenu-glib/dbus-menu.xml1
-rw-r--r--libdbusmenu-glib/menuitem-private.h1
-rw-r--r--libdbusmenu-glib/menuitem.c20
-rw-r--r--libdbusmenu-glib/server.c126
-rw-r--r--tests/json-loader.c1
-rw-r--r--tests/test-glib-layout-client.c5
7 files changed, 158 insertions, 26 deletions
diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c
index fa3b1d2..ba4ae7e 100644
--- a/libdbusmenu-glib/client.c
+++ b/libdbusmenu-glib/client.c
@@ -1026,12 +1026,40 @@ menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVarian
{
g_return_if_fail(DBUSMENU_IS_CLIENT(user_data));
DbusmenuClient * client = DBUSMENU_CLIENT(user_data);
+ DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
if (g_strcmp0(signal, "LayoutUpdated") == 0) {
guint revision; gint parent;
g_variant_get(params, "(ui)", &revision, &parent);
layout_update(proxy, revision, parent, client);
+ } else if (priv->root == NULL) {
+ /* Drop out here, all the rest of these really need to have a root
+ node so we can just ignore them if there isn't one. */
} else if (g_strcmp0(signal, "ItemPropertiesUpdated") == 0) {
+ /* Remove before adding just incase there is a duplicate, against the
+ rules, but we can handle it so let's do it. */
+ GVariantIter ritems;
+ g_variant_iter_init(&ritems, g_variant_get_child_value(params, 1));
+
+ GVariant * ritem;
+ while ((ritem = g_variant_iter_next_value(&ritems)) != NULL) {
+ gint id = g_variant_get_int32(g_variant_get_child_value(ritem, 0));
+ DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id);
+
+ if (menuitem == NULL) {
+ continue;
+ }
+
+ GVariantIter properties;
+ g_variant_iter_init(&properties, g_variant_get_child_value(ritem, 1));
+ gchar * property;
+
+ while (g_variant_iter_next(&properties, "s", &property)) {
+ g_debug("Removing property '%s' on %d", property, id);
+ dbusmenu_menuitem_property_remove(menuitem, property);
+ }
+ }
+
GVariantIter items;
g_variant_iter_init(&items, g_variant_get_child_value(params, 0));
@@ -1248,7 +1276,7 @@ dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name
edata->event = g_strdup(name);
edata->timestamp = timestamp;
edata->variant = variant;
- g_variant_ref(variant);
+ g_variant_ref_sink(variant);
g_dbus_proxy_call(priv->menuproxy,
"Event",
diff --git a/libdbusmenu-glib/dbus-menu.xml b/libdbusmenu-glib/dbus-menu.xml
index e0e70d7..da14c63 100644
--- a/libdbusmenu-glib/dbus-menu.xml
+++ b/libdbusmenu-glib/dbus-menu.xml
@@ -309,6 +309,7 @@ License version 3 and version 2.1 along with this program. If not, see
properties.
</dox:d>
<arg type="a(ia(sv))" name="props" direction="out" />
+ <arg type="a(ia(s))" name="props_removed" direction="out" />
</signal>
<signal name="LayoutUpdated">
<dox:d>
diff --git a/libdbusmenu-glib/menuitem-private.h b/libdbusmenu-glib/menuitem-private.h
index 07704ca..89319dc 100644
--- a/libdbusmenu-glib/menuitem-private.h
+++ b/libdbusmenu-glib/menuitem-private.h
@@ -37,6 +37,7 @@ GVariant * dbusmenu_menuitem_build_variant (DbusmenuMenuitem * mi, const gchar *
gboolean dbusmenu_menuitem_realized (DbusmenuMenuitem * mi);
void dbusmenu_menuitem_set_realized (DbusmenuMenuitem * mi);
GVariant * dbusmenu_menuitem_properties_variant (DbusmenuMenuitem * mi, const gchar ** properties);
+gboolean dbusmenu_menuitem_property_is_default (DbusmenuMenuitem * mi, const gchar * property);
G_END_DECLS
diff --git a/libdbusmenu-glib/menuitem.c b/libdbusmenu-glib/menuitem.c
index da34ff0..54d2540 100644
--- a/libdbusmenu-glib/menuitem.c
+++ b/libdbusmenu-glib/menuitem.c
@@ -1009,7 +1009,7 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro
if (value != NULL) {
gchar * lprop = g_strdup(property);
- g_variant_ref(value);
+ g_variant_ref_sink(value);
if (currentval == NULL || !g_variant_equal((GVariant*)currentval, value)) {
g_hash_table_replace(priv->properties, lprop, value);
@@ -1213,7 +1213,7 @@ copy_helper (gpointer in_key, gpointer in_value, gpointer in_data)
GHashTable * table = (GHashTable *)in_data;
gchar * key = (gchar *)in_key;
GVariant * value = (GVariant *)in_value;
- g_variant_ref(value);
+ g_variant_ref_sink(value);
g_hash_table_insert(table, g_strdup(key), value);
return;
}
@@ -1250,7 +1250,9 @@ dbusmenu_menuitem_properties_copy (DbusmenuMenuitem * mi)
static void
variant_helper (gpointer in_key, gpointer in_value, gpointer user_data)
{
- g_variant_builder_add((GVariantBuilder *)user_data, "{sv}", in_key, in_value);
+ GVariant * value = g_variant_new_dict_entry(g_variant_new_string((gchar *)in_key),
+ g_variant_new_variant((GVariant *)in_value));
+ g_variant_builder_add_value((GVariantBuilder *)user_data, value);
return;
}
@@ -1274,7 +1276,7 @@ dbusmenu_menuitem_properties_variant (DbusmenuMenuitem * mi, const gchar ** prop
if (g_hash_table_size(priv->properties) > 0) {
GVariantBuilder builder;
- g_variant_builder_init(&builder, g_variant_type_new("a{sv}"));
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
g_hash_table_foreach(priv->properties, variant_helper, &builder);
@@ -1495,3 +1497,13 @@ dbusmenu_menuitem_show_to_user (DbusmenuMenuitem * mi, guint timestamp)
return;
}
+
+/* Checks to see if the value of this property is unique or just the
+ default value. */
+/* TODO: Implement this */
+gboolean
+dbusmenu_menuitem_property_is_default (DbusmenuMenuitem * mi, const gchar * property)
+{
+ /* No defaults system yet */
+ return FALSE;
+}
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);
diff --git a/tests/json-loader.c b/tests/json-loader.c
index 14e90e0..36157dc 100644
--- a/tests/json-loader.c
+++ b/tests/json-loader.c
@@ -109,7 +109,6 @@ set_props (DbusmenuMenuitem * mi, JsonObject * node)
if (variant != NULL) {
dbusmenu_menuitem_property_set_variant(mi, member, variant);
- g_variant_unref(variant);
}
}
diff --git a/tests/test-glib-layout-client.c b/tests/test-glib-layout-client.c
index 5ea0cf8..3afe042 100644
--- a/tests/test-glib-layout-client.c
+++ b/tests/test-glib-layout-client.c
@@ -81,6 +81,11 @@ layout_updated (DbusmenuClient * client, gpointer data)
g_debug("Layout Updated");
DbusmenuMenuitem * menuroot = dbusmenu_client_get_root(client);
+ if (menuroot == NULL) {
+ g_debug("Root NULL, waiting");
+ return;
+ }
+
layout_t * layout = &layouts[layouton];
if (!verify_root_to_layout(menuroot, layout)) {