aboutsummaryrefslogtreecommitdiff
path: root/libdbusmenu-glib
diff options
context:
space:
mode:
Diffstat (limited to 'libdbusmenu-glib')
-rw-r--r--libdbusmenu-glib/Makefile.am23
-rw-r--r--libdbusmenu-glib/client-marshal.list1
-rw-r--r--libdbusmenu-glib/client-menuitem.c5
-rw-r--r--libdbusmenu-glib/client-menuitem.h12
-rw-r--r--libdbusmenu-glib/client-private.h48
-rw-r--r--libdbusmenu-glib/client.c183
-rw-r--r--libdbusmenu-glib/client.h89
-rw-r--r--libdbusmenu-glib/dbus-menu.xml22
-rw-r--r--libdbusmenu-glib/defaults.c8
-rw-r--r--libdbusmenu-glib/defaults.h4
-rw-r--r--libdbusmenu-glib/enum-types.c.in116
-rw-r--r--libdbusmenu-glib/enum-types.h.in62
-rw-r--r--libdbusmenu-glib/menuitem-private.h1
-rw-r--r--libdbusmenu-glib/menuitem-proxy.h14
-rw-r--r--libdbusmenu-glib/menuitem.c94
-rw-r--r--libdbusmenu-glib/menuitem.h195
-rw-r--r--libdbusmenu-glib/server.c260
-rw-r--r--libdbusmenu-glib/server.h72
-rw-r--r--libdbusmenu-glib/types.h76
19 files changed, 1205 insertions, 80 deletions
diff --git a/libdbusmenu-glib/Makefile.am b/libdbusmenu-glib/Makefile.am
index 5ddbeb8..8b523aa 100644
--- a/libdbusmenu-glib/Makefile.am
+++ b/libdbusmenu-glib/Makefile.am
@@ -1,6 +1,7 @@
-CLEANFILES =
-
+BUILT_SOURCES =
+CLEANFILES =
+DISTCLEANFILES =
EXTRA_DIST = \
clean-namespaces.xslt \
dbusmenu-glib-0.4.pc.in \
@@ -9,6 +10,8 @@ EXTRA_DIST = \
menuitem-marshal.list \
server-marshal.list
+include $(top_srcdir)/Makefile.am.enum
+
lib_LTLIBRARIES = \
libdbusmenu-glib.la
@@ -19,13 +22,16 @@ libdbusmenu_glibinclude_HEADERS = \
menuitem.h \
menuitem-proxy.h \
server.h \
- client.h
+ client.h \
+ types.h
libdbusmenu_glib_la_SOURCES = \
dbus-menu-clean.xml.h \
dbus-menu-clean.xml.c \
defaults.h \
defaults.c \
+ enum-types.h \
+ enum-types.c \
menuitem.h \
menuitem.c \
menuitem-marshal.h \
@@ -41,6 +47,7 @@ libdbusmenu_glib_la_SOURCES = \
client-marshal.c \
client-menuitem.h \
client-menuitem.c \
+ client-private.h \
client.h \
client.c
@@ -58,6 +65,14 @@ libdbusmenu_glib_la_LIBADD = \
pkgconfig_DATA = dbusmenu-glib-0.4.pc
pkgconfigdir = $(libdir)/pkgconfig
+glib_enum_h = enum-types.h
+glib_enum_c = enum-types.c
+glib_enum_headers = $(addprefix $(srcdir)/, $(libdbusmenu_glibinclude_HEADERS))
+
+DISTCLEANFILES += \
+ enum-types.c \
+ enum-types.h
+
%.xml.h: %.xml
echo "extern const char * $(subst -,_,$(subst .,_,$(basename $(notdir $@))));" > $@
@@ -71,7 +86,7 @@ dbus-menu-clean.xml: dbus-menu.xml
CLEANFILES += dbus-menu-clean.xml
-BUILT_SOURCES = \
+BUILT_SOURCES += \
dbus-menu-clean.xml.c \
dbus-menu-clean.xml.h \
client-marshal.h \
diff --git a/libdbusmenu-glib/client-marshal.list b/libdbusmenu-glib/client-marshal.list
index 866dfa8..96f9302 100644
--- a/libdbusmenu-glib/client-marshal.list
+++ b/libdbusmenu-glib/client-marshal.list
@@ -1,2 +1,3 @@
VOID: OBJECT, UINT
VOID: OBJECT, STRING, VARIANT, UINT, POINTER
+VOID: ENUM
diff --git a/libdbusmenu-glib/client-menuitem.c b/libdbusmenu-glib/client-menuitem.c
index 0f14b85..60f8637 100644
--- a/libdbusmenu-glib/client-menuitem.c
+++ b/libdbusmenu-glib/client-menuitem.c
@@ -30,6 +30,7 @@ License version 3 and version 2.1 along with this program. If not, see
#endif
#include "client-menuitem.h"
+#include "client-private.h"
typedef struct _DbusmenuClientMenuitemPrivate DbusmenuClientMenuitemPrivate;
@@ -39,7 +40,7 @@ struct _DbusmenuClientMenuitemPrivate
};
#define DBUSMENU_CLIENT_MENUITEM_GET_PRIVATE(o) \
-(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_CLIENT_MENUITEM_TYPE, DbusmenuClientMenuitemPrivate))
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), DBUSMENU_TYPE_CLIENT_MENUITEM, DbusmenuClientMenuitemPrivate))
static void dbusmenu_client_menuitem_class_init (DbusmenuClientMenuitemClass *klass);
static void dbusmenu_client_menuitem_init (DbusmenuClientMenuitem *self);
@@ -94,7 +95,7 @@ dbusmenu_client_menuitem_finalize (GObject *object)
DbusmenuClientMenuitem *
dbusmenu_client_menuitem_new (gint id, DbusmenuClient * client)
{
- DbusmenuClientMenuitem * mi = g_object_new(DBUSMENU_CLIENT_MENUITEM_TYPE, "id", id, NULL);
+ DbusmenuClientMenuitem * mi = g_object_new(DBUSMENU_TYPE_CLIENT_MENUITEM, "id", id, NULL);
DbusmenuClientMenuitemPrivate * priv = DBUSMENU_CLIENT_MENUITEM_GET_PRIVATE(mi);
priv->client = client;
return mi;
diff --git a/libdbusmenu-glib/client-menuitem.h b/libdbusmenu-glib/client-menuitem.h
index ef61213..a89cb11 100644
--- a/libdbusmenu-glib/client-menuitem.h
+++ b/libdbusmenu-glib/client-menuitem.h
@@ -35,12 +35,12 @@ License version 3 and version 2.1 along with this program. If not, see
G_BEGIN_DECLS
-#define DBUSMENU_CLIENT_MENUITEM_TYPE (dbusmenu_client_menuitem_get_type ())
-#define DBUSMENU_CLIENT_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DBUSMENU_CLIENT_MENUITEM_TYPE, DbusmenuClientMenuitem))
-#define DBUSMENU_CLIENT_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DBUSMENU_CLIENT_MENUITEM_TYPE, DbusmenuClientMenuitemClass))
-#define DBUSMENU_IS_CLIENT_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DBUSMENU_CLIENT_MENUITEM_TYPE))
-#define DBUSMENU_IS_CLIENT_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_CLIENT_MENUITEM_TYPE))
-#define DBUSMENU_CLIENT_MENUITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_CLIENT_MENUITEM_TYPE, DbusmenuClientMenuitemClass))
+#define DBUSMENU_TYPE_CLIENT_MENUITEM (dbusmenu_client_menuitem_get_type ())
+#define DBUSMENU_CLIENT_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DBUSMENU_TYPE_CLIENT_MENUITEM, DbusmenuClientMenuitem))
+#define DBUSMENU_CLIENT_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DBUSMENU_TYPE_CLIENT_MENUITEM, DbusmenuClientMenuitemClass))
+#define DBUSMENU_IS_CLIENT_MENUITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DBUSMENU_TYPE_CLIENT_MENUITEM))
+#define DBUSMENU_IS_CLIENT_MENUITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_TYPE_CLIENT_MENUITEM))
+#define DBUSMENU_CLIENT_MENUITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_TYPE_CLIENT_MENUITEM, DbusmenuClientMenuitemClass))
typedef struct _DbusmenuClientMenuitem DbusmenuClientMenuitem;
typedef struct _DbusmenuClientMenuitemClass DbusmenuClientMenuitemClass;
diff --git a/libdbusmenu-glib/client-private.h b/libdbusmenu-glib/client-private.h
new file mode 100644
index 0000000..f6df372
--- /dev/null
+++ b/libdbusmenu-glib/client-private.h
@@ -0,0 +1,48 @@
+/*
+A library to communicate a menu object set accross DBus and
+track updates and maintain consistency.
+
+Copyright 2011 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of either or both of the following licenses:
+
+1) the GNU Lesser General Public License version 3, as published by the
+Free Software Foundation; and/or
+2) the GNU Lesser General Public License version 2.1, as published by
+the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the applicable version of the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of both the GNU Lesser General Public
+License version 3 and version 2.1 along with this program. If not, see
+<http://www.gnu.org/licenses/>
+*/
+
+#ifndef __DBUSMENU_CLIENT_PRIVATE_H__
+#define __DBUSMENU_CLIENT_PRIVATE_H__
+
+#include "client.h"
+
+G_BEGIN_DECLS
+
+void dbusmenu_client_send_event (DbusmenuClient * client,
+ gint id,
+ const gchar * name,
+ GVariant * variant,
+ guint timestamp);
+void dbusmenu_client_send_about_to_show(DbusmenuClient * client,
+ gint id,
+ void (*cb) (gpointer user_data),
+ gpointer cb_data);
+
+G_END_DECLS
+
+#endif
diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c
index 0848294..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 */
@@ -79,6 +83,7 @@ struct _DbusmenuClientPrivate
GCancellable * menuproxy_cancel;
GCancellable * layoutcall;
+ GVariant * layout_props;
gint current_revision;
gint my_revision;
@@ -90,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;
@@ -157,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);
@@ -274,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;
@@ -316,6 +335,15 @@ dbusmenu_client_init (DbusmenuClient *self)
priv->layoutcall = NULL;
+ gchar * layout_props[5];
+ 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);
+ g_variant_ref_sink(priv->layout_props);
+
priv->current_revision = 0;
priv->my_revision = 0;
@@ -328,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;
}
@@ -380,6 +411,11 @@ dbusmenu_client_dispose (GObject *object)
priv->layoutcall = NULL;
}
+ if (priv->layout_props != NULL) {
+ g_variant_unref(priv->layout_props);
+ priv->layout_props = NULL;
+ }
+
/* Bring down the menu proxy, ensure we're not
looking for one at the same time. */
if (priv->menuproxy_cancel != NULL) {
@@ -472,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;
@@ -983,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);
@@ -991,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) {
@@ -1001,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)
@@ -1473,6 +1586,33 @@ parse_layout_xml(DbusmenuClient * client, GVariant * layout, DbusmenuMenuitem *
parse_layout_update(childmi, client);
}
+ /* Apply known properties sent in the structure to the
+ menu item. Sometimes they may just be copies */
+ if (childmi != NULL) {
+ GVariantIter iter;
+ 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);
+ g_variant_unref(value);
+ }
+ }
+
position++;
}
@@ -1662,7 +1802,7 @@ update_layout (DbusmenuClient * client)
g_variant_builder_add_value(&tupleb, g_variant_new_int32(0)); // root
g_variant_builder_add_value(&tupleb, g_variant_new_int32(-1)); // recurse
- g_variant_builder_add_value(&tupleb, g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0)); // props
+ g_variant_builder_add_value(&tupleb, priv->layout_props); // props
GVariant * args = g_variant_builder_end(&tupleb);
// g_debug("Args (type: %s): %s", g_variant_get_type_string(args), g_variant_print(args, TRUE));
@@ -1834,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;
+}
+
+
diff --git a/libdbusmenu-glib/client.h b/libdbusmenu-glib/client.h
index 79c0ee2..28d4dd3 100644
--- a/libdbusmenu-glib/client.h
+++ b/libdbusmenu-glib/client.h
@@ -33,6 +33,7 @@ License version 3 and version 2.1 along with this program. If not, see
#include <glib-object.h>
#include "menuitem.h"
+#include "types.h"
G_BEGIN_DECLS
@@ -43,17 +44,89 @@ G_BEGIN_DECLS
#define DBUSMENU_IS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_TYPE_CLIENT))
#define DBUSMENU_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_TYPE_CLIENT, DbusmenuClientClass))
+/**
+ * DBUSMENU_CLIENT_SIGNAL_LAYOUT_UPDATED:
+ *
+ * String to attach to signal #DbusmenuClient::layout-updated
+ */
#define DBUSMENU_CLIENT_SIGNAL_LAYOUT_UPDATED "layout-updated"
+/**
+ * DBUSMENU_CLIENT_SIGNAL_ROOT_CHANGED:
+ *
+ * String to attach to signal #DbusmenuClient::root-changed
+ */
#define DBUSMENU_CLIENT_SIGNAL_ROOT_CHANGED "root-changed"
+/**
+ * DBUSMENU_CLIENT_SIGNAL_NEW_MENUITEM:
+ *
+ * String to attach to signal #DbusmenuClient::new-menuitem
+ */
#define DBUSMENU_CLIENT_SIGNAL_NEW_MENUITEM "new-menuitem"
+/**
+ * DBUSMENU_CLIENT_SIGNAL_ITEM_ACTIVATE:
+ *
+ * String to attach to signal #DbusmenuClient::item-activate
+ */
#define DBUSMENU_CLIENT_SIGNAL_ITEM_ACTIVATE "item-activate"
+/**
+ * DBUSMENU_CLIENT_SIGNAL_EVENT_RESULT:
+ *
+ * String to attach to signal #DbusmenuClient::event-result
+ */
#define DBUSMENU_CLIENT_SIGNAL_EVENT_RESULT "event-result"
+/**
+ * DBUSMENU_CLIENT_SIGNAL_TEXT_DIRECTION_CHANGED:
+ *
+ * String to attach to signal #DbusmenuClient::text-direction-changed
+ */
+#define DBUSMENU_CLIENT_SIGNAL_TEXT_DIRECTION_CHANGED "text-direction-changed"
+/**
+ * DBUSMENU_CLIENT_PROP_DBUS_NAME:
+ *
+ * String to access property #DbusmenuClient:dbus-name
+ */
#define DBUSMENU_CLIENT_PROP_DBUS_NAME "dbus-name"
+/**
+ * DBUSMENU_CLIENT_PROP_DBUS_OBJECT:
+ *
+ * String to access property #DbusmenuClient:dbus-object
+ */
#define DBUSMENU_CLIENT_PROP_DBUS_OBJECT "dbus-object"
+/**
+ * DBUSMENU_CLIENT_PROP_STATUS:
+ *
+ * String to access property #DbusmenuClient:status
+ */
+#define DBUSMENU_CLIENT_PROP_STATUS "status"
+/**
+ * DBUSMENU_CLIENT_PROP_TEXT_DIRECTION:
+ *
+ * String to access property #DbusmenuClient:text-direction
+ */
+#define DBUSMENU_CLIENT_PROP_TEXT_DIRECTION "text-direction"
+/**
+ * DBUSMENU_CLIENT_TYPES_DEFAULT:
+ *
+ * Used to set the 'type' property on a menu item to create
+ * a standard menu item.
+ */
#define DBUSMENU_CLIENT_TYPES_DEFAULT "standard"
+/**
+ * DBUSMENU_CLIENT_TYPES_SEPARATOR:
+ *
+ * Used to set the 'type' property on a menu item to create
+ * a separator menu item.
+ */
#define DBUSMENU_CLIENT_TYPES_SEPARATOR "separator"
+/**
+ * DBUSMENU_CLIENT_TYPES_IMAGE:
+ *
+ * Used to set the 'type' property on a menu item to create
+ * an image menu item. Deprecated as standard menu items now
+ * support images as well.
+ */
#define DBUSMENU_CLIENT_TYPES_IMAGE "standard"
typedef struct _DbusmenuClientPrivate DbusmenuClientPrivate;
@@ -62,6 +135,7 @@ typedef struct _DbusmenuClientPrivate DbusmenuClientPrivate;
DbusmenuClientClass:
@parent_class: #GObjectClass
@layout_updated: Slot for #DbusmenuClient::layout-updated.
+ @root_changed: Slot for #DbusmenuClient::root-changed.
@new_menuitem: Slot for #DbusmenuClient::new-menuitem.
@item_activate: Slot for #DbusmenuClient::item-activate.
@event_result: Slot for #DbusmenuClient::event-error.
@@ -97,7 +171,6 @@ struct _DbusmenuClientClass {
/**
DbusmenuClient:
- @parent: #GObject.
The client for a #DbusmenuServer creating a shared
object set of #DbusmenuMenuitem objects.
@@ -119,6 +192,9 @@ struct _DbusmenuClient {
The type handler is called when a dbusmenu item is created
with a matching type as setup in #dbusmenu_client_add_type_handler
+
+ Return value: #TRUE if the type has been handled. #FALSE if this
+ function was somehow unable to handle it.
*/
typedef gboolean (*DbusmenuClientTypeHandler) (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data);
@@ -146,15 +222,8 @@ gboolean dbusmenu_client_add_type_handler_full (DbusmenuClient * cli
DbusmenuClientTypeHandler newfunc,
gpointer user_data,
DbusmenuClientTypeDestroyHandler destroy_func);
-void dbusmenu_client_send_event (DbusmenuClient * client,
- gint id,
- const gchar * name,
- GVariant * variant,
- guint timestamp);
-void dbusmenu_client_send_about_to_show(DbusmenuClient * client,
- gint id,
- void (*cb) (gpointer user_data),
- gpointer cb_data);
+DbusmenuTextDirection dbusmenu_client_get_text_direction (DbusmenuClient * client);
+DbusmenuStatus dbusmenu_client_get_status (DbusmenuClient * client);
/**
SECTION:client
diff --git a/libdbusmenu-glib/dbus-menu.xml b/libdbusmenu-glib/dbus-menu.xml
index da14c63..829c16e 100644
--- a/libdbusmenu-glib/dbus-menu.xml
+++ b/libdbusmenu-glib/dbus-menu.xml
@@ -171,6 +171,24 @@ License version 3 and version 2.1 along with this program. If not, see
</dox:d>
</property>
+ <property name="text-direction" type="s" access="read">
+ <dox:d>
+ Represents the way the text direction of the application. This
+ allows the server to handle mismatches intelligently. For left-
+ to-right the string is "ltr" for right-to-left it is "rtl".
+ </dox:d>
+ </property>
+
+ <property name="state" type="s" access="read">
+ <dox:d>
+ Tells if the menus are in a normal state or they believe that they
+ could use some attention. Cases for showing them would be if help
+ were referring to them or they accessors were being highlighted.
+ This property can have two values: "normal" in almost all cases and
+ "notice" when they should have a higher priority to be shown.
+ </dox:d>
+ </property>
+
<!-- Functions -->
<method name="GetLayout">
@@ -308,8 +326,8 @@ License version 3 and version 2.1 along with this program. If not, see
the ID of the item with a hashtable of names and values for those
properties.
</dox:d>
- <arg type="a(ia(sv))" name="props" direction="out" />
- <arg type="a(ia(s))" name="props_removed" direction="out" />
+ <arg type="a(ia{sv})" name="updatedProps" direction="out" />
+ <arg type="a(ias)" name="removedProps" direction="out" />
</signal>
<signal name="LayoutUpdated">
<dox:d>
diff --git a/libdbusmenu-glib/defaults.c b/libdbusmenu-glib/defaults.c
index 3ad5d76..c05ef38 100644
--- a/libdbusmenu-glib/defaults.c
+++ b/libdbusmenu-glib/defaults.c
@@ -156,7 +156,7 @@ entry_destroy (gpointer entry)
static DbusmenuDefaults * default_defaults = NULL;
-/**
+/*
* dbusmenu_defaults_ref_default:
*
* Get a reference to the default instance. If it doesn't exist this
@@ -177,7 +177,7 @@ dbusmenu_defaults_ref_default (void)
return default_defaults;
}
-/**
+/*
* dbusmenu_defaults_default_set:
* @defaults: The #DbusmenuDefaults object to add to
* @type: (allow-none): The #DbusmenuMenuitem type for this default if #NULL will default to #DBUSMENU_CLIENT_TYPE_DEFAULT
@@ -216,7 +216,7 @@ dbusmenu_defaults_default_set (DbusmenuDefaults * defaults, const gchar * type,
return;
}
-/**
+/*
* dbusmenu_defaults_default_get:
* @defaults: The default database to use
* @type: (allow-none): The #DbusmenuMenuitem type for this default if #NULL will default to #DBUSMENU_CLIENT_TYPE_DEFAULT
@@ -253,7 +253,7 @@ dbusmenu_defaults_default_get (DbusmenuDefaults * defaults, const gchar * type,
return entry->value;
}
-/**
+/*
* dbusmenu_defaults_default_get_type:
* @defaults: The default database to use
* @type: (allow-none): The #DbusmenuMenuitem type for this default if #NULL will default to #DBUSMENU_CLIENT_TYPE_DEFAULT
diff --git a/libdbusmenu-glib/defaults.h b/libdbusmenu-glib/defaults.h
index ab377f7..a1a8158 100644
--- a/libdbusmenu-glib/defaults.h
+++ b/libdbusmenu-glib/defaults.h
@@ -45,7 +45,7 @@ typedef struct _DbusmenuDefaults DbusmenuDefaults;
typedef struct _DbusmenuDefaultsClass DbusmenuDefaultsClass;
typedef struct _DbusmenuDefaultsPrivate DbusmenuDefaultsPrivate;
-/**
+/*
* DbusmenuDefaultsClass:
*
* All of the signals and functions for #DbusmenuDefaults
@@ -54,7 +54,7 @@ struct _DbusmenuDefaultsClass {
GObjectClass parent_class;
};
-/**
+/*
* DbusmenuDefaults:
*
* A singleton to hold all of the defaults for the menuitems
diff --git a/libdbusmenu-glib/enum-types.c.in b/libdbusmenu-glib/enum-types.c.in
new file mode 100644
index 0000000..9395f5f
--- /dev/null
+++ b/libdbusmenu-glib/enum-types.c.in
@@ -0,0 +1,116 @@
+/*** BEGIN file-header ***/
+/*
+Enums from the dbusmenu headers
+
+Copyright 2011 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of either or both of the following licenses:
+
+1) the GNU Lesser General Public License version 3, as published by the
+ Free Software Foundation; and/or
+2) the GNU Lesser General Public License version 2.1, as published by
+ the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the applicable version of the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of both the GNU Lesser General Public
+License version 3 and version 2.1 along with this program. If not, see
+<http://www.gnu.org/licenses/>
+*/
+
+#include "enum-types.h"
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+#include "@filename@"
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+/**
+ @enum_name@_get_type:
+
+ Builds a GLib type for the #@EnumName@ enumeration.
+
+ Return value: A unique #GType for the #@EnumName@ enum.
+*/
+GType
+@enum_name@_get_type (void)
+{
+ static GType etype = 0;
+ if (G_UNLIKELY(etype == 0)) {
+ static const G@Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL}
+ };
+
+ etype = g_@type@_register_static (g_intern_static_string("@EnumName@"), values);
+ }
+
+ return etype;
+}
+
+/**
+ @enum_name@_get_nick:
+ @value: The value of @EnumName@ to get the nick of
+
+ Looks up in the enum table for the nick of @value.
+
+ Return value: The nick for the given value or #NULL on error
+*/
+const gchar *
+@enum_name@_get_nick (@EnumName@ value)
+{
+ GEnumClass * class = G_ENUM_CLASS(g_type_class_ref(@enum_name@_get_type()));
+ g_return_val_if_fail(class != NULL, NULL);
+
+ const gchar * ret = NULL;
+ GEnumValue * val = g_enum_get_value(class, value);
+ if (val != NULL) {
+ ret = val->value_nick;
+ }
+
+ g_type_class_unref(class);
+ return ret;
+}
+
+/**
+ @enum_name@_get_value_from_nick:
+ @nick: The enum nick to lookup
+
+ Looks up in the enum table for the value of @nick.
+
+ Return value: The value for the given @nick
+*/
+@EnumName@
+@enum_name@_get_value_from_nick (const gchar * nick)
+{
+ GEnumClass * class = G_ENUM_CLASS(g_type_class_ref(@enum_name@_get_type()));
+ g_return_val_if_fail(class != NULL, 0);
+
+ @EnumName@ ret = 0;
+ GEnumValue * val = g_enum_get_value_by_nick(class, nick);
+ if (val != NULL) {
+ ret = val->value;
+ }
+
+ g_type_class_unref(class);
+ return ret;
+}
+
+
+/*** END value-tail ***/
diff --git a/libdbusmenu-glib/enum-types.h.in b/libdbusmenu-glib/enum-types.h.in
new file mode 100644
index 0000000..488b615
--- /dev/null
+++ b/libdbusmenu-glib/enum-types.h.in
@@ -0,0 +1,62 @@
+/*** BEGIN file-header ***/
+/*
+Enums from the dbusmenu headers
+
+Copyright 2011 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of either or both of the following licenses:
+
+1) the GNU Lesser General Public License version 3, as published by the
+ Free Software Foundation; and/or
+2) the GNU Lesser General Public License version 2.1, as published by
+ the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the applicable version of the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of both the GNU Lesser General Public
+License version 3 and version 2.1 along with this program. If not, see
+<http://www.gnu.org/licenses/>
+*/
+
+#ifndef __DBUSMENU_ENUM_TYPES_H__
+#define __DBUSMENU_ENUM_TYPES_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/*** END file-header ***/
+
+/*** BEGIN file-tail ***/
+
+G_END_DECLS
+
+#endif /* __DBUSMENU_ENUM_TYPES_H__ */
+/*** END file-tail ***/
+
+/*** BEGIN file-production ***/
+/* Enumerations from file: "@filename@" */
+#include "@filename@"
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type (void) G_GNUC_CONST;
+const gchar * @enum_name@_get_nick (@EnumName@ value) G_GNUC_CONST;
+@EnumName@ @enum_name@_get_value_from_nick (const gchar * nick) G_GNUC_CONST;
+/**
+ DBUSMENU_TYPE_@ENUMSHORT@:
+
+ Gets the #GType value for the type associated with the
+ #@EnumName@ enumerated type.
+*/
+#define DBUSMENU_TYPE_@ENUMSHORT@ (@enum_name@_get_type())
+
+/*** END value-header ***/
diff --git a/libdbusmenu-glib/menuitem-private.h b/libdbusmenu-glib/menuitem-private.h
index 89319dc..336769d 100644
--- a/libdbusmenu-glib/menuitem-private.h
+++ b/libdbusmenu-glib/menuitem-private.h
@@ -38,6 +38,7 @@ 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);
+gboolean dbusmenu_menuitem_exposed (DbusmenuMenuitem * mi);
G_END_DECLS
diff --git a/libdbusmenu-glib/menuitem-proxy.h b/libdbusmenu-glib/menuitem-proxy.h
index 2a22efe..ee988d8 100644
--- a/libdbusmenu-glib/menuitem-proxy.h
+++ b/libdbusmenu-glib/menuitem-proxy.h
@@ -67,8 +67,7 @@ struct _DbusmenuMenuitemProxyClass {
};
/**
- DbusmeneMenuitemProxy:
- @parent: The instance of #DbusmenuMenuitem
+ DbusmenuMenuitemProxy:
Public instance data for a #DbusmenuMenuitemProxy.
*/
@@ -83,6 +82,17 @@ GType dbusmenu_menuitem_proxy_get_type (void);
DbusmenuMenuitemProxy * dbusmenu_menuitem_proxy_new (DbusmenuMenuitem * mi);
DbusmenuMenuitem * dbusmenu_menuitem_proxy_get_wrapped (DbusmenuMenuitemProxy * pmi);
+/**
+ * SECTION:menuitem-proxy
+ * @short_description: A menuitem that proxies from another menuitem
+ * @stability: Unstable
+ * @include: libdbusmenu-glib/menuitem-proxy.h
+ *
+ * This small object allows for proxying all the properties from a remote
+ * menuitem to a new object that can be moved around appropriately within
+ * the new menu structure.
+ */
+
G_END_DECLS
#endif
diff --git a/libdbusmenu-glib/menuitem.c b/libdbusmenu-glib/menuitem.c
index d420fd6..f0e3bfc 100644
--- a/libdbusmenu-glib/menuitem.c
+++ b/libdbusmenu-glib/menuitem.c
@@ -61,6 +61,7 @@ struct _DbusmenuMenuitemPrivate
gboolean root;
gboolean realized;
DbusmenuDefaults * defaults;
+ gboolean exposed;
};
/* Signals */
@@ -334,6 +335,7 @@ dbusmenu_menuitem_init (DbusmenuMenuitem *self)
priv->realized = FALSE;
priv->defaults = dbusmenu_defaults_ref_default();
+ priv->exposed = FALSE;
return;
}
@@ -1043,31 +1045,34 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro
g_return_val_if_fail(property != NULL, FALSE);
DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+ GVariant * default_value = NULL;
- const gchar * type = menuitem_get_type(mi);
-
- /* Check the expected type to see if we want to have a warning */
- GVariantType * default_type = dbusmenu_defaults_default_get_type(priv->defaults, type, property);
- if (default_type != NULL) {
- /* If we have an expected type we should check to see if
- the value we've been given is of the same type and generate
- a warning if it isn't */
- if (!g_variant_is_of_type(value, default_type)) {
- g_warning("Setting menuitem property '%s' with value of type '%s' when expecting '%s'", property, g_variant_get_type_string(value), g_variant_type_peek_string(default_type));
+ if (value != NULL) {
+ const gchar * type = menuitem_get_type(mi);
+
+ /* Check the expected type to see if we want to have a warning */
+ GVariantType * default_type = dbusmenu_defaults_default_get_type(priv->defaults, type, property);
+ if (default_type != NULL) {
+ /* If we have an expected type we should check to see if
+ the value we've been given is of the same type and generate
+ a warning if it isn't */
+ if (!g_variant_is_of_type(value, default_type)) {
+ g_warning("Setting menuitem property '%s' with value of type '%s' when expecting '%s'", property, g_variant_get_type_string(value), g_variant_type_peek_string(default_type));
+ }
}
- }
- /* Check the defaults database to see if we have a default
- for this property. */
- GVariant * default_value = dbusmenu_defaults_default_get(priv->defaults, type, property);
- if (default_value != NULL) {
- /* Now see if we're setting this to the same value as the
- default. If we are then we just want to swallow this variant
- and make the function behave like we're clearing it. */
- if (g_variant_equal(default_value, value)) {
- g_variant_ref_sink(value);
- g_variant_unref(value);
- value = NULL;
+ /* Check the defaults database to see if we have a default
+ for this property. */
+ default_value = dbusmenu_defaults_default_get(priv->defaults, type, property);
+ if (default_value != NULL) {
+ /* Now see if we're setting this to the same value as the
+ default. If we are then we just want to swallow this variant
+ and make the function behave like we're clearing it. */
+ if (g_variant_equal(default_value, value)) {
+ g_variant_ref_sink(value);
+ g_variant_unref(value);
+ value = NULL;
+ }
}
}
@@ -1228,7 +1233,7 @@ dbusmenu_menuitem_property_get_int (DbusmenuMenuitem * mi, const gchar * propert
/**
- * dbusmenu_menuitem_property_exit:
+ * dbusmenu_menuitem_property_exist:
* @mi: The #DbusmenuMenuitem to look for the property on.
* @property: The property to look for.
*
@@ -1361,7 +1366,7 @@ dbusmenu_menuitem_properties_variant (DbusmenuMenuitem * mi, const gchar ** prop
GVariant * final_variant = NULL;
- if (g_hash_table_size(priv->properties) > 0) {
+ if ((properties == NULL || properties[0] == NULL) && g_hash_table_size(priv->properties) > 0) {
GVariantBuilder builder;
g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
@@ -1370,6 +1375,33 @@ dbusmenu_menuitem_properties_variant (DbusmenuMenuitem * mi, const gchar ** prop
final_variant = g_variant_builder_end(&builder);
}
+ if (properties != NULL) {
+ GVariantBuilder builder;
+ gboolean builder_init = FALSE;
+ int i = 0; const gchar * prop;
+
+ for (prop = properties[i]; prop != NULL; prop = properties[++i]) {
+ GVariant * propvalue = dbusmenu_menuitem_property_get_variant(mi, prop);
+
+ if (propvalue == NULL) {
+ continue;
+ }
+
+ if (!builder_init) {
+ builder_init = TRUE;
+ g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+ }
+
+ GVariant * dict = g_variant_new_dict_entry(g_variant_new_string((gchar *)prop),
+ g_variant_new_variant((GVariant *)propvalue));
+ g_variant_builder_add_value(&builder, dict);
+ }
+
+ if (builder_init) {
+ final_variant = g_variant_builder_end(&builder);
+ }
+ }
+
return final_variant;
}
@@ -1427,6 +1459,8 @@ GVariant *
dbusmenu_menuitem_build_variant (DbusmenuMenuitem * mi, const gchar ** properties, gint recurse)
{
g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), NULL);
+ DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+ priv->exposed = TRUE;
gint id = 0;
if (!dbusmenu_menuitem_get_root(mi)) {
@@ -1451,7 +1485,7 @@ dbusmenu_menuitem_build_variant (DbusmenuMenuitem * mi, const gchar ** propertie
/* Pillage the children */
GList * children = dbusmenu_menuitem_get_children(mi);
- if (children == NULL && recurse != 0) {
+ if (children == NULL || recurse == 0) {
g_variant_builder_add_value(&tupleb, g_variant_new_array(G_VARIANT_TYPE_VARIANT, NULL, 0));
} else {
GVariantBuilder childrenbuilder;
@@ -1613,3 +1647,13 @@ dbusmenu_menuitem_property_is_default (DbusmenuMenuitem * mi, const gchar * prop
g_warn_if_reached();
return FALSE;
}
+
+/* Check to see if this menu item has been sent into the bus yet or
+ not. If no one cares we can give less info */
+gboolean
+dbusmenu_menuitem_exposed (DbusmenuMenuitem * mi)
+{
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
+ DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+ return priv->exposed;
+}
diff --git a/libdbusmenu-glib/menuitem.h b/libdbusmenu-glib/menuitem.h
index 35d7ca8..8174c30 100644
--- a/libdbusmenu-glib/menuitem.h
+++ b/libdbusmenu-glib/menuitem.h
@@ -42,48 +42,232 @@ G_BEGIN_DECLS
#define DBUSMENU_MENUITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_TYPE_MENUITEM, DbusmenuMenuitemClass))
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED:
+ *
+ * String to attach to signal #DbusmenuServer::property-changed
+ */
#define DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED "property-changed"
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED:
+ *
+ * String to attach to signal #DbusmenuServer::item-activated
+ */
#define DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED "item-activated"
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED:
+ *
+ * String to attach to signal #DbusmenuServer::child-added
+ */
#define DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED "child-added"
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED:
+ *
+ * String to attach to signal #DbusmenuServer::child-removed
+ */
#define DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED "child-removed"
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED:
+ *
+ * String to attach to signal #DbusmenuServer::child-moved
+ */
#define DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED "child-moved"
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_REALIZED:
+ *
+ * String to attach to signal #DbusmenuServer::realized
+ */
#define DBUSMENU_MENUITEM_SIGNAL_REALIZED "realized"
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_REALIZED_ID:
+ *
+ * ID to attach to signal #DbusmenuServer::realized
+ */
#define DBUSMENU_MENUITEM_SIGNAL_REALIZED_ID (g_signal_lookup(DBUSMENU_MENUITEM_SIGNAL_REALIZED, DBUSMENU_TYPE_MENUITEM))
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_SHOW_TO_USER:
+ *
+ * String to attach to signal #DbusmenuServer::show-to-user
+ */
#define DBUSMENU_MENUITEM_SIGNAL_SHOW_TO_USER "show-to-user"
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_ABOUT_TO_SHOW:
+ *
+ * String to attach to signal #DbusmenuServer::about-to-show
+ */
#define DBUSMENU_MENUITEM_SIGNAL_ABOUT_TO_SHOW "about-to-show"
#define DBUSMENU_MENUITEM_SIGNAL_EVENT "event"
+/**
+ * DBUSMENU_MENUITEM_PROP_TYPE:
+ *
+ * #DbusmenuMenuitem property used to represent what type of menuitem
+ * this object represents. Type: #G_VARIANT_TYPE_STRING.
+ */
#define DBUSMENU_MENUITEM_PROP_TYPE "type"
+/**
+ * DBUSMENU_MENUITEM_PROP_VISIBLE:
+ *
+ * #DbusmenuMenuitem property used to represent whether the menuitem
+ * should be shown or not. Type: #G_VARIANT_TYPE_BOOLEAN.
+ */
#define DBUSMENU_MENUITEM_PROP_VISIBLE "visible"
+/**
+ * DBUSMENU_MENUITEM_PROP_ENABLED:
+ *
+ * #DbusmenuMenuitem property used to represent whether the menuitem
+ * is clickable or not. Type: #G_VARIANT_TYPE_BOOLEAN.
+ */
#define DBUSMENU_MENUITEM_PROP_ENABLED "enabled"
+/**
+ * DBUSMENU_MENUITEM_PROP_LABEL:
+ *
+ * #DbusmenuMenuitem property used for the text on the menu item.
+ * Type: #G_VARIANT_TYPE_STRING
+ */
#define DBUSMENU_MENUITEM_PROP_LABEL "label"
+/**
+ * DBUSMENU_MENUITEM_PROP_ICON_NAME:
+ *
+ * #DbusmenuMenuitem property that is the name of the icon under the
+ * Freedesktop.org icon naming spec. Type: #G_VARIANT_TYPE_STRING
+ */
#define DBUSMENU_MENUITEM_PROP_ICON_NAME "icon-name"
+/**
+ * DBUSMENU_MENUITEM_PROP_ICON_DATA:
+ *
+ * #DbusmenuMenuitem property that is the raw data of a custom icon
+ * used in the application. Type: #G_VARIANT_TYPE_VARIANT
+ *
+ * It is recommended that this is not set directly but instead the
+ * libdbusmenu-gtk library is used with the function dbusmenu_menuitem_property_set_image()
+ */
#define DBUSMENU_MENUITEM_PROP_ICON_DATA "icon-data"
+/**
+ * DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE:
+ *
+ * #DbusmenuMenuitem property that says what type of toggle entry should
+ * be shown in the menu. Should be either #DBUSMENU_MENUITEM_TOGGLE_CHECK
+ * or #DBUSMENU_MENUITEM_TOGGLE_RADIO. Type: #G_VARIANT_TYPE_STRING
+ */
#define DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE "toggle-type"
+/**
+ * DBUSMENU_MENUITEM_PROP_TOGGLE_STATE:
+ *
+ * #DbusmenuMenuitem property that says what state a toggle entry should
+ * be shown as the menu. Should be either #DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED
+ * #DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED or #DBUSMENU_MENUITEM_TOGGLE_STATUE_UNKNOWN.
+ * Type: #G_VARIANT_TYPE_INT32
+ */
#define DBUSMENU_MENUITEM_PROP_TOGGLE_STATE "toggle-state"
+/**
+ * DBUSMENU_MENUITEM_PROP_SHORTCUT:
+ *
+ * #DbusmenuMenuitem property that is the entries that represent a shortcut
+ * to activate the menuitem. It is an array of arrays of strings.
+ * Type: #G_VARIANT_TYPE_ARRAY
+ *
+ * It is recommended that this is not set directly but instead the
+ * libdbusmenu-gtk library is used with the function dbusmenu_menuitem_property_set_shortcut()
+ */
#define DBUSMENU_MENUITEM_PROP_SHORTCUT "shortcut"
+/**
+ * DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY:
+ *
+ * #DbusmenuMenuitem property that tells how the children of this menuitem
+ * should be displayed. Most likely this will be unset or of the value
+ * #DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU. Type: #G_VARIANT_TYPE_STRING
+ */
#define DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY "children-display"
+/**
+ * DBUSMENU_MENUITEM_TOGGLE_CHECK:
+ *
+ * Used to set #DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE to be a standard
+ * check mark item.
+ */
#define DBUSMENU_MENUITEM_TOGGLE_CHECK "checkmark"
+/**
+ * DBUSMENU_MENUITEM_TOGGLE_RADIO:
+ *
+ * Used to set #DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE to be a standard
+ * radio item.
+ */
#define DBUSMENU_MENUITEM_TOGGLE_RADIO "radio"
+/**
+ * DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED:
+ *
+ * Used to set #DBUSMENU_MENUITEM_PROP_TOGGLE_STATE so that the menu's
+ * toggle item is empty.
+ */
#define DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED 0
+/**
+ * DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED:
+ *
+ * Used to set #DBUSMENU_MENUITEM_PROP_TOGGLE_STATE so that the menu's
+ * toggle item is filled.
+ */
#define DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED 1
+/**
+ * DBUSMENU_MENUITEM_TOGGLE_STATE_UNKNOWN:
+ *
+ * Used to set #DBUSMENU_MENUITEM_PROP_TOGGLE_STATE so that the menu's
+ * toggle item is undecided.
+ */
#define DBUSMENU_MENUITEM_TOGGLE_STATE_UNKNOWN -1
+/**
+ * DBUSMENU_MENUITEM_ICON_NAME_BLANK:
+ *
+ * Used to set #DBUSMENU_MENUITEM_PROP_TOGGLE_STATE so that the menu's
+ * toggle item is undecided.
+ */
#define DBUSMENU_MENUITEM_ICON_NAME_BLANK "blank-icon"
+/**
+ * DBUSMENU_MENUITEM_SHORTCUT_CONTROL:
+ *
+ * Used in #DBUSMENU_MENUITEM_PROP_SHORTCUT to represent the
+ * control key.
+ */
#define DBUSMENU_MENUITEM_SHORTCUT_CONTROL "Control"
+/**
+ * DBUSMENU_MENUITEM_SHORTCUT_ALT:
+ *
+ * Used in #DBUSMENU_MENUITEM_PROP_SHORTCUT to represent the
+ * alternate key.
+ */
#define DBUSMENU_MENUITEM_SHORTCUT_ALT "Alt"
+/**
+ * DBUSMENU_MENUITEM_SHORTCUT_SHIFT:
+ *
+ * Used in #DBUSMENU_MENUITEM_PROP_SHORTCUT to represent the
+ * shift key.
+ */
#define DBUSMENU_MENUITEM_SHORTCUT_SHIFT "Shift"
+/**
+ * DBUSMENU_MENUITEM_SHORTCUT_SUPER:
+ *
+ * Used in #DBUSMENU_MENUITEM_PROP_SHORTCUT to represent the
+ * super key.
+ */
#define DBUSMENU_MENUITEM_SHORTCUT_SUPER "Super"
+/**
+ * DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU:
+ *
+ * Used in #DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY to have the
+ * subitems displayed as a submenu.
+ */
#define DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU "submenu"
typedef struct _DbusmenuMenuitemPrivate DbusmenuMenuitemPrivate;
/**
* DbusmenuMenuitem:
+ * @parent: Parent object
+ * @priv: Private data
*
* This is the #GObject based object that represents a menu
* item. It gets created the same on both the client and
@@ -114,16 +298,18 @@ typedef void (*dbusmenu_menuitem_about_to_show_cb) (DbusmenuMenuitem * mi, gpoin
/**
* dbusmenu_menuitem_buildvariant_slot_t:
* @mi: (in): Menu item that should be built from
+ * @properties: (allow-none): A list of properties that should be the only ones in the resulting variant structure
*
* This is the function that is called to represent this menu item
* as a variant. Should call it's own children.
*
- * Return value: (transfer full) A variant representing this item and it's children
+ * Return value: (transfer full): A variant representing this item and it's children
*/
typedef GVariant * (*dbusmenu_menuitem_buildvariant_slot_t) (DbusmenuMenuitem * mi, gchar ** properties);
/**
* DbusmenuMenuitemClass:
+ * @parent_class: Functions and signals from our parent
* @property_changed: Slot for #DbusmenuMenuitem::property-changed.
* @item_activated: Slot for #DbusmenuMenuitem::item-activated.
* @child_added: Slot for #DbusmenuMenuitem::child-added.
@@ -131,18 +317,19 @@ typedef GVariant * (*dbusmenu_menuitem_buildvariant_slot_t) (DbusmenuMenuitem *
* @child_moved: Slot for #DbusmenuMenuitem::child-moved.
* @realized: Slot for #DbusmenuMenuitem::realized.
* @about_to_show: Slot for #DbusmenuMenuitem::about-to-show.
- * @buildxml: Virtual function that appends the strings required to represent this menu item in the menu XML file.
+ * @buildvariant: Virtual function that appends the strings required to represent this menu item in the menu variant.
* @handle_event: This function is to override how events are handled by subclasses. Look at #dbusmenu_menuitem_handle_event for lots of good information.
* @send_about_to_show: Virtual function that notifies server that the client is about to show a menu.
* @show_to_user: Slot for #DbusmenuMenuitem::show-to-user.
* @event: Slot for #DbsumenuMenuitem::event.
- *
* @reserved1: Reserved for future use.
* @reserved2: Reserved for future use.
* @reserved3: Reserved for future use.
* @reserved4: Reserved for future use.
* @reserved5: Reserved for future use.
- * @reserved6: Reserved for future use.
+ *
+ * Functions and signals that every menuitem should know something
+ * about.
*/
typedef struct _DbusmenuMenuitemClass DbusmenuMenuitemClass;
struct _DbusmenuMenuitemClass
diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c
index aa39991..e3fd2cd 100644
--- a/libdbusmenu-glib/server.c
+++ b/libdbusmenu-glib/server.c
@@ -30,11 +30,13 @@ License version 3 and version 2.1 along with this program. If not, see
#include "config.h"
#endif
+#include <glib/gi18n.h>
#include <gio/gio.h>
#include "menuitem-private.h"
#include "server.h"
#include "server-marshal.h"
+#include "enum-types.h"
#include "dbus-menu-clean.xml.h"
@@ -55,6 +57,9 @@ struct _DbusmenuServerPrivate
GCancellable * bus_lookup;
guint dbus_registration;
+ DbusmenuTextDirection text_direction;
+ DbusmenuStatus status;
+
GArray * prop_array;
guint property_idle;
};
@@ -77,7 +82,9 @@ enum {
PROP_0,
PROP_DBUS_OBJECT,
PROP_ROOT_NODE,
- PROP_VERSION
+ PROP_VERSION,
+ PROP_TEXT_DIRECTION,
+ PROP_STATUS
};
/* Errors */
@@ -124,6 +131,7 @@ static void get_property (GObject * obj,
guint id,
GValue * value,
GParamSpec * pspec);
+static void default_text_direction (DbusmenuServer * server);
static void register_object (DbusmenuServer * server);
static void bus_got_cb (GObject * obj,
GAsyncResult * result,
@@ -289,6 +297,16 @@ dbusmenu_server_class_init (DbusmenuServerClass *class)
"The version of the DBusmenu API that we're implementing.",
DBUSMENU_VERSION_NUMBER, DBUSMENU_VERSION_NUMBER, DBUSMENU_VERSION_NUMBER,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_TEXT_DIRECTION,
+ g_param_spec_enum(DBUSMENU_SERVER_PROP_TEXT_DIRECTION, "The default direction of text",
+ "The object that represents this set of menus on DBus",
+ DBUSMENU_TYPE_TEXT_DIRECTION, DBUSMENU_TEXT_DIRECTION_NONE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_STATUS,
+ g_param_spec_enum(DBUSMENU_SERVER_PROP_STATUS, "Status of viewing the menus",
+ "Exports over DBus whether the menus should be given special visuals",
+ DBUSMENU_TYPE_STATUS, DBUSMENU_STATUS_NORMAL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
if (dbusmenu_node_info == NULL) {
GError * error = NULL;
@@ -348,6 +366,9 @@ dbusmenu_server_init (DbusmenuServer *self)
priv->bus_lookup = NULL;
priv->dbus_registration = 0;
+ default_text_direction(self);
+ priv->status = DBUSMENU_STATUS_NORMAL;
+
return;
}
@@ -463,6 +484,64 @@ set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec)
}
layout_update_signal(DBUSMENU_SERVER(obj));
break;
+ case PROP_TEXT_DIRECTION: {
+ DbusmenuTextDirection indir = g_value_get_enum(value);
+ DbusmenuTextDirection olddir = priv->text_direction;
+
+ /* If being set to none we need to go back to default, otherwise
+ we'll set things the way that we've been told */
+ if (indir == DBUSMENU_TEXT_DIRECTION_NONE) {
+ default_text_direction(DBUSMENU_SERVER(obj));
+ } else {
+ priv->text_direction = indir;
+ }
+
+ /* If the value has changed we need to signal that on DBus */
+ if (priv->text_direction != olddir && priv->bus != NULL && priv->dbusobject != NULL) {
+ GVariantBuilder params;
+ g_variant_builder_init(&params, G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_add_value(&params, g_variant_new_string(DBUSMENU_INTERFACE));
+ GVariant * dict = g_variant_new_dict_entry(g_variant_new_string("text-direction"), g_variant_new_string(dbusmenu_text_direction_get_nick(priv->text_direction)));
+ g_variant_builder_add_value(&params, g_variant_new_array(NULL, &dict, 1));
+ g_variant_builder_add_value(&params, g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0));
+ GVariant * vparams = g_variant_builder_end(&params);
+
+ g_dbus_connection_emit_signal(priv->bus,
+ NULL,
+ priv->dbusobject,
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged",
+ vparams,
+ NULL);
+ }
+
+ break;
+ }
+ case PROP_STATUS: {
+ DbusmenuStatus instatus = g_value_get_enum(value);
+
+ /* If the value has changed we need to signal that on DBus */
+ if (priv->status != instatus && priv->bus != NULL && priv->dbusobject != NULL) {
+ GVariantBuilder params;
+ g_variant_builder_init(&params, G_VARIANT_TYPE_ARRAY);
+ g_variant_builder_add_value(&params, g_variant_new_string(DBUSMENU_INTERFACE));
+ GVariant * dict = g_variant_new_dict_entry(g_variant_new_string("status"), g_variant_new_string(dbusmenu_status_get_nick(instatus)));
+ g_variant_builder_add_value(&params, g_variant_new_array(NULL, &dict, 1));
+ g_variant_builder_add_value(&params, g_variant_new_array(G_VARIANT_TYPE_STRING, NULL, 0));
+ GVariant * vparams = g_variant_builder_end(&params);
+
+ g_dbus_connection_emit_signal(priv->bus,
+ NULL,
+ priv->dbusobject,
+ "org.freedesktop.DBus.Properties",
+ "PropertiesChanged",
+ vparams,
+ NULL);
+ }
+
+ priv->status = instatus;
+ break;
+ }
default:
g_return_if_reached();
break;
@@ -486,6 +565,12 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec)
case PROP_VERSION:
g_value_set_uint(value, DBUSMENU_VERSION_NUMBER);
break;
+ case PROP_TEXT_DIRECTION:
+ g_value_set_enum(value, priv->text_direction);
+ break;
+ case PROP_STATUS:
+ g_value_set_enum(value, priv->status);
+ break;
default:
g_return_if_reached();
break;
@@ -494,6 +579,49 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec)
return;
}
+/* Determines the default text direction */
+static void
+default_text_direction (DbusmenuServer * server)
+{
+ DbusmenuTextDirection dir = DBUSMENU_TEXT_DIRECTION_NONE;
+ DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
+
+ const gchar * env = g_getenv("DBUSMENU_TEXT_DIRECTION");
+ if (env != NULL) {
+ if (g_strcmp0(env, "ltr") == 0) {
+ dir = DBUSMENU_TEXT_DIRECTION_LTR;
+ } else if (g_strcmp0(env, "rtl") == 0) {
+ dir = DBUSMENU_TEXT_DIRECTION_RTL;
+ } else {
+ g_warning("Value of 'DBUSMENU_TEXT_DIRECTION' is '%s' which is not one of 'rtl' or 'ltr'", env);
+ }
+ }
+
+ if (dir == DBUSMENU_TEXT_DIRECTION_NONE) {
+ /* TRANSLATORS: This is the direction of the text and can
+ either be the value 'ltr' for left-to-right text (English)
+ or 'rtl' for right-to-left (Arabic). */
+ const gchar * default_dir = C_("default text direction", "ltr");
+
+ if (g_strcmp0(default_dir, "ltr") == 0) {
+ dir = DBUSMENU_TEXT_DIRECTION_LTR;
+ } else if (g_strcmp0(default_dir, "rtl") == 0) {
+ dir = DBUSMENU_TEXT_DIRECTION_RTL;
+ } else {
+ g_warning("Translation has an invalid value '%s' for default text direction. Defaulting to left-to-right.", default_dir);
+ dir = DBUSMENU_TEXT_DIRECTION_LTR;
+ }
+ }
+
+ /* Shouldn't happen, but incase future patches make a mistake
+ this'll catch them */
+ g_return_if_fail(dir != DBUSMENU_TEXT_DIRECTION_NONE);
+
+ priv->text_direction = dir;
+
+ return;
+}
+
/* Register the object on the dbus bus */
static void
register_object (DbusmenuServer * server)
@@ -611,9 +739,16 @@ bus_get_prop (GDBusConnection * connection, const gchar * sender, const gchar *
/* None of these should happen */
g_return_val_if_fail(g_strcmp0(interface, DBUSMENU_INTERFACE) == 0, NULL);
g_return_val_if_fail(g_strcmp0(path, priv->dbusobject) == 0, NULL);
- g_return_val_if_fail(g_strcmp0(property, "version") == 0, NULL);
- return g_variant_new_uint32(DBUSMENU_VERSION_NUMBER);
+ if (g_strcmp0(property, "version") == 0) {
+ return g_variant_new_uint32(DBUSMENU_VERSION_NUMBER);
+ } else if (g_strcmp0(property, "text-direction") == 0) {
+ return g_variant_new_string(dbusmenu_text_direction_get_nick(priv->text_direction));
+ } else {
+ g_warning("Unknown property '%s'", property);
+ }
+
+ return NULL;
}
/* Handle actually signalling in the idle loop. This way we collect all
@@ -656,7 +791,7 @@ layout_update_signal (DbusmenuServer * server)
typedef struct _prop_idle_item_t prop_idle_item_t;
struct _prop_idle_item_t {
- gint id;
+ DbusmenuMenuitem * mi;
GArray * array;
};
@@ -686,6 +821,7 @@ prop_array_teardown (GArray * prop_array)
}
}
+ g_object_unref(G_OBJECT(iitem->mi));
g_array_free(iitem->array, TRUE);
}
@@ -719,6 +855,12 @@ menuitem_property_idle (gpointer user_data)
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);
+ /* if it's not exposed we're going to block it's properties
+ from getting into the dbus message */
+ if (dbusmenu_menuitem_exposed(iitem->mi) == FALSE) {
+ continue;
+ }
+
GVariantBuilder dictbuilder;
gboolean dictinit = FALSE;
@@ -756,7 +898,7 @@ menuitem_property_idle (gpointer user_data)
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_new_int32(dbusmenu_menuitem_get_id(iitem->mi)));
g_variant_builder_add_value(&tuplebuilder, g_variant_builder_end(&dictbuilder));
if (!item_init) {
@@ -773,7 +915,7 @@ menuitem_property_idle (gpointer user_data)
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_new_int32(dbusmenu_menuitem_get_id(iitem->mi)));
g_variant_builder_add_value(&tuplebuilder, g_variant_builder_end(&removedictbuilder));
if (!removeitem_init) {
@@ -786,9 +928,11 @@ menuitem_property_idle (gpointer user_data)
}
GVariant * megadata[2];
+ gboolean gotsomething = FALSE;
if (item_init) {
megadata[0] = g_variant_builder_end(&itembuilder);
+ gotsomething = TRUE;
} else {
GError * error = NULL;
megadata[0] = g_variant_parse(G_VARIANT_TYPE("a(ia{sv})"), "[ ]", NULL, NULL, &error);
@@ -801,6 +945,7 @@ menuitem_property_idle (gpointer user_data)
if (removeitem_init) {
megadata[1] = g_variant_builder_end(&removeitembuilder);
+ gotsomething = TRUE;
} else {
GError * error = NULL;
megadata[1] = g_variant_parse(G_VARIANT_TYPE("a(ia(s))"), "[ ]", NULL, NULL, &error);
@@ -811,7 +956,7 @@ menuitem_property_idle (gpointer user_data)
}
}
- if (priv->dbusobject != NULL && priv->bus != NULL) {
+ if (gotsomething && priv->dbusobject != NULL && priv->bus != NULL) {
g_dbus_connection_emit_signal(priv->bus,
NULL,
priv->dbusobject,
@@ -854,7 +999,7 @@ menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GVariant * v
prop_idle_item_t * item = NULL;
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);
- if (iitem->id == item_id) {
+ if (iitem->mi == mi) {
item = iitem;
break;
}
@@ -864,7 +1009,8 @@ menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GVariant * v
/* If not, we'll need to build ourselves one */
if (item == NULL) {
prop_idle_item_t myitem;
- myitem.id = item_id;
+ myitem.mi = mi;
+ g_object_ref(G_OBJECT(mi));
myitem.array = g_array_new(FALSE, FALSE, sizeof(prop_idle_prop_t));
g_array_append_val(priv->prop_array, myitem);
@@ -892,7 +1038,9 @@ menuitem_property_changed (DbusmenuMenuitem * mi, gchar * property, GVariant * v
/* If so, we need to swap the value */
if (prop != NULL) {
- g_variant_unref(prop->variant);
+ if (prop->variant != NULL) {
+ g_variant_unref(prop->variant);
+ }
prop->variant = variant;
} else {
/* else we need to add it */
@@ -1458,5 +1606,97 @@ dbusmenu_server_set_root (DbusmenuServer * self, DbusmenuMenuitem * root)
return;
}
+/**
+ dbusmenu_server_get_text_direction:
+ @server: The #DbusmenuServer object to get the text direction from
+
+ Returns the value of the text direction that is being exported
+ over DBus for this server. It should relate to the direction
+ of the labels and other text fields that are being exported by
+ this server.
+
+ Return value: Text direction exported for this server.
+*/
+DbusmenuTextDirection
+dbusmenu_server_get_text_direction (DbusmenuServer * server)
+{
+ g_return_val_if_fail(DBUSMENU_IS_SERVER(server), DBUSMENU_TEXT_DIRECTION_NONE);
+
+ GValue val = {0};
+ g_value_init(&val, DBUSMENU_TYPE_TEXT_DIRECTION);
+ g_object_get_property(G_OBJECT(server), DBUSMENU_SERVER_PROP_TEXT_DIRECTION, &val);
+
+ DbusmenuTextDirection retval = g_value_get_enum(&val);
+ g_value_unset(&val);
+ return retval;
+}
+
+/**
+ dbusmenu_server_set_text_direction:
+ @server: The #DbusmenuServer object to set the text direction on
+ @dir: Direction of the text
+
+ Sets the text direction that should be exported over DBus for
+ this server. If the value is set to #DBUSMENU_TEXT_DIRECTION_NONE
+ the default detection will be used for setting the value and
+ exported over DBus.
+*/
+void
+dbusmenu_server_set_text_direction (DbusmenuServer * server, DbusmenuTextDirection dir)
+{
+ g_return_if_fail(DBUSMENU_IS_SERVER(server));
+ g_return_if_fail(dir == DBUSMENU_TEXT_DIRECTION_NONE || dir == DBUSMENU_TEXT_DIRECTION_LTR || dir == DBUSMENU_TEXT_DIRECTION_RTL);
+
+ GValue newval = {0};
+ g_value_init(&newval, DBUSMENU_TYPE_TEXT_DIRECTION);
+ g_value_set_enum(&newval, dir);
+ g_object_set_property(G_OBJECT(server), DBUSMENU_SERVER_PROP_TEXT_DIRECTION, &newval);
+ g_value_unset(&newval);
+ return;
+}
+/**
+ dbusmenu_server_get_status:
+ @server: The #DbusmenuServer to get the status from
+
+ Gets the current statust hat the server is sending out over
+ DBus.
+
+ Return value: The current status the server is sending
+*/
+DbusmenuStatus
+dbusmenu_server_get_status (DbusmenuServer * server)
+{
+ g_return_val_if_fail(DBUSMENU_IS_SERVER(server), DBUSMENU_STATUS_NORMAL);
+
+ GValue val = {0};
+ g_value_init(&val, DBUSMENU_TYPE_STATUS);
+ g_object_get_property(G_OBJECT(server), DBUSMENU_SERVER_PROP_STATUS, &val);
+
+ DbusmenuStatus retval = g_value_get_enum(&val);
+ g_value_unset(&val);
+
+ return retval;
+}
+
+/**
+ dbusmenu_server_set_status:
+ @server: The #DbusmenuServer to set the status on
+ @status: Status value to set on the server
+
+ Changes the status of the server.
+*/
+void
+dbusmenu_server_set_status (DbusmenuServer * server, DbusmenuStatus status)
+{
+ g_return_if_fail(DBUSMENU_IS_SERVER(server));
+
+ GValue val = {0};
+ g_value_init(&val, DBUSMENU_TYPE_STATUS);
+ g_value_set_enum(&val, status);
+ g_object_set_property(G_OBJECT(server), DBUSMENU_SERVER_PROP_STATUS, &val);
+ g_value_unset(&val);
+
+ return;
+}
diff --git a/libdbusmenu-glib/server.h b/libdbusmenu-glib/server.h
index 5668258..80b7abb 100644
--- a/libdbusmenu-glib/server.h
+++ b/libdbusmenu-glib/server.h
@@ -33,6 +33,7 @@ License version 3 and version 2.1 along with this program. If not, see
#include <glib-object.h>
#include "menuitem.h"
+#include "types.h"
G_BEGIN_DECLS
@@ -43,15 +44,67 @@ G_BEGIN_DECLS
#define DBUSMENU_IS_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUSMENU_TYPE_SERVER))
#define DBUSMENU_SERVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUSMENU_TYPE_SERVER, DbusmenuServerClass))
+/**
+ * DBUSMENU_SERVER_SIGNAL_ID_PROP_UPDATE:
+ *
+ * String to attach to signal #DbusmenuServer::item-property-updated
+ */
#define DBUSMENU_SERVER_SIGNAL_ID_PROP_UPDATE "item-property-updated"
+/**
+ * DBUSMENU_SERVER_SIGNAL_ID_UPDATE:
+ *
+ * String to attach to signal #DbusmenuServer::item-updated
+ */
#define DBUSMENU_SERVER_SIGNAL_ID_UPDATE "item-updated"
+/**
+ * DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATED:
+ *
+ * String to attach to signal #DbusmenuServer::layout-updated
+ */
#define DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATED "layout-updated"
+/**
+ * DBUSMENU_SERVER_SIGNAL_ITEM_ACTIVATION:
+ *
+ * String to attach to signal #DbusmenuServer::item-activation-requested
+ */
#define DBUSMENU_SERVER_SIGNAL_ITEM_ACTIVATION "item-activation-requested"
+/**
+ * DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATE:
+ *
+ * String to attach to signal #DbusmenuServer::layout-updated
+ */
#define DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATE DBUSMENU_SERVER_SIGNAL_LAYOUT_UPDATED
+/**
+ * DBUSMENU_SERVER_PROP_DBUS_OBJECT:
+ *
+ * String to access property #DbusmenuServer:dbus-object
+ */
#define DBUSMENU_SERVER_PROP_DBUS_OBJECT "dbus-object"
+/**
+ * DBUSMENU_SERVER_PROP_ROOT_NODE:
+ *
+ * String to access property #DbusmenuServer:root-node
+ */
#define DBUSMENU_SERVER_PROP_ROOT_NODE "root-node"
+/**
+ * DBUSMENU_SERVER_PROP_VERSION:
+ *
+ * String to access property #DbusmenuServer:version
+ */
#define DBUSMENU_SERVER_PROP_VERSION "version"
+/**
+ * DBUSMENU_SERVER_PROP_TEXT_DIRECTION:
+ *
+ * String to access property #DbusmenuServer:text-direction
+ */
+#define DBUSMENU_SERVER_PROP_TEXT_DIRECTION "text-direction"
+/**
+ * DBUSMENU_SERVER_PROP_STATUS:
+ *
+ * String to access property #DbusmenuServer:status
+ */
+#define DBUSMENU_SERVER_PROP_STATUS "status"
typedef struct _DbusmenuServerPrivate DbusmenuServerPrivate;
@@ -61,8 +114,7 @@ typedef struct _DbusmenuServerPrivate DbusmenuServerPrivate;
@id_prop_update: Slot for #DbusmenuServer::id-prop-update.
@id_update: Slot for #DbusmenuServer::id-update.
@layout_updated: Slot for #DbusmenuServer::layout-update.
- @item_activation_requested: Slot for #DbusmenuServer::item-activation-requested.
-
+ @item_activation: Slot for #DbusmenuServer::item-activation-requested.
@reserved1: Reserved for future use.
@reserved2: Reserved for future use.
@reserved3: Reserved for future use.
@@ -93,7 +145,6 @@ struct _DbusmenuServerClass {
/**
DbusmenuServer:
- @parent: #GObject
A server which represents a sharing of a set of
#DbusmenuMenuitems across DBus to a #DbusmenuClient.
@@ -106,12 +157,19 @@ struct _DbusmenuServer {
DbusmenuServerPrivate * priv;
};
-GType dbusmenu_server_get_type (void);
-DbusmenuServer * dbusmenu_server_new (const gchar * object);
-void dbusmenu_server_set_root (DbusmenuServer * server, DbusmenuMenuitem * root);
+GType dbusmenu_server_get_type (void);
+DbusmenuServer * dbusmenu_server_new (const gchar * object);
+void dbusmenu_server_set_root (DbusmenuServer * self,
+ DbusmenuMenuitem * root);
+DbusmenuTextDirection dbusmenu_server_get_text_direction (DbusmenuServer * server);
+void dbusmenu_server_set_text_direction (DbusmenuServer * server,
+ DbusmenuTextDirection dir);
+DbusmenuStatus dbusmenu_server_get_status (DbusmenuServer * server);
+void dbusmenu_server_set_status (DbusmenuServer * server,
+ DbusmenuStatus status);
/**
- SECIONT:server
+ SECTION:server
@short_description: The server signals changed and
updates on a tree of #DbusmenuMenuitem objecs.
@stability: Unstable
diff --git a/libdbusmenu-glib/types.h b/libdbusmenu-glib/types.h
new file mode 100644
index 0000000..03ae801
--- /dev/null
+++ b/libdbusmenu-glib/types.h
@@ -0,0 +1,76 @@
+/*
+Types that are used in several objects.
+
+Copyright 2011 Canonical Ltd.
+
+Authors:
+ Ted Gould <ted@canonical.com>
+
+This program is free software: you can redistribute it and/or modify it
+under the terms of either or both of the following licenses:
+
+1) the GNU Lesser General Public License version 3, as published by the
+Free Software Foundation; and/or
+2) the GNU Lesser General Public License version 2.1, as published by
+the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+PURPOSE. See the applicable version of the GNU Lesser General Public
+License for more details.
+
+You should have received a copy of both the GNU Lesser General Public
+License version 3 and version 2.1 along with this program. If not, see
+<http://www.gnu.org/licenses/>
+*/
+
+#ifndef __DBUSMENU_TYPES_H__
+#define __DBUSMENU_TYPES_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+/**
+ DbusmenuTextDirection:
+ @DBUSMENU_TEXT_DIRECTION_NONE: Unspecified text direction
+ @DBUSMENU_TEXT_DIRECTION_LTR: Left-to-right text direction
+ @DBUSMENU_TEXT_DIRECTION_RTL: Right-to-left text direction
+
+ The direction of text that the strings that this server
+ will be sending strings as.
+*/
+typedef enum { /*< prefix=DBUSMENU_TEXT_DIRECTION >*/
+ DBUSMENU_TEXT_DIRECTION_NONE, /*< nick=none >*/
+ DBUSMENU_TEXT_DIRECTION_LTR, /*< nick=ltr >*/
+ DBUSMENU_TEXT_DIRECTION_RTL /*< nick=rtl >*/
+} DbusmenuTextDirection;
+
+/**
+ DbusmenuStatus:
+ @DBUSMENU_STATUS_NORMAL: Everything is normal
+ @DBUSMENU_STATUS_NOTICE: The menus should be shown at a higher priority
+
+ Tracks how the menus should be presented to the user.
+*/
+typedef enum { /*< prefix=DBUSMENU_STATUS >*/
+ DBUSMENU_STATUS_NORMAL, /*< nick=normal >*/
+ DBUSMENU_STATUS_NOTICE /*< nick=notice >*/
+} DbusmenuStatus;
+
+/**
+ SECTION:types
+ @short_description: Types that are used by both client and
+ server.
+ @stability: Unstable
+ @include: libdbusmenu-glib/types.h
+
+ Enums that are used to describe states of the server across the
+ bus. They are sent over dbus using their nicks but then turned
+ back into enums by the client.
+*/
+G_END_DECLS
+
+#endif /* __DBUSMENU_TYPES_H__ */
+