Clipboard: Retry on_dataChanged() after a delay on windows (#10109)

An undocumented behaviour of QClipboard::mimeData() is that it can fail on
windows due to the specificities of the windows API that allow a race condition.
In particular it seems that querying the clipboard as soon as the dataChanged()
signal is received favourises this race condition.

Thanks to Trac user bquistorff for the explanation and a proof of concept patch.
This commit is contained in:
Guillaume Munch 2016-04-29 21:51:39 +01:00
parent 8fd223146b
commit 660a43ecf4
2 changed files with 13 additions and 1 deletions

View File

@ -112,7 +112,7 @@ GuiClipboard::GuiClipboard()
connect(qApp->clipboard(), SIGNAL(dataChanged()), connect(qApp->clipboard(), SIGNAL(dataChanged()),
this, SLOT(on_dataChanged())); this, SLOT(on_dataChanged()));
// initialize clipboard status. // initialize clipboard status.
on_dataChanged(); update();
} }
@ -550,6 +550,17 @@ bool GuiClipboard::hasInternal() const
void GuiClipboard::on_dataChanged() void GuiClipboard::on_dataChanged()
{
update();
#if defined(Q_OS_WIN) || defined(Q_CYGWIN_WIN)
// Retry on Windows (#10109)
if (cache_.formats().count() == 0) {
QTimer::singleShot(100, this, SLOT(update()));
}
#endif
}
void GuiClipboard::update()
{ {
//Note: we do not really need to run cache_.update() unless the //Note: we do not really need to run cache_.update() unless the
//data has been changed *and* the GuiClipboard has been queried. //data has been changed *and* the GuiClipboard has been queried.

View File

@ -84,6 +84,7 @@ public:
private Q_SLOTS: private Q_SLOTS:
void on_dataChanged(); void on_dataChanged();
void update();
private: private:
bool plaintext_clipboard_empty_; bool plaintext_clipboard_empty_;