[gnome-session] gsm: Move the definition of a session from gconf to .desktop-like files
- From: Vincent Untz <vuntz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-session] gsm: Move the definition of a session from gconf to .desktop-like files
- Date: Mon, 29 Nov 2010 19:09:40 +0000 (UTC)
commit 30da8bec52103eb812439ddc03dcdb9ff47d34a9
Author: Vincent Untz <vuntz gnome org>
Date: Mon Nov 29 19:06:30 2010 +0100
gsm: Move the definition of a session from gconf to .desktop-like files
This will help us both for the GSettings migration and to implement the
fallback from GNOME Shell to Classic GNOME.
The --default-session-key argument has been changed to --session, which
takes the basename (without extension) of the .desktop-like file to use.
By default, gnome is used, and the gnome.session file is looked for in
$XDG_CONFIG_HOME/gnome-session/sessions,
$XDG_CONFIG_DIRS/gnome-session/sessions,
$XDG_DATA_DIRS/gnome-session/sessions.
data/Makefile.am | 26 +++--
data/gnome-session.schemas.in | 43 ++++++
data/gnome-session.schemas.in.in | 101 --------------
data/gnome.session.desktop.in.in | 7 +
doc/man/gnome-session.1 | 29 +++--
gnome-session/gsm-session-fill.c | 278 +++++++++++++++++++++++++++-----------
gnome-session/gsm-session-fill.h | 6 +-
gnome-session/main.c | 12 +-
8 files changed, 298 insertions(+), 204 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index f023737..65e6c7d 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -15,22 +15,29 @@ desktopdir = $(datadir)/applications
desktop_in_files = session-properties.desktop.in
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
+sessiondir = $(datadir)/gnome-session/sessions
+session_in_in_files = gnome.session.desktop.in.in
+session_in_files = $(session_in_in_files:.session.desktop.in.in=.session.desktop.in)
+session_DATA = $(session_in_files:.session.desktop.in=.session)
+
+%.session.desktop.in: %.session.desktop.in.in Makefile
+ $(AM_V_GEN)sed \
+ -e "s|\ DEFAULT_WM\@|$(DEFAULT_WM)|" \
+ -e "s|\ LIBEXECDIR\@|$(libexecdir)|" \
+ $< > $@
+
+%.session: %.session.desktop.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
+
if USE_GNOME_WM
desktop_in_files += gnome-wm.desktop.in
endif
@INTLTOOL_DESKTOP_RULE@
-schemas_in_in_files = gnome-session.schemas.in.in
-schemas_in_files = $(schemas_in_in_files:.schemas.in.in=.schemas.in)
+schemas_in_files = gnome-session.schemas.in
schemasdir = $(GCONF_SCHEMA_FILE_DIR)
schemas_DATA = $(schemas_in_files:.schemas.in=.schemas)
-$(schemas_in_files): $(schemas_in_files).in Makefile
- $(AM_V_GEN)sed \
- -e "s|\ DEFAULT_WM\@|$(DEFAULT_WM)|" \
- $< > $@
-
@INTLTOOL_SCHEMAS_RULE@
if GCONF_SCHEMAS_INSTALL
@@ -49,15 +56,16 @@ endif
EXTRA_DIST = \
gnome-wm \
$(xsession_in_files) \
- $(schemas_in_in_files) \
+ $(session_in_in_files) \
+ $(schemas_in_files) \
$(ui_DATA) \
$(pixmap_DATA_dist)
CLEANFILES = \
- $(schemas_in_files) \
$(schemas_DATA) \
$(xsession_DATA) \
$(desktop_DATA) \
+ $(session_DATA) \
gnome-wm.desktop
DISTCLEANFILES = \
diff --git a/data/gnome-session.schemas.in b/data/gnome-session.schemas.in
new file mode 100644
index 0000000..f55db08
--- /dev/null
+++ b/data/gnome-session.schemas.in
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<gconfschemafile>
+ <schemalist>
+
+ <schema>
+ <key>/schemas/apps/gnome-session/options/auto_save_session</key>
+ <applyto>/apps/gnome-session/options/auto_save_session</applyto>
+ <owner>gnome</owner>
+ <type>bool</type>
+ <default>false</default>
+ <locale name="C">
+ <short>Save sessions</short>
+ <long>If enabled, gnome-session will save the session automatically.</long>
+ </locale>
+ </schema>
+ <schema>
+ <key>/schemas/apps/gnome-session/options/logout_prompt</key>
+ <applyto>/apps/gnome-session/options/logout_prompt</applyto>
+ <owner>gnome</owner>
+ <type>bool</type>
+ <default>true</default>
+ <locale name="C">
+ <short>Logout prompt</short>
+ <long>If enabled, gnome-session will prompt the user before ending a session.</long>
+ </locale>
+ </schema>
+ <schema>
+ <key>/schemas/desktop/gnome/session/idle_delay</key>
+ <applyto>/desktop/gnome/session/idle_delay</applyto>
+ <owner>gnome</owner>
+ <type>int</type>
+ <default>5</default>
+ <locale name="C">
+ <short>Time before session is considered idle</short>
+ <long>
+ The number of minutes of inactivity before the session is
+ considered idle.
+ </long>
+ </locale>
+ </schema>
+
+ </schemalist>
+</gconfschemafile>
diff --git a/data/gnome.session.desktop.in.in b/data/gnome.session.desktop.in.in
new file mode 100644
index 0000000..e088f3c
--- /dev/null
+++ b/data/gnome.session.desktop.in.in
@@ -0,0 +1,7 @@
+[GNOME Session]
+_Name=GNOME
+Required=windowmanager;panel;filemanager;
+Required-windowmanager= DEFAULT_WM@
+Required-panel=gnome-panel
+Required-filemanager=nautilus
+DefaultApps=gnome-settings-daemon;
diff --git a/doc/man/gnome-session.1 b/doc/man/gnome-session.1
index 59cf661..e55d058 100644
--- a/doc/man/gnome-session.1
+++ b/doc/man/gnome-session.1
@@ -7,7 +7,7 @@
.SH NAME
gnome-session \- Start the GNOME desktop environment
.SH SYNOPSIS
-.B gnome-session [\-\-autostart=DIR] [\-\-default-session-key=KEY] [\-\-failsafe|\-f] [\-\-debug]
+.B gnome-session [\-\-autostart=DIR] [\-\-session=SESSION] [\-\-failsafe|\-f] [\-\-debug]
.SH DESCRIPTION
The \fIgnome-session\fP program starts up the GNOME desktop
environment. This command is typically executed by your login manager
@@ -16,8 +16,12 @@ either your saved session, or it will provide a default session for the
user as defined by the system administrator (or the default GNOME
installation on your system).
.PP
-The default session is defined in the GConf keys under
-\fB/desktop/gnome/session\fP.
+The default session is defined in \fBgnome.session\fP, a .desktop-like
+file that is looked for in
+\fB$XDG_CONFIG_HOME/gnome-session/sessions\fP,
+\fB$XDG_CONFIG_DIRS/gnome-session/sessions\fP and
+\fB$XDG_DATA_DIRS/gnome-session/sessions\fP.
+.PP
When saving a session, \fIgnome-session\fP saves the currently running
applications in the \fB$XDG_CONFIG_HOME/gnome-session/saved-session\fP
directory.
@@ -29,14 +33,12 @@ The following options are supported:
.TP
.I "--autostart=DIR"
Start all applications defined in \fIDIR\fP, instead of starting the
-applications defined in \fB/desktop/gnome/session/default_session\fP,
-or via the \fI--default-session-key\fP option. Multiple
-\fI--autostart\fP options can be passed.
+applications defined in \fBgnome.session\fP, or via the \fI--session\fP
+option. Multiple \fI--autostart\fP options can be passed.
.TP
-.I "--default-session-key=KEY"
-Set the GConf key from which applications running a default session
-should be read to \fIKEY\fP. If not specificed,
-\fB/desktop/gnome/session/default_session\fP will be used.
+.I "--session=SESSION"
+Use the applications defined in \fBSESSION.session\fP. If not specified,
+\fBgnome.session\fP will be used.
.TP
.I "--failsafe"
Run in fail-safe mode. User-specified applications will not be started.
@@ -67,6 +69,13 @@ when gnome-session is invoked.
The applications defined in those directories will be started on login.
\fIgnome-session-properties(1)\fP can be used to easily configure them.
.PP
+.B $XDG_CONFIG_HOME/gnome-session/sessions
+.B $XDG_CONFIG_DIRS/gnome-session/sessions
+.B $XDG_DATA_DIRS/gnome-session/sessions
+.IP
+These directories contain the \fB.session\fP files that can be used
+with the \fI--session\fP option.
+.PP
.B $XDG_CONFIG_HOME/gnome-session/saved-session
.IP
This directory contains the list of applications of the saved session.
diff --git a/gnome-session/gsm-session-fill.c b/gnome-session/gsm-session-fill.c
index 4745ea5..12825cd 100644
--- a/gnome-session/gsm-session-fill.c
+++ b/gnome-session/gsm-session-fill.c
@@ -24,114 +24,103 @@
#include "gsm-session-fill.h"
#include "gsm-consolekit.h"
-#include "gsm-gconf.h"
-#include "gsm-util.h"
#include "gsm-manager.h"
+#include "gsm-util.h"
-#define GSM_GCONF_DEFAULT_SESSION_KEY "/desktop/gnome/session/default_session"
-#define GSM_GCONF_REQUIRED_COMPONENTS_DIRECTORY "/desktop/gnome/session/required_components"
-#define GSM_GCONF_REQUIRED_COMPONENTS_LIST_KEY "/desktop/gnome/session/required_components_list"
+#define GSM_DEFAULT_SESSION "gnome"
+
+#define GSM_KEYFILE_SESSION_GROUP "GNOME Session"
+#define GSM_KEYFILE_REQUIRED_KEY "Required"
+#define GSM_KEYFILE_DEFAULT_KEY "DefaultApps"
/* This doesn't contain the required components, so we need to always
* call append_required_apps() after a call to append_default_apps(). */
static void
append_default_apps (GsmManager *manager,
- const char *default_session_key,
+ GKeyFile *keyfile,
char **autostart_dirs)
{
- GSList *default_apps;
- GSList *a;
- GConfClient *client;
+ char **default_apps;
+ int i;
- g_debug ("main: *** Adding default apps");
+ g_debug ("fill: *** Adding default apps");
- g_assert (default_session_key != NULL);
+ g_assert (keyfile != NULL);
g_assert (autostart_dirs != NULL);
- client = gconf_client_get_default ();
- default_apps = gconf_client_get_list (client,
- default_session_key,
- GCONF_VALUE_STRING,
- NULL);
- g_object_unref (client);
+ default_apps = g_key_file_get_string_list (keyfile,
+ GSM_KEYFILE_SESSION_GROUP, GSM_KEYFILE_DEFAULT_KEY,
+ NULL, NULL);
- for (a = default_apps; a; a = a->next) {
+ if (!default_apps)
+ return;
+
+ for (i = 0; default_apps[i] != NULL; i++) {
char *app_path;
- if (IS_STRING_EMPTY ((char *)a->data)) {
+ if (IS_STRING_EMPTY (default_apps[i]))
continue;
- }
- app_path = gsm_util_find_desktop_file_for_app_name (a->data, autostart_dirs);
+ app_path = gsm_util_find_desktop_file_for_app_name (default_apps[i], autostart_dirs);
if (app_path != NULL) {
gsm_manager_add_autostart_app (manager, app_path, NULL);
g_free (app_path);
}
}
- g_slist_foreach (default_apps, (GFunc) g_free, NULL);
- g_slist_free (default_apps);
+ g_strfreev (default_apps);
}
static void
-append_required_apps (GsmManager *manager)
+append_required_apps (GsmManager *manager,
+ GKeyFile *keyfile)
{
- GSList *required_components;
- GSList *r;
- GConfClient *client;
+ char **required_components;
+ int i;
+
+ g_debug ("fill: *** Adding required apps");
- g_debug ("main: *** Adding required apps");
+ required_components = g_key_file_get_string_list (keyfile,
+ GSM_KEYFILE_SESSION_GROUP, GSM_KEYFILE_REQUIRED_KEY,
+ NULL, NULL);
- client = gconf_client_get_default ();
- required_components = gconf_client_get_list (client,
- GSM_GCONF_REQUIRED_COMPONENTS_LIST_KEY,
- GCONF_VALUE_STRING,
- NULL);
if (required_components == NULL) {
g_warning ("No required applications specified");
+ return;
}
- for (r = required_components; r != NULL; r = r->next) {
- char *path;
- char *default_provider;
- const char *component;
+ for (i = 0; required_components[i] != NULL; i++) {
+ char *key;
+ char *value;
+ char *app_path;
+
+ key = g_strdup_printf ("%s-%s", GSM_KEYFILE_REQUIRED_KEY, required_components[i]);
+ value = g_key_file_get_string (keyfile,
+ GSM_KEYFILE_SESSION_GROUP, key,
+ NULL);
+ g_free (key);
- if (IS_STRING_EMPTY ((char *)r->data)) {
+ if (IS_STRING_EMPTY (value)) {
+ g_free (value);
continue;
}
- component = r->data;
-
- path = g_strdup_printf ("%s/%s",
- GSM_GCONF_REQUIRED_COMPONENTS_DIRECTORY,
- component);
-
- default_provider = gconf_client_get_string (client, path, NULL);
- g_debug ("main: %s looking for component: '%s'", path, default_provider);
- if (default_provider != NULL) {
- char *app_path;
-
- app_path = gsm_util_find_desktop_file_for_app_name (default_provider, NULL);
- if (app_path != NULL) {
- gsm_manager_add_autostart_app (manager, app_path, component);
- } else {
- g_warning ("Unable to find provider '%s' of required component '%s'",
- default_provider,
- component);
- }
- g_free (app_path);
+ g_debug ("fill: %s looking for component: '%s'", required_components[i], value);
+ app_path = gsm_util_find_desktop_file_for_app_name (value, NULL);
+ if (app_path != NULL) {
+ gsm_manager_add_autostart_app (manager, app_path, required_components[i]);
+ } else {
+ g_warning ("Unable to find provider '%s' of required component '%s'",
+ value, required_components[i]);
}
+ g_free (app_path);
- g_free (default_provider);
- g_free (path);
+ g_free (value);
}
- g_debug ("main: *** Done adding required apps");
-
- g_slist_foreach (required_components, (GFunc)g_free, NULL);
- g_slist_free (required_components);
+ g_debug ("fill: *** Done adding required apps");
- g_object_unref (client);
+ g_strfreev (required_components);
}
static void
@@ -153,7 +142,7 @@ maybe_load_saved_session_apps (GsmManager *manager)
static void
load_standard_apps (GsmManager *manager,
- const char *default_session_key)
+ GKeyFile *keyfile)
{
char **autostart_dirs;
int i;
@@ -171,8 +160,8 @@ load_standard_apps (GsmManager *manager,
/* We do this at the end in case a saved session contains an
* application that already provides one of the components. */
- append_default_apps (manager, default_session_key, autostart_dirs);
- append_required_apps (manager);
+ append_default_apps (manager, keyfile, autostart_dirs);
+ append_required_apps (manager, keyfile);
g_strfreev (autostart_dirs);
}
@@ -187,18 +176,155 @@ load_override_apps (GsmManager *manager,
}
}
-void
+static GKeyFile *
+get_session_keyfile_if_valid (const char *path)
+{
+ GKeyFile *keyfile;
+ gsize len;
+ char **list;
+
+ g_debug ("fill: *** Looking if %s is a valid session file", path);
+
+ keyfile = g_key_file_new ();
+
+ if (!g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, NULL)) {
+ g_debug ("Cannot use session '%s': non-existing or invalid file.", path);
+ goto error;
+ }
+
+ if (!g_key_file_has_group (keyfile, GSM_KEYFILE_SESSION_GROUP)) {
+ g_warning ("Cannot use session '%s': no '%s' group.", path, GSM_KEYFILE_SESSION_GROUP);
+ goto error;
+ }
+
+ list = g_key_file_get_string_list (keyfile,
+ GSM_KEYFILE_SESSION_GROUP, GSM_KEYFILE_REQUIRED_KEY,
+ &len, NULL);
+ if (list != NULL) {
+ int i;
+ char *key;
+ char *value;
+
+ for (i = 0; list[i] != NULL; i++) {
+ key = g_strdup_printf ("%s-%s", GSM_KEYFILE_REQUIRED_KEY, list[i]);
+ value = g_key_file_get_string (keyfile,
+ GSM_KEYFILE_SESSION_GROUP, key,
+ NULL);
+ g_free (key);
+
+ if (IS_STRING_EMPTY (value)) {
+ g_free (value);
+ break;
+ }
+
+ g_free (value);
+ }
+
+ if (list[i] != NULL) {
+ g_warning ("Cannot use session '%s': required component '%s' is not defined.", path, list[i]);
+ g_strfreev (list);
+ goto error;
+ }
+
+ g_strfreev (list);
+ }
+
+ /* we don't want an empty session, so if there's no required app, check
+ * that we do have some default apps */
+ if (len == 0) {
+ list = g_key_file_get_string_list (keyfile,
+ GSM_KEYFILE_SESSION_GROUP, GSM_KEYFILE_DEFAULT_KEY,
+ &len, NULL);
+ if (list)
+ g_strfreev (list);
+ if (len == 0) {
+ g_warning ("Cannot use session '%s': no application in the session.", path);
+ goto error;
+ }
+ }
+
+ return keyfile;
+
+error:
+ g_key_file_free (keyfile);
+ return NULL;
+}
+
+/**
+ * find_valid_session_keyfile:
+ * @session: name of session
+ *
+ * We look for the session file in XDG_CONFIG_HOME, XDG_CONFIG_DIRS and
+ * XDG_DATA_DIRS. This enables users and sysadmins to override a specific
+ * session that is shipped in XDG_DATA_DIRS.
+ */
+static GKeyFile *
+find_valid_session_keyfile (const char *session)
+{
+ GPtrArray *dirs;
+ const char * const *system_config_dirs;
+ const char * const *system_data_dirs;
+ int i;
+ GKeyFile *keyfile;
+ char *basename;
+ char *path;
+
+ dirs = g_ptr_array_new ();
+
+ g_ptr_array_add (dirs, (gpointer) g_get_user_config_dir ());
+
+ system_config_dirs = g_get_system_config_dirs ();
+ for (i = 0; system_config_dirs[i]; i++)
+ g_ptr_array_add (dirs, (gpointer) system_config_dirs[i]);
+
+ system_data_dirs = g_get_system_data_dirs ();
+ for (i = 0; system_data_dirs[i]; i++)
+ g_ptr_array_add (dirs, (gpointer) system_data_dirs[i]);
+
+ keyfile = NULL;
+ basename = g_strdup_printf ("%s.session", session);
+ path = NULL;
+
+ for (i = 0; i < dirs->len; i++) {
+ path = g_build_filename (dirs->pdata[i], "gnome-session", "sessions", basename, NULL);
+ keyfile = get_session_keyfile_if_valid (path);
+ if (keyfile != NULL)
+ break;
+ }
+
+ if (dirs)
+ g_ptr_array_free (dirs, TRUE);
+ if (basename)
+ g_free (basename);
+ if (path)
+ g_free (path);
+
+ return keyfile;
+}
+
+gboolean
gsm_session_fill (GsmManager *manager,
char **override_autostart_dirs,
- char *default_session_key)
+ const char *session)
{
+ GKeyFile *keyfile;
+
if (override_autostart_dirs != NULL) {
load_override_apps (manager, override_autostart_dirs);
- } else {
- if (! IS_STRING_EMPTY (default_session_key)) {
- load_standard_apps (manager, default_session_key);
- } else {
- load_standard_apps (manager, GSM_GCONF_DEFAULT_SESSION_KEY);
- }
+ return TRUE;
}
+
+ if (IS_STRING_EMPTY (session))
+ session = GSM_DEFAULT_SESSION;
+
+ keyfile = find_valid_session_keyfile (session);
+
+ if (!keyfile)
+ return FALSE;
+
+ load_standard_apps (manager, keyfile);
+
+ g_key_file_free (keyfile);
+
+ return TRUE;
}
diff --git a/gnome-session/gsm-session-fill.h b/gnome-session/gsm-session-fill.h
index 5d09d77..2a8ec08 100644
--- a/gnome-session/gsm-session-fill.h
+++ b/gnome-session/gsm-session-fill.h
@@ -26,9 +26,9 @@
G_BEGIN_DECLS
-void gsm_session_fill (GsmManager *manager,
- char **override_autostart_dirs,
- char *default_session_key);
+gboolean gsm_session_fill (GsmManager *manager,
+ char **override_autostart_dirs,
+ const char *session);
G_END_DECLS
diff --git a/gnome-session/main.c b/gnome-session/main.c
index 25f3fb4..1c17120 100644
--- a/gnome-session/main.c
+++ b/gnome-session/main.c
@@ -271,10 +271,10 @@ main (int argc, char **argv)
GsmXsmpServer *xsmp_server;
GdmSignalHandler *signal_handler;
static char **override_autostart_dirs = NULL;
- static char *default_session_key = NULL;
+ static char *session_name = NULL;
static GOptionEntry entries[] = {
{ "autostart", 'a', 0, G_OPTION_ARG_STRING_ARRAY, &override_autostart_dirs, N_("Override standard autostart directories"), NULL },
- { "default-session-key", 0, 0, G_OPTION_ARG_STRING, &default_session_key, N_("GConf key used to look up default session"), NULL },
+ { "session", 0, 0, G_OPTION_ARG_STRING, &session_name, N_("Session to use"), NULL },
{ "debug", 0, 0, G_OPTION_ARG_NONE, &debug, N_("Enable debugging code"), NULL },
{ "failsafe", 'f', 0, G_OPTION_ARG_NONE, &failsafe, N_("Do not load user-specified applications"), NULL },
{ "version", 0, 0, G_OPTION_ARG_NONE, &show_version, N_("Version of this application"), NULL },
@@ -350,9 +350,11 @@ main (int argc, char **argv)
gdm_signal_handler_add (signal_handler, SIGINT, signal_cb, manager);
gdm_signal_handler_set_fatal_func (signal_handler, shutdown_cb, manager);
- gsm_session_fill (manager,
- override_autostart_dirs,
- default_session_key);
+ if (!gsm_session_fill (manager,
+ override_autostart_dirs,
+ session_name)) {
+ gsm_util_init_error (TRUE, "%s", "No valid session found.");
+ }
gsm_xsmp_server_start (xsmp_server);
gsm_manager_start (manager);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]