Index: widgets/eggtrayicon.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/widgets/eggtrayicon.c,v
retrieving revision 1.17
diff -u -p -r1.17 eggtrayicon.c
--- widgets/eggtrayicon.c	24 Jul 2006 13:28:41 -0000	1.17
+++ widgets/eggtrayicon.c	7 Aug 2006 01:37:49 -0000
@@ -574,18 +574,11 @@ egg_tray_icon_notify (EggTrayIcon *icon,
   GdkPixbuf *pixbuf;
   int x;
   int y;
-  char *esc_primary;
-  char *esc_secondary;
 
   if (!notify_is_initted ())
     if (!notify_init ("rhythmbox"))
       return;
 
-  if (icon->notify->handle != NULL)
-    {
-      notify_notification_close (icon->notify->handle, NULL);
-    }
-
   if (primary == NULL)
     {
       primary = "";
@@ -595,20 +588,26 @@ egg_tray_icon_notify (EggTrayIcon *icon,
       secondary = "";
     }
 
-  esc_primary = g_markup_escape_text (primary, strlen (primary));
-  esc_secondary = g_markup_escape_text (secondary, strlen (secondary));
-  icon->notify->handle = notify_notification_new (esc_primary,
-                                                  esc_secondary,
-                                                  NULL,
-                                                  GTK_WIDGET (icon));
-  g_free (esc_primary);
-  g_free (esc_secondary);
+  if (icon->notify->handle != NULL)
+    {
+      notify_notification_update (icon->notify->handle,
+				  primary,
+				  secondary,
+				  NULL);
+    }
+  else
+    {
+      icon->notify->handle = notify_notification_new (primary,
+						      secondary,
+						      NULL,
+						      GTK_WIDGET (icon));
+    }
 
   notify_notification_set_timeout (icon->notify->handle, timeout);
 
   if (msgicon)
     {
-      pixbuf = gtk_image_get_pixbuf (GTK_IMAGE (msgicon));
+      pixbuf = g_object_ref (gtk_image_get_pixbuf (GTK_IMAGE (msgicon)));
     }
   else
     {
@@ -653,8 +652,6 @@ egg_tray_icon_notify (EggTrayIcon *icon,
   NotifyIcon *icon_notify = NULL;
   NotifyHints *hints;
   char *fn;
-  char *esc_primary;
-  char *esc_secondary;
 
   if (!notify_is_initted ())
     if (!notify_init ("rhythmbox"))
@@ -686,7 +683,6 @@ egg_tray_icon_notify (EggTrayIcon *icon,
 	    {
 	      icon_notify = NULL;
 	    }
-	  g_free (pix);
 	  g_free (tmp);
 	}
     }
@@ -702,8 +698,6 @@ egg_tray_icon_notify (EggTrayIcon *icon,
       notify_close (icon->notify->handle);
     }
 
-  esc_primary = g_markup_escape_text (primary, strlen (primary));
-  esc_secondary = g_markup_escape_text (secondary, strlen (secondary));
   icon->notify->hints = hints;
   icon->notify->icon = icon_notify;
   icon->notify->handle = notify_send_notification (NULL, "transfer",
@@ -715,8 +709,6 @@ egg_tray_icon_notify (EggTrayIcon *icon,
 			    	   	           hints,
 			    	   	           NULL,
 			    	   	           0);
-  g_free (esc_primary);
-  g_free (esc_secondary);
   return;
 #endif
 #endif
Index: shell/rb-tray-icon.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/shell/rb-tray-icon.c,v
retrieving revision 1.34
diff -u -p -r1.34 rb-tray-icon.c
--- shell/rb-tray-icon.c	17 Jul 2006 14:52:29 -0000	1.34
+++ shell/rb-tray-icon.c	7 Aug 2006 01:37:50 -0000
@@ -30,6 +30,7 @@
 #include <gtk/gtk.h>
 #include <libgnomevfs/gnome-vfs.h>
 #include <libgnomevfs/gnome-vfs-mime-utils.h>
+#include <libsexy/sexy-tooltip.h>
 
 #include "rb-tray-icon.h"
 #include "rb-stock-icons.h"
@@ -39,6 +40,8 @@
 #include "rb-shell.h"
 #include "rb-shell-player.h"
 
+#define TRAY_ICON_DEFAULT_TOOLTIP _("Rhythmbox")
+
 static void rb_tray_icon_class_init (RBTrayIconClass *klass);
 static void rb_tray_icon_init (RBTrayIcon *shell_player);
 static GObject *rb_tray_icon_constructor (GType type, guint n_construct_properties,
@@ -59,6 +62,12 @@ static void rb_tray_icon_button_press_ev
 						RBTrayIcon *icon);
 static void rb_tray_icon_scroll_event_cb (GtkWidget *ebox, GdkEvent *event,
 						RBTrayIcon *icon);
+static void rb_tray_icon_enter_notify_event_cb (RBTrayIcon *icon,
+						GdkEvent *event,
+						GtkWidget *widget);
+static void rb_tray_icon_leave_notify_event_cb (RBTrayIcon *icon,
+						GdkEvent *event,
+						GtkWidget *widget);
 static void rb_tray_icon_show_window_changed_cb (GtkAction *action,
 						 RBTrayIcon *icon);
 static void rb_tray_icon_show_notifications_changed_cb (GtkAction *action,
@@ -71,14 +80,24 @@ static void rb_tray_icon_drop_cb (GtkWid
 				  guint info,
 				  guint time,
 				  RBTrayIcon *icon);
+static void rb_tray_icon_suppress_tooltips (RBTrayIcon *icon, guint duration);
+static void rb_tray_icon_construct_tooltip (RBTrayIcon *icon);
 
 struct RBTrayIconPrivate
 {
-	GtkTooltips *tooltips;
 	GtkUIManager *ui_manager;
 	GtkActionGroup *actiongroup;
 
 	GtkWidget *ebox;
+	GtkWidget *tooltip;
+	gboolean tooltips_should_show;
+	gboolean tooltips_enabled;
+	gboolean tooltips_suppressed;
+	GtkWidget *tooltip_primary;
+	GtkWidget *tooltip_secondary;
+	GtkWidget *tooltip_image_box;
+	guint tooltip_unsuppress_id;
+	guint tooltip_unhide_id;
 
 	RBShell *shell;
 	RBShellPlayer *shell_player;
@@ -161,10 +180,7 @@ rb_tray_icon_init (RBTrayIcon *icon)
 
 	icon->priv = RB_TRAY_ICON_GET_PRIVATE (icon);
 
-	icon->priv->tooltips = gtk_tooltips_new ();
-
-	gtk_tooltips_set_tip (icon->priv->tooltips, GTK_WIDGET (icon),
-			      _("Not playing"), NULL);
+	rb_tray_icon_construct_tooltip (icon);
 
 	icon->priv->ebox = gtk_event_box_new ();
 	g_signal_connect_object (G_OBJECT (icon->priv->ebox),
@@ -175,6 +191,14 @@ rb_tray_icon_init (RBTrayIcon *icon)
 				 "scroll_event",
 				 G_CALLBACK (rb_tray_icon_scroll_event_cb),
 				 icon, 0);
+	g_signal_connect_object (G_OBJECT (icon->priv->ebox),
+				 "enter-notify-event",
+				 G_CALLBACK (rb_tray_icon_enter_notify_event_cb),
+				 icon, G_CONNECT_SWAPPED);
+	g_signal_connect_object (G_OBJECT (icon->priv->ebox),
+				 "leave-notify-event",
+				 G_CALLBACK (rb_tray_icon_leave_notify_event_cb),
+				 icon, G_CONNECT_SWAPPED);
 	gtk_drag_dest_set (icon->priv->ebox, GTK_DEST_DEFAULT_ALL, target_uri, 1, GDK_ACTION_COPY);
 	g_signal_connect_object (G_OBJECT (icon->priv->ebox), "drag_data_received",
 				 G_CALLBACK (rb_tray_icon_drop_cb), icon, 0);
@@ -239,7 +263,11 @@ rb_tray_icon_finalize (GObject *object)
 		g_object_unref (tray->priv->shell_player);
 	}
 
-	gtk_object_destroy (GTK_OBJECT (tray->priv->tooltips));
+	if (tray->priv->tooltip_unsuppress_id > 0)
+		g_source_remove (tray->priv->tooltip_unsuppress_id);
+	if (tray->priv->tooltip_unhide_id > 0)
+		g_source_remove (tray->priv->tooltip_unhide_id);
+	gtk_object_destroy (GTK_OBJECT (tray->priv->tooltip));
 
 	G_OBJECT_CLASS (rb_tray_icon_parent_class)->finalize (object);
 }
@@ -504,14 +532,6 @@ rb_tray_icon_get_geom (RBTrayIcon *icon,
 }
 
 void
-rb_tray_icon_set_tooltip (RBTrayIcon *icon, const char *tooltip)
-{
-	gtk_tooltips_set_tip (icon->priv->tooltips,
-			      GTK_WIDGET (icon),
-			      tooltip, NULL);
-}
-
-void
 rb_tray_icon_notify (RBTrayIcon *icon,
 		     guint timeout,
 		     const char *primary,
@@ -528,6 +548,8 @@ rb_tray_icon_notify (RBTrayIcon *icon,
 	}
 
 	rb_debug ("doing notify: %s", primary);
+	if (timeout > 0)
+		rb_tray_icon_suppress_tooltips (icon, timeout);
 	egg_tray_icon_notify (EGG_TRAY_ICON (icon), timeout, primary, msgicon, secondary);
 }
 
@@ -535,4 +557,173 @@ void
 rb_tray_icon_cancel_notify (RBTrayIcon *icon)
 {
 	egg_tray_icon_cancel_message (EGG_TRAY_ICON (icon), 1);
+}
+
+static void
+rb_tray_icon_update_visibility (RBTrayIcon *icon)
+{
+	if (icon->priv->tooltips_should_show && icon->priv->tooltips_enabled
+			&& !icon->priv->tooltips_suppressed)
+		gtk_widget_show (icon->priv->tooltip);
+	else
+		gtk_widget_hide (icon->priv->tooltip);
+}
+
+static void
+rb_tray_icon_enter_notify_event_cb (RBTrayIcon *icon, GdkEvent *event,
+		GtkWidget *widget)
+{
+	icon->priv->tooltips_should_show = TRUE;
+	rb_tray_icon_update_visibility (icon);
+}
+
+static void
+rb_tray_icon_leave_notify_event_cb (RBTrayIcon *icon, GdkEvent *event,
+		GtkWidget *widget)
+{
+	icon->priv->tooltips_should_show = FALSE;
+	rb_tray_icon_update_visibility (icon);
+}
+
+static void
+rb_tray_icon_tooltip_size_allocate_cb (RBTrayIcon *icon,
+		GtkAllocation *allocation, GtkWidget *tooltip)
+{
+	sexy_tooltip_position_to_widget (SEXY_TOOLTIP (icon->priv->tooltip), icon->priv->ebox);
+}
+
+static void
+rb_tray_icon_construct_tooltip (RBTrayIcon *icon)
+{
+	GtkWidget *hbox, *vbox, *image;
+	gint size;
+	PangoFontDescription *font_desc;
+	
+	icon->priv->tooltips_should_show = FALSE;
+	icon->priv->tooltips_enabled = TRUE;
+	icon->priv->tooltips_suppressed = FALSE;
+	icon->priv->tooltip = sexy_tooltip_new ();
+
+	g_signal_connect_object (icon->priv->tooltip, "size-allocate", (GCallback) rb_tray_icon_tooltip_size_allocate_cb, icon, G_CONNECT_SWAPPED | G_CONNECT_AFTER);
+
+	icon->priv->tooltip_primary = gtk_label_new (TRAY_ICON_DEFAULT_TOOLTIP);
+	gtk_widget_modify_font (icon->priv->tooltip_primary, NULL);
+	size = pango_font_description_get_size (icon->priv->tooltip_primary->style->font_desc);
+	font_desc = pango_font_description_new ();
+	pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
+	pango_font_description_set_size (font_desc, size * PANGO_SCALE_LARGE);
+	gtk_widget_modify_font (icon->priv->tooltip_primary, font_desc);
+	pango_font_description_free (font_desc);
+	gtk_label_set_line_wrap (GTK_LABEL (icon->priv->tooltip_primary),
+				 TRUE);
+	gtk_misc_set_alignment  (GTK_MISC  (icon->priv->tooltip_primary),
+				 0.0, 0.0);
+
+	icon->priv->tooltip_secondary = gtk_label_new (NULL);
+	gtk_widget_set_no_show_all (icon->priv->tooltip_secondary, TRUE);
+	gtk_label_set_line_wrap (GTK_LABEL (icon->priv->tooltip_secondary),
+				 TRUE);
+	gtk_misc_set_alignment  (GTK_MISC  (icon->priv->tooltip_secondary),
+				 0.0, 0.0);
+
+	image = gtk_image_new_from_icon_name ("gnome-media-player",
+					      GTK_ICON_SIZE_DIALOG);
+	icon->priv->tooltip_image_box = gtk_vbox_new (FALSE, 12);
+	gtk_box_pack_start (GTK_BOX (icon->priv->tooltip_image_box), image,
+			    FALSE, FALSE, 0);
+
+	hbox = gtk_hbox_new (FALSE, 12);
+	vbox = gtk_vbox_new (FALSE, 12);
+
+	gtk_box_pack_start (GTK_BOX (vbox), icon->priv->tooltip_primary,
+			    FALSE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (vbox), icon->priv->tooltip_secondary,
+			    TRUE, TRUE, 0);
+	gtk_box_pack_start (GTK_BOX (hbox), icon->priv->tooltip_image_box,
+			    FALSE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (hbox), vbox,
+			    TRUE, TRUE, 0);
+	gtk_widget_show_all (hbox);
+
+	gtk_container_add (GTK_CONTAINER (icon->priv->tooltip), hbox);
+}
+
+static gboolean
+rb_tray_icon_unsuppress_cb (RBTrayIcon *icon)
+{
+	gdk_threads_enter ();
+	icon->priv->tooltips_suppressed = FALSE;
+	rb_tray_icon_update_visibility (icon);
+	icon->priv->tooltip_unsuppress_id = 0;
+	gdk_threads_leave ();
+	return FALSE;
+}
+
+static void
+rb_tray_icon_suppress_tooltips (RBTrayIcon *icon, guint duration)
+{
+	g_return_if_fail (duration > 0);
+
+	icon->priv->tooltips_suppressed = TRUE;
+	rb_tray_icon_update_visibility (icon);
+
+	if (icon->priv->tooltip_unsuppress_id > 0)
+		g_source_remove (icon->priv->tooltip_unsuppress_id);
+	icon->priv->tooltip_unsuppress_id = g_timeout_add (duration, (GSourceFunc) rb_tray_icon_unsuppress_cb, icon);
+}
+
+static gboolean
+rb_tray_icon_unhide_cb (RBTrayIcon *icon)
+{
+	gdk_threads_enter ();
+	rb_tray_icon_update_visibility (icon);
+	icon->priv->tooltip_unhide_id = 0;
+	gdk_threads_leave ();
+	return FALSE;
+}
+
+void
+rb_tray_icon_set_tooltip (RBTrayIcon *icon, const char *primary)
+{
+	/* hide, then reshow in the right position & size */
+	gtk_widget_hide (icon->priv->tooltip);
+	gtk_label_set_text (GTK_LABEL (icon->priv->tooltip_primary),
+			    (primary != NULL) ? primary : TRAY_ICON_DEFAULT_TOOLTIP);
+	if (icon->priv->tooltip_unhide_id > 0)
+		g_source_remove (icon->priv->tooltip_unhide_id);
+	icon->priv->tooltip_unhide_id = g_idle_add ((GSourceFunc) rb_tray_icon_unhide_cb, icon);
+}
+
+void
+rb_tray_icon_set_tooltip_secondary_markup (RBTrayIcon *icon, const char *secondary)
+{
+	if (secondary != NULL) {
+		gtk_label_set_markup (GTK_LABEL (icon->priv->tooltip_secondary), secondary);
+		gtk_widget_show (icon->priv->tooltip_secondary);
+	} else
+		gtk_widget_hide (icon->priv->tooltip_secondary);
+}
+
+void
+rb_tray_icon_set_tooltip_image (RBTrayIcon *icon, GtkWidget *image)
+{
+	GtkWidget *current_image;
+
+	if (image == NULL)
+		image = gtk_image_new_from_icon_name ("gnome-media-player", GTK_ICON_SIZE_DIALOG);
+	current_image = GTK_WIDGET (gtk_container_get_children (GTK_CONTAINER (icon->priv->tooltip_image_box))->data);
+	if (image == current_image)
+		return;
+	gtk_container_remove (GTK_CONTAINER (icon->priv->tooltip_image_box),
+			      current_image);
+	gtk_box_pack_start (GTK_BOX (icon->priv->tooltip_image_box), image,
+			    FALSE, FALSE, 0);
+	gtk_widget_show (image);
+}
+
+void
+rb_tray_icon_enable_tooltips (RBTrayIcon *icon, gboolean enabled)
+{
+	icon->priv->tooltips_enabled = enabled;
+	rb_tray_icon_update_visibility (icon);
 }
Index: shell/rb-tray-icon.h
===================================================================
RCS file: /cvs/gnome/rhythmbox/shell/rb-tray-icon.h,v
retrieving revision 1.10
diff -u -p -r1.10 rb-tray-icon.h
--- shell/rb-tray-icon.h	12 May 2006 16:04:49 -0000	1.10
+++ shell/rb-tray-icon.h	7 Aug 2006 01:37:50 -0000
@@ -65,7 +65,14 @@ void                    rb_tray_icon_not
 
 void                    rb_tray_icon_cancel_notify (RBTrayIcon *icon);
 
-void			rb_tray_icon_set_tooltip(RBTrayIcon *icon, const char *tooltip);
+void	rb_tray_icon_set_tooltip		  (RBTrayIcon *icon,
+						   const char *primary);
+void	rb_tray_icon_set_tooltip_secondary_markup (RBTrayIcon *icon,
+						   const char *secondary);
+void	rb_tray_icon_set_tooltip_image		  (RBTrayIcon *icon,
+						   GtkWidget *image);
+void	rb_tray_icon_enable_tooltips		  (RBTrayIcon *icon,
+						   gboolean enabled);
 
 G_END_DECLS
 
Index: shell/rb-shell.c
===================================================================
RCS file: /cvs/gnome/rhythmbox/shell/rb-shell.c,v
retrieving revision 1.469
diff -u -p -r1.469 rb-shell.c
--- shell/rb-shell.c	31 Jul 2006 11:52:13 -0000	1.469
+++ shell/rb-shell.c	7 Aug 2006 01:37:52 -0000
@@ -142,6 +142,10 @@ static void rb_shell_db_save_error_cb (R
 static void rb_shell_db_entry_added_cb (RhythmDB *db,
 					RhythmDBEntry *entry,
 					RBShell *shell);
+static void rb_shell_db_metadata_art_cb (RhythmDB *db,
+					 RhythmDBEntry *entry,
+					 GValueArray *metadata,
+					 RBShell *shell);
 static void rb_shell_druid_response_cb (GtkDialog *druid,
 					guint response,
 					 RBShell *shell);
@@ -376,6 +380,7 @@ struct RBShellPrivate
 	char *cached_title;
 	char *cached_duration;
 	gboolean cached_playing;
+	char *cached_artist_album_markup;
 
 	guint sidepane_visibility_notify_id;
 	guint toolbar_visibility_notify_id;
@@ -886,6 +891,9 @@ rb_shell_finalize (GObject *object)
 
 	gtk_widget_destroy (GTK_WIDGET (shell->priv->tray_icon));
 
+	if (shell->priv->cached_artist_album_markup != NULL)
+		g_free (shell->priv->cached_artist_album_markup);
+
 	if (shell->priv->save_playlist_id > 0) {
 		g_source_remove (shell->priv->save_playlist_id);
 		shell->priv->save_playlist_id = 0;
@@ -1359,6 +1367,10 @@ rb_shell_constructor (GType type,
 	g_signal_connect_object (G_OBJECT (shell->priv->db), "entry-added",
 				 G_CALLBACK (rb_shell_db_entry_added_cb), shell, 0);
 
+	g_signal_connect_object (G_OBJECT (shell->priv->db),
+				 "entry_extra_metadata_notify::rb:coverArt",
+				 G_CALLBACK (rb_shell_db_metadata_art_cb), shell, 0);
+
 	construct_sources (shell);
 
 	construct_load_ui (shell);
@@ -1720,6 +1732,83 @@ rb_shell_db_entry_added_cb (RhythmDB *db
 	}
 }
 
+static char *
+rb_shell_entry_get_artist_album_markup (RhythmDBEntry *entry)
+{
+	char *artist_escaped, *album_escaped, *markup;
+
+	artist_escaped = g_markup_escape_text (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST), -1);
+	album_escaped = g_markup_escape_text (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM), -1);
+	/* Translators: by Artist from Album*/
+	markup = g_strdup_printf (_("by <b>%s</b> from <b>%s</b>"), artist_escaped, album_escaped);
+	g_free (artist_escaped);
+	g_free (album_escaped);
+
+	return markup;
+}
+
+static void
+rb_shell_hidden_entry_notify (RBShell *shell,
+			      RhythmDBEntry *entry,
+			      GdkPixbuf *pixbuf)
+{
+	char *primary, *secondary;
+	GtkWidget *icon = NULL;
+
+	if (rb_shell_get_visibility (shell)) {
+		rb_debug ("shell is visible, not notifying");
+		return;
+	}
+
+	primary = g_markup_escape_text (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE), -1);
+	secondary = rb_shell_entry_get_artist_album_markup (entry);
+	if (pixbuf != NULL)
+		icon = gtk_image_new_from_pixbuf (pixbuf);
+
+	rb_tray_icon_notify (shell->priv->tray_icon,
+			     4000, primary,
+			     icon, secondary);
+
+	if (icon != NULL)
+		gtk_widget_unref (icon);
+	g_free (primary);
+	g_free (secondary);
+}
+
+static void
+rb_shell_db_metadata_art_cb (RhythmDB *db,
+			     RhythmDBEntry *entry,
+			     GValueArray *metadata,
+			     RBShell *shell)
+{
+	GValue *value;
+	GdkPixbuf *pixbuf, *my_pixbuf;
+	gint icon_size;
+	guint time;
+
+	if (entry != rb_shell_player_get_playing_entry (shell->priv->player_shell))
+		return;
+	if ((value = g_value_array_get_nth (metadata, 0)) == NULL)
+		return;
+	if  (!G_VALUE_HOLDS (value, GDK_TYPE_PIXBUF))
+		return;
+	if ((pixbuf = GDK_PIXBUF (g_value_get_object (value))) == NULL)
+		return;
+
+	gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &icon_size, NULL);
+	my_pixbuf = gdk_pixbuf_scale_simple (pixbuf,
+			icon_size, icon_size,
+			GDK_INTERP_BILINEAR);
+
+	rb_tray_icon_set_tooltip_image (shell->priv->tray_icon,
+					gtk_image_new_from_pixbuf (my_pixbuf));
+
+	if (rb_shell_player_get_playing_time (shell->priv->player_shell, &time, NULL) && time < 4)
+		rb_shell_hidden_entry_notify (shell, entry, my_pixbuf);
+
+	g_object_unref (my_pixbuf);
+}
+
 RBSource *
 rb_shell_get_source_by_entry_type (RBShell *shell,
 				   RhythmDBEntryType type)
@@ -1892,18 +1981,18 @@ rb_shell_playing_entry_changed_cb (RBShe
 				   RhythmDBEntry *entry,
 				   RBShell *shell)
 {
-	char *notifytitle;
+	const char *title;
 
-	/* Translators: by Artist from Album*/
-	notifytitle = g_strdup_printf (_("by %s from %s"),
-				       rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST),
-				       rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM));
-	rb_shell_hidden_notify (shell,
-				4000,
-				rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE),
-				NULL,
-				notifytitle);
-	g_free (notifytitle);
+	title = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE);
+	if (shell->priv->cached_artist_album_markup != NULL)
+		g_free (shell->priv->cached_artist_album_markup);
+	shell->priv->cached_artist_album_markup = rb_shell_entry_get_artist_album_markup (entry);
+
+	rb_tray_icon_set_tooltip (shell->priv->tray_icon, title);
+	rb_tray_icon_set_tooltip_secondary_markup (shell->priv->tray_icon, shell->priv->cached_artist_album_markup);
+	rb_tray_icon_set_tooltip_image (shell->priv->tray_icon, NULL);
+
+	rb_shell_hidden_entry_notify (shell, entry, NULL);
 }
 
 static void
