aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2011-03-16 14:01:25 -0500
committerTed Gould <ted@gould.cx>2011-03-16 14:01:25 -0500
commit3c9af9576901318917a4c20ab668742255bbe429 (patch)
treeff02b9f31e4137b92ab500044c079eb0dd8e0599
parentcec350b1d24eeeb308fd02846bf637d4ec92fbb5 (diff)
parent0c14221e10d1adb346b4c22d7ff503be52a62899 (diff)
downloadlibdbusmenu-3c9af9576901318917a4c20ab668742255bbe429.tar.gz
libdbusmenu-3c9af9576901318917a4c20ab668742255bbe429.tar.bz2
libdbusmenu-3c9af9576901318917a4c20ab668742255bbe429.zip
Import upstream version 0.3.102
-rw-r--r--ChangeLog103
-rwxr-xr-xconfigure22
-rw-r--r--configure.ac6
-rw-r--r--docs/libdbusmenu-glib/reference/libdbusmenu-glib-sections.txt3
-rw-r--r--docs/libdbusmenu-glib/reference/version.xml2
-rw-r--r--docs/libdbusmenu-gtk/reference/version.xml2
-rw-r--r--libdbusmenu-glib/client.c141
-rw-r--r--libdbusmenu-glib/dbus-menu.xml2
-rw-r--r--libdbusmenu-glib/enum-types.c2
-rw-r--r--libdbusmenu-glib/enum-types.h7
-rw-r--r--libdbusmenu-glib/menuitem.c2
-rw-r--r--libdbusmenu-glib/menuitem.h26
-rw-r--r--libdbusmenu-gtk/client.c14
-rw-r--r--libdbusmenu-gtk/dbusmenu-gtk-0.4.pc.in2
-rw-r--r--libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc.in2
-rw-r--r--libdbusmenu-gtk/parser.c73
16 files changed, 338 insertions, 71 deletions
diff --git a/ChangeLog b/ChangeLog
index da7410f..4626e49 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,108 @@
# Generated by Makefile. Do not edit.
+2011-03-16 Ted Gould <ted@gould.cx>
+
+ 0.3.102
+
+2011-03-16 Ted Gould <ted@gould.cx>
+
+ Add handling for children getting removed
+
+2011-03-09 Ted Gould <ted@gould.cx>
+
+ Update to current trunk
+
+2011-03-08 Ted Gould <ted@gould.cx>
+
+ If we call the parse function and we already have the menu item built for the passed in value let's just use that and not bother looking any further.
+
+2011-03-08 Ted Gould <ted@gould.cx>
+
+ Disconnecting the child removed handlers
+
+2011-03-08 Ted Gould <ted@gould.cx>
+
+ Removing the dbusmenu menuitem from the parent if it gets removed on the GTK side
+
+2011-03-08 Ted Gould <ted@gould.cx>
+
+ Add a callback for child-removed as well
+
+2011-03-16 Ted Gould <ted@gould.cx>
+
+ Adding defines for the event identifiers
+
+2011-03-16 Ted Gould <ted@gould.cx>
+
+ Adding event defines to the documentation.
+
+2011-03-16 Ted Gould <ted@gould.cx>
+
+ Adding opened and closed to the spec
+
+2011-03-16 Ted Gould <ted@gould.cx>
+
+ Using the new defines
+
+2011-03-16 Ted Gould <ted@gould.cx>
+
+ Adding defines for the event ids
+
+2011-03-16 Ted Gould <ted@gould.cx>
+
+ Send open and close signals when menu visibility changes.
+
+2011-03-16 Michael Terry <mike@mterry.name>
+
+ add opened and closed events
+
+2011-03-16 Ted Gould <ted@gould.cx>
+
+ Empty images are images too
+
+2011-03-16 Michael Terry <mike@mterry.name>
+
+ handle empty image types
+
+2011-03-16 Ted Gould <ted@gould.cx>
+
+ Removing a noisy warning
+
+2011-03-15 Ted Gould <ted@gould.cx>
+
+ Not everything is a menuitem
+
+2011-03-16 Ted Gould <ted@gould.cx>
+
+ Adding needed dependencies to pkgconfig files
+
+2011-03-15 Ted Gould <ted@gould.cx>
+
+ Adding needed requirements to pkgconfig files.
+
+2011-03-14 Ted Gould <ted@gould.cx>
+
+ Handle NULL better in finding the label
+
+2011-03-14 Michael Terry <mike@mterry.name>
+
+ be a little more cautious about pointers in sanitize_label_text
+
+2011-03-14 Ted Gould <ted@gould.cx>
+
+ Lots of memory leak fixes
+
+2011-03-14 Chris Coulson <chrisccoulson@ubuntu.com>
+
+ The g_variant_get_* family of calls which return a GVariant
+ actually return reference counted, non-floating variant. Ensure that we
+ always keep pointers to these so that we can properly unref them.
+
+ The same also applies to g_variant_iter_next_value.
+
+ Also fix a couple of other minor leaks along the way. This fixes
+ LP: #722972
+
2011-03-10 Ted Gould <ted@gould.cx>
0.3.101
diff --git a/configure b/configure
index 257f96e..5baf0d2 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.67 for libdbusmenu 0.3.101.
+# Generated by GNU Autoconf 2.67 for libdbusmenu 0.3.102.
#
# Report bugs to <ted@canonical.com>.
#
@@ -703,8 +703,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='libdbusmenu'
PACKAGE_TARNAME='libdbusmenu'
-PACKAGE_VERSION='0.3.101'
-PACKAGE_STRING='libdbusmenu 0.3.101'
+PACKAGE_VERSION='0.3.102'
+PACKAGE_STRING='libdbusmenu 0.3.102'
PACKAGE_BUGREPORT='ted@canonical.com'
PACKAGE_URL=''
@@ -1541,7 +1541,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.3.101 to adapt to many kinds of systems.
+\`configure' configures libdbusmenu 0.3.102 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1611,7 +1611,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of libdbusmenu 0.3.101:";;
+ short | recursive ) echo "Configuration of libdbusmenu 0.3.102:";;
esac
cat <<\_ACEOF
@@ -1751,7 +1751,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-libdbusmenu configure 0.3.101
+libdbusmenu configure 0.3.102
generated by GNU Autoconf 2.67
Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2122,7 +2122,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.3.101, which was
+It was created by libdbusmenu $as_me 0.3.102, which was
generated by GNU Autoconf 2.67. Invocation command line was
$ $0 $@
@@ -2943,7 +2943,7 @@ fi
# Define the identity of the package.
PACKAGE=libdbusmenu
- VERSION=0.3.101
+ VERSION=0.3.102
# Some tools Automake needs.
@@ -13294,7 +13294,7 @@ fi
###########################
LIBDBUSMENU_CURRENT=3
-LIBDBUSMENU_REVISION=9
+LIBDBUSMENU_REVISION=10
LIBDBUSMENU_AGE=0
@@ -14616,7 +14616,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.3.101, which was
+This file was extended by libdbusmenu $as_me 0.3.102, which was
generated by GNU Autoconf 2.67. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -14682,7 +14682,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.3.101
+libdbusmenu config.status 0.3.102
configured by $0, generated by GNU Autoconf 2.67,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 8cfa421..84e0bec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,11 +1,11 @@
-AC_INIT(libdbusmenu, 0.3.101, ted@canonical.com)
+AC_INIT(libdbusmenu, 0.3.102, ted@canonical.com)
AC_COPYRIGHT([Copyright 2009,2010 Canonical])
AC_PREREQ(2.62)
AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(libdbusmenu, 0.3.101, [-Wno-portability])
+AM_INIT_AUTOMAKE(libdbusmenu, 0.3.102, [-Wno-portability])
AM_MAINTAINER_MODE
@@ -134,7 +134,7 @@ AC_PATH_PROG([XSLT_PROC], [xsltproc])
###########################
LIBDBUSMENU_CURRENT=3
-LIBDBUSMENU_REVISION=9
+LIBDBUSMENU_REVISION=10
LIBDBUSMENU_AGE=0
AC_SUBST(LIBDBUSMENU_CURRENT)
diff --git a/docs/libdbusmenu-glib/reference/libdbusmenu-glib-sections.txt b/docs/libdbusmenu-glib/reference/libdbusmenu-glib-sections.txt
index 84d8257..4d1e50a 100644
--- a/docs/libdbusmenu-glib/reference/libdbusmenu-glib-sections.txt
+++ b/docs/libdbusmenu-glib/reference/libdbusmenu-glib-sections.txt
@@ -70,6 +70,9 @@ DBUSMENU_MENUITEM_SHORTCUT_ALT
DBUSMENU_MENUITEM_SHORTCUT_CONTROL
DBUSMENU_MENUITEM_SHORTCUT_SHIFT
DBUSMENU_MENUITEM_SHORTCUT_SUPER
+DBUSMENU_MENUITEM_EVENT_ACTIVATED
+DBUSMENU_MENUITEM_EVENT_CLOSED
+DBUSMENU_MENUITEM_EVENT_OPENED
DbusmenuMenuitem
dbusmenu_menuitem_about_to_show_cb
dbusmenu_menuitem_buildvariant_slot_t
diff --git a/docs/libdbusmenu-glib/reference/version.xml b/docs/libdbusmenu-glib/reference/version.xml
index 1dd7a93..27d5f4a 100644
--- a/docs/libdbusmenu-glib/reference/version.xml
+++ b/docs/libdbusmenu-glib/reference/version.xml
@@ -1 +1 @@
-0.3.101
+0.3.102
diff --git a/docs/libdbusmenu-gtk/reference/version.xml b/docs/libdbusmenu-gtk/reference/version.xml
index 1dd7a93..27d5f4a 100644
--- a/docs/libdbusmenu-gtk/reference/version.xml
+++ b/docs/libdbusmenu-gtk/reference/version.xml
@@ -1 +1 @@
-0.3.101
+0.3.102
diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c
index 16e832d..2976436 100644
--- a/libdbusmenu-glib/client.c
+++ b/libdbusmenu-glib/client.c
@@ -598,20 +598,27 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data)
}
/* Callback all the folks we can find */
- GVariantIter * iter = g_variant_iter_new(g_variant_get_child_value(params, 0));
- GVariant * child;
+ GVariant * child = g_variant_get_child_value(params, 0);
+ GVariantIter * iter = g_variant_iter_new(child);
+ g_variant_unref(child);
while ((child = g_variant_iter_next_value(iter)) != NULL) {
if (g_strcmp0(g_variant_get_type_string(child), "(ia{sv})") != 0) {
g_warning("Properties return signature is not '(ia{sv})' it is '%s'", g_variant_get_type_string(child));
+ g_variant_unref(child);
continue;
}
- gint id = g_variant_get_int32(g_variant_get_child_value(child, 0));
+ GVariant * idv = g_variant_get_child_value(child, 0);
+ gint id = g_variant_get_int32(idv);
+ g_variant_unref(idv);
+
GVariant * properties = g_variant_get_child_value(child, 1);
properties_listener_t * listener = find_listener(listeners, 0, id);
if (listener == NULL) {
g_warning("Unable to find listener for ID %d", id);
+ g_variant_unref(properties);
+ g_variant_unref(child);
continue;
}
@@ -621,6 +628,8 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data)
} else {
g_warning("Odd, we've already replied to the listener on ID %d", id);
}
+ g_variant_unref(properties);
+ g_variant_unref(child);
}
g_variant_iter_free(iter);
g_variant_unref(params);
@@ -676,7 +685,9 @@ get_properties_idle (gpointer user_data)
GVariant * variant_ids = g_variant_builder_end(&builder);
/* Build up a prop list to pass */
- g_variant_builder_init(&builder, g_variant_type_new("as"));
+ GVariantType * type = g_variant_type_new("as");
+ g_variant_builder_init(&builder, type);
+ g_variant_type_free(type);
/* TODO: need to use delayed property list here */
GVariant * variant_props = g_variant_builder_end(&builder);
@@ -1050,12 +1061,13 @@ 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, "TextDirection");
if (textdir != NULL) {
- GVariant * str = textdir;
- if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) {
- str = g_variant_get_variant(str);
+ if (g_variant_is_of_type(textdir, G_VARIANT_TYPE_VARIANT)) {
+ GVariant * tmp = g_variant_get_variant(textdir);
+ g_variant_unref(textdir);
+ textdir = tmp;
}
- priv->text_direction = dbusmenu_text_direction_get_value_from_nick(g_variant_get_string(str, NULL));
+ priv->text_direction = dbusmenu_text_direction_get_value_from_nick(g_variant_get_string(textdir, NULL));
g_object_notify(G_OBJECT(user_data), DBUSMENU_CLIENT_PROP_TEXT_DIRECTION);
g_variant_unref(textdir);
@@ -1063,13 +1075,14 @@ menuproxy_build_cb (GObject * object, GAsyncResult * res, gpointer user_data)
/* Check the status if available */
GVariant * status = g_dbus_proxy_get_cached_property(priv->menuproxy, "Status");
- if (textdir != NULL) {
- GVariant * str = status;
- if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) {
- str = g_variant_get_variant(str);
+ if (status != NULL) {
+ if (g_variant_is_of_type(status, G_VARIANT_TYPE_VARIANT)) {
+ GVariant * tmp = g_variant_get_variant(status);
+ g_variant_unref(status);
+ status = tmp;
}
- priv->status = dbusmenu_status_get_value_from_nick(g_variant_get_string(str, NULL));
+ priv->status = dbusmenu_status_get_value_from_nick(g_variant_get_string(status, NULL));
g_object_notify(G_OBJECT(user_data), DBUSMENU_CLIENT_PROP_STATUS);
g_variant_unref(status);
@@ -1142,20 +1155,22 @@ menuproxy_prop_changed_cb (GDBusProxy * proxy, GVariant * properties, GStrv inva
g_variant_iter_init(&iters, properties);
while (g_variant_iter_next(&iters, "{sv}", &key, &value)) {
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);
+ if (g_variant_is_of_type(value, G_VARIANT_TYPE_VARIANT)) {
+ GVariant * tmp = g_variant_get_variant(value);
+ g_variant_unref(value);
+ value = tmp;
}
- priv->text_direction = dbusmenu_text_direction_get_value_from_nick(g_variant_get_string(str, NULL));
+ priv->text_direction = dbusmenu_text_direction_get_value_from_nick(g_variant_get_string(value, NULL));
}
if (g_strcmp0(key, "Status") == 0) {
- GVariant * str = value;
- if (g_variant_is_of_type(str, G_VARIANT_TYPE_VARIANT)) {
- str = g_variant_get_variant(str);
+ if (g_variant_is_of_type(value, G_VARIANT_TYPE_VARIANT)) {
+ GVariant * tmp = g_variant_get_variant(value);
+ g_variant_unref(value);
+ value = tmp;
}
- priv->status = dbusmenu_status_get_value_from_nick(g_variant_get_string(str, NULL));
+ priv->status = dbusmenu_status_get_value_from_nick(g_variant_get_string(value, NULL));
}
if (g_strcmp0(key, "IconThemePath") == 0) {
if (priv->icon_dirs != NULL) {
@@ -1224,11 +1239,14 @@ menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVarian
/* Remove before adding just incase there is a duplicate, against the
rules, but we can handle it so let's do it. */
GVariantIter ritems;
- g_variant_iter_init(&ritems, g_variant_get_child_value(params, 1));
+ GVariant * ritemsv = g_variant_get_child_value(params, 1);
+ g_variant_iter_init(&ritems, ritemsv);
GVariant * ritem;
while ((ritem = g_variant_iter_next_value(&ritems)) != NULL) {
- gint id = g_variant_get_int32(g_variant_get_child_value(ritem, 0));
+ GVariant * idv = g_variant_get_child_value(ritem, 0);
+ gint id = g_variant_get_int32(idv);
+ g_variant_unref(idv);
DbusmenuMenuitem * menuitem = dbusmenu_menuitem_find_id(priv->root, id);
if (menuitem == NULL) {
@@ -1236,7 +1254,8 @@ menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVarian
}
GVariantIter properties;
- g_variant_iter_init(&properties, g_variant_get_child_value(ritem, 1));
+ GVariant * propv = g_variant_get_child_value(ritem, 1);
+ g_variant_iter_init(&properties, propv);
gchar * property;
while (g_variant_iter_next(&properties, "s", &property)) {
@@ -1245,16 +1264,23 @@ menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVarian
g_free(property);
}
g_variant_unref(ritem);
+ g_variant_unref(propv);
}
+ g_variant_unref(ritemsv);
GVariantIter items;
- g_variant_iter_init(&items, g_variant_get_child_value(params, 0));
+ GVariant * itemsv = g_variant_get_child_value(params, 0);
+ g_variant_iter_init(&items, itemsv);
GVariant * item;
while ((item = g_variant_iter_next_value(&items)) != NULL) {
- gint id = g_variant_get_int32(g_variant_get_child_value(item, 0));
+ GVariant * idv = g_variant_get_child_value(item, 0);
+ gint id = g_variant_get_int32(idv);
+ g_variant_unref(idv);
+
GVariantIter properties;
- g_variant_iter_init(&properties, g_variant_get_child_value(item, 1));
+ GVariant * propv = g_variant_get_child_value(item, 1);
+ g_variant_iter_init(&properties, propv);
gchar * property;
GVariant * value;
@@ -1263,14 +1289,21 @@ menuproxy_signal_cb (GDBusProxy * proxy, gchar * sender, gchar * signal, GVarian
if (G_LIKELY(g_variant_is_of_type(value, G_VARIANT_TYPE_VARIANT))) {
/* Unboxing if needed */
internalvalue = g_variant_get_variant(value);
+ g_variant_unref(value);
}
id_prop_update(proxy, id, property, internalvalue, client);
+ g_variant_unref(internalvalue);
}
+ g_variant_unref(propv);
+ g_variant_unref(item);
}
+ g_variant_unref(itemsv);
} else if (g_strcmp0(signal, "ItemPropertyUpdated") == 0) {
gint id; gchar * property; GVariant * value;
g_variant_get(params, "(isv)", &id, &property, &value);
id_prop_update(proxy, id, property, value, client);
+ g_free(property);
+ g_variant_unref(value);
} else if (g_strcmp0(signal, "ItemUpdated") == 0) {
gint id;
g_variant_get(params, "(i)", &id);
@@ -1594,7 +1627,9 @@ parse_layout_xml(DbusmenuClient * client, GVariant * layout, DbusmenuMenuitem *
}
/* First verify and figure out what we've got */
- gint id = g_variant_get_int32(g_variant_get_child_value(layout, 0));
+ GVariant * idv = g_variant_get_child_value(layout, 0);
+ gint id = g_variant_get_int32(idv);
+ g_variant_unref(idv);
if (id < 0) {
return NULL;
}
@@ -1607,8 +1642,10 @@ parse_layout_xml(DbusmenuClient * client, GVariant * layout, DbusmenuMenuitem *
/* Some variables */
GVariantIter children;
- g_variant_iter_init(&children, g_variant_get_child_value(layout, 2));
- GVariant * child;
+ GVariant * childrenv;
+
+ childrenv = g_variant_get_child_value(layout, 2);
+ g_variant_iter_init(&children, childrenv);
guint position = 0;
GList * oldchildren = g_list_copy(dbusmenu_menuitem_get_children(item));
@@ -1616,16 +1653,22 @@ parse_layout_xml(DbusmenuClient * client, GVariant * layout, DbusmenuMenuitem *
/* Go through all the XML Nodes and make sure that we have menuitems
to cover those XML nodes. */
+ GVariant * child;
while ((child = g_variant_iter_next_value(&children)) != NULL) {
/* g_debug("Looking at child: %d", position); */
if (g_variant_is_of_type(child, G_VARIANT_TYPE_VARIANT)) {
- child = g_variant_get_variant(child);
+ GVariant * tmp = g_variant_get_variant(child);
+ g_variant_unref(child);
+ child = tmp;
}
- gint childid = g_variant_get_int32(g_variant_get_child_value(child, 0));
+ GVariant * childidv = g_variant_get_child_value(child, 0);
+ gint childid = g_variant_get_int32(childidv);
+ g_variant_unref(childidv);
if (childid < 0) {
/* Don't increment the position when there isn't a valid
node in the XML tree. It's probably a comment. */
+ g_variant_unref(child);
continue;
}
DbusmenuMenuitem * childmi = NULL;
@@ -1665,10 +1708,12 @@ parse_layout_xml(DbusmenuClient * client, GVariant * layout, DbusmenuMenuitem *
GVariantIter iter;
gchar * prop;
GVariant * value;
+ GVariant * child_props;
/* 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));
+ child_props = g_variant_get_child_value(child, 1);
+ g_variant_iter_init(&iter, child_props);
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);
@@ -1678,15 +1723,17 @@ parse_layout_xml(DbusmenuClient * client, GVariant * layout, DbusmenuMenuitem *
}
/* Now go through and do all the properties. */
- g_variant_iter_init(&iter, g_variant_get_child_value(child, 1));
+ g_variant_iter_init(&iter, child_props);
while (g_variant_iter_next(&iter, "{sv}", &prop, &value)) {
dbusmenu_menuitem_property_set_variant(childmi, prop, value);
g_free(prop);
g_variant_unref(value);
}
+ g_variant_unref(child_props);
}
position++;
+ g_variant_unref(child);
}
/* Remove any children that are no longer used by this version of
@@ -1709,19 +1756,24 @@ parse_layout_xml(DbusmenuClient * client, GVariant * layout, DbusmenuMenuitem *
}
/* now it's time to recurse down the tree. */
- g_variant_iter_init(&children, g_variant_get_child_value(layout, 2));
+ g_variant_iter_init(&children, childrenv);
child = g_variant_iter_next_value(&children);
GList * childmis = dbusmenu_menuitem_get_children(item);
while (child != NULL && childmis != NULL) {
if (g_variant_is_of_type(child, G_VARIANT_TYPE_VARIANT)) {
- child = g_variant_get_variant(child);
+ GVariant * tmp = g_variant_get_variant(child);
+ g_variant_unref(child);
+ child = tmp;
}
- gint xmlid = g_variant_get_int32(g_variant_get_child_value(child, 0));
+ GVariant * xmlidv = g_variant_get_child_value(child, 0);
+ gint xmlid = g_variant_get_int32(xmlidv);
+ g_variant_unref(xmlidv);
/* If this isn't a valid menu item we need to move on
until we have one. This avoids things like comments. */
if (xmlid < 0) {
+ g_variant_unref(child);
child = g_variant_iter_next_value(&children);
continue;
}
@@ -1733,10 +1785,13 @@ parse_layout_xml(DbusmenuClient * client, GVariant * layout, DbusmenuMenuitem *
parse_layout_xml(client, child, DBUSMENU_MENUITEM(childmis->data), item, proxy);
+ g_variant_unref(child);
child = g_variant_iter_next_value(&children);
childmis = g_list_next(childmis);
}
+ g_variant_unref(childrenv);
+
if (child != NULL) {
g_warning("Sync failed, now we've got extra layout nodes.");
}
@@ -1801,6 +1856,7 @@ update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data)
GError * error = NULL;
GVariant * params = NULL;
+ GVariant * layout = NULL;
params = g_dbus_proxy_call_finish(G_DBUS_PROXY(proxy), res, &error);
@@ -1810,8 +1866,11 @@ update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data)
goto out;
}
- guint rev = g_variant_get_uint32(g_variant_get_child_value(params, 0));
- GVariant * layout = g_variant_get_child_value(params, 1);
+ GVariant * revv = g_variant_get_child_value(params, 0);
+ guint rev = g_variant_get_uint32(revv);
+ g_variant_unref(revv);
+
+ layout = g_variant_get_child_value(params, 1);
guint parseable = parse_layout(client, layout);
@@ -1839,6 +1898,10 @@ out:
priv->layoutcall = NULL;
}
+ if (layout != NULL) {
+ g_variant_unref(layout);
+ }
+
if (params != NULL) {
g_variant_unref(params);
}
diff --git a/libdbusmenu-glib/dbus-menu.xml b/libdbusmenu-glib/dbus-menu.xml
index efb55d4..a36c148 100644
--- a/libdbusmenu-glib/dbus-menu.xml
+++ b/libdbusmenu-glib/dbus-menu.xml
@@ -294,6 +294,8 @@ License version 3 and version 2.1 along with this program. If not, see
@li "clicked"
@li "hovered"
+ @li "opened"
+ @li "closed"
Vendor specific events can be added by prefixing them with "x-<vendor>-"
]]></dox:d>
diff --git a/libdbusmenu-glib/enum-types.c b/libdbusmenu-glib/enum-types.c
index dae615c..2520461 100644
--- a/libdbusmenu-glib/enum-types.c
+++ b/libdbusmenu-glib/enum-types.c
@@ -30,7 +30,7 @@ License version 3 and version 2.1 along with this program. If not, see
#include "enum-types.h"
-#include "./types.h"
+#include "types.h"
/**
dbusmenu_text_direction_get_type:
diff --git a/libdbusmenu-glib/enum-types.h b/libdbusmenu-glib/enum-types.h
index f75ec64..d86ba63 100644
--- a/libdbusmenu-glib/enum-types.h
+++ b/libdbusmenu-glib/enum-types.h
@@ -36,10 +36,13 @@ License version 3 and version 2.1 along with this program. If not, see
G_BEGIN_DECLS
/* Enumerations from file: "./types.h" */
-#include "./types.h"
+#include "types.h"
+
+
GType dbusmenu_text_direction_get_type (void) G_GNUC_CONST;
const gchar * dbusmenu_text_direction_get_nick (DbusmenuTextDirection value) G_GNUC_CONST;
DbusmenuTextDirection dbusmenu_text_direction_get_value_from_nick (const gchar * nick) G_GNUC_CONST;
+
/**
DBUSMENU_TYPE_TEXT_DIRECTION:
@@ -48,9 +51,11 @@ DbusmenuTextDirection dbusmenu_text_direction_get_value_from_nick (const gchar *
*/
#define DBUSMENU_TYPE_TEXT_DIRECTION (dbusmenu_text_direction_get_type())
+
GType dbusmenu_status_get_type (void) G_GNUC_CONST;
const gchar * dbusmenu_status_get_nick (DbusmenuStatus value) G_GNUC_CONST;
DbusmenuStatus dbusmenu_status_get_value_from_nick (const gchar * nick) G_GNUC_CONST;
+
/**
DBUSMENU_TYPE_STATUS:
diff --git a/libdbusmenu-glib/menuitem.c b/libdbusmenu-glib/menuitem.c
index 2e5a345..70b5fd2 100644
--- a/libdbusmenu-glib/menuitem.c
+++ b/libdbusmenu-glib/menuitem.c
@@ -430,7 +430,7 @@ get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec)
static void
handle_event (DbusmenuMenuitem * mi, const gchar * name, GVariant * value, guint timestamp)
{
- if (g_strcmp0(name, "clicked") == 0) {
+ if (g_strcmp0(name, DBUSMENU_MENUITEM_EVENT_ACTIVATED) == 0) {
g_signal_emit(G_OBJECT(mi), signals[ITEM_ACTIVATED], 0, timestamp, TRUE);
}
diff --git a/libdbusmenu-glib/menuitem.h b/libdbusmenu-glib/menuitem.h
index f4eb989..afd1d4e 100644
--- a/libdbusmenu-glib/menuitem.h
+++ b/libdbusmenu-glib/menuitem.h
@@ -267,6 +267,32 @@ G_BEGIN_DECLS
*/
#define DBUSMENU_MENUITEM_CHILD_DISPLAY_SUBMENU "submenu"
+/**
+ * DBUSMENU_MENUITEM_EVENT_ACTIVATED:
+ *
+ * String for the event identifier when a menu item is clicked
+ * on by the user.
+ */
+#define DBUSMENU_MENUITEM_EVENT_ACTIVATED "clicked"
+
+/**
+ * DBUSMENU_MENUITEM_EVENT_OPENED:
+ *
+ * String for the event identifier when a menu is opened and
+ * displayed to the user. Only valid for items that contain
+ * submenus.
+ */
+#define DBUSMENU_MENUITEM_EVENT_OPENED "opened"
+
+/**
+ * DBUSMENU_MENUITEM_EVENT_CLOSED:
+ *
+ * String for the event identifier when a menu is closed and
+ * displayed to the user. Only valid for items that contain
+ * submenus.
+ */
+#define DBUSMENU_MENUITEM_EVENT_CLOSED "closed"
+
typedef struct _DbusmenuMenuitemPrivate DbusmenuMenuitemPrivate;
/**
diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c
index 510e74e..497808b 100644
--- a/libdbusmenu-gtk/client.c
+++ b/libdbusmenu-gtk/client.c
@@ -458,7 +458,7 @@ menu_pressed_cb (GtkMenuItem * gmi, DbusmenuMenuitem * mi)
{
if (gtk_menu_item_get_submenu(gmi) == NULL) {
GVariant * variant = g_variant_new("i", 0);
- dbusmenu_menuitem_handle_event(mi, "clicked", variant, gtk_get_current_event_time());
+ dbusmenu_menuitem_handle_event(mi, DBUSMENU_MENUITEM_EVENT_ACTIVATED, variant, gtk_get_current_event_time());
} else {
/* TODO: We need to stop the display of the submenu
until this callback returns. */
@@ -467,6 +467,15 @@ menu_pressed_cb (GtkMenuItem * gmi, DbusmenuMenuitem * mi)
return TRUE;
}
+static void
+submenu_notify_visible_cb (GtkWidget * menu, GParamSpec * pspec, DbusmenuMenuitem * mi)
+{
+ if (gtk_widget_get_visible (menu))
+ dbusmenu_menuitem_handle_event(mi, DBUSMENU_MENUITEM_EVENT_OPENED, NULL, gtk_get_current_event_time());
+ else
+ dbusmenu_menuitem_handle_event(mi, DBUSMENU_MENUITEM_EVENT_CLOSED, NULL, gtk_get_current_event_time());
+}
+
/* Process the visible property */
static void
process_visible (DbusmenuMenuitem * mi, GtkMenuItem * gmi, GVariant * value)
@@ -740,11 +749,12 @@ new_child (DbusmenuMenuitem * mi, DbusmenuMenuitem * child, guint position, Dbus
GtkMenuItem * parent = dbusmenu_gtkclient_menuitem_get(gtkclient, mi);
gtk_menu_item_set_submenu(parent, GTK_WIDGET(menu));
+
+ g_signal_connect(menu, "notify::visible", G_CALLBACK(submenu_notify_visible_cb), mi);
}
GtkMenuItem * childmi = dbusmenu_gtkclient_menuitem_get(gtkclient, child);
gtk_menu_shell_insert(GTK_MENU_SHELL(menu), GTK_WIDGET(childmi), position);
- gtk_widget_show(GTK_WIDGET(menu));
return;
}
diff --git a/libdbusmenu-gtk/dbusmenu-gtk-0.4.pc.in b/libdbusmenu-gtk/dbusmenu-gtk-0.4.pc.in
index 8784556..9a1b460 100644
--- a/libdbusmenu-gtk/dbusmenu-gtk-0.4.pc.in
+++ b/libdbusmenu-gtk/dbusmenu-gtk-0.4.pc.in
@@ -5,7 +5,7 @@ bindir=@bindir@
includedir=@includedir@
Cflags: -I${includedir}/libdbusmenu-0.4
-Requires: dbusmenu-glib-0.4
+Requires: dbusmenu-glib-0.4 gdk-pixbuf-2.0 gtk+-2.0
Libs: -L${libdir} -ldbusmenu-gtk
Name: libdbusmenu-gtk
diff --git a/libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc.in b/libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc.in
index 804b13e..c297db3 100644
--- a/libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc.in
+++ b/libdbusmenu-gtk/dbusmenu-gtk3-0.4.pc.in
@@ -5,7 +5,7 @@ bindir=@bindir@
includedir=@includedir@
Cflags: -I${includedir}/libdbusmenu-0.4
-Requires: dbusmenu-glib-0.4
+Requires: dbusmenu-glib-0.4 gdk-pixbuf-2.0 gtk+-3.0
Libs: -L${libdir} -ldbusmenu-gtk3
Name: libdbusmenu-gtk3
diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c
index 1b032bb..9d93a1e 100644
--- a/libdbusmenu-gtk/parser.c
+++ b/libdbusmenu-gtk/parser.c
@@ -69,6 +69,9 @@ static void action_notify_cb (GtkAction * action,
static void child_added_cb (GtkContainer * menu,
GtkWidget * widget,
gpointer data);
+static void child_removed_cb (GtkContainer * menu,
+ GtkWidget * widget,
+ gpointer data);
static void theme_changed_cb (GtkIconTheme * theme,
gpointer data);
static void item_activated (DbusmenuMenuitem * item,
@@ -98,15 +101,25 @@ static void menuitem_notify_cb (GtkWidget * widget,
DbusmenuMenuitem *
dbusmenu_gtk_parse_menu_structure (GtkWidget * widget)
{
- g_return_val_if_fail(GTK_IS_MENU_ITEM(widget) || GTK_IS_MENU_SHELL(widget), NULL);
+ g_return_val_if_fail(GTK_IS_MENU_ITEM(widget) || GTK_IS_MENU_SHELL(widget), NULL);
+
+ DbusmenuMenuitem * returnval = NULL;
+ gpointer data = g_object_get_data(G_OBJECT(widget), CACHED_MENUITEM);
- RecurseContext recurse = {0};
+ if (data == NULL) {
+ RecurseContext recurse = {0};
- recurse.toplevel = gtk_widget_get_toplevel(widget);
+ recurse.toplevel = gtk_widget_get_toplevel(widget);
- parse_menu_structure_helper(widget, &recurse);
+ parse_menu_structure_helper(widget, &recurse);
+
+ returnval = recurse.parent;
+ } else {
+ returnval = DBUSMENU_MENUITEM(data);
+ g_object_ref(G_OBJECT(returnval));
+ }
- return recurse.parent;
+ return returnval;
}
/**
@@ -124,7 +137,9 @@ dbusmenu_gtk_parse_menu_structure (GtkWidget * widget)
DbusmenuMenuitem *
dbusmenu_gtk_parse_get_cached_item (GtkWidget * widget)
{
- g_return_val_if_fail(GTK_IS_MENU_ITEM(widget), NULL);
+ if (!GTK_IS_MENU_ITEM(widget)) {
+ return NULL;
+ }
return DBUSMENU_MENUITEM(g_object_get_data(G_OBJECT(widget), CACHED_MENUITEM));
}
@@ -160,6 +175,8 @@ parse_data_free (gpointer data)
if (pdata != NULL && pdata->shell != NULL) {
g_signal_handlers_disconnect_matched(pdata->shell, (GSignalMatchType)G_SIGNAL_MATCH_FUNC,
0, 0, NULL, G_CALLBACK(child_added_cb), NULL);
+ g_signal_handlers_disconnect_matched(pdata->shell, (GSignalMatchType)G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL, G_CALLBACK(child_removed_cb), NULL);
g_object_remove_weak_pointer(G_OBJECT(pdata->shell), (gpointer*)&pdata->shell);
}
@@ -246,7 +263,6 @@ new_menuitem (GtkWidget * widget)
static void
parse_menu_structure_helper (GtkWidget * widget, RecurseContext * recurse)
{
-
/* If this is a shell, then let's handle the items in it. */
if (GTK_IS_MENU_SHELL (widget)) {
/* Okay, this is a little janky and all.. but some applications update some
@@ -282,6 +298,10 @@ parse_menu_structure_helper (GtkWidget * widget, RecurseContext * recurse)
"child-added",
G_CALLBACK (child_added_cb),
recurse->parent);
+ g_signal_connect (G_OBJECT (widget),
+ "child-removed",
+ G_CALLBACK (child_removed_cb),
+ recurse->parent);
g_object_add_weak_pointer(G_OBJECT (widget), (gpointer*)&pdata->shell);
}
@@ -371,14 +391,20 @@ sanitize_label_text (const gchar * label)
which we don't. */
gchar * sanitized = NULL;
GError * error = NULL;
+
+ if (label == NULL) {
+ return NULL;
+ }
+
if (pango_parse_markup (label, -1, 0, NULL, &sanitized, NULL, &error)) {
return sanitized;
}
- else {
+
+ if (error != NULL) {
g_warning ("Could not parse '%s': %s", label, error->message);
g_error_free (error);
- return g_strdup (label);
}
+ return g_strdup (label);
}
static gchar *
@@ -533,6 +559,10 @@ construct_dbusmenu_for_widget (GtkWidget * widget)
"child-added",
G_CALLBACK (child_added_cb),
mi);
+ g_signal_connect (G_OBJECT (submenu),
+ "child-removed",
+ G_CALLBACK (child_removed_cb),
+ mi);
g_object_add_weak_pointer(G_OBJECT(submenu), (gpointer*)&pdata->shell);
}
@@ -625,6 +655,9 @@ update_icon (DbusmenuMenuitem *menuitem, GtkImage *image)
if (image != NULL && should_show_image (image)) {
switch (gtk_image_get_storage_type (image)) {
+ case GTK_IMAGE_EMPTY:
+ break;
+
case GTK_IMAGE_PIXBUF:
pixbuf = g_object_ref (gtk_image_get_pixbuf (image));
break;
@@ -940,6 +973,28 @@ child_added_cb (GtkContainer *menu, GtkWidget *widget, gpointer data)
parse_menu_structure_helper(widget, &recurse);
}
+/* A child item was added to a menu we're watching. Let's try to integrate it. */
+static void
+child_removed_cb (GtkContainer *menu, GtkWidget *widget, gpointer data)
+{
+ gpointer pmi = g_object_get_data(G_OBJECT(widget), CACHED_MENUITEM);
+ if (pmi == NULL) {
+ return;
+ }
+
+ DbusmenuMenuitem * child = DBUSMENU_MENUITEM(pmi);
+
+ pmi = g_object_get_data(G_OBJECT(menu), CACHED_MENUITEM);
+ if (pmi == NULL) {
+ return;
+ }
+
+ DbusmenuMenuitem * parent = DBUSMENU_MENUITEM(pmi);
+
+ dbusmenu_menuitem_child_delete(parent, child);
+ return;
+}
+
static void
theme_changed_cb (GtkIconTheme *theme, gpointer data)
{