The King is Dead

I guess a lot of you, kind readers, are pretty well-acquainted with the current idiomatic way to write a GObject type. it’s the usual boilerplate, plus or minus a bunch of macros:

// header
typedef struct _MyObject MyObject;
typedef struct _MyObjectPrivate MyObjectPrivate;
typedef struct _MyObjectClass MyObjectClass;

struct _MyObject {
  GObject parent_instance;
  MyObjectPrivate *priv;
};

struct _MyObjectClass {
  GObjectClass parent_class;
};

GType my_object_get_type (void);

// source
struct _MyObjectPrivate
{
  int foo;
};

G_DEFINE_TYPE (MyObject, my_object, G_TYPE_OBJECT)

static void
my_object_class_init (MyObjectClass *klass)
{
  g_type_class_add_private (klass, sizeof (MyObjectPrivate));
}

static void
my_object_init (MyObject *self)
{
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
                                            my_object_get_type (),
                                            MyObjectPrivate);
  self->priv->foo = 42;
}

boring stuff that everyone had to remember1. the last big change in the way people write GObject happened 10 years ago, and it was the addition of per-instance private data. it seems to me like a good way to celebrate that occasion to change this stuff all over again. ;-)

at the latest GTK+ hackfest, Alex and Ryan had a very evil, and very clever idea to solve a problem in how the per-instance private data is laid out in memory. before that, the layout was:

[[[GTypeInstance] GObject] TypeA] TypeB] [TypeAPrivate] [TypeBPrivate]

as you can see, the offset of the private data for each type changes depending at which point in the class hierarchy initialization we are, and can only be determined once the whole class hierarchy has been initialized. this makes retrieving the pointer of the private data a pretty hard problem; one way to solve it is storing the private pointer when we initialize the instance, and we spare ourselves from type checks and traversals. the main problem is that, in order to get to the private data faster, we need to rely on a specific layout of the instance structure, something that is not really nice if we want to have generic accessors to private data2. for that, it would be really cool if we could only have offsets to through to G_STRUCT_MEMBER().

well, it turns out that if you’re doing memory allocations for the instance you can overallocate a bit, and return a pointer in the middle of the memory you allocated. you can actually allocate the whole private data in a decent layout, and only deal with offsets safely — after all, the type information will store all the offsets for safe access. so, here’s the new layout in memory of a GObject3:

[TypeBPrivate] [TypeAPrivate] [[[[GTypeInstance] GObject] TypeA] TypeB]

that’s neat, isn’t it? now all private data can be accessed simply through offsets, and accessing it should be just as fast as a private pointer.

I can already see people using Valgrind preparing torches and pitchforks — but fear not, my fellow developers: GLib now detects if you’re running under Valgrind, and it will communicate with it4 about this new memory layout, as well as keeping a pointer to the beginning of the allocated region, so that you won’t get false positives in your report.

this was the state at the end of the hackfest. on top of that, I decided to contribute a bunch of “syntactic sugar”5 to cut down the amount of lines and things to remember6, as well as providing a good base towards making GProperty work better, and with fewer headaches.

so, here’s how you create a new GObject type in the Brave New World:

// header
typedef struct _MyObject MyObject;
typedef struct _MyObjectClass MyObjectClass;

struct _MyObject {
  GObject parent_instance;
};

struct _MyObjectClass {
  GObjectClass parent_class;
};

GType my_object_get_type (void);

// source
typedef struct {
  int foo;
} MyObjectPrivate;

G_DEFINE_TYPE_WITH_PRIVATE (MyObject, my_object, G_TYPE_OBJECT)

static void
my_object_class_init (MyObjectClass *klass)
{
}

static void
my_object_init (MyObject *self)
{
  MyObjectPrivate *priv = my_object_get_instance_private (self);

  priv->foo = 42;
}

the my_object_get_instance_private() function is generated by G_DEFINE_TYPE, so you can forget about G_TYPE_INSTANCE_GET_PRIVATE and all that jazz. also, no more g_type_class_add_private() — one less thing to remember is one less thing to screw up. you can still store the private pointer in your instance structure — and if you care about ABI compatibility, you really should — but for new code it’s not necessary. you can finally hide the private data structure inside your source code, instead of having the typedef in your header, sitting there, taunting you. finally, everything is just as fast as it was, as well as backward compatible.

stay tuned for the next blog post, because it’ll finally be about GProperty…

  1. or commit to a script to autogenerate it []
  2. say, for instance, if we’re re-implementing the way properties are handled in GObject []
  3. well, of any GTypeInstance, really []
  4. yes, you can do that, and it’s an impressive amount of crack, luckily for us hidden behind the valgrind.h header provided by the Valgrind folks []
  5. i.e. pre-processor macros []
  6. the port of GIO to the new macros lost around 900 lines []

