aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJason Hallam <devnull@localhost>2016-02-24 10:47:02 +1100
committerJason Hallam <devnull@localhost>2016-02-24 10:47:02 +1100
commit3163777c1d30783a35b73b3e79cf39179d21feee (patch)
tree995ceaecb72750e636529946b26a78b0ec4736b9
parente5a27cf16a0144a534ff07905380af5eedbbb76b (diff)
downloadscintilla-mirror-3163777c1d30783a35b73b3e79cf39179d21feee.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()