aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/changelog8
-rw-r--r--libdbusmenu-glib/client.c3
-rw-r--r--libdbusmenu-glib/menuitem-private.h2
-rw-r--r--libdbusmenu-glib/menuitem.c86
-rw-r--r--libdbusmenu-glib/menuitem.h1
-rw-r--r--libdbusmenu-gtk/client.c2
-rw-r--r--libdbusmenu-gtk/menu.c2
7 files changed, 101 insertions, 3 deletions
diff --git a/debian/changelog b/debian/changelog
index 40c8222..03ce2e2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+libdbusmenu (0.2.9-0ubuntu1~ppa2~ordering5) UNRELEASED; urgency=low
+
+ * Upstream Merge
+ * Changing GTK layer to look at position in realized
+ children to avoid realization races.
+
+ -- Ted Gould <ted@ubuntu.com> Wed, 14 Apr 2010 23:52:15 -0500
+
libdbusmenu (0.2.9-0ubuntu1~ppa2~ordering4) lucid; urgency=low
* Upstream Merge
diff --git a/libdbusmenu-glib/client.c b/libdbusmenu-glib/client.c
index 3ce0ccb..d61b1ae 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"
@@ -645,7 +646,7 @@ 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);
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 515fd36..220f7e5 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.
@@ -518,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
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-gtk/client.c b/libdbusmenu-gtk/client.c
index 3de42fe..eabfa9b 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;
diff --git a/libdbusmenu-gtk/menu.c b/libdbusmenu-gtk/menu.c
index 103ecfe..409b7ed 100644
--- a/libdbusmenu-gtk/menu.c
+++ b/libdbusmenu-gtk/menu.c
@@ -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!");
}