summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2018-08-14 14:52:41 -0400
committerRay Strode <rstrode@redhat.com>2021-07-22 13:42:57 -0400
commit495b4fc0d7c65f76b03108199085df4fca98618c (patch)
tree7adbeabeb82049e008451fc014c955b32fdc1d76
parent2a871da666afd3a5312e061b7933e7b62eb5ee39 (diff)
downloadgdm-495b4fc0d7c65f76b03108199085df4fca98618c.tar.gz
session: support new accountsservice Session and SessionType props
At the moment the user's session is stored in a property called "XSession". This is pretty weird if the user is using wayland. AccountService now supports a more generic property "Session" and a related "SessionType" property to replace "XSession". This commit switches GDM over to use the new properties.
-rw-r--r--daemon/gdm-session-settings.c61
-rw-r--r--daemon/gdm-session-settings.h3
-rw-r--r--daemon/gdm-session-worker.c28
-rw-r--r--daemon/gdm-session-worker.xml3
-rw-r--r--daemon/gdm-session.c85
5 files changed, 152 insertions, 28 deletions
diff --git a/daemon/gdm-session-settings.c b/daemon/gdm-session-settings.c
index 484a3b5b..5b64cb65 100644
--- a/daemon/gdm-session-settings.c
+++ b/daemon/gdm-session-settings.c
@@ -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) {
diff --git a/daemon/gdm-session-settings.h b/daemon/gdm-session-settings.h
index 20946bff..db38ffc7 100644
--- a/daemon/gdm-session-settings.h
+++ b/daemon/gdm-session-settings.h
@@ -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 */
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index 6e307ac6..7d7d2496 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -2584,6 +2584,20 @@ on_saved_session_name_read (GdmSessionWorker *worker)
}
static void
+on_saved_session_type_read (GdmSessionWorker *worker)
+{
+ char *session_type;
+
+ session_type = gdm_session_settings_get_session_type (worker->priv->user_settings);
+
+ g_debug ("GdmSessionWorker: Saved session type is %s", session_type);
+ gdm_dbus_worker_emit_saved_session_type_read (GDM_DBUS_WORKER (worker),
+ session_type);
+ g_free (session_type);
+}
+
+
+static void
do_setup (GdmSessionWorker *worker)
{
GError *error;
@@ -3046,6 +3060,11 @@ gdm_session_worker_handle_initialize (GdmDBusWorker *object,
G_CALLBACK (on_saved_session_name_read),
worker);
+ g_signal_connect_swapped (worker->priv->user_settings,
+ "notify::session-type",
+ G_CALLBACK (on_saved_session_type_read),
+ worker);
+
if (worker->priv->username) {
wait_for_settings = !gdm_session_settings_load (worker->priv->user_settings,
worker->priv->username);
@@ -3102,6 +3121,11 @@ gdm_session_worker_handle_setup (GdmDBusWorker *object,
"notify::session-name",
G_CALLBACK (on_saved_session_name_read),
worker);
+ g_signal_connect_swapped (worker->priv->user_settings,
+ "notify::session-type",
+ G_CALLBACK (on_saved_session_type_read),
+ worker);
+
return TRUE;
}
@@ -3144,6 +3168,10 @@ gdm_session_worker_handle_setup_for_user (GdmDBusWorker *object,
"notify::session-name",
G_CALLBACK (on_saved_session_name_read),
worker);
+ g_signal_connect_swapped (worker->priv->user_settings,
+ "notify::session-type",
+ G_CALLBACK (on_saved_session_type_read),
+ worker);
/* Load settings from accounts daemon before continuing
*/
diff --git a/daemon/gdm-session-worker.xml b/daemon/gdm-session-worker.xml
index 4280fe09..a215779c 100644
--- a/daemon/gdm-session-worker.xml
+++ b/daemon/gdm-session-worker.xml
@@ -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>
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index ce49a8df..dcdbb40a 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -88,6 +88,7 @@ struct _GdmSession
char *selected_program;
char *selected_session;
char *saved_session;
+ char *saved_session_type;
char *saved_language;
char *selected_user;
char *user_x11_authority_file;
@@ -355,7 +356,8 @@ supports_session_type (GdmSession *self,
}
static char **
-get_system_session_dirs (GdmSession *self)
+get_system_session_dirs (GdmSession *self,
+ const char *type)
{
GArray *search_array = NULL;
char **search_dirs;
@@ -376,7 +378,8 @@ get_system_session_dirs (GdmSession *self)
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")) {
+ 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);
@@ -386,13 +389,14 @@ get_system_session_dirs (GdmSession *self)
}
#ifdef ENABLE_WAYLAND_SUPPORT
- if (g_str_equal (supported_type, "wayland")) {
- 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);
}
+
+ g_array_append_val (search_array, wayland_search_dir);
}
#endif
}
@@ -419,16 +423,18 @@ is_prog_in_path (const char *prog)
static GKeyFile *
load_key_file_for_file (GdmSession *self,
const char *file,
+ const char *type,
char **full_path)
{
GKeyFile *key_file;
- GError *error;
+ GError *error = NULL;
gboolean res;
char **search_dirs;
key_file = g_key_file_new ();
- search_dirs = get_system_session_dirs (self),
+ search_dirs = get_system_session_dirs (self, type);
+
error = NULL;
res = g_key_file_load_from_dirs (key_file,
file,
@@ -437,8 +443,11 @@ load_key_file_for_file (GdmSession *self,
G_KEY_FILE_NONE,
&error);
if (! res) {
- g_debug ("GdmSession: File '%s' not found: %s", file, error->message);
- g_error_free (error);
+ g_debug ("GdmSession: File '%s' not found in search dirs", file);
+ if (error != NULL) {
+ g_debug ("GdmSession: %s", error->message);
+ g_error_free (error);
+ }
g_key_file_free (key_file);
key_file = NULL;
}
@@ -451,6 +460,7 @@ load_key_file_for_file (GdmSession *self,
static gboolean
get_session_command_for_file (GdmSession *self,
const char *file,
+ const char *type,
char **command)
{
GKeyFile *key_file;
@@ -465,8 +475,14 @@ 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, NULL);
+ key_file = load_key_file_for_file (self, file, type, NULL);
if (key_file == NULL) {
goto out;
}
@@ -524,13 +540,14 @@ out:
static gboolean
get_session_command_for_name (GdmSession *self,
const char *name,
+ const char *type,
char **command)
{
gboolean res;
char *filename;
filename = g_strdup_printf ("%s.desktop", name);
- res = get_session_command_for_file (self, filename, command);
+ res = get_session_command_for_file (self, filename, type, command);
g_free (filename);
return res;
@@ -566,13 +583,13 @@ get_fallback_session_name (GdmSession *self)
if (self->fallback_session_name != NULL) {
/* verify that the cached version still exists */
- if (get_session_command_for_name (self, self->fallback_session_name, NULL)) {
+ if (get_session_command_for_name (self, self->fallback_session_name, NULL, NULL)) {
goto out;
}
}
name = g_strdup ("gnome");
- if (get_session_command_for_name (self, name, NULL)) {
+ if (get_session_command_for_name (self, name, NULL, NULL)) {
g_free (self->fallback_session_name);
self->fallback_session_name = name;
goto out;
@@ -581,7 +598,7 @@ get_fallback_session_name (GdmSession *self)
sessions = g_sequence_new (g_free);
- search_dirs = get_system_session_dirs (self);
+ search_dirs = get_system_session_dirs (self, NULL);
for (i = 0; search_dirs[i] != NULL; i++) {
GDir *dir;
const char *base_name;
@@ -603,7 +620,7 @@ get_fallback_session_name (GdmSession *self)
continue;
}
- if (get_session_command_for_file (self, base_name, NULL)) {
+ if (get_session_command_for_file (self, base_name, NULL, NULL)) {
name = g_strndup (base_name, strlen (base_name) - strlen (".desktop"));
g_sequence_insert_sorted (sessions, name, (GCompareDataFunc) g_strcmp0, NULL);
}
@@ -676,6 +693,9 @@ gdm_session_select_user (GdmSession *self,
g_free (self->saved_session);
self->saved_session = NULL;
+ g_free (self->saved_session_type);
+ self->saved_session_type = NULL;
+
g_free (self->saved_language);
self->saved_language = NULL;
}
@@ -996,7 +1016,7 @@ worker_on_saved_session_name_read (GdmDBusWorker *worker,
{
GdmSession *self = conversation->session;
- if (! get_session_command_for_name (self, session_name, NULL)) {
+ if (! get_session_command_for_name (self, session_name, self->saved_session_type, NULL)) {
/* ignore sessions that don't exist */
g_debug ("GdmSession: not using invalid .dmrc session: %s", session_name);
g_free (self->saved_session);
@@ -1016,6 +1036,17 @@ worker_on_saved_session_name_read (GdmDBusWorker *worker,
}
+static void
+worker_on_saved_session_type_read (GdmDBusWorker *worker,
+ const char *session_type,
+ GdmSessionConversation *conversation)
+{
+ GdmSession *self = conversation->session;
+
+ g_free (self->saved_session_type);
+ self->saved_session_type = g_strdup (session_type);
+}
+
static GdmSessionConversation *
find_conversation_by_pid (GdmSession *self,
GPid pid)
@@ -1150,6 +1181,9 @@ register_worker (GdmDBusWorkerManager *worker_manager_interface,
"saved-session-name-read",
G_CALLBACK (worker_on_saved_session_name_read), conversation);
g_signal_connect (conversation->worker_proxy,
+ "saved-session-type-read",
+ G_CALLBACK (worker_on_saved_session_type_read), conversation);
+ g_signal_connect (conversation->worker_proxy,
"cancel-pending-query",
G_CALLBACK (worker_on_cancel_pending_query), conversation);
@@ -1946,6 +1980,9 @@ free_conversation (GdmSessionConversation *conversation)
G_CALLBACK (worker_on_saved_session_name_read),
conversation);
g_signal_handlers_disconnect_by_func (conversation->worker_proxy,
+ G_CALLBACK (worker_on_saved_session_type_read),
+ conversation);
+ g_signal_handlers_disconnect_by_func (conversation->worker_proxy,
G_CALLBACK (worker_on_cancel_pending_query),
conversation);
g_clear_object (&conversation->worker_proxy);
@@ -2557,7 +2594,7 @@ get_session_command (GdmSession *self)
session_name = get_session_name (self);
command = NULL;
- res = get_session_command_for_name (self, session_name, &command);
+ res = get_session_command_for_name (self, session_name, NULL, &command);
if (! res) {
g_critical ("Cannot find a command for specified session: %s", session_name);
exit (EXIT_FAILURE);
@@ -2579,7 +2616,7 @@ get_session_desktop_names (GdmSession *self)
filename = g_strdup_printf ("%s.desktop", get_session_name (self));
g_debug ("GdmSession: getting desktop names for file '%s'", filename);
- keyfile = load_key_file_for_file (self, filename, NULL);
+ keyfile = load_key_file_for_file (self, filename, NULL, NULL);
if (keyfile != NULL) {
gchar **names;
@@ -3175,7 +3212,7 @@ gdm_session_is_wayland_session (GdmSession *self)
filename = get_session_filename (self);
if (supports_session_type (self, "wayland")) {
- key_file = load_key_file_for_file (self, filename, &full_path);
+ key_file = load_key_file_for_file (self, filename, "wayland", &full_path);
if (key_file == NULL) {
goto out;
@@ -3198,9 +3235,11 @@ static void
update_session_type (GdmSession *self)
{
#ifdef ENABLE_WAYLAND_SUPPORT
- gboolean is_wayland_session;
+ gboolean is_wayland_session = FALSE;
+
+ if (supports_session_type (self, "wayland"))
+ is_wayland_session = gdm_session_is_wayland_session (self);
- is_wayland_session = gdm_session_is_wayland_session (self);
if (is_wayland_session) {
set_session_type (self, "wayland");
} else {
@@ -3222,7 +3261,7 @@ gdm_session_session_registers (GdmSession *self)
filename = get_session_filename (self);
- key_file = load_key_file_for_file (self, filename, NULL);
+ key_file = load_key_file_for_file (self, filename, NULL, NULL);
session_registers = g_key_file_get_boolean (key_file,
G_KEY_FILE_DESKTOP_GROUP,
@@ -3262,7 +3301,7 @@ gdm_session_bypasses_xsession (GdmSession *self)
filename = get_session_filename (self);
- key_file = load_key_file_for_file (self, filename, NULL);
+ key_file = load_key_file_for_file (self, filename, "x11", NULL);
error = NULL;
res = g_key_file_has_key (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GDM-BypassXsession", NULL);