Feeds

Tuesday 13 April 2010

GSettings Hackfest: Day 1

Yesterday was the first day of the GSettings Hackfest! Ryan, Matthias, Colin, David and I were locked in a meeting room for the whole day (okay, we went out for lunch and Matthias had to leave afterwards) and we put our brains to good use. Or at least, that's the feeling I got ;-) But first, let me thank the various companies who are helping this hackfest: Novell is sponsoring and hosting it, and Red Hat and Codethink are sending folks here. This hackfest will most certainly make a difference on our road to GNOME 3.0, and the support of those companies is a great contribution! And obviously, without the Foundation support, the event wouldn't have been possible, so here's lots of love from the participants to the Foundation too :-)

We spent the morning planning and discussing various topics, and the afternoon was more like a coding session. Unfortunately, we didn't take any fancy picture, but we'll try to do a better job now. Matthias put some notes online, and here's my attempt to summarize the day (with probably a few errors here and there...).

Ryan gave a general overview of GVariant/GSettings/dconf. Here's a quick summary:

GVariant is the part that landed in glib 2.24 (released at the same time as GNOME 2.30). It's a datatype for values of a type that you specify, and which can be simple, or relatively complex (something with a mix of arrays, tuples, dictionaries, strings and integers, for example).

GSettings is an API to access settings. This is the main focus in this hackfest.

dconf is what will store the settings on the disk, and it's a backend for GSettings. So it's actually only an implementation detail; there's also a simple memory-based backend that makes it easy to test GSettings without dconf.

There's also a GObject serializer that exists in a branch, but it needs to be reviewed and it's not something that is blocking anything major.

So what's important in there for developers? The GSettings API is what you should care about, and it's relatively straight-forward:

/* Get settings associated with the org.gnome.hello schema. We now specify
* directly which schema we want, instead of just a path like in gconf. */
settings = g_settings_new ("org.gnome.hello");
/* Fetch a tuple of integer that are stored together (instead of using two
* distinct keys, like in gconf). */
g_settings_get (settings, "preferred_size", "(ii)", &width, &height);
/* Set a string-typed key. */
g_settings_set (settings, "username", "s", "Rupert");
/* Bind a setting to an object property. */
g_settings_bind (settings, "show_picture", image, "visible", G_SETTINGS_BIND_DEFAULT);

There are already two modules with a gsettings branches: devhelp and gedit. While they probably won't work straight away with the final GSettings, it certainly helps get a better view of what porting involves. Unfortunately, a few things need to be completed before GSettings is usable again, which makes it not really fun to do some port right now. But things should be better really soon now.

For distributors and sysadmins, knowing a bit about dconf will still be important since this is where the settings will be stored, and this is the part the will be used to implement non-schemas default values or mandatory values.

Timeline

We obviously discussed planning, and one explicit goal that was set is to merge GSettings in glib at the end of the week. We'll see how it goes, but that's definitely doable since it's not that big.

There's the question of whether all of GNOME can be ported to GSettings in time for GNOME 3. I do hope it will happen, but we'll certainly know more at the end of the week once we've started porting applications using gconf in interesting ways.

Schemas

While there's already support for schemas, it's not set in stone yet and it can be improved in various ways. Among the things we discussed:

The current format is a really simple format that is easy to write and parse for human eyes, but it's not flexible enough to do everything we need. So we worked on a complete XML format, which is still relatively intuitive. However, we expect to make it possible for developers to use the simple format and compile it to a XML file with a small utility during the build.

The schemas are compiled in a database, that will only contain the default values and potential constraints about the values for a key. So if an application wants to access the description of a key (which is the exception, not the usual case), it will have to parse the XML files for this.

Translations of the descriptions will be fetched with gettext, since they will already be in the .mo files and there's no need to duplicate this information.

How to handle localized default values. This is useful for various settings (clock format, default search engine, etc.), so it's definitely something we want to have. Application developers will have to explicitly mark a key as localizable. We're still debating whether all types of settings should be localizable, or if it's only strings. So don't hesitate to share with us good concrete example of non-string settings that should have a localized default value!

While there are still open questions, we made good progress on this, which will enable us to move to other topics quickly.

Configuration Migration

Migration of configuration is a tough topic, and we're unsure what's the best approach here. We quickly brainstormed about some possibilities:

An easy solution would be to just do nothing. It might look brutal at first, but the gconf schemas that are defined by applications today are often suboptimal in various ways, and maintainers wouldn't be unhappy to be able to change a few things here and there. Also moving to GNOME 3 can be seen as an opportunity to do a clean break. But we already know that this would be annoying for users.

The other extreme solution is to migrate all the gconf database at once. The issue with this, though, is that it assumes that applications stop using gconf at the same time, which is not going to happen: we don't have control over all the applications that are used by users. So a user might change the settings of an gconf-based application after the migration has been done, and those changes will never get migrated, even if the applications gets ported later.

An approach where it's up to each application to signal when to migrate its data (and maybe even which part of the data to migrate, with a file mapping gconf keys to GSettings keys) is a third alternative. It looks relatively attractive, but it also has a simple issue: what happens to the shared settings, like everything living under /desktop/gnome?

So no obvious magic solution (surprise!), and we clearly need to think more about it this week.

Best Practices

It's a topic that came up more than once. We certainly need to define some best practices on how to write schemas (how to name keys, what should be in the description, etc.) and as to when to use GSettings. For the schemas best practices, we can certainly look at what is recommended for gconf, although there are requests to change a few things (prefer dash to underscore, for example).

