From 15073fb029c8fc78d7184be7bc0e70d4cbe5ac1b Mon Sep 17 00:00:00 2001 From: Christian Persch Date: Tue, 12 Jun 2012 18:53:35 +0200 Subject: shell: Port to GtkApplication origin commit: https://git.gnome.org/browse/evince/commit/?h=gnome-3-6&id=b999bdd --- shell/ev-application.c | 294 +++++++++++++++++++++++++------------------------ shell/ev-application.h | 6 +- shell/ev-window.c | 26 +---- shell/ev-window.h | 6 +- shell/main.c | 18 ++- 5 files changed, 177 insertions(+), 173 deletions(-) diff --git a/shell/ev-application.c b/shell/ev-application.c index 3f63f0dc..a64a0568 100644 --- a/shell/ev-application.c +++ b/shell/ev-application.c @@ -1,7 +1,7 @@ /* this file is part of atril, a mate document viewer * * Copyright (C) 2004 Martin Kretzschmar - * Copyright © 2010 Christian Persch + * Copyright © 2010, 2012 Christian Persch * * Author: * Martin Kretzschmar @@ -46,7 +46,7 @@ #endif /* ENABLE_DBUS */ struct _EvApplication { - GObject base_instance; + GtkApplication base_instance; gchar *uri; @@ -54,7 +54,6 @@ struct _EvApplication { gchar *data_dir; #ifdef ENABLE_DBUS - GDBusConnection *connection; EvAtrilApplication *skeleton; EvMediaPlayerKeys *keys; gboolean doc_registered; @@ -66,12 +65,10 @@ struct _EvApplication { }; struct _EvApplicationClass { - GObjectClass base_class; + GtkApplicationClass base_class; }; -static EvApplication *instance; - -G_DEFINE_TYPE (EvApplication, ev_application, G_TYPE_OBJECT); +G_DEFINE_TYPE (EvApplication, ev_application, GTK_TYPE_APPLICATION) #ifdef ENABLE_DBUS #define APPLICATION_DBUS_OBJECT_PATH "/org/mate/atril/Atril" @@ -101,20 +98,21 @@ static void ev_application_open_uri_in_window (EvApplication *application, guint timestamp); /** - * ev_application_get_instance: + * ev_application_new: * - * Checks for #EvApplication instance, if it doesn't exist it does create it. + * Creates a new #EvApplication instance. * - * Returns: an instance of the #EvApplication data. + * Returns: (transfer full): a newly created #EvApplication */ EvApplication * -ev_application_get_instance (void) +ev_application_new (void) { - if (!instance) { - instance = EV_APPLICATION (g_object_new (EV_TYPE_APPLICATION, NULL)); - } + const GApplicationFlags flags = G_APPLICATION_NON_UNIQUE; - return instance; + return g_object_new (EV_TYPE_APPLICATION, + "application-id", NULL, + "flags", flags, + NULL); } /* Session */ @@ -157,10 +155,10 @@ smclient_save_state_cb (EggSMClient *client, } static void -smclient_quit_cb (EggSMClient *client, - EvApplication *application) +smclient_quit_cb (EggSMClient *client, + GApplication *application) { - ev_application_shutdown (application); + g_application_quit (application); } static void @@ -292,35 +290,21 @@ ev_spawn (const char *uri, g_free (cmdline); } -static 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; -} - static EvWindow * ev_application_get_empty_window (EvApplication *application, GdkScreen *screen) { EvWindow *empty_window = NULL; - GList *windows = ev_application_get_windows (application); - GList *l; + GList *windows, *l; + windows = gtk_application_get_windows (GTK_APPLICATION (application)); for (l = windows; l != NULL; l = l->next) { - EvWindow *window = EV_WINDOW (l->data); + EvWindow *window; + + if (!EV_IS_WINDOW (l->data)) + continue; + + window = EV_WINDOW (l->data); if (ev_window_is_empty (window) && gtk_window_get_screen (GTK_WINDOW (window)) == screen) { @@ -329,8 +313,6 @@ ev_application_get_empty_window (EvApplication *application, } } - g_list_free (windows); - return empty_window; } @@ -369,18 +351,19 @@ on_reload_cb (GObject *source_object, GVariant *value; GError *error = NULL; + g_application_release (g_application_get_default ()); + value = g_dbus_connection_call_finish (connection, res, &error); - if (!value) { - g_warning ("Failed to Reload: %s", error->message); + if (value != NULL) { + g_variant_unref (value); + } else { + g_printerr ("Failed to Reload: %s\n", error->message); g_error_free (error); } - g_variant_unref (value); /* We did not open a window, so manually clear the startup * notification. */ gdk_notify_startup_complete (); - - ev_application_shutdown (EV_APP); } static void @@ -396,6 +379,8 @@ on_register_uri_cb (GObject *source_object, GVariantBuilder builder; GError *error = NULL; + g_application_release (G_APPLICATION (application)); + value = g_dbus_connection_call_finish (connection, res, &error); if (!value) { g_printerr ("Error registering document: %s\n", error->message); @@ -488,6 +473,7 @@ on_register_uri_cb (GObject *source_object, NULL, on_reload_cb, NULL); + g_application_hold (G_APPLICATION (application)); g_variant_unref (value); ev_register_doc_data_free (data); } @@ -516,23 +502,24 @@ ev_application_register_uri (EvApplication *application, { EvRegisterDocData *data; - if (!application->connection) + if (!application->skeleton) return; if (application->doc_registered) { /* Already registered, reload */ GList *windows, *l; - windows = ev_application_get_windows (application); + windows = gtk_application_get_windows (GTK_APPLICATION (application)); for (l = windows; l != NULL; l = g_list_next (l)) { - EvWindow *ev_window = EV_WINDOW (l->data); + if (!EV_IS_WINDOW (l->data)) + continue; - ev_application_open_uri_in_window (application, uri, ev_window, + ev_application_open_uri_in_window (application, uri, + EV_WINDOW (l->data), screen, dest, mode, search_string, timestamp); } - g_list_free (windows); return; } @@ -545,7 +532,7 @@ ev_application_register_uri (EvApplication *application, data->search_string = search_string ? g_strdup (search_string) : NULL; data->timestamp = timestamp; - g_dbus_connection_call (application->connection, + g_dbus_connection_call (g_application_get_dbus_connection (G_APPLICATION (application)), ATRIL_DAEMON_SERVICE, ATRIL_DAEMON_OBJECT_PATH, ATRIL_DAEMON_INTERFACE, @@ -557,6 +544,8 @@ ev_application_register_uri (EvApplication *application, NULL, on_register_uri_cb, data); + + g_application_hold (G_APPLICATION (application)); } static void @@ -573,7 +562,7 @@ ev_application_unregister_uri (EvApplication *application, * so it's safe to use the sync api */ value = g_dbus_connection_call_sync ( - application->connection, + g_application_get_dbus_connection (G_APPLICATION (application)), ATRIL_DAEMON_SERVICE, ATRIL_DAEMON_OBJECT_PATH, ATRIL_DAEMON_INTERFACE, @@ -731,13 +720,13 @@ handle_get_window_list_cb (EvAtrilApplication *object, paths = g_ptr_array_new (); - windows = ev_application_get_windows (application); + windows = gtk_application_get_windows (GTK_APPLICATION (application)); for (l = windows; l; l = g_list_next (l)) { - EvWindow *window = (EvWindow *)l->data; + if (!EV_IS_WINDOW (l->data)) + continue; - g_ptr_array_add (paths, (gpointer) ev_window_get_dbus_object_path (window)); + g_ptr_array_add (paths, (gpointer) ev_window_get_dbus_object_path (EV_WINDOW (l->data))); } - g_list_free (windows); g_ptr_array_add (paths, NULL); ev_atril_application_complete_get_window_list (object, invocation, @@ -788,17 +777,17 @@ handle_reload_cb (EvAtrilApplication *object, else screen = gdk_screen_get_default (); - windows = ev_application_get_windows (application); + windows = gtk_application_get_windows (GTK_APPLICATION ((application))); for (l = windows; l != NULL; l = g_list_next (l)) { - EvWindow *ev_window = EV_WINDOW (l->data); + if (!EV_IS_WINDOW (l->data)) + continue; ev_application_open_uri_in_window (application, NULL, - ev_window, + EV_WINDOW (l->data), screen, dest, mode, search_string, timestamp); } - g_list_free (windows); if (dest) g_object_unref (dest); @@ -880,9 +869,11 @@ static void ev_application_accel_map_load(EvApplication* application) g_free(accel_map_file); } -void -ev_application_shutdown (EvApplication *application) +static void +ev_application_shutdown (GApplication *gapplication) { + EvApplication *application = EV_APPLICATION (gapplication); + if (application->uri) { #ifdef ENABLE_DBUS ev_application_unregister_uri (application, @@ -897,42 +888,104 @@ ev_application_shutdown (EvApplication *application) g_object_unref (application->scr_saver); application->scr_saver = NULL; + g_free (application->dot_dir); + application->dot_dir = NULL; + + G_APPLICATION_CLASS (ev_application_parent_class)->shutdown (gapplication); +} + +static void +ev_application_activate (GApplication *gapplication) +{ + EvApplication *application = EV_APPLICATION (gapplication); + GList *windows, *l; + + windows = gtk_application_get_windows (GTK_APPLICATION (application)); + for (l = windows; l != NULL; l = l->next) { + if (!EV_IS_WINDOW (l->data)) + continue; + + gtk_window_present (GTK_WINDOW (l->data)); + } +} + #ifdef ENABLE_DBUS - if (application->keys) { - g_object_unref (application->keys); - application->keys = NULL; - } +static gboolean +ev_application_dbus_register (GApplication *gapplication, + GDBusConnection *connection, + const gchar *object_path, + GError **error) +{ + EvApplication *application = EV_APPLICATION (gapplication); + EvAtrilApplication *skeleton; + + if (!G_APPLICATION_CLASS (ev_application_parent_class)->dbus_register (gapplication, + connection, + object_path, + error)) + return FALSE; + + skeleton = ev_atril_application_skeleton_new (); + if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton), + connection, + APPLICATION_DBUS_OBJECT_PATH, + error)) { + g_object_unref (skeleton); + + return FALSE; + } + + application->skeleton = skeleton; + g_signal_connect (skeleton, "handle-get-window-list", + G_CALLBACK (handle_get_window_list_cb), + application); + g_signal_connect (skeleton, "handle-reload", + G_CALLBACK (handle_reload_cb), + application); + application->keys = ev_media_player_keys_new (); + + return TRUE; +} + +static void +ev_application_dbus_unregister (GApplication *gapplication, + GDBusConnection *connection, + const gchar *object_path) +{ + EvApplication *application = EV_APPLICATION (gapplication); + + if (application->keys) { + g_object_unref (application->keys); + application->keys = NULL; + } if (application->skeleton != NULL) { g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (application->skeleton)); g_object_unref (application->skeleton); application->skeleton = NULL; } - if (application->connection != NULL) { - g_object_unref (application->connection); - application->connection = NULL; - } -#endif /* ENABLE_DBUS */ - - g_free (application->dot_dir); - application->dot_dir = NULL; - g_free (application->data_dir); - application->data_dir = NULL; - - g_object_unref (application); - instance = NULL; - gtk_main_quit (); + G_APPLICATION_CLASS (ev_application_parent_class)->dbus_unregister (gapplication, + connection, + object_path); } +#endif /* ENABLE_DBUS */ + static void ev_application_class_init(EvApplicationClass* ev_application_class) { - /* Nothing */ + GApplicationClass *g_application_class = G_APPLICATION_CLASS (ev_application_class); + + g_application_class->activate = ev_application_activate; + g_application_class->shutdown = ev_application_shutdown; + +#ifdef ENABLE_DBUS + g_application_class->dbus_register = ev_application_dbus_register; + g_application_class->dbus_unregister = ev_application_dbus_unregister; +#endif } static void ev_application_init(EvApplication* ev_application) { - GError* error = NULL; - userdir = g_getenv("MATE22_USER_DIR"); if (userdir) @@ -950,85 +1003,42 @@ static void ev_application_init(EvApplication* ev_application) ev_application_accel_map_load (ev_application); -#ifdef ENABLE_DBUS - ev_application->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); - if (ev_application->connection != NULL) { - EvAtrilApplication *skeleton; - - skeleton = ev_atril_application_skeleton_new (); - if (g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton), - ev_application->connection, - APPLICATION_DBUS_OBJECT_PATH, - &error)) { - ev_application->skeleton = skeleton; - g_signal_connect (skeleton, "handle-get-window-list", - G_CALLBACK (handle_get_window_list_cb), - ev_application); - g_signal_connect (skeleton, "handle-reload", - G_CALLBACK (handle_reload_cb), - ev_application); - } else { - g_object_unref (skeleton); - g_printerr ("Failed to register bus object: %s\n", error->message); - g_error_free (error); - } - } else { - g_printerr ("Failed to get bus connection: %s\n", error->message); - g_error_free (error); - } - - ev_application->keys = ev_media_player_keys_new (); -#endif /* ENABLE_DBUS */ - ev_application->scr_saver = totem_scrsaver_new (); g_object_set (ev_application->scr_saver, "reason", _("Running in presentation mode"), NULL); } -GDBusConnection * -ev_application_get_dbus_connection (EvApplication *application) -{ -#ifdef ENABLE_DBUS - return application->connection; -#else - return NULL; -#endif -} - gboolean ev_application_has_window (EvApplication *application) { - GList *l, *toplevels; - gboolean retval = FALSE; + GList *l, *windows; - toplevels = gtk_window_list_toplevels (); + windows = gtk_application_get_windows (GTK_APPLICATION (application)); + for (l = windows; l != NULL; l = l->next) { + if (!EV_IS_WINDOW (l->data)) + continue; - for (l = toplevels; l != NULL && !retval; l = l->next) { - if (EV_IS_WINDOW (l->data)) - retval = TRUE; + return TRUE; } - g_list_free (toplevels); - - return retval; + return FALSE; } guint ev_application_get_n_windows (EvApplication *application) { - GList *l, *toplevels; - guint retval = 0; + GList *l, *windows; + guint retval = 0; - toplevels = gtk_window_list_toplevels (); + windows = gtk_application_get_windows (GTK_APPLICATION (application)); + for (l = windows; l != NULL && !retval; l = l->next) { + if (!EV_IS_WINDOW (l->data)) + continue; - for (l = toplevels; l != NULL; l = l->next) { - if (EV_IS_WINDOW (l->data)) - retval++; + retval++; } - g_list_free (toplevels); - return retval; } diff --git a/shell/ev-application.h b/shell/ev-application.h index 4724148e..f0561b55 100644 --- a/shell/ev-application.h +++ b/shell/ev-application.h @@ -44,12 +44,11 @@ typedef struct _EvApplicationClass EvApplicationClass; #define EV_IS_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_APPLICATION)) #define EV_APPLICATION_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_APPLICATION, EvApplicationClass)) -#define EV_APP (ev_application_get_instance ()) +#define EV_APP ((EvApplication *) g_application_get_default ()) GType ev_application_get_type (void) G_GNUC_CONST; -EvApplication *ev_application_get_instance (void); +EvApplication *ev_application_new (void); -void ev_application_shutdown (EvApplication *application); gboolean ev_application_load_session (EvApplication *application); void ev_application_open_window (EvApplication *application, GdkScreen *screen, @@ -65,7 +64,6 @@ void ev_application_open_uri_list (EvApplication *application, GSList *uri_list, GdkScreen *screen, guint32 timestamp); -GDBusConnection *ev_application_get_dbus_connection (EvApplication *application); gboolean ev_application_has_window (EvApplication *application); guint ev_application_get_n_windows (EvApplication *application); const gchar * ev_application_get_uri (EvApplication *application); diff --git a/shell/ev-window.c b/shell/ev-window.c index 16685012..0c8e1298 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -6,7 +6,7 @@ * Copyright (C) 2004 Martin Kretzschmar * Copyright (C) 2004 Red Hat, Inc. * Copyright (C) 2000, 2001, 2002, 2003, 2004 Marco Pesenti Gritti - * Copyright © 2003, 2004, 2005, 2009 Christian Persch + * Copyright © 2003, 2004, 2005, 2009, 2012 Christian Persch * * Author: * Martin Kretzschmar @@ -381,11 +381,9 @@ static void zoom_control_changed_cb (EphyZoomAction *action, float zoom, EvWindow *ev_window); -static guint ev_window_n_copies = 0; - static gchar *caja_sendto = NULL; -G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_WINDOW) +G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_APPLICATION_WINDOW) static gdouble get_screen_dpi (EvWindow *window) @@ -2715,8 +2713,6 @@ 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, @@ -5866,18 +5862,6 @@ ev_window_drag_data_received (GtkWidget *widget, g_slist_free (uri_list); } -static void -ev_window_finalize (GObject *object) -{ - G_OBJECT_CLASS (ev_window_parent_class)->finalize (object); - - if (ev_window_n_copies == 0) { - ev_application_shutdown (EV_APP); - } else { - ev_window_n_copies--; - } -} - static void ev_window_set_caret_navigation_enabled (EvWindow *window, gboolean enabled) @@ -6246,7 +6230,6 @@ ev_window_class_init (EvWindowClass *ev_window_class) GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (ev_window_class); g_object_class->dispose = ev_window_dispose; - g_object_class->finalize = ev_window_finalize; widget_class->delete_event = ev_window_delete_event; widget_class->key_press_event = ev_window_key_press_event; @@ -7551,7 +7534,7 @@ ev_window_emit_closed (EvWindow *window) * to make sure the signal is emitted. */ if (ev_application_get_n_windows (EV_APP) == 1) - g_dbus_connection_flush_sync (ev_application_get_dbus_connection (EV_APP), NULL, NULL); + g_dbus_connection_flush_sync (g_application_get_dbus_connection (g_application_get_default ()), NULL, NULL); } static void @@ -7609,7 +7592,7 @@ ev_window_init (EvWindow *ev_window) ev_window->priv = EV_WINDOW_GET_PRIVATE (ev_window); #ifdef ENABLE_DBUS - connection = ev_application_get_dbus_connection (EV_APP); + connection = g_application_get_dbus_connection (g_application_get_default ()); if (connection) { EvAtrilWindow *skeleton; @@ -8057,6 +8040,7 @@ ev_window_new (void) ev_window = GTK_WIDGET (g_object_new (EV_TYPE_WINDOW, "type", GTK_WINDOW_TOPLEVEL, + "application", g_application_get_default (), NULL)); return ev_window; diff --git a/shell/ev-window.h b/shell/ev-window.h index d2e7d40f..32d303aa 100644 --- a/shell/ev-window.h +++ b/shell/ev-window.h @@ -60,12 +60,12 @@ typedef struct _EvWindowPrivate EvWindowPrivate; struct _EvWindow { - GtkWindow base_instance; - EvWindowPrivate *priv; + GtkApplicationWindow base_instance; + EvWindowPrivate *priv; }; struct _EvWindowClass { - GtkWindowClass base_class; + GtkApplicationWindowClass base_class; }; GType ev_window_get_type (void) G_GNUC_CONST; diff --git a/shell/main.c b/shell/main.c index d9dd361e..6e21f9f2 100644 --- a/shell/main.c +++ b/shell/main.c @@ -224,8 +224,10 @@ load_files (const char **files) int main (int argc, char *argv[]) { + EvApplication *application; GOptionContext *context; GError *error = NULL; + int status; #ifdef ENABLE_NLS /* Initialize the i18n stuff */ @@ -266,7 +268,15 @@ main (int argc, char *argv[]) egg_set_desktop_file (MATEDATADIR "/applications/atril.desktop"); - ev_application_load_session (EV_APP); + application = ev_application_new (); + if (!g_application_register (G_APPLICATION (application), NULL, &error)) { + g_printerr ("Failed to register: %s\n", error->message); + g_error_free (error); + status = 1; + goto done; + } + + ev_application_load_session (application); load_files (file_arguments); /* Change directory so we don't prevent unmounting in case the initial cwd @@ -274,10 +284,12 @@ main (int argc, char *argv[]) */ g_chdir (g_get_home_dir ()); - gtk_main (); + status = g_application_run (G_APPLICATION (application), 0, NULL); + done: ev_shutdown (); ev_stock_icons_shutdown (); - return 0; + g_object_unref (application); + return status; } -- cgit v1.2.1