summaryrefslogtreecommitdiff
path: root/vcl/qt5
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2020-03-25 18:33:29 +0100
committerJan-Marek Glogowski <glogow@fbihome.de>2020-03-25 22:15:50 +0100
commit313081c0703c66918e95640c74cd57312a1e8bba (patch)
treec98ab48b97989ef3c0dc7ff3f06e7c7b09c1e3ef /vcl/qt5
parent0069dbf431e2596ab2fc4e0759e5457187fb26dc (diff)
tdf#131533 Qt5 defer dropping clipboard ownership
This is maybe a Qt bug. Calling QClipboard::setMimeData from Qt5Clipboard::setContents after a previous call to QClipboard::clear results in a clipboard ownership failure. In a terminal you'll see: "QXcbClipboard::setMimeData: Cannot set X11 selection owner". Calling Application::Reschedule() after the clear() doesn't help. The result is a de-sync between the LO's clipboard state and the real clipboard state, which will lead to a crash on LO shutdown. I'm not sure this fix is correct. Maybe this could also be handled by some X11 flush operation. But it's the only working solution I could find: don't clear, if LO re-claims the ownership later. I tried to reproduce the ownership error by modifying the Qt fridgemagnets example, adding some QClipboard::clear and QClipboard::setMimeData calls to the drop handling, but couldn't reproduce. Maybe the dynamic Qt5MimeData object is also involved. Change-Id: I32b6575a78a4b10a2e2b7b189303ab3a40dc69ca Reviewed-on: https://gerrit.libreoffice.org/c/core/+/90990 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Diffstat (limited to 'vcl/qt5')
-rw-r--r--vcl/qt5/Qt5Clipboard.cxx23
1 files changed, 19 insertions, 4 deletions
diff --git a/vcl/qt5/Qt5Clipboard.cxx b/vcl/qt5/Qt5Clipboard.cxx
index cadedbfd327e..8720cfe44310 100644
--- a/vcl/qt5/Qt5Clipboard.cxx
+++ b/vcl/qt5/Qt5Clipboard.cxx
@@ -30,11 +30,16 @@ Qt5Clipboard::Qt5Clipboard(const OUString& aModeString, const QClipboard::Mode a
, m_aClipboardName(aModeString)
, m_aClipboardMode(aMode)
, m_bOwnClipboardChange(false)
+ , m_bDoClear(false)
{
assert(isSupported(m_aClipboardMode));
// DirectConnection guarantees the changed slot runs in the same thread as the QClipboard
connect(QApplication::clipboard(), &QClipboard::changed, this, &Qt5Clipboard::handleChanged,
Qt::DirectConnection);
+
+ // explicitly queue an event, so we can eventually ignore it
+ connect(this, &Qt5Clipboard::clearClipboard, this, &Qt5Clipboard::handleClearClipboard,
+ Qt::QueuedConnection);
}
css::uno::Reference<css::uno::XInterface> Qt5Clipboard::create(const OUString& aModeString)
@@ -98,6 +103,13 @@ css::uno::Reference<css::datatransfer::XTransferable> Qt5Clipboard::getContents(
return m_aContents;
}
+void Qt5Clipboard::handleClearClipboard()
+{
+ if (!m_bDoClear)
+ return;
+ QApplication::clipboard()->clear(m_aClipboardMode);
+}
+
void Qt5Clipboard::setContents(
const css::uno::Reference<css::datatransfer::XTransferable>& xTrans,
const css::uno::Reference<css::datatransfer::clipboard::XClipboardOwner>& xClipboardOwner)
@@ -110,15 +122,18 @@ void Qt5Clipboard::setContents(
m_aContents = xTrans;
m_aOwner = xClipboardOwner;
- m_bOwnClipboardChange = true;
- if (m_aContents.is())
+ m_bDoClear = !m_aContents.is();
+ if (!m_bDoClear)
+ {
+ m_bOwnClipboardChange = true;
QApplication::clipboard()->setMimeData(new Qt5MimeData(m_aContents), m_aClipboardMode);
+ m_bOwnClipboardChange = false;
+ }
else
{
assert(!m_aOwner.is());
- QApplication::clipboard()->clear(m_aClipboardMode);
+ Q_EMIT clearClipboard();
}
- m_bOwnClipboardChange = false;
aGuard.clear();