diff --git a/.gitignore b/.gitignore index ff3893b..9cbb2dc 100644 --- a/.gitignore +++ b/.gitignore @@ -137,3 +137,4 @@ gdm-2.30.2.tar.bz2 /gdm-40.beta.tar.xz /gdm-40.rc.tar.xz /gdm-40.0.tar.xz +/gdm-41.alpha.tar.xz diff --git a/0001-daemon-Provide-more-flexibility-for-configuring-disp.patch b/0001-daemon-Provide-more-flexibility-for-configuring-disp.patch deleted file mode 100644 index 4cafd95..0000000 --- a/0001-daemon-Provide-more-flexibility-for-configuring-disp.patch +++ /dev/null @@ -1,2265 +0,0 @@ -From 85657aeaf0e7bfa3e5765dd9917891dc2560b650 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Fri, 16 Jul 2021 12:34:57 -0400 -Subject: [PATCH 1/3] daemon: Provide more flexibility for configuring display - server - -There's currently a way to disable wayland, but no way to disable Xorg. -We currently prefer wayland if it's not disabled, but have no way to -prefer Xorg without disabling wayland entirely. - -There's currently no way use legacy Xorg support at all if user display -server support is enabled at a build time. - -This commit adds more flexibility to display server selection. It adds -two new keys: XorgEnable and and PreferredDisplayServer. - -XorgEnable=false disables Xorg support entirely on seat 0. - -PreferredDisplayServer can be set to "wayland", "xorg", "legacy-xorg" or -"none" to select which display server is used by default. If it's set to -"wayland", it will fall back to "xorg". If it's set to "xorg" it will -fall back to "wayland". ---- - common/gdm-settings-keys.h | 2 + - daemon/gdm-display.c | 36 +++++ - daemon/gdm-launch-environment.c | 9 ++ - daemon/gdm-local-display-factory.c | 220 ++++++++++++++++++++++++----- - daemon/gdm-manager.c | 6 - - daemon/gdm-session.c | 109 +++++++------- - data/gdm.schemas.in | 10 ++ - libgdm/gdm-sessions.c | 72 +++++++--- - 8 files changed, 349 insertions(+), 115 deletions(-) - -diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h -index f0059b5c..87685d3c 100644 ---- a/common/gdm-settings-keys.h -+++ b/common/gdm-settings-keys.h -@@ -6,59 +6,61 @@ - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - - #ifndef _GDM_SETTINGS_KEYS_H - #define _GDM_SETTINGS_KEYS_H - - #include - - G_BEGIN_DECLS - - #define GDM_KEY_USER "daemon/User" - #define GDM_KEY_GROUP "daemon/Group" - #define GDM_KEY_AUTO_LOGIN_ENABLE "daemon/AutomaticLoginEnable" - #define GDM_KEY_AUTO_LOGIN_USER "daemon/AutomaticLogin" - #define GDM_KEY_TIMED_LOGIN_ENABLE "daemon/TimedLoginEnable" - #define GDM_KEY_TIMED_LOGIN_USER "daemon/TimedLogin" - #define GDM_KEY_TIMED_LOGIN_DELAY "daemon/TimedLoginDelay" - #define GDM_KEY_INITIAL_SETUP_ENABLE "daemon/InitialSetupEnable" -+#define GDM_KEY_PREFERRED_DISPLAY_SERVER "daemon/PreferredDisplayServer" - #define GDM_KEY_WAYLAND_ENABLE "daemon/WaylandEnable" -+#define GDM_KEY_XORG_ENABLE "daemon/XorgEnable" - - #define GDM_KEY_DEBUG "debug/Enable" - - #define GDM_KEY_INCLUDE "greeter/Include" - #define GDM_KEY_EXCLUDE "greeter/Exclude" - #define GDM_KEY_INCLUDE_ALL "greeter/IncludeAll" - - #define GDM_KEY_DISALLOW_TCP "security/DisallowTCP" - #define GDM_KEY_ALLOW_REMOTE_AUTOLOGIN "security/AllowRemoteAutoLogin" - - #define GDM_KEY_XDMCP_ENABLE "xdmcp/Enable" - #define GDM_KEY_SHOW_LOCAL_GREETER "xdmcp/ShowLocalGreeter" - #define GDM_KEY_MAX_PENDING "xdmcp/MaxPending" - #define GDM_KEY_MAX_SESSIONS "xdmcp/MaxSessions" - #define GDM_KEY_MAX_WAIT "xdmcp/MaxWait" - #define GDM_KEY_DISPLAYS_PER_HOST "xdmcp/DisplaysPerHost" - #define GDM_KEY_UDP_PORT "xdmcp/Port" - #define GDM_KEY_INDIRECT "xdmcp/HonorIndirect" - #define GDM_KEY_MAX_WAIT_INDIRECT "xdmcp/MaxWaitIndirect" - #define GDM_KEY_PING_INTERVAL "xdmcp/PingIntervalSeconds" - #define GDM_KEY_WILLING "xdmcp/Willing" - - #define GDM_KEY_MULTICAST "chooser/Multicast" - #define GDM_KEY_MULTICAST_ADDR "chooser/MulticastAddr" - - G_END_DECLS - - #endif /* _GDM_SETTINGS_KEYS_H */ -diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c -index 2c03b565..bc09def9 100644 ---- a/daemon/gdm-display.c -+++ b/daemon/gdm-display.c -@@ -66,83 +66,86 @@ typedef struct _GdmDisplayPrivate - char *x11_display_name; - int status; - time_t creation_time; - - char *x11_cookie; - gsize x11_cookie_size; - GdmDisplayAccessFile *access_file; - - guint finish_idle_id; - - xcb_connection_t *xcb_connection; - int xcb_screen_number; - - GDBusConnection *connection; - GdmDisplayAccessFile *user_access_file; - - GdmDBusDisplay *display_skeleton; - GDBusObjectSkeleton *object_skeleton; - - GDBusProxy *accountsservice_proxy; - - /* this spawns and controls the greeter session */ - GdmLaunchEnvironment *launch_environment; - - guint is_local : 1; - guint is_initial : 1; - guint allow_timed_login : 1; - guint have_existing_user_accounts : 1; - guint doing_initial_setup : 1; - guint session_registered : 1; -+ -+ GStrv supported_session_types; - } GdmDisplayPrivate; - - enum { - PROP_0, - PROP_ID, - PROP_STATUS, - PROP_SEAT_ID, - PROP_SESSION_ID, - PROP_SESSION_CLASS, - PROP_SESSION_TYPE, - PROP_REMOTE_HOSTNAME, - PROP_X11_DISPLAY_NUMBER, - PROP_X11_DISPLAY_NAME, - PROP_X11_COOKIE, - PROP_X11_AUTHORITY_FILE, - PROP_IS_CONNECTED, - PROP_IS_LOCAL, - PROP_LAUNCH_ENVIRONMENT, - PROP_IS_INITIAL, - PROP_ALLOW_TIMED_LOGIN, - PROP_HAVE_EXISTING_USER_ACCOUNTS, - PROP_DOING_INITIAL_SETUP, - PROP_SESSION_REGISTERED, -+ PROP_SUPPORTED_SESSION_TYPES, - }; - - static void gdm_display_class_init (GdmDisplayClass *klass); - static void gdm_display_init (GdmDisplay *self); - static void gdm_display_finalize (GObject *object); - static void queue_finish (GdmDisplay *self); - static void _gdm_display_set_status (GdmDisplay *self, - int status); - static gboolean wants_initial_setup (GdmDisplay *self); - G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdmDisplay, gdm_display, G_TYPE_OBJECT) - - GQuark - gdm_display_error_quark (void) - { - static GQuark ret = 0; - if (ret == 0) { - ret = g_quark_from_static_string ("gdm_display_error"); - } - - return ret; - } - - time_t - gdm_display_get_creation_time (GdmDisplay *self) - { - GdmDisplayPrivate *priv; - - g_return_val_if_fail (GDM_IS_DISPLAY (self), 0); - - priv = gdm_display_get_instance_private (self); -@@ -885,116 +888,136 @@ _gdm_display_set_launch_environment (GdmDisplay *self, - - priv = gdm_display_get_instance_private (self); - - g_clear_object (&priv->launch_environment); - - priv->launch_environment = g_object_ref (launch_environment); - } - - static void - _gdm_display_set_is_initial (GdmDisplay *self, - gboolean initial) - { - GdmDisplayPrivate *priv; - - priv = gdm_display_get_instance_private (self); - g_debug ("GdmDisplay: initial: %s", initial? "yes" : "no"); - priv->is_initial = initial; - } - - static void - _gdm_display_set_allow_timed_login (GdmDisplay *self, - gboolean allow_timed_login) - { - GdmDisplayPrivate *priv; - - priv = gdm_display_get_instance_private (self); - g_debug ("GdmDisplay: allow timed login: %s", allow_timed_login? "yes" : "no"); - priv->allow_timed_login = allow_timed_login; - } - -+static void -+_gdm_display_set_supported_session_types (GdmDisplay *self, -+ const char * const *supported_session_types) -+ -+{ -+ GdmDisplayPrivate *priv; -+ g_autofree char *supported_session_types_string = NULL; -+ -+ if (supported_session_types != NULL) -+ supported_session_types_string = g_strjoinv (":", (GStrv) supported_session_types); -+ -+ priv = gdm_display_get_instance_private (self); -+ g_debug ("GdmDisplay: supported session types: %s", supported_session_types_string); -+ g_strfreev (priv->supported_session_types); -+ priv->supported_session_types = g_strdupv ((GStrv) supported_session_types); -+} -+ - static void - gdm_display_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) - { - GdmDisplay *self; - - self = GDM_DISPLAY (object); - - switch (prop_id) { - case PROP_ID: - _gdm_display_set_id (self, g_value_get_string (value)); - break; - case PROP_STATUS: - _gdm_display_set_status (self, g_value_get_int (value)); - break; - case PROP_SEAT_ID: - _gdm_display_set_seat_id (self, g_value_get_string (value)); - break; - case PROP_SESSION_ID: - _gdm_display_set_session_id (self, g_value_get_string (value)); - break; - case PROP_SESSION_CLASS: - _gdm_display_set_session_class (self, g_value_get_string (value)); - break; - case PROP_SESSION_TYPE: - _gdm_display_set_session_type (self, g_value_get_string (value)); - break; - case PROP_REMOTE_HOSTNAME: - _gdm_display_set_remote_hostname (self, g_value_get_string (value)); - break; - case PROP_X11_DISPLAY_NUMBER: - _gdm_display_set_x11_display_number (self, g_value_get_int (value)); - break; - case PROP_X11_DISPLAY_NAME: - _gdm_display_set_x11_display_name (self, g_value_get_string (value)); - break; - case PROP_X11_COOKIE: - _gdm_display_set_x11_cookie (self, g_value_get_string (value)); - break; - case PROP_IS_LOCAL: - _gdm_display_set_is_local (self, g_value_get_boolean (value)); - break; - case PROP_ALLOW_TIMED_LOGIN: - _gdm_display_set_allow_timed_login (self, g_value_get_boolean (value)); - break; - case PROP_LAUNCH_ENVIRONMENT: - _gdm_display_set_launch_environment (self, g_value_get_object (value)); - break; - case PROP_IS_INITIAL: - _gdm_display_set_is_initial (self, g_value_get_boolean (value)); - break; - case PROP_SESSION_REGISTERED: - _gdm_display_set_session_registered (self, g_value_get_boolean (value)); - break; -+ case PROP_SUPPORTED_SESSION_TYPES: -+ _gdm_display_set_supported_session_types (self, g_value_get_boxed (value)); -+ break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } - - static void - gdm_display_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) - { - GdmDisplay *self; - GdmDisplayPrivate *priv; - - self = GDM_DISPLAY (object); - priv = gdm_display_get_instance_private (self); - - switch (prop_id) { - case PROP_ID: - g_value_set_string (value, priv->id); - break; - case PROP_STATUS: - g_value_set_int (value, priv->status); - break; - case PROP_SEAT_ID: - g_value_set_string (value, priv->seat_id); - break; - case PROP_SESSION_ID: - g_value_set_string (value, priv->session_id); -@@ -1019,60 +1042,63 @@ gdm_display_get_property (GObject *object, - break; - case PROP_X11_AUTHORITY_FILE: - g_value_take_string (value, - priv->access_file? - gdm_display_access_file_get_path (priv->access_file) : NULL); - break; - case PROP_IS_LOCAL: - g_value_set_boolean (value, priv->is_local); - break; - case PROP_IS_CONNECTED: - g_value_set_boolean (value, priv->xcb_connection != NULL); - break; - case PROP_LAUNCH_ENVIRONMENT: - g_value_set_object (value, priv->launch_environment); - break; - case PROP_IS_INITIAL: - g_value_set_boolean (value, priv->is_initial); - break; - case PROP_HAVE_EXISTING_USER_ACCOUNTS: - g_value_set_boolean (value, priv->have_existing_user_accounts); - break; - case PROP_DOING_INITIAL_SETUP: - g_value_set_boolean (value, priv->doing_initial_setup); - break; - case PROP_SESSION_REGISTERED: - g_value_set_boolean (value, priv->session_registered); - break; - case PROP_ALLOW_TIMED_LOGIN: - g_value_set_boolean (value, priv->allow_timed_login); - break; -+ case PROP_SUPPORTED_SESSION_TYPES: -+ g_value_set_boxed (value, priv->supported_session_types); -+ break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } - - static gboolean - handle_get_id (GdmDBusDisplay *skeleton, - GDBusMethodInvocation *invocation, - GdmDisplay *self) - { - char *id; - - gdm_display_get_id (self, &id, NULL); - - gdm_dbus_display_complete_get_id (skeleton, invocation, id); - - g_free (id); - return TRUE; - } - - static gboolean - handle_get_remote_hostname (GdmDBusDisplay *skeleton, - GDBusMethodInvocation *invocation, - GdmDisplay *self) - { - char *hostname; - - gdm_display_get_remote_hostname (self, &hostname, NULL); - -@@ -1204,60 +1230,61 @@ gdm_display_constructor (GType type, - priv = gdm_display_get_instance_private (self); - - g_free (priv->id); - priv->id = g_strdup_printf ("/org/gnome/DisplayManager/Displays/%lu", - (gulong) self); - - res = register_display (self); - if (! res) { - g_warning ("Unable to register display with system bus"); - } - - return G_OBJECT (self); - } - - static void - gdm_display_dispose (GObject *object) - { - GdmDisplay *self; - GdmDisplayPrivate *priv; - - self = GDM_DISPLAY (object); - priv = gdm_display_get_instance_private (self); - - g_debug ("GdmDisplay: Disposing display"); - - if (priv->finish_idle_id != 0) { - g_source_remove (priv->finish_idle_id); - priv->finish_idle_id = 0; - } - g_clear_object (&priv->launch_environment); -+ g_clear_pointer (&priv->supported_session_types, g_strfreev); - - g_warn_if_fail (priv->status != GDM_DISPLAY_MANAGED); - g_warn_if_fail (priv->user_access_file == NULL); - g_warn_if_fail (priv->access_file == NULL); - - G_OBJECT_CLASS (gdm_display_parent_class)->dispose (object); - } - - static void - gdm_display_class_init (GdmDisplayClass *klass) - { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->get_property = gdm_display_get_property; - object_class->set_property = gdm_display_set_property; - object_class->constructor = gdm_display_constructor; - object_class->dispose = gdm_display_dispose; - object_class->finalize = gdm_display_finalize; - - klass->prepare = gdm_display_real_prepare; - - g_object_class_install_property (object_class, - PROP_ID, - g_param_spec_string ("id", - "id", - "id", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, - PROP_REMOTE_HOSTNAME, -@@ -1364,60 +1391,68 @@ gdm_display_class_init (GdmDisplayClass *klass) - PROP_DOING_INITIAL_SETUP, - g_param_spec_boolean ("doing-initial-setup", - NULL, - NULL, - FALSE, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, - PROP_SESSION_REGISTERED, - g_param_spec_boolean ("session-registered", - NULL, - NULL, - FALSE, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_LAUNCH_ENVIRONMENT, - g_param_spec_object ("launch-environment", - NULL, - NULL, - GDM_TYPE_LAUNCH_ENVIRONMENT, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, - PROP_STATUS, - g_param_spec_int ("status", - "status", - "status", - -1, - G_MAXINT, - GDM_DISPLAY_UNMANAGED, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); -+ -+ g_object_class_install_property (object_class, -+ PROP_SUPPORTED_SESSION_TYPES, -+ g_param_spec_boxed ("supported-session-types", -+ "supported session types", -+ "supported session types", -+ G_TYPE_STRV, -+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - } - - static void - gdm_display_init (GdmDisplay *self) - { - GdmDisplayPrivate *priv; - - priv = gdm_display_get_instance_private (self); - - priv->creation_time = time (NULL); - } - - static void - gdm_display_finalize (GObject *object) - { - GdmDisplay *self; - GdmDisplayPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_DISPLAY (object)); - - self = GDM_DISPLAY (object); - priv = gdm_display_get_instance_private (self); - - g_return_if_fail (priv != NULL); - - g_debug ("GdmDisplay: Finalizing display: %s", priv->id); - g_free (priv->id); - g_free (priv->seat_id); - g_free (priv->session_class); -@@ -1725,60 +1760,61 @@ gdm_display_start_greeter_session (GdmDisplay *self) - G_CALLBACK (on_launch_environment_session_opened), - self, 0); - g_signal_connect_object (priv->launch_environment, - "started", - G_CALLBACK (on_launch_environment_session_started), - self, 0); - g_signal_connect_object (priv->launch_environment, - "stopped", - G_CALLBACK (on_launch_environment_session_stopped), - self, 0); - g_signal_connect_object (priv->launch_environment, - "exited", - G_CALLBACK (on_launch_environment_session_exited), - self, 0); - g_signal_connect_object (priv->launch_environment, - "died", - G_CALLBACK (on_launch_environment_session_died), - self, 0); - - if (auth_file != NULL) { - g_object_set (priv->launch_environment, - "x11-authority-file", auth_file, - NULL); - } - - gdm_launch_environment_start (priv->launch_environment); - - session = gdm_launch_environment_get_session (priv->launch_environment); - g_object_set (G_OBJECT (session), - "display-is-initial", priv->is_initial, -+ "supported-session-types", priv->supported_session_types, - NULL); - - g_free (display_name); - g_free (seat_id); - g_free (hostname); - g_free (auth_file); - } - - void - gdm_display_stop_greeter_session (GdmDisplay *self) - { - GdmDisplayPrivate *priv; - - priv = gdm_display_get_instance_private (self); - - if (priv->launch_environment != NULL) { - - g_signal_handlers_disconnect_by_func (priv->launch_environment, - G_CALLBACK (on_launch_environment_session_opened), - self); - g_signal_handlers_disconnect_by_func (priv->launch_environment, - G_CALLBACK (on_launch_environment_session_started), - self); - g_signal_handlers_disconnect_by_func (priv->launch_environment, - G_CALLBACK (on_launch_environment_session_stopped), - self); - g_signal_handlers_disconnect_by_func (priv->launch_environment, - G_CALLBACK (on_launch_environment_session_exited), - self); - g_signal_handlers_disconnect_by_func (priv->launch_environment, -diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c -index feccf057..5044290c 100644 ---- a/daemon/gdm-launch-environment.c -+++ b/daemon/gdm-launch-environment.c -@@ -117,60 +117,61 @@ static GHashTable * - build_launch_environment (GdmLaunchEnvironment *launch_environment, - gboolean start_session) - { - GHashTable *hash; - struct passwd *pwent; - static const char *const optional_environment[] = { - "GI_TYPELIB_PATH", - "LANG", - "LANGUAGE", - "LC_ADDRESS", - "LC_ALL", - "LC_COLLATE", - "LC_CTYPE", - "LC_IDENTIFICATION", - "LC_MEASUREMENT", - "LC_MESSAGES", - "LC_MONETARY", - "LC_NAME", - "LC_NUMERIC", - "LC_PAPER", - "LC_TELEPHONE", - "LC_TIME", - "LD_LIBRARY_PATH", - "PATH", - "WINDOWPATH", - "XCURSOR_PATH", - "XDG_CONFIG_DIRS", - NULL - }; - char *system_data_dirs; -+ g_auto (GStrv) supported_session_types = NULL; - int i; - - /* create a hash table of current environment, then update keys has necessary */ - hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - - for (i = 0; optional_environment[i] != NULL; i++) { - if (g_getenv (optional_environment[i]) == NULL) { - continue; - } - - g_hash_table_insert (hash, - g_strdup (optional_environment[i]), - g_strdup (g_getenv (optional_environment[i]))); - } - - system_data_dirs = g_strjoinv (":", (char **) g_get_system_data_dirs ()); - - g_hash_table_insert (hash, - g_strdup ("XDG_DATA_DIRS"), - g_strdup_printf ("%s:%s", - DATADIR "/gdm/greeter", - system_data_dirs)); - g_free (system_data_dirs); - - if (launch_environment->priv->x11_authority_file != NULL) - g_hash_table_insert (hash, g_strdup ("XAUTHORITY"), g_strdup (launch_environment->priv->x11_authority_file)); - - if (launch_environment->priv->session_mode != NULL) { - g_hash_table_insert (hash, g_strdup ("GNOME_SHELL_SESSION_MODE"), g_strdup (launch_environment->priv->session_mode)); - -@@ -191,60 +192,68 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment, - g_hash_table_insert (hash, g_strdup ("USER"), g_strdup (launch_environment->priv->user_name)); - g_hash_table_insert (hash, g_strdup ("USERNAME"), g_strdup (launch_environment->priv->user_name)); - - g_hash_table_insert (hash, g_strdup ("GDM_VERSION"), g_strdup (VERSION)); - g_hash_table_remove (hash, "MAIL"); - - g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup ("/")); - g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup ("/")); - g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup ("/bin/sh")); - - gdm_get_pwent_for_name (launch_environment->priv->user_name, &pwent); - if (pwent != NULL) { - if (pwent->pw_dir != NULL && pwent->pw_dir[0] != '\0') { - g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup (pwent->pw_dir)); - g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup (pwent->pw_dir)); - } - - g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup (pwent->pw_shell)); - } - - if (start_session && launch_environment->priv->x11_display_seat_id != NULL) { - char *seat_id; - - seat_id = launch_environment->priv->x11_display_seat_id; - - g_hash_table_insert (hash, g_strdup ("GDM_SEAT_ID"), g_strdup (seat_id)); - } - - g_hash_table_insert (hash, g_strdup ("RUNNING_UNDER_GDM"), g_strdup ("true")); - -+ g_object_get (launch_environment->priv->session, -+ "supported-session-types", -+ &supported_session_types, -+ NULL); -+ g_hash_table_insert (hash, -+ g_strdup ("GDM_SUPPORTED_SESSION_TYPES"), -+ g_strjoinv (":", supported_session_types)); -+ - return hash; - } - - static void - on_session_setup_complete (GdmSession *session, - const char *service_name, - GdmLaunchEnvironment *launch_environment) - { - GHashTable *hash; - GHashTableIter iter; - gpointer key, value; - - hash = build_launch_environment (launch_environment, TRUE); - - g_hash_table_iter_init (&iter, hash); - while (g_hash_table_iter_next (&iter, &key, &value)) { - gdm_session_set_environment_variable (launch_environment->priv->session, key, value); - } - g_hash_table_destroy (hash); - } - - static void - on_session_opened (GdmSession *session, - const char *service_name, - const char *session_id, - GdmLaunchEnvironment *launch_environment) - { - launch_environment->priv->session_id = g_strdup (session_id); - - g_signal_emit (G_OBJECT (launch_environment), signals [OPENED], 0); -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index 8a4ef06c..0bb3851f 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -156,126 +156,221 @@ take_next_display_number (GdmLocalDisplayFactory *factory) - - g_debug ("GdmLocalDisplayFactory: Found the following X displays:"); - for (l = list; l != NULL; l = l->next) { - g_debug ("GdmLocalDisplayFactory: %u", GPOINTER_TO_UINT (l->data)); - } - - for (l = list; l != NULL; l = l->next) { - guint32 num; - num = GPOINTER_TO_UINT (l->data); - - /* always fill zero */ - if (l->prev == NULL && num != 0) { - ret = 0; - break; - } - /* now find the first hole */ - if (l->next == NULL || GPOINTER_TO_UINT (l->next->data) != (num + 1)) { - ret = num + 1; - break; - } - } - out: - - /* now reserve this number */ - g_debug ("GdmLocalDisplayFactory: Reserving X display: %u", ret); - g_hash_table_insert (factory->used_display_numbers, GUINT_TO_POINTER (ret), NULL); - - return ret; - } - -+static char * -+get_preferred_display_server (GdmLocalDisplayFactory *factory) -+{ -+ g_autofree gchar *preferred_display_server = NULL; -+ gboolean wayland_enabled = FALSE, xorg_enabled = FALSE; -+ -+ gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled); -+ gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled); -+ -+ if (wayland_enabled && !xorg_enabled) { -+ return g_strdup ("wayland"); -+ } -+ -+ if (!wayland_enabled && !xorg_enabled) { -+ return g_strdup ("none"); -+ } -+ -+ gdm_settings_direct_get_string (GDM_KEY_PREFERRED_DISPLAY_SERVER, &preferred_display_server); -+ -+ if (g_strcmp0 (preferred_display_server, "wayland") == 0) { -+ if (wayland_enabled) -+ return g_strdup (preferred_display_server); -+ else -+ return g_strdup ("xorg"); -+ } -+ -+ if (g_strcmp0 (preferred_display_server, "xorg") == 0) { -+ if (xorg_enabled) -+ return g_strdup (preferred_display_server); -+ else -+ return g_strdup ("wayland"); -+ } -+ -+ if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) { -+ if (xorg_enabled) -+ return g_strdup (preferred_display_server); -+ } -+ -+ return g_strdup ("none"); -+} -+ -+static const char * -+gdm_local_display_factory_get_session_type (GdmLocalDisplayFactory *factory, -+ gboolean should_fall_back) -+{ -+ const char *session_types[3] = { NULL }; -+ gsize i, session_type_index = 0, number_of_session_types = 0; -+ g_autofree gchar *preferred_display_server = NULL; -+ -+ preferred_display_server = get_preferred_display_server (factory); -+ -+ if (g_strcmp0 (preferred_display_server, "wayland") != 0 && -+ g_strcmp0 (preferred_display_server, "xorg") != 0) -+ return NULL; -+ -+ for (i = 0; i < G_N_ELEMENTS (session_types) - 1; i++) { -+#ifdef ENABLE_WAYLAND_SUPPORT -+ if (number_of_session_types > 0 || -+ g_strcmp0 (preferred_display_server, "wayland") == 0) { -+ gboolean wayland_enabled = FALSE; -+ if (gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled)) { -+ if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE) ) -+ session_types[number_of_session_types++] = "wayland"; -+ } -+ } -+#endif -+ -+ if (number_of_session_types > 0 || -+ g_strcmp0 (preferred_display_server, "xorg") == 0) { -+ gboolean xorg_enabled = FALSE; -+ if (gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled)) { -+ if (xorg_enabled && g_file_test ("/usr/bin/Xorg", G_FILE_TEST_IS_EXECUTABLE) ) -+ session_types[number_of_session_types++] = "x11"; -+ } -+ } -+ } -+ -+ if (should_fall_back) -+ session_type_index++; -+ -+ return session_types[session_type_index]; -+} -+ - static void - on_display_disposed (GdmLocalDisplayFactory *factory, - GdmDisplay *display) - { - g_debug ("GdmLocalDisplayFactory: Display %p disposed", display); - } - - static void - store_display (GdmLocalDisplayFactory *factory, - GdmDisplay *display) - { - GdmDisplayStore *store; - - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - gdm_display_store_add (store, display); - } - --static gboolean --gdm_local_display_factory_use_wayland (void) --{ --#ifdef ENABLE_WAYLAND_SUPPORT -- gboolean wayland_enabled = FALSE; -- if (gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled)) { -- if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE) ) -- return TRUE; -- } --#endif -- return FALSE; --} -- - /* - Example: - dbus-send --system --dest=org.gnome.DisplayManager \ - --type=method_call --print-reply --reply-timeout=2000 \ - /org/gnome/DisplayManager/Manager \ - org.gnome.DisplayManager.Manager.GetDisplays - */ - gboolean - gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *factory, - char **id, - GError **error) - { - gboolean ret; - GdmDisplay *display = NULL; - gboolean is_initial = FALSE; -+ const char *session_type; -+ g_autofree gchar *preferred_display_server = NULL; - - g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE); - - ret = FALSE; - - g_debug ("GdmLocalDisplayFactory: Creating transient display"); - --#ifdef ENABLE_USER_DISPLAY_SERVER -- display = gdm_local_display_new (); -- if (gdm_local_display_factory_use_wayland ()) -- g_object_set (G_OBJECT (display), "session-type", "wayland", NULL); -- is_initial = TRUE; --#else -- if (display == NULL) { -- guint32 num; -+ preferred_display_server = get_preferred_display_server (factory); - -- num = take_next_display_number (factory); -+#ifdef ENABLE_USER_DISPLAY_SERVER -+ if (g_strcmp0 (preferred_display_server, "wayland") == 0 || -+ g_strcmp0 (preferred_display_server, "xorg") == 0) { -+ session_type = gdm_local_display_factory_get_session_type (factory, FALSE); -+ -+ if (session_type == NULL) { -+ g_set_error_literal (error, -+ GDM_DISPLAY_ERROR, -+ GDM_DISPLAY_ERROR_GENERAL, -+ "Both Wayland and Xorg are unavailable"); -+ return FALSE; -+ } - -- display = gdm_legacy_display_new (num); -+ display = gdm_local_display_new (); -+ g_object_set (G_OBJECT (display), "session-type", session_type, NULL); -+ is_initial = TRUE; - } - #endif -+ if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) { -+ if (display == NULL) { -+ guint32 num; -+ -+ num = take_next_display_number (factory); -+ -+ display = gdm_legacy_display_new (num); -+ } -+ } -+ -+ if (display == NULL) { -+ g_set_error_literal (error, -+ GDM_DISPLAY_ERROR, -+ GDM_DISPLAY_ERROR_GENERAL, -+ "Invalid preferred display server configured"); -+ return FALSE; -+ } - - g_object_set (display, - "seat-id", "seat0", - "allow-timed-login", FALSE, - "is-initial", is_initial, - NULL); - - store_display (factory, display); - - if (! gdm_display_manage (display)) { - display = NULL; - goto out; - } - - if (! gdm_display_get_id (display, id, NULL)) { - display = NULL; - goto out; - } - - ret = TRUE; - out: - /* ref either held by store or not at all */ - g_object_unref (display); - - return ret; - } - - static void - finish_display_on_seat_if_waiting (GdmDisplayStore *display_store, - GdmDisplay *display, -@@ -454,190 +549,239 @@ lookup_prepared_display_by_seat_id (const char *id, - return lookup_by_seat_id (id, display, user_data); - } - - static int - on_seat0_graphics_check_timeout (gpointer user_data) - { - GdmLocalDisplayFactory *factory = user_data; - - factory->seat0_graphics_check_timeout_id = 0; - - /* Simply try to re-add seat0. If it is there already (i.e. CanGraphical - * turned TRUE, then we'll find it and it will not be created again). - */ - factory->seat0_graphics_check_timed_out = TRUE; - ensure_display_for_seat (factory, "seat0"); - - return G_SOURCE_REMOVE; - } - - static void - ensure_display_for_seat (GdmLocalDisplayFactory *factory, - const char *seat_id) - { - int ret; - gboolean seat_supports_graphics; - gboolean is_seat0; - const char *session_type = "wayland"; - GdmDisplayStore *store; - GdmDisplay *display = NULL; - g_autofree char *login_session_id = NULL; -+ gboolean wayland_enabled = FALSE, xorg_enabled = FALSE; -+ g_autofree gchar *preferred_display_server = NULL; -+ gboolean falling_back; -+ -+ gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled); -+ gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled); -+ -+ preferred_display_server = get_preferred_display_server (factory); -+ -+ if (g_strcmp0 (preferred_display_server, "none") == 0) { -+ g_debug ("GdmLocalDisplayFactory: Preferred display server is none, so not creating display"); -+ return; -+ } - - ret = sd_seat_can_graphical (seat_id); - - if (ret < 0) { - g_critical ("Failed to query CanGraphical information for seat %s", seat_id); - return; - } - - if (ret == 0) { - g_debug ("GdmLocalDisplayFactory: System doesn't currently support graphics"); - seat_supports_graphics = FALSE; - } else { - g_debug ("GdmLocalDisplayFactory: System supports graphics"); - seat_supports_graphics = TRUE; - } - - if (g_strcmp0 (seat_id, "seat0") == 0) { - is_seat0 = TRUE; - -- /* If we've failed, or are explicitly told to, fall back to legacy X11 support -- */ -- if (factory->num_failures > 0 || !gdm_local_display_factory_use_wayland ()) { -- session_type = NULL; -- g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use X11 fallback"); -- } else { -- g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use wayland"); -- } -+ falling_back = factory->num_failures > 0; -+ session_type = gdm_local_display_factory_get_session_type (factory, falling_back); -+ -+ g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use %s%s", -+ session_type, falling_back? " fallback" : ""); - } else { - is_seat0 = FALSE; - - g_debug ("GdmLocalDisplayFactory: New displays on seat %s will use X11 fallback", seat_id); - /* Force legacy X11 for all auxiliary seats */ - seat_supports_graphics = TRUE; -- session_type = NULL; -+ session_type = "x11"; - } - - /* For seat0, we have a fallback logic to still try starting it after - * SEAT0_GRAPHICS_CHECK_TIMEOUT seconds. i.e. we simply continue even if - * CanGraphical is unset. - * This is ugly, but it means we'll come up eventually in some - * scenarios where no master device is present. - * Note that we'll force an X11 fallback even though there might be - * cases where an wayland capable device is present and simply not marked as - * master-of-seat. In these cases, this should likely be fixed in the - * udev rules. - * - * At the moment, systemd always sets CanGraphical for non-seat0 seats. - * This is because non-seat0 seats are defined by having master-of-seat - * set. This means we can avoid the fallback check for non-seat0 seats, - * which simplifies the code. - */ - if (is_seat0) { - if (!seat_supports_graphics) { - if (!factory->seat0_graphics_check_timed_out) { - if (factory->seat0_graphics_check_timeout_id == 0) { - g_debug ("GdmLocalDisplayFactory: seat0 doesn't yet support graphics. Waiting %d seconds to try again.", SEAT0_GRAPHICS_CHECK_TIMEOUT); - factory->seat0_graphics_check_timeout_id = g_timeout_add_seconds (SEAT0_GRAPHICS_CHECK_TIMEOUT, - on_seat0_graphics_check_timeout, - factory); - - } else { - /* It is not yet time to force X11 fallback. */ - g_debug ("GdmLocalDisplayFactory: seat0 display requested when there is no graphics support before graphics check timeout."); - } - - return; - } - - g_debug ("GdmLocalDisplayFactory: Assuming we can use seat0 for X11 even though system says it doesn't support graphics!"); - g_debug ("GdmLocalDisplayFactory: This might indicate an issue where the framebuffer device is not tagged as master-of-seat in udev."); - seat_supports_graphics = TRUE; -- session_type = NULL; -+ session_type = "x11"; -+ wayland_enabled = FALSE; - } else { - g_clear_handle_id (&factory->seat0_graphics_check_timeout_id, g_source_remove); - } - } - - if (!seat_supports_graphics) - return; - -- g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested", -- session_type? : "X11", seat_id); -+ if (session_type != NULL) -+ g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested", -+ session_type, seat_id); -+ else if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) -+ g_debug ("GdmLocalDisplayFactory: Legacy Xorg login display for seat %s requested", -+ seat_id); -+ - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - - if (is_seat0) - display = gdm_display_store_find (store, lookup_prepared_display_by_seat_id, (gpointer) seat_id); - else - display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id); - - /* Ensure we don't create the same display more than once */ - if (display != NULL) { - g_debug ("GdmLocalDisplayFactory: display already created"); - return; - } - - /* If we already have a login window, switch to it */ - if (gdm_get_login_window_session_id (seat_id, &login_session_id)) { - GdmDisplay *display; - - display = gdm_display_store_find (store, - lookup_by_session_id, - (gpointer) login_session_id); - if (display != NULL && - (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED || - gdm_display_get_status (display) == GDM_DISPLAY_WAITING_TO_FINISH)) { - g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_MANAGED, NULL); - g_debug ("GdmLocalDisplayFactory: session %s found, activating.", - login_session_id); - gdm_activate_session_by_id (factory->connection, seat_id, login_session_id); - return; - } - } - - g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id); - - #ifdef ENABLE_USER_DISPLAY_SERVER -- if (is_seat0) { -- display = gdm_local_display_new (); -- if (session_type != NULL) { -+ if (g_strcmp0 (preferred_display_server, "wayland") == 0 || -+ g_strcmp0 (preferred_display_server, "xorg") == 0) { -+ if (is_seat0) { -+ g_autoptr (GPtrArray) supported_session_types = NULL; -+ -+ if (session_type == NULL) { -+ g_warning ("GdmLocalDisplayFactory: Both Wayland and Xorg sessions are unavailable"); -+ return; -+ } -+ -+ supported_session_types = g_ptr_array_new (); -+ -+ if (g_strcmp0 (preferred_display_server, "wayland") == 0) { -+ if (wayland_enabled) -+ g_ptr_array_add (supported_session_types, "wayland"); -+ } else { -+ if (xorg_enabled) -+ g_ptr_array_add (supported_session_types, "x11"); -+ } -+ -+ if (!falling_back) { -+ if (g_strcmp0 (preferred_display_server, "wayland") == 0) { -+ if (xorg_enabled) -+ g_ptr_array_add (supported_session_types, "x11"); -+ } else { -+ if (wayland_enabled) -+ g_ptr_array_add (supported_session_types, "wayland"); -+ } -+ } -+ -+ g_ptr_array_add (supported_session_types, NULL); -+ -+ display = gdm_local_display_new (); - g_object_set (G_OBJECT (display), "session-type", session_type, NULL); -+ g_object_set (G_OBJECT (display), "supported-session-types", supported_session_types->pdata, NULL); - } - } - #endif - - if (display == NULL) { - guint32 num; -+ const char *supported_session_types[] = { "x11", NULL }; - - num = take_next_display_number (factory); - - display = gdm_legacy_display_new (num); -+ g_object_set (G_OBJECT (display), "supported-session-types", supported_session_types, NULL); - } - - g_object_set (display, "seat-id", seat_id, NULL); - g_object_set (display, "is-initial", is_seat0, NULL); - - store_display (factory, display); - - /* let store own the ref */ - g_object_unref (display); - - if (! gdm_display_manage (display)) { - gdm_display_unmanage (display); - } - - return; - } - - static void - delete_display (GdmLocalDisplayFactory *factory, - const char *seat_id) { - - GdmDisplayStore *store; - - g_debug ("GdmLocalDisplayFactory: Removing used_display_numbers on seat %s", seat_id); - - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - gdm_display_store_foreach_remove (store, lookup_by_seat_id, (gpointer) seat_id); - } - - static gboolean -diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c -index 9c10adff..e433acf3 100644 ---- a/daemon/gdm-manager.c -+++ b/daemon/gdm-manager.c -@@ -2280,61 +2280,60 @@ on_session_reauthentication_started (GdmSession *session, - g_hash_table_steal (manager->priv->open_reauthentication_requests, - source_tag); - gdm_dbus_manager_complete_open_reauthentication_channel (GDM_DBUS_MANAGER (manager), - invocation, - address); - } - } - - static void - clean_user_session (GdmSession *session) - { - g_object_set_data (G_OBJECT (session), "gdm-display", NULL); - g_object_unref (session); - } - - static void - create_user_session_for_display (GdmManager *manager, - GdmDisplay *display, - uid_t allowed_user) - { - GdmSession *session; - gboolean display_is_local = FALSE; - char *display_name = NULL; - char *display_device = NULL; - char *remote_hostname = NULL; - char *display_auth_file = NULL; - char *display_seat_id = NULL; - char *display_id = NULL; - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - g_autofree char *display_session_type = NULL; -- gboolean greeter_is_wayland; - #endif - - g_object_get (G_OBJECT (display), - "id", &display_id, - "x11-display-name", &display_name, - "is-local", &display_is_local, - "remote-hostname", &remote_hostname, - "x11-authority-file", &display_auth_file, - "seat-id", &display_seat_id, - #if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) - "session-type", &display_session_type, - #endif - NULL); - display_device = get_display_device (manager, display); - - session = gdm_session_new (GDM_SESSION_VERIFICATION_MODE_LOGIN, - allowed_user, - display_name, - remote_hostname, - display_device, - display_seat_id, - display_auth_file, - display_is_local, - NULL); - - g_debug ("GdmSession: Created user session for user %d on display %s (seat %s)", - (int) allowed_user, - display_id, - display_seat_id); - -@@ -2378,65 +2377,60 @@ create_user_session_for_display (GdmManager *manager, - g_signal_connect (session, - "authentication-failed", - G_CALLBACK (on_session_authentication_failed), - manager); - g_signal_connect (session, - "session-opened", - G_CALLBACK (on_user_session_opened), - manager); - g_signal_connect (session, - "session-started", - G_CALLBACK (on_user_session_started), - manager); - g_signal_connect (session, - "session-start-failed", - G_CALLBACK (on_session_start_failed), - manager); - g_signal_connect (session, - "session-exited", - G_CALLBACK (on_user_session_exited), - manager); - g_signal_connect (session, - "session-died", - G_CALLBACK (on_user_session_died), - manager); - g_object_set_data (G_OBJECT (session), "gdm-display", display); - g_object_set_data_full (G_OBJECT (display), - "gdm-user-session", - session, - (GDestroyNotify) - clean_user_session); -- --#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER) -- greeter_is_wayland = g_strcmp0 (display_session_type, "wayland") == 0; -- g_object_set (G_OBJECT (session), "ignore-wayland", !greeter_is_wayland, NULL); --#endif - } - - static void - on_display_added (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_export (manager->priv->object_manager, - gdm_display_get_object_skeleton (display)); - - g_signal_connect (display, "notify::status", - G_CALLBACK (on_display_status_changed), - manager); - g_signal_emit (manager, signals[DISPLAY_ADDED], 0, id); - } - } - - GQuark - gdm_manager_error_quark (void) - { - static GQuark ret = 0; - if (ret == 0) { - ret = g_quark_from_static_string ("gdm_manager_error"); - } - -diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c -index 5c5903a4..6960a31c 100644 ---- a/daemon/gdm-session.c -+++ b/daemon/gdm-session.c -@@ -105,84 +105,81 @@ struct _GdmSession - GdmDBusUserVerifier *user_verifier_interface; - GHashTable *user_verifier_extensions; - GdmDBusGreeter *greeter_interface; - GdmDBusRemoteGreeter *remote_greeter_interface; - GdmDBusChooser *chooser_interface; - - GList *pending_worker_connections; - GList *outside_connections; - - GPid session_pid; - - /* object lifetime scope */ - char *session_type; - char *display_name; - char *display_hostname; - char *display_device; - char *display_seat_id; - char *display_x11_authority_file; - gboolean display_is_local; - - GdmSessionVerificationMode verification_mode; - - uid_t allowed_user; - - char *fallback_session_name; - - GDBusServer *worker_server; - GDBusServer *outside_server; - GHashTable *environment; - -+ GStrv supported_session_types; -+ - guint32 is_program_session : 1; - guint32 display_is_initial : 1; --#ifdef ENABLE_WAYLAND_SUPPORT -- guint32 ignore_wayland : 1; --#endif - }; - - enum { - PROP_0, - PROP_VERIFICATION_MODE, - PROP_ALLOWED_USER, - PROP_DISPLAY_NAME, - PROP_DISPLAY_HOSTNAME, - PROP_DISPLAY_IS_LOCAL, - PROP_DISPLAY_IS_INITIAL, - PROP_SESSION_TYPE, - PROP_DISPLAY_DEVICE, - PROP_DISPLAY_SEAT_ID, - PROP_DISPLAY_X11_AUTHORITY_FILE, - PROP_USER_X11_AUTHORITY_FILE, - PROP_CONVERSATION_ENVIRONMENT, --#ifdef ENABLE_WAYLAND_SUPPORT -- PROP_IGNORE_WAYLAND, --#endif -+ PROP_SUPPORTED_SESSION_TYPES, - }; - - enum { - CONVERSATION_STARTED = 0, - CONVERSATION_STOPPED, - SETUP_COMPLETE, - CANCELLED, - HOSTNAME_SELECTED, - CLIENT_REJECTED, - CLIENT_CONNECTED, - CLIENT_DISCONNECTED, - CLIENT_READY_FOR_SESSION_TO_START, - DISCONNECTED, - AUTHENTICATION_FAILED, - VERIFICATION_COMPLETE, - SESSION_OPENED, - SESSION_STARTED, - SESSION_START_FAILED, - SESSION_EXITED, - SESSION_DIED, - REAUTHENTICATION_STARTED, - REAUTHENTICATED, - LAST_SIGNAL - }; - - #ifdef ENABLE_WAYLAND_SUPPORT - static gboolean gdm_session_is_wayland_session (GdmSession *self); - #endif - static void update_session_type (GdmSession *self); - static void set_session_type (GdmSession *self, -@@ -318,105 +315,113 @@ 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->user_verifier_interface != NULL) { - gdm_dbus_user_verifier_emit_verification_complete (self->user_verifier_interface, - service_name); - g_signal_emit (self, signals[VERIFICATION_COMPLETE], 0, service_name); - } - - switch (self->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 gboolean -+supports_session_type (GdmSession *self, -+ const char *session_type) -+{ -+ if (session_type == NULL) -+ return TRUE; -+ -+ return g_strv_contains ((const char * const *) self->supported_session_types, -+ session_type); -+} -+ - static char ** - get_system_session_dirs (GdmSession *self) - { - GArray *search_array = NULL; - char **search_dirs; -- int i; -+ int i, j; - const gchar * const *system_data_dirs = g_get_system_data_dirs (); - - static const char *x_search_dirs[] = { - "/etc/X11/sessions/", - DMCONFDIR "/Sessions/", - DATADIR "/gdm/BuiltInSessions/", - DATADIR "/xsessions/", - }; - - static const char *wayland_search_dir = DATADIR "/wayland-sessions/"; - - search_array = g_array_new (TRUE, TRUE, sizeof (char *)); - -- 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); -- } -+ for (j = 0; self->supported_session_types[j] != NULL; j++) { -+ const char *supported_type = self->supported_session_types[j]; - -- g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs)); -+ if (g_str_equal (supported_type, "x11")) { -+ 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); -+ } -+ -+ g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs)); -+ } - - #ifdef ENABLE_WAYLAND_SUPPORT -- if (!self->ignore_wayland) { --#ifdef ENABLE_USER_DISPLAY_SERVER -- g_array_prepend_val (search_array, wayland_search_dir); -+ if (g_str_equal (supported_type, "wayland")) { -+ g_array_append_val (search_array, wayland_search_dir); - -- for (i = 0; system_data_dirs[i]; i++) { -- gchar *dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL); -- g_array_insert_val (search_array, i, dir); -- } --#else -- 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); -+ 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 - } --#endif - - 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; - -@@ -2197,68 +2202,72 @@ close_conversation (GdmSessionConversation *conversation) - - if (conversation->worker_manager_interface != NULL) { - unexport_worker_manager_interface (self, conversation->worker_manager_interface); - g_clear_object (&conversation->worker_manager_interface); - } - - if (conversation->worker_proxy != NULL) { - GDBusConnection *connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (conversation->worker_proxy)); - g_dbus_connection_close_sync (connection, NULL, NULL); - } - } - - static void - stop_conversation (GdmSessionConversation *conversation) - { - close_conversation (conversation); - - conversation->is_stopping = TRUE; - gdm_session_worker_job_stop (conversation->job); - } - - static void - stop_conversation_now (GdmSessionConversation *conversation) - { - close_conversation (conversation); - - gdm_session_worker_job_stop_now (conversation->job); - g_clear_object (&conversation->job); - } - --#ifdef ENABLE_WAYLAND_SUPPORT - void --gdm_session_set_ignore_wayland (GdmSession *self, -- gboolean ignore_wayland) -+gdm_session_set_supported_session_types (GdmSession *self, -+ const char * const *supported_session_types) - { -- self->ignore_wayland = ignore_wayland; -+ const char * const session_types[] = { "wayland", "x11", NULL }; -+ g_strfreev (self->supported_session_types); -+ -+ if (supported_session_types == NULL) -+ self->supported_session_types = g_strdupv ((GStrv) session_types); -+ else -+ self->supported_session_types = g_strdupv ((GStrv) supported_session_types); - } --#endif - - gboolean - gdm_session_start_conversation (GdmSession *self, - const char *service_name) - { - GdmSessionConversation *conversation; - - g_return_val_if_fail (GDM_IS_SESSION (self), FALSE); - - conversation = g_hash_table_lookup (self->conversations, - service_name); - - if (conversation != NULL) { - if (!conversation->is_stopping) { - g_warning ("GdmSession: conversation %s started more than once", service_name); - return FALSE; - } - g_debug ("GdmSession: stopping old conversation %s", service_name); - gdm_session_worker_job_stop_now (conversation->job); - g_object_unref (conversation->job); - conversation->job = NULL; - } - - g_debug ("GdmSession: starting conversation %s for session (%p)", service_name, self); - - conversation = start_conversation (self, service_name); - - g_hash_table_insert (self->conversations, - g_strdup (service_name), conversation); - return TRUE; -@@ -3137,65 +3146,67 @@ gdm_session_get_conversation_session_id (GdmSession *self, - - conversation = find_conversation_by_name (self, service_name); - - if (conversation == NULL) { - return NULL; - } - - return conversation->session_id; - } - - static char * - get_session_filename (GdmSession *self) - { - return g_strdup_printf ("%s.desktop", get_session_name (self)); - } - - #ifdef ENABLE_WAYLAND_SUPPORT - static gboolean - gdm_session_is_wayland_session (GdmSession *self) - { - GKeyFile *key_file; - gboolean is_wayland_session = FALSE; - char *filename; - char *full_path = NULL; - - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (GDM_IS_SESSION (self), FALSE); - - filename = get_session_filename (self); - -- key_file = load_key_file_for_file (self, filename, &full_path); -+ if (supports_session_type (self, "wayland")) { -+ key_file = load_key_file_for_file (self, filename, &full_path); - -- if (key_file == NULL) { -- goto out; -- } -+ if (key_file == NULL) { -+ goto out; -+ } -+ } - - if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) { - is_wayland_session = TRUE; - } - g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no"); - - out: - g_clear_pointer (&key_file, g_key_file_free); - g_free (filename); - return is_wayland_session; - } - #endif - - static void - update_session_type (GdmSession *self) - { - #ifdef ENABLE_WAYLAND_SUPPORT - gboolean is_wayland_session; - - is_wayland_session = gdm_session_is_wayland_session (self); - if (is_wayland_session) { - set_session_type (self, "wayland"); - } else { - set_session_type (self, NULL); - } - #endif - } - - gboolean - gdm_session_session_registers (GdmSession *self) -@@ -3479,140 +3490,138 @@ gdm_session_set_property (GObject *object, - case PROP_DISPLAY_HOSTNAME: - set_display_hostname (self, g_value_get_string (value)); - break; - case PROP_DISPLAY_DEVICE: - set_display_device (self, g_value_get_string (value)); - break; - case PROP_DISPLAY_SEAT_ID: - set_display_seat_id (self, g_value_get_string (value)); - break; - case PROP_USER_X11_AUTHORITY_FILE: - set_user_x11_authority_file (self, g_value_get_string (value)); - break; - case PROP_DISPLAY_X11_AUTHORITY_FILE: - set_display_x11_authority_file (self, g_value_get_string (value)); - break; - case PROP_DISPLAY_IS_LOCAL: - set_display_is_local (self, g_value_get_boolean (value)); - break; - case PROP_DISPLAY_IS_INITIAL: - set_display_is_initial (self, g_value_get_boolean (value)); - break; - case PROP_VERIFICATION_MODE: - set_verification_mode (self, g_value_get_enum (value)); - break; - case PROP_ALLOWED_USER: - set_allowed_user (self, g_value_get_uint (value)); - break; - case PROP_CONVERSATION_ENVIRONMENT: - set_conversation_environment (self, g_value_get_pointer (value)); - break; --#ifdef ENABLE_WAYLAND_SUPPORT -- case PROP_IGNORE_WAYLAND: -- gdm_session_set_ignore_wayland (self, g_value_get_boolean (value)); -+ case PROP_SUPPORTED_SESSION_TYPES: -+ gdm_session_set_supported_session_types (self, g_value_get_boxed (value)); - break; --#endif - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } - - static void - gdm_session_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) - { - GdmSession *self; - - self = GDM_SESSION (object); - - switch (prop_id) { - case PROP_SESSION_TYPE: - g_value_set_string (value, self->session_type); - break; - case PROP_DISPLAY_NAME: - g_value_set_string (value, self->display_name); - break; - case PROP_DISPLAY_HOSTNAME: - g_value_set_string (value, self->display_hostname); - break; - case PROP_DISPLAY_DEVICE: - g_value_set_string (value, self->display_device); - break; - case PROP_DISPLAY_SEAT_ID: - g_value_set_string (value, self->display_seat_id); - break; - case PROP_USER_X11_AUTHORITY_FILE: - g_value_set_string (value, self->user_x11_authority_file); - break; - case PROP_DISPLAY_X11_AUTHORITY_FILE: - g_value_set_string (value, self->display_x11_authority_file); - break; - case PROP_DISPLAY_IS_LOCAL: - g_value_set_boolean (value, self->display_is_local); - break; - case PROP_DISPLAY_IS_INITIAL: - g_value_set_boolean (value, self->display_is_initial); - break; - case PROP_VERIFICATION_MODE: - g_value_set_enum (value, self->verification_mode); - break; - case PROP_ALLOWED_USER: - g_value_set_uint (value, self->allowed_user); - break; - case PROP_CONVERSATION_ENVIRONMENT: - g_value_set_pointer (value, self->environment); - break; --#ifdef ENABLE_WAYLAND_SUPPORT -- case PROP_IGNORE_WAYLAND: -- g_value_set_boolean (value, self->ignore_wayland); -+ case PROP_SUPPORTED_SESSION_TYPES: -+ g_value_set_boxed (value, self->supported_session_types); - break; --#endif - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } - } - - static void - gdm_session_dispose (GObject *object) - { - GdmSession *self; - - self = GDM_SESSION (object); - - g_debug ("GdmSession: Disposing session"); - - gdm_session_close (self); - -+ g_clear_pointer (&self->supported_session_types, -+ g_strfreev); - g_clear_pointer (&self->conversations, - g_hash_table_unref); - - g_clear_object (&self->user_verifier_interface); - g_clear_pointer (&self->user_verifier_extensions, - g_hash_table_unref); - g_clear_object (&self->greeter_interface); - g_clear_object (&self->remote_greeter_interface); - g_clear_object (&self->chooser_interface); - - g_free (self->display_name); - self->display_name = NULL; - - g_free (self->display_hostname); - self->display_hostname = NULL; - - g_free (self->display_device); - self->display_device = NULL; - - g_free (self->display_seat_id); - self->display_seat_id = NULL; - - g_free (self->display_x11_authority_file); - self->display_x11_authority_file = NULL; - - g_strfreev (self->conversation_environment); - self->conversation_environment = NULL; - - if (self->worker_server != NULL) { - g_dbus_server_stop (self->worker_server); -@@ -3962,69 +3971,67 @@ gdm_session_class_init (GdmSessionClass *session_class) - PROP_DISPLAY_X11_AUTHORITY_FILE, - g_param_spec_string ("display-x11-authority-file", - "display x11 authority file", - "display x11 authority file", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); - /* not construct only */ - g_object_class_install_property (object_class, - PROP_USER_X11_AUTHORITY_FILE, - g_param_spec_string ("user-x11-authority-file", - "", - "", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - g_object_class_install_property (object_class, - PROP_DISPLAY_DEVICE, - g_param_spec_string ("display-device", - "display device", - "display device", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (object_class, - PROP_DISPLAY_SEAT_ID, - g_param_spec_string ("display-seat-id", - "display seat id", - "display seat id", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - --#ifdef ENABLE_WAYLAND_SUPPORT - g_object_class_install_property (object_class, -- PROP_IGNORE_WAYLAND, -- g_param_spec_boolean ("ignore-wayland", -- "ignore wayland", -- "ignore wayland", -- FALSE, -- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); --#endif -+ PROP_SUPPORTED_SESSION_TYPES, -+ g_param_spec_boxed ("supported-session-types", -+ "supported session types", -+ "supported session types", -+ G_TYPE_STRV, -+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); - - /* Ensure we can resolve errors */ - gdm_dbus_error_ensure (GDM_SESSION_WORKER_ERROR); - } - - GdmSession * - gdm_session_new (GdmSessionVerificationMode verification_mode, - uid_t allowed_user, - const char *display_name, - const char *display_hostname, - const char *display_device, - const char *display_seat_id, - const char *display_x11_authority_file, - gboolean display_is_local, - const char * const *environment) - { - GdmSession *self; - - self = g_object_new (GDM_TYPE_SESSION, - "verification-mode", verification_mode, - "allowed-user", (guint) allowed_user, - "display-name", display_name, - "display-hostname", display_hostname, - "display-device", display_device, - "display-seat-id", display_seat_id, - "display-x11-authority-file", display_x11_authority_file, - "display-is-local", display_is_local, - "conversation-environment", environment, - NULL); - -diff --git a/data/gdm.schemas.in b/data/gdm.schemas.in -index 255bff02..a1035f95 100644 ---- a/data/gdm.schemas.in -+++ b/data/gdm.schemas.in -@@ -25,65 +25,75 @@ - - daemon/AutomaticLoginEnable - b - false - - - daemon/AutomaticLogin - s - - - - daemon/TimedLoginEnable - b - false - - - daemon/TimedLogin - s - - - - daemon/TimedLoginDelay - i - 30 - - - daemon/InitialSetupEnable - b - true - -+ -+ daemon/PreferredDisplayServer -+ s -+ wayland -+ - - daemon/WaylandEnable - b - true - -+ -+ daemon/XorgEnable -+ b -+ true -+ - - security/AllowRemoteAutoLogin - b - false - - - - debug/Enable - b - false - - - - security/DisallowTCP - b - true - - - xdmcp/Enable - b - false - - - xdmcp/ShowLocalGreeter - b - true - - - xdmcp/MaxPending - i -diff --git a/libgdm/gdm-sessions.c b/libgdm/gdm-sessions.c -index 75d442ee..97ed5ef3 100644 ---- a/libgdm/gdm-sessions.c -+++ b/libgdm/gdm-sessions.c -@@ -163,171 +163,203 @@ load_session_file (const char *id, - - static gboolean - remove_duplicate_sessions (gpointer key, - gpointer value, - gpointer user_data) - { - gboolean already_known; - GHashTable *names_seen_before; - GdmSessionFile *session; - - names_seen_before = (GHashTable *) user_data; - session = (GdmSessionFile *) value; - already_known = !g_hash_table_add (names_seen_before, session->translated_name); - - if (already_known) - g_debug ("GdmSession: Removing %s (%s) as we already have a session by this name", - session->id, - session->path); - - return already_known; - } - - static void - collect_sessions_from_directory (const char *dirname) - { - GDir *dir; - const char *filename; - - gboolean is_x11 = g_getenv ("WAYLAND_DISPLAY") == NULL && - g_getenv ("RUNNING_UNDER_GDM") != NULL; -+ gboolean is_wayland = g_getenv ("WAYLAND_DISPLAY") != NULL && -+ g_getenv ("RUNNING_UNDER_GDM") != NULL; - - /* FIXME: add file monitor to directory */ - - dir = g_dir_open (dirname, 0, NULL); - if (dir == NULL) { - return; - } - - while ((filename = g_dir_read_name (dir))) { - char *id; - char *full_path; - - if (! g_str_has_suffix (filename, ".desktop")) { - continue; - } - -- if (is_x11 && g_str_has_suffix (filename, "-xorg.desktop")) { -- char *base_name = g_strndup (filename, strlen (filename) - strlen ("-xorg.desktop")); -- char *fallback_name = g_strconcat (base_name, ".desktop", NULL); -- g_free (base_name); -- char *fallback_path = g_build_filename (dirname, fallback_name, NULL); -- g_free (fallback_name); -- if (g_file_test (fallback_path, G_FILE_TEST_EXISTS)) { -- g_free (fallback_path); -- g_debug ("Running under X11, ignoring %s", filename); -- continue; -+ if (is_wayland) { -+ if (g_str_has_suffix (filename, "-wayland.desktop")) { -+ g_autofree char *base_name = g_strndup (filename, strlen (filename) - strlen ("-wayland.desktop")); -+ g_autofree char *other_name = g_strconcat (base_name, ".desktop", NULL); -+ g_autofree char *other_path = g_build_filename (dirname, other_name, NULL); -+ -+ if (g_file_test (other_path, G_FILE_TEST_EXISTS)) { -+ g_debug ("Running under Wayland, ignoring %s", filename); -+ continue; -+ } -+ } else { -+ g_autofree char *base_name = g_strndup (filename, strlen (filename) - strlen (".desktop")); -+ g_autofree char *other_name = g_strdup_printf ("%s-xorg.desktop", base_name); -+ g_autofree char *other_path = g_build_filename (dirname, other_name, NULL); -+ -+ if (g_file_test (other_path, G_FILE_TEST_EXISTS)) { -+ g_debug ("Running under Wayland, ignoring %s", filename); -+ continue; -+ } -+ } -+ } else if (is_x11) { -+ if (g_str_has_suffix (filename, "-xorg.desktop")) { -+ g_autofree char *base_name = g_strndup (filename, strlen (filename) - strlen ("-xorg.desktop")); -+ g_autofree char *other_name = g_strconcat (base_name, ".desktop", NULL); -+ g_autofree char *other_path = g_build_filename (dirname, other_name, NULL); -+ -+ if (g_file_test (other_path, G_FILE_TEST_EXISTS)) { -+ g_debug ("Running under X11, ignoring %s", filename); -+ continue; -+ } -+ } else { -+ g_autofree char *base_name = g_strndup (filename, strlen (filename) - strlen (".desktop")); -+ g_autofree char *other_name = g_strdup_printf ("%s-wayland.desktop", base_name); -+ g_autofree char *other_path = g_build_filename (dirname, other_name, NULL); -+ -+ if (g_file_test (other_path, G_FILE_TEST_EXISTS)) { -+ g_debug ("Running under X11, ignoring %s", filename); -+ continue; -+ } - } -- g_free (fallback_path); - } - - id = g_strndup (filename, strlen (filename) - strlen (".desktop")); - - full_path = g_build_filename (dirname, filename, NULL); - - load_session_file (id, full_path); - - g_free (id); - g_free (full_path); - } - - g_dir_close (dir); - } - - static void - collect_sessions (void) - { - g_autoptr(GHashTable) names_seen_before = NULL; - g_autoptr(GPtrArray) xorg_search_array = NULL; - g_autoptr(GPtrArray) wayland_search_array = NULL; - gchar *session_dir = NULL; - int i; - const char *xorg_search_dirs[] = { - "/etc/X11/sessions/", - DMCONFDIR "/Sessions/", - DATADIR "/gdm/BuiltInSessions/", - DATADIR "/xsessions/", - }; -+ g_auto (GStrv) supported_session_types = NULL; -+ -+ supported_session_types = g_strsplit (g_getenv ("GDM_SUPPORTED_SESSION_TYPES"), ":", -1); - - names_seen_before = g_hash_table_new (g_str_hash, g_str_equal); - xorg_search_array = g_ptr_array_new_with_free_func (g_free); - - const gchar * const *system_data_dirs = g_get_system_data_dirs (); - - for (i = 0; system_data_dirs[i]; i++) { - session_dir = g_build_filename (system_data_dirs[i], "xsessions", NULL); - g_ptr_array_add (xorg_search_array, session_dir); - } - - for (i = 0; i < G_N_ELEMENTS (xorg_search_dirs); i++) { - g_ptr_array_add (xorg_search_array, g_strdup (xorg_search_dirs[i])); - } - - #ifdef ENABLE_WAYLAND_SUPPORT - const char *wayland_search_dirs[] = { - DATADIR "/wayland-sessions/", - }; - - wayland_search_array = g_ptr_array_new_with_free_func (g_free); - - for (i = 0; system_data_dirs[i]; i++) { - session_dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL); - g_ptr_array_add (wayland_search_array, session_dir); - } - - for (i = 0; i < G_N_ELEMENTS (wayland_search_dirs); i++) { - g_ptr_array_add (wayland_search_array, g_strdup (wayland_search_dirs[i])); - } - #endif - - if (gdm_available_sessions_map == NULL) { - gdm_available_sessions_map = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify)gdm_session_file_free); - } - -- for (i = 0; i < xorg_search_array->len; i++) { -- collect_sessions_from_directory (g_ptr_array_index (xorg_search_array, i)); -+ if (!supported_session_types || g_strv_contains ((const char * const *) supported_session_types, "x11")) { -+ for (i = 0; i < xorg_search_array->len; i++) { -+ collect_sessions_from_directory (g_ptr_array_index (xorg_search_array, i)); -+ } - } - - #ifdef ENABLE_WAYLAND_SUPPORT - #ifdef ENABLE_USER_DISPLAY_SERVER -- if (g_getenv ("WAYLAND_DISPLAY") == NULL && g_getenv ("RUNNING_UNDER_GDM") != NULL) { -- goto out; -+ if (!supported_session_types || g_strv_contains ((const char * const *) supported_session_types, "wayland")) { -+ for (i = 0; i < wayland_search_array->len; i++) { -+ collect_sessions_from_directory (g_ptr_array_index (wayland_search_array, i)); -+ } - } - #endif -- -- for (i = 0; i < wayland_search_array->len; i++) { -- collect_sessions_from_directory (g_ptr_array_index (wayland_search_array, i)); -- } - #endif - --out: - g_hash_table_foreach_remove (gdm_available_sessions_map, - remove_duplicate_sessions, - names_seen_before); - } - - /** - * gdm_get_session_ids: - * - * Reads /usr/share/xsessions and other relevant places for possible sessions - * to log into and returns the complete list. - * - * Returns: (transfer full): a %NULL terminated list of session ids - */ - char ** - gdm_get_session_ids (void) - { - GHashTableIter iter; - gpointer key, value; - GPtrArray *array; - - if (!gdm_sessions_map_is_initialized) { - collect_sessions (); - - gdm_sessions_map_is_initialized = TRUE; - } - - array = g_ptr_array_new (); - g_hash_table_iter_init (&iter, gdm_available_sessions_map); - while (g_hash_table_iter_next (&iter, &key, &value)) { - GdmSessionFile *session; --- -2.32.0 - diff --git a/0002-libgdm-Sort-session-list.patch b/0002-libgdm-Sort-session-list.patch deleted file mode 100644 index e4f35ff..0000000 --- a/0002-libgdm-Sort-session-list.patch +++ /dev/null @@ -1,131 +0,0 @@ -From b8adb4f610ab285d1c0b9e7bd4d0e2dc64f3e821 Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Tue, 20 Jul 2021 13:36:45 -0400 -Subject: [PATCH 2/3] libgdm: Sort session list - -Right now the session list comes out in hash table order. - -This commit changes the code to sort by description. ---- - libgdm/gdm-sessions.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/libgdm/gdm-sessions.c b/libgdm/gdm-sessions.c -index 97ed5ef3..f078e04b 100644 ---- a/libgdm/gdm-sessions.c -+++ b/libgdm/gdm-sessions.c -@@ -311,92 +311,111 @@ collect_sessions (void) - g_ptr_array_add (wayland_search_array, g_strdup (wayland_search_dirs[i])); - } - #endif - - if (gdm_available_sessions_map == NULL) { - gdm_available_sessions_map = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify)gdm_session_file_free); - } - - if (!supported_session_types || g_strv_contains ((const char * const *) supported_session_types, "x11")) { - for (i = 0; i < xorg_search_array->len; i++) { - collect_sessions_from_directory (g_ptr_array_index (xorg_search_array, i)); - } - } - - #ifdef ENABLE_WAYLAND_SUPPORT - #ifdef ENABLE_USER_DISPLAY_SERVER - if (!supported_session_types || g_strv_contains ((const char * const *) supported_session_types, "wayland")) { - for (i = 0; i < wayland_search_array->len; i++) { - collect_sessions_from_directory (g_ptr_array_index (wayland_search_array, i)); - } - } - #endif - #endif - - g_hash_table_foreach_remove (gdm_available_sessions_map, - remove_duplicate_sessions, - names_seen_before); - } - -+static gint -+compare_session_ids (gconstpointer a, -+ gconstpointer b) -+{ -+ GdmSessionFile *session_a, *session_b; -+ session_a = (GdmSessionFile *) g_hash_table_lookup (gdm_available_sessions_map, a); -+ session_b = (GdmSessionFile *) g_hash_table_lookup (gdm_available_sessions_map, b); -+ -+ if (session_a == NULL) -+ return -1; -+ -+ if (session_b == NULL) -+ return 1; -+ -+ return g_strcmp0 (session_a->translated_name, session_b->translated_name); -+} -+ - /** - * gdm_get_session_ids: - * - * Reads /usr/share/xsessions and other relevant places for possible sessions - * to log into and returns the complete list. - * - * Returns: (transfer full): a %NULL terminated list of session ids - */ - char ** - gdm_get_session_ids (void) - { - GHashTableIter iter; - gpointer key, value; - GPtrArray *array; - - if (!gdm_sessions_map_is_initialized) { - collect_sessions (); - - gdm_sessions_map_is_initialized = TRUE; - } - - array = g_ptr_array_new (); - g_hash_table_iter_init (&iter, gdm_available_sessions_map); - while (g_hash_table_iter_next (&iter, &key, &value)) { - GdmSessionFile *session; - - session = (GdmSessionFile *) value; - - g_ptr_array_add (array, g_strdup (session->id)); - } - g_ptr_array_add (array, NULL); - -+ g_ptr_array_sort (array, compare_session_ids); -+ - return (char **) g_ptr_array_free (array, FALSE); - } - - /** - * gdm_get_session_name_and_description: - * @id: an id from gdm_get_session_ids() - * @description: (out): optional returned session description - * - * Takes an xsession id and returns the name and comment about it. - * - * Returns: The session name if found, or %NULL otherwise - */ - char * - gdm_get_session_name_and_description (const char *id, - char **description) - { - GdmSessionFile *session; - char *name; - - if (!gdm_sessions_map_is_initialized) { - collect_sessions (); - - gdm_sessions_map_is_initialized = TRUE; - } - - session = (GdmSessionFile *) g_hash_table_lookup (gdm_available_sessions_map, - id); - - if (session == NULL) { - return NULL; --- -2.32.0 - diff --git a/0003-local-display-factory-Fix-overrun-in-session-type-li.patch b/0003-local-display-factory-Fix-overrun-in-session-type-li.patch deleted file mode 100644 index b60d440..0000000 --- a/0003-local-display-factory-Fix-overrun-in-session-type-li.patch +++ /dev/null @@ -1,118 +0,0 @@ -From f067fb9bc471f176b6f6693fd9da5307c35bac3c Mon Sep 17 00:00:00 2001 -From: Ray Strode -Date: Thu, 22 Jul 2021 14:46:50 -0400 -Subject: [PATCH 3/3] local-display-factory: Fix overrun in session type list - generation - -Some confusion in the session type list generation from GNOME/gdm!146, -means we could actually overrun the list. - -This commit fixes that. ---- - daemon/gdm-local-display-factory.c | 16 +++++++++------- - 1 file changed, 9 insertions(+), 7 deletions(-) - -diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c -index 0bb3851f..f2da3b6e 100644 ---- a/daemon/gdm-local-display-factory.c -+++ b/daemon/gdm-local-display-factory.c -@@ -202,87 +202,89 @@ get_preferred_display_server (GdmLocalDisplayFactory *factory) - - gdm_settings_direct_get_string (GDM_KEY_PREFERRED_DISPLAY_SERVER, &preferred_display_server); - - if (g_strcmp0 (preferred_display_server, "wayland") == 0) { - if (wayland_enabled) - return g_strdup (preferred_display_server); - else - return g_strdup ("xorg"); - } - - if (g_strcmp0 (preferred_display_server, "xorg") == 0) { - if (xorg_enabled) - return g_strdup (preferred_display_server); - else - return g_strdup ("wayland"); - } - - if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) { - if (xorg_enabled) - return g_strdup (preferred_display_server); - } - - return g_strdup ("none"); - } - - static const char * - gdm_local_display_factory_get_session_type (GdmLocalDisplayFactory *factory, - gboolean should_fall_back) - { - const char *session_types[3] = { NULL }; -- gsize i, session_type_index = 0, number_of_session_types = 0; -+ gsize i, session_type_index = 0; - g_autofree gchar *preferred_display_server = NULL; - - preferred_display_server = get_preferred_display_server (factory); - - if (g_strcmp0 (preferred_display_server, "wayland") != 0 && - g_strcmp0 (preferred_display_server, "xorg") != 0) - return NULL; - - for (i = 0; i < G_N_ELEMENTS (session_types) - 1; i++) { - #ifdef ENABLE_WAYLAND_SUPPORT -- if (number_of_session_types > 0 || -+ if (i > 0 || - g_strcmp0 (preferred_display_server, "wayland") == 0) { - gboolean wayland_enabled = FALSE; - if (gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled)) { -- if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE) ) -- session_types[number_of_session_types++] = "wayland"; -+ if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE)) { -+ session_types[i] = "wayland"; continue; -+ } - } - } - #endif - -- if (number_of_session_types > 0 || -+ if (i > 0 || - g_strcmp0 (preferred_display_server, "xorg") == 0) { - gboolean xorg_enabled = FALSE; - if (gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled)) { -- if (xorg_enabled && g_file_test ("/usr/bin/Xorg", G_FILE_TEST_IS_EXECUTABLE) ) -- session_types[number_of_session_types++] = "x11"; -+ if (xorg_enabled && g_file_test ("/usr/bin/Xorg", G_FILE_TEST_IS_EXECUTABLE)) { -+ session_types[i] = "x11"; continue; -+ } - } - } - } - - if (should_fall_back) - session_type_index++; - - return session_types[session_type_index]; - } - - static void - on_display_disposed (GdmLocalDisplayFactory *factory, - GdmDisplay *display) - { - g_debug ("GdmLocalDisplayFactory: Display %p disposed", display); - } - - static void - store_display (GdmLocalDisplayFactory *factory, - GdmDisplay *display) - { - GdmDisplayStore *store; - - store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory)); - gdm_display_store_add (store, display); - } - - /* - Example: - dbus-send --system --dest=org.gnome.DisplayManager \ --- -2.32.0 - diff --git a/gdm.spec b/gdm.spec index 6cb524b..7b1e0a4 100644 --- a/gdm.spec +++ b/gdm.spec @@ -10,8 +10,8 @@ Name: gdm Epoch: 1 -Version: 40.0 -Release: 6%{?dist} +Version: 41~alpha +Release: 1%{?dist} Summary: The GNOME Display Manager License: GPLv2+ @@ -22,11 +22,6 @@ Source1: org.gnome.login-screen.gschema.override # moved here from pulseaudio-gdm-hooks-11.1-16 Source5: default.pa-for-gdm -# Already upstream, waiting on a release -Patch10001: 0001-daemon-Provide-more-flexibility-for-configuring-disp.patch -Patch10002: 0002-libgdm-Sort-session-list.patch -Patch10003: 0003-local-display-factory-Fix-overrun-in-session-type-li.patch - # Downstream patches Patch80001: 0001-Honor-initial-setup-being-disabled-by-distro-install.patch Patch90001: 0001-data-add-system-dconf-databases-to-gdm-profile.patch @@ -307,6 +302,9 @@ fi %{_libdir}/pkgconfig/gdm-pam-extensions.pc %changelog +* Wed Jul 28 2021 Ray Strode - 1:41~alpha-1 +- Update to 41.alpha + * Tue Jul 27 2021 Ray Strode - 1:40.0-6 - Correct logic error leading to wrong display server preference getting chosen. diff --git a/sources b/sources index 915634a..62b670d 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (gdm-40.0.tar.xz) = b20d02f8a80f6aff8909a69c6c621c20c5aa1b25cfedd68bf95faaaa56d5f7cd5d607d1a7388b97aa06510684f1e9e474248042a00203f496c39930e001bb64c +SHA512 (gdm-41.alpha.tar.xz) = a84f5a7cc27d1de8706f2b10ca290e5b636c0edf8e6ccadb99f5665dfe176b6c50aad1ac6600843390d91eab91d139de503d33f97229c3e1d1385f398323d707