aboutsummaryrefslogtreecommitdiff
path: root/libdbusmenu-glib
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2011-03-02 16:53:34 -0600
committerTed Gould <ted@gould.cx>2011-03-02 16:53:34 -0600
commitda9a1f784d3c1e8a75f832f60c3f86764810858c (patch)
treee979710140fd56b2a708809cc529459bbaeabfdf /libdbusmenu-glib
parent08409e83ad0cc9beeb27f3f4dce9b98a43138576 (diff)
parent05298620b764d60b942567d09b970342924099f9 (diff)
downloadlibdbusmenu-da9a1f784d3c1e8a75f832f60c3f86764810858c.tar.gz
libdbusmenu-da9a1f784d3c1e8a75f832f60c3f86764810858c.tar.bz2
libdbusmenu-da9a1f784d3c1e8a75f832f60c3f86764810858c.zip
Sync up to trunk
Diffstat (limited to 'libdbusmenu-glib')
-rw-r--r--libdbusmenu-glib/Makefile.am16
-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.c57
-rw-r--r--libdbusmenu-glib/client.h83
-rw-r--r--libdbusmenu-glib/dbus-menu.xml31
-rw-r--r--libdbusmenu-glib/defaults.c10
-rw-r--r--libdbusmenu-glib/defaults.h4
-rw-r--r--libdbusmenu-glib/enum-types.h.in6
-rw-r--r--libdbusmenu-glib/menuitem-marshal.list1
-rw-r--r--libdbusmenu-glib/menuitem-private.h1
-rw-r--r--libdbusmenu-glib/menuitem-proxy.h14
-rw-r--r--libdbusmenu-glib/menuitem.c247
-rw-r--r--libdbusmenu-glib/menuitem.h209
-rw-r--r--libdbusmenu-glib/server.c47
-rw-r--r--libdbusmenu-glib/server.h58
-rw-r--r--libdbusmenu-glib/types.h11
18 files changed, 756 insertions, 104 deletions
diff --git a/libdbusmenu-glib/Makefile.am b/libdbusmenu-glib/Makefile.am
index bf80996..5b04415 100644
--- a/libdbusmenu-glib/Makefile.am
+++ b/libdbusmenu-glib/Makefile.am
@@ -17,12 +17,17 @@ lib_LTLIBRARIES = \
libdbusmenu_glibincludedir=$(includedir)/libdbusmenu-0.4/libdbusmenu-glib/
-libdbusmenu_glibinclude_HEADERS = \
- dbusmenu-glib.h \
+
+EXPORTED_OBJECTS = \
+ enum-types.h \
menuitem.h \
menuitem-proxy.h \
server.h \
- client.h \
+ client.h
+
+libdbusmenu_glibinclude_HEADERS = \
+ $(EXPORTED_OBJECTS) \
+ dbusmenu-glib.h \
types.h
libdbusmenu_glib_la_SOURCES = \
@@ -47,6 +52,7 @@ libdbusmenu_glib_la_SOURCES = \
client-marshal.c \
client-menuitem.h \
client-menuitem.c \
+ client-private.h \
client.h \
client.c
@@ -152,7 +158,9 @@ INTROSPECTION_COMPILER_ARGS = --includedir=$(builddir)
if HAVE_INTROSPECTION
-introspection_sources = $(libdbusmenu_glibinclude_HEADERS) $(libdbusmenu_glib_la_SOURCES)
+introspection_sources = \
+ $(libdbusmenu_glibinclude_HEADERS) \
+ $(EXPORTED_OBJECTS:.h=.c)
Dbusmenu-0.4.gir: libdbusmenu-glib.la
Dbusmenu_0_4_gir_INCLUDES = \
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 f3e332c..83ca056 100644
--- a/libdbusmenu-glib/client.c
+++ b/libdbusmenu-glib/client.c
@@ -33,6 +33,7 @@ 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"
@@ -82,6 +83,7 @@ struct _DbusmenuClientPrivate
GCancellable * menuproxy_cancel;
GCancellable * layoutcall;
+ GVariant * layout_props;
gint current_revision;
gint my_revision;
@@ -333,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;
@@ -400,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) {
@@ -1010,7 +1026,7 @@ menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data)
}
/* Check the text direction if available */
- GVariant * textdir = g_dbus_proxy_get_cached_property(priv->menuproxy, "text-direction");
+ GVariant * textdir = g_dbus_proxy_get_cached_property(priv->menuproxy, "TextDirection");
if (textdir != NULL) {
GVariant * str = textdir;
if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) {
@@ -1053,10 +1069,10 @@ menuproxy_prop_changed_cb (GDBusProxy * proxy, GVariant * properties, GStrv inva
gchar * invalid;
gint i = 0;
for (invalid = invalidated[i]; invalid != NULL; invalid = invalidated[++i]) {
- if (g_strcmp0(invalid, "text-direction") == 0) {
+ if (g_strcmp0(invalid, "TextDirection") == 0) {
priv->text_direction = DBUSMENU_TEXT_DIRECTION_NONE;
}
- if (g_strcmp0(invalid, "status") == 0) {
+ if (g_strcmp0(invalid, "Status") == 0) {
priv->status = DBUSMENU_STATUS_NORMAL;
}
}
@@ -1066,7 +1082,7 @@ menuproxy_prop_changed_cb (GDBusProxy * proxy, GVariant * properties, GStrv inva
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) {
+ if (g_strcmp0(key, "TextDirection") == 0) {
GVariant * str = value;
if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) {
str = g_variant_get_variant(str);
@@ -1074,7 +1090,7 @@ menuproxy_prop_changed_cb (GDBusProxy * proxy, GVariant * properties, GStrv inva
priv->text_direction = dbusmenu_text_direction_get_value_from_nick(g_variant_get_string(str, NULL));
}
- if (g_strcmp0(key, "status") == 0) {
+ 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);
@@ -1152,7 +1168,7 @@ menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVarian
gchar * property;
while (g_variant_iter_next(&properties, "s", &property)) {
- g_debug("Removing property '%s' on %d", property, id);
+ /* g_debug("Removing property '%s' on %d", property, id); */
dbusmenu_menuitem_property_remove(menuitem, property);
}
}
@@ -1570,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++;
}
@@ -1759,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));
diff --git a/libdbusmenu-glib/client.h b/libdbusmenu-glib/client.h
index c04e840..28d4dd3 100644
--- a/libdbusmenu-glib/client.h
+++ b/libdbusmenu-glib/client.h
@@ -44,20 +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;
@@ -66,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.
@@ -101,7 +171,6 @@ struct _DbusmenuClientClass {
/**
DbusmenuClient:
- @parent: #GObject.
The client for a #DbusmenuServer creating a shared
object set of #DbusmenuMenuitem objects.
@@ -123,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);
@@ -150,15 +222,6 @@ 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);
diff --git a/libdbusmenu-glib/dbus-menu.xml b/libdbusmenu-glib/dbus-menu.xml
index 738a0b0..956844e 100644
--- a/libdbusmenu-glib/dbus-menu.xml
+++ b/libdbusmenu-glib/dbus-menu.xml
@@ -164,14 +164,14 @@ License version 3 and version 2.1 along with this program. If not, see
]]></dox:d>
<!-- Properties -->
- <property name="version" type="u" access="read">
+ <property name="Version" type="u" access="read">
<dox:d>
Provides the version of the DBusmenu API that this API is
implementing.
</dox:d>
</property>
- <property name="text-direction" type="s" access="read">
+ <property name="TextDirection" 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-
@@ -179,7 +179,7 @@ License version 3 and version 2.1 along with this program. If not, see
</dox:d>
</property>
- <property name="state" type="s" access="read">
+ <property name="Status" 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
@@ -204,21 +204,24 @@ License version 3 and version 2.1 along with this program. If not, see
<dox:d>
Provides the layout and propertiers that are attached to the entries
that are in the layout. It only gives the items that are children
- of the item that is specified in @parentId. It will return all of the
- properties or specific ones depending of the value in @propertyNames.
+ of the item that is specified in @a parentId. It will return all of the
+ properties or specific ones depending of the value in @a propertyNames.
The format is recursive, where the second 'v' is in the same format
- as the original 'a(ia(sv)a(v))'. If the @recursive flag is set to
- less than one then the second array will have zero entries.
+ as the original 'a(ia{sv}av)'. Its content depends on the value
+ of @a recursionDepth.
</dox:d>
<arg type="i" name="parentId" direction="in">
<dox:d>The ID of the parent node for the layout. For
grabbing the layout from the root node use zero.</dox:d>
</arg>
- <arg type="i" name="recurse" direction="in">
+ <arg type="i" name="recursionDepth" direction="in">
<dox:d>
- The amount of levels of recursion to use. -1, as value would
- deliver all the items under the @parentId.
+ The amount of levels of recursion to use. This affects the
+ content of the second variant array.
+ - -1: deliver all the items under the @a parentId.
+ - 0: no recursion, the array will be empty.
+ - n: array will contains items up to 'n' level depth.
</dox:d>
</arg>
<arg type="as" name="propertyNames" direction="in" >
@@ -233,13 +236,11 @@ License version 3 and version 2.1 along with this program. If not, see
with layoutUpdated signals.</dox:d>
</arg>
<arg type="(ia{sv}av)" name="layout" direction="out">
- <dox:d>The layout as an XML string of IDs.</dox:d>
+ <dox:d>The layout, as a recursive structure.</dox:d>
</arg>
</method>
<method name="GetGroupProperties">
- <annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="QVariantList"/>
- <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="DBusMenuItemList"/>
<dox:d>
Returns the list of items which are children of @a parentId.
</dox:d>
@@ -335,8 +336,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..9eaf9e5 100644
--- a/libdbusmenu-glib/defaults.c
+++ b/libdbusmenu-glib/defaults.c
@@ -30,7 +30,7 @@ License version 3 and version 2.1 along with this program. If not, see
#include "config.h"
#endif
-#include <glib/gi18n.h>
+#include <glib/gi18n-lib.h>
#include "defaults.h"
#include "menuitem.h"
@@ -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.h.in b/libdbusmenu-glib/enum-types.h.in
index 8c5f463..488b615 100644
--- a/libdbusmenu-glib/enum-types.h.in
+++ b/libdbusmenu-glib/enum-types.h.in
@@ -51,6 +51,12 @@ G_END_DECLS
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-marshal.list b/libdbusmenu-glib/menuitem-marshal.list
index e3cb272..4382ed7 100644
--- a/libdbusmenu-glib/menuitem-marshal.list
+++ b/libdbusmenu-glib/menuitem-marshal.list
@@ -4,3 +4,4 @@ VOID: OBJECT, UINT
VOID: OBJECT
VOID: VOID
VOID: UINT
+BOOLEAN: STRING, VARIANT, UINT
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 ee18fab..f7867e4 100644
--- a/libdbusmenu-glib/menuitem.c
+++ b/libdbusmenu-glib/menuitem.c
@@ -61,6 +61,8 @@ struct _DbusmenuMenuitemPrivate
gboolean root;
gboolean realized;
DbusmenuDefaults * defaults;
+ gboolean exposed;
+ DbusmenuMenuitem * parent;
};
/* Signals */
@@ -73,6 +75,7 @@ enum {
REALIZED,
SHOW_TO_USER,
ABOUT_TO_SHOW,
+ EVENT,
LAST_SIGNAL
};
@@ -246,6 +249,23 @@ dbusmenu_menuitem_class_init (DbusmenuMenuitemClass *klass)
NULL, NULL,
_dbusmenu_menuitem_marshal_VOID__VOID,
G_TYPE_BOOLEAN, 0, G_TYPE_NONE);
+ /**
+ DbusmenuMenuitem::event:
+ @arg0: The #DbusmenuMenuitem object.
+ @arg1: Name of the event
+ @arg2: Information passed along with the event
+ @arg3: X11 timestamp of when the event happened
+
+ Emitted when an event is passed through. The event is signalled
+ after handle_event is called.
+ */
+ signals[EVENT] = g_signal_new(DBUSMENU_MENUITEM_SIGNAL_EVENT,
+ G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+ G_STRUCT_OFFSET(DbusmenuMenuitemClass, event),
+ g_signal_accumulator_true_handled, NULL,
+ _dbusmenu_menuitem_marshal_BOOLEAN__STRING_VARIANT_UINT,
+ G_TYPE_BOOLEAN, 3, G_TYPE_STRING, G_TYPE_VARIANT, G_TYPE_UINT);
g_object_class_install_property (object_class, PROP_ID,
g_param_spec_int(PROP_ID_S, "ID for the menu item",
@@ -316,6 +336,7 @@ dbusmenu_menuitem_init (DbusmenuMenuitem *self)
priv->realized = FALSE;
priv->defaults = dbusmenu_defaults_ref_default();
+ priv->exposed = FALSE;
return;
}
@@ -337,6 +358,11 @@ dbusmenu_menuitem_dispose (GObject *object)
priv->defaults = NULL;
}
+ if (priv->parent) {
+ g_object_remove_weak_pointer(G_OBJECT(priv->parent), (gpointer *)&priv->parent);
+ priv->parent = NULL;
+ }
+
G_OBJECT_CLASS (dbusmenu_menuitem_parent_class)->dispose (object);
return;
}
@@ -563,11 +589,12 @@ dbusmenu_menuitem_get_children (DbusmenuMenuitem * mi)
/* For all the taken children we need to signal
that they were removed */
static void
-take_children_signal (gpointer data, gpointer user_data)
+take_children_helper (gpointer data, gpointer user_data)
{
#ifdef MASSIVEDEBUGGING
g_debug("Menuitem %d (%s) signalling child removed %d (%s)", ID(user_data), LABEL(user_data), ID(data), LABEL(data));
#endif
+ dbusmenu_menuitem_unparent(DBUSMENU_MENUITEM(data));
g_signal_emit(G_OBJECT(user_data), signals[CHILD_REMOVED], 0, DBUSMENU_MENUITEM(data), TRUE);
return;
}
@@ -593,7 +620,7 @@ dbusmenu_menuitem_take_children (DbusmenuMenuitem * mi)
DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
GList * children = priv->children;
priv->children = NULL;
- g_list_foreach(children, take_children_signal, mi);
+ g_list_foreach(children, take_children_helper, mi);
dbusmenu_menuitem_property_remove(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY);
@@ -702,6 +729,10 @@ dbusmenu_menuitem_child_append (DbusmenuMenuitem * mi, DbusmenuMenuitem * child)
DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
g_return_val_if_fail(g_list_find(priv->children, child) == NULL, FALSE);
+ if (!dbusmenu_menuitem_set_parent(child, mi)) {
+ return FALSE;
+ }
+
if (priv->children == NULL && !dbusmenu_menuitem_property_exist(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY)) {
dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY, DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU);
}
@@ -734,6 +765,10 @@ dbusmenu_menuitem_child_prepend (DbusmenuMenuitem * mi, DbusmenuMenuitem * child
DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
g_return_val_if_fail(g_list_find(priv->children, child) == NULL, FALSE);
+ if (!dbusmenu_menuitem_set_parent(child, mi)) {
+ return FALSE;
+ }
+
if (priv->children == NULL && !dbusmenu_menuitem_property_exist(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY)) {
dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY, DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU);
}
@@ -764,8 +799,14 @@ dbusmenu_menuitem_child_delete (DbusmenuMenuitem * mi, DbusmenuMenuitem * child)
g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
g_return_val_if_fail(DBUSMENU_IS_MENUITEM(child), FALSE);
+ if (dbusmenu_menuitem_get_parent(child) != mi) {
+ g_warning("Trying to remove a child that doesn't believe we're it's parent.");
+ return FALSE;
+ }
+
DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
priv->children = g_list_remove(priv->children, child);
+ dbusmenu_menuitem_unparent(child);
#ifdef MASSIVEDEBUGGING
g_debug("Menuitem %d (%s) signalling child removed %d (%s)", ID(mi), LABEL(mi), ID(child), LABEL(child));
#endif
@@ -800,6 +841,10 @@ dbusmenu_menuitem_child_add_position (DbusmenuMenuitem * mi, DbusmenuMenuitem *
DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
g_return_val_if_fail(g_list_find(priv->children, child) == NULL, FALSE);
+ if (!dbusmenu_menuitem_set_parent(child, mi)) {
+ return FALSE;
+ }
+
if (priv->children == NULL && !dbusmenu_menuitem_property_exist(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY)) {
dbusmenu_menuitem_property_set(mi, DBUSMENU_MENUITEM_PROP_CHILD_DISPLAY, DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU);
}
@@ -935,6 +980,84 @@ dbusmenu_menuitem_find_id (DbusmenuMenuitem * mi, gint id)
}
/**
+ * dbusmenu_menuitem_set_parent:
+ * @mi: The #DbusmenuMenuitem for which to set the parent
+ * @parent: The new parent #DbusmenuMenuitem
+ *
+ * Sets the parent of @mi to @parent. If @mi already
+ * has a parent, then this call will fail. The parent will
+ * be set automatically when using the usual methods to add a
+ * child menuitem, so this function should not normally be
+ * called directly
+ *
+ * Return value: Whether the parent was set successfully
+ */
+gboolean
+dbusmenu_menuitem_set_parent (DbusmenuMenuitem * mi, DbusmenuMenuitem * parent)
+{
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
+
+ DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+
+ if (priv->parent != NULL) {
+ g_warning ("Menu item already has a parent");
+ return FALSE;
+ }
+
+ priv->parent = parent;
+ g_object_add_weak_pointer(G_OBJECT(priv->parent), (gpointer *)&priv->parent);
+
+ return TRUE;
+}
+
+/**
+ * dbusmenu_menuitem_unparent:
+ * @mi: The #DbusmenuMenuitem to unparent
+ *
+ * Unparents the menu item @mi. If @mi doesn't have a
+ * parent, then this call will fail. The menuitem will
+ * be unparented automatically when using the usual methods
+ * to delete a child menuitem, so this function should not
+ * normally be called directly
+ *
+ * Return value: Whether the menu item was unparented successfully
+ */
+gboolean
+dbusmenu_menuitem_unparent (DbusmenuMenuitem * mi)
+{
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
+ DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+
+ if (priv->parent == NULL) {
+ g_warning("Menu item doesn't have a parent");
+ return FALSE;
+ }
+
+ g_object_remove_weak_pointer(G_OBJECT(priv->parent), (gpointer *)&priv->parent);
+ priv->parent = NULL;
+
+ return TRUE;
+}
+
+/**
+ * dbusmenu_menuitem_get_parent:
+ * @mi: The #DbusmenuMenuitem for which to inspect the parent
+ *
+ * This function looks up the parent of @mi
+ *
+ * Return value: (transfer none): The parent of this menu item
+ */
+DbusmenuMenuitem *
+dbusmenu_menuitem_get_parent (DbusmenuMenuitem * mi)
+{
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), NULL);
+ DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+
+ return priv->parent;
+}
+
+/**
* dbusmenu_menuitem_property_set:
* @mi: The #DbusmenuMenuitem to set the property on.
* @property: Name of the property to set.
@@ -1023,26 +1146,30 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro
{
g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
g_return_val_if_fail(property != NULL, FALSE);
+ g_return_val_if_fail(g_utf8_validate(property, -1, 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) {
+ /* 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) {
+ default_value = dbusmenu_defaults_default_get(priv->defaults, type, property);
+ if (default_value != NULL && 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. */
@@ -1053,7 +1180,9 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro
}
}
+
gboolean replaced = FALSE;
+ gboolean remove = FALSE;
gpointer currentval = g_hash_table_lookup(priv->properties, property);
if (value != NULL) {
@@ -1068,10 +1197,21 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro
gchar * lprop = g_strdup(property);
g_variant_ref_sink(value);
- g_hash_table_replace(priv->properties, lprop, value);
+ /* Really important that this is _insert as that means the value
+ that we just created in the _strdup is free'd and not the one
+ currently in the hashtable. That could be the same as the one
+ being passed in and then the signal emit would be done with a
+ bad value */
+ g_hash_table_insert(priv->properties, lprop, value);
} else {
if (currentval != NULL) {
- g_hash_table_remove(priv->properties, property);
+ /* So the question you should be asking if you're paying attention
+ is "Why not just do the remove here?" It's a good question with
+ an interesting answer. Bascially it's the same reason as above,
+ in a couple cases the passed in properties is the value in the hash
+ table so we can avoid strdup'ing it by removing it (and thus free'ing
+ it) after the signal emition */
+ remove = TRUE;
replaced = TRUE;
}
}
@@ -1092,6 +1232,10 @@ dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * pro
g_signal_emit(G_OBJECT(mi), signals[PROPERTY_CHANGED], 0, property, signalval, TRUE);
}
+ if (remove) {
+ g_hash_table_remove(priv->properties, property);
+ }
+
return TRUE;
}
@@ -1210,7 +1354,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.
*
@@ -1245,9 +1389,7 @@ dbusmenu_menuitem_property_remove (DbusmenuMenuitem * mi, const gchar * property
g_return_if_fail(DBUSMENU_IS_MENUITEM(mi));
g_return_if_fail(property != NULL);
- DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
-
- g_hash_table_remove(priv->properties, property);
+ dbusmenu_menuitem_property_set_variant(mi, property, NULL);
return;
}
@@ -1343,7 +1485,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);
@@ -1352,6 +1494,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;
}
@@ -1409,6 +1578,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)) {
@@ -1433,7 +1604,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;
@@ -1515,9 +1686,24 @@ dbusmenu_menuitem_handle_event (DbusmenuMenuitem * mi, const gchar * name, GVari
#endif
DbusmenuMenuitemClass * class = DBUSMENU_MENUITEM_GET_CLASS(mi);
- if (class->handle_event != NULL) {
- return class->handle_event(mi, name, variant, timestamp);
+ /* We need to keep a ref to the variant because the signal
+ handler will drop the floating ref and then we'll be up
+ a creek if we don't have our own later. */
+ if (variant != NULL) {
+ g_variant_ref_sink(variant);
+ }
+
+ gboolean handled = FALSE;
+ g_signal_emit(G_OBJECT(mi), signals[EVENT], g_quark_from_string(name), name, variant, timestamp, &handled);
+
+ if (!handled && class->handle_event != NULL) {
+ class->handle_event(mi, name, variant, timestamp);
+ }
+
+ if (variant != NULL) {
+ g_variant_unref(variant);
}
+
return;
}
@@ -1583,11 +1769,16 @@ dbusmenu_menuitem_property_is_default (DbusmenuMenuitem * mi, const gchar * prop
return FALSE;
}
- currentval = dbusmenu_defaults_default_get(priv->defaults, menuitem_get_type(mi), property);
- if (currentval != NULL) {
- return TRUE;
- }
+ /* If we haven't stored it locally, then it's the default */
+ return TRUE;
+}
- 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 afd6084..f4eb989 100644
--- a/libdbusmenu-glib/menuitem.h
+++ b/libdbusmenu-glib/menuitem.h
@@ -42,47 +42,237 @@ 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"
+/**
+ * DBUSMENU_MENUITEM_SIGNAL_EVENT:
+ *
+ * String to attach to signal #DbusmenuServer::event
+ */
+#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
@@ -113,16 +303,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.
@@ -130,17 +322,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
@@ -163,13 +357,14 @@ struct _DbusmenuMenuitemClass
void (*show_to_user) (DbusmenuMenuitem * mi, guint timestamp, gpointer cb_data);
gboolean (*about_to_show) (void);
+ void (*event) (const gchar * name, GVariant * value, guint timestamp);
+
/*< Private >*/
void (*reserved1) (void);
void (*reserved2) (void);
void (*reserved3) (void);
void (*reserved4) (void);
void (*reserved5) (void);
- void (*reserved6) (void);
};
GType dbusmenu_menuitem_get_type (void);
@@ -191,6 +386,10 @@ gboolean dbusmenu_menuitem_child_reorder (DbusmenuMenuitem * mi, DbusmenuMenuite
DbusmenuMenuitem * dbusmenu_menuitem_child_find (DbusmenuMenuitem * mi, gint id);
DbusmenuMenuitem * dbusmenu_menuitem_find_id (DbusmenuMenuitem * mi, gint id);
+gboolean dbusmenu_menuitem_set_parent (DbusmenuMenuitem * mi, DbusmenuMenuitem * parent);
+gboolean dbusmenu_menuitem_unparent (DbusmenuMenuitem *mi);
+DbusmenuMenuitem * dbusmenu_menuitem_get_parent (DbusmenuMenuitem * mi);
+
gboolean dbusmenu_menuitem_property_set (DbusmenuMenuitem * mi, const gchar * property, const gchar * value);
gboolean dbusmenu_menuitem_property_set_variant (DbusmenuMenuitem * mi, const gchar * property, GVariant * value);
gboolean dbusmenu_menuitem_property_set_bool (DbusmenuMenuitem * mi, const gchar * property, const gboolean value);
diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c
index 22aec70..14c0c53 100644
--- a/libdbusmenu-glib/server.c
+++ b/libdbusmenu-glib/server.c
@@ -30,7 +30,7 @@ License version 3 and version 2.1 along with this program. If not, see
#include "config.h"
#endif
-#include <glib/gi18n.h>
+#include <glib/gi18n-lib.h>
#include <gio/gio.h>
#include "menuitem-private.h"
@@ -511,7 +511,7 @@ set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec)
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)));
+ GVariant * dict = g_variant_new_dict_entry(g_variant_new_string("TextDirection"), 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);
@@ -535,7 +535,7 @@ set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec)
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)));
+ 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);
@@ -750,9 +750,9 @@ bus_get_prop (GDBusConnection * connection, const gchar * sender, const gchar *
g_return_val_if_fail(g_strcmp0(interface, DBUSMENU_INTERFACE) == 0, NULL);
g_return_val_if_fail(g_strcmp0(path, priv->dbusobject) == 0, NULL);
- if (g_strcmp0(property, "version") == 0) {
+ if (g_strcmp0(property, "Version") == 0) {
return g_variant_new_uint32(DBUSMENU_VERSION_NUMBER);
- } else if (g_strcmp0(property, "text-direction") == 0) {
+ } else if (g_strcmp0(property, "TextDirection") == 0) {
return g_variant_new_string(dbusmenu_text_direction_get_nick(priv->text_direction));
} else if (g_strcmp0(property, "icon-theme-path") == 0) {
GVariant * dirs = NULL;
@@ -764,6 +764,8 @@ bus_get_prop (GDBusConnection * connection, const gchar * sender, const gchar *
}
return dirs;
+ } else if (g_strcmp0(property, "Status") == 0) {
+ return g_variant_new_string(dbusmenu_status_get_nick(priv->status));
} else {
g_warning("Unknown property '%s'", property);
}
@@ -811,7 +813,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;
};
@@ -841,6 +843,7 @@ prop_array_teardown (GArray * prop_array)
}
}
+ g_object_unref(G_OBJECT(iitem->mi));
g_array_free(iitem->array, TRUE);
}
@@ -874,6 +877,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;
@@ -911,7 +920,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) {
@@ -928,7 +937,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) {
@@ -941,9 +950,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);
@@ -956,6 +967,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);
@@ -966,7 +978,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,
@@ -1009,7 +1021,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;
}
@@ -1019,7 +1031,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);
@@ -1047,7 +1060,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 */
@@ -1185,7 +1200,11 @@ bus_get_layout (DbusmenuServer * server, GVariant * params, GDBusMethodInvocatio
GVariant * items = NULL;
if (priv->root != NULL) {
- items = dbusmenu_menuitem_build_variant(priv->root, props, recurse);
+ DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, parent);
+
+ if (mi != NULL) {
+ items = dbusmenu_menuitem_build_variant(mi, props, recurse);
+ }
}
/* What happens if we don't have anything? */
@@ -1642,6 +1661,7 @@ dbusmenu_server_get_text_direction (DbusmenuServer * server)
/**
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
@@ -1689,6 +1709,7 @@ dbusmenu_server_get_status (DbusmenuServer * server)
/**
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.
*/
diff --git a/libdbusmenu-glib/server.h b/libdbusmenu-glib/server.h
index bed567f..5feb09b 100644
--- a/libdbusmenu-glib/server.h
+++ b/libdbusmenu-glib/server.h
@@ -44,16 +44,66 @@ 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;
@@ -64,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.
@@ -96,7 +145,6 @@ struct _DbusmenuServerClass {
/**
DbusmenuServer:
- @parent: #GObject
A server which represents a sharing of a set of
#DbusmenuMenuitems across DBus to a #DbusmenuClient.
@@ -111,7 +159,7 @@ struct _DbusmenuServer {
GType dbusmenu_server_get_type (void);
DbusmenuServer * dbusmenu_server_new (const gchar * object);
-void dbusmenu_server_set_root (DbusmenuServer * server,
+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,
@@ -124,7 +172,7 @@ void dbusmenu_server_set_icon_paths (DbusmenuServer *
GStrv icon_paths);
/**
- 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
index e573476..03ae801 100644
--- a/libdbusmenu-glib/types.h
+++ b/libdbusmenu-glib/types.h
@@ -59,6 +59,17 @@ typedef enum { /*< prefix=DBUSMENU_STATUS >*/
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__ */