summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2017-10-27 11:27:31 +0200
committerThorsten Behrens <Thorsten.Behrens@CIB.de>2017-11-06 12:05:31 +0100
commitc33b45c7e14bf47b857630ce05d38a09ffc7e886 (patch)
treed50bfca09f032d9b8bf6f9714b95bd977cfd6e82 /vcl
parent88945965d55192b3c1b3b62227d3e48f0bfd8da2 (diff)
KF5 correctly initialize QApplication
This turned out more tricky then expected. Originally the KAboutData was assigned to a non-existing QApplication object. Somehow this was prevending the later crashes, if the QApplication was initialized before KAboutData and we were creating QWidgets. The problem turned out to be the referenced arguments to QApplication. While we already passed the command arguments from allocated / heap memory, the argc argument was just the local stack variable! The simple fix is to allocate an int to pass to QApplication and the crashes are gone when assigning KAboutData after QApplication. Also removes some Qt initialization warnings on startup. Change-Id: Ic5b1eea578039fd5875097d23de587b970a6dfca
Diffstat (limited to 'vcl')
-rw-r--r--vcl/unx/kf5/Kf5Instance.cxx100
-rw-r--r--vcl/unx/kf5/Kf5Instance.hxx7
2 files changed, 103 insertions, 4 deletions
diff --git a/vcl/unx/kf5/Kf5Instance.cxx b/vcl/unx/kf5/Kf5Instance.cxx
index b913c79cf64c..4fb218b1ede1 100644
--- a/vcl/unx/kf5/Kf5Instance.cxx
+++ b/vcl/unx/kf5/Kf5Instance.cxx
@@ -20,21 +20,26 @@
#include "Kf5Instance.hxx"
#include <Kf5Instance.moc>
-#include <QtCore/QThread>
-#include <QtWidgets/QApplication>
-#include <QtCore/QAbstractEventDispatcher>
-
#include "Kf5Frame.hxx"
#include "Kf5Data.hxx"
#include "Kf5Timer.hxx"
#include "Kf5VirtualDevice.hxx"
+#include <QtCore/QThread>
+#include <QtWidgets/QApplication>
+#include <QtCore/QAbstractEventDispatcher>
+
#include <vclpluginapi.h>
#include <sal/log.hxx>
+#include <osl/process.h>
#include <headless/svpdummies.hxx>
#include <headless/svpbmp.hxx>
+#include <KAboutData>
+#include <KLocalizedString>
+#include <KStartupInfo>
+
Kf5Instance::Kf5Instance( SalYieldMutex* pMutex )
: SalGenericInstance( pMutex )
, m_postUserEventId( -1 )
@@ -49,6 +54,11 @@ Kf5Instance::Kf5Instance( SalYieldMutex* pMutex )
Kf5Instance::~Kf5Instance()
{
+ // force freeing the QApplication before freeing the arguments,
+ // as it uses references to the provided arguments!
+ m_pQApplication.reset();
+ for( int i = 0; i < *m_pFakeArgc; i++ )
+ free( m_pFakeArgvFreeable[i] );
}
SalFrame* Kf5Instance::CreateChildFrame( SystemParentData* /*pParent*/, SalFrameStyleFlags nStyle )
@@ -190,11 +200,93 @@ extern "C" {
OString aVersion( qVersion() );
SAL_INFO( "vcl.kf5", "qt version string is " << aVersion );
+ QApplication *pQApplication;
+ char **pFakeArgvFreeable = nullptr;
+
+ int nFakeArgc = 2;
+ const sal_uInt32 nParams = osl_getCommandArgCount();
+ OString aDisplay;
+ OUString aParam, aBin;
+
+ for ( sal_uInt32 nIdx = 0; nIdx < nParams; ++nIdx )
+ {
+ osl_getCommandArg( nIdx, &aParam.pData );
+ if ( aParam != "-display" )
+ continue;
+ if ( !pFakeArgvFreeable )
+ {
+ pFakeArgvFreeable = new char*[ nFakeArgc + 2 ];
+ pFakeArgvFreeable[ nFakeArgc++ ] = strdup( "-display" );
+ }
+ else
+ free( pFakeArgvFreeable[ nFakeArgc ] );
+
+ ++nIdx;
+ osl_getCommandArg( nIdx, &aParam.pData );
+ aDisplay = OUStringToOString( aParam, osl_getThreadTextEncoding() );
+ pFakeArgvFreeable[ nFakeArgc ] = strdup( aDisplay.getStr() );
+ }
+ if ( !pFakeArgvFreeable )
+ pFakeArgvFreeable = new char*[ nFakeArgc ];
+ else
+ nFakeArgc++;
+
+ osl_getExecutableFile( &aParam.pData );
+ osl_getSystemPathFromFileURL( aParam.pData, &aBin.pData );
+ OString aExec = OUStringToOString( aBin, osl_getThreadTextEncoding() );
+ pFakeArgvFreeable[ 0 ] = strdup( aExec.getStr() );
+ pFakeArgvFreeable[ 1 ] = strdup( "--nocrashhandler" );
+
+ char **pFakeArgv = new char*[ nFakeArgc ];
+ for( int i = 0; i < nFakeArgc; i++ )
+ pFakeArgv[ i ] = pFakeArgvFreeable[ i ];
+
+ char* session_manager = nullptr;
+ if( getenv( "SESSION_MANAGER" ) != nullptr )
+ {
+ session_manager = strdup( getenv( "SESSION_MANAGER" ));
+ unsetenv( "SESSION_MANAGER" );
+ }
+
+ int * pFakeArgc = new int;
+ *pFakeArgc = nFakeArgc;
+ pQApplication = new QApplication( *pFakeArgc, pFakeArgv );
+
+ if( session_manager != nullptr )
+ {
+ // coverity[tainted_string] - trusted source for setenv
+ setenv( "SESSION_MANAGER", session_manager, 1 );
+ free( session_manager );
+ }
+
+ KAboutData *kAboutData = new KAboutData( I18N_NOOP("LibreOffice"),
+ i18n( "LibreOffice" ),
+ "6.0.0",
+ i18n( "LibreOffice with KF5 Native Widget Support." ),
+ KAboutLicense::File,
+ i18n("Copyright (c) 2017 LibreOffice contributors" ),
+ i18n( "LibreOffice is an office suite." ),
+ "http://libreoffice.org",
+ QLatin1String("libreoffice@lists.freedesktop.org") );
+
+ kAboutData->addAuthor( i18n( "Jan-Marek Glogowski" ),
+ i18n( "Original author and maintainer of the KF5 NWF." ),
+ "glogow@fbihome.de" );
+
+ KAboutData::setApplicationData( *kAboutData );
+
+ QApplication::setQuitOnLastWindowClosed(false);
+
Kf5Instance* pInstance = new Kf5Instance( new SalYieldMutex() );
// initialize SalData
new Kf5Data( pInstance );
+ pInstance->m_pQApplication.reset( pQApplication );
+ pInstance->m_pFakeArgvFreeable.reset( pFakeArgvFreeable );
+ pInstance->m_pFakeArgv.reset( pFakeArgv );
+ pInstance->m_pFakeArgc.reset( pFakeArgc );
+
return pInstance;
}
}
diff --git a/vcl/unx/kf5/Kf5Instance.hxx b/vcl/unx/kf5/Kf5Instance.hxx
index 6c1d846cfeb5..98cfa31c1579 100644
--- a/vcl/unx/kf5/Kf5Instance.hxx
+++ b/vcl/unx/kf5/Kf5Instance.hxx
@@ -26,6 +26,7 @@
#include <QtCore/QObject>
+class QApplication;
class SalYieldMutex;
class SalFrame;
@@ -39,6 +40,12 @@ class Kf5Instance
osl::Condition m_aWaitingYieldCond;
int m_postUserEventId;
+public:
+ std::unique_ptr< QApplication > m_pQApplication;
+ std::unique_ptr< char*[] > m_pFakeArgvFreeable;
+ std::unique_ptr< char*[] > m_pFakeArgv;
+ std::unique_ptr< int > m_pFakeArgc;
+
private Q_SLOTS:
bool ImplYield( bool bWait, bool bHandleAllCurrentEvents );