diff options
-rw-r--r-- | debian/changelog | 8 | ||||
-rw-r--r-- | libdbusmenu-glib/client.c | 3 | ||||
-rw-r--r-- | libdbusmenu-glib/menuitem-private.h | 2 | ||||
-rw-r--r-- | libdbusmenu-glib/menuitem.c | 86 | ||||
-rw-r--r-- | libdbusmenu-glib/menuitem.h | 1 | ||||
-rw-r--r-- | libdbusmenu-gtk/client.c | 2 | ||||
-rw-r--r-- | libdbusmenu-gtk/menu.c | 2 |
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!"); } |