X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgsettings.c;h=23a14bcc90db2540da6dd8c182aa62a172f7dc27;hb=853692bdfd9f8a87aed70d21f643dc13b57c92d1;hp=e3abb748076a41b3e2a381ea50b188a10f3d7251;hpb=ea22300620a10affaa3192d8f56c777a81fcd2c6;p=platform%2Fupstream%2Fglib.git diff --git a/gio/gsettings.c b/gio/gsettings.c index e3abb74..23a14bc 100644 --- a/gio/gsettings.c +++ b/gio/gsettings.c @@ -12,9 +12,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library; if not, see . * * Author: Ryan Lortie */ @@ -85,43 +83,52 @@ * 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 - * gettext-domain attribute of the - * schemalist or schema - * elements and the category that is specified in the l10n attribute of the - * key element. + * gettext-domain attribute of the or + * elements and the category that is specified in the l10n attribute of + * the element. * * GSettings uses schemas in a compact binary form that is created - * by the glib-compile-schemas - * utility. The input is a schema description in an XML format that can be - * described by the following DTD: - * |[FIXME: MISSING XINCLUDE CONTENT]| - * - * glib-compile-schemas expects schema files to have the extension .gschema.xml - * - * At runtime, schemas are identified by their id (as specified - * in the id attribute of the - * schema element). The - * convention for schema ids is to use a dotted name, similar in - * style to a D-Bus bus name, e.g. "org.gnome.SessionManager". In particular, - * if the settings are for a specific service that owns a D-Bus bus name, - * the D-Bus bus name and schema id should match. For schemas which deal - * with settings not associated with one named application, the id should - * not use StudlyCaps, e.g. "org.gnome.font-rendering". - * - * In addition to #GVariant types, keys can have types that have enumerated - * types. These can be described by a choice, - * enum or flags element, see - * . The underlying type of - * such a key is string, but you can use g_settings_get_enum(), - * g_settings_set_enum(), g_settings_get_flags(), g_settings_set_flags() - * access the numeric values corresponding to the string value of enum - * and flags keys. - * - * Default values - * element). The convention for schema + * ids is to use a dotted name, similar in style to a D-Bus bus name, + * e.g. "org.gnome.SessionManager". In particular, if the settings are + * for a specific service that owns a D-Bus bus name, the D-Bus bus name + * and schema id should match. For schemas which deal with settings not + * associated with one named application, the id should not use + * StudlyCaps, e.g. "org.gnome.font-rendering". + * + * In addition to #GVariant types, keys can have types that have + * enumerated types. These can be described by a , + * or element, as seen in the + * [example][schema-enumerated]. The underlying type of such a key + * is string, but you can use g_settings_get_enum(), g_settings_set_enum(), + * g_settings_get_flags(), g_settings_set_flags() access the numeric values + * corresponding to the string value of enum and flags keys. + * + * An example for default value: + * |[ * * * @@ -139,10 +146,10 @@ * * * - * ]]> + * ]| * - * Ranges, choices and enumerated types - * * * @@ -185,52 +192,43 @@ * * * - * ]]> - * - * - * Vendor overrides - * - * Default values are defined in the schemas that get installed by - * an application. Sometimes, it is necessary for a vendor or distributor - * to adjust these defaults. Since patching the XML source for the schema - * is inconvenient and error-prone, - * glib-compile-schemas reads - * so-called 'vendor override' files. These are keyfiles in the same - * directory as the XML schema sources which can override default values. - * The schema id serves as the group name in the key file, and the values - * are expected in serialized GVariant form, as in the following example: - * + * ]| + * + * ## Vendor overrides + * + * Default values are defined in the schemas that get installed by + * an application. Sometimes, it is necessary for a vendor or distributor + * to adjust these defaults. Since patching the XML source for the schema + * is inconvenient and error-prone, + * [glib-compile-schemas][glib-compile-schemas] reads so-called vendor + * override' files. These are keyfiles in the same directory as the XML + * schema sources which can override default values. The schema id serves + * as the group name in the key file, and the values are expected in + * serialized GVariant form, as in the following example: + * |[ * [org.gtk.Example] * key1='string' * key2=1.5 - * - * - * - * glib-compile-schemas expects schema files to have the extension - * .gschema.override - * - * - * - * - * Binding - * - * A very convenient feature of GSettings lets you bind #GObject properties - * directly to settings, using g_settings_bind(). Once a GObject property - * has been bound to a setting, changes on either side are automatically - * propagated to the other side. GSettings handles details like - * mapping between GObject and GVariant types, and preventing infinite - * cycles. - * - * - * This makes it very easy to hook up a preferences dialog to the - * underlying settings. To make this even more convenient, GSettings - * looks for a boolean property with the name "sensitivity" and - * automatically binds it to the writability of the bound setting. - * If this 'magic' gets in the way, it can be suppressed with the - * #G_SETTINGS_BIND_NO_SENSITIVITY flag. - * - * - **/ + * ]| + * + * glib-compile-schemas expects schema files to have the extension + * `.gschema.override`. + * + * ## Binding + * + * A very convenient feature of GSettings lets you bind #GObject properties + * directly to settings, using g_settings_bind(). Once a GObject property + * has been bound to a setting, changes on either side are automatically + * propagated to the other side. GSettings handles details like mapping + * between GObject and GVariant types, and preventing infinite cycles. + * + * This makes it very easy to hook up a preferences dialog to the + * underlying settings. To make this even more convenient, GSettings + * looks for a boolean property with the name "sensitivity" and + * automatically binds it to the writability of the bound setting. + * If this 'magic' gets in the way, it can be suppressed with the + * #G_SETTINGS_BIND_NO_SENSITIVITY flag. + */ struct _GSettingsPrivate { @@ -241,6 +239,8 @@ struct _GSettingsPrivate GSettingsSchema *schema; gchar *path; + gboolean is_subscribed; + GDelayedSettingsBackend *delayed; }; @@ -316,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, @@ -369,8 +395,8 @@ static void settings_backend_keys_changed (GObject *target, GSettingsBackend *backend, const gchar *path, - const gchar * const *items, - gpointer origin_tag) + gpointer origin_tag, + const gchar * const *items) { GSettings *settings = G_SETTINGS (target); gboolean ignore_this; @@ -582,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 @@ -591,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); @@ -645,7 +671,7 @@ g_settings_class_init (GSettingsClass *class) * GSettings::change-event: * @settings: the object on which the signal was emitted * @keys: (array length=n_keys) (element-type GQuark) (allow-none): - * an array of #GQuarks for the changed keys, or %NULL + * an array of #GQuarks for the changed keys, or %NULL * @n_keys: the length of the @keys array, or 0 * * The "change-event" signal is emitted once per change event that @@ -1057,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); @@ -2183,14 +2216,14 @@ g_settings_is_writable (GSettings *settings, /** * g_settings_get_child: * @settings: a #GSettings object - * @name: the name of the 'child' schema + * @name: the name of the child schema * - * Creates a 'child' settings object which has a base path of - * base-path/@name, where - * base-path is the base path of @settings. + * Creates a child settings object which has a base path of + * `base-path/@name`, where `base-path` is the base path of + * @settings. * * The schema for the child settings object must have been declared - * in the schema of @settings using a child element. + * in the schema of @settings using a element. * * Returns: (transfer full): a 'child' settings object * @@ -2852,8 +2885,7 @@ g_settings_binding_writable_changed (GSettings *settings, * * When the @inverted argument is %TRUE, the binding inverts the * value as it passes from the setting to the object, i.e. @property - * will be set to %TRUE if the key is not - * writable. + * will be set to %TRUE if the key is not writable. * * Note that the lifecycle of the binding is tied to the object, * and that you can have only one binding per object property.