From c558e4151788fc1ebce34a29e4516471cf3e561d Mon Sep 17 00:00:00 2001 From: Jehan Date: Fri, 21 Nov 2025 19:19:08 +0100 Subject: [PATCH] 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). --- libgimpwidgets/gimpcolorarea.c | 9 ++++++- libgimpwidgets/gimpcolorselection.c | 40 ++++++++--------------------- 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/libgimpwidgets/gimpcolorarea.c b/libgimpwidgets/gimpcolorarea.c index dcb4e49d4e..215bd57bb0 100644 --- a/libgimpwidgets/gimpcolorarea.c +++ b/libgimpwidgets/gimpcolorarea.c @@ -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: diff --git a/libgimpwidgets/gimpcolorselection.c b/libgimpwidgets/gimpcolorselection.c index de5b2c698d..42c2cb229c 100644 --- a/libgimpwidgets/gimpcolorselection.c +++ b/libgimpwidgets/gimpcolorselection.c @@ -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