Don't destroy the color frames when the number of points changes.
Instead, simply hide them so they keep their color model, but add an
upper limit of an arbitrary number of 16 frames to keep around.
I know that the idea of black toilet paper is traumatizing nomis! ;-)
So here it is, using the CSS "!important" trick to override GTK+ CSS
recoloring code.
In order for the icon to be always visible, even on light background, I
am adding a path around the toilet paper shape (which this time will
be properly recolored by GTK+ with the foreground color, hence making
the icon clearly visible).
The extension dialog will show details about an extension (long
description, screenshot, upstream URLs, etc.) with this widget.
Update the GimpExtensionList to send a "extension-activated" signal on
double click, and make the extensions dialog react on it to display the
extension details for the activated extension.
This is all still mostly a skeleton GUI, but it is starting to get into
shape.
This is using GTK+3 widgets, so I make sure to keep it well separated
from core code. The gimp-2-10 version will have to rework the GUI, but
the GtkListBox and GtkSwitch are nice and make things easier, so it is
worth using them here).
To be used in the next commit.
I keep the GUI and core changes well separated in different commits so
that the core is easy to cherry-pick even though I will have to have
different GUI code.
GIMP_APP_VERSION does not include the micro version.
Also make version comparison with org.gimp.GIMP mandatory to force good
practice. This way, extension makers will have to advertize the version
of GIMP it works for, which will make a sane ecosystem of working
extensions only (hopefully!).
... (valgrind reports Invalid read)
Add gimp_babl_is_valid(), which takes a GimpImageBaseType and a
GimpPrecision, and determines whether the image-type/precision
combination is valid. Use this function to validate that loaded
XCFs use a valid type/precision combination, before trying to
create the image. Otherwise, we get a CRITICAL, and eventually a
segfault, when the combination is invalid.
Use the same function to validate the arguments of
gimp_image_new().
Introduce GIMP_PATTERN_MAX_SIZE (10000) and GIMP_PATTERN_MAX_NAME (256)
and validate pattern dimensions and pattern name length against them.
Add GIMP_BRUSH_MAX_NAME and validate that too.
Also make sure that the names are properly terminated, and some
cleanup.
In app_exit_after_callback(), call gimp_gegl_exit() before
gegl_exit() when performing a quick shut-down in stable versions,
so that gimp-parallel, and, in particular, the async thread pool,
is properly shut down. Code running in the async thread pool may
use GEGL (in particular, now the drawable previews are rendered
asynchronously), and calling gegl_exit() while it's still running
is unsafe.
In GimpAction, instead of connecting the action-history log
function to the action's "activate" signal as a user-provided
handler, call it directly from the default handler.
In subclasses of GimpAction, chain to the parent's activate()
function before emitting the "selected" signal, so that we always
log the action in the history before responding to it.
This allows us to avoid the hack in commit
6544ce4301.
In gimp_metadata_set_from_{exif,iptc,xmp}(), gracefully reject data
of invalid size, returning an error instead of raising a critical.
In particular, this avoids a CRITICAL when loading an XCF with an
empty exif-ata parasite.
In xcf_write_int8(), avoid calling g_output_stream_write_all() with
data == NULL and count == 0, in which case it raises a CRITICAL and
doesn't set bytes_written, which we proceed to use uninitialized.
This can happen, e.g., when writing an empty parasite.