diff --git a/gnome-panel/panel-toplevel.c b/gnome-panel/panel-toplevel.c
index 8c39b77..64d24bf 100644
--- a/gnome-panel/panel-toplevel.c
+++ b/gnome-panel/panel-toplevel.c
@@ -88,6 +88,10 @@ struct _PanelToplevelPrivate {
 	int                     y_bottom;
 
 	int                     monitor;
+	/* this is used when the configured monitor is missing. We keep it so
+	 * we can move the toplevel to the right monitor when it becomes
+	 * available */
+	int                     configured_monitor;
 
 	int                     hide_delay;
 	int                     unhide_delay;
@@ -233,6 +237,12 @@ static GSList       *toplevel_list = NULL;
 
 static void panel_toplevel_calculate_animation_end_geometry (PanelToplevel *toplevel);
 
+static void panel_toplevel_update_monitor       (PanelToplevel *toplevel);
+static void panel_toplevel_set_monitor_internal (PanelToplevel *toplevel,
+						 int            monitor,
+						 gboolean       force_resize);
+
+
 GSList *
 panel_toplevel_list_toplevels (void)
 {
@@ -2115,7 +2125,7 @@ panel_toplevel_update_expanded_position (PanelToplevel *toplevel)
 
 	monitor = panel_multiscreen_get_monitor_at_point (screen, x, y);
 
-	panel_toplevel_set_monitor (toplevel, monitor);
+	panel_toplevel_set_monitor_internal (toplevel, monitor, TRUE);
 
 	x -= panel_multiscreen_x (screen, monitor);
 	y -= panel_multiscreen_y (screen, monitor);
@@ -3042,6 +3052,10 @@ panel_toplevel_size_request (GtkWidget      *widget,
 	toplevel = PANEL_TOPLEVEL (widget);
 	bin = GTK_BIN (widget);
 
+	/* we get a size request when there are new monitors, so first try to
+	 * see if we need to move to a new monitor */
+	panel_toplevel_update_monitor (toplevel);
+
 	if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
 		gtk_widget_size_request (bin->child, requisition);
 
@@ -4479,6 +4493,7 @@ panel_toplevel_init (PanelToplevel *toplevel)
 	toplevel->priv->x_right         = -1;
 	toplevel->priv->y_bottom        = -1;
 	toplevel->priv->monitor         = 0;
+	toplevel->priv->configured_monitor = -1;
 	toplevel->priv->hide_delay      = DEFAULT_HIDE_DELAY;
 	toplevel->priv->unhide_delay    = DEFAULT_UNHIDE_DELAY;
 	toplevel->priv->auto_hide_size  = DEFAULT_AUTO_HIDE_SIZE;
@@ -4983,18 +4998,84 @@ panel_toplevel_get_y_centered (PanelToplevel *toplevel)
 	return toplevel->priv->y_centered;
 }
 
+/**
+ * panel_toplevel_set_monitor_internal:
+ *
+ * Sets the monitor of the toplevel, but only the internal state. We need to
+ * make the difference between the internal state and the configuration of the
+ * user because internal constraints might affect the monitor of the toplevel.
+ *
+ * panel_toplevel_set_monitor_internal() won't update the configuration of the
+ * user.
+ **/
+static void
+panel_toplevel_set_monitor_internal (PanelToplevel *toplevel,
+				     int            monitor,
+				     gboolean       force_resize)
+{
+	if (toplevel->priv->monitor == monitor)
+		return;
+
+	toplevel->priv->monitor = monitor;
+
+	if (force_resize)
+		gtk_widget_queue_resize (GTK_WIDGET (toplevel));
+}
+
+/**
+ * panel_toplevel_update_monitor:
+ *
+ * Moves the toplevel to its configured monitor or the first one, if needed.
+ * This generally happens when the configured monitor was non-existing before,
+ * and it appeared at runtime, or if it was existing and disappeared.
+ *
+ * This must only be called at the beginning of the size request of the
+ * toplevel because it doesn't queue a size request.
+ **/
+static void
+panel_toplevel_update_monitor (PanelToplevel *toplevel)
+{
+	GdkScreen *screen;
+
+	screen = gtk_window_get_screen (GTK_WINDOW (toplevel));
+
+	/* If we were not using the configured monitor, can we use it now? */
+	if ((toplevel->priv->configured_monitor != -1) &&
+	    (toplevel->priv->configured_monitor != toplevel->priv->monitor) &&
+	    toplevel->priv->configured_monitor < panel_multiscreen_monitors (screen)) {
+		panel_toplevel_set_monitor_internal (toplevel,
+						     toplevel->priv->configured_monitor,
+						     FALSE);
+
+	/* else, can we still use the monitor we were using? */
+	} else if (toplevel->priv->monitor >= panel_multiscreen_monitors (screen)) {
+		panel_toplevel_set_monitor_internal (toplevel,
+						     0,
+						     FALSE);
+	}
+}
+
 void
 panel_toplevel_set_monitor (PanelToplevel *toplevel,
 			    int            monitor)
 {
+	GdkScreen *screen;
+
 	g_return_if_fail (PANEL_IS_TOPLEVEL (toplevel));
 
-	if (toplevel->priv->monitor == monitor)
+	if (toplevel->priv->configured_monitor == monitor)
 		return;
 
-	toplevel->priv->monitor = monitor;
+	toplevel->priv->configured_monitor = monitor;
 
-	gtk_widget_queue_resize (GTK_WIDGET (toplevel));
+	/* Only use the configured monitor if it's existing. Else, we ignore
+	 * the non-existing monitor, and keep the old one. The main use case is
+	 * when logging in after having used a multiscreen environment.
+	 * We will put the panel on the monitor 0 for this session, and it will
+	 * move back to the right monitor next time. */
+	screen = gtk_window_get_screen (GTK_WINDOW (toplevel));
+	if (monitor < panel_multiscreen_monitors (screen))
+		panel_toplevel_set_monitor_internal (toplevel, monitor, TRUE);
 
 	g_object_notify (G_OBJECT (toplevel), "monitor");
 }
