diff --git a/configure.ac b/configure.ac
index a9ecc58..7bc3fb1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -124,6 +124,7 @@ LIBPANEL_REQUIRED=2.0.0
 XRANDR_REQUIRED=1.2.0
 CANBERRA_REQUIRED=0.10
 DEVKIT_POWER_REQUIRED=008
+APPINDICATOR_REQUIRED=0.0.10
 
 dnl ---------------------------------------------------------------------------
 dnl - Make above strings available for packaging files (e.g. rpm spec files)
@@ -201,6 +202,27 @@ PKG_CHECK_MODULES(DEVKIT, [
 AC_SUBST(DEVKIT_CFLAGS)
 AC_SUBST(DEVKIT_LIBS)
 
+AC_ARG_ENABLE([appindicator],
+ AS_HELP_STRING([--enable-appindicator[=@<:@no/auto/yes@:>@]],[Build support for application indicators]),
+ [enable_appindicator=$enableval],
+ [enable_appindicator="auto"])
+
+if test x$enable_appindicator = xauto ; then
+  PKG_CHECK_EXISTS([appindicator-0.1 >= $APPINDICATOR_REQUIRED],
+    [enable_appindicator="yes"],
+    [enable_appindicator="no"])
+fi
+
+if test x$enable_appindicator = xyes ; then
+  PKG_CHECK_EXISTS([appindicator-0.1 >= $APPINDICATOR_REQUIRED],
+    [AC_DEFINE(HAVE_APP_INDICATOR, 1, [Have AppIndicator])
+     PKG_CHECK_MODULES(APP_INDICATOR, [appindicator-0.1 >= $APPINDICATOR_REQUIRED])],
+    [AC_MSG_ERROR([appindicator-0.1 is not installed])])
+fi
+AM_CONDITIONAL(HAVE_APP_INDICATOR, [test x$enable_appindicator = xyes])
+AC_SUBST(APP_INDICATOR_CFLAGS)
+AC_SUBST(APP_INDICATOR_LIBS)
+
 AC_PATH_PROG(GCONFTOOL, gconftool-2)
 AM_GCONF_SOURCE_2
 
@@ -597,6 +619,7 @@ echo "
         Self test support:         ${have_tests}
         GConf default support:     ${have_gconfdefaults}
         Docbook support:           ${enable_docbook_docs}
+        App indicator support:     ${enable_appindicator}
         documentation dir:         $DOCDIR
         dbus-1 services dir:       $DBUS_SERVICES_DIR
         gconf-schema dir:          $GCONF_SCHEMA_FILE_DIR
diff --git a/src/Makefile.am b/src/Makefile.am
index 4f9e401..208c6e6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,6 +20,7 @@ INCLUDES =						\
 	$(GSTREAMER_CFLAGS)				\
 	-DI_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE \
 	$(DEVKIT_CFLAGS)				\
+	$(APP_INDICATOR_CFLAGS)				\
 	-DBINDIR=\"$(bindir)\"			 	\
 	-DGNOMELOCALEDIR=\""$(datadir)/locale"\"	\
 	-DDATADIR=\"$(datadir)\"			\
@@ -189,6 +190,7 @@ gnome_power_manager_LDADD =				\
 	$(LIBNOTIFY_LIBS)				\
 	$(GPM_EXTRA_LIBS)				\
 	$(DEVKIT_LIBS)					\
+	$(APP_INDICATOR_LIBS)				\
 	-lm
 
 if HAVE_HAL
diff --git a/src/gpm-engine.c b/src/gpm-engine.c
index d244219..7bab25f 100644
--- a/src/gpm-engine.c
+++ b/src/gpm-engine.c
@@ -75,6 +75,7 @@ enum {
 	DISCHARGING,
 	LOW_CAPACITY,
 	PERHAPS_RECALL,
+        DEVICES_CHANGED,
 	LAST_SIGNAL
 };
 
@@ -491,6 +492,8 @@ gpm_engine_recalculate_state (GpmEngine *engine)
 
 	gpm_engine_recalculate_state_icon (engine);
 	gpm_engine_recalculate_state_summary (engine);
+
+	g_signal_emit (engine, signals [DEVICES_CHANGED], 0);
 }
 
 /**
@@ -1193,6 +1196,13 @@ gpm_engine_class_init (GpmEngineClass *klass)
 			      G_STRUCT_OFFSET (GpmEngineClass, charge_critical),
 			      NULL, NULL, g_cclosure_marshal_VOID__POINTER,
 			      G_TYPE_NONE, 1, G_TYPE_POINTER);
+	signals [DEVICES_CHANGED] =
+		g_signal_new ("devices-changed",
+			      G_TYPE_FROM_CLASS (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (GpmEngineClass, devices_changed),
+			      NULL, NULL, g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE, 0);
 }
 
 /**
diff --git a/src/gpm-engine.h b/src/gpm-engine.h
index bb0be63..3699865 100644
--- a/src/gpm-engine.h
+++ b/src/gpm-engine.h
@@ -65,6 +65,7 @@ typedef struct
 						 DkpDevice	*device);
 	void		(* discharging)		(GpmEngine	*engine,
 						 DkpDevice	*device);
+	void		(* devices_changed)	(GpmEngine	*engine);
 } GpmEngineClass;
 
 GType		 gpm_engine_get_type		(void);
diff --git a/src/gpm-manager.c b/src/gpm-manager.c
index 68577b9..6a60db9 100644
--- a/src/gpm-manager.c
+++ b/src/gpm-manager.c
@@ -379,7 +379,7 @@ gpm_manager_notify (GpmManager *manager, NotifyNotification **notification_class
 	gpm_manager_notify_close (manager, *notification_class);
 
 	/* if the status icon is hidden, don't point at it */
-	if (gtk_status_icon_is_embedded (manager->priv->status_icon))
+	if (manager->priv->status_icon && gtk_status_icon_is_embedded (manager->priv->status_icon))
 		notification = notify_notification_new_with_status_icon (title, message, icon, manager->priv->status_icon);
 	else
 		notification = notify_notification_new (title, message, icon, NULL);
@@ -1961,7 +1961,8 @@ gpm_manager_finalize (GObject *object)
 	g_object_unref (manager->priv->backlight);
 	g_object_unref (manager->priv->console);
 	g_object_unref (manager->priv->client);
-	g_object_unref (manager->priv->status_icon);
+	if (manager->priv->status_icon)
+		g_object_unref (manager->priv->status_icon);
 
 	G_OBJECT_CLASS (gpm_manager_parent_class)->finalize (object);
 }
