diff --git configure.ac configure.ac
index eb90e68..306f3aa 100644
--- configure.ac
+++ configure.ac
@@ -70,6 +70,31 @@ AM_CONDITIONAL(HAVE_LIBCANBERRA_GTK, test "x$CANBERRA_GTK" = "x1")
 
 AM_CONDITIONAL(HAVE_TYPING_BREAK, test "x$TYPING_BREAK" = xtyping-break)
 
+dnl app indicator
+APPINDICATOR_REQUIRED=0.0.7
+
+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_MSG_ERROR([appindicator-0.1 is not installed]))
+        PKG_CHECK_MODULES(APP_INDICATOR,
+                        appindicator-0.1 >= $APPINDICATOR_REQUIRED)
+        AC_SUBST(APP_INDICATOR_CFLAGS)
+        AC_SUBST(APP_INDICATOR_LIBS)
+        AC_DEFINE(HAVE_APP_INDICATOR, 1, [Have AppIndicator])
+fi
+AM_CONDITIONAL(HAVE_APP_INDICATOR, test x"$enable_appindicator" = xyes)
+
 dnl keyboard-properties-capplet
 savecppflags=$CPPFLAGS
 CPPFLAGS="$CPPFLAGS $X_CFLAGS"
diff --git typing-break/Makefile.am typing-break/Makefile.am
index f1b89bf..c03e604 100644
--- typing-break/Makefile.am
+++ typing-break/Makefile.am
@@ -30,6 +30,11 @@ if HAVE_LIBCANBERRA_GTK
   gnome_typing_monitor_LDADD += @LIBCANBERRA_GTK_LIBS@
 endif
 
+if HAVE_APP_INDICATOR
+  gnome_typing_monitor_CFLAGS += -DHAVE_APP_INDICATOR @APP_INDICATOR_CFLAGS@
+  gnome_typing_monitor_LDADD += @APP_INDICATOR_LIBS@
+endif
+
 imagedir = $(pkgdatadir)/pixmaps
 dist_image_DATA = bar.png bar-red.png bar-green.png bar-disabled.png ocean-stripes.png
 
diff --git typing-break/drwright.c typing-break/drwright.c
index 9c7c2a0..5a4dd9e 100644
--- typing-break/drwright.c
+++ typing-break/drwright.c
@@ -29,15 +29,21 @@
 #include <gtk/gtk.h>
 #include <gconf/gconf-client.h>
 
+#ifdef HAVE_APP_INDICATOR
+#include <libappindicator/app-indicator.h>
+#endif /* HAVE_APP_INDICATOR */
+
 #include "drwright.h"
 #include "drw-break-window.h"
 #include "drw-monitor.h"
 #include "drw-utils.h"
 #include "drw-timer.h"
 
+#ifndef HAVE_APP_INDICATOR
 #define BLINK_TIMEOUT        200
 #define BLINK_TIMEOUT_MIN    120
 #define BLINK_TIMEOUT_FACTOR 100
+#endif /* HAVE_APP_INDICATOR */
 
 #define POPUP_ITEM_ENABLED 1
 #define POPUP_ITEM_BREAK   2
@@ -52,6 +58,11 @@ typedef enum {
 	STATE_BREAK_DONE
 } DrwState;
 
