diff --git a/0001-manager-if-falling-back-to-X11-retry-autologin.patch b/0001-manager-if-falling-back-to-X11-retry-autologin.patch new file mode 100644 index 0000000..b5e5ae4 --- /dev/null +++ b/0001-manager-if-falling-back-to-X11-retry-autologin.patch @@ -0,0 +1,144 @@ +From ff98b2817014684ae1acec78ff06f0f461a56a9f Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 24 Mar 2017 23:40:07 -0400 +Subject: [PATCH 1/2] manager: if falling back to X11 retry autologin + +Right now, we get one shot to autologin. If it fails, we fall back to +the greeter. We should give it another go if the reason for the failure +was wayland fallback to X. + +https://bugzilla.gnome.org/show_bug.cgi?id=780520 +--- + daemon/gdm-manager.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c +index e78228b..d4843a6 100644 +--- a/daemon/gdm-manager.c ++++ b/daemon/gdm-manager.c +@@ -1419,114 +1419,119 @@ set_up_session (GdmManager *manager, + user_manager = act_user_manager_get_default (); + user = act_user_manager_get_user (user_manager, username); + g_object_get (user_manager, "is-loaded", &loaded, NULL); + + if (loaded) { + set_up_automatic_login_session_if_user_exists (manager, display, user); + } else { + UsernameLookupOperation *operation; + + operation = g_new (UsernameLookupOperation, 1); + operation->manager = g_object_ref (manager); + operation->display = g_object_ref (display); + operation->username = username; + + g_signal_connect (user, + "notify::is-loaded", + G_CALLBACK (on_user_is_loaded_changed), + operation); + } + } + + static void + greeter_display_started (GdmManager *manager, + GdmDisplay *display) + { + if (manager->priv->ran_once) { + return; + } + + maybe_start_pending_initial_login (manager, display); +- +- manager->priv->ran_once = TRUE; + } + + static void + on_display_status_changed (GdmDisplay *display, + GParamSpec *arg1, + GdmManager *manager) + { + int status; + int display_number = -1; ++ char *session_type = NULL; + #ifdef WITH_PLYMOUTH + gboolean display_is_local = FALSE; + gboolean quit_plymouth = FALSE; + + g_object_get (display, + "is-local", &display_is_local, + NULL); + quit_plymouth = display_is_local && manager->priv->plymouth_is_running; + #endif + +- g_object_get (display, "x11-display-number", &display_number, NULL); ++ g_object_get (display, ++ "x11-display-number", &display_number, ++ "session-type", &session_type, ++ NULL); + + status = gdm_display_get_status (display); + + switch (status) { + case GDM_DISPLAY_PREPARED: + case GDM_DISPLAY_MANAGED: + if ((display_number == -1 && status == GDM_DISPLAY_PREPARED) || + (display_number != -1 && status == GDM_DISPLAY_MANAGED)) { + char *session_class; + + g_object_get (display, + "session-class", &session_class, + NULL); + if (g_strcmp0 (session_class, "greeter") == 0) + set_up_session (manager, display); + g_free (session_class); + } + + if (status == GDM_DISPLAY_MANAGED) { + greeter_display_started (manager, display); + } + break; + case GDM_DISPLAY_FAILED: + case GDM_DISPLAY_UNMANAGED: + case GDM_DISPLAY_FINISHED: + #ifdef WITH_PLYMOUTH + if (quit_plymouth) { + plymouth_quit_without_transition (); + manager->priv->plymouth_is_running = FALSE; + } + #endif + ++ if (status == GDM_DISPLAY_FINISHED || g_strcmp0 (session_type, "x11") == 0) { ++ manager->priv->ran_once = TRUE; ++ } + maybe_start_pending_initial_login (manager, display); + break; + default: + break; + } + + } + + static void + on_display_removed (GdmDisplayStore *display_store, + const char *id, + GdmManager *manager) + { + GdmDisplay *display; + + display = gdm_display_store_lookup (display_store, id); + if (display != NULL) { + g_dbus_object_manager_server_unexport (manager->priv->object_manager, id); + + g_signal_handlers_disconnect_by_func (display, G_CALLBACK (on_display_status_changed), manager); + + g_signal_emit (manager, signals[DISPLAY_REMOVED], 0, id); + } + } + + static void + destroy_start_user_session_operation (StartUserSessionOperation *operation) + { + g_object_set_data (G_OBJECT (operation->session), + "start-user-session-operation", +-- +2.10.2 + diff --git a/0002-session-update-session-search-dirs-when-ignore-wayla.patch b/0002-session-update-session-search-dirs-when-ignore-wayla.patch new file mode 100644 index 0000000..43829db --- /dev/null +++ b/0002-session-update-session-search-dirs-when-ignore-wayla.patch @@ -0,0 +1,292 @@ +From a40384b729b74cf935effceaa1ce9fa6b906138c Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Fri, 24 Mar 2017 23:59:30 -0400 +Subject: [PATCH 2/2] session: update session search dirs when ignore-wayland + changes + +Right now the first time the session search dirs are requested, they +are computed and cached. That leaves them stale if the ignore-wayland +flag changes, which breaks fallback mode in some cases. + +This commit fix the problem by always computing the session search dirs +in full, with no caching. + +https://bugzilla.gnome.org/show_bug.cgi?id=780518 +--- + daemon/gdm-session.c | 34 +++++++++++++++++++++------------- + 1 file changed, 21 insertions(+), 13 deletions(-) + +diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c +index e69291f..08d61de 100644 +--- a/daemon/gdm-session.c ++++ b/daemon/gdm-session.c +@@ -310,131 +310,138 @@ on_establish_credentials_cb (GdmDBusWorker *proxy, + g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + self = g_object_ref (conversation->session); + service_name = g_strdup (conversation->service_name); + + if (worked) { + if (self->priv->user_verifier_interface != NULL) { + gdm_dbus_user_verifier_emit_verification_complete (self->priv->user_verifier_interface, + service_name); + g_signal_emit (self, signals[VERIFICATION_COMPLETE], 0, service_name); + } + + switch (self->priv->verification_mode) { + case GDM_SESSION_VERIFICATION_MODE_LOGIN: + case GDM_SESSION_VERIFICATION_MODE_CHOOSER: + gdm_session_open_session (self, service_name); + break; + case GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE: + default: + break; + } + } else { + report_and_stop_conversation (self, service_name, error); + } + + g_free (service_name); + g_object_unref (self); + } + +-static const char ** ++static char ** + get_system_session_dirs (GdmSession *self) + { +- static GArray *search_array = NULL; ++ GArray *search_array = NULL; ++ char **search_dirs; + + static const char *x_search_dirs[] = { + "/etc/X11/sessions/", + DMCONFDIR "/Sessions/", + DATADIR "/gdm/BuiltInSessions/", + DATADIR "/xsessions/", + NULL + }; + + static const char *wayland_search_dir = DATADIR "/wayland-sessions/"; + +- if (search_array == NULL) { +- search_array = g_array_new (TRUE, TRUE, sizeof (char *)); ++ search_array = g_array_new (TRUE, TRUE, sizeof (char *)); + +- g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs)); ++ g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs)); + + #ifdef ENABLE_WAYLAND_SUPPORT +- if (!self->priv->ignore_wayland) { ++ if (!self->priv->ignore_wayland) { + #ifdef ENABLE_USER_DISPLAY_SERVER +- g_array_prepend_val (search_array, wayland_search_dir); ++ g_array_prepend_val (search_array, wayland_search_dir); + #else +- g_array_append_val (search_array, wayland_search_dir); +-#endif +- } ++ g_array_append_val (search_array, wayland_search_dir); + #endif + } ++#endif + +- return (const char **) search_array->data; ++ search_dirs = g_strdupv ((char **) search_array->data); ++ ++ g_array_free (search_array, TRUE); ++ ++ return search_dirs; + } + + static gboolean + is_prog_in_path (const char *prog) + { + char *f; + gboolean ret; + + f = g_find_program_in_path (prog); + ret = (f != NULL); + g_free (f); + return ret; + } + + static GKeyFile * + load_key_file_for_file (GdmSession *self, + const char *file, + char **full_path) + { + GKeyFile *key_file; + GError *error; + gboolean res; ++ char **search_dirs; + + key_file = g_key_file_new (); + ++ search_dirs = get_system_session_dirs (self), + error = NULL; + res = g_key_file_load_from_dirs (key_file, + file, +- get_system_session_dirs (self), ++ (const char **) search_dirs, + full_path, + G_KEY_FILE_NONE, + &error); + if (! res) { + g_debug ("GdmSession: File '%s' not found: %s", file, error->message); + g_error_free (error); + g_key_file_free (key_file); + key_file = NULL; + } + ++ g_strfreev (search_dirs); ++ + return key_file; + } + + static gboolean + get_session_command_for_file (GdmSession *self, + const char *file, + char **command) + { + GKeyFile *key_file; + GError *error; + char *exec; + gboolean ret; + gboolean res; + + exec = NULL; + ret = FALSE; + if (command != NULL) { + *command = NULL; + } + + g_debug ("GdmSession: getting session command for file '%s'", file); + key_file = load_key_file_for_file (self, file, NULL); + if (key_file == NULL) { + goto out; + } + + error = NULL; + res = g_key_file_get_boolean (key_file, + G_KEY_FILE_DESKTOP_GROUP, + G_KEY_FILE_DESKTOP_KEY_HIDDEN, +@@ -494,113 +501,114 @@ get_session_command_for_name (GdmSession *self, + + filename = g_strdup_printf ("%s.desktop", name); + res = get_session_command_for_file (self, filename, command); + g_free (filename); + + return res; + } + + static const char * + get_default_language_name (GdmSession *self) + { + const char *default_language; + + if (self->priv->saved_language != NULL) { + return self->priv->saved_language; + } + + default_language = g_hash_table_lookup (self->priv->environment, + "LANG"); + + if (default_language != NULL) { + return default_language; + } + + return setlocale (LC_MESSAGES, NULL); + } + + static const char * + get_fallback_session_name (GdmSession *self) + { +- const char **search_dirs; ++ char **search_dirs; + int i; + char *name; + GSequence *sessions; + GSequenceIter *session; + + if (self->priv->fallback_session_name != NULL) { + /* verify that the cached version still exists */ + if (get_session_command_for_name (self, self->priv->fallback_session_name, NULL)) { + goto out; + } + } + + name = g_strdup ("gnome"); + if (get_session_command_for_name (self, name, NULL)) { + g_free (self->priv->fallback_session_name); + self->priv->fallback_session_name = name; + goto out; + } + g_free (name); + + sessions = g_sequence_new (g_free); + + search_dirs = get_system_session_dirs (self); + for (i = 0; search_dirs[i] != NULL; i++) { + GDir *dir; + const char *base_name; + + dir = g_dir_open (search_dirs[i], 0, NULL); + + if (dir == NULL) { + continue; + } + + do { + base_name = g_dir_read_name (dir); + + if (base_name == NULL) { + break; + } + + if (!g_str_has_suffix (base_name, ".desktop")) { + continue; + } + + if (get_session_command_for_file (self, base_name, NULL)) { + + g_sequence_insert_sorted (sessions, g_strdup (base_name), (GCompareDataFunc) g_strcmp0, NULL); + } + } while (base_name != NULL); + + g_dir_close (dir); + } ++ g_strfreev (search_dirs); + + name = NULL; + session = g_sequence_get_begin_iter (sessions); + + if (g_sequence_iter_is_end (session)) + g_error ("GdmSession: no session desktop files installed, aborting..."); + + do { + if (g_sequence_get (session)) { + char *base_name; + + g_free (name); + base_name = g_sequence_get (session); + name = g_strndup (base_name, + strlen (base_name) - + strlen (".desktop")); + + break; + } + session = g_sequence_iter_next (session); + } while (!g_sequence_iter_is_end (session)); + + g_free (self->priv->fallback_session_name); + self->priv->fallback_session_name = name; + + g_sequence_free (sessions); + + out: + return self->priv->fallback_session_name; + } +-- +2.10.2 + diff --git a/gdm.spec b/gdm.spec index 3e0ab39..7c9cc8e 100644 --- a/gdm.spec +++ b/gdm.spec @@ -10,7 +10,7 @@ Name: gdm Epoch: 1 Version: 3.24.0 -Release: 1%{?dist} +Release: 2%{?dist} Summary: The GNOME Display Manager License: GPLv2+ @@ -18,6 +18,8 @@ URL: https://wiki.gnome.org/Projects/GDM Source0: http://download.gnome.org/sources/gdm/3.24/gdm-%{version}.tar.xz Source1: org.gnome.login-screen.gschema.override Patch0: 0001-Honor-initial-setup-being-disabled-by-distro-install.patch +Patch1: 0001-manager-if-falling-back-to-X11-retry-autologin.patch +Patch2: 0002-session-update-session-search-dirs-when-ignore-wayla.patch BuildRequires: pam-devel >= 0:%{pam_version} BuildRequires: desktop-file-utils >= %{desktop_file_utils_version} @@ -102,6 +104,8 @@ files needed to build custom greeters. %prep %setup -q %patch0 -p1 +%patch1 -p1 +%patch2 -p1 autoreconf -i -f intltoolize -f @@ -296,6 +300,10 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : %{_libdir}/pkgconfig/gdm.pc %changelog +* Sat Mar 25 2017 Ray Strode - 1:3.24.0-2 +- Fix fallback to X logic + Resolves: #1435010 + * Tue Mar 21 2017 Kalev Lember - 1:3.24.0-1 - Update to 3.24.0