diff --git a/src/gpm-tray-icon.c b/src/gpm-tray-icon.c
index 569d490..df1f2be 100644
--- a/src/gpm-tray-icon.c
+++ b/src/gpm-tray-icon.c
@@ -41,6 +41,10 @@
 #include <gconf/gconf-client.h>
 #include <devkit-power-gobject/devicekit-power.h>
 
+#ifdef HAVE_APP_INDICATOR
+#include <libappindicator/app-indicator.h>
+#endif
+
 #include "egg-debug.h"
 
 #include "gpm-upower.h"
@@ -57,15 +61,19 @@ struct GpmTrayIconPrivate
 {
 	GConfClient		*conf;
 	GpmEngine		*engine;
+#ifdef HAVE_APP_INDICATOR
+	AppIndicator		*app_indicator;
+#else
 	GtkStatusIcon		*status_icon;
+#endif
 	gboolean		 show_actions;
 };
 
 G_DEFINE_TYPE (GpmTrayIcon, gpm_tray_icon, G_TYPE_OBJECT)
 
-/**
- * gpm_tray_icon_enable_actions:
- **/
+	/**
+	 * gpm_tray_icon_enable_actions:
+	 **/
 static void
 gpm_tray_icon_enable_actions (GpmTrayIcon *icon, gboolean enabled)
 {
@@ -81,7 +89,16 @@ static void
 gpm_tray_icon_show (GpmTrayIcon *icon, gboolean enabled)
 {
 	g_return_if_fail (GPM_IS_TRAY_ICON (icon));
+#ifdef HAVE_APP_INDICATOR
+	if (enabled)
+		app_indicator_set_status (icon->priv->app_indicator,
+					  APP_INDICATOR_STATUS_ACTIVE);
+	else
+		app_indicator_set_status (icon->priv->app_indicator,
+					  APP_INDICATOR_STATUS_PASSIVE);
+#else
 	gtk_status_icon_set_visible (icon->priv->status_icon, enabled);
+#endif
 }
 
 /**
@@ -95,11 +112,13 @@ gpm_tray_icon_set_tooltip (GpmTrayIcon *icon, const gchar *tooltip)
 	g_return_val_if_fail (GPM_IS_TRAY_ICON (icon), FALSE);
 	g_return_val_if_fail (tooltip != NULL, FALSE);
 
+#ifndef HAVE_APP_INDICATOR
 #if GTK_CHECK_VERSION(2,15,0)
 	gtk_status_icon_set_tooltip_text (icon->priv->status_icon, tooltip);
 #else
 	gtk_status_icon_set_tooltip (icon->priv->status_icon, tooltip);
 #endif
+#endif
 	return TRUE;
 }
 
@@ -110,7 +129,11 @@ GtkStatusIcon *
 gpm_tray_icon_get_status_icon (GpmTrayIcon *icon)
 {
 	g_return_val_if_fail (GPM_IS_TRAY_ICON (icon), NULL);
+#ifdef HAVE_APP_INDICATOR
+	return NULL;
+#else
 	return g_object_ref (icon->priv->status_icon);
+#endif
 }
 
 /**
@@ -127,7 +150,11 @@ gpm_tray_icon_set_icon (GpmTrayIcon *icon, const gchar *filename)
 
 	if (filename != NULL) {
 		egg_debug ("Setting icon to %s", filename);
+#ifdef HAVE_APP_INDICATOR
+		app_indicator_set_icon (icon->priv->app_indicator, filename);
+#else
 		gtk_status_icon_set_from_icon_name (icon->priv->status_icon, filename);
+#endif
 
 		/* make sure that we are visible */
 		gpm_tray_icon_show (icon, TRUE);
@@ -171,21 +198,6 @@ gpm_tray_icon_show_preferences_cb (GtkMenuItem *item, gpointer data)
 }
 
 /**
- * gpm_tray_icon_popup_cleared_cd:
- * @widget: The popup Gtkwidget
- *
- * We have to re-enable the tooltip when the popup is removed
- **/
-static void
-gpm_tray_icon_popup_cleared_cd (GtkWidget *widget, GpmTrayIcon *icon)
-{
-	g_return_if_fail (GPM_IS_TRAY_ICON (icon));
-	egg_debug ("clear tray");
-	g_object_ref_sink (widget);
-	g_object_unref (widget);
-}
-
-/**
  * gpm_tray_icon_class_init:
  **/
 static void
