[glib: 1/2] gsettings: Resolve child schemas from the parent's schema source




commit 2632ed7a6966803d5e4f1db05c3f1a9c8f8aac59
Author: Christian Persch <chpe src gnome org>
Date:   Fri Jun 4 12:09:24 2021 +0000

    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 ++++++++---
 gio/tests/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 @@
 <schemalist>
-  <schema id="org.gtk.schemasourcecheck" path="/tests/">
+  <schema id="org.gtk.schemasourcecheck">
     <key name="enabled" type="b">
       <default>true</default>
     </key>
+    <child name="child" schema="org.gtk.schemasourcecheck" />
   </schema>
 </schemalist>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]