← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~ted/libindicate/menu-property-support into lp:libindicate

 

Ted Gould has proposed merging lp:~ted/libindicate/menu-property-support into lp:libindicate.

    Requested reviews:
    Indicator Applet Developers (indicator-applet-developers)


Adds a property for the menu as an object path.  With accessor functions
for setting the menu server.  Also a test!

-- 
https://code.launchpad.net/~ted/libindicate/menu-property-support/+merge/18366
Your team ayatana-commits is subscribed to branch lp:libindicate.
=== modified file 'configure.ac'
--- configure.ac	2009-10-11 15:05:13 +0000
+++ configure.ac	2010-02-01 06:32:14 +0000
@@ -33,7 +33,7 @@
 AC_SUBST(LIBINDICATE_AGE)
 
 ###########################
-# Libindicate versioning 
+# Libindicate GTK+ versioning 
 ###########################
 
 LIBINDICATEGTK_CURRENT=1
@@ -53,10 +53,12 @@
 GLIB_REQUIRED_VERSION=2.18
 GIO_REQUIRED_VERSION=2.18
 XML_REQUIRED_VERSION=2.6
+DBUSMENU_REQUIRED_VERSION=0.2.0
 
 PKG_CHECK_MODULES(LIBINDICATE, glib-2.0 >= $GLIB_REQUIRED_VERSION
                                gio-2.0 >= $GIO_REQUIRED_VERSION
                                dbus-glib-1 >= $DBUS_REQUIRED_VERSION
+                               dbusmenu-glib >= $DBUSMENU_REQUIRED_VERSION
                                libxml-2.0 >= $XML_REQUIRED_VERSION)
 AC_SUBST(LIBINDICATE_CFLAGS)
 AC_SUBST(LIBINDICATE_LIBS)

=== modified file 'libindicate/indicate-interface.xml'
--- libindicate/indicate-interface.xml	2009-09-08 21:56:49 +0000
+++ libindicate/indicate-interface.xml	2010-02-01 06:32:14 +0000
@@ -34,6 +34,7 @@
 		<property name="desktop" type="s" access="read" />
 		<property name="type"    type="s" access="read" />
 		<property name="count"   type="u" access="read" />
+		<property name="menu"    type="o" access="read" />
 
 <!-- Functions -->
 		<method name="GetIndicatorCount">

=== modified file 'libindicate/indicator.c'
--- libindicate/indicator.c	2009-09-14 14:48:43 +0000
+++ libindicate/indicator.c	2010-02-01 06:32:14 +0000
@@ -359,6 +359,23 @@
 }
 
 /**
+	indicate_indicator_get_server:
+	@indicator: a #IndicateIndicator to act on
+
+	Gets the server of the @indicator.
+
+	Return value: The server associated with the indicator
+		or NULL if error.
+*/
+IndicateServer *
+indicate_indicator_get_server (IndicateIndicator * indicator)
+{
+	g_return_val_if_fail(INDICATE_IS_INDICATOR(indicator), NULL);
+	IndicateIndicatorPrivate * priv = INDICATE_INDICATOR_GET_PRIVATE(indicator);
+	return priv->server;
+}
+
+/**
 	indicate_indicator_user_display:
 	@indicator: a #IndicateIndicator to act on
 

=== modified file 'libindicate/indicator.h'
--- libindicate/indicator.h	2009-09-14 14:48:43 +0000
+++ libindicate/indicator.h	2010-02-01 06:32:14 +0000
@@ -141,6 +141,7 @@
 
 /* Every entry has an ID, here's how to get it */
 guint indicate_indicator_get_id (IndicateIndicator * indicator);
+IndicateServer * indicate_indicator_get_server (IndicateIndicator * indicator);
 
 void indicate_indicator_user_display (IndicateIndicator * indicator);
 

=== modified file 'libindicate/listener.c'
--- libindicate/listener.c	2009-11-04 17:51:08 +0000
+++ libindicate/listener.c	2010-02-01 06:32:14 +0000
@@ -1011,6 +1011,10 @@
 		   let's grab the value and call the callback. */
 		guint val = g_value_get_uint(&property);
 		return cb_uint(listener, server, val, cb_data);
