diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2014-04-26 17:54:37 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2014-04-26 17:58:15 +0200 |
commit | 9aa32a34c7c7a2ee4da5f01983a0ed224c38c875 (patch) | |
tree | af7a07f07946d02754769662d207a8a31fa3513f /vcl | |
parent | 68c2e3d6d6392d409fd28302939309328a9ef0c1 (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.
Change-Id: I4bf0f9c8e0b4f7faebaf010a06fcc4ff2e44fa6b
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/unx/kde4/KDE4FilePicker.cxx | 21 | ||||
-rw-r--r-- | vcl/unx/kde4/VCLKDEApplication.cxx | 44 | ||||
-rw-r--r-- | vcl/unx/kde4/VCLKDEApplication.hxx | 2 |
3 files changed, 50 insertions, 17 deletions
diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx index 5f121cce4b38..43bad65ad5e8 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 c79b36e2515f..1b1119faa0ba 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 79859b81ddbd..f1fddfca00ea 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: */ |