[Libreoffice-commits] core.git: vcl/unx

Luboš Luňák l.lunak at collabora.com
Sat Apr 26 08:59:13 PDT 2014


 vcl/unx/kde4/KDE4FilePicker.cxx    |   21 +++--------------
 vcl/unx/kde4/VCLKDEApplication.cxx |   44 +++++++++++++++++++++++++++++++++++++
 vcl/unx/kde4/VCLKDEApplication.hxx |    2 +
 3 files changed, 50 insertions(+), 17 deletions(-)

New commits:
commit 9aa32a34c7c7a2ee4da5f01983a0ed224c38c875
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Sat Apr 26 17:54:37 2014 +0200

    work around LO blocking when asking for QClipboard's contents, helps fdo#35950
    
    Specific to KDE4 vclplug and just a bit of a hack, but it's at least something.
    
    Change-Id: I4bf0f9c8e0b4f7faebaf010a06fcc4ff2e44fa6b

diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index 5f121cc..43bad65 100644
--- a/vcl/unx/kde4/KDE4FilePicker.cxx
+++ b/vcl/unx/kde4/KDE4FilePicker.cxx
@@ -38,6 +38,7 @@
 
 #include "KDE4FilePicker.hxx"
 #include "FPServiceInfo.hxx"
+#include "VCLKDEApplication.hxx"
 
 /* ********* Hack, but needed because of conflicting types... */
 #define Region QtXRegion
@@ -256,25 +257,11 @@ sal_Int16 SAL_CALL KDE4FilePicker::execute()
     _dialog->setFilter(_filter);
     _dialog->filterWidget()->setEditable(false);
 
-    // KFileDialog intergration requires using event loop with QClipboard.
-    // Opening the KDE file dialog here can lead to QClipboard
-    // asking for clipboard contents. If LO core is the owner of the clipboard
-    // content, without event loop use this will block for 5 seconds and timeout,
-    // since the clipboard thread will not be able to acquire SolarMutex
-    // and thus won't be able to respond. If the event loops
-    // are properly integrated and QClipboard can use a nested event loop
-    // (see the KDE VCL plug), then this won't happen.
-    // We cannot simply release SolarMutex here, because the event loop started
-    // by the file dialog would also call back to LO code.
-    assert( qApp->clipboard()->property( "useEventLoopWhenWaiting" ).toBool() == true );
+    VCLKDEApplication::preDialogSetup();
     //block and wait for user input
     int result = _dialog->exec();
-    // HACK: KFileDialog uses KConfig("kdeglobals") for saving some settings
-    // (such as the auto-extension flag), but that doesn't update KGlobal::config()
-    // (which is probably a KDE bug), so force reading the new configuration,
-    // otherwise the next opening of the dialog would use the old settings.
-    KGlobal::config()->reparseConfiguration();
-    if( result == KFileDialog::Accepted)
+    VCLKDEApplication::postDialogCleanup();
+    if( result == KFileDialog::Accepted )
         return ExecutableDialogResults::OK;
 
     return ExecutableDialogResults::CANCEL;
diff --git a/vcl/unx/kde4/VCLKDEApplication.cxx b/vcl/unx/kde4/VCLKDEApplication.cxx
index c79b36e..1b1119f 100644
--- a/vcl/unx/kde4/VCLKDEApplication.cxx
+++ b/vcl/unx/kde4/VCLKDEApplication.cxx
@@ -19,6 +19,7 @@
 
 #include "VCLKDEApplication.hxx"
 
+#include <QClipboard>
 #include <QEvent>
 
 #include "KDESalDisplay.hxx"
@@ -40,4 +41,47 @@ bool VCLKDEApplication::x11EventFilter(XEvent* ev)
     return false;
 }
 
+// various hacks to be performed before re-entering Qt's event loop
+// because of showing a Qt dialog
+void VCLKDEApplication::preDialogSetup()
+{
+    // KFileDialog intergration requires using event loop with QClipboard.
+    // Opening the KDE file dialog here can lead to QClipboard
+    // asking for clipboard contents. If LO core is the owner of the clipboard
+    // content, without event loop use this will block for 5 seconds and timeout,
+    // since the clipboard thread will not be able to acquire SolarMutex
+    // and thus won't be able to respond. If the event loops
+    // are properly integrated and QClipboard can use a nested event loop
+    // (see the KDE VCL plug), then this won't happen.
+    // We cannot simply release SolarMutex here, because the event loop started
+    // by the file dialog would also call back to LO code.
+    assert( qApp->clipboard()->property( "useEventLoopWhenWaiting" ).toBool() == true );
+}
+
+// various hacks to be performed after a Qt dialog has been closed
+void VCLKDEApplication::postDialogCleanup()
+{
+    // HACK: KFileDialog uses KConfig("kdeglobals") for saving some settings
+    // (such as the auto-extension flag), but that doesn't update KGlobal::config()
+    // (which is probably a KDE bug), so force reading the new configuration,
+    // otherwise the next opening of the dialog would use the old settings.
+    KGlobal::config()->reparseConfiguration();
+    // HACK: If Qt owns clipboard or selection, give up on their ownership now. Otherwise
+    // LO core might ask for the contents, but it would block while doing so (i.e. it
+    // doesn't seem to have an equivalent of QClipboard's "useEventLoopWhenWaiting"),
+    // therefore QClipboard wouldn't be able to respond, and whole LO would block until
+    // a timeout. Given that Klipper is most probably running, giving up clipboard/selection
+    // ownership will not only avoid the blocking, but even pasting that content in LO
+    // will in fact work, if Klipper can handle it.
+    // Technically proper solution would be of course to allow Qt to process QClipboard
+    // events while LO waits for clipboard contents, or short-circuit to QClipboard somehow
+    // (it's a mystery why LO's clipboard handling has its own thread when whole LO can
+    // get blocked by both trying to send and receive clipboard contents anyway).
+    QClipboard* clipboard = QApplication::clipboard();
+    if( clipboard->ownsSelection())
+        clipboard->clear( QClipboard::Selection );
+    if( clipboard->ownsClipboard())
+        clipboard->clear( QClipboard::Clipboard );
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/kde4/VCLKDEApplication.hxx b/vcl/unx/kde4/VCLKDEApplication.hxx
index 79859b8..f1fddfc 100644
--- a/vcl/unx/kde4/VCLKDEApplication.hxx
+++ b/vcl/unx/kde4/VCLKDEApplication.hxx
@@ -34,6 +34,8 @@ class VCLKDEApplication : public KApplication
     public:
         VCLKDEApplication();
         virtual bool x11EventFilter(XEvent* event) SAL_OVERRIDE;
+        static void preDialogSetup();
+        static void postDialogCleanup();
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list