@@ -257,14 +269,16 @@ gpm_tray_icon_add_device (GpmTrayIcon *icon, GtkMenu *menu, const GPtrArray *arr
 /**
  * gpm_tray_icon_create_menu:
  *
- * Display the popup menu.
+ * Create the popup menu.
  **/
-static void
-gpm_tray_icon_create_menu (GpmTrayIcon *icon, guint32 timestamp)
+static GtkMenu *
+gpm_tray_icon_create_menu (GpmTrayIcon *icon)
 {
 	GtkMenu *menu = (GtkMenu*) gtk_menu_new ();
 	GtkWidget *item;
+#ifndef HAVE_APP_INDICATOR
 	GtkWidget *image;
+#endif
 	guint dev_cnt = 0;
 	GPtrArray *array;
 
@@ -289,14 +303,62 @@ gpm_tray_icon_create_menu (GpmTrayIcon *icon, guint32 timestamp)
 	}
 
 	/* preferences */
+#ifdef HAVE_APP_INDICATOR
+	item = gtk_menu_item_new_with_mnemonic (_("_Preferences"));
+#else
 	item = gtk_image_menu_item_new_with_mnemonic (_("_Preferences"));
 	image = gtk_image_new_from_icon_name (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU);
 	gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
+#endif
 	g_signal_connect (G_OBJECT (item), "activate",
 			  G_CALLBACK (gpm_tray_icon_show_preferences_cb), icon);
 	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 
 skip_prefs:
+	return menu;
+}
+
+#ifdef HAVE_APP_INDICATOR
+/**
+ * gpm_tray_icon_devices_changed_cb:
+ *
+ * Callback when devices are changed and menu has to be recreated
+ **/
+static void
+gpm_tray_icon_devices_changed_cb (GpmEngine *engine, GpmTrayIcon *icon)
+{
+	GtkMenu *menu;
+	menu = gpm_tray_icon_create_menu (icon);
+	app_indicator_set_menu (icon->priv->app_indicator, menu);
+}
+#else
+/**
+ * gpm_tray_icon_popup_cleared_cd:
+ * @widget: The popup Gtkwidget
+ *
+ * We have to re-enable the tooltip when the popup is removed
+ **/
+static void
+gpm_tray_icon_popup_cleared_cd (GtkWidget *widget, GpmTrayIcon *icon)
+{
+	g_return_if_fail (GPM_IS_TRAY_ICON (icon));
+	egg_debug ("clear tray");
+	g_object_ref_sink (widget);
+	g_object_unref (widget);
+}
+
+/**
+ * gpm_tray_icon_popup_menu:
+ *
+ * Display the popup menu.
+ **/
+static void
+gpm_tray_icon_popup_menu (GpmTrayIcon *icon, guint32 timestamp)
+{
+	GtkMenu *menu;
+
+	menu = gpm_tray_icon_create_menu (icon);
+
 	/* show the menu */
 	gtk_widget_show_all (GTK_WIDGET (menu));
 	gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
@@ -316,7 +378,7 @@ static void
 gpm_tray_icon_popup_menu_cb (GtkStatusIcon *status_icon, guint button, guint32 timestamp, GpmTrayIcon *icon)
 {
 	egg_debug ("icon right clicked");
-	gpm_tray_icon_create_menu (icon, timestamp);
+	gpm_tray_icon_popup_menu (icon, timestamp);
 }
 
 
@@ -330,8 +392,9 @@ static void
 gpm_tray_icon_activate_cb (GtkStatusIcon *status_icon, GpmTrayIcon *icon)
 {
 	egg_debug ("icon left clicked");
-	gpm_tray_icon_create_menu (icon, gtk_get_current_event_time());
+	gpm_tray_icon_popup_menu (icon, gtk_get_current_event_time());
 }
+#endif
 
 /**
  * gpm_conf_gconf_key_changed_cb:
@@ -363,6 +426,9 @@ static void
 gpm_tray_icon_init (GpmTrayIcon *icon)
 {
 	gboolean allowed_in_menu;
+#ifdef HAVE_APP_INDICATOR
+	GtkMenu *menu;
+#endif
 
 	icon->priv = GPM_TRAY_ICON_GET_PRIVATE (icon);
 
@@ -376,6 +442,17 @@ gpm_tray_icon_init (GpmTrayIcon *icon)
 				 (GConfClientNotifyFunc) gpm_conf_gconf_key_changed_cb,
 				 icon, NULL, NULL);
 
+#ifdef HAVE_APP_INDICATOR
+	icon->priv->app_indicator = app_indicator_new ("gnome-power-manager",
+						       "gnome-power-manager",
+						       APP_INDICATOR_CATEGORY_HARDWARE);
+
+	menu = gpm_tray_icon_create_menu (icon);
+	app_indicator_set_menu (icon->priv->app_indicator, menu);
+	g_signal_connect_object (G_OBJECT (icon->priv->engine), "devices-changed",
+				 G_CALLBACK (gpm_tray_icon_devices_changed_cb),
+				 icon, 0);
+#else
 	icon->priv->status_icon = gtk_status_icon_new ();
 	g_signal_connect_object (G_OBJECT (icon->priv->status_icon),
 				 "popup_menu",
@@ -385,6 +462,7 @@ gpm_tray_icon_init (GpmTrayIcon *icon)
 				 "activate",
 				 G_CALLBACK (gpm_tray_icon_activate_cb),
 				 icon, 0);
+#endif
 
 	allowed_in_menu = gconf_client_get_bool (icon->priv->conf, GPM_CONF_UI_SHOW_ACTIONS, NULL);
 	gpm_tray_icon_enable_actions (icon, allowed_in_menu);
@@ -404,7 +482,11 @@ gpm_tray_icon_finalize (GObject *object)
 
 	tray_icon = GPM_TRAY_ICON (object);
 
+#ifdef HAVE_APP_INDICATOR
+	g_object_unref (tray_icon->priv->app_indicator);
+#else
 	g_object_unref (tray_icon->priv->status_icon);
+#endif
 	g_object_unref (tray_icon->priv->engine);
 	g_return_if_fail (tray_icon->priv != NULL);
 