+	} else if (G_VALUE_TYPE(&property) == DBUS_TYPE_G_OBJECT_PATH && cb != NULL) {
+		const gchar * val = (const gchar *)g_value_get_boxed(&property);
+		gchar * propstr = g_strdup(val);
+		return cb(listener, server, propstr, cb_data);
 	} else {
 		/* WTF!?!?!?! */
 		g_warning("Property back from server that we didn't understand.");
@@ -1090,6 +1094,13 @@
 	return get_server_property(listener, server, NULL, callback, "count", data);
 }
 
+void
+indicate_listener_server_get_menu (IndicateListener * listener, IndicateListenerServer * server, indicate_listener_get_server_property_cb callback, gpointer data)
+{
+	return get_server_property(listener, server, callback, NULL, "menu", data);
+}
+
+
 const gchar *
 indicate_listener_server_get_dbusname (IndicateListenerServer * server)
 {

=== modified file 'libindicate/listener.h'
--- libindicate/listener.h	2009-09-14 15:01:18 +0000
+++ libindicate/listener.h	2010-02-01 06:32:14 +0000
@@ -163,6 +163,10 @@
                                                             IndicateListenerServer * server,
                                                             indicate_listener_get_server_uint_property_cb callback,
                                                             gpointer data);
+void                  indicate_listener_server_get_menu    (IndicateListener * listener,
+                                                            IndicateListenerServer * server,
+                                                            indicate_listener_get_server_property_cb callback,
+                                                            gpointer data);
 const gchar *         indicate_listener_server_get_dbusname      (IndicateListenerServer * server);
 guint                 indicate_listener_indicator_get_id         (IndicateListenerIndicator * indicator);
 void                  indicate_listener_server_show_interest     (IndicateListener * listener,

=== modified file 'libindicate/server.c'
--- libindicate/server.c	2009-09-17 15:00:42 +0000
+++ libindicate/server.c	2010-02-01 06:32:14 +0000
@@ -32,6 +32,7 @@
 #include "server-marshal.h"
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
+#include <libdbusmenu-glib/server.h>
 
 /* Errors */
 enum {
@@ -74,7 +75,8 @@
 	PROP_0,
 	PROP_DESKTOP,
 	PROP_TYPE,
-	PROP_COUNT
+	PROP_COUNT,
+	PROP_MENU
 };
 
 static guint signals[LAST_SIGNAL] = { 0 };
@@ -96,6 +98,8 @@
 	gchar * type;
 	guint count;
 
+	DbusmenuServer * dbusmenu;
+
 	// TODO: Should have a more robust way to track this, but this'll work for now
 	guint num_hidden;
 
@@ -125,6 +129,7 @@
 G_DEFINE_TYPE (IndicateServer, indicate_server, G_TYPE_OBJECT);
 
 /* Prototypes */
+static void indicate_server_dispose (GObject * obj);
 static void indicate_server_finalize (GObject * obj);
 static gboolean get_indicator_count (IndicateServer * server, guint * count, GError **error);
 static gboolean get_indicator_list (IndicateServer * server, GArray ** indicators, GError ** error);
@@ -179,6 +184,7 @@
 
 	g_type_class_add_private (class, sizeof (IndicateServerPrivate));
 
+	gobj->dispose = indicate_server_dispose;
 	gobj->finalize = indicate_server_finalize;
 	gobj->set_property = set_property;
 	gobj->get_property = get_property;
@@ -351,6 +357,11 @@
 	                                              "A number reprsenting the number of items in a server",
 												  0, G_MAXUINT, 0,
 	                                              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+	g_object_class_install_property (gobj, PROP_MENU,
+	                                 g_param_spec_boxed("menu", "DBus Menu Object Path",
+	                                              "The DBus Object path to an object with a dbusmenu interface on it.",
+												  DBUS_TYPE_G_OBJECT_PATH,
+	                                              G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 
 	dbus_g_object_type_install_info(INDICATE_TYPE_SERVER,
 	                                &dbus_glib__indicate_server_object_info);
@@ -388,6 +399,7 @@
 	priv->type = NULL;
 	priv->desktop = NULL;
 	priv->count = 0;
+	priv->dbusmenu = NULL;
 
 	guint i;
 	for (i = INDICATE_INTEREST_NONE; i < INDICATE_INTEREST_LAST; i++) {
@@ -400,16 +412,29 @@
 }
 
 static void
+indicate_server_dispose (GObject * obj)
+{
+	IndicateServer * server = INDICATE_SERVER(obj);
+	IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server);
+
+	if (priv->dbusmenu != NULL) {
+		g_object_unref(priv->dbusmenu);
+		priv->dbusmenu = NULL;
+	}
+
+	if (priv->visible) {
+		g_signal_emit(server, signals[SERVER_HIDE], 0, priv->type ? priv->type : "", TRUE);
+	}
+
+	return;
+}
+
+static void
 indicate_server_finalize (GObject * obj)
 {
 	IndicateServer * server = INDICATE_SERVER(obj);
 	IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server);
 
-	/* TODO: This probably shouldn't be as far down as finalize, but it's fine here. */
-	if (priv->visible) {
-		g_signal_emit(server, signals[SERVER_HIDE], 0, priv->type ? priv->type : "", TRUE);
-	}
-
 	if (priv->path) {
 		g_free(priv->path);
 	}
@@ -429,7 +454,6 @@
 set_property (GObject * obj, guint id, const GValue * value, GParamSpec * pspec)
 {
 	g_return_if_fail(G_VALUE_HOLDS_STRING(value) || G_VALUE_HOLDS_UINT(value));
-	g_return_if_fail(id == PROP_DESKTOP || id == PROP_TYPE || id == PROP_COUNT);
 
 	IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(obj);
 	switch (id) {
@@ -453,6 +477,9 @@
 		}
 		break;
 	}
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, pspec);
+		break;
 	}
 
 	return;
