Thiago Macieira
Qt
KDE
Posted by Thiago Macieira
 in Qt, KDE
 on Friday, August 29, 2008 @ 21:15

In the first part of this blog, I discussed a bit the change process and the development process we’re aiming for.

It’s interesting to realise that we’re going through the same process both in KDE and Qt. It’s also interesting that it’s happening at the same time for both — well, slightly ahead for Qt. That’s not, however, a coincidence.

I read a comment on the dot article about opposing a VCS switch every two years. Well, we’re not switching just for the fun of switching. We’re doing it because there are many compelling reasons to do so. (Also, it’s been over 3 years since the Subversion switch, about 4 since we started seriously considering it; Trolltech has been using Perforce for almost 9 years)

And it’s happening now because the DVCS tools have matured enough that we can migrate massive repositories into it. The Qt repository right now has about 170,000 commits and is over 900 MB in size (in Git, well packed). And the KDE repositories I imported had 79404, 71892, 60182 commits for kdelibs, kdebase and koffice, respectively.

And because the old processes and tools have become outdated. And, finally, because we’re people and we talk :-) (that is, exchange of experience and opinions)

Switching to Git

So far I have not approached the second part of my blog title. There’s a very good reason for that: most of what we want to do, the workflow we want to introduce, does not depend on any specific tool. There are feature requirements that many tools do not fulfill, but many do fit the bill.

So why Git, in specific?

We had a lengthy process internally at Trolltech trying to decide whether we should switch to a DVCS and, if so, which tool it should be. That was a very interesting process, but one that would deserve an entire blog on the subject. We had a restricted set at the beginning, but only two serious contenders at the end: Git and Mercurial.

At one point, we came up with a list of what were the criteria we were going to use to make the decision. And then we took a look at which criteria were showstoppers. At the end of the process, there was a clear winner.

The most important criteria in that decision were:

  • Quality of the conversion process (from Perforce)
  • In-house knowledge of the tool
  • Ability of the tool to support our proposed workflow

While the latter criterion was a tie between Mercurial and Git, the first two is where there was a clear winner.

(Disclaimer: there were other reasons, with a varying degree of importance, including some where Git lost to Mercurial)

And if you look at it, those are the exact same criteria that are of importance to KDE now. Sure, there are other tools that also do the job, but who’s going to do the conversion? Who’s going to support and help the developers who aren’t familiar with the tool?

For close to a year now, we’ve had the kde-scm-interest mailing list, whose mandate is to propose a plan to convert from Subversion to another VCS (or Source Control Management - SCM) and how the layout and workflow would be with this tool. Which VCS, it’s not specified. Any is welcome, barring CVS (we’re not going back), Subversion (it’s not conversion if we stay where we are) and solutions that aren’t Free and Open Source.

If you inspect the archives, you’ll see that there’s only one contender. So far, anyways. Others are more than welcome to join and repeat the process for other tools. But mind you: you’re a year behind schedule.

This weekend, I finished converting the KDE Subversion repository into Git. The process created no less than 493 different repositories: I decided that each application in extragear, kdereview, kdesupport or playground should get its own repository. There will be more when I run it again.

The process isn’t correct yet. There are definite import errors found: for instance, Thomas Zander inspected the the KOffice repository and realised that several branches were missing. What’s more, I still have a few ideas to do copy-with-history, which means preserving correctly the moves in SVN. Many of our projects originated in the old kdenonbeta, which I didn’t import.

I am forced to realise that Git isn’t completely ready for us yet. I’ve been using Git for well over a year now and I can see it improving build after build. 1.6.0 is very nice, but not there yet. So I ask the Git developer community: how do we handle 493 separate but related repositories? Mind you, we want to maintain the ability to build them all with very simple commands.

So, while Git is by no means decided for KDE — well advanced, I’d say — it is decided for Qt. We have kickstarted the process to completely switch to Git. Very soon now, we’ll be in the final leg of that process and will hopefully have some news on it. Our goal is to stop using Perforce for Qt 4.5 by October 1st.

