diff --git a/app/core/gimp-data-factories.c b/app/core/gimp-data-factories.c index 06818f3435..a6b4d1c6c5 100644 --- a/app/core/gimp-data-factories.c +++ b/app/core/gimp-data-factories.c @@ -32,12 +32,14 @@ #include "gimp-gradients.h" #include "gimp-memsize.h" #include "gimp-palettes.h" +#include "gimp-utils.h" #include "gimpcontainer.h" #include "gimpbrush-load.h" #include "gimpbrush.h" #include "gimpbrushclipboard.h" #include "gimpbrushgenerated-load.h" #include "gimpbrushpipe-load.h" +#include "gimpcurve.h" #include "gimpdataloaderfactory.h" #include "gimpdynamics.h" #include "gimpdynamics-load.h" @@ -300,6 +302,52 @@ gimp_data_factories_exit (Gimp *gimp) g_clear_object (&gimp->tag_cache); } +gboolean +gimp_data_factories_wait (Gimp *gimp) +{ + GList *data_types; + GList *excluded; + gboolean loaded = TRUE; + + /* TODO: when bumping GLib >= 2.80, use GTYPE_TO_POINTER instead. */ +#define GIMPTYPE_TO_POINTER(t) ((gpointer) (guintptr) (t)) + /* Curves are the only data type without a factory. */ + excluded = g_list_prepend (NULL, GIMPTYPE_TO_POINTER (GIMP_TYPE_CURVE)); +#undef GIMPTYPE_TO_POINTER + + data_types = gimp_get_type_children (GIMP_TYPE_DATA, NULL, excluded); + g_list_free (excluded); + + /* TODO: when bumping GLib >= 2.80, use GPOINTER_TO_TYPE instead. */ +#define GIMPPOINTER_TO_TYPE(p) ((GType) (guintptr) (p)) + + for (GList *iter = data_types; iter; iter = iter->next) + { + GimpDataFactory *factory; + + factory = gimp_get_data_factory (gimp, GIMPPOINTER_TO_TYPE (iter->data)); + + if (factory) + { + GimpAsyncSet *set; + + set = gimp_data_factory_get_async_set (factory); + g_object_get (set, "empty", &loaded, NULL); + if (! loaded) + { + gimp_data_factory_data_wait (factory); + loaded = TRUE; + } + } + } + +#undef GIMPPOINTER_TO_TYPE + + g_list_free (data_types); + + return loaded; +} + gint64 gimp_data_factories_get_memsize (Gimp *gimp, gint64 *gui_size) diff --git a/app/core/gimp-data-factories.h b/app/core/gimp-data-factories.h index eb177c4f91..cd1f2d49aa 100644 --- a/app/core/gimp-data-factories.h +++ b/app/core/gimp-data-factories.h @@ -23,6 +23,8 @@ void gimp_data_factories_add_builtin (Gimp *gimp); void gimp_data_factories_clear (Gimp *gimp); void gimp_data_factories_exit (Gimp *gimp); +gboolean gimp_data_factories_wait (Gimp *gimp); + gint64 gimp_data_factories_get_memsize (Gimp *gimp, gint64 *gui_size); void gimp_data_factories_data_clean (Gimp *gimp); diff --git a/app/core/gimp-utils.c b/app/core/gimp-utils.c index eda0b1ec92..e686b2e655 100644 --- a/app/core/gimp-utils.c +++ b/app/core/gimp-utils.c @@ -1630,6 +1630,50 @@ gimp_version_cmp (const gchar *v1, return -1; } +/** + * gimp_get_type_children: + * @type: the %GType to find children types for. + * @types: set %NULL for the initial call (internal variable for + * recursive calls). + * @excluded: a list of types to exclude. + * + * Gather and recursively return all the subtypes of @type (except any + * type listed in @excluded). + * + * Note that @type itself is not included, so if you wished to have it, + * you must add it yourself after calling this function. + * + * Returns: a list of %Gtypes. + */ +GList * +gimp_get_type_children (GType type, + GList *types, + GList *excluded) +{ + GType *dtypes; + guint n_types; + + dtypes = g_type_children (type, &n_types); + + /* TODO: when bumping GLib >= 2.80, use GTYPE_TO_POINTER instead. */ +#define GIMPTYPE_TO_POINTER(t) ((gpointer) (guintptr) (t)) + + for (gint i = 0; i < n_types; i++) + { + if (g_list_find (excluded, GIMPTYPE_TO_POINTER (dtypes[i]))) + continue; + + types = gimp_get_type_children (dtypes[i], types, excluded); + types = g_list_prepend (types, GIMPTYPE_TO_POINTER (dtypes[i])); + } + +#undef GIMPTYPE_TO_POINTER + + g_free (dtypes); + + return types; +} + /* Private functions */ diff --git a/app/core/gimp-utils.h b/app/core/gimp-utils.h index 9c3bc36faa..5a08df0f8e 100644 --- a/app/core/gimp-utils.h +++ b/app/core/gimp-utils.h @@ -155,3 +155,7 @@ gboolean gimp_win32_have_windows_ink (void); gint gimp_version_cmp (const gchar *v1, const gchar *v2); + +GList * gimp_get_type_children (GType type, + GList *types, + GList *excluded); diff --git a/app/core/gimp.c b/app/core/gimp.c index 8b125f0c98..39ecb8e37a 100644 --- a/app/core/gimp.c +++ b/app/core/gimp.c @@ -892,7 +892,7 @@ gimp_is_restored (Gimp *gimp) { g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE); - return gimp->initialized && gimp->restored; + return gimp->initialized && gimp->restored && gimp_data_factories_wait (gimp); } /** diff --git a/app/file/file-open.c b/app/file/file-open.c index 3ae80b9771..3c30f7ea25 100644 --- a/app/file/file-open.c +++ b/app/file/file-open.c @@ -30,6 +30,7 @@ #include "gegl/gimp-babl.h" #include "core/gimp.h" +#include "core/gimp-data-factories.h" #include "core/gimpcontext.h" #include "core/gimpdocumentlist.h" #include "core/gimpimage.h" @@ -523,6 +524,8 @@ file_open_with_proc_and_display (Gimp *gimp, g_return_val_if_fail (monitor == NULL || G_IS_OBJECT (monitor), NULL); g_return_val_if_fail (status != NULL, NULL); + gimp_data_factories_wait (gimp); + if (gimp->no_interface) run_mode = GIMP_RUN_NONINTERACTIVE;