Copy to Clipboard in QT

The first time I tried to implement clipboard copy in QT all seemed easy. Just call setText on QClipboard object.

QClipboard* clipboard = QApplication::clipboard();
clipboard->setText(text);

Really simple and it doesn’t really work. Well, actually, it depends. If you run this under Windows, it works perfectly. If you run this under Linux, it works until you try to paste into Terminal window. Once you do, you will surprisingly see that clipboard used for Terminal isn’t the same clipboard as for the rest of system. But then you read documentation again and learn a bit about selection clipboard.

QClipboard* clipboard = QApplication::clipboard();

clipboard->setText(text, QClipboard::Clipboard);

if (clipboard->supportsSelection()) {
    clipboard->setText(text, QClipboard::Selection);
}

And now you have a fool-proof setup for both Linux and Windows, right? Well, you’ll notice that in Linux some copy operations are simply ignored. You believe you copied text but the old clipboard content gets pasted. So you copy again just to be sure and it works. Since failure is sporadic at best, you might even convince something is wrong with you keyboard.

However, the issue is actually in timing of clipboard requests. If your code proceeds immediately with other tasks Linux (actually it’s X11 problem but let’s blame Linux ;)) might not recognize the new clipboard content. What you need is a bare minimum pause to be sure system had chance to take control and store the new clipboard information.

QClipboard* clipboard = QApplication::clipboard();

clipboard->setText(text, QClipboard::Clipboard);

if (clipboard->supportsSelection()) {
    clipboard->setText(text, QClipboard::Selection);
}

#if defined(Q_OS_LINUX)
    QThread::msleep(1); //workaround for copied text not being available...
#endif

And now this code finally works for both Linux and Windows.