Thiago Macieira
Qt
KDE
Posted by Thiago Macieira
 in Qt, KDE
 on Friday, August 29, 2008 @ 20:51

You know that with the Title I chose for this blog, I could be talking about Qt or about KDE. It’s ambiguous… :-)

Yesterday, the dot had an article about a new development process for KDE that requires the use of a Decentralised Version Control System (DVCS for short). Believe me if you will, I had nothing to do with that article: I had not talked to Jos before he published it and I even admit to not attending the talks at Akademy on the subject.

But it was a pleasant surprise to read it.

Resistance to change

I’ve been discussing the switch to a different VCS for KDE and for Qt for over a year now. I’ve met a lot of resistance and the article on the dot was no different. There’s a lot of people who oppose the idea.

There’s always resistance to change. People don’t do it out of malice. Quite to the contrary, they do it because resistance to change is a natural reaction. It’s a way of your body and your mind letting you know you’re exiting your comfort zone. And that’s a natural human reaction. Brides and grooms having cold feet the morning of their wedding wouldn’t be a cliché otherwise: they’re about to make a life-changing decision.

Really, look back to all your life-changing decisions and events in your life (gradual changes don’t count). How many of those did you jump into with two feet ahead? Not many, you’ll agree. Marrying, getting a new job, moving to another city or country, for example, are all life-changing decisions. Incidentally, I’ve moved between countries 4 times already and only one of them (the last one) was with two feet ahead: it was when I decided to come back to Trolltech in Norway.

So the resistance we’re seeing now in the KDE community and inside the Trolltech (a.k.a. Qt Software in Nokia) developer community is natural. Some of the criticism is based on technical issues that have to be addressed, most is only fear that has to be managed.

In fact, there’s a whole profession on that, which is called Change Management.

New workflow

The article on the dot discussed the development process where “It’s always Summer in trunk”. I don’t know who coined that expression, but it’s a nice one. I think it appeared in the KDE circle in a blog by Sebastian Kügler: he asked the question “What if we never froze trunk?”

I was part of the discussions that led to that question, when we were discussing where Phonon would live. With my Qt hat on, I was asking for anywhere where “there’s no freeze when TT developers are working on development.

In his blog and in the article, Sebas and others are advocating this idea. It’s something we already do for Qt’s development: the mainline of development never freezes. The feature freezes are preceded by a branching. In KDE terms, it would be equivalent of branches/KDE/4.1 branching off trunk/KDE just before the feature freeze.

That’s fine by itself, but you need the proper tools to pull it off. Remember that you’re going to work extensively with two branches. To give you an idea of the work involved, from the moment that Qt 4.4 branched off the mainline until today, there were 7744 commits into the Qt 4.4 branch (2771 of which after 4.4.0) and 9768 in the mainline (that includes the 4.4 ones). Whereas in KDELibs, there were 3783 commits to trunk since the 4.0 branch, but only 590 into the 4.0 branch since the same point. That’s approximately the same time period.

But the workflow goes beyond “It’s always Summer in trunk” (we’re already there with Qt and I said this blog is both about KDE and Qt). It’s about doing most of the development — which is where most of regressions occur, potentially — in separate branches. More than that, it’s about maintaining an ultra-stable branch somewhere.

If development is where “hot” is, then I’d say that actually “It’s always Spring in trunk”. We don’t want trunk to overheat — even economists say overheated economies are bad (cf. China). We want it to be a self-sustaining exothermic process. Like Spring, there should be periods where it cools down a bit more, there should be periods where it’s warmer than usual.

(I could also have chosen Autumn, but I thought Spring made my analogy look nicer)

Finally, we want developers to feel like experimenting without fear of breaking stuff. We want developers to freely collaborate with each other. And we want new developers to feel readily welcome, not second-class citizens. Granted, obtaining a KDE SVN account is rather easy, compared to many projects out there. But I’ve heard from many new Qt employees who felt like their first commits were very daunting. It was my case too.

