[evolution-data-server] [Esource] Do not set properties on load which did not change
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] [Esource] Do not set properties on load which did not change
- Date: Fri, 24 Jan 2014 16:42:55 +0000 (UTC)
commit 294ec486b3bcb82192844fba07a642a789d19e25
Author: Milan Crha <mcrha redhat com>
Date: Fri Jan 24 17:39:45 2014 +0100
[Esource] Do not set properties on load which did not change
When calling g_object_set(), g_object_set_property() and similar
set functions, the GObject itself notifies about the property change,
even if the value didn't change at all. This was exhibited by false
notifications when (re)loading ESource on a change on all its saved
properties, which, in particular, was causing bug #722399.
libedataserver/e-source.c | 81 ++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 80 insertions(+), 1 deletions(-)
---
diff --git a/libedataserver/e-source.c b/libedataserver/e-source.c
index 1b4077d..4b611d3 100644
--- a/libedataserver/e-source.c
+++ b/libedataserver/e-source.c
@@ -319,6 +319,69 @@ source_localized_hack (GKeyFile *key_file,
g_key_file_set_string (key_file, group_name, key, new_value);
}
+static gboolean
+source_check_values_differ (GType g_type,
+ const GValue *value,
+ const GValue *value2)
+{
+ gboolean differ = TRUE;
+ GValue *value1;
+
+ g_return_val_if_fail (value != NULL, TRUE);
+ g_return_val_if_fail (value2 != NULL, TRUE);
+
+ value1 = g_slice_new0 (GValue);
+ g_value_init (value1, g_type);
+ g_value_copy (value2, value1);
+
+ if (g_value_transform (value, value1)) {
+ #define check_type(name,get) G_STMT_START { \
+ if (G_VALUE_HOLDS_ ## name (value1)) { \
+ differ = g_value_get_ ## get (value1) != g_value_get_ ## get (value2); \
+ break; \
+ } } G_STMT_END
+
+ do {
+ check_type (BOOLEAN, boolean);
+ check_type (CHAR, char);
+ check_type (DOUBLE, double);
+ check_type (ENUM, enum);
+ check_type (FLAGS, flags);
+ check_type (FLOAT, float);
+ check_type (GTYPE, gtype);
+ check_type (INT, int);
+ check_type (INT64, int64);
+ check_type (LONG, long);
+ check_type (POINTER, pointer);
+ check_type (UCHAR, uchar);
+ check_type (UINT, uint);
+ check_type (UINT64, uint64);
+ check_type (ULONG, ulong);
+
+ if (G_VALUE_HOLDS_STRING (value1)) {
+ differ = g_strcmp0 (g_value_get_string (value1), g_value_get_string (value2))
!= 0;
+ break;
+ }
+
+ if (G_VALUE_HOLDS_VARIANT (value1)) {
+ GVariant *variant1, *variant2;
+
+ variant1 = g_value_get_variant (value1);
+ variant2 = g_value_get_variant (value2);
+ differ = g_variant_compare (variant1, variant2) != 0;
+ break;
+ }
+ } while (FALSE);
+
+ #undef check_type
+ }
+
+ g_value_unset (value1);
+ g_slice_free (GValue, value1);
+
+ return differ;
+}
+
static void
source_set_key_file_from_property (GObject *object,
GParamSpec *pspec,
@@ -570,7 +633,23 @@ source_set_property_from_key_file (GObject *object,
}
if (G_IS_VALUE (value)) {
- g_object_set_property (object, pspec->name, value);
+ GValue *cvalue;
+
+ cvalue = g_slice_new0 (GValue);
+ g_value_init (cvalue, pspec->value_type);
+ g_object_get_property (object, pspec->name, cvalue);
+
+ /* This is because the g_object_set_property() invokes "notify" signal
+ on the set property, even if the value did not change, which creates
+ false notifications, which can cause UI or background activities
+ without any real reason (especially with the ''enabled' property load). */
+ if (!G_IS_VALUE (cvalue) || source_check_values_differ (pspec->value_type, value, cvalue))
+ g_object_set_property (object, pspec->name, value);
+
+ if (G_IS_VALUE (cvalue))
+ g_value_unset (cvalue);
+ g_slice_free (GValue, cvalue);
+
g_value_unset (value);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]