1 /*
2 * Copyright © 2009, 2010 Codethink Limited
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author: Ryan Lortie <desrt@desrt.ca>
18 */
19
20 /* Prelude {{{1 */
21 #include "config.h"
22
23 #include <glib.h>
24 #include <glibintl.h>
25
26 #include "gsettings.h"
27
28 #include "gdelayedsettingsbackend.h"
29 #include "gsettingsbackendinternal.h"
30 #include "gsettings-mapping.h"
31 #include "gsettingsschema-internal.h"
32 #include "gaction.h"
33 #include "gmarshal-internal.h"
34
35 #include "strinfo.c"
36
37 /**
38 * SECTION:gsettings
39 * @short_description: High-level API for application settings
40 * @include: gio/gio.h
41 *
42 * The #GSettings class provides a convenient API for storing and retrieving
43 * application settings.
44 *
45 * Reads and writes can be considered to be non-blocking. Reading
46 * settings with #GSettings is typically extremely fast: on
47 * approximately the same order of magnitude (but slower than) a
48 * #GHashTable lookup. Writing settings is also extremely fast in terms
49 * of time to return to your application, but can be extremely expensive
50 * for other threads and other processes. Many settings backends
51 * (including dconf) have lazy initialisation which means in the common
52 * case of the user using their computer without modifying any settings
53 * a lot of work can be avoided. For dconf, the D-Bus service doesn't
54 * even need to be started in this case. For this reason, you should
55 * only ever modify #GSettings keys in response to explicit user action.
56 * Particular care should be paid to ensure that modifications are not
57 * made during startup -- for example, when setting the initial value
58 * of preferences widgets. The built-in g_settings_bind() functionality
59 * is careful not to write settings in response to notify signals as a
60 * result of modifications that it makes to widgets.
61 *
62 * When creating a GSettings instance, you have to specify a schema
63 * that describes the keys in your settings and their types and default
64 * values, as well as some other information.
65 *
66 * Normally, a schema has a fixed path that determines where the settings
67 * are stored in the conceptual global tree of settings. However, schemas
68 * can also be '[relocatable][gsettings-relocatable]', i.e. not equipped with
69 * a fixed path. This is
70 * useful e.g. when the schema describes an 'account', and you want to be
71 * able to store a arbitrary number of accounts.
72 *
73 * Paths must start with and end with a forward slash character ('/')
74 * and must not contain two sequential slash characters. Paths should
75 * be chosen based on a domain name associated with the program or
76 * library to which the settings belong. Examples of paths are
77 * "/org/gtk/settings/file-chooser/" and "/ca/desrt/dconf-editor/".
78 * Paths should not start with "/apps/", "/desktop/" or "/system/" as
79 * they often did in GConf.
80 *
81 * Unlike other configuration systems (like GConf), GSettings does not
82 * restrict keys to basic types like strings and numbers. GSettings stores
83 * values as #GVariant, and allows any #GVariantType for keys. Key names
84 * are restricted to lowercase characters, numbers and '-'. Furthermore,
85 * the names must begin with a lowercase character, must not end
86 * with a '-', and must not contain consecutive dashes.
87 *
88 * Similar to GConf, the default values in GSettings schemas can be
89 * localized, but the localized values are stored in gettext catalogs
90 * and looked up with the domain that is specified in the
91 * `gettext-domain` attribute of the <schemalist> or <schema>
92 * elements and the category that is specified in the `l10n` attribute of
93 * the <default> element. The string which is translated includes all text in
94 * the <default> element, including any surrounding quotation marks.
95 *
96 * The `l10n` attribute must be set to `messages` or `time`, and sets the
97 * [locale category for
98 * translation](https://www.gnu.org/software/gettext/manual/html_node/Aspects.html#index-locale-categories-1).
99 * The `messages` category should be used by default; use `time` for
100 * translatable date or time formats. A translation comment can be added as an
101 * XML comment immediately above the <default> element — it is recommended to
102 * add these comments to aid translators understand the meaning and
103 * implications of the default value. An optional translation `context`
104 * attribute can be set on the <default> element to disambiguate multiple
105 * defaults which use the same string.
106 *
107 * For example:
108 * |[
109 * <!-- Translators: A list of words which are not allowed to be typed, in
110 * GVariant serialization syntax.
111 * See: https://developer.gnome.org/glib/stable/gvariant-text.html -->
112 * <default l10n='messages' context='Banned words'>['bad', 'words']</default>
113 * ]|
114 *
115 * Translations of default values must remain syntactically valid serialized
116 * #GVariants (e.g. retaining any surrounding quotation marks) or runtime
117 * errors will occur.
118 *
119 * GSettings uses schemas in a compact binary form that is created
120 * by the [glib-compile-schemas][glib-compile-schemas]
121 * utility. The input is a schema description in an XML format.
122 *
123 * A DTD for the gschema XML format can be found here:
124 * [gschema.dtd](https://gitlab.gnome.org/GNOME/glib/-/blob/HEAD/gio/gschema.dtd)
125 *
126 * The [glib-compile-schemas][glib-compile-schemas] tool expects schema
127 * files to have the extension `.gschema.xml`.
128 *
129 * At runtime, schemas are identified by their id (as specified in the
130 * id attribute of the <schema> element). The convention for schema
131 * ids is to use a dotted name, similar in style to a D-Bus bus name,
132 * e.g. "org.gnome.SessionManager". In particular, if the settings are
133 * for a specific service that owns a D-Bus bus name, the D-Bus bus name
134 * and schema id should match. For schemas which deal with settings not
135 * associated with one named application, the id should not use
136 * StudlyCaps, e.g. "org.gnome.font-rendering".
137 *
138 * In addition to #GVariant types, keys can have types that have
139 * enumerated types. These can be described by a <choice>,
140 * <enum> or <flags> element, as seen in the
141 * [example][schema-enumerated]. The underlying type of such a key
142 * is string, but you can use g_settings_get_enum(), g_settings_set_enum(),
143 * g_settings_get_flags(), g_settings_set_flags() access the numeric values
144 * corresponding to the string value of enum and flags keys.
145 *
146 * An example for default value:
147 * |[
148 * <schemalist>
149 * <schema id="org.gtk.Test" path="/org/gtk/Test/" gettext-domain="test">
150 *
151 * <key name="greeting" type="s">
152 * <default l10n="messages">"Hello, earthlings"</default>
153 * <summary>A greeting</summary>
154 * <description>
155 * Greeting of the invading martians
156 * </description>
157 * </key>
158 *
159 * <key name="box" type="(ii)">
160 * <default>(20,30)</default>
161 * </key>
162 *
163 * <key name="empty-string" type="s">
164 * <default>""</default>
165 * <summary>Empty strings have to be provided in GVariant form</summary>
166 * </key>
167 *
168 * </schema>
169 * </schemalist>
170 * ]|
171 *
172 * An example for ranges, choices and enumerated types:
173 * |[
174 * <schemalist>
175 *
176 * <enum id="org.gtk.Test.myenum">
177 * <value nick="first" value="1"/>
178 * <value nick="second" value="2"/>
179 * </enum>
180 *
181 * <flags id="org.gtk.Test.myflags">
182 * <value nick="flag1" value="1"/>
183 * <value nick="flag2" value="2"/>
184 * <value nick="flag3" value="4"/>
185 * </flags>
186 *
187 * <schema id="org.gtk.Test">
188 *
189 * <key name="key-with-range" type="i">
190 * <range min="1" max="100"/>
191 * <default>10</default>
192 * </key>
193 *
194 * <key name="key-with-choices" type="s">
195 * <choices>
196 * <choice value='Elisabeth'/>
197 * <choice value='Annabeth'/>
198 * <choice value='Joe'/>
199 * </choices>
200 * <aliases>
201 * <alias value='Anna' target='Annabeth'/>
202 * <alias value='Beth' target='Elisabeth'/>
203 * </aliases>
204 * <default>'Joe'</default>
205 * </key>
206 *
207 * <key name='enumerated-key' enum='org.gtk.Test.myenum'>
208 * <default>'first'</default>
209 * </key>
210 *
211 * <key name='flags-key' flags='org.gtk.Test.myflags'>
212 * <default>["flag1","flag2"]</default>
213 * </key>
214 * </schema>
215 * </schemalist>
216 * ]|
217 *
218 * ## Vendor overrides
219 *
220 * Default values are defined in the schemas that get installed by
221 * an application. Sometimes, it is necessary for a vendor or distributor
222 * to adjust these defaults. Since patching the XML source for the schema
223 * is inconvenient and error-prone,
224 * [glib-compile-schemas][glib-compile-schemas] reads so-called vendor
225 * override' files. These are keyfiles in the same directory as the XML
226 * schema sources which can override default values. The schema id serves
227 * as the group name in the key file, and the values are expected in
228 * serialized GVariant form, as in the following example:
229 * |[
230 * [org.gtk.Example]
231 * key1='string'
232 * key2=1.5
233 * ]|
234 *
235 * glib-compile-schemas expects schema files to have the extension
236 * `.gschema.override`.
237 *
238 * ## Binding
239 *
240 * A very convenient feature of GSettings lets you bind #GObject properties
241 * directly to settings, using g_settings_bind(). Once a GObject property
242 * has been bound to a setting, changes on either side are automatically
243 * propagated to the other side. GSettings handles details like mapping
244 * between GObject and GVariant types, and preventing infinite cycles.
245 *
246 * This makes it very easy to hook up a preferences dialog to the
247 * underlying settings. To make this even more convenient, GSettings
248 * looks for a boolean property with the name "sensitivity" and
249 * automatically binds it to the writability of the bound setting.
250 * If this 'magic' gets in the way, it can be suppressed with the
251 * #G_SETTINGS_BIND_NO_SENSITIVITY flag.
252 *
253 * ## Relocatable schemas # {#gsettings-relocatable}
254 *
255 * A relocatable schema is one with no `path` attribute specified on its
256 * <schema> element. By using g_settings_new_with_path(), a #GSettings object
257 * can be instantiated for a relocatable schema, assigning a path to the
258 * instance. Paths passed to g_settings_new_with_path() will typically be
259 * constructed dynamically from a constant prefix plus some form of instance
260 * identifier; but they must still be valid GSettings paths. Paths could also
261 * be constant and used with a globally installed schema originating from a
262 * dependency library.
263 *
264 * For example, a relocatable schema could be used to store geometry information
265 * for different windows in an application. If the schema ID was
266 * `org.foo.MyApp.Window`, it could be instantiated for paths
267 * `/org/foo/MyApp/main/`, `/org/foo/MyApp/document-1/`,
268 * `/org/foo/MyApp/document-2/`, etc. If any of the paths are well-known
269 * they can be specified as <child> elements in the parent schema, e.g.:
270 * |[
271 * <schema id="org.foo.MyApp" path="/org/foo/MyApp/">
272 * <child name="main" schema="org.foo.MyApp.Window"/>
273 * </schema>
274 * ]|
275 *
276 * ## Build system integration # {#gsettings-build-system}
277 *
278 * GSettings comes with autotools integration to simplify compiling and
279 * installing schemas. To add GSettings support to an application, add the
280 * following to your `configure.ac`:
281 * |[
282 * GLIB_GSETTINGS
283 * ]|
284 *
285 * In the appropriate `Makefile.am`, use the following snippet to compile and
286 * install the named schema:
287 * |[
288 * gsettings_SCHEMAS = org.foo.MyApp.gschema.xml
289 * EXTRA_DIST = $(gsettings_SCHEMAS)
290 *
291 * @GSETTINGS_RULES@
292 * ]|
293 *
294 * No changes are needed to the build system to mark a schema XML file for
295 * translation. Assuming it sets the `gettext-domain` attribute, a schema may
296 * be marked for translation by adding it to `POTFILES.in`, assuming gettext
297 * 0.19 is in use (the preferred method for translation):
298 * |[
299 * data/org.foo.MyApp.gschema.xml
300 * ]|
301 *
302 * Alternatively, if intltool 0.50.1 is in use:
303 * |[
304 * [type: gettext/gsettings]data/org.foo.MyApp.gschema.xml
305 * ]|
306 *
307 * GSettings will use gettext to look up translations for the <summary> and
308 * <description> elements, and also any <default> elements which have a `l10n`
309 * attribute set. Translations must not be included in the `.gschema.xml` file
310 * by the build system, for example by using intltool XML rules with a
311 * `.gschema.xml.in` template.
312 *
313 * If an enumerated type defined in a C header file is to be used in a GSettings
314 * schema, it can either be defined manually using an <enum> element in the
315 * schema XML, or it can be extracted automatically from the C header. This
316 * approach is preferred, as it ensures the two representations are always
317 * synchronised. To do so, add the following to the relevant `Makefile.am`:
318 * |[
319 * gsettings_ENUM_NAMESPACE = org.foo.MyApp
320 * gsettings_ENUM_FILES = my-app-enums.h my-app-misc.h
321 * ]|
322 *
323 * `gsettings_ENUM_NAMESPACE` specifies the schema namespace for the enum files,
324 * which are specified in `gsettings_ENUM_FILES`. This will generate a
325 * `org.foo.MyApp.enums.xml` file containing the extracted enums, which will be
326 * automatically included in the schema compilation, install and uninstall
327 * rules. It should not be committed to version control or included in
328 * `EXTRA_DIST`.
329 */
330
331 /**
332 * GSettings:
333 *
334 * #GSettings is an opaque data structure and can only be accessed
335 * using the following functions.
336 **/
337
338 struct _GSettingsPrivate
339 {
340 /* where the signals go... */
341 GMainContext *main_context;
342
343 GSettingsBackend *backend;
344 GSettingsSchema *schema;
345 gchar *path;
346 };
347
348 enum
349 {
350 PROP_0,
351 PROP_SCHEMA,
352 PROP_SCHEMA_ID,
353 PROP_BACKEND,
354 PROP_PATH,
355 PROP_HAS_UNAPPLIED,
356 PROP_DELAY_APPLY
357 };
358
359 enum
360 {
361 SIGNAL_WRITABLE_CHANGE_EVENT,
362 SIGNAL_WRITABLE_CHANGED,
363 SIGNAL_CHANGE_EVENT,
364 SIGNAL_CHANGED,
365 N_SIGNALS
366 };
367
368 static guint g_settings_signals[N_SIGNALS];
369
G_DEFINE_TYPE_WITH_PRIVATE(GSettings,g_settings,G_TYPE_OBJECT)370 G_DEFINE_TYPE_WITH_PRIVATE (GSettings, g_settings, G_TYPE_OBJECT)
371
372 /* Signals {{{1 */
373 static gboolean
374 g_settings_real_change_event (GSettings *settings,
375 const GQuark *keys,
376 gint n_keys)
377 {
378 gint i;
379
380 if (keys == NULL)
381 keys = g_settings_schema_list (settings->priv->schema, &n_keys);
382
383 for (i = 0; i < n_keys; i++)
384 {
385 const gchar *key = g_quark_to_string (keys[i]);
386
387 if (g_str_has_suffix (key, "/"))
388 continue;
389
390 g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGED], keys[i], key);
391 }
392
393 return FALSE;
394 }
395
396 static gboolean
g_settings_real_writable_change_event(GSettings * settings,GQuark key)397 g_settings_real_writable_change_event (GSettings *settings,
398 GQuark key)
399 {
400 const GQuark *keys = &key;
401 gint n_keys = 1;
402 gint i;
403
404 if (key == 0)
405 keys = g_settings_schema_list (settings->priv->schema, &n_keys);
406
407 for (i = 0; i < n_keys; i++)
408 {
409 const gchar *key = g_quark_to_string (keys[i]);
410
411 if (g_str_has_suffix (key, "/"))
412 continue;
413
414 g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGED], keys[i], key);
415 }
416
417 return FALSE;
418 }
419
420 static void
settings_backend_changed(GObject * target,GSettingsBackend * backend,const gchar * key,gpointer origin_tag)421 settings_backend_changed (GObject *target,
422 GSettingsBackend *backend,
423 const gchar *key,
424 gpointer origin_tag)
425 {
426 GSettings *settings = G_SETTINGS (target);
427 gboolean ignore_this;
428 gint i;
429
430 /* We used to assert here:
431 *
432 * settings->priv->backend == backend
433 *
434 * but it could be the case that a notification is queued for delivery
435 * while someone calls g_settings_delay() (which changes the backend).
436 *
437 * Since the delay backend would just pass that straight through
438 * anyway, it doesn't make sense to try to detect this case.
439 * Therefore, we just accept it.
440 */
441
442 for (i = 0; key[i] == settings->priv->path[i]; i++);
443
444 if (settings->priv->path[i] == '\0' &&
445 g_settings_schema_has_key (settings->priv->schema, key + i))
446 {
447 GQuark quark;
448
449 quark = g_quark_from_string (key + i);
450 g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT],
451 0, &quark, 1, &ignore_this);
452 }
453 }
454
455 static void
settings_backend_path_changed(GObject * target,GSettingsBackend * backend,const gchar * path,gpointer origin_tag)456 settings_backend_path_changed (GObject *target,
457 GSettingsBackend *backend,
458 const gchar *path,
459 gpointer origin_tag)
460 {
461 GSettings *settings = G_SETTINGS (target);
462 gboolean ignore_this;
463
464 if (g_str_has_prefix (settings->priv->path, path))
465 g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT],
466 0, NULL, 0, &ignore_this);
467 }
468
469 static void
settings_backend_keys_changed(GObject * target,GSettingsBackend * backend,const gchar * path,gpointer origin_tag,const gchar * const * items)470 settings_backend_keys_changed (GObject *target,
471 GSettingsBackend *backend,
472 const gchar *path,
473 gpointer origin_tag,
474 const gchar * const *items)
475 {
476 GSettings *settings = G_SETTINGS (target);
477 gboolean ignore_this;
478 gint i;
479
480 for (i = 0; settings->priv->path[i] &&
481 settings->priv->path[i] == path[i]; i++);
482
483 if (path[i] == '\0')
484 {
485 GQuark quarks[256];
486 gint j, l = 0;
487
488 for (j = 0; items[j]; j++)
489 {
490 const gchar *item = items[j];
491 gint k;
492
493 for (k = 0; item[k] == settings->priv->path[i + k]; k++);
494
495 if (settings->priv->path[i + k] == '\0' &&
496 g_settings_schema_has_key (settings->priv->schema, item + k))
497 quarks[l++] = g_quark_from_string (item + k);
498
499 /* "256 quarks ought to be enough for anybody!"
500 * If this bites you, I'm sorry. Please file a bug.
501 */
502 g_assert (l < 256);
503 }
504
505 if (l > 0)
506 g_signal_emit (settings, g_settings_signals[SIGNAL_CHANGE_EVENT],
507 0, quarks, l, &ignore_this);
508 }
509 }
510
511 static void
settings_backend_writable_changed(GObject * target,GSettingsBackend * backend,const gchar * key)512 settings_backend_writable_changed (GObject *target,
513 GSettingsBackend *backend,
514 const gchar *key)
515 {
516 GSettings *settings = G_SETTINGS (target);
517 gboolean ignore_this;
518 gint i;
519
520 for (i = 0; key[i] == settings->priv->path[i]; i++);
521
522 if (settings->priv->path[i] == '\0' &&
523 g_settings_schema_has_key (settings->priv->schema, key + i))
524 g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT],
525 0, g_quark_from_string (key + i), &ignore_this);
526 }
527
528 static void
settings_backend_path_writable_changed(GObject * target,GSettingsBackend * backend,const gchar * path)529 settings_backend_path_writable_changed (GObject *target,
530 GSettingsBackend *backend,
531 const gchar *path)
532 {
533 GSettings *settings = G_SETTINGS (target);
534 gboolean ignore_this;
535
536 if (g_str_has_prefix (settings->priv->path, path))
537 g_signal_emit (settings, g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT],
538 0, (GQuark) 0, &ignore_this);
539 }
540
541 /* Properties, Construction, Destruction {{{1 */
542 static void
g_settings_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)543 g_settings_set_property (GObject *object,
544 guint prop_id,
545 const GValue *value,
546 GParamSpec *pspec)
547 {
548 GSettings *settings = G_SETTINGS (object);
549
550 switch (prop_id)
551 {
552 case PROP_SCHEMA:
553 {
554 GSettingsSchema *schema;
555
556 schema = g_value_dup_boxed (value);
557
558 /* we receive a set_property() call for "settings-schema" even
559 * if it was not specified (ie: with NULL value). ->schema
560 * could already be set at this point (ie: via "schema-id").
561 * check for NULL to avoid clobbering the existing value.
562 */
563 if (schema != NULL)
564 {
565 g_assert (settings->priv->schema == NULL);
566 settings->priv->schema = schema;
567 }
568 }
569 break;
570
571 case PROP_SCHEMA_ID:
572 {
573 const gchar *schema_id;
574
575 schema_id = g_value_get_string (value);
576
577 /* we receive a set_property() call for both "schema" and
578 * "schema-id", even if they are not set. Hopefully only one of
579 * them is non-NULL.
580 */
581 if (schema_id != NULL)
582 {
583 GSettingsSchemaSource *default_source;
584
585 g_assert (settings->priv->schema == NULL);
586 default_source = g_settings_schema_source_get_default ();
587
588 if (default_source == NULL)
589 g_error ("No GSettings schemas are installed on the system");
590
591 settings->priv->schema = g_settings_schema_source_lookup (default_source, schema_id, TRUE);
592
593 if (settings->priv->schema == NULL)
594 g_error ("Settings schema '%s' is not installed", schema_id);
595 }
596 }
597 break;
598
599 case PROP_PATH:
600 settings->priv->path = g_value_dup_string (value);
601 break;
602
603 case PROP_BACKEND:
604 settings->priv->backend = g_value_dup_object (value);
605 break;
606
607 default:
608 g_assert_not_reached ();
609 }
610 }
611
612 static void
g_settings_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)613 g_settings_get_property (GObject *object,
614 guint prop_id,
615 GValue *value,
616 GParamSpec *pspec)
617 {
618 GSettings *settings = G_SETTINGS (object);
619
620 switch (prop_id)
621 {
622 case PROP_SCHEMA:
623 g_value_set_boxed (value, settings->priv->schema);
624 break;
625
626 case PROP_SCHEMA_ID:
627 g_value_set_string (value, g_settings_schema_get_id (settings->priv->schema));
628 break;
629
630 case PROP_BACKEND:
631 g_value_set_object (value, settings->priv->backend);
632 break;
633
634 case PROP_PATH:
635 g_value_set_string (value, settings->priv->path);
636 break;
637
638 case PROP_HAS_UNAPPLIED:
639 g_value_set_boolean (value, g_settings_get_has_unapplied (settings));
640 break;
641
642 case PROP_DELAY_APPLY:
643 g_value_set_boolean (value, G_IS_DELAYED_SETTINGS_BACKEND (settings->priv->backend));
644 break;
645
646 default:
647 g_assert_not_reached ();
648 }
649 }
650
651 static const GSettingsListenerVTable listener_vtable = {
652 settings_backend_changed,
653 settings_backend_path_changed,
654 settings_backend_keys_changed,
655 settings_backend_writable_changed,
656 settings_backend_path_writable_changed
657 };
658
659 static void
g_settings_constructed(GObject * object)660 g_settings_constructed (GObject *object)
661 {
662 GSettings *settings = G_SETTINGS (object);
663 const gchar *schema_path;
664
665 schema_path = g_settings_schema_get_path (settings->priv->schema);
666
667 if (settings->priv->path && schema_path && strcmp (settings->priv->path, schema_path) != 0)
668 g_error ("settings object created with schema '%s' and path '%s', but path '%s' is specified by schema",
669 g_settings_schema_get_id (settings->priv->schema), settings->priv->path, schema_path);
670
671 if (settings->priv->path == NULL)
672 {
673 if (schema_path == NULL)
674 g_error ("attempting to create schema '%s' without a path",
675 g_settings_schema_get_id (settings->priv->schema));
676
677 settings->priv->path = g_strdup (schema_path);
678 }
679
680 if (settings->priv->backend == NULL)
681 settings->priv->backend = g_settings_backend_get_default ();
682
683 g_settings_backend_watch (settings->priv->backend,
684 &listener_vtable, G_OBJECT (settings),
685 settings->priv->main_context);
686 g_settings_backend_subscribe (settings->priv->backend,
687 settings->priv->path);
688 }
689
690 static void
g_settings_finalize(GObject * object)691 g_settings_finalize (GObject *object)
692 {
693 GSettings *settings = G_SETTINGS (object);
694
695 g_settings_backend_unsubscribe (settings->priv->backend,
696 settings->priv->path);
697 g_main_context_unref (settings->priv->main_context);
698 g_object_unref (settings->priv->backend);
699 g_settings_schema_unref (settings->priv->schema);
700 g_free (settings->priv->path);
701
702 G_OBJECT_CLASS (g_settings_parent_class)->finalize (object);
703 }
704
705 static void
g_settings_init(GSettings * settings)706 g_settings_init (GSettings *settings)
707 {
708 settings->priv = g_settings_get_instance_private (settings);
709 settings->priv->main_context = g_main_context_ref_thread_default ();
710 }
711
712 static void
g_settings_class_init(GSettingsClass * class)713 g_settings_class_init (GSettingsClass *class)
714 {
715 GObjectClass *object_class = G_OBJECT_CLASS (class);
716
717 class->writable_change_event = g_settings_real_writable_change_event;
718 class->change_event = g_settings_real_change_event;
719
720 object_class->set_property = g_settings_set_property;
721 object_class->get_property = g_settings_get_property;
722 object_class->constructed = g_settings_constructed;
723 object_class->finalize = g_settings_finalize;
724
725 /**
726 * GSettings::changed:
727 * @settings: the object on which the signal was emitted
728 * @key: the name of the key that changed
729 *
730 * The "changed" signal is emitted when a key has potentially changed.
731 * You should call one of the g_settings_get() calls to check the new
732 * value.
733 *
734 * This signal supports detailed connections. You can connect to the
735 * detailed signal "changed::x" in order to only receive callbacks
736 * when key "x" changes.
737 *
738 * Note that @settings only emits this signal if you have read @key at
739 * least once while a signal handler was already connected for @key.
740 */
741 g_settings_signals[SIGNAL_CHANGED] =
742 g_signal_new (I_("changed"), G_TYPE_SETTINGS,
743 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
744 G_STRUCT_OFFSET (GSettingsClass, changed),
745 NULL, NULL, NULL, G_TYPE_NONE,
746 1, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
747
748 /**
749 * GSettings::change-event:
750 * @settings: the object on which the signal was emitted
751 * @keys: (array length=n_keys) (element-type GQuark) (nullable):
752 * an array of #GQuarks for the changed keys, or %NULL
753 * @n_keys: the length of the @keys array, or 0
754 *
755 * The "change-event" signal is emitted once per change event that
756 * affects this settings object. You should connect to this signal
757 * only if you are interested in viewing groups of changes before they
758 * are split out into multiple emissions of the "changed" signal.
759 * For most use cases it is more appropriate to use the "changed" signal.
760 *
761 * In the event that the change event applies to one or more specified
762 * keys, @keys will be an array of #GQuark of length @n_keys. In the
763 * event that the change event applies to the #GSettings object as a
764 * whole (ie: potentially every key has been changed) then @keys will
765 * be %NULL and @n_keys will be 0.
766 *
767 * The default handler for this signal invokes the "changed" signal
768 * for each affected key. If any other connected handler returns
769 * %TRUE then this default functionality will be suppressed.
770 *
771 * Returns: %TRUE to stop other handlers from being invoked for the
772 * event. FALSE to propagate the event further.
773 */
774 g_settings_signals[SIGNAL_CHANGE_EVENT] =
775 g_signal_new (I_("change-event"), G_TYPE_SETTINGS,
776 G_SIGNAL_RUN_LAST,
777 G_STRUCT_OFFSET (GSettingsClass, change_event),
778 g_signal_accumulator_true_handled, NULL,
779 _g_cclosure_marshal_BOOLEAN__POINTER_INT,
780 G_TYPE_BOOLEAN, 2, G_TYPE_POINTER, G_TYPE_INT);
781 g_signal_set_va_marshaller (g_settings_signals[SIGNAL_CHANGE_EVENT],
782 G_TYPE_FROM_CLASS (class),
783 _g_cclosure_marshal_BOOLEAN__POINTER_INTv);
784
785 /**
786 * GSettings::writable-changed:
787 * @settings: the object on which the signal was emitted
788 * @key: the key
789 *
790 * The "writable-changed" signal is emitted when the writability of a
791 * key has potentially changed. You should call
792 * g_settings_is_writable() in order to determine the new status.
793 *
794 * This signal supports detailed connections. You can connect to the
795 * detailed signal "writable-changed::x" in order to only receive
796 * callbacks when the writability of "x" changes.
797 */
798 g_settings_signals[SIGNAL_WRITABLE_CHANGED] =
799 g_signal_new (I_("writable-changed"), G_TYPE_SETTINGS,
800 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
801 G_STRUCT_OFFSET (GSettingsClass, writable_changed),
802 NULL, NULL, NULL, G_TYPE_NONE,
803 1, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
804
805 /**
806 * GSettings::writable-change-event:
807 * @settings: the object on which the signal was emitted
808 * @key: the quark of the key, or 0
809 *
810 * The "writable-change-event" signal is emitted once per writability
811 * change event that affects this settings object. You should connect
812 * to this signal if you are interested in viewing groups of changes
813 * before they are split out into multiple emissions of the
814 * "writable-changed" signal. For most use cases it is more
815 * appropriate to use the "writable-changed" signal.
816 *
817 * In the event that the writability change applies only to a single
818 * key, @key will be set to the #GQuark for that key. In the event
819 * that the writability change affects the entire settings object,
820 * @key will be 0.
821 *
822 * The default handler for this signal invokes the "writable-changed"
823 * and "changed" signals for each affected key. This is done because
824 * changes in writability might also imply changes in value (if for
825 * example, a new mandatory setting is introduced). If any other
826 * connected handler returns %TRUE then this default functionality
827 * will be suppressed.
828 *
829 * Returns: %TRUE to stop other handlers from being invoked for the
830 * event. FALSE to propagate the event further.
831 */
832 g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT] =
833 g_signal_new (I_("writable-change-event"), G_TYPE_SETTINGS,
834 G_SIGNAL_RUN_LAST,
835 G_STRUCT_OFFSET (GSettingsClass, writable_change_event),
836 g_signal_accumulator_true_handled, NULL,
837 _g_cclosure_marshal_BOOLEAN__UINT,
838 G_TYPE_BOOLEAN, 1, G_TYPE_UINT);
839 g_signal_set_va_marshaller (g_settings_signals[SIGNAL_WRITABLE_CHANGE_EVENT],
840 G_TYPE_FROM_CLASS (class),
841 _g_cclosure_marshal_BOOLEAN__UINTv);
842
843 /**
844 * GSettings:backend:
845 *
846 * The name of the context that the settings are stored in.
847 */
848 g_object_class_install_property (object_class, PROP_BACKEND,
849 g_param_spec_object ("backend",
850 P_("GSettingsBackend"),
851 P_("The GSettingsBackend for this settings object"),
852 G_TYPE_SETTINGS_BACKEND, G_PARAM_CONSTRUCT_ONLY |
853 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
854
855 /**
856 * GSettings:settings-schema:
857 *
858 * The #GSettingsSchema describing the types of keys for this
859 * #GSettings object.
860 *
861 * Ideally, this property would be called 'schema'. #GSettingsSchema
862 * has only existed since version 2.32, however, and before then the
863 * 'schema' property was used to refer to the ID of the schema rather
864 * than the schema itself. Take care.
865 */
866 g_object_class_install_property (object_class, PROP_SCHEMA,
867 g_param_spec_boxed ("settings-schema",
868 P_("schema"),
869 P_("The GSettingsSchema for this settings object"),
870 G_TYPE_SETTINGS_SCHEMA,
871 G_PARAM_CONSTRUCT_ONLY |
872 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
873
874 /**
875 * GSettings:schema:
876 *
877 * The name of the schema that describes the types of keys
878 * for this #GSettings object.
879 *
880 * The type of this property is *not* #GSettingsSchema.
881 * #GSettingsSchema has only existed since version 2.32 and
882 * unfortunately this name was used in previous versions to refer to
883 * the schema ID rather than the schema itself. Take care to use the
884 * 'settings-schema' property if you wish to pass in a
885 * #GSettingsSchema.
886 *
887 * Deprecated:2.32:Use the 'schema-id' property instead. In a future
888 * version, this property may instead refer to a #GSettingsSchema.
889 */
890 g_object_class_install_property (object_class, PROP_SCHEMA_ID,
891 g_param_spec_string ("schema",
892 P_("Schema name"),
893 P_("The name of the schema for this settings object"),
894 NULL,
895 G_PARAM_CONSTRUCT_ONLY |
896 G_PARAM_DEPRECATED | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
897
898 /**
899 * GSettings:schema-id:
900 *
901 * The name of the schema that describes the types of keys
902 * for this #GSettings object.
903 */
904 g_object_class_install_property (object_class, PROP_SCHEMA_ID,
905 g_param_spec_string ("schema-id",
906 P_("Schema name"),
907 P_("The name of the schema for this settings object"),
908 NULL,
909 G_PARAM_CONSTRUCT_ONLY |
910 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
911
912 /**
913 * GSettings:path:
914 *
915 * The path within the backend where the settings are stored.
916 */
917 g_object_class_install_property (object_class, PROP_PATH,
918 g_param_spec_string ("path",
919 P_("Base path"),
920 P_("The path within the backend where the settings are"),
921 NULL,
922 G_PARAM_CONSTRUCT_ONLY |
923 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
924
925 /**
926 * GSettings:has-unapplied:
927 *
928 * If this property is %TRUE, the #GSettings object has outstanding
929 * changes that will be applied when g_settings_apply() is called.
930 */
931 g_object_class_install_property (object_class, PROP_HAS_UNAPPLIED,
932 g_param_spec_boolean ("has-unapplied",
933 P_("Has unapplied changes"),
934 P_("TRUE if there are outstanding changes to apply()"),
935 FALSE,
936 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
937
938 /**
939 * GSettings:delay-apply:
940 *
941 * Whether the #GSettings object is in 'delay-apply' mode. See
942 * g_settings_delay() for details.
943 *
944 * Since: 2.28
945 */
946 g_object_class_install_property (object_class, PROP_DELAY_APPLY,
947 g_param_spec_boolean ("delay-apply",
948 P_("Delay-apply mode"),
949 P_("Whether this settings object is in “delay-apply” mode"),
950 FALSE,
951 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
952 }
953
954 /* Construction (new, new_with_path, etc.) {{{1 */
955 /**
956 * g_settings_new:
957 * @schema_id: the id of the schema
958 *
959 * Creates a new #GSettings object with the schema specified by
960 * @schema_id.
961 *
962 * It is an error for the schema to not exist: schemas are an
963 * essential part of a program, as they provide type information.
964 * If schemas need to be dynamically loaded (for example, from an
965 * optional runtime dependency), g_settings_schema_source_lookup()
966 * can be used to test for their existence before loading them.
967 *
968 * Signals on the newly created #GSettings object will be dispatched
969 * via the thread-default #GMainContext in effect at the time of the
970 * call to g_settings_new(). The new #GSettings will hold a reference
971 * on the context. See g_main_context_push_thread_default().
972 *
973 * Returns: a new #GSettings object
974 *
975 * Since: 2.26
976 */
977 GSettings *
g_settings_new(const gchar * schema_id)978 g_settings_new (const gchar *schema_id)
979 {
980 g_return_val_if_fail (schema_id != NULL, NULL);
981
982 return g_object_new (G_TYPE_SETTINGS,
983 "schema-id", schema_id,
984 NULL);
985 }
986
987 static gboolean
path_is_valid(const gchar * path)988 path_is_valid (const gchar *path)
989 {
990 if (!path)
991 return FALSE;
992
993 if (path[0] != '/')
994 return FALSE;
995
996 if (!g_str_has_suffix (path, "/"))
997 return FALSE;
998
999 return strstr (path, "//") == NULL;
1000 }
1001
1002 /**
1003 * g_settings_new_with_path:
1004 * @schema_id: the id of the schema
1005 * @path: the path to use
1006 *
1007 * Creates a new #GSettings object with the relocatable schema specified
1008 * by @schema_id and a given path.
1009 *
1010 * You only need to do this if you want to directly create a settings
1011 * object with a schema that doesn't have a specified path of its own.
1012 * That's quite rare.
1013 *
1014 * It is a programmer error to call this function for a schema that
1015 * has an explicitly specified path.
1016 *
1017 * It is a programmer error if @path is not a valid path. A valid path
1018 * begins and ends with '/' and does not contain two consecutive '/'
1019 * characters.
1020 *
1021 * Returns: a new #GSettings object
1022 *
1023 * Since: 2.26
1024 */
1025 GSettings *
g_settings_new_with_path(const gchar * schema_id,const gchar * path)1026 g_settings_new_with_path (const gchar *schema_id,
1027 const gchar *path)
1028 {
1029 g_return_val_if_fail (schema_id != NULL, NULL);
1030 g_return_val_if_fail (path_is_valid (path), NULL);
1031
1032 return g_object_new (G_TYPE_SETTINGS,
1033 "schema-id", schema_id,
1034 "path", path,
1035 NULL);
1036 }
1037
1038 /**
1039 * g_settings_new_with_backend:
1040 * @schema_id: the id of the schema
1041 * @backend: the #GSettingsBackend to use
1042 *
1043 * Creates a new #GSettings object with the schema specified by
1044 * @schema_id and a given #GSettingsBackend.
1045 *
1046 * Creating a #GSettings object with a different backend allows accessing
1047 * settings from a database other than the usual one. For example, it may make
1048 * sense to pass a backend corresponding to the "defaults" settings database on
1049 * the system to get a settings object that modifies the system default
1050 * settings instead of the settings for this user.
1051 *
1052 * Returns: a new #GSettings object
1053 *
1054 * Since: 2.26
1055 */
1056 GSettings *
g_settings_new_with_backend(const gchar * schema_id,GSettingsBackend * backend)1057 g_settings_new_with_backend (const gchar *schema_id,
1058 GSettingsBackend *backend)
1059 {
1060 g_return_val_if_fail (schema_id != NULL, NULL);
1061 g_return_val_if_fail (G_IS_SETTINGS_BACKEND (backend), NULL);
1062
1063 return g_object_new (G_TYPE_SETTINGS,
1064 "schema-id", schema_id,
1065 "backend", backend,
1066 NULL);
1067 }
1068
1069 /**
1070 * g_settings_new_with_backend_and_path:
1071 * @schema_id: the id of the schema
1072 * @backend: the #GSettingsBackend to use
1073 * @path: the path to use
1074 *
1075 * Creates a new #GSettings object with the schema specified by
1076 * @schema_id and a given #GSettingsBackend and path.
1077 *
1078 * This is a mix of g_settings_new_with_backend() and
1079 * g_settings_new_with_path().
1080 *
1081 * Returns: a new #GSettings object
1082 *
1083 * Since: 2.26
1084 */
1085 GSettings *
g_settings_new_with_backend_and_path(const gchar * schema_id,GSettingsBackend * backend,const gchar * path)1086 g_settings_new_with_backend_and_path (const gchar *schema_id,
1087 GSettingsBackend *backend,
1088 const gchar *path)
1089 {
1090 g_return_val_if_fail (schema_id != NULL, NULL);
1091 g_return_val_if_fail (G_IS_SETTINGS_BACKEND (backend), NULL);
1092 g_return_val_if_fail (path_is_valid (path), NULL);
1093
1094 return g_object_new (G_TYPE_SETTINGS,
1095 "schema-id", schema_id,
1096 "backend", backend,
1097 "path", path,
1098 NULL);
1099 }
1100
1101 /**
1102 * g_settings_new_full:
1103 * @schema: a #GSettingsSchema
1104 * @backend: (nullable): a #GSettingsBackend
1105 * @path: (nullable): the path to use
1106 *
1107 * Creates a new #GSettings object with a given schema, backend and
1108 * path.
1109 *
1110 * It should be extremely rare that you ever want to use this function.
1111 * It is made available for advanced use-cases (such as plugin systems
1112 * that want to provide access to schemas loaded from custom locations,
1113 * etc).
1114 *
1115 * At the most basic level, a #GSettings object is a pure composition of
1116 * 4 things: a #GSettingsSchema, a #GSettingsBackend, a path within that
1117 * backend, and a #GMainContext to which signals are dispatched.
1118 *
1119 * This constructor therefore gives you full control over constructing
1120 * #GSettings instances. The first 3 parameters are given directly as
1121 * @schema, @backend and @path, and the main context is taken from the
1122 * thread-default (as per g_settings_new()).
1123 *
1124 * If @backend is %NULL then the default backend is used.
1125 *
1126 * If @path is %NULL then the path from the schema is used. It is an
1127 * error if @path is %NULL and the schema has no path of its own or if
1128 * @path is non-%NULL and not equal to the path that the schema does
1129 * have.
1130 *
1131 * Returns: a new #GSettings object
1132 *
1133 * Since: 2.32
1134 */
1135 GSettings *
g_settings_new_full(GSettingsSchema * schema,GSettingsBackend * backend,const gchar * path)1136 g_settings_new_full (GSettingsSchema *schema,
1137 GSettingsBackend *backend,
1138 const gchar *path)
1139 {
1140 g_return_val_if_fail (schema != NULL, NULL);
1141 g_return_val_if_fail (backend == NULL || G_IS_SETTINGS_BACKEND (backend), NULL);
1142 g_return_val_if_fail (path == NULL || path_is_valid (path), NULL);
1143
1144 return g_object_new (G_TYPE_SETTINGS,
1145 "settings-schema", schema,
1146 "backend", backend,
1147 "path", path,
1148 NULL);
1149 }
1150
1151 /* Internal read/write utilities {{{1 */
1152
1153 /* @value will be sunk */
1154 static gboolean
g_settings_write_to_backend(GSettings * settings,GSettingsSchemaKey * key,GVariant * value)1155 g_settings_write_to_backend (GSettings *settings,
1156 GSettingsSchemaKey *key,
1157 GVariant *value)
1158 {
1159 gboolean success;
1160 gchar *path;
1161
1162 path = g_strconcat (settings->priv->path, key->name, NULL);
1163 success = g_settings_backend_write (settings->priv->backend, path, value, NULL);
1164 g_free (path);
1165
1166 return success;
1167 }
1168
1169 static GVariant *
g_settings_read_from_backend(GSettings * settings,GSettingsSchemaKey * key,gboolean user_value_only,gboolean default_value)1170 g_settings_read_from_backend (GSettings *settings,
1171 GSettingsSchemaKey *key,
1172 gboolean user_value_only,
1173 gboolean default_value)
1174 {
1175 GVariant *value;
1176 GVariant *fixup;
1177 gchar *path;
1178
1179 path = g_strconcat (settings->priv->path, key->name, NULL);
1180 if (user_value_only)
1181 value = g_settings_backend_read_user_value (settings->priv->backend, path, key->type);
1182 else
1183 value = g_settings_backend_read (settings->priv->backend, path, key->type, default_value);
1184 g_free (path);
1185
1186 if (value != NULL)
1187 {
1188 fixup = g_settings_schema_key_range_fixup (key, value);
1189 g_variant_unref (value);
1190 }
1191 else
1192 fixup = NULL;
1193
1194 return fixup;
1195 }
1196
1197 /* Public Get/Set API {{{1 (get, get_value, set, set_value, get_mapped) */
1198 /**
1199 * g_settings_get_value:
1200 * @settings: a #GSettings object
1201 * @key: the key to get the value for
1202 *
1203 * Gets the value that is stored in @settings for @key.
1204 *
1205 * It is a programmer error to give a @key that isn't contained in the
1206 * schema for @settings.
1207 *
1208 * Returns: a new #GVariant
1209 *
1210 * Since: 2.26
1211 */
1212 GVariant *
g_settings_get_value(GSettings * settings,const gchar * key)1213 g_settings_get_value (GSettings *settings,
1214 const gchar *key)
1215 {
1216 GSettingsSchemaKey skey;
1217 GVariant *value;
1218
1219 g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
1220 g_return_val_if_fail (key != NULL, NULL);
1221
1222 g_settings_schema_key_init (&skey, settings->priv->schema, key);
1223 value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE);
1224
1225 if (value == NULL)
1226 value = g_settings_schema_key_get_default_value (&skey);
1227
1228 g_settings_schema_key_clear (&skey);
1229
1230 return value;
1231 }
1232
1233 /**
1234 * g_settings_get_user_value:
1235 * @settings: a #GSettings object
1236 * @key: the key to get the user value for
1237 *
1238 * Checks the "user value" of a key, if there is one.
1239 *
1240 * The user value of a key is the last value that was set by the user.
1241 *
1242 * After calling g_settings_reset() this function should always return
1243 * %NULL (assuming something is not wrong with the system
1244 * configuration).
1245 *
1246 * It is possible that g_settings_get_value() will return a different
1247 * value than this function. This can happen in the case that the user
1248 * set a value for a key that was subsequently locked down by the system
1249 * administrator -- this function will return the user's old value.
1250 *
1251 * This function may be useful for adding a "reset" option to a UI or
1252 * for providing indication that a particular value has been changed.
1253 *
1254 * It is a programmer error to give a @key that isn't contained in the
1255 * schema for @settings.
1256 *
1257 * Returns: (nullable) (transfer full): the user's value, if set
1258 *
1259 * Since: 2.40
1260 **/
1261 GVariant *
g_settings_get_user_value(GSettings * settings,const gchar * key)1262 g_settings_get_user_value (GSettings *settings,
1263 const gchar *key)
1264 {
1265 GSettingsSchemaKey skey;
1266 GVariant *value;
1267
1268 g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
1269 g_return_val_if_fail (key != NULL, NULL);
1270
1271 g_settings_schema_key_init (&skey, settings->priv->schema, key);
1272 value = g_settings_read_from_backend (settings, &skey, TRUE, FALSE);
1273 g_settings_schema_key_clear (&skey);
1274
1275 return value;
1276 }
1277
1278 /**
1279 * g_settings_get_default_value:
1280 * @settings: a #GSettings object
1281 * @key: the key to get the default value for
1282 *
1283 * Gets the "default value" of a key.
1284 *
1285 * This is the value that would be read if g_settings_reset() were to be
1286 * called on the key.
1287 *
1288 * Note that this may be a different value than returned by
1289 * g_settings_schema_key_get_default_value() if the system administrator
1290 * has provided a default value.
1291 *
1292 * Comparing the return values of g_settings_get_default_value() and
1293 * g_settings_get_value() is not sufficient for determining if a value
1294 * has been set because the user may have explicitly set the value to
1295 * something that happens to be equal to the default. The difference
1296 * here is that if the default changes in the future, the user's key
1297 * will still be set.
1298 *
1299 * This function may be useful for adding an indication to a UI of what
1300 * the default value was before the user set it.
1301 *
1302 * It is a programmer error to give a @key that isn't contained in the
1303 * schema for @settings.
1304 *
1305 * Returns: (nullable) (transfer full): the default value
1306 *
1307 * Since: 2.40
1308 **/
1309 GVariant *
g_settings_get_default_value(GSettings * settings,const gchar * key)1310 g_settings_get_default_value (GSettings *settings,
1311 const gchar *key)
1312 {
1313 GSettingsSchemaKey skey;
1314 GVariant *value;
1315
1316 g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
1317 g_return_val_if_fail (key != NULL, NULL);
1318
1319 g_settings_schema_key_init (&skey, settings->priv->schema, key);
1320 value = g_settings_read_from_backend (settings, &skey, FALSE, TRUE);
1321
1322 if (value == NULL)
1323 value = g_settings_schema_key_get_default_value (&skey);
1324
1325 g_settings_schema_key_clear (&skey);
1326
1327 return value;
1328 }
1329
1330 /**
1331 * g_settings_get_enum:
1332 * @settings: a #GSettings object
1333 * @key: the key to get the value for
1334 *
1335 * Gets the value that is stored in @settings for @key and converts it
1336 * to the enum value that it represents.
1337 *
1338 * In order to use this function the type of the value must be a string
1339 * and it must be marked in the schema file as an enumerated type.
1340 *
1341 * It is a programmer error to give a @key that isn't contained in the
1342 * schema for @settings or is not marked as an enumerated type.
1343 *
1344 * If the value stored in the configuration database is not a valid
1345 * value for the enumerated type then this function will return the
1346 * default value.
1347 *
1348 * Returns: the enum value
1349 *
1350 * Since: 2.26
1351 **/
1352 gint
g_settings_get_enum(GSettings * settings,const gchar * key)1353 g_settings_get_enum (GSettings *settings,
1354 const gchar *key)
1355 {
1356 GSettingsSchemaKey skey;
1357 GVariant *value;
1358 gint result;
1359
1360 g_return_val_if_fail (G_IS_SETTINGS (settings), -1);
1361 g_return_val_if_fail (key != NULL, -1);
1362
1363 g_settings_schema_key_init (&skey, settings->priv->schema, key);
1364
1365 if (!skey.is_enum)
1366 {
1367 g_critical ("g_settings_get_enum() called on key '%s' which is not "
1368 "associated with an enumerated type", skey.name);
1369 g_settings_schema_key_clear (&skey);
1370 return -1;
1371 }
1372
1373 value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE);
1374
1375 if (value == NULL)
1376 value = g_settings_schema_key_get_default_value (&skey);
1377
1378 result = g_settings_schema_key_to_enum (&skey, value);
1379 g_settings_schema_key_clear (&skey);
1380 g_variant_unref (value);
1381
1382 return result;
1383 }
1384
1385 /**
1386 * g_settings_set_enum:
1387 * @settings: a #GSettings object
1388 * @key: a key, within @settings
1389 * @value: an enumerated value
1390 *
1391 * Looks up the enumerated type nick for @value and writes it to @key,
1392 * within @settings.
1393 *
1394 * It is a programmer error to give a @key that isn't contained in the
1395 * schema for @settings or is not marked as an enumerated type, or for
1396 * @value not to be a valid value for the named type.
1397 *
1398 * After performing the write, accessing @key directly with
1399 * g_settings_get_string() will return the 'nick' associated with
1400 * @value.
1401 *
1402 * Returns: %TRUE, if the set succeeds
1403 **/
1404 gboolean
g_settings_set_enum(GSettings * settings,const gchar * key,gint value)1405 g_settings_set_enum (GSettings *settings,
1406 const gchar *key,
1407 gint value)
1408 {
1409 GSettingsSchemaKey skey;
1410 GVariant *variant;
1411 gboolean success;
1412
1413 g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
1414 g_return_val_if_fail (key != NULL, FALSE);
1415
1416 g_settings_schema_key_init (&skey, settings->priv->schema, key);
1417
1418 if (!skey.is_enum)
1419 {
1420 g_critical ("g_settings_set_enum() called on key '%s' which is not "
1421 "associated with an enumerated type", skey.name);
1422 return FALSE;
1423 }
1424
1425 if (!(variant = g_settings_schema_key_from_enum (&skey, value)))
1426 {
1427 g_critical ("g_settings_set_enum(): invalid enum value %d for key '%s' "
1428 "in schema '%s'. Doing nothing.", value, skey.name,
1429 g_settings_schema_get_id (skey.schema));
1430 g_settings_schema_key_clear (&skey);
1431 return FALSE;
1432 }
1433
1434 success = g_settings_write_to_backend (settings, &skey, g_steal_pointer (&variant));
1435 g_settings_schema_key_clear (&skey);
1436
1437 return success;
1438 }
1439
1440 /**
1441 * g_settings_get_flags:
1442 * @settings: a #GSettings object
1443 * @key: the key to get the value for
1444 *
1445 * Gets the value that is stored in @settings for @key and converts it
1446 * to the flags value that it represents.
1447 *
1448 * In order to use this function the type of the value must be an array
1449 * of strings and it must be marked in the schema file as a flags type.
1450 *
1451 * It is a programmer error to give a @key that isn't contained in the
1452 * schema for @settings or is not marked as a flags type.
1453 *
1454 * If the value stored in the configuration database is not a valid
1455 * value for the flags type then this function will return the default
1456 * value.
1457 *
1458 * Returns: the flags value
1459 *
1460 * Since: 2.26
1461 **/
1462 guint
g_settings_get_flags(GSettings * settings,const gchar * key)1463 g_settings_get_flags (GSettings *settings,
1464 const gchar *key)
1465 {
1466 GSettingsSchemaKey skey;
1467 GVariant *value;
1468 guint result;
1469
1470 g_return_val_if_fail (G_IS_SETTINGS (settings), -1);
1471 g_return_val_if_fail (key != NULL, -1);
1472
1473 g_settings_schema_key_init (&skey, settings->priv->schema, key);
1474
1475 if (!skey.is_flags)
1476 {
1477 g_critical ("g_settings_get_flags() called on key '%s' which is not "
1478 "associated with a flags type", skey.name);
1479 g_settings_schema_key_clear (&skey);
1480 return -1;
1481 }
1482
1483 value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE);
1484
1485 if (value == NULL)
1486 value = g_settings_schema_key_get_default_value (&skey);
1487
1488 result = g_settings_schema_key_to_flags (&skey, value);
1489 g_settings_schema_key_clear (&skey);
1490 g_variant_unref (value);
1491
1492 return result;
1493 }
1494
1495 /**
1496 * g_settings_set_flags:
1497 * @settings: a #GSettings object
1498 * @key: a key, within @settings
1499 * @value: a flags value
1500 *
1501 * Looks up the flags type nicks for the bits specified by @value, puts
1502 * them in an array of strings and writes the array to @key, within
1503 * @settings.
1504 *
1505 * It is a programmer error to give a @key that isn't contained in the
1506 * schema for @settings or is not marked as a flags type, or for @value
1507 * to contain any bits that are not value for the named type.
1508 *
1509 * After performing the write, accessing @key directly with
1510 * g_settings_get_strv() will return an array of 'nicks'; one for each
1511 * bit in @value.
1512 *
1513 * Returns: %TRUE, if the set succeeds
1514 **/
1515 gboolean
g_settings_set_flags(GSettings * settings,const gchar * key,guint value)1516 g_settings_set_flags (GSettings *settings,
1517 const gchar *key,
1518 guint value)
1519 {
1520 GSettingsSchemaKey skey;
1521 GVariant *variant;
1522 gboolean success;
1523
1524 g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
1525 g_return_val_if_fail (key != NULL, FALSE);
1526
1527 g_settings_schema_key_init (&skey, settings->priv->schema, key);
1528
1529 if (!skey.is_flags)
1530 {
1531 g_critical ("g_settings_set_flags() called on key '%s' which is not "
1532 "associated with a flags type", skey.name);
1533 return FALSE;
1534 }
1535
1536 if (!(variant = g_settings_schema_key_from_flags (&skey, value)))
1537 {
1538 g_critical ("g_settings_set_flags(): invalid flags value 0x%08x "
1539 "for key '%s' in schema '%s'. Doing nothing.",
1540 value, skey.name, g_settings_schema_get_id (skey.schema));
1541 g_settings_schema_key_clear (&skey);
1542 return FALSE;
1543 }
1544
1545 success = g_settings_write_to_backend (settings, &skey, g_steal_pointer (&variant));
1546 g_settings_schema_key_clear (&skey);
1547
1548 return success;
1549 }
1550
1551 /**
1552 * g_settings_set_value:
1553 * @settings: a #GSettings object
1554 * @key: the name of the key to set
1555 * @value: a #GVariant of the correct type
1556 *
1557 * Sets @key in @settings to @value.
1558 *
1559 * It is a programmer error to give a @key that isn't contained in the
1560 * schema for @settings or for @value to have the incorrect type, per
1561 * the schema.
1562 *
1563 * If @value is floating then this function consumes the reference.
1564 *
1565 * Returns: %TRUE if setting the key succeeded,
1566 * %FALSE if the key was not writable
1567 *
1568 * Since: 2.26
1569 **/
1570 gboolean
g_settings_set_value(GSettings * settings,const gchar * key,GVariant * value)1571 g_settings_set_value (GSettings *settings,
1572 const gchar *key,
1573 GVariant *value)
1574 {
1575 GSettingsSchemaKey skey;
1576 gboolean success;
1577
1578 g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
1579 g_return_val_if_fail (key != NULL, FALSE);
1580
1581 g_variant_ref_sink (value);
1582 g_settings_schema_key_init (&skey, settings->priv->schema, key);
1583
1584 if (!g_settings_schema_key_type_check (&skey, value))
1585 {
1586 g_critical ("g_settings_set_value: key '%s' in '%s' expects type '%s', but a GVariant of type '%s' was given",
1587 key,
1588 g_settings_schema_get_id (settings->priv->schema),
1589 g_variant_type_peek_string (skey.type),
1590 g_variant_get_type_string (value));
1591 success = FALSE;
1592 }
1593 else if (!g_settings_schema_key_range_check (&skey, value))
1594 {
1595 g_warning ("g_settings_set_value: value for key '%s' in schema '%s' "
1596 "is outside of valid range",
1597 key,
1598 g_settings_schema_get_id (settings->priv->schema));
1599 success = FALSE;
1600 }
1601 else
1602 {
1603 success = g_settings_write_to_backend (settings, &skey, value);
1604 }
1605
1606 g_settings_schema_key_clear (&skey);
1607 g_variant_unref (value);
1608
1609 return success;
1610 }
1611
1612 /**
1613 * g_settings_get:
1614 * @settings: a #GSettings object
1615 * @key: the key to get the value for
1616 * @format: a #GVariant format string
1617 * @...: arguments as per @format
1618 *
1619 * Gets the value that is stored at @key in @settings.
1620 *
1621 * A convenience function that combines g_settings_get_value() with
1622 * g_variant_get().
1623 *
1624 * It is a programmer error to give a @key that isn't contained in the
1625 * schema for @settings or for the #GVariantType of @format to mismatch
1626 * the type given in the schema.
1627 *
1628 * Since: 2.26
1629 */
1630 void
g_settings_get(GSettings * settings,const gchar * key,const gchar * format,...)1631 g_settings_get (GSettings *settings,
1632 const gchar *key,
1633 const gchar *format,
1634 ...)
1635 {
1636 GVariant *value;
1637 va_list ap;
1638
1639 value = g_settings_get_value (settings, key);
1640
1641 if (strchr (format, '&'))
1642 {
1643 g_critical ("%s: the format string may not contain '&' (key '%s' from schema '%s'). "
1644 "This call will probably stop working with a future version of glib.",
1645 G_STRFUNC, key, g_settings_schema_get_id (settings->priv->schema));
1646 }
1647
1648 va_start (ap, format);
1649 g_variant_get_va (value, format, NULL, &ap);
1650 va_end (ap);
1651
1652 g_variant_unref (value);
1653 }
1654
1655 /**
1656 * g_settings_set:
1657 * @settings: a #GSettings object
1658 * @key: the name of the key to set
1659 * @format: a #GVariant format string
1660 * @...: arguments as per @format
1661 *
1662 * Sets @key in @settings to @value.
1663 *
1664 * A convenience function that combines g_settings_set_value() with
1665 * g_variant_new().
1666 *
1667 * It is a programmer error to give a @key that isn't contained in the
1668 * schema for @settings or for the #GVariantType of @format to mismatch
1669 * the type given in the schema.
1670 *
1671 * Returns: %TRUE if setting the key succeeded,
1672 * %FALSE if the key was not writable
1673 *
1674 * Since: 2.26
1675 */
1676 gboolean
g_settings_set(GSettings * settings,const gchar * key,const gchar * format,...)1677 g_settings_set (GSettings *settings,
1678 const gchar *key,
1679 const gchar *format,
1680 ...)
1681 {
1682 GVariant *value;
1683 va_list ap;
1684
1685 va_start (ap, format);
1686 value = g_variant_new_va (format, NULL, &ap);
1687 va_end (ap);
1688
1689 return g_settings_set_value (settings, key, g_steal_pointer (&value));
1690 }
1691
1692 /**
1693 * g_settings_get_mapped:
1694 * @settings: a #GSettings object
1695 * @key: the key to get the value for
1696 * @mapping: (scope call): the function to map the value in the
1697 * settings database to the value used by the application
1698 * @user_data: user data for @mapping
1699 *
1700 * Gets the value that is stored at @key in @settings, subject to
1701 * application-level validation/mapping.
1702 *
1703 * You should use this function when the application needs to perform
1704 * some processing on the value of the key (for example, parsing). The
1705 * @mapping function performs that processing. If the function
1706 * indicates that the processing was unsuccessful (due to a parse error,
1707 * for example) then the mapping is tried again with another value.
1708 *
1709 * This allows a robust 'fall back to defaults' behaviour to be
1710 * implemented somewhat automatically.
1711 *
1712 * The first value that is tried is the user's setting for the key. If
1713 * the mapping function fails to map this value, other values may be
1714 * tried in an unspecified order (system or site defaults, translated
1715 * schema default values, untranslated schema default values, etc).
1716 *
1717 * If the mapping function fails for all possible values, one additional
1718 * attempt is made: the mapping function is called with a %NULL value.
1719 * If the mapping function still indicates failure at this point then
1720 * the application will be aborted.
1721 *
1722 * The result parameter for the @mapping function is pointed to a
1723 * #gpointer which is initially set to %NULL. The same pointer is given
1724 * to each invocation of @mapping. The final value of that #gpointer is
1725 * what is returned by this function. %NULL is valid; it is returned
1726 * just as any other value would be.
1727 *
1728 * Returns: (transfer full): the result, which may be %NULL
1729 **/
1730 gpointer
g_settings_get_mapped(GSettings * settings,const gchar * key,GSettingsGetMapping mapping,gpointer user_data)1731 g_settings_get_mapped (GSettings *settings,
1732 const gchar *key,
1733 GSettingsGetMapping mapping,
1734 gpointer user_data)
1735 {
1736 gpointer result = NULL;
1737 GSettingsSchemaKey skey;
1738 GVariant *value;
1739 gboolean okay;
1740
1741 g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
1742 g_return_val_if_fail (key != NULL, NULL);
1743 g_return_val_if_fail (mapping != NULL, NULL);
1744
1745 g_settings_schema_key_init (&skey, settings->priv->schema, key);
1746
1747 if ((value = g_settings_read_from_backend (settings, &skey, FALSE, FALSE)))
1748 {
1749 okay = mapping (value, &result, user_data);
1750 g_variant_unref (value);
1751 if (okay) goto okay;
1752 }
1753
1754 if ((value = g_settings_schema_key_get_translated_default (&skey)))
1755 {
1756 okay = mapping (value, &result, user_data);
1757 g_variant_unref (value);
1758 if (okay) goto okay;
1759 }
1760
1761 if ((value = g_settings_schema_key_get_per_desktop_default (&skey)))
1762 {
1763 okay = mapping (value, &result, user_data);
1764 g_variant_unref (value);
1765 if (okay) goto okay;
1766 }
1767
1768 if (mapping (skey.default_value, &result, user_data))
1769 goto okay;
1770
1771 if (!mapping (NULL, &result, user_data))
1772 g_error ("The mapping function given to g_settings_get_mapped() for key "
1773 "'%s' in schema '%s' returned FALSE when given a NULL value.",
1774 key, g_settings_schema_get_id (settings->priv->schema));
1775
1776 okay:
1777 g_settings_schema_key_clear (&skey);
1778
1779 return result;
1780 }
1781
1782 /* Convenience API (get, set_string, int, double, boolean, strv) {{{1 */
1783 /**
1784 * g_settings_get_string:
1785 * @settings: a #GSettings object
1786 * @key: the key to get the value for
1787 *
1788 * Gets the value that is stored at @key in @settings.
1789 *
1790 * A convenience variant of g_settings_get() for strings.
1791 *
1792 * It is a programmer error to give a @key that isn't specified as
1793 * having a string type in the schema for @settings.
1794 *
1795 * Returns: a newly-allocated string
1796 *
1797 * Since: 2.26
1798 */
1799 gchar *
g_settings_get_string(GSettings * settings,const gchar * key)1800 g_settings_get_string (GSettings *settings,
1801 const gchar *key)
1802 {
1803 GVariant *value;
1804 gchar *result;
1805
1806 value = g_settings_get_value (settings, key);
1807 result = g_variant_dup_string (value, NULL);
1808 g_variant_unref (value);
1809
1810 return result;
1811 }
1812
1813 /**
1814 * g_settings_set_string:
1815 * @settings: a #GSettings object
1816 * @key: the name of the key to set
1817 * @value: the value to set it to
1818 *
1819 * Sets @key in @settings to @value.
1820 *
1821 * A convenience variant of g_settings_set() for strings.
1822 *
1823 * It is a programmer error to give a @key that isn't specified as
1824 * having a string type in the schema for @settings.
1825 *
1826 * Returns: %TRUE if setting the key succeeded,
1827 * %FALSE if the key was not writable
1828 *
1829 * Since: 2.26
1830 */
1831 gboolean
g_settings_set_string(GSettings * settings,const gchar * key,const gchar * value)1832 g_settings_set_string (GSettings *settings,
1833 const gchar *key,
1834 const gchar *value)
1835 {
1836 return g_settings_set_value (settings, key, g_variant_new_string (value));
1837 }
1838
1839 /**
1840 * g_settings_get_int:
1841 * @settings: a #GSettings object
1842 * @key: the key to get the value for
1843 *
1844 * Gets the value that is stored at @key in @settings.
1845 *
1846 * A convenience variant of g_settings_get() for 32-bit integers.
1847 *
1848 * It is a programmer error to give a @key that isn't specified as
1849 * having a int32 type in the schema for @settings.
1850 *
1851 * Returns: an integer
1852 *
1853 * Since: 2.26
1854 */
1855 gint
g_settings_get_int(GSettings * settings,const gchar * key)1856 g_settings_get_int (GSettings *settings,
1857 const gchar *key)
1858 {
1859 GVariant *value;
1860 gint result;
1861
1862 value = g_settings_get_value (settings, key);
1863 result = g_variant_get_int32 (value);
1864 g_variant_unref (value);
1865
1866 return result;
1867 }
1868
1869 /**
1870 * g_settings_set_int:
1871 * @settings: a #GSettings object
1872 * @key: the name of the key to set
1873 * @value: the value to set it to
1874 *
1875 * Sets @key in @settings to @value.
1876 *
1877 * A convenience variant of g_settings_set() for 32-bit integers.
1878 *
1879 * It is a programmer error to give a @key that isn't specified as
1880 * having a int32 type in the schema for @settings.
1881 *
1882 * Returns: %TRUE if setting the key succeeded,
1883 * %FALSE if the key was not writable
1884 *
1885 * Since: 2.26
1886 */
1887 gboolean
g_settings_set_int(GSettings * settings,const gchar * key,gint value)1888 g_settings_set_int (GSettings *settings,
1889 const gchar *key,
1890 gint value)
1891 {
1892 return g_settings_set_value (settings, key, g_variant_new_int32 (value));
1893 }
1894
1895 /**
1896 * g_settings_get_int64:
1897 * @settings: a #GSettings object
1898 * @key: the key to get the value for
1899 *
1900 * Gets the value that is stored at @key in @settings.
1901 *
1902 * A convenience variant of g_settings_get() for 64-bit integers.
1903 *
1904 * It is a programmer error to give a @key that isn't specified as
1905 * having a int64 type in the schema for @settings.
1906 *
1907 * Returns: a 64-bit integer
1908 *
1909 * Since: 2.50
1910 */
1911 gint64
g_settings_get_int64(GSettings * settings,const gchar * key)1912 g_settings_get_int64 (GSettings *settings,
1913 const gchar *key)
1914 {
1915 GVariant *value;
1916 gint64 result;
1917
1918 value = g_settings_get_value (settings, key);
1919 result = g_variant_get_int64 (value);
1920 g_variant_unref (value);
1921
1922 return result;
1923 }
1924
1925 /**
1926 * g_settings_set_int64:
1927 * @settings: a #GSettings object
1928 * @key: the name of the key to set
1929 * @value: the value to set it to
1930 *
1931 * Sets @key in @settings to @value.
1932 *
1933 * A convenience variant of g_settings_set() for 64-bit integers.
1934 *
1935 * It is a programmer error to give a @key that isn't specified as
1936 * having a int64 type in the schema for @settings.
1937 *
1938 * Returns: %TRUE if setting the key succeeded,
1939 * %FALSE if the key was not writable
1940 *
1941 * Since: 2.50
1942 */
1943 gboolean
g_settings_set_int64(GSettings * settings,const gchar * key,gint64 value)1944 g_settings_set_int64 (GSettings *settings,
1945 const gchar *key,
1946 gint64 value)
1947 {
1948 return g_settings_set_value (settings, key, g_variant_new_int64 (value));
1949 }
1950
1951 /**
1952 * g_settings_get_uint:
1953 * @settings: a #GSettings object
1954 * @key: the key to get the value for
1955 *
1956 * Gets the value that is stored at @key in @settings.
1957 *
1958 * A convenience variant of g_settings_get() for 32-bit unsigned
1959 * integers.
1960 *
1961 * It is a programmer error to give a @key that isn't specified as
1962 * having a uint32 type in the schema for @settings.
1963 *
1964 * Returns: an unsigned integer
1965 *
1966 * Since: 2.30
1967 */
1968 guint
g_settings_get_uint(GSettings * settings,const gchar * key)1969 g_settings_get_uint (GSettings *settings,
1970 const gchar *key)
1971 {
1972 GVariant *value;
1973 guint result;
1974
1975 value = g_settings_get_value (settings, key);
1976 result = g_variant_get_uint32 (value);
1977 g_variant_unref (value);
1978
1979 return result;
1980 }
1981
1982 /**
1983 * g_settings_set_uint:
1984 * @settings: a #GSettings object
1985 * @key: the name of the key to set
1986 * @value: the value to set it to
1987 *
1988 * Sets @key in @settings to @value.
1989 *
1990 * A convenience variant of g_settings_set() for 32-bit unsigned
1991 * integers.
1992 *
1993 * It is a programmer error to give a @key that isn't specified as
1994 * having a uint32 type in the schema for @settings.
1995 *
1996 * Returns: %TRUE if setting the key succeeded,
1997 * %FALSE if the key was not writable
1998 *
1999 * Since: 2.30
2000 */
2001 gboolean
g_settings_set_uint(GSettings * settings,const gchar * key,guint value)2002 g_settings_set_uint (GSettings *settings,
2003 const gchar *key,
2004 guint value)
2005 {
2006 return g_settings_set_value (settings, key, g_variant_new_uint32 (value));
2007 }
2008
2009 /**
2010 * g_settings_get_uint64:
2011 * @settings: a #GSettings object
2012 * @key: the key to get the value for
2013 *
2014 * Gets the value that is stored at @key in @settings.
2015 *
2016 * A convenience variant of g_settings_get() for 64-bit unsigned
2017 * integers.
2018 *
2019 * It is a programmer error to give a @key that isn't specified as
2020 * having a uint64 type in the schema for @settings.
2021 *
2022 * Returns: a 64-bit unsigned integer
2023 *
2024 * Since: 2.50
2025 */
2026 guint64
g_settings_get_uint64(GSettings * settings,const gchar * key)2027 g_settings_get_uint64 (GSettings *settings,
2028 const gchar *key)
2029 {
2030 GVariant *value;
2031 guint64 result;
2032
2033 value = g_settings_get_value (settings, key);
2034 result = g_variant_get_uint64 (value);
2035 g_variant_unref (value);
2036
2037 return result;
2038 }
2039
2040 /**
2041 * g_settings_set_uint64:
2042 * @settings: a #GSettings object
2043 * @key: the name of the key to set
2044 * @value: the value to set it to
2045 *
2046 * Sets @key in @settings to @value.
2047 *
2048 * A convenience variant of g_settings_set() for 64-bit unsigned
2049 * integers.
2050 *
2051 * It is a programmer error to give a @key that isn't specified as
2052 * having a uint64 type in the schema for @settings.
2053 *
2054 * Returns: %TRUE if setting the key succeeded,
2055 * %FALSE if the key was not writable
2056 *
2057 * Since: 2.50
2058 */
2059 gboolean
g_settings_set_uint64(GSettings * settings,const gchar * key,guint64 value)2060 g_settings_set_uint64 (GSettings *settings,
2061 const gchar *key,
2062 guint64 value)
2063 {
2064 return g_settings_set_value (settings, key, g_variant_new_uint64 (value));
2065 }
2066
2067 /**
2068 * g_settings_get_double:
2069 * @settings: a #GSettings object
2070 * @key: the key to get the value for
2071 *
2072 * Gets the value that is stored at @key in @settings.
2073 *
2074 * A convenience variant of g_settings_get() for doubles.
2075 *
2076 * It is a programmer error to give a @key that isn't specified as
2077 * having a 'double' type in the schema for @settings.
2078 *
2079 * Returns: a double
2080 *
2081 * Since: 2.26
2082 */
2083 gdouble
g_settings_get_double(GSettings * settings,const gchar * key)2084 g_settings_get_double (GSettings *settings,
2085 const gchar *key)
2086 {
2087 GVariant *value;
2088 gdouble result;
2089
2090 value = g_settings_get_value (settings, key);
2091 result = g_variant_get_double (value);
2092 g_variant_unref (value);
2093
2094 return result;
2095 }
2096
2097 /**
2098 * g_settings_set_double:
2099 * @settings: a #GSettings object
2100 * @key: the name of the key to set
2101 * @value: the value to set it to
2102 *
2103 * Sets @key in @settings to @value.
2104 *
2105 * A convenience variant of g_settings_set() for doubles.
2106 *
2107 * It is a programmer error to give a @key that isn't specified as
2108 * having a 'double' type in the schema for @settings.
2109 *
2110 * Returns: %TRUE if setting the key succeeded,
2111 * %FALSE if the key was not writable
2112 *
2113 * Since: 2.26
2114 */
2115 gboolean
g_settings_set_double(GSettings * settings,const gchar * key,gdouble value)2116 g_settings_set_double (GSettings *settings,
2117 const gchar *key,
2118 gdouble value)
2119 {
2120 return g_settings_set_value (settings, key, g_variant_new_double (value));
2121 }
2122
2123 /**
2124 * g_settings_get_boolean:
2125 * @settings: a #GSettings object
2126 * @key: the key to get the value for
2127 *
2128 * Gets the value that is stored at @key in @settings.
2129 *
2130 * A convenience variant of g_settings_get() for booleans.
2131 *
2132 * It is a programmer error to give a @key that isn't specified as
2133 * having a boolean type in the schema for @settings.
2134 *
2135 * Returns: a boolean
2136 *
2137 * Since: 2.26
2138 */
2139 gboolean
g_settings_get_boolean(GSettings * settings,const gchar * key)2140 g_settings_get_boolean (GSettings *settings,
2141 const gchar *key)
2142 {
2143 GVariant *value;
2144 gboolean result;
2145
2146 value = g_settings_get_value (settings, key);
2147 result = g_variant_get_boolean (value);
2148 g_variant_unref (value);
2149
2150 return result;
2151 }
2152
2153 /**
2154 * g_settings_set_boolean:
2155 * @settings: a #GSettings object
2156 * @key: the name of the key to set
2157 * @value: the value to set it to
2158 *
2159 * Sets @key in @settings to @value.
2160 *
2161 * A convenience variant of g_settings_set() for booleans.
2162 *
2163 * It is a programmer error to give a @key that isn't specified as
2164 * having a boolean type in the schema for @settings.
2165 *
2166 * Returns: %TRUE if setting the key succeeded,
2167 * %FALSE if the key was not writable
2168 *
2169 * Since: 2.26
2170 */
2171 gboolean
g_settings_set_boolean(GSettings * settings,const gchar * key,gboolean value)2172 g_settings_set_boolean (GSettings *settings,
2173 const gchar *key,
2174 gboolean value)
2175 {
2176 return g_settings_set_value (settings, key, g_variant_new_boolean (value));
2177 }
2178
2179 /**
2180 * g_settings_get_strv:
2181 * @settings: a #GSettings object
2182 * @key: the key to get the value for
2183 *
2184 * A convenience variant of g_settings_get() for string arrays.
2185 *
2186 * It is a programmer error to give a @key that isn't specified as
2187 * having an array of strings type in the schema for @settings.
2188 *
2189 * Returns: (array zero-terminated=1) (transfer full): a
2190 * newly-allocated, %NULL-terminated array of strings, the value that
2191 * is stored at @key in @settings.
2192 *
2193 * Since: 2.26
2194 */
2195 gchar **
g_settings_get_strv(GSettings * settings,const gchar * key)2196 g_settings_get_strv (GSettings *settings,
2197 const gchar *key)
2198 {
2199 GVariant *value;
2200 gchar **result;
2201
2202 value = g_settings_get_value (settings, key);
2203 result = g_variant_dup_strv (value, NULL);
2204 g_variant_unref (value);
2205
2206 return result;
2207 }
2208
2209 /**
2210 * g_settings_set_strv:
2211 * @settings: a #GSettings object
2212 * @key: the name of the key to set
2213 * @value: (nullable) (array zero-terminated=1): the value to set it to, or %NULL
2214 *
2215 * Sets @key in @settings to @value.
2216 *
2217 * A convenience variant of g_settings_set() for string arrays. If
2218 * @value is %NULL, then @key is set to be the empty array.
2219 *
2220 * It is a programmer error to give a @key that isn't specified as
2221 * having an array of strings type in the schema for @settings.
2222 *
2223 * Returns: %TRUE if setting the key succeeded,
2224 * %FALSE if the key was not writable
2225 *
2226 * Since: 2.26
2227 */
2228 gboolean
g_settings_set_strv(GSettings * settings,const gchar * key,const gchar * const * value)2229 g_settings_set_strv (GSettings *settings,
2230 const gchar *key,
2231 const gchar * const *value)
2232 {
2233 GVariant *array;
2234
2235 if (value != NULL)
2236 array = g_variant_new_strv (value, -1);
2237 else
2238 array = g_variant_new_strv (NULL, 0);
2239
2240 return g_settings_set_value (settings, key, array);
2241 }
2242
2243 /* Delayed apply (delay, apply, revert, get_has_unapplied) {{{1 */
2244 /**
2245 * g_settings_delay:
2246 * @settings: a #GSettings object
2247 *
2248 * Changes the #GSettings object into 'delay-apply' mode. In this
2249 * mode, changes to @settings are not immediately propagated to the
2250 * backend, but kept locally until g_settings_apply() is called.
2251 *
2252 * Since: 2.26
2253 */
2254 void
g_settings_delay(GSettings * settings)2255 g_settings_delay (GSettings *settings)
2256 {
2257 GDelayedSettingsBackend *delayed = NULL;
2258
2259 g_return_if_fail (G_IS_SETTINGS (settings));
2260
2261 if (G_IS_DELAYED_SETTINGS_BACKEND (settings->priv->backend))
2262 return;
2263
2264 delayed = g_delayed_settings_backend_new (settings->priv->backend,
2265 settings,
2266 settings->priv->main_context);
2267 g_settings_backend_unwatch (settings->priv->backend, G_OBJECT (settings));
2268 g_object_unref (settings->priv->backend);
2269
2270 settings->priv->backend = G_SETTINGS_BACKEND (delayed);
2271 g_settings_backend_watch (settings->priv->backend,
2272 &listener_vtable, G_OBJECT (settings),
2273 settings->priv->main_context);
2274
2275 g_object_notify (G_OBJECT (settings), "delay-apply");
2276 }
2277
2278 /**
2279 * g_settings_apply:
2280 * @settings: a #GSettings instance
2281 *
2282 * Applies any changes that have been made to the settings. This
2283 * function does nothing unless @settings is in 'delay-apply' mode;
2284 * see g_settings_delay(). In the normal case settings are always
2285 * applied immediately.
2286 **/
2287 void
g_settings_apply(GSettings * settings)2288 g_settings_apply (GSettings *settings)
2289 {
2290 if (G_IS_DELAYED_SETTINGS_BACKEND (settings->priv->backend))
2291 {
2292 GDelayedSettingsBackend *delayed;
2293
2294 delayed = G_DELAYED_SETTINGS_BACKEND (settings->priv->backend);
2295 g_delayed_settings_backend_apply (delayed);
2296 }
2297 }
2298
2299 /**
2300 * g_settings_revert:
2301 * @settings: a #GSettings instance
2302 *
2303 * Reverts all non-applied changes to the settings. This function
2304 * does nothing unless @settings is in 'delay-apply' mode; see
2305 * g_settings_delay(). In the normal case settings are always applied
2306 * immediately.
2307 *
2308 * Change notifications will be emitted for affected keys.
2309 **/
2310 void
g_settings_revert(GSettings * settings)2311 g_settings_revert (GSettings *settings)
2312 {
2313 if (G_IS_DELAYED_SETTINGS_BACKEND (settings->priv->backend))
2314 {
2315 GDelayedSettingsBackend *delayed;
2316
2317 delayed = G_DELAYED_SETTINGS_BACKEND (settings->priv->backend);
2318 g_delayed_settings_backend_revert (delayed);
2319 }
2320 }
2321
2322 /**
2323 * g_settings_get_has_unapplied:
2324 * @settings: a #GSettings object
2325 *
2326 * Returns whether the #GSettings object has any unapplied
2327 * changes. This can only be the case if it is in 'delayed-apply' mode.
2328 *
2329 * Returns: %TRUE if @settings has unapplied changes
2330 *
2331 * Since: 2.26
2332 */
2333 gboolean
g_settings_get_has_unapplied(GSettings * settings)2334 g_settings_get_has_unapplied (GSettings *settings)
2335 {
2336 g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
2337
2338 return G_IS_DELAYED_SETTINGS_BACKEND (settings->priv->backend) &&
2339 g_delayed_settings_backend_get_has_unapplied (
2340 G_DELAYED_SETTINGS_BACKEND (settings->priv->backend));
2341 }
2342
2343 /* Extra API (reset, sync, get_child, is_writable, list_*, ranges) {{{1 */
2344 /**
2345 * g_settings_reset:
2346 * @settings: a #GSettings object
2347 * @key: the name of a key
2348 *
2349 * Resets @key to its default value.
2350 *
2351 * This call resets the key, as much as possible, to its default value.
2352 * That might be the value specified in the schema or the one set by the
2353 * administrator.
2354 **/
2355 void
g_settings_reset(GSettings * settings,const gchar * key)2356 g_settings_reset (GSettings *settings,
2357 const gchar *key)
2358 {
2359 gchar *path;
2360
2361 g_return_if_fail (G_IS_SETTINGS (settings));
2362 g_return_if_fail (key != NULL);
2363
2364 path = g_strconcat (settings->priv->path, key, NULL);
2365 g_settings_backend_reset (settings->priv->backend, path, NULL);
2366 g_free (path);
2367 }
2368
2369 /**
2370 * g_settings_sync:
2371 *
2372 * Ensures that all pending operations are complete for the default backend.
2373 *
2374 * Writes made to a #GSettings are handled asynchronously. For this
2375 * reason, it is very unlikely that the changes have it to disk by the
2376 * time g_settings_set() returns.
2377 *
2378 * This call will block until all of the writes have made it to the
2379 * backend. Since the mainloop is not running, no change notifications
2380 * will be dispatched during this call (but some may be queued by the
2381 * time the call is done).
2382 **/
2383 void
g_settings_sync(void)2384 g_settings_sync (void)
2385 {
2386 g_settings_backend_sync_default ();
2387 }
2388
2389 /**
2390 * g_settings_is_writable:
2391 * @settings: a #GSettings object
2392 * @name: the name of a key
2393 *
2394 * Finds out if a key can be written or not
2395 *
2396 * Returns: %TRUE if the key @name is writable
2397 *
2398 * Since: 2.26
2399 */
2400 gboolean
g_settings_is_writable(GSettings * settings,const gchar * name)2401 g_settings_is_writable (GSettings *settings,
2402 const gchar *name)
2403 {
2404 gboolean writable;
2405 gchar *path;
2406
2407 g_return_val_if_fail (G_IS_SETTINGS (settings), FALSE);
2408
2409 path = g_strconcat (settings->priv->path, name, NULL);
2410 writable = g_settings_backend_get_writable (settings->priv->backend, path);
2411 g_free (path);
2412
2413 return writable;
2414 }
2415
2416 /**
2417 * g_settings_get_child:
2418 * @settings: a #GSettings object
2419 * @name: the name of the child schema
2420 *
2421 * Creates a child settings object which has a base path of
2422 * `base-path/@name`, where `base-path` is the base path of
2423 * @settings.
2424 *
2425 * The schema for the child settings object must have been declared
2426 * in the schema of @settings using a `<child>` element.
2427 *
2428 * The created child settings object will inherit the #GSettings:delay-apply
2429 * mode from @settings.
2430 *
2431 * Returns: (not nullable) (transfer full): a 'child' settings object
2432 *
2433 * Since: 2.26
2434 */
2435 GSettings *
g_settings_get_child(GSettings * settings,const gchar * name)2436 g_settings_get_child (GSettings *settings,
2437 const gchar *name)
2438 {
2439 GSettingsSchema *child_schema;
2440 gchar *child_path;
2441 GSettings *child;
2442
2443 g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
2444
2445 child_schema = g_settings_schema_get_child_schema (settings->priv->schema,
2446 name);
2447 if (child_schema == NULL)
2448 g_error ("Schema '%s' has no child '%s' or child schema not found",
2449 g_settings_schema_get_id (settings->priv->schema), name);
2450
2451 child_path = g_strconcat (settings->priv->path, name, "/", NULL);
2452 child = g_settings_new_full (child_schema,
2453 settings->priv->backend,
2454 child_path);
2455 g_settings_schema_unref (child_schema);
2456 g_free (child_path);
2457
2458 return child;
2459 }
2460
2461 /**
2462 * g_settings_list_keys:
2463 * @settings: a #GSettings object
2464 *
2465 * Introspects the list of keys on @settings.
2466 *
2467 * You should probably not be calling this function from "normal" code
2468 * (since you should already know what keys are in your schema). This
2469 * function is intended for introspection reasons.
2470 *
2471 * You should free the return value with g_strfreev() when you are done
2472 * with it.
2473 *
2474 * Returns: (transfer full) (element-type utf8): a list of the keys on
2475 * @settings, in no defined order
2476 * Deprecated: 2.46: Use g_settings_schema_list_keys() instead.
2477 */
2478 gchar **
g_settings_list_keys(GSettings * settings)2479 g_settings_list_keys (GSettings *settings)
2480 {
2481 return g_settings_schema_list_keys (settings->priv->schema);
2482 }
2483
2484 /**
2485 * g_settings_list_children:
2486 * @settings: a #GSettings object
2487 *
2488 * Gets the list of children on @settings.
2489 *
2490 * The list is exactly the list of strings for which it is not an error
2491 * to call g_settings_get_child().
2492 *
2493 * There is little reason to call this function from "normal" code, since
2494 * you should already know what children are in your schema. This function
2495 * may still be useful there for introspection reasons, however.
2496 *
2497 * You should free the return value with g_strfreev() when you are done
2498 * with it.
2499 *
2500 * Returns: (transfer full) (element-type utf8): a list of the children on
2501 * @settings, in no defined order
2502 */
2503 gchar **
g_settings_list_children(GSettings * settings)2504 g_settings_list_children (GSettings *settings)
2505 {
2506 return g_settings_schema_list_children (settings->priv->schema);
2507 }
2508
2509 /**
2510 * g_settings_get_range:
2511 * @settings: a #GSettings
2512 * @key: the key to query the range of
2513 *
2514 * Queries the range of a key.
2515 *
2516 * Since: 2.28
2517 *
2518 * Deprecated:2.40:Use g_settings_schema_key_get_range() instead.
2519 **/
2520 GVariant *
g_settings_get_range(GSettings * settings,const gchar * key)2521 g_settings_get_range (GSettings *settings,
2522 const gchar *key)
2523 {
2524 GSettingsSchemaKey skey;
2525 GVariant *range;
2526
2527 g_settings_schema_key_init (&skey, settings->priv->schema, key);
2528 range = g_settings_schema_key_get_range (&skey);
2529 g_settings_schema_key_clear (&skey);
2530
2531 return range;
2532 }
2533
2534 /**
2535 * g_settings_range_check:
2536 * @settings: a #GSettings
2537 * @key: the key to check
2538 * @value: the value to check
2539 *
2540 * Checks if the given @value is of the correct type and within the
2541 * permitted range for @key.
2542 *
2543 * Returns: %TRUE if @value is valid for @key
2544 *
2545 * Since: 2.28
2546 *
2547 * Deprecated:2.40:Use g_settings_schema_key_range_check() instead.
2548 **/
2549 gboolean
g_settings_range_check(GSettings * settings,const gchar * key,GVariant * value)2550 g_settings_range_check (GSettings *settings,
2551 const gchar *key,
2552 GVariant *value)
2553 {
2554 GSettingsSchemaKey skey;
2555 gboolean good;
2556
2557 g_settings_schema_key_init (&skey, settings->priv->schema, key);
2558 good = g_settings_schema_key_range_check (&skey, value);
2559 g_settings_schema_key_clear (&skey);
2560
2561 return good;
2562 }
2563
2564 /* Binding {{{1 */
2565 typedef struct
2566 {
2567 GSettingsSchemaKey key;
2568 GSettings *settings;
2569 GObject *object;
2570
2571 GSettingsBindGetMapping get_mapping;
2572 GSettingsBindSetMapping set_mapping;
2573 gpointer user_data;
2574 GDestroyNotify destroy;
2575
2576 guint writable_handler_id;
2577 guint property_handler_id;
2578 const GParamSpec *property;
2579 guint key_handler_id;
2580
2581 /* prevent recursion */
2582 gboolean running;
2583 } GSettingsBinding;
2584
2585 static void
g_settings_binding_free(gpointer data)2586 g_settings_binding_free (gpointer data)
2587 {
2588 GSettingsBinding *binding = data;
2589
2590 g_assert (!binding->running);
2591
2592 if (binding->writable_handler_id)
2593 g_signal_handler_disconnect (binding->settings,
2594 binding->writable_handler_id);
2595
2596 if (binding->key_handler_id)
2597 g_signal_handler_disconnect (binding->settings,
2598 binding->key_handler_id);
2599
2600 if (g_signal_handler_is_connected (binding->object,
2601 binding->property_handler_id))
2602 g_signal_handler_disconnect (binding->object,
2603 binding->property_handler_id);
2604
2605 g_settings_schema_key_clear (&binding->key);
2606
2607 if (binding->destroy)
2608 binding->destroy (binding->user_data);
2609
2610 g_object_unref (binding->settings);
2611
2612 g_slice_free (GSettingsBinding, binding);
2613 }
2614
2615 static GQuark
g_settings_binding_quark(const char * property)2616 g_settings_binding_quark (const char *property)
2617 {
2618 GQuark quark;
2619 gchar *tmp;
2620
2621 tmp = g_strdup_printf ("gsettingsbinding-%s", property);
2622 quark = g_quark_from_string (tmp);
2623 g_free (tmp);
2624
2625 return quark;
2626 }
2627
2628 static void
g_settings_binding_key_changed(GSettings * settings,const gchar * key,gpointer user_data)2629 g_settings_binding_key_changed (GSettings *settings,
2630 const gchar *key,
2631 gpointer user_data)
2632 {
2633 GSettingsBinding *binding = user_data;
2634 GValue value = G_VALUE_INIT;
2635 GVariant *variant;
2636
2637 g_assert (settings == binding->settings);
2638 g_assert (key == binding->key.name);
2639
2640 if (binding->running)
2641 return;
2642
2643 binding->running = TRUE;
2644
2645 g_value_init (&value, binding->property->value_type);
2646
2647 variant = g_settings_read_from_backend (binding->settings, &binding->key, FALSE, FALSE);
2648 if (variant && !binding->get_mapping (&value, variant, binding->user_data))
2649 {
2650 /* silently ignore errors in the user's config database */
2651 g_variant_unref (variant);
2652 variant = NULL;
2653 }
2654
2655 if (variant == NULL)
2656 {
2657 variant = g_settings_schema_key_get_translated_default (&binding->key);
2658 if (variant &&
2659 !binding->get_mapping (&value, variant, binding->user_data))
2660 {
2661 /* flag translation errors with a warning */
2662 g_warning ("Translated default '%s' for key '%s' in schema '%s' "
2663 "was rejected by the binding mapping function",
2664 binding->key.unparsed, binding->key.name,
2665 g_settings_schema_get_id (binding->key.schema));
2666 g_variant_unref (variant);
2667 variant = NULL;
2668 }
2669 }
2670
2671 if (variant == NULL)
2672 {
2673 variant = g_settings_schema_key_get_per_desktop_default (&binding->key);
2674 if (variant &&
2675 !binding->get_mapping (&value, variant, binding->user_data))
2676 {
2677 g_error ("Per-desktop default value for key '%s' in schema '%s' "
2678 "was rejected by the binding mapping function.",
2679 binding->key.name, g_settings_schema_get_id (binding->key.schema));
2680 g_variant_unref (variant);
2681 variant = NULL;
2682 }
2683 }
2684
2685 if (variant == NULL)
2686 {
2687 variant = g_variant_ref (binding->key.default_value);
2688 if (!binding->get_mapping (&value, variant, binding->user_data))
2689 g_error ("The schema default value for key '%s' in schema '%s' "
2690 "was rejected by the binding mapping function.",
2691 binding->key.name, g_settings_schema_get_id (binding->key.schema));
2692 }
2693
2694 g_object_set_property (binding->object, binding->property->name, &value);
2695 g_variant_unref (variant);
2696 g_value_unset (&value);
2697
2698 binding->running = FALSE;
2699 }
2700
2701 static void
g_settings_binding_property_changed(GObject * object,const GParamSpec * pspec,gpointer user_data)2702 g_settings_binding_property_changed (GObject *object,
2703 const GParamSpec *pspec,
2704 gpointer user_data)
2705 {
2706 GSettingsBinding *binding = user_data;
2707 GValue value = G_VALUE_INIT;
2708 GVariant *variant;
2709 gboolean valid = TRUE;
2710
2711 g_assert (object == binding->object);
2712 g_assert (pspec == binding->property);
2713
2714 if (binding->running)
2715 return;
2716
2717 binding->running = TRUE;
2718
2719 g_value_init (&value, pspec->value_type);
2720 g_object_get_property (object, pspec->name, &value);
2721 if ((variant = binding->set_mapping (&value, binding->key.type,
2722 binding->user_data)))
2723 {
2724 g_variant_take_ref (variant);
2725
2726 if (!g_settings_schema_key_type_check (&binding->key, variant))
2727 {
2728 gchar *type_str;
2729 type_str = g_variant_type_dup_string (binding->key.type);
2730 g_critical ("binding mapping function for key '%s' returned "
2731 "GVariant of type '%s' when type '%s' was requested",
2732 binding->key.name, g_variant_get_type_string (variant),
2733 type_str);
2734 g_free (type_str);
2735 valid = FALSE;
2736 }
2737
2738 if (valid && !g_settings_schema_key_range_check (&binding->key, variant))
2739 {
2740 gchar *variant_str;
2741 variant_str = g_variant_print (variant, TRUE);
2742 g_critical ("GObject property '%s' on a '%s' object is out of "
2743 "schema-specified range for key '%s' of '%s': %s",
2744 binding->property->name, g_type_name (binding->property->owner_type),
2745 binding->key.name, g_settings_schema_get_id (binding->key.schema),
2746 variant_str);
2747 g_free (variant_str);
2748 valid = FALSE;
2749 }
2750
2751 if (valid)
2752 {
2753 g_settings_write_to_backend (binding->settings, &binding->key, variant);
2754 }
2755 g_variant_unref (variant);
2756 }
2757 g_value_unset (&value);
2758
2759 binding->running = FALSE;
2760 }
2761
2762 static gboolean
g_settings_bind_invert_boolean_get_mapping(GValue * value,GVariant * variant,gpointer user_data)2763 g_settings_bind_invert_boolean_get_mapping (GValue *value,
2764 GVariant *variant,
2765 gpointer user_data)
2766 {
2767 g_value_set_boolean (value, !g_variant_get_boolean (variant));
2768 return TRUE;
2769 }
2770
2771 static GVariant *
g_settings_bind_invert_boolean_set_mapping(const GValue * value,const GVariantType * expected_type,gpointer user_data)2772 g_settings_bind_invert_boolean_set_mapping (const GValue *value,
2773 const GVariantType *expected_type,
2774 gpointer user_data)
2775 {
2776 return g_variant_new_boolean (!g_value_get_boolean (value));
2777 }
2778
2779 /**
2780 * g_settings_bind:
2781 * @settings: a #GSettings object
2782 * @key: the key to bind
2783 * @object: (type GObject.Object): a #GObject
2784 * @property: the name of the property to bind
2785 * @flags: flags for the binding
2786 *
2787 * Create a binding between the @key in the @settings object
2788 * and the property @property of @object.
2789 *
2790 * The binding uses the default GIO mapping functions to map
2791 * between the settings and property values. These functions
2792 * handle booleans, numeric types and string types in a
2793 * straightforward way. Use g_settings_bind_with_mapping() if
2794 * you need a custom mapping, or map between types that are not
2795 * supported by the default mapping functions.
2796 *
2797 * Unless the @flags include %G_SETTINGS_BIND_NO_SENSITIVITY, this
2798 * function also establishes a binding between the writability of
2799 * @key and the "sensitive" property of @object (if @object has
2800 * a boolean property by that name). See g_settings_bind_writable()
2801 * for more details about writable bindings.
2802 *
2803 * Note that the lifecycle of the binding is tied to @object,
2804 * and that you can have only one binding per object property.
2805 * If you bind the same property twice on the same object, the second
2806 * binding overrides the first one.
2807 *
2808 * Since: 2.26
2809 */
2810 void
g_settings_bind(GSettings * settings,const gchar * key,gpointer object,const gchar * property,GSettingsBindFlags flags)2811 g_settings_bind (GSettings *settings,
2812 const gchar *key,
2813 gpointer object,
2814 const gchar *property,
2815 GSettingsBindFlags flags)
2816 {
2817 GSettingsBindGetMapping get_mapping = NULL;
2818 GSettingsBindSetMapping set_mapping = NULL;
2819
2820 if (flags & G_SETTINGS_BIND_INVERT_BOOLEAN)
2821 {
2822 get_mapping = g_settings_bind_invert_boolean_get_mapping;
2823 set_mapping = g_settings_bind_invert_boolean_set_mapping;
2824
2825 /* can't pass this flag to g_settings_bind_with_mapping() */
2826 flags &= ~G_SETTINGS_BIND_INVERT_BOOLEAN;
2827 }
2828
2829 g_settings_bind_with_mapping (settings, key, object, property, flags,
2830 get_mapping, set_mapping, NULL, NULL);
2831 }
2832
2833 /**
2834 * g_settings_bind_with_mapping: (skip)
2835 * @settings: a #GSettings object
2836 * @key: the key to bind
2837 * @object: (type GObject.Object): a #GObject
2838 * @property: the name of the property to bind
2839 * @flags: flags for the binding
2840 * @get_mapping: a function that gets called to convert values
2841 * from @settings to @object, or %NULL to use the default GIO mapping
2842 * @set_mapping: a function that gets called to convert values
2843 * from @object to @settings, or %NULL to use the default GIO mapping
2844 * @user_data: data that gets passed to @get_mapping and @set_mapping
2845 * @destroy: #GDestroyNotify function for @user_data
2846 *
2847 * Create a binding between the @key in the @settings object
2848 * and the property @property of @object.
2849 *
2850 * The binding uses the provided mapping functions to map between
2851 * settings and property values.
2852 *
2853 * Note that the lifecycle of the binding is tied to @object,
2854 * and that you can have only one binding per object property.
2855 * If you bind the same property twice on the same object, the second
2856 * binding overrides the first one.
2857 *
2858 * Since: 2.26
2859 */
2860 void
g_settings_bind_with_mapping(GSettings * settings,const gchar * key,gpointer object,const gchar * property,GSettingsBindFlags flags,GSettingsBindGetMapping get_mapping,GSettingsBindSetMapping set_mapping,gpointer user_data,GDestroyNotify destroy)2861 g_settings_bind_with_mapping (GSettings *settings,
2862 const gchar *key,
2863 gpointer object,
2864 const gchar *property,
2865 GSettingsBindFlags flags,
2866 GSettingsBindGetMapping get_mapping,
2867 GSettingsBindSetMapping set_mapping,
2868 gpointer user_data,
2869 GDestroyNotify destroy)
2870 {
2871 GSettingsBinding *binding;
2872 GObjectClass *objectclass;
2873 gchar *detailed_signal;
2874 GQuark binding_quark;
2875
2876 g_return_if_fail (G_IS_SETTINGS (settings));
2877 g_return_if_fail (key != NULL);
2878 g_return_if_fail (G_IS_OBJECT (object));
2879 g_return_if_fail (property != NULL);
2880 g_return_if_fail (~flags & G_SETTINGS_BIND_INVERT_BOOLEAN);
2881
2882 objectclass = G_OBJECT_GET_CLASS (object);
2883
2884 binding = g_slice_new0 (GSettingsBinding);
2885 g_settings_schema_key_init (&binding->key, settings->priv->schema, key);
2886 binding->settings = g_object_ref (settings);
2887 binding->object = object;
2888 binding->property = g_object_class_find_property (objectclass, property);
2889 binding->user_data = user_data;
2890 binding->destroy = destroy;
2891 binding->get_mapping = get_mapping ? get_mapping : g_settings_get_mapping;
2892 binding->set_mapping = set_mapping ? set_mapping : g_settings_set_mapping;
2893
2894 if (!(flags & (G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET)))
2895 flags |= G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET;
2896
2897 if (binding->property == NULL)
2898 {
2899 g_critical ("g_settings_bind: no property '%s' on class '%s'",
2900 property, G_OBJECT_TYPE_NAME (object));
2901 return;
2902 }
2903
2904 if ((flags & G_SETTINGS_BIND_GET) &&
2905 (binding->property->flags & G_PARAM_WRITABLE) == 0)
2906 {
2907 g_critical ("g_settings_bind: property '%s' on class '%s' is not "
2908 "writable", binding->property->name, G_OBJECT_TYPE_NAME (object));
2909 return;
2910 }
2911 if ((flags & G_SETTINGS_BIND_SET) &&
2912 (binding->property->flags & G_PARAM_READABLE) == 0)
2913 {
2914 g_critical ("g_settings_bind: property '%s' on class '%s' is not "
2915 "readable", binding->property->name, G_OBJECT_TYPE_NAME (object));
2916 return;
2917 }
2918
2919 if (get_mapping == g_settings_bind_invert_boolean_get_mapping)
2920 {
2921 /* g_settings_bind_invert_boolean_get_mapping() is a private
2922 * function, so if we are here it means that g_settings_bind() was
2923 * called with G_SETTINGS_BIND_INVERT_BOOLEAN.
2924 *
2925 * Ensure that both sides are boolean.
2926 */
2927
2928 if (binding->property->value_type != G_TYPE_BOOLEAN)
2929 {
2930 g_critical ("g_settings_bind: G_SETTINGS_BIND_INVERT_BOOLEAN "
2931 "was specified, but property '%s' on type '%s' has "
2932 "type '%s'", binding->property->name, G_OBJECT_TYPE_NAME (object),
2933 g_type_name ((binding->property->value_type)));
2934 return;
2935 }
2936
2937 if (!g_variant_type_equal (binding->key.type, G_VARIANT_TYPE_BOOLEAN))
2938 {
2939 gchar *type_string = g_variant_type_dup_string (binding->key.type);
2940 g_critical ("g_settings_bind: G_SETTINGS_BIND_INVERT_BOOLEAN "
2941 "was specified, but key '%s' on schema '%s' has "
2942 "type '%s'", key, g_settings_schema_get_id (settings->priv->schema),
2943 type_string);
2944 g_free (type_string);
2945 return;
2946 }
2947
2948 }
2949
2950 else if (((get_mapping == NULL && (flags & G_SETTINGS_BIND_GET)) ||
2951 (set_mapping == NULL && (flags & G_SETTINGS_BIND_SET))) &&
2952 !g_settings_mapping_is_compatible (binding->property->value_type,
2953 binding->key.type))
2954 {
2955 gchar *type_string = g_variant_type_dup_string (binding->key.type);
2956 g_critical ("g_settings_bind: property '%s' on class '%s' has type "
2957 "'%s' which is not compatible with type '%s' of key '%s' "
2958 "on schema '%s'", binding->property->name, G_OBJECT_TYPE_NAME (object),
2959 g_type_name (binding->property->value_type),
2960 type_string, key,
2961 g_settings_schema_get_id (settings->priv->schema));
2962 g_free (type_string);
2963 return;
2964 }
2965
2966 if ((flags & G_SETTINGS_BIND_SET) &&
2967 (~flags & G_SETTINGS_BIND_NO_SENSITIVITY))
2968 {
2969 GParamSpec *sensitive;
2970
2971 sensitive = g_object_class_find_property (objectclass, "sensitive");
2972
2973 if (sensitive && sensitive->value_type == G_TYPE_BOOLEAN &&
2974 (sensitive->flags & G_PARAM_WRITABLE))
2975 g_settings_bind_writable (settings, binding->key.name, object, "sensitive", FALSE);
2976 }
2977
2978 if (flags & G_SETTINGS_BIND_SET)
2979 {
2980 detailed_signal = g_strdup_printf ("notify::%s", binding->property->name);
2981 binding->property_handler_id =
2982 g_signal_connect (object, detailed_signal,
2983 G_CALLBACK (g_settings_binding_property_changed),
2984 binding);
2985 g_free (detailed_signal);
2986
2987 if (~flags & G_SETTINGS_BIND_GET)
2988 g_settings_binding_property_changed (object,
2989 binding->property,
2990 binding);
2991 }
2992
2993 if (flags & G_SETTINGS_BIND_GET)
2994 {
2995 if (~flags & G_SETTINGS_BIND_GET_NO_CHANGES)
2996 {
2997 detailed_signal = g_strdup_printf ("changed::%s", key);
2998 binding->key_handler_id =
2999 g_signal_connect (settings, detailed_signal,
3000 G_CALLBACK (g_settings_binding_key_changed),
3001 binding);
3002 g_free (detailed_signal);
3003 }
3004
3005 g_settings_binding_key_changed (settings, binding->key.name, binding);
3006 }
3007
3008 binding_quark = g_settings_binding_quark (binding->property->name);
3009 g_object_set_qdata_full (object, binding_quark,
3010 binding, g_settings_binding_free);
3011 }
3012
3013 /* Writability binding {{{1 */
3014 typedef struct
3015 {
3016 GSettings *settings;
3017 gpointer object;
3018 const gchar *key;
3019 const gchar *property;
3020 gboolean inverted;
3021 gulong handler_id;
3022 } GSettingsWritableBinding;
3023
3024 static void
g_settings_writable_binding_free(gpointer data)3025 g_settings_writable_binding_free (gpointer data)
3026 {
3027 GSettingsWritableBinding *binding = data;
3028
3029 g_signal_handler_disconnect (binding->settings, binding->handler_id);
3030 g_object_unref (binding->settings);
3031 g_slice_free (GSettingsWritableBinding, binding);
3032 }
3033
3034 static void
g_settings_binding_writable_changed(GSettings * settings,const gchar * key,gpointer user_data)3035 g_settings_binding_writable_changed (GSettings *settings,
3036 const gchar *key,
3037 gpointer user_data)
3038 {
3039 GSettingsWritableBinding *binding = user_data;
3040 gboolean writable;
3041
3042 g_assert (settings == binding->settings);
3043 g_assert (key == binding->key);
3044
3045 writable = g_settings_is_writable (settings, key);
3046
3047 if (binding->inverted)
3048 writable = !writable;
3049
3050 g_object_set (binding->object, binding->property, writable, NULL);
3051 }
3052
3053 /**
3054 * g_settings_bind_writable:
3055 * @settings: a #GSettings object
3056 * @key: the key to bind
3057 * @object: (type GObject.Object):a #GObject
3058 * @property: the name of a boolean property to bind
3059 * @inverted: whether to 'invert' the value
3060 *
3061 * Create a binding between the writability of @key in the
3062 * @settings object and the property @property of @object.
3063 * The property must be boolean; "sensitive" or "visible"
3064 * properties of widgets are the most likely candidates.
3065 *
3066 * Writable bindings are always uni-directional; changes of the
3067 * writability of the setting will be propagated to the object
3068 * property, not the other way.
3069 *
3070 * When the @inverted argument is %TRUE, the binding inverts the
3071 * value as it passes from the setting to the object, i.e. @property
3072 * will be set to %TRUE if the key is not writable.
3073 *
3074 * Note that the lifecycle of the binding is tied to @object,
3075 * and that you can have only one binding per object property.
3076 * If you bind the same property twice on the same object, the second
3077 * binding overrides the first one.
3078 *
3079 * Since: 2.26
3080 */
3081 void
g_settings_bind_writable(GSettings * settings,const gchar * key,gpointer object,const gchar * property,gboolean inverted)3082 g_settings_bind_writable (GSettings *settings,
3083 const gchar *key,
3084 gpointer object,
3085 const gchar *property,
3086 gboolean inverted)
3087 {
3088 GSettingsWritableBinding *binding;
3089 gchar *detailed_signal;
3090 GParamSpec *pspec;
3091
3092 g_return_if_fail (G_IS_SETTINGS (settings));
3093
3094 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property);
3095 if (pspec == NULL)
3096 {
3097 g_critical ("g_settings_bind_writable: no property '%s' on class '%s'",
3098 property, G_OBJECT_TYPE_NAME (object));
3099 return;
3100 }
3101 if ((pspec->flags & G_PARAM_WRITABLE) == 0)
3102 {
3103 g_critical ("g_settings_bind_writable: property '%s' on class '%s' is not writable",
3104 property, G_OBJECT_TYPE_NAME (object));
3105 return;
3106 }
3107
3108 binding = g_slice_new (GSettingsWritableBinding);
3109 binding->settings = g_object_ref (settings);
3110 binding->object = object;
3111 binding->key = g_intern_string (key);
3112 binding->property = g_intern_string (property);
3113 binding->inverted = inverted;
3114
3115 detailed_signal = g_strdup_printf ("writable-changed::%s", key);
3116 binding->handler_id =
3117 g_signal_connect (settings, detailed_signal,
3118 G_CALLBACK (g_settings_binding_writable_changed),
3119 binding);
3120 g_free (detailed_signal);
3121
3122 g_object_set_qdata_full (object, g_settings_binding_quark (property),
3123 binding, g_settings_writable_binding_free);
3124
3125 g_settings_binding_writable_changed (settings, binding->key, binding);
3126 }
3127
3128 /**
3129 * g_settings_unbind:
3130 * @object: (type GObject.Object): the object
3131 * @property: the property whose binding is removed
3132 *
3133 * Removes an existing binding for @property on @object.
3134 *
3135 * Note that bindings are automatically removed when the
3136 * object is finalized, so it is rarely necessary to call this
3137 * function.
3138 *
3139 * Since: 2.26
3140 */
3141 void
g_settings_unbind(gpointer object,const gchar * property)3142 g_settings_unbind (gpointer object,
3143 const gchar *property)
3144 {
3145 GQuark binding_quark;
3146
3147 binding_quark = g_settings_binding_quark (property);
3148 g_object_set_qdata (object, binding_quark, NULL);
3149 }
3150
3151 /* GAction {{{1 */
3152
3153 typedef struct
3154 {
3155 GObject parent_instance;
3156
3157 GSettingsSchemaKey key;
3158 GSettings *settings;
3159 } GSettingsAction;
3160
3161 typedef GObjectClass GSettingsActionClass;
3162
3163 static GType g_settings_action_get_type (void);
3164 static void g_settings_action_iface_init (GActionInterface *iface);
3165 G_DEFINE_TYPE_WITH_CODE (GSettingsAction, g_settings_action, G_TYPE_OBJECT,
3166 G_IMPLEMENT_INTERFACE (G_TYPE_ACTION, g_settings_action_iface_init))
3167
3168 enum
3169 {
3170 ACTION_PROP_0,
3171 ACTION_PROP_NAME,
3172 ACTION_PROP_PARAMETER_TYPE,
3173 ACTION_PROP_ENABLED,
3174 ACTION_PROP_STATE_TYPE,
3175 ACTION_PROP_STATE
3176 };
3177
3178 static const gchar *
g_settings_action_get_name(GAction * action)3179 g_settings_action_get_name (GAction *action)
3180 {
3181 GSettingsAction *gsa = (GSettingsAction *) action;
3182
3183 return gsa->key.name;
3184 }
3185
3186 static const GVariantType *
g_settings_action_get_parameter_type(GAction * action)3187 g_settings_action_get_parameter_type (GAction *action)
3188 {
3189 GSettingsAction *gsa = (GSettingsAction *) action;
3190 const GVariantType *type;
3191
3192 type = g_variant_get_type (gsa->key.default_value);
3193 if (g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
3194 type = NULL;
3195
3196 return type;
3197 }
3198
3199 static gboolean
g_settings_action_get_enabled(GAction * action)3200 g_settings_action_get_enabled (GAction *action)
3201 {
3202 GSettingsAction *gsa = (GSettingsAction *) action;
3203
3204 return g_settings_is_writable (gsa->settings, gsa->key.name);
3205 }
3206
3207 static const GVariantType *
g_settings_action_get_state_type(GAction * action)3208 g_settings_action_get_state_type (GAction *action)
3209 {
3210 GSettingsAction *gsa = (GSettingsAction *) action;
3211
3212 return g_variant_get_type (gsa->key.default_value);
3213 }
3214
3215 static GVariant *
g_settings_action_get_state(GAction * action)3216 g_settings_action_get_state (GAction *action)
3217 {
3218 GSettingsAction *gsa = (GSettingsAction *) action;
3219 GVariant *value;
3220
3221 value = g_settings_read_from_backend (gsa->settings, &gsa->key, FALSE, FALSE);
3222
3223 if (value == NULL)
3224 value = g_settings_schema_key_get_translated_default (&gsa->key);
3225
3226 if (value == NULL)
3227 value = g_variant_ref (gsa->key.default_value);
3228
3229 return value;
3230 }
3231
3232 static GVariant *
g_settings_action_get_state_hint(GAction * action)3233 g_settings_action_get_state_hint (GAction *action)
3234 {
3235 GSettingsAction *gsa = (GSettingsAction *) action;
3236
3237 /* no point in reimplementing this... */
3238 return g_settings_schema_key_get_range (&gsa->key);
3239 }
3240
3241 static void
g_settings_action_change_state(GAction * action,GVariant * value)3242 g_settings_action_change_state (GAction *action,
3243 GVariant *value)
3244 {
3245 GSettingsAction *gsa = (GSettingsAction *) action;
3246
3247 if (g_settings_schema_key_type_check (&gsa->key, value) && g_settings_schema_key_range_check (&gsa->key, value))
3248 g_settings_write_to_backend (gsa->settings, &gsa->key, value);
3249 }
3250
3251 static void
g_settings_action_activate(GAction * action,GVariant * parameter)3252 g_settings_action_activate (GAction *action,
3253 GVariant *parameter)
3254 {
3255 GSettingsAction *gsa = (GSettingsAction *) action;
3256
3257 if (g_variant_is_of_type (gsa->key.default_value, G_VARIANT_TYPE_BOOLEAN))
3258 {
3259 GVariant *old;
3260
3261 if (parameter != NULL)
3262 return;
3263
3264 old = g_settings_action_get_state (action);
3265 parameter = g_variant_new_boolean (!g_variant_get_boolean (old));
3266 g_variant_unref (old);
3267 }
3268
3269 g_action_change_state (action, parameter);
3270 }
3271
3272 static void
g_settings_action_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)3273 g_settings_action_get_property (GObject *object, guint prop_id,
3274 GValue *value, GParamSpec *pspec)
3275 {
3276 GAction *action = G_ACTION (object);
3277
3278 switch (prop_id)
3279 {
3280 case ACTION_PROP_NAME:
3281 g_value_set_string (value, g_settings_action_get_name (action));
3282 break;
3283
3284 case ACTION_PROP_PARAMETER_TYPE:
3285 g_value_set_boxed (value, g_settings_action_get_parameter_type (action));
3286 break;
3287
3288 case ACTION_PROP_ENABLED:
3289 g_value_set_boolean (value, g_settings_action_get_enabled (action));
3290 break;
3291
3292 case ACTION_PROP_STATE_TYPE:
3293 g_value_set_boxed (value, g_settings_action_get_state_type (action));
3294 break;
3295
3296 case ACTION_PROP_STATE:
3297 g_value_take_variant (value, g_settings_action_get_state (action));
3298 break;
3299
3300 default:
3301 g_assert_not_reached ();
3302 }
3303 }
3304
3305 static void
g_settings_action_finalize(GObject * object)3306 g_settings_action_finalize (GObject *object)
3307 {
3308 GSettingsAction *gsa = (GSettingsAction *) object;
3309
3310 g_signal_handlers_disconnect_by_data (gsa->settings, gsa);
3311 g_object_unref (gsa->settings);
3312 g_settings_schema_key_clear (&gsa->key);
3313
3314 G_OBJECT_CLASS (g_settings_action_parent_class)
3315 ->finalize (object);
3316 }
3317
3318 static void
g_settings_action_init(GSettingsAction * gsa)3319 g_settings_action_init (GSettingsAction *gsa)
3320 {
3321 }
3322
3323 static void
g_settings_action_iface_init(GActionInterface * iface)3324 g_settings_action_iface_init (GActionInterface *iface)
3325 {
3326 iface->get_name = g_settings_action_get_name;
3327 iface->get_parameter_type = g_settings_action_get_parameter_type;
3328 iface->get_enabled = g_settings_action_get_enabled;
3329 iface->get_state_type = g_settings_action_get_state_type;
3330 iface->get_state = g_settings_action_get_state;
3331 iface->get_state_hint = g_settings_action_get_state_hint;
3332 iface->change_state = g_settings_action_change_state;
3333 iface->activate = g_settings_action_activate;
3334 }
3335
3336 static void
g_settings_action_class_init(GSettingsActionClass * class)3337 g_settings_action_class_init (GSettingsActionClass *class)
3338 {
3339 class->get_property = g_settings_action_get_property;
3340 class->finalize = g_settings_action_finalize;
3341
3342 g_object_class_override_property (class, ACTION_PROP_NAME, "name");
3343 g_object_class_override_property (class, ACTION_PROP_PARAMETER_TYPE, "parameter-type");
3344 g_object_class_override_property (class, ACTION_PROP_ENABLED, "enabled");
3345 g_object_class_override_property (class, ACTION_PROP_STATE_TYPE, "state-type");
3346 g_object_class_override_property (class, ACTION_PROP_STATE, "state");
3347 }
3348
3349 static void
g_settings_action_changed(GSettings * settings,const gchar * key,gpointer user_data)3350 g_settings_action_changed (GSettings *settings,
3351 const gchar *key,
3352 gpointer user_data)
3353 {
3354 g_object_notify (user_data, "state");
3355 }
3356
3357 static void
g_settings_action_enabled_changed(GSettings * settings,const gchar * key,gpointer user_data)3358 g_settings_action_enabled_changed (GSettings *settings,
3359 const gchar *key,
3360 gpointer user_data)
3361 {
3362 g_object_notify (user_data, "enabled");
3363 }
3364
3365 /**
3366 * g_settings_create_action:
3367 * @settings: a #GSettings
3368 * @key: the name of a key in @settings
3369 *
3370 * Creates a #GAction corresponding to a given #GSettings key.
3371 *
3372 * The action has the same name as the key.
3373 *
3374 * The value of the key becomes the state of the action and the action
3375 * is enabled when the key is writable. Changing the state of the
3376 * action results in the key being written to. Changes to the value or
3377 * writability of the key cause appropriate change notifications to be
3378 * emitted for the action.
3379 *
3380 * For boolean-valued keys, action activations take no parameter and
3381 * result in the toggling of the value. For all other types,
3382 * activations take the new value for the key (which must have the
3383 * correct type).
3384 *
3385 * Returns: (transfer full): a new #GAction
3386 *
3387 * Since: 2.32
3388 **/
3389 GAction *
g_settings_create_action(GSettings * settings,const gchar * key)3390 g_settings_create_action (GSettings *settings,
3391 const gchar *key)
3392 {
3393 GSettingsAction *gsa;
3394 gchar *detailed_signal;
3395
3396 g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
3397 g_return_val_if_fail (key != NULL, NULL);
3398
3399 gsa = g_object_new (g_settings_action_get_type (), NULL);
3400 gsa->settings = g_object_ref (settings);
3401 g_settings_schema_key_init (&gsa->key, settings->priv->schema, key);
3402
3403 detailed_signal = g_strdup_printf ("changed::%s", key);
3404 g_signal_connect (settings, detailed_signal, G_CALLBACK (g_settings_action_changed), gsa);
3405 g_free (detailed_signal);
3406 detailed_signal = g_strdup_printf ("writable-changed::%s", key);
3407 g_signal_connect (settings, detailed_signal, G_CALLBACK (g_settings_action_enabled_changed), gsa);
3408 g_free (detailed_signal);
3409
3410 return G_ACTION (gsa);
3411 }
3412
3413 /* Epilogue {{{1 */
3414
3415 /* vim:set foldmethod=marker: */
3416