aboutsummaryrefslogtreecommitdiff
path: root/libdbusmenu-glib/client.c
diff options
context:
space:
mode:
authorKen VanDine <ken.vandine@canonical.com>2011-02-24 22:42:58 -0500
committerKen VanDine <ken.vandine@canonical.com>2011-02-24 22:42:58 -0500
commitf40abc3f546c829edb4d059b2a4c1cfe1aa9eb81 (patch)
tree4d1246b94fd64432e727cc1c2e8b07cb531f4a14 /libdbusmenu-glib/client.c
parent5d4e1c63e3e0fc2bcce9e1217e6565b8d16a83b4 (diff)
parent9e20f80e0b1b0e804c6b9d37c8faaf719ace90ff (diff)
downloadlibdbusmenu-f40abc3f546c829edb4d059b2a4c1cfe1aa9eb81.tar.gz
libdbusmenu-f40abc3f546c829edb4d059b2a4c1cfe1aa9eb81.tar.bz2
libdbusmenu-f40abc3f546c829edb4d059b2a4c1cfe1aa9eb81.zip
* New upstream release.
* Add a signal on the menuitem for generic event support * Handle the case of a single NULL entry as well. * Not checking defaults when value is NULL * Add the 'type' variable first when processing new menuitems * Protection from unref'ing NULL variants * Only send the requested properties and request fewer * Add in a defaults database * Only send property updates if the menu item has been seen on the bus. * Add a property for text direction. * Add a property for needing attention. * Documentation fixes * Making menuitems track their own parents * Resolving property changes by looking at the properties directly.
Diffstat (limited to 'libdbusmenu-glib/client.c')
-rw-r--r--libdbusmenu-glib/client.c161
1 files changed, 156 insertions, 5 deletions
diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c
index 462dd64..d368a0e 100644
--- a/libdbusmenu-glib/client.c
+++ b/libdbusmenu-glib/client.c
@@ -33,12 +33,14 @@ License version 3 and version 2.1 along with this program. If not, see
#include <gio/gio.h>
#include "client.h"
+#include "client-private.h"
#include "menuitem.h"
#include "menuitem-private.h"
#include "client-menuitem.h"
#include "server-marshal.h"
#include "client-marshal.h"
#include "dbus-menu-clean.xml.h"
+#include "enum-types.h"
/* How many property requests should we queue before
sending the message on dbus */
@@ -48,7 +50,9 @@ License version 3 and version 2.1 along with this program. If not, see
enum {
PROP_0,
PROP_DBUSOBJECT,
- PROP_DBUSNAME
+ PROP_DBUSNAME,
+ PROP_STATUS,
+ PROP_TEXT_DIRECTION
};
/* Signals */
@@ -91,6 +95,9 @@ struct _DbusmenuClientPrivate
GArray * delayed_property_list;
GArray * delayed_property_listeners;
gint delayed_idle;
+
+ DbusmenuTextDirection text_direction;
+ DbusmenuStatus status;
};
typedef struct _newItemPropData newItemPropData;
@@ -158,6 +165,7 @@ static void get_properties_globber (DbusmenuClient * client, gint id, const gcha
static GQuark error_domain (void);
static void item_activated (GDBusProxy * proxy, gint id, guint timestamp, DbusmenuClient * client);
static void menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data);
+static void menuproxy_prop_changed_cb (GDBusProxy * proxy, GVariant * properties, GStrv invalidated, gpointer user_data);
static void menuproxy_name_changed_cb (GObject * object, GParamSpec * pspec, gpointer user_data);
static void menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVariant * params, gpointer user_data);
static void type_handler_destroy (gpointer user_data);
@@ -275,6 +283,16 @@ dbusmenu_client_class_init (DbusmenuClientClass *klass)
"Name of the DBus client we're connecting to.",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_STATUS,
+ g_param_spec_enum(DBUSMENU_CLIENT_PROP_STATUS, "Status of viewing the menus",
+ "Whether the menus should be given special visuals",
+ DBUSMENU_TYPE_STATUS, DBUSMENU_STATUS_NORMAL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_TEXT_DIRECTION,
+ g_param_spec_enum(DBUSMENU_CLIENT_PROP_TEXT_DIRECTION, "Direction text values have",
+ "Signals which direction the default text direction is for the menus",
+ DBUSMENU_TYPE_TEXT_DIRECTION, DBUSMENU_TEXT_DIRECTION_NONE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
if (dbusmenu_node_info == NULL) {
GError * error = NULL;
@@ -317,11 +335,13 @@ dbusmenu_client_init (DbusmenuClient *self)
priv->layoutcall = NULL;
- gchar * layout_props[3];
+ gchar * layout_props[5];
layout_props[0] = DBUSMENU_MENUITEM_PROP_TYPE;
layout_props[1] = DBUSMENU_MENUITEM_PROP_LABEL;
- layout_props[2] = NULL;
- priv->layout_props = g_variant_new_strv((const gchar * const *)layout_props, 2);
+ 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);
g_variant_ref_sink(priv->layout_props);
priv->current_revision = 0;
@@ -336,6 +356,9 @@ dbusmenu_client_init (DbusmenuClient *self)
priv->delayed_property_list = g_array_new(TRUE, FALSE, sizeof(gchar *));
priv->delayed_property_listeners = g_array_new(FALSE, FALSE, sizeof(properties_listener_t));
+ priv->text_direction = DBUSMENU_TEXT_DIRECTION_NONE;
+ priv->status = DBUSMENU_STATUS_NORMAL;
+
return;
}
@@ -485,6 +508,12 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec)
case PROP_DBUSOBJECT:
g_value_set_string(value, priv->dbus_object);
break;
+ case PROP_STATUS:
+ g_value_set_enum(value, priv->status);
+ break;
+ case PROP_TEXT_DIRECTION:
+ g_value_set_enum(value, priv->text_direction);
+ break;
default:
g_warning("Unknown property %d.", id);
return;
@@ -996,6 +1025,19 @@ menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data)
priv->menuproxy_cancel = NULL;
}
+ /* Check the text direction if available */
+ GVariant * textdir = g_dbus_proxy_get_cached_property(priv->menuproxy, "text-direction");
+ if (textdir != NULL) {
+ GVariant * str = textdir;
+ if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) {
+ str = g_variant_get_variant(str);
+ }
+
+ priv->text_direction = dbusmenu_text_direction_get_value_from_nick(g_variant_get_string(str, NULL));
+
+ g_variant_unref(textdir);
+ }
+
/* If we get here, we don't need the DBus proxy */
if (priv->dbusproxy != 0) {
g_bus_unwatch_name(priv->dbusproxy);
@@ -1004,6 +1046,7 @@ menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data)
g_signal_connect(priv->menuproxy, "g-signal", G_CALLBACK(menuproxy_signal_cb), client);
g_signal_connect(priv->menuproxy, "notify::g-name-owner", G_CALLBACK(menuproxy_name_changed_cb), client);
+ g_signal_connect(priv->menuproxy, "g-properties-changed", G_CALLBACK(menuproxy_prop_changed_cb), client);
gchar * name_owner = g_dbus_proxy_get_name_owner(priv->menuproxy);
if (name_owner != NULL) {
@@ -1014,6 +1057,63 @@ menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data)
return;
}
+/* Handle the properites changing */
+static void
+menuproxy_prop_changed_cb (GDBusProxy * proxy, GVariant * properties, GStrv invalidated, gpointer user_data)
+{
+ DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(user_data);
+ DbusmenuTextDirection olddir = priv->text_direction;
+ DbusmenuStatus oldstatus = priv->status;
+
+ /* Invalidate first */
+ gchar * invalid;
+ gint i = 0;
+ for (invalid = invalidated[i]; invalid != NULL; invalid = invalidated[++i]) {
+ if (g_strcmp0(invalid, "text-direction") == 0) {
+ priv->text_direction = DBUSMENU_TEXT_DIRECTION_NONE;
+ }
+ if (g_strcmp0(invalid, "status") == 0) {
+ priv->status = DBUSMENU_STATUS_NORMAL;
+ }
+ }
+
+ /* Check updates */
+ GVariantIter iters;
+ gchar * key; GVariant * value;
+ g_variant_iter_init(&iters, properties);
+ while (g_variant_iter_next(&iters, "{sv}", &key, &value)) {
+ if (g_strcmp0(key, "text-direction") == 0) {
+ GVariant * str = value;
+ if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) {
+ str = g_variant_get_variant(str);
+ }
+
+ priv->text_direction = dbusmenu_text_direction_get_value_from_nick(g_variant_get_string(str, NULL));
+ }
+ if (g_strcmp0(key, "status") == 0) {
+ GVariant * str = value;
+ if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) {
+ str = g_variant_get_variant(str);
+ }
+
+ priv->status = dbusmenu_status_get_value_from_nick(g_variant_get_string(str, NULL));
+ }
+
+ g_variant_unref(value);
+ g_free(key);
+ }
+
+ if (olddir != priv->text_direction) {
+ g_object_notify(G_OBJECT(user_data), DBUSMENU_CLIENT_PROP_TEXT_DIRECTION);
+ }
+
+ if (oldstatus != priv->status) {
+ g_object_notify(G_OBJECT(user_data), DBUSMENU_CLIENT_PROP_STATUS);
+ }
+
+ return;
+}
+
/* Handle the case where we change owners */
static void
menuproxy_name_changed_cb (GObject * object, GParamSpec * pspec, gpointer user_data)
@@ -1490,10 +1590,22 @@ parse_layout_xml(DbusmenuClient * client, GVariant * layout, DbusmenuMenuitem *
menu item. Sometimes they may just be copies */
if (childmi != NULL) {
GVariantIter iter;
- g_variant_iter_init(&iter, g_variant_get_child_value(child, 1));
gchar * prop;
GVariant * value;
+ /* Set the type first as it can manage the behavior of
+ all other properties. */
+ g_variant_iter_init(&iter, g_variant_get_child_value(child, 1));
+ while (g_variant_iter_next(&iter, "{sv}", &prop, &value)) {
+ if (g_strcmp0(prop, DBUSMENU_MENUITEM_PROP_TYPE) == 0) {
+ dbusmenu_menuitem_property_set_variant(childmi, prop, value);
+ }
+ g_free(prop);
+ g_variant_unref(value);
+ }
+
+ /* Now go through and do all the properties. */
+ g_variant_iter_init(&iter, g_variant_get_child_value(child, 1));
while (g_variant_iter_next(&iter, "{sv}", &prop, &value)) {
dbusmenu_menuitem_property_set_variant(childmi, prop, value);
g_free(prop);
@@ -1862,3 +1974,42 @@ dbusmenu_client_add_type_handler_full (DbusmenuClient * client, const gchar * ty
return TRUE;
}
+/**
+ dbusmenu_client_get_text_direction:
+ @client: #DbusmenuClient to check the text direction on
+
+ Gets the text direction that the server is exporting. If
+ the server is not exporting a direction then the value
+ #DBUSMENU_TEXT_DIRECTION_NONE will be returned.
+
+ Return value: Text direction being exported.
+*/
+DbusmenuTextDirection
+dbusmenu_client_get_text_direction (DbusmenuClient * client)
+{
+ g_return_val_if_fail(DBUSMENU_IS_CLIENT(client), DBUSMENU_TEXT_DIRECTION_NONE);
+ DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
+ return priv->text_direction;
+}
+
+/**
+ dbusmenu_client_get_status:
+ @client: #DbusmenuClient to check the status on
+
+ Gets the recommended current status that the server
+ is exporting for the menus. In situtations where the
+ value is #DBUSMENU_STATUS_NOTICE it is recommended that
+ the client show the menus to the user an a more noticible
+ way.
+
+ Return value: Status being exported.
+*/
+DbusmenuStatus
+dbusmenu_client_get_status (DbusmenuClient * client)
+{
+ g_return_val_if_fail(DBUSMENU_IS_CLIENT(client), DBUSMENU_STATUS_NORMAL);
+ DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
+ return priv->status;
+}
+
+