mirror of
https://gitlab.gnome.org/GNOME/nautilus
synced 2024-10-03 22:45:26 +00:00
Renamed nautilus.desktop to nautilus-browser.desktop (this is what it
2008-10-02 Alexander Larsson <alexl@redhat.com> * Makefile.am: * nautilus-browser.desktop.in.in: * nautilus.desktop.in.in: Renamed nautilus.desktop to nautilus-browser.desktop (this is what it does, launch a browser window with no desktop) Created new NoDisplay nautilus.desktop file that is used for autostarting nautilus from gnome-session. * configure.in: Pull in the right cflags/libs for libegg Add nautilus-browser.desktop.in to output * cut-n-paste-code/libegg/Makefile.am: * cut-n-paste-code/libegg/eggdesktopfile.[ch]: Added. * cut-n-paste-code/libegg/eggsmclient-private.h: Added. * cut-n-paste-code/libegg/eggsmclient-xsmp.c: Added. * cut-n-paste-code/libegg/eggsmclient.[ch]: Added. Import eggsmclient from libegg. Save data in desktop file instead of a separate file as per the new gnome-session. * cut-n-paste-code/libegg/eggtreemultidnd.c: Minor update from libegg * src/nautilus-application.[ch]: Use eggsmclient for session handling instead of gnome-client. * src/nautilus-main.c: Don't use gnome_program, instead use eggsmsession and g_option_context_parse directly. This removes support for some internal commandline arguments that are not used anymore. svn path=/trunk/; revision=14680
This commit is contained in:
parent
31d3fc91d8
commit
9c068ad3e6
35
ChangeLog
35
ChangeLog
|
@ -1,3 +1,38 @@
|
||||||
|
2008-10-02 Alexander Larsson <alexl@redhat.com>
|
||||||
|
|
||||||
|
* Makefile.am:
|
||||||
|
* nautilus-browser.desktop.in.in:
|
||||||
|
* nautilus.desktop.in.in:
|
||||||
|
Renamed nautilus.desktop to nautilus-browser.desktop
|
||||||
|
(this is what it does, launch a browser window with no desktop)
|
||||||
|
Created new NoDisplay nautilus.desktop file that is used
|
||||||
|
for autostarting nautilus from gnome-session.
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Pull in the right cflags/libs for libegg
|
||||||
|
Add nautilus-browser.desktop.in to output
|
||||||
|
|
||||||
|
* cut-n-paste-code/libegg/Makefile.am:
|
||||||
|
* cut-n-paste-code/libegg/eggdesktopfile.[ch]: Added.
|
||||||
|
* cut-n-paste-code/libegg/eggsmclient-private.h: Added.
|
||||||
|
* cut-n-paste-code/libegg/eggsmclient-xsmp.c: Added.
|
||||||
|
* cut-n-paste-code/libegg/eggsmclient.[ch]: Added.
|
||||||
|
Import eggsmclient from libegg.
|
||||||
|
Save data in desktop file instead of a separate file as per the
|
||||||
|
new gnome-session.
|
||||||
|
|
||||||
|
* cut-n-paste-code/libegg/eggtreemultidnd.c:
|
||||||
|
Minor update from libegg
|
||||||
|
|
||||||
|
* src/nautilus-application.[ch]:
|
||||||
|
Use eggsmclient for session handling instead of gnome-client.
|
||||||
|
|
||||||
|
* src/nautilus-main.c:
|
||||||
|
Don't use gnome_program, instead use eggsmsession and
|
||||||
|
g_option_context_parse directly.
|
||||||
|
This removes support for some internal commandline arguments
|
||||||
|
that are not used anymore.
|
||||||
|
|
||||||
2008-10-02 Cosimo Cecchi <cosimoc@gnome.org>
|
2008-10-02 Cosimo Cecchi <cosimoc@gnome.org>
|
||||||
|
|
||||||
* libnautilus-extension/libnautilus-extension-uninstalled.pc.in:
|
* libnautilus-extension/libnautilus-extension-uninstalled.pc.in:
|
||||||
|
|
|
@ -10,6 +10,7 @@ desktop_in_files = \
|
||||||
nautilus-computer.desktop.in \
|
nautilus-computer.desktop.in \
|
||||||
nautilus-folder-handler.desktop.in \
|
nautilus-folder-handler.desktop.in \
|
||||||
nautilus-file-management-properties.desktop.in \
|
nautilus-file-management-properties.desktop.in \
|
||||||
|
nautilus-browser.desktop.in \
|
||||||
nautilus-autorun-software.desktop.in
|
nautilus-autorun-software.desktop.in
|
||||||
|
|
||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
|
|
|
@ -370,9 +370,10 @@ fi
|
||||||
dnl ==========================================================================
|
dnl ==========================================================================
|
||||||
|
|
||||||
dnl libegg
|
dnl libegg
|
||||||
LIBEGG_MODULES="gtk+-2.0 libgnome-2.0"
|
LIBEGG_MODULES="gtk+-2.0 gthread-2.0"
|
||||||
LIBEGG_CFLAGS="`$PKG_CONFIG --cflags $LIBEGG_MODULES`"
|
LIBEGG_CFLAGS="`$PKG_CONFIG --cflags $LIBEGG_MODULES`"
|
||||||
AC_SUBST(LIBEGG_CFLAGS)
|
AC_SUBST(LIBEGG_CFLAGS)
|
||||||
|
AC_SUBST(LIBEGG_LIBS)
|
||||||
|
|
||||||
dnl libnautilus-extension
|
dnl libnautilus-extension
|
||||||
LIBNAUTILUS_EXTENSION_MODULES="glib-2.0 gtk+-2.0"
|
LIBNAUTILUS_EXTENSION_MODULES="glib-2.0 gtk+-2.0"
|
||||||
|
@ -461,6 +462,7 @@ nautilus-file-management-properties.desktop.in
|
||||||
nautilus-home.desktop.in
|
nautilus-home.desktop.in
|
||||||
nautilus.desktop.in
|
nautilus.desktop.in
|
||||||
nautilus-folder-handler.desktop.in
|
nautilus-folder-handler.desktop.in
|
||||||
|
nautilus-browser.desktop.in
|
||||||
nautilus-autorun-software.desktop.in
|
nautilus-autorun-software.desktop.in
|
||||||
po/Makefile.in
|
po/Makefile.in
|
||||||
src/Makefile
|
src/Makefile
|
||||||
|
|
|
@ -9,15 +9,38 @@ EGG_TREE_DND_FILES = \
|
||||||
eggtreemultidnd.h \
|
eggtreemultidnd.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
EGG_SMCLIENT_FILES = \
|
||||||
|
eggdesktopfile.c \
|
||||||
|
eggdesktopfile.h \
|
||||||
|
eggsmclient.c \
|
||||||
|
eggsmclient.h \
|
||||||
|
eggsmclient-private.h \
|
||||||
|
eggsmclient-xsmp.c \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
libegg_la_SOURCES = \
|
libegg_la_SOURCES = \
|
||||||
$(EGG_TREE_DND_FILES) \
|
$(EGG_TREE_DND_FILES) \
|
||||||
|
$(EGG_SMCLIENT_FILES) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
libegg_la_CFLAGS = \
|
||||||
|
-DEGG_SM_CLIENT_BACKEND_XSMP \
|
||||||
|
-DG_LOG_DOMAIN=\""EggSMClient"\" \
|
||||||
|
$(LIBEGG_CFLAGS) \
|
||||||
|
$(WARNING_CFLAGS) \
|
||||||
|
$(DISABLE_DEPRECATED)
|
||||||
|
|
||||||
|
libegg_la_LIBADD = \
|
||||||
|
$(LIBEGG_LIBS) \
|
||||||
|
-lSM -lICE
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
update-from-egg.sh \
|
update-from-egg.sh \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
EGG_TREE_DND_DIR = $(srcdir)/../../../libegg/libegg/treeviewutils
|
EGG_TREE_DND_DIR = $(srcdir)/../../../libegg/libegg/treeviewutils
|
||||||
|
EGG_SMCLIENT_DIR = $(srcdir)/../../../libegg/libegg/smclient
|
||||||
|
|
||||||
regenerate-built-sources:
|
regenerate-built-sources:
|
||||||
EGGFILES="$(EGG_TREE_DND_FILES)" EGGDIR="$(EGG_TREE_DND_DIR)" $(srcdir)/update-from-egg.sh
|
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
|
||||||
|
|
1474
cut-n-paste-code/libegg/eggdesktopfile.c
Normal file
1474
cut-n-paste-code/libegg/eggdesktopfile.c
Normal file
File diff suppressed because it is too large
Load diff
159
cut-n-paste-code/libegg/eggdesktopfile.h
Normal file
159
cut-n-paste-code/libegg/eggdesktopfile.h
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
/* 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) G_GNUC_PURE;
|
||||||
|
|
||||||
|
EggDesktopFileType egg_desktop_file_get_desktop_file_type (EggDesktopFile *desktop_file) G_GNUC_PURE;
|
||||||
|
|
||||||
|
const char *egg_desktop_file_get_name (EggDesktopFile *desktop_file) G_GNUC_PURE;
|
||||||
|
const char *egg_desktop_file_get_icon (EggDesktopFile *desktop_file) G_GNUC_PURE;
|
||||||
|
|
||||||
|
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__ */
|
53
cut-n-paste-code/libegg/eggsmclient-private.h
Normal file
53
cut-n-paste-code/libegg/eggsmclient-private.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/* 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__ */
|
1359
cut-n-paste-code/libegg/eggsmclient-xsmp.c
Normal file
1359
cut-n-paste-code/libegg/eggsmclient-xsmp.c
Normal file
File diff suppressed because it is too large
Load diff
578
cut-n-paste-code/libegg/eggsmclient.c
Normal file
578
cut-n-paste-code/libegg/eggsmclient.c
Normal file
|
@ -0,0 +1,578 @@
|
||||||
|
/*
|
||||||
|
* 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] = { 0 };
|
||||||
|
|
||||||
|
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 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_STRING, &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") },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
sm_client_post_parse_func (GOptionContext *context,
|
||||||
|
GOptionGroup *group,
|
||||||
|
gpointer data,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
EggSMClient *client = egg_sm_client_get ();
|
||||||
|
|
||||||
|
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 (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)
|
||||||
|
{
|
||||||
|
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. The application will not even connect to the session
|
||||||
|
* manager. (egg_sm_client_get() will still return an #EggSMClient,
|
||||||
|
* but it will just be a dummy 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.
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
egg_sm_client_set_mode (EggSMClientMode mode)
|
||||||
|
{
|
||||||
|
global_client_mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 (global_client_mode != EGG_SM_CLIENT_MODE_DISABLED &&
|
||||||
|
!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 D-Bus first
|
||||||
|
* and fall back to XSMP if D-Bus session management isn't
|
||||||
|
* available.
|
||||||
|
*/
|
||||||
|
# ifdef EGG_SM_CLIENT_BACKEND_DBUS
|
||||||
|
global_client = egg_sm_client_dbus_new ();
|
||||||
|
# endif
|
||||||
|
# ifdef EGG_SM_CLIENT_BACKEND_XSMP
|
||||||
|
if (!global_client)
|
||||||
|
global_client = egg_sm_client_xsmp_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);
|
||||||
|
}
|
117
cut-n-paste-code/libegg/eggsmclient.h
Normal file
117
cut-n-paste-code/libegg/eggsmclient.h
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
/* 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__ */
|
|
@ -59,7 +59,7 @@ egg_tree_multi_drag_source_get_type (void)
|
||||||
|
|
||||||
if (!our_type)
|
if (!our_type)
|
||||||
{
|
{
|
||||||
const GTypeInfo our_info =
|
static const GTypeInfo our_info =
|
||||||
{
|
{
|
||||||
sizeof (EggTreeMultiDragSourceIface), /* class_size */
|
sizeof (EggTreeMultiDragSourceIface), /* class_size */
|
||||||
NULL, /* base_init */
|
NULL, /* base_init */
|
||||||
|
|
16
nautilus-browser.desktop.in.in
Normal file
16
nautilus-browser.desktop.in.in
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Encoding=UTF-8
|
||||||
|
_Name=File Browser
|
||||||
|
_Comment=Browse the file system with the file manager
|
||||||
|
TryExec=nautilus
|
||||||
|
Exec=nautilus --no-desktop --browser %U
|
||||||
|
Icon=system-file-manager
|
||||||
|
Terminal=false
|
||||||
|
StartupNotify=true
|
||||||
|
Type=Application
|
||||||
|
Categories=GNOME;GTK;System;Utility;Core;
|
||||||
|
OnlyShowIn=GNOME;
|
||||||
|
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||||
|
X-GNOME-Bugzilla-Product=nautilus
|
||||||
|
X-GNOME-Bugzilla-Component=general
|
||||||
|
X-GNOME-Bugzilla-Version=@VERSION@
|
|
@ -1,19 +1,17 @@
|
||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Encoding=UTF-8
|
Encoding=UTF-8
|
||||||
_Name=File Browser
|
_Name=File Manager
|
||||||
_Comment=Browse the file system with the file manager
|
Exec=nautilus
|
||||||
TryExec=nautilus
|
|
||||||
Exec=nautilus --no-desktop --browser %U
|
|
||||||
Icon=system-file-manager
|
Icon=system-file-manager
|
||||||
Terminal=false
|
Terminal=false
|
||||||
StartupNotify=true
|
|
||||||
Type=Application
|
Type=Application
|
||||||
Categories=GNOME;GTK;System;Utility;Core;
|
StartupNotify=true
|
||||||
|
NoDisplay=true
|
||||||
OnlyShowIn=GNOME;
|
OnlyShowIn=GNOME;
|
||||||
X-GNOME-Bugzilla-Bugzilla=GNOME
|
X-GNOME-Bugzilla-Bugzilla=GNOME
|
||||||
X-GNOME-Bugzilla-Product=nautilus
|
X-GNOME-Bugzilla-Product=nautilus
|
||||||
X-GNOME-Bugzilla-Component=general
|
X-GNOME-Bugzilla-Component=general
|
||||||
X-GNOME-Bugzilla-Version=@VERSION@
|
X-GNOME-Bugzilla-Version=@VERSION@
|
||||||
X-GNOME-Autostart-Phase=Desktop
|
X-GNOME-Autostart-Phase=Desktop
|
||||||
X-GNOME-Provides=filemanager
|
|
||||||
X-GNOME-Autostart-Notify=true
|
X-GNOME-Autostart-Notify=true
|
||||||
|
X-GNOME-Provides=filemanager
|
||||||
|
|
|
@ -82,11 +82,9 @@ enum
|
||||||
{
|
{
|
||||||
COMMAND_0, /* unused: 0 is an invalid command */
|
COMMAND_0, /* unused: 0 is an invalid command */
|
||||||
|
|
||||||
COMMAND_RESTART,
|
|
||||||
COMMAND_START_DESKTOP,
|
COMMAND_START_DESKTOP,
|
||||||
COMMAND_STOP_DESKTOP,
|
COMMAND_STOP_DESKTOP,
|
||||||
COMMAND_OPEN_BROWSER,
|
COMMAND_OPEN_BROWSER,
|
||||||
COMMAND_LOAD_SESSION
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Needed for the is_kdesktop_present check */
|
/* Needed for the is_kdesktop_present check */
|
||||||
|
@ -124,9 +122,9 @@ static void drive_connected_callback (GVolumeMonitor *mo
|
||||||
NautilusApplication *application);
|
NautilusApplication *application);
|
||||||
static void drive_listen_for_eject_button (GDrive *drive,
|
static void drive_listen_for_eject_button (GDrive *drive,
|
||||||
NautilusApplication *application);
|
NautilusApplication *application);
|
||||||
static void update_session (gpointer callback_data);
|
|
||||||
static void init_session (void);
|
|
||||||
static gboolean is_kdesktop_present (void);
|
static gboolean is_kdesktop_present (void);
|
||||||
|
static void nautilus_application_load_session (NautilusApplication *application);
|
||||||
|
static char * nautilus_application_get_session_data (void);
|
||||||
|
|
||||||
G_DEFINE_TYPE (NautilusApplication, nautilus_application, G_TYPE_OBJECT);
|
G_DEFINE_TYPE (NautilusApplication, nautilus_application, G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
@ -191,31 +189,6 @@ _unique_message_data_get_geometry_and_uris (UniqueMessageData *message_data,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a hack, because there is no unique_message_data_get()... */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
guchar *data;
|
|
||||||
gint length;
|
|
||||||
|
|
||||||
/* etc... */
|
|
||||||
} UniqueMessageDataInternal;
|
|
||||||
|
|
||||||
static char *
|
|
||||||
_unique_message_data_get_filename (UniqueMessageData *message_data)
|
|
||||||
{
|
|
||||||
UniqueMessageDataInternal *internal;
|
|
||||||
internal = (UniqueMessageDataInternal *)message_data;
|
|
||||||
return g_strndup (internal->data, internal->length);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_unique_message_data_set_filename (UniqueMessageData *message_data,
|
|
||||||
const char *filename)
|
|
||||||
{
|
|
||||||
unique_message_data_set (message_data, filename, strlen (filename));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GList *
|
GList *
|
||||||
nautilus_application_get_window_list (void)
|
nautilus_application_get_window_list (void)
|
||||||
{
|
{
|
||||||
|
@ -275,6 +248,30 @@ automount_all_volumes (NautilusApplication *application)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
smclient_save_state_cb (EggSMClient *client,
|
||||||
|
GKeyFile *state_file,
|
||||||
|
NautilusApplication *application)
|
||||||
|
{
|
||||||
|
char *data;
|
||||||
|
|
||||||
|
data = nautilus_application_get_session_data ();
|
||||||
|
if (data) {
|
||||||
|
g_key_file_set_string (state_file,
|
||||||
|
"Nautilus",
|
||||||
|
"documents",
|
||||||
|
data);
|
||||||
|
}
|
||||||
|
g_free (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
smclient_quit_cb (EggSMClient *client,
|
||||||
|
NautilusApplication *application)
|
||||||
|
{
|
||||||
|
nautilus_main_event_loop_quit (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nautilus_application_init (NautilusApplication *application)
|
nautilus_application_init (NautilusApplication *application)
|
||||||
{
|
{
|
||||||
|
@ -282,13 +279,21 @@ nautilus_application_init (NautilusApplication *application)
|
||||||
application->undo_manager = nautilus_undo_manager_new ();
|
application->undo_manager = nautilus_undo_manager_new ();
|
||||||
|
|
||||||
application->unique_app = unique_app_new_with_commands ("org.gnome.Nautilus", NULL,
|
application->unique_app = unique_app_new_with_commands ("org.gnome.Nautilus", NULL,
|
||||||
"restart", COMMAND_RESTART,
|
|
||||||
"start_desktop", COMMAND_START_DESKTOP,
|
"start_desktop", COMMAND_START_DESKTOP,
|
||||||
"stop_desktop", COMMAND_STOP_DESKTOP,
|
"stop_desktop", COMMAND_STOP_DESKTOP,
|
||||||
"open_browser", COMMAND_OPEN_BROWSER,
|
"open_browser", COMMAND_OPEN_BROWSER,
|
||||||
"load_session", COMMAND_LOAD_SESSION,
|
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
|
||||||
|
application->smclient = egg_sm_client_get ();
|
||||||
|
g_signal_connect (application->smclient, "save_state",
|
||||||
|
G_CALLBACK (smclient_save_state_cb),
|
||||||
|
application);
|
||||||
|
g_signal_connect (application->smclient, "quit",
|
||||||
|
G_CALLBACK (smclient_quit_cb),
|
||||||
|
application);
|
||||||
|
/* TODO: Should connect to quit_requested and block logout on active transfer? */
|
||||||
|
|
||||||
/* register views */
|
/* register views */
|
||||||
fm_icon_view_register ();
|
fm_icon_view_register ();
|
||||||
fm_desktop_icon_view_register ();
|
fm_desktop_icon_view_register ();
|
||||||
|
@ -326,6 +331,7 @@ nautilus_application_finalize (GObject *object)
|
||||||
nautilus_bookmarks_exiting ();
|
nautilus_bookmarks_exiting ();
|
||||||
|
|
||||||
g_object_unref (application->undo_manager);
|
g_object_unref (application->undo_manager);
|
||||||
|
g_object_unref (application->smclient);
|
||||||
|
|
||||||
if (application->volume_monitor) {
|
if (application->volume_monitor) {
|
||||||
g_object_unref (application->volume_monitor);
|
g_object_unref (application->volume_monitor);
|
||||||
|
@ -627,7 +633,6 @@ message_received_cb (UniqueApp *unique_app,
|
||||||
{
|
{
|
||||||
NautilusApplication *application;
|
NautilusApplication *application;
|
||||||
UniqueResponse res;
|
UniqueResponse res;
|
||||||
char *filename;
|
|
||||||
char **uris;
|
char **uris;
|
||||||
char *geometry;
|
char *geometry;
|
||||||
|
|
||||||
|
@ -639,16 +644,6 @@ message_received_cb (UniqueApp *unique_app,
|
||||||
res = UNIQUE_RESPONSE_OK;
|
res = UNIQUE_RESPONSE_OK;
|
||||||
nautilus_main_event_loop_quit (TRUE);
|
nautilus_main_event_loop_quit (TRUE);
|
||||||
|
|
||||||
break;
|
|
||||||
case COMMAND_RESTART:
|
|
||||||
filename = nautilus_application_save_session_to_file ();
|
|
||||||
if (filename != NULL) {
|
|
||||||
nautilus_main_event_loop_quit (TRUE);
|
|
||||||
g_setenv ("_NAUTILUS_RESTART_SESSION_FILENAME", filename, 1);
|
|
||||||
g_free (filename);
|
|
||||||
} else {
|
|
||||||
g_message ("Could not save session. Not restarting.");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case UNIQUE_OPEN:
|
case UNIQUE_OPEN:
|
||||||
case COMMAND_OPEN_BROWSER:
|
case COMMAND_OPEN_BROWSER:
|
||||||
|
@ -667,11 +662,6 @@ message_received_cb (UniqueApp *unique_app,
|
||||||
case COMMAND_STOP_DESKTOP:
|
case COMMAND_STOP_DESKTOP:
|
||||||
nautilus_application_close_desktop ();
|
nautilus_application_close_desktop ();
|
||||||
break;
|
break;
|
||||||
case COMMAND_LOAD_SESSION:
|
|
||||||
filename = _unique_message_data_get_filename (message);
|
|
||||||
nautilus_application_load_session (application, filename);
|
|
||||||
g_free (filename);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
res = UNIQUE_RESPONSE_PASSTHROUGH;
|
res = UNIQUE_RESPONSE_PASSTHROUGH;
|
||||||
break;
|
break;
|
||||||
|
@ -683,12 +673,10 @@ message_received_cb (UniqueApp *unique_app,
|
||||||
void
|
void
|
||||||
nautilus_application_startup (NautilusApplication *application,
|
nautilus_application_startup (NautilusApplication *application,
|
||||||
gboolean kill_shell,
|
gboolean kill_shell,
|
||||||
gboolean restart_shell,
|
|
||||||
gboolean no_default_window,
|
gboolean no_default_window,
|
||||||
gboolean no_desktop,
|
gboolean no_desktop,
|
||||||
gboolean browser_window,
|
gboolean browser_window,
|
||||||
const char *geometry,
|
const char *geometry,
|
||||||
const char *session_to_load,
|
|
||||||
char **urls)
|
char **urls)
|
||||||
{
|
{
|
||||||
UniqueMessageData *message;
|
UniqueMessageData *message;
|
||||||
|
@ -707,12 +695,6 @@ nautilus_application_startup (NautilusApplication *application,
|
||||||
unique_app_send_message (application->unique_app,
|
unique_app_send_message (application->unique_app,
|
||||||
UNIQUE_CLOSE, NULL);
|
UNIQUE_CLOSE, NULL);
|
||||||
|
|
||||||
}
|
|
||||||
} else if (restart_shell) {
|
|
||||||
if (unique_app_is_running (application->unique_app)) {
|
|
||||||
unique_app_send_message (application->unique_app,
|
|
||||||
COMMAND_RESTART, NULL);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* If KDE desktop is running, then force no_desktop */
|
/* If KDE desktop is running, then force no_desktop */
|
||||||
|
@ -749,10 +731,6 @@ nautilus_application_startup (NautilusApplication *application,
|
||||||
|
|
||||||
/* Create the other windows. */
|
/* Create the other windows. */
|
||||||
if (urls != NULL || !no_default_window) {
|
if (urls != NULL || !no_default_window) {
|
||||||
if (urls == NULL) {
|
|
||||||
g_assert (session_to_load == NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unique_app_is_running (application->unique_app)) {
|
if (unique_app_is_running (application->unique_app)) {
|
||||||
message = unique_message_data_new ();
|
message = unique_message_data_new ();
|
||||||
_unique_message_data_set_geometry_and_uris (message, geometry, urls);
|
_unique_message_data_set_geometry_and_uris (message, geometry, urls);
|
||||||
|
@ -772,20 +750,8 @@ nautilus_application_startup (NautilusApplication *application,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session_to_load != NULL) {
|
/* Load session info if availible */
|
||||||
if (unique_app_is_running (application->unique_app)) {
|
nautilus_application_load_session (application);
|
||||||
message = unique_message_data_new ();
|
|
||||||
_unique_message_data_set_filename (message, session_to_load);
|
|
||||||
unique_app_send_message (application->unique_app,
|
|
||||||
COMMAND_LOAD_SESSION, message);
|
|
||||||
unique_message_data_free (message);
|
|
||||||
} else {
|
|
||||||
nautilus_application_load_session (application, session_to_load);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add ourselves to the session */
|
|
||||||
init_session ();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -909,9 +875,6 @@ nautilus_application_open_desktop (NautilusApplication *application)
|
||||||
{
|
{
|
||||||
if (nautilus_application_desktop_windows == NULL) {
|
if (nautilus_application_desktop_windows == NULL) {
|
||||||
nautilus_application_create_desktop_windows (application);
|
nautilus_application_create_desktop_windows (application);
|
||||||
|
|
||||||
/* Make sure we update the session when the desktop is created */
|
|
||||||
update_session (gnome_master_client ());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -923,9 +886,6 @@ nautilus_application_close_desktop (void)
|
||||||
(GFunc) gtk_widget_destroy, NULL);
|
(GFunc) gtk_widget_destroy, NULL);
|
||||||
g_list_free (nautilus_application_desktop_windows);
|
g_list_free (nautilus_application_desktop_windows);
|
||||||
nautilus_application_desktop_windows = NULL;
|
nautilus_application_desktop_windows = NULL;
|
||||||
|
|
||||||
/* Make sure we update the session when the desktop goes away */
|
|
||||||
update_session (gnome_master_client ());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1524,12 +1484,6 @@ mount_removed_callback (GVolumeMonitor *monitor,
|
||||||
g_list_free (close_list);
|
g_list_free (close_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
removed_from_session (GnomeClient *client, gpointer data)
|
|
||||||
{
|
|
||||||
nautilus_main_event_loop_quit (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
icon_to_string (GIcon *icon)
|
icon_to_string (GIcon *icon)
|
||||||
{
|
{
|
||||||
|
@ -1569,16 +1523,16 @@ icon_from_string (const char *string)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
static char *
|
||||||
nautilus_application_save_session_to_file (void)
|
nautilus_application_get_session_data (void)
|
||||||
{
|
{
|
||||||
xmlDocPtr doc;
|
xmlDocPtr doc;
|
||||||
xmlNodePtr root_node, history_node;
|
xmlNodePtr root_node, history_node;
|
||||||
GList *l;
|
GList *l;
|
||||||
char *dir, *filename;
|
char *data;
|
||||||
unsigned n_processed;
|
unsigned n_processed;
|
||||||
int fd;
|
|
||||||
xmlSaveCtxtPtr ctx;
|
xmlSaveCtxtPtr ctx;
|
||||||
|
xmlBufferPtr buffer;
|
||||||
|
|
||||||
doc = xmlNewDoc ("1.0");
|
doc = xmlNewDoc ("1.0");
|
||||||
|
|
||||||
|
@ -1683,296 +1637,223 @@ nautilus_application_save_session_to_file (void)
|
||||||
g_list_free (slots);
|
g_list_free (slots);
|
||||||
}
|
}
|
||||||
|
|
||||||
dir = nautilus_get_user_directory ();
|
buffer = xmlBufferCreate ();
|
||||||
filename = g_build_filename (dir, "saved-session-XXXXXX", NULL);
|
|
||||||
g_free (dir);
|
|
||||||
|
|
||||||
fd = g_mkstemp (filename);
|
|
||||||
if (fd < 0) {
|
|
||||||
g_message ("failed to open session file %s", filename);
|
|
||||||
g_free (filename);
|
|
||||||
filename = NULL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlIndentTreeOutput = 1;
|
xmlIndentTreeOutput = 1;
|
||||||
ctx = xmlSaveToFd (fd, NULL, XML_SAVE_FORMAT);
|
ctx = xmlSaveToBuffer (buffer, "UTF-8", XML_SAVE_FORMAT);
|
||||||
if (xmlSaveDoc (ctx, doc) < 0 ||
|
if (xmlSaveDoc (ctx, doc) < 0 ||
|
||||||
xmlSaveFlush (ctx) < 0) {
|
xmlSaveFlush (ctx) < 0) {
|
||||||
g_message ("failed to save session to %s", filename);
|
g_message ("failed to save session");
|
||||||
g_free (filename);
|
|
||||||
filename = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlSaveClose(ctx);
|
xmlSaveClose(ctx);
|
||||||
close (fd);
|
data = g_strndup (buffer->content, buffer->use);
|
||||||
|
xmlBufferFree (buffer);
|
||||||
|
|
||||||
out:
|
|
||||||
xmlFreeDoc (doc);
|
xmlFreeDoc (doc);
|
||||||
|
|
||||||
return filename;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nautilus_application_load_session (NautilusApplication *application,
|
nautilus_application_load_session (NautilusApplication *application)
|
||||||
const char *filename)
|
|
||||||
{
|
{
|
||||||
xmlDocPtr doc;
|
xmlDocPtr doc;
|
||||||
gboolean bail;
|
gboolean bail;
|
||||||
|
xmlNodePtr root_node;
|
||||||
|
GKeyFile *state_file;
|
||||||
|
char *data;
|
||||||
|
|
||||||
g_assert (filename != NULL);
|
if (!egg_sm_client_is_resumed (application->smclient)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state_file = egg_sm_client_get_state_file (application->smclient);
|
||||||
|
if (!state_file) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = g_key_file_get_string (state_file,
|
||||||
|
"Nautilus",
|
||||||
|
"sessiondata",
|
||||||
|
NULL);
|
||||||
|
if (data == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bail = TRUE;
|
bail = TRUE;
|
||||||
|
|
||||||
if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
|
doc = xmlReadMemory (data, strlen (data), NULL, "UTF-8", 0);
|
||||||
xmlNodePtr root_node;
|
if (doc != NULL && (root_node = xmlDocGetRootElement (doc)) != NULL) {
|
||||||
|
xmlNodePtr node;
|
||||||
|
|
||||||
doc = xmlReadFile (filename, NULL, 0);
|
bail = FALSE;
|
||||||
if (doc != NULL && (root_node = xmlDocGetRootElement (doc)) != NULL) {
|
|
||||||
xmlNodePtr node;
|
|
||||||
|
|
||||||
bail = FALSE;
|
for (node = root_node->children; node != NULL; node = node->next) {
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
if (!strcmp (node->name, "text")) {
|
emit_change = FALSE;
|
||||||
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")) {
|
||||||
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 = icon_from_string (icon_str);
|
|
||||||
}
|
|
||||||
location = g_file_new_for_uri (uri);
|
|
||||||
|
|
||||||
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 {
|
|
||||||
g_message ("unexpected bookmark node %s while parsing %s", bookmark_node->name, filename);
|
|
||||||
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) {
|
|
||||||
g_message ("empty type node while parsing %s", filename);
|
|
||||||
bail = TRUE;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
} else if (!strcmp (bookmark_node->name, "bookmark")) {
|
||||||
|
xmlChar *name, *icon_str, *uri;
|
||||||
|
gboolean has_custom_name;
|
||||||
|
GIcon *icon;
|
||||||
|
GFile *location;
|
||||||
|
|
||||||
location_uri = xmlGetProp (node, "location");
|
uri = xmlGetProp (bookmark_node, "uri");
|
||||||
if (location_uri == NULL) {
|
name = xmlGetProp (bookmark_node, "name");
|
||||||
g_message ("empty location node while parsing %s", filename);
|
has_custom_name = xmlHasProp (bookmark_node, "has_custom_name") ? TRUE : FALSE;
|
||||||
bail = TRUE;
|
icon_str = xmlGetProp (bookmark_node, "icon");
|
||||||
xmlFree (type);
|
icon = NULL;
|
||||||
continue;
|
if (icon_str) {
|
||||||
}
|
icon = icon_from_string (icon_str);
|
||||||
|
|
||||||
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_WINDOW_MIN_WIDTH,
|
|
||||||
NAUTILUS_WINDOW_MIN_HEIGHT,
|
|
||||||
FALSE);
|
|
||||||
}
|
}
|
||||||
xmlFree (geometry);
|
location = g_file_new_for_uri (uri);
|
||||||
|
|
||||||
if (xmlHasProp (node, "maximized")) {
|
emit_change |= nautilus_add_to_history_list_no_notify (location, name, has_custom_name, icon);
|
||||||
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_slot;
|
|
||||||
} else {
|
|
||||||
slot = nautilus_window_open_slot (window, NAUTILUS_WINDOW_OPEN_SLOT_APPEND);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (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_slot, location, FALSE);
|
|
||||||
g_object_unref (location);
|
|
||||||
}
|
|
||||||
} else if (!strcmp (type, "spatial")) {
|
|
||||||
location = g_file_new_for_uri (location_uri);
|
|
||||||
window = nautilus_application_present_spatial_window (application, NULL, NULL, location, gdk_screen_get_default ());
|
|
||||||
g_object_unref (location);
|
g_object_unref (location);
|
||||||
} else {
|
|
||||||
g_message ("unknown window type \"%s\" while parsing %s", type, filename);
|
|
||||||
bail = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlFree (type);
|
if (icon) {
|
||||||
xmlFree (location_uri);
|
g_object_unref (icon);
|
||||||
} else {
|
}
|
||||||
g_message ("unexpected node %s while parsing %s", node->name, filename);
|
xmlFree (name);
|
||||||
|
xmlFree (uri);
|
||||||
|
xmlFree (icon_str);
|
||||||
|
} else {
|
||||||
|
g_message ("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) {
|
||||||
|
g_message ("empty type node while parsing session data");
|
||||||
bail = TRUE;
|
bail = TRUE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location_uri = xmlGetProp (node, "location");
|
||||||
|
if (location_uri == NULL) {
|
||||||
|
g_message ("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_WINDOW_MIN_WIDTH,
|
||||||
|
NAUTILUS_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_slot;
|
||||||
|
} else {
|
||||||
|
slot = nautilus_window_open_slot (window, NAUTILUS_WINDOW_OPEN_SLOT_APPEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (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_slot, location, FALSE);
|
||||||
|
g_object_unref (location);
|
||||||
|
}
|
||||||
|
} else if (!strcmp (type, "spatial")) {
|
||||||
|
location = g_file_new_for_uri (location_uri);
|
||||||
|
window = nautilus_application_present_spatial_window (application, NULL, NULL, location, gdk_screen_get_default ());
|
||||||
|
g_object_unref (location);
|
||||||
|
} else {
|
||||||
|
g_message ("unknown window type \"%s\" while parsing session data", type);
|
||||||
|
bail = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlFree (type);
|
||||||
|
xmlFree (location_uri);
|
||||||
|
} else {
|
||||||
|
g_message ("unexpected node %s while parsing session data", node->name);
|
||||||
|
bail = TRUE;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doc != NULL) {
|
|
||||||
xmlFreeDoc (doc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (doc != NULL) {
|
||||||
|
xmlFreeDoc (doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (data);
|
||||||
|
|
||||||
if (bail) {
|
if (bail) {
|
||||||
g_message ("failed to load session from %s", filename);
|
g_message ("failed to load session");
|
||||||
} else {
|
|
||||||
struct stat buf;
|
|
||||||
|
|
||||||
/* only remove file if it is regular, user-owned and the user has write access. */
|
|
||||||
|
|
||||||
if (g_stat (filename, &buf) == 0 &&
|
|
||||||
S_ISREG (buf.st_mode) &&
|
|
||||||
(buf.st_mode & S_IWUSR) &&
|
|
||||||
buf.st_uid == geteuid()) {
|
|
||||||
g_remove (filename);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
|
||||||
save_session (GnomeClient *client, gint phase, GnomeSaveStyle save_style, gint shutdown,
|
|
||||||
GnomeInteractStyle interact_style, gint fast, gpointer data)
|
|
||||||
{
|
|
||||||
char *argv[3] = { NULL };
|
|
||||||
|
|
||||||
argv[0] = "nautilus";
|
|
||||||
|
|
||||||
argv[2] = nautilus_application_save_session_to_file ();
|
|
||||||
if (argv[2] != NULL) {
|
|
||||||
argv[1] = "--load-session";
|
|
||||||
}
|
|
||||||
|
|
||||||
gnome_client_set_restart_command (client,
|
|
||||||
G_N_ELEMENTS (argv),
|
|
||||||
argv);
|
|
||||||
|
|
||||||
if (argv[2] != NULL) {
|
|
||||||
g_free (argv[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
set_session_restart (GnomeClient *client, gboolean restart)
|
|
||||||
{
|
|
||||||
gnome_client_set_priority (client, 40);
|
|
||||||
|
|
||||||
if (restart && g_getenv ("NAUTILUS_DEBUG") == NULL) {
|
|
||||||
/* Don't respawn in debug mode */
|
|
||||||
gnome_client_set_restart_style (client, GNOME_RESTART_IMMEDIATELY);
|
|
||||||
} else {
|
|
||||||
gnome_client_set_restart_style (client, GNOME_RESTART_IF_RUNNING);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
update_session (gpointer callback_data)
|
|
||||||
{
|
|
||||||
set_session_restart (callback_data,
|
|
||||||
/* Only ever add ourselves to the session
|
|
||||||
* if we have a desktop window. Prevents the
|
|
||||||
* session thrashing that's seen otherwise
|
|
||||||
*/
|
|
||||||
nautilus_application_desktop_windows != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
init_session (void)
|
|
||||||
{
|
|
||||||
GnomeClient *client;
|
|
||||||
|
|
||||||
client = gnome_master_client ();
|
|
||||||
|
|
||||||
g_signal_connect (client, "save_yourself",
|
|
||||||
G_CALLBACK (save_session), NULL);
|
|
||||||
|
|
||||||
g_signal_connect (client, "die",
|
|
||||||
G_CALLBACK (removed_from_session), NULL);
|
|
||||||
|
|
||||||
update_session (client);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef UGLY_HACK_TO_DETECT_KDE
|
#ifdef UGLY_HACK_TO_DETECT_KDE
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <unique/unique.h>
|
#include <unique/unique.h>
|
||||||
|
#include <libegg/eggsmclient.h>
|
||||||
#include <libnautilus-private/nautilus-undo-manager.h>
|
#include <libnautilus-private/nautilus-undo-manager.h>
|
||||||
|
|
||||||
#define NAUTILUS_DESKTOP_ICON_VIEW_IID "OAFIID:Nautilus_File_Manager_Desktop_Icon_View"
|
#define NAUTILUS_DESKTOP_ICON_VIEW_IID "OAFIID:Nautilus_File_Manager_Desktop_Icon_View"
|
||||||
|
@ -55,6 +56,7 @@ typedef struct NautilusShell NautilusShell;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GObject parent;
|
GObject parent;
|
||||||
UniqueApp *unique_app;
|
UniqueApp *unique_app;
|
||||||
|
EggSMClient *smclient;
|
||||||
NautilusUndoManager *undo_manager;
|
NautilusUndoManager *undo_manager;
|
||||||
GVolumeMonitor *volume_monitor;
|
GVolumeMonitor *volume_monitor;
|
||||||
unsigned int automount_idle_id;
|
unsigned int automount_idle_id;
|
||||||
|
@ -68,12 +70,10 @@ GType nautilus_application_get_type (void);
|
||||||
NautilusApplication *nautilus_application_new (void);
|
NautilusApplication *nautilus_application_new (void);
|
||||||
void nautilus_application_startup (NautilusApplication *application,
|
void nautilus_application_startup (NautilusApplication *application,
|
||||||
gboolean kill_shell,
|
gboolean kill_shell,
|
||||||
gboolean restart_shell,
|
|
||||||
gboolean no_default_window,
|
gboolean no_default_window,
|
||||||
gboolean no_desktop,
|
gboolean no_desktop,
|
||||||
gboolean browser_window,
|
gboolean browser_window,
|
||||||
const char *default_geometry,
|
const char *default_geometry,
|
||||||
const char *session_to_load,
|
|
||||||
char **urls);
|
char **urls);
|
||||||
GList * nautilus_application_get_window_list (void);
|
GList * nautilus_application_get_window_list (void);
|
||||||
GList * nautilus_application_get_spatial_window_list (void);
|
GList * nautilus_application_get_spatial_window_list (void);
|
||||||
|
@ -100,7 +100,4 @@ void nautilus_application_close_parent_windows (NautilusSpat
|
||||||
void nautilus_application_close_all_spatial_windows (void);
|
void nautilus_application_close_all_spatial_windows (void);
|
||||||
void nautilus_application_open_desktop (NautilusApplication *application);
|
void nautilus_application_open_desktop (NautilusApplication *application);
|
||||||
void nautilus_application_close_desktop (void);
|
void nautilus_application_close_desktop (void);
|
||||||
void nautilus_application_load_session (NautilusApplication *application,
|
|
||||||
const char *filename);
|
|
||||||
char * nautilus_application_save_session_to_file (void);
|
|
||||||
#endif /* NAUTILUS_APPLICATION_H */
|
#endif /* NAUTILUS_APPLICATION_H */
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
#include <eel/eel-debug.h>
|
#include <eel/eel-debug.h>
|
||||||
#include <eel/eel-glib-extensions.h>
|
#include <eel/eel-glib-extensions.h>
|
||||||
#include <eel/eel-self-checks.h>
|
#include <eel/eel-self-checks.h>
|
||||||
|
#include <libegg/eggsmclient.h>
|
||||||
|
#include <libegg/eggdesktopfile.h>
|
||||||
#include <gdk/gdkx.h>
|
#include <gdk/gdkx.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
@ -130,8 +132,9 @@ nautilus_main_event_loop_quit (gboolean explicit)
|
||||||
{
|
{
|
||||||
if (explicit) {
|
if (explicit) {
|
||||||
/* Explicit --quit, make sure we don't restart */
|
/* Explicit --quit, make sure we don't restart */
|
||||||
gnome_client_set_restart_style (gnome_master_client (),
|
/* TODO: With the old session we needed to set restart
|
||||||
GNOME_RESTART_IF_RUNNING);
|
style to GNOME_RESTART_IF_RUNNING here, but i don't think we need
|
||||||
|
that now since gnome-session doesn't restart apps except on startup. */
|
||||||
}
|
}
|
||||||
while (event_loop_registrants != NULL) {
|
while (event_loop_registrants != NULL) {
|
||||||
gtk_object_destroy (event_loop_registrants->data);
|
gtk_object_destroy (event_loop_registrants->data);
|
||||||
|
@ -302,26 +305,22 @@ int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
gboolean kill_shell;
|
gboolean kill_shell;
|
||||||
gboolean restart_shell;
|
|
||||||
gboolean no_default_window;
|
gboolean no_default_window;
|
||||||
gboolean browser_window;
|
gboolean browser_window;
|
||||||
gboolean no_desktop;
|
gboolean no_desktop;
|
||||||
|
gboolean version;
|
||||||
gboolean autostart_mode;
|
gboolean autostart_mode;
|
||||||
gboolean has_sm_argv;
|
|
||||||
const char *autostart_id;
|
const char *autostart_id;
|
||||||
char *session_to_load;
|
|
||||||
gchar *geometry;
|
gchar *geometry;
|
||||||
const gchar **remaining;
|
const gchar **remaining;
|
||||||
char **p;
|
|
||||||
gboolean perform_self_check;
|
gboolean perform_self_check;
|
||||||
GOptionContext *context;
|
|
||||||
NautilusApplication *application;
|
NautilusApplication *application;
|
||||||
char **argv_copy;
|
GOptionContext *context;
|
||||||
GnomeProgram *program;
|
|
||||||
GFile *file;
|
GFile *file;
|
||||||
char *uri;
|
char *uri;
|
||||||
char **uris;
|
char **uris;
|
||||||
GPtrArray *uris_array;
|
GPtrArray *uris_array;
|
||||||
|
GError *error;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
const GOptionEntry options[] = {
|
const GOptionEntry options[] = {
|
||||||
|
@ -329,6 +328,8 @@ main (int argc, char *argv[])
|
||||||
{ "check", 'c', 0, G_OPTION_ARG_NONE, &perform_self_check,
|
{ "check", 'c', 0, G_OPTION_ARG_NONE, &perform_self_check,
|
||||||
N_("Perform a quick set of self-check tests."), NULL },
|
N_("Perform a quick set of self-check tests."), NULL },
|
||||||
#endif
|
#endif
|
||||||
|
{ "version", '\0', 0, G_OPTION_ARG_NONE, &version,
|
||||||
|
N_("Show the version of the progam."), NULL },
|
||||||
{ "geometry", 'g', 0, G_OPTION_ARG_STRING, &geometry,
|
{ "geometry", 'g', 0, G_OPTION_ARG_STRING, &geometry,
|
||||||
N_("Create the initial window with the given geometry."), N_("GEOMETRY") },
|
N_("Create the initial window with the given geometry."), N_("GEOMETRY") },
|
||||||
{ "no-default-window", 'n', 0, G_OPTION_ARG_NONE, &no_default_window,
|
{ "no-default-window", 'n', 0, G_OPTION_ARG_NONE, &no_default_window,
|
||||||
|
@ -339,20 +340,13 @@ main (int argc, char *argv[])
|
||||||
N_("open a browser window."), NULL },
|
N_("open a browser window."), NULL },
|
||||||
{ "quit", 'q', 0, G_OPTION_ARG_NONE, &kill_shell,
|
{ "quit", 'q', 0, G_OPTION_ARG_NONE, &kill_shell,
|
||||||
N_("Quit Nautilus."), NULL },
|
N_("Quit Nautilus."), NULL },
|
||||||
{ "restart", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &restart_shell,
|
|
||||||
N_("Restart Nautilus."), NULL },
|
|
||||||
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining, NULL, N_("[URI...]") },
|
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining, NULL, N_("[URI...]") },
|
||||||
{ "load-session", 'l', 0, G_OPTION_ARG_STRING, &session_to_load,
|
|
||||||
/* Translators: --no-default-window is a nautilus command line parameter, don't modify it. */
|
|
||||||
N_("Load a saved session from the specified file. Implies \"--no-default-window\"."), N_("FILENAME") },
|
|
||||||
|
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
g_thread_init (NULL);
|
g_thread_init (NULL);
|
||||||
|
|
||||||
setlocale (LC_ALL, "");
|
|
||||||
|
|
||||||
/* This will be done by gtk+ later, but for now, force it to GNOME */
|
/* This will be done by gtk+ later, but for now, force it to GNOME */
|
||||||
g_desktop_app_info_set_desktop_env ("GNOME");
|
g_desktop_app_info_set_desktop_env ("GNOME");
|
||||||
|
|
||||||
|
@ -372,51 +366,44 @@ main (int argc, char *argv[])
|
||||||
autostart_mode = TRUE;
|
autostart_mode = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* detect whether this is a restart request by the SM */
|
|
||||||
has_sm_argv = FALSE;
|
|
||||||
for (p = argv; p - argv < argc; p++) {
|
|
||||||
if (g_str_has_prefix (*p, "--sm-client-id")) {
|
|
||||||
has_sm_argv = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get parameters. */
|
/* Get parameters. */
|
||||||
remaining = NULL;
|
remaining = NULL;
|
||||||
geometry = NULL;
|
geometry = NULL;
|
||||||
session_to_load = NULL;
|
version = FALSE;
|
||||||
kill_shell = FALSE;
|
kill_shell = FALSE;
|
||||||
no_default_window = FALSE;
|
no_default_window = FALSE;
|
||||||
no_desktop = FALSE;
|
no_desktop = FALSE;
|
||||||
perform_self_check = FALSE;
|
perform_self_check = FALSE;
|
||||||
restart_shell = FALSE;
|
|
||||||
browser_window = FALSE;
|
browser_window = FALSE;
|
||||||
|
|
||||||
|
g_set_prgname ("nautilus");
|
||||||
g_set_application_name (_("File Manager"));
|
g_set_application_name (_("File Manager"));
|
||||||
context = g_option_context_new (_("\n\nBrowse the file system with the file manager"));
|
egg_set_desktop_file (DATADIR "/applications/nautilus.desktop");
|
||||||
|
|
||||||
g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
|
context = g_option_context_new (_("\n\nBrowse the file system with the file manager"));
|
||||||
|
g_option_context_add_main_entries (context, options, NULL);
|
||||||
|
|
||||||
|
g_option_context_add_group (context, gtk_get_option_group (TRUE));
|
||||||
|
g_option_context_add_group (context, egg_sm_client_get_option_group ());
|
||||||
|
|
||||||
|
error = NULL;
|
||||||
|
if (!g_option_context_parse (context, &argc, &argv, &error)) {
|
||||||
|
g_printerr ("Could not parse arguments: %s\n", error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version) {
|
||||||
|
g_print ("GNOME nautilus " PACKAGE_VERSION "\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_EXEMPI
|
#ifdef HAVE_EXEMPI
|
||||||
xmp_init();
|
xmp_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
program = gnome_program_init ("nautilus", VERSION,
|
|
||||||
LIBGNOMEUI_MODULE, argc, argv,
|
|
||||||
GNOME_PROGRAM_STANDARD_PROPERTIES,
|
|
||||||
GNOME_PARAM_GOPTION_CONTEXT, context,
|
|
||||||
GNOME_PARAM_HUMAN_READABLE_NAME, _("Nautilus"),
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
/* We do this after gnome_program_init(), since that function sets up
|
|
||||||
* its own handler for SIGSEGV and others --- we want to chain to those
|
|
||||||
* handlers.
|
|
||||||
*/
|
|
||||||
setup_debug_log ();
|
setup_debug_log ();
|
||||||
|
|
||||||
if (session_to_load != NULL) {
|
|
||||||
no_default_window = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If in autostart mode (aka started by gnome-session), we need to ensure
|
/* If in autostart mode (aka started by gnome-session), we need to ensure
|
||||||
* nautilus starts with the correct options.
|
* nautilus starts with the correct options.
|
||||||
*/
|
*/
|
||||||
|
@ -425,16 +412,13 @@ main (int argc, char *argv[])
|
||||||
no_desktop = FALSE;
|
no_desktop = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set default icon for all nautilus windows */
|
|
||||||
gtk_window_set_default_icon_name (NAUTILUS_ICON_FOLDER);
|
|
||||||
|
|
||||||
if (perform_self_check && remaining != NULL) {
|
if (perform_self_check && remaining != NULL) {
|
||||||
/* translators: %s is an option (e.g. --check) */
|
/* translators: %s is an option (e.g. --check) */
|
||||||
fprintf (stderr, _("nautilus: %s cannot be used with URIs.\n"),
|
fprintf (stderr, _("nautilus: %s cannot be used with URIs.\n"),
|
||||||
"--check");
|
"--check");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
if (perform_self_check && (kill_shell || restart_shell)) {
|
if (perform_self_check && kill_shell) {
|
||||||
fprintf (stderr, _("nautilus: --check cannot be used with other options.\n"));
|
fprintf (stderr, _("nautilus: --check cannot be used with other options.\n"));
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -443,11 +427,6 @@ main (int argc, char *argv[])
|
||||||
"--quit");
|
"--quit");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
if (restart_shell && remaining != NULL) {
|
|
||||||
fprintf (stderr, _("nautilus: %s cannot be used with URIs.\n"),
|
|
||||||
"--restart");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
if (geometry != NULL && remaining != NULL && remaining[0] != NULL && remaining[1] != NULL) {
|
if (geometry != NULL && remaining != NULL && remaining[0] != NULL && remaining[1] != NULL) {
|
||||||
fprintf (stderr, _("nautilus: --geometry cannot be used with more than one URI.\n"));
|
fprintf (stderr, _("nautilus: --geometry cannot be used with more than one URI.\n"));
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
@ -468,11 +447,6 @@ main (int argc, char *argv[])
|
||||||
(NAUTILUS_PREFERENCES_DESKTOP_IS_HOME_DIR, TRUE);
|
(NAUTILUS_PREFERENCES_DESKTOP_IS_HOME_DIR, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_sm_argv && eel_preferences_get_boolean (NAUTILUS_PREFERENCES_SHOW_DESKTOP)) {
|
|
||||||
/* we were restarted by the session manager. Don't show default window */
|
|
||||||
no_default_window = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
application = NULL;
|
application = NULL;
|
||||||
|
|
||||||
/* Do either the self-check or the real work. */
|
/* Do either the self-check or the real work. */
|
||||||
|
@ -509,12 +483,16 @@ main (int argc, char *argv[])
|
||||||
|
|
||||||
/* Run the nautilus application. */
|
/* Run the nautilus application. */
|
||||||
application = nautilus_application_new ();
|
application = nautilus_application_new ();
|
||||||
|
|
||||||
|
if (egg_sm_client_is_resumed (application->smclient)) {
|
||||||
|
no_default_window = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
nautilus_application_startup
|
nautilus_application_startup
|
||||||
(application,
|
(application,
|
||||||
kill_shell, restart_shell, no_default_window, no_desktop,
|
kill_shell, no_default_window, no_desktop,
|
||||||
browser_window,
|
browser_window,
|
||||||
geometry,
|
geometry,
|
||||||
session_to_load,
|
|
||||||
uris);
|
uris);
|
||||||
g_strfreev (uris);
|
g_strfreev (uris);
|
||||||
|
|
||||||
|
@ -531,25 +509,5 @@ main (int argc, char *argv[])
|
||||||
|
|
||||||
eel_debug_shut_down ();
|
eel_debug_shut_down ();
|
||||||
|
|
||||||
/* If told to restart, exec() myself again. This is used when
|
|
||||||
* the program is told to restart with CORBA, for example when
|
|
||||||
* an update takes place.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (g_getenv ("_NAUTILUS_RESTART_SESSION_FILENAME") != NULL) {
|
|
||||||
argv_copy = g_new0 (char *, 4);
|
|
||||||
argv_copy[0] = g_strdup (argv[0]);
|
|
||||||
argv_copy[1] = g_strdup ("--load-session");
|
|
||||||
argv_copy[2] = g_strdup (g_getenv ("_NAUTILUS_RESTART_SESSION_FILENAME"));
|
|
||||||
|
|
||||||
g_unsetenv ("_NAUTILUS_RESTART_SESSION_FILENAME");
|
|
||||||
|
|
||||||
execvp (argv[0], argv_copy);
|
|
||||||
|
|
||||||
g_strfreev (argv_copy);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref (G_OBJECT (program));
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue