aboutsummaryrefslogtreecommitdiff
path: root/libdbusmenu-glib/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdbusmenu-glib/client.c')
-rw-r--r--libdbusmenu-glib/client.c56
1 files changed, 41 insertions, 15 deletions
diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c
index a98ae98..1ee8641 100644
--- a/libdbusmenu-glib/client.c
+++ b/libdbusmenu-glib/client.c
@@ -331,6 +331,8 @@ dbusmenu_client_class_init (DbusmenuClientClass *klass)
return;
}
+#define LAYOUT_PROPS_COUNT 5
+
static void
dbusmenu_client_init (DbusmenuClient *self)
{
@@ -351,13 +353,14 @@ dbusmenu_client_init (DbusmenuClient *self)
priv->layoutcall = NULL;
- gchar * layout_props[5];
+ gchar * layout_props[LAYOUT_PROPS_COUNT + 1];
layout_props[0] = DBUSMENU_MENUITEM_PROP_TYPE;
layout_props[1] = DBUSMENU_MENUITEM_PROP_LABEL;
layout_props[2] = DBUSMENU_MENUITEM_PROP_VISIBLE;
layout_props[3] = DBUSMENU_MENUITEM_PROP_ENABLED;
- layout_props[4] = NULL;
- priv->layout_props = g_variant_new_strv((const gchar * const *)layout_props, 4);
+ layout_props[4] = DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY;
+ layout_props[LAYOUT_PROPS_COUNT] = NULL;
+ priv->layout_props = g_variant_new_strv((const gchar * const *)layout_props, LAYOUT_PROPS_COUNT);
g_variant_ref_sink(priv->layout_props);
priv->current_revision = 0;
@@ -441,6 +444,9 @@ dbusmenu_client_dispose (GObject *object)
priv->menuproxy_cancel = NULL;
}
if (priv->menuproxy != NULL) {
+ g_signal_handlers_disconnect_matched(priv->menuproxy,
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
g_object_unref(G_OBJECT(priv->menuproxy));
priv->menuproxy = NULL;
}
@@ -598,10 +604,10 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data)
}
/* Callback all the folks we can find */
- GVariant * child = g_variant_get_child_value(params, 0);
+ GVariant * parent = g_variant_get_child_value(params, 0);
GVariantIter iter;
- g_variant_iter_init(&iter, child);
- g_variant_unref(child);
+ g_variant_iter_init(&iter, parent);
+ GVariant * child;
while ((child = g_variant_iter_next_value(&iter)) != NULL) {
if (g_strcmp0(g_variant_get_type_string(child), "(ia{sv})") != 0) {
g_warning("Properties return signature is not '(ia{sv})' it is '%s'", g_variant_get_type_string(child));
@@ -632,6 +638,7 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data)
g_variant_unref(properties);
g_variant_unref(child);
}
+ g_variant_unref(parent);
g_variant_unref(params);
/* Provide errors for those who we can't */
@@ -1232,7 +1239,7 @@ menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVarian
} 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) {
+ } else if (g_strcmp0(signal, "ItemsPropertiesUpdated") == 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;
@@ -1333,8 +1340,16 @@ menuitem_get_properties_cb (GVariant * properties, GError * error, gpointer data
if (error != NULL) {
g_warning("Error getting properties on a menuitem: %s", error->message);
- g_object_unref(data);
- return;
+ goto out;
+ }
+
+ if (properties == NULL) {
+ goto out;
+ }
+
+ if (!g_variant_is_of_type(properties, G_VARIANT_TYPE("a{sv}"))) {
+ g_warning("Properties are of type '%s' instead of type '%s'", g_variant_get_type_string(properties), "a{sv}");
+ goto out;
}
GVariantIter iter;
@@ -1347,6 +1362,7 @@ menuitem_get_properties_cb (GVariant * properties, GError * error, gpointer data
dbusmenu_menuitem_property_set_variant(item, key, value);
}
+out:
g_object_unref(data);
return;
@@ -1365,12 +1381,16 @@ menuitem_get_properties_replace_cb (GVariant * properties, GError * error, gpoin
g_warning("Unable to replace properties on %d: %s", dbusmenu_menuitem_get_id(DBUSMENU_MENUITEM(data)), error->message);
have_error = TRUE;
}
+
+ if (properties == NULL) {
+ have_error = TRUE;
+ }
/* Get the list of the current properties */
GList * current_props = dbusmenu_menuitem_properties_list(DBUSMENU_MENUITEM(data));
GList * tmp = NULL;
- if (properties != NULL) {
+ if (!have_error && g_variant_is_of_type(properties, G_VARIANT_TYPE("a{sv}"))) {
GVariantIter iter;
g_variant_iter_init(&iter, properties);
gchar * name; GVariant * value;
@@ -1378,7 +1398,7 @@ menuitem_get_properties_replace_cb (GVariant * properties, GError * error, gpoin
/* Remove the entries from the current list that we have new
values for. This way we don't create signals of them being
removed with the duplication of the value being changed. */
- while (g_variant_iter_loop(&iter, "{sv}", &name, &value) && have_error == FALSE) {
+ while (g_variant_iter_loop(&iter, "{sv}", &name, &value)) {
for (tmp = current_props; tmp != NULL; tmp = g_list_next(tmp)) {
if (g_strcmp0((gchar *)tmp->data, name) == 0) {
current_props = g_list_delete_link(current_props, tmp);
@@ -1414,8 +1434,12 @@ menuitem_get_properties_new_cb (GVariant * properties, GError * error, gpointer
if (error != NULL) {
g_warning("Error getting properties on a new menuitem: %s", error->message);
- g_object_unref(propdata->item);
- return;
+ goto out;
+ }
+
+ if (properties == NULL) {
+ g_warning("Not realizing new item as properties for it were unavailable");
+ goto out;
}
DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(propdata->client);
@@ -1449,6 +1473,7 @@ menuitem_get_properties_new_cb (GVariant * properties, GError * error, gpointer
g_signal_emit(G_OBJECT(propdata->client), signals[NEW_MENUITEM], 0, propdata->item, TRUE);
}
+out:
g_object_unref(propdata->item);
g_free(propdata);
@@ -1475,6 +1500,7 @@ menuitem_call_cb (GObject * proxy, GAsyncResult * res, gpointer userdata)
g_variant_unref(edata->variant);
g_free(edata->event);
g_object_unref(edata->menuitem);
+ g_object_unref(edata->client);
g_free(edata);
if (G_UNLIKELY(error != NULL)) {
@@ -1490,14 +1516,13 @@ menuitem_call_cb (GObject * proxy, GAsyncResult * res, gpointer userdata)
/* Sends the event over DBus to the server on the other side
of the bus. */
void
-dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name, GVariant * variant, guint timestamp)
+dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name, GVariant * variant, guint timestamp, DbusmenuMenuitem * mi)
{
g_return_if_fail(DBUSMENU_IS_CLIENT(client));
g_return_if_fail(id >= 0);
g_return_if_fail(name != NULL);
DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
- DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id);
if (mi == NULL) {
g_warning("Asked to activate a menuitem %d that we don't know about", id);
return;
@@ -1509,6 +1534,7 @@ dbusmenu_client_send_event (DbusmenuClient * client, gint id, const gchar * name
event_data_t * edata = g_new0(event_data_t, 1);
edata->client = client;
+ g_object_ref(client);
edata->menuitem = mi;
g_object_ref(edata->menuitem);
edata->event = g_strdup(name);