summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2014-04-26 17:54:37 +0200
committerJan-Marek Glogowski <glogow@fbihome.de>2014-08-20 09:44:50 +0200
commit87b2d9020fe66444badf0eff30b8a97a482ab670 (patch)
tree35432c2d759fdad5c4d1ad2a927710d2dabaa2b6
parent4cd59fe822960592f6c6ecfbe3d80fd1f236f517 (diff)
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. (cherry picked from commit 9aa32a34c7c7a2ee4da5f01983a0ed224c38c875) Conflicts: vcl/unx/kde4/VCLKDEApplication.hxx Change-Id: I4bf0f9c8e0b4f7faebaf010a06fcc4ff2e44fa6b
-rw-r--r--vcl/unx/kde4/KDE4FilePicker.cxx21
-rw-r--r--vcl/unx/kde4/VCLKDEApplication.cxx44
-rw-r--r--vcl/unx/kde4/VCLKDEApplication.hxx2
3 files changed, 50 insertions, 17 deletions
diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index 1ed7ddd91b8a..019760bde5d8 100644
--- a/vcl/unx/kde4/KDE4FilePicker.cxx
+++ b/vcl/unx/kde4/KDE4FilePicker.cxx
@@ -37,6 +37,7 @@
#include "KDE4FilePicker.hxx"
#include "FPServiceInfo.hxx"
+#include "VCLKDEApplication.hxx"
/* ********* Hack, but needed because of conflicting types... */
#define Region QtXRegion
@@ -236,25 +237,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 e196ff3d903a..65f699947cfc 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 4ce0b2ca4f67..d31f4e8ac31d 100644
--- a/vcl/unx/kde4/VCLKDEApplication.hxx
+++ b/vcl/unx/kde4/VCLKDEApplication.hxx
@@ -30,6 +30,8 @@ class VCLKDEApplication : public KApplication
public:
VCLKDEApplication();
virtual bool x11EventFilter(XEvent* event);
+ static void preDialogSetup();
+ static void postDialogCleanup();
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */