From 2632ed7a6966803d5e4f1db05c3f1a9c8f8aac59 Mon Sep 17 00:00:00 2001 From: Christian Persch Date: Fri, 4 Jun 2021 12:09:24 +0000 Subject: [PATCH] gsettings: Resolve child schemas from the parent's schema source --- gio/gsettings.c | 22 ++++++++----------- gio/gsettingsschema-internal.h | 3 +++ gio/gsettingsschema.c | 18 +++++++++++++++ gio/tests/gsettings.c | 11 +++++++--- .../org.gtk.schemasourcecheck.gschema.xml | 3 ++- 5 files changed, 40 insertions(+), 17 deletions(-) diff --git a/gio/gsettings.c b/gio/gsettings.c index a2d5a36e2..ee9c094d9 100644 --- a/gio/gsettings.c +++ b/gio/gsettings.c @@ -2434,28 +2434,24 @@ GSettings * g_settings_get_child (GSettings *settings, const gchar *name) { - const gchar *child_schema; + GSettingsSchema *child_schema; gchar *child_path; - gchar *child_name; GSettings *child; g_return_val_if_fail (G_IS_SETTINGS (settings), NULL); - child_name = g_strconcat (name, "/", NULL); - child_schema = g_settings_schema_get_string (settings->priv->schema, - child_name); + child_schema = g_settings_schema_get_child_schema (settings->priv->schema, + name); if (child_schema == NULL) - g_error ("Schema '%s' has no child '%s'", + g_error ("Schema '%s' has no child '%s' or child schema not found", g_settings_schema_get_id (settings->priv->schema), name); - child_path = g_strconcat (settings->priv->path, child_name, NULL); - child = g_object_new (G_TYPE_SETTINGS, - "backend", settings->priv->backend, - "schema-id", child_schema, - "path", child_path, - NULL); + child_path = g_strconcat (settings->priv->path, name, "/", NULL); + child = g_settings_new_full (child_schema, + settings->priv->backend, + child_path); + g_settings_schema_unref (child_schema); g_free (child_path); - g_free (child_name); return child; } diff --git a/gio/gsettingsschema-internal.h b/gio/gsettingsschema-internal.h index 5f996b4bc..416cf2d8c 100644 --- a/gio/gsettingsschema-internal.h +++ b/gio/gsettingsschema-internal.h @@ -50,6 +50,9 @@ const GQuark * g_settings_schema_list (GSettin const gchar * g_settings_schema_get_string (GSettingsSchema *schema, const gchar *key); +GSettingsSchema * g_settings_schema_get_child_schema (GSettingsSchema *schema, + const gchar *name); + void g_settings_schema_key_init (GSettingsSchemaKey *key, GSettingsSchema *schema, const gchar *name); diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c index a46d5056f..ec0caf655 100644 --- a/gio/gsettingsschema.c +++ b/gio/gsettingsschema.c @@ -968,6 +968,24 @@ g_settings_schema_get_string (GSettingsSchema *schema, return result; } +GSettingsSchema * +g_settings_schema_get_child_schema (GSettingsSchema *schema, + const gchar *name) +{ + const gchar *child_id; + gchar *child_name; + + child_name = g_strconcat (name, "/", NULL); + child_id = g_settings_schema_get_string (schema, child_name); + + g_free (child_name); + + if (child_id == NULL) + return NULL; + + return g_settings_schema_source_lookup (schema->source, child_id, TRUE); +} + GVariantIter * g_settings_schema_get_value (GSettingsSchema *schema, const gchar *key) diff --git a/gio/tests/gsettings.c b/gio/tests/gsettings.c index b809090e7..42eeccd7a 100644 --- a/gio/tests/gsettings.c +++ b/gio/tests/gsettings.c @@ -2572,7 +2572,7 @@ test_schema_source (void) GSettingsBackend *backend; GSettingsSchema *schema; GError *error = NULL; - GSettings *settings; + GSettings *settings, *child; gboolean enabled; backend = g_settings_backend_get_default (); @@ -2628,13 +2628,18 @@ test_schema_source (void) g_assert_nonnull (schema); /* try to use it for something */ - settings = g_settings_new_full (schema, backend, g_settings_schema_get_path (schema)); + settings = g_settings_new_full (schema, backend, "/test/"); g_settings_schema_unref (schema); enabled = FALSE; g_settings_get (settings, "enabled", "b", &enabled); g_assert_true (enabled); - g_object_unref (settings); + /* Check that child schemas are resolved from the correct schema source, see glib#1884 */ + child = g_settings_get_child (settings, "child"); + g_settings_get (settings, "enabled", "b", &enabled); + + g_object_unref (child); + g_object_unref (settings); g_settings_schema_source_unref (source); /* try again, but with no parent */ diff --git a/gio/tests/org.gtk.schemasourcecheck.gschema.xml b/gio/tests/org.gtk.schemasourcecheck.gschema.xml index 42c9c5104..b484da1a3 100644 --- a/gio/tests/org.gtk.schemasourcecheck.gschema.xml +++ b/gio/tests/org.gtk.schemasourcecheck.gschema.xml @@ -1,7 +1,8 @@ - + true +