diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
index 7259bf6..295d726 100644
--- a/daemon/gdm-session-direct.c
+++ b/daemon/gdm-session-direct.c
@@ -108,6 +108,9 @@ enum {
 };
 
 static void     gdm_session_iface_init          (GdmSessionIface      *iface);
+static const char *get_language_name (GdmSessionDirect *session);
+static const char *get_layout_name   (GdmSessionDirect *session);
+static const char *get_session_name  (GdmSessionDirect *session);
 
 G_DEFINE_TYPE_WITH_CODE (GdmSessionDirect,
                          gdm_session_direct,
@@ -1046,6 +1049,9 @@ gdm_session_direct_handle_saved_language_name_read (GdmSessionDirect *session,
                                                             language_name);
         }
 
+        if (session->priv->selected_language == NULL) 
+                send_dbus_string_signal (session, "SetLanguageName",
+                                         get_language_name (session));
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -1079,6 +1085,9 @@ gdm_session_direct_handle_saved_layout_name_read (GdmSessionDirect *session,
                                                           layout_name);
         }
 
+        if (session->priv->selected_layout == NULL) 
+                send_dbus_string_signal (session, "SetLayoutName",
+                                         get_layout_name (session));
 
         return DBUS_HANDLER_RESULT_HANDLED;
 }
@@ -1119,6 +1128,10 @@ gdm_session_direct_handle_saved_session_name_read (GdmSessionDirect *session,
                 _gdm_session_default_session_name_changed (GDM_SESSION (session),
                                                            session_name);
         }
+        
+        if (session->priv->selected_session == NULL)
+                send_dbus_string_signal (session, "SetSessionName",
+                                         get_session_name (session));
  out:
         return DBUS_HANDLER_RESULT_HANDLED;
 }
diff --git a/daemon/gdm-session-settings.c b/daemon/gdm-session-settings.c
index b6c04f7..66a1a73 100644
--- a/daemon/gdm-session-settings.c
+++ b/daemon/gdm-session-settings.c
@@ -37,6 +37,7 @@ struct _GdmSessionSettingsPrivate
         char *session_name;
         char *language_name;
         char *layout_name;
+        gboolean is_loaded_from_file;
 };
 
 static void gdm_session_settings_finalize (GObject *object);
@@ -108,7 +109,7 @@ gdm_session_settings_init (GdmSessionSettings *settings)
         settings->priv = G_TYPE_INSTANCE_GET_PRIVATE (settings,
                                                      GDM_TYPE_SESSION_SETTINGS,
                                                      GdmSessionSettingsPrivate);
-
+        settings->priv->is_loaded_from_file = FALSE;
 }
 
 static void
@@ -258,6 +259,12 @@ gdm_session_settings_new (void)
 }
 
 gboolean
+gdm_session_settings_is_loaded_from_file (GdmSessionSettings *settings)
+{
+    return settings->priv->is_loaded_from_file;
+}
+
+gboolean
 gdm_session_settings_is_loaded (GdmSessionSettings  *settings)
 {
         return settings->priv->session_name != NULL ||
@@ -340,6 +347,7 @@ out:
         g_key_file_free (key_file);
         g_free (filename);
 
+        settings->priv->is_loaded_from_file = is_loaded;
         return is_loaded;
 }
 
diff --git a/daemon/gdm-session-settings.h b/daemon/gdm-session-settings.h
index a546598..d36d2e7 100644
--- a/daemon/gdm-session-settings.h
+++ b/daemon/gdm-session-settings.h
@@ -60,6 +60,7 @@ gboolean            gdm_session_settings_save               (GdmSessionSettings
                                                              const char          *home_directory,
                                                              GError             **error);
 gboolean            gdm_session_settings_is_loaded          (GdmSessionSettings  *settings);
