[Libreoffice-commits] core.git: vcl/inc vcl/qt5

Jan-Marek Glogowski (via logerrit) logerrit at kemper.freedesktop.org
Wed Oct 2 09:11:37 UTC 2019


 vcl/inc/qt5/Qt5Clipboard.hxx |    1 +
 vcl/qt5/Qt5Clipboard.cxx     |   17 +++++++++++------
 2 files changed, 12 insertions(+), 6 deletions(-)

New commits:
commit c386f07ce195c2167f1b56d23cfd95292634e2de
Author:     Jan-Marek Glogowski <jan-marek.glogowski at extern.cib.de>
AuthorDate: Tue Oct 1 20:02:25 2019 +0200
Commit:     Katarina Behrens <Katarina.Behrens at cib.de>
CommitDate: Wed Oct 2 11:10:40 2019 +0200

    tdf#112368 Qt5 handle owned, non-LO clipboard content
    
    LO can actually create clipboard content, which is not backed by
    an XTransferable, for example when copying / selecting the text
    of the file name in the QFileDialog. So the ownership check in
    Qt5Clipboard::handleChanged is wrong and we just have to prevent
    freeing the content in handleChanged while changing the handle
    from Qt5Clipboard::setContents.
    
    This patch simply sets a boolean member, while the QClipboard is
    changed by LO, to handle this case.
    
    Change-Id: Icc41c32c1f9807e7adff7a9ae16a6c6cacc83f1b
    Reviewed-on: https://gerrit.libreoffice.org/79992
    Reviewed-by: Michael Weghorn <m.weghorn at posteo.de>
    Reviewed-by: Katarina Behrens <Katarina.Behrens at cib.de>
    Tested-by: Jenkins

diff --git a/vcl/inc/qt5/Qt5Clipboard.hxx b/vcl/inc/qt5/Qt5Clipboard.hxx
index 93ad36a0e672..56d109b2e528 100644
--- a/vcl/inc/qt5/Qt5Clipboard.hxx
+++ b/vcl/inc/qt5/Qt5Clipboard.hxx
@@ -38,6 +38,7 @@ class Qt5Clipboard final
     osl::Mutex m_aMutex;
     const OUString m_aClipboardName;
     const QClipboard::Mode m_aClipboardMode;
+    bool m_bInSetContents;
 
     // if not empty, this holds the setContents provided XTransferable or a Qt5ClipboardTransferable
     css::uno::Reference<css::datatransfer::XTransferable> m_aContents;
diff --git a/vcl/qt5/Qt5Clipboard.cxx b/vcl/qt5/Qt5Clipboard.cxx
index db018c82150f..4b31864bf2bd 100644
--- a/vcl/qt5/Qt5Clipboard.cxx
+++ b/vcl/qt5/Qt5Clipboard.cxx
@@ -29,6 +29,7 @@ Qt5Clipboard::Qt5Clipboard(const OUString& aModeString, const QClipboard::Mode a
                                     XServiceInfo>(m_aMutex)
     , m_aClipboardName(aModeString)
     , m_aClipboardMode(aMode)
+    , m_bInSetContents(false)
 {
     assert(isSupported(m_aClipboardMode));
     // DirectConnection guarantees the changed slot runs in the same thread as the QClipboard
@@ -73,8 +74,10 @@ css::uno::Reference<css::datatransfer::XTransferable> Qt5Clipboard::getContents(
 {
     osl::MutexGuard aGuard(m_aMutex);
 
-    // if we're the owner, we have the XTransferable from setContents
-    if (isOwner(m_aClipboardMode))
+    // if we're the owner, we might have the XTransferable from setContents. but
+    // maybe a non-LO clipboard change from within LO, like some C'n'P in the
+    // QFileDialog, might have invalidated m_aContents, so we need to check it too.
+    if (isOwner(m_aClipboardMode) && m_aContents.is())
         return m_aContents;
 
     // check if we can still use the shared Qt5ClipboardTransferable
@@ -103,7 +106,9 @@ void Qt5Clipboard::setContents(
     m_aContents = xTrans;
     m_aOwner = xClipboardOwner;
 
-    // these will trigger QClipboard::changed / handleChanged
+    // these QApplication::clipboard() calls will trigger QClipboard::changed / handleChanged.
+    // we need to prevent freeing the contents, so tell handleChanged about us setting it
+    m_bInSetContents = true;
     if (m_aContents.is())
         QApplication::clipboard()->setMimeData(new Qt5MimeData(m_aContents), m_aClipboardMode);
     else
@@ -111,6 +116,7 @@ void Qt5Clipboard::setContents(
         assert(!m_aOwner.is());
         QApplication::clipboard()->clear(m_aClipboardMode);
     }
+    m_bInSetContents = false;
 
     aGuard.clear();
 
@@ -130,8 +136,7 @@ void Qt5Clipboard::handleChanged(QClipboard::Mode aMode)
     css::uno::Reference<css::datatransfer::clipboard::XClipboardOwner> xOldOwner(m_aOwner);
     css::uno::Reference<css::datatransfer::XTransferable> xOldContents(m_aContents);
     // ownership change from LO POV is handled in setContents
-    const bool bLostOwnership = !isOwner(m_aClipboardMode);
-    if (bLostOwnership)
+    if (!m_bInSetContents)
     {
         m_aContents.clear();
         m_aOwner.clear();
@@ -144,7 +149,7 @@ void Qt5Clipboard::handleChanged(QClipboard::Mode aMode)
 
     aGuard.clear();
 
-    if (bLostOwnership && xOldOwner.is())
+    if (!m_bInSetContents && xOldOwner.is())
         xOldOwner->lostOwnership(this, xOldContents);
     for (auto const& listener : aListeners)
         listener->changedContents(aEv);


More information about the Libreoffice-commits mailing list