[easytag] Use GApplication for application life cycle



commit 40c62b5c92f0243ea3f1020a8a547e4e21c854ce
Author: David King <amigadave amigadave com>
Date:   Tue Mar 12 20:43:44 2013 +0000

    Use GApplication for application life cycle
    
    Store a pointer to the main window in EtApplication. Tie the lifetime of
    EtApplication to the lifetime of the application. Move application
    startup code to the ETApplication::activate handler. Present the main
    window if the application is executed while it is already running.

 src/application.c |   55 +++++++++++++++++++++++++++++++++++-
 src/application.h |    4 ++
 src/easytag.c     |   81 ++++++++++++++++++++++++++++++++---------------------
 3 files changed, 107 insertions(+), 33 deletions(-)
---
diff --git a/src/application.c b/src/application.c
index abadbaf..99276df 100644
--- a/src/application.c
+++ b/src/application.c
@@ -27,7 +27,7 @@ G_DEFINE_TYPE (EtApplication, et_application, G_TYPE_APPLICATION)
 
 struct _EtApplicationPrivate
 {
-    gpointer *data;
+    GtkWindow *main_window;
 };
 
 static void
@@ -83,11 +83,30 @@ static gboolean
 et_local_command_line (GApplication *application, gchar **arguments[],
                        gint *exit_status)
 {
+    GError *error = NULL;
+    guint n_args;
     gint i;
     gchar **argv;
 
+    /* Try to register. */
+    if (!g_application_register (application, NULL, &error))
+    {
+        g_critical ("Error registering EtApplication: %s", error->message);
+        g_error_free (error);
+        *exit_status = 1;
+        return TRUE;
+    }
+
     argv = *arguments;
+    n_args = g_strv_length (argv);
     *exit_status = 0;
+
+    if (n_args <= 1)
+    {
+        gtk_init (NULL, NULL);
+        g_application_activate (application);
+        return TRUE;
+    }
     i = 1;
 
     while (argv[i])
@@ -129,6 +148,8 @@ et_application_init (EtApplication *application)
     application->priv = G_TYPE_INSTANCE_GET_PRIVATE (application,
                                                      ET_TYPE_APPLICATION,
                                                      EtApplicationPrivate);
+
+    application->priv->main_window = NULL;
 }
 
 static void
@@ -159,3 +180,35 @@ et_application_new ()
                          "org.gnome.EasyTAG", "flags",
                          G_APPLICATION_FLAGS_NONE, NULL);
 }
+
+/*
+ * et_application_get_window:
+ * @application: the application
+ *
+ * Get the current application window.
+ *
+ * Returns: the current application window, or %NULL if no window is set
+ */
+GtkWindow *
+et_application_get_window (EtApplication *application)
+{
+    g_return_val_if_fail (ET_APPLICATION (application), NULL);
+
+    return application->priv->main_window;
+}
+
+/*
+ * et_application_set_window:
+ * @application: the application
+ * @window: the window to set
+ *
+ * Set the application window, if none has been set already.
+ */
+void
+et_application_set_window (EtApplication *application, GtkWindow *window)
+{
+    g_return_if_fail (ET_APPLICATION (application) || GTK_WINDOW (window)
+                      || application->priv->main_window != NULL);
+
+    application->priv->main_window = window;
+}
diff --git a/src/application.h b/src/application.h
index 61ab63f..c3a1858 100644
--- a/src/application.h
+++ b/src/application.h
@@ -20,10 +20,12 @@
 #define ET_APPLICATION_H_
 
 #include <gio/gio.h>
+#include <gtk/gtk.h>
 
 G_BEGIN_DECLS
 
 #define ET_TYPE_APPLICATION (et_application_get_type ())
+#define ET_APPLICATION(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), ET_TYPE_APPLICATION, EtApplication))
 
 typedef struct _EtApplication EtApplication;
 typedef struct _EtApplicationClass EtApplicationClass;
@@ -44,6 +46,8 @@ struct _EtApplicationClass
 
 GType et_application_get_type (void);
 EtApplication *et_application_new (void);
+GtkWindow *et_application_get_window (EtApplication *application);
+void et_application_set_window (EtApplication *application, GtkWindow *window);
 
 G_END_DECLS
 
