← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~ted/libindicate/ayatanize into lp:libindicate

 

Ted Gould has proposed merging lp:~ted/libindicate/ayatanize into lp:libindicate.

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


Changing to org.ayatana namespace.
-- 
https://code.launchpad.net/~ted/libindicate/ayatanize/+merge/18554
Your team ayatana-commits is subscribed to branch lp:libindicate.
=== modified file '.bzrignore'
--- .bzrignore	2009-10-11 16:09:33 +0000
+++ .bzrignore	2010-02-03 20:02:13 +0000
@@ -154,3 +154,14 @@
 libindicate-gtk/Indicate-Gtk-0.2.typelib
 libindicate-[0-9].[0-9].[0-9].tar.gz
 libindicate-[0-9].[0-9].[0-9].tar.gz.asc
+tests/test-indicator-display
+tests/test-indicator-display-half
+tests/test-interests
+tests/test-interests-multi
+tests/test-max-indicators
+tests/test-max-indicators-repeat
+tests/test-menu
+tests/test-menu-client
+tests/test-menu-server
+tests/test-simple
+tests/test-thousand-indicators

=== modified file 'configure.ac'
--- configure.ac	2010-02-02 08:15:17 +0000
+++ configure.ac	2010-02-03 20:02:13 +0000
@@ -52,14 +52,12 @@
 DBUS_REQUIRED_VERSION=0.76
 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)
+                               dbus-glib-1 >= $DBUS_REQUIRED_VERSION)
 AC_SUBST(LIBINDICATE_CFLAGS)
 AC_SUBST(LIBINDICATE_LIBS)
 

=== modified file 'libindicate-gtk/Makefile.am'
--- libindicate-gtk/Makefile.am	2009-10-11 16:04:14 +0000
+++ libindicate-gtk/Makefile.am	2010-02-03 20:02:13 +0000
@@ -29,6 +29,7 @@
 
 libindicate_gtk_la_CFLAGS = \
 	-I $(srcdir)/.. \
+	-Wall -Werror \
 	$(LIBINDICATEGTK_CFLAGS)
 
 libindicate_gtk_la_LIBADD = \

=== modified file 'libindicate-gtk/listener.c'
--- libindicate-gtk/listener.c	2009-09-08 20:59:59 +0000
+++ libindicate-gtk/listener.c	2010-02-03 20:02:13 +0000
@@ -136,7 +136,7 @@
 	get_property_data->property = g_strdup(property);
 	get_property_data->type = prop_type;
 	
-	org_freedesktop_indicator_get_indicator_property_async (server->proxy , INDICATE_LISTENER_INDICATOR_ID(indicator), property, get_property_cb, get_property_data);
+	org_ayatana_indicate_get_indicator_property_async (server->proxy , INDICATE_LISTENER_INDICATOR_ID(indicator), property, get_property_cb, get_property_data);
 	return;
 }
 

=== modified file 'libindicate/Makefile.am'
--- libindicate/Makefile.am	2009-10-11 16:04:14 +0000
+++ libindicate/Makefile.am	2010-02-03 20:02:13 +0000
@@ -46,6 +46,7 @@
 	dbus-indicate-client.h \
 	dbus-listener-server.h \
 	dbus-listener-client.h \
+	dbus-shared.h \
 	indicate-enum-types.c \
 	server.c \
 	server-marshal.c \

=== added file 'libindicate/dbus-shared.h'
--- libindicate/dbus-shared.h	1970-01-01 00:00:00 +0000
+++ libindicate/dbus-shared.h	2010-02-03 20:02:13 +0000
@@ -0,0 +1,34 @@
+/*
+Some common interfaces that get used all over.
+
+Copyright 2010 Canonical Ltd.
+
+Authors:
+    Ted Gould <ted@xxxxxxxxxxxxx>
+
+This program is free software: you can redistribute it and/or modify it 
+under the terms of either or both of the following licenses:
+
+1) the GNU Lesser General Public License version 3, as published by the 
+Free Software Foundation; and/or
+2) the GNU Lesser General Public License version 2.1, as published by 
+the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful, but 
+WITHOUT ANY WARRANTY; without even the implied warranties of 
+MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 
+PURPOSE.  See the applicable version of the GNU Lesser General Public 
+License for more details.
+
+You should have received a copy of both the GNU Lesser General Public 
+License version 3 and version 2.1 along with this program.  If not, see 
+<http://www.gnu.org/licenses/>
+*/
+
+#ifndef INDICATE_DBUS_SHARED
+#define INDICATE_DBUS_SHARED
+
+#define  INDICATE_DBUS_IFACE            "org.ayatana.indicate"
+#define  INDICATE_LISTENER_DBUS_IFACE   "org.ayatana.indicate.listener"
+
+#endif /* INDICATE_DBUS_SHARED */

=== modified file 'libindicate/indicate-interface.xml'
--- libindicate/indicate-interface.xml	2010-02-01 01:45:54 +0000
+++ libindicate/indicate-interface.xml	2010-02-03 20:02:13 +0000
@@ -28,7 +28,7 @@
 <http://www.gnu.org/licenses/>
 -->
 <node name="/">
-	<interface name="org.freedesktop.indicator">
+	<interface name="org.ayatana.indicate">
 
 <!-- Properties -->
 		<property name="desktop" type="s" access="read" />

=== modified file 'libindicate/indicate-listener.xml'
--- libindicate/indicate-listener.xml	2009-02-23 04:59:44 +0000
+++ libindicate/indicate-listener.xml	2010-02-03 20:02:13 +0000
@@ -28,13 +28,17 @@
 <http://www.gnu.org/licenses/>
 -->
 <node name="/">
