Why I love/hate Gtk+

| No Comments

There are many nice features in Gtk+, and recent versions are particularly noticeable for the good collection of clean, stylish widgets.

The API is pure C, chosen so bindings for other languages (such as Python, Haskell, Scheme, etc) are as easy as possible. (This would be more difficult with C++.) So the code is written in an "objecty" style, even though it is plain C. Since v2.0, there is even GObject, which has made possible all sorts of improvements.

The Python Gtk+ bindings are particularly well done (thanks to JamesH) and make writing Gnome apps in Python a breeze.

But there are certain anachronistic aspects of Gtk+ where some X cruftiness has been exposed. Based on my experience thus far, it seems to be mainly concentrated around the imaging model. X has a notorious imaging model, in part due to its client/sever model (which rocks) but also due to various creeping features over the years. This can be both a good and a bad thing, and unfortunately the documentation on this is not particularly helpful.

Since most of my work is in the area of image processing, I need to do a lot of graphics work, fast screen updates and that sort of thing. And every time I have to to graphics in Gtk+ I cringe, due to all the pfaffing about you have to do just to achieve something simple.

For example, to draw a coloured box, you need to create a GtkDrawingArea widget, then in its expose-event handler (why not "draw" instead of "expose"?). Inside, you need to get a context on the widget, then create a colour, then allocate the colour in the widget context, and only then can you actually draw something. So colour management is my first beef; it is way more effort than it should be. Ideally you should just get a context then set the active colour; if some allocation has to go on underneath, hide it from us! It is fairly safe to assume a 24-bit display these days, and if you don't have one, X should handle the dithering.

Then there's images. Or rather, there's Pixmaps and Images, and Drawables. Getting data into and out of these things is obscenely harder than it should be. We have been blessed with libtiff, libjpeg and libpng for ages now, but the docs seem to all embed ASCII-fied XPM bitmaps into the source - who does that anymore? Pixmaps and bitmaps have slightly different APIs, you have to convert between things to draw, and other stuff 'n' nonsense.

It should be fairly straightforward to allocate an image of a given resolution and bit depth, and be able to bit-twiddle directly in the buffer. Then when you're ready, blit it to the screen as fast as the hardware permits.

I've found it is far easier to use OpenGL for my custom drawing (specifically GtkGLDrawingArea) than deal with the messiness of the above. But even getting this working with Gtk+ is fraught with problems. For a start, you frequently need a fixed size canvas when doing imaging. But you can't allocate a widget with a fixed size in Gtk+ - you can request a size, or set a minimum, but a widget's parent is responsible for sizing its children, so you have to do some funky shuffling to get things sized and laid out properly.

Leave a comment