diff options
Diffstat (limited to 'vcl/qt5')
-rw-r--r-- | vcl/qt5/QtClipboard.cxx | 2 | ||||
-rw-r--r-- | vcl/qt5/QtFrame.cxx | 12 | ||||
-rw-r--r-- | vcl/qt5/QtTransferable.cxx | 81 |
3 files changed, 54 insertions, 41 deletions
diff --git a/vcl/qt5/QtClipboard.cxx b/vcl/qt5/QtClipboard.cxx index e9eb476fb2..ea05784bbf 100644 --- a/vcl/qt5/QtClipboard.cxx +++ b/vcl/qt5/QtClipboard.cxx @@ -103,7 +103,7 @@ css::uno::Reference<css::datatransfer::XTransferable> QtClipboard::getContents() { const auto* pTrans = dynamic_cast<QtClipboardTransferable*>(m_aContents.get()); assert(pTrans); - if (pTrans && pTrans->mimeData() == pMimeData) + if (pTrans && pTrans->hasMimeData(pMimeData)) return m_aContents; } diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx index 6aff814aac..1c3839a287 100644 --- a/vcl/qt5/QtFrame.cxx +++ b/vcl/qt5/QtFrame.cxx @@ -35,6 +35,7 @@ #include <QtX11Support.hxx> #endif +#include <QtCore/QLibraryInfo> #include <QtCore/QMimeData> #include <QtCore/QPoint> #include <QtCore/QSize> @@ -1339,8 +1340,17 @@ void QtFrame::ResolveWindowHandle(SystemEnvData& rData) const if (!rData.pWidget) return; assert(rData.platform != SystemEnvData::Platform::Invalid); - if (rData.platform != SystemEnvData::Platform::Wayland) + // Calling QWidget::winId() implicitly enables native windows to be used instead + // of "alien widgets" that don't have a native widget asscoiated with them, + // s. https://doc.qt.io/qt-6/qwidget.html#native-widgets-vs-alien-widgets + // Avoid native widgets with Qt 5 on Wayland and with Qt 6 altogether as they + // cause unsresponsive UI, s. tdf#122293/QTBUG-75766 and tdf#160565 + // (for qt5 xcb, they're needed for video playback) + if (rData.platform != SystemEnvData::Platform::Wayland + && QLibraryInfo::version().majorVersion() < 6) + { rData.SetWindowHandle(static_cast<QWidget*>(rData.pWidget)->winId()); + } } bool QtFrame::GetUseReducedAnimation() const { return GetQtInstance()->GetUseReducedAnimation(); } diff --git a/vcl/qt5/QtTransferable.cxx b/vcl/qt5/QtTransferable.cxx index d9e0beaa71..1aec5da278 100644 --- a/vcl/qt5/QtTransferable.cxx +++ b/vcl/qt5/QtTransferable.cxx @@ -13,6 +13,7 @@ #include <comphelper/sequence.hxx> #include <sal/log.hxx> #include <o3tl/string_view.hxx> +#include <tools/debug.hxx> #include <QtWidgets/QApplication> @@ -43,22 +44,14 @@ static bool lcl_textMimeInfo(std::u16string_view rMimeString, bool& bHaveNoChars QtTransferable::QtTransferable(const QMimeData* pMimeData) : m_pMimeData(pMimeData) - , m_bProvideUTF16FromOtherEncoding(false) { assert(pMimeData); } css::uno::Sequence<css::datatransfer::DataFlavor> SAL_CALL QtTransferable::getTransferDataFlavors() { - // it's just filled once, ever, so just try to get it without locking first - if (m_aMimeTypeSeq.hasElements()) - return m_aMimeTypeSeq; - - // better safe then sorry; preventing broken usage - // DnD should not be shared and Clipboard access runs in the GUI thread - osl::MutexGuard aGuard(m_aMutex); - if (m_aMimeTypeSeq.hasElements()) - return m_aMimeTypeSeq; + if (!m_pMimeData) + return css::uno::Sequence<css::datatransfer::DataFlavor>(); QStringList aFormatList(m_pMimeData->formats()); // we might add the UTF-16 mime text variant later @@ -101,8 +94,10 @@ css::uno::Sequence<css::datatransfer::DataFlavor> SAL_CALL QtTransferable::getTr nMimeTypeCount++; } - m_bProvideUTF16FromOtherEncoding = (bHaveNoCharset || bHaveUTF8) && !bHaveUTF16; - if (m_bProvideUTF16FromOtherEncoding) + // in case of text/plain data, but no UTF-16 encoded one, + // QtTransferable::getTransferData converts from existing encoding to UTF-16 + const bool bProvideUTF16FromOtherEncoding = (bHaveNoCharset || bHaveUTF8) && !bHaveUTF16; + if (bProvideUTF16FromOtherEncoding) { aFlavor.MimeType = "text/plain;charset=utf-16"; aFlavor.DataType = cppu::UnoType<OUString>::get(); @@ -113,8 +108,7 @@ css::uno::Sequence<css::datatransfer::DataFlavor> SAL_CALL QtTransferable::getTr aMimeTypeSeq.realloc(nMimeTypeCount); - m_aMimeTypeSeq = aMimeTypeSeq; - return m_aMimeTypeSeq; + return aMimeTypeSeq; } sal_Bool SAL_CALL @@ -135,26 +129,24 @@ css::uno::Any SAL_CALL QtTransferable::getTransferData(const css::datatransfer:: if (rFlavor.MimeType == "text/plain;charset=utf-16") { OUString aString; - if (m_bProvideUTF16FromOtherEncoding) - { - if (m_pMimeData->hasFormat("text/plain;charset=utf-8")) - { - QByteArray aByteData(m_pMimeData->data(QStringLiteral("text/plain;charset=utf-8"))); - aString = OUString::fromUtf8(reinterpret_cast<const char*>(aByteData.data())); - } - else - { - QByteArray aByteData(m_pMimeData->data(QStringLiteral("text/plain"))); - aString = OUString(reinterpret_cast<const char*>(aByteData.data()), - aByteData.size(), osl_getThreadTextEncoding()); - } - } - else + // use existing UTF-16 encoded text/plain or convert to UTF-16 as needed + if (m_pMimeData->hasFormat("text/plain;charset=utf-16")) { QByteArray aByteData(m_pMimeData->data(toQString(rFlavor.MimeType))); aString = OUString(reinterpret_cast<const sal_Unicode*>(aByteData.data()), aByteData.size() / 2); } + else if (m_pMimeData->hasFormat("text/plain;charset=utf-8")) + { + QByteArray aByteData(m_pMimeData->data(QStringLiteral("text/plain;charset=utf-8"))); + aString = OUString::fromUtf8(reinterpret_cast<const char*>(aByteData.data())); + } + else + { + QByteArray aByteData(m_pMimeData->data(QStringLiteral("text/plain"))); + aString = OUString(reinterpret_cast<const char*>(aByteData.data()), aByteData.size(), + osl_getThreadTextEncoding()); + } aAny <<= aString; } else @@ -175,11 +167,22 @@ QtClipboardTransferable::QtClipboardTransferable(const QClipboard::Mode aMode, { } -bool QtClipboardTransferable::hasInFlightChanged() const +void QtClipboardTransferable::ensureConsistencyWithSystemClipboard() +{ + 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."); + DBG_TESTSOLARMUTEX(); + setMimeData(pCurrentClipboardData); + } +} + +bool QtClipboardTransferable::hasMimeData(const QMimeData* pMimeData) const { - 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; + SolarMutexGuard aGuard; + return QtTransferable::mimeData() == pMimeData; } css::uno::Any SAL_CALL @@ -189,8 +192,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; } @@ -202,8 +205,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; } @@ -215,8 +218,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; } |