diff options
author | Neil <nyamatongwe@gmail.com> | 2016-02-23 11:17:05 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2016-02-23 11:17:05 +1100 |
commit | e5a27cf16a0144a534ff07905380af5eedbbb76b (patch) | |
tree | e69c721389467400ac1b88d86d67426b82342114 | |
parent | fe0d39ee1c34dfeada9909af44646ce43f0ef226 (diff) | |
download | scintilla-mirror-e5a27cf16a0144a534ff07905380af5eedbbb76b.tar.gz |
Retry OpenClipboard if it fails as another application may have opened it.
-rw-r--r-- | doc/ScintillaHistory.html | 4 | ||||
-rw-r--r-- | test/simpleTests.py | 7 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 21 |
3 files changed, 27 insertions, 5 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 6bdcb1e5d..1c5f2f356 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -538,6 +538,10 @@ <li> IME target range displayed on Qt for OS X. </li> + <li> + On Windows, make clipboard operations more robust by retrying OpenClipboard if it fails + as this may occur when another application has opened the clipboard. + </li> </ul> <h3> <a href="http://www.scintilla.org/scite363.zip">Release 3.6.3</a> diff --git a/test/simpleTests.py b/test/simpleTests.py index c7240b269..62243dd49 100644 --- a/test/simpleTests.py +++ b/test/simpleTests.py @@ -493,13 +493,15 @@ class TestSimple(unittest.TestCase): self.ed.AddText(5, b"a1b2c") self.ed.SetSel(1,3) self.ed.Cut() - self.xite.DoEvents() + # Clipboard = "1b" + self.assertEquals(self.ed.Contents(), b"a2c") self.assertEquals(self.ed.CanPaste(), 1) self.ed.SetSel(0, 0) self.ed.Paste() self.assertEquals(self.ed.Contents(), b"1ba2c") self.ed.SetSel(4,5) self.ed.Copy() + # Clipboard = "c" self.ed.SetSel(1,3) self.ed.Paste() self.assertEquals(self.ed.Contents(), b"1c2c") @@ -508,13 +510,12 @@ class TestSimple(unittest.TestCase): self.assertEquals(self.ed.Contents(), b"1c") def testCopyAllowLine(self): - self.xite.DoEvents() lineEndType = self.ed.EOLMode self.ed.EOLMode = self.ed.SC_EOL_LF self.ed.AddText(5, b"a1\nb2") self.ed.SetSel(1,1) self.ed.CopyAllowLine() - self.xite.DoEvents() + # Clipboard = "a1\n" self.assertEquals(self.ed.CanPaste(), 1) self.ed.SetSel(0, 0) self.ed.Paste() diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index c9a712df2..2e9cce34a 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -2184,9 +2184,25 @@ public: } }; +// OpenClipboard may fail if another application has opened the clipboard. +// 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). +static bool OpenClipboardRetry(HWND hwnd) { + for (int attempt=0; attempt<8; attempt++) { + if (attempt > 0) { + ::Sleep(1 << (attempt-1)); + } + if (::OpenClipboard(hwnd)) { + return true; + } + } + return false; +} + void ScintillaWin::Paste() { - if (!::OpenClipboard(MainHWND())) + if (!::OpenClipboardRetry(MainHWND())) { return; + } UndoGroup ug(pdoc); const bool isLine = SelectionEmpty() && (::IsClipboardFormatAvailable(cfLineSelect) || ::IsClipboardFormatAvailable(cfVSLineTag)); @@ -2737,8 +2753,9 @@ void ScintillaWin::GetIntelliMouseParameters() { } void ScintillaWin::CopyToClipboard(const SelectionText &selectedText) { - if (!::OpenClipboard(MainHWND())) + if (!::OpenClipboardRetry(MainHWND())) { return; + } ::EmptyClipboard(); GlobalMemory uniText; |