We use IRC extensively to communicate amongst ourselves as well as with the community. I hang out on the #qt channel on the Freenode network and help people with questions when I can. A common question that I see (and that makes me cringe at the same time) has to do with understanding threading with Qt and how to make some code they’ve written work. People show their code, or examples based on their code, and I often end up thinking:
You’re doing it wrong
Read the rest of this entry »
(pun intended)
So, it’s been a while since my original blog on multi-touch support in Qt, so I thought I would provide an update on what’s been going on in that area.
Read the rest of this entry »
A few weeks ago, Denis blogged about some thoughts he had on how gesture recognition could work in Qt. One of the things he mentioned, and that was also brought up in the comments, was support for multi-touch gestures. As a MacBook Pro owner, I already use multi-touch gestures every single day. Needless to say, he got my attention. I would certainly like to see multi-touch events and gestures in Qt so that I can start using them myself. The only question is… how do we do it?
Read the rest of this entry »
For the past 2 weeks, I’ve been wrestling with a fix for task 208487. At first glance, it seems pretty far-fetched (at least it did to me): an application that has 2 billion running timers and runs out of timer ids. But then I went and looked at the code (that I wrote!) and the real problem slapped me in the face: any application can only ever start 2 billion timers in total (which is different from having 2 billion concurrent timers). We never recycle timer ids. That means that the following code will quit working after 24.85 days. If we change the timeout to be zero instead, the runtime is reduced to hours instead of days.
class Object : public QObject
{
Q_OBJECT
public:
Object() : QObject() { QTimer::singleShot(1, this, SLOT(timeout())); }
public slots:
void timeout() { QTimer::singleShot(1, this, SLOT(timeout())); }
};
After quickly rejecting the question “Should I fix this?” (of course I should!), I promptly got my hands dirty looking for a solution. Fixing this proved to be harder than I originally anticipated…
Read the rest of this entry »
The news about Nokia’s intentions to acquire Trolltech is very exciting and sobering at the same time. I would characterize my own opinions and thoughts as “cautiously optimistic.” As Trolls, we are still digesting the idea, discussing it amongst ourselves, and processing the incoming information from our own management team as well as the information from Nokia.
I hope that our community, both commercial and open-source alike, don’t get too distraught about a seemingly quiet Trolltech team. We, like you, just found out about this yesterday morning and need time to absorb what this means for us, for you, for everyone. After everything sinks in, we will come out with more information in the near future, and we appreciate your patience until then.
Rest assured, Nokia has the best intentions in making this move. More information will be available soon., however the message from Nokia is clear: development, sales, open-source and community support, etc. will continue as usual. Lee Williams, Senior VP, R&D at Nokia, told us Monday that Nokia wants us to teach them how to do cross-platform and open-source development on the desktop (and not just on mobile phones). This is a bit of a special acquisition because both Trolltech, in its current organizational form, and Nokia will be working together on what the future will bring.
A couple of years ago (3, to be exact), my girlfriend and I bought a house about 45 minutes outside of Oslo. The little village is just far enough and small enough to not get cable TV. So, that means we have to have satellite. I consider myself a lucky geek, because my tuner runs Linux.
Read the rest of this entry »
I just integrated a series of changes that adds support for doing multi-threaded text layout and printing. So it is now safe to use QFont and QFontMetrics outside the GUI thread. This means QPainter::drawText() works too (when painting on QImage, QPrinter, and QPicture). We’ve also done changes to QTextDocument that allow it to be cloned and passed off to a thread, so that all the layouting and printing happens without blocking the GUI.
For those interested, you can checkout tonight’s 4.4 snapshot. In tools/assistant/mainwindow.cpp, you’ll see code like this:
void PrintThread::start(QTextDocument *document)
{
_document = document->clone();
_document->moveToThread(this);
QThread::start();
}
void PrintThread::run()
{
_document->print(printer());
delete _document;
_document = 0;
}
void MainWindow::on_actionFilePrint_triggered()
{
if (!QFontDatabase::supportsThreadedFontRendering()) {
QPrinter printer(QPrinter::HighResolution);
printer.setFullPage(true);
QPrintDialog dlg(&printer, this);
if (dlg.exec() == QDialog::Accepted) {
qApp->setOverrideCursor(Qt::WaitCursor);
tabs->currentBrowser()->document()->print(&printer);
qApp->restoreOverrideCursor();
}
return;
}
PrintThread *thread = new PrintThread(this);
QPrintDialog dlg(thread->printer(), this);
if (dlg.exec() == QDialog::Accepted) {
connect(thread, SIGNAL(finished()), SLOT(printingFinished()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
qApp->setOverrideCursor(Qt::BusyCursor);
thread->start(tabs->currentBrowser()->document());
} else {
delete thread;
}
}
void MainWindow::printingFinished()
{
qApp->restoreOverrideCursor();
}
The Thread Support in Qt documentation has also been updated to show what is supported (Note, at the time of writing, the snapshot documentation has not been updated, check back later if you don’t have a 4.4 snapshot after 27 Sep 2007).
And just to be clear, painting onto a QPixmap or a QWidget outside the GUI is not supported at all. We are looking at ways of making the GL paint engine safe for painting on to FrameBufferObjects and/or Pbuffers, which may or may not make it into 4.4.
Yesterday, I closed task 168853, the “provide a cross-platform atomic API” task. After several rounds of API review (and literally hundreds of completely Qt rebuilds on every test machine), I added QAtomicInt and QAtomicPointer to the 4.4 snapshots. These classes provide atomic operations for integers and pointers, respectively. At the moment, each class supports atomic test-and-set, fetch-and-store, and fetch-and-add. QAtomicInt also supports atomic reference counting with the ref() and deref() functions.
In addition to the actual atomic API, QAtomicInt and QAtomicPointer also provide an API to check whether the hardware supports a particular operation natively, and if the implementation is wait-free. For example, there’s the monstrous Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NATIVELY_SUPPORTED and Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE macros for compile-time checking, and QAtomicInt::isReferenceCountingNative() and QAtomicInt::isReferenceCountingWaitFree() for run-time checking. Note that run-time checking is really only needed if Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE is defined. This gives us, for example, the possibility of building a generic ARM binary that runs on today’s Xscale processors (ARMv5) or an ARMv6 processor (which adds load-linked/store-conditional instructions to support multi-processor/multi-core devices).
So, go get the 4.4 snapshot and give it try. Any and all feedback is welcome 
In a previous blog, I talked about wanting to make QThread::run() call QThread::exec() by default.
I didn’t manage to get it in for 4.3, but I did make the change today for 4.4. Testing with every compiler I could get my hands on indicates that it’s a binary compatible change, so unless proven otherwise, this will go into the 4.4 release (and no, I don’t know when 4.4 be released :D).
This change makes the original example in the previous blog as straight forward as I can get it. Have a look for yourself and see what you think…
A couple of weeks ago, I started trying to find out if a pure virtual function can be made impure without breaking binary compatibility. “Why?” you ask? Because I want to make QThread::run() call QThread::exec() by default. We all know that threading is difficult to do, mostly because of the need to lock data, synchronize threads (with a QWaitCondition or QSemaphore, for example). However, it doesn’t have to be.
Read the rest of this entry »