@@ -463,8 +490,6 @@
 static void
 get_property (GObject * obj, guint id, GValue * value, GParamSpec * pspec)
 {
-	g_return_if_fail(id == PROP_DESKTOP || id == PROP_TYPE || id == PROP_COUNT);
-
 	IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(obj);
 	switch (id) {
 	case PROP_DESKTOP:
@@ -484,6 +509,18 @@
 	case PROP_COUNT:
 		g_value_set_uint(value, priv->count);
 		break;
+	case PROP_MENU:
+		if (priv->dbusmenu != NULL) {
+			GValue strvalue = {0};
+			g_value_init(&strvalue, G_TYPE_STRING);
+			g_object_get_property(G_OBJECT(priv->dbusmenu), DBUSMENU_SERVER_PROP_DBUS_OBJECT, &strvalue);
+			g_value_set_boxed(value, g_value_dup_string(&strvalue));
+			g_value_unset(&strvalue);
+		}
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, id, pspec);
+		break;
 	}
 
 	return;
@@ -1644,6 +1681,43 @@
 	return -1;
 }
 
+/**
+	indicate_server_set_menu:
+	@server: The #IndicateServer to use
+	@menu: A #DbusmenuServer object represting the menu
+
+	This function sets the internal menu representation for this
+	indicator.  It makes it so that when clients ask for information
+	on the menus it'll repospond with the address of this menu.
+
+	It is important to note that there is not signal about menus
+	changing.  So if the indicator is already visible there is no
+	way that a listener would know about the change, and thus is
+	likely to have the wrong menu (or no menu).
+
+	Return value: None.
+*/
+void
+indicate_server_set_menu (IndicateServer * server, DbusmenuServer * menu)
+{
+	g_return_if_fail(INDICATE_IS_SERVER(server));
+	IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server);
+
+	if (priv->visible) {
+		g_warning("Menu being changed when the indicator is visible.  Listeners will NOT be notified of this change.");
+	}
+
+	if (priv->dbusmenu != NULL) {
+		g_object_unref(priv->dbusmenu);
+		priv->dbusmenu = NULL;
+	}
+
+	priv->dbusmenu = menu;
+	g_object_ref(priv->dbusmenu);
+
+	return;
+}
+
 /* *** Folks stuff *** */
 
 /* This checks for folk by looking at the sender value

=== modified file 'libindicate/server.h'
--- libindicate/server.h	2009-09-08 21:57:25 +0000
+++ libindicate/server.h	2010-02-01 06:32:14 +0000
@@ -33,6 +33,8 @@
 #include <glib.h>
 #include <glib-object.h>
 
+#include <libdbusmenu-glib/server.h>
+
 #include "interests.h"
 
 G_BEGIN_DECLS
@@ -199,6 +201,9 @@
 /* See how many indicators we can show */
 gint indicate_server_get_max_indicators (IndicateServer * server);
 
