diff options
-rwxr-xr-x | configure | 22 | ||||
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | libdbusmenu-glib/Makefile.am | 24 | ||||
-rw-r--r-- | libdbusmenu-glib/Makefile.in | 25 | ||||
-rw-r--r-- | libdbusmenu-glib/client.c | 29 | ||||
-rw-r--r-- | libdbusmenu-glib/dbus-menu.xml | 18 | ||||
-rw-r--r-- | libdbusmenu-glib/menuitem-private.h | 2 | ||||
-rw-r--r-- | libdbusmenu-glib/menuitem.c | 97 | ||||
-rw-r--r-- | libdbusmenu-glib/menuitem.h | 1 | ||||
-rw-r--r-- | libdbusmenu-glib/server.c | 14 | ||||
-rw-r--r-- | libdbusmenu-gtk/Makefile.am | 9 | ||||
-rw-r--r-- | libdbusmenu-gtk/Makefile.in | 10 | ||||
-rw-r--r-- | libdbusmenu-gtk/client.c | 29 | ||||
-rw-r--r-- | libdbusmenu-gtk/client.h | 1 | ||||
-rw-r--r-- | libdbusmenu-gtk/menu.c | 6 |
15 files changed, 232 insertions, 61 deletions
@@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.65 for libdbusmenu 0.2.9. +# Generated by GNU Autoconf 2.65 for libdbusmenu 0.3.0. # # Report bugs to <ted@canonical.com>. # @@ -703,8 +703,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libdbusmenu' PACKAGE_TARNAME='libdbusmenu' -PACKAGE_VERSION='0.2.9' -PACKAGE_STRING='libdbusmenu 0.2.9' +PACKAGE_VERSION='0.3.0' +PACKAGE_STRING='libdbusmenu 0.3.0' PACKAGE_BUGREPORT='ted@canonical.com' PACKAGE_URL='' @@ -1494,7 +1494,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libdbusmenu 0.2.9 to adapt to many kinds of systems. +\`configure' configures libdbusmenu 0.3.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1564,7 +1564,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libdbusmenu 0.2.9:";; + short | recursive ) echo "Configuration of libdbusmenu 0.3.0:";; esac cat <<\_ACEOF @@ -1685,7 +1685,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libdbusmenu configure 0.2.9 +libdbusmenu configure 0.3.0 generated by GNU Autoconf 2.65 Copyright (C) 2009 Free Software Foundation, Inc. @@ -2058,7 +2058,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libdbusmenu $as_me 0.2.9, which was +It was created by libdbusmenu $as_me 0.3.0, which was generated by GNU Autoconf 2.65. Invocation command line was $ $0 $@ @@ -2872,7 +2872,7 @@ fi # Define the identity of the package. PACKAGE=libdbusmenu - VERSION=0.2.9 + VERSION=0.3.0 # Some tools Automake needs. @@ -12567,7 +12567,7 @@ fi ########################### LIBDBUSMENU_CURRENT=1 -LIBDBUSMENU_REVISION=6 +LIBDBUSMENU_REVISION=7 LIBDBUSMENU_AGE=0 @@ -13852,7 +13852,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libdbusmenu $as_me 0.2.9, which was +This file was extended by libdbusmenu $as_me 0.3.0, which was generated by GNU Autoconf 2.65. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -13918,7 +13918,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libdbusmenu config.status 0.2.9 +libdbusmenu config.status 0.3.0 configured by $0, generated by GNU Autoconf 2.65, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index b88d96d..d6c7d51 100644 --- a/configure.ac +++ b/configure.ac @@ -1,11 +1,11 @@ -AC_INIT(libdbusmenu, 0.2.9, ted@canonical.com) +AC_INIT(libdbusmenu, 0.3.0, ted@canonical.com) AC_COPYRIGHT([Copyright 2009,2010 Canonical]) AC_PREREQ(2.62) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(libdbusmenu, 0.2.9, [-Wno-portability]) +AM_INIT_AUTOMAKE(libdbusmenu, 0.3.0, [-Wno-portability]) AM_MAINTAINER_MODE @@ -78,7 +78,7 @@ AC_PATH_PROG([VALA_API_GEN], [vapigen]) ########################### LIBDBUSMENU_CURRENT=1 -LIBDBUSMENU_REVISION=6 +LIBDBUSMENU_REVISION=7 LIBDBUSMENU_AGE=0 AC_SUBST(LIBDBUSMENU_CURRENT) 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); diff --git a/libdbusmenu-gtk/Makefile.am b/libdbusmenu-gtk/Makefile.am index 9cc557c..2be63b7 100644 --- a/libdbusmenu-gtk/Makefile.am +++ b/libdbusmenu-gtk/Makefile.am @@ -45,7 +45,10 @@ pkgconfigdir = $(libdir)/pkgconfig -include $(INTROSPECTION_MAKEFILE) INTROSPECTION_GIRS = -INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) --add-include-path=$(top_builddir)/libdbusmenu-glib +INTROSPECTION_SCANNER_ARGS = \ + --add-include-path=$(srcdir) \ + --add-include-path=$(top_builddir)/libdbusmenu-glib \ + $(addprefix --c-include=libdbusmenu-gtk/, $(introspection_sources)) INTROSPECTION_COMPILER_ARGS = --includedir=$(builddir) --includedir=$(top_builddir)/libdbusmenu-glib if HAVE_INTROSPECTION @@ -56,7 +59,7 @@ DbusmenuGtk-0.2.gir: libdbusmenu-gtk.la DbusmenuGtk_0_2_gir_INCLUDES = \ GObject-2.0 \ Gtk-2.0 \ - DbusmenuGlib-0.2 + Dbusmenu-Glib-0.2 DbusmenuGtk_0_2_gir_CFLAGS = $(DBUSMENUGTK_CFLAGS) -I$(top_srcdir) DbusmenuGtk_0_2_gir_LIBS = libdbusmenu-gtk.la DbusmenuGtk_0_2_gir_FILES = $(addprefix $(srcdir)/, $(introspection_sources)) @@ -87,7 +90,7 @@ DbusmenuGtk-0.2.vapi: DbusmenuGtk-0.2.tmp.gir Makefile.am --pkg gdk-pixbuf-2.0 \ --pkg gtk+-2.0 \ --pkg atk \ - --pkg DbusmenuGlib-0.2 \ + --pkg Dbusmenu-Glib-0.2 \ --vapidir=$(top_builddir)/libdbusmenu-glib \ $< diff --git a/libdbusmenu-gtk/Makefile.in b/libdbusmenu-gtk/Makefile.in index 771ba0a..f64ef95 100644 --- a/libdbusmenu-gtk/Makefile.in +++ b/libdbusmenu-gtk/Makefile.in @@ -316,13 +316,17 @@ libdbusmenu_gtk_la_LIBADD = \ pkgconfig_DATA = dbusmenu-gtk.pc pkgconfigdir = $(libdir)/pkgconfig INTROSPECTION_GIRS = $(am__append_1) -INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) --add-include-path=$(top_builddir)/libdbusmenu-glib +INTROSPECTION_SCANNER_ARGS = \ + --add-include-path=$(srcdir) \ + --add-include-path=$(top_builddir)/libdbusmenu-glib \ + $(addprefix --c-include=libdbusmenu-gtk/, $(introspection_sources)) + INTROSPECTION_COMPILER_ARGS = --includedir=$(builddir) --includedir=$(top_builddir)/libdbusmenu-glib @HAVE_INTROSPECTION_TRUE@introspection_sources = $(libdbusmenu_gtkinclude_HEADERS) @HAVE_INTROSPECTION_TRUE@DbusmenuGtk_0_2_gir_INCLUDES = \ @HAVE_INTROSPECTION_TRUE@ GObject-2.0 \ @HAVE_INTROSPECTION_TRUE@ Gtk-2.0 \ -@HAVE_INTROSPECTION_TRUE@ DbusmenuGlib-0.2 +@HAVE_INTROSPECTION_TRUE@ Dbusmenu-Glib-0.2 @HAVE_INTROSPECTION_TRUE@DbusmenuGtk_0_2_gir_CFLAGS = $(DBUSMENUGTK_CFLAGS) -I$(top_srcdir) @HAVE_INTROSPECTION_TRUE@DbusmenuGtk_0_2_gir_LIBS = libdbusmenu-gtk.la @@ -805,7 +809,7 @@ uninstall-am: uninstall-girDATA uninstall-libLTLIBRARIES \ @HAVE_INTROSPECTION_TRUE@ --pkg gdk-pixbuf-2.0 \ @HAVE_INTROSPECTION_TRUE@ --pkg gtk+-2.0 \ @HAVE_INTROSPECTION_TRUE@ --pkg atk \ -@HAVE_INTROSPECTION_TRUE@ --pkg DbusmenuGlib-0.2 \ +@HAVE_INTROSPECTION_TRUE@ --pkg Dbusmenu-Glib-0.2 \ @HAVE_INTROSPECTION_TRUE@ --vapidir=$(top_builddir)/libdbusmenu-glib \ @HAVE_INTROSPECTION_TRUE@ $< diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c index 3de42fe..3bd0af6 100644 --- a/libdbusmenu-gtk/client.c +++ b/libdbusmenu-gtk/client.c @@ -308,7 +308,7 @@ dbusmenu_gtkclient_newitem_base (DbusmenuGtkClient * client, DbusmenuMenuitem * /* Oh, we're a child, let's deal with that */ if (parent != NULL) { - new_child(parent, item, dbusmenu_menuitem_get_position(item, parent), DBUSMENU_GTKCLIENT(client)); + new_child(parent, item, dbusmenu_menuitem_get_position_realized(item, parent), DBUSMENU_GTKCLIENT(client)); } return; @@ -335,7 +335,7 @@ new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, Dbus } GtkMenuItem * childmi = dbusmenu_gtkclient_menuitem_get(gtkclient, child); - gtk_menu_shell_insert(GTK_MENU_SHELL(menu), GTK_WIDGET(childmi), position); + gtk_menu_shell_insert(GTK_MENU_SHELL(menu), GTK_WIDGET(childmi), dbusmenu_menuitem_get_position_realized(child, mi)); gtk_widget_show(GTK_WIDGET(menu)); return; @@ -373,7 +373,7 @@ move_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint new, guint ol } GtkMenuItem * childmi = dbusmenu_gtkclient_menuitem_get(gtkclient, child); - gtk_menu_reorder_child(GTK_MENU(ann_menu), GTK_WIDGET(childmi), new); + gtk_menu_reorder_child(GTK_MENU(ann_menu), GTK_WIDGET(childmi), dbusmenu_menuitem_get_position_realized(child, mi)); return; } @@ -423,6 +423,29 @@ dbusmenu_gtkclient_menuitem_get (DbusmenuGtkClient * client, DbusmenuMenuitem * return GTK_MENU_ITEM(data); } +/** + dbusmenu_gtkclient_menuitem_get_submenu: + @client: A #DbusmenuGtkClient with the item in it. + @item: #DbusmenuMenuitem to get associated #GtkMenu on. + + This grabs the submenu associated with the menuitem. + + Return value: The #GtkMenu if there is one. +*/ +GtkMenu * +dbusmenu_gtkclient_menuitem_get_submenu (DbusmenuGtkClient * client, DbusmenuMenuitem * item) +{ + g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), NULL); + g_return_val_if_fail(DBUSMENU_IS_MENUITEM(item), NULL); + + gpointer data = g_object_get_data(G_OBJECT(item), data_menu); + if (data == NULL) { + return NULL; + } + + return GTK_MENU(data); +} + /* The base type handler that builds a plain ol' GtkMenuItem to represent, well, the GtkMenuItem */ static gboolean diff --git a/libdbusmenu-gtk/client.h b/libdbusmenu-gtk/client.h index 4cfbdcf..7672bf7 100644 --- a/libdbusmenu-gtk/client.h +++ b/libdbusmenu-gtk/client.h @@ -77,6 +77,7 @@ struct _DbusmenuGtkClient { GType dbusmenu_gtkclient_get_type (void); DbusmenuGtkClient * dbusmenu_gtkclient_new (gchar * dbus_name, gchar * dbus_object); GtkMenuItem * dbusmenu_gtkclient_menuitem_get (DbusmenuGtkClient * client, DbusmenuMenuitem * item); +GtkMenu * dbusmenu_gtkclient_menuitem_get_submenu (DbusmenuGtkClient * client, DbusmenuMenuitem * item); void dbusmenu_gtkclient_newitem_base (DbusmenuGtkClient * client, DbusmenuMenuitem * item, GtkMenuItem * gmi, DbusmenuMenuitem * parent); diff --git a/libdbusmenu-gtk/menu.c b/libdbusmenu-gtk/menu.c index 103ecfe..4fa546b 100644 --- a/libdbusmenu-gtk/menu.c +++ b/libdbusmenu-gtk/menu.c @@ -237,7 +237,7 @@ root_child_added (DbusmenuMenuitem * root, DbusmenuMenuitem * child, guint posit GtkMenuItem * mi = dbusmenu_gtkclient_menuitem_get(priv->client, child); if (mi != NULL) { GtkWidget * item = GTK_WIDGET(mi); - gtk_menu_insert(GTK_MENU(menu), item, position); + gtk_menu_insert(GTK_MENU(menu), item, dbusmenu_menuitem_get_position_realized(child, root)); #ifdef MASSIVEDEBUGGING menu_pos_t menu_pos; menu_pos.mi = mi; @@ -260,7 +260,7 @@ root_child_moved (DbusmenuMenuitem * root, DbusmenuMenuitem * child, guint newpo g_debug("Root child moved"); #endif DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(menu); - gtk_menu_reorder_child(GTK_MENU(menu), GTK_WIDGET(dbusmenu_gtkclient_menuitem_get(priv->client, child)), newposition); + gtk_menu_reorder_child(GTK_MENU(menu), GTK_WIDGET(dbusmenu_gtkclient_menuitem_get(priv->client, child)), dbusmenu_menuitem_get_position_realized(child, root)); return; } @@ -300,7 +300,7 @@ child_realized (DbusmenuMenuitem * child, gpointer userdata) if (child_widget != NULL) { gtk_menu_append(menu, child_widget); - gtk_menu_reorder_child(GTK_MENU(menu), child_widget, dbusmenu_menuitem_get_position(child, dbusmenu_client_get_root(DBUSMENU_CLIENT(priv->client)))); + gtk_menu_reorder_child(GTK_MENU(menu), child_widget, dbusmenu_menuitem_get_position_realized(child, dbusmenu_client_get_root(DBUSMENU_CLIENT(priv->client)))); } else { g_warning("Child is realized, but doesn't have a GTK Widget!"); } |