Skip to content
Commits on Source (26)
stages:
- build
build-fedora:
image: fedora:32
stage: build
before_script:
- dnf -y install
accountsservice-devel
audit-libs-devel
check-devel
dconf
desktop-file-utils
gettext-devel
git
gobject-introspection-devel
gtk3-devel
iso-codes-devel
keyutils-libs-devel
libXau-devel
libXdmcp-devel
libattr-devel
libcanberra-devel
libdmx-devel
libselinux-devel
libtool
meson
nss-devel
pam-devel
plymouth-devel
redhat-rpm-config
systemd
systemd-devel
which
xorg-x11-server-Xorg
xorg-x11-server-devel
yelp-devel
yelp-tools
script:
- meson . build --prefix=/usr --sysconfdir=/etc --localstatedir=/var --mandir=/usr/share/man --libdir=/usr/lib64 -Dpam-prefix=/etc -Drun-dir=/run/gdm -Dudev-dir=/lib/udev/rules.d -Ddefault-path=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin -Dprofiling=true -Dplymouth=enabled -Dselinux=enabled
- ninja -C build
- ninja -C build install
- ninja -C build dist
- ninja -C build test
except:
- tags
============
Version 40.1
============
- Better support for unlocking gnome-keyring with disk password
- Better support for flatpak
- Misc auth fixes
- Improved error output in gdm-runtime-config
- Sort session list on login screen
- Support Session and SessionType properties from accountsservice
==============
Version 41.rc1
==============
- Fix fallback to Xorg at login screen
- Fix SessionType in AccountService user config
- Reuse VT on log out
- Translation updates
================
Version 41.alpha
================
- Allow user session to be Wayland even when login screen is Xorg
- Allow wayland user sessions for single GPU vendor nvidia machines
- Translation updates
==========
......
......@@ -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"
......
......@@ -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);
......@@ -910,6 +913,23 @@ _gdm_display_set_allow_timed_login (GdmDisplay *self,
priv->allow_timed_login = allow_timed_login;
}
static void
_gdm_display_set_supported_session_types (GdmDisplay *self,
const char * const *supported_session_types)
{
GdmDisplayPrivate *priv;
g_autofree char *supported_session_types_string = NULL;
if (supported_session_types != NULL)
supported_session_types_string = g_strjoinv (":", (GStrv) supported_session_types);
priv = gdm_display_get_instance_private (self);
g_debug ("GdmDisplay: supported session types: %s", supported_session_types_string);
g_strfreev (priv->supported_session_types);
priv->supported_session_types = g_strdupv ((GStrv) supported_session_types);
}
static void
gdm_display_set_property (GObject *object,
guint prop_id,
......@@ -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);
......
......@@ -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;
}
......
......@@ -183,6 +183,150 @@ 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");
}
struct GdmDisplayServerConfiguration {
const char *display_server;
const char *key;
const char *binary;
const char *session_type;
} display_server_configuration[] = {
#ifdef ENABLE_WAYLAND_SUPPORT
{ "wayland", GDM_KEY_WAYLAND_ENABLE, "/usr/bin/Xwayland", "wayland" },
#endif
{ "xorg", GDM_KEY_XORG_ENABLE, "/usr/bin/Xorg", "x11" },
{ NULL, NULL, NULL },
};
static gboolean
display_server_enabled (GdmLocalDisplayFactory *factory,
const char *display_server)
{
size_t i;
for (i = 0; display_server_configuration[i].display_server != NULL; i++) {
const char *key = display_server_configuration[i].key;
const char *binary = display_server_configuration[i].binary;
gboolean enabled = FALSE;
if (!g_str_equal (display_server_configuration[i].display_server,
display_server))
continue;
if (!gdm_settings_direct_get_boolean (key, &enabled) || !enabled)
return FALSE;
if (!g_file_test (binary, G_FILE_TEST_IS_EXECUTABLE))
return FALSE;
return TRUE;
}
return FALSE;
}
static const char *
get_session_type_for_display_server (GdmLocalDisplayFactory *factory,
const char *display_server)
{
size_t i;
for (i = 0; display_server_configuration[i].display_server != NULL; i++) {
if (!g_str_equal (display_server_configuration[i].display_server,
display_server))
continue;
return display_server_configuration[i].session_type;
}
return NULL;
}
static char **
gdm_local_display_factory_get_session_types (GdmLocalDisplayFactory *factory,
gboolean should_fall_back)
{
g_autofree gchar *preferred_display_server = NULL;
const char *fallback_display_server = NULL;
gboolean wayland_preferred = FALSE;
gboolean xorg_preferred = FALSE;
g_autoptr (GPtrArray) session_types_array = NULL;
char **session_types;
session_types_array = g_ptr_array_new ();
preferred_display_server = get_preferred_display_server (factory);
g_debug ("GdmLocalDisplayFactory: Getting session type (prefers %s, falling back: %s)",
preferred_display_server, should_fall_back? "yes" : "no");
wayland_preferred = g_str_equal (preferred_display_server, "wayland");
xorg_preferred = g_str_equal (preferred_display_server, "xorg");
if (wayland_preferred)
fallback_display_server = "xorg";
else if (xorg_preferred)
fallback_display_server = "wayland";
else
return NULL;
if (!should_fall_back) {
if (display_server_enabled (factory, preferred_display_server))
g_ptr_array_add (session_types_array, (gpointer) get_session_type_for_display_server (factory, preferred_display_server));
}
if (display_server_enabled (factory, fallback_display_server))
g_ptr_array_add (session_types_array, (gpointer) get_session_type_for_display_server (factory, fallback_display_server));
if (session_types_array->len == 0)
return NULL;
g_ptr_array_add (session_types_array, NULL);
session_types = g_strdupv ((char **) session_types_array->pdata);
return session_types;
}
static void
on_display_disposed (GdmLocalDisplayFactory *factory,
GdmDisplay *display)
......@@ -200,19 +344,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 +359,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 +368,48 @@ 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) {
g_auto(GStrv) session_types = NULL;
session_types = gdm_local_display_factory_get_session_types (factory, FALSE);
if (session_types == 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_types[0],
"supported-session-tyes", session_types,
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",
......@@ -477,10 +638,24 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
int ret;
gboolean seat_supports_graphics;
gboolean is_seat0;
const char *session_type = "wayland";
g_auto (GStrv) session_types = NULL;
const char *legacy_session_types[] = { "x11", NULL };
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 = FALSE;
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 +675,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_types = gdm_local_display_factory_get_session_types (factory, falling_back);
g_debug ("GdmLocalDisplayFactory: New displays on seat0 will use %s%s",
session_types[0], 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_types = g_strdupv ((char **) legacy_session_types);
}
/* For seat0, we have a fallback logic to still try starting it after
......@@ -552,7 +724,9 @@ 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;
wayland_enabled = FALSE;
g_strfreev (session_types);
session_types = g_strdupv ((char **) legacy_session_types);
} else {
g_clear_handle_id (&factory->seat0_graphics_check_timeout_id, g_source_remove);
}
......@@ -561,8 +735,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_types != NULL)
g_debug ("GdmLocalDisplayFactory: %s login display for seat %s requested",
session_types[0], 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,10 +776,14 @@ 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) {
g_object_set (G_OBJECT (display), "session-type", session_type, NULL);
if (g_strcmp0 (preferred_display_server, "wayland") == 0 ||
g_strcmp0 (preferred_display_server, "xorg") == 0) {
if (is_seat0) {
display = gdm_local_display_new ();
g_object_set (G_OBJECT (display),
"session-type", session_types[0],
"supported-session-types", session_types,
NULL);
}
}
#endif
......@@ -611,6 +794,10 @@ ensure_display_for_seat (GdmLocalDisplayFactory *factory,
num = take_next_display_number (factory);
display = gdm_legacy_display_new (num);
g_object_set (G_OBJECT (display),
"session-type", legacy_session_types[0],
"supported-session-types", legacy_session_types,
NULL);
}
g_object_set (display, "seat-id", seat_id, NULL);
......
......@@ -1333,7 +1333,7 @@ set_up_automatic_login_session (GdmManager *manager,
GdmDisplay *display)
{
GdmSession *session;
char *display_session_type = NULL;
g_auto (GStrv) supported_session_types = NULL;
/* 0 is root user; since the daemon talks to the session object
* directly, itself, for automatic login
......@@ -1342,11 +1342,12 @@ set_up_automatic_login_session (GdmManager *manager,
session = get_user_session_for_display (display);
g_object_get (G_OBJECT (display),
"session-type", &display_session_type,
"supported-session-types", &supported_session_types,
NULL);
g_object_set (G_OBJECT (session),
"display-is-initial", FALSE,
"supported-session-types", supported_session_types,
NULL);
g_debug ("GdmManager: Starting automatic login conversation");
......@@ -2305,10 +2306,7 @@ create_user_session_for_display (GdmManager *manager,
char *display_auth_file = NULL;
char *display_seat_id = NULL;
char *display_id = NULL;
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
g_autofree char *display_session_type = NULL;
gboolean greeter_is_wayland;
#endif
g_auto (GStrv) supported_session_types = NULL;
g_object_get (G_OBJECT (display),
"id", &display_id,
......@@ -2317,9 +2315,7 @@ create_user_session_for_display (GdmManager *manager,
"remote-hostname", &remote_hostname,
"x11-authority-file", &display_auth_file,
"seat-id", &display_seat_id,
#if defined(ENABLE_WAYLAND_SUPPORT) && defined(ENABLE_USER_DISPLAY_SERVER)
"session-type", &display_session_type,
#endif
"supported-session-types", &supported_session_types,
NULL);
display_device = get_display_device (manager, display);
......@@ -2332,6 +2328,9 @@ create_user_session_for_display (GdmManager *manager,
display_auth_file,
display_is_local,
NULL);
g_object_set (G_OBJECT (session),
"supported-session-types", supported_session_types,
NULL);
g_debug ("GdmSession: Created user session for user %d on display %s (seat %s)",
(int) allowed_user,
......@@ -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
......
......@@ -1103,8 +1103,6 @@ gdm_session_worker_uninitialize_pam (GdmSessionWorker *worker,
gdm_session_worker_stop_auditor (worker);
worker->priv->session_vt = 0;
g_debug ("GdmSessionWorker: state NONE");
gdm_session_worker_set_state (worker, GDM_SESSION_WORKER_STATE_NONE);
}
......
......@@ -133,11 +133,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 {
......@@ -154,9 +153,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 {
......@@ -347,13 +344,24 @@ 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,
const char *type)
{
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[] = {
......@@ -367,35 +375,32 @@ get_system_session_dirs (GdmSession *self,
search_array = g_array_new (TRUE, TRUE, sizeof (char *));
if (type == NULL || g_str_equal (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);
for (j = 0; self->supported_session_types[j] != NULL; j++) {
const char *supported_type = self->supported_session_types[j];
if (g_str_equal (supported_type, "x11") &&
(type == NULL || g_str_equal (type, supported_type))) {
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));
}
g_array_append_vals (search_array, x_search_dirs, G_N_ELEMENTS (x_search_dirs));
}
#ifdef ENABLE_WAYLAND_SUPPORT
if (!self->ignore_wayland &&
(type == NULL || g_str_equal (type, "wayland"))) {
#ifdef ENABLE_USER_DISPLAY_SERVER
g_array_prepend_val (search_array, wayland_search_dir);
if (g_str_equal (supported_type, "wayland") &&
(type == NULL || g_str_equal (type, supported_type))) {
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_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);
g_array_append_val (search_array, wayland_search_dir);
}
g_array_append_val (search_array, wayland_search_dir);
#endif
}
#endif
search_dirs = g_strdupv ((char **) search_array->data);
......@@ -471,6 +476,12 @@ get_session_command_for_file (GdmSession *self,
*command = NULL;
}
if (!supports_session_type (self, type)) {
g_debug ("GdmSession: ignoring %s session command request for file '%s'",
type, file);
goto out;
}
g_debug ("GdmSession: getting session command for file '%s'", file);
key_file = load_key_file_for_file (self, file, type, NULL);
if (key_file == NULL) {
......@@ -1011,19 +1022,22 @@ worker_on_saved_session_name_read (GdmDBusWorker *worker,
g_debug ("GdmSession: not using invalid .dmrc session: %s", session_name);
g_free (self->saved_session);
self->saved_session = NULL;
} else if (strcmp (session_name,
get_default_session_name (self)) != 0) {
g_free (self->saved_session);
self->saved_session = g_strdup (session_name);
if (self->greeter_interface != NULL) {
gdm_dbus_greeter_emit_default_session_name_changed (self->greeter_interface,
session_name);
update_session_type (self);
} else {
if (strcmp (session_name,
get_default_session_name (self)) != 0) {
g_free (self->saved_session);
self->saved_session = g_strdup (session_name);
if (self->greeter_interface != NULL) {
gdm_dbus_greeter_emit_default_session_name_changed (self->greeter_interface,
session_name);
}
}
if (self->saved_session_type != NULL)
set_session_type (self, self->saved_session_type);
}
update_session_type (self);
}
static void
......@@ -2257,14 +2271,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,
......@@ -3189,15 +3207,15 @@ gdm_session_is_wayland_session (GdmSession *self)
{
GKeyFile *key_file;
gboolean is_wayland_session = FALSE;
char *filename;
char *full_path = NULL;
char *filename;
g_autofree char *full_path = NULL;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (GDM_IS_SESSION (self), FALSE);
filename = get_session_filename (self);
key_file = load_key_file_for_file (self, filename, "wayland", &full_path);
key_file = load_key_file_for_file (self, filename, NULL, &full_path);
if (key_file == NULL) {
goto out;
......@@ -3221,7 +3239,8 @@ update_session_type (GdmSession *self)
#ifdef ENABLE_WAYLAND_SUPPORT
gboolean is_wayland_session = FALSE;
is_wayland_session = gdm_session_is_wayland_session (self);
if (supports_session_type (self, "wayland"))
is_wayland_session = gdm_session_is_wayland_session (self);
if (is_wayland_session) {
set_session_type (self, "wayland");
......@@ -3540,11 +3559,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;
......@@ -3598,11 +3615,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;
......@@ -3620,6 +3635,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);
......@@ -4034,15 +4051,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);
......
# disable Wayland on Hi1710 chipsets
ATTR{vendor}=="0x19e5", ATTR{device}=="0x1711", RUN+="@libexecdir@/gdm-runtime-config set daemon WaylandEnable false"
# disable Wayland when using the proprietary nvidia driver
DRIVER=="nvidia", RUN+="@libexecdir@/gdm-runtime-config set daemon WaylandEnable false"
# disable Wayland on hybrid systems with vendor nvidia driver
# default to Xorg on single gpu vendor nvidia systems
DRIVER=="nvidia", ENV{GDM_HAS_VENDOR_NVIDIA_DRIVER}="1"
DRIVER=="nvidia", RUN+="@libexecdir@/gdm-runtime-config set daemon PreferredDisplayServer xorg"
SUBSYSTEM=="drm", KERNEL=="card[1-9]*", ENV{GDM_HAS_NVIDIA_DRIVER}=="1", RUN+="@libexecdir@/gdm-runtime-config set daemon WaylandEnable false"
ACTION=="add", SUBSYSTEM=="module", KERNEL=="nvidia_drm", ATTR{parameters/modeset}=="N", RUN+="@libexecdir@/gdm-runtime-config set daemon WaylandEnable false"
# disable Wayland if modesetting is disabled
IMPORT{cmdline}="nomodeset", RUN+="@libexecdir@/gdm-runtime-config set daemon WaylandEnable false"
......@@ -52,11 +52,21 @@
<signature>b</signature>
<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>
......
......@@ -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);
......
project('gdm', 'c',
version: '40.1',
version: '41.rc',
license: 'GPL2+',
meson_version: '>= 0.50',
)
......
This diff is collapsed.