@@ -1992,6 +2081,7 @@ rb_shell_player_stream_song_changed_cb (
 
 	g_object_get (player, "stream-song", &song, NULL);
 	if (song) {
+		rb_tray_icon_set_tooltip (shell->priv->tray_icon, song);
 		rb_shell_hidden_notify (shell, 4000, song, NULL, NULL);
 		g_free (song);
 	}
@@ -2003,24 +2093,27 @@ rb_shell_set_elapsed (RBShell *shell,
 {
 	gboolean playing;
 	char *elapsed_string;
+	char *elapsed_escaped;
 	char *tooltip;
 
 	rb_shell_player_get_playing (shell->priv->player_shell, &playing, NULL);
 	elapsed_string = rb_shell_player_get_playing_time_string (shell->priv->player_shell);
+	elapsed_escaped = g_markup_escape_text (elapsed_string, -1);
 
-	if (shell->priv->cached_title == NULL)
+	if (shell->priv->cached_artist_album_markup == NULL)
 		tooltip = g_strdup (_("Not playing"));
 	else if (!playing) {
-		/* Translators: the first %s is substituted by the song name, the second one is the elapsed and total time */
+		/* Translators: the first %s is substituted by the artist and album, the second one is the elapsed and total time */
 		tooltip = g_strdup_printf (_("%s\nPaused, %s"),
-					 shell->priv->cached_title, elapsed_string);
+					 shell->priv->cached_artist_album_markup, elapsed_escaped);
 	} else {
-		/* Translators: the first %s is substituted by the song name, the second one is the elapsed and total time */
+		/* Translators: the first %s is substituted by the artist and album, the second one is the elapsed and total time */
 		tooltip = g_strdup_printf (_("%s\n%s"),
-					   shell->priv->cached_title, elapsed_string);
+					   shell->priv->cached_artist_album_markup, elapsed_escaped);
 	}
 
-	rb_tray_icon_set_tooltip (shell->priv->tray_icon, tooltip);
+	rb_tray_icon_set_tooltip_secondary_markup (shell->priv->tray_icon, tooltip);
+	g_free (elapsed_escaped);
 	g_free (elapsed_string);
 	g_free (tooltip);
 }
@@ -2850,15 +2943,20 @@ rb_shell_hidden_notify (RBShell *shell,
 			GtkWidget *icon,
 			const char *secondary)
 {
+	char *primary_escaped, *secondary_escaped;
 
 	if (rb_shell_get_visibility (shell)) {
 		rb_debug ("shell is visible, not notifying");
 		return;
 	}
 
+	primary_escaped = g_markup_escape_text (primary, -1);
+	secondary_escaped = g_markup_escape_text (secondary, -1);
 	rb_tray_icon_notify (shell->priv->tray_icon,
-			     timeout, primary,
-			     icon, secondary);
+			     timeout, primary_escaped,
+			     icon, secondary_escaped);
+	g_free (primary_escaped);
+	g_free (secondary_escaped);
 }
 
 static void
