Commit ae10fd39 authored by Lucas Almeida Rocha's avatar Lucas Almeida Rocha

Merge new-gnome-session branch in trunk.

svn path=/trunk/; revision=4623
parent a4528b95
gnome-session authors
new code base authors
---------------------
Dan Winship <danw@gnome.org>
Lucas Rocha <lucasr@gnome.org>
original gnome-session authors
---------------------
Tom Tromey <tromey@cygnus.com>
......
This diff is collapsed.
This diff is collapsed.
Currently active maintainers
----------------------------
Lucas Rocha
E-mail: lucasr@gnome.org
Userid: lucasr
Vincent Untz
E-mail: vuntz@gnome.org
Userid: vuntz
......
SUBDIRS = \
data \
po \
egg \
gnome-session \
man
compat \
splash \
po \
data
EXTRA_DIST = \
MAINTAINERS \
COPYING-DOCS \
HACKING \
intltool-extract.in \
intltool-merge.in \
intltool-update.in
DISTCLEANFILES = \
intltool-extract \
intltool-merge \
intltool-update
DISTCLEANFILES = \
intltool-extract \
intltool-merge \
intltool-update
......@@ -20,6 +20,11 @@ To subscribe:
Send a mail to desktop-devel-list-request@gnome.org
with the subject "subscribe".
Design notes
============
See http://live.gnome.org/SessionManagement
Installation
============
......
......@@ -5,7 +5,7 @@ srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
PKG_NAME="GNOME Desktop Session Manager"
REQUIRED_AUTOMAKE_VERSION=1.7
REQUIRED_AUTOMAKE_VERSION=1.9
(test -f $srcdir/configure.in \
&& test -f $srcdir/HACKING \
......
INCLUDES = \
$(WARN_CFLAGS) \
$(DBUS_GLIB_CFLAGS) \
$(GCONF_CFLAGS) \
$(GNOME_KEYRING_CFLAGS) \
$(GTK_CFLAGS) \
-I$(top_srcdir)/egg \
-DAT_SPI_REGISTRYD_DIR=\""$(AT_SPI_REGISTRYD_DIR)"\" \
-DDEFAULT_SESSION_DIR=\""$(default_sessiondir)"\" \
-DGNOME_KEYRING_DAEMON=\""$(GNOME_KEYRING_DAEMON)"\" \
-DSYSCONFDIR=\""$(sysconfdir)"\"
LDADD = \
$(DBUS_GLIB_LIBS) \
$(GTK_LIBS)
helperdir = $(pkglibdir)/helpers
helper_PROGRAMS = \
at-spi-registryd-wrapper \
gnome-keyring-daemon-wrapper \
gnome-settings-daemon-helper
default_sessiondir = $(datadir)/gnome/default-session
default_session_DATA = \
at-spi-registryd-wrapper.desktop \
gnome-keyring-daemon-wrapper.desktop \
gnome-settings-daemon-helper.desktop
at_spi_registryd_wrapper_SOURCES = \
at-spi-registryd-wrapper.c
gnome_keyring_daemon_wrapper_SOURCES = \
gnome-keyring-daemon-wrapper.c
gnome_keyring_daemon_wrapper_LDADD = \
$(top_builddir)/egg/libeggsmclient.la \
$(GNOME_KEYRING_LIBS) \
$(LDADD)
gnome_settings_daemon_helper_SOURCES = \
gnome-settings-daemon-helper.c
gnome_settings_daemon_helper_LDADD = \
$(GCONF_LIBS) \
$(LDADD)
%.desktop: %.desktop.in
sed -e 's,\@helperdir\@,$(helperdir),' \
< $^ > $@
CLEANFILES = \
$(default_session_DATA)
EXTRA_DIST = \
README \
at-spi-registryd-wrapper.desktop.in \
gnome-keyring-daemon-wrapper.desktop.in \
gnome-settings-daemon-helper.desktop.in
These are wrappers and helpers to start things that are currently
(GNOME 2.18) started specially by gnome-session, which don't need
special hardcoding in the shiny new future, but where some additional
functionality needs to be added to the programs to take advantage of
the new gnome-session features and make everything work.
* at-spi-registryd-wrapper: This is needed because at-spi-registryd
does not use XSMP to signal to the session manager that it's
ready. (Instead it uses a custom protocol involving a root window
property.) The wrapper watches for the root window property and
then exits with status 0 to signal that it has run successfully.
In the future, at-spi-registryd should just use XSMP (via
EggSMClient or its replacement) to signal when it's ready. Also,
it should register for XSMP auto-restart, so that if it crashes,
gnome-session will restart it.
* gnome-keyring-daemon-wrapper: As with at-spi-registryd-wrapper,
this translates between XSMP and gnome-keyring's own custom
protocol. Unlike at-spi-registryd-wrapper, it actually hangs
around for the entire session, so that it can force
gnome-keyring-daemon to exit when the session ends.
It also uses gnome-session's new Setenv D-Bus interface to set the
GNOME_KEYRING_SOCKET environment variable in gnome-session's (and
its children's) environment.
In the future, gnome-keyring-daemon should just link to
EggSMClient (or its replacement) and use the Setenv D-Bus
interface itself. (Or perhaps GNOME_KEYRING_SOCKET is unnecessary
in the shiny new future since libgnomekeyring uses D-Bus to find
the daemon as well.)
* gnome-settings-daemon-helper: This does two things that have
traditionally been done by gnome-session, but which ought to be
done by gnome-settings-daemon: setting the screen resolution, and
setting the GTK_RC_FILES environment variable.
For setting the screen resolution, see
http://bugzilla.gnome.org/show_bug.cgi?id=434982
For GTK_RC_FILES, gnome-settings-daemon (specifically
gnome-settings-gtk1theme.c) should set this itself using the D-Bus
Setenv interface.
/*
* at-spi-registryd-wrapper: a wrapper to make at-spi-registryd
* conform to the startup item interfaces. (This should go away when
* at-spi-registryd supports session management directly.)
*
* Most of this code comes from the old gnome-session/gsm-at-startup.c.
*
* Copyright (C) 2003 Sun Microsystems, Inc.
* Copyright (C) 2007 Novell, Inc.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <dbus/dbus-glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
static Atom AT_SPI_IOR;
static GdkFilterReturn
registry_ior_watch (GdkXEvent *xevent, GdkEvent *event, gpointer data)
{
XEvent *xev = (XEvent *)xevent;
guint timeout = *(guint *)data;
if (xev->xany.type == PropertyNotify &&
xev->xproperty.atom == AT_SPI_IOR)
{
g_source_remove (timeout);
gtk_main_quit ();
return GDK_FILTER_REMOVE;
}
return GDK_FILTER_CONTINUE;
}
static gboolean
registry_ior_watch_timeout (gpointer data)
{
DBusGProxy *gsm = data;
const char *message;
message = _("Assistive technology support has been requested for this session, but the accessibility registry was not found. Please ensure that the AT-SPI package is installed. Your session has been started without assistive technology support.");
dbus_g_proxy_call (gsm, "InitializationError", NULL,
G_TYPE_STRING, message,
G_TYPE_BOOLEAN, FALSE,
G_TYPE_INVALID,
G_TYPE_INVALID);
exit (1);
/* not reached */
return FALSE;
}
static void
set_gtk_modules (DBusGProxy *gsm)
{
const char *old;
char *value;
gboolean found_gail;
gboolean found_atk_bridge;
GError *error = NULL;
int i;
found_gail = FALSE;
found_atk_bridge = FALSE;
old = g_getenv ("GTK_MODULES");
if (old != NULL)
{
char **old_modules, **modules;
old_modules = g_strsplit (old, ":", -1);
for (i = 0; old_modules[i]; i++)
{
if (!strcmp (old_modules[i], "gail"))
found_gail = TRUE;
else if (!strcmp (old_modules[i], "atk-bridge"))
found_atk_bridge = TRUE;
}
modules = g_new (char *, i + (found_gail ? 0 : 1) +
(found_atk_bridge ? 0 : 1) + 1);
for (i = 0; old_modules[i]; i++)
modules[i] = old_modules[i];
if (!found_gail)
modules[i++] = "gail";
if (!found_atk_bridge)
modules[i++] = "atk-bridge";
modules[i] = NULL;
value = g_strjoinv (":", modules);
g_strfreev (modules);
}
else
value = g_strdup ("gail:atk-bridge");
if (!dbus_g_proxy_call (gsm, "Setenv", &error,
G_TYPE_STRING, "GTK_MODULES",
G_TYPE_STRING, value,
G_TYPE_INVALID,
G_TYPE_INVALID))
{
g_warning ("Could not set GTK_MODULES: %s", error->message);
g_error_free (error);
}
g_free (value);
}
int
main (int argc, char **argv)
{
GdkDisplay *display;
GdkWindow *root;
guint timeout;
GError *error = NULL;
DBusGConnection *connection;
DBusGProxy *gsm;
gtk_init (&argc, &argv);
connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
if (!connection)
g_error ("couldn't get D-Bus connection: %s", error->message);
gsm = dbus_g_proxy_new_for_name (connection,
"org.gnome.SessionManager",
"/org/gnome/SessionManager",
"org.gnome.SessionManager");
display = gdk_display_get_default ();
root = gdk_screen_get_root_window (gdk_display_get_default_screen (display));
AT_SPI_IOR = XInternAtom (gdk_x11_display_get_xdisplay (display),
"AT_SPI_IOR", False);
gdk_window_set_events (root, GDK_PROPERTY_CHANGE_MASK);
gdk_window_add_filter (root, registry_ior_watch, &timeout);
timeout = g_timeout_add (5000, registry_ior_watch_timeout, gsm);
if (!g_spawn_command_line_async (AT_SPI_REGISTRYD_DIR "/at-spi-registryd", &error))
{
registry_ior_watch_timeout (gsm);
/* not reached */
}
gtk_main ();
gdk_window_remove_filter (root, registry_ior_watch, &timeout);
set_gtk_modules (gsm);
g_object_unref (gsm);
return 0;
}
[Desktop Entry]
Type=Application
Name=AT SPI Registry Wrapper
Exec=@helperdir@/at-spi-registryd-wrapper
OnlyShowIn=GNOME;
AutostartCondition=GNOME /desktop/gnome/interface/accessibility
X-GNOME-Autostart-Phase=Initialization
/*
* gnome-keyring-daemon-wrapper: a wrapper to make
* gnome-keyring-daemon conform to the startup item interfaces. (This
* should go away when gnome-keyring-daemon supports session
* management directly.)
*
* Most of this code comes from the old gnome-session/gsm-keyring.c.
*
* Copyright (C) 2003 Red Hat, Inc.
* Copyright (C) 2007 Novell, Inc.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <signal.h>
#include <stdlib.h>
......@@ -8,23 +22,25 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <dbus/dbus-glib.h>
#include <glib.h>
#include <gnome-keyring.h>
#include <gtk/gtkmain.h>
#include "gsm-keyring.h"
#include "eggdesktopfile.h"
#include "eggsmclient.h"
static pid_t gnome_keyring_daemon_pid = 0;
static int keyring_lifetime_pipe[2];
void
gsm_keyring_daemon_stop (void)
static void
keyring_daemon_stop (void)
{
if (gnome_keyring_daemon_pid != 0)
{
kill (gnome_keyring_daemon_pid, SIGTERM);
gnome_keyring_daemon_pid = 0;
}
}
static void
......@@ -47,16 +63,15 @@ child_setup (gpointer user_data)
TRUE);
}
void
gsm_keyring_daemon_start (void)
static void
keyring_daemon_start (DBusGProxy *gsm)
{
GError *err;
char *standard_out;
char **lines, **l;
char **lines, **env;
int status;
long pid;
char *t, *end;
char *pid_str, *end;
const char *old_keyring;
const char *display;
char *argv[2];
......@@ -66,30 +81,33 @@ gsm_keyring_daemon_start (void)
if (old_keyring != NULL &&
access (old_keyring, R_OK | W_OK) == 0)
{
gnome_keyring_daemon_prepare_environment_sync ();
display = g_getenv ("DISPLAY");
if (display != NULL)
gnome_keyring_daemon_set_display_sync (display);
return;
}
}
/* Pipe to slave keyring lifetime to */
pipe (keyring_lifetime_pipe);
err = NULL;
argv[0] = GNOME_KEYRING_DAEMON;
argv[1] = NULL;
g_spawn_sync (NULL, argv, NULL, G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
child_setup, NULL,
&standard_out, NULL, &status, &err);
close (keyring_lifetime_pipe[0]);
/* We leave keyring_lifetime_pipe[1] open for the lifetime of the session,
in order to slave the keyring daemon lifecycle to the session. */
if (err != NULL)
{
g_printerr ("Failed to run gnome-keyring-daemon: %s\n",
err->message);
g_error_free (err);
/* who knows what's wrong, just continue */
exit (1);
}
else
{
......@@ -97,41 +115,88 @@ gsm_keyring_daemon_start (void)
WEXITSTATUS (status) == 0 &&
standard_out != NULL)
{
lines = g_strsplit (standard_out, "\n", 0);
lines = g_strsplit (standard_out, "\n", 3);
for (l = lines; *l; ++l)
if (lines[0] != NULL &&
lines[1] != NULL &&
g_str_has_prefix (lines[1], "GNOME_KEYRING_PID="))
{
/* split the line into name=value */
t = strchr (*l, '=');
if (!t)
continue;
/* make *l be the name and t the value */
*t = 0;
t++;
/* everything that comes out should be an env var */
if (g_str_equal (*l, "GNOME_KEYRING_SOCKET"))
g_setenv (*l, t, TRUE);
/* track the daemon's PID */
if (g_str_equal (*l, "GNOME_KEYRING_PID"))
pid_str = lines[1] + strlen ("GNOME_KEYRING_PID=");
pid = strtol (pid_str, &end, 10);
if (end != pid_str)
{
pid = strtol (t, &end, 10);
if (end != t)
gnome_keyring_daemon_pid = pid;
gnome_keyring_daemon_pid = pid;
env = g_strsplit (lines[0], "=", 2);
if (!dbus_g_proxy_call (gsm, "Setenv", &err,
G_TYPE_STRING, env[0],
G_TYPE_STRING, env[1],
G_TYPE_INVALID,
G_TYPE_INVALID))
{
g_warning ("Could not set %s: %s", env[0], err->message);
g_error_free (err);
}
g_strfreev (env);
}
}
g_strfreev (lines);
gnome_keyring_daemon_prepare_environment_sync ();
}
else
{
/* daemon failed for some reason */
g_printerr ("gnome-keyring-daemon failed to start correctly, exit code: %d\n",
WEXITSTATUS (status));
exit (1);
}
g_free (standard_out);
}
}
static void
quit (EggSMClient *smclient, gpointer user_data)
{
gtk_main_quit ();
}
int
main (int argc, char **argv)
{
EggSMClient *client;
GOptionContext *goption_context;
GError *err = NULL;
DBusGConnection *connection;
DBusGProxy *gsm;
g_type_init ();
goption_context = g_option_context_new (NULL);
g_option_context_add_group (goption_context, gtk_get_option_group (FALSE));
g_option_context_add_group (goption_context, egg_sm_client_get_option_group ());
if (!g_option_context_parse (goption_context, &argc, &argv, &err))
{
g_printerr ("Could not parse arguments: %s\n", err->message);
g_error_free (err);
return 1;
}
connection = dbus_g_bus_get (DBUS_BUS_SESSION, &err);
if (!connection)
g_error ("couldn't get D-Bus connection: %s", err->message);
gsm = dbus_g_proxy_new_for_name (connection,
"org.gnome.SessionManager",
"/org/gnome/SessionManager",
"org.gnome.SessionManager");
egg_set_desktop_file (DEFAULT_SESSION_DIR "/gnome-keyring-daemon-wrapper.desktop");
client = egg_sm_client_get ();
g_signal_connect (client, "quit", G_CALLBACK (quit), NULL);
keyring_daemon_start (gsm);
gtk_main ();
keyring_daemon_stop ();
return 0;
}
[Desktop Entry]
Type=Application
Name=GNOME Keyring Daemon Wrapper
Exec=@helperdir@/gnome-keyring-daemon-wrapper
OnlyShowIn=GNOME;
X-GNOME-Autostart-Phase=Initialization
X-GNOME-AutoRestart=true
X-GNOME-Autostart-Notify=true
/*
* gnome-settings-daemon-helper: Does things g-s-d should do, but doesn't:
*
* 1) Sets screen resolution
* 2) Sets GTK_RC_FILES
*
* (This should go away when g-s-d does these itself.)
*
* Most of this code comes from the old gnome-session/gsm-xrandr.c.
*
* Copyright (C) 2003 Red Hat, Inc.
* Copyright (C) 2007 Novell, Inc.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <dbus/dbus-glib.h>
#include <gtk/gtk.h>
static void
set_gtk1_theme_rcfile (void)
{
DBusGConnection *connection;
DBusGProxy *gsm;
char *value;
GError *error = NULL;
connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
if (!connection)
g_error ("couldn't get D-Bus connection: %s", error->message);
gsm = dbus_g_proxy_new_for_name (connection,
"org.gnome.SessionManager",
"/org/gnome/SessionManager",
"org.gnome.SessionManager");
value = g_strdup_printf (SYSCONFDIR "/gtk/gtkrc:%s/.gtkrc-1.2-gnome2", g_get_home_dir ());
if (!dbus_g_proxy_call (gsm, "Setenv", &error,
G_TYPE_STRING, "GTK_RC_FILES",
G_TYPE_STRING, value,
G_TYPE_INVALID,
G_TYPE_INVALID))
{
g_warning ("Could not set GTK_RC_FILES: %s", error->message);
g_error_free (error);
}
g_free (value);
}
int
main (int argc, char **argv)
{
gtk_init (&argc, &argv);
/* Point GTK_RC_FILES (for gtk 1.2) at a file that we change in in
* gnome-settings-daemon.
*/
set_gtk1_theme_rcfile ();
return 0;
}
[Desktop Entry]
Type=Application
Name=GNOME Settings Daemon Helper
Exec=@helperdir@/gnome-settings-daemon-helper
OnlyShowIn=GNOME;
X-GNOME-Autostart-Phase=Initialization
AC_INIT([gnome-session], [2.22.1],
AC_INIT([gnome-session], [2.23.1],
[http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-session])
AC_CONFIG_SRCDIR([gnome-session])
AC_CONFIG_HEADERS([config.h])
......@@ -61,29 +61,19 @@ dnl pkg-config dependency checks
PKG_PROG_PKG_CONFIG()
PKG_CHECK_MODULES(GNOME_SESSION, glib-2.0 >= $GLIB_REQUIRED gtk+-2.0 >= $GTK_REQUIRED libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED dbus-glib-1 >= $DBUS_GLIB_REQUIRED gnome-settings-daemon gnome-keyring-1 >= $GNOME_KEYRING_REQUIRED)
PKG_CHECK_MODULES(GNOME_SESSION, glib-2.0 >= $GLIB_REQUIRED gtk+-2.0 >= $GTK_REQUIRED libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED dbus-glib-1 >= $DBUS_GLIB_REQUIRED gnome-keyring-1 >= $GNOME_KEYRING_REQUIRED)
dnl Check if libnotify is present
PKG_CHECK_MODULES(GTK, gtk+-2.0 >= $GTK_REQUIRED)
PKG_CHECK_MODULES(DBUS_GLIB, dbus-glib-1 >= $DBUS_GLIB_REQUIRED)
PKG_CHECK_MODULES(GCONF, gconf-2.0)
PKG_CHECK_MODULES(LIBGNOMEUI, libgnomeui-2.0)
PKG_CHECK_MODULES(STARTUP_NOTIFICATION, libstartup-notification-1.0)
LIBNOTIFY_REQUIRED=0.2.1
LIBNOTIFY_CFLAGS=
LIBNOTIFY_LIBS=
PKG_CHECK_MODULES(LIBNOTIFY, libnotify >= $LIBNOTIFY_REQUIRED,
HAVE_LIBNOTIFY="yes", HAVE_LIBNOTIFY="no")
if test "x$HAVE_LIBNOTIFY" = "xyes"; then
AC_DEFINE(HAVE_LIBNOTIFY, 1, [libnotify available])
AC_MSG_RESULT(available)
else
AC_MSG_RESULT(no)
fi
AC_SUBST(LIBNOTIFY_CFLAGS)
AC_SUBST(LIBNOTIFY_LIBS)
PKG_CHECK_MODULES(EGG_SMCLIENT, gtk+-2.0)
PKG_CHECK_MODULES(EGG_LIBGNOMEUI, libgnomeui-2.0)
dnl gconf checks
AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
if test x"$GCONFTOOL" = xno; then
AC_MSG_ERROR([gconftool-2 executable not found in your path - should be installed with GConf])
fi
......@@ -109,8 +99,8 @@ AC_PATH_PROG(GNOME_KEYRING_DAEMON, gnome-keyring-daemon, no)
if test x"$GNOME_KEYRING_DAEMON" = xno; then