diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2014-04-25 13:08:23 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2014-04-25 14:18:05 +0200 |
commit | 65a3622148ea67744c9c1fc18c2b8d48e5f1c79f (patch) | |
tree | 38f7ea19fd1bd3a9a7d2771ba7d4ff01ced2fcbb /vcl | |
parent | e809aa1e916e0f6d1a849d0374f59ef9619b1db7 (diff) |
disable KFileDialog usage if QClipboard can recurse
Change-Id: If23a365b96c1634c2f8940f6ece973089dc3151f
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/CustomTarget_kde4_moc.mk | 3 | ||||
-rw-r--r-- | vcl/unx/kde4/KDESalInstance.cxx | 2 | ||||
-rw-r--r-- | vcl/unx/kde4/KDEXLib.cxx | 14 | ||||
-rw-r--r-- | vcl/unx/kde4/KDEXLib.hxx | 4 | ||||
-rw-r--r-- | vcl/unx/kde4/tst_exclude_posted_events.hxx | 70 |
5 files changed, 85 insertions, 8 deletions
diff --git a/vcl/CustomTarget_kde4_moc.mk b/vcl/CustomTarget_kde4_moc.mk index 9e417548da4b..16d1561944c6 100644 --- a/vcl/CustomTarget_kde4_moc.mk +++ b/vcl/CustomTarget_kde4_moc.mk @@ -12,7 +12,8 @@ $(eval $(call gb_CustomTarget_CustomTarget,vcl/unx/kde4)) $(call gb_CustomTarget_get_target,vcl/unx/kde4) : \ $(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/KDEXLib.moc \ $(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/KDE4FilePicker.moc \ - $(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/tst_exclude_socket_notifiers.moc + $(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/tst_exclude_socket_notifiers.moc \ + $(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/tst_exclude_posted_events.moc $(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/%.moc : \ $(SRCDIR)/vcl/unx/kde4/%.hxx \ 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; +} |