Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/shell
diff options
context:
space:
mode:
Diffstat (limited to 'shell')
-rw-r--r--shell/Makefile.am1
-rw-r--r--shell/ev-application.c367
-rw-r--r--shell/ev-application.h9
-rw-r--r--shell/ev-window.c12
-rw-r--r--shell/main.c41
5 files changed, 168 insertions, 262 deletions
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 8d86efe..987d215 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -17,6 +17,7 @@ INCLUDES= \
-I$(top_srcdir)/properties \
-DGNOMELOCALEDIR=\"$(datadir)/locale\" \
-DGNOMEICONDIR=\""$(datadir)/pixmaps"\" \
+ -DBINDIR=\""$(bindir)"\" \
-DLIBEXECDIR=\""$(libexecdir)"\" \
-DEVINCE_COMPILATION \
$(SHELL_CFLAGS) \
diff --git a/shell/ev-application.c b/shell/ev-application.c
index 24ef1e0..0690cdb 100644
--- a/shell/ev-application.c
+++ b/shell/ev-application.c
@@ -20,8 +20,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
-#include <config.h>
+#include <config.h>
#include <stdlib.h>
#include <string.h>
@@ -63,6 +63,9 @@ static void ev_application_save_print_settings (EvApplication *application);
struct _EvApplication {
GObject base_instance;
+ EvWindow *window;
+ gchar *uri;
+
gchar *dot_dir;
gchar *data_dir;
gchar *accel_map_file;
@@ -70,8 +73,7 @@ struct _EvApplication {
#ifdef ENABLE_DBUS
DBusGConnection *connection;
- GHashTable *windows;
- guint doc_counter;
+ EvMediaPlayerKeys *keys;
#endif
EggToolbarsModel *toolbars_model;
@@ -85,10 +87,6 @@ struct _EvApplication {
gchar *filechooser_open_uri;
gchar *filechooser_save_uri;
-#ifdef ENABLE_DBUS
- EvMediaPlayerKeys *keys;
-#endif /* ENABLE_DBUS */
-
GtkPrintSettings *print_settings;
GtkPageSetup *page_setup;
GKeyFile *print_settings_file;
@@ -128,43 +126,12 @@ ev_application_get_instance (void)
return instance;
}
-#if defined (WITH_SMCLIENT)
/* Session */
-static void
-save_session (EvApplication *application,
- GList *windows_list,
- GKeyFile *state_file)
-{
- GList *l;
- gint i;
- const gchar **uri_list;
- const gchar *empty = "empty-window";
-
- uri_list = g_new (const gchar *, g_list_length (windows_list));
- for (l = windows_list, i = 0; l != NULL; l = g_list_next (l), i++) {
- EvWindow *window = EV_WINDOW (l->data);
-
- if (ev_window_is_empty (window))
- uri_list[i] = empty;
- else
- uri_list[i] = ev_window_get_uri (window);
- }
- g_key_file_set_string_list (state_file,
- "Evince",
- "documents",
- (const char **)uri_list,
- i);
- g_free (uri_list);
-}
-
-#endif /* WITH_SMCLIENT */
-
gboolean
-ev_application_load_session (EvApplication *application,
- const gchar **files)
+ev_application_load_session (EvApplication *application)
{
GKeyFile *state_file;
- gchar **uri_list;
+ gchar *uri;
#ifdef WITH_SMCLIENT
if (egg_sm_client_is_resumed (application->smclient)) {
@@ -175,23 +142,15 @@ ev_application_load_session (EvApplication *application,
#endif /* WITH_SMCLIENT */
return FALSE;
- uri_list = g_key_file_get_string_list (state_file,
- "Evince",
- "documents",
- NULL, NULL);
- if (uri_list) {
- gint i;
- GdkScreen *screen = gdk_screen_get_default ();
-
- for (i = 0; uri_list[i]; i++) {
- if (g_ascii_strcasecmp (uri_list[i], "empty-window") == 0)
- ev_application_open_window (application, screen, GDK_CURRENT_TIME);
- else
- ev_application_open_uri_at_dest (application, uri_list[i], screen,
- NULL, 0, NULL, GDK_CURRENT_TIME);
- }
- g_strfreev (uri_list);
- }
+ uri = g_key_file_get_string (state_file, "Evince", "uri", NULL);
+ if (!uri)
+ return FALSE;
+
+ ev_application_open_uri_at_dest (application, uri,
+ gdk_screen_get_default (),
+ NULL, 0, NULL,
+ GDK_CURRENT_TIME);
+ g_free (uri);
g_key_file_free (state_file);
return TRUE;
@@ -204,13 +163,10 @@ smclient_save_state_cb (EggSMClient *client,
GKeyFile *state_file,
EvApplication *application)
{
- GList *windows;
+ if (!application->uri)
+ return;
- windows = ev_application_get_windows (application);
- if (windows) {
- save_session (application, windows, state_file);
- g_list_free (windows);
- }
+ g_key_file_set_string (state_file, "Evince", "uri", application->uri);
}
static void
@@ -219,7 +175,6 @@ smclient_quit_cb (EggSMClient *client,
{
ev_application_shutdown (application);
}
-
#endif /* WITH_SMCLIENT */
static void
@@ -443,108 +398,63 @@ build_args (GdkScreen *screen,
return args;
}
-/**
- * ev_application_open_window:
- * @application: The instance of the application.
- * @timestamp: Current time value.
- *
- * Creates a new window
- */
-void
-ev_application_open_window (EvApplication *application,
- GdkScreen *screen,
- guint32 timestamp)
+static void
+ev_spawn (const char *uri,
+ GdkScreen *screen,
+ EvLinkDest *dest,
+ EvWindowRunMode mode,
+ const gchar *search_string)
{
- GtkWidget *new_window = ev_window_new ();
+ gchar *argv[6];
+ guint arg = 0;
+ gint i;
+ gboolean res;
+ GError *error = NULL;
- if (screen) {
- ev_stock_icons_set_screen (screen);
- gtk_window_set_screen (GTK_WINDOW (new_window), screen);
- }
-
- if (!GTK_WIDGET_REALIZED (new_window))
- gtk_widget_realize (new_window);
-
-#ifdef GDK_WINDOWING_X11
- if (timestamp <= 0)
- timestamp = gdk_x11_get_server_time (GTK_WIDGET (new_window)->window);
- gdk_x11_window_set_user_time (GTK_WIDGET (new_window)->window, timestamp);
+ argv[arg++] = g_build_filename (BINDIR, "evince", NULL);
- gtk_window_present (GTK_WINDOW (new_window));
-#else
- gtk_window_present_with_time (GTK_WINDOW (new_window), timestamp);
-#endif /* GDK_WINDOWING_X11 */
-}
-
-/**
- * ev_application_get_empty_window:
- * @application: The instance of the application.
- * @screen: The screen where the empty window will be search.
- *
- * It does look if there is any empty window in the indicated screen.
- *
- * Returns: The first empty #EvWindow in the passed #GdkScreen or NULL in other
- * case.
- */
-static EvWindow *
-ev_application_get_empty_window (EvApplication *application,
- GdkScreen *screen)
-{
- EvWindow *empty_window = NULL;
- GList *windows = ev_application_get_windows (application);
- GList *l;
-
- for (l = windows; l != NULL; l = l->next) {
- EvWindow *window = EV_WINDOW (l->data);
+ /* Page label */
+ if (dest) {
+ const gchar *page_label;
- if (ev_window_is_empty (window) &&
- gtk_window_get_screen (GTK_WINDOW (window)) == screen) {
- empty_window = window;
- break;
- }
+ page_label = ev_link_dest_get_page_label (dest);
+ if (page_label)
+ argv[arg++] = g_strdup_printf ("--page-label=%s", page_label);
+ else
+ argv[arg++] = g_strdup_printf ("--page-label=%d",
+ ev_link_dest_get_page (dest));
}
- g_list_free (windows);
-
- return empty_window;
-}
-
-/**
- * ev_application_get_uri_window:
- * @application: The instance of the application.
- * @uri: The uri to be opened.
- *
- * It looks in the list of the windows for the one with the document represented
- * by the passed uri on it. If the window is empty or the document isn't present
- * on any window, it will return NULL.
- *
- * Returns: The #EvWindow where the document represented by the passed uri is
- * shown, NULL in other case.
- */
-static EvWindow *
-ev_application_get_uri_window (EvApplication *application, const char *uri)
-{
- EvWindow *uri_window = NULL;
- GList *windows = gtk_window_list_toplevels ();
- GList *l;
+ /* Find string */
+ if (search_string) {
+ argv[arg++] = g_strdup_printf ("--find=%s", search_string);
+ }
- g_return_val_if_fail (uri != NULL, NULL);
+ /* Mode */
+ switch (mode) {
+ case EV_WINDOW_MODE_FULLSCREEN:
+ argv[arg++] = g_strdup ("-f");
+ break;
+ case EV_WINDOW_MODE_PRESENTATION:
+ argv[arg++] = g_strdup ("-s");
+ break;
+ default:
+ break;
+ }
- for (l = windows; l != NULL; l = l->next) {
- if (EV_IS_WINDOW (l->data)) {
- EvWindow *window = EV_WINDOW (l->data);
- const char *window_uri = ev_window_get_uri (window);
+ argv[arg++] = (gchar *)uri;
+ argv[arg] = NULL;
- if (window_uri && strcmp (window_uri, uri) == 0 && !ev_window_is_empty (window)) {
- uri_window = window;
- break;
- }
- }
+ res = gdk_spawn_on_screen (screen, NULL /* wd */, argv, NULL /* env */,
+ 0, NULL, NULL, NULL, &error);
+ if (!res) {
+ g_warning ("Error launching evince %s: %s\n", uri, error->message);
+ g_error_free (error);
}
- g_list_free (windows);
-
- return uri_window;
+ for (i = 0; i < arg - 1; i++) {
+ g_free (argv[i]);
+ }
}
#ifdef ENABLE_DBUS
@@ -635,28 +545,19 @@ ev_application_unregister_uri (EvApplication *application,
g_object_unref (proxy);
}
-
-static void
-ev_application_window_destroyed (EvApplication *application,
- EvWindow *ev_window)
-{
- gchar *uri = g_hash_table_lookup (application->windows, ev_window);
-
- ev_application_unregister_uri (application, uri);
- g_hash_table_remove (application->windows, ev_window);
-}
#endif /* ENABLE_DBUS */
static void
ev_application_open_uri_in_window (EvApplication *application,
const char *uri,
- EvWindow *ev_window,
GdkScreen *screen,
EvLinkDest *dest,
EvWindowRunMode mode,
const gchar *search_string,
guint timestamp)
{
+ EvWindow *ev_window = application->window;
+
if (screen) {
ev_stock_icons_set_screen (screen);
gtk_window_set_screen (GTK_WINDOW (ev_window), screen);
@@ -666,16 +567,6 @@ ev_application_open_uri_in_window (EvApplication *application,
we can restore window size without flickering */
ev_window_open_uri (ev_window, uri, dest, mode, search_string);
-#ifdef ENABLE_DBUS
- if (application->windows != NULL &&
- !g_hash_table_lookup (application->windows, ev_window)) {
- g_hash_table_insert (application->windows, ev_window, g_strdup (uri));
- g_signal_connect_swapped (ev_window, "destroy",
- G_CALLBACK (ev_application_window_destroyed),
- application);
- }
-#endif
-
if (!GTK_WIDGET_REALIZED (GTK_WIDGET (ev_window)))
gtk_widget_realize (GTK_WIDGET (ev_window));
@@ -712,13 +603,16 @@ ev_application_open_uri_at_dest (EvApplication *application,
const gchar *search_string,
guint timestamp)
{
- EvWindow *ev_window;
-
g_return_if_fail (uri != NULL);
- ev_window = ev_application_get_uri_window (application, uri);
+ if (application->window && !ev_window_is_empty (application->window)) {
+ if (application->uri && strcmp (application->uri, uri) != 0) {
+ /* spawn a new evince process */
+ ev_spawn (uri, screen, dest, mode, search_string);
+ return;
+ }
+ } else {
#ifdef ENABLE_DBUS
- if (!ev_window) {
GHashTable *args = build_args (screen, dest, mode, search_string);
gboolean ret;
@@ -729,23 +623,56 @@ ev_application_open_uri_at_dest (EvApplication *application,
g_hash_table_destroy (args);
if (!ret)
return;
- }
#endif /* ENABLE_DBUS */
- if (ev_window == NULL) {
- ev_window = ev_application_get_empty_window (application, screen);
+ if (!application->window)
+ application->window = EV_WINDOW (ev_window_new ());
}
- if (ev_window == NULL) {
- ev_window = EV_WINDOW (ev_window_new ());
- }
+ application->uri = g_strdup (uri);
- ev_application_open_uri_in_window (application, uri, ev_window,
- screen, dest, mode, search_string,
+ ev_application_open_uri_in_window (application, uri,
+ screen, dest, mode,
+ search_string,
timestamp);
}
/**
+ * ev_application_open_window:
+ * @application: The instance of the application.
+ * @timestamp: Current time value.
+ *
+ * Creates a new window
+ */
+void
+ev_application_open_window (EvApplication *application,
+ GdkScreen *screen,
+ guint32 timestamp)
+{
+ GtkWidget *new_window = ev_window_new ();
+
+ application->window = EV_WINDOW (new_window);
+
+ if (screen) {
+ ev_stock_icons_set_screen (screen);
+ gtk_window_set_screen (GTK_WINDOW (new_window), screen);
+ }
+
+ if (!GTK_WIDGET_REALIZED (new_window))
+ gtk_widget_realize (new_window);
+
+#ifdef GDK_WINDOWING_X11
+ if (timestamp <= 0)
+ timestamp = gdk_x11_get_server_time (new_window->window);
+ gdk_x11_window_set_user_time (new_window->window, timestamp);
+
+ gtk_window_present (GTK_WINDOW (new_window));
+#else
+ gtk_window_present_with_time (GTK_WINDOW (new_window), timestamp);
+#endif /* GDK_WINDOWING_X11 */
+}
+
+/**
* ev_application_open_uri:
* @application: The instance of the application.
* @uri: The uri to be opened
@@ -760,14 +687,22 @@ ev_application_open_uri (EvApplication *application,
guint timestamp,
GError **error)
{
- EvWindow *ev_window;
EvLinkDest *dest = NULL;
EvWindowRunMode mode = EV_WINDOW_MODE_NORMAL;
const gchar *search_string = NULL;
GdkScreen *screen = NULL;
- ev_window = ev_application_get_uri_window (application, uri);
- g_assert (ev_window != NULL);
+ g_assert (application->window != NULL);
+
+ /* FIXME: we don't need uri anymore,
+ * maybe this method should be renamed
+ * as reload, refresh or something like that
+ */
+ if (!application->uri || strcmp (application->uri, uri)) {
+ g_warning ("Invalid uri: %s, expected %s\n",
+ uri, application->uri);
+ return TRUE;
+ }
if (args) {
screen = get_screen_from_args (args);
@@ -776,8 +711,9 @@ ev_application_open_uri (EvApplication *application,
search_string = get_find_string_from_args (args);
}
- ev_application_open_uri_in_window (application, uri, ev_window,
- screen, dest, mode, search_string,
+ ev_application_open_uri_in_window (application, uri,
+ screen, dest, mode,
+ search_string,
timestamp);
if (dest)
@@ -804,12 +740,14 @@ ev_application_open_uri_list (EvApplication *application,
void
ev_application_shutdown (EvApplication *application)
{
+ if (application->uri) {
#ifdef ENABLE_DBUS
- if (application->windows) {
- g_hash_table_destroy (application->windows);
- application->windows = NULL;
- }
+ ev_application_unregister_uri (application,
+ application->uri);
#endif
+ g_free (application->uri);
+ application->uri = NULL;
+ }
if (application->accel_map_file) {
gtk_accel_map_save (application->accel_map_file);
@@ -955,10 +893,6 @@ ev_application_init (EvApplication *ev_application)
dbus_g_connection_register_g_object (ev_application->connection,
APPLICATION_DBUS_OBJECT_PATH,
G_OBJECT (ev_application));
- ev_application->windows = g_hash_table_new_full (g_direct_hash,
- g_direct_equal,
- NULL,
- (GDestroyNotify)g_free);
ev_application->scr_saver = totem_scrsaver_new (ev_application->connection);
} else {
g_warning ("Error connection to DBus: %s\n", error->message);
@@ -968,31 +902,16 @@ ev_application_init (EvApplication *ev_application)
#endif /* ENABLE_DBUS */
}
-/**
- * ev_application_get_windows:
- * @application: The instance of the application.
- *
- * It creates a list of the top level windows.
- *
- * Returns: A #GList of the top level windows.
- */
-GList *
-ev_application_get_windows (EvApplication *application)
+gboolean
+ev_application_has_window (EvApplication *application)
{
- GList *l, *toplevels;
- GList *windows = NULL;
-
- toplevels = gtk_window_list_toplevels ();
-
- for (l = toplevels; l != NULL; l = l->next) {
- if (EV_IS_WINDOW (l->data)) {
- windows = g_list_append (windows, l->data);
- }
- }
-
- g_list_free (toplevels);
+ return application->window != NULL;
+}
- return windows;
+const gchar *
+ev_application_get_uri (EvApplication *application)
+{
+ return application->uri;
}
/**
diff --git a/shell/ev-application.h b/shell/ev-application.h
index 20a60bb..b012514 100644
--- a/shell/ev-application.h
+++ b/shell/ev-application.h
@@ -50,11 +50,9 @@ typedef struct _EvApplicationClass EvApplicationClass;
GType ev_application_get_type (void) G_GNUC_CONST;
EvApplication *ev_application_get_instance (void);
-gboolean ev_application_register_service (EvApplication *application);
-void ev_application_shutdown (EvApplication *application);
-gboolean ev_application_load_session (EvApplication *application,
- const gchar **files);
+void ev_application_shutdown (EvApplication *application);
+gboolean ev_application_load_session (EvApplication *application);
void ev_application_open_window (EvApplication *application,
GdkScreen *screen,
guint32 timestamp);
@@ -69,7 +67,8 @@ void ev_application_open_uri_list (EvApplication *application,
GSList *uri_list,
GdkScreen *screen,
guint32 timestamp);
-GList *ev_application_get_windows (EvApplication *application);
+gboolean ev_application_has_window (EvApplication *application);
+const gchar * ev_application_get_uri (EvApplication *application);
GObject *ev_application_get_media_keys (EvApplication *application);
EggToolbarsModel *ev_application_get_toolbars_model (EvApplication *application);
diff --git a/shell/ev-window.c b/shell/ev-window.c
index b4133ad..f4974e3 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -310,6 +310,8 @@ static void ev_window_media_player_key_pressed (EvWindow *windo
gpointer user_data);
static void ev_window_save_print_page_setup (EvWindow *window);
+static guint ev_window_n_copies = 0;
+
G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_WINDOW)
static void
@@ -2129,6 +2131,8 @@ ev_window_open_copy_at_dest (EvWindow *window,
{
EvWindow *new_window = EV_WINDOW (ev_window_new ());
+ ev_window_n_copies++;
+
if (window->priv->metadata)
new_window->priv->metadata = g_object_ref (window->priv->metadata);
ev_window_open_document (new_window,
@@ -4549,14 +4553,12 @@ ev_window_drag_data_received (GtkWidget *widget,
static void
ev_window_finalize (GObject *object)
{
- GList *windows = ev_application_get_windows (EV_APP);
-
- if (windows == NULL) {
+ if (ev_window_n_copies == 0) {
ev_application_shutdown (EV_APP);
} else {
- g_list_free (windows);
+ ev_window_n_copies--;
}
-
+
G_OBJECT_CLASS (ev_window_parent_class)->finalize (object);
}
diff --git a/shell/main.c b/shell/main.c
index 1de87f6..23872ed 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -141,29 +141,17 @@ launch_previewer (void)
return retval;
}
-static gint
-find_window_list (EvWindow *window,
- const gchar *uri)
-{
- return g_ascii_strcasecmp (uri, ev_window_get_uri (window));
-}
-
static void
load_files (const char **files)
{
GdkScreen *screen = gdk_screen_get_default ();
EvWindowRunMode mode = EV_WINDOW_MODE_NORMAL;
- GList *windows;
gint i;
EvLinkDest *global_dest = NULL;
- windows = ev_application_get_windows (EV_APP);
-
if (!files) {
- if (!windows)
+ if (!ev_application_has_window (EV_APP))
ev_application_open_window (EV_APP, screen, GDK_CURRENT_TIME);
- else
- g_list_free (windows);
return;
}
@@ -176,16 +164,18 @@ load_files (const char **files)
mode = EV_WINDOW_MODE_PRESENTATION;
for (i = 0; files[i]; i++) {
- gchar *uri;
- gchar *label;
- GFile *file;
- EvLinkDest *dest = NULL;
+ gchar *uri;
+ gchar *label;
+ GFile *file;
+ EvLinkDest *dest = NULL;
+ const gchar *app_uri;
file = g_file_new_for_commandline_arg (files[i]);
uri = g_file_get_uri (file);
g_object_unref (file);
- if (g_list_find_custom (windows, uri, (GCompareFunc) find_window_list)) {
+ app_uri = ev_application_get_uri (EV_APP);
+ if (app_uri && strcmp (app_uri, uri) == 0) {
g_free (uri);
continue;
}
@@ -207,16 +197,13 @@ load_files (const char **files)
g_object_unref (dest);
g_free (uri);
}
-
- g_list_free (windows);
}
int
main (int argc, char *argv[])
{
GOptionContext *context;
- GList *toplevels;
- GError *error = NULL;
+ GError *error = NULL;
#ifdef G_OS_WIN32
@@ -265,10 +252,10 @@ main (int argc, char *argv[])
g_option_context_add_group (context, gtk_get_option_group (TRUE));
if (!g_option_context_parse (context, &argc, &argv, &error)) {
- g_printerr ("Cannot parse arguments: %s", error->message);
+ g_printerr ("Cannot parse arguments: %s\n", error->message);
g_error_free (error);
g_option_context_free (context);
-
+
return 1;
}
g_option_context_free (context);
@@ -294,11 +281,9 @@ main (int argc, char *argv[])
gtk_window_set_default_icon_name ("evince");
#endif /* WITH_SMCLIENT && GDK_WINDOWING_X11 */
- ev_application_load_session (EV_APP, file_arguments);
+ ev_application_load_session (EV_APP);
load_files (file_arguments);
- toplevels = gtk_window_list_toplevels ();
- if (toplevels) {
- g_list_free (toplevels);
+ if (ev_application_has_window (EV_APP)) {
/* Change directory so we don't prevent unmounting in case the initial cwd
* is on an external device (see bug #575436)
*/