+gboolean            gdm_session_settings_is_loaded_from_file(GdmSessionSettings  *settings);
 char               *gdm_session_settings_get_language_name  (GdmSessionSettings *settings);
 char               *gdm_session_settings_get_layout_name    (GdmSessionSettings *settings);
 char               *gdm_session_settings_get_session_name   (GdmSessionSettings *settings);
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index fa39c3b..77c212a 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -150,6 +150,10 @@ typedef int (* GdmSessionWorkerPamNewMessagesFunc) (int,
                                                     struct pam_response **,
                                                     gpointer);
 
+static void     on_saved_session_name_read      (GdmSessionWorker *worker);
+static void     on_saved_layout_name_read       (GdmSessionWorker *worker);
+static void     on_saved_language_name_read     (GdmSessionWorker *worker);
+
 G_DEFINE_TYPE (GdmSessionWorker, gdm_session_worker, G_TYPE_OBJECT)
 
 GQuark
@@ -617,6 +621,22 @@ attempt_to_load_user_settings (GdmSessionWorker *worker,
                                    passwd_entry->pw_dir,
                                    NULL);
 
+        /* These singal handlers should be disconnected after the loading,
+         * so that gdm_session_settings_set_* APIs don't cause the emitting
+         * of Saved*NameRead D-Bus signals any more.
+         */
+        g_signal_handlers_disconnect_by_func (worker->priv->user_settings,
+                                              G_CALLBACK (on_saved_session_name_read),
+                                              worker);
+
+        g_signal_handlers_disconnect_by_func (worker->priv->user_settings,
+                                              G_CALLBACK (on_saved_language_name_read),
+                                              worker);
+
+        g_signal_handlers_disconnect_by_func (worker->priv->user_settings,
+                                              G_CALLBACK (on_saved_layout_name_read),
+                                              worker);
+
         seteuid (old_uid);
         setegid (old_gid);
 }
@@ -658,7 +678,7 @@ gdm_session_worker_update_username (GdmSessionWorker *worker)
                  * to keep trying to read settings)
                  */
                 if (worker->priv->username != NULL &&
-                    !gdm_session_settings_is_loaded (worker->priv->user_settings)) {
+                    !gdm_session_settings_is_loaded_from_file (worker->priv->user_settings)) {
                         attempt_to_load_user_settings (worker, worker->priv->username);
                 }
         }
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
index 3a2623c..875f0c8 100644
--- a/daemon/gdm-simple-slave.c
+++ b/daemon/gdm-simple-slave.c
@@ -174,6 +174,7 @@ reset_session (GdmSimpleSlave *slave)
 {
         destroy_session (slave);
         create_new_session (slave);
+        gdm_greeter_server_reset (slave->priv->greeter_server);
         gdm_session_open (GDM_SESSION (slave->priv->session));
 }
 
diff --git a/gui/simple-greeter/gdm-greeter-panel.c b/gui/simple-greeter/gdm-greeter-panel.c
index 6aded10..e7f38bf 100644
--- a/gui/simple-greeter/gdm-greeter-panel.c
+++ b/gui/simple-greeter/gdm-greeter-panel.c
@@ -683,9 +683,18 @@ gdm_greeter_panel_hide_user_options (GdmGreeterPanel *panel)
 void
 gdm_greeter_panel_reset (GdmGreeterPanel *panel)
 {
-        gdm_greeter_panel_set_default_language_name (panel, NULL);
-        gdm_greeter_panel_set_default_layout_name (panel, NULL);
-        gdm_greeter_panel_set_default_session_name (panel, NULL);
+        gdm_option_widget_set_default_item (GDM_OPTION_WIDGET(panel->priv->language_option_widget),
+                                            GDM_OPTION_WIDGET_PREVIOUS_SELECTION);
+        gdm_option_widget_set_active_item (GDM_OPTION_WIDGET(panel->priv->language_option_widget),
+                                           GDM_OPTION_WIDGET_PREVIOUS_SELECTION);
+        gdm_option_widget_set_default_item (GDM_OPTION_WIDGET(panel->priv->layout_option_widget),
+                                            GDM_OPTION_WIDGET_PREVIOUS_SELECTION);
+        gdm_option_widget_set_active_item (GDM_OPTION_WIDGET(panel->priv->layout_option_widget),
+                                           GDM_OPTION_WIDGET_PREVIOUS_SELECTION);
+        gdm_option_widget_set_default_item (GDM_OPTION_WIDGET(panel->priv->session_option_widget),
+                                            GDM_OPTION_WIDGET_PREVIOUS_SELECTION);
+        gdm_option_widget_set_active_item (GDM_OPTION_WIDGET(panel->priv->session_option_widget),
+                                           GDM_OPTION_WIDGET_PREVIOUS_SELECTION);
         gdm_greeter_panel_hide_user_options (panel);
 }
 
