From 677c364559b91f0379166e43436cde91222d9645 Mon Sep 17 00:00:00 2001 From: Niels De Graef Date: Sun, 19 Dec 2021 18:09:28 +0100 Subject: [PATCH 1/2] app: initial work on moving to GtkApplication. Reviewer's message (Jehan): This was a work-in-progress by Niels, which we only keep in this state because Lukas worked over it. I have rebased and fix-amended many broken part of this commit, because various things had been changed in these areas of code since this commit was initially written. --- app/Makefile.am | 2 + app/app.c | 317 +++++++++++++++++----------------- app/display/gimpimagewindow.c | 1 + app/gimpapp.c | 191 ++++++++++++++++++++ app/gimpapp.h | 46 +++++ app/gui/gui.c | 10 +- app/gui/gui.h | 1 + app/gui/splash.c | 11 +- app/gui/splash.h | 7 +- app/meson.build | 1 + app/tests.c | 2 +- app/widgets/gimpwindow.c | 2 +- app/widgets/gimpwindow.h | 6 +- 13 files changed, 421 insertions(+), 176 deletions(-) create mode 100644 app/gimpapp.c create mode 100644 app/gimpapp.h diff --git a/app/Makefile.am b/app/Makefile.am index 58746081119..07bae5532ef 100644 --- a/app/Makefile.am +++ b/app/Makefile.am @@ -57,6 +57,8 @@ libapp_sources = \ app.h \ errors.c \ errors.h \ + gimpapp.c \ + gimpapp.h \ language.c \ language.h \ sanity.c \ diff --git a/app/app.c b/app/app.c index 8e171fe786a..e564fe06371 100644 --- a/app/app.c +++ b/app/app.c @@ -67,6 +67,7 @@ #include "app.h" #include "errors.h" +#include "gimpapp.h" #include "sanity.h" #include "gimp-debug.h" @@ -83,7 +84,7 @@ static void app_restore_after_callback (Gimp *gimp, GimpInitStatusFunc status_callback); static gboolean app_exit_after_callback (Gimp *gimp, gboolean kill_it, - GMainLoop **loop); + GimpApp **app); #if 0 /* left here as documentation how to do compat enums */ @@ -161,6 +162,142 @@ app_exit (gint status) exit (status); } +static void +app_activate_callback (GApplication *gapp, + gpointer user_data) +{ + GimpApp *app = GIMP_APP (gapp); + Gimp *gimp = NULL; + GimpInitStatusFunc update_status_func = NULL; + + gimp = gimp_app_get_gimp (app); + +#ifndef GIMP_CONSOLE_COMPILATION + if (! gimp->no_interface) + update_status_func = gui_init (gimp, gimp_app_get_no_splash (app), gapp, 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); + + /* Load all data files */ + gimp_restore (gimp, update_status_func, NULL); + + /* 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); + + /* Set this after gimp_update_auto_check(). This will be used for the + * next run. + */ + g_object_set (gimp->edit_config, + "config-version", GIMP_VERSION, + 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_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 + + //XXX +#if 0 + /* Load the images given on the command-line. */ + if (filenames) + { + 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_app_get_as_new (app), + initial_monitor); + + g_object_unref (file); + } + } + } +#endif + + /* The software is now fully loaded and ready to be used and get + * external input. + */ + gimp->initialized = TRUE; + + if (app) + { + gimp_batch_run (gimp, + gimp_app_get_batch_interpreter (app), + gimp_app_get_batch_commands (app)); + } +} + gint app_run (const gchar *full_prog_name, const gchar **filenames, @@ -186,15 +323,12 @@ app_run (const gchar *full_prog_name, GimpPDBCompatMode pdb_compat_mode, const gchar *backtrace_file) { - GimpInitStatusFunc update_status_func = NULL; - Gimp *gimp; - GMainLoop *loop; - GMainLoop *run_loop; - GFile *default_folder = NULL; - GFile *gimpdir; - const gchar *abort_message; - GError *font_error = NULL; - gint retval = EXIT_SUCCESS; + Gimp *gimp = NULL; + GApplication *app = NULL; + GFile *default_folder = NULL; + GFile *gimpdir = NULL; + const gchar *abort_message = NULL; + gint retval = EXIT_SUCCESS; if (filenames && filenames[0] && ! filenames[1] && g_file_test (filenames[0], G_FILE_TEST_IS_DIR)) @@ -234,13 +368,13 @@ app_run (const gchar *full_prog_name, stack_trace_mode, pdb_compat_mode); - if (default_folder) - g_object_unref (default_folder); + g_clear_object (&default_folder); + + app = gimp_app_new (gimp, no_splash, as_new, batch_interpreter, batch_commands); gimp_cpu_accel_set_use (use_cpu_accel); - /* Check if the user's gimp_directory exists - */ + /* Check if the user's gimp_directory exists */ gimpdir = gimp_directory_file (NULL); if (g_file_query_file_type (gimpdir, G_FILE_QUERY_INFO_NONE, NULL) != @@ -296,155 +430,20 @@ app_run (const gchar *full_prog_name, G_CALLBACK (app_restore_after_callback), NULL); -#ifndef GIMP_CONSOLE_COMPILATION - if (! no_interface) - update_status_func = gui_init (gimp, no_splash, 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); - - /* 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); - - /* Set this after gimp_update_auto_check(). This will be used for the - * next run. - */ - g_object_set (gimp->edit_config, - "config-version", GIMP_VERSION, - NULL); - - loop = run_loop = g_main_loop_new (NULL, FALSE); - g_signal_connect_after (gimp, "exit", G_CALLBACK (app_exit_after_callback), - &run_loop); - -#ifndef GIMP_CONSOLE_COMPILATION - if (run_loop && ! 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, as_new, - 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 + &app); - /* Load the images given on the command-line. */ - if (filenames) - { - gint i; + g_signal_connect (app, "activate", + G_CALLBACK (app_activate_callback), + NULL); - for (i = 0; filenames[i] != NULL; i++) - { - if (run_loop) - { - GFile *file = g_file_new_for_commandline_arg (filenames[i]); - - file_open_from_command_line (gimp, file, as_new, - 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 (run_loop) - retval = gimp_batch_run (gimp, batch_interpreter, batch_commands); - - if (quit) - /* Emit the "exit" signal, but also properly free all images still - * opened. - */ - gimp_exit (gimp, TRUE); - else - /* Only take into account the batch commands' success when we - * return immediately. - */ - retval = EXIT_SUCCESS; - - if (run_loop) - g_main_loop_run (loop); + g_application_run (app, 0, NULL); if (gimp->be_verbose) g_print ("EXIT: %s\n", G_STRFUNC); - g_main_loop_unref (loop); + g_clear_object (&app); gimp_gegl_exit (gimp); @@ -490,7 +489,7 @@ app_restore_after_callback (Gimp *gimp, static gboolean app_exit_after_callback (Gimp *gimp, gboolean kill_it, - GMainLoop **loop) + GimpApp **app) { if (gimp->be_verbose) g_print ("EXIT: %s\n", G_STRFUNC); @@ -506,10 +505,8 @@ app_exit_after_callback (Gimp *gimp, #ifdef GIMP_UNSTABLE - if (g_main_loop_is_running (*loop)) - g_main_loop_quit (*loop); - - *loop = NULL; + g_application_quit (G_APPLICATION (*app)); + *app = NULL; #else diff --git a/app/display/gimpimagewindow.c b/app/display/gimpimagewindow.c index 1499c27eed8..d407cbf471e 100644 --- a/app/display/gimpimagewindow.c +++ b/app/display/gimpimagewindow.c @@ -1114,6 +1114,7 @@ gimp_image_window_new (Gimp *gimp, "gimp", gimp, "dialog-factory", dialog_factory, "initial-monitor", monitor, + "application", g_application_get_default (), /* The window position will be overridden by the * dialog factory, it is only really used on first * startup. diff --git a/app/gimpapp.c b/app/gimpapp.c new file mode 100644 index 00000000000..7b69bc7a4f9 --- /dev/null +++ b/app/gimpapp.c @@ -0,0 +1,191 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpapp.c + * Copyright (C) 2021 Niels De Graef + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include "gimpapp.h" + +#include "libgimpbase/gimpbase.h" + + +enum +{ + PROP_0, + PROP_GIMP, + N_PROPS +}; + +struct _GimpApp +{ + GtkApplication parent_instance; + + Gimp *gimp; + + gboolean no_splash; + gboolean as_new; + const gchar *batch_interpreter; + const gchar **batch_commands; +}; + + +static void gimp_app_finalize (GObject *object); +static void gimp_app_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_app_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + + +G_DEFINE_TYPE (GimpApp, gimp_app, GTK_TYPE_APPLICATION) + +static GParamSpec *props[N_PROPS] = { NULL, }; + + +static void +gimp_app_class_init (GimpAppClass *klass) +{ + GObjectClass *gobj_class = G_OBJECT_CLASS (klass); + + gobj_class->get_property = gimp_app_get_property; + gobj_class->set_property = gimp_app_set_property; + gobj_class->finalize = gimp_app_finalize; + + props[PROP_GIMP] = + g_param_spec_object ("gimp", "GIMP", "GIMP root object", + GIMP_TYPE_GIMP, + GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + + g_object_class_install_properties (gobj_class, N_PROPS, props); +} + +static void +gimp_app_init (GimpApp *self) +{ +} + +static void +gimp_app_finalize (GObject *object) +{ + GimpApp *self = GIMP_APP (object); + + g_clear_object (&self->gimp); + + G_OBJECT_CLASS (gimp_app_parent_class)->finalize (object); +} + +static void +gimp_app_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpApp *self = GIMP_APP (object); + + switch (property_id) + { + case PROP_GIMP: + g_value_set_object (value, self->gimp); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_app_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpApp *self = GIMP_APP (object); + + switch (property_id) + { + case PROP_GIMP: + self->gimp = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +/* public functions */ + +GApplication * +gimp_app_new (Gimp *gimp, + gboolean no_splash, + gboolean as_new, + const char *batch_interpreter, + const char **batch_commands) +{ + GimpApp *app; + + app = g_object_new (GIMP_TYPE_APP, + "gimp", gimp, + NULL); + + /* 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; + app->as_new = as_new; + app->batch_interpreter = batch_interpreter; + app->batch_commands = batch_commands; + + return G_APPLICATION (app); +} + +Gimp * +gimp_app_get_gimp (GimpApp *self) +{ + g_return_val_if_fail (GIMP_IS_APP (self), NULL); + return self->gimp; +} + +gboolean +gimp_app_get_no_splash (GimpApp *self) +{ + g_return_val_if_fail (GIMP_IS_APP (self), FALSE); + return self->no_splash; +} + +gboolean +gimp_app_get_as_new (GimpApp *self) +{ + g_return_val_if_fail (GIMP_IS_APP (self), FALSE); + return self->as_new; +} + +const char * +gimp_app_get_batch_interpreter (GimpApp *self) +{ + g_return_val_if_fail (GIMP_IS_APP (self), NULL); + return self->batch_interpreter; +} + +const char ** +gimp_app_get_batch_commands (GimpApp *self) +{ + g_return_val_if_fail (GIMP_IS_APP (self), NULL); + return self->batch_commands; +} diff --git a/app/gimpapp.h b/app/gimpapp.h new file mode 100644 index 00000000000..1a8a1c39896 --- /dev/null +++ b/app/gimpapp.h @@ -0,0 +1,46 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpapp.h + * Copyright (C) 2021 Niels De Graef + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#ifndef __GIMP_APP_H__ +#define __GIMP_APP_H__ + +#include +#include + +#include "core/core-types.h" +#include "core/gimp.h" + +#define GIMP_TYPE_APP (gimp_app_get_type ()) +G_DECLARE_FINAL_TYPE (GimpApp, gimp_app, GIMP, APP, GtkApplication) + + +GApplication * gimp_app_new (Gimp *gimp, + gboolean no_splash, + gboolean as_new, + const char *batch_interpreter, + const char **batch_commands); + +Gimp * gimp_app_get_gimp (GimpApp *self); + +gboolean gimp_app_get_no_splash (GimpApp *self); + +gboolean gimp_app_get_as_new (GimpApp *self); + +const char * gimp_app_get_batch_interpreter (GimpApp *self); + +const char ** gimp_app_get_batch_commands (GimpApp *self); + +#endif /* __GIMP_APP_H__ */ diff --git a/app/gui/gui.c b/app/gui/gui.c index c2f69af9eae..91507999d9f 100644 --- a/app/gui/gui.c +++ b/app/gui/gui.c @@ -222,15 +222,17 @@ gui_abort (const gchar *abort_message) * unit testing calls. */ GimpInitStatusFunc -gui_init (Gimp *gimp, - gboolean no_splash, - const gchar *test_base_dir) +gui_init (Gimp *gimp, + gboolean no_splash, + GApplication *app, + const gchar *test_base_dir) { GimpInitStatusFunc status_callback = NULL; gchar *abort_message; g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); g_return_val_if_fail (the_gui_gimp == NULL, NULL); + g_return_val_if_fail (G_IS_APPLICATION (app) || app == NULL, NULL); abort_message = gui_sanity_check (); if (abort_message) @@ -283,7 +285,7 @@ gui_init (Gimp *gimp, if (! no_splash) { - splash_create (gimp, gimp->be_verbose, initial_monitor); + splash_create (gimp, gimp->be_verbose, initial_monitor, app); status_callback = splash_update; } diff --git a/app/gui/gui.h b/app/gui/gui.h index a5cf0fecc4b..af88b086137 100644 --- a/app/gui/gui.h +++ b/app/gui/gui.h @@ -24,6 +24,7 @@ void gui_abort (const gchar *abort_message); GimpInitStatusFunc gui_init (Gimp *gimp, gboolean no_splash, + GApplication *app, const gchar *test_base_dir); gboolean gui_recover (gint n_recoveries); diff --git a/app/gui/splash.c b/app/gui/splash.c index 8df1d8039a4..3ce1bc3d6cf 100644 --- a/app/gui/splash.c +++ b/app/gui/splash.c @@ -109,9 +109,10 @@ static void splash_timer_elapsed (void); /* public functions */ void -splash_create (Gimp *gimp, - gboolean be_verbose, - GdkMonitor *monitor) +splash_create (Gimp *gimp, + gboolean be_verbose, + GdkMonitor *monitor, + GApplication *app) { GtkWidget *frame; GtkWidget *vbox; @@ -123,6 +124,7 @@ splash_create (Gimp *gimp, g_return_if_fail (splash == NULL); g_return_if_fail (GDK_IS_MONITOR (monitor)); + g_return_if_fail (G_IS_APPLICATION (app) || app == NULL); gdk_monitor_get_workarea (monitor, &workarea); @@ -162,13 +164,14 @@ splash_create (Gimp *gimp, splash = g_slice_new0 (GimpSplash); splash->window = - g_object_new (GTK_TYPE_WINDOW, + g_object_new (GTK_TYPE_APPLICATION_WINDOW, "type", GTK_WINDOW_TOPLEVEL, "type-hint", GDK_WINDOW_TYPE_HINT_SPLASHSCREEN, "title", _("GIMP Startup"), "role", "gimp-startup", "window-position", GTK_WIN_POS_CENTER, "resizable", FALSE, + "application", app, NULL); /* Don't remove this call, it's necessary to remove decorations on Windows diff --git a/app/gui/splash.h b/app/gui/splash.h index e3d86da9fba..c6fb9fdfb39 100644 --- a/app/gui/splash.h +++ b/app/gui/splash.h @@ -19,9 +19,10 @@ #define __SPLASH_H__ -void splash_create (Gimp *gimp, - gboolean be_verbose, - GdkMonitor *mointor); +void splash_create (Gimp *gimp, + gboolean be_verbose, + GdkMonitor *mointor, + GApplication *app); void splash_destroy (void); void splash_update (const gchar *label1, diff --git a/app/meson.build b/app/meson.build index 4bc7ea2cca3..11bbadefa7b 100644 --- a/app/meson.build +++ b/app/meson.build @@ -50,6 +50,7 @@ app_debug_files = files( libapp_sources = [ 'app.c', 'errors.c', + 'gimpapp.c', 'gimp-debug.c', 'gimp-log.c', 'gimp-update.c', diff --git a/app/tests.c b/app/tests.c index c1b26c4ff98..3777057631d 100644 --- a/app/tests.c +++ b/app/tests.c @@ -138,7 +138,7 @@ gimp_init_for_gui_testing_internal (gboolean show_gui, gimp_set_show_gui (gimp, show_gui); gimp_load_config (gimp, gimprc, NULL); gimp_gegl_init (gimp); - gui_init (gimp, TRUE, g_getenv ("GIMP_TESTING_ABS_TOP_SRCDIR")); + gui_init (gimp, TRUE, NULL, g_getenv ("GIMP_TESTING_ABS_TOP_SRCDIR")); gimp_init_icon_theme_for_testing (); gimp_initialize (gimp, gimp_status_func_dummy); gimp_restore (gimp, gimp_status_func_dummy, NULL); diff --git a/app/widgets/gimpwindow.c b/app/widgets/gimpwindow.c index d9bc728c9eb..866bb1f92a4 100644 --- a/app/widgets/gimpwindow.c +++ b/app/widgets/gimpwindow.c @@ -59,7 +59,7 @@ static gboolean gimp_window_key_press_event (GtkWidget *widget, GdkEventKey *kevent); -G_DEFINE_TYPE_WITH_PRIVATE (GimpWindow, gimp_window, GTK_TYPE_WINDOW) +G_DEFINE_TYPE_WITH_PRIVATE (GimpWindow, gimp_window, GTK_TYPE_APPLICATION_WINDOW) #define parent_class gimp_window_parent_class diff --git a/app/widgets/gimpwindow.h b/app/widgets/gimpwindow.h index 9ee3af2cb16..be372a138d0 100644 --- a/app/widgets/gimpwindow.h +++ b/app/widgets/gimpwindow.h @@ -34,14 +34,14 @@ typedef struct _GimpWindowPrivate GimpWindowPrivate; struct _GimpWindow { - GtkWindow parent_instance; + GtkApplicationWindow parent_instance; - GimpWindowPrivate *private; + GimpWindowPrivate *private; }; struct _GimpWindowClass { - GtkWindowClass parent_class; + GtkApplicationWindowClass parent_class; void (* monitor_changed) (GimpWindow *window, GdkMonitor *monitor); -- GitLab From df8fe12a86ad9bd9f0a87d9adfbb4a1f081df63e Mon Sep 17 00:00:00 2001 From: Lukas Oberhuber Date: Mon, 7 Feb 2022 10:02:19 +0000 Subject: [PATCH 2/2] app: Add in gimpconsoleapp and gimpcoreapp interface GimpApp is a GtkApplication GimpCoreApp is an interface for common functions GimpConsoleApp is a GtkApplication (to avoid linking in Gtk) --- app/Makefile.am | 6 +- app/app.c | 63 ++++++++----- app/gimpapp.h | 46 ---------- app/gimpconsoleapp.c | 197 ++++++++++++++++++++++++++++++++++++++++ app/gimpconsoleapp.h | 39 ++++++++ app/gimpcoreapp.c | 95 +++++++++++++++++++ app/gimpcoreapp.h | 55 +++++++++++ app/gui/Makefile.am | 2 + app/{ => gui}/gimpapp.c | 76 ++++++++++------ app/gui/gimpapp.h | 47 ++++++++++ app/gui/gui.c | 6 +- app/gui/gui.h | 3 +- app/gui/meson.build | 1 + app/gui/splash.c | 6 +- app/gui/splash.h | 5 +- app/meson.build | 3 +- 16 files changed, 536 insertions(+), 114 deletions(-) delete mode 100644 app/gimpapp.h create mode 100644 app/gimpconsoleapp.c create mode 100644 app/gimpconsoleapp.h create mode 100644 app/gimpcoreapp.c create mode 100644 app/gimpcoreapp.h rename app/{ => gui}/gimpapp.c (60%) create mode 100644 app/gui/gimpapp.h diff --git a/app/Makefile.am b/app/Makefile.am index 07bae5532ef..8fea0e4569f 100644 --- a/app/Makefile.am +++ b/app/Makefile.am @@ -57,8 +57,10 @@ libapp_sources = \ app.h \ errors.c \ errors.h \ - gimpapp.c \ - gimpapp.h \ + gimpcoreapp.c \ + gimpcoreapp.h \ + gimpconsoleapp.c \ + gimpconsoleapp.h \ language.c \ language.h \ sanity.c \ diff --git a/app/app.c b/app/app.c index e564fe06371..7a9088e8305 100644 --- a/app/app.c +++ b/app/app.c @@ -67,7 +67,10 @@ #include "app.h" #include "errors.h" -#include "gimpapp.h" +#ifndef GIMP_CONSOLE_COMPILATION +#include "gui/gimpapp.h" +#endif +#include "gimpconsoleapp.h" #include "sanity.h" #include "gimp-debug.h" @@ -84,7 +87,7 @@ static void app_restore_after_callback (Gimp *gimp, GimpInitStatusFunc status_callback); static gboolean app_exit_after_callback (Gimp *gimp, gboolean kill_it, - GimpApp **app); + GApplication **app); #if 0 /* left here as documentation how to do compat enums */ @@ -163,18 +166,20 @@ app_exit (gint status) } static void -app_activate_callback (GApplication *gapp, - gpointer user_data) +app_activate_callback (GimpCoreApp *app, + gpointer user_data) { - GimpApp *app = GIMP_APP (gapp); Gimp *gimp = NULL; GimpInitStatusFunc update_status_func = NULL; + const gchar **filenames; + + g_return_if_fail (GIMP_IS_CORE_APP (app)); - gimp = gimp_app_get_gimp (app); + gimp = gimp_core_app_get_gimp (app); #ifndef GIMP_CONSOLE_COMPILATION if (! gimp->no_interface) - update_status_func = gui_init (gimp, gimp_app_get_no_splash (app), gapp, NULL); + update_status_func = gui_init (gimp, gimp_app_get_no_splash (GIMP_APP (app)), GIMP_APP (app), NULL); #endif if (! update_status_func) @@ -231,7 +236,7 @@ app_activate_callback (GApplication *gapp, gimp_get_user_context (gimp), NULL, file, - gimp_app_get_as_new (app), + gimp_core_app_get_as_new (app), initial_monitor, &status, &error); if (image) @@ -262,10 +267,9 @@ app_activate_callback (GApplication *gapp, } #endif - //XXX -#if 0 /* Load the images given on the command-line. */ - if (filenames) + filenames = gimp_core_app_get_filenames (app); + if (filenames != NULL) { gint i; @@ -276,14 +280,13 @@ app_activate_callback (GApplication *gapp, GFile *file = g_file_new_for_commandline_arg (filenames[i]); file_open_from_command_line (gimp, file, - gimp_app_get_as_new (app), + gimp_core_app_get_as_new (app), initial_monitor); g_object_unref (file); } } } -#endif /* The software is now fully loaded and ready to be used and get * external input. @@ -292,9 +295,15 @@ app_activate_callback (GApplication *gapp, if (app) { + const char *batch_interpreter; + const char **batch_commands; + + batch_interpreter = gimp_core_app_get_batch_interpreter (app); + batch_commands = gimp_core_app_get_batch_commands (app); + gimp_batch_run (gimp, - gimp_app_get_batch_interpreter (app), - gimp_app_get_batch_commands (app)); + batch_interpreter, + batch_commands); } } @@ -323,12 +332,12 @@ app_run (const gchar *full_prog_name, GimpPDBCompatMode pdb_compat_mode, const gchar *backtrace_file) { - Gimp *gimp = NULL; - GApplication *app = NULL; - GFile *default_folder = NULL; - GFile *gimpdir = NULL; - const gchar *abort_message = NULL; - gint retval = EXIT_SUCCESS; + Gimp *gimp = NULL; + GApplication *app = NULL; + GFile *default_folder = NULL; + GFile *gimpdir = NULL; + const gchar *abort_message = NULL; + gint retval = EXIT_SUCCESS; if (filenames && filenames[0] && ! filenames[1] && g_file_test (filenames[0], G_FILE_TEST_IS_DIR)) @@ -370,7 +379,11 @@ app_run (const gchar *full_prog_name, g_clear_object (&default_folder); - app = gimp_app_new (gimp, no_splash, as_new, batch_interpreter, batch_commands); +#ifndef GIMP_CONSOLE_COMPILATION + app = gimp_app_new (gimp, no_splash, as_new, filenames, batch_interpreter, batch_commands); +#else + app = gimp_console_app_new (gimp, as_new, filenames, batch_interpreter, batch_commands); +#endif gimp_cpu_accel_set_use (use_cpu_accel); @@ -487,9 +500,9 @@ app_restore_after_callback (Gimp *gimp, } static gboolean -app_exit_after_callback (Gimp *gimp, - gboolean kill_it, - GimpApp **app) +app_exit_after_callback (Gimp *gimp, + gboolean kill_it, + GApplication **app) { if (gimp->be_verbose) g_print ("EXIT: %s\n", G_STRFUNC); diff --git a/app/gimpapp.h b/app/gimpapp.h deleted file mode 100644 index 1a8a1c39896..00000000000 --- a/app/gimpapp.h +++ /dev/null @@ -1,46 +0,0 @@ -/* GIMP - The GNU Image Manipulation Program - * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball - * - * gimpapp.h - * Copyright (C) 2021 Niels De Graef - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - */ - -#ifndef __GIMP_APP_H__ -#define __GIMP_APP_H__ - -#include -#include - -#include "core/core-types.h" -#include "core/gimp.h" - -#define GIMP_TYPE_APP (gimp_app_get_type ()) -G_DECLARE_FINAL_TYPE (GimpApp, gimp_app, GIMP, APP, GtkApplication) - - -GApplication * gimp_app_new (Gimp *gimp, - gboolean no_splash, - gboolean as_new, - const char *batch_interpreter, - const char **batch_commands); - -Gimp * gimp_app_get_gimp (GimpApp *self); - -gboolean gimp_app_get_no_splash (GimpApp *self); - -gboolean gimp_app_get_as_new (GimpApp *self); - -const char * gimp_app_get_batch_interpreter (GimpApp *self); - -const char ** gimp_app_get_batch_commands (GimpApp *self); - -#endif /* __GIMP_APP_H__ */ diff --git a/app/gimpconsoleapp.c b/app/gimpconsoleapp.c new file mode 100644 index 00000000000..29114517787 --- /dev/null +++ b/app/gimpconsoleapp.c @@ -0,0 +1,197 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpapp.c + * Copyright (C) 2021 Niels De Graef + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include "gimpconsoleapp.h" + +#include "libgimpbase/gimpbase.h" + + +enum +{ + PROP_0, + PROP_GIMP, + N_PROPS +}; + +struct _GimpConsoleApp +{ + GApplication parent_instance; + + Gimp *gimp; + + gboolean as_new; + const gchar **filenames; + const gchar *batch_interpreter; + const gchar **batch_commands; +}; + + +static void gimp_console_app_finalize (GObject *object); +static void gimp_console_app_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_console_app_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +static void gimp_core_app_interface_init (GimpCoreAppInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (GimpConsoleApp, gimp_console_app, G_TYPE_APPLICATION, + G_IMPLEMENT_INTERFACE (GIMP_TYPE_CORE_APP, + gimp_core_app_interface_init)) + + +static void +gimp_console_app_class_init (GimpConsoleAppClass *klass) +{ + GObjectClass *gobj_class = G_OBJECT_CLASS (klass); + + gobj_class->get_property = gimp_console_app_get_property; + gobj_class->set_property = gimp_console_app_set_property; + gobj_class->finalize = gimp_console_app_finalize; + + g_object_class_override_property (gobj_class, PROP_GIMP, "gimp"); +} + +static void +gimp_core_app_interface_init (GimpCoreAppInterface *iface) +{ + iface->get_gimp = gimp_console_app_get_gimp; + iface->get_as_new = gimp_console_app_get_as_new; + iface->get_filenames = gimp_console_app_get_filenames; + iface->get_batch_interpreter = gimp_console_app_get_batch_interpreter; + iface->get_batch_commands = gimp_console_app_get_batch_commands; +} + +static void +gimp_console_app_init (GimpConsoleApp *self) +{ +} + +static void +gimp_console_app_finalize (GObject *object) +{ + GimpConsoleApp *self = GIMP_CONSOLE_APP (object); + + g_clear_object (&self->gimp); + + G_OBJECT_CLASS (gimp_console_app_parent_class)->finalize (object); +} + +static void +gimp_console_app_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpConsoleApp *self = GIMP_CONSOLE_APP (object); + + switch (property_id) + { + case PROP_GIMP: + g_value_set_object (value, self->gimp); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gimp_console_app_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpConsoleApp *self = GIMP_CONSOLE_APP (object); + + switch (property_id) + { + case PROP_GIMP: + self->gimp = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +/* public functions */ + +GApplication * +gimp_console_app_new (Gimp *gimp, + gboolean as_new, + const char **filenames, + const char *batch_interpreter, + const char **batch_commands) +{ + GimpConsoleApp *app; + + app = g_object_new (GIMP_TYPE_CONSOLE_APP, + "gimp", gimp, + NULL); + + /* 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->as_new = as_new; + app->filenames = filenames; + app->batch_interpreter = batch_interpreter; + app->batch_commands = batch_commands; + + return G_APPLICATION (app); +} + +Gimp * +gimp_console_app_get_gimp (GimpCoreApp *self) +{ + g_return_val_if_fail (GIMP_IS_CONSOLE_APP (self), NULL); + return GIMP_CONSOLE_APP (self)->gimp; +} + +gboolean +gimp_console_app_get_as_new (GimpCoreApp *self) +{ + g_return_val_if_fail (GIMP_IS_CONSOLE_APP (self), FALSE); + return GIMP_CONSOLE_APP (self)->as_new; +} + +const char ** +gimp_console_app_get_filenames (GimpCoreApp *self) +{ + g_return_val_if_fail (GIMP_IS_CONSOLE_APP (self), NULL); + return GIMP_CONSOLE_APP (self)->filenames; +} + +const char * +gimp_console_app_get_batch_interpreter (GimpCoreApp *self) +{ + g_return_val_if_fail (GIMP_IS_CONSOLE_APP (self), NULL); + return GIMP_CONSOLE_APP (self)->batch_interpreter; +} + +const char ** +gimp_console_app_get_batch_commands (GimpCoreApp *self) +{ + g_return_val_if_fail (GIMP_IS_CONSOLE_APP (self), NULL); + return GIMP_CONSOLE_APP (self)->batch_commands; +} diff --git a/app/gimpconsoleapp.h b/app/gimpconsoleapp.h new file mode 100644 index 00000000000..d1d8ca0589d --- /dev/null +++ b/app/gimpconsoleapp.h @@ -0,0 +1,39 @@ + +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpapp.h + * Copyright (C) 2021 Niels De Graef + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#pragma once + +#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) + +GApplication * gimp_console_app_new (Gimp *gimp, + gboolean as_new, + const char **filenames, + const char *batch_interpreter, + const char **batch_commands); + +Gimp * gimp_console_app_get_gimp (GimpCoreApp *self); + +gboolean gimp_console_app_get_as_new (GimpCoreApp *self); + +const char ** gimp_console_app_get_filenames (GimpCoreApp *self); + +const char * gimp_console_app_get_batch_interpreter (GimpCoreApp *self); + +const char ** gimp_console_app_get_batch_commands (GimpCoreApp *self); diff --git a/app/gimpcoreapp.c b/app/gimpcoreapp.c new file mode 100644 index 00000000000..eb140d3149b --- /dev/null +++ b/app/gimpcoreapp.c @@ -0,0 +1,95 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpapp.c + * Copyright (C) 2022 Lukas Oberhuber + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include "gimpcoreapp.h" + +#include "libgimpbase/gimpbase.h" + +G_DEFINE_INTERFACE (GimpCoreApp, gimp_core_app, G_TYPE_OBJECT) + +static void +gimp_core_app_default_init (GimpCoreAppInterface *iface) +{ + /* add properties and signals to the interface here */ + g_object_interface_install_property (iface, + g_param_spec_object ("gimp", + "GIMP", + "GIMP root object", + GIMP_TYPE_GIMP, + GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +} + +Gimp * +gimp_core_app_get_gimp (GimpCoreApp *self) +{ + GimpCoreAppInterface *iface; + + g_return_val_if_fail (GIMP_IS_CORE_APP (self), NULL); + + iface = GIMP_CORE_APP_GET_IFACE (self); + g_return_val_if_fail (iface->get_gimp != NULL, NULL); + return iface->get_gimp (self); +} + +gboolean +gimp_core_app_get_as_new (GimpCoreApp *self) +{ + GimpCoreAppInterface *iface; + + g_return_val_if_fail (GIMP_IS_CORE_APP (self), FALSE); + + iface = GIMP_CORE_APP_GET_IFACE (self); + g_return_val_if_fail (iface->get_as_new != NULL, FALSE); + return iface->get_as_new (self); +} + +const char ** +gimp_core_app_get_filenames (GimpCoreApp *self) +{ + GimpCoreAppInterface *iface; + + g_return_val_if_fail (GIMP_IS_CORE_APP (self), NULL); + + iface = GIMP_CORE_APP_GET_IFACE (self); + g_return_val_if_fail (iface->get_filenames != NULL, NULL); + return iface->get_filenames (self); +} + +const char * +gimp_core_app_get_batch_interpreter (GimpCoreApp *self) +{ + GimpCoreAppInterface *iface; + + g_return_val_if_fail (GIMP_IS_CORE_APP (self), NULL); + + iface = GIMP_CORE_APP_GET_IFACE (self); + g_return_val_if_fail (iface->get_batch_interpreter != NULL, NULL); + return iface->get_batch_interpreter (self); +} + +const char ** +gimp_core_app_get_batch_commands (GimpCoreApp *self) +{ + GimpCoreAppInterface *iface; + + g_return_val_if_fail (GIMP_IS_CORE_APP (self), NULL); + + iface = GIMP_CORE_APP_GET_IFACE (self); + g_return_val_if_fail (iface->get_batch_commands != NULL, NULL); + return iface->get_batch_commands (self); +} diff --git a/app/gimpcoreapp.h b/app/gimpcoreapp.h new file mode 100644 index 00000000000..4f2e0ede486 --- /dev/null +++ b/app/gimpcoreapp.h @@ -0,0 +1,55 @@ + +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpcoreapp.h + * Copyright (C) 2022 Lukas Oberhuber + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#pragma once + +#include + +#include "core/core-types.h" +#include "core/gimp.h" + +G_BEGIN_DECLS + +#define GIMP_TYPE_CORE_APP gimp_core_app_get_type() +G_DECLARE_INTERFACE (GimpCoreApp, gimp_core_app, GIMP, CORE_APP, GObject) + +struct _GimpCoreAppInterface +{ + GTypeInterface parent_iface; + + Gimp * (*get_gimp) (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); + + /* Padding to allow adding up to 12 new virtual functions without + * breaking ABI. */ + gpointer padding[12]; +}; + +Gimp * gimp_core_app_get_gimp (GimpCoreApp *self); + +gboolean gimp_core_app_get_as_new (GimpCoreApp *self); + +const char ** gimp_core_app_get_filenames (GimpCoreApp *self); + +const char * gimp_core_app_get_batch_interpreter (GimpCoreApp *self); + +const char ** gimp_core_app_get_batch_commands (GimpCoreApp *self); + +G_END_DECLS diff --git a/app/gui/Makefile.am b/app/gui/Makefile.am index 579cd63bc0b..990607713f3 100644 --- a/app/gui/Makefile.am +++ b/app/gui/Makefile.am @@ -31,6 +31,8 @@ AM_LDFLAGS = \ noinst_LIBRARIES = libappgui.a libappgui_a_sources = \ + gimpapp.c \ + gimpapp.h \ gimpdbusservice.c \ gimpdbusservice.h \ gimpuiconfigurer.c \ diff --git a/app/gimpapp.c b/app/gui/gimpapp.c similarity index 60% rename from app/gimpapp.c rename to app/gui/gimpapp.c index 7b69bc7a4f9..e25de13c275 100644 --- a/app/gimpapp.c +++ b/app/gui/gimpapp.c @@ -36,25 +36,27 @@ struct _GimpApp gboolean no_splash; gboolean as_new; + const gchar **filenames; const gchar *batch_interpreter; const gchar **batch_commands; }; +static void gimp_app_finalize (GObject *object); +static void gimp_app_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_app_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); -static void gimp_app_finalize (GObject *object); -static void gimp_app_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); -static void gimp_app_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); +static void gimp_core_app_interface_init (GimpCoreAppInterface *iface); -G_DEFINE_TYPE (GimpApp, gimp_app, GTK_TYPE_APPLICATION) - -static GParamSpec *props[N_PROPS] = { NULL, }; +G_DEFINE_TYPE_WITH_CODE (GimpApp, gimp_app, GTK_TYPE_APPLICATION, + G_IMPLEMENT_INTERFACE (GIMP_TYPE_CORE_APP, + gimp_core_app_interface_init)) static void @@ -64,14 +66,19 @@ gimp_app_class_init (GimpAppClass *klass) gobj_class->get_property = gimp_app_get_property; gobj_class->set_property = gimp_app_set_property; - gobj_class->finalize = gimp_app_finalize; + gobj_class->finalize = gimp_app_finalize; - props[PROP_GIMP] = - g_param_spec_object ("gimp", "GIMP", "GIMP root object", - GIMP_TYPE_GIMP, - GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_override_property (gobj_class, PROP_GIMP, "gimp"); +} - g_object_class_install_properties (gobj_class, N_PROPS, props); +static void +gimp_core_app_interface_init (GimpCoreAppInterface *iface) +{ + iface->get_gimp = gimp_app_get_gimp; + iface->get_as_new = gimp_app_get_as_new; + iface->get_filenames = gimp_app_get_filenames; + iface->get_batch_interpreter = gimp_app_get_batch_interpreter; + iface->get_batch_commands = gimp_app_get_batch_commands; } static void @@ -135,6 +142,7 @@ GApplication * gimp_app_new (Gimp *gimp, gboolean no_splash, gboolean as_new, + const char **filenames, const char *batch_interpreter, const char **batch_commands) { @@ -147,45 +155,53 @@ gimp_app_new (Gimp *gimp, /* 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; - app->as_new = as_new; + app->no_splash = no_splash; + app->as_new = as_new; + app->filenames = filenames; app->batch_interpreter = batch_interpreter; - app->batch_commands = batch_commands; + app->batch_commands = batch_commands; return G_APPLICATION (app); } Gimp * -gimp_app_get_gimp (GimpApp *self) +gimp_app_get_gimp (GimpCoreApp *self) { g_return_val_if_fail (GIMP_IS_APP (self), NULL); - return self->gimp; + return GIMP_APP (self)->gimp; } gboolean gimp_app_get_no_splash (GimpApp *self) { g_return_val_if_fail (GIMP_IS_APP (self), FALSE); - return self->no_splash; + return GIMP_APP (self)->no_splash; } gboolean -gimp_app_get_as_new (GimpApp *self) +gimp_app_get_as_new (GimpCoreApp *self) { g_return_val_if_fail (GIMP_IS_APP (self), FALSE); - return self->as_new; + return GIMP_APP (self)->as_new; +} + +const char ** +gimp_app_get_filenames (GimpCoreApp *self) +{ + g_return_val_if_fail (GIMP_IS_APP (self), NULL); + return GIMP_APP (self)->filenames; } const char * -gimp_app_get_batch_interpreter (GimpApp *self) +gimp_app_get_batch_interpreter (GimpCoreApp *self) { g_return_val_if_fail (GIMP_IS_APP (self), NULL); - return self->batch_interpreter; + return GIMP_APP (self)->batch_interpreter; } const char ** -gimp_app_get_batch_commands (GimpApp *self) +gimp_app_get_batch_commands (GimpCoreApp *self) { g_return_val_if_fail (GIMP_IS_APP (self), NULL); - return self->batch_commands; + return GIMP_APP (self)->batch_commands; } diff --git a/app/gui/gimpapp.h b/app/gui/gimpapp.h new file mode 100644 index 00000000000..28fb5f0e558 --- /dev/null +++ b/app/gui/gimpapp.h @@ -0,0 +1,47 @@ + +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpapp.h + * Copyright (C) 2021 Niels De Graef + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#ifndef __GIMP_APP_H__ +#define __GIMP_APP_H__ + +#include + +#include "gimpcoreapp.h" + +#define GIMP_TYPE_APP (gimp_app_get_type ()) +G_DECLARE_FINAL_TYPE (GimpApp, gimp_app, GIMP, APP, GtkApplication) + +GApplication * gimp_app_new (Gimp *gimp, + gboolean no_splash, + gboolean as_new, + const char **filenames, + const char *batch_interpreter, + const char **batch_commands); + +Gimp * gimp_app_get_gimp (GimpCoreApp *self); + +gboolean gimp_app_get_no_splash (GimpApp *self); + +gboolean gimp_app_get_as_new (GimpCoreApp *self); + +const char ** gimp_app_get_filenames (GimpCoreApp *self); + +const char * gimp_app_get_batch_interpreter (GimpCoreApp *self); + +const char ** gimp_app_get_batch_commands (GimpCoreApp *self); + +#endif /* __GIMP_APP_H__ */ diff --git a/app/gui/gui.c b/app/gui/gui.c index 91507999d9f..9909cc1c3ef 100644 --- a/app/gui/gui.c +++ b/app/gui/gui.c @@ -224,7 +224,7 @@ gui_abort (const gchar *abort_message) GimpInitStatusFunc gui_init (Gimp *gimp, gboolean no_splash, - GApplication *app, + GimpApp *app, const gchar *test_base_dir) { GimpInitStatusFunc status_callback = NULL; @@ -232,7 +232,7 @@ gui_init (Gimp *gimp, g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); g_return_val_if_fail (the_gui_gimp == NULL, NULL); - g_return_val_if_fail (G_IS_APPLICATION (app) || app == NULL, NULL); + g_return_val_if_fail (GIMP_IS_APP (app) || app == NULL, NULL); abort_message = gui_sanity_check (); if (abort_message) @@ -700,8 +700,6 @@ gui_restore_after_callback (Gimp *gimp, g_signal_connect (osx_app, "NSApplicationBlockTermination", G_CALLBACK (gui_quartz_quit_callback), image_ui_manager); - - gtkosx_application_ready (osx_app); } #endif /* GDK_WINDOWING_QUARTZ */ diff --git a/app/gui/gui.h b/app/gui/gui.h index af88b086137..e64f5fa1d9a 100644 --- a/app/gui/gui.h +++ b/app/gui/gui.h @@ -18,13 +18,14 @@ #ifndef __GUI_H__ #define __GUI_H__ +#include "gimpapp.h" void gui_libs_init (GOptionContext *context); void gui_abort (const gchar *abort_message); GimpInitStatusFunc gui_init (Gimp *gimp, gboolean no_splash, - GApplication *app, + GimpApp *app, const gchar *test_base_dir); gboolean gui_recover (gint n_recoveries); diff --git a/app/gui/meson.build b/app/gui/meson.build index d128d3101fb..31b208550e7 100644 --- a/app/gui/meson.build +++ b/app/gui/meson.build @@ -7,6 +7,7 @@ gimpdbusservice_gen = gnome.gdbus_codegen( ) libappgui_sources = [ + 'gimpapp.c', 'gimpdbusservice.c', 'gimpuiconfigurer.c', 'gui-message.c', diff --git a/app/gui/splash.c b/app/gui/splash.c index 3ce1bc3d6cf..390dfdc88ed 100644 --- a/app/gui/splash.c +++ b/app/gui/splash.c @@ -112,7 +112,7 @@ void splash_create (Gimp *gimp, gboolean be_verbose, GdkMonitor *monitor, - GApplication *app) + GimpApp *app) { GtkWidget *frame; GtkWidget *vbox; @@ -124,7 +124,7 @@ splash_create (Gimp *gimp, g_return_if_fail (splash == NULL); g_return_if_fail (GDK_IS_MONITOR (monitor)); - g_return_if_fail (G_IS_APPLICATION (app) || app == NULL); + g_return_if_fail (GIMP_IS_APP (app) || app == NULL); gdk_monitor_get_workarea (monitor, &workarea); @@ -171,7 +171,7 @@ splash_create (Gimp *gimp, "role", "gimp-startup", "window-position", GTK_WIN_POS_CENTER, "resizable", FALSE, - "application", app, + "application", GTK_APPLICATION (app), NULL); /* Don't remove this call, it's necessary to remove decorations on Windows diff --git a/app/gui/splash.h b/app/gui/splash.h index c6fb9fdfb39..51e8af63de2 100644 --- a/app/gui/splash.h +++ b/app/gui/splash.h @@ -18,11 +18,12 @@ #ifndef __SPLASH_H__ #define __SPLASH_H__ +#include "gimpapp.h" void splash_create (Gimp *gimp, gboolean be_verbose, - GdkMonitor *mointor, - GApplication *app); + GdkMonitor *monitor, + GimpApp *app); void splash_destroy (void); void splash_update (const gchar *label1, diff --git a/app/meson.build b/app/meson.build index 11bbadefa7b..7b76bab4d5c 100644 --- a/app/meson.build +++ b/app/meson.build @@ -50,7 +50,8 @@ app_debug_files = files( libapp_sources = [ 'app.c', 'errors.c', - 'gimpapp.c', + 'gimpcoreapp.c', + 'gimpconsoleapp.c', 'gimp-debug.c', 'gimp-log.c', 'gimp-update.c', -- GitLab