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
diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index 467e8d8..c94f248 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 3cde3cf..79d80dc 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 dc63cb6..68c9c528 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -58,7 +58,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()));
@@ -213,6 +214,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
@@ -272,6 +274,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()) {
@@ -389,7 +402,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 d9bd4d6..d07b9f6 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: