summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2021-07-16 12:34:57 -0400
committerRay Strode <rstrode@redhat.com>2021-07-22 13:33:18 -0400
commit04853a3b8c17712cc7f74c3c405ef47af53151c1 (patch)
treebdd174fa2bc01eca932938e8007a9007668cb764
parentf66ff435ab9951c783ff17e16ade0a800cec5497 (diff)
downloadgdm-04853a3b8c17712cc7f74c3c405ef47af53151c1.tar.gz
daemon: Provide more flexibility for configuring display server
There's currently a way to disable wayland, but no way to disable Xorg. We currently prefer wayland if it's not disabled, but have no way to prefer Xorg without disabling wayland entirely. There's currently no way use legacy Xorg support at all if user display server support is enabled at a build time. This commit adds more flexibility to display server selection. It adds two new keys: XorgEnable and and PreferredDisplayServer. XorgEnable=false disables Xorg support entirely on seat 0. PreferredDisplayServer can be set to "wayland", "xorg", "legacy-xorg" or "none" to select which display server is used by default. If it's set to "wayland", it will fall back to "xorg". If it's set to "xorg" it will fall back to "wayland".
-rw-r--r--common/gdm-settings-keys.h2
-rw-r--r--daemon/gdm-display.c36
-rw-r--r--daemon/gdm-launch-environment.c9
-rw-r--r--daemon/gdm-local-display-factory.c220
-rw-r--r--daemon/gdm-manager.c6
-rw-r--r--daemon/gdm-session.c109
-rw-r--r--data/gdm.schemas.in10
-rw-r--r--libgdm/gdm-sessions.c72
8 files changed, 349 insertions, 115 deletions
diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h
index f0059b5c..87685d3c 100644
--- a/common/gdm-settings-keys.h
+++ b/common/gdm-settings-keys.h
@@ -33,7 +33,9 @@ G_BEGIN_DECLS
#define GDM_KEY_TIMED_LOGIN_USER "daemon/TimedLogin"
#define GDM_KEY_TIMED_LOGIN_DELAY "daemon/TimedLoginDelay"
#define GDM_KEY_INITIAL_SETUP_ENABLE "daemon/InitialSetupEnable"
+#define GDM_KEY_PREFERRED_DISPLAY_SERVER "daemon/PreferredDisplayServer"
#define GDM_KEY_WAYLAND_ENABLE "daemon/WaylandEnable"
+#define GDM_KEY_XORG_ENABLE "daemon/XorgEnable"
#define GDM_KEY_DEBUG "debug/Enable"
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
index 3a260923..46d5a773 100644
--- a/daemon/gdm-display.c
+++ b/daemon/gdm-display.c
@@ -93,6 +93,8 @@ typedef struct _GdmDisplayPrivate
guint have_existing_user_accounts : 1;
guint doing_initial_setup : 1;
guint session_registered : 1;
+
+ GStrv supported_session_types;
} GdmDisplayPrivate;
enum {
@@ -116,6 +118,7 @@ enum {
PROP_HAVE_EXISTING_USER_ACCOUNTS,
PROP_DOING_INITIAL_SETUP,
PROP_SESSION_REGISTERED,
+ PROP_SUPPORTED_SESSION_TYPES,
};
static void gdm_display_class_init (GdmDisplayClass *klass);
@@ -911,6 +914,23 @@ _gdm_display_set_allow_timed_login (GdmDisplay *self,
}
static void
+_gdm_display_set_supported_session_types (GdmDisplay *self,
+ const char * const *supported_session_types)
+
+{
+ GdmDisplayPrivate *priv;
+ g_autofree char *supported_session_types_string = NULL;
+
+ if (supported_session_types != NULL)
+ supported_session_types_string = g_strjoinv (":", (GStrv) supported_session_types);
+
+ priv = gdm_display_get_instance_private (self);
+ g_debug ("GdmDisplay: supported session types: %s", supported_session_types_string);
+ g_strfreev (priv->supported_session_types);
+ priv->supported_session_types = g_strdupv ((GStrv) supported_session_types);
+}
+
+static void
gdm_display_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -966,6 +986,9 @@ gdm_display_set_property (GObject *object,
case PROP_SESSION_REGISTERED:
_gdm_display_set_session_registered (self, g_value_get_boolean (value));
break;
+ case PROP_SUPPORTED_SESSION_TYPES:
+ _gdm_display_set_supported_session_types (self, g_value_get_boxed (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1044,6 +1067,9 @@ gdm_display_get_property (GObject *object,
case PROP_ALLOW_TIMED_LOGIN:
g_value_set_boolean (value, priv->allow_timed_login);
break;
+ case PROP_SUPPORTED_SESSION_TYPES:
+ g_value_set_boxed (value, priv->supported_session_types);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1229,6 +1255,7 @@ gdm_display_dispose (GObject *object)
priv->finish_idle_id = 0;
}
g_clear_object (&priv->launch_environment);
+ g_clear_pointer (&priv->supported_session_types, g_strfreev);
g_warn_if_fail (priv->status != GDM_DISPLAY_MANAGED);
g_warn_if_fail (priv->user_access_file == NULL);
@@ -1389,6 +1416,14 @@ gdm_display_class_init (GdmDisplayClass *klass)
G_MAXINT,
GDM_DISPLAY_UNMANAGED,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (object_class,
+ PROP_SUPPORTED_SESSION_TYPES,
+ g_param_spec_boxed ("supported-session-types",
+ "supported session types",
+ "supported session types",
+ G_TYPE_STRV,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
}
static void
@@ -1721,6 +1756,7 @@ gdm_display_start_greeter_session (GdmDisplay *self)
session = gdm_launch_environment_get_session (priv->launch_environment);
g_object_set (G_OBJECT (session),
"display-is-initial", priv->is_initial,
+ "supported-session-types", priv->supported_session_types,
NULL);
g_free (display_name);
diff --git a/daemon/gdm-launch-environment.c b/daemon/gdm-launch-environment.c
index 87a1c5ff..14ecfac2 100644
--- a/daemon/gdm-launch-environment.c
+++ b/daemon/gdm-launch-environment.c
@@ -161,6 +161,7 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment,
NULL
};
char *system_data_dirs;
+ g_auto (GStrv) supported_session_types = NULL;
int i;
/* create a hash table of current environment, then update keys has necessary */
@@ -244,6 +245,14 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment,
system_data_dirs));
g_free (system_data_dirs);
+ g_object_get (launch_environment->priv->session,
+ "supported-session-types",
+ &supported_session_types,
+ NULL);
+ g_hash_table_insert (hash,
+ g_strdup ("GDM_SUPPORTED_SESSION_TYPES"),
+ g_strjoinv (":", supported_session_types));
+
return hash;
}
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index 8a4ef06c..0bb3851f 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -183,6 +183,89 @@ take_next_display_number (GdmLocalDisplayFactory *factory)
return ret;
}
+static char *
+get_preferred_display_server (GdmLocalDisplayFactory *factory)
+{
+ g_autofree gchar *preferred_display_server = NULL;
+ gboolean wayland_enabled = FALSE, xorg_enabled = FALSE;
+
+ gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled);
+ gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled);
+
+ if (wayland_enabled && !xorg_enabled) {
+ return g_strdup ("wayland");
+ }
+
+ if (!wayland_enabled && !xorg_enabled) {
+ return g_strdup ("none");
+ }
+
+ gdm_settings_direct_get_string (GDM_KEY_PREFERRED_DISPLAY_SERVER, &preferred_display_server);
+
+ if (g_strcmp0 (preferred_display_server, "wayland") == 0) {
+ if (wayland_enabled)
+ return g_strdup (preferred_display_server);
+ else
+ return g_strdup ("xorg");
+ }
+
+ if (g_strcmp0 (preferred_display_server, "xorg") == 0) {
+ if (xorg_enabled)
+ return g_strdup (preferred_display_server);
+ else
+ return g_strdup ("wayland");
+ }
+
+ if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) {
+ if (xorg_enabled)
+ return g_strdup (preferred_display_server);
+ }
+
+ return g_strdup ("none");
+}
+
+static const char *
+gdm_local_display_factory_get_session_type (GdmLocalDisplayFactory *factory,
+ gboolean should_fall_back)
+{
+ const char *session_types[3] = { NULL };
+ gsize i, session_type_index = 0, number_of_session_types = 0;
+ g_autofree gchar *preferred_display_server = NULL;
+
+ preferred_display_server = get_preferred_display_server (factory);
+
+ if (g_strcmp0 (preferred_display_server, "wayland") != 0 &&
+ g_strcmp0 (preferred_display_server, "xorg") != 0)
+ return NULL;
+
+ for (i = 0; i < G_N_ELEMENTS (session_types) - 1; i++) {
+#ifdef ENABLE_WAYLAND_SUPPORT
+ if (number_of_session_types > 0 ||
+ g_strcmp0 (preferred_display_server, "wayland") == 0) {
+ gboolean wayland_enabled = FALSE;
+ if (gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled)) {
+ if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE) )
+ session_types[number_of_session_types++] = "wayland";
+ }
+ }
+#endif
+
+ if (number_of_session_types > 0 ||
+ g_strcmp0 (preferred_display_server, "xorg") == 0) {
+ gboolean xorg_enabled = FALSE;
+ if (gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled)) {
+ if (xorg_enabled && g_file_test ("/usr/bin/Xorg", G_FILE_TEST_IS_EXECUTABLE) )
+ session_types[number_of_session_types++] = "x11";
+ }
+ }
+ }
+
+ if (should_fall_back)
+ session_type_index++;
+
+ return session_types[session_type_index];
+}
+
static void
on_display_disposed (GdmLocalDisplayFactory *factory,
GdmDisplay *display)
@@ -200,19 +283,6 @@ store_display (GdmLocalDisplayFactory *factory,
gdm_display_store_add (store, display);
}
-static gboolean
-gdm_local_display_factory_use_wayland (void)
-{
-#ifdef ENABLE_WAYLAND_SUPPORT
- gboolean wayland_enabled = FALSE;
- if (gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled)) {
- if (wayland_enabled && g_file_test ("/usr/bin/Xwayland", G_FILE_TEST_IS_EXECUTABLE) )
- return TRUE;
- }
-#endif
- return FALSE;
-}
-
/*
Example:
dbus-send --system --dest=org.gnome.DisplayManager \
@@ -228,6 +298,8 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact
gboolean ret;
GdmDisplay *display = NULL;
gboolean is_initial = FALSE;
+ const char *session_type;
+ g_autofree gchar *preferred_display_server = NULL;
g_return_val_if_fail (GDM_IS_LOCAL_DISPLAY_FACTORY (factory), FALSE);
@@ -235,20 +307,43 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact
g_debug ("GdmLocalDisplayFactory: Creating transient display");
-#ifdef ENABLE_USER_DISPLAY_SERVER
- display = gdm_local_display_new ();
- if (gdm_local_display_factory_use_wayland ())
- g_object_set (G_OBJECT (display), "session-type", "wayland", NULL);
- is_initial = TRUE;
-#else
- if (display == NULL) {
- guint32 num;
+ preferred_display_server = get_preferred_display_server (factory);
- num = take_next_display_number (factory);
+#ifdef ENABLE_USER_DISPLAY_SERVER
+ if (g_strcmp0 (preferred_display_server, "wayland") == 0 ||
+ g_strcmp0 (preferred_display_server, "xorg") == 0) {
+ session_type = gdm_local_display_factory_get_session_type (factory, FALSE);
+
+ if (session_type == NULL) {
+ g_set_error_literal (error,
+ GDM_DISPLAY_ERROR,
+ GDM_DISPLAY_ERROR_GENERAL,
+ "Both Wayland and Xorg are unavailable");
+ return FALSE;
+ }
- display = gdm_legacy_display_new (num);
+ display = gdm_local_display_new ();
+ g_object_set (G_OBJECT (display), "session-type", session_type, NULL);
+ is_initial = TRUE;
}
#endif
+ if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0) {
+ if (display == NULL) {
+ guint32 num;
+
+ num = take_next_display_number (factory);
+
+ display = gdm_legacy_display_new (num);
+ }
+ }
+
+ if (display == NULL) {
+ g_set_error_literal (error,
+ GDM_DISPLAY_ERROR,
+ GDM_DISPLAY_ERROR_GENERAL,
+ "Invalid preferred display server configured");
+ return FALSE;
+ }
g_object_set (display,
"seat-id", "seat0",
@@ -481,6 +576,19 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
GdmDisplayStore *store;
GdmDisplay *display = NULL;
g_autofree char *login_session_id = NULL;
+ gboolean wayland_enabled = FALSE, xorg_enabled = FALSE;
+ g_autofree gchar *preferred_display_server = NULL;
+ gboolean falling_back;
+
+ gdm_settings_direct_get_boolean (GDM_KEY_WAYLAND_ENABLE, &wayland_enabled);
+ gdm_settings_direct_get_boolean (GDM_KEY_XORG_ENABLE, &xorg_enabled);
+
+ preferred_display_server = get_preferred_display_server (factory);
+
+ if (g_strcmp0 (preferred_display_server, "none") == 0) {
+ g_debug ("GdmLocalDisplayFactory: Preferred display server is none, so not creating display");
+ return;
+ }
ret = sd_seat_can_graphical (seat_id);
@@ -500,21 +608,18 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
if (g_strcmp0 (seat_id, "seat0") == 0) {
is_seat0 = TRUE;
- /* If we've failed, or are explicitly told to, fall back to legacy X11 support
- */
- if (factory->num_failures > 0 || !gdm_local_display_factory_use_wayland ()) {
- session_type = NULL;
- g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use X11 fallback");
- } else {
- g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use wayland");
- }
+ falling_back = factory->num_failures > 0;
+ session_type = gdm_local_display_factory_get_session_type (factory, falling_back);
+
+ g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use %s%s",
+ session_type, falling_back? " fallback" : "");
} else {
is_seat0 = FALSE;
g_debug ("GdmLocalDisplayFactory: New displays on seat %s will use X11 fallback", seat_id);
/* Force legacy X11 for all auxiliary seats */
seat_supports_graphics = TRUE;
- session_type = NULL;
+ session_type = "x11";
}
/* For seat0, we have a fallback logic to still try starting it after
@@ -552,7 +657,8 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
g_debug ("GdmLocalDisplayFactory: Assuming we can use seat0 for X11 even though system says it doesn't support graphics!");
g_debug ("GdmLocalDisplayFactory: This might indicate an issue where the framebuffer device is not tagged as master-of-seat in udev.");
seat_supports_graphics = TRUE;
- session_type = NULL;
+ session_type = "x11";
+ wayland_enabled = FALSE;
} else {
g_clear_handle_id (&factory->seat0_graphics_check_timeout_id, g_source_remove);
}
@@ -561,8 +667,13 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
if (!seat_supports_graphics)
return;
- g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested",
- session_type? : "X11", seat_id);
+ if (session_type != NULL)
+ g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested",
+ session_type, seat_id);
+ else if (g_strcmp0 (preferred_display_server, "legacy-xorg") == 0)
+ g_debug ("GdmLocalDisplayFactory: Legacy Xorg login display for seat %s requested",
+ seat_id);
+
store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
if (is_seat0)
@@ -597,20 +708,53 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
g_debug ("GdmLocalDisplayFactory: Adding display on seat %s", seat_id);
#ifdef ENABLE_USER_DISPLAY_SERVER
- if (is_seat0) {
- display = gdm_local_display_new ();
- if (session_type != NULL) {
+ if (g_strcmp0 (preferred_display_server, "wayland") == 0 ||
+ g_strcmp0 (preferred_display_server, "xorg") == 0) {
+ if (is_seat0) {
+ g_autoptr (GPtrArray) supported_session_types = NULL;
+
+ if (session_type == NULL) {
+ g_warning ("GdmLocalDisplayFactory: Both Wayland and Xorg sessions are unavailable");
+ return;
+ }
+
+ supported_session_types = g_ptr_array_new ();
+
+ if (g_strcmp0 (preferred_display_server, "wayland") == 0) {
+ if (wayland_enabled)
+ g_ptr_array_add (supported_session_types, "wayland");
+ } else {
+ if (xorg_enabled)
+ g_ptr_array_add (supported_session_types, "x11");
+ }
+
+ if (!falling_back) {
+ if (g_strcmp0 (preferred_display_server, "wayland") == 0) {
+ if (xorg_enabled)
+ g_ptr_array_add (supported_session_types, "x11");
+ } else {
+ if (wayland_enabled)
+ g_ptr_array_add (supported_session_types, "wayland");
+ }
+ }
+
+ g_ptr_array_add (supported_session_types, NULL);
+
+ display = gdm_local_display_new ();
g_object_set (G_OBJECT (display), "session-type", session_type, NULL);
+ g_object_set (G_OBJECT (display), "supported-session-types", supported_session_types->pdata, NULL);
}
}
#endif
if (display == NULL) {
guint32 num;
+ const char *supported_session_types[] = { "x11", NULL };
num = take_next_display_number (factory);
display = gdm_legacy_display_new (num);
+ g_object_set (G_OBJECT (display), "supported-session-types", supported_session_types, NULL);
}
g_object_set (display, "seat-id", seat_id, NULL);
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index 9c10adff..e433acf3 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -2307,7 +2307,6 @@ create_user_session_for_display (GdmManager *manager,
char *display_id = NULL;
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
g_autofree char *display_session_type = NULL;
- gboolean greeter_is_wayland;
#endif
g_object_get (G_OBJECT (display),
@@ -2405,11 +2404,6 @@ create_user_session_for_display (GdmManager *manager,
session,
(GDestroyNotify)
clean_user_session);
-
-#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
- greeter_is_wayland = g_strcmp0 (display_session_type, "wayland") == 0;
- g_object_set (G_OBJECT (session), "ignore-wayland", !greeter_is_wayland, NULL);
-#endif
}
static void
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index f705f0e0..ce49a8df 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -132,11 +132,10 @@ struct _GdmSession
GDBusServer *outside_server;
GHashTable *environment;
+ GStrv supported_session_types;
+
guint32 is_program_session : 1;
guint32 display_is_initial : 1;
-#ifdef ENABLE_WAYLAND_SUPPORT
- guint32 ignore_wayland : 1;
-#endif
};
enum {
@@ -153,9 +152,7 @@ enum {
PROP_DISPLAY_X11_AUTHORITY_FILE,
PROP_USER_X11_AUTHORITY_FILE,
PROP_CONVERSATION_ENVIRONMENT,
-#ifdef ENABLE_WAYLAND_SUPPORT
- PROP_IGNORE_WAYLAND,
-#endif
+ PROP_SUPPORTED_SESSION_TYPES,
};
enum {
@@ -346,12 +343,23 @@ on_establish_credentials_cb (GdmDBusWorker *proxy,
g_object_unref (self);
}
+static gboolean
+supports_session_type (GdmSession *self,
+ const char *session_type)
+{
+ if (session_type == NULL)
+ return TRUE;
+
+ return g_strv_contains ((const char * const *) self->supported_session_types,
+ session_type);
+}
+
static char **
get_system_session_dirs (GdmSession *self)
{
GArray *search_array = NULL;
char **search_dirs;
- int i;
+ int i, j;
const gchar * const *system_data_dirs = g_get_system_data_dirs ();
static const char *x_search_dirs[] = {
@@ -365,32 +373,29 @@ get_system_session_dirs (GdmSession *self)
search_array = g_array_new (TRUE, TRUE, sizeof (char *));
- for (i = 0; system_data_dirs[i]; i++) {
- gchar *dir = g_build_filename (system_data_dirs[i], "xsessions", NULL);
- g_array_append_val (search_array, dir);
- }
+ for (j = 0; self->supported_session_types[j] != NULL; j++) {
+ const char *supported_type = self->supported_session_types[j];
- g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs));
+ if (g_str_equal (supported_type, "x11")) {
+ for (i = 0; system_data_dirs[i]; i++) {
+ gchar *dir = g_build_filename (system_data_dirs[i], "xsessions", NULL);
+ g_array_append_val (search_array, dir);
+ }
+
+ g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs));
+ }
#ifdef ENABLE_WAYLAND_SUPPORT
- if (!self->ignore_wayland) {
-#ifdef ENABLE_USER_DISPLAY_SERVER
- g_array_prepend_val (search_array, wayland_search_dir);
+ if (g_str_equal (supported_type, "wayland")) {
+ g_array_prepend_val (search_array, wayland_search_dir);
- for (i = 0; system_data_dirs[i]; i++) {
- gchar *dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL);
- g_array_insert_val (search_array, i, dir);
- }
-#else
- for (i = 0; system_data_dirs[i]; i++) {
- gchar *dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL);
- g_array_append_val (search_array, dir);
+ for (i = 0; system_data_dirs[i]; i++) {
+ gchar *dir = g_build_filename (system_data_dirs[i], "wayland-sessions", NULL);
+ g_array_append_val (search_array, dir);
+ }
}
-
- g_array_append_val (search_array, wayland_search_dir);
#endif
}
-#endif
search_dirs = g_strdupv ((char **) search_array->data);
@@ -2225,14 +2230,18 @@ stop_conversation_now (GdmSessionConversation *conversation)
g_clear_object (&conversation->job);
}
-#ifdef ENABLE_WAYLAND_SUPPORT
void
-gdm_session_set_ignore_wayland (GdmSession *self,
- gboolean ignore_wayland)
+gdm_session_set_supported_session_types (GdmSession *self,
+ const char * const *supported_session_types)
{
- self->ignore_wayland = ignore_wayland;
+ const char * const session_types[] = { "wayland", "x11", NULL };
+ g_strfreev (self->supported_session_types);
+
+ if (supported_session_types == NULL)
+ self->supported_session_types = g_strdupv ((GStrv) session_types);
+ else
+ self->supported_session_types = g_strdupv ((GStrv) supported_session_types);
}
-#endif
gboolean
gdm_session_start_conversation (GdmSession *self,
@@ -3165,11 +3174,13 @@ gdm_session_is_wayland_session (GdmSession *self)
filename = get_session_filename (self);
- key_file = load_key_file_for_file (self, filename, &full_path);
+ if (supports_session_type (self, "wayland")) {
+ key_file = load_key_file_for_file (self, filename, &full_path);
- if (key_file == NULL) {
- goto out;
- }
+ if (key_file == NULL) {
+ goto out;
+ }
+ }
if (full_path != NULL && strstr (full_path, "/wayland-sessions/") != NULL) {
is_wayland_session = TRUE;
@@ -3507,11 +3518,9 @@ gdm_session_set_property (GObject *object,
case PROP_CONVERSATION_ENVIRONMENT:
set_conversation_environment (self, g_value_get_pointer (value));
break;
-#ifdef ENABLE_WAYLAND_SUPPORT
- case PROP_IGNORE_WAYLAND:
- gdm_session_set_ignore_wayland (self, g_value_get_boolean (value));
+ case PROP_SUPPORTED_SESSION_TYPES:
+ gdm_session_set_supported_session_types (self, g_value_get_boxed (value));
break;
-#endif
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -3565,11 +3574,9 @@ gdm_session_get_property (GObject *object,
case PROP_CONVERSATION_ENVIRONMENT:
g_value_set_pointer (value, self->environment);
break;
-#ifdef ENABLE_WAYLAND_SUPPORT
- case PROP_IGNORE_WAYLAND:
- g_value_set_boolean (value, self->ignore_wayland);
+ case PROP_SUPPORTED_SESSION_TYPES:
+ g_value_set_boxed (value, self->supported_session_types);
break;
-#endif
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -3587,6 +3594,8 @@ gdm_session_dispose (GObject *object)
gdm_session_close (self);
+ g_clear_pointer (&self->supported_session_types,
+ g_strfreev);
g_clear_pointer (&self->conversations,
g_hash_table_unref);
@@ -4001,15 +4010,13 @@ gdm_session_class_init (GdmSessionClass *session_class)
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
-#ifdef ENABLE_WAYLAND_SUPPORT
g_object_class_install_property (object_class,
- PROP_IGNORE_WAYLAND,
- g_param_spec_boolean ("ignore-wayland",
- "ignore wayland",
- "ignore wayland",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
-#endif
+ PROP_SUPPORTED_SESSION_TYPES,
+ g_param_spec_boxed ("supported-session-types",
+ "supported session types",
+ "supported session types",
+ G_TYPE_STRV,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
/* Ensure we can resolve errors */
gdm_dbus_error_ensure (GDM_SESSION_WORKER_ERROR);
diff --git a/data/gdm.schemas.in b/data/gdm.schemas.in
index 255bff02..a1035f95 100644
--- a/data/gdm.schemas.in
+++ b/data/gdm.schemas.in
@@ -53,11 +53,21 @@
<default>true</default>
</schema>
<schema>
+ <key>daemon/PreferredDisplayServer</key>
+ <signature>s</signature>
+ <default>wayland</default>
+ </schema>
+ <schema>
<key>daemon/WaylandEnable</key>
<signature>b</signature>
<default>true</default>
</schema>
<schema>
+ <key>daemon/XorgEnable</key>
+ <signature>b</signature>
+ <default>true</default>
+ </schema>
+ <schema>
<key>security/AllowRemoteAutoLogin</key>
<signature>b</signature>
<default>false</default>
diff --git a/libgdm/gdm-sessions.c b/libgdm/gdm-sessions.c
index 75d442ee..97ed5ef3 100644
--- a/libgdm/gdm-sessions.c
+++ b/libgdm/gdm-sessions.c
@@ -190,6 +190,8 @@ collect_sessions_from_directory (const char *dirname)
gboolean is_x11 = g_getenv ("WAYLAND_DISPLAY") == NULL &&
g_getenv ("RUNNING_UNDER_GDM") != NULL;
+ gboolean is_wayland = g_getenv ("WAYLAND_DISPLAY") != NULL &&
+ g_getenv ("RUNNING_UNDER_GDM") != NULL;
/* FIXME: add file monitor to directory */
@@ -206,18 +208,46 @@ collect_sessions_from_directory (const char *dirname)
continue;
}
- if (is_x11 && g_str_has_suffix (filename, "-xorg.desktop")) {
- char *base_name = g_strndup (filename, strlen (filename) - strlen ("-xorg.desktop"));
- char *fallback_name = g_strconcat (base_name, ".desktop", NULL);
- g_free (base_name);
- char *fallback_path = g_build_filename (dirname, fallback_name, NULL);
- g_free (fallback_name);
- if (g_file_test (fallback_path, G_FILE_TEST_EXISTS)) {
- g_free (fallback_path);
- g_debug ("Running under X11, ignoring %s", filename);
- continue;
+ if (is_wayland) {
+ if (g_str_has_suffix (filename, "-wayland.desktop")) {
+ g_autofree char *base_name = g_strndup (filename, strlen (filename) - strlen ("-wayland.desktop"));
+ g_autofree char *other_name = g_strconcat (base_name, ".desktop", NULL);
+ g_autofree char *other_path = g_build_filename (dirname, other_name, NULL);
+
+ if (g_file_test (other_path, G_FILE_TEST_EXISTS)) {
+ g_debug ("Running under Wayland, ignoring %s", filename);
+ continue;
+ }
+ } else {
+ g_autofree char *base_name = g_strndup (filename, strlen (filename) - strlen (".desktop"));
+ g_autofree char *other_name = g_strdup_printf ("%s-xorg.desktop", base_name);
+ g_autofree char *other_path = g_build_filename (dirname, other_name, NULL);
+
+ if (g_file_test (other_path, G_FILE_TEST_EXISTS)) {
+ g_debug ("Running under Wayland, ignoring %s", filename);
+ continue;
+ }
+ }
+ } else if (is_x11) {
+ if (g_str_has_suffix (filename, "-xorg.desktop")) {
+ g_autofree char *base_name = g_strndup (filename, strlen (filename) - strlen ("-xorg.desktop"));
+ g_autofree char *other_name = g_strconcat (base_name, ".desktop", NULL);
+ g_autofree char *other_path = g_build_filename (dirname, other_name, NULL);
+
+ if (g_file_test (other_path, G_FILE_TEST_EXISTS)) {
+ g_debug ("Running under X11, ignoring %s", filename);
+ continue;
+ }
+ } else {
+ g_autofree char *base_name = g_strndup (filename, strlen (filename) - strlen (".desktop"));
+ g_autofree char *other_name = g_strdup_printf ("%s-wayland.desktop", base_name);
+ g_autofree char *other_path = g_build_filename (dirname, other_name, NULL);
+
+ if (g_file_test (other_path, G_FILE_TEST_EXISTS)) {
+ g_debug ("Running under X11, ignoring %s", filename);
+ continue;
+ }
}
- g_free (fallback_path);
}
id = g_strndup (filename, strlen (filename) - strlen (".desktop"));
@@ -247,6 +277,9 @@ collect_sessions (void)
DATADIR "/gdm/BuiltInSessions/",
DATADIR "/xsessions/",
};
+ g_auto (GStrv) supported_session_types = NULL;
+
+ supported_session_types = g_strsplit (g_getenv ("GDM_SUPPORTED_SESSION_TYPES"), ":", -1);
names_seen_before = g_hash_table_new (g_str_hash, g_str_equal);
xorg_search_array = g_ptr_array_new_with_free_func (g_free);
@@ -284,23 +317,22 @@ collect_sessions (void)
g_free, (GDestroyNotify)gdm_session_file_free);
}
- for (i = 0; i < xorg_search_array->len; i++) {
- collect_sessions_from_directory (g_ptr_array_index (xorg_search_array, i));
+ if (!supported_session_types || g_strv_contains ((const char * const *) supported_session_types, "x11")) {
+ for (i = 0; i < xorg_search_array->len; i++) {
+ collect_sessions_from_directory (g_ptr_array_index (xorg_search_array, i));
+ }
}
#ifdef ENABLE_WAYLAND_SUPPORT
#ifdef ENABLE_USER_DISPLAY_SERVER
- if (g_getenv ("WAYLAND_DISPLAY") == NULL && g_getenv ("RUNNING_UNDER_GDM") != NULL) {
- goto out;
+ if (!supported_session_types || g_strv_contains ((const char * const *) supported_session_types, "wayland")) {
+ for (i = 0; i < wayland_search_array->len; i++) {
+ collect_sessions_from_directory (g_ptr_array_index (wayland_search_array, i));
+ }
}
#endif
-
- for (i = 0; i < wayland_search_array->len; i++) {
- collect_sessions_from_directory (g_ptr_array_index (wayland_search_array, i));
- }
#endif
-out:
g_hash_table_foreach_remove (gdm_available_sessions_map,
remove_duplicate_sessions,
names_seen_before);