Index: plugins/audiocd/rb-audiocd-source.c
===================================================================
--- plugins/audiocd/rb-audiocd-source.c	(revision 5331)
+++ plugins/audiocd/rb-audiocd-source.c	(working copy)
@@ -54,8 +54,12 @@
 					        GObjectConstructParam *construct_properties);
 
 static gboolean impl_show_popup (RBSource *source);
+static guint impl_want_uri (RBSource *source, const char *uri);
+static gboolean impl_uri_is_source (RBSource *source, const char *uri);
+
 static void impl_delete_thyself (RBSource *source);
 static GList* impl_get_ui_actions (RBSource *source);
+static gboolean impl_try_playlist (RBSource *source);
 
 static gpointer rb_audiocd_load_songs (RBAudioCdSource *source);
 static void rb_audiocd_load_metadata (RBAudioCdSource *source, RhythmDB *db);
@@ -100,6 +104,9 @@
 	source_class->impl_show_popup = impl_show_popup;
 	source_class->impl_delete_thyself = impl_delete_thyself;
 	source_class->impl_get_ui_actions = impl_get_ui_actions;
+	source_class->impl_uri_is_source = impl_uri_is_source;
+	source_class->impl_try_playlist = impl_try_playlist;
+	source_class->impl_want_uri = impl_want_uri;
 
 	g_type_class_add_private (klass, sizeof (RBAudioCdSourcePrivate));
 }
@@ -754,3 +761,47 @@
 
 	return actions;
 }
+
+static guint
+impl_want_uri (RBSource *source, const char *uri)
+{
+	GnomeVFSVolume *volume;
+	char *activation_uri;
+	int retval;
+
+	retval = 0;
+
+	if (g_str_has_prefix (uri, "cdda://") == FALSE)
+		return 0;
+
+	g_object_get (G_OBJECT (source),
+		      "volume", &volume,
+		      NULL);
+	if (volume == NULL)
+		return 0;
+
+	activation_uri = gnome_vfs_volume_get_activation_uri (volume);
+	if (activation_uri == NULL)
+		return 0;
+
+	if (strcmp (activation_uri, uri) == 0)
+		retval = 100;
+
+	g_free (activation_uri);
+
+	return retval;
+}
+
+static gboolean
+impl_uri_is_source (RBSource *source, const char *uri)
+{
+	if (impl_want_uri (source, uri) == 100)
+		return TRUE;
+	return FALSE;
+}
+
+static gboolean
+impl_try_playlist (RBSource *source)
+{
+	return TRUE;
+}
Index: shell/rb-shell.c
===================================================================
--- shell/rb-shell.c	(revision 5331)
+++ shell/rb-shell.c	(working copy)
@@ -130,6 +130,8 @@
 static void source_activated_cb (RBSourceList *sourcelist,
 				 RBSource *source,
 				 RBShell *shell);
+static void rb_shell_activate_source (RBShell *shell,
+				      RBSource *source);
 static void rb_shell_db_save_error_cb (RhythmDB *db,
 				       const char *uri, const GError *error,
 				       RBShell *shell);
@@ -290,6 +292,7 @@
 {
 	VISIBILITY_CHANGED,
 	CREATE_SONG_INFO,
+	REMOVABLE_MEDIA_SCAN_FINISHED,
 	LAST_SIGNAL
 };
 
@@ -654,6 +657,15 @@
 			      G_TYPE_NONE,
 			      2,
 			      RB_TYPE_SONG_INFO, G_TYPE_BOOLEAN);
+	rb_shell_signals[REMOVABLE_MEDIA_SCAN_FINISHED] =
+		g_signal_new ("removable_media_scan_finished",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (RBShellClass, removable_media_scan_finished),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE,
+			      0);
 
 	g_type_class_add_private (klass, sizeof (RBShellPrivate));
 }
@@ -1265,6 +1277,7 @@
 	GDK_THREADS_ENTER ();
 	rb_removable_media_manager_scan (shell->priv->removable_media_manager);
 	GDK_THREADS_LEAVE ();
