515 Commits

Author SHA1 Message Date
Marc Mutz
59db97fdaf QCoreApplication: relax an atomic load in a Q_ASSERT()
A Q_ASSERT() must not have side-effects, incl. ordering memory. So the
implicit loadAcquire() was too strong. The code must also work with
loadRelaxed(), so use that.

Amends the start of the public history.

Change-Id: Ib94bd0989d1a358b552275dc3963b014e6e4c180
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 90dbb413bf78a86d8785e797df7b1558e72f99b8)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
2025-06-13 14:54:21 +00:00
Tor Arne Vestbø
4a7ccb65f0 Lazily create global share context when Qt::AA_ShareOpenGLContexts is set
The requirement to set Qt::AA_ShareOpenGLContexts before creating QGuiApp
was forcing users to also set the default surface format before QGuiApp,
which prevents us from initializing a default surface format based on
the platform integration.

By creating the global share context lazily when requested via the
Qt::AA_ShareOpenGLContext application attribute we open up this
possibility.

Change-Id: I958639c997e96321013b1080c31e2533a36c13ff
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
2025-05-23 17:42:46 +02:00
Kai Köhne
095cacd668 Do not treat the installation of an empty QTranslator as an error
The return value of installTranslator() should indicate whether
the _registration_ was successful. Apart from merely logging
the result, the only sensible action the calling code might
take is to delete the QTranslator object that failed to register.

The old behavior of installTranslator() for empty QTranslator
objects was to store the pointer for further use, but still return
false. This might lead to hard-to-detect memory corruption.

The patch changes behavior to _not_ consider installing empty
QTranslator objects as an error.

This has the following reasons:

* As translations are often done later in the SW development process,
it is common to replace empty .qm files with translated
ones in a very late stage. But having different code paths based on
this can be surprising.

* The other parts of the QTranslator toolchain do not treat
empty translations in a specific way, either.

While at it, also remove the now unused QT_NO_TRANSLATION_BUILDER
macro (left over from Qt 4).

[ChangeLog][Core][Behavior Change] QCoreApplication::installTranslator()
will now return true even for empty translators
(QTranslator::isEmpty()). This makes it explicit that empty QTranslator
objects are registered and queried, and therefore deleting the object
prematurely might result in undefined behavior.

Change-Id: Ia0531afcf5c72aa837406cf5de2cf73052014445
Reviewed-by: Masoud Jami <masoud.jami@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2025-05-06 06:53:31 +00:00
Thiago Macieira
eb8c09c104 QThreadStorage: make the internal finish() function really private
This class is very old and hasn't been modernized since C++98 became a
thing we could rely on. We hadn't come up with the concept of private
headers yet.

This commit moves the exported QThreadStorageData::finish() function
from the public header to QThreadStoragePrivate in a private header and
no longer exports it. It also removes the need to pass the QList as a
void **.

Task-number: QTBUG-135044
Change-Id: I736cb12a7c29716effd7fffd87c7b086a8cb7e19
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-04-11 17:09:49 -07:00
Thiago Macieira
cb382450aa QCoreApplication: implement the ### Qt7 to rename requestPermission
Amends commit 207aae5560aa2865ec55ddb9ecbb50048060c0c0.

Change-Id: Iff0d62fb157087299faafffd6e14a2b95c2bc1de
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2025-02-28 00:52:10 -03:00
Thiago Macieira
64cd765531 QCoreApplication: speed up fallback path in applicationFilePath()
QCoreApplication::arguments() is not cached, so let's not call it twice.

And do move from the path we've just calculated.

Change-Id: Ibc00ec588aa93c19f676fffd400d129e251672b7
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2025-02-26 19:59:42 +00:00
Thiago Macieira
e178567bbb QCoreApplication: avoid extra work in applicationFilePath() if we can
In the four OSes where qAppFileName() returns non-empty, the returned
path is always absolute and canonical, so there's no need for us to
further canonicalize it. So let's have applicationDirPath() have an
early out for it and mark it as Q_LIKELY().

In the other OSes, qAppFileName() is static inline in this very file, so
the compiler will probably see that it's always empty and ignore the
Q_LIKELY().

That leaves the atypical cases of /proc/self/exe being empty on Linux (I
don't know when this could happen, but it's not impossible) or non-
bundle executables on Apple OSes.

