--- old-stuff/shell/rb-shell.c	2006-01-04 09:20:15.000000000 +1000
+++ new-stuff/shell/rb-shell.c	2006-01-04 09:20:15.000000000 +1000
@@ -1154,6 +1154,7 @@ rb_shell_constructor (GType type, guint 
 	rb_debug ("shell: syncing with gconf");
 	rb_shell_sync_sourcelist_visibility (shell);
 	rb_shell_sync_pane_visibility (shell);
+	rb_shell_sync_paned (shell);
 
 	shell->priv->load_error_dialog = rb_load_failure_dialog_new ();
 	shell->priv->show_db_errors = FALSE;
@@ -1262,21 +1263,21 @@ rb_shell_constructor (GType type, guint 
 		g_clear_error (&error);
 	}
 
-	shell->priv->save_playlist_id = g_timeout_add (10000, (GSourceFunc) idle_save_playlist_manager, shell->priv->playlist_manager);
 	
 	rb_shell_sync_window_state (shell, FALSE);
 	rb_shell_sync_fullscreen (shell);
 
 	rb_shell_select_source (shell, RB_SOURCE (shell->priv->library_source));
 
+	gtk_widget_show_all (GTK_WIDGET (shell->priv->tray_icon));
+	rb_shell_sync_smalldisplay (shell);
+	if (eel_gconf_get_boolean (CONF_FIRST_TIME))
+		gtk_widget_show (GTK_WIDGET (shell->priv->window));
 	
 	/* GO GO GO! */
 	rb_debug ("loading database");
 	rhythmdb_load (shell->priv->db);
 	
-	rb_debug ("shell: syncing window state");
-	rb_shell_sync_paned (shell);
-	gtk_widget_show_all (GTK_WIDGET (shell->priv->tray_icon));
 
 	/* Stop here if this is the first time. */
 	if (!eel_gconf_get_boolean (CONF_FIRST_TIME)) {
@@ -1286,12 +1287,10 @@ rb_shell_constructor (GType type, guint 
 		gtk_widget_hide (GTK_WIDGET (shell->priv->window));
 		rb_druid_show (druid);
 		g_object_unref (G_OBJECT (druid));
+	
+		gtk_widget_show (GTK_WIDGET (shell->priv->window));
 	}
 
-	rb_shell_sync_smalldisplay (shell);
-
-	gtk_widget_show (GTK_WIDGET (shell->priv->window));
-
 	return G_OBJECT (shell);
 }
 
@@ -2258,6 +2257,7 @@ idle_handle_load_complete (RBShell *shel
 	rb_debug ("load complete");
 
 	rb_playlist_manager_load_playlists (shell->priv->playlist_manager);
+	shell->priv->save_playlist_id = g_timeout_add (10000, (GSourceFunc) idle_save_playlist_manager, shell->priv->playlist_manager);
 	shell->priv->load_complete = TRUE;
 
 	GDK_THREADS_LEAVE ();

--- old-stuff/rhythmdb/rhythmdb.c	2006-01-04 09:20:15.000000000 +1000
+++ new-stuff/rhythmdb/rhythmdb.c	2006-01-04 09:20:15.000000000 +1000
@@ -1598,7 +1598,7 @@ rhythmdb_process_file_deleted (RhythmDB 
 	}
 }
 
-static gboolean
+gboolean
 rhythmdb_process_events (RhythmDB *db, GTimeVal *timeout)
 {
 	RhythmDBEvent *event;

--- old-stuff/rhythmdb/rhythmdb.h	2006-01-04 09:20:15.000000000 +1000
+++ new-stuff/rhythmdb/rhythmdb.h	2006-01-04 09:20:15.000000000 +1000
@@ -551,6 +551,7 @@ void		rhythmdb_emit_entry_added		(Rhythm
 void		rhythmdb_emit_entry_deleted		(RhythmDB *db, RhythmDBEntry *entry);
 
 gboolean	rhythmdb_is_busy			(RhythmDB *db);
+gboolean 	rhythmdb_process_events 		(RhythmDB *db, GTimeVal *timeout);
 char *		rhythmdb_compute_status_normal		(gint n_songs, glong duration,
 							 GnomeVFSFileSize size);
 RhythmDBEntryType rhythmdb_entry_register_type          (void);

--- old-stuff/rhythmdb/rhythmdb-tree.c	2006-01-04 09:20:15.000000000 +1000
+++ new-stuff/rhythmdb/rhythmdb-tree.c	2006-01-04 09:20:15.000000000 +1000
@@ -129,6 +129,17 @@ enum
 
 const int RHYTHMDB_TREE_PARSER_INITIAL_BUFFER_SIZE = 512;
 
+/*
+ * These batch sizes control how often we process main loop events and rhythmdb
+ * events while loading the database.  Decreasing the main iteration batch size
+ * makes rhythmbox more responsive during startup, but makes it take longer.  
+ * Increasing the rhythmdb event processing batch size probably makes startup
+ * faster, but makes it appear less responsive.  Or something.
+ */
+
+const int RHYTHMDB_TREE_PROCESS_EVENTS_BATCH_SIZE = 200;
+const int RHYTHMDB_TREE_MAIN_ITERATION_BATCH_SIZE = 20;
+
 
 static void
 rhythmdb_tree_class_init (RhythmDBTreeClass *klass)
@@ -208,6 +219,7 @@ struct RhythmDBTreeLoadContext
 	RhythmDBEntry *entry;
 	GString *buf;
 	RhythmDBPropType propid;
+	gint entry_counter;
 
 	gboolean has_date;
 };
@@ -339,6 +351,19 @@ rhythmdb_tree_parser_end_element (struct
 			rb_debug ("found entry without location");
 			rhythmdb_entry_unref (RHYTHMDB (ctx->db), ctx->entry);
 		}
+		ctx->entry_counter++;
+		if (ctx->entry_counter % RHYTHMDB_TREE_MAIN_ITERATION_BATCH_SIZE == 0)
+			g_main_context_iteration (NULL, TRUE);
+
+		if (ctx->entry_counter % RHYTHMDB_TREE_PROCESS_EVENTS_BATCH_SIZE == 0) {
+
+			GTimeVal timeout;
+			g_get_current_time (&timeout);
+			g_time_val_add (&timeout, G_USEC_PER_SEC * 0.25);
+			rhythmdb_process_events (RHYTHMDB (ctx->db), &timeout);
+
+			ctx->entry_counter = 0;
+		}
 		ctx->state = RHYTHMDB_TREE_PARSER_STATE_RHYTHMDB;
 		break;
 	}

