GTK+ 2.4 maintenance

Fixing bugs

The focus of 2.4.x development is naturally bug-fixing, since it is the stable series. New features will appear in GTK+ 2.6. Fixing bugs in a mature codebase like GTK+ is not always easy, as the following examples illustrate. Some bugs are even unfixable. But still, an impressive number of bugs is fixed. During the 2.4 development phase (December 2002 - March 2004), we fixed over 1000 bugs in the stable GTK+ 2.2.x branch. This number was derived by counting references to bugzilla bug numbers in the main ChangeLog files of GLib, Pango and GTK+, so the actual number may even be a bit higher (due to bugs without bugzilla entries, and bugs in the documentation).

Borderline case. Focus drawing in buttons.

Some time ago, we noticed a bug in the size allocation function of GtkButton. The visual effect of the bug is only noticable in styles which use wide lines to draw the focus indicator, which is actually required for some accessability-oriented themes. As you can see, the child of the button (which in the example is a color swatch) is drawing over the focus indicator. The bug is simple to fix, but as a consequence, buttons actually need more space, since they now reserve extra space for the focus indicator. Immediately after 2.4.2 was released, the GIMP developers pointed out that this change is problematic for the many small buttons used in the GIMP user interface. As a compromise, the button size allocation was changed again in 2.4.3 to only request the extra space if the button can actually take the focus. This fixes the issues noticed in the GIMP, since the problematic buttons there are not focusable, and we haven't heard complaints about the new behaviour from other GTK+ users.

Performance improvements

While the performance of GTK+ is reasonable on modern hardware, we are always looking at ways to improve the percieved performance. Things we are currently looking at include predictive exposes, unsetting the background when mapping windows, and reducing the overhead of signal emissions. These patches will first appear in the HEAD branch of GTK+ (which will eventually lead to 2.6), but it is not unlikely that we backport them to GTK+ 2.4 after they have proven stable.

Predictive exposes. To understand what predictive exposes are and how they can help the performance of menus, one has to know the normal sequence of events when a window is mapped: The application sends a MapWindow request, which the X server sends on to the window manager. The window manager decides where to place the window, and sends another MapRequest for the window to the X server. This time, the X server maps the window and creates a MapNotify, followed by Expose events which cause the application to draw the contents of the newly mapped window. You will notice that this includes two roundtrips to the X server. But X also has the concept of override-redirect windows, for which the window manager is not involved in the mapping process. For these, there is no real need to wait for the Expose events before starting to draw, since we know that they will be send. Thus, predicting the expose events allows us to get rid of the context switch to the X server and back between popping up the window and drawing it, which will make it less likely that some other process gets scheduled in between.

Unsetting the background. When the X server maps a new window, it fills it with the background color or pixmap, then sends Expose events and waits for the application to draw the contents of the window. This can cause noticable flicker, e.g. when switching between tabs in a GtkNotebook. Fortunately, X allows to set the background of a window to None, and doesn't do any initial filling when windows with background None are mapped. This is not a problem for GTK+, which draws its own background color anyway, and it completely eliminates the flickering when switching notebook pages.

Reduce signal emission overhead. GTK+ makes heavy use of signals. These Signals are a generic callback mechanism implemented in GObject and have nothing to do with traditional Unix signals. Emitting a signal involves analysing varargs function arguments, and marshalling them in a form suitable for use by the connected callback function. Thus a signal emission has a considerable overhead when compared to a regular function call, and it be worth to avoid the signal emission completely if there are no callbacks connected.