Kaydet (Commit) 380f3b4b authored tarafından Jan-Marek Glogowski's avatar Jan-Marek Glogowski

KDE4: 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.

Change-Id: I10c422f1c0d7448d4a7ad28e57a32ed2cb42f48f
üst 7dd97334
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "KDE4FilePicker.hxx" #include "KDE4FilePicker.hxx"
#include "FPServiceInfo.hxx" #include "FPServiceInfo.hxx"
#include "KDEXLib.hxx"
/* ********* Hack, but needed because of conflicting types... */ /* ********* Hack, but needed because of conflicting types... */
#define Region QtXRegion #define Region QtXRegion
...@@ -113,10 +114,11 @@ QString toQString(const OUString& s) ...@@ -113,10 +114,11 @@ QString toQString(const OUString& s)
// KDE4FilePicker // KDE4FilePicker
KDE4FilePicker::KDE4FilePicker( const uno::Reference<uno::XComponentContext>& ) KDE4FilePicker::KDE4FilePicker( const uno::Reference<uno::XComponentContext>&, KDEXLib *xlib )
: KDE4FilePicker_Base(_helperMutex) : KDE4FilePicker_Base(_helperMutex)
, _resMgr( ResMgr::CreateResMgr("fps_office") ) , _resMgr( ResMgr::CreateResMgr("fps_office") )
, allowRemoteUrls( false ) , allowRemoteUrls( false )
, _mXLib( xlib )
{ {
_extraControls = new QWidget(); _extraControls = new QWidget();
_layout = new QGridLayout(_extraControls); _layout = new QGridLayout(_extraControls);
...@@ -261,8 +263,11 @@ sal_Int16 SAL_CALL KDE4FilePicker::execute() ...@@ -261,8 +263,11 @@ sal_Int16 SAL_CALL KDE4FilePicker::execute()
_dialog->filterWidget()->setEditable(false); _dialog->filterWidget()->setEditable(false);
// We're entering a nested loop. // 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(); int result = _dialog->exec();
_mXLib->freezeYield( false );
// HACK: KFileDialog uses KConfig("kdeglobals") for saving some settings // HACK: KFileDialog uses KConfig("kdeglobals") for saving some settings
// (such as the auto-extension flag), but that doesn't update KGlobal::config() // (such as the auto-extension flag), but that doesn't update KGlobal::config()
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
class KFileDialog; class KFileDialog;
class QWidget; class QWidget;
class QLayout; class QLayout;
class KDEXLib;
class ResMgr; class ResMgr;
...@@ -82,8 +83,10 @@ protected: ...@@ -82,8 +83,10 @@ protected:
bool allowRemoteUrls; bool allowRemoteUrls;
KDEXLib* _mXLib;
public: 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(); virtual ~KDE4FilePicker();
// XFilePickerNotifier // XFilePickerNotifier
......
...@@ -58,7 +58,8 @@ ...@@ -58,7 +58,8 @@
KDEXLib::KDEXLib() : KDEXLib::KDEXLib() :
SalXLib(), m_bStartupDone(false), m_pApplication(0), SalXLib(), m_bStartupDone(false), m_pApplication(0),
m_pFreeCmdLineArgs(0), m_pAppCmdLineArgs(0), m_nFakeCmdLineArgs( 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 // the timers created here means they belong to the main thread
connect( &timeoutTimer, SIGNAL( timeout()), this, SLOT( timeoutActivated())); connect( &timeoutTimer, SIGNAL( timeout()), this, SLOT( timeoutActivated()));
...@@ -213,6 +214,7 @@ void KDEXLib::setupEventLoop() ...@@ -213,6 +214,7 @@ void KDEXLib::setupEventLoop()
eventLoopType = GlibEventLoop; eventLoopType = GlibEventLoop;
old_gpoll = g_main_context_get_poll_func( NULL ); old_gpoll = g_main_context_get_poll_func( NULL );
g_main_context_set_poll_func( NULL, gpoll_wrapper ); g_main_context_set_poll_func( NULL, gpoll_wrapper );
m_pApplication->clipboard()->setProperty( "useEventLoopWhenWaiting", true );
return; return;
} }
#endif #endif
...@@ -272,6 +274,17 @@ void KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents ) ...@@ -272,6 +274,17 @@ void KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents )
return SalXLib::Yield( bWait, 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), // if we are the main thread (which is where the event processing is done),
// good, just do it // good, just do it
if( qApp->thread() == QThread::currentThread()) { if( qApp->thread() == QThread::currentThread()) {
...@@ -389,7 +402,7 @@ uno::Reference< ui::dialogs::XFilePicker2 > KDEXLib::createFilePicker( ...@@ -389,7 +402,7 @@ uno::Reference< ui::dialogs::XFilePicker2 > KDEXLib::createFilePicker(
SalYieldMutexReleaser aReleaser; SalYieldMutexReleaser aReleaser;
return Q_EMIT createFilePickerSignal( xMSF ); 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" #include "KDEXLib.moc"
......
...@@ -52,6 +52,7 @@ class KDEXLib : public QObject, public SalXLib ...@@ -52,6 +52,7 @@ class KDEXLib : public QObject, public SalXLib
QTimer timeoutTimer; QTimer timeoutTimer;
QTimer userEventTimer; QTimer userEventTimer;
enum { LibreOfficeEventLoop, GlibEventLoop, QtUnixEventLoop } eventLoopType; enum { LibreOfficeEventLoop, GlibEventLoop, QtUnixEventLoop } eventLoopType;
bool m_bYieldFrozen;
private: private:
void setupEventLoop(); void setupEventLoop();
...@@ -84,6 +85,7 @@ class KDEXLib : public QObject, public SalXLib ...@@ -84,6 +85,7 @@ class KDEXLib : public QObject, public SalXLib
virtual void Wakeup(); virtual void Wakeup();
virtual void PostUserEvent(); virtual void PostUserEvent();
void freezeYield(bool freeze) { m_bYieldFrozen = freeze; }
void doStartup(); void doStartup();
public Q_SLOTS: public Q_SLOTS:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment