diff options
-rw-r--r-- | engine/dconf-engine.c | 52 | ||||
-rw-r--r-- | tests/dconf-mock-gvdb.c | 21 |
2 files changed, 63 insertions, 10 deletions
diff --git a/engine/dconf-engine.c b/engine/dconf-engine.c index 9e4b358..714a062 100644 --- a/engine/dconf-engine.c +++ b/engine/dconf-engine.c @@ -346,18 +346,36 @@ dconf_engine_get_state (DConfEngine *engine) static gboolean dconf_engine_source_has_lock (DConfEngineSource *source, - const gchar *key) + GvdbPath *path) { + gboolean locked = FALSE; + GVariant *value; + if (source->locks == NULL) return FALSE; - return gvdb_table_has_value (source->locks, key); + value = gvdb_table_get_best_value_for_path (source->locks, path); + if (value) + { + /* Historically, the empty string, "" has meant 'locked', so + * consider any non-binary value to be TRUE. + */ + locked = TRUE; + + if (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)) + locked = g_variant_get_boolean (value); + + g_variant_unref (value); + } + + return locked; } static gboolean dconf_engine_is_writable_internal (DConfEngine *engine, const gchar *key) { + GvdbPath path; gint i; /* We must check several things: @@ -374,13 +392,21 @@ dconf_engine_is_writable_internal (DConfEngine *engine, if (engine->sources[0]->writable == FALSE) return FALSE; + /* This must be true, because the only way we have locks is if they + * are in source #1 or lower, except for the cases that were handled + * above. + */ + g_assert (engine->n_sources > 1); + + gvdb_path_init (&path, key, '/'); + /* Ignore locks in the first source. * * Either it is writable and therefore ignoring locks is the right * thing to do, or it's non-writable and we caught that case above. */ for (i = 1; i < engine->n_sources; i++) - if (dconf_engine_source_has_lock (engine->sources[i], key)) + if (dconf_engine_source_has_lock (engine->sources[i], &path)) return FALSE; return TRUE; @@ -607,13 +633,19 @@ dconf_engine_read (DConfEngine *engine, * * Note: i > 0 (strictly). Ignore locks for source #0. */ - if (~flags & DCONF_READ_USER_VALUE) - for (i = engine->n_sources - 1; i > 0; i--) - if (dconf_engine_source_has_lock (engine->sources[i], key)) - { - lock_level = i; - break; - } + if (~flags & DCONF_READ_USER_VALUE && engine->has_locks) + { + GvdbPath path; + + gvdb_path_init (&path, key, '/'); + + for (i = engine->n_sources - 1; i > 0; i--) + if (dconf_engine_source_has_lock (engine->sources[i], &path)) + { + lock_level = i; + break; + } + } /* Only do steps 2 to 4 if we have no locks and we have a writable source. */ if (!lock_level && engine->n_sources != 0 && engine->sources[0]->writable) diff --git a/tests/dconf-mock-gvdb.c b/tests/dconf-mock-gvdb.c index 4f58de1..ff5f039 100644 --- a/tests/dconf-mock-gvdb.c +++ b/tests/dconf-mock-gvdb.c @@ -209,3 +209,24 @@ dconf_mock_gvdb_table_invalidate (GvdbTable *table) { table->is_valid = FALSE; } + +GVariant * +gvdb_table_get_best_value_for_path (GvdbTable *table, + GvdbPath *path) +{ + /* TODO: make this actually check different path components */ + return gvdb_table_get_value (table, path->string); +} + +void +gvdb_path_init (GvdbPath *path, + const gchar *key, + gchar separator) +{ + path->string = key; +} + +void +gvdb_path_clear (GvdbPath *path) +{ +} |