+#ifdef HAVE_APP_INDICATOR
+#define TYPING_MONITOR_ACTIVE_ICON "bar-green"
+#define TYPING_MONITOR_ATTENTION_ICON "bar-red"
+#endif /* HAVE_APP_INDICATOR */
+
 struct _DrWright {
 	/* Widgets. */
 	GtkWidget      *break_window;
@@ -76,10 +87,15 @@ struct _DrWright {
 	gboolean        enabled;
 
 	guint           clock_timeout_id;
+#ifndef HAVE_APP_INDICATOR
 	guint           blink_timeout_id;
 
 	gboolean        blink_on;
+#endif /* HAVE_APP_INDICATOR */
 
+#ifdef HAVE_APP_INDICATOR
+	AppIndicator   *indicator;
+#else
 	GtkStatusIcon  *icon;
 
 	GdkPixbuf      *neutral_bar;
@@ -87,6 +103,7 @@ struct _DrWright {
 	GdkPixbuf      *green_bar;
 	GdkPixbuf      *disabled_bar;
 	GdkPixbuf      *composite_bar;
+#endif /* HAVE_APP_INDICATOR */
 
 	GtkWidget      *warn_dialog;
 };
@@ -94,7 +111,12 @@ struct _DrWright {
 static void     activity_detected_cb           (DrwMonitor     *monitor,
 						DrWright       *drwright);
 static gboolean maybe_change_state             (DrWright       *drwright);
+static gint     get_time_left                  (DrWright       *drwright);
+#ifdef HAVE_APP_INDICATOR
+static gboolean update_menu_text               (DrWright       *drwright);
+#else
 static gboolean update_tooltip                 (DrWright       *drwright);
+#endif /* HAVE_APP_INDICATOR */
 static void     break_window_done_cb           (GtkWidget      *window,
 						DrWright       *dr);
 static void     break_window_postpone_cb       (GtkWidget      *window,
@@ -107,7 +129,11 @@ static void     popup_preferences_cb           (GtkAction      *action,
 						DrWright       *dr);
 static void     popup_about_cb                 (GtkAction      *action,
 						DrWright       *dr);
+#ifdef HAVE_APP_INDICATOR
+static void     init_app_indicator             (DrWright       *dr);
+#else
 static void     init_tray_icon                 (DrWright       *dr);
+#endif /* HAVE_APP_INDICATOR */
 static GList *  create_secondary_break_windows (void);
 
 static const GtkActionEntry actions[] = {
@@ -126,6 +152,31 @@ setup_debug_values (DrWright *dr)
 	dr->break_time = 10;
 }
 
+#ifdef HAVE_APP_INDICATOR
+static void
+update_app_indicator (DrWright *dr)
+{
+	AppIndicatorStatus new_status;
+
+	if (!dr->enabled) {
+		app_indicator_set_status (dr->indicator,
+					  APP_INDICATOR_STATUS_PASSIVE);
+		return;
+	}
+
+	switch (dr->state) {
+	case STATE_WARN:
+	case STATE_BREAK_SETUP:
+	case STATE_BREAK:
+		new_status = APP_INDICATOR_STATUS_ATTENTION;
+		break;
+	default:
+		new_status = APP_INDICATOR_STATUS_ACTIVE;
+	}
+
+	app_indicator_set_status (dr->indicator, new_status);
+}
+#else
 static void
 update_icon (DrWright *dr)
 {
@@ -264,6 +315,7 @@ stop_blinking (DrWright *dr)
 
 	/*gtk_widget_hide (GTK_WIDGET (dr->icon));*/
 }
+#endif /* HAVE_APP_INDICATOR */
 
 static gboolean
 grab_keyboard_on_window (GdkWindow *window,
@@ -317,8 +369,10 @@ maybe_change_state (DrWright *dr)
 			dr->break_window = NULL;
 		}
 
+#ifndef HAVE_APP_INDICATOR
 		gtk_status_icon_set_from_pixbuf (dr->icon,
 						 dr->neutral_bar);
+#endif /* HAVE_APP_INDICATOR */
 
 		dr->save_last_time = 0;
 
@@ -329,8 +383,12 @@ maybe_change_state (DrWright *dr)
 			dr->state = STATE_RUNNING;
 		}
 
+#ifdef HAVE_APP_INDICATOR
+		update_menu_text (dr);
+#else
 		update_tooltip (dr);
 		stop_blinking (dr);
+#endif /* HAVE_APP_INDICATOR */
 		break;
 
 	case STATE_RUNNING:
@@ -342,7 +400,9 @@ maybe_change_state (DrWright *dr)
 		} else if (dr->state != STATE_WARN
 			   && elapsed_time >= dr->type_time - dr->warn_time) {
 			dr->state = STATE_WARN;
+#ifndef HAVE_APP_INDICATOR
 			start_blinking (dr);
+#endif /* HAVE_APP_INDICATOR */
 		}
 		break;
 
@@ -355,9 +415,11 @@ maybe_change_state (DrWright *dr)
 			break;
 		}
 
+#ifndef HAVE_APP_INDICATOR
 		stop_blinking (dr);
 		gtk_status_icon_set_from_pixbuf (dr->icon,
 						 dr->red_bar);
+#endif /* HAVE_APP_INDICATOR */
 
 		drw_timer_start (dr->timer);
 
@@ -397,9 +459,11 @@ maybe_change_state (DrWright *dr)
 		break;
 
 	case STATE_BREAK_DONE_SETUP:
+#ifndef HAVE_APP_INDICATOR
 		stop_blinking (dr);
 		gtk_status_icon_set_from_pixbuf (dr->icon,
 						 dr->green_bar);
+#endif /* HAVE_APP_INDICATOR */
 
 		dr->state = STATE_BREAK_DONE;
 		break;
@@ -415,15 +479,53 @@ maybe_change_state (DrWright *dr)
 
 	dr->last_elapsed_time = elapsed_time;
 
+#ifdef HAVE_APP_INDICATOR
+	update_app_indicator (dr);
+#else
 	update_icon (dr);
+#endif /* HAVE_APP_INDICATOR */
 
 	return TRUE;
 }
 
