Corrected bit about Qt's memory policy.
Update - 10th Aug. 2000OK, so someone thought this was slashdot material. I really do not think it is, for two reasons :
To start with, the very title of the story is wrong : This is not about GTK+, but about Gtk--. GTK+ is certainly the best C toolkit around. However my interest is in C++ toolkits (using them, not implementing them), because I much prefer C++ to C for application development. So switching to Qt/KDE was a logical and practical move, not a political statement.
I am NOT a "long time Gnome hacker". My contribution to Gnome is fairly limited and of very mild importance. I entered Gnome (Gtk-- actually) as a potential application developer because of Rosegarden, and not as a direct contributor. Gtk-- not being ready, I started to help on it, and got caught in that process. Right now I think my contribution to Gnome could be summed up as helping on the proverbial "throw-away prototype" for a GTK+ C++ wrapper, and in that process helping Havoc in making a better one.
I did not help Havoc with Inti because Havoc was working full-time on it, with a very tight schedule, and I could only contribute on my free time. So I wouldn't be of much help. The main reason, however, was simply that I wanted to get back working on Rosegarden, and getting involved in yet another toolkit would certainly drive me further away from this. I just couldn't picture myself saying to Chris and Rich "ok guys, let me hack on this brand new toolkit a little more and I'll resume work on the Rosegarden GUI right away".
I'm also hardly a "slashdot familiar". I do read it daily, and have contributed an article two years ago. I'd think it takes more to be called "familiar" :-).
Finally, english not being my first language, please forgive grammar & spelling errors. Corrections are welcome.
Anyway, here goes.
I left Gtk-- due to having irreconcilable differences with the
other (and, at the time of this writing, the current and only)
maintainer, Karl Nelson.
However, I feel that the series of events which led to this is
worth telling a little about.
It started by Havoc Pennington, a prominent member of the Gnome community and Red Hat Labs employee, who got assigned to find a suitable C++ solution which RedHat could pitch against Qt. Red Hat supports GTK+, which is, as everybody knows, in The One True Language of Hackerdom : C. However, in plain old reality C is all but obsolete and almost everybody in the software industry uses slightly more evolved languages like C++, Visual Basic or Java, except when under very specific constraints, like embedded systems or legacy stuff. So Red Hat is confronted to customers willing to write Linux applications but wanting to use C++, therefore choosing Qt. Hence the need of a presentable C++ wrapper around GTK+.
Gtk-- was about the only contender. Though there are several other C++ wrappers for GTK+ (an old peeve of the Gtk-- team), they basically all suck, being either very incomplete, very badly coded, or both. Gtk-- simply sucked less.
The problem though was that Havoc had to provide a solution on which he had complete control, since it would be proposed to customers. E.g. something more "Open Source" and less "Free Software", so to say :-).
But Gtk-- contains large lumps of very obscure and
quasi-unmaintainable code. Mostly in the preprocessor, among
others. Libsig++ (used by Gtk--) isn't a model of clarity
either.
It also follows design decisions which, although long (and I do
mean long) debated, were highly questionable (read
just plain wrong - though it took me a while to realize
it) nonetheless, like the overuse of references as opposed to
pointers, or the strange memory management policy (allowing the
use of both statically and dynamically allocated widgets). I'm
certainly among the first ones to blame for these. Basically,
Gtk-- was too hairy to be shown to customers, and too
complicated internally to be maintained in a reliable and timely
manner.
Working with us (me and Karl), was also not ideal. Karl and me were almost never in agreement on technical decisions (hence the aforementioned long debates). Although my training is academic, I consider myself being part of the software industry, and that its software development techniques aren't so bad. They are frowned upon by the academia purists, but have the merit to be confronted to reality. Karl is pure academia and rejects the software industry world as a whole. Havoc is, obviously, from the industry as well. So even though giving the Gtk-- helm to Havoc never was a problem, collaboration between the three of us could be forseen as tumultuous at best.
So Havoc had no choice but to write his own GTK+ C++ wrappers. (dramatic musical effect here). Oh the agony :-).
But that would have created yet another GTK+ C++ wrapper, and what's worse, one endorsed and supported by Red Hat. I felt that this would be a serious blow to Gtk-- and Gnome, which very much need good C++ wrappers as well. It also seemed to me that Havoc had a saner approach to the problem than we had (less "technical prowess", more user-oriented).
This last point is worth expanding a little. See "Why does Inti contain yet another C++ binding for GTK+?" from the Inti FAQ. Havoc cites two examples of differences between Inti and Gtk--, which in fact were the core of the disagreement. Karl's position was that "we discussed them for so long, so we must be right". He would probably still consider that Havoc got these wrong. The personal and professional experience I've acquired since then tells me he got them right.
These examples also very much demonstrate the main fault in Gtk-- : solving technical problems for the sake of them, without considering that these problems shouldn't even been posed in the first place.
One thing we were proud of with Gtk--, especially compared to Qt, was our integration with the STL. We'd provide STL iterators for many a thing, like glib's lists, gtk's text widget, and even the gtk container widget interface. While the first two certainly have their uses, it's fairly clear that the last one has almost none. Given the restrictions on a container's children list, about the only thing you can do with an STL interface on it is run the find() algorithm on it. This is a typical example of "cool but useless" feature, with great hack value but no practical one whatsoever.
In Gtk-- you can create widgets in two ways :
Gtk::Button foo("press me");
Gtk::Button *foo = new Gtk::Button("press me");
class MyWidget { // some methods public: Gtk::Button m_button; Gtk::Label m_label; };
However allowing for this has one major problem : you can't have a clear memory management policy. Given that widgets organize in a tree (a parent container holds children, parent-less widgets are toplevel windows) about the only sane policy you can have is for a prent widget to own its children. Both Gtk+ and Qt follow this. But this means you have to create widgets through pointers only, or else you'll end up deleting objects which are on the stack, which is quite a nasty way to corrupt your memory. We used to think this was unacceptable. After working for a few months with Qt, I think we were stupid. We ended up putting the user in full charge of the memory management, and I do mean in full charge. The user had a choice between :
Contrast this with :
What we did was just providing a additional ways for the programmer to shoot himself in the foot, and nothing else. The so-called "flexibility" is in fact only in the bullet's caliber. Again, there was no real added value in what we provided. Just a lot more complexity on both our side and the users, and less safety.
There are ways to ensure that objects are created from the
heap but Qt chooses not to use any of them. I'm not sure
why. My guess is that it's because it would make the API
overall inconsistent (there are Qt objects which aren't
widgets and you can create on the stack), or that it simply
wasn't worth the hassle. There are also ways to determine
whether an object is on the heap or the stack, although with
very strong restrictions.
See item 27 of Scott Meyers' "More
effective C++", and a follow-up
discussion if you want more information on these two
questions.
In that light I suggested Karl that we folded Gtk-- and helped Havoc, who could use a hand, being caught as he was between Gnome and his RH management. We'd provide a way for our users to upgrade from Gtk-- to Havoc's stuff, port Gnome-- to it, and everybody would be happy :
However, Karl refused (to put it mildly). The exchange which ensued was quite unpleasant. Though he kindly apologized later, it was clear to me that I just had to leave. Gtk-- had stopped being fun a long time ago, and I couldn't be part of something which I totally disapproved. So I left. And Havoc wrote Inti, which purpose is better described here.
As a conclusion, I'll point out that I hold no grudges, and feel no bitterness (I'm just too happy with Qt/KDE to care :-). I think Havoc's decision to go on with his own project was the right one, and that keeping Gtk-- alive, although very understandable, is a bad one. Karl told me that he intended to make Gtk-- the best graphic toolkit. I'm all too wary of such intents. And actually I think that Inti is a better toolkit than Gtk--, because Havoc made the right decisions : simplicity and practicality over flexibility for the sake of it.
I could only find one serious reaction to Inti's release comparing it to Gtk--, so I guess I was being overly pessimistic about the impossibility of the two projects co-existing without problems. That Havoc has been very conspicuous about its existence is certainly a reason. However the main point still stands : a lot was to gain from folding Gtk-- in favor of Inti, and Inti is a better toolkit than Gtk--.