I was meant for the stage

like a lot of Gnome developers, I’ll also be at the Desktop Summit 2011 in Berlin:

I'm going to the Desktop Summit!

I have a talk on Saturday at 11:20, and I’ll have the Board meetings contending for my presentation, hacking and meeting time during most of the conference — but every minute I can spare I’ll be available for chatting about Gnome, Gnome OS, GTK+, and Clutter.

by the way, make sure to attend the talk that Damien, Neil and Chris will present right after mine — it’s going to be awesome.

see you in Berlin!

This is Why We Fight

one thing that bugged me since the implementation of the Clutter animation framework in its current form was the property access API in GObject — especially the boxing/unboxing of GValues. since GLib 2.28 2.24 we had a new macro (G_VALUE_COLLECT_INIT) that avoided doing unnecessary work, but the end result of setting a property was still:

  • box it inside a GValue
  • call the set_property implementation of your class
  • unbox the GValue
  • call the public setter function
  • set the value inside the private data structure
  • free the GValue

there are at least two unnecessary steps, there: the boxing inside GValue should only be necessary for transformation purposes — i.e. taking a GValue and running the transformation function from the passed value type to the property type — but that path should not be taken for variadic arguments functions like g_object_set() since the type used to read the value from the va_list is the property type itself and no transformation is necessary or possble; and calling the set_property() implementation, which is just a huge switch on the property id used when installing the property on a class, just to then call the public accessors. now, try modifying five or so properties at the same time on a hundred objects at 60 frames per second. you can probably get away with it — but only just.

last year, Rob Staudinger proposed some code that provided property access through both accessor functions and direct structure member access through field offset. sadly, I felt that his API was still repeating the same issues of the GParamSpec API: constructors with different signatures (try remembering the arguments and their order between integer properties, enumeration properties, string and boxed properties); reliance on a big switch inside the class implementation; and a general lack of integration with GObject itself.

the last point is mostly what interested me; GParamSpec is meant to be used as a validation tool for a value; it describes the constraints, the default, the prerequisite type, etc.. it’s used to describe properties, but that’s almost a side-effect — a GParamSpec can exist in a vacuum, and can be used regardless of GObject itself. if we wanted to access an object property, the object class should be far more involved in this. we should be able to tie the property description to the structure field that backs it in the implementation; we should be able to define the functions that access it; and we should be able to even provide a default implementation of these accessor functions without requiring developers to actually write them.

another issue with the current state of affairs with GObject properties is the amount of code you have to write. let’s look at a simple class mapping a bunch of fields to properties. right now, you’d have to write every single accessor pair, with hand-written validation; you’d have to hard-code the defaults in three places (the GParamSpec, the instance init function and the accessors); and you’d have to write the set_property() and the get_property() implementation, which end up calling the public accessors anyway because you want to do validation and notification of changes in one place only.

almost all of this code could be autogenerated, even through the C pre-processor.

so, to make a long story short, during the past couple of weeks I started fleshing out the implementation of a new property API for GObject — GProperty.

GProperty is still based on GParamSpec, but it hides all the nasty so you only get a bunch of constructors with the same signature (no more trips to devhelp to check out the <code>g_param_spec_enum()</code> order of arguments) and a generic API for setting constraints like ranges, default values and prerequisite types. plus, you get to specify the field and/or the accessor functions:

  test_object_property[PROP_FOO] =
    g_int8_property_new ("foo", G_PROPERTY_READWRITE,
                         G_STRUCT_OFFSET (TestObjectPrivate, foo),
                         NULL, /* setter */
                         NULL  /* getter */);

  test_object_property[PROP_BAR] =
    g_float_property_new ("bar", G_PROPERTY_READWRITE,
                          -1,
                          test_object_set_bar,
                          test_object_get_bar);

  g_object_class_install_properties (object_class,
                                     G_N_ELEMENTS (test_object_property),
                                     test_object_property);

