diff options
author | Ray Strode <rstrode@redhat.com> | 2011-03-01 15:19:33 -0500 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2011-03-01 15:29:57 -0500 |
commit | 8ecc1022c3e3c0b162ac8008237f04b003792c49 (patch) | |
tree | fb97eea10cf7dd23c416cc60a6e6d21166333a36 /daemon/gdm-session-settings.c | |
parent | a205e28061953d0d83133dbf5ba594b543ed5c74 (diff) | |
download | gdm-8ecc1022c3e3c0b162ac8008237f04b003792c49.tar.gz |
daemon: ensure account is loaded before login
Since we load the user account information asynchronously, it's
conceivable that in some oddly timed situations, the
user's language and session won't be loaded by the time we are
ready for login.
This commit adds an explicit stage in the login cycle for waiting
on the user to load.
Diffstat (limited to 'daemon/gdm-session-settings.c')
-rw-r--r-- | daemon/gdm-session-settings.c | 95 |
1 files changed, 76 insertions, 19 deletions
diff --git a/daemon/gdm-session-settings.c b/daemon/gdm-session-settings.c index b9b809bc..ec56dc02 100644 --- a/daemon/gdm-session-settings.c +++ b/daemon/gdm-session-settings.c @@ -37,6 +37,7 @@ struct _GdmSessionSettingsPrivate { ActUserManager *user_manager; + ActUser *user; char *session_name; char *language_name; }; @@ -58,6 +59,7 @@ enum { PROP_0 = 0, PROP_SESSION_NAME, PROP_LANGUAGE_NAME, + PROP_IS_LOADED }; G_DEFINE_TYPE (GdmSessionSettings, gdm_session_settings, G_TYPE_OBJECT) @@ -96,6 +98,10 @@ gdm_session_settings_class_install_properties (GdmSessionSettingsClass *settings NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (object_class, PROP_LANGUAGE_NAME, param_spec); + + param_spec = g_param_spec_boolean ("is-loaded", NULL, NULL, + FALSE, G_PARAM_READABLE); + g_object_class_install_property (object_class, PROP_IS_LOADED, param_spec); } static void @@ -117,6 +123,10 @@ gdm_session_settings_finalize (GObject *object) settings = GDM_SESSION_SETTINGS (object); + if (settings->priv->user != NULL) { + g_object_unref (settings->priv->user); + } + g_free (settings->priv->session_name); g_free (settings->priv->language_name); @@ -210,6 +220,10 @@ gdm_session_settings_get_property (GObject *object, g_value_set_string (value, settings->priv->language_name); break; + case PROP_IS_LOADED: + g_value_set_boolean (value, gdm_session_settings_is_loaded (settings)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -229,42 +243,85 @@ gdm_session_settings_new (void) gboolean gdm_session_settings_is_loaded (GdmSessionSettings *settings) { - return settings->priv->session_name != NULL || - settings->priv->language_name != NULL; + if (settings->priv->user == NULL) { + return FALSE; + } + + return act_user_is_loaded (settings->priv->user); } -gboolean -gdm_session_settings_load (GdmSessionSettings *settings, - const char *username) +static void +load_settings_from_user (GdmSessionSettings *settings) { - ActUser *user; const char *session_name; const char *language_name; - g_return_val_if_fail (settings != NULL, FALSE); - g_return_val_if_fail (username != NULL, FALSE); - g_return_val_if_fail (!gdm_session_settings_is_loaded (settings), FALSE); - - user = act_user_manager_get_user (settings->priv->user_manager, - username); - - if (!act_user_is_loaded (user)) { - g_object_unref (user); - return FALSE; + if (!act_user_is_loaded (settings->priv->user)) { + g_warning ("GdmSessionSettings: trying to load user settings from unloaded user"); + return; } - session_name = act_user_get_x_session (user); + session_name = act_user_get_x_session (settings->priv->user); if (session_name != NULL) { gdm_session_settings_set_session_name (settings, session_name); } - language_name = act_user_get_language (user); + language_name = act_user_get_language (settings->priv->user); if (language_name != NULL) { gdm_session_settings_set_language_name (settings, language_name); } - g_object_unref (user); + + g_object_notify (G_OBJECT (settings), "is-loaded"); +} + +static void +on_user_is_loaded_changed (ActUser *user, + GParamSpec *pspec, + GdmSessionSettings *settings) +{ + if (act_user_is_loaded (settings->priv->user)) { + load_settings_from_user (settings); + } +} + +gboolean +gdm_session_settings_load (GdmSessionSettings *settings, + const char *username) +{ + ActUser *old_user; + + g_return_val_if_fail (settings != NULL, FALSE); + g_return_val_if_fail (username != NULL, FALSE); + g_return_val_if_fail (!gdm_session_settings_is_loaded (settings), FALSE); + + if (settings->priv->user != NULL) { + old_user = settings->priv->user; + + g_signal_handlers_disconnect_by_func (G_OBJECT (settings->priv->user), + G_CALLBACK (on_user_is_loaded_changed), + settings); + } else { + old_user = NULL; + } + + settings->priv->user = act_user_manager_get_user (settings->priv->user_manager, + username); + if (old_user != NULL) { + g_object_unref (old_user); + old_user = NULL; + } + + if (!act_user_is_loaded (settings->priv->user)) { + g_signal_connect (settings->priv->user, + "notify::is-loaded", + G_CALLBACK (on_user_is_loaded_changed), + settings); + return FALSE; + } + + load_settings_from_user (settings); return TRUE; } |