Fixing these 2 warnings in the CI which end up fatal:
WARNING: Invalid fragment for 'Gimp.Parasite': it should be struct
Serializes the object properties of @config to a [class@Parasite].
^~~~~~~~~~~~~~~~
WARNING: Invalid fragment for 'GLib.MainLoop': it should be struct
it has a GUI and is hanging around in a [class@GLib.MainLoop], it must call
^~~~~~~~~~~~~~~~~~~~~
GLib has a specific type of NULL-terminated string arrays:
`G_TYPE_STRV`, which is the `GType` of `char**` aka `GStrv`.
By using this type, we can avoid having a `GimpStringArray` which is a
bit cumbersome to use for both the C API, as well as bindings. By using
`GStrv`, we allow other languages to pass on string lists as they are
used to, while the bindings will make sure to do the right thing.
In the end, it makes the API a little bit simpler for everyone, and
reduces confusion for people who are used to working with string arrays
in other C/GLib based code (and not having 2 different types to denote
the same thing).
Related: https://gitlab.gnome.org/GNOME/gimp/-/issues/5919
… object arrays.
We were not supporting duplicating object pspec for no good reason. Well
maybe the reason was that libgimpconfig does not see these types which
are in libgimp. But then the trick is to compare by name.
As for object array, they are present as subtypes of GimpArray specs.
Yet most GimpParamSpec*Array-s are subclass of GimpParamSpecArray but
GimpParamSpecObjectArray are their own GParamSpecBoxed subclass (same as
the Gimp*Array-s are just typedef-s of GimpArray but GimpObjectArray is
its own boxed type).
So I had to move the object array test as its own case to fix support.
Finally do not ignore anymore any type in gimp_config_class_init(). When
we create a GimpConfig, we want to know when a type is not implemented
as parameter (and if it's a well known type, we need to implement it).
Since the parsing failure I was experiencing was normal (not a bug), and
since I was not seeing error being passed down to deserialize(), I
assume this assert was always wrong. I hadn't realize that the GError
object was in fact populated by deserialized through g_scanner_error()
calls which were setting the GError passed at creation of the scanner
through a handler.
So there was indeed a bug in one of the functions called by our
deserialize() implementation. There was one failure case where the error
was just reported with g_warning() instead of g_scanner_error().
Now that it's fixed, I brought back the asserts (previous commits)
because the error object is actually always well populated.
As discussed with mitch on IRC, these asserts make no sense. They can
happen if we fail to parse user-side data. Also currently deserialize()
does not even pass the GError down so we would always assert on failed
parsing.
What must be done instead if change the signature of deserialize() and
all its implementations, with a GError arg. Then this GError will
properly bubble up to the caller for appropriate handling.
… assert the existence of GError.
This is even worse as deserialize() method does not even take a GError
parameter anyway so this assert will always go off when a
deserialization failed (which happened in my case as I was working on a
plug-in API, hence gimp_procedure_config_load_last() actually failed to
load a previous version of the plug-in-settings when I changed a
procedure arg's type).
Just fail the deserialization normally and let the calling code handling
this case. Nevertheless it is kind of useful to bubble-up the error to
calling code, so I add a TODO in the interface header (hopefully to see
and improve this before we release GIMP 3.0).
Since it appeared with GLib 2.68.0, we could not change this until we
bumped the dependency which has only become possible a few days ago
(since Debian testing is our baseline for dependency bumps). Cf.
previous commit.
As this is a drop-in replacement (just a guint parameter changed to
gsize to avoid integer overflow), search-and-replace with:
> sed -i 's/g_memdup\>/g_memdup2/g' `grep -rIl 'g_memdup\>' *`
… followed by a few manual alignment tweaks when necessary.
This gets rid of the many deprecation warnings which we had lately when
building with a recent GLib version.
Still the same problem as ever with the Python binding where we have a
hard time creating GParamSpec, hence we make them from object
properties.
See: https://gitlab.gnome.org/GNOME/pygobject/-/issues/227#note_570031
But then again, the Python binding way to create GObject properties does
not seem to give us a way to use our custom param types (or I didn't
find how). So when I create a property with Gimp.RGB type in Python, it
doesn't appear as a GIMP_PARAM_SPEC_RGB to our C code, but as a
G_PARAM_SPEC_BOXED. So my trick is to check the value type instead.
Note that I check the default value, but in reality it doesn't seem to
work much either. Better than no support at all anyway.
Used for instance if a plug-in had a GimpParasite argument (or aux
argument), which might not seem too useful at first. But anyway we
propose the type, so let's support it properly.
And actually I am going to use it in the next commit as a trick to save
binary data in stored last values for a plug-in.
… drawable array instead of a single drawable.
Instead of expecting a single drawable, GimpImageProcedure's run()
function will now have an array of drawable as parameter.
As a consequence, all existing plug-ins are broken again. I am going to
fix them in the next commit so that this change can be easily reviewed
and examined if needed later.
I only fix the Vala demo plug-in now (or rather, I just use the first
layer in the array for now) because otherwise the build fails.
It isn't being used by any plug-in or any code in GIMP at all even.
Let's get rid of it while we can still break API, so we can cut down on
all the complexity of the gimp-param stuff a bit.
Negative int values were not correctly handled because value.v_int is unsigned
causing a conversion to a large positive value.
To fix this we cast it to gint64 first before making it negative.
In gimp_config_deserialize_fundamental(), we can't use
g_value_set_static_string() because that will in the end pass the
GScanner's temporary scanner->value.v_string to
GObject::set_property(), and depending on set_property()'s
implementation, we might not dup the string (for example objects
created via gimp_config_type_register() will simply use g_value_copy()
and end up with a dangling pointer as a string member).
Especially need to watch out with forgetting `(array)` and `(out)`
annotations, as they can really give a different API in certain (if not
most) bindings.
gimp_config_type_register() currently overrides GimpConfig::equal()
to only compare the properties of the most-derived type. However,
this prevents the properties of GimpOperationSettings from being
considered during comparison of operation-config objects. Instead,
don't override GimpConfig::equal(), and rely on
GIMP_CONFIG_PARAM_DONT_COMPARE to exclude specific base-class
properties from comparison.
Allow calling gimp_scanner_new_string() with a NULL `text` and a
negative `text_len` (which is interpreted as 0), instead of
requiring `text_len == 0` in this case. This allows passing a
negative `text_len` unconditionally to infer the length, even when
the string may be NULL.
In gimp_config_deserialize_fundamental(), cast integer token values
to the target value type *before* negating them, to avoid
performing unsigned negation, which can result in a positive value
when cast to the target value type (in particular, when the target
value type is float/double).
More of the files were wrong, or at least not absolutely identical to
the files generated by the autotools. I am not doing any code change
other than trying to make both build systems produce identical files
(except for slight differences on 2 files not worth the effort) even
though maybe some things can be improved (especially on the include
list). Maybe to be improved later.
Also fixing 2 of the previously autotools-generated files because of
space typos which should have been committed earlier.
Finally it is to be noted that there is no logics to copy the generated
files back to the source directory in the meson rules. I am not sure
anyway this is really worth it and maybe we should just stop tracking
these generated files eventually.
Allow passing a non-NULL `pspecs` with `n_pspecs == 0` to
gimp_config_type_register(), in particular since
g_object_class_list_properties() may return such values.
There is at least one valid case of a config type registration with no
parameters: when registering the gegl:nop operation. This is the default
case when running the GEGL operation tool. See implementation of
gimp_filter_tool_get_operation().
Therefore we ended up crashing GIMP just by calling this tool.
It now supports all GParamSpecs possible on the wire protocol, except
the ones that are implemented in app/ and libgimp/ (image, drawable,
...) and are not visible to libgimpconfig
GimpConfigWriter contains several constructors with the convention
`gimp_config_writer_new_* ()`. This will lead to problems however with
languages like Vala, where it cannot disambiguate the following:
```
// calls config_writer_new_string()
Gimp.ConfigWriter w = new ConfigWriter.string("xxx");
// calls config_writer_string()
w.string("xxx")
```
Using `from_` in constructors is general practice in GObject-bsed
libraries because of this.
This also fixes an error when trying to use vapigen on the GIMP .GIR
file.
The `GIMP_CONFIG_PROP_*` macros do not automatically set
`G_PARAM_STATIC_STRINGS`, which means each property that uses such a
macro does not have this flag set by default (and almost none set it
themselves). By adding `G_PARAM_STATIC_STRINGS` to
`GIMP_CONFIG_PARAM_FLAGS`, we can prevent this from happening, which
should lead to some unnecessary string copies being prevented.
libgimp is anyway processed at the very end after all other libgimp*
were built. This way, it also fixes#3746, by removing the $(top_srcdir)
everywhere from introspected files, hence making the build work again
with older automake.
Basically this commit makes sure that all return values that are marked
as "Returns:" also have a `(nullable)` annotation if it is mentioned on
the same line that NULL can also be returned.
This will prevent a few problems in GObject-introspection.
The latter is broken and doesn't guarantee a decimal point with the
current bug. Also, g_ascii_dtostr() doesn't need the format parameter
and produces nicer output.
A number without a decimal point can be put into a gdouble just fine,
no need to refuse them. Moreover, g_ascii_dtostr() serializes doubles
without fractional part without a decimal point, and we are soon going
to use it.
Several returned values had no documentation, and needed in particular
(transfer) annotations.
Fixes various warnings:
> return value: Missing (transfer) annotation
Only libgimpwidgets is not introspected yet as it didn't work from
scratch and I don't have the time right now to look into it. Anyway with
all the others, we already have so many warnings during the GObject
Introspection step now that we have a lot of work to do already!
When an error occurs, we want to prevent overwriting any previous
version of the file by incomplete contents. So run
g_output_stream_close() with a cancelled GCancellable to do so.
See also discussion in #2565.
Move swap/cache and temporary files out the GIMP user config dir:
libgimpbase: add gimp_cache_directory() and gimp_temp_directory()
which return the new default values inside XDG_CACHE_HOME and the
system temp directory. Like all directories from gimpenv.[ch] the
values can be overridden by environment variables. Improve API docs
for all functions returning directories.
Add new config file substitutions ${gimp_cache_dir} and
${gimp_temp_dir}.
Document all the new stuff in the gimp and gimprc manpages.
app: default "swap-path" and "temp-path" to the new config file
substitutions. On startup and config changes, make sure that the swap
and temp directories actually exist.
In the preferences dialog, add reset buttons to all file path pages.
... and G_TYPE_INSTANCE_GET_PRIVATE()
g_type_class_add_private() and G_TYPE_INSTANCE_GET_PRIVATE() were
deprecated in GLib 2.58. Instead, use
G_DEFINE_[ABSTRACT_]TYPE_WITH_PRIVATE(), and
G_ADD_PRIVATE[_DYNAMIC](), and the implictly-defined
foo_get_instance_private() functions, all of which are available in
the GLib versions we depend on.
This commit only covers types registered using one of the
G_DEFINE_FOO() macros (i.e., most types), but not types with a
custom registration function, of which we still have a few -- GLib
currently only provides a (non-deprecated) public API for adding a
private struct using the G_DEFINE_FOO() macros.
Note that this commit was 99% auto-generated (because I'm not
*that* crazy :), so if there are any style mismatches... we'll have
to live with them for now.
Unlike the last two commits, we don't port GimpConfig to
G_DEFINE_INTERFACE(), since we need to provide a base initializer
for it. However, this commit aligns it with the rest of our
intefaces, by renaming gimp_config_interface_get_type() to
gimp_config_get_type(), and by performing class initialization for
the interface in a separate function than base initialization.
Keep gimp_config_interface_get_type() around as a deprecated
function, to maintain ABI compatibility. It will be removed in a
separate commit in master, so that this commit can be easily
cherry-picked to gimp-2-10.
even if we don't have private members (yet). Also make class padding 8
pointers in all headers. This commit moves nothing to private, it just
makes all headers consistent and adjusts .c files accordigly.
Update the dprod production of generated enum files to include
abbreviated value descriptions, as per the previous commits.
Add a comment for translators above the abbreviated descriptions,
specifying the full description they abbreviate.
Commit 1e6acbd4e1 modified the
generated enum recipes to run gimp-mkenums from the source
directory, instead of the build directory, so that only the
basenames of the corresponding header files would appear in
the comment at the top of the generated files. This was a
mistake -- $(GIMP_MKENUMS) is expecting to be invoked from the
build directory.
Switch back to running gimp-mkenums from the build directory. To
avoid including the relative path from the build directory to the
source directory in the generated file, add a @basename@ production
variable to gimp-mkenums, which exapnds to the basename of the
input file, and use it instead of @filename@ in the recipes for the
generated enum files.