there are a bunch of other features (automatic atomic properties, macros for auto-generating accessors, per-class default value overriding) for which I’ll just point you again to the bug and the GLib branch; today, though, I wanted to verify whether one of the reasons for working on this — making generic property access faster — actually benefited from these changes. it turns out that it really does: calling g_object_set() in a tight loop with simple values (integers and floating point) improved from the equivalent, GParamSpec-based classic implementation by 2.10x on my Core 2 Duo; if you throw a string into the mix, the improvement is by 1.5x. my initial ballpark figures were way smaller, so I was pleasantly surprised.

hopefully, this work will get more eyeballs during this cycle — and it’ll land in time for 2.32 (and Gnome 3.2).

All Arise

I am GNOME

congratulations to everyone who contributed — feature, widget, application, translation, one-liner, documentation, art, design. you all rock my world.

today I’m immensely proud to be a GNOME developer and user.

January Hymn

as usual, I’m pretty lame at blogging about what I do. I decided to break the silence ((on the blog; I barely shut up on Twitter)) because a couple of awesome things happened these final days of January.

gnome-utils: after years of neglect, and due to a spectacular sugar rush on Saturday, I took again a look at gnome-utils — and in an afternoon I ported the Dictionary to both GSettings and GtkApplication. the APIs are a breeze to use, and the amount of crappy code I wrote years ago before getting a bigger clue about GObject and GTK+ development has been reduced. kudos Ryan, and everyone else who worked on GSettings and G(tk)Application. depending on time constraints, either I or Cosimo (maintainer extraordinaire) will do a release today.

clutter: a bit earlier than expected, but today I just spun the first release of the stable cycle — 1.6.0. I’ll send you to the announcement on the Clutter blog for details — but I wanted to copy the “thanks” section on this blog, in order to give these people a token of my appreciation for their work in making this the best Clutter release as of yet:

Robert Bragg, Neil Roberts, Damien Lespiau, Elliot Smith, Chris Lord, Owen W. Taylor, Bastian Winkler, Tomeu Vizoso, Kristian Høgsberg, nobled, Lucas Rocha, Ole André Vadla Ravnås, Adel Gadllah, Alexandre Quessy, Andika Triwidada, Johan Bilien, Jussi Kukkonen, Piotr Drąg, Alejandro Piñeiro, Aron Xu, Colin Walters, Evan Nemerson, Giovanni Campagna, Maxim Ermilov, Mike Owens, Nguyễn Thái Ngọc Duy, Ray Strode, Rob Bradford, Roland Peffer, Stephen Kennedy, Viatcheslav Gachkaylo, muflone.

these guys rock my world, and if you use Clutter then they rock your world as well. so if you meet any of them, make sure you offer them a beer or a beverage of choice.

GObject Hint/1

if you need to store a Unix Time timestamp inside a GObject property, use an int64 as the property type.

don’t use a GTimeVal, and above all: don’t even think about adding a GType for GTimeVal inside your own project.

first of all, because all that you can do with GTimeVal you can also do it with an int64; second of all, because if everyone starts defining boxed types for types in GLib, we’ll soon start to get collisions. and, no: adding a boxed type in GLib is not a good idea — see above, re: int64.

if you need second resolution (which is fine for most operations), just use tv.tv_sec; if you need millisecond resolution (which is fine for file operations), just use:

  gint64 msecs = tv.tv_sec * 1000 + tv.tv_usec / 1000;

and if you need microsecond resolution (which is fine if you’re bordering insanity), then use:

  gint64 usecs = tv.tv_sec * G_USEC_PER_SEC + tv.tv_usec;

this blog post has been brought to you by your friendly neighbour GObject and language binding developer.

Code Quality

Morten, it’s actually my fault.

the patch that was submitted was the incorrect one; I’ve been fixing the implementation since then, mostly because the API is correct — and went through different eyeballs to ensure that — and we wanted to land it before the GLib freeze. the implementation, alas, has issues — and not just the ones you saw.

as I said, it’s definitely my fault: I reviewed the original in a way that was less than acceptable. I sincerely apologize for that.

okay, having said that, and resuming my usual self: bitching on planet GNOME is not going to get anything fixed. insulting the maintainer when the issue lies mostly in a “patch lieutenant” (such as myself) is also not how polite people deal with errors.