+	g_signal_emit (shell, rb_shell_signals[REMOVABLE_MEDIA_SCAN_FINISHED], 0);
 	return FALSE;
 }
 
@@ -1659,6 +1672,12 @@
 {
 	rb_debug ("source activated");
 
+	rb_shell_activate_source (shell, source);
+}
+
+static void
+rb_shell_activate_source (RBShell *shell, RBSource *source)
+{
 	/* Stop the playing source, if any */
 	rb_shell_player_set_playing_source (shell->priv->player_shell, NULL);
 
@@ -3178,8 +3197,9 @@
 
 typedef struct {
 	RBShell *shell;
+	RBSource *playlist_source;
 	gboolean can_use_playlist;
-	RBSource *playlist_source;
+	gboolean source_is_entry;
 } PlaylistParseData;
 
 #if TOTEM_PL_PARSER_CHECK_VERSION(2,19,0)
@@ -3211,6 +3231,7 @@
 	if (data->playlist_source == NULL) {
 		if (source != NULL && rb_source_try_playlist (source)) {
 			data->playlist_source = RB_SOURCE (g_object_ref (source));
+			data->source_is_entry = rb_source_uri_is_source (source, uri);
 		} else {
 			data->can_use_playlist = FALSE;
 		}
@@ -3238,7 +3259,10 @@
 		   GError **error)
 {
 	RhythmDBEntry *entry;
+	RBSource *playlist_source;
+
 	entry = rhythmdb_entry_lookup_by_location (shell->priv->db, uri);
+	playlist_source = NULL;
 
 	if (entry == NULL) {
 		TotemPlParser *parser;
@@ -3247,9 +3271,10 @@
 
 		data.shell = shell;
 		data.can_use_playlist = TRUE;
+		data.source_is_entry = FALSE;
 		data.playlist_source = NULL;
 
-		rb_debug ("adding uri %s", uri);
+		rb_debug ("adding uri %s, play %d", uri, play);
 		parser = totem_pl_parser_new ();
 
 #if TOTEM_PL_PARSER_CHECK_VERSION(2,19,0)
@@ -3273,14 +3298,13 @@
 			if (data.can_use_playlist && data.playlist_source) {
 				rb_debug ("adding playlist %s to source", uri);
 				rb_source_add_uri (data.playlist_source, uri, NULL, NULL);
-				g_object_unref (data.playlist_source);
 
 				/* FIXME: We need some way to determine whether the URI as
 				 * given will appear in the db, or whether something else will.
 				 * This hack assumes we'll never add local playlists to the db
 				 * directly.
 				 */
-				if (rb_uri_is_local (uri)) {
+				if (rb_uri_is_local (uri) && (data.source_is_entry == FALSE)) {
 					play = FALSE;
 				}
 			} else {
@@ -3294,9 +3318,20 @@
 			if (!rb_shell_add_uri (shell, uri, NULL, NULL, error))
 				return FALSE;
 		}
+
+		if (data.source_is_entry != FALSE)
+			playlist_source = data.playlist_source;
+		else
+			g_object_unref (data.playlist_source);
 	}
 
 	if (play) {
+		if (playlist_source != NULL) {
+			rb_shell_activate_source (shell, playlist_source);
+			g_object_unref (playlist_source);
+			return TRUE;
+		}
+
 		if (entry == NULL)
 			entry = rhythmdb_entry_lookup_by_location (shell->priv->db, uri);
 
Index: shell/rb-shell.h
===================================================================
--- shell/rb-shell.h	(revision 5331)
+++ shell/rb-shell.h	(working copy)
@@ -76,6 +76,7 @@
 	/* signals */
 	void	(*visibility_changed)	(RBShell *shell, gboolean visible);
 	void	(*create_song_info)	(RBShell *shell, RBSongInfo *song_info, gboolean multi);
+	void	(*removable_media_scan_finished) (RBShell *shell);
 } RBShellClass;
 
 GType		rb_shell_get_type	(void);
Index: shell/main.c
===================================================================
--- shell/main.c	(revision 5331)
+++ shell/main.c	(working copy)
@@ -76,6 +76,8 @@
 
 static gboolean load_uri_args (const char **args, GFunc handler, gpointer user_data);
 static void dbus_load_uri (const char *filename, DBusGProxy *proxy);
+static void removable_media_scan_finished (RBShell *shell, gpointer data);
+static void local_load_uri (const char *filename, RBShell *shell);
 
 static void main_shell_weak_ref_cb (gpointer data, GObject *objptr);
 
@@ -271,6 +273,11 @@
 			obj = rb_shell_get_playlist_manager (rb_shell);
 			path = rb_shell_get_playlist_manager_path (rb_shell);
 			dbus_g_connection_register_g_object (session_bus, path, obj);
+
+			g_signal_connect (G_OBJECT (rb_shell),
+					  "removable_media_scan_finished",
+					  G_CALLBACK (removable_media_scan_finished),
+					  NULL);
 		}
 	} else if (!no_registration && session_bus != NULL) {
 		DBusGProxy *shell_proxy;
@@ -362,9 +369,11 @@
 				G_TYPE_STRING, filename,
 				G_TYPE_BOOLEAN, TRUE,
 				G_TYPE_INVALID,
-				G_TYPE_INVALID))
+				G_TYPE_INVALID)) {
 		g_printerr ("Failed to load %s: %s",
 			    filename, error->message);
+		g_error_free (error);
+	}
 }
 
 static void