+#ifdef HAVE_APP_INDICATOR
+static gboolean
+update_menu_text (DrWright *dr)
+{
+	const gchar normal_msg_template[]        = "Take a break now (next in %dm)";
+	const gchar less_than_one_msg_template[] = "Take a break now (next in less than one minute)";
+
+	gint       min;
+	gchar     *str;
+	GtkWidget *item;
+
+	if (!dr->enabled) {
+		app_indicator_set_status (dr->indicator,
+					  APP_INDICATOR_STATUS_PASSIVE);
+		return TRUE;
+	}
+
+	min = get_time_left (dr);
+
+	if (min >= 1) {
+		str = g_strdup_printf (_(normal_msg_template), min);
+	} else {
+		str = g_strdup_printf (_(less_than_one_msg_template));
+	}
+
+	/* set menu text */
+	item = gtk_ui_manager_get_widget(dr->ui_manager, "/Pop/TakeABreak");
+	gtk_menu_item_set_label (GTK_MENU_ITEM (item), str);
+
+	g_free (str);
+
+	return TRUE;
+}
+#else
 static gboolean
 update_tooltip (DrWright *dr)
 {
-	gint   elapsed_time, min;
+	gint   min;
 	gchar *str;
 
 	if (!dr->enabled) {
@@ -432,9 +534,7 @@ update_tooltip (DrWright *dr)
 		return TRUE;
 	}
 
-	elapsed_time = drw_timer_elapsed (dr->timer);
-
-	min = floor (0.5 + (dr->type_time - elapsed_time - dr->save_last_time) / 60.0);
+	min = get_time_left (dr);
 
 	if (min >= 1) {
 		str = g_strdup_printf (ngettext("%d minute until the next break",
@@ -451,6 +551,17 @@ update_tooltip (DrWright *dr)
 
 	return TRUE;
 }
+#endif /* HAVE_APP_INDICATOR */
+
+static gint
+get_time_left (DrWright *dr)
+{
+	gint elapsed_time;
+
+	elapsed_time = drw_timer_elapsed (dr->timer);
+
+	return floor (0.5 + (dr->type_time - elapsed_time - dr->save_last_time) / 60.0);
+}
 
 static void
 activity_detected_cb (DrwMonitor *monitor,
@@ -491,7 +602,11 @@ gconf_notify_cb (GConfClient *client,
 							  "/Pop/TakeABreak");
 			gtk_widget_set_sensitive (item, dr->enabled);
 
+#ifdef HAVE_APP_INDICATOR
+			update_menu_text (dr);
+#else
 			update_tooltip (dr);
+#endif /* HAVE_APP_INDICATOR */
 		}
 	}
 
@@ -557,6 +672,7 @@ popup_about_cb (GtkAction *action, DrWright *dr)
 			       NULL);
 }
 
+#ifndef HAVE_APP_INDICATOR
 static void
 popup_menu_cb (GtkWidget *widget,
 	       guint      button,
@@ -575,6 +691,7 @@ popup_menu_cb (GtkWidget *widget,
 			0,
 			gtk_get_current_event_time());
 }
