From f275856fa59d3fdd58e6b95bcd81a48bbd1edea5 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 15 Oct 2022 21:30:19 +0300 Subject: [PATCH 26/26] gtk: Make property_page_change_value() to refresh widget only for changes It was already documented to refresh widget when there was something to change. Not doing that failed to abort a loop where widget refresh triggered "changed" signal again, in gtk4-client See osdn #45874 Signed-off-by: Marko Lindqvist --- client/gui-gtk-2.0/editprop.c | 38 ++++++++++++++++++++-------------- client/gui-gtk-3.0/editprop.c | 38 ++++++++++++++++++++-------------- client/gui-gtk-3.22/editprop.c | 38 ++++++++++++++++++++-------------- 3 files changed, 69 insertions(+), 45 deletions(-) diff --git a/client/gui-gtk-2.0/editprop.c b/client/gui-gtk-2.0/editprop.c index f769e8371e..64ee3f027a 100644 --- a/client/gui-gtk-2.0/editprop.c +++ b/client/gui-gtk-2.0/editprop.c @@ -218,7 +218,7 @@ static const char *valtype_get_name(enum value_types valtype); To add a new member to union propval_data, see the steps for adding a new value type above. - New property values are "constructed" by objbind_get_value_from_object. + New property values are "constructed" by objbind_get_value_from_object(). ****************************************************************************/ union propval_data { gpointer v_pointer; @@ -473,7 +473,7 @@ static bool objbind_get_allowed_value_span(struct objbind *ob, double *pmax, double *pstep, double *pbig_step); -static void objbind_set_modified_value(struct objbind *ob, +static bool objbind_set_modified_value(struct objbind *ob, struct objprop *op, struct propval *pv); static struct propval *objbind_get_modified_value(struct objbind *ob, @@ -1183,9 +1183,10 @@ static bool propval_equal(struct propval *pva, case VALTYPE_BOOL: return pva->data.v_bool == pvb->data.v_bool; case VALTYPE_STRING: - if (pva->data.v_const_string && pvb->data.v_const_string) { - return 0 == strcmp(pva->data.v_const_string, - pvb->data.v_const_string); + if (pva->data.v_const_string != NULL + && pvb->data.v_const_string != NULL) { + return !strcmp(pva->data.v_const_string, + pvb->data.v_const_string); } return pva->data.v_const_string == pvb->data.v_const_string; case VALTYPE_PIXBUF: @@ -1424,7 +1425,7 @@ static void objbind_request_destroy_object(struct objbind *ob) Returns a newly allocated property value for the given object property on the object referenced by the given object bind, or NULL on failure. - NB: You must call propval_free on the non-NULL return value when it + NB: You must call propval_free() on the non-NULL return value when it no longer needed. ****************************************************************************/ static struct propval *objbind_get_value_from_object(struct objbind *ob, @@ -2093,8 +2094,10 @@ static void objbind_clear_all_modified_values(struct objbind *ob) /**************************************************************************** Store a modified property value, but only if it is different from the current value. Always makes a copy of the given value when storing. + + Returns whether anything changed. ****************************************************************************/ -static void objbind_set_modified_value(struct objbind *ob, +static bool objbind_set_modified_value(struct objbind *ob, struct objprop *op, struct propval *pv) { @@ -2104,14 +2107,14 @@ static void objbind_set_modified_value(struct objbind *ob, enum object_property_ids propid; if (!ob || !op) { - return; + return FALSE; } propid = objprop_get_id(op); pv_old = objbind_get_value_from_object(ob, op); if (!pv_old) { - return; + return FALSE; } equal = propval_equal(pv, pv_old); @@ -2119,7 +2122,7 @@ static void objbind_set_modified_value(struct objbind *ob, if (equal) { objbind_clear_modified_value(ob, op); - return; + return FALSE; } pv_copy = propval_copy(pv); @@ -2130,6 +2133,8 @@ static void objbind_set_modified_value(struct objbind *ob, ps = propstate_new(op, pv_copy); propstate_hash_insert(ob->propstate_table, propid, ps); } + + return TRUE; } /**************************************************************************** @@ -3077,8 +3082,8 @@ static void objprop_refresh_widget(struct objprop *op, propid = objprop_get_id(op); /* NB: We must take care to propval_free the return value of - * objbind_get_value_from_object, since it always makes a - * copy, but to NOT free the result of objbind_get_modified_value + * objbind_get_value_from_object(), since it always makes a + * copy, but to NOT free the result of objbind_get_modified_value() * since it returns its own stored value. */ pv = objbind_get_value_from_object(ob, op); modified = objbind_property_is_modified(ob, op); @@ -5347,6 +5352,7 @@ static void property_page_change_value(struct property_page *pp, GtkTreePath *path; GtkTreeIter iter; struct objbind *ob; + bool changed = FALSE; if (!pp || !op || !pp->object_view) { return; @@ -5363,14 +5369,16 @@ static void property_page_change_value(struct property_page *pp, path = p->data; if (gtk_tree_model_get_iter(model, &iter, path)) { gtk_tree_model_get(model, &iter, 0, &ob, -1); - objbind_set_modified_value(ob, op, pv); + changed |= objbind_set_modified_value(ob, op, pv); } gtk_tree_path_free(path); } g_list_free(rows); - ob = property_page_get_focused_objbind(pp); - objprop_refresh_widget(op, ob); + if (changed) { + ob = property_page_get_focused_objbind(pp); + objprop_refresh_widget(op, ob); + } } /**************************************************************************** diff --git a/client/gui-gtk-3.0/editprop.c b/client/gui-gtk-3.0/editprop.c index df64a18f9f..1bde141b62 100644 --- a/client/gui-gtk-3.0/editprop.c +++ b/client/gui-gtk-3.0/editprop.c @@ -219,7 +219,7 @@ static const char *valtype_get_name(enum value_types valtype); To add a new member to union propval_data, see the steps for adding a new value type above. - New property values are "constructed" by objbind_get_value_from_object. + New property values are "constructed" by objbind_get_value_from_object(). ****************************************************************************/ union propval_data { gpointer v_pointer; @@ -477,7 +477,7 @@ static bool objbind_get_allowed_value_span(struct objbind *ob, double *pmax, double *pstep, double *pbig_step); -static void objbind_set_modified_value(struct objbind *ob, +static bool objbind_set_modified_value(struct objbind *ob, struct objprop *op, struct propval *pv); static struct propval *objbind_get_modified_value(struct objbind *ob, @@ -1187,9 +1187,10 @@ static bool propval_equal(struct propval *pva, case VALTYPE_BOOL: return pva->data.v_bool == pvb->data.v_bool; case VALTYPE_STRING: - if (pva->data.v_const_string && pvb->data.v_const_string) { - return 0 == strcmp(pva->data.v_const_string, - pvb->data.v_const_string); + if (pva->data.v_const_string != NULL + && pvb->data.v_const_string != NULL) { + return !strcmp(pva->data.v_const_string, + pvb->data.v_const_string); } return pva->data.v_const_string == pvb->data.v_const_string; case VALTYPE_PIXBUF: @@ -1428,7 +1429,7 @@ static void objbind_request_destroy_object(struct objbind *ob) Returns a newly allocated property value for the given object property on the object referenced by the given object bind, or NULL on failure. - NB: You must call propval_free on the non-NULL return value when it + NB: You must call propval_free() on the non-NULL return value when it no longer needed. ****************************************************************************/ static struct propval *objbind_get_value_from_object(struct objbind *ob, @@ -2097,8 +2098,10 @@ static void objbind_clear_all_modified_values(struct objbind *ob) /**************************************************************************** Store a modified property value, but only if it is different from the current value. Always makes a copy of the given value when storing. + + Returns whether anything changed. ****************************************************************************/ -static void objbind_set_modified_value(struct objbind *ob, +static bool objbind_set_modified_value(struct objbind *ob, struct objprop *op, struct propval *pv) { @@ -2108,14 +2111,14 @@ static void objbind_set_modified_value(struct objbind *ob, enum object_property_ids propid; if (!ob || !op) { - return; + return FALSE; } propid = objprop_get_id(op); pv_old = objbind_get_value_from_object(ob, op); if (!pv_old) { - return; + return FALSE; } equal = propval_equal(pv, pv_old); @@ -2123,7 +2126,7 @@ static void objbind_set_modified_value(struct objbind *ob, if (equal) { objbind_clear_modified_value(ob, op); - return; + return FALSE; } pv_copy = propval_copy(pv); @@ -2134,6 +2137,8 @@ static void objbind_set_modified_value(struct objbind *ob, ps = propstate_new(op, pv_copy); propstate_hash_insert(ob->propstate_table, propid, ps); } + + return TRUE; } /**************************************************************************** @@ -3111,8 +3116,8 @@ static void objprop_refresh_widget(struct objprop *op, propid = objprop_get_id(op); /* NB: We must take care to propval_free the return value of - * objbind_get_value_from_object, since it always makes a - * copy, but to NOT free the result of objbind_get_modified_value + * objbind_get_value_from_object(), since it always makes a + * copy, but to NOT free the result of objbind_get_modified_value() * since it returns its own stored value. */ pv = objbind_get_value_from_object(ob, op); modified = objbind_property_is_modified(ob, op); @@ -5446,6 +5451,7 @@ static void property_page_change_value(struct property_page *pp, GtkTreePath *path; GtkTreeIter iter; struct objbind *ob; + bool changed = FALSE; if (!pp || !op || !pp->object_view) { return; @@ -5462,14 +5468,16 @@ static void property_page_change_value(struct property_page *pp, path = p->data; if (gtk_tree_model_get_iter(model, &iter, path)) { gtk_tree_model_get(model, &iter, 0, &ob, -1); - objbind_set_modified_value(ob, op, pv); + changed |= objbind_set_modified_value(ob, op, pv); } gtk_tree_path_free(path); } g_list_free(rows); - ob = property_page_get_focused_objbind(pp); - objprop_refresh_widget(op, ob); + if (changed) { + ob = property_page_get_focused_objbind(pp); + objprop_refresh_widget(op, ob); + } } /**************************************************************************** diff --git a/client/gui-gtk-3.22/editprop.c b/client/gui-gtk-3.22/editprop.c index aa064ff639..7db4dc336f 100644 --- a/client/gui-gtk-3.22/editprop.c +++ b/client/gui-gtk-3.22/editprop.c @@ -219,7 +219,7 @@ static const char *valtype_get_name(enum value_types valtype); To add a new member to union propval_data, see the steps for adding a new value type above. - New property values are "constructed" by objbind_get_value_from_object. + New property values are "constructed" by objbind_get_value_from_object(). ****************************************************************************/ union propval_data { gpointer v_pointer; @@ -477,7 +477,7 @@ static bool objbind_get_allowed_value_span(struct objbind *ob, double *pmax, double *pstep, double *pbig_step); -static void objbind_set_modified_value(struct objbind *ob, +static bool objbind_set_modified_value(struct objbind *ob, struct objprop *op, struct propval *pv); static struct propval *objbind_get_modified_value(struct objbind *ob, @@ -1187,9 +1187,10 @@ static bool propval_equal(struct propval *pva, case VALTYPE_BOOL: return pva->data.v_bool == pvb->data.v_bool; case VALTYPE_STRING: - if (pva->data.v_const_string && pvb->data.v_const_string) { - return 0 == strcmp(pva->data.v_const_string, - pvb->data.v_const_string); + if (pva->data.v_const_string != NULL + && pvb->data.v_const_string != NULL) { + return !strcmp(pva->data.v_const_string, + pvb->data.v_const_string); } return pva->data.v_const_string == pvb->data.v_const_string; case VALTYPE_PIXBUF: @@ -1428,7 +1429,7 @@ static void objbind_request_destroy_object(struct objbind *ob) Returns a newly allocated property value for the given object property on the object referenced by the given object bind, or NULL on failure. - NB: You must call propval_free on the non-NULL return value when it + NB: You must call propval_free() on the non-NULL return value when it no longer needed. ****************************************************************************/ static struct propval *objbind_get_value_from_object(struct objbind *ob, @@ -2097,8 +2098,10 @@ static void objbind_clear_all_modified_values(struct objbind *ob) /**************************************************************************** Store a modified property value, but only if it is different from the current value. Always makes a copy of the given value when storing. + + Returns whether anything changed. ****************************************************************************/ -static void objbind_set_modified_value(struct objbind *ob, +static bool objbind_set_modified_value(struct objbind *ob, struct objprop *op, struct propval *pv) { @@ -2108,14 +2111,14 @@ static void objbind_set_modified_value(struct objbind *ob, enum object_property_ids propid; if (!ob || !op) { - return; + return FALSE; } propid = objprop_get_id(op); pv_old = objbind_get_value_from_object(ob, op); if (!pv_old) { - return; + return FALSE; } equal = propval_equal(pv, pv_old); @@ -2123,7 +2126,7 @@ static void objbind_set_modified_value(struct objbind *ob, if (equal) { objbind_clear_modified_value(ob, op); - return; + return FALSE; } pv_copy = propval_copy(pv); @@ -2134,6 +2137,8 @@ static void objbind_set_modified_value(struct objbind *ob, ps = propstate_new(op, pv_copy); propstate_hash_insert(ob->propstate_table, propid, ps); } + + return TRUE; } /**************************************************************************** @@ -3111,8 +3116,8 @@ static void objprop_refresh_widget(struct objprop *op, propid = objprop_get_id(op); /* NB: We must take care to propval_free the return value of - * objbind_get_value_from_object, since it always makes a - * copy, but to NOT free the result of objbind_get_modified_value + * objbind_get_value_from_object(), since it always makes a + * copy, but to NOT free the result of objbind_get_modified_value() * since it returns its own stored value. */ pv = objbind_get_value_from_object(ob, op); modified = objbind_property_is_modified(ob, op); @@ -5446,6 +5451,7 @@ static void property_page_change_value(struct property_page *pp, GtkTreePath *path; GtkTreeIter iter; struct objbind *ob; + bool changed = FALSE; if (!pp || !op || !pp->object_view) { return; @@ -5462,14 +5468,16 @@ static void property_page_change_value(struct property_page *pp, path = p->data; if (gtk_tree_model_get_iter(model, &iter, path)) { gtk_tree_model_get(model, &iter, 0, &ob, -1); - objbind_set_modified_value(ob, op, pv); + changed |= objbind_set_modified_value(ob, op, pv); } gtk_tree_path_free(path); } g_list_free(rows); - ob = property_page_get_focused_objbind(pp); - objprop_refresh_widget(op, ob); + if (changed) { + ob = property_page_get_focused_objbind(pp); + objprop_refresh_widget(op, ob); + } } /**************************************************************************** -- 2.35.1