Kent
Qt
QSA
Posted by Kent
 in Qt, QSA
 on Friday, August 29, 2008 @ 14:04

Been having some fun this week trying to add support for data bindings to Qt Script, and now I have something that seems to work. This code shows the basic usage:

QScriptEngine engine;
QPushButton button;
QScriptValue scriptButton = engine.newQObject(&button);
engine.evaluate("x = 'foo'");
scriptButton.setProperty("text", "x", QScriptValue::DataBinding);

This will cause the button’s text property to be updated whenever the script variable x changes, either from C++ (QScriptValue::setProperty()) or from
script. QObject properties can be part of the binding expression as well, as long as the NOTIFY attribute is specified in the Q_PROPERTY definition. Qt Script will discover that the property has a signal associated with it and use it to track changes. Qt’s classes already use NOTIFY for some properties (e.g. QLabel::text).

Below is a small example. The text property of a label is bound to the text property of a lineedit and the script variable verb; the final value is made by concatenating the lineedit’s text, the verb and a string literal.

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QWidget win;
    QVBoxLayout *vbox = new QVBoxLayout(&win);
    QLineEdit *lineEdit = new QLineEdit();
    QLabel *label = new QLabel();
    label->setStyleSheet("font-size: 24px");
    vbox->addWidget(lineEdit);
    vbox->addWidget(label);

    QScriptEngine engine;
    QScriptEngineDebugger debugger;
    debugger.attachTo(&engine);
    vbox->addWidget(debugger.widget(QScriptEngineDebugger::ConsoleWidget));

    QScriptValue scriptLineEdit = engine.newQObject(lineEdit);
    engine.globalObject().setProperty("lineEdit", scriptLineEdit);
    QScriptValue scriptLabel = engine.newQObject(label);
    engine.globalObject().setProperty("label", scriptLabel);

    engine.evaluate("verb = 'smack'");
    scriptLabel.setProperty("text", "lineEdit.text + ' ' + verb + 's you!'", QScriptValue::DataBinding);

    win.show();

    return app.exec();
}

The result, after typing something into the lineedit and assigning something to verb:

Qt Script data binding example

I’ve also added an extension to QScriptClass that enables you to send property change notifications for custom (non-QObject-based) script objects, i.e. you can use your own notify mechanism.

As I said, this isn’t in Qt yet, it’s just an experiment, but it’s looking pretty interesting.

Andreas
Uncategorized
Posted by Andreas
 in Uncategorized
 on Friday, August 29, 2008 @ 10:19

Over the past few months, many of us trolls have had the pleasure of meeting groups of enthusiastic Nokians. Everybody is excited about Qt. It feels a bit overwhealming sometimes, different people have different expectations as to what a small group of people can do. Excitement, expectations, concerns. Enthusiasm! But the whole progress is easier when you get to meet peers that are, yeah, quite allright people. That’s what makes the whole job worth it for me. Set aside technical trouble and new procedures (which quite frankly aren’t as scary as I first thought!). Who’s doing what now and how will this work? Then someone comes over and shows you a layout they wrote. How they used scripting, widgets. Wrote plugins. Can you do this? Can you do that? Yeah, you know, you usually can.

So walking to work today, I found myself fumbling in my pocket, pulling out the Nokia-badge that we now all wear, and putting it on right when I went out of the subway station. It felt allright.

Thomas Zander
Qt
KDE
Graphics Dojo
Posted by Thomas Zander
 in Qt, KDE, Graphics Dojo
 on Thursday, August 28, 2008 @ 13:28

