Make QCoreApplication::applicationName available after app destruction.

Calling applicationName() in the destructor of a global static (e.g.
via QLockFile) was working when calling setApplicationName explicitly
but otherwise it would suddenly return an empty string.
This led to inconsistencies, the application name switching from
non-empty to empty at saving-on-destruction time.

There was already a global static, used when setting the app name
explicitly before construction. Use it now to store the app name
in all cases (explicitly set, or fallback).

Change-Id: I71d3a0c40158f8bfd022c385b198346a2594b1cb
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
David Faure 2015-02-22 19:35:43 +01:00
parent dce3721f90
commit 6c973dee2c
2 changed files with 23 additions and 12 deletions

View File

@ -368,7 +368,9 @@ struct QCoreApplicationData {
}
#endif
QString orgName, orgDomain, application;
QString orgName, orgDomain;
QString application; // application name, initially from argv[0], can then be modified.
QString applicationNameCompat; // for QDesktopServices. Only set explicitly.
QString applicationVersion;
#ifndef QT_NO_LIBRARY
@ -750,6 +752,9 @@ void QCoreApplication::init()
Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object");
QCoreApplication::self = this;
// Store app name (so it's still available after QCoreApplication is destroyed)
coreappdata()->application = d_func()->appName();
QLoggingRegistry::instance()->init();
#ifndef QT_NO_QOBJECT
@ -2345,9 +2350,13 @@ QString QCoreApplication::organizationDomain()
*/
void QCoreApplication::setApplicationName(const QString &application)
{
if (coreappdata()->application == application)
QString newAppName = application;
if (newAppName.isEmpty() && QCoreApplication::self)
newAppName = QCoreApplication::self->d_func()->appName();
if (coreappdata()->application == newAppName)
return;
coreappdata()->application = application;
coreappdata()->application = newAppName;
coreappdata()->applicationNameCompat = newAppName;
#ifndef QT_NO_QOBJECT
if (QCoreApplication::self)
emit QCoreApplication::self->applicationNameChanged();
@ -2359,16 +2368,13 @@ QString QCoreApplication::applicationName()
#ifdef Q_OS_BLACKBERRY
coreappdata()->loadManifest();
#endif
QString appname = coreappdata() ? coreappdata()->application : QString();
if (appname.isEmpty() && QCoreApplication::self)
appname = QCoreApplication::self->d_func()->appName();
return appname;
return coreappdata() ? coreappdata()->application : QString();
}
// Exported for QDesktopServices (Qt4 behavior compatibility)
Q_CORE_EXPORT QString qt_applicationName_noFallback()
{
return coreappdata()->application;
return coreappdata()->applicationNameCompat;
}
/*!

View File

@ -102,10 +102,15 @@ void tst_QCoreApplication::qAppName()
const char* appName = "tst_qcoreapplication";
#endif
int argc = 1;
char *argv[] = { const_cast<char*>(appName) };
TestApplication app(argc, argv);
QCOMPARE(::qAppName(), QString::fromLatin1(appName));
{
int argc = 1;
char *argv[] = { const_cast<char*>(appName) };
TestApplication app(argc, argv);
QCOMPARE(::qAppName(), QString::fromLatin1(appName));
QCOMPARE(QCoreApplication::applicationName(), QString::fromLatin1(appName));
}
// The application name should still be available after destruction;
// global statics often rely on this.
QCOMPARE(QCoreApplication::applicationName(), QString::fromLatin1(appName));
}