Hacking local defaults into GConf

It’s very useful to create a limited JHBuild moduleset that builds just a tiny portion of GNOME. We do this for GNOME Shell and it allows people to get GNOME Shell running in just a few minutes without debugging build problems in a gigantic pile of modules. However a persistent problem with doing this is GConf defaults. Because people are testing within their current session, instead of running a completely new session, the gconfd is the system installed gconfd and is looking in the system defaults database for schemas. But the install rules for the jhbuilt modules can’t install schemas there. So the applications don’t get the right default values.

We’ve known for a long time that the right thing to do is to have the application read the defaults information directly; as well as fixing this problem with multiple installlation prefixes, it increase robustness. dconf and GSettings will work this way. But I wanted a quick fix for the gnome-shell JHbuild, not an entire new subsystem. So, today I sat down and wrote gconf-defaults-hack.

gconf-defaults-hack is a small LD_PRELOAD library (yep, yuck), that intercepts two core calls from libgconf: gconf_engine_get_fuller() and gconf_engine_get_default_from_schema(). First these functions are executed as normally, but then if they fail and no default at all was found, the hack library goes and looks in $sysconfdir/etc/gconf/schemas to see if it can find the defaults itself. Obviously, parsing even through a small set of schema XML files on every lookup would be prohibitive, so the first time a lookup is triggered, all the schema files are read at once, and the extracted defaults written to a SQLite database. As long as the mtime of the schema files don’t change, subsequent lookups will continue to use the same database.

You can clone it from git://git.fishsoup.net/gconf-defaults-hack (browse; README)

Is there some better way of making a non-system install of an application work without modifying or hacking GConf? If you know of such, speak up. Would this be better as a modification to libgconf? Conceptually, probably, yes, and making such a modification could be an interesting project for someone. But I was most interested in getting this working without thinking too much about what was long-term supportable.

4 Comments

  1. Posted June 8, 2009 at 6:20 am | Permalink

    Don’t know how much applicable is this to GNOME Shell, but in Sugar we are launching the shell inside a new session bus. As we are using GConf D-BUS, we don’t have the issue you are seeing.

  2. Owen
    Posted June 8, 2009 at 7:24 am | Permalink

    Using a separate session makes a lot of sense for running a nested environment. But ‘gnome-shell –replace’ replaces the user’s existing window manager, and should integrate with logout, the screensaver, etc, so it’s probably not to applicable for us. (Or for someone just JHBuilding a single application.) There are maybe also potential synchronization problems if you have two gconfd’s both writing to the same user database?

  3. Ray Strode
    Posted June 9, 2009 at 2:54 pm | Permalink

    Another idea might be to just add a $GCONF_SOURCE_PATH_FILE environment variable that points to a file in your jhbuild install root (say ~/gnome-shell/install/etc/gnome-shell/gconf-path) which has something like:

    # pull from jhbuild gconf config source for schemas
    xml:readonly:$(HOME)/gnome-shell/install/etc/gconf/gconf.xml.defaults

    # but use system gconf database for settings
    include /etc/gconf/2/path

    Would require a small patch to gconf though to check $GCONF_SOURCE_PATH_FILE before trying GCONF_CONFDIR/path though.

    • Owen
      Posted June 10, 2009 at 8:28 am | Permalink

      Hmm, changing the path for gconfd isn’t really an option, since we are using the user’s normal gconfd from the enclosing session.

      Though maybe an option would be to patch libgconf to allow an extra of local sources to read *after* querying the engine:

      export GCONF_FALLBACK_SOURCES=xml:readonly:$(HOME)/gnome-shell/install/etc/gconf/gconf.xml.defaults

      Then we could add GConf to the jhbuild, and schema installation would go into the local directory (because we’re using the locally build gconftool), and we could set the environment variable.

      Certainly cleaner than my approach. The main disadvantage I see is that we couldn’t work with both gconf-dbus and normal gconf, since we’d have to jhbuild one or the other. Are any Linux distros using gconf-dbus?