For the last 5 years a huge focus of my work has been on fonts and text. You know you went to far when you can tell the difference between a Helvetica and an Arial by just looking at the printed ‘a’.
Its unsurprising that people end up asking me what the difference is between leading and linespacing, why the customer claims we don’t do kerning for that specific font, why WYSIWYG actually fails for most people. I naturally can’t be because I’m the only one stupid enough to claim to know this, right?
I considered claiming ignorance, but then my weird behavior may no longer have any reason, so that would just make me a worse freak. Instead I just wrote an application that shows everyone how text works. And I’ll write a blog or two about what you can see on screen and how that relates to your questions even before you have them. Genius or what?
So, here is an example text;
fontanatomy1.png
let me quickly go over the different parts. In red we have the outline, this is the total amount of space that the text takes. This is what is reserved in your user interface for the text. The sizes you see on the right hand side are the major anatomical dividers of a font face. Much like your body has a head and legs (I’m making assumptions about that, work with me). The baseline is the only one that is really interesting to point out. it’s the zero-point for a font. All measurements start from there. So you have a part that’s above and a part that’s below the baseline. I’ll leave it to your imagination to mirror that to your own anatomy.
In blue we have the size taken by the individual characters. But when we are talking about fonts we actually should be talking about glyphs. There are subtle differences, but I won’t bore you with that. Each glyph has its own rectangle as you can see in the blue. This is useful to see since the m is wider than the j, which is useful to know since you position the characters next to each other. The blue little gradients are helpers (called bearings) to position the glyphs better so they visually look more pleasing.

Ok, with the basics behind you here are a bit more interesting things; consider the two following screenshots.
fontanatomy2.pngfontanatomy3.png

The only difference is that kerning is turned on for the first and turned off for the second. Notice how the blue boxes overlap in the first image and how they are simply placed side by side in the second.
In general you want kerning to be turned on, its on by default in Qt because it increases readability.

Last example; this one is tricky.
fontanatomy4.pngfontanatomy5.png
Fonts are designed in a way that they can be scaled and reused for any size. Which is a pretty neat idea since it avoids using a crystal ball to figure out which sizes to ship your font in. There is a little problem, though. A font that is printed on paper at 10cm per character needs a lot of detail but if you use the same character at on screen at just a couple of millimeters height, you have problems to make that one look good.
So, font makers ship something called ‘hints’. Which make their fonts look better at smaller sizes then the computer could do automatically. This is enabled per default and is practically speaking exactly what you want.
Except for one problem; if you add all those little adjustments they can add up. So much that if you have a sentence you can have a word that fits just fine when you show the font on screen, but if you then take the same width and same text but on paper, those little adjustments may just move a word to the next line.
In other words; hinting gets in the way of what you see is what you get text-layout. So, in Qt you can turn this off. Allowing you to get the exact same line-breakings on screen as you get on paper.
Look at the following two screenshots. You will see a little spacing between the little blue squares in the one where the hinting is turned off. We call this mode ‘designer metrics’.
if you want to play around with this stuff yourself, here you can find the sources;

svn checkout svn://labs.trolltech.com/svn/graphics/fontAnatomy

For the people that are still here, thanks for sharing the pain! And I’ll answer the question of “why should I care!”. The concepts shown in this blog have good support in Qt4. The point to take home is that the font is the one that specifies all the information. If the font doesn’t have kerning, game over. If the font has horrible sizing information, you are out of luck. With this little tool at least you can see the differences that different fonts make.

Jörg
Labs
WebKit
Posted by Jörg
 in Labs, WebKit
 on Wednesday, August 27, 2008 @ 12:35

I want to introduce a feature that we’ve been asked for over and over: QtWebKit on Windows CE. Its still in the works but already in a quite usable state. Eventually its possible to create your own applications with web browsing capabilities on your favourite Windows CE device!

To give QtWebKit for Windows CE a whirl, you can fetch the current source from the QtWebKit git repository. So make sure that you have the following software installed:

  • Qt for Windows CE
  • Git for getting the source
  • Perl for calling the build script

First of all, download the source code:

git clone git://code.staikos.net/webkit
git checkout -b wince origin/joerg/wince-master

You now should have a local branch called wince, which is based on the remote Windows CE branch. Then you must set up your environment to build Qt for Windows CE applications.
This could look like this:

