aboutsummaryrefslogtreecommitdiff
path: root/libdbusmenu-glib
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2010-05-27 11:36:00 -0500
committerTed Gould <ted@gould.cx>2010-05-27 11:36:00 -0500
commit77dfdb6c174eed409e8060fd08f6e0bd50d8e9ec (patch)
treeb86c7d1a4376b377429437912c4d1fc90c91d46b /libdbusmenu-glib
parent187a33539569163ee953903010169356b8d57beb (diff)
parent7f65b44564cda33de94688b35f0b191fedea1bf8 (diff)
downloadlibdbusmenu-77dfdb6c174eed409e8060fd08f6e0bd50d8e9ec.tar.gz
libdbusmenu-77dfdb6c174eed409e8060fd08f6e0bd50d8e9ec.tar.bz2
libdbusmenu-77dfdb6c174eed409e8060fd08f6e0bd50d8e9ec.zip
Import upstream version 0.3.0
Diffstat (limited to 'libdbusmenu-glib')
-rw-r--r--libdbusmenu-glib/Makefile.am24
-rw-r--r--libdbusmenu-glib/Makefile.in25
-rw-r--r--libdbusmenu-glib/client.c29
-rw-r--r--libdbusmenu-glib/dbus-menu.xml18
-rw-r--r--libdbusmenu-glib/menuitem-private.h2
-rw-r--r--libdbusmenu-glib/menuitem.c97
-rw-r--r--libdbusmenu-glib/menuitem.h1
-rw-r--r--libdbusmenu-glib/server.c14
8 files changed, 175 insertions, 35 deletions
diff --git a/libdbusmenu-glib/Makefile.am b/libdbusmenu-glib/Makefile.am
index c1aff41..3df1513 100644
--- a/libdbusmenu-glib/Makefile.am
+++ b/libdbusmenu-glib/Makefile.am
@@ -99,21 +99,25 @@ menuitem-marshal.c: $(srcdir)/menuitem-marshal.list
-include $(INTROSPECTION_MAKEFILE)
INTROSPECTION_GIRS =
-INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir)
+INTROSPECTION_SCANNER_ARGS = \
+ --add-include-path=$(srcdir) \
+ $(addprefix --c-include=libdbusmenu-glib/, $(introspection_sources))
INTROSPECTION_COMPILER_ARGS = --includedir=$(builddir)
if HAVE_INTROSPECTION
introspection_sources = $(libdbusmenu_glibinclude_HEADERS)
-DbusmenuGlib-0.2.gir: libdbusmenu-glib.la
-DbusmenuGlib_0_2_gir_INCLUDES = \
+Dbusmenu_Glib-0.2.gir: libdbusmenu-glib.la
+Dbusmenu_Glib_0_2_gir_INCLUDES = \
GObject-2.0
-DbusmenuGlib_0_2_gir_CFLAGS = $(DBUSMENUGLIB_CFLAGS)
-DbusmenuGlib_0_2_gir_LIBS = libdbusmenu-glib.la
-DbusmenuGlib_0_2_gir_FILES = $(addprefix $(srcdir)/, $(introspection_sources))
+Dbusmenu_Glib_0_2_gir_CFLAGS = $(DBUSMENUGLIB_CFLAGS)
+Dbusmenu_Glib_0_2_gir_LIBS = libdbusmenu-glib.la
+Dbusmenu_Glib_0_2_gir_FILES = $(addprefix $(srcdir)/, $(introspection_sources))
+Dbusmenu_Glib_0_2_gir_NAMESPACE = Dbusmenu
+Dbusmenu_Glib_0_2_gir_VERSION = Glib-0.2
-INTROSPECTION_GIRS += DbusmenuGlib-0.2.gir
+INTROSPECTION_GIRS += Dbusmenu-Glib-0.2.gir
girdir = $(datadir)/gir-1.0
gir_DATA = $(INTROSPECTION_GIRS)
@@ -132,10 +136,10 @@ endif
if HAVE_INTROSPECTION
vapidir = $(datadir)/vala/vapi
-vapi_DATA = DbusmenuGlib-0.2.vapi
+vapi_DATA = Dbusmenu-Glib-0.2.vapi
-DbusmenuGlib-0.2.vapi: DbusmenuGlib-0.2.gir
- $(VALA_API_GEN) --library=DbusmenuGlib-0.2 $<
+Dbusmenu-Glib-0.2.vapi: Dbusmenu-Glib-0.2.gir
+ $(VALA_API_GEN) --library=Dbusmenu-Glib-0.2 $<
CLEANFILES += $(vapi_DATA)
diff --git a/libdbusmenu-glib/Makefile.in b/libdbusmenu-glib/Makefile.in
index 1556622..94d607f 100644
--- a/libdbusmenu-glib/Makefile.in
+++ b/libdbusmenu-glib/Makefile.in
@@ -36,7 +36,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-@HAVE_INTROSPECTION_TRUE@am__append_1 = DbusmenuGlib-0.2.gir
+@HAVE_INTROSPECTION_TRUE@am__append_1 = Dbusmenu-Glib-0.2.gir
@HAVE_INTROSPECTION_TRUE@am__append_2 = $(gir_DATA) $(typelib_DATA) \
@HAVE_INTROSPECTION_TRUE@ $(vapi_DATA)
subdir = libdbusmenu-glib
@@ -339,15 +339,20 @@ BUILT_SOURCES = \
server-marshal.c
INTROSPECTION_GIRS = $(am__append_1)
-INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir)
+INTROSPECTION_SCANNER_ARGS = \
+ --add-include-path=$(srcdir) \
+ $(addprefix --c-include=libdbusmenu-glib/, $(introspection_sources))
+
INTROSPECTION_COMPILER_ARGS = --includedir=$(builddir)
@HAVE_INTROSPECTION_TRUE@introspection_sources = $(libdbusmenu_glibinclude_HEADERS)
-@HAVE_INTROSPECTION_TRUE@DbusmenuGlib_0_2_gir_INCLUDES = \
+@HAVE_INTROSPECTION_TRUE@Dbusmenu_Glib_0_2_gir_INCLUDES = \
@HAVE_INTROSPECTION_TRUE@ GObject-2.0
-@HAVE_INTROSPECTION_TRUE@DbusmenuGlib_0_2_gir_CFLAGS = $(DBUSMENUGLIB_CFLAGS)
-@HAVE_INTROSPECTION_TRUE@DbusmenuGlib_0_2_gir_LIBS = libdbusmenu-glib.la
-@HAVE_INTROSPECTION_TRUE@DbusmenuGlib_0_2_gir_FILES = $(addprefix $(srcdir)/, $(introspection_sources))
+@HAVE_INTROSPECTION_TRUE@Dbusmenu_Glib_0_2_gir_CFLAGS = $(DBUSMENUGLIB_CFLAGS)
+@HAVE_INTROSPECTION_TRUE@Dbusmenu_Glib_0_2_gir_LIBS = libdbusmenu-glib.la
+@HAVE_INTROSPECTION_TRUE@Dbusmenu_Glib_0_2_gir_FILES = $(addprefix $(srcdir)/, $(introspection_sources))
+@HAVE_INTROSPECTION_TRUE@Dbusmenu_Glib_0_2_gir_NAMESPACE = Dbusmenu
+@HAVE_INTROSPECTION_TRUE@Dbusmenu_Glib_0_2_gir_VERSION = Glib-0.2
@HAVE_INTROSPECTION_TRUE@girdir = $(datadir)/gir-1.0
@HAVE_INTROSPECTION_TRUE@gir_DATA = $(INTROSPECTION_GIRS)
@HAVE_INTROSPECTION_TRUE@typelibdir = $(libdir)/girepository-1.0
@@ -357,7 +362,7 @@ INTROSPECTION_COMPILER_ARGS = --includedir=$(builddir)
# VAPI Files
#########################
@HAVE_INTROSPECTION_TRUE@vapidir = $(datadir)/vala/vapi
-@HAVE_INTROSPECTION_TRUE@vapi_DATA = DbusmenuGlib-0.2.vapi
+@HAVE_INTROSPECTION_TRUE@vapi_DATA = Dbusmenu-Glib-0.2.vapi
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
@@ -885,10 +890,10 @@ menuitem-marshal.c: $(srcdir)/menuitem-marshal.list
-include $(INTROSPECTION_MAKEFILE)
-@HAVE_INTROSPECTION_TRUE@DbusmenuGlib-0.2.gir: libdbusmenu-glib.la
+@HAVE_INTROSPECTION_TRUE@Dbusmenu_Glib-0.2.gir: libdbusmenu-glib.la
-@HAVE_INTROSPECTION_TRUE@DbusmenuGlib-0.2.vapi: DbusmenuGlib-0.2.gir
-@HAVE_INTROSPECTION_TRUE@ $(VALA_API_GEN) --library=DbusmenuGlib-0.2 $<
+@HAVE_INTROSPECTION_TRUE@Dbusmenu-Glib-0.2.vapi: Dbusmenu-Glib-0.2.gir
+@HAVE_INTROSPECTION_TRUE@ $(VALA_API_GEN) --library=Dbusmenu-Glib-0.2 $<
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c
index f5546a2..c0d3b7a 100644
--- a/libdbusmenu-glib/client.c
+++ b/libdbusmenu-glib/client.c
@@ -35,6 +35,7 @@ License version 3 and version 2.1 along with this program. If not, see
#include "client.h"
#include "menuitem.h"
+#include "menuitem-private.h"
#include "client-menuitem.h"
#include "dbusmenu-client.h"
#include "server-marshal.h"
@@ -366,6 +367,7 @@ id_update (DBusGProxy * proxy, gint id, DbusmenuClient * client)
gchar * properties[1] = {NULL}; /* This gets them all */
g_debug("Getting properties");
+ g_object_ref(menuitem);
org_ayatana_dbusmenu_get_properties_async(proxy, id, (const gchar **)properties, menuitem_get_properties_cb, menuitem);
return;
}
@@ -531,6 +533,9 @@ build_proxies (DbusmenuClient * client)
static gint
parse_node_get_id (xmlNodePtr node)
{
+ if (node->type != XML_ELEMENT_NODE) {
+ return -1;
+ }
if (g_strcmp0((gchar *)node->name, "menu") != 0) {
/* This kills some nodes early */
g_warning("XML Node is not 'menu' it is '%s'", node->name);
@@ -573,10 +578,12 @@ menuitem_get_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError
g_return_if_fail(DBUSMENU_IS_MENUITEM(data));
if (error != NULL) {
g_warning("Error getting properties on a menuitem: %s", error->message);
+ g_object_unref(data);
return;
}
g_hash_table_foreach(properties, get_properties_helper, data);
g_hash_table_destroy(properties);
+ g_object_unref(data);
return;
}
@@ -605,6 +612,8 @@ menuitem_get_properties_replace_cb (DBusGProxy * proxy, GHashTable * properties,
if (!have_error) {
menuitem_get_properties_cb(proxy, properties, error, data);
+ } else {
+ g_object_unref(data);
}
return;
@@ -617,6 +626,7 @@ menuitem_get_properties_new_cb (DBusGProxy * proxy, GHashTable * properties, GEr
{
if (error != NULL) {
g_warning("Error getting properties on a new menuitem: %s", error->message);
+ g_object_unref(data);
return;
}
g_return_if_fail(data != NULL);
@@ -624,6 +634,7 @@ menuitem_get_properties_new_cb (DBusGProxy * proxy, GHashTable * properties, GEr
newItemPropData * propdata = (newItemPropData *)data;
DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(propdata->client);
+ g_object_ref(propdata->item);
menuitem_get_properties_cb (proxy, properties, error, propdata->item);
gboolean handled = FALSE;
@@ -645,12 +656,13 @@ menuitem_get_properties_new_cb (DBusGProxy * proxy, GHashTable * properties, GEr
#ifdef MASSIVEDEBUGGING
g_debug("Client has realized a menuitem: %d", dbusmenu_menuitem_get_id(propdata->item));
#endif
- g_signal_emit(G_OBJECT(propdata->item), DBUSMENU_MENUITEM_SIGNAL_REALIZED_ID, 0, TRUE);
+ dbusmenu_menuitem_set_realized(propdata->item);
if (!handled) {
g_signal_emit(G_OBJECT(propdata->client), signals[NEW_MENUITEM], 0, propdata->item, TRUE);
}
+ g_object_unref(propdata->item);
g_free(propdata);
return;
@@ -748,7 +760,6 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it
if (parent != NULL) {
dbusmenu_menuitem_child_delete(parent, item);
}
- g_object_unref(G_OBJECT(item));
item = NULL;
}
@@ -767,13 +778,16 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it
propdata->parent = parent;
gchar * properties[1] = {NULL}; /* This gets them all */
+ g_object_ref(item);
org_ayatana_dbusmenu_get_properties_async(proxy, id, (const gchar **)properties, menuitem_get_properties_new_cb, propdata);
} else {
g_warning("Unable to allocate memory to get properties for menuitem. This menuitem will never be realized.");
}
} else {
/* Refresh the properties */
+ /* XXX: We shouldn't need to get the properties everytime we reuse an entry */
gchar * properties[1] = {NULL}; /* This gets them all */
+ g_object_ref(item);
org_ayatana_dbusmenu_get_properties_async(proxy, id, (const gchar **)properties, menuitem_get_properties_replace_cb, item);
}
@@ -807,6 +821,7 @@ parse_layout_xml(DbusmenuClient * client, xmlNodePtr node, DbusmenuMenuitem * it
dbusmenu_menuitem_child_delete(item, childmi);
}
dbusmenu_menuitem_child_add_position(item, newchildmi, position);
+ g_object_unref(newchildmi);
} else {
dbusmenu_menuitem_child_reorder(item, childmi, position);
}
@@ -844,9 +859,6 @@ parse_layout (DbusmenuClient * client, const gchar * layout)
xmlNodePtr root = xmlDocGetRootElement(xmldoc);
DbusmenuMenuitem * oldroot = priv->root;
- if (oldroot != NULL) {
- g_object_ref(oldroot);
- }
priv->root = parse_layout_xml(client, root, priv->root, NULL, priv->menuproxy);
xmlFreeDoc(xmldoc);
@@ -864,17 +876,14 @@ parse_layout (DbusmenuClient * client, const gchar * layout)
clean up that old root */
if (oldroot != NULL) {
dbusmenu_menuitem_set_root(oldroot, FALSE);
+ g_object_unref(oldroot);
+ oldroot = NULL;
}
/* If the root changed we can signal that */
g_signal_emit(G_OBJECT(client), signals[ROOT_CHANGED], 0, priv->root, TRUE);
}
- /* We need to unref it in this function no matter */
- if (oldroot != NULL) {
- g_object_unref(oldroot);
- }
-
return 1;
}
diff --git a/libdbusmenu-glib/dbus-menu.xml b/libdbusmenu-glib/dbus-menu.xml
index ad21f68..7bccf28 100644
--- a/libdbusmenu-glib/dbus-menu.xml
+++ b/libdbusmenu-glib/dbus-menu.xml
@@ -29,12 +29,18 @@ License version 3 and version 2.1 along with this program. If not, see
<http://www.gnu.org/licenses/>
-->
<node name="/" xmlns:dox="http://www.ayatana.org/dbus/dox.dtd">
+ <dox:d><![CDATA[
+ @mainpage
+
+ The goal of DBusMenu is to expose menus on DBus.
+
+ Main interface is documented here: @ref org::ayatana::dbusmenu
+ ]]></dox:d>
<interface name="org.ayatana.dbusmenu">
<dox:d><![CDATA[
- The goal of this DBus interface is to be able to pass menu items
- through DBus.
+ A DBus interface to expose menus on DBus.
- Items are represented with a unique numeric id and a dictionary of
+ Menu items are represented with a unique numeric id and a dictionary of
properties.
To reduce the amount of DBus traffic, a property should only be returned
@@ -82,6 +88,12 @@ License version 3 and version 2.1 along with this program. If not, see
<td>true</td>
</tr>
<tr>
+ <td>visible</td>
+ <td>boolean</td>
+ <td>True if the item is visible in the menu.</td>
+ <td>true</td>
+ </tr>
+ <tr>
<td>icon-name</td>
<td>string</td>
<td>Icon name of the item, following the freedesktop.org icon spec.</td>
diff --git a/libdbusmenu-glib/menuitem-private.h b/libdbusmenu-glib/menuitem-private.h
index 1c7c16a..3a0c026 100644
--- a/libdbusmenu-glib/menuitem-private.h
+++ b/libdbusmenu-glib/menuitem-private.h
@@ -34,6 +34,8 @@ License version 3 and version 2.1 along with this program. If not, see
G_BEGIN_DECLS
void dbusmenu_menuitem_buildxml (DbusmenuMenuitem * mi, GPtrArray * array);
+gboolean dbusmenu_menuitem_realized (DbusmenuMenuitem * mi);
+void dbusmenu_menuitem_set_realized (DbusmenuMenuitem * mi);
G_END_DECLS
diff --git a/libdbusmenu-glib/menuitem.c b/libdbusmenu-glib/menuitem.c
index fce8ed5..6a3c4bc 100644
--- a/libdbusmenu-glib/menuitem.c
+++ b/libdbusmenu-glib/menuitem.c
@@ -59,6 +59,7 @@ struct _DbusmenuMenuitemPrivate
GList * children;
GHashTable * properties;
gboolean root;
+ gboolean realized;
};
/* Signals */
@@ -278,6 +279,7 @@ dbusmenu_menuitem_init (DbusmenuMenuitem *self)
priv->properties = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, _g_value_free);
priv->root = FALSE;
+ priv->realized = FALSE;
return;
}
@@ -423,6 +425,46 @@ dbusmenu_menuitem_get_id (DbusmenuMenuitem * mi)
}
/**
+ dbusmenu_menuitem_realized:
+ @mi: #DbusmenuMenuitem to check on
+
+ This function returns whether the menuitem has been realized or
+ not. This is significant mostly in client implementations that
+ can use this additional state to see if the second layers of
+ the implementation have been built yet.
+
+ Return value: Returns whether or not the menu item has been realized
+ yet or not.
+*/
+gboolean
+dbusmenu_menuitem_realized (DbusmenuMenuitem * mi)
+{
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), FALSE);
+ DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+ return priv->realized;
+}
+
+/**
+ dbusmenu_menuitem_set_realized:
+ @mi: #DbusmenuMenuitem to realize
+
+ Sets the internal variable tracking whether it's been realized and
+ signals the DbusmenuMenuitem::realized event.
+*/
+void
+dbusmenu_menuitem_set_realized (DbusmenuMenuitem * mi)
+{
+ g_return_if_fail(DBUSMENU_IS_MENUITEM(mi));
+ DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+ if (priv->realized) {
+ g_warning("Realized entry realized again? ID: %d", dbusmenu_menuitem_get_id(mi));
+ }
+ priv->realized = TRUE;
+ g_signal_emit(G_OBJECT(mi), signals[REALIZED], 0, TRUE);
+ return;
+}
+
+/**
dbusmenu_menuitem_get_children:
@mi: The #DbusmenuMenuitem to query.
@@ -450,6 +492,7 @@ take_children_signal (gpointer data, gpointer user_data)
g_debug("Menuitem %d (%s) signalling child removed %d (%s)", ID(user_data), LABEL(user_data), ID(data), LABEL(data));
#endif
g_signal_emit(G_OBJECT(user_data), signals[CHILD_REMOVED], 0, DBUSMENU_MENUITEM(data), TRUE);
+ g_object_unref(G_OBJECT(data));
return;
}
@@ -517,6 +560,50 @@ dbusmenu_menuitem_get_position (DbusmenuMenuitem * mi, DbusmenuMenuitem * parent
}
/**
+ dbusmenu_menuitem_get_position_realized:
+ @mi: The #DbusmenuMenuitem to find the position of
+ @parent: The #DbusmenuMenuitem who's children contain @mi
+
+ This function is very similar to #dbusmenu_menuitem_get_position
+ except that it only counts in the children that have been realized.
+
+ Return value: The position of @mi in the realized children of @parent.
+*/
+guint
+dbusmenu_menuitem_get_position_realized (DbusmenuMenuitem * mi, DbusmenuMenuitem * parent)
+{
+ #ifdef MASSIVEDEBUGGING
+ if (!DBUSMENU_IS_MENUITEM(mi)) g_warning("Getting position of %d (%s), it's at: %d (mi fail)", ID(mi), LABEL(mi), 0);
+ if (!DBUSMENU_IS_MENUITEM(parent)) g_warning("Getting position of %d (%s), it's at: %d (parent fail)", ID(mi), LABEL(mi), 0);
+ #endif
+
+ /* TODO: I'm not too happy returning zeros here. But that's all I've got */
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(mi), 0);
+ g_return_val_if_fail(DBUSMENU_IS_MENUITEM(parent), 0);
+
+ GList * childs = dbusmenu_menuitem_get_children(parent);
+ if (childs == NULL) return 0;
+ guint count = 0;
+ for ( ; childs != NULL; childs = childs->next, count++) {
+ if (!dbusmenu_menuitem_realized(DBUSMENU_MENUITEM(childs->data))) {
+ count--;
+ continue;
+ }
+ if (childs->data == mi) {
+ break;
+ }
+ }
+
+ if (childs == NULL) return 0;
+
+ #ifdef MASSIVEDEBUGGING
+ g_debug("Getting position of %d (%s), it's at: %d", ID(mi), LABEL(mi), count);
+ #endif
+
+ return count;
+}
+
+/**
dbusmenu_menuitem_child_append:
@mi: The #DbusmenuMenuitem which will become a new parent
@child: The #DbusmenMenuitem that will be a child
@@ -533,10 +620,13 @@ dbusmenu_menuitem_child_append (DbusmenuMenuitem * mi, DbusmenuMenuitem * child)
g_return_val_if_fail(DBUSMENU_IS_MENUITEM(child), FALSE);
DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+ g_return_val_if_fail(g_list_find(priv->children, child) == NULL, FALSE);
+
priv->children = g_list_append(priv->children, child);
#ifdef MASSIVEDEBUGGING
g_debug("Menuitem %d (%s) signalling child added %d (%s) at %d", ID(mi), LABEL(mi), ID(child), LABEL(child), g_list_length(priv->children) - 1);
#endif
+ g_object_ref(G_OBJECT(child));
g_signal_emit(G_OBJECT(mi), signals[CHILD_ADDED], 0, child, g_list_length(priv->children) - 1, TRUE);
return TRUE;
}
@@ -558,10 +648,13 @@ dbusmenu_menuitem_child_prepend (DbusmenuMenuitem * mi, DbusmenuMenuitem * child
g_return_val_if_fail(DBUSMENU_IS_MENUITEM(child), FALSE);
DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+ g_return_val_if_fail(g_list_find(priv->children, child) == NULL, FALSE);
+
priv->children = g_list_prepend(priv->children, child);
#ifdef MASSIVEDEBUGGING
g_debug("Menuitem %d (%s) signalling child added %d (%s) at %d", ID(mi), LABEL(mi), ID(child), LABEL(child), 0);
#endif
+ g_object_ref(G_OBJECT(child));
g_signal_emit(G_OBJECT(mi), signals[CHILD_ADDED], 0, child, 0, TRUE);
return TRUE;
}
@@ -589,6 +682,7 @@ dbusmenu_menuitem_child_delete (DbusmenuMenuitem * mi, DbusmenuMenuitem * child)
g_debug("Menuitem %d (%s) signalling child removed %d (%s)", ID(mi), LABEL(mi), ID(child), LABEL(child));
#endif
g_signal_emit(G_OBJECT(mi), signals[CHILD_REMOVED], 0, child, TRUE);
+ g_object_unref(G_OBJECT(child));
return TRUE;
}
@@ -611,10 +705,13 @@ dbusmenu_menuitem_child_add_position (DbusmenuMenuitem * mi, DbusmenuMenuitem *
g_return_val_if_fail(DBUSMENU_IS_MENUITEM(child), FALSE);
DbusmenuMenuitemPrivate * priv = DBUSMENU_MENUITEM_GET_PRIVATE(mi);
+ g_return_val_if_fail(g_list_find(priv->children, child) == NULL, FALSE);
+
priv->children = g_list_insert(priv->children, child, position);
#ifdef MASSIVEDEBUGGING
g_debug("Menuitem %d (%s) signalling child added %d (%s) at %d", ID(mi), LABEL(mi), ID(child), LABEL(child), position);
#endif
+ g_object_ref(G_OBJECT(child));
g_signal_emit(G_OBJECT(mi), signals[CHILD_ADDED], 0, child, position, TRUE);
return TRUE;
}
diff --git a/libdbusmenu-glib/menuitem.h b/libdbusmenu-glib/menuitem.h
index cb6b8f4..e5b5ae2 100644
--- a/libdbusmenu-glib/menuitem.h
+++ b/libdbusmenu-glib/menuitem.h
@@ -148,6 +148,7 @@ gint dbusmenu_menuitem_get_id (DbusmenuMenuitem * mi);
GList * dbusmenu_menuitem_get_children (DbusmenuMenuitem * mi);
GList * dbusmenu_menuitem_take_children (DbusmenuMenuitem * mi) G_GNUC_WARN_UNUSED_RESULT;
guint dbusmenu_menuitem_get_position (DbusmenuMenuitem * mi, DbusmenuMenuitem * parent);
+guint dbusmenu_menuitem_get_position_realized (DbusmenuMenuitem * mi, DbusmenuMenuitem * parent);
gboolean dbusmenu_menuitem_child_append (DbusmenuMenuitem * mi, DbusmenuMenuitem * child);
gboolean dbusmenu_menuitem_child_prepend (DbusmenuMenuitem * mi, DbusmenuMenuitem * child);
diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c
index d87c024..0da66cc 100644
--- a/libdbusmenu-glib/server.c
+++ b/libdbusmenu-glib/server.c
@@ -146,8 +146,8 @@ dbusmenu_server_class_init (DbusmenuServerClass *class)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(DbusmenuServerClass, id_update),
NULL, NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE, 1, G_TYPE_UINT);
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
/**
DbusmenuServer::layout-updated:
@arg0: The #DbusmenuServer emitting the signal.
@@ -404,6 +404,16 @@ _dbusmenu_server_get_layout (DbusmenuServer * server, gint parent, guint * revis
}
} else {
DbusmenuMenuitem * item = dbusmenu_menuitem_find_id(priv->root, parent);
+ if (item == NULL) {
+ if (error != NULL) {
+ g_set_error(error,
+ error_quark(),
+ INVALID_MENUITEM_ID,
+ "The ID supplied %d does not refer to a menu item we have",
+ parent);
+ }
+ return FALSE;
+ }
dbusmenu_menuitem_buildxml(item, xmlarray);
}
g_ptr_array_add(xmlarray, NULL);