diff --git a/src/easytag.c b/src/easytag.c
index d30a026..84643a7 100644
--- a/src/easytag.c
+++ b/src/easytag.c
@@ -177,7 +177,7 @@ setup_sigchld (void)
  * Returns: the exit status to be passed to the calling process
  */
 static gint
-command_line (EtApplication *application,
+command_line (GApplication *application,
               GApplicationCommandLine *command_line, gpointer user_data)
 {
     gchar **argv;
@@ -276,51 +276,35 @@ command_line (EtApplication *application,
         g_free(path2check);
     }
 
+    /* Initialize GTK. */
+    if (et_application_get_window (ET_APPLICATION (application)) == NULL)
+    {
+        gtk_init (&argc, &argv);
+    }
+
     g_strfreev (argv);
 
+    g_application_activate (application);
+
     return 0;
 }
 
-/********
- * Main *
- ********/
-int main (int argc, char *argv[])
+static void
+activate (GApplication *application, gpointer user_data)
 {
-    EtApplication *application;
-    gint status;
+    GtkWindow *main_window;
     GtkWidget *MainVBox;
     GtkWidget *HBox, *VBox;
-    //GError *error = NULL;
-
 
-#ifdef G_OS_WIN32
-    weasytag_init();
-    //ET_Win32_Init(hInstance);
-#else /* !G_OS_WIN32 */
-    /* Signal handling to display a message(SIGSEGV, ...) */
-    setup_sigbus_fpe_segv ();
-    // Must handle this signal to avoid zombie of applications executed (ex: xmms)
-    setup_sigchld ();
-#endif /* !G_OS_WIN32 */
-
-    INIT_DIRECTORY = NULL;
-
-    /* FIXME: Move remaining initialisation code into EtApplication. */
-    application = et_application_new ();
-    g_signal_connect (application, "command-line", G_CALLBACK (command_line),
-                      NULL);
-    status = g_application_run (G_APPLICATION (application), argc, argv);
-    g_object_unref (application);
-    if (status != 0)
+    main_window = et_application_get_window (ET_APPLICATION (application));
+    if (main_window != NULL)
     {
-        return status;
+        gtk_window_present (main_window);
+        return;
     }
 
     Charset_Insert_Locales_Init();
 
-    /* Initialize GTK */
-    gtk_init(&argc, &argv);
-
     /* Starting messages */
     Log_Print(LOG_OK,_("Starting EasyTAG version %s (PID: %d)…"),PACKAGE_VERSION,getpid());
 #ifdef ENABLE_MP3
@@ -371,6 +355,8 @@ int main (int argc, char *argv[])
 
     /* The main window */
     MainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+    et_application_set_window (ET_APPLICATION (application),
+                               GTK_WINDOW (MainWindow));
     gtk_window_set_title (GTK_WINDOW (MainWindow),
                           PACKAGE_NAME " " PACKAGE_VERSION);
     // This part is needed to set correctly the position of handle panes
@@ -454,6 +440,37 @@ int main (int argc, char *argv[])
 
     /* Enter the event loop */
     gtk_main ();
+}
+
+/********
+ * Main *
+ ********/
+int main (int argc, char *argv[])
+{
+    EtApplication *application;
+    gint status;
+
+    /* FIXME: Move remaining initialisation code into EtApplication. */
+#ifdef G_OS_WIN32
+    weasytag_init();
+    /* ET_Win32_Init(hInstance); */
+#else /* !G_OS_WIN32 */
+    /* Signal handling to display a message(SIGSEGV, ...) */
+    setup_sigbus_fpe_segv ();
+    /* Must handle this signal to avoid zombies of child processes (e.g. xmms)
+     */
+    setup_sigchld ();
+#endif /* !G_OS_WIN32 */
+
+    INIT_DIRECTORY = NULL;
+
+    application = et_application_new ();
+    g_signal_connect (application, "command-line", G_CALLBACK (command_line),
+                      NULL);
+    g_signal_connect (application, "activate", G_CALLBACK (activate), NULL);
+    status = g_application_run (G_APPLICATION (application), argc, argv);
+    g_object_unref (application);
+
     return status;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]