diff options
author | Jan-Marek Glogowski <glogow@fbihome.de> | 2014-02-26 18:19:11 +0000 |
---|---|---|
committer | Tor Lillqvist <tml@collabora.com> | 2014-03-07 08:37:17 +0200 |
commit | 5c1236fe2dd4a7a0aeca40487788af095429e64b (patch) | |
tree | 57ee4c92075e87b4f2fb7330c6a9e95dc4912bbb /vcl | |
parent | eb66d534b78c471ebbffe960d7df5a683a7e8f8e (diff) |
fdo#74416: sleep in yield for native file picker
As it seems to be the only way to poll the clipboard, reintroduce
m_pApplication->clipboard()->setProperty(
"useEventLoopWhenWaiting", true );
To prevent crashes, disable event processing in the Qt thread while
the dialog is open.
Instead this applies the same workaround as the Windows backend to
sleep a ms, which keeps the FP dialogs more usable, but feels like
a horrible workaround.
This is still slower then running processEvent in Yield but still
much better then the current situation.
(cherry picked from commit 380f3b4b6cbbe8e82b58ddf55e95c5005307b51f)
Change-Id: I10c422f1c0d7448d4a7ad28e57a32ed2cb42f48f
Reviewed-on: https://gerrit.libreoffice.org/8435
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/unx/kde4/KDE4FilePicker.cxx | 9 | ||||
-rw-r--r-- | vcl/unx/kde4/KDE4FilePicker.hxx | 5 | ||||
-rw-r--r-- | vcl/unx/kde4/KDEXLib.cxx | 17 | ||||
-rw-r--r-- | vcl/unx/kde4/KDEXLib.hxx | 2 |
4 files changed, 28 insertions, 5 deletions
diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx index b3fde26b90a2..405eafeb6573 100644 --- a/vcl/unx/kde4/KDE4FilePicker.cxx +++ b/vcl/unx/kde4/KDE4FilePicker.cxx @@ -38,6 +38,7 @@ #include "KDE4FilePicker.hxx" #include "FPServiceInfo.hxx" +#include "KDEXLib.hxx" /* ********* Hack, but needed because of conflicting types... */ #define Region QtXRegion @@ -113,10 +114,11 @@ QString toQString(const OUString& s) // KDE4FilePicker ////////////////////////////////////////////////////////////////////////// -KDE4FilePicker::KDE4FilePicker( const uno::Reference<uno::XComponentContext>& ) +KDE4FilePicker::KDE4FilePicker( const uno::Reference<uno::XComponentContext>&, KDEXLib *xlib ) : KDE4FilePicker_Base(_helperMutex) , _resMgr( ResMgr::CreateResMgr("fps_office") ) , allowRemoteUrls( false ) + , _mXLib( xlib ) { _extraControls = new QWidget(); _layout = new QGridLayout(_extraControls); @@ -261,8 +263,11 @@ sal_Int16 SAL_CALL KDE4FilePicker::execute() _dialog->filterWidget()->setEditable(false); // We're entering a nested loop. - // Release the yield mutex to prevent deadlocks. + // Prevent yield calls, which would crash LO. + + _mXLib->freezeYield( true ); int result = _dialog->exec(); + _mXLib->freezeYield( false ); // HACK: KFileDialog uses KConfig("kdeglobals") for saving some settings // (such as the auto-extension flag), but that doesn't update KGlobal::config() diff --git a/vcl/unx/kde4/KDE4FilePicker.hxx b/vcl/unx/kde4/KDE4FilePicker.hxx index 6dc97df86cc2..81acf0cd6e88 100644 --- a/vcl/unx/kde4/KDE4FilePicker.hxx +++ b/vcl/unx/kde4/KDE4FilePicker.hxx @@ -40,6 +40,7 @@ class KFileDialog; class QWidget; class QLayout; +class KDEXLib; class ResMgr; @@ -82,8 +83,10 @@ protected: bool allowRemoteUrls; + KDEXLib* _mXLib; + public: - KDE4FilePicker( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& ); + KDE4FilePicker( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&, KDEXLib* ); virtual ~KDE4FilePicker(); // XFilePickerNotifier diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx index 7c67e3518130..b4be6d661d9a 100644 --- a/vcl/unx/kde4/KDEXLib.cxx +++ b/vcl/unx/kde4/KDEXLib.cxx @@ -64,7 +64,8 @@ KDEXLib::KDEXLib() : SalXLib(), m_bStartupDone(false), m_pApplication(0), m_pFreeCmdLineArgs(0), m_pAppCmdLineArgs(0), m_nFakeCmdLineArgs( 0 ), - eventLoopType( LibreOfficeEventLoop ) + eventLoopType( LibreOfficeEventLoop ), + m_bYieldFrozen( false ) { // the timers created here means they belong to the main thread connect( &timeoutTimer, SIGNAL( timeout()), this, SLOT( timeoutActivated())); @@ -225,6 +226,7 @@ void KDEXLib::setupEventLoop() eventLoopType = GlibEventLoop; old_gpoll = g_main_context_get_poll_func( NULL ); g_main_context_set_poll_func( NULL, gpoll_wrapper ); + m_pApplication->clipboard()->setProperty( "useEventLoopWhenWaiting", true ); return; } #endif @@ -308,6 +310,17 @@ void KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) return SalXLib::Yield( bWait, bHandleAllCurrentEvents ); } + if( m_bYieldFrozen ) { + if( qApp->thread() != QThread::currentThread() ) { + QAbstractEventDispatcher* dispatcher = QAbstractEventDispatcher::instance( qApp->thread() ); + if( dispatcher->hasPendingEvents() ) { + struct timespec delay = {0, ( 1000000 )}; + nanosleep(&delay, NULL); + } + } + return; + } + // if we are the main thread (which is where the event processing is done), // good, just do it if( qApp->thread() == QThread::currentThread()) { @@ -425,7 +438,7 @@ uno::Reference< ui::dialogs::XFilePicker2 > KDEXLib::createFilePicker( SalYieldMutexReleaser aReleaser; return Q_EMIT createFilePickerSignal( xMSF ); } - return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF ) ); + return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF, this ) ); } #include "KDEXLib.moc" diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx index d9bd4d611deb..d07b9f6c6d81 100644 --- a/vcl/unx/kde4/KDEXLib.hxx +++ b/vcl/unx/kde4/KDEXLib.hxx @@ -52,6 +52,7 @@ class KDEXLib : public QObject, public SalXLib QTimer timeoutTimer; QTimer userEventTimer; enum { LibreOfficeEventLoop, GlibEventLoop, QtUnixEventLoop } eventLoopType; + bool m_bYieldFrozen; private: void setupEventLoop(); @@ -84,6 +85,7 @@ class KDEXLib : public QObject, public SalXLib virtual void Wakeup(); virtual void PostUserEvent(); + void freezeYield(bool freeze) { m_bYieldFrozen = freeze; } void doStartup(); public Q_SLOTS: |