When to use GSettings is a fun topic: it's really something that should be used to store settings, and not state. So the position of a window, for example, would not be appropriate to store in GSettings. However, without a good API to store transient data, it's likely that GSettings will get abused for this like gconf is being abused. And it seems we don't all agree on what is a setting and what is transient data: having an expander open is an interesting case where Ryan and I are happy to disagree :-)

D-Bus discussion

Hrm, okay, I didn't listen too much to that part of the discussion, so I have nothing really interesting to write about it. But with Colin (who doesn't admit yet he maintains D-Bus) and David (who's writing gdbus) together, there was probably insightful opinions :-) The good news is that gdbus should be ready soon, and I heard some talks about porting gvfs to it...

Hacking

So as you can see, there were a good number of topics discussed. But we slowly turned to our editors after lunch: David focused on gdbus; Ryan worked on GHashFile, an API to store data on disk, which will be used by dconf; Colin progressed on GtkApplication; I did some stupid work to save GSettings stored in the memory backend to keyfiles.

So what happens today? We'll see when the hackfest begins, but it looks like we'll be able to use GSettings again, at least with the memory backend, which will make it easier to review the GSettings branch and start porting applications.

Trackbacks

Comments

The obvious solution for migration, if time permits, would be to write a GSettings backend for GConf and use it together with a tool which migrates the whole database over at one point. Existing applications would continue to work unchanged and moving over to the GSettings API would preserve the old settings. Simple timeline would be;
1) Install new GSettings backend for GConf, at package installation time the whole database would be migrated
2) Continue to use applications unchanged, with the settings stored in whatever format GSetting uses
3) Port over applications to the GSettings API
4) Remove GConf

Sure, it might not be technically feasible to maintain the current GConf API & behavior on top of GSettings, but it would provide the best user experience (settings maintained) and best developer experience (use old and new APIs)

I agree with Johan. I'm not looking forward to any proposal that has my app depending on *both* GSettings and GConf (for example, using GSettings for my own prefs, but still needing GConf to access things like desktop-wide font settings).

Anyone who thinks that changing APIs is going to change the way prefs are abused is fooling themselves...the vast majority of developers are not interested in the purported advantages of a clean break.

«We're still debating whether all types of settings should be localizable, or if it's only strings. So don't hesitate to share with us good concrete example of non-string settings that should have a localized default value!»

In the Maemo Address Book we have a setting (represented by an enum) to choose whether you want to display the contacts by “Given Family”, “Family Given” or “Nickname”. The default value varies based on the language: in English you get “Given Family”, but in other languages you get “Family Given”.
The Maemo address book is not going to be ported to GSettings, but I think our use case could be common for other applications too.

Any reason we can't use the same GSettings API for both settings and state, but keep them in two different stores? One store for all app settings works the way that's already been described, but the API could let you access a separate app-specific and machine-specific store in some XDG directory for storing state.

This would give apps a realistic option to avoid abusing GSettings, without having to waste time reinventing it for storing state. And people might even being syncing settings, who knows?

I think the easiest way to handle migration is to write a really simple, robust and not necessarily very performant or memory efficient read-only gsettings backend (based on the gconf code) for the on-disk gconf file format. Then apps could use this to access the old data and do their own migration (possibly with some utility functions for copying stuff that doesn't need much changes).

This way apps could run without linking to gconf, ORBit2 or relying on the gconf daemon.

Additionally, while we don't expect all apps to perhaps be ported for Gnome 3.0 we really have to nail the whole platform so that apps that spend the time to convert from gconf really gets rid of the gconf dependency.

"I did some stupid work to save GSettings stored in the memory backend to keyfiles."

Awesome! Yes please. Because that way i can duplicate GSettings in an XDG-config directory and still be able to read them with older glib & older gtk after I port my app to newer API but still want to have compatability for older platforms.

One of the bigger complaints I've heard (despite Havoc trying to avoid in his how to maintain compatibility guide) is around configuration versioning ie. the cases where you have a mounted $HOME across multiple systems. Quite often configuration settings get screwed up as you run multiple versions of GNOME on those systems. The problem gets a little worse also when you start putting in a filesystem that allows cloning/snapshotting i.e., what happens when you clone your filesystem prior to an update of the desktop and then want to switch back. This will likely rise its ugly head again as soon as BTFS (or similar) becomes the default system and package updates get handled different (as they are with OpenSolaris and ZFS).

@Marco Barisione: for this use case, with GSettings, you'd still use a string, especially since it supports a range of values. So you can specify that the value has to be one of “Given Family”, “Family Given” or “Nickname”.

@Sandy: there's no easy way to choose a different store at the moment (although you can hack around this by temporarly settings an environment variable when getting a GSettings object). We're talking about how to handle transient state information right now, so we might be able to find a good story soon :-)

@Dmitrijs Ledkovs: hrm, keep in mind that, by default , your application will likely use a dconf backend, so the data won't get saved to a keyfile. And if you start saving the data in a keyfile by forcing the backend (via an environment variable), the application won't be able to use this data once another backend gets used: we don't really support migrating settings from one backend to another right now.

Add a comment

Name or nickname :

Email address :

Website (optional) :

Comment :

4+3?

Please use correct english.

HTML code is displayed as text and web addresses are automatically converted.