call vsvars32
set QTDIR=c:\Qt\4.4.1
set PATH=%QTDIR%\bin;%PATH%
setcepaths wince-mymakespec

Go into your WebKit directory and call the build script:

perl WebKitTools\Scripts\build-webkit

If everything goes well, you will find in WebKitBuild\Release\bin a QtWebKit4.dll and QtLauncher.exe. Deploy these files to your device (with the Qt binaries including network and image plugins), run it and browse the web!

For Windows CE 5 I strongly recommend to build a smaller Qt version, tailored to your needs. Remember that you only have 32 MB memory per process which is pretty soon filled if you’re displaying web sites with many images or animations.

Try it, have fun and use the mailing list qt-wince-interest@trolltech.com if you have questions or comments.

Kent
Qt
QSA
Posted by Kent
 in Qt, QSA
 on Monday, August 25, 2008 @ 14:45

At Akademy (which was a great event by the way!) I had an interesting talk with Pino (the man with Okular vision 8-) ) about an almost equally interesting feature of the Adobe Acrobat JavaScript API. Quoting the reference:

Many of the JavaScript methods provided by Acrobat accept either a list of arguments, as is customary in JavaScript, or a single object argument with properties that contain the arguments. For example, these two calls are equivalent:

app.alert("Acrobat Multimedia", 3);

app.alert( { cMsg: "Acrobat Multimedia", nIcon: 3 } );

The second form uses JavaScript’s object literal syntax to provide arguments in a declarative style, which can make for more readable code, and relieves the script author of having to worry about the order of arguments. However, it does present a new challenge to the implementer of the API: Does he have to implement every function twice now, once per argument-passing style?

Short answer: No (and that’s the honest truth). Long answer: Read on.

What we’ll do is wrap a proxy function around the function that implements the API; the job of the proxy is to detect which particular argument-passing style is used in an invocation, and call the real function using a single argument-passing style regardless (i.e. convert the object literal to a list or vice versa). Essentially we are building our own little type system on top of barebones JS. Sure, this means that some additional glue code has to be written for initializing the JS bindings, and there will be a slight overhead involved with calling a public API function, but I believe in most cases that’s a small price to pay, considering the alternative. The solution presented works on a per-function basis anyway, so you don’t have to use it for everything.

I’ve written a small JavaScript function, called argumentative(), that does the work; you can download it here. To use it, you first prepare your own “private” implementations of the API in whatever call-style you wish, for example list-style:

function __alert(msg, icon, type, title, doc, checkbox)
{
    // For now we just dump the arguments, a real implementation
    // would display a message box.
    print("msg:", msg, "icon:", icon, "type:", type);
    print("title:", title, "doc:", doc, "checkbox:", checkbox);
}

Then you call argumentative(), passing it your function, and an array of argument descriptors. argumentative() will return a proxy function, which is the function you actually want to expose to script authors (i.e. your public API).

alert = argumentative(__alert,
    [ { name: 'cMsg', type: String },
      { name: 'nIcon', type: Number, defaultValue: 0 },
      { name: 'nType', type: Number, defaultValue: 0 },
      { name: 'cTitle', type: String, defaultValue: 'Adobe Acrobat' },
      { name: 'oDoc', type: Object, optional: true },
      { name: 'oCheckbox', type: Object, optional: true,
        properties: [ { name: 'cMsg', type: String, defaultValue: 'Do not show this message again' },
                          { name: 'bInitialValue', type: Boolean, defaultValue: false } ]
      }
    ]);

The purpose of the name property of an argument descriptor should be obvious. The type property is optional; if it is specified, the proxy function will check that the actual argument is of the specified type before invoking your function; this means you can potentially get rid of a lot of type checks in your own code. (The type-checking approach is inspired by John Resig’s strict() function, found in his book “Pro JavaScript Techniques”.) The defaultValue property is optional; if it is specified, its value will be used if the argument is missing in a call. Descriptors for object-based types can additionally specify a properties property, which is just another array of argument descriptors; the proxy function will recursively validate the properties of the object, and substitute in default values if appropriate, before calling your function.