-	<interface name="org.freedesktop.indicator.listener">
+	<interface name="org.ayatana.indicate.listener">
 
 <!-- Functions -->
 		<method name="GetIndicatorServers">
 			<arg type="as" name="server_ids" direction="out" />
 		</method>
 
+<!-- Signals -->
+		<signal name="IndicatorServersReport">
+		</signal>
+
 <!-- End of interesting stuff -->
 
 	</interface>

=== modified file 'libindicate/listener-private.h'
--- libindicate/listener-private.h	2009-08-28 21:59:26 +0000
+++ libindicate/listener-private.h	2010-02-03 20:02:13 +0000
@@ -48,11 +48,7 @@
 	DBusGConnection * session_bus;
 	DBusGConnection * system_bus;
 
-	DBusGProxy * dbus_proxy_session;
-	DBusGProxy * dbus_proxy_system;
-
-	GList * proxies_working;
-	GList * proxies_possible;
+	GList * proxies;
 
 	GArray * proxy_todo;
 	guint todo_idle;

=== modified file 'libindicate/listener.c'
--- libindicate/listener.c	2010-02-01 06:13:31 +0000
+++ libindicate/listener.c	2010-02-03 20:02:13 +0000
@@ -27,15 +27,15 @@
 <http://www.gnu.org/licenses/>
 */
 
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-
+#include <stdlib.h>
 #include "listener.h"
 #include "listener-marshal.h"
 #include <dbus/dbus-glib-bindings.h>
+#include <dbus/dbus-glib-lowlevel.h>
 #include "dbus-indicate-client.h"
 #include "dbus-listener-client.h"
 #include "interests-priv.h"
+#include "dbus-shared.h"
 
 /* Errors */
 enum {
@@ -50,6 +50,7 @@
 	SERVER_ADDED,
 	SERVER_REMOVED,
 	SERVER_COUNT_CHANGED,
+	INDICATOR_SERVERS_REPORT,
 	LAST_SIGNAL
 };
 
@@ -62,10 +63,12 @@
 	DBusGProxy * property_proxy;
 	DBusGConnection * connection;
 	gchar * name;
+	gchar * path;
 	gchar * type;
 	IndicateListener * listener;
 	GHashTable * indicators;
 	guint introspect_level;
+	gboolean hidden;
 
 	IndicateListenerServer server;
 } proxy_t;
@@ -86,28 +89,27 @@
 typedef struct {
 	DBusGConnection * bus;
 	gchar * name;
-	gboolean startup;
+	gchar * path;
 } proxy_todo_t;
 
 G_DEFINE_TYPE (IndicateListener, indicate_listener, G_TYPE_OBJECT);
 
 /* Prototypes */
 static void indicate_listener_finalize (GObject * obj);
-static void dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, IndicateListener * listener);
+static DBusHandlerResult dbus_filter_show_server (DBusConnection * connection, DBusMessage * message, void * user_data);
 static void proxy_struct_destroy (gpointer data);
-static void build_todo_list_cb (DBusGProxy * proxy, char ** names, GError * error, void * data);
-static void todo_list_add (const gchar * name, DBusGProxy * proxy, IndicateListener * listener, gboolean startup);
+static void todo_list_add (const gchar * name, const gchar * path, IndicateListener * listener);
 static gboolean todo_idle (gpointer data);
+void set_max_indicators_cb (DBusGProxy * proxy, GError * error, gpointer userdata);
+static void get_type_initial_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data);
 static void get_type_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data);
 static void proxy_indicator_added_legacy (DBusGProxy * proxy, guint id, gchar * type, proxy_t * proxyt);
-static void proxy_server_added (DBusGProxy * proxy, const gchar * type, proxy_t * proxyt);
 static void proxy_indicator_added (DBusGProxy * proxy, guint id, proxy_t * proxyt);
 static void proxy_indicator_removed_legacy (DBusGProxy * proxy, guint id, gchar * type, proxy_t * proxyt);
 static void proxy_indicator_removed (DBusGProxy * proxy, guint id, proxy_t * proxyt);
 static void proxy_indicator_modified (DBusGProxy * proxy, guint id, const gchar * property, proxy_t * proxyt);
 static void proxy_server_count_changed (DBusGProxy * proxy, guint count, proxy_t * proxyt);
 static void proxy_get_indicator_list (DBusGProxy * proxy, GArray * indicators, GError * error, gpointer data);
-static void introspect_this (DBusGProxy * proxy, char * OUT_data, GError * error, gpointer data);
 
 /* DBus interface */
 gboolean _indicate_listener_get_indicator_servers (IndicateListener * listener, GList * servers);
@@ -169,6 +171,13 @@
 	                                        NULL, NULL,
 	                                        _indicate_listener_marshal_VOID__POINTER_UINT,
 	                                        G_TYPE_NONE, 2, INDICATE_TYPE_LISTENER_SERVER, G_TYPE_UINT);
+	signals[INDICATOR_SERVERS_REPORT] = g_signal_new("indicator-servers-report",
+	                                        G_TYPE_FROM_CLASS (class),
+	                                        G_SIGNAL_RUN_LAST,
+	                                        G_STRUCT_OFFSET (IndicateListenerClass, indicator_servers_report),
+	                                        NULL, NULL,
+	                                        g_cclosure_marshal_VOID__VOID,
+	                                        G_TYPE_NONE, 0, G_TYPE_NONE);
 
 	dbus_g_object_register_marshaller(_indicate_listener_marshal_VOID__UINT_STRING,
 	                                  G_TYPE_NONE,
@@ -176,6 +185,9 @@
 	                                  G_TYPE_STRING,
 	                                  G_TYPE_INVALID);
 
