diff options
-rw-r--r-- | vcl/inc/qt5/QtTransferable.hxx | 18 | ||||
-rw-r--r-- | vcl/qt5/QtTransferable.cxx | 24 |
2 files changed, 27 insertions, 15 deletions
diff --git a/vcl/inc/qt5/QtTransferable.hxx b/vcl/inc/qt5/QtTransferable.hxx index 11d673b98a12..38cb4d92005b 100644 --- a/vcl/inc/qt5/QtTransferable.hxx +++ b/vcl/inc/qt5/QtTransferable.hxx @@ -36,6 +36,14 @@ class QtTransferable : public cppu::WeakImplHelper<css::datatransfer::XTransfera const QMimeData* m_pMimeData; bool m_bProvideUTF16FromOtherEncoding; +protected: + /** Sets new mime data. + * Since data flavors supported by this class depend on the mime data, + * results from previous calls to the public methods of this + * class are no longer valid after setting new mime data using this method. + */ + void setMimeData(const QMimeData* pMimeData) { m_pMimeData = pMimeData; } + public: QtTransferable(const QMimeData* pMimeData); const QMimeData* mimeData() const { return m_pMimeData; } @@ -52,17 +60,17 @@ public: * the QClipboard's object thread, which is the QApplication's thread, so all of * the access has to go through RunInMainThread(). * - * If we detect a QMimeData change, we simply drop reporting any content. In theory - * we can recover in the case where there hadn't been any calls of the XTransferable - * interface, but currently we don't. But we ensure to never report mixed content, - * so we'll just cease operation on QMimeData change. + * If we detect a QMimeData change, the mime data is updated with the new one from + * the system clipboard. Note however that this means that results of any previous + * calls of the XTransferable interface will be out of sync with the newly set mime + * data, so this scenario should generally be avoided. **/ class QtClipboardTransferable final : public QtTransferable { // to detect in-flight QMimeData changes const QClipboard::Mode m_aMode; - bool hasInFlightChanged() const; + void ensureConsistencyWithSystemClipboard(); public: explicit QtClipboardTransferable(const QClipboard::Mode aMode, const QMimeData* pMimeData); diff --git a/vcl/qt5/QtTransferable.cxx b/vcl/qt5/QtTransferable.cxx index 675e5ef75cdc..41c2c58392ef 100644 --- a/vcl/qt5/QtTransferable.cxx +++ b/vcl/qt5/QtTransferable.cxx @@ -164,11 +164,15 @@ QtClipboardTransferable::QtClipboardTransferable(const QClipboard::Mode aMode, { } -bool QtClipboardTransferable::hasInFlightChanged() const +void QtClipboardTransferable::ensureConsistencyWithSystemClipboard() { - const bool bChanged(mimeData() != QApplication::clipboard()->mimeData(m_aMode)); - SAL_WARN_IF(bChanged, "vcl.qt", "In flight clipboard change detected - broken clipboard read!"); - return bChanged; + const QMimeData* pCurrentClipboardData = QApplication::clipboard()->mimeData(m_aMode); + if (mimeData() != pCurrentClipboardData) + { + SAL_WARN("vcl.qt", "In flight clipboard change detected - updating mime data with current " + "clipboard contents."); + setMimeData(pCurrentClipboardData); + } } css::uno::Any SAL_CALL @@ -178,8 +182,8 @@ QtClipboardTransferable::getTransferData(const css::datatransfer::DataFlavor& rF auto* pSalInst(GetQtInstance()); SolarMutexGuard g; pSalInst->RunInMainThread([&, this]() { - if (!hasInFlightChanged()) - aAny = QtTransferable::getTransferData(rFlavor); + ensureConsistencyWithSystemClipboard(); + aAny = QtTransferable::getTransferData(rFlavor); }); return aAny; } @@ -191,8 +195,8 @@ css::uno::Sequence<css::datatransfer::DataFlavor> auto* pSalInst(GetQtInstance()); SolarMutexGuard g; pSalInst->RunInMainThread([&, this]() { - if (!hasInFlightChanged()) - aSeq = QtTransferable::getTransferDataFlavors(); + ensureConsistencyWithSystemClipboard(); + aSeq = QtTransferable::getTransferDataFlavors(); }); return aSeq; } @@ -204,8 +208,8 @@ QtClipboardTransferable::isDataFlavorSupported(const css::datatransfer::DataFlav auto* pSalInst(GetQtInstance()); SolarMutexGuard g; pSalInst->RunInMainThread([&, this]() { - if (!hasInFlightChanged()) - bIsSupported = QtTransferable::isDataFlavorSupported(rFlavor); + ensureConsistencyWithSystemClipboard(); + bIsSupported = QtTransferable::isDataFlavorSupported(rFlavor); }); return bIsSupported; } |