[gimp] app: cleanup MR !734.



commit fb1cb22f62b8db626399e6caf8cb294f0dddcef6
Author: Jehan <jehan girinstud io>
Date:   Thu Oct 6 20:44:06 2022 +0200

    app: cleanup MR !734.
    
    - app_activate_callback() moved with other private functions.
    - Removing the `if (app)` test in app_activate_callback() as we don't
      set it to NULL anymore. The app variable is always set.
    - As a consequence of the previous point, change signature of
      app_exit_after_callback() which doesn't have to change the value of
      app anymore.
    - Don't emit direcly the "exit" signal from app_activate_callback(). We
      must call `gimp_exit (gimp, TRUE);` instead, which does more than just
      emitting this signal. It also takes care of cleaning any remaining
      images without a display. If we don't do this, we are leaking
      GeglBuffer when opening images from command lines while quitting
      immediately with --quit.
    - Get rid of gimp_core_app_set_values() which was completely bypassing
      the fact that all the properties of a GimpCoreApp were construct-only.
      Instead make these proper properties. I use a trick used in other
      interface, creating a gimp_container_view_install_properties() which
      is called from child classes.
      The point of GimpCoreApp is not just to share a common interface, it's
      rather to weakly simulate some kind of multi-inheritance in GObject.
      Since we want both GimpApp and GimpConsoleApp to inherit from a same
      parent class while we also want them to inherit either from
      GtkApplication and GApplication respectively (yet without linking to
      GTK in this second case), we are stuck as far as normal GObject
      inheritance goes. This is why we use an interface to which we add a
      private struct through a GQuark trick. We want the property settings
      and function implementations to also be part of this shared code.
    - Get rid of all the abstract methods of GimpCoreApp of the form
      get_*(). These are useless as we don't expect these to have different
      implementation depending on the actual child class. Once again, our
      main goal was to simulate multiple inheritance rather than actually
      have an interface with various implementations.
    - Make "no-splash" a property of GimpApp, because it's cleaner this way.
    - Fix gimp_core_app_private_finalize().
    - don't use #pragma once, it's not standard. Just use include guards.
    - Fix includes: order was wrong, include from the source, not other
      headers, etc.
    - Clean various other details, coding styles, fix several more bugs and
      moreā€¦

 app/app.c            | 369 +++++++++++++++++++++++++--------------------------
 app/gimpconsoleapp.c |  25 +++-
 app/gimpconsoleapp.h |   7 +-
 app/gimpcoreapp.c    | 236 ++++++++++++++++++++++----------
 app/gimpcoreapp.h    |  65 ++++-----
 app/gui/gimpapp.c    |  92 +++++++++++--
 app/gui/gimpapp.h    |   4 -
 app/gui/gui-types.h  |   1 +
 app/gui/gui.c        |   1 +
 app/gui/gui.h        |   1 -
 app/gui/splash.h     |   2 -
 11 files changed, 491 insertions(+), 312 deletions(-)
---
diff --git a/app/app.c b/app/app.c
index 515618f900..af86865269 100644
--- a/app/app.c
+++ b/app/app.c
@@ -60,17 +60,18 @@
 #include "file/file-open.h"
 
 #ifndef GIMP_CONSOLE_COMPILATION
+#include <gtk/gtk.h>
+
 #include "dialogs/user-install-dialog.h"
 
+#include "gui/gimpapp.h"
 #include "gui/gui.h"
 #endif
 
 #include "app.h"
 #include "errors.h"
-#ifndef GIMP_CONSOLE_COMPILATION
-#include "gui/gimpapp.h"
-#endif
 #include "gimpconsoleapp.h"
+#include "gimpcoreapp.h"
 #include "language.h"
 #include "sanity.h"
 #include "gimp-debug.h"
@@ -84,11 +85,13 @@
 static void       app_init_update_noop       (const gchar        *text1,
                                               const gchar        *text2,
                                               gdouble             percentage);
+static void       app_activate_callback      (GimpCoreApp        *app,
+                                              gpointer            user_data);
 static void       app_restore_after_callback (Gimp               *gimp,
                                               GimpInitStatusFunc  status_callback);
 static gboolean   app_exit_after_callback    (Gimp               *gimp,
                                               gboolean            kill_it,
-                                              GApplication      **app);
+                                              GApplication       *app);
 
 #if 0
 /*  left here as documentation how to do compat enums  */
@@ -166,183 +169,6 @@ app_exit (gint status)
   exit (status);
 }
 
