disable KFileDialog usage if QClipboard can recurse
Change-Id: If23a365b96c1634c2f8940f6ece973089dc3151f
This commit is contained in:
parent
e809aa1e91
commit
65a3622148
27
configure.ac
27
configure.ac
@ -11275,6 +11275,33 @@ int main(int argc, char *argv[])
|
||||
# Remove meta object data
|
||||
rm -f "${TSTBASE}."*
|
||||
|
||||
AC_MSG_CHECKING([whether Qt avoids QClipboard recursion caused by posted events])
|
||||
|
||||
# Prepare meta object data
|
||||
TSTBASE="tst_exclude_posted_events"
|
||||
TSTMOC="${SRC_ROOT}/vcl/unx/kde4/${TSTBASE}"
|
||||
ln -fs "${TSTMOC}.hxx"
|
||||
$MOC4 "${TSTBASE}.hxx" -o "${TSTBASE}.moc"
|
||||
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#include "tst_exclude_posted_events.moc"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
exit(tst_excludePostedEvents());
|
||||
return 0;
|
||||
}
|
||||
]])],[
|
||||
AC_MSG_RESULT([yes])
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_WARN([native KDE4 file pickers will be disabled at runtime - fix your Qt4 library!])
|
||||
])
|
||||
|
||||
# Remove meta object data
|
||||
rm -f "${TSTBASE}."*
|
||||
|
||||
LIBS=$save_LIBS
|
||||
CXXFLAGS=$save_CXXFLAGS
|
||||
AC_LANG_POP([C++])
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 >
|
||||
|
70
vcl/unx/kde4/tst_exclude_posted_events.hxx
Normal file
70
vcl/unx/kde4/tst_exclude_posted_events.hxx
Normal file
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user