X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgsettings.c;h=23a14bcc90db2540da6dd8c182aa62a172f7dc27;hb=2138deb07ebb7d7e541c0cd35b966e107d1bf800;hp=fdc3c9d10cf20465ca2d13cf7c578e8ce78e2e29;hpb=59c9291f5f12492bab5bb303af41a38b930be97b;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gsettings.c b/gio/gsettings.c index fdc3c9d..23a14bc 100644 --- a/gio/gsettings.c +++ b/gio/gsettings.c @@ -83,6 +83,16 @@ * the names must begin with a lowercase character, must not end * with a '-', and must not contain consecutive dashes. * + * GSettings supports change notification. The primary mechanism to + * watch for changes is to connect to the "changed" signal. You can + * optionally watch for changes on only a single key by using a signal + * detail. Signals are only guaranteed to be emitted for a given key + * after you have read the value of that key while a signal handler was + * connected for that key. Signals may or may not be emitted in the + * case that the key "changed" to the value that you had previously + * read. Signals may be reported in additional cases as well and the + * "changed" signal should really be treated as "may have changed". + * * Similar to GConf, the default values in GSettings schemas can be * localized, but the localized values are stored in gettext catalogs * and looked up with the domain that is specified in the @@ -229,6 +239,8 @@ struct _GSettingsPrivate GSettingsSchema *schema; gchar *path; + gboolean is_subscribed; + GDelayedSettingsBackend *delayed; }; @@ -304,6 +316,32 @@ g_settings_real_writable_change_event (GSettings *settings, return FALSE; } +static gboolean +g_settings_has_signal_handlers (GSettings *settings, + const gchar *key) +{ + GSettingsClass *class = G_SETTINGS_GET_CLASS (settings); + GQuark keyq; + + if (class->change_event != g_settings_real_change_event || + class->writable_change_event != g_settings_real_writable_change_event) + return TRUE; + + keyq = g_quark_from_string (key); + + if (g_signal_has_handler_pending (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT], 0, TRUE) || + g_signal_has_handler_pending (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGED], 0, TRUE) || + g_signal_has_handler_pending (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGED], keyq, TRUE) || + g_signal_has_handler_pending (settings, g_settings_signals[SIGNAL_CHANGE_EVENT], 0, TRUE) || + g_signal_has_handler_pending (settings, g_settings_signals[SIGNAL_CHANGED], 0, TRUE) || + g_signal_has_handler_pending (settings, g_settings_signals[SIGNAL_CHANGED], keyq, TRUE)) + return TRUE; + + /* None of that? Then surely nobody is watching.... */ + return FALSE; +} + + static void settings_backend_changed (GObject *target, GSettingsBackend *backend, @@ -570,8 +608,6 @@ g_settings_constructed (GObject *object) g_settings_backend_watch (settings->priv->backend, &listener_vtable, G_OBJECT (settings), settings->priv->main_context); - g_settings_backend_subscribe (settings->priv->backend, - settings->priv->path); } static void @@ -579,8 +615,10 @@ g_settings_finalize (GObject *object) { GSettings *settings = G_SETTINGS (object); - g_settings_backend_unsubscribe (settings->priv->backend, - settings->priv->path); + if (settings->priv->is_subscribed) + g_settings_backend_unsubscribe (settings->priv->backend, + settings->priv->path); + g_main_context_unref (settings->priv->main_context); g_object_unref (settings->priv->backend); g_settings_schema_unref (settings->priv->schema); @@ -1045,6 +1083,13 @@ g_settings_read_from_backend (GSettings *settings, GVariant *fixup; gchar *path; + /* If we are not yet watching for changes, consider doing it now... */ + if (!settings->priv->is_subscribed && g_settings_has_signal_handlers (settings, key->name)) + { + g_settings_backend_subscribe (settings->priv->backend, settings->priv->path); + settings->priv->is_subscribed = TRUE; + } + path = g_strconcat (settings->priv->path, key->name, NULL); if (user_value_only) value = g_settings_backend_read_user_value (settings->priv->backend, path, key->type);