+	dbus_g_object_type_install_info(INDICATE_TYPE_LISTENER,
+	                                &dbus_glib__indicate_listener_object_info);
+
 	return;
 }
 
@@ -194,28 +206,8 @@
 		return;
 	}
 
-	/* Set up the DBUS service proxies */
-	priv->dbus_proxy_session = dbus_g_proxy_new_for_name_owner (priv->session_bus,
-	                                                                DBUS_SERVICE_DBUS,
-	                                                                DBUS_PATH_DBUS,
-	                                                                DBUS_INTERFACE_DBUS,
-	                                                                &error);
-	if (error != NULL) {
-		g_error("Unable to get dbus proxy on session bus: %s", error->message);
-		g_error_free(error);
-		return;
-	}
-
-	/* Set up name change signals */
-	dbus_g_proxy_add_signal(priv->dbus_proxy_session, "NameOwnerChanged",
-	                        G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
-	                        G_TYPE_INVALID);
-	dbus_g_proxy_connect_signal(priv->dbus_proxy_session, "NameOwnerChanged",
-	                            G_CALLBACK(dbus_owner_change), listener, NULL);
-
 	/* Initialize Data structures */
-	priv->proxies_working = NULL;
-	priv->proxies_possible = NULL;
+	priv->proxies = NULL;
 
 	/* TODO: Look at some common scenarios and find out how to make this sized */
 	priv->proxy_todo = g_array_new(FALSE, TRUE, sizeof(proxy_todo_t));
@@ -223,12 +215,18 @@
 
 	priv->max_indicators = -1;
 
+	dbus_g_connection_register_g_object(priv->session_bus,
+	                                    "/org/ayatana/indicate/listener",
+	                                    G_OBJECT(listener));
+
 	/*            WARNING              */
 	/* Starting massive asynchronisity */
 	/*                                 */
 
-	/* Build todo list */
-	org_freedesktop_DBus_list_names_async (priv->dbus_proxy_session, build_todo_list_cb, listener);
+	dbus_connection_add_filter(dbus_g_connection_get_connection(priv->session_bus), dbus_filter_show_server, listener, NULL);
+	dbus_bus_add_match(dbus_g_connection_get_connection(priv->session_bus), "type='signal',interface='" INDICATE_DBUS_IFACE "',member='ServerShow'", NULL);
+
+	g_signal_emit(G_OBJECT(listener), signals[INDICATOR_SERVERS_REPORT], 0, TRUE);
 
 	return;
 }
@@ -239,32 +237,27 @@
 	IndicateListener * listener = INDICATE_LISTENER(obj);
 	IndicateListenerPrivate * priv = INDICATE_LISTENER_GET_PRIVATE(listener);
 
-	dbus_g_proxy_disconnect_signal(priv->dbus_proxy_session, "NameOwnerChanged",
-	                               G_CALLBACK(dbus_owner_change), listener);
-	dbus_g_proxy_disconnect_signal(priv->dbus_proxy_system, "NameOwnerChanged",
-	                               G_CALLBACK(dbus_owner_change), listener);
-	
 	if (priv->todo_idle != 0) {
 		g_idle_remove_by_data(obj);
 	}
 	/* Hack: proxy_struct_destroy() lacks a user_data parameter, but since the
 	 * caller is responsible for handling params on the stack, it works
 	 */
-	g_list_foreach(priv->proxies_possible, (GFunc)proxy_struct_destroy, NULL);
-	g_list_free(priv->proxies_possible);
-	g_list_foreach(priv->proxies_working, (GFunc)proxy_struct_destroy, NULL);
-	g_list_free(priv->proxies_working);
-
-	g_object_unref(priv->dbus_proxy_session);
-	g_object_unref(priv->dbus_proxy_system);
-
-	dbus_g_connection_unref(priv->session_bus);
-	dbus_g_connection_unref(priv->system_bus);
+	g_list_foreach(priv->proxies, (GFunc)proxy_struct_destroy, NULL);
+	g_list_free(priv->proxies);
 
 	G_OBJECT_CLASS (indicate_listener_parent_class)->finalize (obj);
 	return;
 }
 
+/**
+	indicate_listener_new:
+
+	Creates a new Listener object.  Does not set this to the default
+	listener object.
+
+	Return value: A new listener object.
+*/
 IndicateListener *
 indicate_listener_new (void)
 {
@@ -273,8 +266,22 @@
 	return listener;
 }
 
+/* The pointer to the default listener object */
 static IndicateListener * default_indicate_listener = NULL;
 
+/**
+	indcate_listener_ref_default:
+
+	Looks for the default listener, and if it doesn't exist it'll
+	allocate a new one and mark it the default.  This is what most
+	programs should use rather than #indicate_listener_new because
+	it is rare that anyone would need more than a single listener.
+	This function does increase the ref count on the object so anyone
+	calling it should unref thier instance of the default listener.
+
+	Return value: The default instance of #IndicateListener for the
+		program.
+*/
 IndicateListener *
 indicate_listener_ref_default (void)
 {
@@ -289,43 +296,26 @@
 	return default_indicate_listener;
 }
 
