summaryrefslogtreecommitdiff
path: root/vcl/unx/kde4
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2014-04-25 13:08:23 +0200
committerLuboš Luňák <l.lunak@collabora.com>2014-04-25 14:18:05 +0200
commit65a3622148ea67744c9c1fc18c2b8d48e5f1c79f (patch)
tree38f7ea19fd1bd3a9a7d2771ba7d4ff01ced2fcbb /vcl/unx/kde4
parente809aa1e916e0f6d1a849d0374f59ef9619b1db7 (diff)
disable KFileDialog usage if QClipboard can recurse
Change-Id: If23a365b96c1634c2f8940f6ece973089dc3151f
Diffstat (limited to 'vcl/unx/kde4')
-rw-r--r--vcl/unx/kde4/KDESalInstance.cxx2
-rw-r--r--vcl/unx/kde4/KDEXLib.cxx14
-rw-r--r--vcl/unx/kde4/KDEXLib.hxx4
-rw-r--r--vcl/unx/kde4/tst_exclude_posted_events.hxx70
4 files changed, 83 insertions, 7 deletions
diff --git a/vcl/unx/kde4/KDESalInstance.cxx b/vcl/unx/kde4/KDESalInstance.cxx
index 023d79051741..094cd2055cd5 100644
--- a/vcl/unx/kde4/KDESalInstance.cxx
+++ b/vcl/unx/kde4/KDESalInstance.cxx
@@ -35,7 +35,7 @@ uno::Reference< ui::dialogs::XFilePicker2 > KDESalInstance::createFilePicker(
const uno::Reference< uno::XComponentContext >& xMSF )
{
KDEXLib* kdeXLib = static_cast<KDEXLib*>( mpXLib );
- if (kdeXLib->haveQt4SocketExcludeFix())
+ if (kdeXLib->allowKdeDialogs())
return uno::Reference< ui::dialogs::XFilePicker2 >(
kdeXLib->createFilePicker(xMSF) );
else
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index 24557bc6fed7..f6c15b06076c 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -47,13 +47,14 @@
#if KDE_HAVE_GLIB
#include "KDE4FilePicker.hxx"
#include "tst_exclude_socket_notifiers.moc"
+#include "tst_exclude_posted_events.moc"
#endif
KDEXLib::KDEXLib() :
SalXLib(), m_bStartupDone(false), m_pApplication(0),
m_pFreeCmdLineArgs(0), m_pAppCmdLineArgs(0), m_nFakeCmdLineArgs( 0 ),
m_frameWidth( -1 ), m_isGlibEventLoopType(false),
- m_haveQt4SocketExcludeFix(false)
+ m_allowKdeDialogs(false)
{
// the timers created here means they belong to the main thread.
// As the timeoutTimer runs the LO event queue, which may block on a dialog,
@@ -187,9 +188,14 @@ void KDEXLib::Init()
#if KDE_HAVE_GLIB
m_isGlibEventLoopType = QAbstractEventDispatcher::instance()->inherits( "QEventDispatcherGlib" );
- if (m_isGlibEventLoopType && (0 == tst_processEventsExcludeSocket()))
+ // Using KDE dialogs (and their nested event loops) works only with a proper event loop integration
+ // that will release SolarMutex when waiting for more events.
+ // Moreover there are bugs in Qt event loop code that allow QClipboard recursing because the event
+ // loop processes also events that it should not at that point, so no dialogs in that case either.
+ if (m_isGlibEventLoopType && (0 == tst_processEventsExcludeSocket()) && tst_excludePostedEvents() == 0 )
// See http://bugreports.qt.nokia.com/browse/QTBUG-37380
- m_haveQt4SocketExcludeFix = true;
+ // https://bugreports.qt-project.org/browse/QTBUG-34614
+ m_allowKdeDialogs = true;
#endif
setupEventLoop();
@@ -238,7 +244,7 @@ void KDEXLib::setupEventLoop()
{
old_gpoll = g_main_context_get_poll_func( NULL );
g_main_context_set_poll_func( NULL, gpoll_wrapper );
- if( m_haveQt4SocketExcludeFix )
+ if( m_allowKdeDialogs )
m_pApplication->clipboard()->setProperty( "useEventLoopWhenWaiting", true );
return;
}
diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx
index e45543d47f26..1f2a2dd1f436 100644
--- a/vcl/unx/kde4/KDEXLib.hxx
+++ b/vcl/unx/kde4/KDEXLib.hxx
@@ -53,7 +53,7 @@ class KDEXLib : public QObject, public SalXLib
QTimer userEventTimer;
int m_frameWidth;
bool m_isGlibEventLoopType;
- bool m_haveQt4SocketExcludeFix;
+ bool m_allowKdeDialogs;
private:
void setupEventLoop();
@@ -88,7 +88,7 @@ class KDEXLib : public QObject, public SalXLib
virtual void PostUserEvent() SAL_OVERRIDE;
void doStartup();
- bool haveQt4SocketExcludeFix() { return m_haveQt4SocketExcludeFix; }
+ bool allowKdeDialogs() { return m_allowKdeDialogs; }
public Q_SLOTS:
com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFilePicker2 >
diff --git a/vcl/unx/kde4/tst_exclude_posted_events.hxx b/vcl/unx/kde4/tst_exclude_posted_events.hxx
new file mode 100644
index 000000000000..777907cd34e0
--- /dev/null
+++ b/vcl/unx/kde4/tst_exclude_posted_events.hxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ *
+ * This code is based on the SocketEventsTester from the Qt4 test suite.
+ */
+
+#pragma once
+
+#include <qcoreapplication.h>
+#include <qeventloop.h>
+#include <qtimer.h>
+
+const QEvent::Type eventType = QEvent::User;
+
+class Test
+ : public QObject
+{
+ Q_OBJECT
+ public:
+ Test();
+ virtual bool event( QEvent* e );
+ bool processed;
+};
+
+Test::Test()
+ : processed( false )
+{
+}
+
+bool Test::event( QEvent* e )
+{
+ if( e->type() == eventType )
+ processed = true;
+ return QObject::event( e );
+}
+
+#define QVERIFY(a) \
+ if (!a) return 1;
+
+static int tst_excludePostedEvents()
+{
+ Test test;
+ QCoreApplication::postEvent( &test, new QEvent( eventType ));
+ QEventLoop loop;
+ QTimer::singleShot(200, &loop, SLOT(quit()));
+ loop.processEvents(QEventLoop::ExcludeUserInputEvents
+ | QEventLoop::ExcludeSocketNotifiers
+// | QEventLoop::WaitForMoreEvents
+ | QEventLoop::X11ExcludeTimers);
+ QVERIFY( !test.processed );
+ QTimer::singleShot(200, &loop, SLOT(quit()));
+ loop.exec();
+ QVERIFY( test.processed );
+ return 0;
+}