diff options
author | Jason Hallam <unknown> | 2016-02-24 10:47:02 +1100 |
---|---|---|
committer | Jason Hallam <unknown> | 2016-02-24 10:47:02 +1100 |
commit | f1fb342721e222e7eae1f15f2b180b4ff070b9c0 (patch) | |
tree | fc3e05d9bfa936be338cc22caf654d330fcc58a0 | |
parent | 92b6a5aa31c305a9ad5c7abb50d4384a5205336c (diff) | |
download | scintilla-mirror-f1fb342721e222e7eae1f15f2b180b4ff070b9c0.tar.gz |
Retry copying to clipboard if it fails as another application may have opened it
-rw-r--r-- | doc/ScintillaHistory.html | 2 | ||||
-rw-r--r-- | qt/ScintillaEditBase/ScintillaQt.cpp | 38 |
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() |