From 495b4fc0d7c65f76b03108199085df4fca98618c Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 14 Aug 2018 14:52:41 -0400 Subject: session: support new accountsservice Session and SessionType props At the moment the user's session is stored in a property called "XSession". This is pretty weird if the user is using wayland. AccountService now supports a more generic property "Session" and a related "SessionType" property to replace "XSession". This commit switches GDM over to use the new properties. --- daemon/gdm-session-settings.c | 61 ++++++++++++++++++++++++++++--- daemon/gdm-session-settings.h | 3 ++ daemon/gdm-session-worker.c | 28 ++++++++++++++ daemon/gdm-session-worker.xml | 3 ++ daemon/gdm-session.c | 85 +++++++++++++++++++++++++++++++------------ 5 files changed, 152 insertions(+), 28 deletions(-) diff --git a/daemon/gdm-session-settings.c b/daemon/gdm-session-settings.c index 484a3b5b..5b64cb65 100644 --- a/daemon/gdm-session-settings.c +++ b/daemon/gdm-session-settings.c @@ -39,6 +39,7 @@ struct _GdmSessionSettingsPrivate ActUserManager *user_manager; ActUser *user; char *session_name; + char *session_type; char *language_name; }; @@ -58,6 +59,7 @@ static void gdm_session_settings_get_property (GObject *object, enum { PROP_0 = 0, PROP_SESSION_NAME, + PROP_SESSION_TYPE, PROP_LANGUAGE_NAME, PROP_IS_LOADED }; @@ -93,6 +95,11 @@ gdm_session_settings_class_install_properties (GdmSessionSettingsClass *settings NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_SESSION_NAME, param_spec); + param_spec = g_param_spec_string ("session-type", "Session Type", + "The type of the session", + NULL, G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_SESSION_TYPE, param_spec); + param_spec = g_param_spec_string ("language-name", "Language Name", "The name of the language", NULL, @@ -163,6 +170,19 @@ gdm_session_settings_set_session_name (GdmSessionSettings *settings, } } +void +gdm_session_settings_set_session_type (GdmSessionSettings *settings, + const char *session_type) +{ + g_return_if_fail (GDM_IS_SESSION_SETTINGS (settings)); + + if (settings->priv->session_type == NULL || + g_strcmp0 (settings->priv->session_type, session_type) != 0) { + settings->priv->session_type = g_strdup (session_type); + g_object_notify (G_OBJECT (settings), "session-type"); + } +} + char * gdm_session_settings_get_language_name (GdmSessionSettings *settings) { @@ -177,6 +197,13 @@ gdm_session_settings_get_session_name (GdmSessionSettings *settings) return g_strdup (settings->priv->session_name); } +char * +gdm_session_settings_get_session_type (GdmSessionSettings *settings) +{ + g_return_val_if_fail (GDM_IS_SESSION_SETTINGS (settings), NULL); + return g_strdup (settings->priv->session_type); +} + static void gdm_session_settings_set_property (GObject *object, guint prop_id, @@ -196,6 +223,10 @@ gdm_session_settings_set_property (GObject *object, gdm_session_settings_set_session_name (settings, g_value_get_string (value)); break; + case PROP_SESSION_TYPE: + gdm_session_settings_set_session_type (settings, g_value_get_string (value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -216,6 +247,10 @@ gdm_session_settings_get_property (GObject *object, g_value_set_string (value, settings->priv->session_name); break; + case PROP_SESSION_TYPE: + g_value_set_string (value, settings->priv->session_type); + break; + case PROP_LANGUAGE_NAME: g_value_set_string (value, settings->priv->language_name); break; @@ -254,6 +289,7 @@ static void load_settings_from_user (GdmSessionSettings *settings) { const char *session_name; + const char *session_type; const char *language_name; if (!act_user_is_loaded (settings->priv->user)) { @@ -261,20 +297,31 @@ load_settings_from_user (GdmSessionSettings *settings) return; } - session_name = act_user_get_x_session (settings->priv->user); - g_debug ("GdmSessionSettings: saved session is %s", session_name); + /* if the user doesn't have saved state, they don't have any settings worth reading */ + if (!act_user_get_saved (settings->priv->user)) + goto out; + + session_type = act_user_get_session_type (settings->priv->user); + session_name = act_user_get_session (settings->priv->user); - if (session_name != NULL) { + g_debug ("GdmSessionSettings: saved session is %s (type %s)", session_name, session_type); + + if (session_type != NULL && session_type[0] != '\0') { + gdm_session_settings_set_session_type (settings, session_type); + } + + if (session_name != NULL && session_name[0] != '\0') { gdm_session_settings_set_session_name (settings, session_name); } language_name = act_user_get_language (settings->priv->user); g_debug ("GdmSessionSettings: saved language is %s", language_name); - if (language_name != NULL) { + if (language_name != NULL && language_name[0] != '\0') { gdm_session_settings_set_language_name (settings, language_name); } +out: g_object_notify (G_OBJECT (settings), "is-loaded"); } @@ -349,7 +396,11 @@ gdm_session_settings_save (GdmSessionSettings *settings, } if (settings->priv->session_name != NULL) { - act_user_set_x_session (user, settings->priv->session_name); + act_user_set_session (user, settings->priv->session_name); + } + + if (settings->priv->session_type != NULL) { + act_user_set_session_type (user, settings->priv->session_type); } if (settings->priv->language_name != NULL) { diff --git a/daemon/gdm-session-settings.h b/daemon/gdm-session-settings.h index 20946bff..db38ffc7 100644 --- a/daemon/gdm-session-settings.h +++ b/daemon/gdm-session-settings.h @@ -60,10 +60,13 @@ gboolean gdm_session_settings_save (GdmSessionSettings gboolean gdm_session_settings_is_loaded (GdmSessionSettings *settings); char *gdm_session_settings_get_language_name (GdmSessionSettings *settings); char *gdm_session_settings_get_session_name (GdmSessionSettings *settings); +char *gdm_session_settings_get_session_type (GdmSessionSettings *settings); void gdm_session_settings_set_language_name (GdmSessionSettings *settings, const char *language_name); void gdm_session_settings_set_session_name (GdmSessionSettings *settings, const char *session_name); +void gdm_session_settings_set_session_type (GdmSessionSettings *settings, + const char *session_type); G_END_DECLS #endif /* GDM_SESSION_SETTINGS_H */ diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c index 6e307ac6..7d7d2496 100644 --- a/daemon/gdm-session-worker.c +++ b/daemon/gdm-session-worker.c @@ -2583,6 +2583,20 @@ on_saved_session_name_read (GdmSessionWorker *worker) g_free (session_name); } +static void +on_saved_session_type_read (GdmSessionWorker *worker) +{ + char *session_type; + + session_type = gdm_session_settings_get_session_type (worker->priv->user_settings); + + g_debug ("GdmSessionWorker: Saved session type is %s", session_type); + gdm_dbus_worker_emit_saved_session_type_read (GDM_DBUS_WORKER (worker), + session_type); + g_free (session_type); +} + + static void do_setup (GdmSessionWorker *worker) { @@ -3046,6 +3060,11 @@ gdm_session_worker_handle_initialize (GdmDBusWorker *object, G_CALLBACK (on_saved_session_name_read), worker); + g_signal_connect_swapped (worker->priv->user_settings, + "notify::session-type", + G_CALLBACK (on_saved_session_type_read), + worker); + if (worker->priv->username) { wait_for_settings = !gdm_session_settings_load (worker->priv->user_settings, worker->priv->username); @@ -3102,6 +3121,11 @@ gdm_session_worker_handle_setup (GdmDBusWorker *object, "notify::session-name", G_CALLBACK (on_saved_session_name_read), worker); + g_signal_connect_swapped (worker->priv->user_settings, + "notify::session-type", + G_CALLBACK (on_saved_session_type_read), + worker); + return TRUE; } @@ -3144,6 +3168,10 @@ gdm_session_worker_handle_setup_for_user (GdmDBusWorker *object, "notify::session-name", G_CALLBACK (on_saved_session_name_read), worker); + g_signal_connect_swapped (worker->priv->user_settings, + "notify::session-type", + G_CALLBACK (on_saved_session_type_read), + worker); /* Load settings from accounts daemon before continuing */ diff --git a/daemon/gdm-session-worker.xml b/daemon/gdm-session-worker.xml index 4280fe09..a215779c 100644 --- a/daemon/gdm-session-worker.xml +++ b/daemon/gdm-session-worker.xml @@ -78,6 +78,9 @@ + + + diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c index ce49a8df..dcdbb40a 100644 --- a/daemon/gdm-session.c +++ b/daemon/gdm-session.c @@ -88,6 +88,7 @@ struct _GdmSession char *selected_program; char *selected_session; char *saved_session; + char *saved_session_type; char *saved_language; char *selected_user; char *user_x11_authority_file; @@ -355,7 +356,8 @@ supports_session_type (GdmSession *self, } static char ** -get_system_session_dirs (GdmSession *self) +get_system_session_dirs (GdmSession *self, + const char *type) { GArray *search_array = NULL; char **search_dirs; @@ -376,7 +378,8 @@ get_system_session_dirs (GdmSession *self) for (j = 0; self->supported_session_types[j] != NULL; j++) { const char *supported_type = self->supported_session_types[j]; - if (g_str_equal (supported_type, "x11")) { + if (g_str_equal (supported_type, "x11") || + (type == NULL || g_str_equal (type, supported_type))) { for (i = 0; system_data_dirs[i]; i++) { gchar *dir = g_build_filename (system_data_dirs[i], "xsessions", NULL); g_array_append_val (search_array, dir); @@ -386,13 +389,14 @@ get_system_session_dirs (GdmSession *self) } #ifdef ENABLE_WAYLAND_SUPPORT - if (g_str_equal (supported_type, "wayland")) { - g_array_prepend_val (search_array, wayland_search_dir); - + if (g_str_equal (supported_type, "wayland") || + (type == NULL || g_str_equal (type, supported_type))) { for (i = 0; system_data_dirs[i]; i++) { gchar *dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL); g_array_append_val (search_array, dir); } + + g_array_append_val (search_array, wayland_search_dir); } #endif } @@ -419,16 +423,18 @@ is_prog_in_path (const char *prog) static GKeyFile * load_key_file_for_file (GdmSession *self, const char *file, + const char *type, char **full_path) { GKeyFile *key_file; - GError *error; + GError *error = NULL; gboolean res; char **search_dirs; key_file = g_key_file_new (); - search_dirs = get_system_session_dirs (self), + search_dirs = get_system_session_dirs (self, type); + error = NULL; res = g_key_file_load_from_dirs (key_file, file, @@ -437,8 +443,11 @@ load_key_file_for_file (GdmSession *self, G_KEY_FILE_NONE, &error); if (! res) { - g_debug ("GdmSession: File '%s' not found: %s", file, error->message); - g_error_free (error); + g_debug ("GdmSession: File '%s' not found in search dirs", file); + if (error != NULL) { + g_debug ("GdmSession: %s", error->message); + g_error_free (error); + } g_key_file_free (key_file); key_file = NULL; } @@ -451,6 +460,7 @@ load_key_file_for_file (GdmSession *self, static gboolean get_session_command_for_file (GdmSession *self, const char *file, + const char *type, char **command) { GKeyFile *key_file; @@ -465,8 +475,14 @@ get_session_command_for_file (GdmSession *self, *command = NULL; } + if (!supports_session_type (self, type)) { + g_debug ("GdmSession: ignoring %s session command request for file '%s'", + type, file); + goto out; + } + g_debug ("GdmSession: getting session command for file '%s'", file); - key_file = load_key_file_for_file (self, file, NULL); + key_file = load_key_file_for_file (self, file, type, NULL); if (key_file == NULL) { goto out; } @@ -524,13 +540,14 @@ out: static gboolean get_session_command_for_name (GdmSession *self, const char *name, + const char *type, char **command) { gboolean res; char *filename; filename = g_strdup_printf ("%s.desktop", name); - res = get_session_command_for_file (self, filename, command); + res = get_session_command_for_file (self, filename, type, command); g_free (filename); return res; @@ -566,13 +583,13 @@ get_fallback_session_name (GdmSession *self) if (self->fallback_session_name != NULL) { /* verify that the cached version still exists */ - if (get_session_command_for_name (self, self->fallback_session_name, NULL)) { + if (get_session_command_for_name (self, self->fallback_session_name, NULL, NULL)) { goto out; } } name = g_strdup ("gnome"); - if (get_session_command_for_name (self, name, NULL)) { + if (get_session_command_for_name (self, name, NULL, NULL)) { g_free (self->fallback_session_name); self->fallback_session_name = name; goto out; @@ -581,7 +598,7 @@ get_fallback_session_name (GdmSession *self) sessions = g_sequence_new (g_free); - search_dirs = get_system_session_dirs (self); + search_dirs = get_system_session_dirs (self, NULL); for (i = 0; search_dirs[i] != NULL; i++) { GDir *dir; const char *base_name; @@ -603,7 +620,7 @@ get_fallback_session_name (GdmSession *self) continue; } - if (get_session_command_for_file (self, base_name, NULL)) { + if (get_session_command_for_file (self, base_name, NULL, NULL)) { name = g_strndup (base_name, strlen (base_name) - strlen (".desktop")); g_sequence_insert_sorted (sessions, name, (GCompareDataFunc) g_strcmp0, NULL); } @@ -676,6 +693,9 @@ gdm_session_select_user (GdmSession *self, g_free (self->saved_session); self->saved_session = NULL; + g_free (self->saved_session_type); + self->saved_session_type = NULL; + g_free (self->saved_language); self->saved_language = NULL; } @@ -996,7 +1016,7 @@ worker_on_saved_session_name_read (GdmDBusWorker *worker, { GdmSession *self = conversation->session; - if (! get_session_command_for_name (self, session_name, NULL)) { + if (! get_session_command_for_name (self, session_name, self->saved_session_type, NULL)) { /* ignore sessions that don't exist */ g_debug ("GdmSession: not using invalid .dmrc session: %s", session_name); g_free (self->saved_session); @@ -1016,6 +1036,17 @@ worker_on_saved_session_name_read (GdmDBusWorker *worker, } +static void +worker_on_saved_session_type_read (GdmDBusWorker *worker, + const char *session_type, + GdmSessionConversation *conversation) +{ + GdmSession *self = conversation->session; + + g_free (self->saved_session_type); + self->saved_session_type = g_strdup (session_type); +} + static GdmSessionConversation * find_conversation_by_pid (GdmSession *self, GPid pid) @@ -1149,6 +1180,9 @@ register_worker (GdmDBusWorkerManager *worker_manager_interface, g_signal_connect (conversation->worker_proxy, "saved-session-name-read", G_CALLBACK (worker_on_saved_session_name_read), conversation); + g_signal_connect (conversation->worker_proxy, + "saved-session-type-read", + G_CALLBACK (worker_on_saved_session_type_read), conversation); g_signal_connect (conversation->worker_proxy, "cancel-pending-query", G_CALLBACK (worker_on_cancel_pending_query), conversation); @@ -1945,6 +1979,9 @@ free_conversation (GdmSessionConversation *conversation) g_signal_handlers_disconnect_by_func (conversation->worker_proxy, G_CALLBACK (worker_on_saved_session_name_read), conversation); + g_signal_handlers_disconnect_by_func (conversation->worker_proxy, + G_CALLBACK (worker_on_saved_session_type_read), + conversation); g_signal_handlers_disconnect_by_func (conversation->worker_proxy, G_CALLBACK (worker_on_cancel_pending_query), conversation); @@ -2557,7 +2594,7 @@ get_session_command (GdmSession *self) session_name = get_session_name (self); command = NULL; - res = get_session_command_for_name (self, session_name, &command); + res = get_session_command_for_name (self, session_name, NULL, &command); if (! res) { g_critical ("Cannot find a command for specified session: %s", session_name); exit (EXIT_FAILURE); @@ -2579,7 +2616,7 @@ get_session_desktop_names (GdmSession *self) filename = g_strdup_printf ("%s.desktop", get_session_name (self)); g_debug ("GdmSession: getting desktop names for file '%s'", filename); - keyfile = load_key_file_for_file (self, filename, NULL); + keyfile = load_key_file_for_file (self, filename, NULL, NULL); if (keyfile != NULL) { gchar **names; @@ -3175,7 +3212,7 @@ gdm_session_is_wayland_session (GdmSession *self) filename = get_session_filename (self); if (supports_session_type (self, "wayland")) { - key_file = load_key_file_for_file (self, filename, &full_path); + key_file = load_key_file_for_file (self, filename, "wayland", &full_path); if (key_file == NULL) { goto out; @@ -3198,9 +3235,11 @@ static void update_session_type (GdmSession *self) { #ifdef ENABLE_WAYLAND_SUPPORT - gboolean is_wayland_session; + gboolean is_wayland_session = FALSE; + + if (supports_session_type (self, "wayland")) + is_wayland_session = gdm_session_is_wayland_session (self); - is_wayland_session = gdm_session_is_wayland_session (self); if (is_wayland_session) { set_session_type (self, "wayland"); } else { @@ -3222,7 +3261,7 @@ gdm_session_session_registers (GdmSession *self) filename = get_session_filename (self); - key_file = load_key_file_for_file (self, filename, NULL); + key_file = load_key_file_for_file (self, filename, NULL, NULL); session_registers = g_key_file_get_boolean (key_file, G_KEY_FILE_DESKTOP_GROUP, @@ -3262,7 +3301,7 @@ gdm_session_bypasses_xsession (GdmSession *self) filename = get_session_filename (self); - key_file = load_key_file_for_file (self, filename, NULL); + key_file = load_key_file_for_file (self, filename, "x11", NULL); error = NULL; res = g_key_file_has_key (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GDM-BypassXsession", NULL); -- cgit v1.2.1