Change-Id: Ic47b28bda60085bcbcc8fffd28a0f3b864e07fd5
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2025-02-26 11:59:42 -08:00
Thiago Macieira
d34a3536bf QCoreApplication: avoid QFileInfo in applicationDirPath()
QFileInfo allocates a lot of memory, so it's not very good a tool for
manipulating just strings. As this function is called very early in the
application's lifetime (by the first qDebug() or so), we can avoid
creating the QFileInfoPrivate by going straight to QFileSystemEngine,
which is what QFileInfo::path() would have done:

QString QFileInfo::path() const
{
    Q_D(const QFileInfo);
    if (d->isDefaultConstructed)
        return ""_L1;
    return d->fileEntry.path();
}

Change-Id: Ie911c42577113c477aa9fffd5dcbb7e6f24af8f6
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2025-02-26 11:59:42 -08:00
Thiago Macieira
87ba5348e9 QCoreApplication: remove the applicationDirPath() cache
It's just a string manipulation and it's not that important to keep
cached. Especially since we wouldn't update it when
applicationFilePath()'s cache was invalidated on argv[0] change:

    if (d->argc) {
        static QByteArray procName = QByteArray(d->argv[0]);
        if (procName != QByteArrayView(d->argv[0])) {
            // clear the cache if the procname changes, so we reprocess it.
            d->cachedApplicationFilePath = QString();
            procName.assign(d->argv[0]);
        }
    }

Amends commit e6f483c0e802969e79aca5b37ef3f4912a6e25d7.

Change-Id: I52a4cd2ebf500a941d5dfffd4b5e10ff22523d61
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2025-02-26 11:59:42 -08:00
Thiago Macieira
d09c6c1046 Short live QCoreApplication::instanceExists()
This is a thread-safe version of

    QCoreApplication::instance() != nullptr

for Qt 6.x, because QCoreApplication::self is not atomic and thus
reading it from outside the main thread could be a data race.

That's not to say it always is: if by construction the code can only run
in the main thread or while QCoreApplication definitely exists, that's
safe. Therefore, this commit focuses on places that are meant to be used
in multi-threaded environment (ruling out most of QtGui and QtWidgets)
or where the code was going to dereference the returned pointer anyway.

Change-Id: I6fc556c5fe5cbe0b5902fffdfb6b3bb345b0ee50
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2025-02-26 06:45:07 +00:00
Thiago Macieira
fd857d400a QThreadStorage: don't print the destruction ordering warning on app exit
This warning here was very confusing (so I'm also updating the language
to be clearer what it means). It is here to advise users of
QThreadStorage that they may have destroyed the object before all
threads using the object have finished. That means there will be memory
leaks, hence the user should fix the issue.

But the one time we don't care (too much) about memory leaks is when the
application is about to exit -- all memory is being released back to the
OS anyway. This may happen because of Static De-Initialization Order
Fiasco: the Q_GLOBAL_STATIC or equivalents holding QThreadStorage were
destroyed before the QThreadData for the exit()ing thread did. That
problem became more prevalent after the series of changes ending in
commit 2f69a05bd0cd7ce63890f709ff3ed7a4f78acd70, because that made the
QThreadData clean up happen very late in the execution.

Unfortunately, there's no way for us to know when we're being called
during application exit, so this is the next best thing:
QCoreApplication::instance() does not exist. We're using a private
function in QCoreApplication because in Qt 6.x, QCoreApplication::self
is not atomic and reading it would be a data race.

The QThread::currentThread() call was superfluous, because it was always
true. It was a relic from Qt 3, from before we had QAdoptedThread.

Pick-to: 6.8 6.9
Fixes: QTBUG-133500
Change-Id: I48d84d76f2b72483ed92fffdd54c6ad17e3d67d3
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2025-02-18 12:04:21 -08:00
Thiago Macieira
e6f483c0e8 QCoreApplicationPrivate: make cachedApplicationFilePath non-static
I don't see why it needed to be static, given that the setter checks for
!self and prints a warning.

Pick-to: 6.9
Change-Id: I2d4b632db7d7c9fac21dfffd3f302b5a7aac2e89
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2025-02-11 18:20:20 -08:00
Thiago Macieira
4074cc9424 QCoreApplication: make libraryPathsLocked() file-static
Amends 08ad96404b4c915eece1a547bf12e91664e7cdff.

