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