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>
79#if defined(Q_OS_HARMONY) && !defined(QT_BOOTSTRAPPED)
80#include <QtCore/private/qcore_ohos_p.h>
81#include <QtCore/private/qnapi_p.h>
82#include <QtCore/private/qohosmemoizingjsthreadfetcher_p.h>
86# include "qcore_mac_p.h"
93# ifndef Q_OS_INTEGRITY
97# include <sys/types.h>
99# include "qcore_unix_p.h"
103# include <sys/auxv.h>
111#include <emscripten/val.h>
114#ifdef QT_BOOTSTRAPPED
115#include <private/qtrace_p.h>
117#include <qtcore_tracepoints_p.h>
125# include <qt_windows.h>
130using namespace Qt::StringLiterals;
133 "#include <qcoreevent.h>"
145#if (defined(Q_OS_WIN) || defined(Q_OS_DARWIN)) && !defined(QT_BOOTSTRAPPED)
146extern QString qAppFileName();
149Q_CONSTINIT
bool QCoreApplicationPrivate::setuidAllowed =
false;
151#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
)
152# warning "Audit remaining direct usages of this variable for memory ordering semantics"
153Q_CONSTINIT QBasicAtomicPointer<QCoreApplication> QCoreApplication::self =
nullptr;
156Q_CONSTINIT
static QBasicAtomicPointer<QCoreApplication> g_self =
nullptr;
158# define qApp g_self.loadRelaxed()
161
162
163
164
165
166
167
168
169
170bool QCoreApplication::instanceExists()
noexcept
172 return qApp !=
nullptr;
176#if !defined(Q_OS_WIN) || defined(QT_BOOTSTRAPPED)
178QString QCoreApplicationPrivate::infoDictionaryStringProperty(
const QString &propertyName)
181 QCFString cfPropertyName = propertyName.toCFString();
182 CFTypeRef string = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
185 bundleName = QString::fromCFString(
static_cast<CFStringRef>(string));
189QString QCoreApplicationPrivate::appName()
const
191 QString applicationName;
193 applicationName = infoDictionaryStringProperty(QStringLiteral(
"CFBundleName"));
195 if (applicationName.isEmpty() && argv[0]) {
196 char *p = strrchr(argv[0],
'/');
197 applicationName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
200 return applicationName;
203#if defined(Q_OS_HARMONY) && !defined(QT_BOOTSTRAPPED)
204static QOhosMemoizingJsThreadFetcher<QString> bundleVersionNameFetcher(
205 [](QOhosJsState &jsState) -> std::optional<QString> {
206 const auto flag = jsState.eval<QNapi::Number>(
207 "@ohos.bundle.bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION");
208 return QString::fromStdString(
209 jsState.eval<QNapi::String>(
210 "@ohos.bundle.bundleManager.getBundleInfoForSelfSync(*).versionName",
213 "BundleInfo.versionName");
216QString QCoreApplicationPrivate::appVersion()
const
218 QString applicationVersion;
219#if defined(Q_OS_DARWIN)
220 applicationVersion = infoDictionaryStringProperty(QStringLiteral(
"CFBundleVersion"));
221#elif defined(Q_OS_ANDROID) && !defined(QT_BOOTSTRAPPED)
222 QJniObject context(QNativeInterface::QAndroidApplication::context());
223 if (context.isValid()) {
224 QJniObject pm = context.callObjectMethod(
225 "getPackageManager",
"()Landroid/content/pm/PackageManager;");
226 QJniObject pn = context.callObjectMethod<jstring>(
"getPackageName");
227 if (pm.isValid() && pn.isValid()) {
228 QJniObject packageInfo = pm.callObjectMethod(
229 "getPackageInfo",
"(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;",
231 if (packageInfo.isValid()) {
232 QJniObject versionName = packageInfo.getObjectField(
233 "versionName",
"Ljava/lang/String;");
234 if (versionName.isValid())
235 return versionName.toString();
239#elif defined(Q_OS_HARMONY) && !defined(QT_BOOTSTRAPPED)
240 applicationVersion = bundleVersionNameFetcher.optValue().value_or(QString());
242 return applicationVersion;
246bool QCoreApplicationPrivate::checkInstance(
const char *function)
248 bool b = (
qApp !=
nullptr);
250 qWarning(
"QApplication::%s: Please instantiate the QApplication object first", function);
254#if QT_CONFIG(commandlineparser)
255void QCoreApplicationPrivate::addQtOptions(QList<QCommandLineOption> *options)
257 options->append(QCommandLineOption(QStringLiteral(
"qmljsdebugger"),
258 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."),
259 QStringLiteral(
"value")));
263void QCoreApplicationPrivate::processCommandLineArguments()
265 int j = argc ? 1 : 0;
266 for (
int i = 1; i < argc; ++i) {
269 if (*argv[i] !=
'-') {
273 const char *arg = argv[i];
276 if (strncmp(arg,
"-qmljsdebugger=", 15) == 0) {
277 qmljs_debug_arguments = QString::fromLocal8Bit(arg + 15);
278 }
else if (strcmp(arg,
"-qmljsdebugger") == 0 && i < argc - 1) {
280 qmljs_debug_arguments = QString::fromLocal8Bit(argv[i]);
305Q_GLOBAL_STATIC(QVFuncList, postRList)
306Q_CONSTINIT
static QBasicMutex globalRoutinesMutex;
310
311
312
313
314
328 const auto locker = qt_scoped_lock(globalRoutinesMutex);
337 const auto locker = qt_scoped_lock(globalRoutinesMutex);
346 const auto locker = qt_scoped_lock(globalRoutinesMutex);
355 if (!preRList.exists())
359 const auto locker = qt_scoped_lock(globalRoutinesMutex);
366 for (QtStartUpFunction f : list)
370void Q_CORE_EXPORT qt_call_post_routines()
372 if (!postRList.exists())
379 const auto locker = qt_scoped_lock(globalRoutinesMutex);
380 qSwap(*postRList, list);
385 for (QtCleanUpFunction f : std::as_const(list))
394Q_CONSTINIT
bool QCoreApplicationPrivate::is_app_running =
false;
396Q_CONSTINIT
bool QCoreApplicationPrivate::is_app_closing =
false;
400 const QPostEventList &l = QThreadData::current()->postEventList;
401 return l.size() - l.startOffset;
408Q_CONSTINIT uint QCoreApplicationPrivate::attribs =
409 (1 << Qt::AA_SynthesizeMouseForUnhandledTouchEvents) |
410 (1 << Qt::AA_SynthesizeMouseForUnhandledTabletEvents);
425#if QT_CONFIG(library)
438Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
441Q_CONSTINIT
static bool quitLockEnabled =
true;
450static inline bool isArgvModified(
int argc,
char **argv)
452 if (__argc != argc || !__argv )
456 for (
int a = 0; a < argc; ++a) {
457 if (argv[a] != __argv[a] && strcmp(argv[a], __argv[a]))
463static inline bool contains(
int argc,
char **argv,
const char *needle)
465 for (
int a = 0; a < argc; ++a) {
466 if (!strcmp(argv[a], needle))
473QCoreApplicationPrivate::QCoreApplicationPrivate(
int &aargc,
char **aargv)
474 : argc(aargc), argv(aargv)
476 static const char *
const empty =
"";
477 if (argc == 0 || argv ==
nullptr) {
479 argv =
const_cast<
char **>(&empty);
482 if (!isArgvModified(argc, argv)) {
484 origArgv = q20::make_unique_for_overwrite<
char *[]>(argc);
485 std::copy(argv, argv + argc, origArgv.get());
490 QCoreApplicationPrivate::is_app_closing =
false;
492# if defined(Q_OS_UNIX)
493 if (Q_UNLIKELY(!setuidAllowed && (geteuid() != getuid())))
494 qFatal(
"FATAL: The application binary appears to be running setuid, this is a security hole.");
497 QThread *cur = QThread::currentThread();
498 if (cur != theMainThread.loadAcquire())
499 qWarning(
"WARNING: QApplication was not created in the main() thread.");
503QCoreApplicationPrivate::~QCoreApplicationPrivate()
508#if defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED)
509 cleanupDebuggingConsole();
515void QCoreApplicationPrivate::cleanupThreadData()
517 auto thisThreadData = threadData.loadRelaxed();
519 if (thisThreadData && !threadData_clean) {
521 QThreadStoragePrivate::finish(&thisThreadData->tls);
525 thisThreadData->clearEvents();
526 thisThreadData->quitNow =
false;
527 threadData_clean =
true;
531void QCoreApplicationPrivate::createEventDispatcher()
533 Q_Q(QCoreApplication);
534 QThreadData *data = QThreadData::current();
535 Q_ASSERT(!data->hasEventDispatcher());
536 eventDispatcher = data->createEventDispatcher();
537 eventDispatcher->setParent(q);
540void QCoreApplicationPrivate::eventDispatcherReady()
544Q_CONSTINIT QBasicAtomicPointer<QThread> QCoreApplicationPrivate::theMainThread = Q_BASIC_ATOMIC_INITIALIZER(
nullptr);
545Q_CONSTINIT QBasicAtomicPointer<
void> QCoreApplicationPrivate::theMainThreadId = Q_BASIC_ATOMIC_INITIALIZER(
nullptr);
546QThread *QCoreApplicationPrivate::mainThread()
548 Q_ASSERT(theMainThread.loadRelaxed() !=
nullptr);
549 return theMainThread.loadRelaxed();
556 if (!QCoreApplicationPrivate::checkInstance(
"qAppName"))
558 return QCoreApplication::instance()->d_func()->appName();
561void QCoreApplicationPrivate::initLocale()
563#if defined(QT_BOOTSTRAPPED)
565#elif defined(Q_OS_UNIX)
566 Q_CONSTINIT
static bool qt_locale_initialized =
false;
567 if (qt_locale_initialized)
569 qt_locale_initialized =
true;
574 setlocale(LC_ALL,
"");
578# if defined(Q_OS_INTEGRITY)
579 setlocale(LC_CTYPE,
"UTF-8");
580# elif defined(Q_OS_QNX)
583# elif defined(Q_OS_ANDROID) && __ANDROID_API__ < __ANDROID_API_O__
586# elif defined(Q_OS_VXWORKS)
590 const std::string oldEncoding = nl_langinfo(CODESET);
591 if (!Q_LIKELY(qstricmp(oldEncoding.data(),
"UTF-8") == 0
592 || qstricmp(oldEncoding.data(),
"utf8") == 0)) {
593 const QByteArray oldLocale = setlocale(LC_ALL,
nullptr);
594 QByteArray newLocale;
595 bool warnOnOverride =
true;
596# if defined(Q_OS_DARWIN)
600 warnOnOverride = qstrcmp(setlocale(LC_CTYPE,
nullptr),
"C") != 0
601 || getenv(
"LC_ALL") || getenv(
"LC_CTYPE") || getenv(
"LANG");
605 newLocale = setlocale(LC_CTYPE,
"UTF-8");
607 newLocale = setlocale(LC_CTYPE,
nullptr);
608 if (qsizetype dot = newLocale.indexOf(
'.'); dot != -1)
609 newLocale.truncate(dot);
610 if (qsizetype at = newLocale.indexOf(
'@'); at != -1)
611 newLocale.truncate(at);
612 newLocale +=
".UTF-8";
613 newLocale = setlocale(LC_CTYPE, newLocale);
616 if (newLocale.isEmpty())
617 newLocale = setlocale(LC_CTYPE,
"C.UTF-8");
618 if (newLocale.isEmpty())
619 newLocale = setlocale(LC_CTYPE,
"C.utf8");
622 if (newLocale.isEmpty()) {
624 qWarning(
"Detected locale \"%s\" with character encoding \"%s\", which is not UTF-8.\n"
625 "Qt depends on a UTF-8 locale, but has failed to switch to one.\n"
626 "If this causes problems, reconfigure your locale. See the locale(1) manual\n"
627 "for more information.", oldLocale.constData(), oldEncoding.data());
628 }
else if (warnOnOverride) {
630 qWarning(
"Detected locale \"%s\" with character encoding \"%s\", which is not UTF-8.\n"
631 "Qt depends on a UTF-8 locale, and has switched to \"%s\" instead.\n"
632 "If this causes problems, reconfigure your locale. See the locale(1) manual\n"
633 "for more information.",
634 oldLocale.constData(), oldEncoding.data(), newLocale.constData());
643
644
645
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
719
720
721
722
723
724
725
726
727
728
729
732
733
734QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
738 : QObject(p,
nullptr)
741 d_func()->q_ptr =
this;
747
748
749
750
751
752
753
754
755
756
757
758
759
760QCoreApplication::QCoreApplication(
int &argc,
char **argv
766 : d_ptr(
new QCoreApplicationPrivate(argc, argv))
768 : QObject(*
new QCoreApplicationPrivate(argc, argv))
771 d_func()->q_ptr =
this;
774 QCoreApplicationPrivate::eventDispatcher->startingUp();
779
780
781
782
783
785void Q_TRACE_INSTRUMENT(qtcore) QCoreApplicationPrivate::init()
787 Q_TRACE_SCOPE(QCoreApplicationPrivate_init);
789#if defined(Q_OS_MACOS)
790 QMacAutoReleasePool pool;
793 Q_Q(QCoreApplication);
795#if defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED)
796 initDebuggingConsole();
801 Q_ASSERT_X(!QCoreApplication::self,
"QCoreApplication",
"there should be only one application object");
802#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
803# ifdef __cpp_lib_atomic_ref
804 std::atomic_ref(QCoreApplication::self).store(q, std::memory_order_relaxed);
806 QCoreApplication::self = q;
808 g_self.storeRelaxed(q);
810 QCoreApplication::self.storeRelaxed(q);
815 emscripten::val hardwareConcurrency = emscripten::val::global(
"navigator")[
"hardwareConcurrency"];
816 if (hardwareConcurrency.isUndefined())
817 QThreadPrivate::idealThreadCount = 2;
819 QThreadPrivate::idealThreadCount = hardwareConcurrency.as<
int>();
824 if (!coreappdata()->applicationNameSet)
825 coreappdata()->application = appName();
827 if (!coreappdata()->applicationVersionSet)
828 coreappdata()->applicationVersion = appVersion();
830#if (defined(Q_OS_ANDROID) || defined(Q_OS_HARMONY)) && !defined(QT_BOOTSTRAPPED)
835 QLoggingRegistry::instance()->initializeRules();
838#if QT_CONFIG(library)
842 if (coreappdata->libPathsInitialized()) {
843 const QStringList appPaths = std::exchange(coreappdata->app_libpaths, {});
844 Q_ASSERT(!coreappdata->libPathsInitialized());
846 if (coreappdata->libPathsManuallySet()) {
847 const QStringList manualPaths = std::exchange(coreappdata->manual_libpaths, {});
848 Q_ASSERT(!coreappdata->libPathsManuallySet());
854 QStringList newPaths(q->libraryPaths());
855 for (qsizetype i = manualPaths.size(), j = appPaths.size(); i > 0 || j > 0; qt_noop()) {
857 newPaths.prepend(manualPaths[--i]);
858 }
else if (--i < 0) {
859 newPaths.removeAll(appPaths[j]);
860 }
else if (manualPaths[i] != appPaths[j]) {
861 newPaths.removeAll(appPaths[j]);
865 coreappdata->manual_libpaths.swap(newPaths);
872 Q_ASSERT(!eventDispatcher);
873 auto thisThreadData = threadData.loadRelaxed();
874 eventDispatcher = thisThreadData->eventDispatcher.loadRelaxed();
877 if (!eventDispatcher)
878 createEventDispatcher();
879 Q_ASSERT(eventDispatcher);
881 if (!eventDispatcher->parent()) {
882 eventDispatcher->moveToThread(thisThreadData->thread.loadAcquire());
883 eventDispatcher->setParent(q);
886 thisThreadData->eventDispatcher = eventDispatcher;
887 eventDispatcherReady();
890 processCommandLineArguments();
892 qt_call_pre_routines();
893 QT_MANGLE_NAMESPACE(qt_startup_hook)();
894#ifndef QT_BOOTSTRAPPED
895 QtPrivate::initBindingStatusThreadId();
896 if (Q_UNLIKELY(qtHookData[QHooks::Startup]))
897 reinterpret_cast<QHooks::StartupCallback>(qtHookData[QHooks::Startup])();
901 is_app_running =
true;
906
907
908QCoreApplication::~QCoreApplication()
910 preRoutinesCalled =
false;
912 qt_call_post_routines();
915 QCoreApplicationPrivate::is_app_closing =
true;
916 QCoreApplicationPrivate::is_app_running =
false;
919#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
920# ifdef __cpp_lib_atomic_ref
921 std::atomic_ref(self).store(
nullptr, std::memory_order_relaxed);
925 g_self.storeRelaxed(
nullptr);
927 self.storeRelaxed(
nullptr);
932 QThreadPoolPrivate::destroyGlobalThreadPool();
936 QCoreApplicationPrivate::destroyEventDispatcher();
939#if QT_CONFIG(library)
940 if (coreappdata.exists()) {
942 coreappdata->app_libpaths = QStringList();
943 coreappdata->manual_libpaths = QStringList();
944 Q_ASSERT(!coreappdata->libPathsManuallySet());
945 Q_ASSERT(!coreappdata->libPathsInitialized());
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973void QCoreApplication::setSetuidAllowed(
bool allow)
975 QCoreApplicationPrivate::setuidAllowed = allow;
979
980
981
982
983
984
985
986bool QCoreApplication::isSetuidAllowed()
988 return QCoreApplicationPrivate::setuidAllowed;
992
993
994
995
996
997
998
999
1000
1001void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute,
bool on)
1005 static_assert(Qt::AA_AttributeCount <=
sizeof(QCoreApplicationPrivate::attribs) * CHAR_BIT);
1008 QCoreApplicationPrivate::attribs |= 1 << attribute;
1010 QCoreApplicationPrivate::attribs &= ~(1 << attribute);
1011#if defined(QT_NO_QOBJECT)
1012 if (Q_UNLIKELY(qApp)) {
1014 if (Q_UNLIKELY(QCoreApplicationPrivate::is_app_running)) {
1016 switch (attribute) {
1017 case Qt::AA_PluginApplication:
1018 case Qt::AA_UseDesktopOpenGL:
1019 case Qt::AA_UseOpenGLES:
1020 case Qt::AA_UseSoftwareOpenGL:
1021#ifdef QT_BOOTSTRAPPED
1022 qWarning(
"Attribute %d must be set before QCoreApplication is created.",
1025 qWarning(
"Attribute Qt::%s must be set before QCoreApplication is created.",
1026 QMetaEnum::fromType<Qt::ApplicationAttribute>().valueToKey(attribute));
1036
1037
1038
1039
1040
1041bool QCoreApplication::testAttribute(Qt::ApplicationAttribute attribute)
1043 return QCoreApplicationPrivate::testAttribute(attribute);
1046#ifndef QT_NO_QOBJECT
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1067bool QCoreApplication::isQuitLockEnabled()
1069 return quitLockEnabled;
1072static bool doNotify(QObject *, QEvent *);
1074void QCoreApplication::setQuitLockEnabled(
bool enabled)
1076 quitLockEnabled = enabled;
1080
1081
1082
1083
1084
1085
1086bool QCoreApplication::notifyInternal2(QObject *receiver, QEvent *event)
1092 QObjectPrivate *d = receiver->d_func();
1093 QThreadData *threadData = d->threadData.loadAcquire();
1094 bool selfRequired = threadData->requiresCoreApplication;
1095 if (selfRequired && !
qApp)
1100 bool result =
false;
1101 void *cbdata[] = { receiver, event, &result };
1102 if (QInternal::activateCallbacks(QInternal::EventNotifyCallback, cbdata)) {
1106 QScopedScopeLevelCounter scopeLevelCounter(threadData);
1108 return doNotify(receiver, event);
1110 if (QCoreApplicationPrivate::is_app_closing)
1113#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
)
1114 if (!QThread::isMainThread())
1117 return qApp->notify(receiver, event);
1121
1122
1123
1124
1125
1126
1127bool QCoreApplication::forwardEvent(QObject *receiver, QEvent *event, QEvent *originatingEvent)
1129 if (event && originatingEvent)
1130 event->m_spont = originatingEvent->m_spont;
1132 return notifyInternal2(receiver, event);
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
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
1188bool QCoreApplication::notify(QObject *receiver, QEvent *event)
1193#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
)
1194 Q_ASSERT(receiver->d_func()->threadData.loadAcquire()->thread.loadRelaxed()
1195 == QCoreApplicationPrivate::mainThread());
1199 if (QCoreApplicationPrivate::is_app_closing)
1201 return doNotify(receiver, event);
1204static bool doNotify(QObject *receiver, QEvent *event)
1209 if (receiver ==
nullptr) {
1210 qWarning(
"QCoreApplication::notify: Unexpected null receiver");
1214 QCoreApplicationPrivate::checkReceiverThread(receiver,
"QCoreApplication::notify");
1216 return receiver->isWidgetType() ?
false : QCoreApplicationPrivate::notify_helper(receiver, event);
1219bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
1222 Q_ASSERT(QThread::isMainThread());
1226 for (qsizetype i = 0; i < extraData->eventFilters.size(); ++i) {
1227 QObject *obj = extraData->eventFilters.at(i);
1230 if (obj->d_func()->threadData.loadRelaxed() != threadData.loadRelaxed()) {
1231 qWarning(
"QCoreApplication: Application event filter cannot be in a different thread.");
1234 if (obj->eventFilter(receiver, event))
1241bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event)
1243 if (receiver !=
qApp && receiver->d_func()->extraData) {
1244 for (qsizetype i = 0; i < receiver->d_func()->extraData->eventFilters.size(); ++i) {
1245 QObject *obj = receiver->d_func()->extraData->eventFilters.at(i);
1248 if (obj->d_func()->threadData.loadRelaxed() != receiver->d_func()->threadData.loadRelaxed()) {
1249 qWarning(
"QCoreApplication: Object event filter cannot be in a different thread.");
1252 if (obj->eventFilter(receiver, event))
1260
1261
1262
1263
1264bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
1268 Q_TRACE(QCoreApplication_notify_entry, receiver, event, event->type());
1269 bool consumed =
false;
1270 bool filtered =
false;
1271 Q_TRACE_EXIT(QCoreApplication_notify_exit, consumed, filtered);
1274 if (QThread::isMainThread()
1275 && QCoreApplication::self
1276 && QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) {
1281 if (sendThroughObjectEventFilters(receiver, event)) {
1287 consumed = receiver->event(event);
1292
1293
1294
1295
1296
1298bool QCoreApplication::startingUp()
1300 return !QCoreApplicationPrivate::is_app_running;
1304
1305
1306
1307
1308
1310bool QCoreApplication::closingDown()
1312 return QCoreApplicationPrivate::is_app_closing;
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
1347 QThreadData *data = QThreadData::current();
1348 if (!data->hasEventDispatcher())
1350 data->eventDispatcher.loadRelaxed()->processEvents(flags);
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags,
int ms)
1367 QCoreApplication::processEvents(flags, QDeadlineTimer(ms));
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, QDeadlineTimer deadline)
1399 QThreadData *data = QThreadData::current();
1400 if (!data->hasEventDispatcher())
1403 while (data->eventDispatcher.loadRelaxed()->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) {
1404 if (deadline.hasExpired())
1410
1411
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439int QCoreApplication::exec()
1441 if (!QCoreApplicationPrivate::checkInstance(
"exec"))
1444 QThreadData *threadData = self->d_func()->threadData.loadAcquire();
1445 if (threadData != QThreadData::current()) {
1446 qWarning(
"%s::exec: Must be called from the main thread", self->metaObject()->className());
1449 if (!threadData->eventLoops.isEmpty()) {
1450 qWarning(
"QCoreApplication::exec: The event loop is already running");
1454 threadData->quitNow =
false;
1455 QEventLoop eventLoop;
1456 self->d_func()->in_exec =
true;
1457 self->d_func()->aboutToQuitEmitted =
false;
1458 int returnCode = eventLoop.exec(QEventLoop::ApplicationExec);
1459 threadData->quitNow =
false;
1462 self->d_func()->execCleanup();
1473void QCoreApplicationPrivate::execCleanup()
1475 threadData.loadRelaxed()->quitNow =
false;
1477 QCoreApplication::sendPostedEvents(
nullptr, QEvent::DeferredDelete);
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511void QCoreApplication::exit(
int returnCode)
1517 if (!qstdweb::haveAsyncify())
1518 qFatal(
"Terminating since we don't have asyncify");
1520 QCoreApplicationPrivate *d = self->d_func();
1521 if (!d->aboutToQuitEmitted) {
1522 emit self->aboutToQuit(QCoreApplication::QPrivateSignal());
1523 d->aboutToQuitEmitted =
true;
1525 QThreadData *data = d->threadData.loadRelaxed();
1526 data->quitNow =
true;
1527 for (qsizetype i = 0; i < data->eventLoops.size(); ++i) {
1528 QEventLoop *eventLoop = data->eventLoops.at(i);
1529 eventLoop->exit(returnCode);
1534
1535
1537#ifndef QT_NO_QOBJECT
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
1554 Q_ASSERT_X(receiver,
"QCoreApplication::sendEvent",
"Unexpected null receiver");
1555 Q_ASSERT_X(event,
"QCoreApplication::sendEvent",
"Unexpected null event");
1557 Q_TRACE(QCoreApplication_sendEvent, receiver, event, event->type());
1559 event->m_spont =
false;
1560 return notifyInternal2(receiver, event);
1564
1565
1566bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent *event)
1568 Q_ASSERT_X(receiver,
"QCoreApplication::sendSpontaneousEvent",
"Unexpected null receiver");
1569 Q_ASSERT_X(event,
"QCoreApplication::sendSpontaneousEvent",
"Unexpected null event");
1571 Q_TRACE(QCoreApplication_sendSpontaneousEvent, receiver, event, event->type());
1573 event->m_spont =
true;
1574 return notifyInternal2(receiver, event);
1579QCoreApplicationPrivate::QPostEventListLocker QCoreApplicationPrivate::lockThreadPostEventList(QObject *object)
1581 QPostEventListLocker locker;
1584 locker.threadData = QThreadData::current();
1585 locker.locker = qt_unique_lock(locker.threadData->postEventList.mutex);
1589 auto &threadData = QObjectPrivate::get(object)->threadData;
1594 locker.threadData = threadData.loadAcquire();
1595 if (!locker.threadData) {
1600 auto temporaryLocker = qt_unique_lock(locker.threadData->postEventList.mutex);
1601 if (locker.threadData == threadData.loadAcquire()) {
1602 locker.locker = std::move(temporaryLocker);
1607 Q_ASSERT(locker.threadData);
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647void QCoreApplication::postEvent(QObject *receiver, QEvent *event,
int priority)
1649 Q_ASSERT_X(event,
"QCoreApplication::postEvent",
"Unexpected null event");
1651 Q_TRACE_SCOPE(QCoreApplication_postEvent, receiver, event, event->type());
1654 if (receiver ==
nullptr) {
1655 qWarning(
"QCoreApplication::postEvent: Unexpected null receiver");
1660 auto locker = QCoreApplicationPrivate::lockThreadPostEventList(receiver);
1661 if (!locker.threadData) {
1667 QThreadData *data = locker.threadData;
1670 QT_WARNING_DISABLE_DEPRECATED
1672 if (receiver->d_func()->postedEvents.loadAcquire()
1673 && self && self->compressEvent(event, receiver, &data->postEventList)) {
1674 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.fetchAndAddRelease(1);
1687 data->canWait =
false;
1690 QAbstractEventDispatcher* dispatcher = data->eventDispatcher.loadAcquire();
1692 dispatcher->wakeUp();
1696
1697
1698
1699#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
1700bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
1702 return d_func()->compressEvent(event, receiver, postedEvents);
1706bool QCoreApplicationPrivate::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
1710 Q_ASSERT(postedEvents);
1713 if (event->type() == QEvent::Timer) {
1714 const int timerId =
static_cast<QTimerEvent *>(event)->timerId();
1715 auto it = postedEvents->cbegin();
1716 const auto end = postedEvents->cend();
1718 if (it->event && it->event->type() == QEvent::Timer && it->receiver == receiver) {
1719 if (
static_cast<QTimerEvent *>(it->event)->timerId() == timerId) {
1729 if (event->type() == QEvent::Quit) {
1730 for (
const QPostEvent &cur : std::as_const(*postedEvents)) {
1731 if (cur.receiver != receiver
1732 || cur.event ==
nullptr
1733 || cur.event->type() != event->type())
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761void QCoreApplication::sendPostedEvents(QObject *receiver,
int event_type)
1766 QThreadData *data = QThreadData::current();
1768 QCoreApplicationPrivate::sendPostedEvents(receiver, event_type, data);
1771void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver,
int event_type,
1774 if (event_type == -1) {
1779 if (receiver && receiver->d_func()->threadData.loadRelaxed() != data) {
1780 qWarning(
"QCoreApplication::sendPostedEvents: Cannot send "
1781 "posted events for objects in another thread");
1785 ++data->postEventList.recursion;
1787 auto locker = qt_unique_lock(data->postEventList.mutex);
1792 data->canWait = (data->postEventList.size() == 0);
1794 if (data->postEventList.size() == 0
1795 || (receiver && !receiver->d_func()->postedEvents.loadAcquire())) {
1796 --data->postEventList.recursion;
1800 data->canWait =
true;
1804 qsizetype startOffset = data->postEventList.startOffset;
1805 qsizetype &i = (!event_type && !receiver) ? data->postEventList.startOffset : startOffset;
1806 data->postEventList.insertionOffset = data->postEventList.size();
1810 Q_DISABLE_COPY_MOVE(CleanUp)
1815 bool exceptionCaught;
1817 inline CleanUp(QObject *receiver,
int event_type, QThreadData *data) :
1818 receiver(receiver), event_type(event_type), data(data), exceptionCaught(
true)
1822 if (exceptionCaught) {
1824 data->canWait =
false;
1827 --data->postEventList.recursion;
1828 if (!data->postEventList.recursion && !data->canWait && data->hasEventDispatcher())
1829 data->eventDispatcher.loadRelaxed()->wakeUp();
1833 if (!event_type && !receiver && data->postEventList.startOffset >= 0) {
1834 const QPostEventList::iterator it = data->postEventList.begin();
1835 data->postEventList.erase(it, it + data->postEventList.startOffset);
1836 data->postEventList.insertionOffset -= data->postEventList.startOffset;
1837 Q_ASSERT(data->postEventList.insertionOffset >= 0);
1838 data->postEventList.startOffset = 0;
1842 CleanUp cleanup(receiver, event_type, data);
1844 while (i < data->postEventList.size()) {
1846 if (i >= data->postEventList.insertionOffset)
1849 const QPostEvent &pe = data->postEventList.at(i);
1854 if ((receiver && receiver != pe.receiver) || (event_type && event_type != pe.event->type())) {
1855 data->canWait =
false;
1859 if (pe.event->type() == QEvent::DeferredDelete) {
1866 const int eventLoopLevel =
static_cast<QDeferredDeleteEvent *>(pe.event)->loopLevel();
1867 const int eventScopeLevel =
static_cast<QDeferredDeleteEvent *>(pe.event)->scopeLevel();
1869 const bool postedBeforeOutermostLoop = eventLoopLevel == 0;
1870 const bool allowDeferredDelete =
1871 (eventLoopLevel + eventScopeLevel > data->loopLevel + data->scopeLevel
1872 || (postedBeforeOutermostLoop && data->loopLevel > 0)
1873 || (event_type == QEvent::DeferredDelete
1874 && eventLoopLevel + eventScopeLevel == data->loopLevel + data->scopeLevel));
1875 if (!allowDeferredDelete) {
1877 if (!event_type && !receiver) {
1882 QPostEvent pe_copy = pe;
1886 const_cast<QPostEvent &>(pe).event =
nullptr;
1889 data->postEventList.addEvent(pe_copy);
1897 pe.event->m_posted =
false;
1898 QEvent *e = pe.event;
1899 QObject * r = pe.receiver;
1902 const auto previous = r->d_func()->postedEvents.fetchAndSubAcquire(1);
1903 Q_ASSERT(previous > 0);
1907 const_cast<QPostEvent &>(pe).event =
nullptr;
1910 const auto relocker = qScopeGuard([&locker] { locker.lock(); });
1912 const std::unique_ptr<QEvent> event_deleter(e);
1915 QCoreApplication::sendEvent(r, e);
1922 cleanup.exceptionCaught =
false;
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1944void QCoreApplication::removePostedEvents(QObject *receiver,
int eventType)
1946 auto locker = QCoreApplicationPrivate::lockThreadPostEventList(receiver);
1947 QThreadData *data = locker.threadData;
1953 if (receiver && !receiver->d_func()->postedEvents.loadAcquire())
1958 QVarLengthArray<QEvent*> events;
1959 qsizetype n = data->postEventList.size();
1962 for (qsizetype i = 0; i < n; ++i) {
1963 const QPostEvent &pe = data->postEventList.at(i);
1965 if ((!receiver || pe.receiver == receiver)
1966 && (pe.event && (eventType == 0 || pe.event->type() == eventType))) {
1967 pe.receiver->d_func()->postedEvents.fetchAndSubAcquire(1);
1968 pe.event->m_posted =
false;
1969 events.append(pe.event);
1970 const_cast<QPostEvent &>(pe).event =
nullptr;
1971 }
else if (!data->postEventList.recursion) {
1973 qSwap(data->postEventList[i], data->postEventList[j]);
1979 if (receiver && eventType == 0) {
1980 Q_ASSERT(!receiver->d_func()->postedEvents.loadRelaxed());
1984 if (!data->postEventList.recursion) {
1986 data->postEventList.erase(data->postEventList.begin() + j, data->postEventList.end());
1994
1995
1996
1997
1998
1999
2000
2001
2002
2004void QCoreApplicationPrivate::removePostedEvent(QEvent * event)
2006 if (!event || !event->m_posted)
2009 QThreadData *data = QThreadData::current();
2011 const auto locker = qt_scoped_lock(data->postEventList.mutex);
2013 if (data->postEventList.size() == 0) {
2014#if defined(QT_DEBUG)
2015 qDebug(
"QCoreApplication::removePostedEvent: Internal error: %p %d is posted",
2016 (
void*)event, event->type());
2021 for (
const QPostEvent &pe : std::as_const(data->postEventList)) {
2022 if (pe.event == event) {
2024 qWarning(
"QCoreApplication::removePostedEvent: Event of type %d deleted while posted to %s %s",
2026 pe.receiver->metaObject()->className(),
2027 pe.receiver->objectName().toLocal8Bit().data());
2029 pe.receiver->d_func()->postedEvents.fetchAndSubAcquire(1);
2030 pe.event->m_posted =
false;
2032 const_cast<QPostEvent &>(pe).event =
nullptr;
2039
2040
2041bool QCoreApplication::event(QEvent *e)
2043 if (e->type() == QEvent::Quit) {
2047 return QObject::event(e);
2050void QCoreApplicationPrivate::ref()
2055void QCoreApplicationPrivate::deref()
2057 quitLockRef.deref();
2059 if (quitLockEnabled && canQuitAutomatically())
2060 quitAutomatically();
2063bool QCoreApplicationPrivate::canQuitAutomatically()
2074 if (quitLockRef.loadRelaxed())
2080void QCoreApplicationPrivate::quitAutomatically()
2082 Q_Q(QCoreApplication);
2090 QCoreApplication::postEvent(q,
new QEvent(QEvent::Quit));
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127void QCoreApplication::quit()
2132 if (!self->d_func()->in_exec)
2135 self->d_func()->quit();
2138void QCoreApplicationPrivate::quit()
2140 Q_Q(QCoreApplication);
2142 if (QThread::isMainThread()) {
2143 QEvent quitEvent(QEvent::Quit);
2144 QCoreApplication::sendEvent(q, &quitEvent);
2146 QCoreApplication::postEvent(q,
new QEvent(QEvent::Quit));
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2173#ifndef QT_NO_TRANSLATION
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2205bool QCoreApplication::installTranslator(QTranslator *translationFile)
2207 if (!translationFile)
2210 if (!QCoreApplicationPrivate::checkInstance(
"installTranslator"))
2213 QCoreApplicationPrivate *d = self->d_func();
2215 QWriteLocker locker(&d->translateMutex);
2216 d->translators.prepend(translationFile);
2219 if (translationFile->isEmpty())
2222#ifndef QT_NO_QOBJECT
2223 QEvent ev(QEvent::LanguageChange);
2224 QCoreApplication::sendEvent(self, &ev);
2231
2232
2233
2234
2235
2236
2237
2238
2240bool QCoreApplication::removeTranslator(QTranslator *translationFile)
2242 if (!translationFile)
2244 if (!QCoreApplicationPrivate::checkInstance(
"removeTranslator"))
2246 QCoreApplicationPrivate *d = self->d_func();
2247 QWriteLocker locker(&d->translateMutex);
2248 if (d->translators.removeAll(translationFile)) {
2249#ifndef QT_NO_QOBJECT
2251 if (!self->closingDown()) {
2252 QEvent ev(QEvent::LanguageChange);
2253 QCoreApplication::sendEvent(self, &ev);
2264 qsizetype percentPos = 0;
2266 while ((percentPos = result->indexOf(u'%', percentPos + len)) != -1) {
2268 if (percentPos + len == result->size())
2271 if (result->at(percentPos + len) == u'L') {
2273 if (percentPos + len == result->size())
2279 if (result->at(percentPos + len) == u'n') {
2282 result->replace(percentPos, len, fmt);
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322QString QCoreApplication::translate(
const char *context,
const char *sourceText,
2323 const char *disambiguation,
int n)
2331 QCoreApplicationPrivate *d = self->d_func();
2332 QReadLocker locker(&d->translateMutex);
2333 if (!d->translators.isEmpty()) {
2334 QList<QTranslator*>::ConstIterator it;
2335 QTranslator *translationFile;
2336 for (it = d->translators.constBegin(); it != d->translators.constEnd(); ++it) {
2337 translationFile = *it;
2338 result = translationFile->translate(context, sourceText, disambiguation, n);
2339 if (!result.isNull())
2345 if (result.isNull())
2346 result = QString::fromUtf8(sourceText);
2348 replacePercentN(&result, n);
2355 return QCoreApplication::translate(
nullptr, id,
nullptr, n);
2358bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator)
2360 if (!QCoreApplication::self)
2362 QCoreApplicationPrivate *d = QCoreApplication::self->d_func();
2363 QReadLocker locker(&d->translateMutex);
2364 return d->translators.contains(translator);
2369QString QCoreApplication::translate(
const char *context,
const char *sourceText,
2370 const char *disambiguation,
int n)
2373 Q_UNUSED(disambiguation);
2374 QString ret = QString::fromUtf8(sourceText);
2376 ret.replace(
"%n"_L1, QString::number(n));
2382#ifndef QT_BOOTSTRAPPED
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406QString QCoreApplication::applicationDirPath()
2409 qWarning(
"QCoreApplication::applicationDirPath: Please instantiate the QApplication object first");
2413 QFileSystemEntry appFilePath(applicationFilePath(), QFileSystemEntry::FromInternalPath{});
2414 return appFilePath.isEmpty() ? QString() : appFilePath.path();
2417#if !defined(Q_OS_WIN) && !defined(Q_OS_DARWIN)
2421# if defined(Q_OS_ANDROID) || defined(Q_OS_HARMONY)
2424# elif defined(Q_OS_LINUX)
2426 return QFile::decodeName(qt_readlink(
"/proc/self/exe"));
2427# elif defined(AT_EXECPATH)
2429 char execfn[PATH_MAX];
2430 if (elf_aux_info(AT_EXECPATH, execfn,
sizeof(execfn)) != 0)
2433 qsizetype len = qstrlen(execfn);
2434 return QFile::decodeName(QByteArray::fromRawData(execfn, len));
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457QString QCoreApplication::applicationFilePath()
2460 qWarning(
"QCoreApplication::applicationFilePath: Please instantiate the QApplication object first");
2464 QCoreApplicationPrivate *d = self->d_func();
2467 static QByteArray procName = QByteArray(d->argv[0]);
2468 if (procName != QByteArrayView(d->argv[0])) {
2470 d->cachedApplicationFilePath = QString();
2471 procName.assign(d->argv[0]);
2475 if (!d->cachedApplicationFilePath.isNull())
2476 return d->cachedApplicationFilePath;
2478 QString absPath = qAppFileName();
2479 if (Q_LIKELY(!absPath.isEmpty())) {
2481 return d->cachedApplicationFilePath = std::move(absPath);
2484 if (
const QStringList args = arguments(); !args.isEmpty()) {
2485 const QString &argv0 = args[0];
2487 if (!argv0.isEmpty() && argv0.at(0) == u'/') {
2489
2490
2491
2493 }
else if (argv0.contains(u'/')) {
2495
2496
2497
2498 absPath = QDir::current().absoluteFilePath(argv0);
2501
2502
2503
2504 absPath = QStandardPaths::findExecutable(argv0);
2508 absPath = QFileInfo(absPath).canonicalFilePath();
2509 if (!absPath.isEmpty()) {
2510 return d->cachedApplicationFilePath = std::move(absPath);
2517
2518
2519
2520
2521qint64 QCoreApplication::applicationPid()
noexcept
2523#if defined(Q_OS_WIN)
2524 return GetCurrentProcessId();
2525#elif defined(Q_OS_VXWORKS)
2526 return (pid_t) taskIdCurrent;
2533static QStringList winCmdArgs()
2542 if (
wchar_t **argv = CommandLineToArgvW(GetCommandLine(), &size)) {
2543 result.reserve(size);
2544 wchar_t **argvEnd = argv + size;
2545 for (
wchar_t **a = argv; a < argvEnd; ++a)
2546 result.append(QString::fromWCharArray(*a));
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2585QStringList QCoreApplication::arguments()
2590 qWarning(
"QCoreApplication::arguments: Please instantiate the QApplication object first");
2594 const QCoreApplicationPrivate *d = self->d_func();
2596 const int argc = d->argc;
2597 char **
const argv = d->argv;
2600#if defined(Q_OS_WIN)
2601 const bool argsModifiedByUser = d->origArgv ==
nullptr;
2602 if (!argsModifiedByUser) {
2603 QStringList commandLineArguments = winCmdArgs();
2608 if (argc != d->origArgc) {
2615 for (
int i = 0; i < d->origArgc; ++i) {
2616 if (!contains(argc, argv, d->origArgv[i]))
2617 commandLineArguments.removeAll(QString::fromLocal8Bit(d->origArgv[i]));
2621 return commandLineArguments;
2625 for (
int a = 0; a < argc; ++a)
2626 list << QString::fromLocal8Bit(argv[a]);
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2648
2649
2650
2651
2652
2653
2654
2655void QCoreApplication::setOrganizationName(
const QString &orgName)
2657 if (coreappdata()->orgName == orgName)
2659 coreappdata()->orgName = orgName;
2660#ifndef QT_NO_QOBJECT
2661 if (QCoreApplication::self)
2662 emit QCoreApplication::self->organizationNameChanged();
2666QString QCoreApplication::organizationName()
2668 return coreappdata()->orgName;
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2687
2688
2689
2690
2691
2692void QCoreApplication::setOrganizationDomain(
const QString &orgDomain)
2694 if (coreappdata()->orgDomain == orgDomain)
2696 coreappdata()->orgDomain = orgDomain;
2697#ifndef QT_NO_QOBJECT
2698 if (QCoreApplication::self)
2699 emit QCoreApplication::self->organizationDomainChanged();
2703QString QCoreApplication::organizationDomain()
2705 return coreappdata()->orgDomain;
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2725
2726
2727
2728
2729
2730void QCoreApplication::setApplicationName(
const QString &application)
2732 coreappdata()->applicationNameSet = !application.isEmpty();
2733 QString newAppName = application;
2734 if (newAppName.isEmpty() && QCoreApplication::self)
2735 newAppName = QCoreApplication::self->d_func()->appName();
2736 if (coreappdata()->application == newAppName)
2738 coreappdata()->application = newAppName;
2739#ifndef QT_NO_QOBJECT
2740 if (QCoreApplication::self)
2741 emit QCoreApplication::self->applicationNameChanged();
2745QString QCoreApplication::applicationName()
2747 return coreappdata() ? coreappdata()->application : QString();
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2781
2782
2783
2784
2785
2786void QCoreApplication::setApplicationVersion(
const QString &version)
2788 coreappdata()->applicationVersionSet = !version.isEmpty();
2789 QString newVersion = version;
2790 if (newVersion.isEmpty() && QCoreApplication::self)
2791 newVersion = QCoreApplication::self->d_func()->appVersion();
2792 if (coreappdata()->applicationVersion == newVersion)
2794 coreappdata()->applicationVersion = newVersion;
2795#ifndef QT_NO_QOBJECT
2796 if (QCoreApplication::self)
2797 emit QCoreApplication::self->applicationVersionChanged();
2801QString QCoreApplication::applicationVersion()
2803 return coreappdata() ? coreappdata()->applicationVersion : QString();
2806#if QT_CONFIG(permissions) || defined(Q_QDOC)
2809
2810
2811
2812
2813
2814
2815
2816
2817Qt::PermissionStatus QCoreApplication::checkPermission(
const QPermission &permission)
2819 return QPermissions::Private::checkPermission(permission);
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2889
2890
2891
2892
2893
2894
2895
2896void QCoreApplication::requestPermissionImpl(
const QPermission &requestedPermission,
2897 QtPrivate::QSlotObjectBase *slotObjRaw,
const QObject *context)
2899 QtPrivate::SlotObjUniquePtr slotObj{slotObjRaw};
2902 if (!QThread::isMainThread()) {
2903 qCWarning(lcPermissions,
"Permissions can only be requested from the GUI (main) thread");
2907 class PermissionReceiver :
public QObject
2910 explicit PermissionReceiver(QtPrivate::SlotObjUniquePtr &&slotObject,
const QObject *context)
2911 : slotObject(std::move(slotObject)), context(context ? context :
this)
2913 Q_ASSERT(
this->context);
2914 moveToThread(
this->context->thread());
2917 void finalizePermissionRequest(
const QPermission &permission)
2919 Q_ASSERT(slotObject);
2922 void *args[] = {
nullptr,
const_cast<QPermission *>(&permission) };
2923 slotObject->call(
const_cast<QObject *>(context.data()), args);
2928 QtPrivate::SlotObjUniquePtr slotObject;
2929 QPointer<
const QObject> context;
2933 auto receiver = std::make_shared<PermissionReceiver>(std::move(slotObj), context);
2935 QPermissions::Private::requestPermission(requestedPermission,
2936 [=, receiver = std::move(receiver)](Qt::PermissionStatus status)
mutable {
2937 if (status == Qt::PermissionStatus::Undetermined) {
2938 Q_ASSERT_X(
false,
"QPermission",
2939 "Internal error: requestPermission() should never return Undetermined");
2940 status = Qt::PermissionStatus::Denied;
2943 if (QCoreApplication::self) {
2944 QPermission permission = requestedPermission;
2945 permission.m_status = status;
2946 auto receiverObject = receiver.get();
2947 QMetaObject::invokeMethod(receiverObject,
2948 [receiver = std::move(receiver), permission] {
2949 receiver->finalizePermissionRequest(permission);
2950 }, Qt::QueuedConnection);
2957#if QT_CONFIG(library)
2958static QStringList libraryPathsLocked();
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993QStringList QCoreApplication::libraryPaths()
2995 QMutexLocker locker(&coreappdata->libraryPathMutex);
2996 return libraryPathsLocked();
3000
3001
3002static QStringList libraryPathsLocked()
3004 QCoreApplicationData *d = coreappdata;
3005 if (d->libPathsManuallySet())
3006 return d->manual_libpaths;
3008 QStringList *app_libpaths = &d->app_libpaths;
3009 if (!d->libPathsInitialized()) {
3011 auto setPathsFromEnv = [&](QString libPathEnv) {
3012 if (!libPathEnv.isEmpty()) {
3013 QStringList paths = libPathEnv.split(QDir::listSeparator(), Qt::SkipEmptyParts);
3014 for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
3015 QString canonicalPath = QDir(*it).canonicalPath();
3016 if (!canonicalPath.isEmpty()
3017 && !app_libpaths->contains(canonicalPath)) {
3018 app_libpaths->append(canonicalPath);
3023 setPathsFromEnv(qEnvironmentVariable(
"QT_PLUGIN_PATH"));
3025 const auto pluginPaths = QLibraryInfo::paths(QLibraryInfo::PluginsPath);
3026 for (
auto path : pluginPaths) {
3027 if (QFile::exists(path)) {
3029 path = QDir(path).canonicalPath();
3030 if (!app_libpaths->contains(path))
3031 app_libpaths->append(path);
3038 QString app_location = QCoreApplication::applicationFilePath();
3039 app_location.truncate(app_location.lastIndexOf(u'/'));
3040 app_location = QDir(app_location).canonicalPath();
3041 if (QFile::exists(app_location) && !app_libpaths->contains(app_location))
3042 app_libpaths->append(app_location);
3044 if (app_libpaths->isEmpty())
3045 app_libpaths->reserve(1);
3046 Q_ASSERT(d->libPathsInitialized());
3048 return *app_libpaths;
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068void QCoreApplication::setLibraryPaths(
const QStringList &paths)
3070 QCoreApplicationData *d = coreappdata;
3071 QMutexLocker locker(&d->libraryPathMutex);
3076 if (!d->libPathsInitialized())
3077 libraryPathsLocked();
3079 d->manual_libpaths = paths;
3080 if (d->manual_libpaths.isEmpty())
3081 d->manual_libpaths.reserve(1);
3082 Q_ASSERT(d->libPathsManuallySet());
3085 QFactoryLoader::refreshAll();
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107void QCoreApplication::addLibraryPath(
const QString &path)
3112 QString canonicalPath = QDir(path).canonicalPath();
3113 if (canonicalPath.isEmpty())
3116 QCoreApplicationData *d = coreappdata;
3117 QMutexLocker locker(&d->libraryPathMutex);
3119 QStringList *libpaths = &d->manual_libpaths;
3120 if (d->libPathsManuallySet()) {
3121 if (d->manual_libpaths.contains(canonicalPath))
3125 libraryPathsLocked();
3126 QStringList *app_libpaths = &d->app_libpaths;
3127 if (app_libpaths->contains(canonicalPath))
3130 *libpaths = *app_libpaths;
3133 libpaths->prepend(canonicalPath);
3134 Q_ASSERT(d->libPathsManuallySet());
3136 QFactoryLoader::refreshAll();
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151void QCoreApplication::removeLibraryPath(
const QString &path)
3156 QString canonicalPath = QDir(path).canonicalPath();
3157 if (canonicalPath.isEmpty())
3160 QCoreApplicationData *d = coreappdata;
3161 QMutexLocker locker(&d->libraryPathMutex);
3163 QStringList *libpaths = &d->manual_libpaths;
3164 if (d->libPathsManuallySet()) {
3165 if (libpaths->removeAll(canonicalPath) == 0)
3169 libraryPathsLocked();
3170 QStringList *app_libpaths = &d->app_libpaths;
3171 if (!app_libpaths->contains(canonicalPath))
3174 *libpaths = *app_libpaths;
3175 libpaths->removeAll(canonicalPath);
3176 Q_ASSERT(d->libPathsManuallySet());
3180 QFactoryLoader::refreshAll();
3185#ifndef QT_NO_QOBJECT
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216void QCoreApplication::installNativeEventFilter(QAbstractNativeEventFilter *filterObj)
3218 if (QCoreApplication::testAttribute(Qt::AA_PluginApplication)) {
3219 qWarning(
"Native event filters are not applied when the Qt::AA_PluginApplication attribute is set");
3223 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread.loadAcquire());
3224 if (!filterObj || !eventDispatcher)
3226 eventDispatcher->installNativeEventFilter(filterObj);
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242void QCoreApplication::removeNativeEventFilter(QAbstractNativeEventFilter *filterObject)
3244 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread.loadAcquire());
3245 if (!filterObject || !eventDispatcher)
3247 eventDispatcher->removeNativeEventFilter(filterObject);
3251
3252
3253
3254QAbstractEventDispatcher *QCoreApplication::eventDispatcher()
3256 if (QCoreApplicationPrivate::theMainThread.loadAcquire())
3257 return QCoreApplicationPrivate::theMainThread.loadRelaxed()->eventDispatcher();
3262
3263
3264
3265
3266
3267void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
3269 QThread *mainThread = QCoreApplicationPrivate::theMainThread.loadAcquire();
3271 mainThread = QThread::currentThread();
3272 mainThread->setEventDispatcher(eventDispatcher);
3275void QCoreApplicationPrivate::destroyEventDispatcher()
3278 QThreadData *data = QThreadData::current();
3279 Q_ASSERT(data->eventDispatcher.loadAcquire() == eventDispatcher);
3283 QAbstractEventDispatcher *dispatcher = eventDispatcher;
3284 eventDispatcher =
nullptr;
3285 data->eventDispatcher.storeRelaxed(
nullptr);
3287 dispatcher->closingDown();
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
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
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3402void *QCoreApplication::resolveInterface(
const char *name,
int revision)
const
3404#if defined(Q_OS_ANDROID)
3409 using namespace QNativeInterface;
3410 struct AndroidApplication :
public QAndroidApplication {};
3411 static AndroidApplication androidApplication;
3412 QT_NATIVE_INTERFACE_RETURN_IF(QAndroidApplication, &androidApplication);
3414#if defined(Q_OS_HARMONY)
3415 using namespace QNativeInterface;
3416 struct HarmonyApplication :
public QHarmonyApplication {};
3417 static HarmonyApplication harmonyApplication;
3418 QT_NATIVE_INTERFACE_RETURN_IF(QHarmonyApplication, &harmonyApplication);
3420 Q_UNUSED(name); Q_UNUSED(revision);
3426#ifndef QT_NO_QOBJECT
3427#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