From my Own True Love (Lost at Sea)

Third day of the GTK hackfest. They have taken the bridge and the second hall. We have barred the gates but cannot hold them for long. The ground shakes, drums… drums in the deep. We cannot get out. A shadow lurks in the dark. We can not get out… they are coming.

today, the topics discussed were two:

  • ClutterBenjamin, Matthias, and I discussed how to integrate Clutter with GTK in the future. the plan that is shaping up is to hollow out GtkWidget and make it the minimal semantic unit of the structure of an application; a button, a combo box, a text entry, etc. each widget would then be composed of internal elements — the background and the text for a button; the icons, the progress bar, and the text, for an entry, and so on, and so forth. each element maps the CSS box model (as far as it makes sense), and it’s backed by a ClutterActor. layout management of each element, and rendering, is deferred to Clutter. so, each GtkWidget has-a ClutterActor, that you can also access to use Clutter directly. implementing a GtkWidget would then be simplified to actually building the structure that has to be rendered, drawing with Cairo on provided surfaces if you have custom content instead of primitives like texture data or text, thus leaving the rest to the scene graph underneath. while this is not a radical change in how GTK+ works, we’re definitely considering bumping to the 4.0 API version — this time it wouldn’t be such a quantum leap like it has been for the 2.x to 3.x transition. all this work depends on the Clutter 2.0 effort, which will take the bulk of the next cycle for me. hopefully, with a little help, we’ll be able to do a GTK+ 4.0 in 12 months.
  • design — after lunch, we all sat down with the GNOME designers, and talked about the direction for the toolkit, especially with regards to enabling touch on widgets, and adding more widgets that are touch-oriented to be used when designing applications for touchscreen environments. we also discussed a lot about themeing, and how app developers should use or depend on themes like they do on ABI. then we went through the design whiteboards section of the wiki to see what tasks involve the toolkit — like printing, notification, selection, and content selection.

all in all, it was a very productive day; we’re churning through the agenda points at a fairly good pace, and hopefully we’ll soon be able to work on all the areas that have been identified, in order to make GNOME rock.

Youth and Beauty Brigade

first day of the GTK+ Hackfest.

while we waited for various participants to arrive, discussions started on a couple of topics:

  • accessibility — Benjamin reported on the various discussions and deliberations that happened during the latest Accessibility Hackfest; what we want to achieve is a state in which the accessibility team has fewer headaches working around issues in the toolkit, and can instead work on the toolkit itself. there is also a question of what kind of API to expose to application developers, not just for people writing AT apps, but also for people writing UI testing suites.
  • multi-touch — Chase, Benjamin, Ryan, and occasionally myself, caught up a bit on the overall issues of what kind of API to expose from GTK+ to applications, and what kind of approaches we should be using internally. the bulk of the discussion will resume either this evening, where alcohol will be involved in making them long and very much detailed; or tomorrow, where hangover will keep them focused and short.

plus, people were really interested in the correctness of the regular expression on my tee, which was initially amusing, up until the point a whiteboard and a state machine were involved. occupational hazards, I guess.

I also want to point out that at no point knives, or other weaponry, was involved in the various discussions.

I’d like to thank Red Hat (and the Red Hat office in Brno) for offering the conference room for the hackfest.

Bridges and Balloons

after a rather interesting, albeit not really eventful, journey that spanned cars, buses, a train, and a plane, I’m finally in the lovely Brno — with 2 degrees Celsius and a lot of snow — for the 2012 GTK+ hackfest.

unlike the previous two hackfests, and against my usual inability to write interesting stuff, I’ll try and live-blog the event as much as I can.

as you can see on the wiki page, the agenda is pretty dense, and it’s going to be an intense 6 days hackathon, filled with discussions as much as coding. my part? talking about rainbows and unicorns, obviously.

a lot happened in the months between the Desktop Summit in Berlin, where we first sat down and talked about what Clutter does, and what GTK needs; there has been various progress in the Clutter API towards a sane base for a 2.0 release. if you try and compile an existing application using Clutter with the 1.9 developers snapshots, you’ll notice the depth and breadth of deprecations and API additions. a lot more needs to change — and some of this work on getting from here to there is detailed on the Clutter wiki, under the not at all threatening name of Clutter Apocalypses. I’ll try and write other blog posts about how I envision those changes, and why I think they are necessary for a 2.0 API version.

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