-/* Function to track when people get on and off the bus. */
-static void
-dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, const gchar * new, IndicateListener * listener)
+/* A small filter function that notices when someone sends
+   a ServerShow signal and creates an entry for us to investigate
+   them more in an idle loop lookup. */
+static DBusHandlerResult
+dbus_filter_show_server (DBusConnection * connection, DBusMessage * message, void * user_data)
 {
-	g_return_if_fail(INDICATE_IS_LISTENER(listener));
-	IndicateListenerPrivate * priv = INDICATE_LISTENER_GET_PRIVATE(listener);
-
-	/* If someone is getting on the bus we add them to the
-	   todo list to see if they come up with something interesting */
-	if (prev != NULL && prev[0] == '\0') {
-		todo_list_add(name, proxy, listener, FALSE);
-	}
-
-	/* If they're leaving the bus we need to figure out if we
-	   were tracking them or not, and remove them from the
-	   appropriate lists. */
-	if (new != NULL && new[0] == '\0') {
-		proxy_t searchitem;
-		searchitem.connection = priv->session_bus;
-		searchitem.name = (gchar *)name; /* Droping const, not that it isn't, but to remove the warning */
-
-		GList * proxyt_item;
-		proxyt_item = g_list_find_custom(priv->proxies_working, &searchitem, proxy_t_equal);
-		if (proxyt_item != NULL) {
-			proxy_struct_destroy((proxy_t *)proxyt_item->data);
-			priv->proxies_working = g_list_remove(priv->proxies_working, proxyt_item->data);
-		}
-		proxyt_item = g_list_find_custom(priv->proxies_possible, &searchitem, proxy_t_equal);
-		if (proxyt_item != NULL) {
-			proxy_struct_destroy((proxy_t *)proxyt_item->data);
-			priv->proxies_possible = g_list_remove(priv->proxies_possible, proxyt_item->data);
-		}
-	}
-
-	return;
+	if (!dbus_message_is_signal(message, INDICATE_DBUS_IFACE, "ServerShow")) {
+		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	}
+
+	const char * sender = dbus_message_get_sender(message);
+	const char * path = dbus_message_get_path(message);
+
+	todo_list_add(sender, path, INDICATE_LISTENER(user_data));
+
+	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
+/* A hashtable for each function to look at all of the indicators
+   on a proxy_t object and signal their destruction */
 static void
 proxy_struct_destroy_indicators (gpointer key, gpointer value, gpointer data)
 {
@@ -337,12 +327,13 @@
 	return;
 }
 
+/* Cleans up a proxy_t struct after allocation.  It signals that
+   all of the indicators are going away and the server itself. */
 static void
 proxy_struct_destroy (gpointer data)
 {
 	proxy_t * proxy_data = data;
 
-	/* TODO: Clear the indicators by signaling */
 	if (proxy_data->indicators != NULL) {
 		g_hash_table_foreach(proxy_data->indicators,
 							 proxy_struct_destroy_indicators,
@@ -361,7 +352,14 @@
 		g_object_unref(G_OBJECT(proxy_data->proxy));
 	}
 
-	g_free(proxy_data->name);
+	if (proxy_data->name != NULL) {
+		g_free(proxy_data->name);
+	}
+
+	if (proxy_data->path != NULL) {
+		g_free(proxy_data->path);
+	}
+
 	if (proxy_data->type != NULL) {
 		g_free(proxy_data->type);
 	}
@@ -370,26 +368,11 @@
 	return;
 }
 
-static void
-build_todo_list_cb (DBusGProxy * proxy, char ** names, GError * error, void * data)
-{
-	IndicateListener * listener = INDICATE_LISTENER(data);
-
-	if (error != NULL) {
-		g_warning("Unable to get names: %s", error->message);
-		return;
-	}
-
-	guint i = 0;
-	for (i = 0; names[i] != NULL; i++) {
-		todo_list_add(names[i], proxy, listener, TRUE);
-	}
-
-	return;
-}
-
-static void
-todo_list_add (const gchar * name, DBusGProxy * proxy, IndicateListener * listener, gboolean startup)
+/* Creates a todo list item for the particular server and
+   path as they've signaled that they're on DBus and like
+   talking about indicators. */
+static void
+todo_list_add (const gchar * name, const gchar * path, IndicateListener * listener)
 {
 	if (name == NULL || name[0] != ':') {
 		return;
@@ -399,8 +382,8 @@
 
 	proxy_todo_t todo;
 	todo.name = g_strdup(name);
+	todo.path = g_strdup(path);
 	todo.bus  = priv->session_bus;
-	todo.startup = startup;
 
 	g_array_append_val(priv->proxy_todo, todo);
 
@@ -431,44 +414,131 @@
 	}
 
 	proxy_todo_t * todo = &g_array_index(priv->proxy_todo, proxy_todo_t, priv->proxy_todo->len - 1);
+	/* Remove the todo list */
+	priv->proxy_todo = g_array_remove_index(priv->proxy_todo, priv->proxy_todo->len - 1);
+
+	/* Check to see if we already have this item, if so,
+	   we assume that it's signal handler will handle the
+	   ServerShow signal.  We're just going to exit this 
+	   function. */
+	if (TRUE) {
+		proxy_t searchitem;
+		searchitem.name = todo->name;
+		searchitem.connection = todo->bus;
+
+		GList * proxyitem = g_list_find_custom(priv->proxies, &searchitem, proxy_t_equal);
+		if (proxyitem != NULL) {
+			g_free(todo->name);
+			g_free(todo->path);
+			g_free(todo);
+			return TRUE;
+		}
+	}
 
 	proxy_t * proxyt = g_new0(proxy_t, 1);
 	proxyt->name = todo->name;
+	proxyt->path = todo->path;
 	proxyt->type = NULL;
-	proxyt->proxy = dbus_g_proxy_new_for_name(todo->bus,
-	                                          proxyt->name,
-	                                          "/org/freedesktop/indicate",
-	                                          "org.freedesktop.indicator");
 	proxyt->property_proxy = NULL;
+	proxyt->proxy = NULL;
 	proxyt->listener = listener;
 	proxyt->indicators = NULL;
+	proxyt->hidden = FALSE;
 	proxyt->connection = todo->bus;
 	proxyt->server.name = todo->name;
-	proxyt->server.proxy = proxyt->proxy;
+	proxyt->server.proxy = NULL;
 	proxyt->server.connection = proxyt->connection;
 	proxyt->server.max_indicators = priv->max_indicators;
 
-	priv->proxy_todo = g_array_remove_index(priv->proxy_todo, priv->proxy_todo->len - 1);
-
-	if (proxyt->proxy == NULL) {
+	/* Build the indicators hash */
+	proxyt->indicators = g_hash_table_new(g_direct_hash, g_direct_equal);
+
+	/* Build the proxy and ensure that it gets created.  If
+	   it gets created we're all happy. */
+	GError * error = NULL;
+	proxyt->proxy = dbus_g_proxy_new_for_name_owner(todo->bus,
+	                                                proxyt->name,
+	                                                todo->path,
+	                                                INDICATE_DBUS_IFACE,
+	                                                &error);
+
+	g_free(todo);
+
+	if (error != NULL) {
 		g_warning("Unable to create proxy for %s", proxyt->name);
+		g_error_free(error);
 		return TRUE;
 	}
 
-	dbus_g_proxy_add_signal(proxyt->proxy, "ServerShow",
-	                        G_TYPE_STRING, G_TYPE_INVALID);
-	dbus_g_proxy_connect_signal(proxyt->proxy, "ServerShow",
-	                            G_CALLBACK(proxy_server_added), proxyt, NULL);
-
-	priv->proxies_possible = g_list_prepend(priv->proxies_possible, proxyt);
-
-	/* Look through the introspection data to see if this
-	   is already a server */
-	introspect_this (NULL, NULL, NULL, proxyt);
+	/* Making sure the server has the proxy as well */
+	proxyt->server.proxy = proxyt->proxy;
+
+	/* Adding into the list of proxies */
+	priv->proxies = g_list_prepend(priv->proxies, proxyt);
+
+	/* Setup all the signals that we need off of this
+	   proxy.  Lot's of fun signals. */
+	dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorAdded",
+	                            G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorAdded",
+	                            G_CALLBACK(proxy_indicator_added_legacy), proxyt, NULL);
+	dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorNew",
+	                            G_TYPE_UINT, G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorNew",
+	                            G_CALLBACK(proxy_indicator_added), proxyt, NULL);
+	dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorRemoved",
+	                            G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorRemoved",
+	                            G_CALLBACK(proxy_indicator_removed_legacy), proxyt, NULL);
+	dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorDelete",
+	                            G_TYPE_UINT, G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorDelete",
+	                            G_CALLBACK(proxy_indicator_removed), proxyt, NULL);
+	dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorModified",
+	                            G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorModified",
+	                            G_CALLBACK(proxy_indicator_modified), proxyt, NULL);
+	dbus_g_proxy_add_signal(proxyt->proxy, "ServerCountChanged",
+	                            G_TYPE_UINT, G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal(proxyt->proxy, "ServerCountChanged",
+	                            G_CALLBACK(proxy_server_count_changed), proxyt, NULL);
+
+	/* We're setting the max number of indicators from the default
+	   when we detect it.  This should give a reasonable amount of
+	   time for listeners to set the default if they want something
+	   different from infinite.  Otherwise it'd be easy to miss the
+	   first couple. */
+	proxyt->server.max_indicators = priv->max_indicators;
+	if (proxyt->server.max_indicators != -1) {
+		org_ayatana_indicate_set_max_indicators_async(proxyt->proxy, proxyt->server.max_indicators, set_max_indicators_cb, proxyt->name);
+	}
+
+	indicate_listener_server_get_type(proxyt->listener, &proxyt->server, get_type_initial_cb, proxyt);
+	org_ayatana_indicate_get_indicator_list_async(proxyt->proxy, proxy_get_indicator_list, proxyt);
 
 	return TRUE;
 }
 
