diff options
author | Benedikt Meurer <benny@xfce.org> | 2006-05-15 21:16:40 +0000 |
---|---|---|
committer | Benedikt Meurer <benny@xfce.org> | 2006-05-15 21:16:40 +0000 |
commit | c90234920c9e254ec96c76ce2c0e1452c370698d (patch) | |
tree | eb7ce3c57d757b4812ad1939538fbe2b12f772bb | |
parent | b177765df5e07c13db7a96921f265042cdbf3887 (diff) | |
download | thunar-c90234920c9e254ec96c76ce2c0e1452c370698d.tar.gz |
2006-05-15 Benedikt Meurer <benny@xfce.org>
* thunar/thunar-file.h: Add convenience macro thunar_file_dup_uri().
* thunar/thunar-ice.{c,h}, thunar/thunar-session-client.{c,h},
thunar/main.c, thunar/Makefile.am, configure.in.in: Add session
management support, based on XSM. Bug #1415.
(Old svn revision: 21691)
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | configure.in.in | 5 | ||||
-rw-r--r-- | thunar/Makefile.am | 11 | ||||
-rw-r--r-- | thunar/main.c | 30 | ||||
-rw-r--r-- | thunar/thunar-file.h | 10 | ||||
-rw-r--r-- | thunar/thunar-ice.c | 141 | ||||
-rw-r--r-- | thunar/thunar-ice.h | 31 | ||||
-rw-r--r-- | thunar/thunar-session-client.c | 472 | ||||
-rw-r--r-- | thunar/thunar-session-client.h | 42 |
9 files changed, 735 insertions, 14 deletions
@@ -1,3 +1,10 @@ +2006-05-15 Benedikt Meurer <benny@xfce.org> + + * thunar/thunar-file.h: Add convenience macro thunar_file_dup_uri(). + * thunar/thunar-ice.{c,h}, thunar/thunar-session-client.{c,h}, + thunar/main.c, thunar/Makefile.am, configure.in.in: Add session + management support, based on XSM. Bug #1415. + 2006-05-14 Benedikt Meurer <benny@xfce.org> * thunar-vfs/thunar-vfs-job.c: Fix compile warning. Bug #1756. diff --git a/configure.in.in b/configure.in.in index f9d7bb10..3e814e82 100644 --- a/configure.in.in +++ b/configure.in.in @@ -173,6 +173,11 @@ XDT_CHECK_PACKAGE([LIBPNG], [libpng], [1.2.0], [], XDT_CHECK_PACKAGE([LIBPNG], [libpng12], [1.2.0]) ]) +dnl ******************************************** +dnl *** Check for session management support *** +dnl ******************************************** +XDT_CHECK_LIBSM() + dnl ********************************** dnl *** Optional support for D-BUS *** dnl ********************************** diff --git a/thunar/Makefile.am b/thunar/Makefile.am index 54642d8b..d2f99de9 100644 --- a/thunar/Makefile.am +++ b/thunar/Makefile.am @@ -80,6 +80,8 @@ Thunar_SOURCES = \ thunar-gtk-extensions.h \ thunar-history.c \ thunar-history.h \ + thunar-ice.c \ + thunar-ice.h \ thunar-icon-factory.c \ thunar-icon-factory.h \ thunar-icon-renderer.c \ @@ -129,6 +131,8 @@ Thunar_SOURCES = \ thunar-renamer-pair.h \ thunar-renamer-progress.c \ thunar-renamer-progress.h \ + thunar-session-client.c \ + thunar-session-client.h \ thunar-shortcuts-icon-renderer.c \ thunar-shortcuts-icon-renderer.h \ thunar-shortcuts-model.c \ @@ -174,22 +178,23 @@ Thunar_SOURCES = \ thunar-window-ui.h Thunar_CFLAGS = \ - $(CAIRO_CFLAGS) \ $(EXO_CFLAGS) \ $(GTHREAD_CFLAGS) \ + $(LIBSM_CFLAGS) \ $(PLATFORM_CFLAGS) Thunar_LDFLAGS = \ -no-undefined \ + $(LIBSM_LDFLAGS) \ $(PLATFORM_LDFLAGS) Thunar_LDADD = \ $(top_builddir)/tdb/libtdb.la \ $(top_builddir)/thunar-vfs/libthunar-vfs-$(THUNAR_VERSION_API).la \ $(top_builddir)/thunarx/libthunarx-$(THUNAR_VERSION_API).la \ - $(CAIRO_LIBS) \ $(EXO_LIBS) \ - $(GTHREAD_LIBS) + $(GTHREAD_LIBS) \ + $(LIBSM_LIBS) Thunar_DEPENDENCIES = \ $(top_builddir)/tdb/libtdb.la \ diff --git a/thunar/main.c b/thunar/main.c index cfd39425..3165fcbb 100644 --- a/thunar/main.c +++ b/thunar/main.c @@ -34,6 +34,7 @@ #include <thunar/thunar-dbus-client.h> #include <thunar/thunar-dbus-service.h> #include <thunar/thunar-gobject-extensions.h> +#include <thunar/thunar-session-client.h> #include <thunar/thunar-stock.h> @@ -41,10 +42,12 @@ /* --- globals --- */ static gboolean opt_bulk_rename = FALSE; static gboolean opt_daemon = FALSE; +static gchar *opt_sm_client_id = NULL; static gboolean opt_quit = FALSE; static gboolean opt_version = FALSE; + /* --- command line options --- */ static GOptionEntry option_entries[] = { @@ -54,6 +57,7 @@ static GOptionEntry option_entries[] = #else { "daemon", 0, 0, G_OPTION_ARG_NONE, &opt_daemon, N_ ("Run in daemon mode (not supported)"), NULL, }, #endif + { "sm-client-id", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &opt_sm_client_id, NULL, NULL, }, #ifdef HAVE_DBUS { "quit", 'q', 0, G_OPTION_ARG_NONE, &opt_quit, N_ ("Quit a running Thunar instance"), NULL, }, #else @@ -68,13 +72,14 @@ static GOptionEntry option_entries[] = int main (int argc, char **argv) { + ThunarSessionClient *session_client; #ifdef HAVE_DBUS - ThunarDBusService *dbus_service; + ThunarDBusService *dbus_service; #endif - ThunarApplication *application; - GError *error = NULL; - gchar *working_directory; - gchar **filenames = NULL; + ThunarApplication *application; + GError *error = NULL; + gchar *working_directory; + gchar **filenames = NULL; /* setup translation domain */ xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8"); @@ -111,13 +116,10 @@ main (int argc, char **argv) /* check if we should print version information */ if (G_UNLIKELY (opt_version)) { - g_print ("%s %s (Xfce %s)\n", PACKAGE_NAME, PACKAGE_VERSION, xfce_version_string ()); - g_print ("\n"); + g_print ("%s %s (Xfce %s)\n\n", PACKAGE_NAME, PACKAGE_VERSION, xfce_version_string ()); g_print ("%s\n", _("Copyright (c) 2004-2006")); - g_print ("\t%s\n", _("The Thunar development team. All rights reserved.")); - g_print ("\n"); - g_print ("%s\n", _("Written by Benedikt Meurer <benny@xfce.org>.")); - g_print ("\n"); + g_print ("\t%s\n\n", _("The Thunar development team. All rights reserved.")); + g_print ("%s\n\n", _("Written by Benedikt Meurer <benny@xfce.org>.")); g_print (_("Please report bugs to <%s>."), PACKAGE_BUGREPORT); g_print ("\n"); return EXIT_SUCCESS; @@ -222,6 +224,9 @@ error0: g_free (working_directory); g_strfreev (filenames); + /* connect to the session manager */ + session_client = thunar_session_client_new (opt_sm_client_id); + /* do not enter the main loop, unless we have atleast one window or we are in daemon mode */ if (thunar_application_has_windows (application) || thunar_application_get_daemon (application)) { @@ -239,6 +244,9 @@ error0: #endif } + /* disconnect from the session manager */ + g_object_unref (G_OBJECT (session_client)); + /* release the application reference */ g_object_unref (G_OBJECT (application)); diff --git a/thunar/thunar-file.h b/thunar/thunar-file.h index 11861b37..0fe7736a 100644 --- a/thunar/thunar-file.h +++ b/thunar/thunar-file.h @@ -299,6 +299,16 @@ GList *thunar_file_list_to_path_list (GList *file_list); **/ #define thunar_file_get_free_space(file, free_space_return) (thunar_vfs_info_get_free_space (THUNAR_FILE ((file))->info, (free_space_return))) +/** + * thunar_file_dup_uri: + * @file : a #ThunarFile instance. + * + * Returns the URI for the @file. The caller is responsible + * to free the returned string when no longer needed. + * + * Return value: the URI for @file. + **/ +#define thunar_file_dup_uri(file) (thunar_vfs_path_dup_uri (thunar_file_get_path ((file)))) /** diff --git a/thunar/thunar-ice.c b/thunar/thunar-ice.c new file mode 100644 index 00000000..13957ef9 --- /dev/null +++ b/thunar/thunar-ice.c @@ -0,0 +1,141 @@ +/* $Id$ */ +/*- + * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#ifdef HAVE_LIBSM +#include <X11/ICE/ICElib.h> +#endif + +#include <thunar/thunar-ice.h> + + + +#ifdef HAVE_LIBSM +static void +thunar_ice_error_handler (IceConn connection) +{ + /* + * The I/O error handler does whatever is necessary to respond + * to the I/O error and then returns, but it does not call + * IceCloseConnection. The ICE connection is given a "bad IO" + * status, and all future reads and writes to the connection + * are ignored. The next time IceProcessMessages is called it + * will return a status of IceProcessMessagesIOError. At that + * time, the application should call IceCloseConnection. + */ +} + + + +static gboolean +thunar_ice_process_messages (GIOChannel *channel, + GIOCondition condition, + gpointer client_data) +{ + IceProcessMessagesStatus status; + IceConn connection = client_data; + + /* try to process pending messages */ + status = IceProcessMessages (connection, NULL, NULL); + if (G_UNLIKELY (status == IceProcessMessagesIOError)) + { + /* we were disconnected from the session manager */ + IceSetShutdownNegotiation (connection, False); + IceCloseConnection (connection); + } + + return TRUE; +} + + + +static void +thunar_ice_connection_watch (IceConn connection, + IcePointer client_data, + Bool opening, + IcePointer *watch_data) +{ + GIOChannel *channel; + guint watch_id; + gint fd; + + if (G_LIKELY (opening)) + { + /* determine the file descriptor */ + fd = IceConnectionNumber (connection); + + /* Make sure we don't pass on these file descriptors to an exec'd child process */ + fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC); + + /* allocate an I/O channel to watch the connection */ + channel = g_io_channel_unix_new (fd); + watch_id = g_io_add_watch (channel, G_IO_ERR | G_IO_HUP | G_IO_IN, thunar_ice_process_messages, connection); + g_io_channel_unref (channel); + + /* remember the watch id */ + *watch_data = GUINT_TO_POINTER (watch_id); + } + else + { + /* remove the watch */ + watch_id = GPOINTER_TO_UINT (*watch_data); + g_source_remove (watch_id); + } +} +#endif /* !HAVE_LIBSM */ + + + +/** + * thunar_ice_init: + * + * This function should be called before you use any ICE functions. + * It will arrange for ICE connections to be read and dispatched via + * the Glib event loop mechanism. This function can be called any number + * of times without any harm. + **/ +void +thunar_ice_init (void) +{ +#ifdef HAVE_LIBSM + static gboolean initialized = FALSE; + + if (G_LIKELY (!initialized)) + { + /* setup our custom I/O error handler */ + IceSetIOErrorHandler (thunar_ice_error_handler); + + /* add the connection watch */ + IceAddConnectionWatch (thunar_ice_connection_watch, NULL); + + initialized = TRUE; + } +#endif /* !HAVE_LIBSM */ +} + diff --git a/thunar/thunar-ice.h b/thunar/thunar-ice.h new file mode 100644 index 00000000..c687aa71 --- /dev/null +++ b/thunar/thunar-ice.h @@ -0,0 +1,31 @@ +/* $Id$ */ +/*- + * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __THUNAR_ICE_H__ +#define __THUNAR_ICE_H__ + +#include <glib.h> + +G_BEGIN_DECLS; + +void thunar_ice_init (void); + +G_END_DECLS; + +#endif /* !__THUNAR_ICE_H__ */ diff --git a/thunar/thunar-session-client.c b/thunar/thunar-session-client.c new file mode 100644 index 00000000..1c57ad92 --- /dev/null +++ b/thunar/thunar-session-client.c @@ -0,0 +1,472 @@ +/* $Id$ */ +/*- + * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_MEMORY_H +#include <memory.h> +#endif +#include <stdio.h> +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#ifdef HAVE_STRING_H +#include <string.h> +#endif + +#ifdef HAVE_LIBSM +#include <X11/SM/SMlib.h> +#endif + +#include <thunar/thunar-application.h> +#include <thunar/thunar-ice.h> +#include <thunar/thunar-session-client.h> + + + +static void thunar_session_client_class_init (ThunarSessionClientClass *klass); +static void thunar_session_client_init (ThunarSessionClient *session_client); +static void thunar_session_client_finalize (GObject *object); +#ifdef HAVE_LIBSM +static gboolean thunar_session_client_connect (ThunarSessionClient *session_client, + const gchar *previous_id); +static void thunar_session_client_restore (ThunarSessionClient *session_client); +static void thunar_session_client_die (SmcConn connection, + ThunarSessionClient *session_client); +static void thunar_session_client_save_complete (SmcConn connection, + ThunarSessionClient *session_client); +static void thunar_session_client_save_yourself (SmcConn connection, + ThunarSessionClient *session_client, + gint save_type, + Bool shutdown, + gint interact_style, + Bool fast); +static void thunar_session_client_shutdown_cancelled (SmcConn connection, + ThunarSessionClient *session_client); +#endif /* !HAVE_LIBSM */ + + + +struct _ThunarSessionClientClass +{ + GObjectClass __parent__; +}; + +struct _ThunarSessionClient +{ + GObject __parent__; + gchar *path; + gchar *id; + +#ifdef HAVE_LIBSM + SmcConn connection; +#endif +}; + + + +static GObjectClass *thunar_session_client_parent_class; + + + +GType +thunar_session_client_get_type (void) +{ + static GType type = G_TYPE_INVALID; + + if (G_UNLIKELY (type == G_TYPE_INVALID)) + { + static const GTypeInfo info = + { + sizeof (ThunarSessionClientClass), + NULL, + NULL, + (GClassInitFunc) thunar_session_client_class_init, + NULL, + NULL, + sizeof (ThunarSessionClient), + 0, + (GInstanceInitFunc) thunar_session_client_init, + NULL, + }; + + type = g_type_register_static (G_TYPE_OBJECT, I_("ThunarSessionClient"), &info, 0); + } + + return type; +} + + + +static void +thunar_session_client_class_init (ThunarSessionClientClass *klass) +{ + GObjectClass *gobject_class; + + /* determine the parent type class */ + thunar_session_client_parent_class = g_type_class_peek_parent (klass); + + gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = thunar_session_client_finalize; +} + + + +static void +thunar_session_client_init (ThunarSessionClient *session_client) +{ + /* initialize the ICE layer */ + thunar_ice_init (); +} + + + +static void +thunar_session_client_finalize (GObject *object) +{ + ThunarSessionClient *session_client = THUNAR_SESSION_CLIENT (object); + +#ifdef HAVE_LIBSM + /* disconnect from the session manager */ + if (G_LIKELY (session_client->connection != NULL)) + SmcCloseConnection (session_client->connection, 0, NULL); +#endif /* !HAVE_LIBSM */ + + /* release internal state */ + g_free (session_client->path); + g_free (session_client->id); + + (*G_OBJECT_CLASS (thunar_session_client_parent_class)->finalize) (object); +} + + + +#ifdef HAVE_LIBSM +static gboolean +thunar_session_client_connect (ThunarSessionClient *session_client, + const gchar *previous_id) +{ + SmcCallbacks session_callbacks; + SmPropValue value_discard[3]; + SmPropValue value_restart[4]; + SmPropValue value_userid[1]; + SmProp *properties[5]; + SmProp prop_clone; + SmProp prop_discard; + SmProp prop_program; + SmProp prop_restart; + SmProp prop_userid; + gchar error_string[1]; + gchar *spec; + gchar *id = NULL; + + /* setup the session client callbacks */ + session_callbacks.die.callback = (SmcDieProc) thunar_session_client_die; + session_callbacks.die.client_data = session_client; + session_callbacks.save_complete.callback = (SmcSaveCompleteProc) thunar_session_client_save_complete; + session_callbacks.save_complete.client_data = session_client; + session_callbacks.save_yourself.callback = (SmcSaveYourselfProc) thunar_session_client_save_yourself; + session_callbacks.save_yourself.client_data = session_client; + session_callbacks.shutdown_cancelled.callback = (SmcShutdownCancelledProc) thunar_session_client_shutdown_cancelled; + session_callbacks.shutdown_cancelled.client_data = session_client; + + /* try to establish a connection to the session manager */ + session_client->connection = SmcOpenConnection (NULL, NULL, SmProtoMajor, SmProtoMinor, SmcDieProcMask + | SmcSaveCompleteProcMask | SmcSaveYourselfProcMask + | SmcShutdownCancelledProcMask, &session_callbacks, + (gchar *) previous_id, &id, sizeof (error_string), error_string); + if (G_UNLIKELY (session_client->connection == NULL)) + return FALSE; + + /* tell GDK about our new session id */ + gdk_set_sm_client_id (id); + + /* remember the returned client id */ + if (g_mem_is_system_malloc ()) + { + /* just use the memory */ + session_client->id = id; + } + else + { + /* use GLib memory management */ + session_client->id = g_strdup (id); + free (id); + } + + /* determine the session file path */ + spec = g_strconcat ("sessions/Thunar-", session_client->id, NULL); + session_client->path = xfce_resource_save_location (XFCE_RESOURCE_CACHE, spec, TRUE); + g_free (spec); + + /* verify that we were able to create the path to the file */ + if (G_UNLIKELY (session_client->path == NULL)) + { + /* disconnect from the session manager */ + SmcCloseConnection (session_client->connection, 0, NULL); + session_client->connection = NULL; + return FALSE; + } + + /* SmCloneCommand (see SmRestartCommand) */ + prop_clone.name = SmCloneCommand; + prop_clone.type = SmLISTofARRAY8; + prop_clone.num_vals = 1; + prop_clone.vals = &value_restart[0]; + + /* SmDiscardCommand */ + prop_discard.name = SmDiscardCommand; + prop_discard.type = SmLISTofARRAY8; + prop_discard.num_vals = G_N_ELEMENTS (value_discard); + prop_discard.vals = &value_discard[0]; + value_discard[0].value = "rm"; + value_discard[0].length = sizeof ("rm") - 1; + value_discard[1].value = "-f"; + value_discard[1].length = sizeof ("-f") - 1; + value_discard[2].value = session_client->path; + value_discard[2].length = strlen (session_client->path); + + /* SmProgram (see SmRestartCommand) */ + prop_program.name = SmProgram; + prop_program.type = SmARRAY8; + prop_program.num_vals = 1; + prop_program.vals = &value_restart[0]; + + /* SmRestartCommand */ + prop_restart.name = SmRestartCommand; + prop_restart.type = SmLISTofARRAY8; + prop_restart.num_vals = G_N_ELEMENTS (value_restart); + prop_restart.vals = &value_restart[0]; + value_restart[0].value = "Thunar"; + value_restart[0].length = sizeof ("Thunar") - 1; + value_restart[1].value = "--sm-client-id"; + value_restart[1].length = sizeof ("--sm-client-id") - 1; + value_restart[2].value = session_client->id; + value_restart[2].length = strlen (session_client->id); + value_restart[3].value = "--daemon"; + value_restart[3].length = sizeof ("--daemon") - 1; + + /* SmUserID */ + prop_userid.name = SmUserID; + prop_userid.type = SmARRAY8; + prop_userid.num_vals = G_N_ELEMENTS (value_userid); + prop_userid.vals = &value_userid[0]; + value_userid[0].value = (gchar *) g_get_user_name (); + value_userid[0].length = strlen (value_userid[0].value); + + /* setup the properties list */ + properties[0] = &prop_clone; + properties[1] = &prop_discard; + properties[2] = &prop_program; + properties[3] = &prop_restart; + properties[4] = &prop_userid; + + /* send the properties to the session manager */ + SmcSetProperties (session_client->connection, G_N_ELEMENTS (properties), properties); + + return TRUE; +} + + + +static void +thunar_session_client_restore (ThunarSessionClient *session_client) +{ + ThunarApplication *application; + const gchar *uri; + ThunarFile *directory; + GtkWidget *window; + XfceRc *rc; + gchar **roles; + guint n; + + /* try to open the session file */ + rc = xfce_rc_simple_open (session_client->path, TRUE); + if (G_UNLIKELY (rc == NULL)) + return; + + /* grab a reference on the application */ + application = thunar_application_get (); + + /* determine all window roles */ + roles = xfce_rc_get_groups (rc); + for (n = 0; roles[n] != NULL; ++n) + { + /* enter the group */ + xfce_rc_set_group (rc, roles[n]); + + /* determine the URI for the new window */ + uri = xfce_rc_read_entry (rc, "URI", NULL); + if (G_UNLIKELY (uri == NULL)) + continue; + + /* determine the directory for the new window */ + directory = thunar_file_get_for_uri (uri, NULL); + if (G_UNLIKELY (directory == NULL)) + continue; + + /* verify that we have a directory */ + if (thunar_file_is_directory (directory)) + { + /* open the new window */ + window = g_object_new (THUNAR_TYPE_WINDOW, + "current-directory", directory, + "role", roles[n], + NULL); + thunar_application_take_window (application, GTK_WINDOW (window)); + gtk_widget_show (window); + } + + /* cleanup */ + g_object_unref (G_OBJECT (directory)); + } + + /* cleanup */ + g_object_unref (G_OBJECT (application)); + xfce_rc_close (rc); + g_strfreev (roles); +} + + + +static void +thunar_session_client_die (SmcConn connection, + ThunarSessionClient *session_client) +{ + g_return_if_fail (THUNAR_IS_SESSION_CLIENT (session_client)); + g_return_if_fail (session_client->connection == connection); + + /* terminate the application */ + gtk_main_quit (); +} + + + +static void +thunar_session_client_save_complete (SmcConn connection, + ThunarSessionClient *session_client) +{ + g_return_if_fail (THUNAR_IS_SESSION_CLIENT (session_client)); + g_return_if_fail (session_client->connection == connection); +} + + + +static void +thunar_session_client_save_yourself (SmcConn connection, + ThunarSessionClient *session_client, + gint save_type, + Bool shutdown, + gint interact_style, + Bool fast) +{ + ThunarApplication *application; + const gchar *role; + ThunarFile *directory; + GList *windows; + GList *lp; + gchar *uri; + FILE *fp; + + g_return_if_fail (THUNAR_IS_SESSION_CLIENT (session_client)); + g_return_if_fail (session_client->connection == connection); + + /* check if we should save our current state */ + if (save_type == SmSaveLocal || save_type == SmSaveBoth) + { + /* try to open the session file for writing */ + fp = fopen (session_client->path, "w"); + if (G_LIKELY (fp != NULL)) + { + /* save the active windows */ + application = thunar_application_get (); + windows = thunar_application_get_windows (application); + for (lp = windows; lp != NULL; lp = lp->next) + { + /* determine the directory for the window */ + directory = thunar_window_get_current_directory (lp->data); + if (G_UNLIKELY (directory == NULL)) + continue; + + /* determine the role for the window */ + role = gtk_window_get_role (lp->data); + if (G_UNLIKELY (role == NULL)) + continue; + + /* save the window */ + uri = thunar_file_dup_uri (directory); + fprintf (fp, "[%s]\n", role); + fprintf (fp, "URI=%s\n\n", uri); + g_free (uri); + } + + /* cleanup */ + g_object_unref (G_OBJECT (application)); + g_list_free (windows); + fclose (fp); + } + } + + /* tell the session manager that we're done */ + SmcSaveYourselfDone (connection, True); +} + + + +static void +thunar_session_client_shutdown_cancelled (SmcConn connection, + ThunarSessionClient *session_client) +{ + g_return_if_fail (THUNAR_IS_SESSION_CLIENT (session_client)); + g_return_if_fail (session_client->connection == connection); +} +#endif /* !HAVE_LIBSM */ + + + +/** + * thunar_session_client_new: + * @session_id : the previous session id, or %NULL. + * + * Allocates a new #ThunarSessionClient with the specified + * @session_id. If @session_id is %NULL the session manager + * will assign a new session id, otherwise the session for + * the specified id will be restored. + * + * Return value: the newly allocated #ThunarSessionClient. + **/ +ThunarSessionClient* +thunar_session_client_new (const gchar *session_id) +{ + ThunarSessionClient *session_client; + + /* allocate a new session client */ + session_client = g_object_new (THUNAR_TYPE_SESSION_CLIENT, NULL); + +#ifdef HAVE_LIBSM + /* try to connect to the session manager and restore the previous session */ + if (thunar_session_client_connect (session_client, session_id) && session_id != NULL) + thunar_session_client_restore (session_client); +#endif /* !HAVE_LIBSM */ + + return session_client; +} + diff --git a/thunar/thunar-session-client.h b/thunar/thunar-session-client.h new file mode 100644 index 00000000..ed7a5605 --- /dev/null +++ b/thunar/thunar-session-client.h @@ -0,0 +1,42 @@ +/* $Id$ */ +/*- + * Copyright (c) 2006 Benedikt Meurer <benny@xfce.org> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __THUNAR_SESSION_CLIENT_H__ +#define __THUNAR_SESSION_CLIENT_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS; + +typedef struct _ThunarSessionClientClass ThunarSessionClientClass; +typedef struct _ThunarSessionClient ThunarSessionClient; + +#define THUNAR_TYPE_SESSION_CLIENT (thunar_session_client_get_type ()) +#define THUNAR_SESSION_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THUNAR_TYPE_SESSION_CLIENT, ThunarSessionClient)) +#define THUNAR_SESSION_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), THUNAR_TYPE_SESSION_CLIENT, ThunarSessionClientClass)) +#define THUNAR_IS_SESSION_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THUNAR_TYPE_SESSION_CLIENT)) +#define THUNAR_IS_SESSION_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), THUNAR_TYPE_SESSION_CLIENT)) +#define THUNAR_SESSION_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THUNAR_TYPE_SESSION_CLIENT, ThunarSessionClientClass)) + +GType thunar_session_client_get_type (void) G_GNUC_CONST; +ThunarSessionClient *thunar_session_client_new (const gchar *session_id) G_GNUC_MALLOC; + +G_END_DECLS; + +#endif /* !__THUNAR_SESSION_CLIENT_H__ */ |