← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~agateau/dbusmenu/about-to-show into lp:dbusmenu

 

Aurélien Gâteau has proposed merging lp:~agateau/dbusmenu/about-to-show into lp:dbusmenu.

    Requested reviews:
    DBus Menu Team (dbusmenu-team)


This changeset adds the "bool AboutToShow(int)" method and ensures this method is called when menus are about to show.

Current code does not exploit the returned value, which should be set to true by the server if the menu has been updated. It should nevertheless ensure KDE application menus will continue to show up correctly in the GNOME desktop when the hack I introduced in dbusmenu-qt for Lucid a3 is removed.
-- 
https://code.launchpad.net/~agateau/dbusmenu/about-to-show/+merge/20570
Your team ayatana-commits is subscribed to branch lp:dbusmenu.
=== modified file 'libdbusmenu-glib/client-menuitem.c'
--- libdbusmenu-glib/client-menuitem.c	2010-02-04 02:45:12 +0000
+++ libdbusmenu-glib/client-menuitem.c	2010-03-03 16:52:15 +0000
@@ -46,6 +46,7 @@
 static void dbusmenu_client_menuitem_dispose    (GObject *object);
 static void dbusmenu_client_menuitem_finalize   (GObject *object);
 static void handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp);
+static void send_about_to_show (DbusmenuMenuitem * mi);
 
 G_DEFINE_TYPE (DbusmenuClientMenuitem, dbusmenu_client_menuitem, DBUSMENU_TYPE_MENUITEM);
 
@@ -61,6 +62,7 @@
 
 	DbusmenuMenuitemClass * mclass = DBUSMENU_MENUITEM_CLASS(klass);
 	mclass->handle_event = handle_event;
+	mclass->send_about_to_show = send_about_to_show;
 
 	return;
 }
@@ -104,3 +106,11 @@
 	dbusmenu_client_send_event(priv->client, dbusmenu_menuitem_get_id(mi), name, value, timestamp);
 	return;
 }
+
+static void
+send_about_to_show (DbusmenuMenuitem * mi)
+{
+	DbusmenuClientMenuitemPrivate * priv = DBUSMENU_CLIENT_MENUITEM_GET_PRIVATE(mi);
+	dbusmenu_client_send_about_to_show(priv->client, dbusmenu_menuitem_get_id(mi));
+	return;
+}

=== modified file 'libdbusmenu-glib/client.c'
--- libdbusmenu-glib/client.c	2010-02-24 19:17:38 +0000
+++ libdbusmenu-glib/client.c	2010-03-03 16:52:15 +0000
@@ -668,6 +668,36 @@
 	return;
 }
 
+static void
+about_to_show_cb (DBusGProxy * proxy, gboolean need_update, GError * error, gpointer userdata)
+{
+	DbusmenuClient * client = DBUSMENU_CLIENT(userdata);
+	if (error != NULL) {
+		g_warning("Unable to send about_to_show: %s", error->message);
+		return;
+	}
+
+	if (need_update) {
+		update_layout(client);
+	}
+	return;
+}
+
+void
+dbusmenu_client_send_about_to_show(DbusmenuClient * client, gint id)
+{
+	DbusmenuClientPrivate * priv = DBUSMENU_CLIENT_GET_PRIVATE(client);
+	org_ayatana_dbusmenu_about_to_show_async (priv->menuproxy, id, about_to_show_cb, client);
+	/*
+	FIXME: We should wait until either
+	 - about_to_show_cb has been called and need_update was false
+	 - about_to_show_cb has been called, need_update was true and menu has been
+	   updated
+	 - about_to_show_cb has not been called and we already waited for 10msecs
+	*/
+	return;
+}
+
 /* Parse recursively through the XML and make it into
    objects as need be */
 static DbusmenuMenuitem *

=== modified file 'libdbusmenu-glib/client.h'
--- libdbusmenu-glib/client.h	2010-02-04 17:59:00 +0000
+++ libdbusmenu-glib/client.h	2010-03-03 16:52:15 +0000
@@ -109,6 +109,8 @@
                                                         const gchar * name,
                                                         const GValue * value,
                                                         guint timestamp);
+void                 dbusmenu_client_send_about_to_show(DbusmenuClient * client,
+                                                        gint id);
 
 /**
 	SECTION:client

=== modified file 'libdbusmenu-glib/dbus-menu.xml'
--- libdbusmenu-glib/dbus-menu.xml	2010-02-04 23:56:30 +0000
+++ libdbusmenu-glib/dbus-menu.xml	2010-03-03 16:52:15 +0000
@@ -265,6 +265,11 @@
 			</arg>
 		</method>
 
+		<method name="AboutToShow">
+			<arg type="i" name="id" direction="in"></arg>
+			<arg type="b" name="needUpdate" direction="out"></arg>
+		</method>
+
 <!-- Signals -->
 		<signal name="ItemPropertyUpdated">
 			<dox:d>

=== modified file 'libdbusmenu-glib/menuitem.c'
--- libdbusmenu-glib/menuitem.c	2010-02-08 22:02:12 +0000
+++ libdbusmenu-glib/menuitem.c	2010-03-03 16:52:15 +0000
@@ -1203,3 +1203,17 @@
 	}
 	return;
 }
+void
+dbusmenu_menuitem_send_about_to_show (DbusmenuMenuitem * mi)
+{
+	g_return_if_fail(DBUSMENU_IS_MENUITEM(mi));
+	#ifdef MASSIVEDEBUGGING
+	g_debug("Submenu for menuitem %d (%s) is about to be shown", ID(mi), LABEL(mi));
+	#endif
+	DbusmenuMenuitemClass * class = DBUSMENU_MENUITEM_GET_CLASS(mi);
+
+	if (class->send_about_to_show != NULL) {
+		return class->send_about_to_show(mi);
+	}
+	return;
+}

=== modified file 'libdbusmenu-glib/menuitem.h'
--- libdbusmenu-glib/menuitem.h	2010-02-05 18:48:48 +0000
+++ libdbusmenu-glib/menuitem.h	2010-03-03 16:52:15 +0000
@@ -95,6 +95,8 @@
 	@handle_event: This function is to override how events are handled
 			by subclasses.  Look at #dbusmenu_menuitem_handle_event for
 			lots of good information.
+	@send_about_to_show: Virtual function that notifies server that the
+			client is about to show a menu.
 	@reserved1: Reserved for future use.
 	@reserved2: Reserved for future use.
 	@reserved3: Reserved for future use.
@@ -116,9 +118,10 @@
 	/* Virtual functions */
 	void (*buildxml) (GPtrArray * stringarray);
 	void (*handle_event) (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp);
