16#include <private/qproperty_p.h>
17#include <qdatastream.h>
22#include <private/qfilesystementry_p.h>
24#include <private/qloggingregistry_p.h>
25#include <qscopeguard.h>
26#include <qstandardpaths.h>
29#include <qthreadstorage.h>
31#include <QtCore/qpromise.h>
33#include <private/qthread_p.h>
35#include <qthreadpool.h>
36#include <private/qthreadpool_p.h>
39#include <qlibraryinfo.h>
41#include <qvarlengtharray.h>
42#include <private/qfactoryloader_p.h>
43#include <private/qfunctions_p.h>
44#include <private/qlocale_p.h>
45#include <private/qlocking_p.h>
46#include <private/qhooks_p.h>
47#include <private/qnativeinterface_p.h>
50#include <private/qstdweb_p.h>
53#if QT_CONFIG(permissions)
54#include <private/qpermissions_p.h>
59# if defined(Q_OS_DARWIN)
60# include "qeventdispatcher_cf_p.h"
62# if !defined(QT_NO_GLIB)
63# include "qeventdispatcher_glib_p.h"
66# if !defined(Q_OS_WASM)
67# include "qeventdispatcher_unix_p.h"
71#include "qeventdispatcher_win_p.h"
75#if defined(Q_OS_ANDROID)
76#include <QtCore/qjniobject.h>
80# include "qcore_mac_p.h"
87# ifndef Q_OS_INTEGRITY
91# include <sys/types.h>
93# include "qcore_unix_p.h"
98# if defined(Q_OS_LINUX) && !defined(AT_EXECFN
)
108#include <emscripten/val.h>
111#ifdef QT_BOOTSTRAPPED
112#include <private/qtrace_p.h>
114#include <qtcore_tracepoints_p.h>
122# include <qt_windows.h>
127using namespace Qt::StringLiterals;
130 "#include <qcoreevent.h>"
142#if (defined(Q_OS_WIN) || defined(Q_OS_DARWIN)) && !defined(QT_BOOTSTRAPPED)
143extern QString qAppFileName();
146Q_CONSTINIT
bool QCoreApplicationPrivate::setuidAllowed =
false;
148#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
)
149# warning "Audit remaining direct usages of this variable for memory ordering semantics"
150Q_CONSTINIT QBasicAtomicPointer<QCoreApplication> QCoreApplication::self =
nullptr;
153Q_CONSTINIT
static QBasicAtomicPointer<QCoreApplication> g_self =
nullptr;
155# define qApp g_self.loadRelaxed()
158
159
160
161
162
163
164
165
166
167bool QCoreApplication::instanceExists()
noexcept
169 return qApp !=
nullptr;
173#if !defined(Q_OS_WIN) || defined(QT_BOOTSTRAPPED)
175QString QCoreApplicationPrivate::infoDictionaryStringProperty(
const QString &propertyName)
178 QCFString cfPropertyName = propertyName.toCFString();
179 CFTypeRef string = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
182 bundleName = QString::fromCFString(
static_cast<CFStringRef>(string));
186QString QCoreApplicationPrivate::appName()
const
188 QString applicationName;
190 applicationName = infoDictionaryStringProperty(QStringLiteral(
"CFBundleName"));
192 if (applicationName.isEmpty() && argv[0]) {
193 char *p = strrchr(argv[0],
'/');
194 applicationName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
197 return applicationName;
199QString QCoreApplicationPrivate::appVersion()
const
201 QString applicationVersion;
202#if defined(Q_OS_DARWIN)
203 applicationVersion = infoDictionaryStringProperty(QStringLiteral(
"CFBundleVersion"));
204#elif defined(Q_OS_ANDROID) && !defined(QT_BOOTSTRAPPED)
205 QJniObject context(QNativeInterface::QAndroidApplication::context());
206 if (context.isValid()) {
207 QJniObject pm = context.callObjectMethod(
208 "getPackageManager",
"()Landroid/content/pm/PackageManager;");
209 QJniObject pn = context.callObjectMethod<jstring>(
"getPackageName");
210 if (pm.isValid() && pn.isValid()) {
211 QJniObject packageInfo = pm.callObjectMethod(
212 "getPackageInfo",
"(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;",
214 if (packageInfo.isValid()) {
215 QJniObject versionName = packageInfo.getObjectField(
216 "versionName",
"Ljava/lang/String;");
217 if (versionName.isValid())
218 return versionName.toString();
223 return applicationVersion;
227bool QCoreApplicationPrivate::checkInstance(
const char *function)
229 bool b = (
qApp !=
nullptr);
231 qWarning(
"QApplication::%s: Please instantiate the QApplication object first", function);
235#if QT_CONFIG(commandlineparser)
236void QCoreApplicationPrivate::addQtOptions(QList<QCommandLineOption> *options)
238 options->append(QCommandLineOption(QStringLiteral(
"qmljsdebugger"),
239 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."),
240 QStringLiteral(
"value")));
244void QCoreApplicationPrivate::processCommandLineArguments()
246 int j = argc ? 1 : 0;
247 for (
int i = 1; i < argc; ++i) {
250 if (*argv[i] !=
'-') {
254 const char *arg = argv[i];
257 if (strncmp(arg,
"-qmljsdebugger=", 15) == 0) {
258 qmljs_debug_arguments = QString::fromLocal8Bit(arg + 15);
259 }
else if (strcmp(arg,
"-qmljsdebugger") == 0 && i < argc - 1) {
261 qmljs_debug_arguments = QString::fromLocal8Bit(argv[i]);
286Q_GLOBAL_STATIC(QVFuncList, postRList)
287Q_CONSTINIT
static QBasicMutex globalRoutinesMutex;
291
292
293
294
295
309 const auto locker = qt_scoped_lock(globalRoutinesMutex);
318 const auto locker = qt_scoped_lock(globalRoutinesMutex);
327 const auto locker = qt_scoped_lock(globalRoutinesMutex);
336 if (!preRList.exists())
340 const auto locker = qt_scoped_lock(globalRoutinesMutex);
347 for (QtStartUpFunction f : list)
351void Q_CORE_EXPORT qt_call_post_routines()
353 if (!postRList.exists())
360 const auto locker = qt_scoped_lock(globalRoutinesMutex);
361 qSwap(*postRList, list);
366 for (QtCleanUpFunction f : std::as_const(list))
375Q_CONSTINIT
bool QCoreApplicationPrivate::is_app_running =
false;
377Q_CONSTINIT
bool QCoreApplicationPrivate::is_app_closing =
false;
381 const QPostEventList &l = QThreadData::current()->postEventList;
382 return l.size() - l.startOffset;
389Q_CONSTINIT uint QCoreApplicationPrivate::attribs =
390 (1 << Qt::AA_SynthesizeMouseForUnhandledTouchEvents) |
391 (1 << Qt::AA_SynthesizeMouseForUnhandledTabletEvents);
406#if QT_CONFIG(library)
419Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
422Q_CONSTINIT
static bool quitLockEnabled =
true;
431static inline bool isArgvModified(
int argc,
char **argv)
433 if (__argc != argc || !__argv )
437 for (
int a = 0; a < argc; ++a) {
438 if (argv[a] != __argv[a] && strcmp(argv[a], __argv[a]))
444static inline bool contains(
int argc,
char **argv,
const char *needle)
446 for (
int a = 0; a < argc; ++a) {
447 if (!strcmp(argv[a], needle))
454QCoreApplicationPrivate::QCoreApplicationPrivate(
int &aargc,
char **aargv)
455 : argc(aargc), argv(aargv)
457 static const char *
const empty =
"";
458 if (argc == 0 || argv ==
nullptr) {
460 argv =
const_cast<
char **>(&empty);
463 if (!isArgvModified(argc, argv)) {
465 origArgv = q20::make_unique_for_overwrite<
char *[]>(argc);
466 std::copy(argv, argv + argc, origArgv.get());
471 QCoreApplicationPrivate::is_app_closing =
false;
473# if defined(Q_OS_UNIX)
474 if (Q_UNLIKELY(!setuidAllowed && (geteuid() != getuid())))
475 qFatal(
"FATAL: The application binary appears to be running setuid, this is a security hole.");
478 QThread *cur = QThread::currentThread();
479 if (cur != theMainThread.loadAcquire())
480 qWarning(
"WARNING: QApplication was not created in the main() thread.");
484QCoreApplicationPrivate::~QCoreApplicationPrivate()
489#if defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED)
490 cleanupDebuggingConsole();
496void QCoreApplicationPrivate::cleanupThreadData()
498 auto thisThreadData = threadData.loadRelaxed();
500 if (thisThreadData && !threadData_clean) {
502 QThreadStoragePrivate::finish(&thisThreadData->tls);
506 const auto locker = qt_scoped_lock(thisThreadData->postEventList.mutex);
507 for (
const QPostEvent &pe : std::as_const(thisThreadData->postEventList)) {
509 pe.receiver->d_func()->postedEvents.fetchAndSubAcquire(1);
510 pe.event->m_posted =
false;
514 thisThreadData->postEventList.clear();
515 thisThreadData->postEventList.recursion = 0;
516 thisThreadData->quitNow =
false;
517 threadData_clean =
true;
521void QCoreApplicationPrivate::createEventDispatcher()
523 Q_Q(QCoreApplication);
524 QThreadData *data = QThreadData::current();
525 Q_ASSERT(!data->hasEventDispatcher());
526 eventDispatcher = data->createEventDispatcher();
527 eventDispatcher->setParent(q);
530void QCoreApplicationPrivate::eventDispatcherReady()
534Q_CONSTINIT QBasicAtomicPointer<QThread> QCoreApplicationPrivate::theMainThread = Q_BASIC_ATOMIC_INITIALIZER(
nullptr);
535Q_CONSTINIT QBasicAtomicPointer<
void> QCoreApplicationPrivate::theMainThreadId = Q_BASIC_ATOMIC_INITIALIZER(
nullptr);
536QThread *QCoreApplicationPrivate::mainThread()
538 Q_ASSERT(theMainThread.loadRelaxed() !=
nullptr);
539 return theMainThread.loadRelaxed();
542void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
544 QThread *currentThread = QThread::currentThread();
545 QThread *thr = receiver->thread();
546 Q_ASSERT_X(currentThread == thr || !thr,
547 "QCoreApplication::sendEvent",
548 qPrintable(QString::fromLatin1(
"Cannot send events to objects owned by a different thread. "
549 "Current thread %1. Receiver '%2' was created in thread %3").arg(
550 QDebug::toString(currentThread), QDebug::toString(receiver), QDebug::toString(thr))));
551 Q_UNUSED(currentThread);
559 if (!QCoreApplicationPrivate::checkInstance(
"qAppName"))
561 return QCoreApplication::instance()->d_func()->appName();
564void QCoreApplicationPrivate::initLocale()
566#if defined(QT_BOOTSTRAPPED)
568#elif defined(Q_OS_UNIX)
569 Q_CONSTINIT
static bool qt_locale_initialized =
false;
570 if (qt_locale_initialized)
572 qt_locale_initialized =
true;
577 setlocale(LC_ALL,
"");
581# if defined(Q_OS_INTEGRITY)
582 setlocale(LC_CTYPE,
"UTF-8");
583# elif defined(Q_OS_QNX)
586# elif defined(Q_OS_ANDROID) && __ANDROID_API__ < __ANDROID_API_O__
589# elif defined(Q_OS_VXWORKS)
593 const std::string oldEncoding = nl_langinfo(CODESET);
594 if (!Q_LIKELY(qstricmp(oldEncoding.data(),
"UTF-8") == 0
595 || qstricmp(oldEncoding.data(),
"utf8") == 0)) {
596 const QByteArray oldLocale = setlocale(LC_ALL,
nullptr);
597 QByteArray newLocale;
598 bool warnOnOverride =
true;
599# if defined(Q_OS_DARWIN)
603 warnOnOverride = qstrcmp(setlocale(LC_CTYPE,
nullptr),
"C") != 0
604 || getenv(
"LC_ALL") || getenv(
"LC_CTYPE") || getenv(
"LANG");
608 newLocale = setlocale(LC_CTYPE,
"UTF-8");
610 newLocale = setlocale(LC_CTYPE,
nullptr);
611 if (qsizetype dot = newLocale.indexOf(
'.'); dot != -1)
612 newLocale.truncate(dot);
613 if (qsizetype at = newLocale.indexOf(
'@'); at != -1)
614 newLocale.truncate(at);
615 newLocale +=
".UTF-8";
616 newLocale = setlocale(LC_CTYPE, newLocale);
619 if (newLocale.isEmpty())
620 newLocale = setlocale(LC_CTYPE,
"C.UTF-8");
621 if (newLocale.isEmpty())
622 newLocale = setlocale(LC_CTYPE,
"C.utf8");
625 if (newLocale.isEmpty()) {
627 qWarning(
"Detected locale \"%s\" with character encoding \"%s\", which is not UTF-8.\n"
628 "Qt depends on a UTF-8 locale, but has failed to switch to one.\n"
629 "If this causes problems, reconfigure your locale. See the locale(1) manual\n"
630 "for more information.", oldLocale.constData(), oldEncoding.data());
631 }
else if (warnOnOverride) {
633 qWarning(
"Detected locale \"%s\" with character encoding \"%s\", which is not UTF-8.\n"
634 "Qt depends on a UTF-8 locale, and has switched to \"%s\" instead.\n"
635 "If this causes problems, reconfigure your locale. See the locale(1) manual\n"
636 "for more information.",
637 oldLocale.constData(), oldEncoding.data(), newLocale.constData());
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
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
722
723
724
725
726
727
728
729
730
731
732
735
736
737QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
741 : QObject(p,
nullptr)
744 d_func()->q_ptr =
this;
750
751
752
753
754
755
756
757
758
759
760
761
762
763QCoreApplication::QCoreApplication(
int &argc,
char **argv
769 : d_ptr(
new QCoreApplicationPrivate(argc, argv))
771 : QObject(*
new QCoreApplicationPrivate(argc, argv))
774 d_func()->q_ptr =
this;
777 QCoreApplicationPrivate::eventDispatcher->startingUp();
782
783
784
785
786
788void Q_TRACE_INSTRUMENT(qtcore) QCoreApplicationPrivate::init()
790 Q_TRACE_SCOPE(QCoreApplicationPrivate_init);
792#if defined(Q_OS_MACOS)
793 QMacAutoReleasePool pool;
796 Q_Q(QCoreApplication);
798#if defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED)
799 initDebuggingConsole();
804 Q_ASSERT_X(!QCoreApplication::self,
"QCoreApplication",
"there should be only one application object");
805#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
806# ifdef __cpp_lib_atomic_ref
807 std::atomic_ref(QCoreApplication::self).store(q, std::memory_order_relaxed);
809 QCoreApplication::self = q;
811 g_self.storeRelaxed(q);
813 QCoreApplication::self.storeRelaxed(q);
818 emscripten::val hardwareConcurrency = emscripten::val::global(
"navigator")[
"hardwareConcurrency"];
819 if (hardwareConcurrency.isUndefined())
820 QThreadPrivate::idealThreadCount = 2;
822 QThreadPrivate::idealThreadCount = hardwareConcurrency.as<
int>();
827 if (!coreappdata()->applicationNameSet)
828 coreappdata()->application = appName();
830 if (!coreappdata()->applicationVersionSet)
831 coreappdata()->applicationVersion = appVersion();
833#if defined(Q_OS_ANDROID) && !defined(QT_BOOTSTRAPPED)
838 QLoggingRegistry::instance()->initializeRules();
841#if QT_CONFIG(library)
845 if (coreappdata->libPathsInitialized()) {
846 const QStringList appPaths = std::exchange(coreappdata->app_libpaths, {});
847 Q_ASSERT(!coreappdata->libPathsInitialized());
849 if (coreappdata->libPathsManuallySet()) {
850 const QStringList manualPaths = std::exchange(coreappdata->manual_libpaths, {});
851 Q_ASSERT(!coreappdata->libPathsManuallySet());
857 QStringList newPaths(q->libraryPaths());
858 for (qsizetype i = manualPaths.size(), j = appPaths.size(); i > 0 || j > 0; qt_noop()) {
860 newPaths.prepend(manualPaths[--i]);
861 }
else if (--i < 0) {
862 newPaths.removeAll(appPaths[j]);
863 }
else if (manualPaths[i] != appPaths[j]) {
864 newPaths.removeAll(appPaths[j]);
868 coreappdata->manual_libpaths.swap(newPaths);
875 Q_ASSERT(!eventDispatcher);
876 auto thisThreadData = threadData.loadRelaxed();
877 eventDispatcher = thisThreadData->eventDispatcher.loadRelaxed();
880 if (!eventDispatcher)
881 createEventDispatcher();
882 Q_ASSERT(eventDispatcher);
884 if (!eventDispatcher->parent()) {
885 eventDispatcher->moveToThread(thisThreadData->thread.loadAcquire());
886 eventDispatcher->setParent(q);
889 thisThreadData->eventDispatcher = eventDispatcher;
890 eventDispatcherReady();
893 processCommandLineArguments();
895 qt_call_pre_routines();
896 QT_MANGLE_NAMESPACE(qt_startup_hook)();
897#ifndef QT_BOOTSTRAPPED
898 QtPrivate::initBindingStatusThreadId();
899 if (Q_UNLIKELY(qtHookData[QHooks::Startup]))
900 reinterpret_cast<QHooks::StartupCallback>(qtHookData[QHooks::Startup])();
904 is_app_running =
true;
909
910
911QCoreApplication::~QCoreApplication()
913 preRoutinesCalled =
false;
915 qt_call_post_routines();
917#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
918# ifdef __cpp_lib_atomic_ref
919 std::atomic_ref(self).store(
nullptr, std::memory_order_relaxed);
923 g_self.storeRelaxed(
nullptr);
925 self.storeRelaxed(
nullptr);
929 QCoreApplicationPrivate::is_app_closing =
true;
930 QCoreApplicationPrivate::is_app_running =
false;
935 QThreadPool *globalThreadPool =
nullptr;
937 globalThreadPool = QThreadPool::globalInstance();
941 if (globalThreadPool) {
942 globalThreadPool->waitForDone();
943 delete globalThreadPool;
948 d_func()->threadData.loadRelaxed()->eventDispatcher =
nullptr;
949 if (QCoreApplicationPrivate::eventDispatcher)
950 QCoreApplicationPrivate::eventDispatcher->closingDown();
951 QCoreApplicationPrivate::eventDispatcher =
nullptr;
954#if QT_CONFIG(library)
955 if (coreappdata.exists()) {
957 coreappdata->app_libpaths = QStringList();
958 coreappdata->manual_libpaths = QStringList();
959 Q_ASSERT(!coreappdata->libPathsManuallySet());
960 Q_ASSERT(!coreappdata->libPathsInitialized());
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988void QCoreApplication::setSetuidAllowed(
bool allow)
990 QCoreApplicationPrivate::setuidAllowed = allow;
994
995
996
997
998
999
1000
1001bool QCoreApplication::isSetuidAllowed()
1003 return QCoreApplicationPrivate::setuidAllowed;
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute,
bool on)
1020 static_assert(Qt::AA_AttributeCount <=
sizeof(QCoreApplicationPrivate::attribs) * CHAR_BIT);
1023 QCoreApplicationPrivate::attribs |= 1 << attribute;
1025 QCoreApplicationPrivate::attribs &= ~(1 << attribute);
1026#if defined(QT_NO_QOBJECT)
1027 if (Q_UNLIKELY(qApp)) {
1029 if (Q_UNLIKELY(QCoreApplicationPrivate::is_app_running)) {
1031 switch (attribute) {
1032 case Qt::AA_PluginApplication:
1033 case Qt::AA_UseDesktopOpenGL:
1034 case Qt::AA_UseOpenGLES:
1035 case Qt::AA_UseSoftwareOpenGL:
1036#ifdef QT_BOOTSTRAPPED
1037 qWarning(
"Attribute %d must be set before QCoreApplication is created.",
1040 qWarning(
"Attribute Qt::%s must be set before QCoreApplication is created.",
1041 QMetaEnum::fromType<Qt::ApplicationAttribute>().valueToKey(attribute));
1051
1052
1053
1054
1055
1056bool QCoreApplication::testAttribute(Qt::ApplicationAttribute attribute)
1058 return QCoreApplicationPrivate::testAttribute(attribute);
1061#ifndef QT_NO_QOBJECT
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1082bool QCoreApplication::isQuitLockEnabled()
1084 return quitLockEnabled;
1087static bool doNotify(QObject *, QEvent *);
1089void QCoreApplication::setQuitLockEnabled(
bool enabled)
1091 quitLockEnabled = enabled;
1095
1096
1097
1098
1099
1100
1101bool QCoreApplication::notifyInternal2(QObject *receiver, QEvent *event)
1107 QObjectPrivate *d = receiver->d_func();
1108 QThreadData *threadData = d->threadData.loadAcquire();
1109 bool selfRequired = threadData->requiresCoreApplication;
1110 if (selfRequired && !
qApp)
1115 bool result =
false;
1116 void *cbdata[] = { receiver, event, &result };
1117 if (QInternal::activateCallbacks(QInternal::EventNotifyCallback, cbdata)) {
1121 QScopedScopeLevelCounter scopeLevelCounter(threadData);
1123 return doNotify(receiver, event);
1125#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
)
1126 if (!QThread::isMainThread())
1129 return qApp->notify(receiver, event);
1133
1134
1135
1136
1137
1138
1139bool QCoreApplication::forwardEvent(QObject *receiver, QEvent *event, QEvent *originatingEvent)
1141 if (event && originatingEvent)
1142 event->m_spont = originatingEvent->m_spont;
1144 return notifyInternal2(receiver, event);
1148
1149
1150
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
1200bool QCoreApplication::notify(QObject *receiver, QEvent *event)
1205#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
)
1206 Q_ASSERT(receiver->d_func()->threadData.loadAcquire()->thread.loadRelaxed()
1207 == QCoreApplicationPrivate::mainThread());
1211 if (QCoreApplicationPrivate::is_app_closing)
1213 return doNotify(receiver, event);
1216static bool doNotify(QObject *receiver, QEvent *event)
1221 if (receiver ==
nullptr) {
1222 qWarning(
"QCoreApplication::notify: Unexpected null receiver");
1227 QCoreApplicationPrivate::checkReceiverThread(receiver);
1230 return receiver->isWidgetType() ?
false : QCoreApplicationPrivate::notify_helper(receiver, event);
1233bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
1236 Q_ASSERT(QThread::isMainThread());
1240 for (qsizetype i = 0; i < extraData->eventFilters.size(); ++i) {
1241 QObject *obj = extraData->eventFilters.at(i);
1244 if (obj->d_func()->threadData.loadRelaxed() != threadData.loadRelaxed()) {
1245 qWarning(
"QCoreApplication: Application event filter cannot be in a different thread.");
1248 if (obj->eventFilter(receiver, event))
1255bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event)
1257 if (receiver !=
qApp && receiver->d_func()->extraData) {
1258 for (qsizetype i = 0; i < receiver->d_func()->extraData->eventFilters.size(); ++i) {
1259 QObject *obj = receiver->d_func()->extraData->eventFilters.at(i);
1262 if (obj->d_func()->threadData.loadRelaxed() != receiver->d_func()->threadData.loadRelaxed()) {
1263 qWarning(
"QCoreApplication: Object event filter cannot be in a different thread.");
1266 if (obj->eventFilter(receiver, event))
1274
1275
1276
1277
1278bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
1282 Q_TRACE(QCoreApplication_notify_entry, receiver, event, event->type());
1283 bool consumed =
false;
1284 bool filtered =
false;
1285 Q_TRACE_EXIT(QCoreApplication_notify_exit, consumed, filtered);
1288 if (QThread::isMainThread()
1289 && QCoreApplication::self
1290 && QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) {
1295 if (sendThroughObjectEventFilters(receiver, event)) {
1301 consumed = receiver->event(event);
1306
1307
1308
1309
1310
1312bool QCoreApplication::startingUp()
1314 return !QCoreApplicationPrivate::is_app_running;
1318
1319
1320
1321
1322
1324bool QCoreApplication::closingDown()
1326 return QCoreApplicationPrivate::is_app_closing;
1331
1332
1333
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
1359void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
1361 QThreadData *data = QThreadData::current();
1362 if (!data->hasEventDispatcher())
1364 data->eventDispatcher.loadRelaxed()->processEvents(flags);
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags,
int ms)
1381 QCoreApplication::processEvents(flags, QDeadlineTimer(ms));
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, QDeadlineTimer deadline)
1413 QThreadData *data = QThreadData::current();
1414 if (!data->hasEventDispatcher())
1417 while (data->eventDispatcher.loadRelaxed()->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) {
1418 if (deadline.hasExpired())
1424
1425
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453int QCoreApplication::exec()
1455 if (!QCoreApplicationPrivate::checkInstance(
"exec"))
1458 QThreadData *threadData = self->d_func()->threadData.loadAcquire();
1459 if (threadData != QThreadData::current()) {
1460 qWarning(
"%s::exec: Must be called from the main thread", self->metaObject()->className());
1463 if (!threadData->eventLoops.isEmpty()) {
1464 qWarning(
"QCoreApplication::exec: The event loop is already running");
1468 threadData->quitNow =
false;
1469 QEventLoop eventLoop;
1470 self->d_func()->in_exec =
true;
1471 self->d_func()->aboutToQuitEmitted =
false;
1472 int returnCode = eventLoop.exec(QEventLoop::ApplicationExec);
1473 threadData->quitNow =
false;
1476 self->d_func()->execCleanup();
1487void QCoreApplicationPrivate::execCleanup()
1489 threadData.loadRelaxed()->quitNow =
false;
1491 QCoreApplication::sendPostedEvents(
nullptr, QEvent::DeferredDelete);
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525void QCoreApplication::exit(
int returnCode)
1531 if (!qstdweb::haveAsyncify())
1532 qFatal(
"Terminating since we don't have asyncify");
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
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661void QCoreApplication::postEvent(QObject *receiver, QEvent *event,
int priority)
1663 Q_ASSERT_X(event,
"QCoreApplication::postEvent",
"Unexpected null event");
1665 Q_TRACE_SCOPE(QCoreApplication_postEvent, receiver, event, event->type());
1668 if (receiver ==
nullptr) {
1669 qWarning(
"QCoreApplication::postEvent: Unexpected null receiver");
1674 auto locker = QCoreApplicationPrivate::lockThreadPostEventList(receiver);
1675 if (!locker.threadData) {
1681 QThreadData *data = locker.threadData;
1684 QT_WARNING_DISABLE_DEPRECATED
1686 if (receiver->d_func()->postedEvents.loadAcquire()
1687 && self && self->compressEvent(event, receiver, &data->postEventList)) {
1688 Q_TRACE(QCoreApplication_postEvent_event_compressed, receiver, event);
1695 std::unique_ptr<QEvent> eventDeleter(event);
1696 Q_TRACE(QCoreApplication_postEvent_event_posted, receiver, event, event->type());
1697 data->postEventList.addEvent(QPostEvent(receiver, event, priority));
1698 Q_UNUSED(eventDeleter.release());
1699 event->m_posted =
true;
1700 receiver->d_func()->postedEvents.fetchAndAddRelease(1);
1701 data->canWait =
false;
1704 QAbstractEventDispatcher* dispatcher = data->eventDispatcher.loadAcquire();
1706 dispatcher->wakeUp();
1710
1711
1712
1713#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
1714bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
1716 return d_func()->compressEvent(event, receiver, postedEvents);
1720bool QCoreApplicationPrivate::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
1724 Q_ASSERT(postedEvents);
1727 if (event->type() == QEvent::Timer) {
1728 const int timerId =
static_cast<QTimerEvent *>(event)->timerId();
1729 auto it = postedEvents->cbegin();
1730 const auto end = postedEvents->cend();
1732 if (it->event && it->event->type() == QEvent::Timer && it->receiver == receiver) {
1733 if (
static_cast<QTimerEvent *>(it->event)->timerId() == timerId) {
1743 if (event->type() == QEvent::Quit) {
1744 for (
const QPostEvent &cur : std::as_const(*postedEvents)) {
1745 if (cur.receiver != receiver
1746 || cur.event ==
nullptr
1747 || cur.event->type() != event->type())
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775void QCoreApplication::sendPostedEvents(QObject *receiver,
int event_type)
1780 QThreadData *data = QThreadData::current();
1782 QCoreApplicationPrivate::sendPostedEvents(receiver, event_type, data);
1785void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver,
int event_type,
1788 if (event_type == -1) {
1793 if (receiver && receiver->d_func()->threadData.loadRelaxed() != data) {
1794 qWarning(
"QCoreApplication::sendPostedEvents: Cannot send "
1795 "posted events for objects in another thread");
1799 ++data->postEventList.recursion;
1801 auto locker = qt_unique_lock(data->postEventList.mutex);
1806 data->canWait = (data->postEventList.size() == 0);
1808 if (data->postEventList.size() == 0
1809 || (receiver && !receiver->d_func()->postedEvents.loadAcquire())) {
1810 --data->postEventList.recursion;
1814 data->canWait =
true;
1818 qsizetype startOffset = data->postEventList.startOffset;
1819 qsizetype &i = (!event_type && !receiver) ? data->postEventList.startOffset : startOffset;
1820 data->postEventList.insertionOffset = data->postEventList.size();
1824 Q_DISABLE_COPY_MOVE(CleanUp)
1829 bool exceptionCaught;
1831 inline CleanUp(QObject *receiver,
int event_type, QThreadData *data) :
1832 receiver(receiver), event_type(event_type), data(data), exceptionCaught(
true)
1836 if (exceptionCaught) {
1838 data->canWait =
false;
1841 --data->postEventList.recursion;
1842 if (!data->postEventList.recursion && !data->canWait && data->hasEventDispatcher())
1843 data->eventDispatcher.loadRelaxed()->wakeUp();
1847 if (!event_type && !receiver && data->postEventList.startOffset >= 0) {
1848 const QPostEventList::iterator it = data->postEventList.begin();
1849 data->postEventList.erase(it, it + data->postEventList.startOffset);
1850 data->postEventList.insertionOffset -= data->postEventList.startOffset;
1851 Q_ASSERT(data->postEventList.insertionOffset >= 0);
1852 data->postEventList.startOffset = 0;
1856 CleanUp cleanup(receiver, event_type, data);
1858 while (i < data->postEventList.size()) {
1860 if (i >= data->postEventList.insertionOffset)
1863 const QPostEvent &pe = data->postEventList.at(i);
1868 if ((receiver && receiver != pe.receiver) || (event_type && event_type != pe.event->type())) {
1869 data->canWait =
false;
1873 if (pe.event->type() == QEvent::DeferredDelete) {
1880 const int eventLoopLevel =
static_cast<QDeferredDeleteEvent *>(pe.event)->loopLevel();
1881 const int eventScopeLevel =
static_cast<QDeferredDeleteEvent *>(pe.event)->scopeLevel();
1883 const bool postedBeforeOutermostLoop = eventLoopLevel == 0;
1884 const bool allowDeferredDelete =
1885 (eventLoopLevel + eventScopeLevel > data->loopLevel + data->scopeLevel
1886 || (postedBeforeOutermostLoop && data->loopLevel > 0)
1887 || (event_type == QEvent::DeferredDelete
1888 && eventLoopLevel + eventScopeLevel == data->loopLevel + data->scopeLevel));
1889 if (!allowDeferredDelete) {
1891 if (!event_type && !receiver) {
1896 QPostEvent pe_copy = pe;
1900 const_cast<QPostEvent &>(pe).event =
nullptr;
1903 data->postEventList.addEvent(pe_copy);
1911 pe.event->m_posted =
false;
1912 QEvent *e = pe.event;
1913 QObject * r = pe.receiver;
1916 const auto previous = r->d_func()->postedEvents.fetchAndSubAcquire(1);
1917 Q_ASSERT(previous > 0);
1921 const_cast<QPostEvent &>(pe).event =
nullptr;
1924 const auto relocker = qScopeGuard([&locker] { locker.lock(); });
1926 const std::unique_ptr<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.loadAcquire())
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.fetchAndSubAcquire(1);
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.loadRelaxed());
1998 if (!data->postEventList.recursion) {
2000 data->postEventList.erase(data->postEventList.begin() + j, data->postEventList.end());
2008
2009
2010
2011
2012
2013
2014
2015
2016
2018void QCoreApplicationPrivate::removePostedEvent(QEvent * event)
2020 if (!event || !event->m_posted)
2023 QThreadData *data = QThreadData::current();
2025 const auto locker = qt_scoped_lock(data->postEventList.mutex);
2027 if (data->postEventList.size() == 0) {
2028#if defined(QT_DEBUG)
2029 qDebug(
"QCoreApplication::removePostedEvent: Internal error: %p %d is posted",
2030 (
void*)event, event->type());
2035 for (
const QPostEvent &pe : std::as_const(data->postEventList)) {
2036 if (pe.event == event) {
2038 qWarning(
"QCoreApplication::removePostedEvent: Event of type %d deleted while posted to %s %s",
2040 pe.receiver->metaObject()->className(),
2041 pe.receiver->objectName().toLocal8Bit().data());
2043 pe.receiver->d_func()->postedEvents.fetchAndSubAcquire(1);
2044 pe.event->m_posted =
false;
2046 const_cast<QPostEvent &>(pe).event =
nullptr;
2053
2054
2055bool QCoreApplication::event(QEvent *e)
2057 if (e->type() == QEvent::Quit) {
2061 return QObject::event(e);
2064void QCoreApplicationPrivate::ref()
2069void QCoreApplicationPrivate::deref()
2071 quitLockRef.deref();
2073 if (quitLockEnabled && canQuitAutomatically())
2074 quitAutomatically();
2077bool QCoreApplicationPrivate::canQuitAutomatically()
2088 if (quitLockRef.loadRelaxed())
2094void QCoreApplicationPrivate::quitAutomatically()
2096 Q_Q(QCoreApplication);
2104 QCoreApplication::postEvent(q,
new QEvent(QEvent::Quit));
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
2140
2141void QCoreApplication::quit()
2146 if (!self->d_func()->in_exec)
2149 self->d_func()->quit();
2152void QCoreApplicationPrivate::quit()
2154 Q_Q(QCoreApplication);
2156 if (QThread::isMainThread()) {
2157 QEvent quitEvent(QEvent::Quit);
2158 QCoreApplication::sendEvent(q, &quitEvent);
2160 QCoreApplication::postEvent(q,
new QEvent(QEvent::Quit));
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2187#ifndef QT_NO_TRANSLATION
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
2214
2215
2216
2217
2219bool QCoreApplication::installTranslator(QTranslator *translationFile)
2221 if (!translationFile)
2224 if (!QCoreApplicationPrivate::checkInstance(
"installTranslator"))
2227 QCoreApplicationPrivate *d = self->d_func();
2229 QWriteLocker locker(&d->translateMutex);
2230 d->translators.prepend(translationFile);
2233 if (translationFile->isEmpty())
2236#ifndef QT_NO_QOBJECT
2237 QEvent ev(QEvent::LanguageChange);
2238 QCoreApplication::sendEvent(self, &ev);
2245
2246
2247
2248
2249
2250
2251
2252
2254bool QCoreApplication::removeTranslator(QTranslator *translationFile)
2256 if (!translationFile)
2258 if (!QCoreApplicationPrivate::checkInstance(
"removeTranslator"))
2260 QCoreApplicationPrivate *d = self->d_func();
2261 QWriteLocker locker(&d->translateMutex);
2262 if (d->translators.removeAll(translationFile)) {
2263#ifndef QT_NO_QOBJECT
2265 if (!self->closingDown()) {
2266 QEvent ev(QEvent::LanguageChange);
2267 QCoreApplication::sendEvent(self, &ev);
2278 qsizetype percentPos = 0;
2280 while ((percentPos = result->indexOf(u'%', percentPos + len)) != -1) {
2282 if (percentPos + len == result->size())
2285 if (result->at(percentPos + len) == u'L') {
2287 if (percentPos + len == result->size())
2293 if (result->at(percentPos + len) == u'n') {
2296 result->replace(percentPos, len, fmt);
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
2333
2334
2335
2336QString QCoreApplication::translate(
const char *context,
const char *sourceText,
2337 const char *disambiguation,
int n)
2345 QCoreApplicationPrivate *d = self->d_func();
2346 QReadLocker locker(&d->translateMutex);
2347 if (!d->translators.isEmpty()) {
2348 QList<QTranslator*>::ConstIterator it;
2349 QTranslator *translationFile;
2350 for (it = d->translators.constBegin(); it != d->translators.constEnd(); ++it) {
2351 translationFile = *it;
2352 result = translationFile->translate(context, sourceText, disambiguation, n);
2353 if (!result.isNull())
2359 if (result.isNull())
2360 result = QString::fromUtf8(sourceText);
2362 replacePercentN(&result, n);
2369 return QCoreApplication::translate(
nullptr, id,
nullptr, n);
2372bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator)
2374 if (!QCoreApplication::self)
2376 QCoreApplicationPrivate *d = QCoreApplication::self->d_func();
2377 QReadLocker locker(&d->translateMutex);
2378 return d->translators.contains(translator);
2383QString QCoreApplication::translate(
const char *context,
const char *sourceText,
2384 const char *disambiguation,
int n)
2387 Q_UNUSED(disambiguation);
2388 QString ret = QString::fromUtf8(sourceText);
2390 ret.replace(
"%n"_L1, QString::number(n));
2396#ifndef QT_BOOTSTRAPPED
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420QString QCoreApplication::applicationDirPath()
2423 qWarning(
"QCoreApplication::applicationDirPath: Please instantiate the QApplication object first");
2427 QFileSystemEntry appFilePath(applicationFilePath(), QFileSystemEntry::FromInternalPath{});
2428 return appFilePath.isEmpty() ? QString() : appFilePath.path();
2431#if !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN)
2435# if defined(Q_OS_ANDROID) || defined(Q_OS_OHOS)
2438# elif defined(Q_OS_LINUX)
2441# if QT_CONFIG(getauxval)
2443 if (
auto ptr =
reinterpret_cast<
const char *>(getauxval(AT_EXECFN)); ptr && *ptr ==
'/')
2444 return QFile::decodeName(ptr);
2448 return QFile::decodeName(qt_readlink(
"/proc/self/exe"));
2449# elif defined(AT_EXECPATH)
2451 char execfn[PATH_MAX];
2452 if (elf_aux_info(AT_EXECPATH, execfn,
sizeof(execfn)) != 0)
2455 qsizetype len = qstrlen(execfn);
2456 return QFile::decodeName(QByteArray::fromRawData(execfn, len));
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479QString QCoreApplication::applicationFilePath()
2482 qWarning(
"QCoreApplication::applicationFilePath: Please instantiate the QApplication object first");
2486 QCoreApplicationPrivate *d = self->d_func();
2489 static QByteArray procName = QByteArray(d->argv[0]);
2490 if (procName != QByteArrayView(d->argv[0])) {
2492 d->cachedApplicationFilePath = QString();
2493 procName.assign(d->argv[0]);
2497 if (!d->cachedApplicationFilePath.isNull())
2498 return d->cachedApplicationFilePath;
2500 QString absPath = qAppFileName();
2501 if (Q_LIKELY(!absPath.isEmpty())) {
2503 return d->cachedApplicationFilePath = std::move(absPath);
2506 if (
const QStringList args = arguments(); !args.isEmpty()) {
2507 const QString &argv0 = args[0];
2509 if (!argv0.isEmpty() && argv0.at(0) == u'/') {
2511
2512
2513
2515 }
else if (argv0.contains(u'/')) {
2517
2518
2519
2520 absPath = QDir::current().absoluteFilePath(argv0);
2523
2524
2525
2526 absPath = QStandardPaths::findExecutable(argv0);
2530 absPath = QFileInfo(absPath).canonicalFilePath();
2531 if (!absPath.isEmpty()) {
2532 return d->cachedApplicationFilePath = std::move(absPath);
2539
2540
2541
2542
2543qint64 QCoreApplication::applicationPid()
noexcept
2545#if defined(Q_OS_WIN)
2546 return GetCurrentProcessId();
2547#elif defined(Q_OS_VXWORKS)
2548 return (pid_t) taskIdCurrent;
2555static QStringList winCmdArgs()
2564 if (
wchar_t **argv = CommandLineToArgvW(GetCommandLine(), &size)) {
2565 result.reserve(size);
2566 wchar_t **argvEnd = argv + size;
2567 for (
wchar_t **a = argv; a < argvEnd; ++a)
2568 result.append(QString::fromWCharArray(*a));
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
2603
2604
2605
2607QStringList QCoreApplication::arguments()
2612 qWarning(
"QCoreApplication::arguments: Please instantiate the QApplication object first");
2616 const QCoreApplicationPrivate *d = self->d_func();
2618 const int argc = d->argc;
2619 char **
const argv = d->argv;
2622#if defined(Q_OS_WIN)
2623 const bool argsModifiedByUser = d->origArgv ==
nullptr;
2624 if (!argsModifiedByUser) {
2625 QStringList commandLineArguments = winCmdArgs();
2630 if (argc != d->origArgc) {
2637 for (
int i = 0; i < d->origArgc; ++i) {
2638 if (!contains(argc, argv, d->origArgv[i]))
2639 commandLineArguments.removeAll(QString::fromLocal8Bit(d->origArgv[i]));
2643 return commandLineArguments;
2647 for (
int a = 0; a < argc; ++a)
2648 list << QString::fromLocal8Bit(argv[a]);
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2670
2671
2672
2673
2674
2675
2676
2677void QCoreApplication::setOrganizationName(
const QString &orgName)
2679 if (coreappdata()->orgName == orgName)
2681 coreappdata()->orgName = orgName;
2682#ifndef QT_NO_QOBJECT
2683 if (QCoreApplication::self)
2684 emit QCoreApplication::self->organizationNameChanged();
2688QString QCoreApplication::organizationName()
2690 return coreappdata()->orgName;
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2709
2710
2711
2712
2713
2714void QCoreApplication::setOrganizationDomain(
const QString &orgDomain)
2716 if (coreappdata()->orgDomain == orgDomain)
2718 coreappdata()->orgDomain = orgDomain;
2719#ifndef QT_NO_QOBJECT
2720 if (QCoreApplication::self)
2721 emit QCoreApplication::self->organizationDomainChanged();
2725QString QCoreApplication::organizationDomain()
2727 return coreappdata()->orgDomain;
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2747
2748
2749
2750
2751
2752void QCoreApplication::setApplicationName(
const QString &application)
2754 coreappdata()->applicationNameSet = !application.isEmpty();
2755 QString newAppName = application;
2756 if (newAppName.isEmpty() && QCoreApplication::self)
2757 newAppName = QCoreApplication::self->d_func()->appName();
2758 if (coreappdata()->application == newAppName)
2760 coreappdata()->application = newAppName;
2761#ifndef QT_NO_QOBJECT
2762 if (QCoreApplication::self)
2763 emit QCoreApplication::self->applicationNameChanged();
2767QString QCoreApplication::applicationName()
2769 return coreappdata() ? coreappdata()->application : QString();
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2800
2801
2802
2803
2804
2805void QCoreApplication::setApplicationVersion(
const QString &version)
2807 coreappdata()->applicationVersionSet = !version.isEmpty();
2808 QString newVersion = version;
2809 if (newVersion.isEmpty() && QCoreApplication::self)
2810 newVersion = QCoreApplication::self->d_func()->appVersion();
2811 if (coreappdata()->applicationVersion == newVersion)
2813 coreappdata()->applicationVersion = newVersion;
2814#ifndef QT_NO_QOBJECT
2815 if (QCoreApplication::self)
2816 emit QCoreApplication::self->applicationVersionChanged();
2820QString QCoreApplication::applicationVersion()
2822 return coreappdata() ? coreappdata()->applicationVersion : QString();
2825#if QT_CONFIG(permissions) || defined(Q_QDOC)
2828
2829
2830
2831
2832
2833
2834
2835
2836Qt::PermissionStatus QCoreApplication::checkPermission(
const QPermission &permission)
2838 return QPermissions::Private::checkPermission(permission);
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
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
2903
2904
2905
2908
2909
2910
2911
2912
2913
2914
2915void QCoreApplication::requestPermissionImpl(
const QPermission &requestedPermission,
2916 QtPrivate::QSlotObjectBase *slotObjRaw,
const QObject *context)
2918 QtPrivate::SlotObjUniquePtr slotObj{slotObjRaw};
2921 if (!QThread::isMainThread()) {
2922 qCWarning(lcPermissions,
"Permissions can only be requested from the GUI (main) thread");
2926 class PermissionReceiver :
public QObject
2929 explicit PermissionReceiver(QtPrivate::SlotObjUniquePtr &&slotObject,
const QObject *context)
2930 : slotObject(std::move(slotObject)), context(context ? context :
this)
2932 Q_ASSERT(
this->context);
2933 moveToThread(
this->context->thread());
2936 void finalizePermissionRequest(
const QPermission &permission)
2938 Q_ASSERT(slotObject);
2941 void *args[] = {
nullptr,
const_cast<QPermission *>(&permission) };
2942 slotObject->call(
const_cast<QObject *>(context.data()), args);
2947 QtPrivate::SlotObjUniquePtr slotObject;
2948 QPointer<
const QObject> context;
2952 auto receiver = std::make_shared<PermissionReceiver>(std::move(slotObj), context);
2954 QPermissions::Private::requestPermission(requestedPermission,
2955 [=, receiver = std::move(receiver)](Qt::PermissionStatus status)
mutable {
2956 if (status == Qt::PermissionStatus::Undetermined) {
2957 Q_ASSERT_X(
false,
"QPermission",
2958 "Internal error: requestPermission() should never return Undetermined");
2959 status = Qt::PermissionStatus::Denied;
2962 if (QCoreApplication::self) {
2963 QPermission permission = requestedPermission;
2964 permission.m_status = status;
2965 auto receiverObject = receiver.get();
2966 QMetaObject::invokeMethod(receiverObject,
2967 [receiver = std::move(receiver), permission] {
2968 receiver->finalizePermissionRequest(permission);
2969 }, Qt::QueuedConnection);
2976#if QT_CONFIG(library)
2977static QStringList libraryPathsLocked();
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012QStringList QCoreApplication::libraryPaths()
3014 QMutexLocker locker(&coreappdata->libraryPathMutex);
3015 return libraryPathsLocked();
3019
3020
3021static QStringList libraryPathsLocked()
3023 QCoreApplicationData *d = coreappdata;
3024 if (d->libPathsManuallySet())
3025 return d->manual_libpaths;
3027 QStringList *app_libpaths = &d->app_libpaths;
3028 if (!d->libPathsInitialized()) {
3030 auto setPathsFromEnv = [&](QString libPathEnv) {
3031 if (!libPathEnv.isEmpty()) {
3032 QStringList paths = libPathEnv.split(QDir::listSeparator(), Qt::SkipEmptyParts);
3033 for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
3034 QString canonicalPath = QDir(*it).canonicalPath();
3035 if (!canonicalPath.isEmpty()
3036 && !app_libpaths->contains(canonicalPath)) {
3037 app_libpaths->append(canonicalPath);
3042 setPathsFromEnv(qEnvironmentVariable(
"QT_PLUGIN_PATH"));
3048 if (CFBundleRef bundleRef = CFBundleGetMainBundle()) {
3049 if (QCFType<CFURLRef> urlRef = CFBundleCopyBuiltInPlugInsURL(bundleRef)) {
3050 if (QCFType<CFURLRef> absoluteUrlRef = CFURLCopyAbsoluteURL(urlRef)) {
3051 if (QCFString path = CFURLCopyFileSystemPath(absoluteUrlRef, kCFURLPOSIXPathStyle)) {
3052 if (QFile::exists(path)) {
3053 path = QDir(path).canonicalPath();
3054 if (!app_libpaths->contains(path))
3055 app_libpaths->append(path);
3063 const auto pluginPaths = QLibraryInfo::paths(QLibraryInfo::PluginsPath);
3064 for (
auto path : pluginPaths) {
3065 if (QFile::exists(path)) {
3067 path = QDir(path).canonicalPath();
3068 if (!app_libpaths->contains(path))
3069 app_libpaths->append(path);
3076 QString app_location = QCoreApplication::applicationFilePath();
3077 app_location.truncate(app_location.lastIndexOf(u'/'));
3078 app_location = QDir(app_location).canonicalPath();
3079 if (QFile::exists(app_location) && !app_libpaths->contains(app_location))
3080 app_libpaths->append(app_location);
3082 if (app_libpaths->isEmpty())
3083 app_libpaths->reserve(1);
3084 Q_ASSERT(d->libPathsInitialized());
3086 return *app_libpaths;
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106void QCoreApplication::setLibraryPaths(
const QStringList &paths)
3108 QCoreApplicationData *d = coreappdata;
3109 QMutexLocker locker(&d->libraryPathMutex);
3114 if (!d->libPathsInitialized())
3115 libraryPathsLocked();
3117 d->manual_libpaths = paths;
3118 if (d->manual_libpaths.isEmpty())
3119 d->manual_libpaths.reserve(1);
3120 Q_ASSERT(d->libPathsManuallySet());
3123 QFactoryLoader::refreshAll();
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145void QCoreApplication::addLibraryPath(
const QString &path)
3150 QString canonicalPath = QDir(path).canonicalPath();
3151 if (canonicalPath.isEmpty())
3154 QCoreApplicationData *d = coreappdata;
3155 QMutexLocker locker(&d->libraryPathMutex);
3157 QStringList *libpaths = &d->manual_libpaths;
3158 if (d->libPathsManuallySet()) {
3159 if (d->manual_libpaths.contains(canonicalPath))
3163 libraryPathsLocked();
3164 QStringList *app_libpaths = &d->app_libpaths;
3165 if (app_libpaths->contains(canonicalPath))
3168 *libpaths = *app_libpaths;
3171 libpaths->prepend(canonicalPath);
3172 Q_ASSERT(d->libPathsManuallySet());
3174 QFactoryLoader::refreshAll();
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189void QCoreApplication::removeLibraryPath(
const QString &path)
3194 QString canonicalPath = QDir(path).canonicalPath();
3195 if (canonicalPath.isEmpty())
3198 QCoreApplicationData *d = coreappdata;
3199 QMutexLocker locker(&d->libraryPathMutex);
3201 QStringList *libpaths = &d->manual_libpaths;
3202 if (d->libPathsManuallySet()) {
3203 if (libpaths->removeAll(canonicalPath) == 0)
3207 libraryPathsLocked();
3208 QStringList *app_libpaths = &d->app_libpaths;
3209 if (!app_libpaths->contains(canonicalPath))
3212 *libpaths = *app_libpaths;
3213 libpaths->removeAll(canonicalPath);
3214 Q_ASSERT(d->libPathsManuallySet());
3218 QFactoryLoader::refreshAll();
3223#ifndef QT_NO_QOBJECT
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254void QCoreApplication::installNativeEventFilter(QAbstractNativeEventFilter *filterObj)
3256 if (QCoreApplication::testAttribute(Qt::AA_PluginApplication)) {
3257 qWarning(
"Native event filters are not applied when the Qt::AA_PluginApplication attribute is set");
3261 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread.loadAcquire());
3262 if (!filterObj || !eventDispatcher)
3264 eventDispatcher->installNativeEventFilter(filterObj);
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280void QCoreApplication::removeNativeEventFilter(QAbstractNativeEventFilter *filterObject)
3282 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread.loadAcquire());
3283 if (!filterObject || !eventDispatcher)
3285 eventDispatcher->removeNativeEventFilter(filterObject);
3289
3290
3291
3292QAbstractEventDispatcher *QCoreApplication::eventDispatcher()
3294 if (QCoreApplicationPrivate::theMainThread.loadAcquire())
3295 return QCoreApplicationPrivate::theMainThread.loadRelaxed()->eventDispatcher();
3300
3301
3302
3303
3304
3305void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
3307 QThread *mainThread = QCoreApplicationPrivate::theMainThread.loadAcquire();
3309 mainThread = QThread::currentThread();
3310 mainThread->setEventDispatcher(eventDispatcher);
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
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3424void *QCoreApplication::resolveInterface(
const char *name,
int revision)
const
3426#if defined(Q_OS_ANDROID)
3431 using namespace QNativeInterface;
3432 struct AndroidApplication :
public QAndroidApplication {};
3433 static AndroidApplication androidApplication;
3434 QT_NATIVE_INTERFACE_RETURN_IF(QAndroidApplication, &androidApplication);
3436 Q_UNUSED(name); Q_UNUSED(revision);
3442#ifndef QT_NO_QOBJECT
3443#include "moc_qcoreapplication.cpp"
Q_TRACE_POINT(qtcore, QCoreApplication_notify_exit, bool consumed, bool filtered)
void QT_MANGLE_NAMESPACE qt_startup_hook()
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)
QString applicationVersion
QCoreApplicationData() noexcept
bool applicationVersionSet