summaryrefslogtreecommitdiff
path: root/common/dconf-changeset.c
diff options
context:
space:
mode:
authorDaniel Playfair Cal <daniel.playfair.cal@gmail.com>2018-08-13 14:25:47 +1000
committerDaniel Playfair Cal <daniel.playfair.cal@gmail.com>2019-12-29 20:07:43 +1100
commit77f799922ab6afbaeb3f7ee41c96548439fd3dbd (patch)
treecb3f0ad3b38a51badbcae04cd410fb244804290c /common/dconf-changeset.c
parent2206d4955184f45e47c3407d4af7fd46474cdbdb (diff)
downloaddconf-77f799922ab6afbaeb3f7ee41c96548439fd3dbd.tar.gz
Changeset: make dconf_changeset_filter_changes filter out key/path resets when appropriate
Diffstat (limited to 'common/dconf-changeset.c')
-rw-r--r--common/dconf-changeset.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/common/dconf-changeset.c b/common/dconf-changeset.c
index 705fec9..cea34c1 100644
--- a/common/dconf-changeset.c
+++ b/common/dconf-changeset.c
@@ -793,7 +793,7 @@ dconf_changeset_filter_changes (DConfChangeset *base,
DConfChangeset *changes)
{
DConfChangeset *result = NULL;
- GHashTableIter iter;
+ GHashTableIter iter_changes;
gpointer key, val;
g_return_val_if_fail (base->is_database, NULL);
@@ -805,13 +805,43 @@ dconf_changeset_filter_changes (DConfChangeset *base,
* Note: because 'base' is a database changeset we don't have to
* worry about it containing NULL values (dir resets).
*/
- g_hash_table_iter_init (&iter, changes->table);
- while (g_hash_table_iter_next (&iter, &key, &val))
+ g_hash_table_iter_init (&iter_changes, changes->table);
+ while (g_hash_table_iter_next (&iter_changes, &key, &val))
{
GVariant *base_val = g_hash_table_lookup (base->table, key);
- if (base_val == NULL || !g_variant_equal (val, base_val))
+ if (g_str_has_suffix (key, "/"))
+ {
+ // Path reset
+ gboolean reset_is_effective = FALSE;
+ GHashTableIter iter_base;
+ gpointer base_key = NULL;
+
+ g_return_val_if_fail (val == NULL, NULL);
+
+ // First we check whether there are any keys in base that would be reset
+ g_hash_table_iter_init (&iter_base, base->table);
+ while (g_hash_table_iter_next (&iter_base, &base_key, NULL))
+ if (g_str_has_prefix (base_key, key) && !g_str_equal (base_key, key))
+ {
+ reset_is_effective = TRUE;
+ break;
+ }
+
+ if (reset_is_effective)
+ {
+ if (!result)
+ result = dconf_changeset_new ();
+
+ dconf_changeset_set (result, key, val);
+ }
+ }
+ else if (base_val == NULL && val == NULL)
+ continue; // Resetting a key that wasn't set
+ else if (val == NULL || base_val == NULL || !g_variant_equal (val, base_val))
{
+ // Resetting an existing key, inserting a value under a key that was not
+ // set, or replacing an existing value with a different one.
if (!result)
result = dconf_changeset_new ();