+/* A callback function for the getting the type when it is looked
+   at initially.  So that we'll send a signal that the server has
+   been added so that everyone knows. */
+static void
+get_type_initial_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data)
+{
+	get_type_cb(listener, server, type, data);
+
+	proxy_t * proxyt = (proxy_t *)data;
+
+	if (!proxyt->hidden && proxyt->type != NULL) {
+		g_signal_emit(proxyt->listener, signals[SERVER_ADDED], 0, &proxyt->server, proxyt->type, TRUE);
+	}
+
+	return;
+}
+
+/* Callback from getting the type of the server.  We're not using
+   this directly now, only through get_type_initial_cb right now
+   though we might use it more directly later. */
 static void
 get_type_cb (IndicateListener * listener, IndicateListenerServer * server, gchar * type, gpointer data)
 {
@@ -480,8 +550,11 @@
 
 	proxy_t * proxyt = (proxy_t *)data;
 
-	proxy_server_added (proxyt->proxy, type, proxyt);
-	org_freedesktop_indicator_get_indicator_list_async(proxyt->proxy, proxy_get_indicator_list, proxyt);
+	if (proxyt->type != NULL) {
+		g_free(proxyt->type);
+		proxyt->type = NULL;
+	}
+	proxyt->type = g_strdup(type);
 
 	return;
 }
