GConf

Background

GConf simplifies the administration of preferences. It provides a central location for system administrators to set preferences, enables them to employ mandatory settings, provides default settings (and a method to reset all values to their default), documents each setting, and provides a mechanism for applications to be notified when certain preferences change (this is the Gnome mechanism that enables automatic application of preferences).

GConf stores preferences as key-value pairs. The keys are structured hierarchically and are referred to in a filesystem-like manner (which sometimes confuses new users who try to use the command line tools). Each key corresponds to a preference and has an associated type (string, int, bool, etc.). For example, the repeat rate for keys that are held down is stored in /desktop/gnome/peripherals/keyboard/rate; that key has a type of int and, on my system, a value of 30.

There is a gconf-editor program and a gconftool-2 command line tool that will let you see what keys exist, what their values are, and modify them. You can read more about GConf and how to use the gconftool-2 tool in the Gnome Desktop System Administration Guide. However, as a quick introduction, try out the following commands:

  • gconftool-2 --recursive-list /apps/eog
  • gconftool-2 --get --get-type --short-docs --long-docs --get-schema-name /apps/eog/full_screen/upscale
  • gconftool-2 --set /apps/eog/full_screen/upscale --type bool false

Using the GConf library

There are five things to learn for basic usage of GConf: startup, retrieving and setting values, adding listeners, basic sanity checking, and asynchronous issues. One important thing to keep in mind is that programs should be written to be robust to bogus values stored in the GConf database (similar to how they need to be robust to bogus user input; both can provide erroneous values).

A basic GConf application will need to include gconf/gconf-client.h, call gconf_init(argc, argv, NULL) (the NULL is specified to ignore errors; see the Error Reporting section of the GConf Manual if you want to worry about error handling), and then obtain a GConfClient* via gconf_client_get_default().

To retrieve the value of a key from GConf, use the gconf_client_get_<type> functions, where <type> corresponds to one of the GConf Data Types. For example, retrieving the value of the /apps/metacity/general/reduced_resources key (which, among other things, determines whether wireframe resize is turned on) can be done as follows:

  gconf_client_get_bool (client,
                         "/apps/metacity/general/reduced_resources",
                         NULL);

Here, the client is the GConfClient* returned from gconf_client_get_default, and the NULL is specified to ignore errors. To set the value of a key in GConf, use the gconf_client_set_<type> functions. For example, the same key value can be set to true as follows:

  gconf_client_set_bool (client,
                         "/apps/metacity/general/reduced_resources",
                         TRUE,
                         NULL);

In order to add listeners to key values so that your application can be notified when certain keys change, you must first tell gconf that you want to watch keys below a certain "directory". This is done for performance reasons. (Even when those performance issues are irrelevant, such as when you only want to watch a single key, this call must still be made). For example, if you want to monitor the /apps/metacity/general/reduced_resources key, you would first call

  gconf_client_add_dir(client,
                       "/apps/metacity/general",
                       GCONF_CLIENT_PRELOAD_NONE,
                       NULL);

Here, NULL is to ignore errors again, and the GCONF_CLIENT_PRELOAD_NONE is just to specify that we do not want any preloading (preloading is another optimization issue). Then, to actually get gconf to call your callback function when the key changes, you call

  gconf_client_notify_add(client,
                          "/apps/metacity/general/reduced_resources",
                          gconf_key_changed_callback,
                          user_data,
                          destroy_notify_function,
                          NULL);

Here, gconf_key_changed_callback is the callback function for GConf to call when the key changes, user_data is a pointer to some data you want passed to the callback function, destroy_notify_function is a function to call on user_data when either the notify is removed or the GConfClient is destroyed (passing NULL is perfectly fine to provide no such callback), and the NULL is once again there to ignore errors. The gconf_key_changed_callback should be of the following type:

  void (*GConfClientNotifyFunc) (GConfClient *client,
                                 guint cnxn_id,
                                 GConfEntry *entry,
                                 gpointer user_data);

Sanity checking for a boolean value form the GConf database is rather easy; all that needs to be done in the GConfClientNotifyFunc is to make sure the value corresponding to entry is non-NULL and that it's type is boolean:

  gconf_entry_get_value (entry) != NULL &&
  gconf_entry_get_value (entry)->type == GCONF_VALUE_BOOL)

For other types in the database, other checking may need to be done. For example, if a key's value is a string that contains a filename, one may need to check whether the file exists; if the key's value is an integer, one may need to check whether it is in range.

When writing an application that uses GConf, it is important to remember that notifications of changes may be received asynchronously and that outside events can trigger changes while your program is executing. Thus, in many cases, you may need to keep track of an old value and compare to the current/new value and see if there has really been a change before executing some block of code.

Language bindings

Issues specific to the various language bindings (including compilation instructions) can be found at one of the below links:

Learning more

To help you get started, I am including a few examples.

If you are going to be writing an application that introduces new GConf keys, you should read the sections of the GConf manual on Namespace division and Schema Files.