diff options
author | Ken VanDine <ken.vandine@canonical.com> | 2011-02-24 22:42:58 -0500 |
---|---|---|
committer | Ken VanDine <ken.vandine@canonical.com> | 2011-02-24 22:42:58 -0500 |
commit | f40abc3f546c829edb4d059b2a4c1cfe1aa9eb81 (patch) | |
tree | 4d1246b94fd64432e727cc1c2e8b07cb531f4a14 /libdbusmenu-glib/client.c | |
parent | 5d4e1c63e3e0fc2bcce9e1217e6565b8d16a83b4 (diff) | |
parent | 9e20f80e0b1b0e804c6b9d37c8faaf719ace90ff (diff) | |
download | libdbusmenu-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.c | 161 |
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; +} + + |