aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJason Hallam <unknown>2016-02-24 10:47:02 +1100
committerJason Hallam <unknown>2016-02-24 10:47:02 +1100
commitf1fb342721e222e7eae1f15f2b180b4ff070b9c0 (patch)
treefc3e05d9bfa936be338cc22caf654d330fcc58a0
parent92b6a5aa31c305a9ad5c7abb50d4384a5205336c (diff)
downloadscintilla-mirror-f1fb342721e222e7eae1f15f2b180b4ff070b9c0.tar.gz
Retry copying to clipboard if it fails as another application may have opened it
-rw-r--r--doc/ScintillaHistory.html2
-rw-r--r--qt/ScintillaEditBase/ScintillaQt.cpp38
2 files changed, 28 insertions, 12 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html
index 1c5f2f356..97c6d4f9f 100644
--- a/doc/ScintillaHistory.html
+++ b/doc/ScintillaHistory.html
@@ -539,7 +539,7 @@
IME target range displayed on Qt for OS X.
</li>
<li>
- On Windows, make clipboard operations more robust by retrying OpenClipboard if it fails
+ On Qt and Windows, make clipboard operations more robust by retrying if they fail
as this may occur when another application has opened the clipboard.
</li>
</ul>
diff --git a/qt/ScintillaEditBase/ScintillaQt.cpp b/qt/ScintillaEditBase/ScintillaQt.cpp
index 3b7db8002..e4bbb5c1d 100644
--- a/qt/ScintillaEditBase/ScintillaQt.cpp
+++ b/qt/ScintillaEditBase/ScintillaQt.cpp
@@ -25,6 +25,7 @@
#include <QScrollBar>
#include <QTimer>
#include <QTextCodec>
+#include <QThread>
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -306,21 +307,36 @@ void ScintillaQt::ReconfigureScrollBars()
}
}
+static bool clipboardAccessFailed;
+static void ClipboardMessageHandler(QtMsgType, const QMessageLogContext &, const QString &)
+{
+ clipboardAccessFailed = true;
+}
+
void ScintillaQt::CopyToModeClipboard(const SelectionText &selectedText, QClipboard::Mode clipboardMode_)
{
- QClipboard *clipboard = QApplication::clipboard();
- clipboard->clear(clipboardMode_);
- QString su = StringFromSelectedText(selectedText);
- QMimeData *mimeData = new QMimeData();
- mimeData->setText(su);
- if (selectedText.rectangular) {
- AddRectangularToMime(mimeData, su);
- }
+ // Try up to 8 times, with an initial delay of 1 ms and an exponential
+ // back off for a maximum total delay of 127 ms (1+2+4+8+16+32+64).
+ QString text = StringFromSelectedText(selectedText);
+ for (int attempt = 0; attempt < 8; attempt++) {
+ if (attempt > 0)
+ QThread::msleep(1 << (attempt-1));
+
+ QMimeData *mimeData = new QMimeData;
+ mimeData->setText(text);
+ if (selectedText.rectangular)
+ AddRectangularToMime(mimeData, text);
- // Allow client code to add additional data (e.g rich text).
- emit aboutToCopy(mimeData);
+ // Allow client code to add additional data (e.g rich text).
+ emit aboutToCopy(mimeData);
- clipboard->setMimeData(mimeData, clipboardMode_);
+ clipboardAccessFailed = false;
+ QtMessageHandler handler = qInstallMessageHandler(ClipboardMessageHandler);
+ QApplication::clipboard()->setMimeData(mimeData, clipboardMode_);
+ qInstallMessageHandler(handler);
+ if (!clipboardAccessFailed)
+ return;
+ }
}
void ScintillaQt::Copy()