X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=inline;f=shell%2Fev-application.c;h=53d284f1fad805d28f234b1fe91de26edce896e7;hb=e69ef41816684c78b04ee91a5c1a4e8a2b8cebc9;hp=2b4762927818627945823d599e60e067e6f4cdf3;hpb=06001de7e17bdccc2197b9f690269e6f8328e521;p=evince.git diff --git a/shell/ev-application.c b/shell/ev-application.c index 2b476292..53d284f1 100644 --- a/shell/ev-application.c +++ b/shell/ev-application.c @@ -26,8 +26,8 @@ #include "ev-application.h" #include "ev-utils.h" -#include "ev-document-types.h" #include "ev-file-helpers.h" +#include "ev-document-factory.h" #include #include @@ -36,6 +36,7 @@ #include #include #include +#include #include #ifdef ENABLE_DBUS @@ -45,20 +46,22 @@ G_DEFINE_TYPE (EvApplication, ev_application, G_TYPE_OBJECT); -#define EV_APPLICATION_GET_PRIVATE(object) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_APPLICATION, EvApplicationPrivate)) - #define APPLICATION_SERVICE_NAME "org.gnome.evince.ApplicationService" #ifdef ENABLE_DBUS gboolean ev_application_register_service (EvApplication *application) { - DBusGConnection *connection; + static DBusGConnection *connection = NULL; DBusGProxy *driver_proxy; GError *err = NULL; guint request_name_result; + if (connection) { + g_warning ("Service already registered."); + return FALSE; + } + connection = dbus_g_bus_get (DBUS_BUS_STARTER, &err); if (connection == NULL) { g_warning ("Service registration failed."); @@ -74,27 +77,26 @@ ev_application_register_service (EvApplication *application) if (!org_freedesktop_DBus_request_name (driver_proxy, APPLICATION_SERVICE_NAME, - 0, &request_name_result, &err)) { + DBUS_NAME_FLAG_DO_NOT_QUEUE, + &request_name_result, &err)) { g_warning ("Service registration failed."); g_clear_error (&err); } + g_object_unref (driver_proxy); + if (request_name_result == DBUS_REQUEST_NAME_REPLY_EXISTS) { return FALSE; } -#if DBUS_VERSION == 33 - dbus_g_object_class_install_info (G_OBJECT_GET_CLASS (application), - &dbus_glib_ev_application_object_info); -#else dbus_g_object_type_install_info (EV_TYPE_APPLICATION, &dbus_glib_ev_application_object_info); -#endif - dbus_g_connection_register_g_object (connection, "/org/gnome/evince/Evince", G_OBJECT (application)); - + + application->scr_saver = totem_scrsaver_new (connection); + return TRUE; } #endif /* ENABLE_DBUS */ @@ -111,40 +113,195 @@ ev_application_get_instance (void) return instance; } +static void +removed_from_session (GnomeClient *client, EvApplication *application) +{ + ev_application_shutdown (application); +} + +static gint +save_session (GnomeClient *client, gint phase, GnomeSaveStyle save_style, gint shutdown, + GnomeInteractStyle interact_style, gint fast, EvApplication *application) +{ + GList *windows, *l; + char **restart_argv; + int argc = 0, k; + + windows = ev_application_get_windows (application); + restart_argv = g_new (char *, g_list_length (windows) + 1); + restart_argv[argc++] = g_strdup ("evince"); + + for (l = windows; l != NULL; l = l->next) { + EvWindow *window = EV_WINDOW (l->data); + restart_argv[argc++] = g_strdup (ev_window_get_uri (window)); + } + + gnome_client_set_restart_command (client, argc, restart_argv); + + for (k = 0; k < argc; k++) { + g_free (restart_argv[k]); + } + + g_list_free (windows); + g_free (restart_argv); + + return TRUE; +} + +static void +init_session (EvApplication *application) +{ + GnomeClient *client; + + client = gnome_master_client (); + + g_signal_connect (client, "save_yourself", + G_CALLBACK (save_session), application); + g_signal_connect (client, "die", + G_CALLBACK (removed_from_session), application); +} + +static GdkDisplay * +ev_display_open_if_needed (const gchar *name) +{ + GSList *displays; + GSList *l; + GdkDisplay *display = NULL; + + displays = gdk_display_manager_list_displays (gdk_display_manager_get ()); + + for (l = displays; l != NULL; l = l->next) { + const gchar *display_name = gdk_display_get_name ((GdkDisplay *) l->data); + + if (g_ascii_strcasecmp (display_name, name) == 0) { + display = l->data; + break; + } + } + + g_slist_free (displays); + + return display != NULL ? display : gdk_display_open (name); +} + +static GdkScreen * +get_screen_from_args (GHashTable *args) +{ + GValue *value = NULL; + GdkDisplay *display = NULL; + GdkScreen *screen = NULL; + + g_assert (args != NULL); + + value = g_hash_table_lookup (args, "display"); + if (value) { + const gchar *display_name; + + display_name = g_value_get_string (value); + display = ev_display_open_if_needed (display_name); + } + + value = g_hash_table_lookup (args, "screen"); + if (value) { + gint screen_number; + + screen_number = g_value_get_int (value); + screen = gdk_display_get_screen (display, screen_number); + } + + return screen; +} + +static EvWindowRunMode +get_window_run_mode_from_args (GHashTable *args) +{ + EvWindowRunMode mode = EV_WINDOW_MODE_NORMAL; + GValue *value = NULL; + + g_assert (args != NULL); + + value = g_hash_table_lookup (args, "mode"); + if (value) { + mode = g_value_get_uint (value); + } + + return mode; +} + +static EvLinkDest * +get_destination_from_args (GHashTable *args) +{ + EvLinkDest *dest = NULL; + GValue *value = NULL; + + g_assert (args != NULL); + + value = g_hash_table_lookup (args, "page-label"); + if (value) { + const gchar *page_label; + + page_label = g_value_get_string (value); + dest = ev_link_dest_new_page_label (page_label); + } + + return dest; +} + +static gboolean +get_unlink_temp_file_from_args (GHashTable *args) +{ + gboolean unlink_temp_file = FALSE; + GValue *value = NULL; + + g_assert (args != NULL); + + value = g_hash_table_lookup (args, "unlink-temp-file"); + if (value) { + unlink_temp_file = g_value_get_boolean (value); + } + + return unlink_temp_file; +} + gboolean ev_application_open_window (EvApplication *application, + GHashTable *args, guint32 timestamp, GError **error) { GtkWidget *new_window = ev_window_new (); + GdkScreen *screen = NULL; + if (args) { + screen = get_screen_from_args (args); + } + + if (screen) { + gtk_window_set_screen (GTK_WINDOW (new_window), screen); + } + gtk_widget_show (new_window); -#ifdef HAVE_GTK_WINDOW_PRESENT_WITH_TIME gtk_window_present_with_time (GTK_WINDOW (new_window), timestamp); -#else - gtk_window_present (GTK_WINDOW (new_window)); -#endif - return TRUE; } static EvWindow * -ev_application_get_empty_window (EvApplication *application) +ev_application_get_empty_window (EvApplication *application, + GdkScreen *screen) { EvWindow *empty_window = NULL; - GList *windows = gtk_window_list_toplevels (); + GList *windows = ev_application_get_windows (application); GList *l; for (l = windows; l != NULL; l = l->next) { - if (EV_IS_WINDOW (l->data)) { - EvWindow *window = EV_WINDOW (l->data); + EvWindow *window = EV_WINDOW (l->data); - if (ev_window_is_empty (window)) { - empty_window = window; - break; - } + if (ev_window_is_empty (window) && + gtk_window_get_screen (GTK_WINDOW (window)) == screen) { + empty_window = window; + break; } } @@ -167,7 +324,7 @@ ev_application_get_uri_window (EvApplication *application, const char *uri) EvWindow *window = EV_WINDOW (l->data); const char *window_uri = ev_window_get_uri (window); - if (window_uri && strcmp (window_uri, uri) == 0) { + if (window_uri && strcmp (window_uri, uri) == 0 && !ev_window_is_empty (window)) { uri_window = window; break; } @@ -179,47 +336,96 @@ ev_application_get_uri_window (EvApplication *application, const char *uri) return uri_window; } -gboolean -ev_application_open_uri (EvApplication *application, - const char *uri, - const char *page_label, - guint timestamp, - GError **error) +void +ev_application_open_uri_at_dest (EvApplication *application, + const char *uri, + GdkScreen *screen, + EvLinkDest *dest, + EvWindowRunMode mode, + gboolean unlink_temp_file, + guint timestamp) { - EvWindow *new_window; + EvWindow *new_window; + GtkIconTheme *icon_theme; + + g_return_if_fail (uri != NULL); + + icon_theme = gtk_icon_theme_get_for_screen (screen); + if (icon_theme) { + gchar **path = NULL; + gint n_paths; + gint i; + gchar *ev_icons_path; + + /* GtkIconTheme will then look in Evince custom hicolor dir + * for icons as well as the standard search paths + */ + ev_icons_path = g_build_filename (DATADIR, "icons", NULL); + gtk_icon_theme_get_search_path (icon_theme, &path, &n_paths); + for (i = n_paths - 1; i >= 0; i--) { + if (g_ascii_strcasecmp (ev_icons_path, path[i]) == 0) + break; + } + + if (i < 0) + gtk_icon_theme_append_search_path (icon_theme, + ev_icons_path); - g_return_val_if_fail (uri != NULL, FALSE); + g_free (ev_icons_path); + g_strfreev (path); + } new_window = ev_application_get_uri_window (application, uri); - if (new_window != NULL) { -#ifdef HAVE_GTK_WINDOW_PRESENT_WITH_TIME - gtk_window_present_with_time (GTK_WINDOW (new_window), - timestamp); -#else - gtk_window_present (GTK_WINDOW (new_window)); -#endif - return TRUE; + + if (new_window == NULL) { + new_window = ev_application_get_empty_window (application, screen); } - new_window = ev_application_get_empty_window (application); - if (new_window == NULL) { new_window = EV_WINDOW (ev_window_new ()); - gtk_widget_show (GTK_WIDGET (new_window)); } - - ev_window_open_uri (new_window, uri); -#ifdef HAVE_GTK_WINDOW_PRESENT_WITH_TIME + if (screen) + gtk_window_set_screen (GTK_WINDOW (new_window), screen); + + /* We need to load uri before showing the window, so + we can restore window size without flickering */ + ev_window_open_uri (new_window, uri, dest, mode, unlink_temp_file); + + ev_document_fc_mutex_lock (); + gtk_widget_show (GTK_WIDGET (new_window)); + ev_document_fc_mutex_unlock (); + gtk_window_present_with_time (GTK_WINDOW (new_window), timestamp); -#else - gtk_window_present (GTK_WINDOW (new_window)); -#endif +} - if (page_label != NULL) { - ev_window_open_page_label (new_window, page_label); +gboolean +ev_application_open_uri (EvApplication *application, + const char *uri, + GHashTable *args, + guint timestamp, + GError **error) +{ + EvLinkDest *dest = NULL; + EvWindowRunMode mode = EV_WINDOW_MODE_NORMAL; + gboolean unlink_temp_file = FALSE; + GdkScreen *screen = NULL; + + if (args) { + screen = get_screen_from_args (args); + dest = get_destination_from_args (args); + mode = get_window_run_mode_from_args (args); + unlink_temp_file = (mode == EV_WINDOW_MODE_PREVIEW && + get_unlink_temp_file_from_args (args)); } + + ev_application_open_uri_at_dest (application, uri, screen, + dest, mode, unlink_temp_file, + timestamp); + + if (dest) + g_object_unref (dest); return TRUE; } @@ -227,15 +433,15 @@ ev_application_open_uri (EvApplication *application, void ev_application_open_uri_list (EvApplication *application, GSList *uri_list, + GdkScreen *screen, guint timestamp) { GSList *l; for (l = uri_list; l != NULL; l = l->next) { - ev_application_open_uri (application, (char *)l->data, - NULL, - timestamp, - NULL); + ev_application_open_uri_at_dest (application, (char *)l->data, + screen, NULL, 0, FALSE, + timestamp); } } @@ -244,17 +450,23 @@ ev_application_shutdown (EvApplication *application) { if (application->toolbars_model) { g_object_unref (application->toolbars_model); + g_object_unref (application->preview_toolbars_model); g_free (application->toolbars_file); application->toolbars_model = NULL; + application->preview_toolbars_model = NULL; application->toolbars_file = NULL; } +#ifndef HAVE_GTK_RECENT if (application->recent_model) { g_object_unref (application->recent_model); application->recent_model = NULL; } - +#endif + + g_free (application->last_chooser_uri); g_object_unref (application); + gtk_main_quit (); } @@ -266,20 +478,34 @@ ev_application_class_init (EvApplicationClass *ev_application_class) static void ev_application_init (EvApplication *ev_application) { + init_session (ev_application); + ev_application->toolbars_model = egg_toolbars_model_new (); ev_application->toolbars_file = g_build_filename (ev_dot_dir (), "evince_toolbar.xml", NULL); - if (!egg_toolbars_model_load (ev_application->toolbars_model, - ev_application->toolbars_file)) { - egg_toolbars_model_load (ev_application->toolbars_model, - DATADIR"/evince-toolbar.xml"); + egg_toolbars_model_load_names (ev_application->toolbars_model, + DATADIR "/evince-toolbar.xml"); + + if (!egg_toolbars_model_load_toolbars (ev_application->toolbars_model, + ev_application->toolbars_file)) { + egg_toolbars_model_load_toolbars (ev_application->toolbars_model, + DATADIR"/evince-toolbar.xml"); } egg_toolbars_model_set_flags (ev_application->toolbars_model, 0, EGG_TB_MODEL_NOT_REMOVABLE); - + + ev_application->preview_toolbars_model = egg_toolbars_model_new (); + + egg_toolbars_model_load_toolbars (ev_application->preview_toolbars_model, + DATADIR"/evince-preview-toolbar.xml"); + + egg_toolbars_model_set_flags (ev_application->preview_toolbars_model, 0, + EGG_TB_MODEL_NOT_REMOVABLE); + +#ifndef HAVE_GTK_RECENT ev_application->recent_model = egg_recent_model_new (EGG_RECENT_MODEL_SORT_MRU); /* FIXME we should add a mime type filter but current eggrecent has only a varargs style api which does not work well when @@ -287,22 +513,67 @@ ev_application_init (EvApplication *ev_application) egg_recent_model_set_limit (ev_application->recent_model, 5); egg_recent_model_set_filter_groups (ev_application->recent_model, "Evince", NULL); +#endif /* HAVE_GTK_RECENT */ +} + +GList * +ev_application_get_windows (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 windows; } -EggToolbarsModel *ev_application_get_toolbars_model (EvApplication *application) +EggToolbarsModel *ev_application_get_toolbars_model (EvApplication *application, + gboolean preview) { - return application->toolbars_model; + return preview ? + application->preview_toolbars_model : application->toolbars_model; } +#ifndef HAVE_GTK_RECENT EggRecentModel *ev_application_get_recent_model (EvApplication *application) { return application->recent_model; } +#endif void ev_application_save_toolbars_model (EvApplication *application) { - egg_toolbars_model_save (application->toolbars_model, - application->toolbars_file, "1.0"); + egg_toolbars_model_save_toolbars (application->toolbars_model, + application->toolbars_file, "1.0"); +} + +void ev_application_set_chooser_uri (EvApplication *application, const gchar *uri) +{ + g_free (application->last_chooser_uri); + application->last_chooser_uri = g_strdup (uri); } +const gchar* ev_application_get_chooser_uri (EvApplication *application) +{ + return application->last_chooser_uri; +} +void ev_application_screensaver_enable (EvApplication *application) +{ + if (application->scr_saver) + totem_scrsaver_enable (application->scr_saver); +} + +void ev_application_screensaver_disable (EvApplication *application) +{ + if (application->scr_saver) + totem_scrsaver_disable (application->scr_saver); +}