@@ -519,85 +592,6 @@
 	return;
 }
 
-/* Function called on the ServerShow signal from the bus, which is
-   usually when a DBus client says that they have some indicators
-   that we could be interested in.  Also, this function is called
-   in the discovery phase of starting up a new listener if we find
-   some indicators on the client. */
-static void
-proxy_server_added (DBusGProxy * proxy, const gchar * type, proxy_t * proxyt)
-{
-	g_debug("Proxy Server Added");
-	/* Check to see if we have an indicators table.  If we
-	   do this function's probably already been run.  If not
-	   we need to trick this server out. */
-	if (proxyt->indicators == NULL) {
-		proxyt->indicators = g_hash_table_new(g_direct_hash, g_direct_equal);
-
-		IndicateListenerPrivate * priv = INDICATE_LISTENER_GET_PRIVATE(proxyt->listener);
-
-		/* Move the proxy from 'possible' to 'working'. */
-		GList * proxyt_item;
-		proxyt_item = g_list_find_custom(priv->proxies_possible, proxyt, proxy_t_equal);
-		if (proxyt_item != NULL) {
-			priv->proxies_possible = g_list_remove(priv->proxies_possible, proxyt_item->data);
-		}
-		priv->proxies_working = g_list_prepend(priv->proxies_working, proxyt);
-
-		/* Connect to all the indicator based signals
-		   that are coming from this server */
-		dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorAdded",
-								G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID);
-		dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorAdded",
-									G_CALLBACK(proxy_indicator_added_legacy), proxyt, NULL);
-		dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorNew",
-								G_TYPE_UINT, G_TYPE_INVALID);
-		dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorNew",
-									G_CALLBACK(proxy_indicator_added), proxyt, NULL);
-		dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorRemoved",
-								G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID);
-		dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorRemoved",
-									G_CALLBACK(proxy_indicator_removed_legacy), proxyt, NULL);
-		dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorDelete",
-								G_TYPE_UINT, G_TYPE_INVALID);
-		dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorDelete",
-									G_CALLBACK(proxy_indicator_removed), proxyt, NULL);
-		dbus_g_proxy_add_signal(proxyt->proxy, "IndicatorModified",
-								G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID);
-		dbus_g_proxy_connect_signal(proxyt->proxy, "IndicatorModified",
-									G_CALLBACK(proxy_indicator_modified), proxyt, NULL);
-		dbus_g_proxy_add_signal(proxyt->proxy, "ServerCountChanged",
-								G_TYPE_UINT, G_TYPE_INVALID);
-		dbus_g_proxy_connect_signal(proxyt->proxy, "ServerCountChanged",
-									G_CALLBACK(proxy_server_count_changed), proxyt, NULL);
-
-		/* If we've got a type let it override the type
-		   we had here before */
-		if (type != NULL) {
-			if (proxyt->type != NULL) {
-				g_free(proxyt->type);
-			}
-			proxyt->type = g_strdup(type);
-		}
-
-		/* We're setting the max number of indicators from the default
-		   when we detect it.  This should give a reasonable amount of
-		   time for listeners to set the default if they want something
-		   different from infinite.  Otherwise it'd be easy to miss the
-		   first couple. */
-		proxyt->server.max_indicators = priv->max_indicators;
-		if (proxyt->server.max_indicators != -1) {
-			org_freedesktop_indicator_set_max_indicators_async(proxyt->proxy, proxyt->server.max_indicators, set_max_indicators_cb, proxyt->name);
-		}
-
-		/* Signal to clients of the listener that there's a new
-		   server.  Note the server parameter here is the pointer
-		   to the server struct in the proxy data structure. */
-		g_signal_emit(proxyt->listener, signals[SERVER_ADDED], 0, &proxyt->server, proxyt->type, TRUE);
-	}
-
-	return;
-}
 
 /* A fun little wrapper so that we can support the
    signals on the indicator v1 interface.  It just drops
@@ -619,10 +613,6 @@
 	g_debug("Proxy Indicator Added");
 	g_return_if_fail(proxyt != NULL);
 
-	if (proxyt->indicators == NULL) {
-		proxy_server_added (proxy, NULL, proxyt);
-	}
-
 	if (!g_hash_table_lookup(proxyt->indicators, GUINT_TO_POINTER(id))) {
 		g_hash_table_insert(proxyt->indicators, GUINT_TO_POINTER(id), GUINT_TO_POINTER(TRUE));
 		g_signal_emit(proxyt->listener, signals[INDICATOR_ADDED], 0, &proxyt->server, GUINT_TO_POINTER(id), TRUE);
@@ -800,7 +790,7 @@
 	get_property_data->property = g_strdup(property);
 	get_property_data->type = prop_type;
 	
-	org_freedesktop_indicator_get_indicator_property_async (server->proxy , INDICATE_LISTENER_INDICATOR_ID(indicator), property, get_property_cb, get_property_data);
+	org_ayatana_indicate_get_indicator_property_async (server->proxy , INDICATE_LISTENER_INDICATOR_ID(indicator), property, get_property_cb, get_property_data);
 	return;
 }
 
@@ -914,7 +904,7 @@
 void
 indicate_listener_display (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator)
 {
-	org_freedesktop_indicator_show_indicator_to_user_async (server->proxy, INDICATE_LISTENER_INDICATOR_ID(indicator), listener_display_cb, NULL);
+	org_ayatana_indicate_show_indicator_to_user_async (server->proxy, INDICATE_LISTENER_INDICATOR_ID(indicator), listener_display_cb, NULL);
 
 	return;
 }
@@ -945,7 +935,7 @@
 void
 indicate_listener_displayed (IndicateListener * listener, IndicateListenerServer * server, IndicateListenerIndicator * indicator, gboolean displayed)
 {
-	org_freedesktop_indicator_indicator_displayed_async (server->proxy,
+	org_ayatana_indicate_indicator_displayed_async (server->proxy,
 	                                                     INDICATE_LISTENER_INDICATOR_ID(indicator),
 	                                                     displayed,
 	                                                     listener_displayed_cb,
@@ -1038,11 +1028,7 @@
 	searchitem.name = server->name;
 	searchitem.connection = server->connection;
 
-	GList * proxyitem = g_list_find_custom(priv->proxies_possible, &searchitem, proxy_t_equal);
-	if (proxyitem == NULL) {
-		proxyitem = g_list_find_custom(priv->proxies_working, &searchitem, proxy_t_equal);
-	}
-
+	GList * proxyitem = g_list_find_custom(priv->proxies, &searchitem, proxy_t_equal);
 	if (proxyitem == NULL) {
 		g_warning("Can not find a proxy for the server at all.");
 		return;
@@ -1053,7 +1039,7 @@
 	if (proxyt->property_proxy == NULL) {
 		proxyt->property_proxy = dbus_g_proxy_new_for_name(proxyt->connection,
 		                                                   proxyt->name,
-		                                                   "/org/freedesktop/indicate",
+		                                                   proxyt->path,
 		                                                   DBUS_INTERFACE_PROPERTIES);
 	}
 
@@ -1069,7 +1055,7 @@
 	                         property_cb,
 	                         localdata,
 	                         NULL,
-	                         G_TYPE_STRING, "org.freedesktop.indicator",
+	                         G_TYPE_STRING, INDICATE_DBUS_IFACE,
 	                         G_TYPE_STRING, property_name,
 	                         G_TYPE_INVALID, G_TYPE_VALUE, G_TYPE_INVALID);
 
@@ -1151,7 +1137,7 @@
 	}
 
 	if (!server->interests[interest]) {
-		org_freedesktop_indicator_show_interest_async (server->proxy, interest_to_string(interest), interest_cb, server);
+		org_ayatana_indicate_show_interest_async (server->proxy, interest_to_string(interest), interest_cb, server);
 		server->interests[interest] = TRUE;
 	}
 	return;
@@ -1161,7 +1147,7 @@
 indicate_listener_server_remove_interest (IndicateListener * listener, IndicateListenerServer * server, IndicateInterests interest)
 {
 	if (server->interests[interest]) {
-		org_freedesktop_indicator_remove_interest_async (server->proxy, interest_to_string(interest), interest_cb, server);
+		org_ayatana_indicate_remove_interest_async (server->proxy, interest_to_string(interest), interest_cb, server);
 		server->interests[interest] = FALSE;
 	}
 	return;
@@ -1195,101 +1181,6 @@
   return our_type;
 }
 
-static const gchar * _introspector_path[] = {"", "org", "freedesktop", "indicate", NULL};
-static const gchar * _introspector_fullpath[] = {"/", "/org", "/org/freedesktop", "/org/freedesktop/indicate", NULL};
-static const gchar * _introspector_interface = "org.freedesktop.indicator";
-
-static void
-introspect_this (DBusGProxy * proxy, char * OUT_data, GError * error, gpointer data)
-{
-	/* g_debug("Introspect this:\n%s", OUT_data); */
-	proxy_t * server = (proxy_t *)data;
-	if (proxy != NULL) {
-		g_object_unref(proxy);
-	}
-	if (error != NULL) {
-		/* We probably couldn't introspect that far up.  That's
-		   life, it happens. Or there's a timeout, that happens
-		   too, I guess some apps are too busy for us. */
-		/* g_debug("Introspection error on %s object %s: %s", server->name, _introspector_fullpath[server->introspect_level], error->message); */
-		return;
-	}
-
-	if (OUT_data != NULL) {
-		xmlDocPtr xmldoc;
-		/* Parse the XML */
-		xmldoc = xmlReadMemory(OUT_data, g_utf8_strlen(OUT_data, 16*1024), "introspection.xml", NULL, 0);
-
-		/* Check for root being "node" */
-		xmlNodePtr root = xmlDocGetRootElement(xmldoc);
-		if (g_strcmp0((gchar *)root->name, "node") != 0) {
-			xmlFreeDoc(xmldoc);
-			g_warning("Introspection data from %s is not valid: %s", server->name, OUT_data);
-			return;
-		}
-
-		server->introspect_level += 1;
-		const gchar * nodename = NULL;
-		const gchar * nameval = NULL;
-		if (_introspector_path[server->introspect_level] == NULL) {
-			/* We're looking for our interface */
-			nodename = "interface";
-			nameval = _introspector_interface;
-		} else {
-			/* We're looking for our next node */
-			nodename = "node";
-			nameval = _introspector_path[server->introspect_level];
-		}
-
-		gboolean found = FALSE;
-		xmlNodePtr children;
-		for (children = root->children; children != NULL; children = children->next) {
-			gchar * xmlnameval = NULL;
-			if (g_strcmp0((gchar *)children->name, nodename) == 0) {
-				xmlAttrPtr attrib;
-				for (attrib = children->properties; attrib != NULL; attrib = attrib->next) {
-					if (g_strcmp0((gchar *)attrib->name, "name") == 0) {
-						if (attrib->children != NULL) {
-							xmlnameval = (gchar *)attrib->children->content;
-						}
-						break;
-					}
-				}
-
-				if (!g_strcmp0(nameval, xmlnameval)) {
-					found = TRUE;
-					break;
-				}
-			}
-		}
-
-		xmlFreeDoc(xmldoc);
-
-		if (!found) {
-			/* Ah, nothing we're interested in */
-			return;
-		}
-
-		if (_introspector_path[server->introspect_level] == NULL) {
-			/* If we've found the interface at the end of the tree, whoo! hoo! */
-			/* Now we know it's safe to get the type on it */
-			indicate_listener_server_get_type(server->listener, &server->server, get_type_cb, server);
-			return;
-		}
-	} else {
-		server->introspect_level = 0;
-	}
-
-	DBusGProxy * newproxy = dbus_g_proxy_new_for_name(server->connection,
-	                                                  server->name,
-	                                                  _introspector_fullpath[server->introspect_level],
-	                                                  DBUS_INTERFACE_INTROSPECTABLE);
-
-	org_freedesktop_DBus_Introspectable_introspect_async(newproxy, introspect_this, server);
-
-	return;
-}
-
 /**
 	indicate_listener_set_default_max_indicators:
 	@listener: Instance of #IndicateListener to set on.
@@ -1331,7 +1222,7 @@
 
 	if (server->max_indicators != max) {
 		server->max_indicators = max;
-		org_freedesktop_indicator_set_max_indicators_async(server->proxy, server->max_indicators, set_max_indicators_cb, server->name);
+		org_ayatana_indicate_set_max_indicators_async(server->proxy, server->max_indicators, set_max_indicators_cb, server->name);
 	}
 
 	return;

=== modified file 'libindicate/listener.h'
--- libindicate/listener.h	2010-02-01 02:31:17 +0000
+++ libindicate/listener.h	2010-02-03 20:02:13 +0000
@@ -79,10 +79,10 @@
 	@server_added: Slot for IndicateListener::server-added.
 	@server_removed: Slot for IndicateListener::server-removed.
 	@server_count_changed: Slot for IndicateListener::server-count-changed.
+	@indicator_servers_report: Slot for IndicateListener::indicator-servers-report.
 	@indicate_listener_reserved1: Reserved for future use
 	@indicate_listener_reserved2: Reserved for future use
 	@indicate_listener_reserved3: Reserved for future use
-	@indicate_listener_reserved4: Reserved for future use
 
 	The class has all of the signals that are supplied by
 	the listener about what is happening on the server.
@@ -101,11 +101,12 @@
 	void (* server_removed) (IndicateListenerServer * server, gchar * type);
 	void (* server_count_changed) (IndicateListenerServer * server, guint count);
 
+	void (* indicator_servers_report) (void);
+
 	/* Future Use */
 	void (*indicate_listener_reserved1)(void);
 	void (*indicate_listener_reserved2)(void);
 	void (*indicate_listener_reserved3)(void);