@@ -373,3 +382,22 @@
 	rb_debug ("caught shell finalization");
 	gtk_main_quit ();
 }
+
+static void
+removable_media_scan_finished (RBShell *shell, gpointer data)
+{
+	load_uri_args ((const char **) remaining_args, (GFunc) local_load_uri, shell);
+}
+
+static void
+local_load_uri (const char *filename, RBShell *shell)
+{
+	GError *error = NULL;
+	rb_debug ("Using load_uri for %s", filename);
+	if (!rb_shell_load_uri (shell, filename, TRUE, &error)) {
+		g_printerr ("Failed to load %s: %s",
+			    filename, error->message);
+		g_error_free (error);
+	}
+}
+
Index: sources/rb-source.c
===================================================================
--- sources/rb-source.c	(revision 5331)
+++ sources/rb-source.c	(working copy)
@@ -943,6 +943,15 @@
 }
 
 gboolean
+rb_source_uri_is_source (RBSource *source, const char *uri)
+{
+	RBSourceClass *klass = RB_SOURCE_GET_CLASS (source);
+	if (klass->impl_uri_is_source)
+		return klass->impl_uri_is_source (source, uri);
+	return FALSE;
+}
+
+gboolean
 rb_source_add_uri (RBSource *source, const char *uri, const char *title, const char *genre)
 {
 	RBSourceClass *klass = RB_SOURCE_GET_CLASS (source);
Index: sources/rb-source.h
===================================================================
--- sources/rb-source.h	(revision 5331)
+++ sources/rb-source.h	(working copy)
@@ -110,6 +110,7 @@
 	gboolean	(*impl_try_playlist)	(RBSource *source);
 	guint		(*impl_want_uri)	(RBSource *source, const char *uri);
 	gboolean	(*impl_add_uri)		(RBSource *source, const char *uri, const char *title, const char *genre);
+	gboolean	(*impl_uri_is_source)	(RBSource *source, const char *uri);
 
 	gboolean	(*impl_can_pause)	(RBSource *source);
 	RBSourceEOFType	(*impl_handle_eos)	(RBSource *source);
@@ -175,6 +176,7 @@
 
 gboolean	rb_source_try_playlist		(RBSource *source);
 guint		rb_source_want_uri		(RBSource *source, const char *uri);
+gboolean	rb_source_uri_is_source		(RBSource *source, const char *uri);
 gboolean	rb_source_add_uri		(RBSource *source, const char *uri, const char *title, const char *genre);
 
 gboolean	rb_source_can_pause		(RBSource *source);
