Read with interested Aaron’s commentary on theming in GTK+. If you ignore the trolls and read Benjamin’s comment you will start to understand the problem. Ben is the current maintainer of gtk-engines since I have been too busy with organising GUADEC. We’ve both spent some time thinking about the very same problems. In fact, it’s all the more interesting because I suggested to Ben that we should start thinking about a new theme API for exactly some of the points Aaron raises.
The real issue he has is that certain widgets are special cased within the engine to give them a unique look. The original idea of the GTK+ theme API was to provide a number of widget drawing primitives which were indepedant of the widget being drawn (e.g. draw_box, draw_shadow).
This is all very well and good, until you get to examples like the one mentioned. The treeview headers are actually just plain ordinary buttons, there is no special “treeview header” widget. There is no way for the theme to know that what it is drawing are treeview headers unless it actually inspects the widget heirarchy and various other things. It gets even worse if (for example) you want to draw the first and last header button differently. I agree with Aaron that the methods we have to use in gtk-engines are suboptimal, fairly ugly and as a consequence means he cannot achieve the same effect in his custom widget. The ideal way to do this would be to pass a detail hint to the engine when treeview headers are draw. Even then however, the detail strings are undocumented, as with much of the shadier bits of the theming API.
I think one of the problems here is that it is not easy to distinguish the exact “real world” context of a widget in GTK+. As an example, the theme engines often include similar nasty widget inspection hacks to make comboboxes appear as one entire widget, rather than a separate entry and button. It would also be nice to be able to do button grouping (i.e. give the appearance two buttons are related using the theme), but again there is no way to reliably pass this sort of context information to the theme engine.
So in short, we are aware of these issues but are limited in our options to solve them. You can either have more generic looking widgets (e.g. treeview headers that look like normal buttons), or we can use a few tricks to special case a some of them to give the appearance of a more unified widget set. Maybe if Ben and I can start planning a new theming method now, we can solve all these problems for GTK+ 3!
[ Update: Perhaps a good way to describe the problem is that there is a lack of spatial awareness in GTK+. Widget paths and hierarchies are fairly well defined and could be described as the vertical context. However, what surrounds the widget and what its purpose is (the horizontal spatial context) is hardly defined at all.]
What do you think of the QStyle approach:
http://doc.trolltech.com/4.3/qstyle.html
it is already funny reading how gtk+ 3 is going to solve all problems. like quantum computing – just around the corner all the time…
I don’t think I’ve switched desktop themes in at least three years. Not because I love my current one that much, but because I don’t care how it looks as long as
1) It’s not crazy
2) It works
I agree with Jakub here – just don’t use themes.
As in the update at the end of the article, “Spatial” theming certainly seems like an excellent, versatile plan for the future.
However, in the mean time, I think Gtk+ 2.x has a long life ahead of it – with many mature applications and bindings. If “detail hints” are a good option, good we go ahead and _define_ and document a good API (since there doesn’t seem to be one currently) for these hints and include it in 2.14 or 2.16?
Many applications seem to customise TreeView widgets (inconsistently – because of the problems outlined) so they, even as a special case, would be a good priority…
taj, could you summarize “the QStyle approach”? I don’t see anything in that API that’s very descriptive of which way they leaned. They have a bunch of “combobox” style stuff, so it looks like they haven’t solved it either, but just have a really big API to handle lots of special cases (which is basically useless for custom widgets).