+/* Setting a server to use */
+void indicate_server_set_menu (IndicateServer * server, DbusmenuServer * menu);
+
 /**
 	SECTION:server
 	@short_description: The representation of the application on DBus.

=== modified file 'tests/Makefile.am'
--- tests/Makefile.am	2009-12-10 15:13:43 +0000
+++ tests/Makefile.am	2010-02-01 06:32:14 +0000
@@ -131,6 +131,38 @@
 	$(LIBINDICATE_LIBS)
 
 ##########################
+# test menu
+##########################
+
+TESTS += test-menu
+check_PROGRAMS += test-menu-client test-menu-server
+
+test-menu: test-menu-client test-menu-server Makefile.am
+	@echo "#!/bin/sh" > $@
+	@echo "$(DBUS_RUNNER) --task ./test-menu-client --task-name Client --task ./test-menu-server --task-name Server" >> $@
+	@chmod +x $@
+
+test_menu_client_SOURCES = \
+	test-menu-client.c
+
+test_menu_client_CFLAGS = \
+	$(LIBINDICATE_CFLAGS) -I$(srcdir)/..
+
+test_menu_client_LDADD = \
+	../libindicate/libindicate.la \
+	$(LIBINDICATE_LIBS)
+
+test_menu_server_SOURCES = \
+	test-menu-server.c
+
+test_menu_server_CFLAGS = \
+	$(LIBINDICATE_CFLAGS) -I$(srcdir)/..
+
+test_menu_server_LDADD = \
+	../libindicate/libindicate.la \
+	$(LIBINDICATE_LIBS)
+
+##########################
 # test thousand indicators
 ##########################
 

=== added file 'tests/test-menu-client.c'
--- tests/test-menu-client.c	1970-01-01 00:00:00 +0000
+++ tests/test-menu-client.c	2010-02-01 06:32:14 +0000
@@ -0,0 +1,36 @@
+
+#include <glib.h>
+#include "libindicate/indicator.h"
+
+static gboolean passed = TRUE;
+static GMainLoop * mainloop = NULL;
+
+static gboolean
+done_timeout_cb (gpointer data)
+{
+	g_debug("All done.");
+	g_main_loop_quit(mainloop);
+	return FALSE;
+}
+
+int
+main (int argc, char * argv)
+{
+	g_type_init();
+
+	g_debug("Starting client");
+	IndicateIndicator * indicator = indicate_indicator_new();
+
+	DbusmenuServer * server = dbusmenu_server_new("/org/test/menu");
+	indicate_server_set_menu(indicate_indicator_get_server(indicator), server);
+
+	g_debug("Show indicator");
+	indicate_indicator_show(indicator);
+
+	g_timeout_add_seconds(2, done_timeout_cb, indicator);
+
+	mainloop = g_main_loop_new(NULL, FALSE);
+	g_main_loop_run(mainloop);
+
+	return !passed;
+}

=== added file 'tests/test-menu-server.c'
--- tests/test-menu-server.c	1970-01-01 00:00:00 +0000
+++ tests/test-menu-server.c	2010-02-01 06:32:14 +0000
@@ -0,0 +1,52 @@
+
+#include <glib.h>
+#include "libindicate/listener.h"
+
+static gboolean passed = TRUE;
+static GMainLoop * mainloop = NULL;
+
+void
+cb (IndicateListener * listener, IndicateListenerServer * server, gchar * value, gpointer data)
+{
+	g_debug("Got menu: %s", value);
+	if (g_strcmp0(value, "/org/test/menu") != 0) {
+		passed = FALSE;
+	}
+	g_main_loop_quit(mainloop);
+	return;
+}
+
+static void
+server_added (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data)
+{
+	g_debug("Indicator Server Added:   %s %s", INDICATE_LISTENER_SERVER_DBUS_NAME(server), type);
+	g_debug("\tLooking for menus...");
+	indicate_listener_server_get_menu(listener, server, cb, NULL);
+	return;
+}
+
+static gboolean
+failed_cb (gpointer data)
+{
+	g_debug("Failed to get a server in 5 seconds.");
+	passed = FALSE;
+	g_main_loop_quit(mainloop);
+	return FALSE;
+}
+
+int
+main (int argc, char * argv)
+{
+	g_type_init();
+
+	IndicateListener * listener = indicate_listener_ref_default();
+
+	g_signal_connect(listener, INDICATE_LISTENER_SIGNAL_SERVER_ADDED, G_CALLBACK(server_added), NULL);
+
+	g_timeout_add_seconds(5, failed_cb, NULL);
+
+	mainloop = g_main_loop_new(NULL, FALSE);
+	g_main_loop_run(mainloop);
+
+	return !passed;
+}


Follow ups