diff options
-rw-r--r-- | data/Makefile.am | 26 | ||||
-rw-r--r-- | data/gnome-session.schemas.in | 43 | ||||
-rw-r--r-- | data/gnome-session.schemas.in.in | 101 | ||||
-rw-r--r-- | data/gnome.session.desktop.in.in | 7 | ||||
-rw-r--r-- | doc/man/gnome-session.1 | 29 | ||||
-rw-r--r-- | gnome-session/gsm-session-fill.c | 278 | ||||
-rw-r--r-- | gnome-session/gsm-session-fill.h | 6 | ||||
-rw-r--r-- | gnome-session/main.c | 12 |
8 files changed, 298 insertions, 204 deletions
diff --git a/data/Makefile.am b/data/Makefile.am index f0237372..65e6c7d7 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 00000000..f55db084 --- /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.schemas.in.in b/data/gnome-session.schemas.in.in deleted file mode 100644 index 4e5d87d6..00000000 --- a/data/gnome-session.schemas.in.in +++ /dev/null @@ -1,101 +0,0 @@ -<?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> - <schema> - <key>/schemas/desktop/gnome/session/default_session</key> - <applyto>/desktop/gnome/session/default_session</applyto> - <owner>gnome</owner> - <type>list</type> - <list_type>string</list_type> - <default>[gnome-settings-daemon]</default> - <!-- FIXME when not string frozen: mention that required components are added to the default session --> - <locale name="C"> - <short>Default session</short> - <long>List of applications that are part of the default session.</long> - </locale> - </schema> - <schema> - <key>/schemas/desktop/gnome/session/required_components_list</key> - <applyto>/desktop/gnome/session/required_components_list</applyto> - <owner>gnome</owner> - <type>list</type> - <list_type>string</list_type> - <default>[windowmanager,panel,filemanager]</default> - <locale name="C"> - <short>Required session components</short> - <long>List of components that are required as part of the session. (Each element names a key under "/desktop/gnome/session/required_components"). The Startup Applications preferences tool will not normally allow users to remove a required component from the session, and the session manager will automatically add the required components back to the session at login time if they do get removed.</long> - </locale> - </schema> - <schema> - <key>/schemas/desktop/gnome/session/required_components/windowmanager</key> - <applyto>/desktop/gnome/session/required_components/windowmanager</applyto> - <owner>gnome</owner> - <type>string</type> - <default>@DEFAULT_WM@</default> - <locale name="C"> - <short>Window Manager</short> - <long>The window manager is the program that draws the title bar and borders around windows, and allows you to move and resize windows.</long> - </locale> - </schema> - <schema> - <key>/schemas/desktop/gnome/session/required_components/panel</key> - <applyto>/desktop/gnome/session/required_components/panel</applyto> - <owner>gnome</owner> - <type>string</type> - <default>gnome-panel</default> - <locale name="C"> - <short>Panel</short> - <long>The panel provides the bar at the top or bottom of the screen containing menus, the window list, status icons, the clock, etc.</long> - </locale> - </schema> - <schema> - <key>/schemas/desktop/gnome/session/required_components/filemanager</key> - <applyto>/desktop/gnome/session/required_components/filemanager</applyto> - <owner>gnome</owner> - <type>string</type> - <default>nautilus</default> - <locale name="C"> - <short>File Manager</short> - <long>The file manager provides the desktop icons and allows you to interact with your saved files.</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 00000000..e088f3ce --- /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 59cf661f..e55d058a 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 4745ea5a..12825cda 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 5d09d771..2a8ec08e 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 25f3fb41..1c171204 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); |