Skip to content
Commits on Source (206)
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 41.0
============
- Translation updates
==============
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
==========
Version 40
==========
- 100% CPU fix
- Translation updates
================
Version 40.rc
================
- Fingerprint auth fixes
- Fix timeout handling for graphics bringup
- Translation updates
================
Version 40.beta
================
- xinit script improvements
- Build goo fixes
- Support systems that boot before the graphics subsystem fully loads
- Don't overwrite PATH set by user
- Generalize gdm-disable-wayland into new gdm-runtime-config tool
- Fail hard if accountsservice fails
- PAM integration improvements
- Leak fixes
- Stop using deprecated systemd functions
- Translation updates
================
Version 3.38.2.1
================
......
......@@ -257,10 +257,10 @@ _read_bytes (int fd,
return FALSE;
} else if (bytes_left_to_read > 0) {
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
"%s", g_strerror (errno));
g_set_error_literal (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
g_strerror (errno));
return FALSE;
}
......@@ -292,10 +292,10 @@ gdm_generate_random_bytes (gsize size,
fd = open ("/dev/urandom", O_RDONLY);
if (fd < 0) {
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
"%s", g_strerror (errno));
g_set_error_literal (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
g_strerror (errno));
close (fd);
return NULL;
}
......@@ -512,24 +512,6 @@ goto_login_session (GDBusConnection *connection,
return FALSE;
}
res = sd_seat_can_multi_session (seat_id);
if (res < 0) {
free (seat_id);
g_debug ("failed to determine whether seat can do multi session: %s", strerror (-res));
g_set_error (error, GDM_COMMON_ERROR, 0, _("The system is unable to determine whether to switch to an existing login screen or start up a new login screen."));
return FALSE;
}
if (res == 0) {
free (seat_id);
g_set_error (error, GDM_COMMON_ERROR, 0, _("The system is unable to start up a new login screen."));
return FALSE;
}
res = gdm_get_login_window_session_id (seat_id, &session_id);
if (res && session_id != NULL) {
res = gdm_activate_session_by_id (connection, seat_id, session_id);
......@@ -974,3 +956,126 @@ gdm_find_display_session (GPid pid,
return TRUE;
}
static void
load_env_file (GFile *file,
GdmLoadEnvVarFunc load_env_func,
GdmExpandVarFunc expand_func,
gpointer user_data)
{
gchar *contents;
gchar **lines;
gchar *line, *p;
gchar *var, *var_end;
gchar *expanded;
char *filename;
int i;
filename = g_file_get_path (file);
g_debug ("Loading env vars from %s\n", filename);
g_free (filename);
if (g_file_load_contents (file, NULL, &contents, NULL, NULL, NULL)) {
lines = g_strsplit (contents, "\n", -1);
g_free (contents);
for (i = 0; lines[i] != NULL; i++) {
line = lines[i];
p = line;
while (g_ascii_isspace (*p))
p++;
if (*p == '#' || *p == '\0')
continue;
var = p;
while (gdm_shell_var_is_valid_char (*p, p == var))
p++;
var_end = p;
while (g_ascii_isspace (*p))
p++;
if (var == var_end || *p != '=') {
g_warning ("Invalid env.d line '%s'\n", line);
continue;
}
*var_end = 0;
p++; /* Skip = */
while (g_ascii_isspace (*p))
p++;
expanded = gdm_shell_expand (p, expand_func, user_data);
expanded = g_strchomp (expanded);
load_env_func (var, expanded, user_data);
g_free (expanded);
}
g_strfreev (lines);
}
}
static gint
compare_str (gconstpointer a,
gconstpointer b)
{
return strcmp (*(const char **)a, *(const char **)b);
}
static void
gdm_load_env_dir (GFile *dir,
GdmLoadEnvVarFunc load_env_func,
GdmExpandVarFunc expand_func,
gpointer user_data)
{
GFileInfo *info = NULL;
GFileEnumerator *enumerator = NULL;
GPtrArray *names = NULL;
GFile *file;
const gchar *name;
int i;
enumerator = g_file_enumerate_children (dir,
G_FILE_ATTRIBUTE_STANDARD_TYPE","
G_FILE_ATTRIBUTE_STANDARD_NAME","
G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN","
G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP,
G_FILE_QUERY_INFO_NONE,
NULL, NULL);
if (!enumerator) {
goto out;
}
names = g_ptr_array_new_with_free_func (g_free);
while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL) {
if (g_file_info_get_file_type (info) == G_FILE_TYPE_REGULAR &&
!g_file_info_get_is_hidden (info) &&
g_str_has_suffix (g_file_info_get_name (info), ".env"))
g_ptr_array_add (names, g_strdup (g_file_info_get_name (info)));
g_clear_object (&info);
}
g_ptr_array_sort (names, compare_str);
for (i = 0; i < names->len; i++) {
name = g_ptr_array_index (names, i);
file = g_file_get_child (dir, name);
load_env_file (file, load_env_func, expand_func, user_data);
g_object_unref (file);
}
out:
g_clear_pointer (&names, g_ptr_array_unref);
g_clear_object (&enumerator);
}
void
gdm_load_env_d (GdmLoadEnvVarFunc load_env_func,
GdmExpandVarFunc expand_func,
gpointer user_data)
{
GFile *dir;
dir = g_file_new_for_path (DATADIR "/gdm/env.d");
gdm_load_env_dir (dir, load_env_func, expand_func, user_data);
g_object_unref (dir);
dir = g_file_new_for_path (GDMCONFDIR "/env.d");
gdm_load_env_dir (dir, load_env_func, expand_func, user_data);
g_object_unref (dir);
}
......@@ -43,6 +43,10 @@ GQuark gdm_common_error_quark (void);
typedef char * (*GdmExpandVarFunc) (const char *var,
gpointer user_data);
typedef void (*GdmLoadEnvVarFunc) (const char *var,
const char *value,
gpointer user_data);
G_BEGIN_DECLS
int gdm_wait_on_pid (int pid);
......@@ -87,6 +91,10 @@ gboolean gdm_activate_session_by_id (GDBusConnection *connection,
const char *seat_id,
const char *session_id);
void gdm_load_env_d (GdmLoadEnvVarFunc load_env_func,
GdmExpandVarFunc expand_func,
gpointer user_data);
G_END_DECLS
#endif /* _GDM_COMMON_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"
......
......@@ -183,3 +183,17 @@ gdm_dbus_get_uid_for_name (const char *system_bus_name,
return retval;
}
void
gdm_dbus_error_ensure (GQuark domain)
{
/* The primary purpose of this function is to make sure the error quark
* is registered internally with gdbus before any bus traffic occurs,
* so we get remote errors mapped correctly to their local counterparts.
* This error quark registration happens implicitly the first time the
* quark is used.
* Note that g_debug is never optimized away, only the output is suppressed.
*/
g_debug ("GdmDBusUtils: Registered DBus error domain '%s'",
g_quark_to_string (domain));
}
......@@ -35,4 +35,6 @@ gboolean gdm_dbus_get_pid_for_name (const char *system_bus_name,
gboolean gdm_dbus_get_uid_for_name (const char *system_bus_name,
uid_t *out_uid,
GError **error);
void gdm_dbus_error_ensure (GQuark domain);
#endif
......@@ -270,10 +270,10 @@ _create_xauth_file_for_user (const char *username,
if (g_file_test (GDM_XAUTH_DIR, G_FILE_TEST_IS_DIR) == FALSE) {
g_remove (GDM_XAUTH_DIR);
if (g_mkdir (GDM_XAUTH_DIR, 0711) != 0) {
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
"%s", g_strerror (errno));
g_set_error_literal (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
g_strerror (errno));
goto out;
}
......@@ -372,10 +372,10 @@ _create_xauth_file_for_user (const char *username,
errno = 0;
fp = fdopen (fd, "w");
if (fp == NULL) {
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
"%s", g_strerror (errno));
g_set_error_literal (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
g_strerror (errno));
close (fd);
fd = -1;
goto out;
......@@ -532,10 +532,10 @@ gdm_display_access_file_add_display_with_cookie (GdmDisplayAccessFile *file,
*/
if (!XauWriteAuth (file->fp, &auth_entry)
|| fflush (file->fp) == EOF) {
g_set_error (error,
g_set_error_literal (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
"%s", g_strerror (errno));
g_strerror (errno));
display_added = FALSE;
} else {
display_added = TRUE;
......
......@@ -76,7 +76,7 @@ purge_display (char *id,
}
}
static void
static gboolean
purge_displays (GdmDisplayFactory *factory)
{
GdmDisplayFactoryPrivate *priv;
......@@ -86,6 +86,8 @@ purge_displays (GdmDisplayFactory *factory)
gdm_display_store_foreach_remove (priv->display_store,
(GdmDisplayStoreFunc)purge_display,
NULL);
return G_SOURCE_REMOVE;
}
void
......
......@@ -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);
......@@ -514,9 +517,9 @@ static gboolean
look_for_existing_users_sync (GdmDisplay *self)
{
GdmDisplayPrivate *priv;
GError *error = NULL;
GVariant *call_result;
GVariant *user_list;
g_autoptr(GError) error = NULL;
g_autoptr(GVariant) call_result = NULL;
g_autoptr(GVariant) user_list = NULL;
priv = gdm_display_get_instance_private (self);
priv->accountsservice_proxy = g_dbus_proxy_new_sync (priv->connection,
......@@ -529,7 +532,7 @@ look_for_existing_users_sync (GdmDisplay *self)
if (!priv->accountsservice_proxy) {
g_critical ("Failed to contact accountsservice: %s", error->message);
goto out;
return FALSE;
}
call_result = g_dbus_proxy_call_sync (priv->accountsservice_proxy,
......@@ -542,16 +545,13 @@ look_for_existing_users_sync (GdmDisplay *self)
if (!call_result) {
g_critical ("Failed to list cached users: %s", error->message);
goto out;
return FALSE;
}
g_variant_get (call_result, "(@ao)", &user_list);
priv->have_existing_user_accounts = g_variant_n_children (user_list) > 0;
g_variant_unref (user_list);
g_variant_unref (call_result);
out:
g_clear_error (&error);
return priv->accountsservice_proxy != NULL && call_result != NULL;
return TRUE;
}
gboolean
......@@ -678,8 +678,6 @@ gdm_display_unmanage (GdmDisplay *self)
priv = gdm_display_get_instance_private (self);
g_debug ("GdmDisplay: unmanage display");
gdm_display_disconnect (self);
if (priv->user_access_file != NULL) {
......@@ -915,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,
......@@ -971,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;
......@@ -1049,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;
......@@ -1234,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);
......@@ -1394,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
......@@ -1476,9 +1506,9 @@ static void
self_destruct (GdmDisplay *self)
{
g_object_ref (self);
if (gdm_display_get_status (self) == GDM_DISPLAY_MANAGED) {
gdm_display_unmanage (self);
}
g_debug ("GdmDisplay: initiating display self-destruct");
gdm_display_unmanage (self);
if (gdm_display_get_status (self) != GDM_DISPLAY_FINISHED) {
queue_finish (self);
......@@ -1726,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);
......
......@@ -113,6 +113,23 @@ static void gdm_launch_environment_finalize (GObject
G_DEFINE_TYPE_WITH_PRIVATE (GdmLaunchEnvironment, gdm_launch_environment, G_TYPE_OBJECT)
static char *
get_var_cb (const char *var,
gpointer user_data)
{
const char *value = g_hash_table_lookup (user_data, var);
return g_strdup (value);
}
static void
load_env_func (const char *var,
const char *value,
gpointer user_data)
{
GHashTable *environment = user_data;
g_hash_table_replace (environment, g_strdup (var), g_strdup (value));
}
static GHashTable *
build_launch_environment (GdmLaunchEnvironment *launch_environment,
gboolean start_session)
......@@ -144,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 */
......@@ -159,15 +177,6 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment,
g_strdup (g_getenv (optional_environment[i])));
}
system_data_dirs = g_strjoinv (":", (char **) g_get_system_data_dirs ());
g_hash_table_insert (hash,
g_strdup ("XDG_DATA_DIRS"),
g_strdup_printf ("%s:%s",
DATADIR "/gdm/greeter",
system_data_dirs));
g_free (system_data_dirs);
if (launch_environment->priv->x11_authority_file != NULL)
g_hash_table_insert (hash, g_strdup ("XAUTHORITY"), g_strdup (launch_environment->priv->x11_authority_file));
......@@ -218,6 +227,32 @@ build_launch_environment (GdmLaunchEnvironment *launch_environment,
g_hash_table_insert (hash, g_strdup ("RUNNING_UNDER_GDM"), g_strdup ("true"));
/* Now populate XDG_DATA_DIRS from env.d if we're running initial setup; this allows
* e.g. Flatpak apps to be recognized by gnome-shell.
*/
if (g_strcmp0 (launch_environment->priv->session_mode, INITIAL_SETUP_SESSION_MODE) == 0)
gdm_load_env_d (load_env_func, get_var_cb, hash);
/* Prepend our own XDG_DATA_DIRS value */
system_data_dirs = g_strdup (g_hash_table_lookup (hash, "XDG_DATA_DIRS"));
if (!system_data_dirs)
system_data_dirs = g_strjoinv (":", (char **) g_get_system_data_dirs ());
g_hash_table_insert (hash,
g_strdup ("XDG_DATA_DIRS"),
g_strdup_printf ("%s:%s",
DATADIR "/gdm/greeter",
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;
}
......
This diff is collapsed.
......@@ -121,9 +121,9 @@ static void gdm_manager_class_init (GdmManagerClass *klass);
static void gdm_manager_init (GdmManager *manager);
static void gdm_manager_dispose (GObject *object);
static GdmSession *create_user_session_for_display (GdmManager *manager,
GdmDisplay *display,
uid_t allowed_user);
static void create_user_session_for_display (GdmManager *manager,
GdmDisplay *display,
uid_t allowed_user);
static void start_user_session (GdmManager *manager,
StartUserSessionOperation *operation);
static void clean_user_session (GdmSession *session);
......@@ -1333,19 +1333,21 @@ 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
*/
session = create_user_session_for_display (manager, display, 0);
create_user_session_for_display (manager, display, 0);
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");
......@@ -1544,6 +1546,8 @@ on_display_status_changed (GdmDisplay *display,
}
#endif
g_object_set_data (G_OBJECT (display), "gdm-user-session", NULL);
if (display == manager->priv->automatic_login_display) {
g_clear_weak_pointer (&manager->priv->automatic_login_display);
......@@ -2289,7 +2293,7 @@ clean_user_session (GdmSession *session)
g_object_unref (session);
}
static GdmSession *
static void
create_user_session_for_display (GdmManager *manager,
GdmDisplay *display,
uid_t allowed_user)
......@@ -2302,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,
......@@ -2314,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);
......@@ -2329,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,
......@@ -2399,16 +2401,9 @@ create_user_session_for_display (GdmManager *manager,
g_object_set_data (G_OBJECT (session), "gdm-display", display);
g_object_set_data_full (G_OBJECT (display),
"gdm-user-session",
g_object_ref (session),
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
return session;
}
static void
......
......@@ -39,6 +39,7 @@ struct _GdmSessionSettingsPrivate
ActUserManager *user_manager;
ActUser *user;
char *session_name;
char *session_type;
char *language_name;
};
......@@ -58,6 +59,7 @@ static void gdm_session_settings_get_property (GObject *object,
enum {
PROP_0 = 0,
PROP_SESSION_NAME,
PROP_SESSION_TYPE,
PROP_LANGUAGE_NAME,
PROP_IS_LOADED
};
......@@ -93,6 +95,11 @@ gdm_session_settings_class_install_properties (GdmSessionSettingsClass *settings
NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_SESSION_NAME, param_spec);
param_spec = g_param_spec_string ("session-type", "Session Type",
"The type of the session",
NULL, G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_SESSION_TYPE, param_spec);
param_spec = g_param_spec_string ("language-name", "Language Name",
"The name of the language",
NULL,
......@@ -163,6 +170,19 @@ gdm_session_settings_set_session_name (GdmSessionSettings *settings,
}
}
void
gdm_session_settings_set_session_type (GdmSessionSettings *settings,
const char *session_type)
{
g_return_if_fail (GDM_IS_SESSION_SETTINGS (settings));
if (settings->priv->session_type == NULL ||
g_strcmp0 (settings->priv->session_type, session_type) != 0) {
settings->priv->session_type = g_strdup (session_type);
g_object_notify (G_OBJECT (settings), "session-type");
}
}
char *
gdm_session_settings_get_language_name (GdmSessionSettings *settings)
{
......@@ -177,6 +197,13 @@ gdm_session_settings_get_session_name (GdmSessionSettings *settings)
return g_strdup (settings->priv->session_name);
}
char *
gdm_session_settings_get_session_type (GdmSessionSettings *settings)
{
g_return_val_if_fail (GDM_IS_SESSION_SETTINGS (settings), NULL);
return g_strdup (settings->priv->session_type);
}
static void
gdm_session_settings_set_property (GObject *object,
guint prop_id,
......@@ -196,6 +223,10 @@ gdm_session_settings_set_property (GObject *object,
gdm_session_settings_set_session_name (settings, g_value_get_string (value));
break;
case PROP_SESSION_TYPE:
gdm_session_settings_set_session_type (settings, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
......@@ -216,6 +247,10 @@ gdm_session_settings_get_property (GObject *object,
g_value_set_string (value, settings->priv->session_name);
break;
case PROP_SESSION_TYPE:
g_value_set_string (value, settings->priv->session_type);
break;
case PROP_LANGUAGE_NAME:
g_value_set_string (value, settings->priv->language_name);
break;
......@@ -254,6 +289,7 @@ static void
load_settings_from_user (GdmSessionSettings *settings)
{
const char *session_name;
const char *session_type;
const char *language_name;
if (!act_user_is_loaded (settings->priv->user)) {
......@@ -261,20 +297,31 @@ load_settings_from_user (GdmSessionSettings *settings)
return;
}
session_name = act_user_get_x_session (settings->priv->user);
g_debug ("GdmSessionSettings: saved session is %s", session_name);
/* if the user doesn't have saved state, they don't have any settings worth reading */
if (!act_user_get_saved (settings->priv->user))
goto out;
session_type = act_user_get_session_type (settings->priv->user);
session_name = act_user_get_session (settings->priv->user);
if (session_name != NULL) {
g_debug ("GdmSessionSettings: saved session is %s (type %s)", session_name, session_type);
if (session_type != NULL && session_type[0] != '\0') {
gdm_session_settings_set_session_type (settings, session_type);
}
if (session_name != NULL && session_name[0] != '\0') {
gdm_session_settings_set_session_name (settings, session_name);
}
language_name = act_user_get_language (settings->priv->user);
g_debug ("GdmSessionSettings: saved language is %s", language_name);
if (language_name != NULL) {
if (language_name != NULL && language_name[0] != '\0') {
gdm_session_settings_set_language_name (settings, language_name);
}
out:
g_object_notify (G_OBJECT (settings), "is-loaded");
}
......@@ -349,7 +396,11 @@ gdm_session_settings_save (GdmSessionSettings *settings,
}
if (settings->priv->session_name != NULL) {
act_user_set_x_session (user, settings->priv->session_name);
act_user_set_session (user, settings->priv->session_name);
}
if (settings->priv->session_type != NULL) {
act_user_set_session_type (user, settings->priv->session_type);
}
if (settings->priv->language_name != NULL) {
......
......@@ -60,10 +60,13 @@ gboolean gdm_session_settings_save (GdmSessionSettings
gboolean gdm_session_settings_is_loaded (GdmSessionSettings *settings);
char *gdm_session_settings_get_language_name (GdmSessionSettings *settings);
char *gdm_session_settings_get_session_name (GdmSessionSettings *settings);
char *gdm_session_settings_get_session_type (GdmSessionSettings *settings);
void gdm_session_settings_set_language_name (GdmSessionSettings *settings,
const char *language_name);
void gdm_session_settings_set_session_name (GdmSessionSettings *settings,
const char *session_name);
void gdm_session_settings_set_session_type (GdmSessionSettings *settings,
const char *session_type);
G_END_DECLS
#endif /* GDM_SESSION_SETTINGS_H */
......@@ -36,6 +36,7 @@ typedef enum _GdmSessionWorkerError {
GDM_SESSION_WORKER_ERROR_COMMUNICATING,
GDM_SESSION_WORKER_ERROR_WORKER_DIED,
GDM_SESSION_WORKER_ERROR_SERVICE_UNAVAILABLE,
GDM_SESSION_WORKER_ERROR_TOO_MANY_RETRIES,
GDM_SESSION_WORKER_ERROR_AUTHENTICATING,
GDM_SESSION_WORKER_ERROR_AUTHORIZING,
GDM_SESSION_WORKER_ERROR_OPENING_LOG_FILE,
......
This diff is collapsed.
......@@ -78,6 +78,9 @@
<signal name="SavedSessionNameRead">
<arg name="session_name" type="s"/>
</signal>
<signal name="SavedSessionTypeRead">
<arg name="session_type" type="s"/>
</signal>
<signal name="UsernameChanged">
<arg name="new_username" type="s"/>
</signal>
......
This diff is collapsed.
......@@ -289,6 +289,17 @@ spawn_session (State *state,
"WAYLAND_SOCKET",
"GNOME_SHELL_SESSION_MODE",
NULL };
/* The environment variables listed below are those we have set (or
* received from our own execution environment) only as a fallback to
* make things work, as opposed to a information directly pertaining to
* the session about to be started. Variables listed here will not
* overwrite the existing environment (possibly) imported from the
* systemd --user instance.
* As an example: We need a PATH for some of the launched subprocesses
* to work, but if the user (or the distributor) has customized the PATH
* via one of systemds user-environment-generators, that version should
* be preferred. */
static const char *fallback_variables[] = { "PATH", NULL };
g_debug ("Running wayland session");
......@@ -320,7 +331,16 @@ spawn_session (State *state,
continue;
}
g_subprocess_launcher_setenv (launcher, environment_entry[0], environment_entry[1], FALSE);
/* Merge the environment block imported from systemd --user with the
* environment we have set for ourselves (and thus pass on to the
* launcher process). Variables we have set have precedence, as to not
* import stale data from prior user sessions, with the exception of
* those listed in fallback_variables. See the comment there for more
* explanations. */
g_subprocess_launcher_setenv (launcher,
environment_entry[0],
environment_entry[1],
g_strv_contains (fallback_variables, environment_entry[0]));
}
/* Don't allow session specific environment variables from earlier sessions to
......