diff options
author | Ted Gould <ted@gould.cx> | 2011-01-31 15:52:26 -0600 |
---|---|---|
committer | Ted Gould <ted@gould.cx> | 2011-01-31 15:52:26 -0600 |
commit | 284b6b17cfc3b0be1f371c4787eec795c166c7ca (patch) | |
tree | b79c3891b3af838a4f36857ac61044e5e81bf138 | |
parent | 6022220a0c208d0fea140ed3ed80e1806983f3b9 (diff) | |
parent | 6c339510a684ba9a8f01fc57188bb4953be0e30b (diff) | |
download | libdbusmenu-284b6b17cfc3b0be1f371c4787eec795c166c7ca.tar.gz libdbusmenu-284b6b17cfc3b0be1f371c4787eec795c166c7ca.tar.bz2 libdbusmenu-284b6b17cfc3b0be1f371c4787eec795c166c7ca.zip |
* New upstream release.
* Fix crashes on rapidly creating and destroying client
and menu objects (LP: #709754)
* Fix dynamically changed submenus to get the parsed
(LP: #696896)
* Fix bad signature on GetProperties with no hits
-rw-r--r-- | ChangeLog | 52 | ||||
-rwxr-xr-x | configure | 22 | ||||
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | debian/changelog | 11 | ||||
-rw-r--r-- | docs/libdbusmenu-glib/reference/version.xml | 2 | ||||
-rw-r--r-- | docs/libdbusmenu-gtk/reference/version.xml | 2 | ||||
-rw-r--r-- | libdbusmenu-glib/client.c | 40 | ||||
-rw-r--r-- | libdbusmenu-glib/server.c | 4 | ||||
-rw-r--r-- | libdbusmenu-gtk/menu.c | 39 | ||||
-rw-r--r-- | libdbusmenu-gtk/parser.c | 31 |
10 files changed, 180 insertions, 29 deletions
@@ -1,5 +1,57 @@ # Generated by Makefile. Do not edit. +2011-01-31 Ted Gould <ted@gould.cx> + + 0.3.95 + +2011-01-31 Ted Gould <ted@gould.cx> + + Fix the property return signature. + +2011-01-31 Michael Terry <mike@mterry.name> + + fix variant type of props return + +2011-01-31 Ted Gould <ted@gould.cx> + + Handling changing submenus by watching for the notify event + +2011-01-31 Ted Gould <ted@gould.cx> + + Handle the case where we don't have a cached item. Not sure how that'd be, but we shouldn't let it drop. + +2011-01-31 Ted Gould <ted@gould.cx> + + Switching to take_children() so that we can ensure all the data remains valid + +2011-01-28 Michael Terry <mike@mterry.name> + + notice new submenus + +2011-01-31 Ted Gould <ted@gould.cx> + + Fixing a set of issues with not keeping references to objects in callbacks. + +2011-01-31 Ted Gould <ted@gould.cx> + + Attaching bug number + +2011-01-31 Ted Gould <ted@gould.cx> + + Switching the properties callback to use custom structure so that we can reference the client throughout the callback. + +2011-01-31 Ted Gould <ted@gould.cx> + + Keeping the root so that we can remove the signal handlers. + +2011-01-31 Ted Gould <ted@gould.cx> + + Disconnect realized handler when we don't care about the item anymore. + +2011-01-31 Ted Gould <ted@gould.cx> + + Keep a ref to the client through-out the call to the update + 2011-01-27 Ted Gould <ted@gould.cx> 0.3.94 @@ -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.94. +# Generated by GNU Autoconf 2.67 for libdbusmenu 0.3.95. # # 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.94' -PACKAGE_STRING='libdbusmenu 0.3.94' +PACKAGE_VERSION='0.3.95' +PACKAGE_STRING='libdbusmenu 0.3.95' PACKAGE_BUGREPORT='ted@canonical.com' PACKAGE_URL='' @@ -1540,7 +1540,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.94 to adapt to many kinds of systems. +\`configure' configures libdbusmenu 0.3.95 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1610,7 +1610,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libdbusmenu 0.3.94:";; + short | recursive ) echo "Configuration of libdbusmenu 0.3.95:";; esac cat <<\_ACEOF @@ -1750,7 +1750,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libdbusmenu configure 0.3.94 +libdbusmenu configure 0.3.95 generated by GNU Autoconf 2.67 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2121,7 +2121,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.94, which was +It was created by libdbusmenu $as_me 0.3.95, which was generated by GNU Autoconf 2.67. Invocation command line was $ $0 $@ @@ -2942,7 +2942,7 @@ fi # Define the identity of the package. PACKAGE=libdbusmenu - VERSION=0.3.94 + VERSION=0.3.95 # Some tools Automake needs. @@ -13280,7 +13280,7 @@ fi ########################### LIBDBUSMENU_CURRENT=3 -LIBDBUSMENU_REVISION=2 +LIBDBUSMENU_REVISION=3 LIBDBUSMENU_AGE=0 @@ -14602,7 +14602,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.94, which was +This file was extended by libdbusmenu $as_me 0.3.95, which was generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14668,7 +14668,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.94 +libdbusmenu config.status 0.3.95 configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 619cb17..b479fce 100644 --- a/configure.ac +++ b/configure.ac @@ -1,11 +1,11 @@ -AC_INIT(libdbusmenu, 0.3.94, ted@canonical.com) +AC_INIT(libdbusmenu, 0.3.95, ted@canonical.com) AC_COPYRIGHT([Copyright 2009,2010 Canonical]) AC_PREREQ(2.62) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(libdbusmenu, 0.3.94, [-Wno-portability]) +AM_INIT_AUTOMAKE(libdbusmenu, 0.3.95, [-Wno-portability]) AM_MAINTAINER_MODE @@ -136,7 +136,7 @@ AC_PATH_PROG([XSLT_PROC], [xsltproc]) ########################### LIBDBUSMENU_CURRENT=3 -LIBDBUSMENU_REVISION=2 +LIBDBUSMENU_REVISION=3 LIBDBUSMENU_AGE=0 AC_SUBST(LIBDBUSMENU_CURRENT) diff --git a/debian/changelog b/debian/changelog index 01e5582..83aa7be 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,14 @@ +libdbusmenu (0.3.95-0ubuntu1~ppa1) UNRELEASED; urgency=low + + * New upstream release. + * Fix crashes on rapidly creating and destroying client + and menu objects (LP: #709754) + * Fix dynamically changed submenus to get the parsed + (LP: #696896) + * Fix bad signature on GetProperties with no hits + + -- Ted Gould <ted@ubuntu.com> Mon, 31 Jan 2011 15:45:37 -0600 + libdbusmenu (0.3.94-0ubuntu1) natty; urgency=low * New upstream release. diff --git a/docs/libdbusmenu-glib/reference/version.xml b/docs/libdbusmenu-glib/reference/version.xml index d48d6ae..14756e4 100644 --- a/docs/libdbusmenu-glib/reference/version.xml +++ b/docs/libdbusmenu-glib/reference/version.xml @@ -1 +1 @@ -0.3.94 +0.3.95 diff --git a/docs/libdbusmenu-gtk/reference/version.xml b/docs/libdbusmenu-gtk/reference/version.xml index d48d6ae..14756e4 100644 --- a/docs/libdbusmenu-gtk/reference/version.xml +++ b/docs/libdbusmenu-gtk/reference/version.xml @@ -1 +1 @@ -0.3.94 +0.3.95 diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c index b196c9f..5e492a3 100644 --- a/libdbusmenu-glib/client.c +++ b/libdbusmenu-glib/client.c @@ -129,6 +129,12 @@ struct _type_handler_t { gchar * type; }; +typedef struct _properties_callback_t properties_callback_t; +struct _properties_callback_t { + DbusmenuClient * client; + GArray * listeners; +}; + #define DBUSMENU_CLIENT_GET_PRIVATE(o) (DBUSMENU_CLIENT(o)->priv) #define DBUSMENU_INTERFACE "com.canonical.dbusmenu" @@ -512,7 +518,8 @@ find_listener (GArray * listeners, guint index, gint id) static void get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data) { - GArray * listeners = (GArray *)user_data; + properties_callback_t * cbdata = (properties_callback_t *)user_data; + GArray * listeners = cbdata->listeners; int i; GError * error = NULL; GVariant * params = NULL; @@ -526,9 +533,8 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data) properties_listener_t * listener = &g_array_index(listeners, properties_listener_t, i); listener->callback(NULL, error, listener->user_data); } - g_array_free(listeners, TRUE); g_error_free(error); - return; + goto out; } /* Callback all the folks we can find */ @@ -575,8 +581,11 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data) g_error_free(localerror); } +out: /* Clean up */ g_array_free(listeners, TRUE); + g_object_unref(cbdata->client); + g_free(user_data); return; } @@ -586,6 +595,7 @@ get_properties_callback (GObject *obj, GAsyncResult * res, gpointer user_data) static gboolean get_properties_idle (gpointer user_data) { + properties_callback_t * cbdata = NULL; DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(user_data); g_return_val_if_fail(priv->menuproxy != NULL, TRUE); @@ -616,6 +626,11 @@ get_properties_idle (gpointer user_data) g_variant_builder_add_value(&builder, variant_props); GVariant * variant_params = g_variant_builder_end(&builder); + cbdata = g_new(properties_callback_t, 1); + cbdata->listeners = priv->delayed_property_listeners; + cbdata->client = DBUSMENU_CLIENT(user_data); + g_object_ref(G_OBJECT(user_data)); + g_dbus_proxy_call(priv->menuproxy, "GetGroupProperties", variant_params, @@ -623,7 +638,7 @@ get_properties_idle (gpointer user_data) -1, /* timeout */ NULL, /* cancellable */ get_properties_callback, - priv->delayed_property_listeners); + cbdata); /* Free properties */ gchar ** dataregion = (gchar **)g_array_free(priv->delayed_property_list, FALSE); @@ -1553,11 +1568,6 @@ update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data) DbusmenuClient * client = DBUSMENU_CLIENT(data); DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client); - if (priv->layoutcall != NULL) { - g_object_unref(priv->layoutcall); - priv->layoutcall = NULL; - } - GError * error = NULL; GVariant * params = NULL; @@ -1566,7 +1576,7 @@ update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data) if (error != NULL) { g_warning("Getting layout failed: %s", error->message); g_error_free(error); - return; + goto out; } guint rev; @@ -1580,7 +1590,7 @@ update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data) if (parseable == 0) { g_warning("Unable to parse layout!"); - return; + goto out; } priv->my_revision = rev; @@ -1596,6 +1606,13 @@ update_layout_cb (GObject * proxy, GAsyncResult * res, gpointer data) update_layout(client); } +out: + if (priv->layoutcall != NULL) { + g_object_unref(priv->layoutcall); + priv->layoutcall = NULL; + } + + g_object_unref(G_OBJECT(client)); return; } @@ -1622,6 +1639,7 @@ update_layout (DbusmenuClient * client) priv->layoutcall = g_cancellable_new(); + g_object_ref(G_OBJECT(client)); g_dbus_proxy_call(priv->menuproxy, "GetLayout", g_variant_new("(i)", 0), /* root */ diff --git a/libdbusmenu-glib/server.c b/libdbusmenu-glib/server.c index adb9f91..777e4ef 100644 --- a/libdbusmenu-glib/server.c +++ b/libdbusmenu-glib/server.c @@ -946,9 +946,9 @@ bus_get_group_properties (DbusmenuServer * server, GVariant * params, GDBusMetho ret = g_variant_builder_end(&builder); } else { GError * error = NULL; - ret = g_variant_parse(g_variant_type_new("a(ia(sv))"), "[]", NULL, NULL, NULL); + ret = g_variant_parse(g_variant_type_new("a(ia{sv})"), "[]", NULL, NULL, NULL); if (error != NULL) { - g_warning("Unable to parse '[]' as a 'a(ia(sv))': %s", error->message); + g_warning("Unable to parse '[]' as a 'a(ia{sv})': %s", error->message); g_error_free(error); ret = NULL; } diff --git a/libdbusmenu-gtk/menu.c b/libdbusmenu-gtk/menu.c index 9c4f7f8..2a27fe2 100644 --- a/libdbusmenu-gtk/menu.c +++ b/libdbusmenu-gtk/menu.c @@ -46,6 +46,7 @@ enum { /* Private */ struct _DbusmenuGtkMenuPrivate { DbusmenuGtkClient * client; + DbusmenuMenuitem * root; gchar * dbus_object; gchar * dbus_name; @@ -63,6 +64,8 @@ static void get_property (GObject * obj, guint id, GValue * value, GParamSpec * /* Internal */ static void build_client (DbusmenuGtkMenu * self); static void child_realized (DbusmenuMenuitem * child, gpointer userdata); +static void remove_child_signals (gpointer data, gpointer user_data); +static void root_changed (DbusmenuGtkClient * client, DbusmenuMenuitem * newroot, DbusmenuGtkMenu * menu); /* GObject Stuff */ G_DEFINE_TYPE (DbusmenuGtkMenu, dbusmenu_gtkmenu, GTK_TYPE_MENU); @@ -127,6 +130,12 @@ dbusmenu_gtkmenu_dispose (GObject *object) { DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(object); + /* Remove signals from the root */ + if (priv->root != NULL) { + /* This will clear the root */ + root_changed(priv->client, NULL, DBUSMENU_GTKMENU(object)); + } + if (priv->client != NULL) { g_object_unref(G_OBJECT(priv->client)); priv->client = NULL; @@ -271,6 +280,10 @@ root_child_delete (DbusmenuMenuitem * root, DbusmenuMenuitem * child, DbusmenuGt #ifdef MASSIVEDEBUGGING g_debug("Root child deleted"); #endif + + /* Remove signal for realized */ + remove_child_signals(child, menu); + DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(menu); GtkWidget * item = GTK_WIDGET(dbusmenu_gtkclient_menuitem_get(priv->client, child)); if (item != NULL) { @@ -308,15 +321,41 @@ child_realized (DbusmenuMenuitem * child, gpointer userdata) return; } +/* Remove any signals we attached to children -- just realized right now */ +static void +remove_child_signals (gpointer data, gpointer user_data) +{ + g_signal_handlers_disconnect_by_func(G_OBJECT(data), child_realized, user_data); + return; +} + /* When the root menuitem changes we need to resetup things so that we're back in the game. */ static void root_changed (DbusmenuGtkClient * client, DbusmenuMenuitem * newroot, DbusmenuGtkMenu * menu) { + DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(menu); + + /* Clear out our interest in the old root */ + if (priv->root != NULL) { + GList * children = dbusmenu_menuitem_get_children(priv->root); + g_list_foreach(children, remove_child_signals, menu); + + g_signal_handlers_disconnect_by_func(G_OBJECT(priv->root), root_child_added, menu); + g_signal_handlers_disconnect_by_func(G_OBJECT(priv->root), root_child_moved, menu); + g_signal_handlers_disconnect_by_func(G_OBJECT(priv->root), root_child_delete, menu); + + g_object_unref(priv->root); + priv->root = NULL; + } + if (newroot == NULL) { gtk_widget_hide(GTK_WIDGET(menu)); return; } + priv->root = newroot; + g_object_ref(priv->root); + g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED, G_CALLBACK(root_child_added), menu); g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED, G_CALLBACK(root_child_moved), menu); g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(root_child_delete), menu); diff --git a/libdbusmenu-gtk/parser.c b/libdbusmenu-gtk/parser.c index 5d71585..7e5e7e1 100644 --- a/libdbusmenu-gtk/parser.c +++ b/libdbusmenu-gtk/parser.c @@ -649,6 +649,37 @@ widget_notify_cb (GtkWidget *widget, } } } + else if (pspec->name == g_intern_static_string ("submenu")) + { + /* The underlying submenu got swapped out. Let's see what it is now. */ + /* First, delete any children that may exist currently. */ + DbusmenuMenuitem * item = DBUSMENU_MENUITEM(g_object_get_data(G_OBJECT(widget), CACHED_MENUITEM)); + if (item != NULL) + { + GList * children = dbusmenu_menuitem_take_children (item); + GList * child = children; + while (child != NULL) { + g_object_unref (G_OBJECT(child->data)); + child = child->next; + } + g_list_free(children); + } + + /* Now parse new submenu. */ + RecurseContext recurse = {0}; + recurse.toplevel = gtk_widget_get_toplevel(widget); + recurse.parent = item; + + if (item != NULL) { + GtkWidget * menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)); + parse_menu_structure_helper(menu, &recurse); + } else { + /* Note: it would be really odd that we wouldn't have a cached + item, but we should handle that appropriately. */ + parse_menu_structure_helper(widget, &recurse); + g_object_unref(G_OBJECT(recurse.parent)); + } + } } static gboolean |