1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Copyright (C) 2016 Intel Corporation.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40
41 #include "qcoreapplication.h"
42 #include "qcoreapplication_p.h"
43
44 #ifndef QT_NO_QOBJECT
45 #include "qabstracteventdispatcher.h"
46 #include "qcoreevent.h"
47 #include "qeventloop.h"
48 #endif
49 #include "qmetaobject.h"
50 #include "qcorecmdlineargs_p.h"
51 #include <qdatastream.h>
52 #include <qdebug.h>
53 #include <qdir.h>
54 #include <qfile.h>
55 #include <qfileinfo.h>
56 #include <qmutex.h>
57 #include <private/qloggingregistry_p.h>
58 #include <qscopeguard.h>
59 #include <qstandardpaths.h>
60 #ifndef QT_NO_QOBJECT
61 #include <qthread.h>
62 #include <qthreadstorage.h>
63 #include <private/qthread_p.h>
64 #if QT_CONFIG(thread)
65 #include <qthreadpool.h>
66 #endif
67 #endif
68 #include <qelapsedtimer.h>
69 #include <qlibraryinfo.h>
70 #include <qvarlengtharray.h>
71 #include <private/qfactoryloader_p.h>
72 #include <private/qfunctions_p.h>
73 #include <private/qlocale_p.h>
74 #include <private/qlocking_p.h>
75 #include <private/qhooks_p.h>
76
77 #ifndef QT_NO_QOBJECT
78 #if defined(Q_OS_UNIX)
79 # if defined(Q_OS_DARWIN)
80 # include "qeventdispatcher_cf_p.h"
81 # else
82 # if !defined(QT_NO_GLIB)
83 # include "qeventdispatcher_glib_p.h"
84 # endif
85 # endif
86 # include "qeventdispatcher_unix_p.h"
87 #endif
88 #ifdef Q_OS_WIN
89 # ifdef Q_OS_WINRT
90 # include "qeventdispatcher_winrt_p.h"
91 # include "qfunctions_winrt.h"
92 # include <wrl.h>
93 # include <Windows.ApplicationModel.core.h>
94 using namespace ABI::Windows::ApplicationModel::Core;
95 using namespace Microsoft::WRL;
96 # else
97 # include "qeventdispatcher_win_p.h"
98 # endif
99 #endif
100 #endif // QT_NO_QOBJECT
101
102 #if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
103 # include <private/qjni_p.h>
104 # include <private/qjnihelpers_p.h>
105 #endif
106
107 #ifdef Q_OS_MAC
108 # include "qcore_mac_p.h"
109 #endif
110
111 #include <stdlib.h>
112
113 #ifdef Q_OS_UNIX
114 # include <locale.h>
115 # include <unistd.h>
116 # include <sys/types.h>
117 #endif
118
119 #ifdef Q_OS_VXWORKS
120 # include <taskLib.h>
121 #endif
122
123 #ifdef Q_OS_WASM
124 #include <emscripten/val.h>
125 #endif
126
127 #ifdef QT_BOOTSTRAPPED
128 #include <private/qtrace_p.h>
129 #else
130 #include <qtcore_tracepoints_p.h>
131 #endif
132
133 #include <algorithm>
134
135 QT_BEGIN_NAMESPACE
136
137 #if defined(Q_OS_WIN) || defined(Q_OS_MAC)
138 extern QString qAppFileName();
139 #endif
140
141 #if QT_VERSION >= 0x060000
142 # error "Bump QCoreApplicatoinPrivate::app_compile_version to 0x060000"
143 #endif
144 int QCoreApplicationPrivate::app_compile_version = 0x050000; //we don't know exactly, but it's at least 5.0.0
145
146 bool QCoreApplicationPrivate::setuidAllowed = false;
147
148 #if !defined(Q_OS_WIN)
149 #ifdef Q_OS_DARWIN
infoDictionaryStringProperty(const QString & propertyName)150 QString QCoreApplicationPrivate::infoDictionaryStringProperty(const QString &propertyName)
151 {
152 QString bundleName;
153 QCFString cfPropertyName = propertyName.toCFString();
154 CFTypeRef string = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(),
155 cfPropertyName);
156 if (string)
157 bundleName = QString::fromCFString(static_cast<CFStringRef>(string));
158 return bundleName;
159 }
160 #endif
appName() const161 QString QCoreApplicationPrivate::appName() const
162 {
163 QString applicationName;
164 #ifdef Q_OS_DARWIN
165 applicationName = infoDictionaryStringProperty(QStringLiteral("CFBundleName"));
166 #endif
167 if (applicationName.isEmpty() && argv[0]) {
168 char *p = strrchr(argv[0], '/');
169 applicationName = QString::fromLocal8Bit(p ? p + 1 : argv[0]);
170 }
171
172 return applicationName;
173 }
appVersion() const174 QString QCoreApplicationPrivate::appVersion() const
175 {
176 QString applicationVersion;
177 #ifndef QT_BOOTSTRAPPED
178 # ifdef Q_OS_DARWIN
179 applicationVersion = infoDictionaryStringProperty(QStringLiteral("CFBundleVersion"));
180 # elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
181 QJNIObjectPrivate context(QtAndroidPrivate::context());
182 if (context.isValid()) {
183 QJNIObjectPrivate pm = context.callObjectMethod(
184 "getPackageManager", "()Landroid/content/pm/PackageManager;");
185 QJNIObjectPrivate pn = context.callObjectMethod<jstring>("getPackageName");
186 if (pm.isValid() && pn.isValid()) {
187 QJNIObjectPrivate packageInfo = pm.callObjectMethod(
188 "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;",
189 pn.object(), 0);
190 if (packageInfo.isValid()) {
191 QJNIObjectPrivate versionName = packageInfo.getObjectField(
192 "versionName", "Ljava/lang/String;");
193 if (versionName.isValid())
194 return versionName.toString();
195 }
196 }
197 }
198 # endif
199 #endif
200 return applicationVersion;
201 }
202 #endif
203
204 QString *QCoreApplicationPrivate::cachedApplicationFilePath = nullptr;
205
checkInstance(const char * function)206 bool QCoreApplicationPrivate::checkInstance(const char *function)
207 {
208 bool b = (QCoreApplication::self != nullptr);
209 if (!b)
210 qWarning("QApplication::%s: Please instantiate the QApplication object first", function);
211 return b;
212 }
213
214 #if QT_CONFIG(commandlineparser)
addQtOptions(QList<QCommandLineOption> * options)215 void QCoreApplicationPrivate::addQtOptions(QList<QCommandLineOption> *options)
216 {
217 options->append(QCommandLineOption(QStringLiteral("qmljsdebugger"),
218 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."),
219 QStringLiteral("value")));
220 }
221 #endif
222
processCommandLineArguments()223 void QCoreApplicationPrivate::processCommandLineArguments()
224 {
225 int j = argc ? 1 : 0;
226 for (int i = 1; i < argc; ++i) {
227 if (!argv[i])
228 continue;
229 if (*argv[i] != '-') {
230 argv[j++] = argv[i];
231 continue;
232 }
233 const char *arg = argv[i];
234 if (arg[1] == '-') // startsWith("--")
235 ++arg;
236 if (strncmp(arg, "-qmljsdebugger=", 15) == 0) {
237 qmljs_debug_arguments = QString::fromLocal8Bit(arg + 15);
238 } else if (strcmp(arg, "-qmljsdebugger") == 0 && i < argc - 1) {
239 ++i;
240 qmljs_debug_arguments = QString::fromLocal8Bit(argv[i]);
241 } else {
242 argv[j++] = argv[i];
243 }
244 }
245
246 if (j < argc) {
247 argv[j] = nullptr;
248 argc = j;
249 }
250 }
251
252 // Support for introspection
253
qt_startup_hook()254 extern "C" void Q_CORE_EXPORT qt_startup_hook()
255 {
256 }
257
258 typedef QList<QtStartUpFunction> QStartUpFuncList;
259 Q_GLOBAL_STATIC(QStartUpFuncList, preRList)
260 typedef QList<QtCleanUpFunction> QVFuncList;
261 Q_GLOBAL_STATIC(QVFuncList, postRList)
262 static QBasicMutex globalRoutinesMutex;
263
264 /*!
265 \internal
266
267 Adds a global routine that will be called from the QCoreApplication
268 constructor. The public API is Q_COREAPP_STARTUP_FUNCTION.
269 */
qAddPreRoutine(QtStartUpFunction p)270 void qAddPreRoutine(QtStartUpFunction p)
271 {
272 QStartUpFuncList *list = preRList();
273 if (!list)
274 return;
275
276 if (QCoreApplication::instance())
277 p();
278
279 // Due to C++11 parallel dynamic initialization, this can be called
280 // from multiple threads.
281 const auto locker = qt_scoped_lock(globalRoutinesMutex);
282 list->prepend(p); // in case QCoreApplication is re-created, see qt_call_pre_routines
283 }
284
qAddPostRoutine(QtCleanUpFunction p)285 void qAddPostRoutine(QtCleanUpFunction p)
286 {
287 QVFuncList *list = postRList();
288 if (!list)
289 return;
290 const auto locker = qt_scoped_lock(globalRoutinesMutex);
291 list->prepend(p);
292 }
293
qRemovePostRoutine(QtCleanUpFunction p)294 void qRemovePostRoutine(QtCleanUpFunction p)
295 {
296 QVFuncList *list = postRList();
297 if (!list)
298 return;
299 const auto locker = qt_scoped_lock(globalRoutinesMutex);
300 list->removeAll(p);
301 }
302
qt_call_pre_routines()303 static void qt_call_pre_routines()
304 {
305 if (!preRList.exists())
306 return;
307
308 QVFuncList list;
309 {
310 const auto locker = qt_scoped_lock(globalRoutinesMutex);
311 // Unlike qt_call_post_routines, we don't empty the list, because
312 // Q_COREAPP_STARTUP_FUNCTION is a macro, so the user expects
313 // the function to be executed every time QCoreApplication is created.
314 list = *preRList;
315 }
316 for (int i = 0; i < list.count(); ++i)
317 list.at(i)();
318 }
319
qt_call_post_routines()320 void Q_CORE_EXPORT qt_call_post_routines()
321 {
322 if (!postRList.exists())
323 return;
324
325 forever {
326 QVFuncList list;
327 {
328 // extract the current list and make the stored list empty
329 const auto locker = qt_scoped_lock(globalRoutinesMutex);
330 qSwap(*postRList, list);
331 }
332
333 if (list.isEmpty())
334 break;
335 for (QtCleanUpFunction f : qAsConst(list))
336 f();
337 }
338 }
339
340
341 // initialized in qcoreapplication and in qtextstream autotest when setlocale is called.
342 static bool qt_locale_initialized = false;
343
344 #ifndef QT_NO_QOBJECT
345
346 // app starting up if false
347 bool QCoreApplicationPrivate::is_app_running = false;
348 // app closing down if true
349 bool QCoreApplicationPrivate::is_app_closing = false;
350
qGlobalPostedEventsCount()351 Q_CORE_EXPORT uint qGlobalPostedEventsCount()
352 {
353 QThreadData *currentThreadData = QThreadData::current();
354 return currentThreadData->postEventList.size() - currentThreadData->postEventList.startOffset;
355 }
356
357 QAbstractEventDispatcher *QCoreApplicationPrivate::eventDispatcher = nullptr;
358
359 #endif // QT_NO_QOBJECT
360
361 QCoreApplication *QCoreApplication::self = nullptr;
362 uint QCoreApplicationPrivate::attribs =
363 (1 << Qt::AA_SynthesizeMouseForUnhandledTouchEvents) |
364 (1 << Qt::AA_SynthesizeMouseForUnhandledTabletEvents);
365
366 struct QCoreApplicationData {
QCoreApplicationDataQCoreApplicationData367 QCoreApplicationData() noexcept {
368 applicationNameSet = false;
369 applicationVersionSet = false;
370 }
~QCoreApplicationDataQCoreApplicationData371 ~QCoreApplicationData() {
372 #ifndef QT_NO_QOBJECT
373 // cleanup the QAdoptedThread created for the main() thread
374 if (auto *t = QCoreApplicationPrivate::theMainThread.loadAcquire()) {
375 QThreadData *data = QThreadData::get2(t);
376 data->deref(); // deletes the data and the adopted thread
377 }
378 #endif
379 }
380
381 QString orgName, orgDomain;
382 QString application; // application name, initially from argv[0], can then be modified.
383 QString applicationVersion;
384 bool applicationNameSet; // true if setApplicationName was called
385 bool applicationVersionSet; // true if setApplicationVersion was called
386
387 #if QT_CONFIG(library)
388 QScopedPointer<QStringList> app_libpaths;
389 QScopedPointer<QStringList> manual_libpaths;
390 #endif
391
392 };
393
394 Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
395
396 #ifndef QT_NO_QOBJECT
397 static bool quitLockRefEnabled = true;
398 #endif
399
400 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
401 // Check whether the command line arguments passed to QCoreApplication
402 // match those passed into main(), to see if the user has modified them
403 // before passing them on to us. We do this by comparing to the global
404 // __argv/__argc (MS extension). Deep comparison is required since
405 // argv/argc is rebuilt by our WinMain entrypoint.
isArgvModified(int argc,char ** argv)406 static inline bool isArgvModified(int argc, char **argv)
407 {
408 if (__argc != argc || !__argv /* wmain() */)
409 return true;
410 if (__argv == argv)
411 return false;
412 for (int a = 0; a < argc; ++a) {
413 if (argv[a] != __argv[a] && strcmp(argv[a], __argv[a]))
414 return true;
415 }
416 return false;
417 }
418
contains(int argc,char ** argv,const char * needle)419 static inline bool contains(int argc, char **argv, const char *needle)
420 {
421 for (int a = 0; a < argc; ++a) {
422 if (!strcmp(argv[a], needle))
423 return true;
424 }
425 return false;
426 }
427 #endif // Q_OS_WIN && !Q_OS_WINRT
428
QCoreApplicationPrivate(int & aargc,char ** aargv,uint flags)429 QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint flags)
430 :
431 #ifndef QT_NO_QOBJECT
432 QObjectPrivate(),
433 #endif
434 argc(aargc)
435 , argv(aargv)
436 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
437 , origArgc(0)
438 , origArgv(nullptr)
439 #endif
440 , application_type(QCoreApplicationPrivate::Tty)
441 #ifndef QT_NO_QOBJECT
442 , in_exec(false)
443 , aboutToQuitEmitted(false)
444 , threadData_clean(false)
445 #else
446 , q_ptr(nullptr)
447 #endif
448 {
449 app_compile_version = flags & 0xffffff;
450 static const char *const empty = "";
451 if (argc == 0 || argv == nullptr) {
452 argc = 0;
453 argv = const_cast<char **>(&empty);
454 }
455 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
456 if (!isArgvModified(argc, argv)) {
457 origArgc = argc;
458 origArgv = new char *[argc];
459 std::copy(argv, argv + argc, QT_MAKE_CHECKED_ARRAY_ITERATOR(origArgv, argc));
460 }
461 #endif // Q_OS_WIN && !Q_OS_WINRT
462
463 #ifndef QT_NO_QOBJECT
464 QCoreApplicationPrivate::is_app_closing = false;
465
466 # if defined(Q_OS_UNIX)
467 if (Q_UNLIKELY(!setuidAllowed && (geteuid() != getuid())))
468 qFatal("FATAL: The application binary appears to be running setuid, this is a security hole.");
469 # endif // Q_OS_UNIX
470
471 #ifdef Q_OS_WINRT
472 QThreadData::setMainThread();
473 #endif
474
475 QThread *cur = QThread::currentThread(); // note: this may end up setting theMainThread!
476 if (cur != theMainThread.loadAcquire())
477 qWarning("WARNING: QApplication was not created in the main() thread.");
478 #endif
479 }
480
~QCoreApplicationPrivate()481 QCoreApplicationPrivate::~QCoreApplicationPrivate()
482 {
483 #ifndef QT_NO_QOBJECT
484 cleanupThreadData();
485 #endif
486 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
487 delete [] origArgv;
488 #endif
489 QCoreApplicationPrivate::clearApplicationFilePath();
490 }
491
492 #ifndef QT_NO_QOBJECT
493
cleanupThreadData()494 void QCoreApplicationPrivate::cleanupThreadData()
495 {
496 auto thisThreadData = threadData.loadRelaxed();
497
498 if (thisThreadData && !threadData_clean) {
499 #if QT_CONFIG(thread)
500 void *data = &thisThreadData->tls;
501 QThreadStorageData::finish((void **)data);
502 #endif
503
504 // need to clear the state of the mainData, just in case a new QCoreApplication comes along.
505 const auto locker = qt_scoped_lock(thisThreadData->postEventList.mutex);
506 for (int i = 0; i < thisThreadData->postEventList.size(); ++i) {
507 const QPostEvent &pe = thisThreadData->postEventList.at(i);
508 if (pe.event) {
509 --pe.receiver->d_func()->postedEvents;
510 pe.event->posted = false;
511 delete pe.event;
512 }
513 }
514 thisThreadData->postEventList.clear();
515 thisThreadData->postEventList.recursion = 0;
516 thisThreadData->quitNow = false;
517 threadData_clean = true;
518 }
519 }
520
createEventDispatcher()521 void QCoreApplicationPrivate::createEventDispatcher()
522 {
523 Q_Q(QCoreApplication);
524 QThreadData *data = QThreadData::current();
525 Q_ASSERT(!data->hasEventDispatcher());
526 eventDispatcher = data->createEventDispatcher();
527 eventDispatcher->setParent(q);
528 }
529
eventDispatcherReady()530 void QCoreApplicationPrivate::eventDispatcherReady()
531 {
532 }
533
534 QBasicAtomicPointer<QThread> QCoreApplicationPrivate::theMainThread = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
mainThread()535 QThread *QCoreApplicationPrivate::mainThread()
536 {
537 Q_ASSERT(theMainThread.loadRelaxed() != nullptr);
538 return theMainThread.loadRelaxed();
539 }
540
threadRequiresCoreApplication()541 bool QCoreApplicationPrivate::threadRequiresCoreApplication()
542 {
543 QThreadData *data = QThreadData::current(false);
544 if (!data)
545 return true; // default setting
546 return data->requiresCoreApplication;
547 }
548
checkReceiverThread(QObject * receiver)549 void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
550 {
551 QThread *currentThread = QThread::currentThread();
552 QThread *thr = receiver->thread();
553 Q_ASSERT_X(currentThread == thr || !thr,
554 "QCoreApplication::sendEvent",
555 QString::asprintf("Cannot send events to objects owned by a different thread. "
556 "Current thread 0x%p. Receiver '%ls' (of type '%s') was created in thread 0x%p",
557 currentThread, qUtf16Printable(receiver->objectName()),
558 receiver->metaObject()->className(), thr)
559 .toLocal8Bit().data());
560 Q_UNUSED(currentThread);
561 Q_UNUSED(thr);
562 }
563
564 #endif // QT_NO_QOBJECT
565
appendApplicationPathToLibraryPaths()566 void QCoreApplicationPrivate::appendApplicationPathToLibraryPaths()
567 {
568 #if QT_CONFIG(library)
569 QStringList *app_libpaths = coreappdata()->app_libpaths.data();
570 if (!app_libpaths)
571 coreappdata()->app_libpaths.reset(app_libpaths = new QStringList);
572 QString app_location = QCoreApplication::applicationFilePath();
573 app_location.truncate(app_location.lastIndexOf(QLatin1Char('/')));
574 #ifdef Q_OS_WINRT
575 if (app_location.isEmpty())
576 app_location.append(QLatin1Char('/'));
577 #endif
578 app_location = QDir(app_location).canonicalPath();
579 if (QFile::exists(app_location) && !app_libpaths->contains(app_location))
580 app_libpaths->append(app_location);
581 #endif
582 }
583
qAppName()584 QString qAppName()
585 {
586 if (!QCoreApplicationPrivate::checkInstance("qAppName"))
587 return QString();
588 return QCoreApplication::instance()->d_func()->appName();
589 }
590
initLocale()591 void QCoreApplicationPrivate::initLocale()
592 {
593 if (qt_locale_initialized)
594 return;
595 qt_locale_initialized = true;
596 #if defined(Q_OS_UNIX) && !defined(QT_BOOTSTRAPPED)
597 setlocale(LC_ALL, "");
598 #endif
599 }
600
601
602 /*!
603 \class QCoreApplication
604 \inmodule QtCore
605 \brief The QCoreApplication class provides an event loop for Qt
606 applications without UI.
607
608 This class is used by non-GUI applications to provide their event
609 loop. For non-GUI application that uses Qt, there should be exactly
610 one QCoreApplication object. For GUI applications, see
611 QGuiApplication. For applications that use the Qt Widgets module,
612 see QApplication.
613
614 QCoreApplication contains the main event loop, where all events
615 from the operating system (e.g., timer and network events) and
616 other sources are processed and dispatched. It also handles the
617 application's initialization and finalization, as well as
618 system-wide and application-wide settings.
619
620 \section1 The Event Loop and Event Handling
621
622 The event loop is started with a call to exec(). Long-running
623 operations can call processEvents() to keep the application
624 responsive.
625
626 In general, we recommend that you create a QCoreApplication,
627 QGuiApplication or a QApplication object in your \c main()
628 function as early as possible. exec() will not return until
629 the event loop exits; e.g., when quit() is called.
630
631 Several static convenience functions are also provided. The
632 QCoreApplication object is available from instance(). Events can
633 be sent with sendEvent() or posted to an event queue with postEvent().
634 Pending events can be removed with removePostedEvents() or dispatched
635 with sendPostedEvents().
636
637 The class provides a quit() slot and an aboutToQuit() signal.
638
639 \section1 Application and Library Paths
640
641 An application has an applicationDirPath() and an
642 applicationFilePath(). Library paths (see QLibrary) can be retrieved
643 with libraryPaths() and manipulated by setLibraryPaths(), addLibraryPath(),
644 and removeLibraryPath().
645
646 \section1 Internationalization and Translations
647
648 Translation files can be added or removed
649 using installTranslator() and removeTranslator(). Application
650 strings can be translated using translate(). The QObject::tr()
651 and QObject::trUtf8() functions are implemented in terms of
652 translate().
653
654 \section1 Accessing Command Line Arguments
655
656 The command line arguments which are passed to QCoreApplication's
657 constructor should be accessed using the arguments() function.
658
659 \note QCoreApplication removes option \c -qmljsdebugger="...". It parses the
660 argument of \c qmljsdebugger, and then removes this option plus its argument.
661
662 For more advanced command line option handling, create a QCommandLineParser.
663
664 \section1 Locale Settings
665
666 On Unix/Linux Qt is configured to use the system locale settings by
667 default. This can cause a conflict when using POSIX functions, for
668 instance, when converting between data types such as floats and
669 strings, since the notation may differ between locales. To get
670 around this problem, call the POSIX function \c{setlocale(LC_NUMERIC,"C")}
671 right after initializing QApplication, QGuiApplication or QCoreApplication
672 to reset the locale that is used for number formatting to "C"-locale.
673
674 \sa QGuiApplication, QAbstractEventDispatcher, QEventLoop,
675 {Semaphores Example}, {Wait Conditions Example}
676 */
677
678 /*!
679 \fn static QCoreApplication *QCoreApplication::instance()
680
681 Returns a pointer to the application's QCoreApplication (or
682 QGuiApplication/QApplication) instance.
683
684 If no instance has been allocated, \nullptr is returned.
685 */
686
687 /*!
688 \internal
689 */
QCoreApplication(QCoreApplicationPrivate & p)690 QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
691 #ifdef QT_NO_QOBJECT
692 : d_ptr(&p)
693 #else
694 : QObject(p, nullptr)
695 #endif
696 {
697 d_func()->q_ptr = this;
698 // note: it is the subclasses' job to call
699 // QCoreApplicationPrivate::eventDispatcher->startingUp();
700 }
701
702 #ifndef QT_NO_QOBJECT
703 /*!
704 \deprecated
705 This function is equivalent to calling \c {QCoreApplication::eventDispatcher()->flush()},
706 which also is deprecated, see QAbstractEventDispatcher::flush(). Use sendPostedEvents()
707 and processEvents() for more fine-grained control of the event loop instead.
708
709 Historically this functions was used to flush the platform-specific native event queues.
710
711 \sa sendPostedEvents(), processEvents(), QAbstractEventDispatcher::flush()
712 */
713 #if QT_DEPRECATED_SINCE(5, 9)
flush()714 void QCoreApplication::flush()
715 {
716 if (self && self->d_func()->eventDispatcher)
717 self->d_func()->eventDispatcher->flush();
718 }
719 #endif
720 #endif
721
722 /*!
723 Constructs a Qt core application. Core applications are applications without
724 a graphical user interface. Such applications are used at the console or as
725 server processes.
726
727 The \a argc and \a argv arguments are processed by the application,
728 and made available in a more convenient form by the arguments()
729 function.
730
731 \warning The data referred to by \a argc and \a argv must stay valid
732 for the entire lifetime of the QCoreApplication object. In addition,
733 \a argc must be greater than zero and \a argv must contain at least
734 one valid character string.
735 */
QCoreApplication(int & argc,char ** argv,int _internal)736 QCoreApplication::QCoreApplication(int &argc, char **argv
737 #ifndef Q_QDOC
738 , int _internal
739 #endif
740 )
741 #ifdef QT_NO_QOBJECT
742 : d_ptr(new QCoreApplicationPrivate(argc, argv, _internal))
743 #else
744 : QObject(*new QCoreApplicationPrivate(argc, argv, _internal))
745 #endif
746 {
747 d_func()->q_ptr = this;
748 d_func()->init();
749 #ifndef QT_NO_QOBJECT
750 QCoreApplicationPrivate::eventDispatcher->startingUp();
751 #endif
752 }
753
754 /*!
755 \enum QCoreApplication::anonymous
756 \internal
757
758 \value ApplicationFlags QT_VERSION
759 */
760
init()761 void QCoreApplicationPrivate::init()
762 {
763 Q_TRACE_SCOPE(QCoreApplicationPrivate_init);
764
765 #if defined(Q_OS_MACOS)
766 QMacAutoReleasePool pool;
767 #endif
768
769 Q_Q(QCoreApplication);
770
771 initLocale();
772
773 Q_ASSERT_X(!QCoreApplication::self, "QCoreApplication", "there should be only one application object");
774 QCoreApplication::self = q;
775
776 #if QT_CONFIG(thread)
777 #ifdef Q_OS_WASM
778 QThreadPrivate::idealThreadCount = emscripten::val::global("navigator")["hardwareConcurrency"].as<int>();
779 #endif
780 #endif
781
782 // Store app name/version (so they're still available after QCoreApplication is destroyed)
783 if (!coreappdata()->applicationNameSet)
784 coreappdata()->application = appName();
785
786 if (!coreappdata()->applicationVersionSet)
787 coreappdata()->applicationVersion = appVersion();
788
789 #if defined(Q_OS_ANDROID)
790 // We've deferred initializing the logging registry due to not being
791 // able to guarantee that logging happened on the same thread as the
792 // Qt main thread, but now that the Qt main thread is set up, we can
793 // enable categorized logging.
794 QLoggingRegistry::instance()->initializeRules();
795 #endif
796
797 #if QT_CONFIG(library)
798 // Reset the lib paths, so that they will be recomputed, taking the availability of argv[0]
799 // into account. If necessary, recompute right away and replay the manual changes on top of the
800 // new lib paths.
801 QStringList *appPaths = coreappdata()->app_libpaths.take();
802 QStringList *manualPaths = coreappdata()->manual_libpaths.take();
803 if (appPaths) {
804 if (manualPaths) {
805 // Replay the delta. As paths can only be prepended to the front or removed from
806 // anywhere in the list, we can just linearly scan the lists and find the items that
807 // have been removed. Once the original list is exhausted we know all the remaining
808 // items have been added.
809 QStringList newPaths(q->libraryPaths());
810 for (int i = manualPaths->length(), j = appPaths->length(); i > 0 || j > 0; qt_noop()) {
811 if (--j < 0) {
812 newPaths.prepend((*manualPaths)[--i]);
813 } else if (--i < 0) {
814 newPaths.removeAll((*appPaths)[j]);
815 } else if ((*manualPaths)[i] != (*appPaths)[j]) {
816 newPaths.removeAll((*appPaths)[j]);
817 ++i; // try again with next item.
818 }
819 }
820 delete manualPaths;
821 coreappdata()->manual_libpaths.reset(new QStringList(newPaths));
822 }
823 delete appPaths;
824 }
825 #endif
826
827 #ifndef QT_NO_QOBJECT
828 // use the event dispatcher created by the app programmer (if any)
829 Q_ASSERT(!eventDispatcher);
830 auto thisThreadData = threadData.loadRelaxed();
831 eventDispatcher = thisThreadData->eventDispatcher.loadRelaxed();
832
833 // otherwise we create one
834 if (!eventDispatcher)
835 createEventDispatcher();
836 Q_ASSERT(eventDispatcher);
837
838 if (!eventDispatcher->parent()) {
839 eventDispatcher->moveToThread(thisThreadData->thread.loadAcquire());
840 eventDispatcher->setParent(q);
841 }
842
843 thisThreadData->eventDispatcher = eventDispatcher;
844 eventDispatcherReady();
845 #endif
846
847 processCommandLineArguments();
848
849 qt_call_pre_routines();
850 qt_startup_hook();
851 #ifndef QT_BOOTSTRAPPED
852 if (Q_UNLIKELY(qtHookData[QHooks::Startup]))
853 reinterpret_cast<QHooks::StartupCallback>(qtHookData[QHooks::Startup])();
854 #endif
855
856 #ifndef QT_NO_QOBJECT
857 is_app_running = true; // No longer starting up.
858 #endif
859 }
860
861 /*!
862 Destroys the QCoreApplication object.
863 */
~QCoreApplication()864 QCoreApplication::~QCoreApplication()
865 {
866 qt_call_post_routines();
867
868 self = nullptr;
869 #ifndef QT_NO_QOBJECT
870 QCoreApplicationPrivate::is_app_closing = true;
871 QCoreApplicationPrivate::is_app_running = false;
872 #endif
873
874 #if QT_CONFIG(thread)
875 // Synchronize and stop the global thread pool threads.
876 QThreadPool *globalThreadPool = nullptr;
877 QT_TRY {
878 globalThreadPool = QThreadPool::globalInstance();
879 } QT_CATCH (...) {
880 // swallow the exception, since destructors shouldn't throw
881 }
882 if (globalThreadPool) {
883 globalThreadPool->waitForDone();
884 delete globalThreadPool;
885 }
886 #endif
887
888 #ifndef QT_NO_QOBJECT
889 d_func()->threadData.loadRelaxed()->eventDispatcher = nullptr;
890 if (QCoreApplicationPrivate::eventDispatcher)
891 QCoreApplicationPrivate::eventDispatcher->closingDown();
892 QCoreApplicationPrivate::eventDispatcher = nullptr;
893 #endif
894
895 #if QT_CONFIG(library)
896 coreappdata()->app_libpaths.reset();
897 coreappdata()->manual_libpaths.reset();
898 #endif
899 }
900
901 /*!
902 \since 5.3
903
904 Allows the application to run setuid on UNIX platforms if \a allow
905 is true.
906
907 If \a allow is false (the default) and Qt detects the application is
908 running with an effective user id different than the real user id,
909 the application will be aborted when a QCoreApplication instance is
910 created.
911
912 Qt is not an appropriate solution for setuid programs due to its
913 large attack surface. However some applications may be required
914 to run in this manner for historical reasons. This flag will
915 prevent Qt from aborting the application when this is detected,
916 and must be set before a QCoreApplication instance is created.
917
918 \note It is strongly recommended not to enable this option since
919 it introduces security risks.
920 */
setSetuidAllowed(bool allow)921 void QCoreApplication::setSetuidAllowed(bool allow)
922 {
923 QCoreApplicationPrivate::setuidAllowed = allow;
924 }
925
926 /*!
927 \since 5.3
928
929 Returns true if the application is allowed to run setuid on UNIX
930 platforms.
931
932 \sa QCoreApplication::setSetuidAllowed()
933 */
isSetuidAllowed()934 bool QCoreApplication::isSetuidAllowed()
935 {
936 return QCoreApplicationPrivate::setuidAllowed;
937 }
938
939
940 /*!
941 Sets the attribute \a attribute if \a on is true;
942 otherwise clears the attribute.
943
944 \note Some application attributes must be set \b before creating a
945 QCoreApplication instance. Refer to the Qt::ApplicationAttribute
946 documentation for more information.
947
948 \sa testAttribute()
949 */
setAttribute(Qt::ApplicationAttribute attribute,bool on)950 void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on)
951 {
952 if (on)
953 QCoreApplicationPrivate::attribs |= 1 << attribute;
954 else
955 QCoreApplicationPrivate::attribs &= ~(1 << attribute);
956 #if defined(QT_NO_QOBJECT)
957 if (Q_UNLIKELY(qApp)) {
958 #else
959 if (Q_UNLIKELY(QCoreApplicationPrivate::is_app_running)) {
960 #endif
961 switch (attribute) {
962 case Qt::AA_EnableHighDpiScaling:
963 case Qt::AA_DisableHighDpiScaling:
964 case Qt::AA_PluginApplication:
965 case Qt::AA_UseDesktopOpenGL:
966 case Qt::AA_UseOpenGLES:
967 case Qt::AA_UseSoftwareOpenGL:
968 case Qt::AA_ShareOpenGLContexts:
969 #ifdef QT_BOOTSTRAPPED
970 qWarning("Attribute %d must be set before QCoreApplication is created.",
971 attribute);
972 #else
973 qWarning("Attribute Qt::%s must be set before QCoreApplication is created.",
974 QMetaEnum::fromType<Qt::ApplicationAttribute>().valueToKey(attribute));
975 #endif
976 break;
977 default:
978 break;
979 }
980 }
981 }
982
983 /*!
984 Returns \c true if attribute \a attribute is set;
985 otherwise returns \c false.
986
987 \sa setAttribute()
988 */
989 bool QCoreApplication::testAttribute(Qt::ApplicationAttribute attribute)
990 {
991 return QCoreApplicationPrivate::testAttribute(attribute);
992 }
993
994
995 #ifndef QT_NO_QOBJECT
996
997 /*!
998 \property QCoreApplication::quitLockEnabled
999
1000 \brief Whether the use of the QEventLoopLocker feature can cause the
1001 application to quit.
1002
1003 The default is \c true.
1004
1005 \sa QEventLoopLocker
1006 */
1007
1008 bool QCoreApplication::isQuitLockEnabled()
1009 {
1010 return quitLockRefEnabled;
1011 }
1012
1013 static bool doNotify(QObject *, QEvent *);
1014
1015 void QCoreApplication::setQuitLockEnabled(bool enabled)
1016 {
1017 quitLockRefEnabled = enabled;
1018 }
1019
1020 #if QT_DEPRECATED_SINCE(5, 6)
1021 /*!
1022 \internal
1023 \deprecated
1024
1025 This function is here to make it possible for Qt extensions to
1026 hook into event notification without subclassing QApplication
1027 */
1028 bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
1029 {
1030 return notifyInternal2(receiver, event);
1031 }
1032 #endif
1033
1034 /*!
1035 \internal
1036 \since 5.6
1037
1038 This function is here to make it possible for Qt extensions to
1039 hook into event notification without subclassing QApplication.
1040 */
1041 bool QCoreApplication::notifyInternal2(QObject *receiver, QEvent *event)
1042 {
1043 bool selfRequired = QCoreApplicationPrivate::threadRequiresCoreApplication();
1044 if (!self && selfRequired)
1045 return false;
1046
1047 // Make it possible for Qt Script to hook into events even
1048 // though QApplication is subclassed...
1049 bool result = false;
1050 void *cbdata[] = { receiver, event, &result };
1051 if (QInternal::activateCallbacks(QInternal::EventNotifyCallback, cbdata)) {
1052 return result;
1053 }
1054
1055 // Qt enforces the rule that events can only be sent to objects in
1056 // the current thread, so receiver->d_func()->threadData is
1057 // equivalent to QThreadData::current(), just without the function
1058 // call overhead.
1059 QObjectPrivate *d = receiver->d_func();
1060 QThreadData *threadData = d->threadData;
1061 QScopedScopeLevelCounter scopeLevelCounter(threadData);
1062 if (!selfRequired)
1063 return doNotify(receiver, event);
1064 return self->notify(receiver, event);
1065 }
1066
1067 /*!
1068 \internal
1069 \since 5.10
1070
1071 Forwards the \a event to the \a receiver, using the spontaneous
1072 state of the \a originatingEvent if specified.
1073 */
1074 bool QCoreApplication::forwardEvent(QObject *receiver, QEvent *event, QEvent *originatingEvent)
1075 {
1076 if (event && originatingEvent)
1077 event->spont = originatingEvent->spont;
1078
1079 return notifyInternal2(receiver, event);
1080 }
1081
1082 /*!
1083 Sends \a event to \a receiver: \a {receiver}->event(\a event).
1084 Returns the value that is returned from the receiver's event
1085 handler. Note that this function is called for all events sent to
1086 any object in any thread.
1087
1088 For certain types of events (e.g. mouse and key events),
1089 the event will be propagated to the receiver's parent and so on up to
1090 the top-level object if the receiver is not interested in the event
1091 (i.e., it returns \c false).
1092
1093 There are five different ways that events can be processed;
1094 reimplementing this virtual function is just one of them. All five
1095 approaches are listed below:
1096 \list 1
1097 \li Reimplementing \l {QWidget::}{paintEvent()}, \l {QWidget::}{mousePressEvent()} and so
1098 on. This is the most common, easiest, and least powerful way.
1099
1100 \li Reimplementing this function. This is very powerful, providing
1101 complete control; but only one subclass can be active at a time.
1102
1103 \li Installing an event filter on QCoreApplication::instance(). Such
1104 an event filter is able to process all events for all widgets, so
1105 it's just as powerful as reimplementing notify(); furthermore, it's
1106 possible to have more than one application-global event filter.
1107 Global event filters even see mouse events for
1108 \l{QWidget::isEnabled()}{disabled widgets}. Note that application
1109 event filters are only called for objects that live in the main
1110 thread.
1111
1112 \li Reimplementing QObject::event() (as QWidget does). If you do
1113 this you get Tab key presses, and you get to see the events before
1114 any widget-specific event filters.
1115
1116 \li Installing an event filter on the object. Such an event filter gets all
1117 the events, including Tab and Shift+Tab key press events, as long as they
1118 do not change the focus widget.
1119 \endlist
1120
1121 \b{Future direction:} This function will not be called for objects that live
1122 outside the main thread in Qt 6. Applications that need that functionality
1123 should find other solutions for their event inspection needs in the meantime.
1124 The change may be extended to the main thread, causing this function to be
1125 deprecated.
1126
1127 \warning If you override this function, you must ensure all threads that
1128 process events stop doing so before your application object begins
1129 destruction. This includes threads started by other libraries that you may be
1130 using, but does not apply to Qt's own threads.
1131
1132 \sa QObject::event(), installNativeEventFilter()
1133 */
1134
1135 bool QCoreApplication::notify(QObject *receiver, QEvent *event)
1136 {
1137 // no events are delivered after ~QCoreApplication() has started
1138 if (QCoreApplicationPrivate::is_app_closing)
1139 return true;
1140 return doNotify(receiver, event);
1141 }
1142
1143 static bool doNotify(QObject *receiver, QEvent *event)
1144 {
1145 if (receiver == nullptr) { // serious error
1146 qWarning("QCoreApplication::notify: Unexpected null receiver");
1147 return true;
1148 }
1149
1150 #ifndef QT_NO_DEBUG
1151 QCoreApplicationPrivate::checkReceiverThread(receiver);
1152 #endif
1153
1154 return receiver->isWidgetType() ? false : QCoreApplicationPrivate::notify_helper(receiver, event);
1155 }
1156
1157 bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event)
1158 {
1159 // We can't access the application event filters outside of the main thread (race conditions)
1160 Q_ASSERT(receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread());
1161
1162 if (extraData) {
1163 // application event filters are only called for objects in the GUI thread
1164 for (int i = 0; i < extraData->eventFilters.size(); ++i) {
1165 QObject *obj = extraData->eventFilters.at(i);
1166 if (!obj)
1167 continue;
1168 if (obj->d_func()->threadData != threadData) {
1169 qWarning("QCoreApplication: Application event filter cannot be in a different thread.");
1170 continue;
1171 }
1172 if (obj->eventFilter(receiver, event))
1173 return true;
1174 }
1175 }
1176 return false;
1177 }
1178
1179 bool QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject *receiver, QEvent *event)
1180 {
1181 if (receiver != QCoreApplication::instance() && receiver->d_func()->extraData) {
1182 for (int i = 0; i < receiver->d_func()->extraData->eventFilters.size(); ++i) {
1183 QObject *obj = receiver->d_func()->extraData->eventFilters.at(i);
1184 if (!obj)
1185 continue;
1186 if (obj->d_func()->threadData != receiver->d_func()->threadData) {
1187 qWarning("QCoreApplication: Object event filter cannot be in a different thread.");
1188 continue;
1189 }
1190 if (obj->eventFilter(receiver, event))
1191 return true;
1192 }
1193 }
1194 return false;
1195 }
1196
1197 /*!
1198 \internal
1199
1200 Helper function called by QCoreApplicationPrivate::notify() and qapplication.cpp
1201 */
1202 bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)
1203 {
1204 // Note: when adjusting the tracepoints in here
1205 // consider adjusting QApplicationPrivate::notify_helper too.
1206 Q_TRACE(QCoreApplication_notify_entry, receiver, event, event->type());
1207 bool consumed = false;
1208 bool filtered = false;
1209 Q_TRACE_EXIT(QCoreApplication_notify_exit, consumed, filtered);
1210
1211 // send to all application event filters (only does anything in the main thread)
1212 if (QCoreApplication::self
1213 && receiver->d_func()->threadData.loadRelaxed()->thread.loadAcquire() == mainThread()
1214 && QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) {
1215 filtered = true;
1216 return filtered;
1217 }
1218 // send to all receiver event filters
1219 if (sendThroughObjectEventFilters(receiver, event)) {
1220 filtered = true;
1221 return filtered;
1222 }
1223
1224 // deliver the event
1225 consumed = receiver->event(event);
1226 return consumed;
1227 }
1228
1229 /*!
1230 Returns \c true if an application object has not been created yet;
1231 otherwise returns \c false.
1232
1233 \sa closingDown()
1234 */
1235
1236 bool QCoreApplication::startingUp()
1237 {
1238 return !QCoreApplicationPrivate::is_app_running;
1239 }
1240
1241 /*!
1242 Returns \c true if the application objects are being destroyed;
1243 otherwise returns \c false.
1244
1245 \sa startingUp()
1246 */
1247
1248 bool QCoreApplication::closingDown()
1249 {
1250 return QCoreApplicationPrivate::is_app_closing;
1251 }
1252
1253
1254 /*!
1255 Processes some pending events for the calling thread according to
1256 the specified \a flags.
1257
1258 You can call this function occasionally when your program is busy
1259 performing a long operation (e.g. copying a file).
1260
1261 In the event that you are running a local loop which calls this function
1262 continuously, without an event loop, the
1263 \l{QEvent::DeferredDelete}{DeferredDelete} events will
1264 not be processed. This can affect the behaviour of widgets,
1265 e.g. QToolTip, that rely on \l{QEvent::DeferredDelete}{DeferredDelete}
1266 events to function properly. An alternative would be to call
1267 \l{QCoreApplication::sendPostedEvents()}{sendPostedEvents()} from
1268 within that local loop.
1269
1270 Calling this function processes events only for the calling thread,
1271 and returns after all available events have been processed. Available
1272 events are events queued before the function call. This means that
1273 events that are posted while the function runs will be queued until
1274 a later round of event processing.
1275
1276 \threadsafe
1277
1278 \sa exec(), QTimer, QEventLoop::processEvents(), flush(), sendPostedEvents()
1279 */
1280 void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
1281 {
1282 QThreadData *data = QThreadData::current();
1283 if (!data->hasEventDispatcher())
1284 return;
1285 data->eventDispatcher.loadRelaxed()->processEvents(flags);
1286 }
1287
1288 /*!
1289 \overload processEvents()
1290
1291 Processes pending events for the calling thread for \a ms
1292 milliseconds or until there are no more events to process,
1293 whichever is shorter.
1294
1295 You can call this function occasionally when your program is busy
1296 doing a long operation (e.g. copying a file).
1297
1298 Calling this function processes events only for the calling thread.
1299
1300 \note Unlike the \l{QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)}{processEvents()}
1301 overload, this function also processes events that are posted while the function runs.
1302
1303 \note All events that were queued before the timeout will be processed,
1304 however long it takes.
1305
1306 \threadsafe
1307
1308 \sa exec(), QTimer, QEventLoop::processEvents()
1309 */
1310 void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int ms)
1311 {
1312 // ### Qt 6: consider splitting this method into a public and a private
1313 // one, so that a user-invoked processEvents can be detected
1314 // and handled properly.
1315 QThreadData *data = QThreadData::current();
1316 if (!data->hasEventDispatcher())
1317 return;
1318 QElapsedTimer start;
1319 start.start();
1320 while (data->eventDispatcher.loadRelaxed()->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) {
1321 if (start.elapsed() > ms)
1322 break;
1323 }
1324 }
1325
1326 /*****************************************************************************
1327 Main event loop wrappers
1328 *****************************************************************************/
1329
1330 /*!
1331 Enters the main event loop and waits until exit() is called. Returns
1332 the value that was passed to exit() (which is 0 if exit() is called via
1333 quit()).
1334
1335 It is necessary to call this function to start event handling. The
1336 main event loop receives events from the window system and
1337 dispatches these to the application widgets.
1338
1339 To make your application perform idle processing (by executing a
1340 special function whenever there are no pending events), use a
1341 QTimer with 0 timeout. More advanced idle processing schemes can
1342 be achieved using processEvents().
1343
1344 We recommend that you connect clean-up code to the
1345 \l{QCoreApplication::}{aboutToQuit()} signal, instead of putting it in
1346 your application's \c{main()} function because on some platforms the
1347 exec() call may not return. For example, on Windows
1348 when the user logs off, the system terminates the process after Qt
1349 closes all top-level windows. Hence, there is no guarantee that the
1350 application will have time to exit its event loop and execute code at
1351 the end of the \c{main()} function after the exec()
1352 call.
1353
1354 \sa quit(), exit(), processEvents(), QApplication::exec()
1355 */
1356 int QCoreApplication::exec()
1357 {
1358 if (!QCoreApplicationPrivate::checkInstance("exec"))
1359 return -1;
1360
1361 QThreadData *threadData = self->d_func()->threadData;
1362 if (threadData != QThreadData::current()) {
1363 qWarning("%s::exec: Must be called from the main thread", self->metaObject()->className());
1364 return -1;
1365 }
1366 if (!threadData->eventLoops.isEmpty()) {
1367 qWarning("QCoreApplication::exec: The event loop is already running");
1368 return -1;
1369 }
1370
1371 threadData->quitNow = false;
1372 QEventLoop eventLoop;
1373 self->d_func()->in_exec = true;
1374 self->d_func()->aboutToQuitEmitted = false;
1375 int returnCode = eventLoop.exec();
1376 threadData->quitNow = false;
1377
1378 if (self)
1379 self->d_func()->execCleanup();
1380
1381 return returnCode;
1382 }
1383
1384
1385 // Cleanup after eventLoop is done executing in QCoreApplication::exec().
1386 // This is for use cases in which QCoreApplication is instantiated by a
1387 // library and not by an application executable, for example, Active X
1388 // servers.
1389
1390 void QCoreApplicationPrivate::execCleanup()
1391 {
1392 threadData.loadRelaxed()->quitNow = false;
1393 in_exec = false;
1394 if (!aboutToQuitEmitted)
1395 emit q_func()->aboutToQuit(QCoreApplication::QPrivateSignal());
1396 aboutToQuitEmitted = true;
1397 QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
1398 }
1399
1400
1401 /*!
1402 Tells the application to exit with a return code.
1403
1404 After this function has been called, the application leaves the
1405 main event loop and returns from the call to exec(). The exec()
1406 function returns \a returnCode. If the event loop is not running,
1407 this function does nothing.
1408
1409 By convention, a \a returnCode of 0 means success, and any non-zero
1410 value indicates an error.
1411
1412 It's good practice to always connect signals to this slot using a
1413 \l{Qt::}{QueuedConnection}. If a signal connected (non-queued) to this slot
1414 is emitted before control enters the main event loop (such as before
1415 "int main" calls \l{QCoreApplication::}{exec()}), the slot has no effect
1416 and the application never exits. Using a queued connection ensures that the
1417 slot will not be invoked until after control enters the main event loop.
1418
1419 Note that unlike the C library function of the same name, this
1420 function \e does return to the caller -- it is event processing that
1421 stops.
1422
1423 \sa quit(), exec()
1424 */
1425 void QCoreApplication::exit(int returnCode)
1426 {
1427 if (!self)
1428 return;
1429 QThreadData *data = self->d_func()->threadData.loadRelaxed();
1430 data->quitNow = true;
1431 for (int i = 0; i < data->eventLoops.size(); ++i) {
1432 QEventLoop *eventLoop = data->eventLoops.at(i);
1433 eventLoop->exit(returnCode);
1434 }
1435 }
1436
1437 /*****************************************************************************
1438 QCoreApplication management of posted events
1439 *****************************************************************************/
1440
1441 #ifndef QT_NO_QOBJECT
1442 /*!
1443 \fn bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
1444
1445 Sends event \a event directly to receiver \a receiver, using the
1446 notify() function. Returns the value that was returned from the
1447 event handler.
1448
1449 The event is \e not deleted when the event has been sent. The normal
1450 approach is to create the event on the stack, for example:
1451
1452 \snippet code/src_corelib_kernel_qcoreapplication.cpp 0
1453
1454 \sa postEvent(), notify()
1455 */
1456 bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
1457 {
1458 Q_TRACE(QCoreApplication_sendEvent, receiver, event, event->type());
1459
1460 if (event)
1461 event->spont = false;
1462 return notifyInternal2(receiver, event);
1463 }
1464
1465 /*!
1466 \internal
1467 */
1468 bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent *event)
1469 {
1470 Q_TRACE(QCoreApplication_sendSpontaneousEvent, receiver, event, event->type());
1471
1472 if (event)
1473 event->spont = true;
1474 return notifyInternal2(receiver, event);
1475 }
1476
1477 #endif // QT_NO_QOBJECT
1478
1479 QCoreApplicationPrivate::QPostEventListLocker QCoreApplicationPrivate::lockThreadPostEventList(QObject *object)
1480 {
1481 QPostEventListLocker locker;
1482
1483 if (!object) {
1484 locker.threadData = QThreadData::current();
1485 locker.locker = qt_unique_lock(locker.threadData->postEventList.mutex);
1486 return locker;
1487 }
1488
1489 auto &threadData = QObjectPrivate::get(object)->threadData;
1490
1491 // if object has moved to another thread, follow it
1492 for (;;) {
1493 // synchronizes with the storeRelease in QObject::moveToThread
1494 locker.threadData = threadData.loadAcquire();
1495 if (!locker.threadData) {
1496 // destruction in progress
1497 return locker;
1498 }
1499
1500 auto temporaryLocker = qt_unique_lock(locker.threadData->postEventList.mutex);
1501 if (locker.threadData == threadData.loadAcquire()) {
1502 locker.locker = std::move(temporaryLocker);
1503 break;
1504 }
1505 }
1506
1507 Q_ASSERT(locker.threadData);
1508 return locker;
1509 }
1510
1511 /*!
1512 \since 4.3
1513
1514 Adds the event \a event, with the object \a receiver as the
1515 receiver of the event, to an event queue and returns immediately.
1516
1517 The event must be allocated on the heap since the post event queue
1518 will take ownership of the event and delete it once it has been
1519 posted. It is \e {not safe} to access the event after
1520 it has been posted.
1521
1522 When control returns to the main event loop, all events that are
1523 stored in the queue will be sent using the notify() function.
1524
1525 Events are sorted in descending \a priority order, i.e. events
1526 with a high \a priority are queued before events with a lower \a
1527 priority. The \a priority can be any integer value, i.e. between
1528 INT_MAX and INT_MIN, inclusive; see Qt::EventPriority for more
1529 details. Events with equal \a priority will be processed in the
1530 order posted.
1531
1532 \threadsafe
1533
1534 \sa sendEvent(), notify(), sendPostedEvents(), Qt::EventPriority
1535 */
1536 void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority)
1537 {
1538 Q_TRACE_SCOPE(QCoreApplication_postEvent, receiver, event, event->type());
1539
1540 if (receiver == nullptr) {
1541 qWarning("QCoreApplication::postEvent: Unexpected null receiver");
1542 delete event;
1543 return;
1544 }
1545
1546 auto locker = QCoreApplicationPrivate::lockThreadPostEventList(receiver);
1547 if (!locker.threadData) {
1548 // posting during destruction? just delete the event to prevent a leak
1549 delete event;
1550 return;
1551 }
1552
1553 QThreadData *data = locker.threadData;
1554
1555 // if this is one of the compressible events, do compression
1556 if (receiver->d_func()->postedEvents
1557 && self && self->compressEvent(event, receiver, &data->postEventList)) {
1558 Q_TRACE(QCoreApplication_postEvent_event_compressed, receiver, event);
1559 return;
1560 }
1561
1562 if (event->type() == QEvent::DeferredDelete)
1563 receiver->d_ptr->deleteLaterCalled = true;
1564
1565 if (event->type() == QEvent::DeferredDelete && data == QThreadData::current()) {
1566 // remember the current running eventloop for DeferredDelete
1567 // events posted in the receiver's thread.
1568
1569 // Events sent by non-Qt event handlers (such as glib) may not
1570 // have the scopeLevel set correctly. The scope level makes sure that
1571 // code like this:
1572 // foo->deleteLater();
1573 // qApp->processEvents(); // without passing QEvent::DeferredDelete
1574 // will not cause "foo" to be deleted before returning to the event loop.
1575
1576 // If the scope level is 0 while loopLevel != 0, we are called from a
1577 // non-conformant code path, and our best guess is that the scope level
1578 // should be 1. (Loop level 0 is special: it means that no event loops
1579 // are running.)
1580 int loopLevel = data->loopLevel;
1581 int scopeLevel = data->scopeLevel;
1582 if (scopeLevel == 0 && loopLevel != 0)
1583 scopeLevel = 1;
1584 static_cast<QDeferredDeleteEvent *>(event)->level = loopLevel + scopeLevel;
1585 }
1586
1587 // delete the event on exceptions to protect against memory leaks till the event is
1588 // properly owned in the postEventList
1589 QScopedPointer<QEvent> eventDeleter(event);
1590 Q_TRACE(QCoreApplication_postEvent_event_posted, receiver, event, event->type());
1591 data->postEventList.addEvent(QPostEvent(receiver, event, priority));
1592 eventDeleter.take();
1593 event->posted = true;
1594 ++receiver->d_func()->postedEvents;
1595 data->canWait = false;
1596 locker.unlock();
1597
1598 QAbstractEventDispatcher* dispatcher = data->eventDispatcher.loadAcquire();
1599 if (dispatcher)
1600 dispatcher->wakeUp();
1601 }
1602
1603 /*!
1604 \internal
1605 Returns \c true if \a event was compressed away (possibly deleted) and should not be added to the list.
1606 */
1607 bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventList *postedEvents)
1608 {
1609 #ifdef Q_OS_WIN
1610 Q_ASSERT(event);
1611 Q_ASSERT(receiver);
1612 Q_ASSERT(postedEvents);
1613
1614 // compress posted timers to this object.
1615 if (event->type() == QEvent::Timer && receiver->d_func()->postedEvents > 0) {
1616 int timerId = ((QTimerEvent *) event)->timerId();
1617 for (int i=0; i<postedEvents->size(); ++i) {
1618 const QPostEvent &e = postedEvents->at(i);
1619 if (e.receiver == receiver && e.event && e.event->type() == QEvent::Timer
1620 && ((QTimerEvent *) e.event)->timerId() == timerId) {
1621 delete event;
1622 return true;
1623 }
1624 }
1625 return false;
1626 }
1627 #endif
1628
1629 if (event->type() == QEvent::DeferredDelete) {
1630 if (receiver->d_ptr->deleteLaterCalled) {
1631 // there was a previous DeferredDelete event, so we can drop the new one
1632 delete event;
1633 return true;
1634 }
1635 // deleteLaterCalled is set to true in postedEvents when queueing the very first
1636 // deferred deletion event.
1637 return false;
1638 }
1639
1640 if (event->type() == QEvent::Quit && receiver->d_func()->postedEvents > 0) {
1641 for (int i = 0; i < postedEvents->size(); ++i) {
1642 const QPostEvent &cur = postedEvents->at(i);
1643 if (cur.receiver != receiver
1644 || cur.event == nullptr
1645 || cur.event->type() != event->type())
1646 continue;
1647 // found an event for this receiver
1648 delete event;
1649 return true;
1650 }
1651 }
1652
1653 return false;
1654 }
1655
1656 /*!
1657 Immediately dispatches all events which have been previously queued
1658 with QCoreApplication::postEvent() and which are for the object \a
1659 receiver and have the event type \a event_type.
1660
1661 Events from the window system are \e not dispatched by this
1662 function, but by processEvents().
1663
1664 If \a receiver is \nullptr, the events of \a event_type are sent for
1665 all objects. If \a event_type is 0, all the events are sent for
1666 \a receiver.
1667
1668 \note This method must be called from the thread in which its QObject
1669 parameter, \a receiver, lives.
1670
1671 \sa flush(), postEvent()
1672 */
1673 void QCoreApplication::sendPostedEvents(QObject *receiver, int event_type)
1674 {
1675 // ### Qt 6: consider splitting this method into a public and a private
1676 // one, so that a user-invoked sendPostedEvents can be detected
1677 // and handled properly.
1678 QThreadData *data = QThreadData::current();
1679
1680 QCoreApplicationPrivate::sendPostedEvents(receiver, event_type, data);
1681 }
1682
1683 void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type,
1684 QThreadData *data)
1685 {
1686 if (event_type == -1) {
1687 // we were called by an obsolete event dispatcher.
1688 event_type = 0;
1689 }
1690
1691 if (receiver && receiver->d_func()->threadData != data) {
1692 qWarning("QCoreApplication::sendPostedEvents: Cannot send "
1693 "posted events for objects in another thread");
1694 return;
1695 }
1696
1697 ++data->postEventList.recursion;
1698
1699 auto locker = qt_unique_lock(data->postEventList.mutex);
1700
1701 // by default, we assume that the event dispatcher can go to sleep after
1702 // processing all events. if any new events are posted while we send
1703 // events, canWait will be set to false.
1704 data->canWait = (data->postEventList.size() == 0);
1705
1706 if (data->postEventList.size() == 0 || (receiver && !receiver->d_func()->postedEvents)) {
1707 --data->postEventList.recursion;
1708 return;
1709 }
1710
1711 data->canWait = true;
1712
1713 // okay. here is the tricky loop. be careful about optimizing
1714 // this, it looks the way it does for good reasons.
1715 int startOffset = data->postEventList.startOffset;
1716 int &i = (!event_type && !receiver) ? data->postEventList.startOffset : startOffset;
1717 data->postEventList.insertionOffset = data->postEventList.size();
1718
1719 // Exception-safe cleaning up without the need for a try/catch block
1720 struct CleanUp {
1721 QObject *receiver;
1722 int event_type;
1723 QThreadData *data;
1724 bool exceptionCaught;
1725
1726 inline CleanUp(QObject *receiver, int event_type, QThreadData *data) :
1727 receiver(receiver), event_type(event_type), data(data), exceptionCaught(true)
1728 {}
1729 inline ~CleanUp()
1730 {
1731 if (exceptionCaught) {
1732 // since we were interrupted, we need another pass to make sure we clean everything up
1733 data->canWait = false;
1734 }
1735
1736 --data->postEventList.recursion;
1737 if (!data->postEventList.recursion && !data->canWait && data->hasEventDispatcher())
1738 data->eventDispatcher.loadRelaxed()->wakeUp();
1739
1740 // clear the global list, i.e. remove everything that was
1741 // delivered.
1742 if (!event_type && !receiver && data->postEventList.startOffset >= 0) {
1743 const QPostEventList::iterator it = data->postEventList.begin();
1744 data->postEventList.erase(it, it + data->postEventList.startOffset);
1745 data->postEventList.insertionOffset -= data->postEventList.startOffset;
1746 Q_ASSERT(data->postEventList.insertionOffset >= 0);
1747 data->postEventList.startOffset = 0;
1748 }
1749 }
1750 };
1751 CleanUp cleanup(receiver, event_type, data);
1752
1753 while (i < data->postEventList.size()) {
1754 // avoid live-lock
1755 if (i >= data->postEventList.insertionOffset)
1756 break;
1757
1758 const QPostEvent &pe = data->postEventList.at(i);
1759 ++i;
1760
1761 if (!pe.event)
1762 continue;
1763 if ((receiver && receiver != pe.receiver) || (event_type && event_type != pe.event->type())) {
1764 data->canWait = false;
1765 continue;
1766 }
1767
1768 if (pe.event->type() == QEvent::DeferredDelete) {
1769 // DeferredDelete events are sent either
1770 // 1) when the event loop that posted the event has returned; or
1771 // 2) if explicitly requested (with QEvent::DeferredDelete) for
1772 // events posted by the current event loop; or
1773 // 3) if the event was posted before the outermost event loop.
1774
1775 int eventLevel = static_cast<QDeferredDeleteEvent *>(pe.event)->loopLevel();
1776 int loopLevel = data->loopLevel + data->scopeLevel;
1777 const bool allowDeferredDelete =
1778 (eventLevel > loopLevel
1779 || (!eventLevel && loopLevel > 0)
1780 || (event_type == QEvent::DeferredDelete
1781 && eventLevel == loopLevel));
1782 if (!allowDeferredDelete) {
1783 // cannot send deferred delete
1784 if (!event_type && !receiver) {
1785 // we must copy it first; we want to re-post the event
1786 // with the event pointer intact, but we can't delay
1787 // nulling the event ptr until after re-posting, as
1788 // addEvent may invalidate pe.
1789 QPostEvent pe_copy = pe;
1790
1791 // null out the event so if sendPostedEvents recurses, it
1792 // will ignore this one, as it's been re-posted.
1793 const_cast<QPostEvent &>(pe).event = nullptr;
1794
1795 // re-post the copied event so it isn't lost
1796 data->postEventList.addEvent(pe_copy);
1797 }
1798 continue;
1799 }
1800 }
1801
1802 // first, we diddle the event so that we can deliver
1803 // it, and that no one will try to touch it later.
1804 pe.event->posted = false;
1805 QEvent *e = pe.event;
1806 QObject * r = pe.receiver;
1807
1808 --r->d_func()->postedEvents;
1809 Q_ASSERT(r->d_func()->postedEvents >= 0);
1810
1811 // next, update the data structure so that we're ready
1812 // for the next event.
1813 const_cast<QPostEvent &>(pe).event = nullptr;
1814
1815 locker.unlock();
1816 const auto relocker = qScopeGuard([&locker] { locker.lock(); });
1817
1818 QScopedPointer<QEvent> event_deleter(e); // will delete the event (with the mutex unlocked)
1819
1820 // after all that work, it's time to deliver the event.
1821 QCoreApplication::sendEvent(r, e);
1822
1823 // careful when adding anything below this point - the
1824 // sendEvent() call might invalidate any invariants this
1825 // function depends on.
1826 }
1827
1828 cleanup.exceptionCaught = false;
1829 }
1830
1831 /*!
1832 \since 4.3
1833
1834 Removes all events of the given \a eventType that were posted
1835 using postEvent() for \a receiver.
1836
1837 The events are \e not dispatched, instead they are removed from
1838 the queue. You should never need to call this function. If you do
1839 call it, be aware that killing events may cause \a receiver to
1840 break one or more invariants.
1841
1842 If \a receiver is \nullptr, the events of \a eventType are removed
1843 for all objects. If \a eventType is 0, all the events are removed
1844 for \a receiver. You should never call this function with \a
1845 eventType of 0.
1846
1847 \threadsafe
1848 */
1849
1850 void QCoreApplication::removePostedEvents(QObject *receiver, int eventType)
1851 {
1852 auto locker = QCoreApplicationPrivate::lockThreadPostEventList(receiver);
1853 QThreadData *data = locker.threadData;
1854
1855 // the QObject destructor calls this function directly. this can
1856 // happen while the event loop is in the middle of posting events,
1857 // and when we get here, we may not have any more posted events
1858 // for this object.
1859 if (receiver && !receiver->d_func()->postedEvents)
1860 return;
1861
1862 //we will collect all the posted events for the QObject
1863 //and we'll delete after the mutex was unlocked
1864 QVarLengthArray<QEvent*> events;
1865 int n = data->postEventList.size();
1866 int j = 0;
1867
1868 for (int i = 0; i < n; ++i) {
1869 const QPostEvent &pe = data->postEventList.at(i);
1870
1871 if ((!receiver || pe.receiver == receiver)
1872 && (pe.event && (eventType == 0 || pe.event->type() == eventType))) {
1873 --pe.receiver->d_func()->postedEvents;
1874 pe.event->posted = false;
1875 events.append(pe.event);
1876 const_cast<QPostEvent &>(pe).event = nullptr;
1877 } else if (!data->postEventList.recursion) {
1878 if (i != j)
1879 qSwap(data->postEventList[i], data->postEventList[j]);
1880 ++j;
1881 }
1882 }
1883
1884 #ifdef QT_DEBUG
1885 if (receiver && eventType == 0) {
1886 Q_ASSERT(!receiver->d_func()->postedEvents);
1887 }
1888 #endif
1889
1890 if (!data->postEventList.recursion) {
1891 // truncate list
1892 data->postEventList.erase(data->postEventList.begin() + j, data->postEventList.end());
1893 }
1894
1895 locker.unlock();
1896 qDeleteAll(events);
1897 }
1898
1899 /*!
1900 Removes \a event from the queue of posted events, and emits a
1901 warning message if appropriate.
1902
1903 \warning This function can be \e really slow. Avoid using it, if
1904 possible.
1905
1906 \threadsafe
1907 */
1908
1909 void QCoreApplicationPrivate::removePostedEvent(QEvent * event)
1910 {
1911 if (!event || !event->posted)
1912 return;
1913
1914 QThreadData *data = QThreadData::current();
1915
1916 const auto locker = qt_scoped_lock(data->postEventList.mutex);
1917
1918 if (data->postEventList.size() == 0) {
1919 #if defined(QT_DEBUG)
1920 qDebug("QCoreApplication::removePostedEvent: Internal error: %p %d is posted",
1921 (void*)event, event->type());
1922 return;
1923 #endif
1924 }
1925
1926 for (int i = 0; i < data->postEventList.size(); ++i) {
1927 const QPostEvent & pe = data->postEventList.at(i);
1928 if (pe.event == event) {
1929 #ifndef QT_NO_DEBUG
1930 qWarning("QCoreApplication::removePostedEvent: Event of type %d deleted while posted to %s %s",
1931 event->type(),
1932 pe.receiver->metaObject()->className(),
1933 pe.receiver->objectName().toLocal8Bit().data());
1934 #endif
1935 --pe.receiver->d_func()->postedEvents;
1936 pe.event->posted = false;
1937 delete pe.event;
1938 const_cast<QPostEvent &>(pe).event = nullptr;
1939 return;
1940 }
1941 }
1942 }
1943
1944 /*!\reimp
1945
1946 */
1947 bool QCoreApplication::event(QEvent *e)
1948 {
1949 if (e->type() == QEvent::Quit) {
1950 quit();
1951 return true;
1952 }
1953 return QObject::event(e);
1954 }
1955
1956 /*! \enum QCoreApplication::Encoding
1957 \obsolete
1958
1959 This enum type used to define the 8-bit encoding of character string
1960 arguments to translate(). This enum is now obsolete and UTF-8 will be
1961 used in all cases.
1962
1963 \value UnicodeUTF8 UTF-8.
1964 \omitvalue Latin1
1965 \omitvalue DefaultCodec \omit UTF-8. \endomit
1966 \omitvalue CodecForTr
1967
1968 \sa QObject::tr(), QString::fromUtf8()
1969 */
1970
1971 void QCoreApplicationPrivate::ref()
1972 {
1973 quitLockRef.ref();
1974 }
1975
1976 void QCoreApplicationPrivate::deref()
1977 {
1978 if (!quitLockRef.deref())
1979 maybeQuit();
1980 }
1981
1982 void QCoreApplicationPrivate::maybeQuit()
1983 {
1984 if (quitLockRef.loadRelaxed() == 0 && in_exec && quitLockRefEnabled && shouldQuit())
1985 QCoreApplication::postEvent(QCoreApplication::instance(), new QEvent(QEvent::Quit));
1986 }
1987
1988 /*!
1989 Tells the application to exit with return code 0 (success).
1990 Equivalent to calling QCoreApplication::exit(0).
1991
1992 It's common to connect the QGuiApplication::lastWindowClosed() signal
1993 to quit(), and you also often connect e.g. QAbstractButton::clicked() or
1994 signals in QAction, QMenu, or QMenuBar to it.
1995
1996 It's good practice to always connect signals to this slot using a
1997 \l{Qt::}{QueuedConnection}. If a signal connected (non-queued) to this slot
1998 is emitted before control enters the main event loop (such as before
1999 "int main" calls \l{QCoreApplication::}{exec()}), the slot has no effect
2000 and the application never exits. Using a queued connection ensures that the
2001 slot will not be invoked until after control enters the main event loop.
2002
2003 Example:
2004
2005 \snippet code/src_corelib_kernel_qcoreapplication.cpp 1
2006
2007 \sa exit(), aboutToQuit(), QGuiApplication::lastWindowClosed()
2008 */
2009
2010 void QCoreApplication::quit()
2011 {
2012 exit(0);
2013 }
2014
2015 /*!
2016 \fn void QCoreApplication::aboutToQuit()
2017
2018 This signal is emitted when the application is about to quit the
2019 main event loop, e.g. when the event loop level drops to zero.
2020 This may happen either after a call to quit() from inside the
2021 application or when the user shuts down the entire desktop session.
2022
2023 The signal is particularly useful if your application has to do some
2024 last-second cleanup. Note that no user interaction is possible in
2025 this state.
2026
2027 \sa quit()
2028 */
2029
2030 #endif // QT_NO_QOBJECT
2031
2032 #ifndef QT_NO_TRANSLATION
2033 /*!
2034 Adds the translation file \a translationFile to the list of
2035 translation files to be used for translations.
2036
2037 Multiple translation files can be installed. Translations are
2038 searched for in the reverse order in which they were installed,
2039 so the most recently installed translation file is searched first
2040 and the first translation file installed is searched last.
2041 The search stops as soon as a translation containing a matching
2042 string is found.
2043
2044 Installing or removing a QTranslator, or changing an installed QTranslator
2045 generates a \l{QEvent::LanguageChange}{LanguageChange} event for the
2046 QCoreApplication instance. A QApplication instance will propagate the event
2047 to all toplevel widgets, where a reimplementation of changeEvent can
2048 re-translate the user interface by passing user-visible strings via the
2049 tr() function to the respective property setters. User-interface classes
2050 generated by Qt Designer provide a \c retranslateUi() function that can be
2051 called.
2052
2053 The function returns \c true on success and false on failure.
2054
2055 \sa removeTranslator(), translate(), QTranslator::load(), {Dynamic Translation}
2056 */
2057
2058 bool QCoreApplication::installTranslator(QTranslator *translationFile)
2059 {
2060 if (!translationFile)
2061 return false;
2062
2063 if (!QCoreApplicationPrivate::checkInstance("installTranslator"))
2064 return false;
2065 QCoreApplicationPrivate *d = self->d_func();
2066 {
2067 QWriteLocker locker(&d->translateMutex);
2068 d->translators.prepend(translationFile);
2069 }
2070
2071 #ifndef QT_NO_TRANSLATION_BUILDER
2072 if (translationFile->isEmpty())
2073 return false;
2074 #endif
2075
2076 #ifndef QT_NO_QOBJECT
2077 QEvent ev(QEvent::LanguageChange);
2078 QCoreApplication::sendEvent(self, &ev);
2079 #endif
2080
2081 return true;
2082 }
2083
2084 /*!
2085 Removes the translation file \a translationFile from the list of
2086 translation files used by this application. (It does not delete the
2087 translation file from the file system.)
2088
2089 The function returns \c true on success and false on failure.
2090
2091 \sa installTranslator(), translate(), QObject::tr()
2092 */
2093
2094 bool QCoreApplication::removeTranslator(QTranslator *translationFile)
2095 {
2096 if (!translationFile)
2097 return false;
2098 if (!QCoreApplicationPrivate::checkInstance("removeTranslator"))
2099 return false;
2100 QCoreApplicationPrivate *d = self->d_func();
2101 QWriteLocker locker(&d->translateMutex);
2102 if (d->translators.removeAll(translationFile)) {
2103 #ifndef QT_NO_QOBJECT
2104 locker.unlock();
2105 if (!self->closingDown()) {
2106 QEvent ev(QEvent::LanguageChange);
2107 QCoreApplication::sendEvent(self, &ev);
2108 }
2109 #endif
2110 return true;
2111 }
2112 return false;
2113 }
2114
2115 static void replacePercentN(QString *result, int n)
2116 {
2117 if (n >= 0) {
2118 int percentPos = 0;
2119 int len = 0;
2120 while ((percentPos = result->indexOf(QLatin1Char('%'), percentPos + len)) != -1) {
2121 len = 1;
2122 if (percentPos + len == result->length())
2123 break;
2124 QString fmt;
2125 if (result->at(percentPos + len) == QLatin1Char('L')) {
2126 ++len;
2127 if (percentPos + len == result->length())
2128 break;
2129 fmt = QLatin1String("%L1");
2130 } else {
2131 fmt = QLatin1String("%1");
2132 }
2133 if (result->at(percentPos + len) == QLatin1Char('n')) {
2134 fmt = fmt.arg(n);
2135 ++len;
2136 result->replace(percentPos, len, fmt);
2137 len = fmt.length();
2138 }
2139 }
2140 }
2141 }
2142
2143 /*!
2144 \threadsafe
2145
2146 Returns the translation text for \a sourceText, by querying the
2147 installed translation files. The translation files are searched
2148 from the most recently installed file back to the first
2149 installed file.
2150
2151 QObject::tr() provides this functionality more conveniently.
2152
2153 \a context is typically a class name (e.g., "MyDialog") and \a
2154 sourceText is either English text or a short identifying text.
2155
2156 \a disambiguation is an identifying string, for when the same \a
2157 sourceText is used in different roles within the same context. By
2158 default, it is \nullptr.
2159
2160 See the \l QTranslator and \l QObject::tr() documentation for
2161 more information about contexts, disambiguations and comments.
2162
2163 \a n is used in conjunction with \c %n to support plural forms.
2164 See QObject::tr() for details.
2165
2166 If none of the translation files contain a translation for \a
2167 sourceText in \a context, this function returns a QString
2168 equivalent of \a sourceText.
2169
2170 This function is not virtual. You can use alternative translation
2171 techniques by subclassing \l QTranslator.
2172
2173 \sa QObject::tr(), installTranslator(), removeTranslator(), translate()
2174 */
2175 QString QCoreApplication::translate(const char *context, const char *sourceText,
2176 const char *disambiguation, int n)
2177 {
2178 QString result;
2179
2180 if (!sourceText)
2181 return result;
2182
2183 if (self) {
2184 QCoreApplicationPrivate *d = self->d_func();
2185 QReadLocker locker(&d->translateMutex);
2186 if (!d->translators.isEmpty()) {
2187 QList<QTranslator*>::ConstIterator it;
2188 QTranslator *translationFile;
2189 for (it = d->translators.constBegin(); it != d->translators.constEnd(); ++it) {
2190 translationFile = *it;
2191 result = translationFile->translate(context, sourceText, disambiguation, n);
2192 if (!result.isNull())
2193 break;
2194 }
2195 }
2196 }
2197
2198 if (result.isNull())
2199 result = QString::fromUtf8(sourceText);
2200
2201 replacePercentN(&result, n);
2202 return result;
2203 }
2204
2205 /*! \fn static QString QCoreApplication::translate(const char *context, const char *key, const char *disambiguation, Encoding encoding, int n = -1)
2206
2207 \obsolete
2208 */
2209
2210 // Declared in qglobal.h
2211 QString qtTrId(const char *id, int n)
2212 {
2213 return QCoreApplication::translate(nullptr, id, nullptr, n);
2214 }
2215
2216 bool QCoreApplicationPrivate::isTranslatorInstalled(QTranslator *translator)
2217 {
2218 if (!QCoreApplication::self)
2219 return false;
2220 QCoreApplicationPrivate *d = QCoreApplication::self->d_func();
2221 QReadLocker locker(&d->translateMutex);
2222 return d->translators.contains(translator);
2223 }
2224
2225 #else
2226
2227 QString QCoreApplication::translate(const char *context, const char *sourceText,
2228 const char *disambiguation, int n)
2229 {
2230 Q_UNUSED(context)
2231 Q_UNUSED(disambiguation)
2232 QString ret = QString::fromUtf8(sourceText);
2233 if (n >= 0)
2234 ret.replace(QLatin1String("%n"), QString::number(n));
2235 return ret;
2236 }
2237
2238 #endif //QT_NO_TRANSLATION
2239
2240 // Makes it possible to point QCoreApplication to a custom location to ensure
2241 // the directory is added to the patch, and qt.conf and deployed plugins are
2242 // found from there. This is for use cases in which QGuiApplication is
2243 // instantiated by a library and not by an application executable, for example,
2244 // Active X servers.
2245
2246 void QCoreApplicationPrivate::setApplicationFilePath(const QString &path)
2247 {
2248 if (QCoreApplicationPrivate::cachedApplicationFilePath)
2249 *QCoreApplicationPrivate::cachedApplicationFilePath = path;
2250 else
2251 QCoreApplicationPrivate::cachedApplicationFilePath = new QString(path);
2252 }
2253
2254 /*!
2255 Returns the directory that contains the application executable.
2256
2257 For example, if you have installed Qt in the \c{C:\Qt}
2258 directory, and you run the \c{regexp} example, this function will
2259 return "C:/Qt/examples/tools/regexp".
2260
2261 On \macos and iOS this will point to the directory actually containing
2262 the executable, which may be inside an application bundle (if the
2263 application is bundled).
2264
2265 \warning On Linux, this function will try to get the path from the
2266 \c {/proc} file system. If that fails, it assumes that \c
2267 {argv[0]} contains the absolute file name of the executable. The
2268 function also assumes that the current directory has not been
2269 changed by the application.
2270
2271 \sa applicationFilePath()
2272 */
2273 QString QCoreApplication::applicationDirPath()
2274 {
2275 if (!self) {
2276 qWarning("QCoreApplication::applicationDirPath: Please instantiate the QApplication object first");
2277 return QString();
2278 }
2279
2280 QCoreApplicationPrivate *d = self->d_func();
2281 if (d->cachedApplicationDirPath.isNull())
2282 d->cachedApplicationDirPath = QFileInfo(applicationFilePath()).path();
2283 return d->cachedApplicationDirPath;
2284 }
2285
2286 /*!
2287 Returns the file path of the application executable.
2288
2289 For example, if you have installed Qt in the \c{/usr/local/qt}
2290 directory, and you run the \c{regexp} example, this function will
2291 return "/usr/local/qt/examples/tools/regexp/regexp".
2292
2293 \warning On Linux, this function will try to get the path from the
2294 \c {/proc} file system. If that fails, it assumes that \c
2295 {argv[0]} contains the absolute file name of the executable. The
2296 function also assumes that the current directory has not been
2297 changed by the application.
2298
2299 \sa applicationDirPath()
2300 */
2301 QString QCoreApplication::applicationFilePath()
2302 {
2303 if (!self) {
2304 qWarning("QCoreApplication::applicationFilePath: Please instantiate the QApplication object first");
2305 return QString();
2306 }
2307
2308 QCoreApplicationPrivate *d = self->d_func();
2309
2310 if (d->argc) {
2311 static QByteArray procName = QByteArray(d->argv[0]);
2312 if (procName != d->argv[0]) {
2313 // clear the cache if the procname changes, so we reprocess it.
2314 QCoreApplicationPrivate::clearApplicationFilePath();
2315 procName = QByteArray(d->argv[0]);
2316 }
2317 }
2318
2319 if (QCoreApplicationPrivate::cachedApplicationFilePath)
2320 return *QCoreApplicationPrivate::cachedApplicationFilePath;
2321
2322 #if defined(Q_OS_WIN)
2323 QCoreApplicationPrivate::setApplicationFilePath(QFileInfo(qAppFileName()).filePath());
2324 return *QCoreApplicationPrivate::cachedApplicationFilePath;
2325 #elif defined(Q_OS_MAC)
2326 QString qAppFileName_str = qAppFileName();
2327 if(!qAppFileName_str.isEmpty()) {
2328 QFileInfo fi(qAppFileName_str);
2329 if (fi.exists()) {
2330 QCoreApplicationPrivate::setApplicationFilePath(fi.canonicalFilePath());
2331 return *QCoreApplicationPrivate::cachedApplicationFilePath;
2332 }
2333 }
2334 #endif
2335 #if defined( Q_OS_UNIX )
2336 # if defined(Q_OS_LINUX) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_EMBEDDED))
2337 // Try looking for a /proc/<pid>/exe symlink first which points to
2338 // the absolute path of the executable
2339 QFileInfo pfi(QString::fromLatin1("/proc/%1/exe").arg(getpid()));
2340 if (pfi.exists() && pfi.isSymLink()) {
2341 QCoreApplicationPrivate::setApplicationFilePath(pfi.canonicalFilePath());
2342 return *QCoreApplicationPrivate::cachedApplicationFilePath;
2343 }
2344 # endif
2345 if (!arguments().isEmpty()) {
2346 QString argv0 = QFile::decodeName(arguments().at(0).toLocal8Bit());
2347 QString absPath;
2348
2349 if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) {
2350 /*
2351 If argv0 starts with a slash, it is already an absolute
2352 file path.
2353 */
2354 absPath = argv0;
2355 } else if (argv0.contains(QLatin1Char('/'))) {
2356 /*
2357 If argv0 contains one or more slashes, it is a file path
2358 relative to the current directory.
2359 */
2360 absPath = QDir::current().absoluteFilePath(argv0);
2361 } else {
2362 /*
2363 Otherwise, the file path has to be determined using the
2364 PATH environment variable.
2365 */
2366 absPath = QStandardPaths::findExecutable(argv0);
2367 }
2368
2369 absPath = QDir::cleanPath(absPath);
2370
2371 QFileInfo fi(absPath);
2372 if (fi.exists()) {
2373 QCoreApplicationPrivate::setApplicationFilePath(fi.canonicalFilePath());
2374 return *QCoreApplicationPrivate::cachedApplicationFilePath;
2375 }
2376 }
2377
2378 #endif
2379 return QString();
2380 }
2381
2382 /*!
2383 \since 4.4
2384
2385 Returns the current process ID for the application.
2386 */
2387 qint64 QCoreApplication::applicationPid()
2388 {
2389 #if defined(Q_OS_WIN)
2390 return GetCurrentProcessId();
2391 #elif defined(Q_OS_VXWORKS)
2392 return (pid_t) taskIdCurrent;
2393 #else
2394 return getpid();
2395 #endif
2396 }
2397
2398 /*!
2399 \since 4.1
2400
2401 Returns the list of command-line arguments.
2402
2403 Usually arguments().at(0) is the program name, arguments().at(1)
2404 is the first argument, and arguments().last() is the last
2405 argument. See the note below about Windows.
2406
2407 Calling this function is slow - you should store the result in a variable
2408 when parsing the command line.
2409
2410 \warning On Unix, this list is built from the argc and argv parameters passed
2411 to the constructor in the main() function. The string-data in argv is
2412 interpreted using QString::fromLocal8Bit(); hence it is not possible to
2413 pass, for example, Japanese command line arguments on a system that runs in a
2414 Latin1 locale. Most modern Unix systems do not have this limitation, as they are
2415 Unicode-based.
2416
2417 On Windows, the list is built from the argc and argv parameters only if
2418 modified argv/argc parameters are passed to the constructor. In that case,
2419 encoding problems might occur.
2420
2421 Otherwise, the arguments() are constructed from the return value of
2422 \l{http://msdn2.microsoft.com/en-us/library/ms683156(VS.85).aspx}{GetCommandLine()}.
2423 As a result of this, the string given by arguments().at(0) might not be
2424 the program name on Windows, depending on how the application was started.
2425
2426 \sa applicationFilePath(), QCommandLineParser
2427 */
2428
2429 QStringList QCoreApplication::arguments()
2430 {
2431 QStringList list;
2432
2433 if (!self) {
2434 qWarning("QCoreApplication::arguments: Please instantiate the QApplication object first");
2435 return list;
2436 }
2437
2438 const QCoreApplicationPrivate *d = self->d_func();
2439
2440 const int argc = d->argc;
2441 char ** const argv = d->argv;
2442 list.reserve(argc);
2443
2444 #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
2445 const bool argsModifiedByUser = d->origArgv == nullptr;
2446 if (!argsModifiedByUser) {
2447 // On Windows, it is possible to pass Unicode arguments on
2448 // the command line, but we don't implement any of the wide
2449 // entry-points (wmain/wWinMain), so get the arguments from
2450 // the Windows API instead of using argv. Note that we only
2451 // do this when argv were not modified by the user in main().
2452 QString cmdline = QString::fromWCharArray(GetCommandLine());
2453 QStringList commandLineArguments = qWinCmdArgs(cmdline);
2454
2455 // Even if the user didn't modify argv before passing them
2456 // on to QCoreApplication, derived QApplications might have.
2457 // If that's the case argc will differ from origArgc.
2458 if (argc != d->origArgc) {
2459 // Note: On MingGW the arguments from GetCommandLine are
2460 // not wildcard expanded (if wildcard expansion is enabled),
2461 // as opposed to the arguments in argv. This means we can't
2462 // compare commandLineArguments to argv/origArgc, but
2463 // must remove elements by value, based on whether they
2464 // were filtered out from argc.
2465 for (int i = 0; i < d->origArgc; ++i) {
2466 if (!contains(argc, argv, d->origArgv[i]))
2467 commandLineArguments.removeAll(QString::fromLocal8Bit(d->origArgv[i]));
2468 }
2469 }
2470
2471 return commandLineArguments;
2472 } // Fall back to rebuilding from argv/argc when a modified argv was passed.
2473 #endif // defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
2474
2475 for (int a = 0; a < argc; ++a)
2476 list << QString::fromLocal8Bit(argv[a]);
2477
2478 return list;
2479 }
2480
2481 /*!
2482 \property QCoreApplication::organizationName
2483 \brief the name of the organization that wrote this application
2484
2485 The value is used by the QSettings class when it is constructed
2486 using the empty constructor. This saves having to repeat this
2487 information each time a QSettings object is created.
2488
2489 On Mac, QSettings uses \l {QCoreApplication::}{organizationDomain()} as the organization
2490 if it's not an empty string; otherwise it uses
2491 organizationName(). On all other platforms, QSettings uses
2492 organizationName() as the organization.
2493
2494 \sa organizationDomain, applicationName
2495 */
2496
2497 /*!
2498 \fn void QCoreApplication::organizationNameChanged()
2499 \internal
2500
2501 While not useful from C++ due to how organizationName is normally set once on
2502 startup, this is still needed for QML so that bindings are reevaluated after
2503 that initial change.
2504 */
2505 void QCoreApplication::setOrganizationName(const QString &orgName)
2506 {
2507 if (coreappdata()->orgName == orgName)
2508 return;
2509 coreappdata()->orgName = orgName;
2510 #ifndef QT_NO_QOBJECT
2511 if (QCoreApplication::self)
2512 emit QCoreApplication::self->organizationNameChanged();
2513 #endif
2514 }
2515
2516 QString QCoreApplication::organizationName()
2517 {
2518 return coreappdata()->orgName;
2519 }
2520
2521 /*!
2522 \property QCoreApplication::organizationDomain
2523 \brief the Internet domain of the organization that wrote this application
2524
2525 The value is used by the QSettings class when it is constructed
2526 using the empty constructor. This saves having to repeat this
2527 information each time a QSettings object is created.
2528
2529 On Mac, QSettings uses organizationDomain() as the organization
2530 if it's not an empty string; otherwise it uses organizationName().
2531 On all other platforms, QSettings uses organizationName() as the
2532 organization.
2533
2534 \sa organizationName, applicationName, applicationVersion
2535 */
2536 /*!
2537 \fn void QCoreApplication::organizationDomainChanged()
2538 \internal
2539
2540 Primarily for QML, see organizationNameChanged.
2541 */
2542 void QCoreApplication::setOrganizationDomain(const QString &orgDomain)
2543 {
2544 if (coreappdata()->orgDomain == orgDomain)
2545 return;
2546 coreappdata()->orgDomain = orgDomain;
2547 #ifndef QT_NO_QOBJECT
2548 if (QCoreApplication::self)
2549 emit QCoreApplication::self->organizationDomainChanged();
2550 #endif
2551 }
2552
2553 QString QCoreApplication::organizationDomain()
2554 {
2555 return coreappdata()->orgDomain;
2556 }
2557
2558 /*!
2559 \property QCoreApplication::applicationName
2560 \brief the name of this application
2561
2562 The value is used by the QSettings class when it is constructed
2563 using the empty constructor. This saves having to repeat this
2564 information each time a QSettings object is created.
2565
2566 If not set, the application name defaults to the executable name (since 5.0).
2567
2568 \sa organizationName, organizationDomain, applicationVersion, applicationFilePath()
2569 */
2570 /*!
2571 \fn void QCoreApplication::applicationNameChanged()
2572 \internal
2573
2574 Primarily for QML, see organizationNameChanged.
2575 */
2576 void QCoreApplication::setApplicationName(const QString &application)
2577 {
2578 coreappdata()->applicationNameSet = !application.isEmpty();
2579 QString newAppName = application;
2580 if (newAppName.isEmpty() && QCoreApplication::self)
2581 newAppName = QCoreApplication::self->d_func()->appName();
2582 if (coreappdata()->application == newAppName)
2583 return;
2584 coreappdata()->application = newAppName;
2585 #ifndef QT_NO_QOBJECT
2586 if (QCoreApplication::self)
2587 emit QCoreApplication::self->applicationNameChanged();
2588 #endif
2589 }
2590
2591 QString QCoreApplication::applicationName()
2592 {
2593 return coreappdata() ? coreappdata()->application : QString();
2594 }
2595
2596 // Exported for QDesktopServices (Qt4 behavior compatibility)
2597 Q_CORE_EXPORT QString qt_applicationName_noFallback()
2598 {
2599 return coreappdata()->applicationNameSet ? coreappdata()->application : QString();
2600 }
2601
2602 /*!
2603 \property QCoreApplication::applicationVersion
2604 \since 4.4
2605 \brief the version of this application
2606
2607 If not set, the application version defaults to a platform-specific value
2608 determined from the main application executable or package (since Qt 5.9):
2609
2610 \table
2611 \header
2612 \li Platform
2613 \li Source
2614 \row
2615 \li Windows (classic desktop)
2616 \li PRODUCTVERSION parameter of the VERSIONINFO resource
2617 \row
2618 \li Universal Windows Platform
2619 \li version attribute of the application package manifest
2620 \row
2621 \li macOS, iOS, tvOS, watchOS
2622 \li CFBundleVersion property of the information property list
2623 \row
2624 \li Android
2625 \li android:versionName property of the AndroidManifest.xml manifest element
2626 \endtable
2627
2628 On other platforms, the default is the empty string.
2629
2630 \sa applicationName, organizationName, organizationDomain
2631 */
2632 /*!
2633 \fn void QCoreApplication::applicationVersionChanged()
2634 \internal
2635
2636 Primarily for QML, see organizationNameChanged.
2637 */
2638 void QCoreApplication::setApplicationVersion(const QString &version)
2639 {
2640 coreappdata()->applicationVersionSet = !version.isEmpty();
2641 QString newVersion = version;
2642 if (newVersion.isEmpty() && QCoreApplication::self)
2643 newVersion = QCoreApplication::self->d_func()->appVersion();
2644 if (coreappdata()->applicationVersion == newVersion)
2645 return;
2646 coreappdata()->applicationVersion = newVersion;
2647 #ifndef QT_NO_QOBJECT
2648 if (QCoreApplication::self)
2649 emit QCoreApplication::self->applicationVersionChanged();
2650 #endif
2651 }
2652
2653 QString QCoreApplication::applicationVersion()
2654 {
2655 return coreappdata() ? coreappdata()->applicationVersion : QString();
2656 }
2657
2658 #if QT_CONFIG(library)
2659
2660 Q_GLOBAL_STATIC(QRecursiveMutex, libraryPathMutex)
2661
2662 /*!
2663 Returns a list of paths that the application will search when
2664 dynamically loading libraries.
2665
2666 The return value of this function may change when a QCoreApplication
2667 is created. It is not recommended to call it before creating a
2668 QCoreApplication. The directory of the application executable (\b not
2669 the working directory) is part of the list if it is known. In order
2670 to make it known a QCoreApplication has to be constructed as it will
2671 use \c {argv[0]} to find it.
2672
2673 Qt provides default library paths, but they can also be set using
2674 a \l{Using qt.conf}{qt.conf} file. Paths specified in this file
2675 will override default values. Note that if the qt.conf file is in
2676 the directory of the application executable, it may not be found
2677 until a QCoreApplication is created. If it is not found when calling
2678 this function, the default library paths will be used.
2679
2680 The list will include the installation directory for plugins if
2681 it exists (the default installation directory for plugins is \c
2682 INSTALL/plugins, where \c INSTALL is the directory where Qt was
2683 installed). The colon separated entries of the \c QT_PLUGIN_PATH
2684 environment variable are always added. The plugin installation
2685 directory (and its existence) may change when the directory of
2686 the application executable becomes known.
2687
2688 If you want to iterate over the list, you can use the \l foreach
2689 pseudo-keyword:
2690
2691 \snippet code/src_corelib_kernel_qcoreapplication.cpp 2
2692
2693 \sa setLibraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary,
2694 {How to Create Qt Plugins}
2695 */
2696 QStringList QCoreApplication::libraryPaths()
2697 {
2698 QMutexLocker locker(libraryPathMutex());
2699 return libraryPathsLocked();
2700 }
2701
2702 /*!
2703 \internal
2704 */
2705 QStringList QCoreApplication::libraryPathsLocked()
2706 {
2707 if (coreappdata()->manual_libpaths)
2708 return *(coreappdata()->manual_libpaths);
2709
2710 if (!coreappdata()->app_libpaths) {
2711 QStringList *app_libpaths = new QStringList;
2712 coreappdata()->app_libpaths.reset(app_libpaths);
2713
2714 auto setPathsFromEnv = [&](QString libPathEnv) {
2715 if (!libPathEnv.isEmpty()) {
2716 QStringList paths = libPathEnv.split(QDir::listSeparator(), Qt::SkipEmptyParts);
2717 for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) {
2718 QString canonicalPath = QDir(*it).canonicalPath();
2719 if (!canonicalPath.isEmpty()
2720 && !app_libpaths->contains(canonicalPath)) {
2721 app_libpaths->append(canonicalPath);
2722 }
2723 }
2724 }
2725 };
2726 setPathsFromEnv(qEnvironmentVariable("QT_PLUGIN_PATH"));
2727 #ifdef Q_OS_ANDROID
2728 setPathsFromEnv(qEnvironmentVariable("QT_BUNDLED_LIBS_PATH"));
2729 #endif
2730 #ifdef Q_OS_DARWIN
2731 // Check the main bundle's PlugIns directory as this is a standard location for Apple OSes.
2732 // Note that the QLibraryInfo::PluginsPath below will coincidentally be the same as this value
2733 // but with a different casing, so it can't be relied upon when the underlying filesystem
2734 // is case sensitive (and this is always the case on newer OSes like iOS).
2735 if (CFBundleRef bundleRef = CFBundleGetMainBundle()) {
2736 if (QCFType<CFURLRef> urlRef = CFBundleCopyBuiltInPlugInsURL(bundleRef)) {
2737 if (QCFType<CFURLRef> absoluteUrlRef = CFURLCopyAbsoluteURL(urlRef)) {
2738 if (QCFString path = CFURLCopyFileSystemPath(absoluteUrlRef, kCFURLPOSIXPathStyle)) {
2739 if (QFile::exists(path)) {
2740 path = QDir(path).canonicalPath();
2741 if (!app_libpaths->contains(path))
2742 app_libpaths->append(path);
2743 }
2744 }
2745 }
2746 }
2747 }
2748 #endif // Q_OS_DARWIN
2749
2750 QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath);
2751 if (QFile::exists(installPathPlugins)) {
2752 // Make sure we convert from backslashes to slashes.
2753 installPathPlugins = QDir(installPathPlugins).canonicalPath();
2754 if (!app_libpaths->contains(installPathPlugins))
2755 app_libpaths->append(installPathPlugins);
2756 }
2757
2758 // If QCoreApplication is not yet instantiated,
2759 // make sure we add the application path when we construct the QCoreApplication
2760 if (self) self->d_func()->appendApplicationPathToLibraryPaths();
2761 }
2762 return *(coreappdata()->app_libpaths);
2763 }
2764
2765
2766
2767 /*!
2768
2769 Sets the list of directories to search when loading libraries to
2770 \a paths. All existing paths will be deleted and the path list
2771 will consist of the paths given in \a paths.
2772
2773 The library paths are reset to the default when an instance of
2774 QCoreApplication is destructed.
2775
2776 \sa libraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary
2777 */
2778 void QCoreApplication::setLibraryPaths(const QStringList &paths)
2779 {
2780 QMutexLocker locker(libraryPathMutex());
2781
2782 // setLibraryPaths() is considered a "remove everything and then add some new ones" operation.
2783 // When the application is constructed it should still amend the paths. So we keep the originals
2784 // around, and even create them if they don't exist, yet.
2785 if (!coreappdata()->app_libpaths)
2786 libraryPathsLocked();
2787
2788 if (coreappdata()->manual_libpaths)
2789 *(coreappdata()->manual_libpaths) = paths;
2790 else
2791 coreappdata()->manual_libpaths.reset(new QStringList(paths));
2792
2793 locker.unlock();
2794 QFactoryLoader::refreshAll();
2795 }
2796
2797 /*!
2798 Prepends \a path to the beginning of the library path list, ensuring that
2799 it is searched for libraries first. If \a path is empty or already in the
2800 path list, the path list is not changed.
2801
2802 The default path list consists of a single entry, the installation
2803 directory for plugins. The default installation directory for plugins
2804 is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was
2805 installed.
2806
2807 The library paths are reset to the default when an instance of
2808 QCoreApplication is destructed.
2809
2810 \sa removeLibraryPath(), libraryPaths(), setLibraryPaths()
2811 */
2812 void QCoreApplication::addLibraryPath(const QString &path)
2813 {
2814 if (path.isEmpty())
2815 return;
2816
2817 QString canonicalPath = QDir(path).canonicalPath();
2818 if (canonicalPath.isEmpty())
2819 return;
2820
2821 QMutexLocker locker(libraryPathMutex());
2822
2823 QStringList *libpaths = coreappdata()->manual_libpaths.data();
2824 if (libpaths) {
2825 if (libpaths->contains(canonicalPath))
2826 return;
2827 } else {
2828 // make sure that library paths are initialized
2829 libraryPathsLocked();
2830 QStringList *app_libpaths = coreappdata()->app_libpaths.data();
2831 if (app_libpaths->contains(canonicalPath))
2832 return;
2833
2834 coreappdata()->manual_libpaths.reset(libpaths = new QStringList(*app_libpaths));
2835 }
2836
2837 libpaths->prepend(canonicalPath);
2838 locker.unlock();
2839 QFactoryLoader::refreshAll();
2840 }
2841
2842 /*!
2843 Removes \a path from the library path list. If \a path is empty or not
2844 in the path list, the list is not changed.
2845
2846 The library paths are reset to the default when an instance of
2847 QCoreApplication is destructed.
2848
2849 \sa addLibraryPath(), libraryPaths(), setLibraryPaths()
2850 */
2851 void QCoreApplication::removeLibraryPath(const QString &path)
2852 {
2853 if (path.isEmpty())
2854 return;
2855
2856 QString canonicalPath = QDir(path).canonicalPath();
2857 if (canonicalPath.isEmpty())
2858 return;
2859
2860 QMutexLocker locker(libraryPathMutex());
2861
2862 QStringList *libpaths = coreappdata()->manual_libpaths.data();
2863 if (libpaths) {
2864 if (libpaths->removeAll(canonicalPath) == 0)
2865 return;
2866 } else {
2867 // make sure that library paths is initialized
2868 libraryPathsLocked();
2869 QStringList *app_libpaths = coreappdata()->app_libpaths.data();
2870 if (!app_libpaths->contains(canonicalPath))
2871 return;
2872
2873 coreappdata()->manual_libpaths.reset(libpaths = new QStringList(*app_libpaths));
2874 libpaths->removeAll(canonicalPath);
2875 }
2876
2877 locker.unlock();
2878 QFactoryLoader::refreshAll();
2879 }
2880
2881 #endif // QT_CONFIG(library)
2882
2883 #ifndef QT_NO_QOBJECT
2884
2885 /*!
2886 Installs an event filter \a filterObj for all native events
2887 received by the application in the main thread.
2888
2889 The event filter \a filterObj receives events via its \l {QAbstractNativeEventFilter::}{nativeEventFilter()}
2890 function, which is called for all native events received in the main thread.
2891
2892 The QAbstractNativeEventFilter::nativeEventFilter() function should
2893 return true if the event should be filtered, i.e. stopped. It should
2894 return false to allow normal Qt processing to continue: the native
2895 event can then be translated into a QEvent and handled by the standard
2896 Qt \l{QEvent} {event} filtering, e.g. QObject::installEventFilter().
2897
2898 If multiple event filters are installed, the filter that was
2899 installed last is activated first.
2900
2901 \note The filter function set here receives native messages,
2902 i.e. MSG or XCB event structs.
2903
2904 \note Native event filters will be disabled in the application when the
2905 Qt::AA_PluginApplication attribute is set.
2906
2907 For maximum portability, you should always try to use QEvent
2908 and QObject::installEventFilter() whenever possible.
2909
2910 \sa QObject::installEventFilter()
2911
2912 \since 5.0
2913 */
2914 void QCoreApplication::installNativeEventFilter(QAbstractNativeEventFilter *filterObj)
2915 {
2916 if (QCoreApplication::testAttribute(Qt::AA_PluginApplication)) {
2917 qWarning("Native event filters are not applied when the Qt::AA_PluginApplication attribute is set");
2918 return;
2919 }
2920
2921 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread.loadAcquire());
2922 if (!filterObj || !eventDispatcher)
2923 return;
2924 eventDispatcher->installNativeEventFilter(filterObj);
2925 }
2926
2927 /*!
2928 Removes an event \a filterObject from this object. The
2929 request is ignored if such an event filter has not been installed.
2930
2931 All event filters for this object are automatically removed when
2932 this object is destroyed.
2933
2934 It is always safe to remove an event filter, even during event
2935 filter activation (i.e. from the nativeEventFilter() function).
2936
2937 \sa installNativeEventFilter()
2938 \since 5.0
2939 */
2940 void QCoreApplication::removeNativeEventFilter(QAbstractNativeEventFilter *filterObject)
2941 {
2942 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
2943 if (!filterObject || !eventDispatcher)
2944 return;
2945 eventDispatcher->removeNativeEventFilter(filterObject);
2946 }
2947
2948 /*!
2949 \deprecated
2950
2951 This function returns \c true if there are pending events; otherwise
2952 returns \c false. Pending events can be either from the window
2953 system or posted events using postEvent().
2954
2955 \note this function is not thread-safe. It may only be called in the main
2956 thread and only if there are no other threads running in the application
2957 (including threads Qt starts for its own purposes).
2958
2959 \sa QAbstractEventDispatcher::hasPendingEvents()
2960 */
2961 #if QT_DEPRECATED_SINCE(5, 3)
2962 bool QCoreApplication::hasPendingEvents()
2963 {
2964 QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance();
2965 if (eventDispatcher)
2966 return eventDispatcher->hasPendingEvents();
2967 return false;
2968 }
2969 #endif
2970
2971 /*!
2972 Returns a pointer to the event dispatcher object for the main thread. If no
2973 event dispatcher exists for the thread, this function returns \nullptr.
2974 */
2975 QAbstractEventDispatcher *QCoreApplication::eventDispatcher()
2976 {
2977 if (QCoreApplicationPrivate::theMainThread.loadAcquire())
2978 return QCoreApplicationPrivate::theMainThread.loadRelaxed()->eventDispatcher();
2979 return nullptr;
2980 }
2981
2982 /*!
2983 Sets the event dispatcher for the main thread to \a eventDispatcher. This
2984 is only possible as long as there is no event dispatcher installed yet. That
2985 is, before QCoreApplication has been instantiated. This method takes
2986 ownership of the object.
2987 */
2988 void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
2989 {
2990 QThread *mainThread = QCoreApplicationPrivate::theMainThread.loadAcquire();
2991 if (!mainThread)
2992 mainThread = QThread::currentThread(); // will also setup theMainThread
2993 mainThread->setEventDispatcher(eventDispatcher);
2994 }
2995
2996 #endif // QT_NO_QOBJECT
2997
2998 /*!
2999 \macro Q_COREAPP_STARTUP_FUNCTION(QtStartUpFunction ptr)
3000 \since 5.1
3001 \relates QCoreApplication
3002 \reentrant
3003
3004 Adds a global function that will be called from the QCoreApplication
3005 constructor. This macro is normally used to initialize libraries
3006 for program-wide functionality, without requiring the application to
3007 call into the library for initialization.
3008
3009 The function specified by \a ptr should take no arguments and should
3010 return nothing. For example:
3011
3012 \snippet code/src_corelib_kernel_qcoreapplication.cpp 3
3013
3014 Note that the startup function will run at the end of the QCoreApplication constructor,
3015 before any GUI initialization. If GUI code is required in the function,
3016 use a timer (or a queued invocation) to perform the initialization later on,
3017 from the event loop.
3018
3019 If QCoreApplication is deleted and another QCoreApplication is created,
3020 the startup function will be invoked again.
3021
3022 \note This macro is not suitable for use in library code that is then
3023 statically linked into an application since the function may not be called
3024 at all due to being eliminated by the linker.
3025 */
3026
3027 /*!
3028 \fn void qAddPostRoutine(QtCleanUpFunction ptr)
3029 \threadsafe
3030 \relates QCoreApplication
3031
3032 Adds a global routine that will be called from the QCoreApplication
3033 destructor. This function is normally used to add cleanup routines
3034 for program-wide functionality.
3035
3036 The cleanup routines are called in the reverse order of their addition.
3037
3038 The function specified by \a ptr should take no arguments and should
3039 return nothing. For example:
3040
3041 \snippet code/src_corelib_kernel_qcoreapplication.cpp 4
3042
3043 Note that for an application- or module-wide cleanup, qAddPostRoutine()
3044 is often not suitable. For example, if the program is split into dynamically
3045 loaded modules, the relevant module may be unloaded long before the
3046 QCoreApplication destructor is called. In such cases, if using qAddPostRoutine()
3047 is still desirable, qRemovePostRoutine() can be used to prevent a routine
3048 from being called by the QCoreApplication destructor. For example, if that
3049 routine was called before the module was unloaded.
3050
3051 For modules and libraries, using a reference-counted
3052 initialization manager or Qt's parent-child deletion mechanism may
3053 be better. Here is an example of a private class that uses the
3054 parent-child mechanism to call a cleanup function at the right
3055 time:
3056
3057 \snippet code/src_corelib_kernel_qcoreapplication.cpp 5
3058
3059 By selecting the right parent object, this can often be made to
3060 clean up the module's data at the right moment.
3061
3062 \note This function has been thread-safe since Qt 5.10.
3063
3064 \sa qRemovePostRoutine()
3065 */
3066
3067 /*!
3068 \fn void qRemovePostRoutine(QtCleanUpFunction ptr)
3069 \threadsafe
3070 \relates QCoreApplication
3071 \since 5.3
3072
3073 Removes the cleanup routine specified by \a ptr from the list of
3074 routines called by the QCoreApplication destructor. The routine
3075 must have been previously added to the list by a call to
3076 qAddPostRoutine(), otherwise this function has no effect.
3077
3078 \note This function has been thread-safe since Qt 5.10.
3079
3080 \sa qAddPostRoutine()
3081 */
3082
3083 /*!
3084 \macro Q_DECLARE_TR_FUNCTIONS(context)
3085 \relates QCoreApplication
3086
3087 The Q_DECLARE_TR_FUNCTIONS() macro declares and implements two
3088 translation functions, \c tr() and \c trUtf8(), with these
3089 signatures:
3090
3091 \snippet code/src_corelib_kernel_qcoreapplication.cpp 6
3092
3093 This macro is useful if you want to use QObject::tr() or
3094 QObject::trUtf8() in classes that don't inherit from QObject.
3095
3096 Q_DECLARE_TR_FUNCTIONS() must appear at the very top of the
3097 class definition (before the first \c{public:} or \c{protected:}).
3098 For example:
3099
3100 \snippet code/src_corelib_kernel_qcoreapplication.cpp 7
3101
3102 The \a context parameter is normally the class name, but it can
3103 be any text.
3104
3105 \sa Q_OBJECT, QObject::tr(), QObject::trUtf8()
3106 */
3107
3108 QT_END_NAMESPACE
3109
3110 #ifndef QT_NO_QOBJECT
3111 #include "moc_qcoreapplication.cpp"
3112 #endif
3113