15#include <private/qproperty_p.h>
16#include <qdatastream.h>
22#include <private/qloggingregistry_p.h>
23#include <qscopeguard.h>
24#include <qstandardpaths.h>
27#include <qthreadstorage.h>
29#include <QtCore/qpromise.h>
31#include <private/qthread_p.h>
33#include <qthreadpool.h>
34#include <private/qthreadpool_p.h>
37#include <qlibraryinfo.h>
39#include <qvarlengtharray.h>
40#include <private/qfactoryloader_p.h>
41#include <private/qfunctions_p.h>
42#include <private/qlocale_p.h>
43#include <private/qlocking_p.h>
44#include <private/qhooks_p.h>
45#include <private/qnativeinterface_p.h>
47#if QT_CONFIG(permissions)
48#include <private/qpermissions_p.h>
53# if defined(Q_OS_DARWIN)
54# include "qeventdispatcher_cf_p.h"
56# if !defined(QT_NO_GLIB)
57# include "qeventdispatcher_glib_p.h"
60# if !defined(Q_OS_WASM)
61# include "qeventdispatcher_unix_p.h"
65#include "qeventdispatcher_win_p.h"
69#if defined(Q_OS_ANDROID)
70#include <QtCore/qjniobject.h>
74# include "qcore_mac_p.h"
81# ifndef Q_OS_INTEGRITY
85# include <sys/types.h>
87# include "qcore_unix_p.h"
99#include <emscripten/val.h>
102#ifdef QT_BOOTSTRAPPED
103#include <private/qtrace_p.h>
105#include <qtcore_tracepoints_p.h>
113# include <qt_windows.h>
122using namespace Qt::StringLiterals;
125 "#include <qcoreevent.h>"
137#if defined(Q_OS_WIN) || defined(Q_OS_DARWIN)
138extern QString qAppFileName();
141Q_CONSTINIT
bool QCoreApplicationPrivate::setuidAllowed =
false;
144Q_CONSTINIT
static QBasicAtomicPointer<QCoreApplication> g_self =
nullptr;
146# define qApp g_self.loadRelaxed()
148#if !defined(Q_OS_WIN)
150QString QCoreApplicationPrivate::infoDictionaryStringProperty(
const QString &propertyName)
153 QCFString cfPropertyName = propertyName.toCFString();
154 CFTypeRef string = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
157 bundleName = QString::fromCFString(
static_cast<CFStringRef>(string));
161QString QCoreApplicationPrivate::appName()
const
163 QString applicationName;
165 applicationName = infoDictionaryStringProperty(QStringLiteral(
"CFBundleName"));
167 if (applicationName.isEmpty() && argv[0]) {
168 char *p = strrchr(argv[0],
'/');
169 applicationName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
172 return applicationName;
174QString QCoreApplicationPrivate::appVersion()
const
176 QString applicationVersion;
177#ifdef QT_BOOTSTRAPPED
178#elif defined(Q_OS_DARWIN)
179 applicationVersion = infoDictionaryStringProperty(QStringLiteral(
"CFBundleVersion"));
180#elif defined(Q_OS_ANDROID)
181 QJniObject context(QNativeInterface::QAndroidApplication::context());
182 if (context.isValid()) {
183 QJniObject pm = context.callObjectMethod(
184 "getPackageManager",
"()Landroid/content/pm/PackageManager;");
185 QJniObject pn = context.callObjectMethod<jstring>(
"getPackageName");
186 if (pm.isValid() && pn.isValid()) {
187 QJniObject packageInfo = pm.callObjectMethod(
188 "getPackageInfo",
"(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;",
190 if (packageInfo.isValid()) {
191 QJniObject versionName = packageInfo.getObjectField(
192 "versionName",
"Ljava/lang/String;");
193 if (versionName.isValid())
194 return versionName.toString();
199 return applicationVersion;
205bool QCoreApplicationPrivate::checkInstance(
const char *function)
207 bool b = (
qApp !=
nullptr);
209 qWarning(
"QApplication::%s: Please instantiate the QApplication object first", function);
213#if QT_CONFIG(commandlineparser)
214void QCoreApplicationPrivate::addQtOptions(QList<QCommandLineOption> *options)
216 options->append(QCommandLineOption(QStringLiteral(
"qmljsdebugger"),
217 QStringLiteral(
"Activates the QML/JS debugger with a specified port. The value must be of format port:1234[,block]. \"block\" makes the application wait for a connection."),
218 QStringLiteral(
"value")));
222void QCoreApplicationPrivate::processCommandLineArguments()
224 int j = argc ? 1 : 0;
225 for (
int i = 1; i < argc; ++i) {
228 if (*argv[i] !=
'-') {
232 const char *arg = argv[i];
235 if (strncmp(arg,
"-qmljsdebugger=", 15) == 0) {
236 qmljs_debug_arguments = QString::fromLocal8Bit(arg + 15);
237 }
else if (strcmp(arg,
"-qmljsdebugger") == 0 && i < argc - 1) {
239 qmljs_debug_arguments = QString::fromLocal8Bit(argv[i]);
264Q_GLOBAL_STATIC(QVFuncList, postRList)
265Q_CONSTINIT
static QBasicMutex globalRoutinesMutex;
269
270
271
272
273
281 Q_ASSERT(QCoreApplication::instance());
287 const auto locker = qt_scoped_lock(globalRoutinesMutex);
296 const auto locker = qt_scoped_lock(globalRoutinesMutex);
305 const auto locker = qt_scoped_lock(globalRoutinesMutex);
314 if (!preRList.exists())
318 const auto locker = qt_scoped_lock(globalRoutinesMutex);
325 for (QtStartUpFunction f : list)
329void Q_CORE_EXPORT qt_call_post_routines()
331 if (!postRList.exists())
338 const auto locker = qt_scoped_lock(globalRoutinesMutex);
339 qSwap(*postRList, list);
344 for (QtCleanUpFunction f : std::as_const(list))
353Q_CONSTINIT
bool QCoreApplicationPrivate::is_app_running =
false;
355Q_CONSTINIT
bool QCoreApplicationPrivate::is_app_closing =
false;
360 return l.size() - l.startOffset;
367Q_CONSTINIT uint QCoreApplicationPrivate::attribs =
368 (1 << Qt::AA_SynthesizeMouseForUnhandledTouchEvents) |
369 (1 << Qt::AA_SynthesizeMouseForUnhandledTabletEvents);
378#if !defined(QT_NO_QOBJECT) && defined(Q_OS_WIN)
381 if (
auto *t = QCoreApplicationPrivate::theMainThread.loadAcquire()) {
382 QThreadData *data = QThreadData::get2(t);
394#if QT_CONFIG(library)
401Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
404Q_CONSTINIT
static bool quitLockEnabled =
true;
413static inline bool isArgvModified(
int argc,
char **argv)
415 if (__argc != argc || !__argv )
419 for (
int a = 0; a < argc; ++a) {
420 if (argv[a] != __argv[a] && strcmp(argv[a], __argv[a]))
426static inline bool contains(
int argc,
char **argv,
const char *needle)
428 for (
int a = 0; a < argc; ++a) {
429 if (!strcmp(argv[a], needle))
436QCoreApplicationPrivate::QCoreApplicationPrivate(
int &aargc,
char **aargv)
447 , application_type(QCoreApplicationPrivate::Tty)
450 , aboutToQuitEmitted(
false)
451 , threadData_clean(
false)
456 static const char *
const empty =
"";
457 if (argc == 0 || argv ==
nullptr) {
459 argv =
const_cast<
char **>(&empty);
462 if (!isArgvModified(argc, argv)) {
464 origArgv =
new char *[argc];
465 std::copy(argv, argv + argc, QT_MAKE_CHECKED_ARRAY_ITERATOR(origArgv, argc));
470 QCoreApplicationPrivate::is_app_closing =
false;
472# if defined(Q_OS_UNIX)
473 if (Q_UNLIKELY(!setuidAllowed && (geteuid() != getuid())))
474 qFatal(
"FATAL: The application binary appears to be running setuid, this is a security hole.");
477 QThread *cur = QThread::currentThread();
478 if (cur != theMainThread.loadAcquire())
479 qWarning(
"WARNING: QApplication was not created in the main() thread.");
483QCoreApplicationPrivate::~QCoreApplicationPrivate()
490 cleanupDebuggingConsole();
492 QCoreApplicationPrivate::clearApplicationFilePath();
497void QCoreApplicationPrivate::cleanupThreadData()
499 auto thisThreadData = threadData.loadRelaxed();
501 if (thisThreadData && !threadData_clean) {
503 void *data = &thisThreadData->tls;
504 QThreadStorageData::finish((
void **)data);
508 const auto locker = qt_scoped_lock(thisThreadData->postEventList.mutex);
509 for (
const QPostEvent &pe : std::as_const(thisThreadData->postEventList)) {
511 --pe.receiver->d_func()->postedEvents;
512 pe.event->m_posted =
false;
516 thisThreadData->postEventList.clear();
517 thisThreadData->postEventList.recursion = 0;
518 thisThreadData->quitNow =
false;
519 threadData_clean =
true;
523void QCoreApplicationPrivate::createEventDispatcher()
525 Q_Q(QCoreApplication);
526 QThreadData *data = QThreadData::current();
527 Q_ASSERT(!data->hasEventDispatcher());
528 eventDispatcher = data->createEventDispatcher();
529 eventDispatcher->setParent(q);
532void QCoreApplicationPrivate::eventDispatcherReady()
536Q_CONSTINIT QBasicAtomicPointer<QThread> QCoreApplicationPrivate::theMainThread = Q_BASIC_ATOMIC_INITIALIZER(
nullptr);
537Q_CONSTINIT QBasicAtomicPointer<
void> QCoreApplicationPrivate::theMainThreadId = Q_BASIC_ATOMIC_INITIALIZER(
nullptr);
538QThread *QCoreApplicationPrivate::mainThread()
540 Q_ASSERT(theMainThread.loadRelaxed() !=
nullptr);
541 return theMainThread.loadRelaxed();
544bool QCoreApplicationPrivate::threadRequiresCoreApplication()
546 QThreadData *data = QThreadData::current(
false);
549 return data->requiresCoreApplication;
552void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
554 QThread *currentThread = QThread::currentThread();
555 QThread *thr = receiver->thread();
556 Q_ASSERT_X(currentThread == thr || !thr,
557 "QCoreApplication::sendEvent",
558 qPrintable(QString::fromLatin1(
"Cannot send events to objects owned by a different thread. "
559 "Current thread %1. Receiver '%2' was created in thread %3").arg(
560 QDebug::toString(currentThread), QDebug::toString(receiver), QDebug::toString(thr))));
561 Q_UNUSED(currentThread);
567void QCoreApplicationPrivate::appendApplicationPathToLibraryPaths()
569#if QT_CONFIG(library)
570 QStringList *app_libpaths = coreappdata()->app_libpaths.get();
572 coreappdata()->app_libpaths.reset(app_libpaths =
new QStringList);
573 QString app_location = QCoreApplication::applicationFilePath();
574 app_location.truncate(app_location.lastIndexOf(u'/'));
575 app_location = QDir(app_location).canonicalPath();
576 if (QFile::exists(app_location) && !app_libpaths->contains(app_location))
577 app_libpaths->append(app_location);
583 if (!QCoreApplicationPrivate::checkInstance(
"qAppName"))
585 return QCoreApplication::instance()->d_func()->appName();
588void QCoreApplicationPrivate::initLocale()
590#if defined(QT_BOOTSTRAPPED)
592#elif defined(Q_OS_UNIX)
593 Q_CONSTINIT
static bool qt_locale_initialized =
false;
594 if (qt_locale_initialized)
596 qt_locale_initialized =
true;
601 setlocale(LC_ALL,
"");
605# if defined(Q_OS_INTEGRITY)
606 setlocale(LC_CTYPE,
"UTF-8");
607# elif defined(Q_OS_QNX)
610# elif defined(Q_OS_ANDROID) && __ANDROID_API__ < __ANDROID_API_O__
613# elif defined(Q_OS_VXWORKS)
617 const std::string oldEncoding = nl_langinfo(CODESET);
618 if (!Q_LIKELY(qstricmp(oldEncoding.data(),
"UTF-8") == 0
619 || qstricmp(oldEncoding.data(),
"utf8") == 0)) {
620 const QByteArray oldLocale = setlocale(LC_ALL,
nullptr);
621 QByteArray newLocale;
622 bool warnOnOverride =
true;
623# if defined(Q_OS_DARWIN)
627 warnOnOverride = qstrcmp(setlocale(LC_CTYPE,
nullptr),
"C") != 0
628 || getenv(
"LC_ALL") || getenv(
"LC_CTYPE") || getenv(
"LANG");
632 newLocale = setlocale(LC_CTYPE,
"UTF-8");
634 newLocale = setlocale(LC_CTYPE,
nullptr);
635 if (qsizetype dot = newLocale.indexOf(
'.'); dot != -1)
636 newLocale.truncate(dot);
637 if (qsizetype at = newLocale.indexOf(
'@'); at != -1)
638 newLocale.truncate(at);
639 newLocale +=
".UTF-8";
640 newLocale = setlocale(LC_CTYPE, newLocale);
643 if (newLocale.isEmpty())
644 newLocale = setlocale(LC_CTYPE,
"C.UTF-8");
645 if (newLocale.isEmpty())
646 newLocale = setlocale(LC_CTYPE,
"C.utf8");
649 if (newLocale.isEmpty()) {
651 qWarning(
"Detected locale \"%s\" with character encoding \"%s\", which is not UTF-8.\n"
652 "Qt depends on a UTF-8 locale, but has failed to switch to one.\n"
653 "If this causes problems, reconfigure your locale. See the locale(1) manual\n"
654 "for more information.", oldLocale.constData(), oldEncoding.data());
655 }
else if (warnOnOverride) {
657 qWarning(
"Detected locale \"%s\" with character encoding \"%s\", which is not UTF-8.\n"
658 "Qt depends on a UTF-8 locale, and has switched to \"%s\" instead.\n"
659 "If this causes problems, reconfigure your locale. See the locale(1) manual\n"
660 "for more information.",
661 oldLocale.constData(), oldEncoding.data(), newLocale.constData());
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
746
747
748
749
750
751
752
755
756
757QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
761 : QObject(p,
nullptr)
764 d_func()->q_ptr =
this;
770
771
772
773
774
775
776
777
778
779
780
781
782
783QCoreApplication::QCoreApplication(
int &argc,
char **argv
789 : d_ptr(
new QCoreApplicationPrivate(argc, argv))
791 : QObject(*
new QCoreApplicationPrivate(argc, argv))
794 d_func()->q_ptr =
this;
797 QCoreApplicationPrivate::eventDispatcher->startingUp();
802
803
804
805
806
808void Q_TRACE_INSTRUMENT(qtcore) QCoreApplicationPrivate::init()
810 Q_TRACE_SCOPE(QCoreApplicationPrivate_init);
812#if defined(Q_OS_MACOS)
813 QMacAutoReleasePool pool;
816 Q_Q(QCoreApplication);
819 initDebuggingConsole();
824 Q_ASSERT_X(!QCoreApplication::self,
"QCoreApplication",
"there should be only one application object");
825 QCoreApplication::self = q;
826 g_self.storeRelaxed(q);
830 emscripten::val hardwareConcurrency = emscripten::val::global(
"navigator")[
"hardwareConcurrency"];
831 if (hardwareConcurrency.isUndefined())
832 QThreadPrivate::idealThreadCount = 2;
834 QThreadPrivate::idealThreadCount = hardwareConcurrency.as<
int>();
839 if (!coreappdata()->applicationNameSet)
840 coreappdata()->application = appName();
842 if (!coreappdata()->applicationVersionSet)
843 coreappdata()->applicationVersion = appVersion();
845#if defined(Q_OS_ANDROID)
850 QLoggingRegistry::instance()->initializeRules();
853#if QT_CONFIG(library)
857 QStringList *appPaths = coreappdata()->app_libpaths.release();
858 QStringList *manualPaths = coreappdata()->manual_libpaths.release();
865 QStringList newPaths(q->libraryPaths());
866 for (qsizetype i = manualPaths->size(), j = appPaths->size(); i > 0 || j > 0; qt_noop()) {
868 newPaths.prepend((*manualPaths)[--i]);
869 }
else if (--i < 0) {
870 newPaths.removeAll((*appPaths)[j]);
871 }
else if ((*manualPaths)[i] != (*appPaths)[j]) {
872 newPaths.removeAll((*appPaths)[j]);
877 coreappdata()->manual_libpaths.reset(
new QStringList(newPaths));
885 Q_ASSERT(!eventDispatcher);
886 auto thisThreadData = threadData.loadRelaxed();
887 eventDispatcher = thisThreadData->eventDispatcher.loadRelaxed();
890 if (!eventDispatcher)
891 createEventDispatcher();
892 Q_ASSERT(eventDispatcher);
894 if (!eventDispatcher->parent()) {
895 eventDispatcher->moveToThread(thisThreadData->thread.loadAcquire());
896 eventDispatcher->setParent(q);
899 thisThreadData->eventDispatcher = eventDispatcher;
900 eventDispatcherReady();
903 processCommandLineArguments();
905 qt_call_pre_routines();
907#ifndef QT_BOOTSTRAPPED
908 QtPrivate::initBindingStatusThreadId();
909 if (Q_UNLIKELY(qtHookData[QHooks::Startup]))
910 reinterpret_cast<QHooks::StartupCallback>(qtHookData[QHooks::Startup])();
914 is_app_running =
true;
919
920
921QCoreApplication::~QCoreApplication()
923 preRoutinesCalled =
false;
925 qt_call_post_routines();
928 g_self.storeRelaxed(
nullptr);
930 QCoreApplicationPrivate::is_app_closing =
true;
931 QCoreApplicationPrivate::is_app_running =
false;
936 QThreadPool *globalThreadPool =
nullptr;
937 QThreadPool *guiThreadPool =
nullptr;
939 globalThreadPool = QThreadPool::globalInstance();
940 guiThreadPool = QThreadPoolPrivate::qtGuiInstance();
944 if (globalThreadPool) {
945 globalThreadPool->waitForDone();
946 delete globalThreadPool;
949 guiThreadPool->waitForDone();
950 delete guiThreadPool;
955 d_func()->threadData.loadRelaxed()->eventDispatcher =
nullptr;
956 if (QCoreApplicationPrivate::eventDispatcher)
957 QCoreApplicationPrivate::eventDispatcher->closingDown();
958 QCoreApplicationPrivate::eventDispatcher =
nullptr;
961#if QT_CONFIG(library)
962 coreappdata()->app_libpaths.reset();
963 coreappdata()->manual_libpaths.reset();
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990void QCoreApplication::setSetuidAllowed(
bool allow)
992 QCoreApplicationPrivate::setuidAllowed = allow;
996
997
998
999
1000
1001
1002
1003bool QCoreApplication::isSetuidAllowed()
1005 return QCoreApplicationPrivate::setuidAllowed;
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute,
bool on)
1022 static_assert(Qt::AA_AttributeCount <=
sizeof(QCoreApplicationPrivate::attribs) * CHAR_BIT);
1025 QCoreApplicationPrivate::attribs |= 1 << attribute;
1027 QCoreApplicationPrivate::attribs &= ~(1 << attribute);
1028#if defined(QT_NO_QOBJECT)
1029 if (Q_UNLIKELY(qApp)) {
1031 if (Q_UNLIKELY(QCoreApplicationPrivate::is_app_running)) {
1033 switch (attribute) {
1034 case Qt::AA_PluginApplication:
1035 case Qt::AA_UseDesktopOpenGL:
1036 case Qt::AA_UseOpenGLES:
1037 case Qt::AA_UseSoftwareOpenGL:
1038 case Qt::AA_ShareOpenGLContexts:
1039#ifdef QT_BOOTSTRAPPED
1040 qWarning(
"Attribute %d must be set before QCoreApplication is created.",
1043 qWarning(
"Attribute Qt::%s must be set before QCoreApplication is created.",
1044 QMetaEnum::fromType<Qt::ApplicationAttribute>().valueToKey(attribute));
1054
1055
1056
1057
1058
1059bool QCoreApplication::testAttribute(Qt::ApplicationAttribute attribute)
1061 return QCoreApplicationPrivate::testAttribute(attribute);
1064#ifndef QT_NO_QOBJECT
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1085bool QCoreApplication::isQuitLockEnabled()
1087 return quitLockEnabled;
1090static bool doNotify(QObject *, QEvent *);
1092void QCoreApplication::setQuitLockEnabled(
bool enabled)
1094 quitLockEnabled = enabled;
1098
1099
1100
1101
1102
1103
1104bool QCoreApplication::notifyInternal2(QObject *receiver, QEvent *event)
1106 bool selfRequired = QCoreApplicationPrivate::threadRequiresCoreApplication();
1107 if (selfRequired && !
qApp)
1112 bool result =
false;
1113 void *cbdata[] = { receiver, event, &result };
1114 if (QInternal::activateCallbacks(QInternal::EventNotifyCallback, cbdata)) {
1122 QObjectPrivate *d = receiver->d_func();
1123 QThreadData *threadData = d->threadData.loadAcquire();
1124 QScopedScopeLevelCounter scopeLevelCounter(threadData);
1126 return doNotify(receiver, event);
1128#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
)
1129 if (!QThread::isMainThread())
1132 return qApp->notify(receiver, event);
1136
1137
1138
1139
1140
1141
1142bool QCoreApplication::forwardEvent(QObject *receiver, QEvent *event, QEvent *originatingEvent)
1144 if (event && originatingEvent)
1145 event->m_spont = originatingEvent->m_spont;
1147 return notifyInternal2(receiver, event);
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1203bool QCoreApplication::notify(QObject *receiver, QEvent *event)
1208#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
)
1209 Q_ASSERT(receiver->d_func()->threadData.loadAcquire()->thread.loadRelaxed()
1210 == QCoreApplicationPrivate::mainThread());
1214 if (QCoreApplicationPrivate::is_app_closing)
1216 return doNotify(receiver, event);
1219static bool doNotify(QObject *receiver, QEvent *event)
1224 if (receiver ==
nullptr) {
1225 qWarning(
"QCoreApplication::notify: Unexpected null receiver");
1230 QCoreApplicationPrivate::checkReceiverThread(receiver);
1233 return receiver->isWidgetType() ?
false : QCoreApplicationPrivate::notify_helper(receiver, event);
1236bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
1239 Q_ASSERT(QThread::isMainThread());
1243 for (qsizetype i = 0; i < extraData->eventFilters.size(); ++i) {
1244 QObject *obj = extraData->eventFilters.at(i);
1247 if (obj->d_func()->threadData.loadRelaxed() != threadData.loadRelaxed()) {
1248 qWarning(
"QCoreApplication: Application event filter cannot be in a different thread.");
1251 if (obj->eventFilter(receiver, event))
1258bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event)
1260 if (receiver !=
qApp && receiver->d_func()->extraData) {
1261 for (qsizetype i = 0; i < receiver->d_func()->extraData->eventFilters.size(); ++i) {
1262 QObject *obj = receiver->d_func()->extraData->eventFilters.at(i);
1265 if (obj->d_func()->threadData.loadRelaxed() != receiver->d_func()->threadData.loadRelaxed()) {
1266 qWarning(
"QCoreApplication: Object event filter cannot be in a different thread.");
1269 if (obj->eventFilter(receiver, event))
1277
1278
1279
1280
1281bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
1285 Q_TRACE(QCoreApplication_notify_entry, receiver, event, event->type());
1286 bool consumed =
false;
1287 bool filtered =
false;
1288 Q_TRACE_EXIT(QCoreApplication_notify_exit, consumed, filtered);
1291 if (QThread::isMainThread()
1292 && QCoreApplication::self
1293 && QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) {
1298 if (sendThroughObjectEventFilters(receiver, event)) {
1304 consumed = receiver->event(event);
1309
1310
1311
1312
1313
1315bool QCoreApplication::startingUp()
1317 return !QCoreApplicationPrivate::is_app_running;
1321
1322
1323
1324
1325
1327bool QCoreApplication::closingDown()
1329 return QCoreApplicationPrivate::is_app_closing;
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
1364 QThreadData *data = QThreadData::current();
1365 if (!data->hasEventDispatcher())
1367 data->eventDispatcher.loadRelaxed()->processEvents(flags);
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags,
int ms)
1384 QCoreApplication::processEvents(flags, QDeadlineTimer(ms));
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, QDeadlineTimer deadline)
1416 QThreadData *data = QThreadData::current();
1417 if (!data->hasEventDispatcher())
1420 while (data->eventDispatcher.loadRelaxed()->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) {
1421 if (deadline.hasExpired())
1427
1428
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456int QCoreApplication::exec()
1458 if (!QCoreApplicationPrivate::checkInstance(
"exec"))
1461 QThreadData *threadData = self->d_func()->threadData.loadAcquire();
1462 if (threadData != QThreadData::current()) {
1463 qWarning(
"%s::exec: Must be called from the main thread", self->metaObject()->className());
1466 if (!threadData->eventLoops.isEmpty()) {
1467 qWarning(
"QCoreApplication::exec: The event loop is already running");
1471 threadData->quitNow =
false;
1472 QEventLoop eventLoop;
1473 self->d_func()->in_exec =
true;
1474 self->d_func()->aboutToQuitEmitted =
false;
1475 int returnCode = eventLoop.exec(QEventLoop::ApplicationExec);
1476 threadData->quitNow =
false;
1479 self->d_func()->execCleanup();
1490void QCoreApplicationPrivate::execCleanup()
1492 threadData.loadRelaxed()->quitNow =
false;
1495 qCDebug(lcDeleteLater) <<
"Sending deferred delete events as part of exec cleanup";
1496 QCoreApplication::sendPostedEvents(
nullptr, QEvent::DeferredDelete);
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530void QCoreApplication::exit(
int returnCode)
1534 QCoreApplicationPrivate *d = self->d_func();
1535 if (!d->aboutToQuitEmitted) {
1536 emit self->aboutToQuit(QCoreApplication::QPrivateSignal());
1537 d->aboutToQuitEmitted =
true;
1539 QThreadData *data = d->threadData.loadRelaxed();
1540 data->quitNow =
true;
1541 for (qsizetype i = 0; i < data->eventLoops.size(); ++i) {
1542 QEventLoop *eventLoop = data->eventLoops.at(i);
1543 eventLoop->exit(returnCode);
1548
1549
1551#ifndef QT_NO_QOBJECT
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
1568 Q_ASSERT_X(receiver,
"QCoreApplication::sendEvent",
"Unexpected null receiver");
1569 Q_ASSERT_X(event,
"QCoreApplication::sendEvent",
"Unexpected null event");
1571 Q_TRACE(QCoreApplication_sendEvent, receiver, event, event->type());
1573 event->m_spont =
false;
1574 return notifyInternal2(receiver, event);
1578
1579
1580bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent *event)
1582 Q_ASSERT_X(receiver,
"QCoreApplication::sendSpontaneousEvent",
"Unexpected null receiver");
1583 Q_ASSERT_X(event,
"QCoreApplication::sendSpontaneousEvent",
"Unexpected null event");
1585 Q_TRACE(QCoreApplication_sendSpontaneousEvent, receiver, event, event->type());
1587 event->m_spont =
true;
1588 return notifyInternal2(receiver, event);
1593QCoreApplicationPrivate::QPostEventListLocker QCoreApplicationPrivate::lockThreadPostEventList(QObject *object)
1595 QPostEventListLocker locker;
1598 locker.threadData = QThreadData::current();
1599 locker.locker = qt_unique_lock(locker.threadData->postEventList.mutex);
1603 auto &threadData = QObjectPrivate::get(object)->threadData;
1608 locker.threadData = threadData.loadAcquire();
1609 if (!locker.threadData) {
1614 auto temporaryLocker = qt_unique_lock(locker.threadData->postEventList.mutex);
1615 if (locker.threadData == threadData.loadAcquire()) {
1616 locker.locker = std::move(temporaryLocker);
1621 Q_ASSERT(locker.threadData);
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650void QCoreApplication::postEvent(QObject *receiver, QEvent *event,
int priority)
1652 Q_ASSERT_X(event,
"QCoreApplication::postEvent",
"Unexpected null event");
1654 Q_TRACE_SCOPE(QCoreApplication_postEvent, receiver, event, event->type());
1657 if (receiver ==
nullptr) {
1658 qWarning(
"QCoreApplication::postEvent: Unexpected null receiver");
1663 auto locker = QCoreApplicationPrivate::lockThreadPostEventList(receiver);
1664 if (!locker.threadData) {
1670 QThreadData *data = locker.threadData;
1673 if (receiver->d_func()->postedEvents
1674 && self && self->compressEvent(event, receiver, &data->postEventList)) {
1675 Q_TRACE(QCoreApplication_postEvent_event_compressed, receiver, event);
1681 std::unique_ptr<QEvent> eventDeleter(event);
1682 Q_TRACE(QCoreApplication_postEvent_event_posted, receiver, event, event->type());
1683 data->postEventList.addEvent(QPostEvent(receiver, event, priority));
1684 Q_UNUSED(eventDeleter.release());
1685 event->m_posted =
true;
1686 ++receiver->d_func()->postedEvents;
1687 data->canWait =
false;
1690 QAbstractEventDispatcher* dispatcher = data->eventDispatcher.loadAcquire();
1692 dispatcher->wakeUp();
1696
1697
1698
1699bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
1703 Q_ASSERT(postedEvents);
1706 if (event->type() == QEvent::Timer) {
1707 const int timerId =
static_cast<QTimerEvent *>(event)->timerId();
1708 auto it = postedEvents->cbegin();
1709 const auto end = postedEvents->cend();
1711 if (it->event && it->event->type() == QEvent::Timer && it->receiver == receiver) {
1712 if (
static_cast<QTimerEvent *>(it->event)->timerId() == timerId) {
1722 if (event->type() == QEvent::Quit) {
1723 for (
const QPostEvent &cur : std::as_const(*postedEvents)) {
1724 if (cur.receiver != receiver
1725 || cur.event ==
nullptr
1726 || cur.event->type() != event->type())
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754void QCoreApplication::sendPostedEvents(QObject *receiver,
int event_type)
1759 QThreadData *data = QThreadData::current();
1761 QCoreApplicationPrivate::sendPostedEvents(receiver, event_type, data);
1764void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver,
int event_type,
1767 if (event_type == -1) {
1772 if (receiver && receiver->d_func()->threadData.loadRelaxed() != data) {
1773 qWarning(
"QCoreApplication::sendPostedEvents: Cannot send "
1774 "posted events for objects in another thread");
1778 ++data->postEventList.recursion;
1780 auto locker = qt_unique_lock(data->postEventList.mutex);
1785 data->canWait = (data->postEventList.size() == 0);
1787 if (data->postEventList.size() == 0 || (receiver && !receiver->d_func()->postedEvents)) {
1788 --data->postEventList.recursion;
1792 data->canWait =
true;
1796 qsizetype startOffset = data->postEventList.startOffset;
1797 qsizetype &i = (!event_type && !receiver) ? data->postEventList.startOffset : startOffset;
1798 data->postEventList.insertionOffset = data->postEventList.size();
1802 Q_DISABLE_COPY_MOVE(CleanUp)
1807 bool exceptionCaught;
1809 inline CleanUp(QObject *receiver,
int event_type, QThreadData *data) :
1810 receiver(receiver), event_type(event_type), data(data), exceptionCaught(
true)
1814 if (exceptionCaught) {
1816 data->canWait =
false;
1819 --data->postEventList.recursion;
1820 if (!data->postEventList.recursion && !data->canWait && data->hasEventDispatcher())
1821 data->eventDispatcher.loadRelaxed()->wakeUp();
1825 if (!event_type && !receiver && data->postEventList.startOffset >= 0) {
1826 const QPostEventList::iterator it = data->postEventList.begin();
1827 data->postEventList.erase(it, it + data->postEventList.startOffset);
1828 data->postEventList.insertionOffset -= data->postEventList.startOffset;
1829 Q_ASSERT(data->postEventList.insertionOffset >= 0);
1830 data->postEventList.startOffset = 0;
1834 CleanUp cleanup(receiver, event_type, data);
1836 while (i < data->postEventList.size()) {
1838 if (i >= data->postEventList.insertionOffset)
1841 const QPostEvent &pe = data->postEventList.at(i);
1846 if ((receiver && receiver != pe.receiver) || (event_type && event_type != pe.event->type())) {
1847 data->canWait =
false;
1851 if (pe.event->type() == QEvent::DeferredDelete) {
1858 const auto *event =
static_cast<QDeferredDeleteEvent *>(pe.event);
1859 qCDebug(lcDeleteLater) <<
"Processing deferred delete event for" << pe.receiver
1860 <<
"with loop level" << event->loopLevel() <<
"and scope level" << event->scopeLevel();
1862 qCDebug(lcDeleteLater) <<
"Checking" << data->thread <<
"with loop level"
1863 << data->loopLevel <<
"and scope level" << data->scopeLevel;
1865 bool allowDeferredDelete =
false;
1866 if (event->loopLevel() == 0 && data->loopLevel > 0) {
1867 qCDebug(lcDeleteLater) <<
"Event was posted outside outermost event loop"
1868 <<
"and current thread has an event loop running.";
1869 allowDeferredDelete =
true;
1871 const int totalEventLevel = event->loopLevel() + event->scopeLevel();
1872 const int totalThreadLevel = data->loopLevel + data->scopeLevel;
1874 if (totalEventLevel > totalThreadLevel) {
1875 qCDebug(lcDeleteLater) <<
"Combined levels of event" << totalEventLevel
1876 <<
"is higher than thread" << totalThreadLevel;
1877 allowDeferredDelete =
true;
1878 }
else if (event_type == QEvent::DeferredDelete && totalEventLevel == totalThreadLevel) {
1879 qCDebug(lcDeleteLater) <<
"Explicit send of DeferredDelete and"
1880 <<
"levels of event" << totalEventLevel
1881 <<
"is same as thread" << totalThreadLevel;
1882 allowDeferredDelete =
true;
1886 if (!allowDeferredDelete) {
1887 qCDebug(lcDeleteLater) <<
"Failed conditions for deferred delete. Deferring again";
1890 if (!event_type && !receiver) {
1895 QPostEvent pe_copy = pe;
1899 const_cast<QPostEvent &>(pe).event =
nullptr;
1902 data->postEventList.addEvent(pe_copy);
1906 qCDebug(lcDeleteLater) <<
"Sending deferred delete to" << pe.receiver;
1912 pe.event->m_posted =
false;
1913 QEvent *e = pe.event;
1914 QObject * r = pe.receiver;
1916 --r->d_func()->postedEvents;
1917 Q_ASSERT(r->d_func()->postedEvents >= 0);
1921 const_cast<QPostEvent &>(pe).event =
nullptr;
1924 const auto relocker = qScopeGuard([&locker] { locker.lock(); });
1926 QScopedPointer<QEvent> event_deleter(e);
1929 QCoreApplication::sendEvent(r, e);
1936 cleanup.exceptionCaught =
false;
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1958void QCoreApplication::removePostedEvents(QObject *receiver,
int eventType)
1960 auto locker = QCoreApplicationPrivate::lockThreadPostEventList(receiver);
1961 QThreadData *data = locker.threadData;
1967 if (receiver && !receiver->d_func()->postedEvents)
1972 QVarLengthArray<QEvent*> events;
1973 qsizetype n = data->postEventList.size();
1976 for (qsizetype i = 0; i < n; ++i) {
1977 const QPostEvent &pe = data->postEventList.at(i);
1979 if ((!receiver || pe.receiver == receiver)
1980 && (pe.event && (eventType == 0 || pe.event->type() == eventType))) {
1981 --pe.receiver->d_func()->postedEvents;
1982 pe.event->m_posted =
false;
1983 events.append(pe.event);
1984 const_cast<QPostEvent &>(pe).event =
nullptr;
1985 }
else if (!data->postEventList.recursion) {
1987 qSwap(data->postEventList[i], data->postEventList[j]);
1993 if (receiver && eventType == 0) {
1994 Q_ASSERT(!receiver->d_func()->postedEvents);
1998 if (!data->postEventList.recursion) {
2000 data->postEventList.erase(data->postEventList.begin() + j, data->postEventList.end());
2008
2009
2010
2011
2012
2013
2014
2015
2017void QCoreApplicationPrivate::removePostedEvent(QEvent * event)
2019 if (!event || !event->m_posted)
2022 QThreadData *data = QThreadData::current();
2024 const auto locker = qt_scoped_lock(data->postEventList.mutex);
2026 if (data->postEventList.size() == 0) {
2027#if defined(QT_DEBUG)
2028 qDebug(
"QCoreApplication::removePostedEvent: Internal error: %p %d is posted",
2029 (
void*)event, event->type());
2034 for (
const QPostEvent &pe : std::as_const(data->postEventList)) {
2035 if (pe.event == event) {
2037 qWarning(
"QCoreApplication::removePostedEvent: Event of type %d deleted while posted to %s %s",
2039 pe.receiver->metaObject()->className(),
2040 pe.receiver->objectName().toLocal8Bit().data());
2042 --pe.receiver->d_func()->postedEvents;
2043 pe.event->m_posted =
false;
2045 const_cast<QPostEvent &>(pe).event =
nullptr;
2052
2053
2054bool QCoreApplication::event(QEvent *e)
2056 if (e->type() == QEvent::Quit) {
2060 return QObject::event(e);
2063void QCoreApplicationPrivate::ref()
2068void QCoreApplicationPrivate::deref()
2070 quitLockRef.deref();
2072 if (quitLockEnabled && canQuitAutomatically())
2073 quitAutomatically();
2076bool QCoreApplicationPrivate::canQuitAutomatically()
2087 if (quitLockRef.loadRelaxed())
2093void QCoreApplicationPrivate::quitAutomatically()
2095 Q_Q(QCoreApplication);
2103 QCoreApplication::postEvent(q,
new QEvent(QEvent::Quit));
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140void QCoreApplication::quit()
2145 if (!self->d_func()->in_exec)
2148 self->d_func()->quit();
2151void QCoreApplicationPrivate::quit()
2153 Q_Q(QCoreApplication);
2155 if (QThread::isMainThread()) {
2156 QEvent quitEvent(QEvent::Quit);
2157 QCoreApplication::sendEvent(q, &quitEvent);
2159 QCoreApplication::postEvent(q,
new QEvent(QEvent::Quit));
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2186#ifndef QT_NO_TRANSLATION
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2215bool QCoreApplication::installTranslator(QTranslator *translationFile)
2217 if (!translationFile)
2220 if (!QCoreApplicationPrivate::checkInstance(
"installTranslator"))
2222 QCoreApplicationPrivate *d = self->d_func();
2224 QWriteLocker locker(&d->translateMutex);
2225 d->translators.prepend(translationFile);
2228#ifndef QT_NO_TRANSLATION_BUILDER
2229 if (translationFile->isEmpty())
2233#ifndef QT_NO_QOBJECT
2234 QEvent ev(QEvent::LanguageChange);
2235 QCoreApplication::sendEvent(self, &ev);
2242
2243
2244
2245
2246
2247
2248
2249
2251bool QCoreApplication::removeTranslator(QTranslator *translationFile)
2253 if (!translationFile)
2255 if (!QCoreApplicationPrivate::checkInstance(
"removeTranslator"))
2257 QCoreApplicationPrivate *d = self->d_func();
2258 QWriteLocker locker(&d->translateMutex);
2259 if (d->translators.removeAll(translationFile)) {
2260#ifndef QT_NO_QOBJECT
2262 if (!self->closingDown()) {
2263 QEvent ev(QEvent::LanguageChange);
2264 QCoreApplication::sendEvent(self, &ev);
2275 qsizetype percentPos = 0;
2277 while ((percentPos = result->indexOf(u'%', percentPos + len)) != -1) {
2279 if (percentPos + len == result->size())
2282 if (result->at(percentPos + len) == u'L') {
2284 if (percentPos + len == result->size())
2290 if (result->at(percentPos + len) == u'n') {
2293 result->replace(percentPos, len, fmt);
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333QString QCoreApplication::translate(
const char *context,
const char *sourceText,
2334 const char *disambiguation,
int n)
2342 QCoreApplicationPrivate *d = self->d_func();
2343 QReadLocker locker(&d->translateMutex);
2344 if (!d->translators.isEmpty()) {
2345 QList<QTranslator*>::ConstIterator it;
2346 QTranslator *translationFile;
2347 for (it = d->translators.constBegin(); it != d->translators.constEnd(); ++it) {
2348 translationFile = *it;
2349 result = translationFile->translate(context, sourceText, disambiguation, n);
2350 if (!result.isNull())
2356 if (result.isNull())
2357 result = QString::fromUtf8(sourceText);
2359 replacePercentN(&result, n);
2366 return QCoreApplication::translate(
nullptr, id,
nullptr, n);
2369bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator)
2371 if (!QCoreApplication::self)
2373 QCoreApplicationPrivate *d = QCoreApplication::self->d_func();
2374 QReadLocker locker(&d->translateMutex);
2375 return d->translators.contains(translator);
2380QString QCoreApplication::translate(
const char *context,
const char *sourceText,
2381 const char *disambiguation,
int n)
2384 Q_UNUSED(disambiguation);
2385 QString ret = QString::fromUtf8(sourceText);
2387 ret.replace(
"%n"_L1, QString::number(n));
2399void QCoreApplicationPrivate::setApplicationFilePath(
const QString &path)
2401 if (QCoreApplicationPrivate::cachedApplicationFilePath)
2402 *QCoreApplicationPrivate::cachedApplicationFilePath = path;
2404 QCoreApplicationPrivate::cachedApplicationFilePath =
new QString(path);
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430QString QCoreApplication::applicationDirPath()
2433 qWarning(
"QCoreApplication::applicationDirPath: Please instantiate the QApplication object first");
2437 QCoreApplicationPrivate *d = self->d_func();
2438 if (d->cachedApplicationDirPath.isNull())
2439 d->cachedApplicationDirPath = QFileInfo(applicationFilePath()).path();
2440 return d->cachedApplicationDirPath;
2443#if !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN)
2446# if defined(Q_OS_ANDROID)
2449# elif defined(Q_OS_LINUX)
2451 return QFile::decodeName(qt_readlink(
"/proc/self/exe"));
2452# elif defined(AT_EXECPATH)
2454 char execfn[PATH_MAX];
2455 if (elf_aux_info(AT_EXECPATH, execfn,
sizeof(execfn)) != 0)
2458 qsizetype len = qstrlen(execfn);
2459 return QFile::decodeName(QByteArray::fromRawData(execfn, len));
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482QString QCoreApplication::applicationFilePath()
2485 qWarning(
"QCoreApplication::applicationFilePath: Please instantiate the QApplication object first");
2489 QCoreApplicationPrivate *d = self->d_func();
2492 static QByteArray procName = QByteArray(d->argv[0]);
2493 if (procName != QByteArrayView(d->argv[0])) {
2495 QCoreApplicationPrivate::clearApplicationFilePath();
2496 procName.assign(d->argv[0]);
2500 if (QCoreApplicationPrivate::cachedApplicationFilePath)
2501 return *QCoreApplicationPrivate::cachedApplicationFilePath;
2503 QString absPath = qAppFileName();
2504 if (absPath.isEmpty() && !arguments().isEmpty()) {
2505 QString argv0 = QFile::decodeName(arguments().at(0).toLocal8Bit());
2507 if (!argv0.isEmpty() && argv0.at(0) == u'/') {
2509
2510
2511
2513 }
else if (argv0.contains(u'/')) {
2515
2516
2517
2518 absPath = QDir::current().absoluteFilePath(argv0);
2521
2522
2523
2524 absPath = QStandardPaths::findExecutable(argv0);
2528 absPath = QFileInfo(absPath).canonicalFilePath();
2529 if (!absPath.isEmpty()) {
2530 QCoreApplicationPrivate::setApplicationFilePath(absPath);
2531 return *QCoreApplicationPrivate::cachedApplicationFilePath;
2537
2538
2539
2540
2541qint64 QCoreApplication::applicationPid()
2543#if defined(Q_OS_WIN)
2544 return GetCurrentProcessId();
2545#elif defined(Q_OS_VXWORKS)
2546 return (pid_t) taskIdCurrent;
2553static QStringList winCmdArgs()
2562 if (
wchar_t **argv = CommandLineToArgvW(GetCommandLine(), &size)) {
2563 result.reserve(size);
2564 wchar_t **argvEnd = argv + size;
2565 for (
wchar_t **a = argv; a < argvEnd; ++a)
2566 result.append(QString::fromWCharArray(*a));
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2604QStringList QCoreApplication::arguments()
2609 qWarning(
"QCoreApplication::arguments: Please instantiate the QApplication object first");
2613 const QCoreApplicationPrivate *d = self->d_func();
2615 const int argc = d->argc;
2616 char **
const argv = d->argv;
2619#if defined(Q_OS_WIN)
2620 const bool argsModifiedByUser = d->origArgv ==
nullptr;
2621 if (!argsModifiedByUser) {
2622 QStringList commandLineArguments = winCmdArgs();
2627 if (argc != d->origArgc) {
2634 for (
int i = 0; i < d->origArgc; ++i) {
2635 if (!contains(argc, argv, d->origArgv[i]))
2636 commandLineArguments.removeAll(QString::fromLocal8Bit(d->origArgv[i]));
2640 return commandLineArguments;
2644 for (
int a = 0; a < argc; ++a)
2645 list << QString::fromLocal8Bit(argv[a]);
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2667
2668
2669
2670
2671
2672
2673
2674void QCoreApplication::setOrganizationName(
const QString &orgName)
2676 if (coreappdata()->orgName == orgName)
2678 coreappdata()->orgName = orgName;
2679#ifndef QT_NO_QOBJECT
2680 if (QCoreApplication::self)
2681 emit QCoreApplication::self->organizationNameChanged();
2685QString QCoreApplication::organizationName()
2687 return coreappdata()->orgName;
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2706
2707
2708
2709
2710
2711void QCoreApplication::setOrganizationDomain(
const QString &orgDomain)
2713 if (coreappdata()->orgDomain == orgDomain)
2715 coreappdata()->orgDomain = orgDomain;
2716#ifndef QT_NO_QOBJECT
2717 if (QCoreApplication::self)
2718 emit QCoreApplication::self->organizationDomainChanged();
2722QString QCoreApplication::organizationDomain()
2724 return coreappdata()->orgDomain;
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2744
2745
2746
2747
2748
2749void QCoreApplication::setApplicationName(
const QString &application)
2751 coreappdata()->applicationNameSet = !application.isEmpty();
2752 QString newAppName = application;
2753 if (newAppName.isEmpty() && QCoreApplication::self)
2754 newAppName = QCoreApplication::self->d_func()->appName();
2755 if (coreappdata()->application == newAppName)
2757 coreappdata()->application = newAppName;
2758#ifndef QT_NO_QOBJECT
2759 if (QCoreApplication::self)
2760 emit QCoreApplication::self->applicationNameChanged();
2764QString QCoreApplication::applicationName()
2766 return coreappdata() ? coreappdata()->application : QString();
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2797
2798
2799
2800
2801
2802void QCoreApplication::setApplicationVersion(
const QString &version)
2804 coreappdata()->applicationVersionSet = !version.isEmpty();
2805 QString newVersion = version;
2806 if (newVersion.isEmpty() && QCoreApplication::self)
2807 newVersion = QCoreApplication::self->d_func()->appVersion();
2808 if (coreappdata()->applicationVersion == newVersion)
2810 coreappdata()->applicationVersion = newVersion;
2811#ifndef QT_NO_QOBJECT
2812 if (QCoreApplication::self)
2813 emit QCoreApplication::self->applicationVersionChanged();
2817QString QCoreApplication::applicationVersion()
2819 return coreappdata() ? coreappdata()->applicationVersion : QString();
2822#if QT_CONFIG(permissions) || defined(Q_QDOC)
2825
2826
2827
2828
2829
2830
2831
2832
2833Qt::PermissionStatus QCoreApplication::checkPermission(
const QPermission &permission)
2835 return QPermissions::Private::checkPermission(permission);
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2905
2906
2907
2908
2909
2910
2911
2912void QCoreApplication::requestPermission(
const QPermission &requestedPermission,
2913 QtPrivate::QSlotObjectBase *slotObjRaw,
const QObject *context)
2915 QtPrivate::SlotObjUniquePtr slotObj{slotObjRaw};
2918 if (!QThread::isMainThread()) {
2919 qCWarning(lcPermissions,
"Permissions can only be requested from the GUI (main) thread");
2923 class PermissionReceiver :
public QObject
2926 explicit PermissionReceiver(QtPrivate::SlotObjUniquePtr &&slotObject,
const QObject *context)
2927 : slotObject(std::move(slotObject)), context(context ? context :
this)
2929 Q_ASSERT(
this->context);
2930 moveToThread(
this->context->thread());
2933 void finalizePermissionRequest(
const QPermission &permission)
2935 Q_ASSERT(slotObject);
2938 void *args[] = {
nullptr,
const_cast<QPermission *>(&permission) };
2939 slotObject->call(
const_cast<QObject *>(context.data()), args);
2945 QtPrivate::SlotObjSharedPtr slotObject;
2946 QPointer<
const QObject> context;
2949 PermissionReceiver *receiver =
new PermissionReceiver(std::move(slotObj), context);
2951 QPermissions::Private::requestPermission(requestedPermission, [=](Qt::PermissionStatus status) {
2952 if (status == Qt::PermissionStatus::Undetermined) {
2953 Q_ASSERT_X(
false,
"QPermission",
2954 "Internal error: requestPermission() should never return Undetermined");
2955 status = Qt::PermissionStatus::Denied;
2958 if (QCoreApplication::self) {
2959 QPermission permission = requestedPermission;
2960 permission.m_status = status;
2961 QMetaObject::invokeMethod(receiver,
2962 &PermissionReceiver::finalizePermissionRequest,
2963 Qt::QueuedConnection,
2971#if QT_CONFIG(library)
2973Q_GLOBAL_STATIC(QRecursiveMutex, libraryPathMutex)
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004QStringList QCoreApplication::libraryPaths()
3006 QMutexLocker locker(libraryPathMutex());
3007 return libraryPathsLocked();
3011
3012
3013QStringList QCoreApplication::libraryPathsLocked()
3015 if (coreappdata()->manual_libpaths)
3016 return *(coreappdata()->manual_libpaths);
3018 if (!coreappdata()->app_libpaths) {
3019 QStringList *app_libpaths =
new QStringList;
3020 coreappdata()->app_libpaths.reset(app_libpaths);
3022 auto setPathsFromEnv = [&](QString libPathEnv) {
3023 if (!libPathEnv.isEmpty()) {
3024 QStringList paths = libPathEnv.split(QDir::listSeparator(), Qt::SkipEmptyParts);
3025 for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
3026 QString canonicalPath = QDir(*it).canonicalPath();
3027 if (!canonicalPath.isEmpty()
3028 && !app_libpaths->contains(canonicalPath)) {
3029 app_libpaths->append(canonicalPath);
3034 setPathsFromEnv(qEnvironmentVariable(
"QT_PLUGIN_PATH"));
3040 if (CFBundleRef bundleRef = CFBundleGetMainBundle()) {
3041 if (QCFType<CFURLRef> urlRef = CFBundleCopyBuiltInPlugInsURL(bundleRef)) {
3042 if (QCFType<CFURLRef> absoluteUrlRef = CFURLCopyAbsoluteURL(urlRef)) {
3043 if (QCFString path = CFURLCopyFileSystemPath(absoluteUrlRef, kCFURLPOSIXPathStyle)) {
3044 if (QFile::exists(path)) {
3045 path = QDir(path).canonicalPath();
3046 if (!app_libpaths->contains(path))
3047 app_libpaths->append(path);
3055 QString installPathPlugins = QLibraryInfo::path(QLibraryInfo::PluginsPath);
3056 if (QFile::exists(installPathPlugins)) {
3058 installPathPlugins = QDir(installPathPlugins).canonicalPath();
3059 if (!app_libpaths->contains(installPathPlugins))
3060 app_libpaths->append(installPathPlugins);
3065 if (self) self->d_func()->appendApplicationPathToLibraryPaths();
3067 return *(coreappdata()->app_libpaths);
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084void QCoreApplication::setLibraryPaths(
const QStringList &paths)
3086 QMutexLocker locker(libraryPathMutex());
3091 if (!coreappdata()->app_libpaths)
3092 libraryPathsLocked();
3094 if (coreappdata()->manual_libpaths)
3095 *(coreappdata()->manual_libpaths) = paths;
3097 coreappdata()->manual_libpaths.reset(
new QStringList(paths));
3100 QFactoryLoader::refreshAll();
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119void QCoreApplication::addLibraryPath(
const QString &path)
3124 QString canonicalPath = QDir(path).canonicalPath();
3125 if (canonicalPath.isEmpty())
3128 QMutexLocker locker(libraryPathMutex());
3130 QStringList *libpaths = coreappdata()->manual_libpaths.get();
3132 if (libpaths->contains(canonicalPath))
3136 libraryPathsLocked();
3137 QStringList *app_libpaths = coreappdata()->app_libpaths.get();
3138 if (app_libpaths->contains(canonicalPath))
3141 coreappdata()->manual_libpaths.reset(libpaths =
new QStringList(*app_libpaths));
3144 libpaths->prepend(canonicalPath);
3146 QFactoryLoader::refreshAll();
3150
3151
3152
3153
3154
3155
3156
3157
3158void QCoreApplication::removeLibraryPath(
const QString &path)
3163 QString canonicalPath = QDir(path).canonicalPath();
3164 if (canonicalPath.isEmpty())
3167 QMutexLocker locker(libraryPathMutex());
3169 QStringList *libpaths = coreappdata()->manual_libpaths.get();
3171 if (libpaths->removeAll(canonicalPath) == 0)
3175 libraryPathsLocked();
3176 QStringList *app_libpaths = coreappdata()->app_libpaths.get();
3177 if (!app_libpaths->contains(canonicalPath))
3180 coreappdata()->manual_libpaths.reset(libpaths =
new QStringList(*app_libpaths));
3181 libpaths->removeAll(canonicalPath);
3185 QFactoryLoader::refreshAll();
3190#ifndef QT_NO_QOBJECT
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221void QCoreApplication::installNativeEventFilter(QAbstractNativeEventFilter *filterObj)
3223 if (QCoreApplication::testAttribute(Qt::AA_PluginApplication)) {
3224 qWarning(
"Native event filters are not applied when the Qt::AA_PluginApplication attribute is set");
3228 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread.loadAcquire());
3229 if (!filterObj || !eventDispatcher)
3231 eventDispatcher->installNativeEventFilter(filterObj);
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247void QCoreApplication::removeNativeEventFilter(QAbstractNativeEventFilter *filterObject)
3249 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread.loadAcquire());
3250 if (!filterObject || !eventDispatcher)
3252 eventDispatcher->removeNativeEventFilter(filterObject);
3256
3257
3258
3259QAbstractEventDispatcher *QCoreApplication::eventDispatcher()
3261 if (QCoreApplicationPrivate::theMainThread.loadAcquire())
3262 return QCoreApplicationPrivate::theMainThread.loadRelaxed()->eventDispatcher();
3267
3268
3269
3270
3271
3272void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
3274 QThread *mainThread = QCoreApplicationPrivate::theMainThread.loadAcquire();
3276 mainThread = QThread::currentThread();
3277 mainThread->setEventDispatcher(eventDispatcher);
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3391void *QCoreApplication::resolveInterface(
const char *name,
int revision)
const
3393#if defined(Q_OS_ANDROID)
3398 using namespace QNativeInterface;
3399 struct AndroidApplication :
public QAndroidApplication {};
3400 static AndroidApplication androidApplication;
3401 QT_NATIVE_INTERFACE_RETURN_IF(QAndroidApplication, &androidApplication);
3403 Q_UNUSED(name); Q_UNUSED(revision);
3409#ifndef QT_NO_QOBJECT
3410#include "moc_qcoreapplication.cpp"
Q_TRACE_POINT(qtcore, QCoreApplication_notify_exit, bool consumed, bool filtered)
static QString qAppFileName()
QList< QtStartUpFunction > QStartUpFuncList
Q_TRACE_METADATA(qtcore, "ENUM { AUTO, RANGE User ... MaxUser } QEvent::Type;")
QString qtTrId(const char *id, int n)
Q_TRACE_POINT(qtcore, QCoreApplication_postEvent_exit)
static void qt_call_pre_routines()
qsizetype qGlobalPostedEventsCount()
static Q_CONSTINIT bool preRoutinesCalled
QList< QtCleanUpFunction > QVFuncList
static void replacePercentN(QString *result, int n)
Q_TRACE_POINT(qtcore, QCoreApplication_postEvent_event_compressed, QObject *receiver, QEvent *event)
Q_TRACE_POINT(qtcore, QCoreApplication_postEvent_entry, QObject *receiver, QEvent *event, QEvent::Type type)
Q_TRACE_PREFIX(qtcore, "#include <qcoreevent.h>")
Q_CORE_EXPORT void qAddPostRoutine(QtCleanUpFunction)
void(* QtCleanUpFunction)()
void(* QtStartUpFunction)()
Q_CORE_EXPORT void qAddPreRoutine(QtStartUpFunction)
Q_CORE_EXPORT void qRemovePostRoutine(QtCleanUpFunction)
Q_GLOBAL_STATIC(QReadWriteLock, g_updateMutex)
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
QString applicationVersion
QCoreApplicationData() noexcept
bool applicationVersionSet