libgimpwidgets: update color area correctly when updating color.

Since we don't necessarily re-render the color area when the color
change, let's store the actually rendered color, additionally to the
supposedly rendered color. Otherwise when changing the color by very
small increments, small enough that the color is always perceptually
identical to the previous color, we never re-render the widget, even
when the rendered color is now quite different. Indeed the "identical
color" algorithm, based on CIE2000 distance, is not transitive.

Additionally I do not check for perceptual identity in
GimpColorSelection anymore, because we also check for this in the
GimpColorArea. Better always having the right color set in the area.

This was raised in #11339 (even though the initial issue was about the
hexadecimal field).
This commit is contained in:
Jehan 2025-11-21 19:19:08 +01:00
parent b5a3529d49
commit c558e41517
2 changed files with 18 additions and 31 deletions

View file

@ -80,6 +80,7 @@ struct _GimpColorArea
GimpColorAreaType type;
GeglColor *color;
GeglColor *rendered;
guint draw_border : 1;
guint needs_render : 1;
@ -237,6 +238,7 @@ gimp_color_area_init (GimpColorArea *area)
area->rowstride = 0;
area->draw_border = FALSE;
area->color = gegl_color_new ("black");
area->rendered = NULL;
gtk_drag_dest_set (GTK_WIDGET (area),
GTK_DEST_DEFAULT_HIGHLIGHT |
@ -267,6 +269,7 @@ gimp_color_area_finalize (GObject *object)
g_clear_pointer (&area->buf, g_free);
g_clear_object (&area->color);
g_clear_object (&area->rendered);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@ -528,7 +531,8 @@ gimp_color_area_set_color (GimpColorArea *area,
g_return_if_fail (GIMP_IS_COLOR_AREA (area));
g_return_if_fail (GEGL_IS_COLOR (color));
if (! gimp_color_is_perceptually_identical (area->color, color))
if (! area->rendered ||
! gimp_color_is_perceptually_identical (area->rendered, color))
{
area->needs_render = TRUE;
gtk_widget_queue_draw (GTK_WIDGET (area));
@ -741,6 +745,9 @@ gimp_color_area_render_buf (GtkWidget *widget,
guchar *p;
gdouble frac;
g_clear_object (&area->rendered);
area->rendered = gegl_color_duplicate (color);
switch (type)
{
case GIMP_COLOR_AREA_FLAT:

View file

@ -440,23 +440,14 @@ void
gimp_color_selection_set_color (GimpColorSelection *selection,
GeglColor *color)
{
GeglColor *old_color;
UpdateType update;
g_return_if_fail (GIMP_IS_COLOR_SELECTION (selection));
g_return_if_fail (GEGL_IS_COLOR (color));
old_color = selection->color;
g_object_unref (selection->color);
selection->color = gegl_color_duplicate (color);
update = UPDATE_ALL;
if (gimp_color_is_perceptually_identical (color, old_color))
update &= ~UPDATE_COLOR;
gimp_color_selection_update (selection, update);
gimp_color_selection_update (selection, UPDATE_ALL);
gimp_color_selection_color_changed (selection);
g_object_unref (old_color);
}
/**
@ -676,20 +667,15 @@ gimp_color_selection_notebook_changed (GimpColorSelector *selector,
GeglColor *color,
GimpColorSelection *selection)
{
GeglColor *old_color;
UpdateType update;
UpdateType update;
old_color = selection->color;
update = UPDATE_SCALES | UPDATE_ENTRY | UPDATE_COLOR;
g_object_unref (selection->color);
selection->color = gegl_color_duplicate (color);
update = UPDATE_SCALES | UPDATE_ENTRY;
if (! gimp_color_is_perceptually_identical (color, old_color))
update |= UPDATE_COLOR;
gimp_color_selection_update (selection, update);
gimp_color_selection_color_changed (selection);
g_object_unref (old_color);
}
static void
@ -697,21 +683,15 @@ gimp_color_selection_scales_changed (GimpColorSelector *selector,
GeglColor *color,
GimpColorSelection *selection)
{
UpdateType update;
GeglColor *old_color;
UpdateType update;
old_color = selection->color;
update = UPDATE_ENTRY | UPDATE_NOTEBOOK | UPDATE_COLOR;
g_object_unref (selection->color);
selection->color = gegl_color_duplicate (color);
update = UPDATE_ENTRY | UPDATE_NOTEBOOK;
if (! gimp_color_is_perceptually_identical (color, old_color))
update |= UPDATE_COLOR;
gimp_color_selection_update (selection, update);
gimp_color_selection_color_changed (selection);
g_object_unref (old_color);
}
static void