mirror of
https://gitlab.gnome.org/GNOME/nautilus
synced 2024-08-25 02:36:07 +00:00
smclient: remove XSMP support
EggSmClient is not well-maintained, and it doesn't seem like it will ever hit GTK+, and the overall implementation seems to be poorly tested and buggy. Moreover, moving to 3.0 with nautilus being an application, it makes less sense to have it save opened windows state, as it might not be always running at all.
This commit is contained in:
parent
ee06a67a63
commit
f42d5aa97d
|
@ -9,38 +9,23 @@ EGG_TREE_DND_FILES = \
|
|||
eggtreemultidnd.h \
|
||||
$(NULL)
|
||||
|
||||
EGG_SMCLIENT_FILES = \
|
||||
eggdesktopfile.c \
|
||||
eggdesktopfile.h \
|
||||
eggsmclient.c \
|
||||
eggsmclient.h \
|
||||
eggsmclient-private.h \
|
||||
eggsmclient-xsmp.c \
|
||||
$(NULL)
|
||||
|
||||
libegg_la_SOURCES = \
|
||||
$(EGG_TREE_DND_FILES) \
|
||||
$(EGG_SMCLIENT_FILES) \
|
||||
$(NULL)
|
||||
|
||||
libegg_la_CFLAGS = \
|
||||
-DEGG_SM_CLIENT_BACKEND_XSMP \
|
||||
-DG_LOG_DOMAIN=\""EggSMClient"\" \
|
||||
$(BASE_CFLAGS) \
|
||||
$(WARNING_CFLAGS) \
|
||||
$(DISABLE_DEPRECATED)
|
||||
|
||||
libegg_la_LIBADD = \
|
||||
$(LIBEGG_LIBS) \
|
||||
-lSM -lICE
|
||||
$(BASE_LIBS)
|
||||
|
||||
EXTRA_DIST = \
|
||||
update-from-egg.sh \
|
||||
$(NULL)
|
||||
|
||||
EGG_TREE_DND_DIR = $(srcdir)/../../../libegg/libegg/treeviewutils
|
||||
EGG_SMCLIENT_DIR = $(srcdir)/../../../libegg/libegg/smclient
|
||||
|
||||
regenerate-built-sources:
|
||||
EGGFILES="$(EGG_TREE_DND_FILES)" EGGDIR="$(EGG_TREE_DND_DIR)" $(srcdir)/update-from-egg.sh
|
||||
EGGFILES="$(EGG_SMCLIENT_FILES)" EGGDIR="$(EGG_SMCLIENT_DIR)" $(srcdir)/update-from-egg.sh
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,159 +0,0 @@
|
|||
/* eggdesktopfile.h - Freedesktop.Org Desktop Files
|
||||
* Copyright (C) 2007 Novell, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; see the file COPYING.LIB. If not,
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place -
|
||||
* Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __EGG_DESKTOP_FILE_H__
|
||||
#define __EGG_DESKTOP_FILE_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct EggDesktopFile EggDesktopFile;
|
||||
|
||||
typedef enum {
|
||||
EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED,
|
||||
|
||||
EGG_DESKTOP_FILE_TYPE_APPLICATION,
|
||||
EGG_DESKTOP_FILE_TYPE_LINK,
|
||||
EGG_DESKTOP_FILE_TYPE_DIRECTORY
|
||||
} EggDesktopFileType;
|
||||
|
||||
EggDesktopFile *egg_desktop_file_new (const char *desktop_file_path,
|
||||
GError **error);
|
||||
|
||||
EggDesktopFile *egg_desktop_file_new_from_data_dirs (const char *desktop_file_path,
|
||||
GError **error);
|
||||
EggDesktopFile *egg_desktop_file_new_from_dirs (const char *desktop_file_path,
|
||||
const char **search_dirs,
|
||||
GError **error);
|
||||
EggDesktopFile *egg_desktop_file_new_from_key_file (GKeyFile *key_file,
|
||||
const char *source,
|
||||
GError **error);
|
||||
|
||||
void egg_desktop_file_free (EggDesktopFile *desktop_file);
|
||||
|
||||
const char *egg_desktop_file_get_source (EggDesktopFile *desktop_file);
|
||||
|
||||
EggDesktopFileType egg_desktop_file_get_desktop_file_type (EggDesktopFile *desktop_file);
|
||||
|
||||
const char *egg_desktop_file_get_name (EggDesktopFile *desktop_file);
|
||||
const char *egg_desktop_file_get_icon (EggDesktopFile *desktop_file);
|
||||
|
||||
gboolean egg_desktop_file_can_launch (EggDesktopFile *desktop_file,
|
||||
const char *desktop_environment);
|
||||
|
||||
gboolean egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file);
|
||||
gboolean egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file);
|
||||
gboolean egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file);
|
||||
|
||||
char *egg_desktop_file_parse_exec (EggDesktopFile *desktop_file,
|
||||
GSList *documents,
|
||||
GError **error);
|
||||
|
||||
gboolean egg_desktop_file_launch (EggDesktopFile *desktop_file,
|
||||
GSList *documents,
|
||||
GError **error,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
typedef enum {
|
||||
EGG_DESKTOP_FILE_LAUNCH_CLEARENV = 1,
|
||||
EGG_DESKTOP_FILE_LAUNCH_PUTENV,
|
||||
EGG_DESKTOP_FILE_LAUNCH_SCREEN,
|
||||
EGG_DESKTOP_FILE_LAUNCH_WORKSPACE,
|
||||
EGG_DESKTOP_FILE_LAUNCH_DIRECTORY,
|
||||
EGG_DESKTOP_FILE_LAUNCH_TIME,
|
||||
EGG_DESKTOP_FILE_LAUNCH_FLAGS,
|
||||
EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC,
|
||||
EGG_DESKTOP_FILE_LAUNCH_RETURN_PID,
|
||||
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE,
|
||||
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE,
|
||||
EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE,
|
||||
EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID
|
||||
} EggDesktopFileLaunchOption;
|
||||
|
||||
/* Standard Keys */
|
||||
#define EGG_DESKTOP_FILE_GROUP "Desktop Entry"
|
||||
|
||||
#define EGG_DESKTOP_FILE_KEY_TYPE "Type"
|
||||
#define EGG_DESKTOP_FILE_KEY_VERSION "Version"
|
||||
#define EGG_DESKTOP_FILE_KEY_NAME "Name"
|
||||
#define EGG_DESKTOP_FILE_KEY_GENERIC_NAME "GenericName"
|
||||
#define EGG_DESKTOP_FILE_KEY_NO_DISPLAY "NoDisplay"
|
||||
#define EGG_DESKTOP_FILE_KEY_COMMENT "Comment"
|
||||
#define EGG_DESKTOP_FILE_KEY_ICON "Icon"
|
||||
#define EGG_DESKTOP_FILE_KEY_HIDDEN "Hidden"
|
||||
#define EGG_DESKTOP_FILE_KEY_ONLY_SHOW_IN "OnlyShowIn"
|
||||
#define EGG_DESKTOP_FILE_KEY_NOT_SHOW_IN "NotShowIn"
|
||||
#define EGG_DESKTOP_FILE_KEY_TRY_EXEC "TryExec"
|
||||
#define EGG_DESKTOP_FILE_KEY_EXEC "Exec"
|
||||
#define EGG_DESKTOP_FILE_KEY_PATH "Path"
|
||||
#define EGG_DESKTOP_FILE_KEY_TERMINAL "Terminal"
|
||||
#define EGG_DESKTOP_FILE_KEY_MIME_TYPE "MimeType"
|
||||
#define EGG_DESKTOP_FILE_KEY_CATEGORIES "Categories"
|
||||
#define EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY "StartupNotify"
|
||||
#define EGG_DESKTOP_FILE_KEY_STARTUP_WM_CLASS "StartupWMClass"
|
||||
#define EGG_DESKTOP_FILE_KEY_URL "URL"
|
||||
|
||||
/* Accessors */
|
||||
gboolean egg_desktop_file_has_key (EggDesktopFile *desktop_file,
|
||||
const char *key,
|
||||
GError **error);
|
||||
char *egg_desktop_file_get_string (EggDesktopFile *desktop_file,
|
||||
const char *key,
|
||||
GError **error) G_GNUC_MALLOC;
|
||||
char *egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file,
|
||||
const char *key,
|
||||
const char *locale,
|
||||
GError **error) G_GNUC_MALLOC;
|
||||
gboolean egg_desktop_file_get_boolean (EggDesktopFile *desktop_file,
|
||||
const char *key,
|
||||
GError **error);
|
||||
double egg_desktop_file_get_numeric (EggDesktopFile *desktop_file,
|
||||
const char *key,
|
||||
GError **error);
|
||||
char **egg_desktop_file_get_string_list (EggDesktopFile *desktop_file,
|
||||
const char *key,
|
||||
gsize *length,
|
||||
GError **error) G_GNUC_MALLOC;
|
||||
char **egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file,
|
||||
const char *key,
|
||||
const char *locale,
|
||||
gsize *length,
|
||||
GError **error) G_GNUC_MALLOC;
|
||||
|
||||
|
||||
/* Errors */
|
||||
#define EGG_DESKTOP_FILE_ERROR egg_desktop_file_error_quark()
|
||||
|
||||
GQuark egg_desktop_file_error_quark (void);
|
||||
|
||||
typedef enum {
|
||||
EGG_DESKTOP_FILE_ERROR_INVALID,
|
||||
EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE,
|
||||
EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION
|
||||
} EggDesktopFileError;
|
||||
|
||||
/* Global application desktop file */
|
||||
void egg_set_desktop_file (const char *desktop_file_path);
|
||||
EggDesktopFile *egg_get_desktop_file (void);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __EGG_DESKTOP_FILE_H__ */
|
|
@ -1,53 +0,0 @@
|
|||
/* eggsmclient-private.h
|
||||
* Copyright (C) 2007 Novell, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __EGG_SM_CLIENT_PRIVATE_H__
|
||||
#define __EGG_SM_CLIENT_PRIVATE_H__
|
||||
|
||||
#include <gdkconfig.h>
|
||||
#include "eggsmclient.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GKeyFile *egg_sm_client_save_state (EggSMClient *client);
|
||||
void egg_sm_client_quit_requested (EggSMClient *client);
|
||||
void egg_sm_client_quit_cancelled (EggSMClient *client);
|
||||
void egg_sm_client_quit (EggSMClient *client);
|
||||
|
||||
#if defined (GDK_WINDOWING_X11)
|
||||
# ifdef EGG_SM_CLIENT_BACKEND_XSMP
|
||||
GType egg_sm_client_xsmp_get_type (void);
|
||||
EggSMClient *egg_sm_client_xsmp_new (void);
|
||||
# endif
|
||||
# ifdef EGG_SM_CLIENT_BACKEND_DBUS
|
||||
GType egg_sm_client_dbus_get_type (void);
|
||||
EggSMClient *egg_sm_client_dbus_new (void);
|
||||
# endif
|
||||
#elif defined (GDK_WINDOWING_WIN32)
|
||||
GType egg_sm_client_win32_get_type (void);
|
||||
EggSMClient *egg_sm_client_win32_new (void);
|
||||
#elif defined (GDK_WINDOWING_QUARTZ)
|
||||
GType egg_sm_client_osx_get_type (void);
|
||||
EggSMClient *egg_sm_client_osx_new (void);
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
#endif /* __EGG_SM_CLIENT_PRIVATE_H__ */
|
File diff suppressed because it is too large
Load diff
|
@ -1,609 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Novell, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "eggsmclient.h"
|
||||
#include "eggsmclient-private.h"
|
||||
|
||||
static void egg_sm_client_debug_handler (const char *log_domain,
|
||||
GLogLevelFlags log_level,
|
||||
const char *message,
|
||||
gpointer user_data);
|
||||
|
||||
enum {
|
||||
SAVE_STATE,
|
||||
QUIT_REQUESTED,
|
||||
QUIT_CANCELLED,
|
||||
QUIT,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
struct _EggSMClientPrivate {
|
||||
GKeyFile *state_file;
|
||||
};
|
||||
|
||||
#define EGG_SM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_SM_CLIENT, EggSMClientPrivate))
|
||||
|
||||
G_DEFINE_TYPE (EggSMClient, egg_sm_client, G_TYPE_OBJECT)
|
||||
|
||||
static EggSMClient *global_client;
|
||||
static EggSMClientMode global_client_mode = EGG_SM_CLIENT_MODE_NORMAL;
|
||||
|
||||
static void
|
||||
egg_sm_client_init (EggSMClient *client)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
static void
|
||||
egg_sm_client_class_init (EggSMClientClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (EggSMClientPrivate));
|
||||
|
||||
/**
|
||||
* EggSMClient::save_state:
|
||||
* @client: the client
|
||||
* @state_file: a #GKeyFile to save state information into
|
||||
*
|
||||
* Emitted when the session manager has requested that the
|
||||
* application save information about its current state. The
|
||||
* application should save its state into @state_file, and then the
|
||||
* session manager may then restart the application in a future
|
||||
* session and tell it to initialize itself from that state.
|
||||
*
|
||||
* You should not save any data into @state_file's "start group"
|
||||
* (ie, the %NULL group). Instead, applications should save their
|
||||
* data into groups with names that start with the application name,
|
||||
* and libraries that connect to this signal should save their data
|
||||
* into groups with names that start with the library name.
|
||||
*
|
||||
* Alternatively, rather than (or in addition to) using @state_file,
|
||||
* the application can save its state by calling
|
||||
* egg_sm_client_set_restart_command() during the processing of this
|
||||
* signal (eg, to include a list of files to open).
|
||||
**/
|
||||
signals[SAVE_STATE] =
|
||||
g_signal_new ("save_state",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (EggSMClientClass, save_state),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE,
|
||||
1, G_TYPE_POINTER);
|
||||
|
||||
/**
|
||||
* EggSMClient::quit_requested:
|
||||
* @client: the client
|
||||
*
|
||||
* Emitted when the session manager requests that the application
|
||||
* exit (generally because the user is logging out). The application
|
||||
* should decide whether or not it is willing to quit (perhaps after
|
||||
* asking the user what to do with documents that have unsaved
|
||||
* changes) and then call egg_sm_client_will_quit(), passing %TRUE
|
||||
* or %FALSE to give its answer to the session manager. (It does not
|
||||
* need to give an answer before returning from the signal handler;
|
||||
* it can interact with the user asynchronously and then give its
|
||||
* answer later on.) If the application does not connect to this
|
||||
* signal, then #EggSMClient will automatically return %TRUE on its
|
||||
* behalf.
|
||||
*
|
||||
* The application should not save its session state as part of
|
||||
* handling this signal; if the user has requested that the session
|
||||
* be saved when logging out, then ::save_state will be emitted
|
||||
* separately.
|
||||
*
|
||||
* If the application agrees to quit, it should then wait for either
|
||||
* the ::quit_cancelled or ::quit signals to be emitted.
|
||||
**/
|
||||
signals[QUIT_REQUESTED] =
|
||||
g_signal_new ("quit_requested",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (EggSMClientClass, quit_requested),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
|
||||
/**
|
||||
* EggSMClient::quit_cancelled:
|
||||
* @client: the client
|
||||
*
|
||||
* Emitted when the session manager decides to cancel a logout after
|
||||
* the application has already agreed to quit. After receiving this
|
||||
* signal, the application can go back to what it was doing before
|
||||
* receiving the ::quit_requested signal.
|
||||
**/
|
||||
signals[QUIT_CANCELLED] =
|
||||
g_signal_new ("quit_cancelled",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (EggSMClientClass, quit_cancelled),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
|
||||
/**
|
||||
* EggSMClient::quit:
|
||||
* @client: the client
|
||||
*
|
||||
* Emitted when the session manager wants the application to quit
|
||||
* (generally because the user is logging out). The application
|
||||
* should exit as soon as possible after receiving this signal; if
|
||||
* it does not, the session manager may choose to forcibly kill it.
|
||||
*
|
||||
* Normally a GUI application would only be sent a ::quit if it
|
||||
* agreed to quit in response to a ::quit_requested signal. However,
|
||||
* this is not guaranteed; in some situations the session manager
|
||||
* may decide to end the session without giving applications a
|
||||
* chance to object.
|
||||
**/
|
||||
signals[QUIT] =
|
||||
g_signal_new ("quit",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (EggSMClientClass, quit),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
}
|
||||
|
||||
static gboolean sm_client_disable = FALSE;
|
||||
static char *sm_client_state_file = NULL;
|
||||
static char *sm_client_id = NULL;
|
||||
static char *sm_config_prefix = NULL;
|
||||
|
||||
static gboolean
|
||||
sm_client_post_parse_func (GOptionContext *context,
|
||||
GOptionGroup *group,
|
||||
gpointer data,
|
||||
GError **error)
|
||||
{
|
||||
EggSMClient *client;
|
||||
|
||||
if (sm_client_id == NULL)
|
||||
{
|
||||
const gchar *desktop_autostart_id;
|
||||
|
||||
desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
|
||||
|
||||
if (desktop_autostart_id != NULL)
|
||||
sm_client_id = g_strdup (desktop_autostart_id);
|
||||
}
|
||||
|
||||
/* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
|
||||
* use the same client id. */
|
||||
g_unsetenv ("DESKTOP_AUTOSTART_ID");
|
||||
|
||||
if (global_client_mode != EGG_SM_CLIENT_MODE_DISABLED)
|
||||
{
|
||||
client = egg_sm_client_get ();
|
||||
|
||||
if (EGG_SM_CLIENT_GET_CLASS (client)->startup)
|
||||
EGG_SM_CLIENT_GET_CLASS (client)->startup (client, sm_client_id);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_sm_client_get_option_group:
|
||||
*
|
||||
* Creates a %GOptionGroup containing the session-management-related
|
||||
* options. You should add this group to the application's
|
||||
* %GOptionContext if you want to use #EggSMClient.
|
||||
*
|
||||
* Return value: the %GOptionGroup
|
||||
**/
|
||||
GOptionGroup *
|
||||
egg_sm_client_get_option_group (void)
|
||||
{
|
||||
const GOptionEntry entries[] = {
|
||||
{ "sm-client-disable", 0, 0,
|
||||
G_OPTION_ARG_NONE, &sm_client_disable,
|
||||
N_("Disable connection to session manager"), NULL },
|
||||
{ "sm-client-state-file", 0, 0,
|
||||
G_OPTION_ARG_FILENAME, &sm_client_state_file,
|
||||
N_("Specify file containing saved configuration"), N_("FILE") },
|
||||
{ "sm-client-id", 0, 0,
|
||||
G_OPTION_ARG_STRING, &sm_client_id,
|
||||
N_("Specify session management ID"), N_("ID") },
|
||||
/* GnomeClient compatibility option */
|
||||
{ "sm-disable", 0, G_OPTION_FLAG_HIDDEN,
|
||||
G_OPTION_ARG_NONE, &sm_client_disable,
|
||||
NULL, NULL },
|
||||
/* GnomeClient compatibility option. This is a dummy option that only
|
||||
* exists so that sessions saved by apps with GnomeClient can be restored
|
||||
* later when they've switched to EggSMClient. See bug #575308.
|
||||
*/
|
||||
{ "sm-config-prefix", 0, G_OPTION_FLAG_HIDDEN,
|
||||
G_OPTION_ARG_STRING, &sm_config_prefix,
|
||||
NULL, NULL },
|
||||
{ NULL }
|
||||
};
|
||||
GOptionGroup *group;
|
||||
|
||||
/* Use our own debug handler for the "EggSMClient" domain. */
|
||||
g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,
|
||||
egg_sm_client_debug_handler, NULL);
|
||||
|
||||
group = g_option_group_new ("sm-client",
|
||||
_("Session management options:"),
|
||||
_("Show session management options"),
|
||||
NULL, NULL);
|
||||
g_option_group_add_entries (group, entries);
|
||||
g_option_group_set_parse_hooks (group, NULL, sm_client_post_parse_func);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_sm_client_set_mode:
|
||||
* @mode: an #EggSMClient mode
|
||||
*
|
||||
* Sets the "mode" of #EggSMClient as follows:
|
||||
*
|
||||
* %EGG_SM_CLIENT_MODE_DISABLED: Session management is completely
|
||||
* disabled, until the mode is changed again. The application will
|
||||
* not even connect to the session manager. (egg_sm_client_get()
|
||||
* will still return an #EggSMClient object.)
|
||||
*
|
||||
* %EGG_SM_CLIENT_MODE_NO_RESTART: The application will connect to
|
||||
* the session manager (and thus will receive notification when the
|
||||
* user is logging out, etc), but will request to not be
|
||||
* automatically restarted with saved state in future sessions.
|
||||
*
|
||||
* %EGG_SM_CLIENT_MODE_NORMAL: The default. #EggSMCLient will
|
||||
* function normally.
|
||||
*
|
||||
* This must be called before the application's main loop begins and
|
||||
* before any call to egg_sm_client_get(), unless the mode was set
|
||||
* earlier to %EGG_SM_CLIENT_MODE_DISABLED and this call enables
|
||||
* session management. Note that option parsing will call
|
||||
* egg_sm_client_get().
|
||||
**/
|
||||
void
|
||||
egg_sm_client_set_mode (EggSMClientMode mode)
|
||||
{
|
||||
EggSMClientMode old_mode = global_client_mode;
|
||||
|
||||
g_return_if_fail (global_client == NULL || global_client_mode == EGG_SM_CLIENT_MODE_DISABLED);
|
||||
g_return_if_fail (!(global_client != NULL && mode == EGG_SM_CLIENT_MODE_DISABLED));
|
||||
|
||||
global_client_mode = mode;
|
||||
|
||||
if (global_client != NULL && old_mode == EGG_SM_CLIENT_MODE_DISABLED)
|
||||
{
|
||||
if (EGG_SM_CLIENT_GET_CLASS (global_client)->startup)
|
||||
EGG_SM_CLIENT_GET_CLASS (global_client)->startup (global_client, sm_client_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_sm_client_get_mode:
|
||||
*
|
||||
* Gets the global #EggSMClientMode. See egg_sm_client_set_mode()
|
||||
* for details.
|
||||
*
|
||||
* Return value: the global #EggSMClientMode
|
||||
**/
|
||||
EggSMClientMode
|
||||
egg_sm_client_get_mode (void)
|
||||
{
|
||||
return global_client_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_sm_client_get:
|
||||
*
|
||||
* Returns the master #EggSMClient for the application.
|
||||
*
|
||||
* On platforms that support saved sessions (ie, POSIX/X11), the
|
||||
* application will only request to be restarted by the session
|
||||
* manager if you call egg_set_desktop_file() to set an application
|
||||
* desktop file. In particular, if the desktop file contains the key
|
||||
* "X
|
||||
*
|
||||
* Return value: the master #EggSMClient.
|
||||
**/
|
||||
EggSMClient *
|
||||
egg_sm_client_get (void)
|
||||
{
|
||||
if (!global_client)
|
||||
{
|
||||
if (!sm_client_disable)
|
||||
{
|
||||
#if defined (GDK_WINDOWING_WIN32)
|
||||
global_client = egg_sm_client_win32_new ();
|
||||
#elif defined (GDK_WINDOWING_QUARTZ)
|
||||
global_client = egg_sm_client_osx_new ();
|
||||
#else
|
||||
/* If both D-Bus and XSMP are compiled in, try XSMP first
|
||||
* (since it supports state saving) and fall back to D-Bus
|
||||
* if XSMP isn't available.
|
||||
*/
|
||||
# ifdef EGG_SM_CLIENT_BACKEND_XSMP
|
||||
global_client = egg_sm_client_xsmp_new ();
|
||||
# endif
|
||||
# ifdef EGG_SM_CLIENT_BACKEND_DBUS
|
||||
if (!global_client)
|
||||
global_client = egg_sm_client_dbus_new ();
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Fallback: create a dummy client, so that callers don't have
|
||||
* to worry about a %NULL return value.
|
||||
*/
|
||||
if (!global_client)
|
||||
global_client = g_object_new (EGG_TYPE_SM_CLIENT, NULL);
|
||||
}
|
||||
|
||||
return global_client;
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_sm_client_is_resumed:
|
||||
* @client: the client
|
||||
*
|
||||
* Checks whether or not the current session has been resumed from
|
||||
* a previous saved session. If so, the application should call
|
||||
* egg_sm_client_get_state_file() and restore its state from the
|
||||
* returned #GKeyFile.
|
||||
*
|
||||
* Return value: %TRUE if the session has been resumed
|
||||
**/
|
||||
gboolean
|
||||
egg_sm_client_is_resumed (EggSMClient *client)
|
||||
{
|
||||
g_return_val_if_fail (client == global_client, FALSE);
|
||||
|
||||
return sm_client_state_file != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_sm_client_get_state_file:
|
||||
* @client: the client
|
||||
*
|
||||
* If the application was resumed by the session manager, this will
|
||||
* return the #GKeyFile containing its state from the previous
|
||||
* session.
|
||||
*
|
||||
* Note that other libraries and #EggSMClient itself may also store
|
||||
* state in the key file, so if you call egg_sm_client_get_groups(),
|
||||
* on it, the return value will likely include groups that you did not
|
||||
* put there yourself. (It is also not guaranteed that the first
|
||||
* group created by the application will still be the "start group"
|
||||
* when it is resumed.)
|
||||
*
|
||||
* Return value: the #GKeyFile containing the application's earlier
|
||||
* state, or %NULL on error. You should not free this key file; it
|
||||
* is owned by @client.
|
||||
**/
|
||||
GKeyFile *
|
||||
egg_sm_client_get_state_file (EggSMClient *client)
|
||||
{
|
||||
EggSMClientPrivate *priv = EGG_SM_CLIENT_GET_PRIVATE (client);
|
||||
char *state_file_path;
|
||||
GError *err = NULL;
|
||||
|
||||
g_return_val_if_fail (client == global_client, NULL);
|
||||
|
||||
if (!sm_client_state_file)
|
||||
return NULL;
|
||||
if (priv->state_file)
|
||||
return priv->state_file;
|
||||
|
||||
if (!strncmp (sm_client_state_file, "file://", 7))
|
||||
state_file_path = g_filename_from_uri (sm_client_state_file, NULL, NULL);
|
||||
else
|
||||
state_file_path = g_strdup (sm_client_state_file);
|
||||
|
||||
priv->state_file = g_key_file_new ();
|
||||
if (!g_key_file_load_from_file (priv->state_file, state_file_path, 0, &err))
|
||||
{
|
||||
g_warning ("Could not load SM state file '%s': %s",
|
||||
sm_client_state_file, err->message);
|
||||
g_clear_error (&err);
|
||||
g_key_file_free (priv->state_file);
|
||||
priv->state_file = NULL;
|
||||
}
|
||||
|
||||
g_free (state_file_path);
|
||||
return priv->state_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_sm_client_set_restart_command:
|
||||
* @client: the client
|
||||
* @argc: the length of @argv
|
||||
* @argv: argument vector
|
||||
*
|
||||
* Sets the command used to restart @client if it does not have a
|
||||
* .desktop file that can be used to find its restart command.
|
||||
*
|
||||
* This can also be used when handling the ::save_state signal, to
|
||||
* save the current state via an updated command line. (Eg, providing
|
||||
* a list of filenames to open when the application is resumed.)
|
||||
**/
|
||||
void
|
||||
egg_sm_client_set_restart_command (EggSMClient *client,
|
||||
int argc,
|
||||
const char **argv)
|
||||
{
|
||||
g_return_if_fail (EGG_IS_SM_CLIENT (client));
|
||||
|
||||
if (EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command)
|
||||
EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command (client, argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_sm_client_will_quit:
|
||||
* @client: the client
|
||||
* @will_quit: whether or not the application is willing to quit
|
||||
*
|
||||
* This MUST be called in response to the ::quit_requested signal, to
|
||||
* indicate whether or not the application is willing to quit. The
|
||||
* application may call it either directly from the signal handler, or
|
||||
* at some later point (eg, after asynchronously interacting with the
|
||||
* user).
|
||||
*
|
||||
* If the application does not connect to ::quit_requested,
|
||||
* #EggSMClient will call this method on its behalf (passing %TRUE
|
||||
* for @will_quit).
|
||||
*
|
||||
* After calling this method, the application should wait to receive
|
||||
* either ::quit_cancelled or ::quit.
|
||||
**/
|
||||
void
|
||||
egg_sm_client_will_quit (EggSMClient *client,
|
||||
gboolean will_quit)
|
||||
{
|
||||
g_return_if_fail (EGG_IS_SM_CLIENT (client));
|
||||
|
||||
if (EGG_SM_CLIENT_GET_CLASS (client)->will_quit)
|
||||
EGG_SM_CLIENT_GET_CLASS (client)->will_quit (client, will_quit);
|
||||
}
|
||||
|
||||
/**
|
||||
* egg_sm_client_end_session:
|
||||
* @style: a hint at how to end the session
|
||||
* @request_confirmation: whether or not the user should get a chance
|
||||
* to confirm the action
|
||||
*
|
||||
* Requests that the session manager end the current session. @style
|
||||
* indicates how the session should be ended, and
|
||||
* @request_confirmation indicates whether or not the user should be
|
||||
* given a chance to confirm the logout/reboot/shutdown. Both of these
|
||||
* flags are merely hints though; the session manager may choose to
|
||||
* ignore them.
|
||||
*
|
||||
* Return value: %TRUE if the request was sent; %FALSE if it could not
|
||||
* be (eg, because it could not connect to the session manager).
|
||||
**/
|
||||
gboolean
|
||||
egg_sm_client_end_session (EggSMClientEndStyle style,
|
||||
gboolean request_confirmation)
|
||||
{
|
||||
EggSMClient *client = egg_sm_client_get ();
|
||||
|
||||
g_return_val_if_fail (EGG_IS_SM_CLIENT (client), FALSE);
|
||||
|
||||
if (EGG_SM_CLIENT_GET_CLASS (client)->end_session)
|
||||
{
|
||||
return EGG_SM_CLIENT_GET_CLASS (client)->end_session (client, style,
|
||||
request_confirmation);
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Signal-emitting callbacks from platform-specific code */
|
||||
|
||||
GKeyFile *
|
||||
egg_sm_client_save_state (EggSMClient *client)
|
||||
{
|
||||
GKeyFile *state_file;
|
||||
char *group;
|
||||
|
||||
g_return_val_if_fail (client == global_client, NULL);
|
||||
|
||||
state_file = g_key_file_new ();
|
||||
|
||||
g_debug ("Emitting save_state");
|
||||
g_signal_emit (client, signals[SAVE_STATE], 0, state_file);
|
||||
g_debug ("Done emitting save_state");
|
||||
|
||||
group = g_key_file_get_start_group (state_file);
|
||||
if (group)
|
||||
{
|
||||
g_free (group);
|
||||
return state_file;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_key_file_free (state_file);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
egg_sm_client_quit_requested (EggSMClient *client)
|
||||
{
|
||||
g_return_if_fail (client == global_client);
|
||||
|
||||
if (!g_signal_has_handler_pending (client, signals[QUIT_REQUESTED], 0, FALSE))
|
||||
{
|
||||
g_debug ("Not emitting quit_requested because no one is listening");
|
||||
egg_sm_client_will_quit (client, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
g_debug ("Emitting quit_requested");
|
||||
g_signal_emit (client, signals[QUIT_REQUESTED], 0);
|
||||
g_debug ("Done emitting quit_requested");
|
||||
}
|
||||
|
||||
void
|
||||
egg_sm_client_quit_cancelled (EggSMClient *client)
|
||||
{
|
||||
g_return_if_fail (client == global_client);
|
||||
|
||||
g_debug ("Emitting quit_cancelled");
|
||||
g_signal_emit (client, signals[QUIT_CANCELLED], 0);
|
||||
g_debug ("Done emitting quit_cancelled");
|
||||
}
|
||||
|
||||
void
|
||||
egg_sm_client_quit (EggSMClient *client)
|
||||
{
|
||||
g_return_if_fail (client == global_client);
|
||||
|
||||
g_debug ("Emitting quit");
|
||||
g_signal_emit (client, signals[QUIT], 0);
|
||||
g_debug ("Done emitting quit");
|
||||
|
||||
/* FIXME: should we just call gtk_main_quit() here? */
|
||||
}
|
||||
|
||||
static void
|
||||
egg_sm_client_debug_handler (const char *log_domain,
|
||||
GLogLevelFlags log_level,
|
||||
const char *message,
|
||||
gpointer user_data)
|
||||
{
|
||||
static int debug = -1;
|
||||
|
||||
if (debug < 0)
|
||||
debug = (g_getenv ("EGG_SM_CLIENT_DEBUG") != NULL);
|
||||
|
||||
if (debug)
|
||||
g_log_default_handler (log_domain, log_level, message, NULL);
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
/* eggsmclient.h
|
||||
* Copyright (C) 2007 Novell, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __EGG_SM_CLIENT_H__
|
||||
#define __EGG_SM_CLIENT_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define EGG_TYPE_SM_CLIENT (egg_sm_client_get_type ())
|
||||
#define EGG_SM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT, EggSMClient))
|
||||
#define EGG_SM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT, EggSMClientClass))
|
||||
#define EGG_IS_SM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT))
|
||||
#define EGG_IS_SM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT))
|
||||
#define EGG_SM_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT, EggSMClientClass))
|
||||
|
||||
typedef struct _EggSMClient EggSMClient;
|
||||
typedef struct _EggSMClientClass EggSMClientClass;
|
||||
typedef struct _EggSMClientPrivate EggSMClientPrivate;
|
||||
|
||||
typedef enum {
|
||||
EGG_SM_CLIENT_END_SESSION_DEFAULT,
|
||||
EGG_SM_CLIENT_LOGOUT,
|
||||
EGG_SM_CLIENT_REBOOT,
|
||||
EGG_SM_CLIENT_SHUTDOWN
|
||||
} EggSMClientEndStyle;
|
||||
|
||||
typedef enum {
|
||||
EGG_SM_CLIENT_MODE_DISABLED,
|
||||
EGG_SM_CLIENT_MODE_NO_RESTART,
|
||||
EGG_SM_CLIENT_MODE_NORMAL
|
||||
} EggSMClientMode;
|
||||
|
||||
struct _EggSMClient
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
};
|
||||
|
||||
struct _EggSMClientClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* signals */
|
||||
void (*save_state) (EggSMClient *client,
|
||||
GKeyFile *state_file);
|
||||
|
||||
void (*quit_requested) (EggSMClient *client);
|
||||
void (*quit_cancelled) (EggSMClient *client);
|
||||
void (*quit) (EggSMClient *client);
|
||||
|
||||
/* virtual methods */
|
||||
void (*startup) (EggSMClient *client,
|
||||
const char *client_id);
|
||||
void (*set_restart_command) (EggSMClient *client,
|
||||
int argc,
|
||||
const char **argv);
|
||||
void (*will_quit) (EggSMClient *client,
|
||||
gboolean will_quit);
|
||||
gboolean (*end_session) (EggSMClient *client,
|
||||
EggSMClientEndStyle style,
|
||||
gboolean request_confirmation);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_egg_reserved1) (void);
|
||||
void (*_egg_reserved2) (void);
|
||||
void (*_egg_reserved3) (void);
|
||||
void (*_egg_reserved4) (void);
|
||||
};
|
||||
|
||||
GType egg_sm_client_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GOptionGroup *egg_sm_client_get_option_group (void);
|
||||
|
||||
/* Initialization */
|
||||
void egg_sm_client_set_mode (EggSMClientMode mode);
|
||||
EggSMClientMode egg_sm_client_get_mode (void);
|
||||
EggSMClient *egg_sm_client_get (void);
|
||||
|
||||
/* Resuming a saved session */
|
||||
gboolean egg_sm_client_is_resumed (EggSMClient *client);
|
||||
GKeyFile *egg_sm_client_get_state_file (EggSMClient *client);
|
||||
|
||||
/* Alternate means of saving state */
|
||||
void egg_sm_client_set_restart_command (EggSMClient *client,
|
||||
int argc,
|
||||
const char **argv);
|
||||
|
||||
/* Handling "quit_requested" signal */
|
||||
void egg_sm_client_will_quit (EggSMClient *client,
|
||||
gboolean will_quit);
|
||||
|
||||
/* Initiate a logout/reboot/shutdown */
|
||||
gboolean egg_sm_client_end_session (EggSMClientEndStyle style,
|
||||
gboolean request_confirmation);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
#endif /* __EGG_SM_CLIENT_H__ */
|
|
@ -1,8 +1,6 @@
|
|||
# List of source files containing translatable strings.
|
||||
# Please keep this file sorted alphabetically.
|
||||
[encoding: UTF-8]
|
||||
cut-n-paste-code/libegg/eggdesktopfile.c
|
||||
cut-n-paste-code/libegg/eggsmclient.c
|
||||
data/nautilus.xml.in
|
||||
eel/eel-canvas.c
|
||||
eel/eel-editable-label.c
|
||||
|
|
|
@ -64,8 +64,6 @@ nautilus_SOURCES = \
|
|||
nautilus-actions.h \
|
||||
nautilus-application.c \
|
||||
nautilus-application.h \
|
||||
nautilus-application-smclient.c \
|
||||
nautilus-application-smclient.h \
|
||||
nautilus-bookmark-list.c \
|
||||
nautilus-bookmark-list.h \
|
||||
nautilus-bookmarks-window.c \
|
||||
|
|
|
@ -1,459 +0,0 @@
|
|||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
||||
/*
|
||||
* nautilus-application-smclient: a little module for session handling.
|
||||
*
|
||||
* Copyright (C) 2000 Red Hat, Inc.
|
||||
* Copyright (C) 2010 Cosimo Cecchi <cosimoc@gnome.org>
|
||||
*
|
||||
* Nautilus 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.
|
||||
*
|
||||
* Nautilus 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.
|
||||
*/
|
||||
|
||||
#include "nautilus-application-smclient.h"
|
||||
|
||||
#include "nautilus-navigation-window.h"
|
||||
#include "nautilus-window-private.h"
|
||||
#include "nautilus-window-slot.h"
|
||||
|
||||
#include <eel/eel-gtk-extensions.h>
|
||||
#include <eel/eel-vfs-extensions.h>
|
||||
#include <libxml/xmlsave.h>
|
||||
|
||||
#define DEBUG_FLAG NAUTILUS_DEBUG_SMCLIENT
|
||||
#include <libnautilus-private/nautilus-debug.h>
|
||||
|
||||
static char *
|
||||
nautilus_application_get_session_data (NautilusApplication *self)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr root_node, history_node;
|
||||
GList *l, *window_list;
|
||||
char *data;
|
||||
unsigned n_processed;
|
||||
xmlSaveCtxtPtr ctx;
|
||||
xmlBufferPtr buffer;
|
||||
|
||||
doc = xmlNewDoc ("1.0");
|
||||
|
||||
root_node = xmlNewNode (NULL, "session");
|
||||
xmlDocSetRootElement (doc, root_node);
|
||||
|
||||
history_node = xmlNewChild (root_node, NULL, "history", NULL);
|
||||
|
||||
n_processed = 0;
|
||||
for (l = nautilus_get_history_list (); l != NULL; l = l->next) {
|
||||
NautilusBookmark *bookmark;
|
||||
xmlNodePtr bookmark_node;
|
||||
GIcon *icon;
|
||||
char *tmp;
|
||||
|
||||
bookmark = l->data;
|
||||
|
||||
bookmark_node = xmlNewChild (history_node, NULL, "bookmark", NULL);
|
||||
|
||||
tmp = nautilus_bookmark_get_name (bookmark);
|
||||
xmlNewProp (bookmark_node, "name", tmp);
|
||||
g_free (tmp);
|
||||
|
||||
icon = nautilus_bookmark_get_icon (bookmark);
|
||||
tmp = g_icon_to_string (icon);
|
||||
g_object_unref (icon);
|
||||
if (tmp) {
|
||||
xmlNewProp (bookmark_node, "icon", tmp);
|
||||
g_free (tmp);
|
||||
}
|
||||
|
||||
tmp = nautilus_bookmark_get_uri (bookmark);
|
||||
xmlNewProp (bookmark_node, "uri", tmp);
|
||||
|
||||
DEBUG ("Saving history information for uri %s", tmp);
|
||||
|
||||
g_free (tmp);
|
||||
|
||||
if (nautilus_bookmark_get_has_custom_name (bookmark)) {
|
||||
xmlNewProp (bookmark_node, "has_custom_name", "TRUE");
|
||||
}
|
||||
|
||||
if (++n_processed > 50) { /* prevent history list from growing arbitrarily large. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
window_list = gtk_application_get_windows (GTK_APPLICATION (self));
|
||||
|
||||
for (l = window_list; l != NULL; l = l->next) {
|
||||
xmlNodePtr win_node, slot_node;
|
||||
NautilusWindow *window;
|
||||
NautilusWindowSlot *slot, *active_slot;
|
||||
GList *slots, *m;
|
||||
char *tmp;
|
||||
|
||||
window = l->data;
|
||||
|
||||
slots = nautilus_window_get_slots (window);
|
||||
active_slot = nautilus_window_get_active_slot (window);
|
||||
|
||||
/* store one slot as window location. Otherwise
|
||||
* older Nautilus versions will bail when reading the file. */
|
||||
tmp = nautilus_window_slot_get_location_uri (active_slot);
|
||||
|
||||
if (eel_uri_is_desktop (tmp)) {
|
||||
g_list_free (slots);
|
||||
g_free (tmp);
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG ("Saving opened window for uri %s", tmp);
|
||||
win_node = xmlNewChild (root_node, NULL, "window", NULL);
|
||||
|
||||
xmlNewProp (win_node, "location", tmp);
|
||||
g_free (tmp);
|
||||
|
||||
xmlNewProp (win_node, "type", NAUTILUS_IS_NAVIGATION_WINDOW (window) ? "navigation" : "spatial");
|
||||
|
||||
if (NAUTILUS_IS_NAVIGATION_WINDOW (window)) { /* spatial windows store their state as file metadata */
|
||||
GdkWindow *gdk_window;
|
||||
|
||||
tmp = eel_gtk_window_get_geometry_string (GTK_WINDOW (window));
|
||||
xmlNewProp (win_node, "geometry", tmp);
|
||||
g_free (tmp);
|
||||
|
||||
gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
|
||||
|
||||
if (gdk_window &&
|
||||
gdk_window_get_state (gdk_window) & GDK_WINDOW_STATE_MAXIMIZED) {
|
||||
xmlNewProp (win_node, "maximized", "TRUE");
|
||||
}
|
||||
|
||||
if (gdk_window &&
|
||||
gdk_window_get_state (gdk_window) & GDK_WINDOW_STATE_STICKY) {
|
||||
xmlNewProp (win_node, "sticky", "TRUE");
|
||||
}
|
||||
|
||||
if (gdk_window &&
|
||||
gdk_window_get_state (gdk_window) & GDK_WINDOW_STATE_ABOVE) {
|
||||
xmlNewProp (win_node, "keep-above", "TRUE");
|
||||
}
|
||||
}
|
||||
|
||||
for (m = slots; m != NULL; m = m->next) {
|
||||
slot = NAUTILUS_WINDOW_SLOT (m->data);
|
||||
|
||||
slot_node = xmlNewChild (win_node, NULL, "slot", NULL);
|
||||
|
||||
tmp = nautilus_window_slot_get_location_uri (slot);
|
||||
xmlNewProp (slot_node, "location", tmp);
|
||||
g_free (tmp);
|
||||
|
||||
if (slot == active_slot) {
|
||||
xmlNewProp (slot_node, "active", "TRUE");
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free (slots);
|
||||
}
|
||||
|
||||
buffer = xmlBufferCreate ();
|
||||
xmlIndentTreeOutput = 1;
|
||||
ctx = xmlSaveToBuffer (buffer, "UTF-8", XML_SAVE_FORMAT);
|
||||
if (xmlSaveDoc (ctx, doc) < 0 ||
|
||||
xmlSaveFlush (ctx) < 0) {
|
||||
DEBUG ("Failed to save session");
|
||||
}
|
||||
|
||||
xmlSaveClose(ctx);
|
||||
data = g_strndup (buffer->content, buffer->use);
|
||||
xmlBufferFree (buffer);
|
||||
|
||||
xmlFreeDoc (doc);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
smclient_save_state_cb (EggSMClient *client,
|
||||
GKeyFile *state_file,
|
||||
NautilusApplication *application)
|
||||
{
|
||||
char *data;
|
||||
|
||||
DEBUG ("Received SaveState signal from the SMClient");
|
||||
|
||||
data = nautilus_application_get_session_data (application);
|
||||
|
||||
if (data != NULL) {
|
||||
g_key_file_set_string (state_file,
|
||||
"Nautilus",
|
||||
"documents",
|
||||
data);
|
||||
}
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
smclient_quit_cb (EggSMClient *client,
|
||||
NautilusApplication *application)
|
||||
{
|
||||
DEBUG ("Received Quit signal from the SMClient");
|
||||
|
||||
nautilus_application_quit (application);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_application_smclient_initialize (NautilusApplication *self)
|
||||
{
|
||||
egg_sm_client_set_mode (EGG_SM_CLIENT_MODE_NORMAL);
|
||||
|
||||
g_signal_connect (self->smclient, "save_state",
|
||||
G_CALLBACK (smclient_save_state_cb),
|
||||
self);
|
||||
g_signal_connect (self->smclient, "quit",
|
||||
G_CALLBACK (smclient_quit_cb),
|
||||
self);
|
||||
|
||||
/* TODO: Should connect to quit_requested and block logout on active transfer? */
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_application_smclient_load (NautilusApplication *application,
|
||||
gboolean *no_default_window)
|
||||
{
|
||||
xmlDocPtr doc;
|
||||
gboolean bail;
|
||||
xmlNodePtr root_node;
|
||||
GKeyFile *state_file;
|
||||
char *data;
|
||||
|
||||
DEBUG ("Loading session data");
|
||||
|
||||
nautilus_application_smclient_initialize (application);
|
||||
|
||||
if (!egg_sm_client_is_resumed (application->smclient)) {
|
||||
DEBUG ("SMClient not resumed");
|
||||
return;
|
||||
}
|
||||
|
||||
state_file = egg_sm_client_get_state_file (application->smclient);
|
||||
if (!state_file) {
|
||||
DEBUG ("No SMClient state file");
|
||||
return;
|
||||
}
|
||||
|
||||
data = g_key_file_get_string (state_file,
|
||||
"Nautilus",
|
||||
"documents",
|
||||
NULL);
|
||||
if (data == NULL) {
|
||||
DEBUG ("No SMClient session data");
|
||||
return;
|
||||
}
|
||||
|
||||
*no_default_window = TRUE;
|
||||
bail = TRUE;
|
||||
|
||||
doc = xmlReadMemory (data, strlen (data), NULL, "UTF-8", 0);
|
||||
if (doc != NULL && (root_node = xmlDocGetRootElement (doc)) != NULL) {
|
||||
xmlNodePtr node;
|
||||
|
||||
bail = FALSE;
|
||||
|
||||
for (node = root_node->children; node != NULL; node = node->next) {
|
||||
|
||||
if (!strcmp (node->name, "text")) {
|
||||
continue;
|
||||
} else if (!strcmp (node->name, "history")) {
|
||||
xmlNodePtr bookmark_node;
|
||||
gboolean emit_change;
|
||||
|
||||
emit_change = FALSE;
|
||||
|
||||
for (bookmark_node = node->children; bookmark_node != NULL; bookmark_node = bookmark_node->next) {
|
||||
if (!strcmp (bookmark_node->name, "text")) {
|
||||
continue;
|
||||
} else if (!strcmp (bookmark_node->name, "bookmark")) {
|
||||
xmlChar *name, *icon_str, *uri;
|
||||
gboolean has_custom_name;
|
||||
GIcon *icon;
|
||||
GFile *location;
|
||||
|
||||
uri = xmlGetProp (bookmark_node, "uri");
|
||||
name = xmlGetProp (bookmark_node, "name");
|
||||
has_custom_name = xmlHasProp (bookmark_node, "has_custom_name") ? TRUE : FALSE;
|
||||
icon_str = xmlGetProp (bookmark_node, "icon");
|
||||
icon = NULL;
|
||||
if (icon_str) {
|
||||
icon = g_icon_new_for_string (icon_str, NULL);
|
||||
}
|
||||
location = g_file_new_for_uri (uri);
|
||||
|
||||
DEBUG ("Adding %s to the history list", name);
|
||||
|
||||
emit_change |= nautilus_add_to_history_list_no_notify (location, name, has_custom_name, icon);
|
||||
|
||||
g_object_unref (location);
|
||||
|
||||
if (icon) {
|
||||
g_object_unref (icon);
|
||||
}
|
||||
xmlFree (name);
|
||||
xmlFree (uri);
|
||||
xmlFree (icon_str);
|
||||
} else {
|
||||
DEBUG ("Unexpected bookmark node %s while parsing session data", bookmark_node->name);
|
||||
bail = TRUE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (emit_change) {
|
||||
nautilus_send_history_list_changed ();
|
||||
}
|
||||
} else if (!strcmp (node->name, "window")) {
|
||||
NautilusWindow *window;
|
||||
xmlChar *type, *location_uri, *slot_uri;
|
||||
xmlNodePtr slot_node;
|
||||
GFile *location;
|
||||
int i;
|
||||
|
||||
type = xmlGetProp (node, "type");
|
||||
if (type == NULL) {
|
||||
DEBUG ("Empty type node while parsing session data");
|
||||
bail = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
location_uri = xmlGetProp (node, "location");
|
||||
if (location_uri == NULL) {
|
||||
DEBUG ("Empty location node while parsing session data");
|
||||
bail = TRUE;
|
||||
xmlFree (type);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp (type, "navigation")) {
|
||||
xmlChar *geometry;
|
||||
|
||||
window = nautilus_application_create_navigation_window (application, NULL, gdk_screen_get_default ());
|
||||
|
||||
geometry = xmlGetProp (node, "geometry");
|
||||
if (geometry != NULL) {
|
||||
eel_gtk_window_set_initial_geometry_from_string
|
||||
(GTK_WINDOW (window),
|
||||
geometry,
|
||||
NAUTILUS_NAVIGATION_WINDOW_MIN_WIDTH,
|
||||
NAUTILUS_NAVIGATION_WINDOW_MIN_HEIGHT,
|
||||
FALSE);
|
||||
}
|
||||
xmlFree (geometry);
|
||||
|
||||
if (xmlHasProp (node, "maximized")) {
|
||||
gtk_window_maximize (GTK_WINDOW (window));
|
||||
} else {
|
||||
gtk_window_unmaximize (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
if (xmlHasProp (node, "sticky")) {
|
||||
gtk_window_stick (GTK_WINDOW (window));
|
||||
} else {
|
||||
gtk_window_unstick (GTK_WINDOW (window));
|
||||
}
|
||||
|
||||
if (xmlHasProp (node, "keep-above")) {
|
||||
gtk_window_set_keep_above (GTK_WINDOW (window), TRUE);
|
||||
} else {
|
||||
gtk_window_set_keep_above (GTK_WINDOW (window), FALSE);
|
||||
}
|
||||
|
||||
for (i = 0, slot_node = node->children; slot_node != NULL; slot_node = slot_node->next) {
|
||||
if (!strcmp (slot_node->name, "slot")) {
|
||||
slot_uri = xmlGetProp (slot_node, "location");
|
||||
if (slot_uri != NULL) {
|
||||
NautilusWindowSlot *slot;
|
||||
|
||||
if (i == 0) {
|
||||
slot = window->details->active_pane->active_slot;
|
||||
} else {
|
||||
slot = nautilus_window_open_slot (window->details->active_pane, NAUTILUS_WINDOW_OPEN_SLOT_APPEND);
|
||||
}
|
||||
|
||||
DEBUG ("Resuming navigation window slot for uri %s", slot_uri);
|
||||
|
||||
location = g_file_new_for_uri (slot_uri);
|
||||
nautilus_window_slot_open_location (slot, location, FALSE);
|
||||
|
||||
if (xmlHasProp (slot_node, "active")) {
|
||||
nautilus_window_set_active_slot (slot->pane->window, slot);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
xmlFree (slot_uri);
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
/* This may be an old session file */
|
||||
location = g_file_new_for_uri (location_uri);
|
||||
nautilus_window_slot_open_location (window->details->active_pane->active_slot, location, FALSE);
|
||||
g_object_unref (location);
|
||||
}
|
||||
} else if (!strcmp (type, "spatial")) {
|
||||
DEBUG ("Resuming spatial window for uri %s", location_uri);
|
||||
|
||||
location = g_file_new_for_uri (location_uri);
|
||||
window = nautilus_application_get_spatial_window (application, NULL, NULL,
|
||||
location, gdk_screen_get_default (),
|
||||
NULL);
|
||||
|
||||
nautilus_window_go_to (window, location);
|
||||
|
||||
g_object_unref (location);
|
||||
} else {
|
||||
DEBUG ("Unknown window type \"%s\" while parsing session data", type);
|
||||
bail = TRUE;
|
||||
}
|
||||
|
||||
xmlFree (type);
|
||||
xmlFree (location_uri);
|
||||
} else {
|
||||
DEBUG ("Unexpected node %s while parsing session data", node->name);
|
||||
bail = TRUE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (doc != NULL) {
|
||||
xmlFreeDoc (doc);
|
||||
}
|
||||
|
||||
g_free (data);
|
||||
|
||||
if (bail) {
|
||||
DEBUG ("Failed to load session");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nautilus_application_smclient_startup (NautilusApplication *self)
|
||||
{
|
||||
g_assert (self->smclient == NULL);
|
||||
|
||||
DEBUG ("Starting up SMClient");
|
||||
|
||||
egg_sm_client_set_mode (EGG_SM_CLIENT_MODE_DISABLED);
|
||||
self->smclient = egg_sm_client_get ();
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
||||
/*
|
||||
* nautilus-application-smclient: a little module for session handling.
|
||||
*
|
||||
* Copyright (C) 2000 Red Hat, Inc.
|
||||
* Copyright (C) 2010 Cosimo Cecchi <cosimoc@gnome.org>
|
||||
*
|
||||
* Nautilus 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.
|
||||
*
|
||||
* Nautilus 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 __NAUTILUS_APPLICATION_SMCLIENT_H__
|
||||
#define __NAUTILUS_APPLICATION_SMCLIENT_H__
|
||||
|
||||
#include "nautilus-application.h"
|
||||
|
||||
void nautilus_application_smclient_startup (NautilusApplication *self);
|
||||
void nautilus_application_smclient_load (NautilusApplication *self,
|
||||
gboolean *no_default_window);
|
||||
|
||||
#endif /* __NAUTILUS_APPLICATION_SMCLIENT_H__ */
|
|
@ -37,7 +37,6 @@
|
|||
#include "file-manager/fm-empty-view.h"
|
||||
#endif /* ENABLE_EMPTY_VIEW */
|
||||
|
||||
#include "nautilus-application-smclient.h"
|
||||
#include "nautilus-desktop-window.h"
|
||||
#include "nautilus-image-properties-page.h"
|
||||
#include "nautilus-navigation-window.h"
|
||||
|
@ -1334,15 +1333,8 @@ nautilus_application_command_line (GApplication *app,
|
|||
g_option_context_add_main_entries (context, options, NULL);
|
||||
g_option_context_add_group (context, gtk_get_option_group (TRUE));
|
||||
|
||||
if (!self->initialized) {
|
||||
g_option_context_add_group (context, egg_sm_client_get_option_group ());
|
||||
}
|
||||
|
||||
argv = g_application_command_line_get_arguments (command_line, &argc);
|
||||
|
||||
/* we need to do this here, as parsing the EggSMClient option context,
|
||||
* unsets this variable.
|
||||
*/
|
||||
autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
|
||||
if (autostart_id != NULL && *autostart_id != '\0') {
|
||||
autostart_mode = TRUE;
|
||||
|
@ -1451,9 +1443,6 @@ nautilus_application_command_line (GApplication *app,
|
|||
g_signal_connect (gtk_accel_map_get (), "changed",
|
||||
G_CALLBACK (queue_accel_map_save_callback), NULL);
|
||||
|
||||
/* Initialize SMClient and load session info if availible */
|
||||
nautilus_application_smclient_load (self, &no_default_window);
|
||||
|
||||
self->initialized = TRUE;
|
||||
}
|
||||
|
||||
|
@ -1536,9 +1525,6 @@ nautilus_application_startup (GApplication *app)
|
|||
/* create an undo manager */
|
||||
self->undo_manager = nautilus_undo_manager_new ();
|
||||
|
||||
/* initialize the session manager client */
|
||||
nautilus_application_smclient_startup (self);
|
||||
|
||||
/* Initialize preferences. This is needed to create the
|
||||
* global GSettings objects.
|
||||
*/
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <gio/gio.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <libegg/eggsmclient.h>
|
||||
#include <libnautilus-private/nautilus-undo-manager.h>
|
||||
|
||||
#define NAUTILUS_DESKTOP_ICON_VIEW_IID "OAFIID:Nautilus_File_Manager_Desktop_Icon_View"
|
||||
|
@ -58,7 +57,6 @@ typedef struct _NautilusSpatialWindow NautilusSpatialWindow;
|
|||
typedef struct {
|
||||
GtkApplication parent;
|
||||
|
||||
EggSMClient *smclient;
|
||||
NautilusUndoManager *undo_manager;
|
||||
GVolumeMonitor *volume_monitor;
|
||||
GDBusProxy *proxy;
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
|
||||
#include <libnautilus-private/nautilus-debug.h>
|
||||
#include <eel/eel-debug.h>
|
||||
#include <libegg/eggdesktopfile.h>
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
@ -93,10 +92,6 @@ main (int argc, char *argv[])
|
|||
|
||||
g_set_prgname ("nautilus");
|
||||
|
||||
if (g_file_test (DATADIR "/applications/nautilus.desktop", G_FILE_TEST_EXISTS)) {
|
||||
egg_set_desktop_file (DATADIR "/applications/nautilus.desktop");
|
||||
}
|
||||
|
||||
#ifdef HAVE_EXEMPI
|
||||
xmp_init();
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue