diff --git a/gio/gdelayedsettingsbackend.c b/gio/gdelayedsettingsbackend.c index 6c1866b5b..20bcc375c 100644 --- a/gio/gdelayedsettingsbackend.c +++ b/gio/gdelayedsettingsbackend.c @@ -104,6 +104,32 @@ g_delayed_settings_backend_read (GSettingsBackend *backend, return result; } +static GVariant * +g_delayed_settings_backend_read_user_value (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type) +{ + GDelayedSettingsBackend *delayed = G_DELAYED_SETTINGS_BACKEND (backend); + gboolean value_found = FALSE; + gpointer result = NULL; + + /* If we find an explicit NULL in our changeset then we want to return + * NULL (because the user value has been reset). + * + * Otherwise, chain up. + */ + g_mutex_lock (&delayed->priv->lock); + value_found = g_tree_lookup_extended (delayed->priv->delayed, key, NULL, &result); + if (result) + g_variant_ref (result); + g_mutex_unlock (&delayed->priv->lock); + + if (value_found) + return result; + + return g_settings_backend_read_user_value (delayed->priv->backend, key, expected_type); +} + static gboolean g_delayed_settings_backend_write (GSettingsBackend *backend, const gchar *key, @@ -429,6 +455,7 @@ g_delayed_settings_backend_class_init (GDelayedSettingsBackendClass *class) GObjectClass *object_class = G_OBJECT_CLASS (class); backend_class->read = g_delayed_settings_backend_read; + backend_class->read_user_value = g_delayed_settings_backend_read_user_value; backend_class->write = g_delayed_settings_backend_write; backend_class->write_tree = g_delayed_settings_backend_write_tree; backend_class->reset = g_delayed_settings_backend_reset; diff --git a/gio/gsettingsbackend.c b/gio/gsettingsbackend.c index 608a452af..be28dc1e9 100644 --- a/gio/gsettingsbackend.c +++ b/gio/gsettingsbackend.c @@ -745,6 +745,43 @@ g_settings_backend_read (GSettingsBackend *backend, return value; } +/*< private > + * g_settings_backend_read_user_value: + * @backend: a #GSettingsBackend implementation + * @key: the key to read + * @expected_type: a #GVariantType + * + * Reads the 'user value' of a key. + * + * This is the value of the key that the user has control over and has + * set for themselves. Put another way: if the user did not set the + * value for themselves, then this will return %NULL (even if the + * sysadmin has provided a default value). + * + * Returns: the value that was read, or %NULL + */ +GVariant * +g_settings_backend_read_user_value (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type) +{ + GVariant *value; + + value = G_SETTINGS_BACKEND_GET_CLASS (backend) + ->read_user_value (backend, key, expected_type); + + if (value != NULL) + value = g_variant_take_ref (value); + + if G_UNLIKELY (value && !g_variant_is_of_type (value, expected_type)) + { + g_variant_unref (value); + value = NULL; + } + + return value; +} + /*< private > * g_settings_backend_write: * @backend: a #GSettingsBackend implementation @@ -903,6 +940,14 @@ ignore_subscription (GSettingsBackend *backend, { } +static GVariant * +g_settings_backend_real_read_user_value (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type) +{ + return g_settings_backend_read (backend, key, expected_type, FALSE); +} + static void g_settings_backend_init (GSettingsBackend *backend) { @@ -918,6 +963,8 @@ g_settings_backend_class_init (GSettingsBackendClass *class) class->subscribe = ignore_subscription; class->unsubscribe = ignore_subscription; + class->read_user_value = g_settings_backend_real_read_user_value; + gobject_class->finalize = g_settings_backend_finalize; } diff --git a/gio/gsettingsbackend.h b/gio/gsettingsbackend.h index 293ca651f..2c253559b 100644 --- a/gio/gsettingsbackend.h +++ b/gio/gsettingsbackend.h @@ -93,7 +93,11 @@ struct _GSettingsBackendClass GPermission * (*get_permission) (GSettingsBackend *backend, const gchar *path); - gpointer padding[24]; + GVariant * (*read_user_value) (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type); + + gpointer padding[23]; }; struct _GSettingsBackend diff --git a/gio/gsettingsbackendinternal.h b/gio/gsettingsbackendinternal.h index f782c7cbc..0c22f9074 100644 --- a/gio/gsettingsbackendinternal.h +++ b/gio/gsettingsbackendinternal.h @@ -62,6 +62,9 @@ GVariant * g_settings_backend_read (GSettin const gchar *key, const GVariantType *expected_type, gboolean default_value); +GVariant * g_settings_backend_read_user_value (GSettingsBackend *backend, + const gchar *key, + const GVariantType *expected_type); gboolean g_settings_backend_write (GSettingsBackend *backend, const gchar *key, GVariant *value,