Blame SOURCES/0001-local-display-factory-Provide-more-flexibility-for-c.patch

4e44f9
From a8f8a5ee422d6ae3d87c1fba351313a5d98ded6e Mon Sep 17 00:00:00 2001
4e44f9
From: Ray Strode <rstrode@redhat.com>
4e44f9
Date: Fri, 16 Jul 2021 12:34:57 -0400
4e44f9
Subject: [PATCH] local-display-factory: Provide more flexibility for
4e44f9
 configuring display server
4e44f9
4e44f9
There's currently a way to disable wayland, but no way to disable Xorg.
4e44f9
We currently prefer wayland if it's not disabled, but have no way to
4e44f9
prefer Xorg without disabling wayland entirely.
4e44f9
4e44f9
There's currently no way use legacy Xorg support at all if user display
4e44f9
server support is enabled at a build time.
4e44f9
4e44f9
This commit adds more flexibility to display server selection. It adds
4e44f9
two new keys: XorgEnable and and PreferredDisplayServer.
4e44f9
4e44f9
XorgEnable=false disables Xorg support entirely on seat 0.
4e44f9
4e44f9
PreferredDisplayServer can be set to "wayland", "xorg", "legacy-xorg" or
4e44f9
"none" to select which display server is used by default. If it's set to
4e44f9
"wayland", it will fall back to "xorg". If it's set to "xorg" it will
4e44f9
fall back to "wayland".
4e44f9
---
4e44f9
 common/gdm-settings-keys.h         |   2 +
4e44f9
 daemon/gdm-display.c               |  36 +++++
4e44f9
 daemon/gdm-launch-environment.c    |   9 ++
4e44f9
 daemon/gdm-local-display-factory.c | 224 ++++++++++++++++++++++++-----
4e44f9
 daemon/gdm-manager.c               |  22 ++-
4e44f9
 daemon/gdm-session.c               | 115 ++++++++-------
4e44f9
 data/gdm.schemas.in                |  10 ++
4e44f9
 libgdm/gdm-sessions.c              |  72 +++++++---
4e44f9
 8 files changed, 366 insertions(+), 124 deletions(-)
4e44f9
4e44f9
diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h
4e44f9
index f0059b5cf..87685d3cd 100644
4e44f9
--- a/common/gdm-settings-keys.h
4e44f9
+++ b/common/gdm-settings-keys.h
4e44f9
@@ -6,59 +6,61 @@
4e44f9
  * modify it under the terms of the GNU Library General Public
4e44f9
  * License as published by the Free Software Foundation; either
4e44f9
  * version 2 of the License, or (at your option) any later version.
4e44f9
  *
4e44f9
  * This library is distributed in the hope that it will be useful,
4e44f9
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
4e44f9
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
4e44f9
  * Library General Public License for more details.
4e44f9
  *
4e44f9
  * You should have received a copy of the GNU Library General Public
4e44f9
  * License along with this library; if not, write to the
4e44f9
  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
4e44f9
  * Boston, MA 02110-1301, USA.
4e44f9
  */
4e44f9
 
4e44f9
 #ifndef _GDM_SETTINGS_KEYS_H
4e44f9
 #define _GDM_SETTINGS_KEYS_H
4e44f9
 
4e44f9
 #include <glib.h>
4e44f9
 
4e44f9
 G_BEGIN_DECLS
4e44f9
 
4e44f9
 #define GDM_KEY_USER "daemon/User"
4e44f9
 #define GDM_KEY_GROUP "daemon/Group"
4e44f9
 #define GDM_KEY_AUTO_LOGIN_ENABLE "daemon/AutomaticLoginEnable"
4e44f9
 #define GDM_KEY_AUTO_LOGIN_USER "daemon/AutomaticLogin"
4e44f9
 #define GDM_KEY_TIMED_LOGIN_ENABLE "daemon/TimedLoginEnable"
4e44f9
 #define GDM_KEY_TIMED_LOGIN_USER "daemon/TimedLogin"
4e44f9
 #define GDM_KEY_TIMED_LOGIN_DELAY "daemon/TimedLoginDelay"
4e44f9
 #define GDM_KEY_INITIAL_SETUP_ENABLE "daemon/InitialSetupEnable"
4e44f9
+#define GDM_KEY_PREFERRED_DISPLAY_SERVER "daemon/PreferredDisplayServer"
4e44f9
 #define GDM_KEY_WAYLAND_ENABLE "daemon/WaylandEnable"
4e44f9
+#define GDM_KEY_XORG_ENABLE "daemon/XorgEnable"
4e44f9
 
4e44f9
 #define GDM_KEY_DEBUG "debug/Enable"
4e44f9
 
4e44f9
 #define GDM_KEY_INCLUDE "greeter/Include"
4e44f9
 #define GDM_KEY_EXCLUDE "greeter/Exclude"
4e44f9
 #define GDM_KEY_INCLUDE_ALL "greeter/IncludeAll"
4e44f9
 
4e44f9
 #define GDM_KEY_DISALLOW_TCP "security/DisallowTCP"
4e44f9
 #define GDM_KEY_ALLOW_REMOTE_AUTOLOGIN "security/AllowRemoteAutoLogin"
4e44f9
 
4e44f9
 #define GDM_KEY_XDMCP_ENABLE "xdmcp/Enable"
4e44f9
 #define GDM_KEY_SHOW_LOCAL_GREETER "xdmcp/ShowLocalGreeter"
4e44f9
 #define GDM_KEY_MAX_PENDING "xdmcp/MaxPending"
4e44f9
 #define GDM_KEY_MAX_SESSIONS "xdmcp/MaxSessions"
4e44f9
 #define GDM_KEY_MAX_WAIT "xdmcp/MaxWait"
4e44f9
 #define GDM_KEY_DISPLAYS_PER_HOST "xdmcp/DisplaysPerHost"
4e44f9
 #define GDM_KEY_UDP_PORT "xdmcp/Port"
4e44f9
 #define GDM_KEY_INDIRECT "xdmcp/HonorIndirect"
4e44f9
 #define GDM_KEY_MAX_WAIT_INDIRECT "xdmcp/MaxWaitIndirect"
4e44f9
 #define GDM_KEY_PING_INTERVAL "xdmcp/PingIntervalSeconds"
4e44f9
 #define GDM_KEY_WILLING "xdmcp/Willing"
4e44f9
 
4e44f9
 #define GDM_KEY_MULTICAST "chooser/Multicast"
4e44f9
 #define GDM_KEY_MULTICAST_ADDR "chooser/MulticastAddr"
4e44f9
 
4e44f9
 G_END_DECLS
4e44f9
 
4e44f9
 #endif /* _GDM_SETTINGS_KEYS_H */
4e44f9
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
4e44f9
index 3a260923a..46d5a7732 100644
4e44f9
--- a/daemon/gdm-display.c
4e44f9
+++ b/daemon/gdm-display.c
4e44f9
@@ -66,83 +66,86 @@ typedef struct _GdmDisplayPrivate
4e44f9
         char                 *x11_display_name;
4e44f9
         int                   status;
4e44f9
         time_t                creation_time;
4e44f9
 
4e44f9
         char                 *x11_cookie;
4e44f9
         gsize                 x11_cookie_size;
4e44f9
         GdmDisplayAccessFile *access_file;
4e44f9
 
4e44f9
         guint                 finish_idle_id;
4e44f9
 
4e44f9
         xcb_connection_t     *xcb_connection;
4e44f9
         int                   xcb_screen_number;
4e44f9
 
4e44f9
         GDBusConnection      *connection;
4e44f9
         GdmDisplayAccessFile *user_access_file;
4e44f9
 
4e44f9
         GdmDBusDisplay       *display_skeleton;
4e44f9
         GDBusObjectSkeleton  *object_skeleton;
4e44f9
 
4e44f9
         GDBusProxy           *accountsservice_proxy;
4e44f9
 
4e44f9
         /* this spawns and controls the greeter session */
4e44f9
         GdmLaunchEnvironment *launch_environment;
4e44f9
 
4e44f9
         guint                 is_local : 1;
4e44f9
         guint                 is_initial : 1;
4e44f9
         guint                 allow_timed_login : 1;
4e44f9
         guint                 have_existing_user_accounts : 1;
4e44f9
         guint                 doing_initial_setup : 1;
4e44f9
         guint                 session_registered : 1;
4e44f9
+
4e44f9
+        GStrv                 supported_session_types;
4e44f9
 } GdmDisplayPrivate;
4e44f9
 
4e44f9
 enum {
4e44f9
         PROP_0,
4e44f9
         PROP_ID,
4e44f9
         PROP_STATUS,
4e44f9
         PROP_SEAT_ID,
4e44f9
         PROP_SESSION_ID,
4e44f9
         PROP_SESSION_CLASS,
4e44f9
         PROP_SESSION_TYPE,
4e44f9
         PROP_REMOTE_HOSTNAME,
4e44f9
         PROP_X11_DISPLAY_NUMBER,
4e44f9
         PROP_X11_DISPLAY_NAME,
4e44f9
         PROP_X11_COOKIE,
4e44f9
         PROP_X11_AUTHORITY_FILE,
4e44f9
         PROP_IS_CONNECTED,
4e44f9
         PROP_IS_LOCAL,
4e44f9
         PROP_LAUNCH_ENVIRONMENT,
4e44f9
         PROP_IS_INITIAL,
4e44f9
         PROP_ALLOW_TIMED_LOGIN,
4e44f9
         PROP_HAVE_EXISTING_USER_ACCOUNTS,
4e44f9
         PROP_DOING_INITIAL_SETUP,
4e44f9
         PROP_SESSION_REGISTERED,
4e44f9
+        PROP_SUPPORTED_SESSION_TYPES,
4e44f9
 };
4e44f9
 
4e44f9
 static void     gdm_display_class_init  (GdmDisplayClass *klass);
4e44f9
 static void     gdm_display_init        (GdmDisplay      *self);
4e44f9
 static void     gdm_display_finalize    (GObject         *object);
4e44f9
 static void     queue_finish            (GdmDisplay      *self);
4e44f9
 static void     _gdm_display_set_status (GdmDisplay *self,
4e44f9
                                          int         status);
4e44f9
 static gboolean wants_initial_setup (GdmDisplay *self);
4e44f9
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdmDisplay, gdm_display, G_TYPE_OBJECT)
4e44f9
 
4e44f9
 GQuark
4e44f9
 gdm_display_error_quark (void)
4e44f9
 {
4e44f9
         static GQuark ret = 0;
4e44f9
         if (ret == 0) {
4e44f9
                 ret = g_quark_from_static_string ("gdm_display_error");
4e44f9
         }
4e44f9
 
4e44f9
         return ret;
4e44f9
 }
4e44f9
 
4e44f9
 time_t
4e44f9
 gdm_display_get_creation_time (GdmDisplay *self)