@@ -693,49 +702,20 @@ void
 gdm_greeter_panel_set_default_language_name (GdmGreeterPanel *panel,
                                              const char      *language_name)
 {
-        char *normalized_language_name;
-
         g_return_if_fail (GDM_IS_GREETER_PANEL (panel));
 
-        if (language_name != NULL) {
-                normalized_language_name = gdm_normalize_language_name (language_name);
-        } else {
-                normalized_language_name = NULL;
-        }
-
-        if (normalized_language_name != NULL &&
-            !gdm_option_widget_lookup_item (GDM_OPTION_WIDGET (panel->priv->language_option_widget),
-                                            normalized_language_name, NULL, NULL, NULL)) {
-                gdm_recent_option_widget_add_item (GDM_RECENT_OPTION_WIDGET (panel->priv->language_option_widget),
-                                                   normalized_language_name);
-        }
-
         gdm_option_widget_set_default_item (GDM_OPTION_WIDGET (panel->priv->language_option_widget),
-                                            normalized_language_name);
-
-        g_free (normalized_language_name);
+                                            GDM_OPTION_WIDGET_PREVIOUS_SELECTION);
 }
 
 void
 gdm_greeter_panel_set_default_layout_name (GdmGreeterPanel *panel,
                                            const char      *layout_name)
 {
-#ifdef HAVE_LIBXKLAVIER
         g_return_if_fail (GDM_IS_GREETER_PANEL (panel));
 
-        if (layout_name != NULL &&
-            !gdm_option_widget_lookup_item (GDM_OPTION_WIDGET (panel->priv->layout_option_widget),
-                                            layout_name, NULL, NULL, NULL)) {
-                gdm_recent_option_widget_add_item (GDM_RECENT_OPTION_WIDGET (panel->priv->layout_option_widget),
-                                                   layout_name);
-        }
-
         gdm_option_widget_set_default_item (GDM_OPTION_WIDGET (panel->priv->layout_option_widget),
-                                            layout_name);
-
-        g_debug ("GdmGreeterPanel: activating layout: %s", layout_name);
-        gdm_layout_activate (layout_name);
-#endif
+                                            GDM_OPTION_WIDGET_PREVIOUS_SELECTION);
 }
 
 void
@@ -744,13 +724,6 @@ gdm_greeter_panel_set_default_session_name (GdmGreeterPanel *panel,
 {
         g_return_if_fail (GDM_IS_GREETER_PANEL (panel));
 
-        if (session_name != NULL &&
-            !gdm_option_widget_lookup_item (GDM_OPTION_WIDGET (panel->priv->session_option_widget),
-                                            session_name, NULL, NULL, NULL)) {
-                g_warning ("Default session is not available");
-                return;
-        }
-
         gdm_option_widget_set_default_item (GDM_OPTION_WIDGET (panel->priv->session_option_widget),
-                                            session_name);
+                                            GDM_OPTION_WIDGET_PREVIOUS_SELECTION);
 }
diff --git a/gui/simple-greeter/gdm-language-option-widget.c b/gui/simple-greeter/gdm-language-option-widget.c
index ff8445f..2115997 100644
--- a/gui/simple-greeter/gdm-language-option-widget.c
+++ b/gui/simple-greeter/gdm-language-option-widget.c
@@ -232,6 +232,14 @@ gdm_language_option_widget_init (GdmLanguageOptionWidget *widget)
                                     _("Choose a language from the "
                                       "full list of available languages."),
                                     GDM_OPTION_WIDGET_POSITION_BOTTOM);