-static void
-app_activate_callback (GimpCoreApp *app,
-                       gpointer     user_data)
-{
-  Gimp               *gimp               = NULL;
-  GimpInitStatusFunc  update_status_func = NULL;
-  const gchar       **filenames;
-  const gchar        *current_language;
-  gchar              *prev_language      = NULL;
-  GError             *font_error         = NULL;
-
-  g_return_if_fail (GIMP_IS_CORE_APP (app));
-
-  gimp = gimp_core_app_get_gimp (app);
-
-  gimp_core_app_set_exit_status (app, EXIT_SUCCESS);
-
-#ifndef GIMP_CONSOLE_COMPILATION
-  if (! gimp->no_interface)
-    update_status_func = gui_init (gimp, gimp_app_get_no_splash (GIMP_APP (app)), GIMP_APP (app), NULL);
-#endif
-
-  if (! update_status_func)
-    update_status_func = app_init_update_noop;
-
-  /*  Create all members of the global Gimp instance which need an already
-   *  parsed gimprc, e.g. the data factories
-   */
-  gimp_initialize (gimp, update_status_func);
-
-  g_object_get (gimp->edit_config,
-                "prev-language", &prev_language,
-                NULL);
-  /* Language was already initialized. I call this again only to get the
-   * actual language information.
-   */
-  current_language = language_init (NULL);
-  gimp->query_all = (prev_language == NULL ||
-                     g_strcmp0 (prev_language, current_language) != 0);
-  g_free (prev_language);
-
-  /*  Load all data files */
-  gimp_restore (gimp, update_status_func, &font_error);
-
-  /*  enable autosave late so we don't autosave when the
-   *  monitor resolution is set in gui_init()
-   */
-  gimp_rc_set_autosave (GIMP_RC (gimp->edit_config), TRUE);
-
-  /*  check for updates *after* enabling config autosave, so that the timestamp
-   *  is saved
-   */
-  gimp_update_auto_check (gimp->edit_config, gimp);
-
-  /* Setting properties to be used for the next run.  */
-  g_object_set (gimp->edit_config,
-                /* Set this after gimp_update_auto_check(). */
-                "config-version", GIMP_VERSION,
-                /* Set this after gimp_restore(). */
-                "prev-language",  current_language,
-                NULL);
-
-#ifndef GIMP_CONSOLE_COMPILATION
-  if (! gimp->no_interface)
-    {
-      /* Before opening images from command line, check for salvaged images
-       * and query interactively to know if we should recover or discard
-       * them.
-       */
-      GList *recovered_files;
-      GList *iter;
-
-      recovered_files = errors_recovered ();
-      if (recovered_files &&
-          gui_recover (g_list_length (recovered_files)))
-        {
-          for (iter = recovered_files; iter; iter = iter->next)
-            {
-              GFile             *file;
-              GimpImage         *image;
-              GError            *error = NULL;
-              GimpPDBStatusType  status;
-
-              file = g_file_new_for_path (iter->data);
-              image = file_open_with_display (gimp,
-                                              gimp_get_user_context (gimp),
-                                              NULL,
-                                              file,
-                                              gimp_core_app_get_as_new (app),
-                                              initial_monitor,
-                                              &status, &error);
-              if (image)
-                {
-                  /* Break ties with the backup directory. */
-                  gimp_image_set_file (image, NULL);
-                  /* One of the rare exceptions where we should call
-                   * gimp_image_dirty() directly instead of creating
-                   * an undo. We want the image to be dirty from
-                   * scratch, without anything to undo.
-                   */
-                  gimp_image_dirty (image, GIMP_DIRTY_IMAGE);
-                }
-              else
-                {
-                  g_error_free (error);
-                }
-
-              g_object_unref (file);
-            }
-        }
-      /* Delete backup XCF images. */
-      for (iter = recovered_files; iter; iter = iter->next)
-        {
-          g_unlink (iter->data);
-        }
-      g_list_free_full (recovered_files, g_free);
-    }
-#endif
-
-  /*  Load the images given on the command-line. */
-  filenames = gimp_core_app_get_filenames (app);
-  if (filenames != NULL)
-    {
-      gint i;
-
-      for (i = 0; filenames[i] != NULL; i++)
-        {
-          if (app)
-            {
-              GFile *file = g_file_new_for_commandline_arg (filenames[i]);
-
-              file_open_from_command_line (gimp, file,
-                                           gimp_core_app_get_as_new (app),
-                                           initial_monitor);
-
-              g_object_unref (file);
-            }
-        }
-    }
-
-  /* The software is now fully loaded and ready to be used and get
-   * external input.
-   */
-  gimp->initialized = TRUE;
-
-  if (font_error)
-    {
-      gimp_message_literal (gimp, NULL,
-                            GIMP_MESSAGE_INFO,
-                            font_error->message);
-      g_error_free (font_error);
-    }
-
-  if (app)
-    {
-      gint batch_retval;
-
-      batch_retval = gimp_batch_run (gimp,
-                      gimp_core_app_get_batch_interpreter (app),
-                      gimp_core_app_get_batch_commands (app));
-
-      if (gimp_core_app_get_quit (app))
-        {
-          /*  Only if we are in batch mode, we want to exit with the
-           *  return value of the batch command.
-           */
-            gimp_core_app_set_exit_status (app, batch_retval);
-
-          /* Return value, needed for the signal call; let's just ignore the
-          * result. */
-          gboolean cb_retval;
-
-          g_signal_emit_by_name (gimp, "exit", TRUE, &cb_retval);
-        }
-    }
-}
-
 gint
 app_run (const gchar         *full_prog_name,
          const gchar        **filenames,
@@ -481,7 +307,7 @@ app_run (const gchar         *full_prog_name,
 
   g_signal_connect_after (gimp, "exit",
                           G_CALLBACK (app_exit_after_callback),
-                          &app);
+                          app);
 
   g_signal_connect (app, "activate",
                     G_CALLBACK (app_activate_callback),
@@ -523,6 +349,175 @@ app_init_update_noop (const gchar *text1,
   /*  deliberately do nothing  */
 }
 
+static void
+app_activate_callback (GimpCoreApp *app,
+                       gpointer     user_data)
+{
+  Gimp               *gimp               = NULL;
+  GimpInitStatusFunc  update_status_func = NULL;
+  const gchar       **filenames;
+  const gchar        *current_language;
+  gchar              *prev_language      = NULL;
+  GError             *font_error         = NULL;
+  gint                batch_retval;
+
+  g_return_if_fail (GIMP_IS_CORE_APP (app));
+
+  gimp = gimp_core_app_get_gimp (app);
+
+  gimp_core_app_set_exit_status (app, EXIT_SUCCESS);
+
+#ifndef GIMP_CONSOLE_COMPILATION
+  if (! gimp->no_interface)
+    update_status_func = gui_init (gimp, gimp_app_get_no_splash (GIMP_APP (app)), GIMP_APP (app), NULL);
+#endif
+
+  if (! update_status_func)
+    update_status_func = app_init_update_noop;
+
+  /*  Create all members of the global Gimp instance which need an already
+   *  parsed gimprc, e.g. the data factories
+   */
+  gimp_initialize (gimp, update_status_func);
+
+  g_object_get (gimp->edit_config,
+                "prev-language", &prev_language,
+                NULL);
+  /* Language was already initialized. I call this again only to get the
+   * actual language information.
+   */
+  current_language = language_init (NULL);
+  gimp->query_all = (prev_language == NULL ||
+                     g_strcmp0 (prev_language, current_language) != 0);
+  g_free (prev_language);
+
+  /*  Load all data files */
+  gimp_restore (gimp, update_status_func, &font_error);
+
+  /*  enable autosave late so we don't autosave when the
+   *  monitor resolution is set in gui_init()
+   */
+  gimp_rc_set_autosave (GIMP_RC (gimp->edit_config), TRUE);
+
+  /*  check for updates *after* enabling config autosave, so that the timestamp
+   *  is saved
+   */
+  gimp_update_auto_check (gimp->edit_config, gimp);
+
+  /* Setting properties to be used for the next run.  */
+  g_object_set (gimp->edit_config,
+                /* Set this after gimp_update_auto_check(). */
+                "config-version", GIMP_VERSION,
+                /* Set this after gimp_restore(). */
+                "prev-language",  current_language,
+                NULL);
+
+#ifndef GIMP_CONSOLE_COMPILATION
+  if (! gimp->no_interface)
+    {
+      /* Before opening images from command line, check for salvaged images
+       * and query interactively to know if we should recover or discard
+       * them.
+       */
+      GList *recovered_files;
+      GList *iter;
+
+      recovered_files = errors_recovered ();
+      if (recovered_files &&
+          gui_recover (g_list_length (recovered_files)))
+        {
+          for (iter = recovered_files; iter; iter = iter->next)
+            {
+              GFile             *file;
+              GimpImage         *image;
+              GError            *error = NULL;
+              GimpPDBStatusType  status;
+
+              file = g_file_new_for_path (iter->data);
+              image = file_open_with_display (gimp,
+                                              gimp_get_user_context (gimp),
+                                              NULL,
+                                              file,
+                                              gimp_core_app_get_as_new (app),
+                                              initial_monitor,
+                                              &status, &error);
+              if (image)
+                {
+                  /* Break ties with the backup directory. */
+                  gimp_image_set_file (image, NULL);
+                  /* One of the rare exceptions where we should call
+                   * gimp_image_dirty() directly instead of creating
+                   * an undo. We want the image to be dirty from
+                   * scratch, without anything to undo.
+                   */
+                  gimp_image_dirty (image, GIMP_DIRTY_IMAGE);
+                }
+              else
+                {
+                  g_error_free (error);
+                }
+
+              g_object_unref (file);
+            }
+        }
+      /* Delete backup XCF images. */
+      for (iter = recovered_files; iter; iter = iter->next)
+        {
+          g_unlink (iter->data);
+        }
+      g_list_free_full (recovered_files, g_free);
+    }
+#endif
+
+  /*  Load the images given on the command-line. */
+  filenames = gimp_core_app_get_filenames (app);
+  if (filenames != NULL)
+    {
+      gint i;
+
+      for (i = 0; filenames[i] != NULL; i++)
+        {
+          GFile *file = g_file_new_for_commandline_arg (filenames[i]);
+
+          file_open_from_command_line (gimp, file,
+                                       gimp_core_app_get_as_new (app),
+                                       initial_monitor);
+
+          g_object_unref (file);
+        }
+    }
+
+  /* The software is now fully loaded and ready to be used and get
+   * external input.
+   */
+  gimp->initialized = TRUE;
+
+  if (font_error)
+    {
+      gimp_message_literal (gimp, NULL,
+                            GIMP_MESSAGE_INFO,
+                            font_error->message);
+      g_error_free (font_error);
+    }
+
+  batch_retval = gimp_batch_run (gimp,
+                                 gimp_core_app_get_batch_interpreter (app),
+                                 gimp_core_app_get_batch_commands (app));
+
+  if (gimp_core_app_get_quit (app))
+    {
+      /*  Only if we are in batch mode, we want to exit with the
+       *  return value of the batch command.
+       */
+      gimp_core_app_set_exit_status (app, batch_retval);
+
+      /* Emit the "exit" signal, but also properly free all images still
+      * opened.
+      */
+      gimp_exit (gimp, TRUE);
+    }
+}
+
 static void
 app_restore_after_callback (Gimp               *gimp,
                             GimpInitStatusFunc  status_callback)
@@ -538,9 +533,9 @@ app_restore_after_callback (Gimp               *gimp,
 }
 
 static gboolean
-app_exit_after_callback (Gimp          *gimp,
-                         gboolean       kill_it,
-                         GApplication **app)
+app_exit_after_callback (Gimp         *gimp,
+                         gboolean      kill_it,
+                         GApplication *app)
 {
   if (gimp->be_verbose)
     g_print ("EXIT: %s\n", G_STRFUNC);
@@ -556,7 +551,7 @@ app_exit_after_callback (Gimp          *gimp,
 
 #ifdef GIMP_UNSTABLE
 
-  g_application_quit (G_APPLICATION (*app));
+  g_application_quit (G_APPLICATION (app));
 
 #else
 
@@ -564,7 +559,7 @@ app_exit_after_callback (Gimp          *gimp,
 
   gegl_exit ();
 
-  exit (gimp_core_app_get_exit_status (GIMP_CORE_APP (*app)));
+  exit (gimp_core_app_get_exit_status (GIMP_CORE_APP (app)));
 
 #endif
 
diff --git a/app/gimpconsoleapp.c b/app/gimpconsoleapp.c
index f9325991f1..82bc5a1adf 100644
--- a/app/gimpconsoleapp.c
+++ b/app/gimpconsoleapp.c
@@ -16,10 +16,17 @@
 
 #include <config.h>
 
-#include "gimpconsoleapp.h"
+#include <gio/gio.h>
 
 #include "libgimpbase/gimpbase.h"
 
+#include "core/core-types.h"
+
+#include "core/gimp.h"
+
+#include "gimpconsoleapp.h"
+#include "gimpcoreapp.h"
+
 struct _GimpConsoleApp
 {
   GApplication parent_instance;
@@ -36,6 +43,10 @@ gimp_console_app_class_init (GimpConsoleAppClass *klass)
   GObjectClass *gobj_class = G_OBJECT_CLASS (klass);
 
   gobj_class->finalize     = gimp_core_app_finalize;
+  gobj_class->get_property = gimp_core_app_get_property;
+  gobj_class->set_property = gimp_core_app_set_property;
+
+  gimp_core_app_install_properties (gobj_class);
 }
 
 static void
@@ -55,11 +66,15 @@ gimp_console_app_new (Gimp        *gimp,
 {
   GimpConsoleApp *app;
 
-  app = g_object_new (GIMP_TYPE_CONSOLE_APP, NULL);
+  app = g_object_new (GIMP_TYPE_CONSOLE_APP,
+                      "gimp",              gimp,
+                      "filenames",         filenames,
+                      "as-new",            as_new,
 
-  gimp_core_app_set_values (GIMP_CORE_APP (app), gimp,
-                            quit, as_new, filenames,
-                            batch_interpreter, batch_commands);
+                      "quit",              quit,
+                      "batch-interpreter", batch_interpreter,
+                      "batch-commands",    batch_commands,
+                      NULL);
 
   return G_APPLICATION (app);
 }
diff --git a/app/gimpconsoleapp.h b/app/gimpconsoleapp.h
index acb717f1e8..7b0fa7ca4c 100644
--- a/app/gimpconsoleapp.h
+++ b/app/gimpconsoleapp.h
@@ -15,9 +15,9 @@
  * <https://www.gnu.org/licenses/>.
  */
 
-#pragma once
+#ifndef __GIMP_CONSOLE_APP_H__
+#define __GIMP_CONSOLE_APP_H__
 
-#include "gimpcoreapp.h"
 
 #define GIMP_TYPE_CONSOLE_APP (gimp_console_app_get_type ())
 G_DECLARE_FINAL_TYPE (GimpConsoleApp, gimp_console_app, GIMP, CONSOLE_APP, GApplication)
@@ -28,3 +28,6 @@ GApplication  *    gimp_console_app_new                   (Gimp         *gimp,
                                                            const char  **filenames,
                                                            const char   *batch_interpreter,
                                                            const char  **batch_commands);
+
+
+#endif /* __GIMP_CONSOLE_APP_H__ */
diff --git a/app/gimpcoreapp.c b/app/gimpcoreapp.c
index 140b8fc49c..fa6468a40c 100644
--- a/app/gimpcoreapp.c
+++ b/app/gimpcoreapp.c
@@ -16,37 +16,38 @@
 
 #include <config.h>
 
-#include "gimpcoreapp.h"
+#include <gio/gio.h>
 
 #include "libgimpbase/gimpbase.h"
 
-#define GIMP_CORE_APP_GET_PRIVATE(obj) (gimp_core_app_get_private ((GimpCoreApp *) (obj)))
+#include "core/core-types.h"
 
-enum
-{
-  PROP_0,
-  PROP_GIMP,
-  N_PROPS
-};
+#include "core/gimp.h"
+
+#include "gimpcoreapp.h"
+
+
+#define GIMP_CORE_APP_GET_PRIVATE(obj) (gimp_core_app_get_private ((GimpCoreApp *) (obj)))
 
 typedef struct _GimpCoreAppPrivate GimpCoreAppPrivate;
 
 struct _GimpCoreAppPrivate
 {
-  Gimp          *gimp;
-  gboolean       quit;
-  gboolean       as_new;
-  const gchar  **filenames;
-  const gchar   *batch_interpreter;
-  const gchar  **batch_commands;
-  gint           exit_status;
+  Gimp       *gimp;
+  gboolean    as_new;
+  gchar     **filenames;
+
+  gboolean    quit;
+  gchar      *batch_interpreter;
+  gchar     **batch_commands;
+  gint        exit_status;
 };
 
 /*  local function prototypes  */
 
-static GimpCoreAppPrivate *
-              gimp_core_app_get_private      (GimpCoreApp        *app);
-static void   gimp_core_app_private_finalize (GimpCoreAppPrivate *private);
+static GimpCoreAppPrivate * gimp_core_app_get_private      (GimpCoreApp        *app);
+static void                 gimp_core_app_private_finalize (GimpCoreAppPrivate *private);
+
 
 G_DEFINE_INTERFACE (GimpCoreApp, gimp_core_app, G_TYPE_OBJECT)
 
@@ -60,26 +61,146 @@ gimp_core_app_default_init (GimpCoreAppInterface *iface)
                                                             "GIMP root object",
                                                             GIMP_TYPE_GIMP,
                                                             GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+  g_object_interface_install_property (iface,
+                                       g_param_spec_boxed ("filenames",
+                                                           "Files to open at start",
+                                                           "Files to open at start",
+                                                           G_TYPE_STRV,
+                                                           GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+  g_object_interface_install_property (iface,
+                                       g_param_spec_boolean ("as-new",
+                                                             "Open images as new",
+                                                             "Open images as new",
+                                                             FALSE,
+                                                             GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
-  iface->get_gimp              = gimp_core_app_get_gimp;
-  iface->get_quit              = gimp_core_app_get_quit;
-  iface->get_as_new            = gimp_core_app_get_as_new;
-  iface->get_filenames         = gimp_core_app_get_filenames;
-  iface->get_batch_interpreter = gimp_core_app_get_batch_interpreter;
-  iface->get_batch_commands    = gimp_core_app_get_batch_commands;
-  iface->set_exit_status       = gimp_core_app_set_exit_status;
-  iface->get_exit_status       = gimp_core_app_get_exit_status;
-  iface->set_values            = gimp_core_app_set_values;
+  g_object_interface_install_property (iface,
+                                       g_param_spec_boolean ("quit",
+                                                             "Quit",
+                                                             "Quit GIMP immediately after running batch 
commands",
+                                                             FALSE,
+                                                             GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+  g_object_interface_install_property (iface,
+                                       g_param_spec_string ("batch-interpreter",
+                                                            "The procedure to process batch commands with",
+                                                            "The procedure to process batch commands with",
+                                                            NULL,
+                                                            GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_interface_install_property (iface,
+                                       g_param_spec_boxed ("batch-commands",
+                                                           "Batch commands to run",
+                                                           "Batch commands to run",
+                                                           G_TYPE_STRV,
+                                                           GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 }
 
+
+/* Protected functions. */
+
 void
 gimp_core_app_finalize (GObject *object)
 {
-  GimpCoreAppPrivate *private = gimp_core_app_get_private ((GimpCoreApp *) object);
+  g_object_set_qdata (object,
+                      g_quark_from_static_string ("gimp-core-app-private"),
+                      NULL);
+}
+
+/**
+ * gimp_container_view_install_properties:
+ * @klass: the class structure for a type deriving from #GObject
+ *
+ * Installs the necessary properties for a class implementing
+ * #GimpCoreApp. Please call this function in the *_class_init()
+ * function of the child class.
+ **/
+void
+gimp_core_app_install_properties (GObjectClass *klass)
+{
+  g_object_class_override_property (klass, GIMP_CORE_APP_PROP_GIMP, "gimp");
+  g_object_class_override_property (klass, GIMP_CORE_APP_PROP_FILENAMES, "filenames");
+  g_object_class_override_property (klass, GIMP_CORE_APP_PROP_AS_NEW, "as-new");
+
+  g_object_class_override_property (klass, GIMP_CORE_APP_PROP_QUIT, "quit");
+  g_object_class_override_property (klass, GIMP_CORE_APP_PROP_BATCH_INTERPRETER, "batch-interpreter");
+  g_object_class_override_property (klass, GIMP_CORE_APP_PROP_BATCH_COMMANDS, "batch-commands");
+}
+
+void
+gimp_core_app_set_property (GObject      *object,
+                            guint         property_id,
+                            const GValue *value,
+                            GParamSpec   *pspec)
+{
+  GimpCoreAppPrivate *private;
+
+  private = GIMP_CORE_APP_GET_PRIVATE (object);
+
+  switch (property_id)
+    {
+    case GIMP_CORE_APP_PROP_GIMP:
+      private->gimp = g_value_get_object (value);
+      break;
+    case GIMP_CORE_APP_PROP_FILENAMES:
+      private->filenames = g_value_dup_boxed (value);
+      break;
+    case GIMP_CORE_APP_PROP_AS_NEW:
+      private->as_new = g_value_get_boolean (value);
+      break;
+    case GIMP_CORE_APP_PROP_QUIT:
+      private->quit = g_value_get_boolean (value);
+      break;
+    case GIMP_CORE_APP_PROP_BATCH_INTERPRETER:
+      private->batch_interpreter = g_value_dup_string (value);
+      break;
+    case GIMP_CORE_APP_PROP_BATCH_COMMANDS:
+      private->batch_commands = g_value_dup_boxed (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+void
+gimp_core_app_get_property (GObject    *object,
+                            guint       property_id,
+                            GValue     *value,
+                            GParamSpec *pspec)
+{
+  GimpCoreAppPrivate *private;
 
-  gimp_core_app_private_finalize (private);
+  private = GIMP_CORE_APP_GET_PRIVATE (object);
+
+  switch (property_id)
+    {
+    case GIMP_CORE_APP_PROP_GIMP:
+      g_value_set_object (value, private->gimp);
+      break;
+    case GIMP_CORE_APP_PROP_FILENAMES:
+      g_value_set_static_boxed (value, private->filenames);
+      break;
+    case GIMP_CORE_APP_PROP_AS_NEW:
+      g_value_set_boolean (value, private->as_new);
+      break;
+    case GIMP_CORE_APP_PROP_QUIT:
+      g_value_set_boolean (value, private->quit);
+      break;
+    case GIMP_CORE_APP_PROP_BATCH_INTERPRETER:
+      g_value_set_static_string (value, private->batch_interpreter);
+      break;
+    case GIMP_CORE_APP_PROP_BATCH_COMMANDS:
+      g_value_set_static_boxed (value, private->batch_commands);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
 }
 
+
+/* Public functions. */
+
 Gimp *
 gimp_core_app_get_gimp (GimpCoreApp *self)
 {
@@ -116,7 +237,7 @@ gimp_core_app_get_as_new (GimpCoreApp *self)
   return private->as_new;
 }
 
-const char **
+const gchar **
 gimp_core_app_get_filenames (GimpCoreApp *self)
 {
   GimpCoreAppPrivate *private;
@@ -125,10 +246,10 @@ gimp_core_app_get_filenames (GimpCoreApp *self)
 
   private = GIMP_CORE_APP_GET_PRIVATE (self);
 
-  return private->filenames;
+  return (const gchar **) private->filenames;
 }
 
-const char *
+const gchar *
 gimp_core_app_get_batch_interpreter (GimpCoreApp *self)
 {
   GimpCoreAppPrivate *private;
@@ -137,10 +258,10 @@ gimp_core_app_get_batch_interpreter (GimpCoreApp *self)
 
   private = GIMP_CORE_APP_GET_PRIVATE (self);
 
-  return private->batch_interpreter;
+  return (const gchar *) private->batch_interpreter;
 }
 
-const char **
+const gchar **
 gimp_core_app_get_batch_commands (GimpCoreApp *self)
 {
   GimpCoreAppPrivate *private;
@@ -149,7 +270,7 @@ gimp_core_app_get_batch_commands (GimpCoreApp *self)
 
   private = GIMP_CORE_APP_GET_PRIVATE (self);
 
-  return private->batch_commands;
+  return (const gchar **) private->batch_commands;
 }
 
 void
@@ -176,39 +297,8 @@ gimp_core_app_get_exit_status (GimpCoreApp *self)
   return private->exit_status;
 }
 
-void
-gimp_core_app_set_values(GimpCoreApp  *self,
-                         Gimp         *gimp,
-                         gboolean      quit,
-                         gboolean      as_new,
-                         const gchar **filenames,
-                         const gchar  *batch_interpreter,
-                         const gchar **batch_commands)
-{
-  GimpCoreAppPrivate *private;
-
-  g_return_if_fail (GIMP_IS_CORE_APP (self));
-
-  private = GIMP_CORE_APP_GET_PRIVATE (self);
-
-  private->gimp              = gimp;
-  private->quit              = quit;
-  private->as_new            = as_new;
-  private->filenames         = filenames;
-  private->batch_interpreter = batch_interpreter;
-  private->batch_commands    = batch_commands;
-}
-
 /*  Private functions  */
 
-static void
-gimp_core_app_private_finalize (GimpCoreAppPrivate *private)
-{
-  g_slice_free (GimpCoreAppPrivate, private);
-
-  g_clear_object (&private->gimp);
-}
-
 static GimpCoreAppPrivate *
 gimp_core_app_get_private (GimpCoreApp *app)
 {
@@ -229,11 +319,17 @@ gimp_core_app_get_private (GimpCoreApp *app)
 
       g_object_set_qdata_full ((GObject *) app, private_key, private,
                                (GDestroyNotify) gimp_core_app_private_finalize);
-
-      /* g_signal_connect (view, "destroy",
-                        G_CALLBACK (gimp_core_app_private_dispose),
-                        private); */
     }
 
   return private;
 }
+
+static void
+gimp_core_app_private_finalize (GimpCoreAppPrivate *private)
+{
+  g_clear_pointer (&private->filenames, g_strfreev);
+  g_clear_pointer (&private->batch_interpreter, g_free);
+  g_clear_pointer (&private->batch_commands, g_strfreev);
+
+  g_slice_free (GimpCoreAppPrivate, private);
+}
diff --git a/app/gimpcoreapp.h b/app/gimpcoreapp.h
index 5967adbdf6..88153d6f89 100644
--- a/app/gimpcoreapp.h
+++ b/app/gimpcoreapp.h
@@ -15,14 +15,24 @@
  * <https://www.gnu.org/licenses/>.
  */
 
-#pragma once
+#ifndef __GIMP_CORE_APP_H__
+#define __GIMP_CORE_APP_H__
 
-#include <gio/gio.h>
+G_BEGIN_DECLS
 
-#include "core/core-types.h"
-#include "core/gimp.h"
+enum
+{
+  GIMP_CORE_APP_PROP_0,
+  GIMP_CORE_APP_PROP_GIMP,
+  GIMP_CORE_APP_PROP_FILENAMES,
+  GIMP_CORE_APP_PROP_AS_NEW,
 
-G_BEGIN_DECLS
+  GIMP_CORE_APP_PROP_QUIT,
+  GIMP_CORE_APP_PROP_BATCH_INTERPRETER,
+  GIMP_CORE_APP_PROP_BATCH_COMMANDS,
+
+  GIMP_CORE_APP_PROP_LAST = GIMP_CORE_APP_PROP_BATCH_COMMANDS,
+};
 
 #define GIMP_TYPE_CORE_APP gimp_core_app_get_type()
 G_DECLARE_INTERFACE (GimpCoreApp, gimp_core_app, GIMP, CORE_APP, GObject)
@@ -31,23 +41,6 @@ struct _GimpCoreAppInterface
 {
   GTypeInterface parent_iface;
 
-  Gimp *        (*get_gimp)              (GimpCoreApp  *self);
-  gboolean      (*get_quit)              (GimpCoreApp  *self);
-  gboolean      (*get_as_new)            (GimpCoreApp  *self);
-  const char ** (*get_filenames)         (GimpCoreApp *self);
-  const char *  (*get_batch_interpreter) (GimpCoreApp *self);
-  const char ** (*get_batch_commands)    (GimpCoreApp *self);
-  void          (*set_exit_status)       (GimpCoreApp *self,
-                                          gint         exit_status);
-  gint          (*get_exit_status)       (GimpCoreApp *self);
-  void          (*set_values)            (GimpCoreApp *self,
-                                          Gimp        *gimp,
-                                          gboolean     quit,
-                                          gboolean     as_new,
-                                          const char **filenames,
-                                          const char  *batch_interpreter,
-                                          const char **batch_commands);
-
   /* Padding to allow adding up to 12 new virtual functions without
    * breaking ABI. */
   gpointer padding[12];
@@ -61,23 +54,31 @@ gboolean           gimp_core_app_get_quit              (GimpCoreApp *self);
 
 gboolean           gimp_core_app_get_as_new            (GimpCoreApp *self);
 
-const char **      gimp_core_app_get_filenames         (GimpCoreApp *self);
+const gchar **     gimp_core_app_get_filenames         (GimpCoreApp *self);
 
-const char *       gimp_core_app_get_batch_interpreter (GimpCoreApp *self);
+const gchar *      gimp_core_app_get_batch_interpreter (GimpCoreApp *self);
 
-const char **      gimp_core_app_get_batch_commands    (GimpCoreApp *self);
+const gchar **     gimp_core_app_get_batch_commands    (GimpCoreApp *self);
 
 void               gimp_core_app_set_exit_status       (GimpCoreApp *self,
                                                         gint         exit_status);
 
 gboolean           gimp_core_app_get_exit_status       (GimpCoreApp *self);
 
-void               gimp_core_app_set_values            (GimpCoreApp *self,
-                                                        Gimp        *gimp,
-                                                        gboolean     quit,
-                                                        gboolean     as_new,
-                                                        const char **filenames,
-                                                        const char  *batch_interpreter,
-                                                        const char **batch_commands);
+
+/* Protected functions. */
+
+void               gimp_core_app_install_properties    (GObjectClass *klass);
+void               gimp_core_app_get_property          (GObject      *object,
+                                                        guint         property_id,
+                                                        GValue       *value,
+                                                        GParamSpec   *pspec);
+void               gimp_core_app_set_property          (GObject      *object,
+                                                        guint         property_id,
+                                                        const GValue *value,
+                                                        GParamSpec   *pspec);
+
 
 G_END_DECLS
+
+#endif /* __GIMP_CORE_APP_H__ */
diff --git a/app/gui/gimpapp.c b/app/gui/gimpapp.c
index 98b9afa541..cb1274d4ca 100644
--- a/app/gui/gimpapp.c
+++ b/app/gui/gimpapp.c
@@ -16,10 +16,25 @@
 
 #include <config.h>
 
-#include "gimpapp.h"
+#include <gtk/gtk.h>
 
 #include "libgimpbase/gimpbase.h"
 
+#include "core/core-types.h"
+
+#include "core/gimp.h"
+
+#include "gimpcoreapp.h"
+
+#include "gimpapp.h"
+
+
+enum
+{
+  PROP_0,
+  PROP_NO_SPLASH = GIMP_CORE_APP_PROP_LAST + 1,
+};
+
 struct _GimpApp
 {
   GtkApplication parent_instance;
@@ -27,9 +42,20 @@ struct _GimpApp
   gboolean       no_splash;
 };
 
+
+static void gimp_app_get_property (GObject      *object,
+                                   guint         property_id,
+                                   GValue       *value,
+                                   GParamSpec   *pspec);
+static void gimp_app_set_property (GObject      *object,
+                                   guint         property_id,
+                                   const GValue *value,
+                                   GParamSpec   *pspec);
+
+
 G_DEFINE_TYPE_WITH_CODE (GimpApp, gimp_app, GTK_TYPE_APPLICATION,
                          G_IMPLEMENT_INTERFACE (GIMP_TYPE_CORE_APP,
-                                                gimp_app_class_init))
+                                                NULL))
 
 
 static void
@@ -38,6 +64,16 @@ gimp_app_class_init (GimpAppClass *klass)
   GObjectClass *gobj_class = G_OBJECT_CLASS (klass);
 
   gobj_class->finalize     = gimp_core_app_finalize;
+  gobj_class->get_property = gimp_app_get_property;
+  gobj_class->set_property = gimp_app_set_property;
+
+  gimp_core_app_install_properties (gobj_class);
+
+  g_object_class_install_property (gobj_class, PROP_NO_SPLASH,
+                                   g_param_spec_boolean ("no-splash", NULL, NULL,
+                                                         FALSE,
+                                                         GIMP_PARAM_READWRITE |
+                                                         G_PARAM_CONSTRUCT_ONLY));
 }
 
 static void
@@ -45,6 +81,42 @@ gimp_app_init (GimpApp *self)
 {
 }
 
+static void
+gimp_app_get_property (GObject    *object,
+                       guint       property_id,
+                       GValue     *value,
+                       GParamSpec *pspec)
+{
+  switch (property_id)
+    {
+    case PROP_NO_SPLASH:
+      g_value_set_boolean (value, GIMP_APP (object)->no_splash);
+      break;
+
+    default:
+      gimp_core_app_get_property (object, property_id, value, pspec);
+      break;
+    }
+}
+
+static void
+gimp_app_set_property (GObject      *object,
+                       guint         property_id,
+                       const GValue *value,
+                       GParamSpec   *pspec)
+{
+  switch (property_id)
+    {
+    case PROP_NO_SPLASH:
+      GIMP_APP (object)->no_splash = g_value_get_boolean (value);
+      break;
+
+    default:
+      gimp_core_app_set_property (object, property_id, value, pspec);
+      break;
+    }
+}
+
 /*  public functions  */
 
 GApplication *
@@ -58,15 +130,17 @@ gimp_app_new (Gimp        *gimp,
 {
   GimpApp *app;
 
-  app = g_object_new (GIMP_TYPE_APP, NULL);
+  app = g_object_new (GIMP_TYPE_APP,
+                      "gimp",              gimp,
+                      "filenames",         filenames,
+                      "as-new",            as_new,
 
-  /* We shouldn't have to pass these externally, so I didn't bother making
-   * GObject properties for them. In the end, they should just be parsed by
-   * the GApplication code */
-  app->no_splash         = no_splash;
+                      "quit",              quit,
+                      "batch-interpreter", batch_interpreter,
+                      "batch-commands",    batch_commands,
 
-  gimp_core_app_set_values(GIMP_CORE_APP(app), gimp, quit, as_new, filenames,
-                           batch_interpreter, batch_commands);
+                      "no-splash",         no_splash,
+                      NULL);
 
   return G_APPLICATION (app);
 }
diff --git a/app/gui/gimpapp.h b/app/gui/gimpapp.h
index bf4cb18068..c60c76753b 100644
--- a/app/gui/gimpapp.h
+++ b/app/gui/gimpapp.h
@@ -1,4 +1,3 @@
-
 /* GIMP - The GNU Image Manipulation Program
  * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
  *
@@ -18,9 +17,6 @@
 #ifndef __GIMP_APP_H__
 #define __GIMP_APP_H__
 
-#include <gtk/gtk.h>
-
-#include "gimpcoreapp.h"
 
 #define GIMP_TYPE_APP (gimp_app_get_type ())
 G_DECLARE_FINAL_TYPE (GimpApp, gimp_app, GIMP, APP, GtkApplication)
diff --git a/app/gui/gui-types.h b/app/gui/gui-types.h
index 82e9f20ea5..294192c652 100644
--- a/app/gui/gui-types.h
+++ b/app/gui/gui-types.h
@@ -23,5 +23,6 @@
 #include "dialogs/dialogs-types.h"
 #include "menus/menus-types.h"
 
+#include "gimpapp.h"
 
 #endif /* __GUI_TYPES_H__ */
diff --git a/app/gui/gui.c b/app/gui/gui.c
index bf4b099fac..1538cf9790 100644
--- a/app/gui/gui.c
+++ b/app/gui/gui.c
@@ -27,6 +27,7 @@
 #include "libgimpwidgets/gimpwidgets-private.h"
 
 #include "gui-types.h"
+#include "gimpapp.h"
 
 #include "config/gimpguiconfig.h"
 
diff --git a/app/gui/gui.h b/app/gui/gui.h
index e64f5fa1d9..8bfdb312b3 100644
--- a/app/gui/gui.h
+++ b/app/gui/gui.h
@@ -18,7 +18,6 @@
 #ifndef __GUI_H__
 #define __GUI_H__
 
-#include "gimpapp.h"
 
 void               gui_libs_init (GOptionContext *context);
 void               gui_abort     (const gchar    *abort_message);
diff --git a/app/gui/splash.h b/app/gui/splash.h
index 51e8af63de..9f18e02ea1 100644
--- a/app/gui/splash.h
+++ b/app/gui/splash.h
@@ -18,8 +18,6 @@
 #ifndef __SPLASH_H__
 #define __SPLASH_H__
 
-#include "gimpapp.h"
-
 void   splash_create    (Gimp         *gimp,
                          gboolean      be_verbose,
                          GdkMonitor   *monitor,


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