[Libreoffice-commits] core.git: Branch 'private/jmux/libreoffice-4-2+kde4' - 9 commits - configure.ac vcl/CustomTarget_kde4_moc.mk vcl/Library_vclplug_kde4.mk vcl/unx
Jan-Marek Glogowski
glogow at fbihome.de
Fri Mar 21 18:38:58 PDT 2014
Rebased ref, commits from common ancestor:
commit 631f43939c770613bf5d37cfccae06b0b1805c05
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date: Fri Mar 14 21:02:16 2014 +0100
fdo#67011 KDE4: prevent blocking in Display::Yield
SalX11Display registers a Yield handler, which splits check and
and processing into two functions, which both lock the yield mutex.
Normally this no problem, but during a Drag'n'Drop operation the
D'n'D thread also checks and processes XEvents (for D'n'D). So the
XNextEvent in Display::Yield will actually block, if the seen XEvent
was for D'n'D and was already processed.
(cherry picked from commit 6c7374f071d998f726cd4a5b67baf54e357d096b)
Change-Id: Ifb0631b38abc0ddab23cd74aad05120b4b3dacad
diff --git a/vcl/unx/kde4/KDESalDisplay.cxx b/vcl/unx/kde4/KDESalDisplay.cxx
index 21440fc..650b266 100644
--- a/vcl/unx/kde4/KDESalDisplay.cxx
+++ b/vcl/unx/kde4/KDESalDisplay.cxx
@@ -51,6 +51,10 @@ void SalKDEDisplay::Yield()
if( DispatchInternalEvent() )
return;
+ // Prevent blocking from Drag'n'Drop events, which may have already have processed the event
+ if (XEventsQueued( pDisp_, QueuedAfterReading ) == 0)
+ return;
+
DBG_ASSERT( static_cast<SalYieldMutex*>(GetSalData()->m_pInstance->GetYieldMutex())->GetThreadId() ==
osl::Thread::getCurrentIdentifier(),
"will crash soon since solar mutex not locked in SalKDEDisplay::Yield" );
commit 0f4ca8163650925d36c18fb898d81d1b942e9344
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date: Mon Mar 10 14:54:58 2014 +0000
Revert "fdo#67011: Run Display::Yield through KDEXLib::Yield."
This reverts commit 95f60222e75486336b6569afa8f34d60b51c94ad.
(cherry picked from commit 69e7f4491ec78384c46653d3cd8870c97cc9218a)
Change-Id: I180172424092eb64e8a7bc02072e1d477641cc8d
diff --git a/vcl/unx/kde4/KDESalDisplay.cxx b/vcl/unx/kde4/KDESalDisplay.cxx
index ee330e7..21440fc 100644
--- a/vcl/unx/kde4/KDESalDisplay.cxx
+++ b/vcl/unx/kde4/KDESalDisplay.cxx
@@ -25,8 +25,6 @@
#include <assert.h>
#include <unx/saldata.hxx>
-#include <qthread.h>
-
SalKDEDisplay* SalKDEDisplay::selfptr = NULL;
SalKDEDisplay::SalKDEDisplay( Display* pDisp )
@@ -50,26 +48,18 @@ SalKDEDisplay::~SalKDEDisplay()
void SalKDEDisplay::Yield()
{
- // We yield the display throught the main Qt thread.
- // Actually this Yield may call the Display::Yield, which results in an
- // unlimited cycle.
- static bool break_cyclic_yield_recursion = false;
- bool is_qt_gui_thread = ( qApp->thread() == QThread::currentThread() );
-
- if( DispatchInternalEvent() || break_cyclic_yield_recursion )
+ if( DispatchInternalEvent() )
return;
- if( is_qt_gui_thread )
- break_cyclic_yield_recursion = true;
-
DBG_ASSERT( static_cast<SalYieldMutex*>(GetSalData()->m_pInstance->GetYieldMutex())->GetThreadId() ==
osl::Thread::getCurrentIdentifier(),
"will crash soon since solar mutex not locked in SalKDEDisplay::Yield" );
- static_cast<KDEXLib*>(GetXLib())->Yield( true, false );
-
- if( is_qt_gui_thread )
- break_cyclic_yield_recursion = false;
+ XEvent event;
+ XNextEvent( pDisp_, &event );
+ if( checkDirectInputEvent( &event ))
+ return;
+ qApp->x11ProcessEvent( &event );
}
// HACK: When using Qt event loop, input methods (japanese, etc.) will get broken because
commit 27921efa90d44f58b9e6d725f9e9d389f9f197fa
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date: Mon Mar 10 15:05:22 2014 +0000
KDE4: add Qt4 glib ExcludeSocket runtime check
Add a runtime check and configure warning to disable KDE4 native
file pickers, if the Qt4 glib dispatcher doesn't honor the
QEventLoop::ExcludeSocketNotifiers flag.
This way polling the QClipboard using the event loop won't
crash LibreOffice with recursive paint events,
See https://bugreports.qt-project.org/browse/QTBUG-37380
(cherry picked from commit cc8d566d74a2e0b969b92d9cf22cc95a3bf31a98)
Change-Id: I48795deef82eaf6f95a4e518baea66c52f0b7400
diff --git a/configure.ac b/configure.ac
index 50f1162..f36cbaf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -11126,7 +11126,7 @@ if test "$test_kde4" = "yes" -a "$ENABLE_KDE4" = "TRUE"; then
fi
qt_test_include="Qt/qobject.h"
- qt_test_library="libQtCore.so"
+ qt_test_library="libQtNetwork.so"
kde_test_include="kwindowsystem.h"
kde_test_library="libsolid.so"
@@ -11213,8 +11213,9 @@ the root of your Qt installation by exporting QT4DIR before running "configure".
AC_MSG_ERROR([KDE4 libraries not found. Please specify the root of your KDE4 installation by exporting KDE4DIR before running "configure".])
fi
- KDE4_CFLAGS="`pkg-config --cflags QtCore` `pkg-config --cflags QtGui` -I$kde_incdir -DQT_CLEAN_NAMESPACE -DQT_THREAD_SUPPORT"
- KDE4_LIBS="-L$kde_libdir -L$qt_lib_dir -lkio -lkfile -lkdeui -lkdecore -lQtCore -lQtGui"
+ PKG_CHECK_MODULES([QT4],[QtNetwork QtGui])
+ KDE4_CFLAGS="-I$kde_incdir $QT4_CFLAGS -DQT_CLEAN_NAMESPACE -DQT_THREAD_SUPPORT"
+ KDE4_LIBS="-L$kde_libdir -lkio -lkfile -lkdeui -lkdecore -L$qt_lib_dir $QT4_LIBS"
KDE4_CFLAGS=$(printf '%s' "$KDE4_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g")
AC_LANG_PUSH([C++])
@@ -11236,11 +11237,47 @@ int main(int argc, char **argv) {
# Sets also KDE_GLIB_CFLAGS/KDE_GLIB_LIBS if successful.
PKG_CHECK_MODULES(KDE_GLIB,[glib-2.0 >= 2.4],
[
- KDE_HAVE_GLIB=1
- AC_DEFINE(KDE_HAVE_GLIB,1)
- KDE_GLIB_CFLAGS=$(printf '%s' "$KDE_GLIB_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g")
+ KDE_HAVE_GLIB=1
+ AC_DEFINE(KDE_HAVE_GLIB,1)
+ KDE_GLIB_CFLAGS=$(printf '%s' "$KDE_GLIB_CFLAGS" | sed -e "s/-I/${ISYSTEM?}/g")
+
+ AC_LANG_PUSH([C++])
+ save_CXXFLAGS=$CXXFLAGS
+ CXXFLAGS="$CXXFLAGS $KDE4_CFLAGS"
+ save_LIBS=$LIBS
+ LIBS="$LIBS $KDE4_LIBS"
+ AC_MSG_CHECKING([whether Qt has fixed ExcludeSocketNotifiers])
+
+ # Prepare meta object data
+ TSTBASE="tst_exclude_socket_notifiers"
+ 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_socket_notifiers.moc"
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+ exit(tst_processEventsExcludeSocket());
+ 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++])
],
- AC_MSG_WARN([[No Glib found, KDE4 support will not integrate with Qt's Glib event loop support]]))
+ AC_MSG_WARN([[No Glib found, KDE4 support will not use native file pickers!]]))
fi
AC_SUBST(KDE4_CFLAGS)
AC_SUBST(KDE4_LIBS)
diff --git a/vcl/CustomTarget_kde4_moc.mk b/vcl/CustomTarget_kde4_moc.mk
index 0846b0b..9e41754 100644
--- a/vcl/CustomTarget_kde4_moc.mk
+++ b/vcl/CustomTarget_kde4_moc.mk
@@ -11,7 +11,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)/KDE4FilePicker.moc \
+ $(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/tst_exclude_socket_notifiers.moc
$(call gb_CustomTarget_get_workdir,vcl/unx/kde4)/%.moc : \
$(SRCDIR)/vcl/unx/kde4/%.hxx \
diff --git a/vcl/Library_vclplug_kde4.mk b/vcl/Library_vclplug_kde4.mk
index c72fe00..18ffa02 100644
--- a/vcl/Library_vclplug_kde4.mk
+++ b/vcl/Library_vclplug_kde4.mk
@@ -76,7 +76,7 @@ endif
$(eval $(call gb_Library_add_exception_objects,vclplug_kde4,\
vcl/unx/kde4/KDEData \
- vcl/unx/kde4/KDE4FilePicker \
+ vcl/unx/kde4/KDE4FilePicker \
vcl/unx/kde4/KDESalDisplay \
vcl/unx/kde4/KDESalFrame \
vcl/unx/kde4/KDESalGraphics \
diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index b3fde26..1cb1460 100644
--- a/vcl/unx/kde4/KDE4FilePicker.cxx
+++ b/vcl/unx/kde4/KDE4FilePicker.cxx
@@ -261,8 +261,12 @@ sal_Int16 SAL_CALL KDE4FilePicker::execute()
_dialog->filterWidget()->setEditable(false);
// We're entering a nested loop.
- // Release the yield mutex to prevent deadlocks.
- int result = _dialog->exec();
+ int result;
+ {
+ // Release the yield mutex to prevent deadlocks.
+ SalYieldMutexReleaser aReleaser;
+ result = _dialog->exec();
+ }
// 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/KDEData.cxx b/vcl/unx/kde4/KDEData.cxx
index ccbbd99..0e87c62 100644
--- a/vcl/unx/kde4/KDEData.cxx
+++ b/vcl/unx/kde4/KDEData.cxx
@@ -27,6 +27,7 @@
#include "KDEData.hxx"
#include "KDEXLib.hxx"
+#include "KDESalDisplay.hxx"
KDEData::~KDEData()
@@ -37,6 +38,7 @@ void KDEData::Init()
{
pXLib_ = new KDEXLib();
pXLib_->Init();
+ SetDisplay( SalKDEDisplay::self() );
}
void KDEData::initNWF()
diff --git a/vcl/unx/kde4/KDESalInstance.cxx b/vcl/unx/kde4/KDESalInstance.cxx
index 9670172..023d790 100644
--- a/vcl/unx/kde4/KDESalInstance.cxx
+++ b/vcl/unx/kde4/KDESalInstance.cxx
@@ -32,10 +32,14 @@ SalFrame* KDESalInstance::CreateFrame( SalFrame *pParent, sal_uLong nState )
}
uno::Reference< ui::dialogs::XFilePicker2 > KDESalInstance::createFilePicker(
- const uno::Reference< uno::XComponentContext >& xMSF )
+ const uno::Reference< uno::XComponentContext >& xMSF )
{
- return uno::Reference< ui::dialogs::XFilePicker2 >(
- static_cast<KDEXLib*>( mpXLib )->createFilePicker(xMSF) );
+ KDEXLib* kdeXLib = static_cast<KDEXLib*>( mpXLib );
+ if (kdeXLib->haveQt4SocketExcludeFix())
+ return uno::Reference< ui::dialogs::XFilePicker2 >(
+ kdeXLib->createFilePicker(xMSF) );
+ else
+ return X11SalInstance::createFilePicker( xMSF );
}
int KDESalInstance::getFrameWidth()
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index 5c4cd10..820d39a 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -19,7 +19,6 @@
#include "VCLKDEApplication.hxx"
-#include "KDE4FilePicker.hxx"
#include "KDESalInstance.hxx"
#include <kapplication.h>
@@ -45,15 +44,17 @@
#include <config_kde4.h>
+#if KDE_HAVE_GLIB
+#include "KDE4FilePicker.hxx"
+#include "tst_exclude_socket_notifiers.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_frameWidth( -1 ), m_isGlibEventLoopType(false),
+ m_haveQt4SocketExcludeFix(false)
{
-#if KDE_HAVE_GLIB
- m_isGlibEventLoopType = QAbstractEventDispatcher::instance()->inherits( "QEventDispatcherGlib" );
-#endif
-
// 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,
// the timer has to use a Qt::QueuedConnection, otherwise the nested event
@@ -168,6 +169,14 @@ void KDEXLib::Init()
m_pApplication = new VCLKDEApplication();
kapp->disableSessionManagement();
KApplication::setQuitOnLastWindowClosed(false);
+
+#if KDE_HAVE_GLIB
+ m_isGlibEventLoopType = QAbstractEventDispatcher::instance()->inherits( "QEventDispatcherGlib" );
+ if (m_isGlibEventLoopType && (0 == tst_processEventsExcludeSocket()))
+ // See http://bugreports.qt.nokia.com/browse/QTBUG-37380
+ m_haveQt4SocketExcludeFix = true;
+#endif
+
setupEventLoop();
Display* pDisp = QX11Info::display();
@@ -188,9 +197,8 @@ void KDEXLib::Init()
#include <glib.h>
static GPollFunc old_gpoll = NULL;
-static gint gpoll_wrapper( GPollFD*, guint, gint );
-gint gpoll_wrapper( GPollFD* ufds, guint nfds, gint timeout )
+static gint gpoll_wrapper( GPollFD* ufds, guint nfds, gint timeout )
{
SalYieldMutexReleaser release; // release YieldMutex (and re-acquire at block end)
return old_gpoll( ufds, nfds, timeout );
@@ -215,6 +223,8 @@ void KDEXLib::setupEventLoop()
{
old_gpoll = g_main_context_get_poll_func( NULL );
g_main_context_set_poll_func( NULL, gpoll_wrapper );
+ if( m_haveQt4SocketExcludeFix )
+ m_pApplication->clipboard()->setProperty( "useEventLoopWhenWaiting", true );
return;
}
#endif
@@ -367,11 +377,15 @@ using namespace com::sun::star;
uno::Reference< ui::dialogs::XFilePicker2 > KDEXLib::createFilePicker(
const uno::Reference< uno::XComponentContext >& xMSF )
{
+#if KDE_HAVE_GLIB
if( qApp->thread() != QThread::currentThread()) {
SalYieldMutexReleaser aReleaser;
return Q_EMIT createFilePickerSignal( xMSF );
}
return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF ) );
+#else
+ return NULL;
+#endif
}
#define Region QtXRegion
diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx
index f26948d..a88258c 100644
--- a/vcl/unx/kde4/KDEXLib.hxx
+++ b/vcl/unx/kde4/KDEXLib.hxx
@@ -53,6 +53,7 @@ class KDEXLib : public QObject, public SalXLib
QTimer userEventTimer;
int m_frameWidth;
bool m_isGlibEventLoopType;
+ bool m_haveQt4SocketExcludeFix;
private:
void setupEventLoop();
@@ -87,6 +88,7 @@ class KDEXLib : public QObject, public SalXLib
virtual void PostUserEvent();
void doStartup();
+ bool haveQt4SocketExcludeFix() { return m_haveQt4SocketExcludeFix; }
public Q_SLOTS:
com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFilePicker2 >
diff --git a/vcl/unx/kde4/tst_exclude_socket_notifiers.hxx b/vcl/unx/kde4/tst_exclude_socket_notifiers.hxx
new file mode 100644
index 0000000..0c874fd
--- /dev/null
+++ b/vcl/unx/kde4/tst_exclude_socket_notifiers.hxx
@@ -0,0 +1,126 @@
+/* -*- 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 <qthread.h>
+#include <qtimer.h>
+#include <QtNetwork/qtcpserver.h>
+#include <QtNetwork/qtcpsocket.h>
+
+class SocketEventsTester: public QObject
+{
+ Q_OBJECT
+public:
+ SocketEventsTester()
+ {
+ socket = 0;
+ server = 0;
+ dataSent = false;
+ testResult = false;
+ dataArrived = false;
+ }
+ ~SocketEventsTester()
+ {
+ delete socket;
+ delete server;
+ }
+ bool init()
+ {
+ bool ret = false;
+ server = new QTcpServer();
+ socket = new QTcpSocket();
+ connect(server, SIGNAL(newConnection()), this, SLOT(sendHello()));
+ connect(socket, SIGNAL(readyRead()), this, SLOT(sendAck()), Qt::DirectConnection);
+ if((ret = server->listen(QHostAddress::LocalHost, 0))) {
+ socket->connectToHost(server->serverAddress(), server->serverPort());
+ socket->waitForConnected();
+ }
+ return ret;
+ }
+
+ QTcpSocket *socket;
+ QTcpServer *server;
+ bool dataSent;
+ bool testResult;
+ bool dataArrived;
+public slots:
+ void sendAck()
+ {
+ dataArrived = true;
+ }
+ void sendHello()
+ {
+ char data[10] ="HELLO";
+ qint64 size = sizeof(data);
+
+ QTcpSocket *serverSocket = server->nextPendingConnection();
+ serverSocket->write(data, size);
+ dataSent = serverSocket->waitForBytesWritten(-1);
+ QEventLoop loop;
+ //allow the TCP/IP stack time to loopback the data, so our socket is ready to read
+ QTimer::singleShot(200, &loop, SLOT(quit()));
+ loop.exec(QEventLoop::ExcludeSocketNotifiers);
+ testResult = dataArrived;
+ //check the deferred event is processed
+ QTimer::singleShot(200, &loop, SLOT(quit()));
+ loop.exec();
+ serverSocket->close();
+ QThread::currentThread()->exit(0);
+ }
+};
+
+class SocketTestThread : public QThread
+{
+ Q_OBJECT
+public:
+ SocketTestThread():QThread(0),testResult(false){};
+ void run()
+ {
+ SocketEventsTester *tester = new SocketEventsTester();
+ if (tester->init())
+ exec();
+ dataSent = tester->dataSent;
+ testResult = tester->testResult;
+ dataArrived = tester->dataArrived;
+ delete tester;
+ }
+ bool dataSent;
+ bool testResult;
+ bool dataArrived;
+};
+
+#define QVERIFY(a) \
+ if (!a) return 1;
+
+static int tst_processEventsExcludeSocket()
+{
+ SocketTestThread thread;
+ thread.start();
+ QVERIFY(thread.wait());
+ QVERIFY(thread.dataSent);
+ QVERIFY(!thread.testResult);
+ QVERIFY(thread.dataArrived);
+ return 0;
+}
+
commit 4fa045185fe7db0b308db7afed52295c4f2719b7
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date: Fri Mar 14 15:16:11 2014 +0100
KDE4: change eventLoopType enum to glib bool
Just check for glib; it's the default in later Qt4 versions on unix.
(cherry picked from commit 516a8dedac9c3cb77cd26a740cf793b1cab920d0)
Change-Id: Iacf688c09b4e70955302c8c79d189ec2fd7eacda
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index e936c69..5c4cd10 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -45,21 +45,15 @@
#include <config_kde4.h>
-#if KDE_HAVE_GLIB
-#define GLIB_EVENT_LOOP_SUPPORT 1
-#else
-#define GLIB_EVENT_LOOP_SUPPORT 0
-#endif
-
-#if GLIB_EVENT_LOOP_SUPPORT
-#include <glib-2.0/glib.h>
-#endif
-
KDEXLib::KDEXLib() :
SalXLib(), m_bStartupDone(false), m_pApplication(0),
m_pFreeCmdLineArgs(0), m_pAppCmdLineArgs(0), m_nFakeCmdLineArgs( 0 ),
- eventLoopType( LibreOfficeEventLoop ), m_frameWidth( -1 )
+ m_frameWidth( -1 ), m_isGlibEventLoopType(false)
{
+#if KDE_HAVE_GLIB
+ m_isGlibEventLoopType = QAbstractEventDispatcher::instance()->inherits( "QEventDispatcherGlib" );
+#endif
+
// 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,
// the timer has to use a Qt::QueuedConnection, otherwise the nested event
@@ -190,9 +184,17 @@ void KDEXLib::Init()
// needs to be unlocked shortly before entering the main sleep (e.g. select()) and locked
// immediatelly after. So we need to know which event loop implementation is used and
// hook accordingly.
-#if GLIB_EVENT_LOOP_SUPPORT
+#if KDE_HAVE_GLIB
+#include <glib.h>
+
static GPollFunc old_gpoll = NULL;
static gint gpoll_wrapper( GPollFD*, guint, gint );
+
+gint gpoll_wrapper( GPollFD* ufds, guint nfds, gint timeout )
+{
+ SalYieldMutexReleaser release; // release YieldMutex (and re-acquire at block end)
+ return old_gpoll( ufds, nfds, timeout );
+}
#endif
static bool ( *old_qt_event_filter )( void* );
@@ -208,35 +210,19 @@ static bool qt_event_filter( void* m )
void KDEXLib::setupEventLoop()
{
old_qt_event_filter = QAbstractEventDispatcher::instance()->setEventFilter( qt_event_filter );
-#if GLIB_EVENT_LOOP_SUPPORT
-// Glib is simple, it has g_main_context_set_poll_func() for wrapping the sleep call.
-// The catch is that Qt has a bug that allows triggering timers even when they should
-// not be, leading to crashes caused by QClipboard re-entering the event loop.
-// (http://bugreports.qt.nokia.com/browse/QTBUG-14461), so enable only with Qt>=4.8.0,
-// where it is fixed.
-#if QT_VERSION >= QT_VERSION_CHECK( 4, 8, 0 )
- if( QAbstractEventDispatcher::instance()->inherits( "QEventDispatcherGlib" ))
+#if KDE_HAVE_GLIB
+ if( m_isGlibEventLoopType )
{
- eventLoopType = GlibEventLoop;
old_gpoll = g_main_context_get_poll_func( NULL );
g_main_context_set_poll_func( NULL, gpoll_wrapper );
return;
}
#endif
-#endif
-}
-
-#if GLIB_EVENT_LOOP_SUPPORT
-gint gpoll_wrapper( GPollFD* ufds, guint nfds, gint timeout )
-{
- SalYieldMutexReleaser release; // release YieldMutex (and re-acquire at block end)
- return old_gpoll( ufds, nfds, timeout );
}
-#endif
void KDEXLib::Insert( int fd, void* data, YieldFunc pending, YieldFunc queued, YieldFunc handle )
{
- if( eventLoopType == LibreOfficeEventLoop )
+ if( !m_isGlibEventLoopType )
return SalXLib::Insert( fd, data, pending, queued, handle );
SocketData sdata;
sdata.data = data;
@@ -251,7 +237,7 @@ void KDEXLib::Insert( int fd, void* data, YieldFunc pending, YieldFunc queued, Y
void KDEXLib::Remove( int fd )
{
- if( eventLoopType == LibreOfficeEventLoop )
+ if( !m_isGlibEventLoopType )
return SalXLib::Remove( fd );
SocketData sdata = socketData.take( fd );// according to SalXLib::Remove() this should be safe
delete sdata.notifier;
@@ -265,7 +251,7 @@ void KDEXLib::socketNotifierActivated( int fd )
void KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents )
{
- if( eventLoopType == LibreOfficeEventLoop )
+ if( !m_isGlibEventLoopType )
{
if( qApp->thread() == QThread::currentThread())
{
@@ -307,7 +293,7 @@ void KDEXLib::processYield( bool bWait, bool bHandleAllCurrentEvents )
void KDEXLib::StartTimer( sal_uLong nMS )
{
- if( eventLoopType == LibreOfficeEventLoop )
+ if( !m_isGlibEventLoopType )
return SalXLib::StartTimer( nMS );
timeoutTimer.setInterval( nMS );
// QTimer's can be started only in their thread (main thread here)
@@ -324,7 +310,7 @@ void KDEXLib::startTimeoutTimer()
void KDEXLib::StopTimer()
{
- if( eventLoopType == LibreOfficeEventLoop )
+ if( !m_isGlibEventLoopType )
return SalXLib::StopTimer();
timeoutTimer.stop();
}
@@ -338,14 +324,14 @@ void KDEXLib::timeoutActivated()
void KDEXLib::Wakeup()
{
- if( eventLoopType == LibreOfficeEventLoop )
+ if( !m_isGlibEventLoopType )
return SalXLib::Wakeup();
QAbstractEventDispatcher::instance( qApp->thread())->wakeUp(); // main thread event loop
}
void KDEXLib::PostUserEvent()
{
- if( eventLoopType == LibreOfficeEventLoop )
+ if( !m_isGlibEventLoopType )
return SalXLib::PostUserEvent();
if( qApp->thread() == QThread::currentThread())
startUserEventTimer();
diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx
index 1d307a0..f26948d 100644
--- a/vcl/unx/kde4/KDEXLib.hxx
+++ b/vcl/unx/kde4/KDEXLib.hxx
@@ -51,8 +51,8 @@ class KDEXLib : public QObject, public SalXLib
QHash< int, SocketData > socketData; // key is fd
QTimer timeoutTimer;
QTimer userEventTimer;
- enum { LibreOfficeEventLoop, GlibEventLoop, QtUnixEventLoop } eventLoopType;
int m_frameWidth;
+ bool m_isGlibEventLoopType;
private:
void setupEventLoop();
commit 6c27dbbd8ba00dd334a5890954e388795e4bcafd
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date: Wed Feb 26 17:02:38 2014 +0200
KDE4: Drop Qt 4.9 support
I don't think there will ever be any 4.9 release, so drop all the
unused code.
(cherry picked from commit 7dd973344a8e2c09ac52aa02739b6b921f6df87e)
Change-Id: Ieca21e5d62d478dcde26f812e246d27029027bb5
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index e08856e..e936c69 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -45,12 +45,6 @@
#include <config_kde4.h>
-#if QT_VERSION >= QT_VERSION_CHECK( 4, 9, 0 )
-#define QT_UNIX_EVENT_LOOP_SUPPORT 1
-#else
-#define QT_UNIX_EVENT_LOOP_SUPPORT 0
-#endif
-
#if KDE_HAVE_GLIB
#define GLIB_EVENT_LOOP_SUPPORT 1
#else
@@ -200,12 +194,6 @@ void KDEXLib::Init()
static GPollFunc old_gpoll = NULL;
static gint gpoll_wrapper( GPollFD*, guint, gint );
#endif
-#if QT_UNIX_EVENT_LOOP_SUPPORT
-static int (*qt_select)(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
- const struct timeval *orig_timeout);
-static int lo_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
- const struct timeval *orig_timeout);
-#endif
static bool ( *old_qt_event_filter )( void* );
static bool qt_event_filter( void* m )
@@ -236,21 +224,6 @@ void KDEXLib::setupEventLoop()
}
#endif
#endif
-#if QT_UNIX_EVENT_LOOP_SUPPORT
-// When Qt does not use Glib support, it uses its own Unix event dispatcher.
-// That one has aboutToBlock() and awake() signals, but they are broken (either
-// functionality or semantics), as e.g. awake() is not emitted right after the dispatcher
-// is woken up from sleep again, but only later (which is too late for re-acquiring SolarMutex).
-// This should be fixed with Qt-4.8.0 (?) where support for adding custom select() function
-// has been added too (http://bugreports.qt.nokia.com/browse/QTBUG-16934).
- if( QAbstractEventDispatcher::instance()->inherits( "QEventDispatcherUNIX" ))
- {
- eventLoopType = QtUnixEventLoop;
- QInternal::callFunction( QInternal::GetUnixSelectFunction, reinterpret_cast< void** >( &qt_select ));
- QInternal::callFunction( QInternal::SetUnixSelectFunction, reinterpret_cast< void** >( lo_select ));
- return;
- }
-#endif
}
#if GLIB_EVENT_LOOP_SUPPORT
@@ -261,15 +234,6 @@ gint gpoll_wrapper( GPollFD* ufds, guint nfds, gint timeout )
}
#endif
-#if QT_UNIX_EVENT_LOOP_SUPPORT
-int lo_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
- const struct timeval *orig_timeout)
-{
- SalYieldMutexReleaser release; // release YieldMutex (and re-acquire at block end)
- return qt_select( nfds, fdread, fdwrite, fdexcept, orig_timeout );
-}
-#endif
-
void KDEXLib::Insert( int fd, void* data, YieldFunc pending, YieldFunc queued, YieldFunc handle )
{
if( eventLoopType == LibreOfficeEventLoop )
commit 4d0950bb872ad6f029e5d40e9a84dffa93aa0c5e
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date: Thu Mar 13 21:55:31 2014 +0100
Revert "Rewrite Qt4 based nested yield mutex locking."
This reverts the unx/kde4/KDEXLib.cxx part of
commit 13a34f4c6307d1bd2443cbf3fbd83bfdd8cdbafb.
Conflicts:
vcl/unx/kde4/KDE4FilePicker.cxx
vcl/unx/kde4/KDEXLib.cxx
(cherry picked from commit daf011870efae282244c0298494820d9a0c6d3bc)
Change-Id: I4075fc26d54e5abb2e1cdb535d84f16c8fd3df09
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index 6bd6c1a..e08856e 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -301,9 +301,6 @@ void KDEXLib::socketNotifierActivated( int fd )
void KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents )
{
- // Nested yield loop counter.
- static int loop_depth = 0;
-
if( eventLoopType == LibreOfficeEventLoop )
{
if( qApp->thread() == QThread::currentThread())
@@ -317,21 +314,13 @@ void KDEXLib::Yield( bool bWait, bool bHandleAllCurrentEvents )
// if we are the main thread (which is where the event processing is done),
// good, just do it
- if( qApp->thread() == QThread::currentThread()) {
- // Release the yield lock before entering a nested loop.
- if (loop_depth > 0)
- SalYieldMutexReleaser aReleaser;
- loop_depth++;
+ if( qApp->thread() == QThread::currentThread())
processYield( bWait, bHandleAllCurrentEvents );
- loop_depth--;
- }
- else {
+ else
+ {
// we were called from another thread;
// release the yield lock to prevent deadlock.
SalYieldMutexReleaser aReleaser;
-
- // if this deadlocks, event processing needs to go into a separate
- // thread or some other solution needs to be found
Q_EMIT processYieldSignal( bWait, bHandleAllCurrentEvents );
}
}
commit ab630adf7e4becf4ecd3999982c0fcff59db0228
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date: Mon Mar 10 14:57:10 2014 +0000
Revert "KDE4: sleep in yield for native file picker"
This reverts commit 380f3b4b6cbbe8e82b58ddf55e95c5005307b51f.
Conflicts:
vcl/unx/kde4/KDEXLib.cxx
vcl/unx/kde4/KDEXLib.hxx
(cherry picked from commit 52a2bde753fdf62cd8bb8498ef92abcce86e6c12)
Change-Id: I8528bd881dbe1aee228d61c06ae018f3a75449b1
diff --git a/vcl/unx/kde4/KDE4FilePicker.cxx b/vcl/unx/kde4/KDE4FilePicker.cxx
index 405eafe..b3fde26 100644
--- a/vcl/unx/kde4/KDE4FilePicker.cxx
+++ b/vcl/unx/kde4/KDE4FilePicker.cxx
@@ -38,7 +38,6 @@
#include "KDE4FilePicker.hxx"
#include "FPServiceInfo.hxx"
-#include "KDEXLib.hxx"
/* ********* Hack, but needed because of conflicting types... */
#define Region QtXRegion
@@ -114,11 +113,10 @@ QString toQString(const OUString& s)
// KDE4FilePicker
//////////////////////////////////////////////////////////////////////////
-KDE4FilePicker::KDE4FilePicker( const uno::Reference<uno::XComponentContext>&, KDEXLib *xlib )
+KDE4FilePicker::KDE4FilePicker( const uno::Reference<uno::XComponentContext>& )
: KDE4FilePicker_Base(_helperMutex)
, _resMgr( ResMgr::CreateResMgr("fps_office") )
, allowRemoteUrls( false )
- , _mXLib( xlib )
{
_extraControls = new QWidget();
_layout = new QGridLayout(_extraControls);
@@ -263,11 +261,8 @@ sal_Int16 SAL_CALL KDE4FilePicker::execute()
_dialog->filterWidget()->setEditable(false);
// We're entering a nested loop.
- // Prevent yield calls, which would crash LO.
-
- _mXLib->freezeYield( true );
+ // Release the yield mutex to prevent deadlocks.
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 81acf0c..6dc97df 100644
--- a/vcl/unx/kde4/KDE4FilePicker.hxx
+++ b/vcl/unx/kde4/KDE4FilePicker.hxx
@@ -40,7 +40,6 @@
class KFileDialog;
class QWidget;
class QLayout;
-class KDEXLib;
class ResMgr;
@@ -83,10 +82,8 @@ protected:
bool allowRemoteUrls;
- KDEXLib* _mXLib;
-
public:
- KDE4FilePicker( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >&, KDEXLib* );
+ KDE4FilePicker( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& );
virtual ~KDE4FilePicker();
// XFilePickerNotifier
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index f8923c3..6bd6c1a 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -64,8 +64,7 @@
KDEXLib::KDEXLib() :
SalXLib(), m_bStartupDone(false), m_pApplication(0),
m_pFreeCmdLineArgs(0), m_pAppCmdLineArgs(0), m_nFakeCmdLineArgs( 0 ),
- eventLoopType( LibreOfficeEventLoop ),
- m_bYieldFrozen( false ), m_frameWidth( -1 )
+ eventLoopType( LibreOfficeEventLoop ), m_frameWidth( -1 )
{
// 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,
@@ -233,7 +232,6 @@ 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
@@ -317,17 +315,6 @@ 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()) {
@@ -445,7 +432,7 @@ uno::Reference< ui::dialogs::XFilePicker2 > KDEXLib::createFilePicker(
SalYieldMutexReleaser aReleaser;
return Q_EMIT createFilePickerSignal( xMSF );
}
- return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF, this ) );
+ return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF ) );
}
#define Region QtXRegion
diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx
index dd7f83f..1d307a0 100644
--- a/vcl/unx/kde4/KDEXLib.hxx
+++ b/vcl/unx/kde4/KDEXLib.hxx
@@ -52,7 +52,6 @@ class KDEXLib : public QObject, public SalXLib
QTimer timeoutTimer;
QTimer userEventTimer;
enum { LibreOfficeEventLoop, GlibEventLoop, QtUnixEventLoop } eventLoopType;
- bool m_bYieldFrozen;
int m_frameWidth;
private:
@@ -87,7 +86,6 @@ class KDEXLib : public QObject, public SalXLib
virtual void Wakeup();
virtual void PostUserEvent();
- void freezeYield(bool freeze) { m_bYieldFrozen = freeze; }
void doStartup();
public Q_SLOTS:
commit 37e56b26abf3a6ff5284e5eb3321dac1eda8a2b9
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date: Thu Feb 27 08:51:00 2014 +0000
KDE4: Report correct check and radio item sizes
Use the correct sizs from the current style.
(cherry picked from commit ab1f5eab4830f00dbbd7c883b98b59975ecd3bb1)
Change-Id: I0a5307989ba8172b011eafa04d00fa3fb4b9919c
diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index b1a0efe..6e20ef1 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -820,12 +820,26 @@ sal_Bool KDESalGraphics::getNativeControlRegion( ControlType type, ControlPart p
break;
}
case CTRL_MENU_POPUP:
- if (part == PART_MENU_ITEM_CHECK_MARK || part == PART_MENU_ITEM_RADIO_MARK)
- { // core uses this to detect radio/checkbox sizes, so just set a square
- contentRect.setWidth(contentRect.height());
+ {
+ int h, w;
+ switch ( part ) {
+ case PART_MENU_ITEM_CHECK_MARK:
+ h = kapp->style()->pixelMetric(QStyle::PM_IndicatorHeight);
+ w = kapp->style()->pixelMetric(QStyle::PM_IndicatorWidth);
+ retVal = true;
+ break;
+ case PART_MENU_ITEM_RADIO_MARK:
+ h = kapp->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorHeight);
+ w = kapp->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth);
retVal = true;
+ break;
+ }
+ if (retVal) {
+ contentRect = QRect(0, 0, w, h);
+ boundingRect = contentRect;
}
break;
+ }
case CTRL_FRAME:
{
if( part == PART_BORDER )
commit 42e21993bb9e943990a20a56dc9a9c9d89e683b0
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date: Thu Feb 27 20:34:00 2014 +0000
KDE4: evaluate frameWidth in the Qt thread
When opening a document via Java UNO without a running LO instance, one
gets the following Qt error messages:
CE> QObject: Cannot create children for a parent that is in a different thread.
CE> (Parent is Oxygen::WidgetStateEngine(0x8deb878), parent's thread is QThread(0x8d6cf70), current thread is QThread(0xa8fa7fc8)
CE> QObject::installEventFilter(): Cannot filter events for objects in a different thread.
CE> QObject::installEventFilter(): Cannot filter events for objects in a different thread.
CE> QObject::installEventFilter(): Cannot filter events for objects in a different thread.
This happens, because the Java UNO call is processed in the first /
Qt thread while document loading happens in a second thread.
Document loading actually just calls getNativeControlRegion, which
should not involve any drawing. But the KDE4 backend does some style
processing to get the correct frame width (QWidget::ensurePolished(),
which uses GUI based events and need to be processed in the Qt
thread.
(cherry picked from commit 7163d64b90ac4d4259b1d0379cfca348dd30601c)
Change-Id: I8a0bf7c22e517bbe163bff1465f88ae422fd8767
diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx
index 967864f..b1a0efe 100644
--- a/vcl/unx/kde4/KDESalGraphics.cxx
+++ b/vcl/unx/kde4/KDESalGraphics.cxx
@@ -31,10 +31,12 @@
#undef Region
#include "KDESalGraphics.hxx"
+#include "KDESalInstance.hxx"
#include <vcl/settings.hxx>
#include <vcl/decoview.hxx>
#include <rtl/ustrbuf.hxx>
+#include <unx/saldata.hxx>
using namespace ::rtl;
@@ -165,21 +167,6 @@ namespace
kapp->style()->drawComplexControl(element, option, &painter);
}
- int getFrameWidth()
- {
- static int s_nFrameWidth = -1;
- if( s_nFrameWidth < 0 )
- {
- // fill in a default
- QFrame aFrame( NULL );
- aFrame.setFrameRect( QRect(0, 0, 100, 30) );
- aFrame.setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
- aFrame.ensurePolished();
- s_nFrameWidth = aFrame.frameWidth();
- }
- return s_nFrameWidth;
- }
-
void lcl_drawFrame(QStyle::PrimitiveElement element, QImage* image, QStyle::State state)
{
#if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) )
@@ -554,7 +541,7 @@ sal_Bool KDESalGraphics::drawNativeControl( ControlType type, ControlPart part,
vclStateValue2StateFlag(nControlState, value) );
// draw just the border, see http://qa.openoffice.org/issues/show_bug.cgi?id=107945
- int fw = getFrameWidth();
+ int fw = static_cast< KDESalInstance* >(GetSalData()->m_pInstance)->getFrameWidth();
clipRegion = new QRegion( QRegion( widgetRect ).subtracted( widgetRect.adjusted( fw, fw, -fw, -fw )));
}
else if (type == CTRL_WINDOW_BACKGROUND)
@@ -843,7 +830,7 @@ sal_Bool KDESalGraphics::getNativeControlRegion( ControlType type, ControlPart p
{
if( part == PART_BORDER )
{
- int nFrameWidth = getFrameWidth();
+ int nFrameWidth = static_cast< KDESalInstance* >(GetSalData()->m_pInstance)->getFrameWidth();
sal_uInt16 nStyle = val.getNumericVal();
if( nStyle & FRAME_DRAW_NODRAW )
{
diff --git a/vcl/unx/kde4/KDESalInstance.cxx b/vcl/unx/kde4/KDESalInstance.cxx
index 224ac3a..9670172 100644
--- a/vcl/unx/kde4/KDESalInstance.cxx
+++ b/vcl/unx/kde4/KDESalInstance.cxx
@@ -38,4 +38,9 @@ uno::Reference< ui::dialogs::XFilePicker2 > KDESalInstance::createFilePicker(
static_cast<KDEXLib*>( mpXLib )->createFilePicker(xMSF) );
}
+int KDESalInstance::getFrameWidth()
+{
+ return static_cast<KDEXLib*>( mpXLib )->getFrameWidth();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/kde4/KDESalInstance.hxx b/vcl/unx/kde4/KDESalInstance.hxx
index 3c07f52..f73af0d 100644
--- a/vcl/unx/kde4/KDESalInstance.hxx
+++ b/vcl/unx/kde4/KDESalInstance.hxx
@@ -36,6 +36,7 @@ class KDESalInstance : public X11SalInstance
virtual com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFilePicker2 >
createFilePicker( const com::sun::star::uno::Reference<
com::sun::star::uno::XComponentContext >& );
+ int getFrameWidth();
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx
index 4a9b70b..f8923c3 100644
--- a/vcl/unx/kde4/KDEXLib.cxx
+++ b/vcl/unx/kde4/KDEXLib.cxx
@@ -65,7 +65,7 @@ KDEXLib::KDEXLib() :
SalXLib(), m_bStartupDone(false), m_pApplication(0),
m_pFreeCmdLineArgs(0), m_pAppCmdLineArgs(0), m_nFakeCmdLineArgs( 0 ),
eventLoopType( LibreOfficeEventLoop ),
- m_bYieldFrozen( false )
+ m_bYieldFrozen( false ), m_frameWidth( -1 )
{
// 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,
@@ -92,6 +92,9 @@ KDEXLib::KDEXLib() :
this, SLOT( createFilePicker( const com::sun::star::uno::Reference<
com::sun::star::uno::XComponentContext >&) ),
Qt::BlockingQueuedConnection );
+
+ connect( this, SIGNAL( getFrameWidthSignal() ),
+ this, SLOT( getFrameWidth() ), Qt::BlockingQueuedConnection );
}
KDEXLib::~KDEXLib()
@@ -445,6 +448,27 @@ uno::Reference< ui::dialogs::XFilePicker2 > KDEXLib::createFilePicker(
return uno::Reference< ui::dialogs::XFilePicker2 >( new KDE4FilePicker( xMSF, this ) );
}
+#define Region QtXRegion
+#include <qframe.h>
+#undef Region
+
+int KDEXLib::getFrameWidth()
+{
+ if( m_frameWidth >= 0 )
+ return m_frameWidth;
+ if( qApp->thread() != QThread::currentThread()) {
+ SalYieldMutexReleaser aReleaser;
+ return Q_EMIT getFrameWidthSignal();
+ }
+
+ // fill in a default
+ QFrame aFrame( NULL );
+ aFrame.setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
+ aFrame.ensurePolished();
+ m_frameWidth = aFrame.frameWidth();
+ return m_frameWidth;
+}
+
#include "KDEXLib.moc"
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx
index d07b9f6..dd7f83f 100644
--- a/vcl/unx/kde4/KDEXLib.hxx
+++ b/vcl/unx/kde4/KDEXLib.hxx
@@ -53,6 +53,7 @@ class KDEXLib : public QObject, public SalXLib
QTimer userEventTimer;
enum { LibreOfficeEventLoop, GlibEventLoop, QtUnixEventLoop } eventLoopType;
bool m_bYieldFrozen;
+ int m_frameWidth;
private:
void setupEventLoop();
@@ -71,6 +72,7 @@ class KDEXLib : public QObject, public SalXLib
com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFilePicker2 >
createFilePickerSignal( const com::sun::star::uno::Reference<
com::sun::star::uno::XComponentContext >& );
+ int getFrameWidthSignal();
public:
KDEXLib();
@@ -89,9 +91,10 @@ class KDEXLib : public QObject, public SalXLib
void doStartup();
public Q_SLOTS:
- virtual com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFilePicker2 >
+ com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XFilePicker2 >
createFilePicker( const com::sun::star::uno::Reference<
com::sun::star::uno::XComponentContext >& );
+ int getFrameWidth();
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list