← Back to team overview

ayatana-commits team mailing list archive

[Branch ~dbusmenu-team/dbusmenu/trunk] Rev 96: Changing the GTK layer to look at the realized location instead of the absolute location in the m...

 

Merge authors:
  Ted Gould (ted)
Related merge proposals:
  https://code.launchpad.net/~ted/dbusmenu/ordering-issues-again/+merge/23454
  proposed by: Ted Gould (ted)
  review: Approve - Kalle Valo (kvalo)
------------------------------------------------------------
revno: 96 [merge]
committer: Ted Gould <ted@xxxxxxxx>
branch nick: trunk
timestamp: Thu 2010-04-15 01:15:42 -0500
message:
  Changing the GTK layer to look at the realized location instead of the absolute location in the menu ordering.
modified:
  libdbusmenu-glib/client.c
  libdbusmenu-glib/menuitem-private.h
  libdbusmenu-glib/menuitem.c
  libdbusmenu-glib/menuitem.h
  libdbusmenu-glib/server.c
  libdbusmenu-gtk/client.c
  libdbusmenu-gtk/menu.c


--
lp:dbusmenu
https://code.launchpad.net/~dbusmenu-team/dbusmenu/trunk

Your team ayatana-commits is subscribed to branch lp:dbusmenu.
To unsubscribe from this branch go to https://code.launchpad.net/~dbusmenu-team/dbusmenu/trunk/+edit-subscription
=== modified file 'libdbusmenu-glib/client.c'
--- libdbusmenu-glib/client.c	2010-03-31 19:47:29 +0000
+++ libdbusmenu-glib/client.c	2010-04-15 04:41:32 +0000
@@ -35,6 +35,7 @@
 
 #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 @@
 	#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);
@@ -748,6 +749,7 @@
 			if (parent != NULL) {
 				dbusmenu_menuitem_child_delete(parent, item);
 			}
+			/* XXX: Should this be an unref?  Who's reffing this that it exists without a parent? */
 			g_object_unref(G_OBJECT(item));
 			item = NULL;
 		}
@@ -773,6 +775,7 @@
 		}
 	} 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 */
 		org_ayatana_dbusmenu_get_properties_async(proxy, id, (const gchar **)properties, menuitem_get_properties_replace_cb, item);
 	}

=== modified file 'libdbusmenu-glib/menuitem-private.h'
--- libdbusmenu-glib/menuitem-private.h	2010-01-21 23:13:52 +0000
+++ libdbusmenu-glib/menuitem-private.h	2010-04-15 04:40:22 +0000
@@ -34,6 +34,8 @@
 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
 

=== modified file 'libdbusmenu-glib/menuitem.c'
--- libdbusmenu-glib/menuitem.c	2010-03-31 18:51:48 +0000
+++ libdbusmenu-glib/menuitem.c	2010-04-15 04:47:01 +0000
@@ -59,6 +59,7 @@
 	GList * children;
 	GHashTable * properties;
 	gboolean root;
+	gboolean realized;
 };
 
 /* Signals */
@@ -278,6 +279,7 @@
 	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_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.
 
@@ -449,6 +491,7 @@
 	#ifdef MASSIVEDEBUGGING
 	g_debug("Menuitem %d (%s) signalling child removed %d (%s)", ID(user_data), LABEL(user_data), ID(data), LABEL(data));
 	#endif
+	g_object_unref(G_OBJECT(data));
 	g_signal_emit(G_OBJECT(user_data), signals[CHILD_REMOVED], 0, DBUSMENU_MENUITEM(data), TRUE);
 	return;
 }
@@ -517,6 +560,50 @@
 }
 
 /**
+	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 @@
 	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 @@
 	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;
 }
@@ -588,6 +681,7 @@
 	#ifdef MASSIVEDEBUGGING
 	g_debug("Menuitem %d (%s) signalling child removed %d (%s)", ID(mi), LABEL(mi), ID(child), LABEL(child));
 	#endif
+	g_object_unref(G_OBJECT(child));
 	g_signal_emit(G_OBJECT(mi), signals[CHILD_REMOVED], 0, child, TRUE);
 	return TRUE;
 }
@@ -611,10 +705,13 @@
 	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;
 }

=== modified file 'libdbusmenu-glib/menuitem.h'
--- libdbusmenu-glib/menuitem.h	2010-03-31 18:51:48 +0000
+++ libdbusmenu-glib/menuitem.h	2010-04-15 04:47:01 +0000
@@ -148,6 +148,7 @@
 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);

=== modified file 'libdbusmenu-glib/server.c'
--- libdbusmenu-glib/server.c	2010-03-31 17:29:20 +0000
+++ libdbusmenu-glib/server.c	2010-04-14 21:58:17 +0000
@@ -404,6 +404,16 @@
 		}
 	} 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);

=== modified file 'libdbusmenu-gtk/client.c'
--- libdbusmenu-gtk/client.c	2010-03-31 18:51:48 +0000
+++ libdbusmenu-gtk/client.c	2010-04-15 05:54:44 +0000
@@ -308,7 +308,7 @@
 
 	/* 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 @@
 	} 
 
 	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 @@
 	}
 
 	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;
 }

=== modified file 'libdbusmenu-gtk/menu.c'
--- libdbusmenu-gtk/menu.c	2010-03-31 18:49:32 +0000
+++ libdbusmenu-gtk/menu.c	2010-04-15 05:54:44 +0000
@@ -237,7 +237,7 @@
 	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 @@
 	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 @@
 
 	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!");
 	}