-	void (*indicate_listener_reserved4)(void);
 };
 
 GType indicate_listener_get_type (void) G_GNUC_CONST;

=== modified file 'libindicate/server.c'
--- libindicate/server.c	2010-02-01 05:59:25 +0000
+++ libindicate/server.c	2010-02-03 20:02:13 +0000
@@ -33,6 +33,7 @@
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
 #include <libdbusmenu-glib/server.h>
+#include "dbus-shared.h"
 
 /* Errors */
 enum {
@@ -129,6 +130,7 @@
 G_DEFINE_TYPE (IndicateServer, indicate_server, G_TYPE_OBJECT);
 
 /* Prototypes */
+static DBusHandlerResult dbus_filter_new_listener (DBusConnection * connection, DBusMessage * message, void * user_data);
 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);
@@ -390,7 +392,7 @@
 
 	IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server);
 
-	priv->path = g_strdup("/org/freedesktop/indicate");
+	priv->path = g_strdup("/org/ayatana/indicate");
 	priv->indicators = NULL;
 	priv->num_hidden = 0;
 	priv->visible = FALSE;
@@ -408,6 +410,11 @@
 	priv->interestedfolks = NULL;
 	priv->max_indicators = MAX_INDICATORS_UNSET;
 
+	priv->connection = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
+
+	dbus_connection_add_filter(dbus_g_connection_get_connection(priv->connection), dbus_filter_new_listener, server, NULL);
+	dbus_bus_add_match(dbus_g_connection_get_connection(priv->connection), "type='signal',interface='" INDICATE_LISTENER_DBUS_IFACE "',member='IndicatorServersReport'", NULL);
+
 	return;
 }
 
@@ -526,6 +533,27 @@
 	return;
 }
 
+/* A small dbus filter that waits on the IndicatorServersReport
+   signal and sends the Show signal if this server is not hidden. */
+static DBusHandlerResult
+dbus_filter_new_listener (DBusConnection * connection, DBusMessage * message, void * user_data)
+{
+	if (!dbus_message_is_signal(message, INDICATE_LISTENER_DBUS_IFACE, "IndicatorServersReport")) {
+		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	}
+
+	IndicateServer * server = INDICATE_SERVER(user_data);
+
+	if (server != NULL) {
+		IndicateServerPrivate * priv = INDICATE_SERVER_GET_PRIVATE(server);
+		if (priv->visible) {
+			g_signal_emit(server, signals[SERVER_SHOW], 0, priv->type ? priv->type : "", TRUE);
+		}
+	}
+
+	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
 /* Small little function to get an error quark for usage
    with the GError errors back across DBus */
 static GQuark