+	void (*send_about_to_show) (DbusmenuMenuitem * mi);
 
 	void (*reserved1) (void);
-	void (*reserved2) (void);
+	/* void (*reserved2) (void); */
 	/* void (*reserved3) (void); */
 	/* void (*reserved4) (void); -- realized, realloc when bumping lib version */
 };
@@ -159,6 +162,7 @@
 
 void dbusmenu_menuitem_foreach (DbusmenuMenuitem * mi, void (*func) (DbusmenuMenuitem * mi, gpointer data), gpointer data);
 void dbusmenu_menuitem_handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, guint timestamp);
+void dbusmenu_menuitem_send_about_to_show (DbusmenuMenuitem * mi);
 
 /**
 	SECTION:menuitem

=== modified file 'libdbusmenu-glib/server.c'
--- libdbusmenu-glib/server.c	2010-02-18 16:27:53 +0000
+++ libdbusmenu-glib/server.c	2010-03-03 16:52:16 +0000
@@ -41,6 +41,7 @@
 static gboolean _dbusmenu_server_get_group_properties (DbusmenuServer * server, GArray * ids, GArray * properties, GHashTable ** values, GError ** error);
 static gboolean _dbusmenu_server_event (DbusmenuServer * server, gint id, gchar * eventid, GValue * data, guint timestamp, GError ** error);
 static gboolean _dbusmenu_server_get_children (DbusmenuServer * server, gint id, GPtrArray * properties, GPtrArray ** output, GError ** error);
+static gboolean _dbusmenu_server_about_to_show (DbusmenuServer * server, gint id, gboolean * need_update, GError ** error);
 
 #include "dbusmenu-server.h"
 
@@ -578,6 +579,28 @@
 	return TRUE;
 }
 
+static gboolean
+_dbusmenu_server_about_to_show (DbusmenuServer * server, gint id, gboolean * need_update, GError ** error)
+{
+	DbusmenuServerPrivate * priv = DBUSMENU_SERVER_GET_PRIVATE(server);
+	DbusmenuMenuitem * mi = dbusmenu_menuitem_find_id(priv->root, id);
+
+	if (mi == 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",
+			            id);
+		}
+		return FALSE;
+	}
+
+	/* GTK+ does not support about-to-show concept for now */
+	*need_update = FALSE;
+	return TRUE;
+}
+
 /* Public Interface */
 /**
 	dbusmenu_server_new:

=== modified file 'libdbusmenu-gtk/client.c'
--- libdbusmenu-gtk/client.c	2010-02-04 18:56:49 +0000
+++ libdbusmenu-gtk/client.c	2010-03-03 16:52:16 +0000
@@ -109,10 +109,14 @@
 static gboolean
 menu_pressed_cb (GtkMenuItem * gmi, DbusmenuMenuitem * mi)
 {
-	GValue value = {0};
-	g_value_init(&value, G_TYPE_INT);
-	g_value_set_int(&value, 0);
-	dbusmenu_menuitem_handle_event(mi, "clicked", &value, gtk_get_current_event_time());
+	if (gtk_menu_item_get_submenu(gmi) == NULL) {
+		GValue value = {0};
+		g_value_init(&value, G_TYPE_INT);
+		g_value_set_int(&value, 0);
+		dbusmenu_menuitem_handle_event(mi, "clicked", &value, gtk_get_current_event_time());
+	} else {
+		dbusmenu_menuitem_send_about_to_show(mi);
+	}
 	return TRUE;
 }
 

=== modified file 'libdbusmenu-gtk/menu.c'
--- libdbusmenu-gtk/menu.c	2009-10-05 14:00:34 +0000
+++ libdbusmenu-gtk/menu.c	2010-03-03 16:52:16 +0000
@@ -96,6 +96,17 @@
 }
 
 static void
+menu_focus_cb(DbusmenuGtkMenu * menu, gpointer userdata)
+{
+	g_debug(__FUNCTION__);
+	DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(menu);
+	if (priv->client != NULL) {
+		dbusmenu_client_send_about_to_show(DBUSMENU_CLIENT(priv->client), 0);
+	}
+	return;
+}
+
+static void
 dbusmenu_gtkmenu_init (DbusmenuGtkMenu *self)
 {
 	DbusmenuGtkMenuPrivate * priv = DBUSMENU_GTKMENU_GET_PRIVATE(self);
@@ -105,6 +116,8 @@
 	priv->dbus_object = NULL;
 	priv->dbus_name = NULL;
 
+	g_signal_connect(G_OBJECT(self), "focus", G_CALLBACK(menu_focus_cb), self);
+
 	return;
 }
 


Follow ups