There's no need to have it in QCoreApplication, if it isn't called from
anywhere outside of qcoreapplication.cpp and (now) doesn't require
access to any QCoreApplication privates.

Pick-to: 6.9
Change-Id: I60a929aed02f71d25e00fffdcd42d092d5533cc4
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2025-02-04 00:01:46 -03:00
Thiago Macieira
39b47431fd QCoreApplication: move some content to libraryPathsLocked()
Amends ee0fd8700724848e73c228d973bf72e246077d07 ("Selectively update
library paths when creating QCoreApplication") which introduced
QCoreApplicationData::manual_libpaths. There's no need to have the
separate function in QCoreApplicationPrivate.

Note: the comment near the change seems to be the opposite of what it
really is. I've left it unchanged.

Pick-to: 6.9
Change-Id: I7abd6d7cfcb6747a6ae4fffd32fbf3a6fdf720fa
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2025-02-03 21:01:46 -06:00
Thiago Macieira
c15bfcd5c0 QCoreApplication: clean up after {win,mac} removal from Bootstrap
Amends commit bf8a5ab418a21d802910728ed24a0a7fad230526. Just some
tidying up.

Change-Id: I3d07a7b151241317ab6bfffd3e79a40db4dab441
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2025-01-24 16:26:33 -08:00
Thiago Macieira
b5e05e1af7 QCoreApplication: remove the indirection to {app,manual}_libpath
Instead of storing a pointer to a QStringList to indicate whether the
list was populated or not, use the QList's d-pointer. Unlike QString and
QByteArray, QList does not have isNull(), so we roll out our own.

Pick-to: 6.9
Change-Id: I6903de324c8215ed4934fffd9d997a34f2e7fa99
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2025-01-18 19:05:48 +00:00
Thiago Macieira
a314e4b985 QCoreApplication: move the QRecursiveMutex into QCoreApplicationData
There's no need for it to be a global, if the data isn't either. I have
a vague recollection of the data also being globals back in the
day... (they used to be plain QStringList pointers).

Pick-to: 6.9
Change-Id: Ie5f1a71d0b20a0195822fffd992101c94824a07f
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2025-01-18 16:05:47 -03:00
Thiago Macieira
981c2e8b74 QCoreApplicationPrivate: use std::unique_ptr for origArgv
Pick-to: 6.9
Change-Id: Id03feb55d3c3899aa4fffffdc0b3ee7b0742f9e8
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2025-01-15 19:10:31 -08:00
Thiago Macieira
f68df05a77 QCoreApplicationPrivate: use NSDMI to initialize the members
This removes the need for #if in the initialization list and the ugly
whitespace-before-punctuation syntax.

Pick-to: 6.9
Change-Id: Id33ec83e574360f65c9bfffd22b8cb450156477b
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2025-01-15 19:10:31 -08:00
Thiago Macieira
bf8a5ab418 Bootstrap: remove qcoreapplication_{mac,win}.cpp & QStandardPaths
We don't need to discover the application's name or file path. This also
removes the only use of QStandardPaths::findExecutable(), so we can
remove the entire class too.

Change-Id: Id297dc9b56ada635cfc9fffd679ead9378fffb03
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2025-01-15 19:10:30 -08:00
Thiago Macieira
357351b7ab Revert "Add categorized logging of delete later machinery"
This reverts commit c3a2b9f35a9a12ff3c6f5f0d11844de161b47c2a.

Unfortunately, some of the log messages happen WAY too late at process
exit time, when QtCore is unloading. In particular, the worst offender
is the one in QThreadPrivate::finish(), which is called after the last
QObject in the thread that called ::exit() was getting destroyed. This
implies we have Static (De)Initialization Order Fiascos happening (the
logging recurses into qlocale.cpp and the defaultLocalePrivate global
static has already been destroyed).

I need to revert this commit in order to fix QThreadData destruction.
The functionality is welcome back in QtCore once the fixes are in, so
long as whoever does it fixes the issues we're seeing in the CI (and I
can't reproduce on my development machine). I've created QTBUG-132429 to
track the reversal and see if the functionality can be brought back in.

Task-number: QTBUG-120124
Task-number: QTBUG-132429
Pick-to: 6.9 6.8
Change-Id: Iecf8f14529c7a2bb2185fffdfd328066098826b1
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2025-01-06 17:48:27 -03:00
Marc Mutz
63f1c6fcba Port QtCore from QScoped- to std::unique_ptr [1/2]: private uses
This patch series is in preparation of enabling QT_NO_SCOPED_POINTER
when building QtCore, a prerequisite for enabling this opt-out in leaf
modules.

This first part of the patch series ports objects whose use cannot
"leak" into other modules, e.g. because they are in .cpp files or are
private members and is thus SC (and, as demonstrated by various static
assertions we put into the source code over the years, BC).

The second patch will deal with objects in protected and public APIs,
and thus might be QUIP-6 SiC Type A.

Pick-to: 6.9
Task-number: QTBUG-132213
Change-Id: If4967f6e563a4e7d74550fad4c6d354fad1beef5
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2024-12-31 08:27:00 +01:00
Thiago Macieira
438b2f2d60 Q*Application: move the compressEvent() virtual to the Private class
One of the parameters is the QPostEventList, which is declared in
qthread_p.h:
   class QPostEventList : public QList<QPostEvent>
and is thus private API anyway. This also requires the ELFVERSION: token
in qthread_p.h to avoid marking every class derived from Q*Application
as needing private Qt ABI.

We can't remove the virtual in Qt 6, so we keep the fallback
implementations to just forward to the Private::compressEvent() call.

I've elected to mark the QApplication's override as final.

Change-Id: I49a46f42e62bcaf7db69fffd12a664d8720bbe46
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-12-13 07:53:10 -08:00
Thiago Macieira
d7c9619a81 QObjectData: relax accesses to postedEvents
If one wants to access the event list itself, they have to lock the
postedEventList mutex, so none of these probably need any more ordering
than Relaxed. I've left most of them in Acquire/Release because we don't
have time to reason whether Relaxed suffices (the one exception is a
loadRelaxed() that calls a function that does loadAcquire()).

Amends commit ba6c1d2785ca6d8a8b162abcd9d978ab0c52ea2d.

Pick-to: 6.8
Change-Id: I35810f961b96aaf63d74fffd1eda73b3e059583d
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-12-05 13:04:46 -08:00
Allan Sandfeld Jensen
083e44318c Make multi-threaded image transforms and painter fills configurable
Some users prefer to avoid having this many threads. This also
moves disabling it for WASM from sources to config.

Fixes: QTBUG-129650
Change-Id: Ib4c7903e85ba9cb75a9e013d1032653ea0ab8b84
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
2024-12-05 22:04:46 +01:00
Thiago Macieira
32ee5539fd QCoreApplication: replace threadRequiresCoreApplication()
With a direct access to the threadData's variable.

Amends commit 10c529b08de7cd55b4c3e3654464119246498273 ("Add a way for
auxiliary threads to handle events without CoreApp", Qt 5.6), which
introduced QDaemonThread, for QtDBus use. We don't need to get the
QThreadData from TLS, because we are processing events for an object
associated with that particular thread.

This removes the only use of QThreadData::current(false) in all of Qt.
Refactoring in the next commit(s).

Change-Id: Ica2bab556bd431519a1bfffd859911ea7daf062f
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2024-11-26 16:35:45 -08:00
Thiago Macieira
763e5a27cd Make QCoreApplication::self an atomic for Qt 7
We use it from many places in Qt that may run before QCoreApplication
has been created (officially not supported but it happens) and after it
has been destroyed. In particular, we have code in QtDBus that runs in
another thread after QCoreApplication has been destroyed and uses the
event system.

This is not a complete change for Qt 7, it's just a reminder for work to
be completed then.

Change-Id: Ie3a0fc665babafd9888dfffd6c551e42f87a9dbd
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2024-11-14 16:55:44 -08:00
Thiago Macieira
4578e3f898 QThread/Win: replace the adopted thread watcher with a thread_local
The adopted thread watcher thread on Windows was a massive hack: because
Win32's Thread Local Storage support[1] did not support registering a
destructor for the data, we couldn't use the same trick we did on Unix
to run some code on the adopted thread when it was about to terminate.
So instead we launched another thread (which would also be adopted so we
had to protect against being watched) to watch the adopted threads and
post notifications. This consumed more resources and also emitted the
QThread::finished() signal from the watcher thread, not the adopted
one. Plus, this could cause crashes if QtCore was unloaded while the
watcher thread was running.

We can now depend on C++11 thread_locals on Windows, which therefore
allows us to run code shortly before the thread's exit. This commit
copies code from qthread_unix.cpp introduced in commit
4fabde349f16b59f37568da2a4c050c6dd53a34e, not including the two-phase
cleaning up.

This allows us to remove the QThreadData destruction code from
QCoreApplicationData.

[1] https://learn.microsoft.com/en-us/windows/win32/ProcThread/using-thread-local-storage

Change-Id: I09deebfec02a15082a68fffd7f650427eabdee54
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2024-11-14 16:55:43 -08:00
Thiago Macieira
65093a84c2 QThread/Unix: do clean up the QAdoptedThread for the main thread
Commit 1ed0dd88a32cd2c5ae100b48e14ff55bcbb652e6 ("QThread/Unix: make
QThreadPrivate::finish() be called much later") introduced this problem.
Commit 4fabde349f16b59f37568da2a4c050c6dd53a34e split the thread
termination in two phases, but did not fix this.

This re-applies commit 950b35cf97ad398f97883efd2a18ee97994a8a9c ("Clear
the current thread data for the main thread"), which was reverted in
commit 7dc622290bb8e81af634034f443e25be0d6d48a3 ("Make sure QThreadData
and QAdoptedThread object is destroyed at app exit"), both from Qt 5.1.

Between Qt 5.1 and 6.7, the responsibility of clearing the
QAdoptedThread for the main thread was split: it could occur either in
~QCoreApplicationData if exit() was called in that thread or in
~QThreadData() if it wasn't (e.g., when the Qt "main thread" is not
main()'s thread):
  * frame #0: 0x0000000101db8a28 QtCore`QAdoptedThread::~QAdoptedThread(this=0x000060000176c070) at qthread.cpp:139:1
    frame #1: 0x0000000101db81eb QtCore`QThreadData::~QThreadData(this=0x0000600002468000) at qthread.cpp:82:5
    frame #2: 0x0000000101db8379 QtCore`QThreadData::~QThreadData(this=0x0000600002468000) at qthread.cpp:57:1
    frame #3: 0x0000000101db841c QtCore`QThreadData::deref(this=0x0000600002468000) at qthread.cpp:108:9
    frame #4: 0x0000000101f4ec79 QtCore`destroy_current_thread_data(p=0x0000600002468000) at qthread_unix.cpp:104:11

This commit centralizes and gives ~QThreadData() the exclusive
responsibility.  That requires not resetting QThreadData::threadId so
~QThreadData can know it is theMainThread.

Fixes: QTBUG-130895
Task-number: QTBUG-129927
Task-number: QTBUG-129846
Task-number: QTBUG-130341
Task-number: QTBUG-117996
Pick-to: 6.8
Change-Id: Ie3f3cbdc5523837b505cfffd95fba5e6498b5069
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2024-11-13 11:00:02 -08:00
Thiago Macieira
9bac90db46 QCoreApplication: use QThread::isMainThread() more
QCoreApplicationPrivate::mainThread() asserts that there is a main
thread, which means we can't use it to detect after the main thread has
been unset (late destructor-on-exit).

Pick-to: 6.8
Change-Id: Iedcd0827d1e659f3de35fffd60cac0b47cc496bb
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2024-11-13 11:00:01 -08:00
Thiago Macieira
a90349aa21 QCoreApplication: remove now-unnecessary thread affinity check
Partially reverts commit 65953e05d3d9aefd158d4073820083155aaae5e4 (the
rest will be addressed in the next commit) now that we have an atomic
access to the QCoreApplication instance.

This thread-affinity check code was there because the code had a data
race in accessing QCoreApplication::self. It ensured that we only read
that variable if the receiver was in the main thread, because if a
receiver is not in the main thread, then it can't be QCoreApplication.

Pick-to: 6.8
Change-Id: I09618961cca80fef2dc1fffdab65316164023207
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2024-11-13 11:00:01 -08:00
Thiago Macieira
7d92ecd917 Add a way to access QCoreApplication's instance atomically
We use it from many places in Qt that may run before QCoreApplication
has been created (officially not supported but it happens) and after it
has been destroyed. In particular, we have code in QtDBus that runs in
another thread after QCoreApplication has been destroyed and uses the
event system. Accessing QCoreApplication::self anywhere but the main
thread was a race condition in those conditions.

Pick-to: 6.8
Change-Id: If4ad1af9301dca98ba69fffdf88c63b220db53ac
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2024-11-13 11:00:00 -08:00
Ahmad Samir
5cd6d227f9 QCoreApplication: move GetCommandLine() call to winCmdArgs()
Gets rid of one QString allocation.

Drive-by change, remove redundant inline keyword from a static helper.

Change-Id: Ie34bbc541f661ef6f07d6384e51af461f917556e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-11-06 22:35:22 +02:00
Assam Boudjelthia
0db5b424cd Android: support uncompressed native libs within APKs
Android 6 and above produces uncompressed native libraries that
are only part of the APK by default. However, Qt had this behavior
explicitly disabled via packagingOptions.jniLibs.useLegacyPackaging
Gradle flag (previously extractNativeLibs manifest flag) because
we didn't support loading libraries directly from the APK.

This patch adds support for reading and loading shared libraries
directly from the APK without having them extracted to disk. Enabling
this might increase slightly the total size of produced APKs, but
saves on disk space after installation and also on update sizes from
the Play Store and slightly faster startups [1][2].

Loading libraries on the Java side is handled by System.loadLibrary().
On C++, dlopen(3) can directly handle library paths relative to the
APK file [3] which would save us the need to add custom code that calls
android_dlopen_ext() [4] which works with compressed libraries then
using AssetFileDescriptor and having to manage its file descriptor
manually.

To ensure proper integration with various Qt APIs and modules, this
adds a QAbstractFileEngine/Iterator implementations to allow reading
and listing APK files. Since, the files are expected to not change,
they are cached once at startup and re-used thereafter. The engine
implementation allows reading the libraries content using Android's
AssetManager. Also, it allows mapping the libraries directly to
memory to allow proper integration with QPluginLoader.

For plugins, the native libs dir inside the APK is added to Qt and
QML plugins search paths.

With this patch, both compressed and uncompressed libs should work,
to ensure this, an auto test is added with 'useLegacyPackaging true'
to make sure both scenarios still works.

[ChangeLog][Android] Add support for uncompressed native libraries
within APKs.

[1] https://android-developers.googleblog.com/2016/07/improvements-for-
smaller-app-downloads.html
[2] https://developer.android.com/guide/topics/manifest/application-
element#extractNativeLibs
[3] https://android.googlesource.com/platform/bionic/+/master/android-
changes-for-ndk-developers.md#Opening-shared-libraries-directly-from-an-
APK
[4] https://developer.android.com/ndk/reference/group/
libdl#android_dlopen_ext

Fixes: QTBUG-61072
Fixes: QTBUG-97650
Change-Id: Ica6c4cc9e5bd8f3610829b76b64bf599339435d9
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2024-10-05 00:56:01 +03:00
Marc Mutz
c59ebcfe72 Inline qcorecmdlineargs_p.h into qcoreapplication.cpp
... its only remaining user.

Amends 71b54cc24431e8bc6e97f5d62132bd5261764c3a, which removed the
only remaining non-qcoreapplication.cpp user of qWinCmdArgs().

In the process, rename the function to non-public-API-looking
winCmdArgs(), and adjust its Q_OS_ protection to what its caller uses
(Q_OS_WIN; was: Q_OS_WIN32).

As a drive-by, change an old-style- to reinterpret_cast.

Pick-to: 6.8
Task-number: QTBUG-126219
Change-Id: Id37e62e9df2a0c44bb1e446e409fd36e11cb77ce
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-09-21 10:03:41 +02:00
Tor Arne Vestbø
60f07671e1 Android: Return QAndroidApplication instance via nativeInterface() getter
The QAndroidApplication native interface wrongly uses static methods
instead of virtual functions, which has lead to client call sites not
using the preferred QCoreApplication::nativeInterface() API to resolve
the interface, and a lack of an implementation in QCoreApplication
for the resolveInterface function.

We now implement resolveInterface for Android, so that the interface
can be resolved via QCoreApplication::nativeInterface(), even if the
interface itself (for now) is based on static methods.

Task-number: QTBUG-128796
Pick-to: 6.8
Change-Id: Id4d8b9a6fcc7d0e2cc76de07dc0742dc5917f3ca
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2024-09-10 20:44:54 +02:00
Zhao Yuhang
60a2888f8c Move debugging trick to more appropriate place
It seems qcoreapplication_win.cpp is a better place for it.

Change-Id: I9861da1521b6e0d353863031f70f68aa6c60217a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-09-09 05:38:07 +00:00
Joerg Bornemann
dfa52e3ae6 Simplify the console detection for QT_WIN_DEBUG_CONSOLE
Instead of reading the PE header we can try to retrieve the stdout
handle, and if it's present, we have a console, or redirected output.

This amends commit 639437cf34783573e14d35ceb68ee8d9de495d7b.

Pick-to: 6.7 6.8
Task-number: QTBUG-127732
Change-Id: Ib6dd1a37552519fd867e7c39e588a085513f97e0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Reviewed-by: Zhao Yuhang <yuhangzhao@deepin.org>
2024-09-05 17:28:19 +02:00
Joerg Bornemann
cef270265f Ignore QT_WIN_DEBUG_CONSOLE for console applications
On Windows, the windeployqt tool failed if QT_WIN_DEBUG_CONSOLE was set
to "attached", because the following happened:
- windeployqt calls qtpaths
- qtpaths attaches to windeployqt's console
- qtpaths' output goes to that console
- windeployqt cannot read qtpaths' output anymore

Other Qt-based command line tools are also affected.

The QT_WIN_DEBUG_CONSOLE environment variable was introduced to see
output from Gui applications on the console. It should not affect
console applications.

We now determine whether the current process was linked with
/SUBSYSTEM:CONSOLE and ignore QT_WIN_DEBUG_CONSOLE's value in that case.

Fixes: QTBUG-127732
Pick-to: 6.7 6.8
Change-Id: Iba7031eed88c7b38cfe3e794c1885b504e4f2ee4
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Zhao Yuhang <yuhangzhao@deepin.org>
2024-08-16 07:51:13 +02:00
Mårten Nordheim
0d3400b97d compressEvent: Remove superfluous check
Before compressEvent is called, receivedPostedEvents is checked for non-zero

Change-Id: I1cbf17a6ce7f48886ff1341fb59c87ee341abf37
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-08-09 18:28:33 +02:00
Volker Hilsheimer
1e1c680173 Logging: use qCDebug/Warning/Info when for categorized logging
When building qt with QT_NO_DEBUG/WARNING/INFO_OUTPUT set, then the
qDebug/Warning/Info macros expand to `QMessageLogger::noDebug`. That
helper is not defined to take a logging category or category function,
so using `qDebug(lcX, ...)` breaks the build. The correct way to emit
categorized logging is to use the qCDebug/Warning/Info macros.

Task-number: QTBUG-125589
Pick-to: 6.8 6.7 6.5
Change-Id: I968b0e826871a09023c11fec9e51caa5a2c4dc0b
Reviewed-by: Jonas Karlsson <jonas.karlsson@qt.io>
2024-07-16 17:59:05 +02:00
Mitch Curtis
3f19c154c5 QCoreApplication: improve warning in checkReceiverThread
- Remove extra '0x'.
- Use QDebug::toString() to get more descriptive output for each object
  involved.

Change-Id: I84cadd89f448453cd4d7f1e7073199fd8c6af7a4
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2024-07-04 21:25:29 +08:00
Mårten Nordheim
b039d2251a compressEvents: simplify TimerEvent compression
While better in some benchmarks, it turns out to be less efficient to
first find an event to the receiver, and then checking the event-ptr
and -type in other benchmarks, compared to just iterating the list and
checking these values.

Partially reverts 3e6b42ae9dbf4f90ba890d78a4c49f9936f4976b

Fixes: QTBUG-126394
Pick-to: 6.8 6.7
Change-Id: I748bda3d31350aea6e87db9bd57359ab17cf5d67
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: YAMAMOTO Atsushi - Signal Slot <atsushi.yamamoto@signal-slot.co.jp>
2024-06-19 01:08:08 +02:00
Marc Mutz
199a4535e7 QCoreApplication: fix a clazy-rule-of-three
The local RAII class was missing the Q_DISABLE_COPY(_MOVE). Add it.

Amends f9035587b98ac5dc9491e642b8ec84470ec03f0e.

Pick-to: 6.8 6.7
Change-Id: I19dfa18c301698e45353435b9b77e62332e54c31
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
2024-06-06 17:09:42 +00:00
Thiago Macieira
ed70faf87a QCoreApplication: make removeNativeEventFilter() remove from main thread
installNativeEventFilter() always installs on the main thread, so match
it.

[ChangeLog][QtCore][QCoreApplication] Fixed a mismatch on which event
dispatcher was modified between installNativeEventFilter() and
removeNativeEventFilter(). Now both functions in QCoreApplication access
the main thread's event dispatcher. To access the current thread's
dispatcher, use QAbstractEventDispatcher's functions.

Fixes: QTBUG-124783
Pick-to: 6.5 6.7
Change-Id: I6979d02a7395405cbf23fffd17ca09e1ac43f1f3
Reviewed-by: David Faure <david.faure@kdab.com>
2024-05-07 21:22:27 +00:00
Tor Arne Vestbø
0b494c47d3 Don't quit automatically via QEventLoopLocker if there are open windows
As part of df359bcb703db5a8adbf14e88ba4ae0d54f0cfcd the semantics and
interaction between QEventLoopLocker and QGuiApplication was changed,
based on the assumption that these two mechanisms were independent
and should not affect each other.

This had a surprising regression where the use of QEventLoopLocker in
combination with the QCoreApplication::isQuitLockEnabled() automatic
quit would end up quitting the app, even if it had open windows, for
example when the last job of some internal job queue finished.

It could be argued that if the app has open windows that should not
be closed, they should ignore the Close event, and that an application
with running QEventLoopLocker jobs should maintain an active window
showing the progress of those jobs, but still, this is regression
that we want to fix.

We now bail out if !lastWindowClosed() in QGuiApplication's
canQuitAutomatically, which is triggered from QEventLoopLocker's
isQuitLockEnabled() behavior. And we do so regardless of whether
quitOnLastWindowClosed is set or not, as the latter property
determines the behavior when closing a window, not the behavior
when a QEventLoopLocker goes out of scope.

Similarly, we now block quitting of the application when triggered
by quitOnLastWindowClosed() if a QEventLoop is active, regardless of
the isQuitLockEnabled(), as the latter property is determining
whether we should trigger a quit, not whether we should block them.

[ChangeLog][Important behavior changes] Fixed a regression where
the last QEventLoopLocker going out of scope would quit the app,
even if there were open windows, if quitOnLastWindowClosed was
false.

[ChangeLog][Important behavior changes] Fixed a regression where
closing the last window would quit the app, even if there were
active QEventLoopLockers, if isQuitLockEnabled was false.

Fixes: QTBUG-124386
Pick-to: 6.7 6.5
Change-Id: I84fd0ddea78a2f417f3a17b326113c880079cf85
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2024-04-29 14:26:38 +00:00
Jarek Kobus
a3d50112e4 QThread: Introduce static isMainThread() helper
Useful for QtCreator, as a replacement for
Utils::isMainThread() inside threadutils.h,
may serve for other projects, too.

Introduce static QCoreApplicationPrivate::theMainThreadId
atomic helper field holding the id of the main thread.

Change-Id: Iccc0302f423f47b5ecad86c4cd3de4d1ee36155f
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-04-26 18:19:39 +02:00
Zhao Yuhang
d12490f661 QtCore: avoid unnecessary export in static build
We only need it to be exported in shared builds.
Without this change, there will always be an
exported symbol called "qt_startup_hook" for
executables that linked against QtCore statically,
this is absolutely not the Qt user would expect.

Change-Id: Icf19df09531e13184ea019aa708d6b93fa626f85
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-04-06 13:14:52 +00:00
Mitch Curtis
baa44b9ddf Qt::ApplicationAttribute: static_assert that we don't go higher than 32
Because we can't support it on 32 bit operating systems.

Task-number: QTBUG-69558
Change-Id: I406ecccdf039d7d4f4c24268c92c91e367655cba
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-04-04 11:31:51 +08:00
Christian Ehrlicher
3dc755a0ae QCoreApplication: work around gcc 11.3 compiler bug
Fix the amiguity in the comparison of a QByteArray and a char*

Task-number: QTBUG-117661
Change-Id: Ic5142b7bc2a8220d244312414618028e8cc50d09
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2024-03-04 06:13:54 +01:00