diff options
-rw-r--r-- | common/gdm-settings-keys.h | 2 | ||||
-rw-r--r-- | daemon/gdm-display.c | 36 | ||||
-rw-r--r-- | daemon/gdm-launch-environment.c | 9 | ||||
-rw-r--r-- | daemon/gdm-local-display-factory.c | 220 | ||||
-rw-r--r-- | daemon/gdm-manager.c | 6 | ||||
-rw-r--r-- | daemon/gdm-session.c | 109 | ||||
-rw-r--r-- | data/gdm.schemas.in | 10 | ||||
-rw-r--r-- | libgdm/gdm-sessions.c | 72 |
8 files changed, 349 insertions, 115 deletions
diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h index f0059b5c..87685d3c 100644 --- a/common/gdm-settings-keys.h +++ b/common/gdm-settings-keys.h @@ -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); |