Anyway, now the script author can either do:

alert("my message", 1, 2, "my title", null, { cMsg: "check", bInitialValue: false } );

or

alert( { cMsg: "my message", nIcon: 1, nType: 2, cTitle: "my title",
          oDoc: null, oCheckbox: { cMsg: "check", bInitialValue: false } } );

To your implementation, the two calls will appear identical. (By the way, the argumentative() function lets you control which style you want to receive the arguments in; if you pass 1 as the third argument, your function will receive arguments single-argument-object style, instead of as a list.) If the script author does this:

alert();
alert( { } );

in both cases he will get an error saying that the cMsg argument is missing, as expected. Similarly, if he does this:

alert( { cMsg: "my message", oCheckbox: { cMsg: "check", bInitialValue: "ciao" } } );

he will get an error saying that the argument oCheckbox.bInitialValue has the wrong type.

In the case of the Adobe JS bindings, the argumentative() function could also easily be augmented to support the special acrohelp argument (in which case the function should return a list of its own arguments, rather than call the real function); the function proxy already has all the information it needs.

OK, now for the Qt Script-related part (I almost forgot this is a Qt blog). Most, if not all, JS API functions like those for Acrobat (including alert()) have to be implemented as native functions. So how can you take advantage of the argumentative() functionality in this case? It’s actually pretty simple, as demonstrated by the following C++ snippet:

QScriptEngine engine;
/* evaluate argumentative.js
 ... ... */

QScriptValue descriptors = engine.evaluate(/* the same array of descriptors defined in an earlier snippet */);
QScriptValue fun = engine.newFunction(alert); // alert is a function pointer
QScriptValue proxy = eng.evaluate("argumentative")
                    .call(QScriptValue(), QScriptValueList() << fun << descriptors);
engine.globalObject().setProperty("alert", proxy); // install the public API function

The full example can be downloaded here; it’s a partial implemention of the alert() function using a proper Qt message box, and shows that the native function works the same regardless of which argument-passing style the script uses.

lorn
Qt
Qtopia
KDE
Posted by lorn
 in Qt, Qtopia, KDE
 on Saturday, August 23, 2008 @ 03:12

I love Qt, which is one reason I work for Trolltech^WQtsoftware in Nokia. and thanks to the efforts of the qt4 on maemo project Maemo Qt4, there is yet another platform/device open to any application that is created with Qt4.

gutenbrowser on maemo

Here is my old-yet-updated Gutenbrowser project on Maemo on n810. (the copyright on gutenbrowser is 1998-2008! now). I don’t work on it as much as it needs. Especially now with rug rats and yard apes about.

All it took was a recompile!

Just install the scratchbox sdk for maemo. Grab the qt4 for Maemo sources, compile, install them, and your good to go! hmmm… what’s next?

Thiago Macieira
KDE
Rants
Posted by Thiago Macieira
 in KDE, Rants
 on Friday, August 22, 2008 @ 10:41

Disclaimer: this is a rant. I have been trying for the past few days to make desktop effects work and not use 90% of my CPU. I am frustrated, so this blog will step on people’s toes. Maybe you shouldn’t read it.

I remember when I was using KDE 3 and I enabled the desktop effects. The only objective of that was to have semi-transparent windows: I had just got a collection of nice wallpaper pictures, but what’s the use if you never see the desktop? So I turned the feature on, and it worked — more or less. There was a nice feature which you could set the transparency level differently for active and inactive windows, but once you clicked the Windows Operations menu (Alt+F3, the application icon in the top-left corner), the transparency level would become stuck for that window. To make matters worse, there was this one application that, if moved, would become 100% transparent. I had to be careful to change the level just after starting it, before doing anything in it.

But that wasn’t too big a deal. After all, kwin in KDE 3 was never meant to have those effects. They were hackish.