+
+        gdm_option_widget_add_item (GDM_OPTION_WIDGET (widget),
+                                    GDM_OPTION_WIDGET_PREVIOUS_SELECTION,
+                                    C_("language", "Previous Language"),
+                                    _("User previous language selection"),
+                                    GDM_OPTION_WIDGET_POSITION_BOTTOM);
+        gdm_option_widget_set_default_item (GDM_OPTION_WIDGET (widget),
+                                            GDM_OPTION_WIDGET_PREVIOUS_SELECTION);
 }
 
 static void
diff --git a/gui/simple-greeter/gdm-layout-option-widget.c b/gui/simple-greeter/gdm-layout-option-widget.c
index a6eb1b9..7b92c36 100644
--- a/gui/simple-greeter/gdm-layout-option-widget.c
+++ b/gui/simple-greeter/gdm-layout-option-widget.c
@@ -224,6 +224,15 @@ gdm_layout_option_widget_init (GdmLayoutOptionWidget *widget)
                                     _("Choose a keyboard layout from the "
                                       "full list of available layouts."),
                                     GDM_OPTION_WIDGET_POSITION_BOTTOM);
+
+        gdm_option_widget_add_item (GDM_OPTION_WIDGET (widget),
+                                    GDM_OPTION_WIDGET_PREVIOUS_SELECTION,
+                                    C_("keyboard", "Previous Layout"),
+                                    _("Use previous keyboard layout"),
+                                    GDM_OPTION_WIDGET_POSITION_BOTTOM);
+        gdm_option_widget_set_default_item (GDM_OPTION_WIDGET (widget),
+                                            GDM_OPTION_WIDGET_PREVIOUS_SELECTION);
+
 }
 
 static void
diff --git a/gui/simple-greeter/gdm-option-widget.h b/gui/simple-greeter/gdm-option-widget.h
index e8c8753..088e3cd 100644
--- a/gui/simple-greeter/gdm-option-widget.h
+++ b/gui/simple-greeter/gdm-option-widget.h
@@ -57,6 +57,8 @@ typedef enum {
         GDM_OPTION_WIDGET_POSITION_BOTTOM,
 } GdmOptionWidgetPosition;
 
+#define GDM_OPTION_WIDGET_PREVIOUS_SELECTION "__previous"
+
 GType                  gdm_option_widget_get_type               (void);
 GtkWidget *            gdm_option_widget_new                    (const char *label_text);
 
diff --git a/gui/simple-greeter/gdm-session-option-widget.c b/gui/simple-greeter/gdm-session-option-widget.c
index 961ac94..2914996 100644
--- a/gui/simple-greeter/gdm-session-option-widget.c
+++ b/gui/simple-greeter/gdm-session-option-widget.c
@@ -75,6 +75,7 @@ gdm_session_option_widget_activated (GdmOptionWidget *widget)
         }
 
         g_signal_emit (G_OBJECT (widget), signals[SESSION_ACTIVATED], 0);
+        g_free (active_item_id);
 }
 
 
@@ -136,6 +137,14 @@ gdm_session_option_widget_init (GdmSessionOptionWidget *widget)
         widget->priv = GDM_SESSION_OPTION_WIDGET_GET_PRIVATE (widget);
 
         add_available_sessions (widget);
+
+        gdm_option_widget_add_item (GDM_OPTION_WIDGET (widget),
+                                    GDM_OPTION_WIDGET_PREVIOUS_SELECTION,
+                                    _("Previous Session"),
+                                    _("Use previous session"),
+                                    GDM_OPTION_WIDGET_POSITION_BOTTOM);
+        gdm_option_widget_set_default_item (GDM_OPTION_WIDGET (widget),
+                                            GDM_OPTION_WIDGET_PREVIOUS_SELECTION);
 }
 
 static void
