ayatana-commits team mailing list archive
-
ayatana-commits team
-
Mailing list archive
-
Message #00793
[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