Come KDE 4… I decided to continue using the desktop effects. After all, now kwin was meant to have those effects. The drawback was that kwin constantly used 40-90% CPU time, while doing absolutely nothing. I mean, the computer was idle, no windows had any activity, but it still would use CPU. Konsole takes 20 seconds to redraw if you try to resize the window. And to make matters worse, I can’t use my wallpaper collection, because the slideshow mode always expands the pictures without considering the aspect ratio.

Someone in the office told me that XRender worked just as well, but without the CPU overhead. I have no idea why, but I just can’t set that mode. Trying to change from OpenGL to XRender makes the entire desktop freeze: the helpful “you’ve changed configurations, do you want to keep them” dialog with a 15-second automatic cancellation doesn’t even appear. But it does cancel, so it goes back to OpenGL. Trying to enable desktop effects with XRender gives me a message that it didn’t work and the old configuration was restored.

I tried to debug kwin. Only to find out that you shouldn’t do it from inside the X session. Everything freezes just after you press Enter on the “attach” line on gdb. So I switched to a virtual console, managed to attach to kwin, but the backtrace was useless due to glib appearing in the middle. Debugging the timers with glib is too difficult — the Qt default event dispatcher is easier.

So I restart kwin without glib (QT_NO_GLIB=1 kwin –replace). Only to find out that that doesn’t work. It took me a few tries doing that and doing killall kwin to get a new kwin running. And to my surprise, I couldn’t find anything wrong with kwin under those conditions. Thinking I had done something wrong, I restarted KDE with glib turned off. And my suspicion was confirmed: turning glib off makes kwin use acceptable 1% CPU.

Performance was still bad, though. I mean, what’s the point of having windows flying by when you switch desktops if all you get is two frames?

On Wednesday, Sebas blogged about NVidia releasing a new driver that fixed most of the performance issues. So I decided I would try, and I’d also try the many settings that presumably make performance better. So I downloaded version 177.67, built and installed; changed my xorg.conf to add the options that Sebas recommended; and restarted X. And for a while it appeared to be working correctly.

Until some Konsole windows started disappearing. No, wait, they weren’t crashing or off-screen: they were just invisible. Yes, 100% transparent. I could even interact with them, but I couldn’t see what was wrong. So… undo some of the modifications to xorg.conf and restart X.

Problem not gone. And to make it worse, some other windows started appearing black. Including the window decoration (borders, title bar, buttons). I assume it’s the same problem affecting konsole, with the difference that konsole uses windows with alpha channels, thus making it go invisible instead of black. The interesting thing is that, when moving windows (I had an effect on to make them more transparent), the black window became slightly transparent! I managed to get most of the windows appearing when I minimise then restore the window. Not all, though (including one program I need for work).

So I try fiddle with my settings. I ran nvidia-settings to find out if I were using the correct driver. And to my surprise after starting that program, all windows stopped updating! Actually, they were updating, but I wasn’t seeing them. If I clicked on another window, the window that had just become deactivated would update. So, yeah, I found a new interesting effect: freeze until focus lost.

Turning desktop effects off and back on helped. I had to do it twice because the second screen on my Twin View setup doesn’t enable the effects on the first try.

Come today: I’m told that NVidia released a new version, 177.68, which fixes some bugs. So I go and upgrade the driver. And indeed things feel snappier. I can see the effects as they are meant to look like. However, the black windows don’t go away.

I tried using nvidia-settings again. And a similar problem as yesterday started appearing. Only even worse than “redraw when focus lost”. I could see the screen repainting from top to bottom, scan line by scan line. It took about 5 seconds (1680×1050). I don’t think I’ve seen that happen since CGA was the norm!

Turning effects off and then back on (twice) fixed that problem.

But the black windows are still appearing. To almost all programs (konqueror, vmware-server-console, hooligan, etc.). Apparently Emacs isn’t affected.

So my solution? Turn effects off. I need to work. I can’t fight my system. After all, the whole point of the effects is to improve my user experience, not to make it worse. And I can’t use wallpapers anyways…