finally, saying that the code needs to be taken out back is a lame cop-out and it is an untenable position for anyone contributing. the code went in, there were issues, so it needs to be fixed. if we waited for perfect code the amount of merged we’d get would be zero. that code has been in the bug for the past 6 months, and it’s been discussed in the past IRC meetings, with public minutes and logs.

so, please: file bugs. I’ll try to close them faster than you can open them.

Walk the line

I’ve noticed that I haven’t blogged about JSON-GLib in a while.

since the last time, I release version 0.10, which had a lot of fixes in the JSON ⬌ GObject transformation code, thanks to the contributions of Tristan Van Berkom. the 0.10 release allowed to transform all GObject properties of fundamental types — and to register transformation functions for boxed types as well. it also had bugs fixes coming from Clutter and other projects using JSON-GLib.

now we’re near the 0.12 release — I released the first release candidate on August 2nd, and I plan to do another release candidate along with the GNOME 2.31.90 snapshot.

for this cycle I’ve had the contribution of Luca Bruno, who wrote a JsonBuilder class which provides a simple API for building JSON trees. JsonBuilder has been inspired by JSONWriter and by GVariantBuilder:

JsonBuilder *builder = json_builder_new ();

json_builder_begin_object (builder);

json_builder_set_member_name (builder, "url");
json_builder_add_string_value (builder, "http://www.gnome.org/img/flash/two-thirty.png");

json_builder_set_member_name (builder, "size");
json_builder_begin_array (builder);
json_builder_add_int_value (builder, 652);
json_builder_add_int_value (builder, 242);
json_builder_end_array (builder);

json_builder_end_object (builder);

JsonGenerator *gen = json_generator_new ();
json_generator_set_root (json_builder_get_root (builder));
char *str = json_generator_to_data (generator);

g_object_unref (generator);
g_object_unref (builder);

/* "str" now contains the string:
 * { "url" : "http://www.gnome.org/img/flash/two-thirty.png", "size" : [ 652, 242 ] }
 */

in the same spirit, I had a fun two hours hacking session that resulted in an XmlReader-like API for JSON trees, called JsonReader:

/* str contains the JSON from the example above */
JsonParser *parser = json_parser_new ();
json_parser_load_from_data (parser, str, -1, NULL);

JsonReader *reader = json_reader_new (json_parser_get_root (parser));

json_reader_read_member (reader, "url");
const char *url = json_reader_get_string_value (reader);
json_reader_end_member (reader);

json_reader_read_member (reader, "size");

json_reader_read_element (reader, 0);
int width = json_reader_get_int_value (reader);
json_reader_end_element (reader);

json_reader_read_element (reader, 1);
int height = json_reader_get_int_value (reader);
json_reader_end_element (reader);

json_reader_end_member (reader);

g_object_unref (reader);
g_object_unref (parser);

I also added support for parsing (synchronously and asynchronously) JSON from a GInputStream and generating stringified JSON to a GOutputStream (in this case, only synchronously). this means that JSON-GLib now depends on GIO.

for the next cycle, which is going to be fairly relaxed in terms of duration, I’m planning some new features like support for the JSON Schema draft in the JsonParser class; and a sensible implementation of a Path API for direct access of members.

if you have bug reports, feature requests, or code you want to contribute, feel free to hop in Bugzilla and file a new ticket.

have fun!

GTK+ Meeting @ GUADEC 2010 – update

since I’m stupid and I scheduled the team meeting before I could actually be in The Hague, I had to move the meeting. and, again, since I’m stupid I managed to schedule it against important talks of the day — and my own.

so: the GTK+ team meeting has been moved to the common area after the last talk of Wednesday, July 28th. sorry for the inconvenience I caused, and please don’t hurt me when you see me.

GTK+ Meeting @ GUADEC 2010

GUADEC is one of the rare occasions for the people hacking on gtk to meet face to face and use a high bandwidth channel to discuss development of everyone’s favorite toolkit.

I’ve reserved a room under the BOF schedule page; currently, it’s on July 27th, between 16:00 and 18:00 (to avoid conflicting with talks).

we need to gather the attendance list, to verify if we should actually have the meeting or if informal discussions are more suited. please, fill out the attendance list and we’ll see you at GUADEC!

I'm attending GUADEC