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

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