And if that weren’t enough, one or several kio_imap4 became runaway, printing a debug message from KIO::SlaveBase::waitForAnswer in an infinite loop. That exhausted my disk space in my /home filesystem, thereby making Kontact crash and lose all of its settings. I’m still synchronising my IMAP folders as I write this…

At least one good thing came out of this ordeal: I found out why kwin consumes so much CPU. If you’re affected by this problem, turn glib support off in Qt. (export QT_NO_GLIB=1 before KDE is started, or compile Qt with the -no-glib option)

By the way, Konsole still lags in drawing, even with desktop effects turned off. That means it’s not caused by the desktop effects.

Comments Off
harald
Qt
KDE
Accessibility
Posted by harald
 in Qt, KDE, Accessibility
 on Wednesday, August 13, 2008 @ 15:36

To summarize my achievement at Akademy:

[Argument: a{sv} {"a" = [Variant(int): 1], "b" = [Variant(QByteArray): {99}], "c" = [Variant(QString): "b"], "d" = [Variant(uint): 42], "date" = [Variant: [Argument: (iii) 1977, 1, 1]], "datetime" = [Variant: [Argument: ((iii)(iiii)i) [Argument: (iii) 0, 0, 0],[Argument: (iiii) 8, 59, 31, 0], 0]], "dtlist" = [Variant: [Argument: a((iii)(iiii)i) {[Argument: ((iii)(iiii)i) [Argument: (iii) 0, 0, 0], [Argument: (iiii) -1, -1, -1, -1], 0], [Argument: ((iii)(iiii)i) [Argument: (iii) 1977, 9, 13], [Argument: (iiii) 0, 0, 0, 0], 0], [Argument: ((iii)(iiii)i) [Argument: (iii) 2006, 6, 18], [Argument: (iiii) 13, 14, 0, 0], 0]}]], "e" = [Variant(short): -47], "f" = [Variant: [Variant(int): 0]], "ismap" = [Variant: [Argument: a{is} {-47 = "c", 1 = "a", 2000 = "b"}]], "lldtmap" = [Variant: [Argument: a{x((iii)(iiii)i)} {0 = [Argument: ((iii)(iiii)i) [Argument: (iii) 0, 0, 0], [Argument: (iiii) -1, -1, -1, -1], 0], 1 = [Argument: ((iii)(iiii)i)[Argument: (iii) 1970, 1, 1], [Argument: (iiii) 0, 0, 1, 0], 1], 1150629776 = [Argument: ((iii)(iiii)i) [Argument: (iii) 2006, 6, 18], [Argument: (iiii) 11, 22, 56, 0], 1]}]], "pointf" = [Variant: [Argument: (dd) 0.5, -0.5]], "ssmap" = [Variant: [Argument: a{ss} {"a" = "a", "b" = "c", "c" = "b"}]], "time" = [Variant: [Argument: (iiii) 8, 58, 0, 0]]}]

Looks scary? It’s supposed to. D-Bus supports recursive complex types like structures, maps or variants, and until now, neither the Qt D-Bus viewer (part of Qt’s demos) nor the qdbus command line client were able to dump the contents of complex arguments. So, one day of hacking later, and thanks to a small API addition from Mr. QtDBus Thiago, we can now show pretty much everything that comes through the bus. The above example shows the output of one of our D-Bus tests - you can find complex structures inside variants and complex structs inside maps, and everything is nicely dumped.

But don’t worry - not many interfaces use deep nesting. Why we started to write the code in the first place is to display rectangles (4 integers in a D-Bus structure) from Qt’s D-Bus accessibility, Decibel’s properties (a D-Bus map structure) or some of the more complex calls of Telepathy.

The code will be available in Qt 4.5’s snapshots, happy introspecting!

P.S.: Many, many thanks to the organizers of this year’s Akademy. As always, it’s a great pleasure to be here.



© 2008 Nokia Corporation and/or its subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation in Finland and/or other countries worldwide.
All other trademarks are property of their respective owners.