Themes Are Evil, Part II

In a previous post, I showed how a GTK+ theme engine can corrupt memory of any application unfortunate enough to be used with it.

In today’s edition, our guest star is the Qt theme engine. It does not, as far as I know, corrupt your memory or otherwise make your innocent application crash.[*] Instead it changes how your program works. For example, for Gnumeric it changes how numbers imported are handled.

If you import the number “8,5” in a decimal-comma locale then you would hope to get eight-and-a-half, right? Well, with the Qt theme you get eight and we, the Gnumeric team, look incompetent. The problem arises because the Qt theme, quite reasonably, initializes the qt library. During that, less reasonably, the following code gets executed:

setlocale( LC_ALL, “” ); // use correct char set mapping
setlocale( LC_NUMERIC, “C” ); // make sprintf()/scanf() work

I am not kidding. The Qt library thinks it should change your locale. What on Earth have the Trolls been drinking? Impure home destilled booze in large quantities?

This problem in various disguises have had us puzzled for quite a while and only very recently was the Qt theme identified as the triggering factor. Once that happened, it was not too hard to locate, but before that we have spent maybe 40 hours looking for this bug. The workaround is to set up a one-shot idle handler that resets the locale properly when the gui comes us. (Repeat this for every GTK+ program that displays or accepts floating-point values.)

The Qt theme people never caught this. If they are mostly “theme” people I can understand, but if they are mostly “Qt” people they really should have known. In either case, it is another exhibit for the case that the GTK+ theme model is seriously flawed.

[*] Well, if you use threads it might. The Qt library calls setlocale to change locale and that’s not allowed in a threaded program.