+#endif /* HAVE_APP_INDICATOR */
 
 static void
 break_window_done_cb (GtkWidget *window,
@@ -585,7 +702,11 @@ break_window_done_cb (GtkWidget *window,
 	dr->state = STATE_BREAK_DONE_SETUP;
 	dr->break_window = NULL;
 
+#ifdef HAVE_APP_INDICATOR
+	update_menu_text (dr);
+#else
 	update_tooltip (dr);
+#endif /* HAVE_APP_INDICATOR */
 	maybe_change_state (dr);
 }
 
@@ -613,8 +734,13 @@ break_window_postpone_cb (GtkWidget *window,
 
 	drw_timer_start (dr->timer);
 	maybe_change_state (dr);
+#ifdef HAVE_APP_INDICATOR
+	update_menu_text (dr);
+	update_app_indicator (dr);
+#else
 	update_icon (dr);
 	update_tooltip (dr);
+#endif /* HAVE_APP_INDICATOR */
 }
 
 static void
@@ -631,6 +757,33 @@ break_window_destroy_cb (GtkWidget *window,
 	dr->secondary_break_windows = NULL;
 }
 
+#ifdef HAVE_APP_INDICATOR
+static void
+init_app_indicator (DrWright *dr)
+{
+	GtkWidget *indicator_menu;
+
+	dr->indicator =
+		app_indicator_new_with_path ("typing-break-indicator",
+					     TYPING_MONITOR_ACTIVE_ICON,
+					     APP_INDICATOR_CATEGORY_APPLICATION_STATUS,
+			                     IMAGEDIR);
+	if (dr->enabled) {
+		app_indicator_set_status (dr->indicator,
+					  APP_INDICATOR_STATUS_ACTIVE);
+	} else {
+		app_indicator_set_status (dr->indicator,
+					  APP_INDICATOR_STATUS_PASSIVE);
+	}
+
+	indicator_menu = gtk_ui_manager_get_widget (dr->ui_manager, "/Pop");
+	app_indicator_set_menu (dr->indicator, GTK_MENU (indicator_menu));
+	app_indicator_set_attention_icon (dr->indicator, TYPING_MONITOR_ATTENTION_ICON);
+
+	update_menu_text (dr);
+	update_app_indicator (dr);
+}
+#else
 static void
 init_tray_icon (DrWright *dr)
 {
@@ -644,6 +797,7 @@ init_tray_icon (DrWright *dr)
 			  G_CALLBACK (popup_menu_cb),
 			  dr);
 }
+#endif /* HAVE_APP_INDICATOR */
 
 static GList *
 create_secondary_break_windows (void)
@@ -758,6 +912,12 @@ drwright_new (void)
 			  G_CALLBACK (activity_detected_cb),
 			  dr);
 
+#ifdef	HAVE_APP_INDICATOR
+	init_app_indicator (dr);
+	g_timeout_add_seconds (12,
+			       (GSourceFunc) update_menu_text,
+			       dr);
+#else
 	dr->neutral_bar = gdk_pixbuf_new_from_file (IMAGEDIR "/bar.png", NULL);
 	dr->red_bar = gdk_pixbuf_new_from_file (IMAGEDIR "/bar-red.png", NULL);
 	dr->green_bar = gdk_pixbuf_new_from_file (IMAGEDIR "/bar-green.png", NULL);
@@ -768,6 +928,7 @@ drwright_new (void)
 	g_timeout_add_seconds (12,
 		       (GSourceFunc) update_tooltip,
 		       dr);
+#endif /* HAVE_APP_INDICATOR */
 	g_timeout_add_seconds (1,
 		       (GSourceFunc) maybe_change_state,
 		       dr);
diff --git typing-break/main.c typing-break/main.c
index 30f5c3e..7dfe980 100644
--- typing-break/main.c
+++ typing-break/main.c
@@ -95,6 +95,7 @@ main (int argc, char *argv[])
 		return 0;
 	}
 
+#ifndef HAVE_APP_INDICATOR
 	if (!no_check && !have_tray ()) {
 		GtkWidget *dialog;
 
@@ -112,6 +113,7 @@ main (int argc, char *argv[])
 
 		gtk_widget_destroy (dialog);
 	}
+#endif /* HAVE_APP_INDICATOR */
 	
 	drwright = drwright_new ();
 