4e44f9
 {
4e44f9
         GdmDisplayPrivate *priv;
4e44f9
 
4e44f9
         g_return_val_if_fail (GDM_IS_DISPLAY (self), 0);
4e44f9
 
4e44f9
         priv = gdm_display_get_instance_private (self);
4e44f9
@@ -883,116 +886,136 @@ _gdm_display_set_launch_environment (GdmDisplay           *self,
4e44f9
 
4e44f9
         priv = gdm_display_get_instance_private (self);
4e44f9
 
4e44f9
         g_clear_object (&priv->launch_environment);
4e44f9
 
4e44f9
         priv->launch_environment = g_object_ref (launch_environment);
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 _gdm_display_set_is_initial (GdmDisplay     *self,
4e44f9
                              gboolean        initial)
4e44f9
 {
4e44f9
         GdmDisplayPrivate *priv;
4e44f9
 
4e44f9
         priv = gdm_display_get_instance_private (self);
4e44f9
         g_debug ("GdmDisplay: initial: %s", initial? "yes" : "no");
4e44f9
         priv->is_initial = initial;
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 _gdm_display_set_allow_timed_login (GdmDisplay     *self,
4e44f9
                                     gboolean        allow_timed_login)
4e44f9
 {
4e44f9
         GdmDisplayPrivate *priv;
4e44f9
 
4e44f9
         priv = gdm_display_get_instance_private (self);
4e44f9
         g_debug ("GdmDisplay: allow timed login: %s", allow_timed_login? "yes" : "no");
4e44f9
         priv->allow_timed_login = allow_timed_login;
4e44f9
 }
4e44f9
 
4e44f9
+static void
4e44f9
+_gdm_display_set_supported_session_types (GdmDisplay         *self,
4e44f9
+                                          const char * const *supported_session_types)
4e44f9
+
4e44f9
+{
4e44f9
+        GdmDisplayPrivate *priv;
4e44f9
+        g_autofree char *supported_session_types_string = NULL;
4e44f9
+
4e44f9
+        if (supported_session_types != NULL)
4e44f9
+                supported_session_types_string = g_strjoinv (":", (GStrv) supported_session_types);
4e44f9
+
4e44f9
+        priv = gdm_display_get_instance_private (self);
4e44f9
+        g_debug ("GdmDisplay: supported session types: %s", supported_session_types_string);
4e44f9
+        g_strfreev (priv->supported_session_types);
4e44f9
+        priv->supported_session_types = g_strdupv ((GStrv) supported_session_types);
4e44f9
+}
4e44f9
+
4e44f9
 static void
4e44f9
 gdm_display_set_property (GObject        *object,
4e44f9
                           guint           prop_id,
4e44f9
                           const GValue   *value,
4e44f9
                           GParamSpec     *pspec)
4e44f9
 {
4e44f9
         GdmDisplay *self;
4e44f9
 
4e44f9
         self = GDM_DISPLAY (object);
4e44f9
 
4e44f9
         switch (prop_id) {
4e44f9
         case PROP_ID:
4e44f9
                 _gdm_display_set_id (self, g_value_get_string (value));
4e44f9
                 break;
4e44f9
         case PROP_STATUS:
4e44f9
                 _gdm_display_set_status (self, g_value_get_int (value));
4e44f9
                 break;
4e44f9
         case PROP_SEAT_ID:
4e44f9
                 _gdm_display_set_seat_id (self, g_value_get_string (value));
4e44f9
                 break;
4e44f9
         case PROP_SESSION_ID:
4e44f9
                 _gdm_display_set_session_id (self, g_value_get_string (value));
4e44f9
                 break;
4e44f9
         case PROP_SESSION_CLASS:
4e44f9
                 _gdm_display_set_session_class (self, g_value_get_string (value));
4e44f9
                 break;
4e44f9
         case PROP_SESSION_TYPE:
4e44f9
                 _gdm_display_set_session_type (self, g_value_get_string (value));
4e44f9
                 break;
4e44f9
         case PROP_REMOTE_HOSTNAME:
4e44f9
                 _gdm_display_set_remote_hostname (self, g_value_get_string (value));
4e44f9
                 break;
4e44f9
         case PROP_X11_DISPLAY_NUMBER:
4e44f9
                 _gdm_display_set_x11_display_number (self, g_value_get_int (value));
4e44f9
                 break;
4e44f9
         case PROP_X11_DISPLAY_NAME:
4e44f9
                 _gdm_display_set_x11_display_name (self, g_value_get_string (value));
4e44f9
                 break;
4e44f9
         case PROP_X11_COOKIE:
4e44f9
                 _gdm_display_set_x11_cookie (self, g_value_get_string (value));
4e44f9
                 break;
4e44f9
         case PROP_IS_LOCAL:
4e44f9
                 _gdm_display_set_is_local (self, g_value_get_boolean (value));
4e44f9
                 break;
4e44f9
         case PROP_ALLOW_TIMED_LOGIN:
4e44f9
                 _gdm_display_set_allow_timed_login (self, g_value_get_boolean (value));
4e44f9
                 break;
4e44f9
         case PROP_LAUNCH_ENVIRONMENT:
4e44f9
                 _gdm_display_set_launch_environment (self, g_value_get_object (value));
4e44f9
                 break;
4e44f9
         case PROP_IS_INITIAL:
4e44f9
                 _gdm_display_set_is_initial (self, g_value_get_boolean (value));
4e44f9
                 break;
4e44f9
         case PROP_SESSION_REGISTERED:
4e44f9
                 _gdm_display_set_session_registered (self, g_value_get_boolean (value));
4e44f9
                 break;
4e44f9
+        case PROP_SUPPORTED_SESSION_TYPES:
4e44f9
+                _gdm_display_set_supported_session_types (self, g_value_get_boxed (value));
4e44f9
+                break;
4e44f9
         default:
4e44f9
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
4e44f9
                 break;
4e44f9
         }
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 gdm_display_get_property (GObject        *object,
4e44f9
                           guint           prop_id,
4e44f9
                           GValue         *value,
4e44f9
                           GParamSpec     *pspec)
4e44f9
 {
4e44f9
         GdmDisplay *self;
4e44f9
         GdmDisplayPrivate *priv;
4e44f9
 
4e44f9
         self = GDM_DISPLAY (object);
4e44f9
         priv = gdm_display_get_instance_private (self);
4e44f9
 
4e44f9
         switch (prop_id) {
4e44f9
         case PROP_ID:
4e44f9
                 g_value_set_string (value, priv->id);
4e44f9
                 break;
4e44f9
         case PROP_STATUS:
4e44f9
                 g_value_set_int (value, priv->status);
4e44f9
                 break;
4e44f9
         case PROP_SEAT_ID:
4e44f9
                 g_value_set_string (value, priv->seat_id);
4e44f9
                 break;
4e44f9
         case PROP_SESSION_ID:
4e44f9
                 g_value_set_string (value, priv->session_id);
4e44f9
@@ -1017,60 +1040,63 @@ gdm_display_get_property (GObject        *object,
4e44f9
                 break;
4e44f9
         case PROP_X11_AUTHORITY_FILE:
4e44f9
                 g_value_take_string (value,
4e44f9
                                      priv->access_file?
4e44f9
                                      gdm_display_access_file_get_path (priv->access_file) : NULL);
4e44f9
                 break;
4e44f9
         case PROP_IS_LOCAL:
4e44f9
                 g_value_set_boolean (value, priv->is_local);
4e44f9
                 break;
4e44f9
         case PROP_IS_CONNECTED:
4e44f9
                 g_value_set_boolean (value, priv->xcb_connection != NULL);
4e44f9
                 break;
4e44f9
         case PROP_LAUNCH_ENVIRONMENT:
4e44f9
                 g_value_set_object (value, priv->launch_environment);
4e44f9
                 break;
4e44f9
         case PROP_IS_INITIAL:
4e44f9
                 g_value_set_boolean (value, priv->is_initial);
4e44f9
                 break;
4e44f9
         case PROP_HAVE_EXISTING_USER_ACCOUNTS:
4e44f9
                 g_value_set_boolean (value, priv->have_existing_user_accounts);
4e44f9
                 break;
4e44f9
         case PROP_DOING_INITIAL_SETUP:
4e44f9
                 g_value_set_boolean (value, priv->doing_initial_setup);
4e44f9
                 break;
4e44f9
         case PROP_SESSION_REGISTERED:
4e44f9
                 g_value_set_boolean (value, priv->session_registered);
4e44f9
                 break;
4e44f9
         case PROP_ALLOW_TIMED_LOGIN:
4e44f9
                 g_value_set_boolean (value, priv->allow_timed_login);
4e44f9
                 break;
4e44f9
+        case PROP_SUPPORTED_SESSION_TYPES:
4e44f9
+                g_value_set_boxed (value, priv->supported_session_types);
4e44f9
+                break;
4e44f9
         default:
4e44f9
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
4e44f9
                 break;
4e44f9
         }
4e44f9
 }
4e44f9
 
4e44f9
 static gboolean
4e44f9
 handle_get_id (GdmDBusDisplay        *skeleton,
4e44f9
                GDBusMethodInvocation *invocation,
4e44f9
                GdmDisplay            *self)
4e44f9
 {
4e44f9
         char *id;
4e44f9
 
4e44f9
         gdm_display_get_id (self, &id, NULL);
4e44f9
 
4e44f9
         gdm_dbus_display_complete_get_id (skeleton, invocation, id);
4e44f9
 
4e44f9
         g_free (id);
4e44f9
         return TRUE;
4e44f9
 }
4e44f9
 
4e44f9
 static gboolean
4e44f9
 handle_get_remote_hostname (GdmDBusDisplay        *skeleton,
4e44f9
                             GDBusMethodInvocation *invocation,
4e44f9
                             GdmDisplay            *self)
4e44f9
 {
4e44f9
         char *hostname;
4e44f9
 
4e44f9
         gdm_display_get_remote_hostname (self, &hostname, NULL);
4e44f9
 
4e44f9
@@ -1202,60 +1228,61 @@ gdm_display_constructor (GType                  type,
4e44f9
         priv = gdm_display_get_instance_private (self);
4e44f9
 
4e44f9
         g_free (priv->id);
4e44f9
         priv->id = g_strdup_printf ("/org/gnome/DisplayManager/Displays/%lu",
4e44f9
                                           (gulong) self);
4e44f9
 
4e44f9
         res = register_display (self);
4e44f9
         if (! res) {
4e44f9
                 g_warning ("Unable to register display with system bus");
4e44f9
         }
4e44f9
 
4e44f9
         return G_OBJECT (self);
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 gdm_display_dispose (GObject *object)
4e44f9
 {
4e44f9
         GdmDisplay *self;
4e44f9
         GdmDisplayPrivate *priv;
4e44f9
 
4e44f9
         self = GDM_DISPLAY (object);
4e44f9
         priv = gdm_display_get_instance_private (self);
4e44f9
 
4e44f9
         g_debug ("GdmDisplay: Disposing display");
4e44f9
 
4e44f9
         if (priv->finish_idle_id != 0) {
4e44f9
                 g_source_remove (priv->finish_idle_id);
4e44f9
                 priv->finish_idle_id = 0;
4e44f9
         }
4e44f9
         g_clear_object (&priv->launch_environment);
4e44f9
+        g_clear_pointer (&priv->supported_session_types, g_strfreev);
4e44f9
 
4e44f9
         g_warn_if_fail (priv->status != GDM_DISPLAY_MANAGED);
4e44f9
         g_warn_if_fail (priv->user_access_file == NULL);
4e44f9
         g_warn_if_fail (priv->access_file == NULL);
4e44f9
 
4e44f9
         G_OBJECT_CLASS (gdm_display_parent_class)->dispose (object);
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 gdm_display_class_init (GdmDisplayClass *klass)
4e44f9
 {
4e44f9
         GObjectClass   *object_class = G_OBJECT_CLASS (klass);
4e44f9
 
4e44f9
         object_class->get_property = gdm_display_get_property;
4e44f9
         object_class->set_property = gdm_display_set_property;
4e44f9
         object_class->constructor = gdm_display_constructor;
4e44f9
         object_class->dispose = gdm_display_dispose;
4e44f9
         object_class->finalize = gdm_display_finalize;
4e44f9
 
4e44f9
         klass->prepare = gdm_display_real_prepare;
4e44f9
 
4e44f9
         g_object_class_install_property (object_class,
4e44f9
                                          PROP_ID,
4e44f9
                                          g_param_spec_string ("id",
4e44f9
                                                               "id",
4e44f9
                                                               "id",
4e44f9
                                                               NULL,
4e44f9
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
4e44f9
         g_object_class_install_property (object_class,
4e44f9
                                          PROP_REMOTE_HOSTNAME,
4e44f9
@@ -1362,60 +1389,68 @@ gdm_display_class_init (GdmDisplayClass *klass)
4e44f9
                                          PROP_DOING_INITIAL_SETUP,
4e44f9
                                          g_param_spec_boolean ("doing-initial-setup",
4e44f9
                                                                NULL,
4e44f9
                                                                NULL,
4e44f9
                                                                FALSE,
4e44f9
                                                                G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
4e44f9
         g_object_class_install_property (object_class,
4e44f9
                                          PROP_SESSION_REGISTERED,
4e44f9
                                          g_param_spec_boolean ("session-registered",
4e44f9
                                                                NULL,
4e44f9
                                                                NULL,
4e44f9
                                                                FALSE,
4e44f9
                                                                G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
4e44f9
 
4e44f9
         g_object_class_install_property (object_class,
4e44f9
                                          PROP_LAUNCH_ENVIRONMENT,
4e44f9
                                          g_param_spec_object ("launch-environment",
4e44f9
                                                               NULL,
4e44f9
                                                               NULL,
4e44f9
                                                               GDM_TYPE_LAUNCH_ENVIRONMENT,
4e44f9
                                                               G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
4e44f9
         g_object_class_install_property (object_class,
4e44f9
                                          PROP_STATUS,
4e44f9
                                          g_param_spec_int ("status",
4e44f9
                                                            "status",
4e44f9
                                                            "status",
4e44f9
                                                            -1,
4e44f9
                                                            G_MAXINT,
4e44f9
                                                            GDM_DISPLAY_UNMANAGED,
4e44f9
                                                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
4e44f9
+
4e44f9
+        g_object_class_install_property (object_class,
4e44f9
+                                         PROP_SUPPORTED_SESSION_TYPES,
4e44f9
+                                         g_param_spec_boxed ("supported-session-types",
4e44f9
+                                                             "supported session types",
4e44f9
+                                                             "supported session types",
4e44f9
+                                                             G_TYPE_STRV,
4e44f9
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 gdm_display_init (GdmDisplay *self)
4e44f9
 {
4e44f9
         GdmDisplayPrivate *priv;
4e44f9
 
4e44f9
         priv = gdm_display_get_instance_private (self);
4e44f9
 
4e44f9
         priv->creation_time = time (NULL);
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 gdm_display_finalize (GObject *object)
4e44f9
 {
4e44f9
         GdmDisplay *self;
4e44f9
         GdmDisplayPrivate *priv;
4e44f9
 
4e44f9
         g_return_if_fail (object != NULL);
4e44f9
         g_return_if_fail (GDM_IS_DISPLAY (object));
4e44f9
 
4e44f9
         self = GDM_DISPLAY (object);
4e44f9
         priv = gdm_display_get_instance_private (self);
4e44f9
 
4e44f9
         g_return_if_fail (priv != NULL);
4e44f9
 
4e44f9
         g_debug ("GdmDisplay: Finalizing display: %s", priv->id);
4e44f9
         g_free (priv->id);
4e44f9
         g_free (priv->seat_id);
4e44f9
         g_free (priv->session_class);
4e44f9
@@ -1694,60 +1729,61 @@ gdm_display_start_greeter_session (GdmDisplay *self)
4e44f9
                                  G_CALLBACK (on_launch_environment_session_opened),
4e44f9
                                  self, 0);
4e44f9
         g_signal_connect_object (priv->launch_environment,
4e44f9
                                  "started",
4e44f9
                                  G_CALLBACK (on_launch_environment_session_started),
4e44f9
                                  self, 0);
4e44f9
         g_signal_connect_object (priv->launch_environment,
4e44f9
                                  "stopped",
4e44f9
                                  G_CALLBACK (on_launch_environment_session_stopped),
4e44f9
                                  self, 0);
4e44f9
         g_signal_connect_object (priv->launch_environment,
4e44f9
                                  "exited",
4e44f9
                                  G_CALLBACK (on_launch_environment_session_exited),
4e44f9
                                  self, 0);
4e44f9
         g_signal_connect_object (priv->launch_environment,
4e44f9
                                  "died",
4e44f9
                                  G_CALLBACK (on_launch_environment_session_died),
4e44f9
                                  self, 0);
4e44f9
 
4e44f9
         if (auth_file != NULL) {
4e44f9
                 g_object_set (priv->launch_environment,
4e44f9
                               "x11-authority-file", auth_file,
4e44f9
                               NULL);
4e44f9
         }
4e44f9
 
4e44f9
         gdm_launch_environment_start (priv->launch_environment);
4e44f9
 
4e44f9
         session = gdm_launch_environment_get_session (priv->launch_environment);
4e44f9
         g_object_set (G_OBJECT (session),
4e44f9
                       "display-is-initial", priv->is_initial,
4e44f9
+                      "supported-session-types", priv->supported_session_types,
4e44f9
                       NULL);
4e44f9
 
4e44f9
         g_free (display_name);
4e44f9
         g_free (seat_id);
4e44f9
         g_free (hostname);
4e44f9
         g_free (auth_file);
4e44f9
 }
4e44f9
 
4e44f9
 void
4e44f9
 gdm_display_stop_greeter_session (GdmDisplay *self)
4e44f9
 {
4e44f9
         GdmDisplayPrivate *priv;
4e44f9
 
4e44f9
         priv = gdm_display_get_instance_private (self);
4e44f9
 
4e44f9
         if (priv->launch_environment != NULL) {
4e44f9
 
4e44f9
                 g_signal_handlers_disconnect_by_func (priv->launch_environment,
4e44f9
                                                       G_CALLBACK (on_launch_environment_session_opened),
4e44f9
                                                       self);
4e44f9
                 g_signal_handlers_disconnect_by_func (priv->launch_environment,
4e44f9
                                                       G_CALLBACK (on_launch_environment_session_started),
4e44f9
                                                       self);
4e44f9
                 g_signal_handlers_disconnect_by_func (priv->launch_environment,
4e44f9
                                                       G_CALLBACK (on_launch_environment_session_stopped),
4e44f9
                                                       self);
4e44f9
                 g_signal_handlers_disconnect_by_func (priv->launch_environment,
4e44f9
                                                       G_CALLBACK (on_launch_environment_session_exited),
4e44f9
                                                       self);
4e44f9
                 g_signal_handlers_disconnect_by_func (priv->launch_environment,
4e44f9
diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c
4e44f9
index 87a1c5ffe..14ecfac2d 100644
4e44f9
--- a/daemon/gdm-launch-environment.c
4e44f9
+++ b/daemon/gdm-launch-environment.c
4e44f9
@@ -134,60 +134,61 @@ static GHashTable *
4e44f9
 build_launch_environment (GdmLaunchEnvironment *launch_environment,
4e44f9
                           gboolean              start_session)
4e44f9
 {
4e44f9
         GHashTable    *hash;
4e44f9
         struct passwd *pwent;
4e44f9
         static const char *const optional_environment[] = {
4e44f9
                 "GI_TYPELIB_PATH",
4e44f9
                 "LANG",
4e44f9
                 "LANGUAGE",
4e44f9
                 "LC_ADDRESS",
4e44f9
                 "LC_ALL",
4e44f9
                 "LC_COLLATE",
4e44f9
                 "LC_CTYPE",
4e44f9
                 "LC_IDENTIFICATION",
4e44f9
                 "LC_MEASUREMENT",
4e44f9
                 "LC_MESSAGES",
4e44f9
                 "LC_MONETARY",
4e44f9
                 "LC_NAME",
4e44f9
                 "LC_NUMERIC",
4e44f9
                 "LC_PAPER",
4e44f9
                 "LC_TELEPHONE",
4e44f9
                 "LC_TIME",
4e44f9
                 "LD_LIBRARY_PATH",
4e44f9
                 "PATH",
4e44f9
                 "WINDOWPATH",
4e44f9
                 "XCURSOR_PATH",
4e44f9
                 "XDG_CONFIG_DIRS",
4e44f9
                 NULL
4e44f9
         };
4e44f9
         char *system_data_dirs;
4e44f9
+        g_auto (GStrv) supported_session_types = NULL;
4e44f9
         int i;
4e44f9
 
4e44f9
         /* create a hash table of current environment, then update keys has necessary */
4e44f9
         hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
4e44f9
 
4e44f9
         for (i = 0; optional_environment[i] != NULL; i++) {
4e44f9
                 if (g_getenv (optional_environment[i]) == NULL) {
4e44f9
                         continue;
4e44f9
                 }
4e44f9
 
4e44f9
                 g_hash_table_insert (hash,
4e44f9
                                      g_strdup (optional_environment[i]),
4e44f9
                                      g_strdup (g_getenv (optional_environment[i])));
4e44f9
         }
4e44f9
 
4e44f9
         if (launch_environment->priv->x11_authority_file != NULL)
4e44f9
                 g_hash_table_insert (hash, g_strdup ("XAUTHORITY"), g_strdup (launch_environment->priv->x11_authority_file));
4e44f9
 
4e44f9
         if (launch_environment->priv->session_mode != NULL) {
4e44f9
                 g_hash_table_insert (hash, g_strdup ("GNOME_SHELL_SESSION_MODE"), g_strdup (launch_environment->priv->session_mode));
4e44f9
 
4e44f9
 		if (strcmp (launch_environment->priv->session_mode, INITIAL_SETUP_SESSION_MODE) != 0) {
4e44f9
 			/* gvfs is needed for fetching remote avatars in the initial setup. Disable it otherwise. */
4e44f9
 			g_hash_table_insert (hash, g_strdup ("GVFS_DISABLE_FUSE"), g_strdup ("1"));
4e44f9
 			g_hash_table_insert (hash, g_strdup ("GIO_USE_VFS"), g_strdup ("local"));
4e44f9
 			g_hash_table_insert (hash, g_strdup ("GVFS_REMOTE_VOLUME_MONITOR_IGNORE"), g_strdup ("1"));
4e44f9
 
4e44f9
 			/* The locked down dconf profile should not be used for the initial setup session.
4e44f9
 			 * This allows overridden values from the user profile to take effect.
4e44f9
 			 */
4e44f9
@@ -217,60 +218,68 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment,
4e44f9
         }
4e44f9
 
4e44f9
         if (start_session && launch_environment->priv->x11_display_seat_id != NULL) {
4e44f9
                 char *seat_id;
4e44f9
 
4e44f9
                 seat_id = launch_environment->priv->x11_display_seat_id;
4e44f9
 
4e44f9
                 g_hash_table_insert (hash, g_strdup ("GDM_SEAT_ID"), g_strdup (seat_id));
4e44f9
         }
4e44f9
 
4e44f9
         g_hash_table_insert (hash, g_strdup ("RUNNING_UNDER_GDM"), g_strdup ("true"));
4e44f9
 
4e44f9
         /* Now populate XDG_DATA_DIRS from env.d if we're running initial setup; this allows
4e44f9
          * e.g. Flatpak apps to be recognized by gnome-shell.
4e44f9
          */
4e44f9
         if (g_strcmp0 (launch_environment->priv->session_mode, INITIAL_SETUP_SESSION_MODE) == 0)
4e44f9
                 gdm_load_env_d (load_env_func, get_var_cb, hash);
4e44f9
 
4e44f9
         /* Prepend our own XDG_DATA_DIRS value */
4e44f9
         system_data_dirs = g_strdup (g_hash_table_lookup (hash, "XDG_DATA_DIRS"));
4e44f9
         if (!system_data_dirs)
4e44f9
                 system_data_dirs = g_strjoinv (":", (char **) g_get_system_data_dirs ());
4e44f9
 
4e44f9
         g_hash_table_insert (hash,
4e44f9
                              g_strdup ("XDG_DATA_DIRS"),
4e44f9
                              g_strdup_printf ("%s:%s",
4e44f9
                                               DATADIR "/gdm/greeter",
4e44f9
                                               system_data_dirs));
4e44f9
         g_free (system_data_dirs);
4e44f9
 
4e44f9
+        g_object_get (launch_environment->priv->session,
4e44f9
+                      "supported-session-types",
4e44f9
+                      &supported_session_types,
4e44f9
+                      NULL);
4e44f9
+        g_hash_table_insert (hash,
4e44f9
+                             g_strdup ("GDM_SUPPORTED_SESSION_TYPES"),
4e44f9
+                             g_strjoinv (":", supported_session_types));
4e44f9
+
4e44f9
         return hash;
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 on_session_setup_complete (GdmSession        *session,
4e44f9
                            const char        *service_name,
4e44f9
                            GdmLaunchEnvironment *launch_environment)
4e44f9
 {
4e44f9
         GHashTable       *hash;
4e44f9
         GHashTableIter    iter;
4e44f9
         gpointer          key, value;
4e44f9
 
4e44f9
         hash = build_launch_environment (launch_environment, TRUE);
4e44f9
 
4e44f9
         g_hash_table_iter_init (&iter, hash);
4e44f9
         while (g_hash_table_iter_next (&iter, &key, &value)) {
4e44f9
                 gdm_session_set_environment_variable (launch_environment->priv->session, key, value);
4e44f9
         }
4e44f9
         g_hash_table_destroy (hash);
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 on_session_opened (GdmSession           *session,
4e44f9
                    const char           *service_name,
4e44f9
                    const char           *session_id,
4e44f9
                    GdmLaunchEnvironment *launch_environment)
4e44f9
 {
4e44f9
         launch_environment->priv->session_id = g_strdup (session_id);
4e44f9
 
4e44f9
         g_signal_emit (G_OBJECT (launch_environment), signals [OPENED], 0);
4e44f9
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
4e44f9
index 8a4ef06cd..141d64c6b 100644
4e44f9
--- a/daemon/gdm-local-display-factory.c
4e44f9
+++ b/daemon/gdm-local-display-factory.c
4e44f9
@@ -156,126 +156,225 @@ take_next_display_number (GdmLocalDisplayFactory *factory)
4e44f9
 
4e44f9
         g_debug ("GdmLocalDisplayFactory: Found the following X displays:");
4e44f9
         for (l = list; l != NULL; l = l->next) {
4e44f9
                 g_debug ("GdmLocalDisplayFactory: %u", GPOINTER_TO_UINT (l->data));
4e44f9
         }
4e44f9
 
4e44f9
         for (l = list; l != NULL; l = l->next) {
4e44f9
                 guint32 num;
4e44f9
                 num = GPOINTER_TO_UINT (l->data);
4e44f9
 
4e44f9
                 /* always fill zero */
4e44f9
                 if (l->prev == NULL && num != 0) {
4e44f9
                         ret = 0;
4e44f9
                         break;
4e44f9
                 }
4e44f9
                 /* now find the first hole */
4e44f9
                 if (l->next == NULL || GPOINTER_TO_UINT (l->next->data) != (num + 1)) {
4e44f9
                         ret = num + 1;
4e44f9
                         break;
4e44f9
                 }
4e44f9
         }
4e44f9
  out:
4e44f9
 
4e44f9
         /* now reserve this number */
4e44f9
         g_debug ("GdmLocalDisplayFactory: Reserving X display: %u", ret);
4e44f9
         g_hash_table_insert (factory->used_display_numbers, GUINT_TO_POINTER (ret), NULL);
4e44f9
 
4e44f9
         return ret;
4e44f9
 }
4e44f9
 
4e44f9
+static char *
4e44f9
+get_preferred_display_server (GdmLocalDisplayFactory *factory)
4e44f9
+{
4e44f9
+        g_autofree gchar *preferred_display_server = NULL;
4e44f9
+        gboolean wayland_enabled = FALSE, xorg_enabled = FALSE;
4e44f9
+
4e44f9
+        gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled);
4e44f9
+        gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled);
4e44f9
+
4e44f9
+        if (wayland_enabled && !xorg_enabled) {
4e44f9
+                return g_strdup ("wayland");
4e44f9
+        }
4e44f9
+
4e44f9
+        if (!wayland_enabled && !xorg_enabled) {
4e44f9
+                return g_strdup ("none");
4e44f9
+        }
4e44f9
+
4e44f9
+        gdm_settings_direct_get_string (GDM_KEY_PREFERRED_DISPLAY_SERVER, &preferred_display_server);
4e44f9
+
4e44f9
+        if (g_strcmp0 (preferred_display_server, "wayland") == 0) {
4e44f9
+                if (wayland_enabled)
4e44f9
+                        return g_strdup (preferred_display_server);
4e44f9
+                else
4e44f9
+                        return g_strdup ("xorg");
4e44f9
+        }
4e44f9
+
4e44f9
+        if (g_strcmp0 (preferred_display_server, "xorg") == 0) {
4e44f9
+                if (xorg_enabled)
4e44f9
+                        return g_strdup (preferred_display_server);
4e44f9
+                else
4e44f9
+                        return g_strdup ("wayland");
4e44f9
+        }
4e44f9
+
4e44f9
+        if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) {
4e44f9
+                if (xorg_enabled)
4e44f9
+                        return g_strdup (preferred_display_server);
4e44f9
+        }
4e44f9
+
4e44f9
+        return g_strdup ("none");
4e44f9
+}
4e44f9
+
4e44f9
+static const char *
4e44f9
+gdm_local_display_factory_get_session_type (GdmLocalDisplayFactory *factory,
4e44f9
+                                            gboolean                should_fall_back)
4e44f9
+{
4e44f9
+        const char *session_types[3] = { NULL };
4e44f9
+        gsize i, session_type_index = 0;
4e44f9
+        g_autofree gchar *preferred_display_server = NULL;
4e44f9
+
4e44f9
+        preferred_display_server = get_preferred_display_server (factory);
4e44f9
+
4e44f9
+        if (g_strcmp0 (preferred_display_server, "wayland") != 0 &&
4e44f9
+            g_strcmp0 (preferred_display_server, "xorg") != 0)
4e44f9
+              return NULL;
4e44f9
+
4e44f9
+        for (i = 0; i < G_N_ELEMENTS (session_types) - 1; i++) {
4e44f9
+#ifdef ENABLE_WAYLAND_SUPPORT
4e44f9
+            if (i > 0 ||
4e44f9
+                g_strcmp0 (preferred_display_server, "wayland") == 0) {
4e44f9
+                    gboolean wayland_enabled = FALSE;
4e44f9
+                    if (gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled)) {
4e44f9
+                            if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE)) {
4e44f9
+                                    session_types[i] = "wayland";
4e44f9
+                                    continue;
4e44f9
+                            }
4e44f9
+                    }
4e44f9
+            }
4e44f9
+#endif
4e44f9
+
4e44f9
+            if (i > 0 ||
4e44f9
+                g_strcmp0 (preferred_display_server, "xorg") == 0) {
4e44f9
+                    gboolean xorg_enabled = FALSE;
4e44f9
+                    if (gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled)) {
4e44f9
+                            if (xorg_enabled && g_file_test ("/usr/bin/Xorg", G_FILE_TEST_IS_EXECUTABLE)) {
4e44f9
+                                    session_types[i] = "x11";
4e44f9
+                                    continue;
4e44f9
+                            }
4e44f9
+                    }
4e44f9
+            }
4e44f9
+        }
4e44f9
+
4e44f9
+        if (should_fall_back)
4e44f9
+                session_type_index++;
4e44f9
+
4e44f9
+        return session_types[session_type_index];
4e44f9
+}
4e44f9
+
4e44f9
 static void
4e44f9
 on_display_disposed (GdmLocalDisplayFactory *factory,
4e44f9
                      GdmDisplay             *display)
4e44f9
 {
4e44f9
         g_debug ("GdmLocalDisplayFactory: Display %p disposed", display);
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 store_display (GdmLocalDisplayFactory *factory,
4e44f9
                GdmDisplay             *display)
4e44f9
 {
4e44f9
         GdmDisplayStore *store;
4e44f9
 
4e44f9
         store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
4e44f9
         gdm_display_store_add (store, display);
4e44f9
 }
4e44f9
 
4e44f9
-static gboolean
4e44f9
-gdm_local_display_factory_use_wayland (void)
4e44f9
-{
4e44f9
-#ifdef ENABLE_WAYLAND_SUPPORT
4e44f9
-        gboolean wayland_enabled = FALSE;
4e44f9
-        if (gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled)) {
4e44f9
-                if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE) )
4e44f9
-                        return TRUE;
4e44f9
-        }
4e44f9
-#endif
4e44f9
-        return FALSE;
4e44f9
-}
4e44f9
-
4e44f9
 /*
4e44f9
   Example:
4e44f9
   dbus-send --system --dest=org.gnome.DisplayManager \
4e44f9
   --type=method_call --print-reply --reply-timeout=2000 \
4e44f9
   /org/gnome/DisplayManager/Manager \
4e44f9
   org.gnome.DisplayManager.Manager.GetDisplays
4e44f9
 */
4e44f9
 gboolean
4e44f9
 gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *factory,
4e44f9
                                                     char                  **id,
4e44f9
                                                     GError                **error)
4e44f9
 {
4e44f9
         gboolean         ret;
4e44f9
         GdmDisplay      *display = NULL;
4e44f9
         gboolean         is_initial = FALSE;
4e44f9
+        const char      *session_type;
4e44f9
+        g_autofree gchar *preferred_display_server = NULL;
4e44f9
 
4e44f9
         g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
4e44f9
 
4e44f9
         ret = FALSE;
4e44f9
 
4e44f9
         g_debug ("GdmLocalDisplayFactory: Creating transient display");
4e44f9
 
4e44f9
-#ifdef ENABLE_USER_DISPLAY_SERVER
4e44f9
-        display = gdm_local_display_new ();
4e44f9
-        if (gdm_local_display_factory_use_wayland ())
4e44f9
-                g_object_set (G_OBJECT (display), "session-type", "wayland", NULL);
4e44f9
-        is_initial = TRUE;
4e44f9
-#else
4e44f9
-        if (display == NULL) {
4e44f9
-                guint32 num;
4e44f9
+        preferred_display_server = get_preferred_display_server (factory);
4e44f9
 
4e44f9
-                num = take_next_display_number (factory);
4e44f9
+#ifdef ENABLE_USER_DISPLAY_SERVER
4e44f9
+        if (g_strcmp0 (preferred_display_server, "wayland") == 0 ||
4e44f9
+            g_strcmp0 (preferred_display_server, "xorg") == 0) {
4e44f9
+                session_type = gdm_local_display_factory_get_session_type (factory, FALSE);
4e44f9
+
4e44f9
+                if (session_type == NULL) {
4e44f9
+                        g_set_error_literal (error,
4e44f9
+                                             GDM_DISPLAY_ERROR,
4e44f9
+                                             GDM_DISPLAY_ERROR_GENERAL,
4e44f9
+                                             "Both Wayland and Xorg are unavailable");
4e44f9
+                        return FALSE;
4e44f9
+                }
4e44f9
 
4e44f9
-                display = gdm_legacy_display_new (num);
4e44f9
+                display = gdm_local_display_new ();
4e44f9
+                g_object_set (G_OBJECT (display), "session-type", session_type, NULL);
4e44f9
+                is_initial = TRUE;
4e44f9
         }
4e44f9
 #endif
4e44f9
+        if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) {
4e44f9
+                if (display == NULL) {
4e44f9
+                        guint32 num;
4e44f9
+
4e44f9
+                        num = take_next_display_number (factory);
4e44f9
+
4e44f9
+                        display = gdm_legacy_display_new (num);
4e44f9
+                }
4e44f9
+        }
4e44f9
+
4e44f9
+        if (display == NULL) {
4e44f9
+                g_set_error_literal (error,
4e44f9
+                                     GDM_DISPLAY_ERROR,
4e44f9
+                                     GDM_DISPLAY_ERROR_GENERAL,
4e44f9
+                                     "Invalid preferred display server configured");
4e44f9
+                return FALSE;
4e44f9
+        }
4e44f9
 
4e44f9
         g_object_set (display,
4e44f9
                       "seat-id", "seat0",
4e44f9
                       "allow-timed-login", FALSE,
4e44f9
                       "is-initial", is_initial,
4e44f9
                       NULL);
4e44f9
 
4e44f9
         store_display (factory, display);
4e44f9
 
4e44f9
         if (! gdm_display_manage (display)) {
4e44f9
                 display = NULL;
4e44f9
                 goto out;
4e44f9
         }
4e44f9
 
4e44f9
         if (! gdm_display_get_id (display, id, NULL)) {
4e44f9
                 display = NULL;
4e44f9
                 goto out;
4e44f9
         }
4e44f9
 
4e44f9
         ret = TRUE;
4e44f9
  out:
4e44f9
         /* ref either held by store or not at all */
4e44f9
         g_object_unref (display);
4e44f9
 
4e44f9
         return ret;
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 finish_display_on_seat_if_waiting (GdmDisplayStore *display_store,
4e44f9
                                    GdmDisplay      *display,
4e44f9
@@ -454,190 +553,239 @@ lookup_prepared_display_by_seat_id (const char *id,
4e44f9
         return lookup_by_seat_id (id, display, user_data);
4e44f9
 }
4e44f9
 
4e44f9
 static int
4e44f9
 on_seat0_graphics_check_timeout (gpointer user_data)
4e44f9
 {
4e44f9
         GdmLocalDisplayFactory *factory = user_data;
4e44f9
 
4e44f9
         factory->seat0_graphics_check_timeout_id = 0;
4e44f9
 
4e44f9
         /* Simply try to re-add seat0. If it is there already (i.e. CanGraphical
4e44f9
          * turned TRUE, then we'll find it and it will not be created again).
4e44f9
          */
4e44f9
         factory->seat0_graphics_check_timed_out = TRUE;
4e44f9
         ensure_display_for_seat (factory, "seat0");
4e44f9
 
4e44f9
         return G_SOURCE_REMOVE;
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 ensure_display_for_seat (GdmLocalDisplayFactory *factory,
4e44f9
                          const char             *seat_id)
4e44f9
 {
4e44f9
         int ret;
4e44f9
         gboolean seat_supports_graphics;
4e44f9
         gboolean is_seat0;
4e44f9
         const char *session_type = "wayland";
4e44f9
         GdmDisplayStore *store;
4e44f9
         GdmDisplay      *display = NULL;
4e44f9
         g_autofree char *login_session_id = NULL;
4e44f9
+        gboolean wayland_enabled = FALSE, xorg_enabled = FALSE;
4e44f9
+        g_autofree gchar *preferred_display_server = NULL;
4e44f9
+        gboolean falling_back;
4e44f9
+
4e44f9
+        gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled);
4e44f9
+        gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled);
4e44f9
+
4e44f9
+        preferred_display_server = get_preferred_display_server (factory);
4e44f9
+
4e44f9
+        if (g_strcmp0 (preferred_display_server, "none") == 0) {
4e44f9
+               g_debug ("GdmLocalDisplayFactory: Preferred display server is none, so not creating display");
4e44f9
+               return;
4e44f9
+        }
4e44f9
 
4e44f9
         ret = sd_seat_can_graphical (seat_id);
4e44f9
 
4e44f9
         if (ret < 0) {
4e44f9
                 g_critical ("Failed to query CanGraphical information for seat %s", seat_id);
4e44f9
                 return;
4e44f9
         }
4e44f9
 
4e44f9
         if (ret == 0) {
4e44f9
                 g_debug ("GdmLocalDisplayFactory: System doesn't currently support graphics");
4e44f9
                 seat_supports_graphics = FALSE;
4e44f9
         } else {
4e44f9
                 g_debug ("GdmLocalDisplayFactory: System supports graphics");
4e44f9
                 seat_supports_graphics = TRUE;
4e44f9
         }
4e44f9
 
4e44f9
         if (g_strcmp0 (seat_id, "seat0") == 0) {
4e44f9
                 is_seat0 = TRUE;
4e44f9
 
4e44f9
-                /* If we've failed, or are explicitly told to, fall back to legacy X11 support
4e44f9
-                 */
4e44f9
-                if (factory->num_failures > 0 || !gdm_local_display_factory_use_wayland ()) {
4e44f9
-                        session_type = NULL;
4e44f9
-                        g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use X11 fallback");
4e44f9
-                } else {
4e44f9
-                        g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use wayland");
4e44f9
-                }
4e44f9
+                falling_back = factory->num_failures > 0;
4e44f9
+                session_type = gdm_local_display_factory_get_session_type (factory, falling_back);
4e44f9
+
4e44f9
+                g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use %s%s",
4e44f9
+                         session_type, falling_back? " fallback" : "");
4e44f9
         } else {
4e44f9
                 is_seat0 = FALSE;
4e44f9
 
4e44f9
                 g_debug ("GdmLocalDisplayFactory: New displays on seat %s will use X11 fallback", seat_id);
4e44f9
                 /* Force legacy X11 for all auxiliary seats */
4e44f9
                 seat_supports_graphics = TRUE;
4e44f9
-                session_type = NULL;
4e44f9
+                session_type = "x11";
4e44f9
         }
4e44f9
 
4e44f9
         /* For seat0, we have a fallback logic to still try starting it after
4e44f9
          * SEAT0_GRAPHICS_CHECK_TIMEOUT seconds. i.e. we simply continue even if
4e44f9
          * CanGraphical is unset.
4e44f9
          * This is ugly, but it means we'll come up eventually in some
4e44f9
          * scenarios where no master device is present.
4e44f9
          * Note that we'll force an X11 fallback even though there might be
4e44f9
          * cases where an wayland capable device is present and simply not marked as
4e44f9
          * master-of-seat. In these cases, this should likely be fixed in the
4e44f9
          * udev rules.
4e44f9
          *
4e44f9
          * At the moment, systemd always sets CanGraphical for non-seat0 seats.
4e44f9
          * This is because non-seat0 seats are defined by having master-of-seat
4e44f9
          * set. This means we can avoid the fallback check for non-seat0 seats,
4e44f9
          * which simplifies the code.
4e44f9
          */
4e44f9
         if (is_seat0) {
4e44f9
                 if (!seat_supports_graphics) {
4e44f9
                         if (!factory->seat0_graphics_check_timed_out) {
4e44f9
                                 if (factory->seat0_graphics_check_timeout_id == 0) {
4e44f9
                                         g_debug ("GdmLocalDisplayFactory: seat0 doesn't yet support graphics.  Waiting %d seconds to try again.", SEAT0_GRAPHICS_CHECK_TIMEOUT);
4e44f9
                                         factory->seat0_graphics_check_timeout_id = g_timeout_add_seconds (SEAT0_GRAPHICS_CHECK_TIMEOUT,
4e44f9
                                                                                                           on_seat0_graphics_check_timeout,
4e44f9
                                                                                                           factory);
4e44f9
 
4e44f9
                                 } else {
4e44f9
                                         /* It is not yet time to force X11 fallback. */
4e44f9
                                         g_debug ("GdmLocalDisplayFactory: seat0 display requested when there is no graphics support before graphics check timeout.");
4e44f9
                                 }
4e44f9
 
4e44f9
                                 return;
4e44f9
                         }
4e44f9
 
4e44f9
                         g_debug ("GdmLocalDisplayFactory: Assuming we can use seat0 for X11 even though system says it doesn't support graphics!");
4e44f9
                         g_debug ("GdmLocalDisplayFactory: This might indicate an issue where the framebuffer device is not tagged as master-of-seat in udev.");
4e44f9
                         seat_supports_graphics = TRUE;
4e44f9
-                        session_type = NULL;
4e44f9
+                        session_type = "x11";
4e44f9
+                        wayland_enabled = FALSE;
4e44f9
                 } else {
4e44f9
                         g_clear_handle_id (&factory->seat0_graphics_check_timeout_id, g_source_remove);
4e44f9
                 }
4e44f9
         }
4e44f9
 
4e44f9
         if (!seat_supports_graphics)
4e44f9
                 return;
4e44f9
 
4e44f9
-        g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested",
4e44f9
-                 session_type? : "X11", seat_id);
4e44f9
+        if (session_type != NULL)
4e44f9
+                g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested",
4e44f9
+                         session_type, seat_id);
4e44f9
+        else if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0)
4e44f9
+                g_debug ("GdmLocalDisplayFactory: Legacy Xorg login display for seat %s requested",
4e44f9
+                         seat_id);
4e44f9
+
4e44f9
         store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
4e44f9
 
4e44f9
         if (is_seat0)
4e44f9
                 display = gdm_display_store_find (store, lookup_prepared_display_by_seat_id, (gpointer) seat_id);
4e44f9
         else
4e44f9
                 display = gdm_display_store_find (store, lookup_by_seat_id, (gpointer) seat_id);
4e44f9
 
4e44f9
         /* Ensure we don't create the same display more than once */
4e44f9
         if (display != NULL) {
4e44f9
                 g_debug ("GdmLocalDisplayFactory: display already created");
4e44f9
                 return;
4e44f9
         }
4e44f9
 
4e44f9
         /* If we already have a login window, switch to it */
4e44f9
         if (gdm_get_login_window_session_id (seat_id, &login_session_id)) {
4e44f9
                 GdmDisplay *display;
4e44f9
 
4e44f9
                 display = gdm_display_store_find (store,
4e44f9
                                                   lookup_by_session_id,
4e44f9
                                                   (gpointer) login_session_id);
4e44f9
                 if (display != NULL &&
4e44f9
                     (gdm_display_get_status (display) == GDM_DISPLAY_MANAGED ||
4e44f9
                      gdm_display_get_status (display) == GDM_DISPLAY_WAITING_TO_FINISH)) {
4e44f9
                         g_object_set (G_OBJECT (display), "status", GDM_DISPLAY_MANAGED, NULL);
4e44f9
                         g_debug ("GdmLocalDisplayFactory: session %s found, activating.",
4e44f9
                                  login_session_id);
4e44f9
                         gdm_activate_session_by_id (factory->connection, seat_id, login_session_id);
4e44f9
                         return;
4e44f9
                 }
4e44f9
         }
4e44f9
 
4e44f9
         g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id);
4e44f9
 
4e44f9
 #ifdef ENABLE_USER_DISPLAY_SERVER
4e44f9
-        if (is_seat0) {
4e44f9
-                display = gdm_local_display_new ();
4e44f9
-                if (session_type != NULL) {
4e44f9
+        if (g_strcmp0 (preferred_display_server, "wayland") == 0 ||
4e44f9
+            g_strcmp0 (preferred_display_server, "xorg") == 0) {
4e44f9
+                if (is_seat0) {
4e44f9
+                        g_autoptr (GPtrArray) supported_session_types = NULL;
4e44f9
+
4e44f9
+                        if (session_type == NULL) {
4e44f9
+                                g_warning ("GdmLocalDisplayFactory: Both Wayland and Xorg sessions are unavailable");
4e44f9
+                                return;
4e44f9
+                        }
4e44f9
+
4e44f9
+                        supported_session_types = g_ptr_array_new ();
4e44f9
+
4e44f9
+                        if (g_strcmp0 (preferred_display_server, "wayland") == 0) {
4e44f9
+                                if (wayland_enabled)
4e44f9
+                                        g_ptr_array_add (supported_session_types, "wayland");
4e44f9
+                        } else {
4e44f9
+                                if (xorg_enabled)
4e44f9
+                                        g_ptr_array_add (supported_session_types, "x11");
4e44f9
+                        }
4e44f9
+
4e44f9
+                        if (!falling_back) {
4e44f9
+                                if (g_strcmp0 (preferred_display_server, "wayland") == 0) {
4e44f9
+                                        if (xorg_enabled)
4e44f9
+                                                g_ptr_array_add (supported_session_types, "x11");
4e44f9
+                                } else {
4e44f9
+                                        if (wayland_enabled)
4e44f9
+                                                g_ptr_array_add (supported_session_types, "wayland");
4e44f9
+                                }
4e44f9
+                        }
4e44f9
+
4e44f9
+                        g_ptr_array_add (supported_session_types, NULL);
4e44f9
+
4e44f9
+                        display = gdm_local_display_new ();
4e44f9
                         g_object_set (G_OBJECT (display), "session-type", session_type, NULL);
4e44f9
+                        g_object_set (G_OBJECT (display), "supported-session-types", supported_session_types->pdata, NULL);
4e44f9
                 }
4e44f9
         }
4e44f9
 #endif
4e44f9
 
4e44f9
         if (display == NULL) {
4e44f9
                 guint32 num;
4e44f9
+                const char *supported_session_types[] = { "x11", NULL };
4e44f9
 
4e44f9
                 num = take_next_display_number (factory);
4e44f9
 
4e44f9
                 display = gdm_legacy_display_new (num);
4e44f9
+                g_object_set (G_OBJECT (display), "supported-session-types", supported_session_types, NULL);
4e44f9
         }
4e44f9
 
4e44f9
         g_object_set (display, "seat-id", seat_id, NULL);
4e44f9
         g_object_set (display, "is-initial", is_seat0, NULL);
4e44f9
 
4e44f9
         store_display (factory, display);
4e44f9
 
4e44f9
         /* let store own the ref */
4e44f9
         g_object_unref (display);
4e44f9
 
4e44f9
         if (! gdm_display_manage (display)) {
4e44f9
                 gdm_display_unmanage (display);
4e44f9
         }
4e44f9
 
4e44f9
         return;
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 delete_display (GdmLocalDisplayFactory *factory,
4e44f9
                 const char             *seat_id) {
4e44f9
 
4e44f9
         GdmDisplayStore *store;
4e44f9
 
4e44f9
         g_debug ("GdmLocalDisplayFactory: Removing used_display_numbers on seat %s", seat_id);
4e44f9
 
4e44f9
         store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
4e44f9
         gdm_display_store_foreach_remove (store, lookup_by_seat_id, (gpointer) seat_id);
4e44f9
 }
4e44f9
 
4e44f9
 static gboolean
4e44f9
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
4e44f9
index 9c10adff3..4c2752fee 100644
4e44f9
--- a/daemon/gdm-manager.c
4e44f9
+++ b/daemon/gdm-manager.c
4e44f9
@@ -1306,74 +1306,75 @@ get_automatic_login_details (GdmManager *manager,
4e44f9
                 *usernamep = username;
4e44f9
         } else {
4e44f9
                 g_free (username);
4e44f9
         }
4e44f9
 
4e44f9
         return enabled;
4e44f9
 }
4e44f9
 
4e44f9
 static const char *
4e44f9
 get_username_for_greeter_display (GdmManager *manager,
4e44f9
                                   GdmDisplay *display)
4e44f9
 {
4e44f9
         gboolean doing_initial_setup = FALSE;
4e44f9
 
4e44f9
         g_object_get (G_OBJECT (display),
4e44f9
                       "doing-initial-setup", &doing_initial_setup,
4e44f9
                       NULL);
4e44f9
 
4e44f9
         if (doing_initial_setup) {
4e44f9
                 return INITIAL_SETUP_USERNAME;
4e44f9
         } else {
4e44f9
                 return GDM_USERNAME;
4e44f9
         }
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 set_up_automatic_login_session (GdmManager *manager,
4e44f9
                                 GdmDisplay *display)
4e44f9
 {
4e44f9
         GdmSession *session;
4e44f9
-        char       *display_session_type = NULL;
4e44f9
+        g_auto (GStrv) supported_session_types = NULL;
4e44f9
 
4e44f9
         /* 0 is root user; since the daemon talks to the session object
4e44f9
          * directly, itself, for automatic login
4e44f9
          */
4e44f9
         create_user_session_for_display (manager, display, 0);
4e44f9
         session = get_user_session_for_display (display);
4e44f9
 
4e44f9
         g_object_get (G_OBJECT (display),
4e44f9
-                      "session-type", &display_session_type,
4e44f9
+                      "supported-session-types", &supported_session_types,
4e44f9
                       NULL);
4e44f9
 
4e44f9
         g_object_set (G_OBJECT (session),
4e44f9
                       "display-is-initial", FALSE,
4e44f9
+                      "supported-session-types", supported_session_types,
4e44f9
                       NULL);
4e44f9
 
4e44f9
         g_debug ("GdmManager: Starting automatic login conversation");
4e44f9
         gdm_session_start_conversation (session, "gdm-autologin");
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 set_up_chooser_session (GdmManager *manager,
4e44f9
                         GdmDisplay *display)
4e44f9
 {
4e44f9
         const char *allowed_user;
4e44f9
         struct passwd *passwd_entry;
4e44f9
 
4e44f9
         allowed_user = get_username_for_greeter_display (manager, display);
4e44f9
 
4e44f9
         if (!gdm_get_pwent_for_name (allowed_user, &passwd_entry)) {
4e44f9
                 g_warning ("GdmManager: couldn't look up username %s",
4e44f9
                            allowed_user);
4e44f9
                 gdm_display_unmanage (display);
4e44f9
                 gdm_display_finish (display);
4e44f9
                 return;
4e44f9
         }
4e44f9
 
4e44f9
         gdm_display_start_greeter_session (display);
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 set_up_greeter_session (GdmManager *manager,
4e44f9
                         GdmDisplay *display)
4e44f9
 {
4e44f9
@@ -2278,87 +2279,85 @@ on_session_reauthentication_started (GdmSession *session,
4e44f9
 
4e44f9
         if (invocation != NULL) {
4e44f9
                 g_hash_table_steal (manager->priv->open_reauthentication_requests,
4e44f9
                                     source_tag);
4e44f9
                 gdm_dbus_manager_complete_open_reauthentication_channel (GDM_DBUS_MANAGER (manager),
4e44f9
                                                                          invocation,
4e44f9
                                                                          address);
4e44f9
         }
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 clean_user_session (GdmSession *session)
4e44f9
 {
4e44f9
         g_object_set_data (G_OBJECT (session), "gdm-display", NULL);
4e44f9
         g_object_unref (session);
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 create_user_session_for_display (GdmManager *manager,
4e44f9
                                  GdmDisplay *display,
4e44f9
                                  uid_t       allowed_user)
4e44f9
 {
4e44f9
         GdmSession *session;
4e44f9
         gboolean    display_is_local = FALSE;
4e44f9
         char       *display_name = NULL;
4e44f9
         char       *display_device = NULL;
4e44f9
         char       *remote_hostname = NULL;
4e44f9
         char       *display_auth_file = NULL;
4e44f9
         char       *display_seat_id = NULL;
4e44f9
         char       *display_id = NULL;
4e44f9
-#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
4e44f9
-        g_autofree char *display_session_type = NULL;
4e44f9
-        gboolean    greeter_is_wayland;
4e44f9
-#endif
4e44f9
+        g_auto (GStrv) supported_session_types = NULL;
4e44f9
 
4e44f9
         g_object_get (G_OBJECT (display),
4e44f9
                       "id", &display_id,
4e44f9
                       "x11-display-name", &display_name,
4e44f9
                       "is-local", &display_is_local,
4e44f9
                       "remote-hostname", &remote_hostname,
4e44f9
                       "x11-authority-file", &display_auth_file,
4e44f9
                       "seat-id", &display_seat_id,
4e44f9
-#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
4e44f9
-                      "session-type", &display_session_type,
4e44f9
-#endif
4e44f9
+                      "supported-session-types", &supported_session_types,
4e44f9
                       NULL);
4e44f9
         display_device = get_display_device (manager, display);
4e44f9
 
4e44f9
         session = gdm_session_new (GDM_SESSION_VERIFICATION_MODE_LOGIN,
4e44f9
                                    allowed_user,
4e44f9
                                    display_name,
4e44f9
                                    remote_hostname,
4e44f9
                                    display_device,
4e44f9
                                    display_seat_id,
4e44f9
                                    display_auth_file,
4e44f9
                                    display_is_local,
4e44f9
                                    NULL);
4e44f9
+        g_object_set (G_OBJECT (session),
4e44f9
+                      "supported-session-types", supported_session_types,
4e44f9
+                      NULL);
4e44f9
 
4e44f9
         g_debug ("GdmSession: Created user session for user %d on display %s (seat %s)",
4e44f9
                  (int) allowed_user,
4e44f9
                  display_id,
4e44f9
                  display_seat_id);
4e44f9
 
4e44f9
         g_free (display_name);
4e44f9
         g_free (remote_hostname);
4e44f9
         g_free (display_auth_file);
4e44f9
         g_free (display_seat_id);
4e44f9
 
4e44f9
         g_signal_connect (session,
4e44f9
                           "reauthentication-started",
4e44f9
                           G_CALLBACK (on_session_reauthentication_started),
4e44f9
                           manager);
4e44f9
         g_signal_connect (session,
4e44f9
                           "reauthenticated",
4e44f9
                           G_CALLBACK (on_session_reauthenticated),
4e44f9
                           manager);
4e44f9
         g_signal_connect (session,
4e44f9
                           "client-ready-for-session-to-start",
4e44f9
                           G_CALLBACK (on_session_client_ready_for_session_to_start),
4e44f9
                           manager);
4e44f9
         g_signal_connect (session,
4e44f9
                           "client-connected",
4e44f9
                           G_CALLBACK (on_session_client_connected),
4e44f9
                           manager);
4e44f9
         g_signal_connect (session,
4e44f9
                           "client-disconnected",
4e44f9
                           G_CALLBACK (on_session_client_disconnected),
4e44f9
@@ -2378,65 +2377,60 @@ create_user_session_for_display (GdmManager *manager,
4e44f9
         g_signal_connect (session,
4e44f9
                           "authentication-failed",
4e44f9
                           G_CALLBACK (on_session_authentication_failed),
4e44f9
                           manager);
4e44f9
         g_signal_connect (session,
4e44f9
                           "session-opened",
4e44f9
                           G_CALLBACK (on_user_session_opened),
4e44f9
                           manager);
4e44f9
         g_signal_connect (session,
4e44f9
                           "session-started",
4e44f9
                           G_CALLBACK (on_user_session_started),
4e44f9
                           manager);
4e44f9
         g_signal_connect (session,
4e44f9
                           "session-start-failed",
4e44f9
                           G_CALLBACK (on_session_start_failed),
4e44f9
                           manager);
4e44f9
         g_signal_connect (session,
4e44f9
                           "session-exited",
4e44f9
                           G_CALLBACK (on_user_session_exited),
4e44f9
                           manager);
4e44f9
         g_signal_connect (session,
4e44f9
                           "session-died",
4e44f9
                           G_CALLBACK (on_user_session_died),
4e44f9
                           manager);
4e44f9
         g_object_set_data (G_OBJECT (session), "gdm-display", display);
4e44f9
         g_object_set_data_full (G_OBJECT (display),
4e44f9
                                 "gdm-user-session",
4e44f9
                                 session,
4e44f9
                                 (GDestroyNotify)
4e44f9
                                 clean_user_session);
4e44f9
-
4e44f9
-#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
4e44f9
-        greeter_is_wayland = g_strcmp0 (display_session_type, "wayland") == 0;
4e44f9
-        g_object_set (G_OBJECT (session), "ignore-wayland", !greeter_is_wayland, NULL);
4e44f9
-#endif
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 on_display_added (GdmDisplayStore *display_store,
4e44f9
                   const char      *id,
4e44f9
                   GdmManager      *manager)
4e44f9
 {
4e44f9
         GdmDisplay *display;
4e44f9
 
4e44f9
         display = gdm_display_store_lookup (display_store, id);
4e44f9
 
4e44f9
         if (display != NULL) {
4e44f9
                 g_dbus_object_manager_server_export (manager->priv->object_manager,
4e44f9
                                                      gdm_display_get_object_skeleton (display));
4e44f9
 
4e44f9
                 g_signal_connect (display, "notify::status",
4e44f9
                                   G_CALLBACK (on_display_status_changed),
4e44f9
                                   manager);
4e44f9
                 g_signal_emit (manager, signals[DISPLAY_ADDED], 0, id);
4e44f9
         }
4e44f9
 }
4e44f9
 
4e44f9
 GQuark
4e44f9
 gdm_manager_error_quark (void)
4e44f9
 {
4e44f9
         static GQuark ret = 0;
4e44f9
         if (ret == 0) {
4e44f9
                 ret = g_quark_from_static_string ("gdm_manager_error");
4e44f9
         }
4e44f9
 
4e44f9
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
4e44f9
index a010cecf5..2b941e5e1 100644
4e44f9
--- a/daemon/gdm-session.c
4e44f9
+++ b/daemon/gdm-session.c
4e44f9
@@ -106,84 +106,81 @@ struct _GdmSession
4e44f9
         GdmDBusUserVerifier   *user_verifier_interface;
4e44f9
         GHashTable            *user_verifier_extensions;
4e44f9
         GdmDBusGreeter        *greeter_interface;
4e44f9
         GdmDBusRemoteGreeter  *remote_greeter_interface;
4e44f9
         GdmDBusChooser        *chooser_interface;
4e44f9
 
4e44f9
         GList               *pending_worker_connections;
4e44f9
         GList               *outside_connections;
4e44f9
 
4e44f9
         GPid                 session_pid;
4e44f9
 
4e44f9
         /* object lifetime scope */
4e44f9
         char                *session_type;
4e44f9
         char                *display_name;
4e44f9
         char                *display_hostname;
4e44f9
         char                *display_device;
4e44f9
         char                *display_seat_id;
4e44f9
         char                *display_x11_authority_file;
4e44f9
         gboolean             display_is_local;
4e44f9
 
4e44f9
         GdmSessionVerificationMode verification_mode;
4e44f9
 
4e44f9
         uid_t                allowed_user;
4e44f9
 
4e44f9
         char                *fallback_session_name;
4e44f9
 
4e44f9
         GDBusServer         *worker_server;
4e44f9
         GDBusServer         *outside_server;
4e44f9
         GHashTable          *environment;
4e44f9
 
4e44f9
+        GStrv                supported_session_types;
4e44f9
+
4e44f9
         guint32              is_program_session : 1;
4e44f9
         guint32              display_is_initial : 1;
4e44f9
-#ifdef ENABLE_WAYLAND_SUPPORT
4e44f9
-        guint32              ignore_wayland : 1;
4e44f9
-#endif
4e44f9
 };
4e44f9
 
4e44f9
 enum {
4e44f9
         PROP_0,
4e44f9
         PROP_VERIFICATION_MODE,
4e44f9
         PROP_ALLOWED_USER,
4e44f9
         PROP_DISPLAY_NAME,
4e44f9
         PROP_DISPLAY_HOSTNAME,
4e44f9
         PROP_DISPLAY_IS_LOCAL,
4e44f9
         PROP_DISPLAY_IS_INITIAL,
4e44f9
         PROP_SESSION_TYPE,
4e44f9
         PROP_DISPLAY_DEVICE,
4e44f9
         PROP_DISPLAY_SEAT_ID,
4e44f9
         PROP_DISPLAY_X11_AUTHORITY_FILE,
4e44f9
         PROP_USER_X11_AUTHORITY_FILE,
4e44f9
         PROP_CONVERSATION_ENVIRONMENT,
4e44f9
-#ifdef ENABLE_WAYLAND_SUPPORT
4e44f9
-        PROP_IGNORE_WAYLAND,
4e44f9
-#endif
4e44f9
+        PROP_SUPPORTED_SESSION_TYPES,
4e44f9
 };
4e44f9
 
4e44f9
 enum {
4e44f9
         CONVERSATION_STARTED = 0,
4e44f9
         CONVERSATION_STOPPED,
4e44f9
         SETUP_COMPLETE,
4e44f9
         CANCELLED,
4e44f9
         HOSTNAME_SELECTED,
4e44f9
         CLIENT_REJECTED,
4e44f9
         CLIENT_CONNECTED,
4e44f9
         CLIENT_DISCONNECTED,
4e44f9
         CLIENT_READY_FOR_SESSION_TO_START,
4e44f9
         DISCONNECTED,
4e44f9
         AUTHENTICATION_FAILED,
4e44f9
         VERIFICATION_COMPLETE,
4e44f9
         SESSION_OPENED,
4e44f9
         SESSION_OPENED_FAILED,
4e44f9
         SESSION_STARTED,
4e44f9
         SESSION_START_FAILED,
4e44f9
         SESSION_EXITED,
4e44f9
         SESSION_DIED,
4e44f9
         REAUTHENTICATION_STARTED,
4e44f9
         REAUTHENTICATED,
4e44f9
         LAST_SIGNAL
4e44f9
 };
4e44f9
 
4e44f9
 #ifdef ENABLE_WAYLAND_SUPPORT
4e44f9
 static gboolean gdm_session_is_wayland_session (GdmSession *self);
4e44f9
 #endif
4e44f9
 static void update_session_type (GdmSession *self);
4e44f9
@@ -320,109 +317,117 @@ on_establish_credentials_cb (GdmDBusWorker *proxy,
4e44f9
             g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
4e44f9
                 return;
4e44f9
 
4e44f9
         self = g_object_ref (conversation->session);
4e44f9
         service_name = g_strdup (conversation->service_name);
4e44f9
 
4e44f9
         if (worked) {
4e44f9
                 switch (self->verification_mode) {
4e44f9
                 case GDM_SESSION_VERIFICATION_MODE_LOGIN:
4e44f9
                 case GDM_SESSION_VERIFICATION_MODE_CHOOSER:
4e44f9
                         gdm_session_open_session (self, service_name);
4e44f9
                         break;
4e44f9
                 case GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE:
4e44f9
                         if (self->user_verifier_interface != NULL) {
4e44f9
                                 gdm_dbus_user_verifier_emit_verification_complete (self->user_verifier_interface,
4e44f9
                                                                                    service_name);
4e44f9
                                 g_signal_emit (self, signals[VERIFICATION_COMPLETE], 0, service_name);
4e44f9
                         }
4e44f9
                         break;
4e44f9
                 default:
4e44f9
                         break;
4e44f9
                 }
4e44f9
         } else {
4e44f9
                 report_and_stop_conversation (self, service_name, error);
4e44f9
         }
4e44f9
 
4e44f9
         g_free (service_name);
4e44f9
         g_object_unref (self);
4e44f9
 }
4e44f9
 
4e44f9
+static gboolean
4e44f9
+supports_session_type (GdmSession *self,
4e44f9
+                       const char *session_type)
4e44f9
+{
4e44f9
+        if (session_type == NULL)
4e44f9
+                return TRUE;
4e44f9
+
4e44f9
+        return g_strv_contains ((const char * const *) self->supported_session_types,
4e44f9
+                                session_type);
4e44f9
+}
4e44f9
+
4e44f9
 static char **
4e44f9
 get_system_session_dirs (GdmSession *self,
4e44f9
                          const char *type)
4e44f9
 {
4e44f9
         GArray *search_array = NULL;
4e44f9
         char **search_dirs;
4e44f9
-        int i;
4e44f9
+        int i, j;
4e44f9
         const gchar * const *system_data_dirs = g_get_system_data_dirs ();
4e44f9
 
4e44f9
         static const char *x_search_dirs[] = {
4e44f9
                 "/etc/X11/sessions/",
4e44f9
                 DMCONFDIR "/Sessions/",
4e44f9
                 DATADIR "/gdm/BuiltInSessions/",
4e44f9
                 DATADIR "/xsessions/",
4e44f9
         };
4e44f9
 
4e44f9
         static const char *wayland_search_dir = DATADIR "/wayland-sessions/";
4e44f9
 
4e44f9
         search_array = g_array_new (TRUE, TRUE, sizeof (char *));
4e44f9
 
4e44f9
-        if (type == NULL || g_str_equal (type, "x11")) {
4e44f9
-                for (i = 0; system_data_dirs[i]; i++) {
4e44f9
-                        gchar *dir = g_build_filename (system_data_dirs[i], "xsessions", NULL);
4e44f9
-                        g_array_append_val (search_array, dir);
4e44f9
+        for (j = 0; self->supported_session_types[j] != NULL; j++) {
4e44f9
+                const char *supported_type = self->supported_session_types[j];
4e44f9
+
4e44f9
+                if (g_str_equal (supported_type, "x11") &&
4e44f9
+                    (type == NULL || g_str_equal (type, supported_type))) {
4e44f9
+                        for (i = 0; system_data_dirs[i]; i++) {
4e44f9
+                                gchar *dir = g_build_filename (system_data_dirs[i], "xsessions", NULL);
4e44f9
+                                g_array_append_val (search_array, dir);
4e44f9
+                        }
4e44f9
+
4e44f9
+                        g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs));
4e44f9
                 }
4e44f9
 
4e44f9
-                g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs));
4e44f9
-        }
4e44f9
 
4e44f9
 #ifdef ENABLE_WAYLAND_SUPPORT
4e44f9
-        if (!self->ignore_wayland &&
4e44f9
-            (type == NULL || g_str_equal (type, "wayland"))) {
4e44f9
-#ifdef ENABLE_USER_DISPLAY_SERVER
4e44f9
-                g_array_prepend_val (search_array, wayland_search_dir);
4e44f9
+                if (g_str_equal (supported_type, "wayland") &&
4e44f9
+                    (type == NULL || g_str_equal (type, supported_type))) {
4e44f9
+                        for (i = 0; system_data_dirs[i]; i++) {
4e44f9
+                                gchar *dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL);
4e44f9
+                                g_array_append_val (search_array, dir);
4e44f9
+                        }
4e44f9
 
4e44f9
-                for (i = 0; system_data_dirs[i]; i++) {
4e44f9
-                        gchar *dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL);
4e44f9
-                        g_array_insert_val (search_array, i, dir);
4e44f9
+                        g_array_append_val (search_array, wayland_search_dir);
4e44f9
                 }
4e44f9
-#else
4e44f9
-                for (i = 0; system_data_dirs[i]; i++) {
4e44f9
-                        gchar *dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL);
4e44f9
-                        g_array_append_val (search_array, dir);
4e44f9
-                }
4e44f9
-
4e44f9
-                g_array_append_val (search_array, wayland_search_dir);
4e44f9
 #endif
4e44f9
         }
4e44f9
-#endif
4e44f9
 
4e44f9
         search_dirs = g_strdupv ((char **) search_array->data);
4e44f9
 
4e44f9
         g_array_free (search_array, TRUE);
4e44f9
 
4e44f9
         return search_dirs;
4e44f9
 }
4e44f9
 
4e44f9
 static gboolean
4e44f9
 is_prog_in_path (const char *prog)
4e44f9
 {
4e44f9
         char    *f;
4e44f9
         gboolean ret;
4e44f9
 
4e44f9
         f = g_find_program_in_path (prog);
4e44f9
         ret = (f != NULL);
4e44f9
         g_free (f);
4e44f9
         return ret;
4e44f9
 }
4e44f9
 
4e44f9
 static GKeyFile *
4e44f9
 load_key_file_for_file (GdmSession   *self,
4e44f9
                         const char   *file,
4e44f9
                         const char   *type,
4e44f9
                         char        **full_path)
4e44f9
 {
4e44f9
         GKeyFile   *key_file;
4e44f9
         GError     *error = NULL;
4e44f9
         gboolean    res;
4e44f9
         char      **search_dirs;
4e44f9
@@ -444,60 +449,66 @@ load_key_file_for_file (GdmSession   *self,
4e44f9
                         g_debug ("GdmSession: %s", error->message);
4e44f9
                         g_error_free (error);
4e44f9
                 }
4e44f9
                 g_key_file_free (key_file);
4e44f9
                 key_file = NULL;
4e44f9
         }
4e44f9
 
4e44f9
         g_strfreev (search_dirs);
4e44f9
 
4e44f9
         return key_file;
4e44f9
 }
4e44f9
 
4e44f9
 static gboolean
4e44f9
 get_session_command_for_file (GdmSession  *self,
4e44f9
                               const char  *file,
4e44f9
                               const char  *type,
4e44f9
                               char       **command)
4e44f9
 {
4e44f9
         GKeyFile   *key_file;
4e44f9
         GError     *error;
4e44f9
         char       *exec;
4e44f9
         gboolean    ret;
4e44f9
         gboolean    res;
4e44f9
 
4e44f9
         exec = NULL;
4e44f9
         ret = FALSE;
4e44f9
         if (command != NULL) {
4e44f9
                 *command = NULL;
4e44f9
         }
4e44f9
 
4e44f9
+        if (!supports_session_type (self, type)) {
4e44f9
+                g_debug ("GdmSession: ignoring %s session command request for file '%s'",
4e44f9
+                         type, file);
4e44f9
+                goto out;
4e44f9
+        }
4e44f9
+
4e44f9
         g_debug ("GdmSession: getting session command for file '%s'", file);
4e44f9
         key_file = load_key_file_for_file (self, file, type, NULL);
4e44f9
         if (key_file == NULL) {
4e44f9
                 goto out;
4e44f9
         }
4e44f9
 
4e44f9
         error = NULL;
4e44f9
         res = g_key_file_get_boolean (key_file,
4e44f9
                                       G_KEY_FILE_DESKTOP_GROUP,
4e44f9
                                       G_KEY_FILE_DESKTOP_KEY_HIDDEN,
4e44f9
                                       &error);
4e44f9
         if (error == NULL && res) {
4e44f9
                 g_debug ("GdmSession: Session %s is marked as hidden", file);
4e44f9
                 goto out;
4e44f9
         }
4e44f9
 
4e44f9
         exec = g_key_file_get_string (key_file,
4e44f9
                                       G_KEY_FILE_DESKTOP_GROUP,
4e44f9
                                       G_KEY_FILE_DESKTOP_KEY_TRY_EXEC,
4e44f9
                                       NULL);
4e44f9
         if (exec != NULL) {
4e44f9
                 res = is_prog_in_path (exec);
4e44f9
                 g_free (exec);
4e44f9
                 exec = NULL;
4e44f9
 
4e44f9
                 if (! res) {
4e44f9
                         g_debug ("GdmSession: Command not found: %s",
4e44f9
                                  G_KEY_FILE_DESKTOP_KEY_TRY_EXEC);
4e44f9
                         goto out;
4e44f9
                 }
4e44f9
@@ -2230,68 +2241,72 @@ close_conversation (GdmSessionConversation *conversation)
4e44f9
 
4e44f9
         if (conversation->worker_manager_interface != NULL) {
4e44f9
                 unexport_worker_manager_interface (self, conversation->worker_manager_interface);
4e44f9
                 g_clear_object (&conversation->worker_manager_interface);
4e44f9
         }
4e44f9
 
4e44f9
         if (conversation->worker_proxy != NULL) {
4e44f9
                 GDBusConnection *connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (conversation->worker_proxy));
4e44f9
                 g_dbus_connection_close_sync (connection, NULL, NULL);
4e44f9
         }
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 stop_conversation (GdmSessionConversation *conversation)
4e44f9
 {
4e44f9
         close_conversation (conversation);
4e44f9
 
4e44f9
         conversation->is_stopping = TRUE;
4e44f9
         gdm_session_worker_job_stop (conversation->job);
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 stop_conversation_now (GdmSessionConversation *conversation)
4e44f9
 {
4e44f9
         close_conversation (conversation);
4e44f9
 
4e44f9
         gdm_session_worker_job_stop_now (conversation->job);
4e44f9
         g_clear_object (&conversation->job);
4e44f9
 }
4e44f9
 
4e44f9
-#ifdef ENABLE_WAYLAND_SUPPORT
4e44f9
 void
4e44f9
-gdm_session_set_ignore_wayland (GdmSession *self,
4e44f9
-                                gboolean    ignore_wayland)
4e44f9
+gdm_session_set_supported_session_types (GdmSession         *self,
4e44f9
+                                         const char * const *supported_session_types)
4e44f9
 {
4e44f9
-        self->ignore_wayland = ignore_wayland;
4e44f9
+        const char * const session_types[] = { "wayland", "x11", NULL };
4e44f9
+        g_strfreev (self->supported_session_types);
4e44f9
+
4e44f9
+        if (supported_session_types == NULL)
4e44f9
+                self->supported_session_types = g_strdupv ((GStrv) session_types);
4e44f9
+        else
4e44f9
+                self->supported_session_types = g_strdupv ((GStrv) supported_session_types);
4e44f9
 }
4e44f9
-#endif
4e44f9
 
4e44f9
 gboolean
4e44f9
 gdm_session_start_conversation (GdmSession *self,
4e44f9
                                 const char *service_name)
4e44f9
 {
4e44f9
         GdmSessionConversation *conversation;
4e44f9
 
4e44f9
         g_return_val_if_fail (GDM_IS_SESSION (self), FALSE);
4e44f9
 
4e44f9
         conversation = g_hash_table_lookup (self->conversations,
4e44f9
                                             service_name);
4e44f9
 
4e44f9
         if (conversation != NULL) {
4e44f9
                 if (!conversation->is_stopping) {
4e44f9
                         g_warning ("GdmSession: conversation %s started more than once", service_name);
4e44f9
                         return FALSE;
4e44f9
                 }
4e44f9
                 g_debug ("GdmSession: stopping old conversation %s", service_name);
4e44f9
                 gdm_session_worker_job_stop_now (conversation->job);
4e44f9
                 g_object_unref (conversation->job);
4e44f9
                 conversation->job = NULL;
4e44f9
         }
4e44f9
 
4e44f9
         g_debug ("GdmSession: starting conversation %s for session (%p)", service_name, self);
4e44f9
 
4e44f9
         conversation = start_conversation (self, service_name);
4e44f9
 
4e44f9
         g_hash_table_insert (self->conversations,
4e44f9
                              g_strdup (service_name), conversation);
4e44f9
         return TRUE;
4e44f9
@@ -3162,69 +3177,69 @@ gdm_session_get_session_id (GdmSession *self)
4e44f9
 
4e44f9
 const char *
4e44f9
 gdm_session_get_conversation_session_id (GdmSession *self,
4e44f9
                                          const char *service_name)
4e44f9
 {
4e44f9
         GdmSessionConversation *conversation;
4e44f9
 
4e44f9
         g_return_val_if_fail (GDM_IS_SESSION (self), NULL);
4e44f9
 
4e44f9
         conversation = find_conversation_by_name (self, service_name);
4e44f9
 
4e44f9
         if (conversation == NULL) {
4e44f9
                 return NULL;
4e44f9
         }
4e44f9
 
4e44f9
         return conversation->session_id;
4e44f9
 }
4e44f9
 
4e44f9
 static char *
4e44f9
 get_session_filename (GdmSession *self)
4e44f9
 {
4e44f9
         return g_strdup_printf ("%s.desktop", get_session_name (self));
4e44f9
 }
4e44f9
 
4e44f9
 #ifdef ENABLE_WAYLAND_SUPPORT
4e44f9
 static gboolean
4e44f9
 gdm_session_is_wayland_session (GdmSession *self)
4e44f9
 {
4e44f9
         GKeyFile   *key_file;
4e44f9
         gboolean    is_wayland_session = FALSE;
4e44f9
-        char       *filename;
4e44f9
-        char       *full_path = NULL;
4e44f9
+        char            *filename;
4e44f9
+        g_autofree char *full_path = NULL;
4e44f9
 
4e44f9
         g_return_val_if_fail (self != NULL, FALSE);
4e44f9
         g_return_val_if_fail (GDM_IS_SESSION (self), FALSE);
4e44f9
 
4e44f9
         filename = get_session_filename (self);
4e44f9
 
4e44f9
-        key_file = load_key_file_for_file (self, filename, "wayland", &full_path);
4e44f9
+        key_file = load_key_file_for_file (self, filename, NULL, &full_path);
4e44f9
 
4e44f9
         if (key_file == NULL) {
4e44f9
                 goto out;
4e44f9
         }
4e44f9
 
4e44f9
         if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) {
4e44f9
                 is_wayland_session = TRUE;
4e44f9
         }
4e44f9
         g_debug ("GdmSession: checking if file '%s' is wayland session: %s", filename, is_wayland_session? "yes" : "no");
4e44f9
 
4e44f9
 out:
4e44f9
         g_clear_pointer (&key_file, g_key_file_free);
4e44f9
         g_free (filename);
4e44f9
         return is_wayland_session;
4e44f9
 }
4e44f9
 #endif
4e44f9
 
4e44f9
 static void
4e44f9
 update_session_type (GdmSession *self)
4e44f9
 {
4e44f9
 #ifdef ENABLE_WAYLAND_SUPPORT
4e44f9
         gboolean is_wayland_session = FALSE;
4e44f9
 
4e44f9
         is_wayland_session = gdm_session_is_wayland_session (self);
4e44f9
 
4e44f9
         if (is_wayland_session) {
4e44f9
                 set_session_type (self, "wayland");
4e44f9
         } else {
4e44f9
                 set_session_type (self, NULL);
4e44f9
         }
4e44f9
@@ -3513,140 +3528,138 @@ gdm_session_set_property (GObject      *object,
4e44f9
         case PROP_DISPLAY_HOSTNAME:
4e44f9
                 set_display_hostname (self, g_value_get_string (value));
4e44f9
                 break;
4e44f9
         case PROP_DISPLAY_DEVICE:
4e44f9
                 set_display_device (self, g_value_get_string (value));
4e44f9
                 break;
4e44f9
         case PROP_DISPLAY_SEAT_ID:
4e44f9
                 set_display_seat_id (self, g_value_get_string (value));
4e44f9
                 break;
4e44f9
         case PROP_USER_X11_AUTHORITY_FILE:
4e44f9
                 set_user_x11_authority_file (self, g_value_get_string (value));
4e44f9
                 break;
4e44f9
         case PROP_DISPLAY_X11_AUTHORITY_FILE:
4e44f9
                 set_display_x11_authority_file (self, g_value_get_string (value));
4e44f9
                 break;
4e44f9
         case PROP_DISPLAY_IS_LOCAL:
4e44f9
                 set_display_is_local (self, g_value_get_boolean (value));
4e44f9
                 break;
4e44f9
         case PROP_DISPLAY_IS_INITIAL:
4e44f9
                 set_display_is_initial (self, g_value_get_boolean (value));
4e44f9
                 break;
4e44f9
         case PROP_VERIFICATION_MODE:
4e44f9
                 set_verification_mode (self, g_value_get_enum (value));
4e44f9
                 break;
4e44f9
         case PROP_ALLOWED_USER:
4e44f9
                 set_allowed_user (self, g_value_get_uint (value));
4e44f9
                 break;
4e44f9
         case PROP_CONVERSATION_ENVIRONMENT:
4e44f9
                 set_conversation_environment (self, g_value_get_pointer (value));
4e44f9
                 break;
4e44f9
-#ifdef ENABLE_WAYLAND_SUPPORT
4e44f9
-        case PROP_IGNORE_WAYLAND:
4e44f9
-                gdm_session_set_ignore_wayland (self, g_value_get_boolean (value));
4e44f9
+        case PROP_SUPPORTED_SESSION_TYPES:
4e44f9
+                gdm_session_set_supported_session_types (self, g_value_get_boxed (value));
4e44f9
                 break;
4e44f9
-#endif
4e44f9
         default:
4e44f9
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
4e44f9
                 break;
4e44f9
         }
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 gdm_session_get_property (GObject    *object,
4e44f9
                           guint       prop_id,
4e44f9
                           GValue     *value,
4e44f9
                           GParamSpec *pspec)
4e44f9
 {
4e44f9
         GdmSession *self;
4e44f9
 
4e44f9
         self = GDM_SESSION (object);
4e44f9
 
4e44f9
         switch (prop_id) {
4e44f9
         case PROP_SESSION_TYPE:
4e44f9
                 g_value_set_string (value, self->session_type);
4e44f9
                 break;
4e44f9
         case PROP_DISPLAY_NAME:
4e44f9
                 g_value_set_string (value, self->display_name);
4e44f9
                 break;
4e44f9
         case PROP_DISPLAY_HOSTNAME:
4e44f9
                 g_value_set_string (value, self->display_hostname);
4e44f9
                 break;
4e44f9
         case PROP_DISPLAY_DEVICE:
4e44f9
                 g_value_set_string (value, self->display_device);
4e44f9
                 break;
4e44f9
         case PROP_DISPLAY_SEAT_ID:
4e44f9
                 g_value_set_string (value, self->display_seat_id);
4e44f9
                 break;
4e44f9
         case PROP_USER_X11_AUTHORITY_FILE:
4e44f9
                 g_value_set_string (value, self->user_x11_authority_file);
4e44f9
                 break;
4e44f9
         case PROP_DISPLAY_X11_AUTHORITY_FILE:
4e44f9
                 g_value_set_string (value, self->display_x11_authority_file);
4e44f9
                 break;
4e44f9
         case PROP_DISPLAY_IS_LOCAL:
4e44f9
                 g_value_set_boolean (value, self->display_is_local);
4e44f9
                 break;
4e44f9
         case PROP_DISPLAY_IS_INITIAL:
4e44f9
                 g_value_set_boolean (value, self->display_is_initial);
4e44f9
                 break;
4e44f9
         case PROP_VERIFICATION_MODE:
4e44f9
                 g_value_set_enum (value, self->verification_mode);
4e44f9
                 break;
4e44f9
         case PROP_ALLOWED_USER:
4e44f9
                 g_value_set_uint (value, self->allowed_user);
4e44f9
                 break;
4e44f9
         case PROP_CONVERSATION_ENVIRONMENT:
4e44f9
                 g_value_set_pointer (value, self->environment);
4e44f9
                 break;
4e44f9
-#ifdef ENABLE_WAYLAND_SUPPORT
4e44f9
-        case PROP_IGNORE_WAYLAND:
4e44f9
-                g_value_set_boolean (value, self->ignore_wayland);
4e44f9
+        case PROP_SUPPORTED_SESSION_TYPES:
4e44f9
+                g_value_set_boxed (value, self->supported_session_types);
4e44f9
                 break;
4e44f9
-#endif
4e44f9
         default:
4e44f9
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
4e44f9
                 break;
4e44f9
         }
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 gdm_session_dispose (GObject *object)
4e44f9
 {
4e44f9
         GdmSession *self;
4e44f9
 
4e44f9
         self = GDM_SESSION (object);
4e44f9
 
4e44f9
         g_debug ("GdmSession: Disposing session");
4e44f9
 
4e44f9
         gdm_session_close (self);
4e44f9
 
4e44f9
+        g_clear_pointer (&self->supported_session_types,
4e44f9
+                         g_strfreev);
4e44f9
         g_clear_pointer (&self->conversations,
4e44f9
                          g_hash_table_unref);
4e44f9
 
4e44f9
         g_clear_object (&self->user_verifier_interface);
4e44f9
         g_clear_pointer (&self->user_verifier_extensions,
4e44f9
                          g_hash_table_unref);
4e44f9
         g_clear_object (&self->greeter_interface);
4e44f9
         g_clear_object (&self->remote_greeter_interface);
4e44f9
         g_clear_object (&self->chooser_interface);
4e44f9
 
4e44f9
         g_free (self->display_name);
4e44f9
         self->display_name = NULL;
4e44f9
 
4e44f9
         g_free (self->display_hostname);
4e44f9
         self->display_hostname = NULL;
4e44f9
 
4e44f9
         g_free (self->display_device);
4e44f9
         self->display_device = NULL;
4e44f9
 
4e44f9
         g_free (self->display_seat_id);
4e44f9
         self->display_seat_id = NULL;
4e44f9
 
4e44f9
         g_free (self->display_x11_authority_file);
4e44f9
         self->display_x11_authority_file = NULL;
4e44f9
 
4e44f9
         g_strfreev (self->conversation_environment);
4e44f9
         self->conversation_environment = NULL;
4e44f9
 
4e44f9
         if (self->worker_server != NULL) {
4e44f9
                 g_dbus_server_stop (self->worker_server);
4e44f9
@@ -4007,69 +4020,67 @@ gdm_session_class_init (GdmSessionClass *session_class)
4e44f9
                                          PROP_DISPLAY_X11_AUTHORITY_FILE,
4e44f9
                                          g_param_spec_string ("display-x11-authority-file",
4e44f9
                                                               "display x11 authority file",
4e44f9
                                                               "display x11 authority file",
4e44f9
                                                               NULL,
4e44f9
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
4e44f9
         /* not construct only */
4e44f9
         g_object_class_install_property (object_class,
4e44f9
                                          PROP_USER_X11_AUTHORITY_FILE,
4e44f9
                                          g_param_spec_string ("user-x11-authority-file",
4e44f9
                                                               "",
4e44f9
                                                               "",
4e44f9
                                                               NULL,
4e44f9
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
4e44f9
         g_object_class_install_property (object_class,
4e44f9
                                          PROP_DISPLAY_DEVICE,
4e44f9
                                          g_param_spec_string ("display-device",
4e44f9
                                                               "display device",
4e44f9
                                                               "display device",
4e44f9
                                                               NULL,
4e44f9
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
4e44f9
 
4e44f9
         g_object_class_install_property (object_class,
4e44f9
                                          PROP_DISPLAY_SEAT_ID,
4e44f9
                                          g_param_spec_string ("display-seat-id",
4e44f9
                                                               "display seat id",
4e44f9
                                                               "display seat id",
4e44f9
                                                               NULL,
4e44f9
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
4e44f9
 
4e44f9
-#ifdef ENABLE_WAYLAND_SUPPORT
4e44f9
         g_object_class_install_property (object_class,
4e44f9
-                                         PROP_IGNORE_WAYLAND,
4e44f9
-                                         g_param_spec_boolean ("ignore-wayland",
4e44f9
-                                                               "ignore wayland",
4e44f9
-                                                               "ignore wayland",
4e44f9
-                                                               FALSE,
4e44f9
-                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
4e44f9
-#endif
4e44f9
+                                         PROP_SUPPORTED_SESSION_TYPES,
4e44f9
+                                         g_param_spec_boxed ("supported-session-types",
4e44f9
+                                                             "supported session types",
4e44f9
+                                                             "supported session types",
4e44f9
+                                                             G_TYPE_STRV,
4e44f9
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
4e44f9
 
4e44f9
         /* Ensure we can resolve errors */
4e44f9
         gdm_dbus_error_ensure (GDM_SESSION_WORKER_ERROR);
4e44f9
 }
4e44f9
 
4e44f9
 GdmSession *
4e44f9
 gdm_session_new (GdmSessionVerificationMode  verification_mode,
4e44f9
                  uid_t                       allowed_user,
4e44f9
                  const char                 *display_name,
4e44f9
                  const char                 *display_hostname,
4e44f9
                  const char                 *display_device,
4e44f9
                  const char                 *display_seat_id,
4e44f9
                  const char                 *display_x11_authority_file,
4e44f9
                  gboolean                    display_is_local,
4e44f9
                  const char * const         *environment)
4e44f9
 {
4e44f9
         GdmSession *self;
4e44f9
 
4e44f9
         self = g_object_new (GDM_TYPE_SESSION,
4e44f9
                              "verification-mode", verification_mode,
4e44f9
                              "allowed-user", (guint) allowed_user,
4e44f9
                              "display-name", display_name,
4e44f9
                              "display-hostname", display_hostname,
4e44f9
                              "display-device", display_device,
4e44f9
                              "display-seat-id", display_seat_id,
4e44f9
                              "display-x11-authority-file", display_x11_authority_file,
4e44f9
                              "display-is-local", display_is_local,
4e44f9
                              "conversation-environment", environment,
4e44f9
                              NULL);
4e44f9
 
4e44f9
diff --git a/data/gdm.schemas.in b/data/gdm.schemas.in
4e44f9
index 255bff023..a1035f95e 100644
4e44f9
--- a/data/gdm.schemas.in
4e44f9
+++ b/data/gdm.schemas.in
4e44f9
@@ -25,65 +25,75 @@
4e44f9
     <schema>
4e44f9
       <key>daemon/AutomaticLoginEnable</key>
4e44f9
       <signature>b</signature>
4e44f9
       <default>false</default>
4e44f9
     </schema>
4e44f9
     <schema>
4e44f9
       <key>daemon/AutomaticLogin</key>
4e44f9
       <signature>s</signature>
4e44f9
       <default></default>
4e44f9
     </schema>
4e44f9
     <schema>
4e44f9
       <key>daemon/TimedLoginEnable</key>
4e44f9
       <signature>b</signature>
4e44f9
       <default>false</default>
4e44f9
     </schema>
4e44f9
     <schema>
4e44f9
       <key>daemon/TimedLogin</key>
4e44f9
       <signature>s</signature>
4e44f9
       <default></default>
4e44f9
     </schema>
4e44f9
     <schema>
4e44f9
       <key>daemon/TimedLoginDelay</key>
4e44f9
       <signature>i</signature>
4e44f9
       <default>30</default>
4e44f9
     </schema>
4e44f9
     <schema>
4e44f9
       <key>daemon/InitialSetupEnable</key>
4e44f9
       <signature>b</signature>
4e44f9
       <default>true</default>
4e44f9
     </schema>
4e44f9
+    <schema>
4e44f9
+      <key>daemon/PreferredDisplayServer</key>
4e44f9
+      <signature>s</signature>
4e44f9
+      <default>wayland</default>
4e44f9
+    </schema>
4e44f9
     <schema>
4e44f9
       <key>daemon/WaylandEnable</key>
4e44f9
       <signature>b</signature>
4e44f9
       <default>true</default>
4e44f9
     </schema>
4e44f9
+    <schema>
4e44f9
+      <key>daemon/XorgEnable</key>
4e44f9
+      <signature>b</signature>
4e44f9
+      <default>true</default>
4e44f9
+    </schema>
4e44f9
     <schema>
4e44f9
       <key>security/AllowRemoteAutoLogin</key>
4e44f9
       <signature>b</signature>
4e44f9
       <default>false</default>
4e44f9
     </schema>
4e44f9
 
4e44f9
     <schema>
4e44f9
       <key>debug/Enable</key>
4e44f9
       <signature>b</signature>
4e44f9
       <default>false</default>
4e44f9
     </schema>
4e44f9
 
4e44f9
     <schema>
4e44f9
       <key>security/DisallowTCP</key>
4e44f9
       <signature>b</signature>
4e44f9
       <default>true</default>
4e44f9
     </schema>
4e44f9
     <schema>
4e44f9
       <key>xdmcp/Enable</key>
4e44f9
       <signature>b</signature>
4e44f9
       <default>false</default>
4e44f9
     </schema>
4e44f9
     <schema>
4e44f9
       <key>xdmcp/ShowLocalGreeter</key>
4e44f9
       <signature>b</signature>
4e44f9
       <default>true</default>
4e44f9
     </schema>
4e44f9
     <schema>
4e44f9
       <key>xdmcp/MaxPending</key>
4e44f9
       <signature>i</signature>
4e44f9
diff --git a/libgdm/gdm-sessions.c b/libgdm/gdm-sessions.c
4e44f9
index a13225050..f078e04b8 100644
4e44f9
--- a/libgdm/gdm-sessions.c
4e44f9
+++ b/libgdm/gdm-sessions.c
4e44f9
@@ -163,171 +163,203 @@ load_session_file (const char              *id,
4e44f9
 
4e44f9
 static gboolean
4e44f9
 remove_duplicate_sessions (gpointer key,
4e44f9
                            gpointer value,
4e44f9
                            gpointer user_data)
4e44f9
 {
4e44f9
         gboolean already_known;
4e44f9
         GHashTable *names_seen_before;
4e44f9
         GdmSessionFile *session;
4e44f9
 
4e44f9
         names_seen_before = (GHashTable *) user_data;
4e44f9
         session = (GdmSessionFile *) value;
4e44f9
         already_known = !g_hash_table_add (names_seen_before, session->translated_name);
4e44f9
 
4e44f9
         if (already_known)
4e44f9
                 g_debug ("GdmSession: Removing %s (%s) as we already have a session by this name",
4e44f9
                          session->id,
4e44f9
                          session->path);
4e44f9
 
4e44f9
         return already_known;
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 collect_sessions_from_directory (const char *dirname)
4e44f9
 {
4e44f9
         GDir       *dir;
4e44f9
         const char *filename;
4e44f9
 
4e44f9
         gboolean is_x11 = g_getenv ("WAYLAND_DISPLAY") == NULL &&
4e44f9
                           g_getenv ("RUNNING_UNDER_GDM") != NULL;
4e44f9
+        gboolean is_wayland = g_getenv ("WAYLAND_DISPLAY") != NULL &&
4e44f9
+                              g_getenv ("RUNNING_UNDER_GDM") != NULL;
4e44f9
 
4e44f9
         /* FIXME: add file monitor to directory */
4e44f9
 
4e44f9
         dir = g_dir_open (dirname, 0, NULL);
4e44f9
         if (dir == NULL) {
4e44f9
                 return;
4e44f9
         }
4e44f9
 
4e44f9
         while ((filename = g_dir_read_name (dir))) {
4e44f9
                 char *id;
4e44f9
                 char *full_path;
4e44f9
 
4e44f9
                 if (! g_str_has_suffix (filename, ".desktop")) {
4e44f9
                         continue;
4e44f9
                 }
4e44f9
 
4e44f9
-                if (is_x11 && g_str_has_suffix (filename, "-xorg.desktop")) {
4e44f9
-                        char *base_name = g_strndup (filename, strlen (filename) - strlen ("-xorg.desktop"));
4e44f9
-                        char *fallback_name = g_strconcat (base_name, ".desktop", NULL);
4e44f9
-                        g_free (base_name);
4e44f9
-                        char *fallback_path = g_build_filename (dirname, fallback_name, NULL);
4e44f9
-                        g_free (fallback_name);
4e44f9
-                        if (g_file_test (fallback_path, G_FILE_TEST_EXISTS)) {
4e44f9
-                                g_free (fallback_path);
4e44f9
-                                g_debug ("Running under X11, ignoring %s", filename);
4e44f9
-                                continue;
4e44f9
+                if (is_wayland) {
4e44f9
+                        if (g_str_has_suffix (filename, "-wayland.desktop")) {
4e44f9
+                                g_autofree char *base_name = g_strndup (filename, strlen (filename) - strlen ("-wayland.desktop"));
4e44f9
+                                g_autofree char *other_name = g_strconcat (base_name, ".desktop", NULL);
4e44f9
+                                g_autofree char *other_path = g_build_filename (dirname, other_name, NULL);
4e44f9
+
4e44f9
+                                if (g_file_test (other_path, G_FILE_TEST_EXISTS)) {
4e44f9
+                                        g_debug ("Running under Wayland, ignoring %s", filename);
4e44f9
+                                        continue;
4e44f9
+                                }
4e44f9
+                        } else {
4e44f9
+                                g_autofree char *base_name = g_strndup (filename, strlen (filename) - strlen (".desktop"));
4e44f9
+                                g_autofree char *other_name = g_strdup_printf ("%s-xorg.desktop", base_name);
4e44f9
+                                g_autofree char *other_path = g_build_filename (dirname, other_name, NULL);
4e44f9
+
4e44f9
+                                if (g_file_test (other_path, G_FILE_TEST_EXISTS)) {
4e44f9
+                                        g_debug ("Running under Wayland, ignoring %s", filename);
4e44f9
+                                        continue;
4e44f9
+                                }
4e44f9
+                        }
4e44f9
+                } else if (is_x11) {
4e44f9
+                        if (g_str_has_suffix (filename, "-xorg.desktop")) {
4e44f9
+                                g_autofree char *base_name = g_strndup (filename, strlen (filename) - strlen ("-xorg.desktop"));
4e44f9
+                                g_autofree char *other_name = g_strconcat (base_name, ".desktop", NULL);
4e44f9
+                                g_autofree char *other_path = g_build_filename (dirname, other_name, NULL);
4e44f9
+
4e44f9
+                                if (g_file_test (other_path, G_FILE_TEST_EXISTS)) {
4e44f9
+                                        g_debug ("Running under X11, ignoring %s", filename);
4e44f9
+                                        continue;
4e44f9
+                                }
4e44f9
+                        } else {
4e44f9
+                                g_autofree char *base_name = g_strndup (filename, strlen (filename) - strlen (".desktop"));
4e44f9
+                                g_autofree char *other_name = g_strdup_printf ("%s-wayland.desktop", base_name);
4e44f9
+                                g_autofree char *other_path = g_build_filename (dirname, other_name, NULL);
4e44f9
+
4e44f9
+                                if (g_file_test (other_path, G_FILE_TEST_EXISTS)) {
4e44f9
+                                        g_debug ("Running under X11, ignoring %s", filename);
4e44f9
+                                        continue;
4e44f9
+                                }
4e44f9
                         }
4e44f9
-                        g_free (fallback_path);
4e44f9
                 }
4e44f9
 
4e44f9
                 id = g_strndup (filename, strlen (filename) - strlen (".desktop"));
4e44f9
 
4e44f9
                 full_path = g_build_filename (dirname, filename, NULL);
4e44f9
 
4e44f9
                 load_session_file (id, full_path);
4e44f9
 
4e44f9
                 g_free (id);
4e44f9
                 g_free (full_path);
4e44f9
         }
4e44f9
 
4e44f9
         g_dir_close (dir);
4e44f9
 }
4e44f9
 
4e44f9
 static void
4e44f9
 collect_sessions (void)
4e44f9
 {
4e44f9
         g_autoptr(GHashTable) names_seen_before = NULL;
4e44f9
         g_autoptr(GPtrArray) xorg_search_array = NULL;
4e44f9
         g_autoptr(GPtrArray) wayland_search_array = NULL;
4e44f9
         gchar      *session_dir = NULL;
4e44f9
         int         i;
4e44f9
         const char *xorg_search_dirs[] = {
4e44f9
                 "/etc/X11/sessions/",
4e44f9
                 DMCONFDIR "/Sessions/",
4e44f9
                 DATADIR "/gdm/BuiltInSessions/",
4e44f9
                 DATADIR "/xsessions/",
4e44f9
         };
4e44f9
+        g_auto (GStrv) supported_session_types = NULL;
4e44f9
+
4e44f9
+        supported_session_types = g_strsplit (g_getenv ("GDM_SUPPORTED_SESSION_TYPES"), ":", -1);
4e44f9
 
4e44f9
         names_seen_before = g_hash_table_new (g_str_hash, g_str_equal);
4e44f9
         xorg_search_array = g_ptr_array_new_with_free_func (g_free);
4e44f9
 
4e44f9
         const gchar * const *system_data_dirs = g_get_system_data_dirs ();
4e44f9
 
4e44f9
         for (i = 0; system_data_dirs[i]; i++) {
4e44f9
                 session_dir = g_build_filename (system_data_dirs[i], "xsessions", NULL);
4e44f9
                 g_ptr_array_add (xorg_search_array, session_dir);
4e44f9
         }
4e44f9
 
4e44f9
         for (i = 0; i < G_N_ELEMENTS (xorg_search_dirs); i++) {
4e44f9
                 g_ptr_array_add (xorg_search_array, g_strdup (xorg_search_dirs[i]));
4e44f9
         }
4e44f9
 
4e44f9
 #ifdef ENABLE_WAYLAND_SUPPORT
4e44f9
         const char *wayland_search_dirs[] = {
4e44f9
                 DATADIR "/wayland-sessions/",
4e44f9
         };
4e44f9
 
4e44f9
         wayland_search_array = g_ptr_array_new_with_free_func (g_free);
4e44f9
 
4e44f9
         for (i = 0; system_data_dirs[i]; i++) {
4e44f9
                 session_dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL);
4e44f9
                 g_ptr_array_add (wayland_search_array, session_dir);
4e44f9
         }
4e44f9
 
4e44f9
         for (i = 0; i < G_N_ELEMENTS (wayland_search_dirs); i++) {
4e44f9
                 g_ptr_array_add (wayland_search_array, g_strdup (wayland_search_dirs[i]));
4e44f9
         }
4e44f9
 #endif
4e44f9
 
4e44f9
         if (gdm_available_sessions_map == NULL) {
4e44f9
                 gdm_available_sessions_map = g_hash_table_new_full (g_str_hash, g_str_equal,
4e44f9
                                                                     g_free, (GDestroyNotify)gdm_session_file_free);
4e44f9
         }
4e44f9
 
4e44f9
-        for (i = 0; i < xorg_search_array->len; i++) {
4e44f9
-                collect_sessions_from_directory (g_ptr_array_index (xorg_search_array, i));
4e44f9
+        if (!supported_session_types || g_strv_contains ((const char * const *) supported_session_types, "x11")) {
4e44f9
+                for (i = 0; i < xorg_search_array->len; i++) {
4e44f9
+                        collect_sessions_from_directory (g_ptr_array_index (xorg_search_array, i));
4e44f9
+                }
4e44f9
         }
4e44f9
 
4e44f9
 #ifdef ENABLE_WAYLAND_SUPPORT
4e44f9
 #ifdef ENABLE_USER_DISPLAY_SERVER
4e44f9
-        if (g_getenv ("WAYLAND_DISPLAY") == NULL && g_getenv ("RUNNING_UNDER_GDM") != NULL) {
4e44f9
-                goto out;
4e44f9
+        if (!supported_session_types  || g_strv_contains ((const char * const *) supported_session_types, "wayland")) {
4e44f9
+                for (i = 0; i < wayland_search_array->len; i++) {
4e44f9
+                        collect_sessions_from_directory (g_ptr_array_index (wayland_search_array, i));
4e44f9
+                }
4e44f9
         }
4e44f9
 #endif
4e44f9
-
4e44f9
-        for (i = 0; i < wayland_search_array->len; i++) {
4e44f9
-                collect_sessions_from_directory (g_ptr_array_index (wayland_search_array, i));
4e44f9
-        }
4e44f9
 #endif
4e44f9
 
4e44f9
-out:
4e44f9
         g_hash_table_foreach_remove (gdm_available_sessions_map,
4e44f9
                                      remove_duplicate_sessions,
4e44f9
                                      names_seen_before);
4e44f9
 }
4e44f9
 
4e44f9
 static gint
4e44f9
 compare_session_ids (gconstpointer  a,
4e44f9
                      gconstpointer  b)
4e44f9
 {
4e44f9
         GdmSessionFile *session_a, *session_b;
4e44f9
         session_a = (GdmSessionFile *) g_hash_table_lookup (gdm_available_sessions_map, a);
4e44f9
         session_b = (GdmSessionFile *) g_hash_table_lookup (gdm_available_sessions_map, b);
4e44f9
 
4e44f9
         if (session_a == NULL)
4e44f9
                 return -1;
4e44f9
 
4e44f9
         if (session_b == NULL)
4e44f9
                 return 1;
4e44f9
 
4e44f9
         return g_strcmp0 (session_a->translated_name, session_b->translated_name);
4e44f9
 }
4e44f9
 
4e44f9
 /**
4e44f9
  * gdm_get_session_ids:
4e44f9
  *
4e44f9
  * Reads /usr/share/xsessions and other relevant places for possible sessions
4e44f9
  * to log into and returns the complete list.
4e44f9
  *
4e44f9
  * Returns: (transfer full): a %NULL terminated list of session ids
4e44f9
  */
4e44f9
-- 
4e44f9
2.31.1
4e44f9