Compare commits

..

205 Commits
6.10 ... dev

Author SHA1 Message Date
Marc Mutz
532400a722 tst_QPointer: make capture compatible between C++17..23
Clang 19 -std=c++23 complained that ITERATIONS_PER_THREAD was
captured, but not used, so 668d81f73a5c2f4ec14764d1892f2eaf6494c0f1
dropped it, after making the variable constexpr.

Picking that change back to older branches, we found that MSVC
(14.29?) complains that it's _not_ captured anymore:

   tst_qpointer.cpp(491): error C3493: 'ITERATIONS_PER_THREAD' cannot be implicitly captured because no default capture mode has been specified

To appease both compilers, and cover the maximum range of C++ standard
editions, use implicit [&] capture, which should work everywhere.

Not picking to 6.5, because the cherry-pick of
668d81f73a5c2f4ec14764d1892f2eaf6494c0f1 already had to make that
change in order to pass CI.

Pick-to: 6.10 6.9 6.8
Change-Id: Iacbd53d3904608e8c9cd73edf31ba7924fd508e6
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2025-06-15 16:37:14 +00:00
Marc Mutz
6600a332c6 QScopeGuard: only include what you need
... not all of qglobal.h.

[ChangeLog][Potentially Source-Incompatible Changes][QtCore] The
qscopeguard.h header no longer includes qglobal.h, but only what it
itself needs. A backwards-compatible fix is to not depend on
transitive includes and include all you need explicitly.

Pick-to: 6.10
Change-Id: I257ae4cbd36d331e2fbda7fa238dcbc26a75647c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-15 16:37:06 +00:00
Frédéric Lefebvre
00750cd8ba Refactor tst_QScroller::overshoot
tst_QScroller::overshoot was initially a boilerplate, making it
difficult to understand what was actually being tested.

Refactor this test to be data-driven. Additionally, create a new test
function, overshoot_segments, which was part of
tst_QScroller::overshoot and should be tested independently.

Transfer the blacklisted platform of overshoot to overshoot_segments.

Change-Id: I59d89dfab4bb09c41fce99ad4f40163736c6ef78
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-15 17:44:06 +02:00
Matthias Rauter
bb48dbb113 Add conversion from QUtf8StringView to std::u8string_view
Writing the tests for QUtf8StringView showed that this conversation does
not work if the underlying storage_type is not char8_t. This is
something a user rightfully expects from our library and we therefore
added an explicit conversion operator for it.

[ChangeLog][QtCore][QUtf8StringView] Added std::u8string_view operator
if compiled with C++20.

Pick-to: 6.10
Change-Id: Ia80507bdd76686bee16a40745be064e9bdfef130
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2025-06-15 09:35:08 +00:00
Christian Ehrlicher
cfd52c5c5f QStyleSheetStyle: replace c arrays with std::array
Replace some c-arrays with std::array<> for easier handling.

Pick-to: 6.10 6.9
Change-Id: I34766a2aad603d83187515626982adc976667d48
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-14 16:55:46 +00:00
Axel Spoerl
3416d28c8b QWindowsScreenManager::removeScreen() - don't leave stale screen behind
QWindowsScreenManager::removeScreen() read an element from m_screens
and removed it. If the removed screen was not the primary screen,
QWindowSystemInterface::flushWindowSystemEvents() is called.

When removeScreen() is called from handleScreenChanges() in the same
class, flushing window events can lead to a re-entry. That is e.g. the
case when a RDP connection is closed and the server removes the virtual
screen.

QWindowScreenManager::removeScreen() removes the platform screen only
at the very end, which means that m_screens contains a stale pointer.
The re-entry can therefore crash with a double delete.

Take the platform screen at the beginning of the method, to make it
safe for re-entry.

Fixes: QTBUG-135337
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: Id18a6fb3e72922bcdb62c9e79857b6bb713c0c1b
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Wladimir Leuschner <wladimir.leuschner@qt.io>
2025-06-14 17:51:17 +02:00
Marc Mutz
e45916fada [docs] QScopeGuard: fix a grammar mistake in ctor docs
Even though there are two \fn's, we still use singular form when we
refer to the effects of the function.

Amends 4f077b7e5ff1081afc0e362bdab6522c2b7ee43b.

Pick-to: 6.10 6.9 6.8 6.5
Change-Id: I7cc150eb96b4aac40abcf7076bb82049a209f837
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-14 15:38:40 +02:00
Marc Mutz
902e0a723a [docs] QScopeGuard: mention dismiss()ing in \class
The class docs should include a discussion of salient API, not leave
that only to \fn's.

Amends 9229452e574e603aa86fd5adb28da33cf5879db9.

Pick-to: 6.10 6.9 6.8 6.5
Change-Id: I53144c7e56eca21ceeda0c1bca0028e987da9e18
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-14 15:38:40 +02:00
Fabian Kosmale
f2ef861688 moc: support __has_include
__has_include is part of C++17, but moc did not handle it so far.
This commit fixes moc to correctly support it.

It should be noted that support for __has_include relies on all
necessary include paths being passed to moc.

Pick-to: 6.10 6.9 6.8
Fixes: QTBUG-136097
Change-Id: I7284e97dea12d1637b38349d32e090c0102124e7
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-14 12:48:30 +02:00
Fabian Kosmale
246b43d581 cmake: Unify the set flags between AUTOMOC and qt_wrap_cpp
For AUTOMOC, we were missing the compiler flavor flag, as well as the
WIN32 define. While the latter has not caused any known issues yet, the
former is rather problematic for implementing __has_include in moc.

Note that this only applies in the case where the AUTOMOC flags are set
by us in a qt_ function like qt_add_excutable. Plain add_executable
won't benefit from it, but we already mention that Qt targets should not
use plain CMake functions.

This change is (indirectly) tested by the commit adding __has_include
support for moc.

Task-number: QTBUG-136097
Pick-to: 6.10 6.9 6.8
Change-Id: Ie2beb08a44a3a67e3bc363d9c1ba93b7d6a49133
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2025-06-14 12:48:30 +02:00
Ulf Hermann
9a7d06f0d4 QNetworkAccessBackend: Do not leak wrapped upload byte device
The wrappedUploadByteDevice is obviously intended to be owned by
QNetworkAccessBackend. It needs to be deleted when QNetworkAccessBackend
is destroyed.

Ideally we shouldn't use bare pointers at all here, but since we need
to pick this back all the way to 6.5, a minimal fix is preferred.

Amends commit bba0bdb35c2806bcdde8e89965e99b3d412b8d3a

Change-Id: Icbe857ad02c23693c313d3fcb2d0ee068362e5b7
Pick-to: 6.10 6.9 6.8 6.5
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2025-06-14 09:38:39 +00:00
Marc Mutz
f4e7eebd27 QCoreApplication: fold two atomic ops into one
The old code performed a fetchAndSubAcquire() followed by an implicit
loadAcquire() in the Q_ASSERT(). But fetchAndSub() returns the old
value, so we don't need to re-load it; we just need to store the
result of fetchAndSub().

We need to adjust the assertion, of course, since we're now checking
the old value, which is one more than a load would show, so replace ≥
0 with > 0.

Amends the start of the public history.

Pick-to: 6.10 6.9 6.8 6.5
Change-Id: I6f6804261cd56a5a8bbb276ed7a0ac360c94195e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-14 09:38:39 +00:00
Thiago Macieira
96dfe0373c QVarLengthArray: use assign() for the iterator,iterator ctor
Let's avoid std::back_inserter for non-complex types, which generates a
huge amount of unnecessary code. The implementation of assign() is far
more modern.

Pick-to: 6.10
Change-Id: Ia8b9c90336af2bebd49ffffd0d69ace761c6aa59
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2025-06-13 21:24:53 -07:00
Thiago Macieira
54069d37ef tst_ContainerApiSymmetry: add non-deprecated copy assignment to Movable
Despite the name, this class is copyable, as evidenced by the fact it
has a copy constructor. But that copy constructor causes the implicitly-
declared copy-assignment operator to be deprecated.

warning: implicitly-declared ‘constexpr Movable& Movable::operator=(const Movable&)’ is deprecated [-Wdeprecated-copy]
tst_containerapisymmetry.cpp:55:5: note: because ‘Movable’ has user-provided ‘Movable::Movable(const Movable&)’

Amends 2e1763d83a1dacfc5b747934fb77fa7cec7bfe47 (5.14).

Pick-to: 6.10 6.9 6.8 6.5
Change-Id: Ie661f7361a8d86648b21fffdaf9e7d076f86ebe9
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2025-06-13 21:24:29 -07:00
Rami Potinkara
1141a6fa17 Android: fix QtDisplayManager getDisplaySize function
This patch fixed QtDisplayManager::getDisplaySize
function to use API's that do not require
MANAGE_APP_TOKENS permission.

The function previously failed on 32-bit architectures
with Android 11 aka SDK 30 aka VERSION R due to
createWindowContext requiring MANAGE_APP_TOKENS
permission. The earlier try-catch lead to next error,
because of invalid values.

Amends: 98120622ff1f6f87664f4c42e830000a21391751

Fixes: QTBUG-137027
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: Ia9c3a64ea41ad0575a34a96858851a1123cfc915
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-14 06:37:14 +03:00
Ahmad Samir
cee8ea7c13 QDirListing: properly deprecate ExcludeSpecial
Add "since 6.10" to ExcludeOther's docs.

Found in API review.

Amends c553f39e3d3cd02854850da0dfc639acbae59299.

Pick-to: 6.10
Change-Id: I3edb32d4d50864ddbdde03aaca750d590a0e0854
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-14 05:40:56 +03:00
Mårten Nordheim
94f0ff704e Schannel: Use modern key management APIs
The key/certificate lifetime management in our Schannel backend is a
little lacking. We haven't guaranteed that the original contexts are
held alive for the full duration of their usage. Though with default
settings they get persisted to disk so it has been mostly fine.

One problem with that is that the legacy APIs in Windows for this is not
smart enough to figure out that a repeatedly-loaded key is the same one,
so it 'persists' a new file to disk every time we set up a credential
context for a connection. For a busy server this may end up with
creating a ton of small files that don't get deleted (or reused).

By using the ncrypt APIs we don't fully stop persisting _all_ data to
disk, but from testing we now only have one file per key. Regardless of
the amount of connections.

Another patch around lifetimes can be done for dev, and dev only, as
it's quite a bit more extensive, and not fit for picking back to the
LTS branches.

Fixes: QTBUG-136055
Pick-to: 6.10 6.9 6.8
Change-Id: I61398a3773ef8c25aab21df3e78b71f3ab11d488
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2025-06-14 04:40:56 +02:00
Christian Ehrlicher
a0c591c120 QStyleSheetStyle: use range-based for loops
Replace some for loops with range-based ones.

Pick-to: 6.10 6.9
Change-Id: Ib11fb4ec5785b8ec4c9c297684f90d7f5031fe58
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-13 23:10:14 +02:00
Volker Hilsheimer
560bf5a077 Android/iOS: prefer files icons to come from the Icon theme
There are no icons for computer, trash, desktop, folders, files etc. on
mobile platforms. QAbstractFileIconProvider tests the
QPlatformTheme::PreferFileIconFromTheme hint, and if set, gives
QIcon::fromTheme a try with an icon name mapped to the icon provider's
icon type.

We have at least some mapping of such standard icons in the native icon
engines, and those engines would also be the right place to perform
additional platform specific look-ups of icons (i.e. for specific file
types). So as a first improvement, try to use the icon engine for file
icon provider icons.

Task-number: QTBUG-134239
Pick-to: 6.10
Change-Id: Ib8c301a19b0d7e23f1d3ebdccde2147709f3ddb3
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-13 19:52:41 +02:00
Volker Hilsheimer
9f93ddd2f3 QGroupBox: document non-standard behavior for enable/disable logic
When QGroupBox::checked changes, it disables children, and enables
children that are not explicitly disabled. The group box itself however
remains enabled, so it's possible for user code to override the behavior
for individual child widgets, which can happen accidentally when
the order in which children are added, and the checked state of the
group box is changed, is inconsistent.

We won't change this as it has too many side effects. Instead, document
the conceptually deviation from enable/disable state propagation.

Pick-to: 6.10 6.9 6.8 6.5
Fixes: QTBUG-25938
Change-Id: I2aa37600ec932cd4ce721bfa98f63169eb0d0beb
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-13 19:31:12 +02:00
Marc Mutz
ab53b12931 QAccessibleWidget: replace QString default arg with overload
We should not use defaulted arguments of non-trivial type, because
their construction and destruction, even if not passed, is repeated at
every call site, producing O(n) executable code.

By overloading out-of-line, we execute the same code at runtime, but
we have only one copy of the arg construction and destruction, in the
library, O(1) executable code production.

Found in API-review of QAccessibleWidgetV2.

Amends the start of the public history.

Can't pick further than (unreleased) 6.10, because this adds a new
symbol.

Pick-to: 6.10
Task-number: QTBUG-98117
Change-Id: I705bca764992d9e7a2aa1021e0f94006b6817177
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-13 14:31:56 +02:00
Axel Spoerl
444e5b63c3 Blacklist tst_qscroller::overshoot() on Windows
Function has become flaky due to additions made in
84e09e060bedd37d8de7cded7e430371e335c029.

Blacklist for now.
Add missing link to QTBUG-134105 in BLACKLIST file.

Task-number: QTBUG-134105
Pick-to: 6.10 6.9
Change-Id: I2e53ab8de08575f13c950dd92d24ad3017a7dc0a
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2025-06-13 12:25:08 +00:00
Volker Hilsheimer
5dc261357e a11y on macOS: return a valid window element
Our accessibilityWindow implementation asks the parent for it's window,
expecting that it will always be the same. This is conceptually correct.

However, as we don't represent windows through QAccessibilityInterface
and instead rely on the natively provided element, the filtering out of
ignored elements result in accessibilityParent return a null object once
the parent is the window.

Instead, check if we get an interface that represents a Window, and
if so fall through to the code returning the NSView (after going through
QAcessibilityInterface::window call, which was so far missing).

And if we then get a Window element as the parent, then we don't have
to call accessibilityWindow on that parent again. Instead, return the
result directly and only keep going if we got some other element.

Add a test case that confirms that we now get a valid result for the
window attribute.

Pick-to: 6.10 6.9 6.8 6.5
Fixes: QTBUG-137157
Change-Id: Ifa485734b290284bd5a1286e3b3c18454442fa10
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
2025-06-13 14:25:08 +02:00
Marc Mutz
90dbb413bf 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.

Pick-to: 6.10
Change-Id: Ib94bd0989d1a358b552275dc3963b014e6e4c180
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-13 14:25:04 +02:00
Marc Mutz
5efcbf9fb8 QAccessibleWidgetV2: make the dtor protected
QAccessibleWidget (i.e. V1) has a protected dtor, so V2, which merely
extends V1 because we can't add new virtuals (via a new base class)
due to BC constraints, shouldn't differ in this respect.

Amends bb2121551c3d7b1af1553710bc211ba0e39b4212.

Found in API-review.

Pick-to: 6.10
Change-Id: I0c9a00691a14c600b020ff1a9f433634bb7c8d24
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-13 14:25:04 +02:00
Marc Mutz
b9a43e7767 tst_moc: fix Clang -Winline-namespace-reopened-noninline
Says Clang:

  tst_moc.cpp:86:14: warning: inline namespace reopened as a non-inline namespace [-Winline-namespace-reopened-noninline]
     86 |    namespace B::inline C {}
        |              ^
        |    inline
  tst_moc.cpp:84:21: note: previous definition is here
     84 | namespace A::inline B {}
        |                     ^

There's no minimally-invasive fix, because neither

   inline namespace B::inline C {}

nor

   namespace inline B::inline C {}

are valid C++.

So wrap the whole thing in another namespace ("Qt_", to avoid clashing
with somthing else, incl. our own namespace Qt), so we have roughly
the same structure as before, but with two non-inline outer namespaces
instead of one.

Amends 5222df2be7d10bf44dfc2971774eadcb526b7a13.

Pick-to: 6.10 6.9 6.8 6.5
Change-Id: Ia0e35e87934abebc76b719e3bd8124ac77ea07f5
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2025-06-13 14:25:04 +02:00
Marc Mutz
79ab9305c1 QAccessibleWidgetV2: de-inline ctors and avoid QString default arg
We should not use defaulted arguments of non-trivial type, because
their construction and destruction, even if not passed, is repeated at
every call site, producing O(n) executable code.

By overloading out-of-line, we execute the same code at runtime, but
a) we have only one copy of the arg construction and destruction, in
the library, O(1) executable code production, and b) being out-of-line
in the library, the compiler can optimize the call to the base class
ctor away, if it wants to, because it sees its implementation.

Found in API-review.

Amends bb2121551c3d7b1af1553710bc211ba0e39b4212.

Pick-to: 6.10
Task-number: QTBUG-98117
Change-Id: Ib6a3b15cc861893797c0445a91691132b21bbf2c
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-13 12:25:04 +00:00
Wladimir Leuschner
295933aadc WindowsQPA: Make custom titlebar a child window
The current approach for custom titlebar uses an overlay of a
frameless popup window at the position of the titlebar area. This
involves synchronizing the window state, position and size of the
popup window with the original window. Also, the drawing of
rounded edges needs to be done manually with the old approach.
This patch adds the titlebar as a real child to the
original window, so that the window manager takes care of the
synchronization and clipping process.

Fixes: QTBUG-135643
Fixes: QTBUG-133943
Fixes: QTBUG-133946
Pick-to: 6.10 6.9
Change-Id: I1770580a1c306074f41a7ff64c1d525c93918480
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
2025-06-13 14:25:04 +02:00
Kai Uwe Broulik
3d405bfe67 doc: Fix typo in QCalendarWidget::dateTextFormat
renderd -> rendered

Pick-to: 6.10 6.8 6.9 6.5
Change-Id: If4df3cd0dd7a11e30283bf5925dc6364d0d79225
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-13 13:38:52 +02:00
Jonas Karlsson
c15e9740b3 Fix standardbutton-apply-16.png
There were some artifacts added (white pixels and bad anti aliasing)
when the icon was changed in e771e5e2d7ae77f46d01f087242e0f777fdc02ac

Pick-to: 6.10 6.9 6.8 6.5
Change-Id: I12a8658090a1f081321e53433d17fc19ad3e5f12
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-13 13:38:51 +02:00
Even Oscar Andersen
30c254591d wasm: a11y - Implement support for disabled attribute
Fixes: QTBUG-137449
Change-Id: I6aa07c7108b5ad14c12e6f24e71b8dda12fec483
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
2025-06-13 12:02:20 +02:00
Dheerendra Purohit
60841478d3 Doc: Fix QtConcurrent::run member function parameter order documentation
Updated the description to match Qt 6 behavior,
clarifying that the instance argument now follows
the member function pointer.

Fixes: QTBUG-113401
Pick-to: 6.10 6.9 6.8
Change-Id: I6cb9c63718790eda153bc5202ed4eb1d23f032bc
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-13 08:27:35 +00:00
Christian Ehrlicher
4832f61212 SQL/DB2: Add and document DB2_ROOT
Sync the cmake arguments to search for DB2 with the rest of the qsql
find modules and provide a DB2_ROOT env or cmake var.
Also allow the old variables as a fallback.

Pick-to: 6.10
Change-Id: I587e519b5cf3513e9580f64f0fb9b46bf789da5c
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2025-06-13 07:42:54 +00:00
Thiago Macieira
6489c41234 QTest::CrashHandler: print the Unix signal si_code name
It's easier to interpret an "SEGV_MAPERR", "FPE_INTDIV", or "ILL_ILLOPC"
rather than "code 1".

Alongside the decoded instruction pointer from the previous commit, we
now get a message like:

  Received signal 11 (SIGSEGV), code SEGV_MAPERR, at address 0x00005637dd5c1346, for address 0x0000000000000004

Change-Id: Ic9f54e06fd2956fea3ccfffde7aa7b54167333b7
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2025-06-12 19:14:58 -07:00
Thiago Macieira
5d28c05ba8 QFileSystemEngine/Unix: fix typos and correct comments
Change-Id: I4d90d8ea8d25b89c9e8dfffd0210fc99e0d5ac3e
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2025-06-12 23:14:41 -03:00
Thiago Macieira
e1d418bcd0 QFileSystemEngine/Unix: avoid an unnecessary conversion to QString
Sometimes, fillMetaData() is called with a QFileSystemEntry with only
the native (QByteArray) format, which we used above in this function
anyway in order to lstat() and stat() the path. This avoids forcing the
QFSE to create the QString form for us to check the first character.

Pick-to: 6.10 6.9 6.8
Change-Id: I8d93f6db83a28d70a192fffd6668734a8024b88b
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2025-06-12 23:14:37 -03:00
Thiago Macieira
c5e6034bbd QFileSystemEngine/Linux: correct a minor problem with lstatx() failures
Our wrappers around the statx(2) system call on Linux return the
negative of errno, to avoid setting errno and reading it back for the
OSes where the system call doesn't apply. That means the vast majority
of errors from qt_lstatx() will not be -1 (the most common being -2 for
ENOENT) and we'd thus not enter the next block:

    // second, we try a regular stat(2)
    if (statResult == -1 && (what & QFileSystemMetaData::PosixStatFlags)) {

Pick-to: 6.10 6.9 6.8
Change-Id: I489e7c9ee1327fb98510fffd315c66948956534f
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2025-06-12 23:14:36 -03:00
Thiago Macieira
07d3d3935c QRangeModel/Doc: link to QtWidgets only if the feature is set
Amends efe41182fda94c0e4805c24b3305577e5da81880.

The code already tests for QT_NO_WIDGETS before including and using
Widgets APIs, and we will want to extend the corelib_snippets target
with more of the existing snippets code to make sure that they build.

To not break -no-widgets builds, don't link against Qt::Widgets unless
the feature is set.

Pick-to: 6.10
Fixes: QTBUG-137556
Change-Id: Ic30fd519416068c275c3fffd0e1df10a76ce8fad
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-12 21:17:58 +00:00
Volker Hilsheimer
45202b26ce Fix -no-feature-draganddrop builds
Amends 7d0017cda8fde28a1130feaeecf41010b40e3cb3 which added the APIs,
and ef7e5ea616a3f04ff0ba5f6fe34487a332152b01 which only added the guard
for QListWidget.

Address header review comment.

Pick-to: 6.10
Task-number: QTBUG-137478
Change-Id: I405190190f4d64dd810d7d35e9ef616ab0147b19
Reviewed-by: David Faure <david.faure@kdab.com>
2025-06-12 20:22:38 +02:00
Marc Mutz
668d81f73a tst_QPointer: fix Clang 19 -Wunused-lambda-capture
Clang informs that ITERATIONS_PER_THREAD need not be captured:

  tst_qpointer.cpp:548:66: warning: lambda capture 'ITERATIONS_PER_THREAD' is not required to be captured for this use [-Wunused-lambda-capture]
    548 |                 QThread::create([&startSemaphore, &targetObject, ITERATIONS_PER_THREAD]() {
        |                                                                ~~^~~~~~~~~~~~~~~~~~~~~

Make ITERATIONS_PER_THREAD (and NUM_THREADS, while at it) constexpr,
indicating even to non-language-lawyers that these variables, indeed,
need not be captured, then drop the capture.

Amends 253f34082f526ff1ffd9eaefac73cc9aa616ab2a.

Pick-to: 6.10 6.9 6.8 6.5
Change-Id: I27d94763058e1dcea3a65d4ff2c859b40336446f
Reviewed-by: David Faure <david.faure@kdab.com>
2025-06-12 18:22:38 +00:00
Marc Mutz
901a6e7986 tst_ContainerApiSymmetry: ensure we're checking defined iterator types
The old code used the same type of container for both target and
source in the range-assign() test. This limits our test coverage.

Fork the test to explicitly test with random-access (std::vector), as
well as forward-only (std::forward_list) iterators. This ensures we
have coverage of random-access, forward as well as the existing input
iterator types.

Amends 426d975cee9c783aec0832f376b836cdabee983f.

Pick-to: 6.10 6.9 6.8
Change-Id: I59c7a322ecbcc564baa1263e02b234bc53563fac
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2025-06-12 20:22:38 +02:00
Marc Mutz
c51a038615 tst_ContainerApiSymmetry: rename a variable in assign_impl()
A container is not an iterator, so don't call a container
'iter'. Since we're copying from it, call it 'src'.

Amends 7cbdc8abbda12488f51317313347bbc220b42fe0.

Pick-to: 6.10 6.9 6.8
Change-Id: I7732465f222032b2833396576873fed370f71d11
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2025-06-12 20:22:38 +02:00
Thiago Macieira
4f0156fa4b Q*Mutex: unexport for Qt 7
Those weren't caught for the Qt 6.0 release.

Pick-to: 6.10
Change-Id: I5831d4ad80b7f60d8782fffd6c64ef552f82ad6e
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2025-06-12 11:22:38 -07:00
Alexey Edelev
d91d49ffe2 Move Android ABI detection to the separate function
Allows reusing the Android ABI detection.

Pick-to: 6.8 6.9 6.10
Change-Id: I8e452605b25e522c953f39a525c038a88174094b
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2025-06-12 18:58:33 +02:00
Alexey Edelev
1f10cd4b45 Introduce _qt_internal_append_cmake_configure_depends
The function append the unique entries to the CMAKE_CONFIGURE_DEPENDS
property. This suppress the ninja recompat issue, which complains
about the duplicated entries in that come from the
CMAKE_CONFIGURE_DEPENDS property. It's likely the CMake issue, but
we may work around it.

Pick-to: 6.8 6.9 6.10
Change-Id: I2f10834b0dca3d2aa08fe13fba69849e97fa77d0
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2025-06-12 18:58:33 +02:00
Mårten Nordheim
1bcfbfa3bc QDateTime::currentDateTime: fix time zone offset for repeated hours
Because we were consulting GetLocalTime we didn't get disambiguated
times for repeated hours. Drop that code-path and simple rely on
GetSystemTime instead.

Done-with: Mate Barany <mate.barany@qt.io>
Done-with: Edward Welbourne <edward.welbourne@qt.io>
Fixes: QTBUG-133656
Pick-to: 6.10 6.9 6.8
Change-Id: I3f1f09edfd9fb3135ccc12bf98e06254327e76fe
Reviewed-by: Mate Barany <mate.barany@qt.io>
2025-06-12 16:58:33 +00:00
Mårten Nordheim
3af5e42bdd Http2ProtocolHandler: fix logic error with potential use-after-free
We previously asserted that the reply was not nullptr, except in some
special circumstance. But then we proceeded to dereference it anyway.
This was then recently changed to be an if-check, but that just
highlighted the logic-flaw (and made static analyzers warn about it...)

What we want to assert is that the stream object is valid and
conditionally return early if the reply is nullptr, which it is for
promised streams, since no request has been made yet so no reply is
created.

At the same time, update the logic in the QHttp2Stream to not store or
emit header-related signals for a stream that has been reset.

Pick-to: 6.10 6.9
Change-Id: I55d69bbedc027893f6ad125c29468a34e7fb406f
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2025-06-12 18:58:33 +02:00
Mårten Nordheim
f9fbdba3a1 Schannel: Use smart-ptr to manage the certiticate context
We already have the alias for it, we just never updated the stored
member to use it.

Pick-to: 6.10 6.9 6.8
Change-Id: I850c9f0b899a15603b4c5ac83693019b856effb2
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2025-06-12 16:58:33 +00:00
Marc Mutz
6c18b438a3 QMetaObject: port QArgumentType to QByteArrayView
Now that argumentTypesFromString() actually doesn't normalize types
anymore, all type names are substrings of the signature, and so
QByteArrayView suffices (was: QByteArray) to hold the result.

QArgumentType in only used transitively, during QMetaObject member
function or QObject::connect() calls, so the source string will also
never go out of scope before the QArgumentType object that references
it.

As a drive-by, make the QArgumentType ctor explicit and port from
QVLA::op+=() to emplace_back().

No discernable impact on tst_bench_qobject's connect_disconnect.

Task-number: QTBUG-135572
Change-Id: If6544917b9df8191a256dc2a67e31c6b7e5a38cb
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-12 18:03:50 +02:00
Marc Mutz
afdf37ad8f QMetaObject: deprecate the Qt 6 QVector -> QList porting kludge
The argumentTypesFromString() function is clearly documented not to
perform any normalization, yet in typical Qt 6.0 porting rush, it did,
and this kludge was never removed.

Do it now; it's in the way of porting QArgumentType from QBA to QBAV,
and it's causing correct code to incorrectly fail.

This, however, changes the behavior of QMetaObject::indexOf*(), because
they don't fall back to normalization (indeed, these functions are used
as isNormalized checks, e.g. in connect()). So we can't remove the
kludge just yet, but we can drag it out of the fast path and re-try
with QVector replaced by QList when nothing was found using the
original signature. This way, we only pessimize unported users (and
calls that would have failed for other reasons, by scanning for
"QVector<" in the signature).

Add a qWarning() that we'll remove this behavior going forward.

It does, however, fix the bug that signals and slots that contain
types that match, but are not, "QVector<", fail to be found by the
machinery:

[ChangeLog][QtCore][QMetaObject/QObject] Fixed a bug that caused
signals and slots with argument types matching "QVector<"
(e.g. "MyQVector<int>" or "NotQt::QVector<int>") to not be found in
QObject::connect() or QMetaObject::indexOfMethod().

[ChangeLog][Deprecation Notices][QMetaObject] The
indexOf{Constructor,Slot,Signal,Method}() functions are documented to
require input according to QMetaObject::normalizedSignature(), but
accepted a QList declared as QVector. This was an internal porting aid
and is being deprecated now. Watch out for runtime warnings about this.
QObject::connect() and QMetaObject::invokeMethod() are unaffected, as
they fall back to normalizeSignature() automatically.

No change in tst_bench_qobject connect performance, which is
unsurprising, as the benchmark doesn't use a QVector alias.

Amends 03326a2fec416405b437089874f6439e937bbada.

Task-number: QTBUG-135572
Pick-to: 6.10
Change-Id: I7fd9293bba5d2b57b4452e55499ffbf360bc6123
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2025-06-12 16:03:50 +00:00
Olivier De Cannière
5aa1bc4621 Widgets: Set viewItemPosition style option for QTableView and QListView
Before this patch, we did not set the view item positions in the views.
This was fine as they were ignored until
b780eaf6a063a7efe03417cf6b7008a188e222a4 added a condition to early exit
on invalid positions. This then broke all qss background styling using
QStyleOptionViewItem::ViewItemPosition as they were always invalid.

Set the position when trying to draw a cell of the view before
reaching the code handling the qss rules for backgrounds.

Fixes: QTBUG-137346
Pick-to: 6.10 6.9 6.8
Change-Id: I83d7a3ea7b9bab98889791bb807988a74e355b93
Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
2025-06-12 17:22:23 +02:00
Petri Virkkunen
76bf2512e7 Android: Add default template argument return type to AndroidBackendRegister
For AndroidBackendRegister::callInterface, it would be more convenient
to call simple functions without parameters, without being forced to
specify the void return type. Added a default void type argument for
the return type.

Change-Id: Ib7f631c172955cdf0b2e853155fd57c06bef9843
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-12 13:37:19 +00:00
Petri Virkkunen
43e52253d5 Android: Add some developer documentation to AndroidBackendRegister
A quick blurb to explain the usecase and limitations of
AndroidBackendRegister, meant for future developers.

Also documents the two public-facing functions, getInterface()
and callInterface().

Change-Id: I79f07d4a19fdb1f4a53529ab42a8663999759f85
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-12 16:37:19 +03:00
Morten Sørvig
c2ec20b226 wasm: don't recreate WebGL context on surface change
The native WebGL context is tied to a single canvas,
and can only be used with that canvas. (Qt creates
one canvas per QPlatformWindow).

This means that we need new native contexts in cases
where a QWindow is repeatedly created and destroyed.
It can be tempting to just create a new WebGL context
"behind the scenes" on the makeCurrent() call in this
case, but this does not work since GL resources created
by user code with the original WebGL context in place
are now invalid.

Inform user code that this has happened by signaling
a context loss. This is done by returning false from
makeCurrent(), and then making sure isValid() returns
false as well.

The context becomes invalid whenever the owning platform
window is destroyed; add a call from ~QWasmWindow() which
handles that bookkeeping.

Pick-to: 6.10
Task-number: QTBUG-120138
Change-Id: I929b9bb51153007c16630b1a991399f01ebffa62
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
2025-06-12 15:37:19 +02:00
Gleb Popov
59c29436db QNativeSocketEngine: React on POLLHUP too when selecting for writing
FreeBSD may return a single POLLHUP revent not coupled with any of POLLOUT nor
POLLERR. This causes a busy-loop, so put POLLHUP into write_flags.

Change-Id: Ief62138eeb6de8e2caf1d6937507bfd828adfb81
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-12 15:20:49 +03:00
Gleb Popov
4ba106b38f QEventDispatcherGlib: Put G_IO_HUP into pfd.events for all cases of QSocketNotifier::Type
On FreeBSD when asked for POLLOUT the poll() syscall returns only POLLHUP to
signify the fact that the other side closed the connection. It never sends
POLLERR for EOF cases, which results in a busy-loop inside the Glib dispatcher:
- poll() returns immediately with POLLHUP for a closed socket
- socketNotifierSourceCheck() does not detect it, because .events = POLLOUT | POLLERR
  and we get .revents = POLLHUP. The (events & revents != 0) condition evaluates to false
- the code decides there is nothing to do and a new iteration starts

A similar issue in dbus code: https://gitlab.freedesktop.org/dbus/dbus/-/merge_requests/526

Change-Id: I2660a5179031da8eb9fe2562abe7fb283c77f64a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-12 15:20:49 +03:00
David Boddie
5b86fca7cf Doc: Remove redundant "see also" link
Pick-to: 6.9 6.10
Change-Id: Id48d97a171b55f3dbf8d1fa32e23b82d28e5552d
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
2025-06-12 12:20:49 +00:00
Thiago Macieira
25f396218d QBasicMutex: bring back fastTryUnlock for MSVC
MSVC exports inline functions, so we're not allowed to remove them. This
is an unlikely problem, though, since it was only called from other
inline functions: if the compiler was inlining content into user code
(as it should), then it would likely have inlined this one too; if
instead the inliner was disabled, then it wouldn't have inlined the
caller either.

Amends commit 1957597aa6bc6ebd8bd1f903389800897411ac5d. Seen in API
review.

Pick-to: 6.10
Task-number: QTBUG-137478
Change-Id: Idd01170c3396c5b6fefefffd748f3335fc42fd79
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2025-06-12 12:20:49 +00:00
Marc Mutz
184d0bf2ec QSharedPointer: fix uninit'ed field 'destroyer'
The getAndRef(const QObject*) function failed to initialize
ExternalRefCountData's destroyer field: the Qt::Uninitialized ctor
doesn't init anything and there are no following assignments to the
field, either.

This probably a) caused some Coverty complaint (but I didn't check,
because the Coverity UI is so clumsy) and b) was harmless, seeing as
the -1 in strongref indicated that the destroyer is never to be fired.

Fix it nevertheless by initializing it to nullptr.

Amends the start of the public history.

Pick-to: 6.10 6.9 6.8 6.5
Change-Id: Ib76b4bc00b08289bb8d6d58096b43501b47814d1
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-12 14:04:58 +02:00
Marc Mutz
e4b0549a4c QSocks5SocketEngine: don't depend on zero-initialization of QBasicAtomic
It's unclear¹ whether static zero-initialization of a static
QBasicAtomic actually initializes the object with a zero value, or
whether it remains default-constructed (without a value until a
following call to std::atomic_init gives it one).

Play it safe and use Q_BASIC_ATOMIC_INITIALIZER(0) to dodge any issues
the old code may have had.

¹ see ongoing discussion on the Jira ticket

Amends 04d6495bf773a6bb0d4fa6980df22d3b81a605b0.

Task-number: QTBUG-137465
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: Iee0d75ce10a589390afdd9069b7040a1c9c608e1
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-12 14:04:58 +02:00
Marc Mutz
5aefe2d9a1 QRegion: fix potential UB in QBasicAtomic initialization
Until C++17 (inclusive), a default-constructed std::atomic object can,
officially, only be initialized with a call to std::atomic_init, for
which QBasicAtomic doesn't have API. It is even unclear whether
zero-initialization of static and thread-local objects will cause the
object to be initialized.

QRegion is using QtPrivate::RefCount, but that's just another wrapper
around QBasicAtomic, so it has the same problems: it must always be
initialized.

So don't default-construct and then storeRelaxed() (via
initializeOwned()), use NSDMI with (newly-added)
Q_REFCOUNT_INITIALIZE_OWNED to avoid this dark language corner.

Task-number: QTBUG-137465
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: I4b765aed329211984c35c40fbc5648bf104990ce
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-12 14:04:58 +02:00
Jani Korteniemi
3047d6a8a1 Fix androiddeployqt copying build directory
When project's Android package source directory is set to the
project level (instead of project/android) androiddeployqt keeps
copying the build directory under itself infinitely.

Add check to copyFiles:
-If android source dir is the same as project source dir
-And if current directory copied is in build directory path

Pick-to: 6.5 6.8 6.9 6.10
Fixes: QTBUG-126743
Change-Id: If45766152c6cbf9e2ee916baa5a15282d3fedaf2
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-12 08:58:39 +03:00
Marc Mutz
270b219410 QTRY_IMPL: revert an incorrect change to a code comment
The comment in the QTRY_IMPL macro definition pertains to the
following using namespace std::chrono_literals, which has nothing to
do with the default timeout of QTRY_ macros, because that is
determined somewhere else. Further, "5 seconds" is not a valid chrono
literal, as "5s" was.

Partially reverts 55f163382d36ddf908fc2884f2020a1b92340c10.

Found in API-review.

Pick-to: 6.10
Change-Id: Ic1242436bf87d7067e3c5240eb2687505e24800f
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2025-06-12 00:34:17 +02:00
Marc Mutz
f1e1a933a6 qdebug.h: remove duplicate includes
Added by 51f702d4029148570d255daef80d071d98cf1e16 w/o rationale.

Found in API-review.

Pick-to: 6.10
Change-Id: Ia0afd3d3aaf7a8bc392333b8359ce5b5496bec7f
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2025-06-12 00:34:17 +02:00
Mårten Nordheim
9ed754e754 Schannel: fix verifying intermediate certificates with netscape ext
We were always checking 'client' or 'server' usage depending on our own type,
which breaks for any intermediate certificate with the 'ca' usage set.

We assume that any non-leaf certificate should be a CA (if anything),
and leaf certificates must be for client or server usage.

Pick-to: 6.10 6.9 6.8 6.5
Fixes: QTBUG-137041
Change-Id: I268f3bad669df77351fc458f56e318db75ecac7b
Reviewed-by: Mate Barany <mate.barany@qt.io>
2025-06-11 21:22:55 +02:00
Volker Hilsheimer
33dc247b6a Test: don't discard result of QFile::open
QVERIFY that the file could be opened, fail the test if it couldn't.

Pick-to: 6.10 6.9
Change-Id: Iab9b819e70b71fade6a58286edff8e022748d9f6
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
2025-06-11 20:10:43 +02:00
Fabian Kosmale
3f0261ebe3 QSFPM: Support source model undergoing reset during setSourceModel
Since 9d8663c18e88cb0b5a65f86cfd7726f3d31e04d6, we print a warning when
endResetModel is called without beginResetModel.
This however triggers false positives with a QSFPM if we set a source
model which is resetting at this point in time:
The QSFPM reacts to the endResetModel signal in _q_sourceReset by
calling its own endResetModel, but it does not have the resetting flag
set.
Fix this by deferring the endResetModel work that we are doing in
setSourceModel if the source is undergoing reset.

Task-number: QTBUG-132775
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: I363f2f34a06cc5de031fa87c6274322bf03bd77f
Reviewed-by: David Faure <david.faure@kdab.com>
2025-06-11 20:01:04 +02:00
Topi Reinio
a9a68a87b9 Doc: Adjust styling of QML property signatures in offline docs
Recent changes in QDoc's output for QML type reference pages included
rearranging the `extra synopsis` element, i.e, read-only, since, and
deprecation information for properties.

As a result, the existing CSS for the offline documentation caused some
elements to be rendered on top of each other when using the qlitehtml-
based backend in Qt Assistant and Qt Creator.

To fix the layout, set a fixed width for the table elements that
are used to display the properties, property groups, and methods.
This change brings the style of QML reference pages closer to that
of C++ reference, where signatures also have a fixed width.

Pick-to: 6.10 6.9 6.8
Fixes: QTBUG-136990
Change-Id: I72adbeaca46cd9dd99c54368257268dc8db6bfdc
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
Reviewed-by: David Boddie <david.boddie@qt.io>
2025-06-11 17:21:52 +00:00
Matthias Rauter
25df8042a4 Incorporate the sub-class-of info when deriving mimetypes
The tika mimetype database contains multiple rules that would fit to a
valid file (e.g. svg file that is svg and xml) with the same priority
(50 in case of svg and xml). The choice is thus ambiguous which leads to
regressions in the reported mimetype.

In order to break ambiguity, we look now also at the sub-class-of
element and we prefer sub-classes as they are more narrow and detailed
than the super-class.
The recommended checking order of freedesktop.org suggests that this is
the correct thing to do: "If any of the mimetypes resulting from a glob
match is equal to or a subclass of the result from the magic sniffing,
use this as the result." However, this does not fit perfectly to the
case of the bug report because both results come from magic sniffing.

If two rules match and have the same priority, without one being a
sub-class of the other, there is still an ambiguity. In that case we
now print a warning about the ambiguity.

The patch adds a test for the previously ambiguous case. There is no
test for the warning on ambiguity, because such a test file would be
difficult to generate and is probably not worth the effort.

Fixes: QTBUG-133221
Pick-to: 6.10 6.9 6.8
Change-Id: I1817ec4da947cd91729d0ce35defc9f63cd784d9
Reviewed-by: Mate Barany <mate.barany@qt.io>
2025-06-11 18:46:52 +02:00
Marc Mutz
fe7f01019c tst_QMetaObject: don't compare QByteArray/QLatin1StringView
This isn't needed, and actually counter-productive, because this mix
used to be ambiguous in Qt 6.5.

Amends 5c563a98a5ffe2a72a641bfa9ed30e17ecffd893.

Not picking to 6.5, because the 6.5 cherry-pick of the amended commit
doesn't compile, so the _L1's were already removed as part of manual
conflict resolution.

Pick-to: 6.10 6.9 6.8
Change-Id: I1810f90c7cf6e3760f1d99e026b291311501c3aa
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2025-06-11 18:46:52 +02:00
Matthias Rauter
26bf2bedca Extend tests for QUtf8StringView
The existing tests were taken from tst_QLatin1StringView. This patch
adds the simple tests from tst_QStringView.

The tests fromLiteral(), fromRange() and fromContainer() are not
included in this patch.

Pick-to: 6.10 6.9 6.8 6.5
Task-number: QTBUG-132097
Change-Id: I1efc0c2d2f474f6644261575a745aa8f7e5ac4b2
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-11 18:18:04 +02:00
Volker Hilsheimer
7ac8815a19 QRM: silence gcc warning that an array can never be nullptr
If T is a C-array, like it is in some of our tests, then an instance of
that can never be nullptr, which recent gcc versions think warrants a
compile time warning -Waddress.

As a C array is a valid data structure to instantiate a QRangeModel
from, silence that warning by handling the case explicitly.

Pick-to: 6.10
Change-Id: I63090891988e677cf3ae2d871418b1abd4d1dc71
Reviewed-by: Matthias Rauter <matthias.rauter@qt.io>
2025-06-11 18:18:04 +02:00
Matthias Rauter
dd81b42127 Make include guard match its filename
Pick-to: 6.10
Change-Id: I57af3c237bddffc424cab734faa30deacaa9bcdb
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2025-06-11 16:59:46 +02:00
Laszlo Agocs
fdbc8079c9 rhi: Update the docs and manual test for geometry shaders
Task-number: QTBUG-137521
Change-Id: Ic9256eaaa55aef20c622429058fda9235c1f73c1
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
2025-06-11 15:15:42 +02:00
Aaron McCarthy
7dd952667c Copy Android files from the application source in aux mode
The application provided overrides of the Android files were not being
used in aux mode. In aux mode androiddeployqt was only copying the
Android files from the Qt sources and updating them.

With this change androiddeployqt also copies the Android files from the
application source, allowing overrides prior to template processing.

Change-Id: Idf790f1c270691dab8fe093c20e84bed79bf481d
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-11 23:15:42 +10:00
Cristian Le
00a96237fd Propagate _Qt6CTestMacros in RunCMake
Propagate the `_Qt6CTestMacros` variable so that
`_qt_internal_get_cmake_test_configure_options` can be used
inside the RunCMake tests

Pick-to: 6.8 6.9 6.10
Change-Id: I2b7f3996315169d840bab3dff011927288c9782d
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2025-06-11 09:14:06 +02:00
Tor Arne Vestbø
cdb33c3d56 macOS: Remove linkage to AGL framework
It's no longer available on macOS 26, and we don't use it anymore
anyways.

Pick-to: 6.10 6.9 6.8 6.5
Change-Id: Ia1d0e37dda177f333646e598e517f4af20215dad
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2025-06-10 21:17:22 -07:00
David Faure
5e971101f0 QIdentityProxyModel: avoid emitting reset in no-op setSourceModel
QSortFilterProxyModel does this exactly, it was missing in
QIdentityProxyModel.

Pick-to: 6.10
Change-Id: If14bc7a377c1ad9235dd70222e3bfbf88eef11c0
Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
2025-06-11 04:08:35 +02:00
Tor Arne Vestbø
b9c77b9685 macOS: Explicitly link the platform plugin to Foundation
In the macOS 26 SDK the NSUserActivityTypeBrowsingWeb is claimed to come
from both Foundation (as in earlier SDKS), as well as CoreServices.

However the latter is not the case on macOS 15, resulting into load
errors with missing symbol.

By explicitly linking to Foundation, and putting it first in the
framework list, we trigger the linker to use the right reference
for the symbol.

Reported upstream as FB17876148.

Pick-to: 6.10 6.9 6.8 6.5
Change-Id: I0c3203f92851ad9fa862aed237823f0e1e28f6ff
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2025-06-10 15:41:35 -07:00
Samuli Piippo
0f6c93c453 wayland: fix EGL build without x11
Amend 7c0a96785fee4fea8ef1452166b1dde88957445c and add needed
defines to fix EGL build without x11. Otherwise eglplatform.h
will try to include X11 headers.
See 4cc5428548cb8ab973e4b0281dd123d59bfaf6a0 for more details.

Pick-to: 6.10
Change-Id: I2c284219e83fecf862520a2f667d561adf4d4357
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-10 21:32:56 +00:00
Samuli Piippo
ccb854799d CMake: build QGnomePortalInterface always when DBus is available
Builds with DBus but without XCB/Wayland, failed with:
  qgnometheme.cpp:(.text+0x3ec): undefined reference to `vtable for QGnomePortalInterface'
  /usr/bin/ld: src/gui/CMakeFiles/Gui.dir/platform/unix/qgnometheme.cpp.o: in function `QGnomeThemePrivate::QGnomeThemePrivate()':

Change CMake configuration and build QGnomePortalInterface always with DBus,
except on Apple platforms, where it is not needed.

Pick-to: 6.10
Change-Id: I3fb6400d87ba08f03c30e33924c8c7d483486c3b
Reviewed-by: MohammadHossein Qanbari <mohammad.qanbari@qt.io>
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-10 21:32:56 +00:00
Volker Hilsheimer
1ee43844d4 Exclude MSVC version 19.44 in tst_qcheckedint and tst_qnumeric
Still causing an internal compiler error with the currently latest VC++
version.

Amends 4e3a1675793995e44f5c84f28bfdc0fd02aa27cc.

Pick-to: 6.10
Change-Id: Ia4290c9b21eb8163180d725ed200629e36e85f1f
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
2025-06-10 22:57:53 +02:00
Christian Ehrlicher
46c2aa2b61 QPA/Windows: Fix QPainter warnings when animations are disabled
Don't draw on a QImage with a size of 0/0.

This amends 5feefd30734cd12753956819fc7c152be07c24cd

Pick-to: 6.10 6.9 6.9.1
Fixes: QTBUG-135844
Task-number: QTBUG-127634
Change-Id: Ib57cdccfabe67454984f3229f9d7ad02dd0d9992
Reviewed-by: Błażej Szczygieł <mumei6102@gmail.com>
Reviewed-by: Wladimir Leuschner <wladimir.leuschner@qt.io>
2025-06-10 18:30:25 +00:00
Edward Welbourne
5e9efe45df Make QTest::failOnWarning() fail also on any message type >= warning
Particularly for the no-parameter case, which fails on any warning, it
makes no sense to not also fail on a critical.

Pick-to: 6.10 6.9
Change-Id: I36f02a7dfb195616ce68babedbccc61480935fb9
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
2025-06-10 20:11:54 +02:00
Edward Welbourne
dd5f409c58 Rework tst_QDate{,Time} QDataStream test to include all versions
In tst_QDate the test previously had a hard-coded list of versions by
name. This, however, needed updates on each new release (or at least
new version of QDS), which have been neglected since Qt 5.0. The
tst_QDateTime version, meanwhile, only identified versions by their
numeric value, not their symbolic names.

So borrow the way tst_QCalendar enumerates QCalendar::System, making
QDataStream a Q_GADGET and its Version a Q_ENUM to support this, to
iterate over all versions algorithmically. Apply to both data stream
tests to get a more consistent form for their data tags.

Change-Id: I04d1060cfec822cfcdc0bce6d15b636fc165fe36
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-10 20:11:54 +02:00
Edward Welbourne
3905d3c4df Use QMetaEnum::fromType() instead of staticMetaObject.enumerator()
The old way relied on the order of enums within the type; using
fromType() makes the enum specific.

Change-Id: I418473a6983861ca105ccc5eb249f441dbbb28cf
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-10 20:11:54 +02:00
Tor Arne Vestbø
f67ef4934b Add QOperatingSystemVersion/QSysInfo support for macOS 26 (Tahoe)
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: If6e7ee92e7c491c91a17e2730112319a132ca623
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-10 11:11:54 -07:00
Frédéric Lefebvre
372a8f904a Unblacklist tst_qListView::styleOptionViewItem on Ubuntu Wayland
tst_qListView::styleOptionViewItem is no longer flaky on Ubuntu
Wayland.

Fixes: QTBUG-127920
Pick-to: 6.10
Change-Id: Ia79292c283bc21bb84b3cc30a7d6c1863c8d0836
Reviewed-by: Liang Qi <liang.qi@qt.io>
2025-06-10 18:41:35 +02:00
Liang Qi
22e193e293 Unblacklist tst_qGraphicsItem::itemUsesExtendedStyleOption on Wayland
tst_qGraphicsItem::itemUsesExtendedStyleOption is no longer flaky on
Ubuntu Wayland.

Fixes: QTBUG-115293
Pick-to: 6.10
Change-Id: Ic971a13c37398bd2eaa9ccb16c10bcf62fdb8d69
Reviewed-by: Liang Qi <liang.qi@qt.io>
2025-06-10 18:41:35 +02:00
Frédéric Lefebvre
ccd7eda005 Unblacklist tst_qGraphicsItem::cursor on Ubuntu Wayland
tst_qGraphicsItem::cursor is no longer flaky on Ubuntu Wayland.

Fixes: QTBUG-127920
Pick-to: 6.10
Change-Id: Ie9096f8790bd031b642c5f5c259445859848c2f5
Reviewed-by: Liang Qi <liang.qi@qt.io>
2025-06-10 18:41:35 +02:00
Frédéric Lefebvre
e3225008cb Unblacklist tst_qPrinter::testPrintPreviewDialog on Ubuntu Wayland
tst_qPrinter::testPrintPreviewDialog is no longer flaky on Ubuntu
Wayland.

Fixes: QTBUG-127920
Pick-to: 6.10
Change-Id: Iea857db7be3ef6656667b32011009d561b92a749
Reviewed-by: Liang Qi <liang.qi@qt.io>
2025-06-10 18:41:35 +02:00
Frédéric Lefebvre
cb97b31906 Unblacklist tst_qBackingStore::flush on Ubuntu Wayland
tst_qBackingStore::flush is no longer flaky on Ubuntu Wayland

Fixes: QTBUG-127920
Pick-to: 6.10
Change-Id: I16d91ceb8854f4aee8c569c792e8cb7977cb95ca
Reviewed-by: Liang Qi <liang.qi@qt.io>
2025-06-10 18:41:34 +02:00
David Boddie
d02ac6b3e0 doc: Fix links and auto-links
Changed function names to include parentheses so that they can be auto-
linked to getters and setters for bindable properties.

Pick-to: 6.9 6.10
Change-Id: I72a06a7def55348bd1295e559751a16c62c93a84
Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
2025-06-10 16:02:28 +00:00
Petri Virkkunen
2c6be851ae Android: Support multi-arg signal generation in androiddeployqt
This commit introduces support for generating Java code for
multi-argument QML signals.

Pre-existing code remains unchanged, and the new code is only executed
when the number of params in a signal is above 1.

Multi-arg signals are handled with a new generated interface type,
named after the signal, which has a default method that takes an
Object[] array and calls the user-implemented signal method with the
arguments cast to the desired types.

For example, a QML signal with the following signature:

signal manyTypeArgSignal(intValue: int, boolValue: bool,
doubleValue: double, stringValue: string)

Is generated into this Java code:

@FunctionalInterface
public interface manyTypeArgSignalListener {
    default void onSignalEmitted(Object[] args) {
        onSignalEmitted((Integer) args[0], (Boolean) args[1], (Double) args[2], (String) args[3]);
    }
    void onManyTypeArgSignal(Integer intValue, Boolean boolValue, Double doubleValue, String stringValue);
}
public int connectManyTypeArgSignalListener(manyTypeArgSignalListener signalListener) {
    return connectSignalListener("manyTypeArgSignal", new Class[]{ Integer.class, Boolean.class, Double.class, String.class }, signalListener);
}

Task-number: QTBUG-124489
Change-Id: I94e3e88e807017bcbeba16cf0e34263e28e5885f
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-10 18:09:25 +03:00
Mårten Nordheim
8d5db24c14 Http2: fix handling incoming frames on locally reset stream
After some of the RST stream handling was updated to more closely
follow the RFC it was accidentally not updating the handleHEADERS
function, and the handleDATA function was handled incorrectly leading
to a potential nullptr dereference.

Amends d17d260948e16549d82f1fdd4dec98d246b0622e.

Pick-to: 6.10 6.9
Change-Id: I345448efd7da92f4f74033b03a5c040b5db9d271
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
2025-06-10 17:09:25 +02:00
Mårten Nordheim
904aec2f37 Http2: Explicitly send RST_STREAM on cancelled request
It will do this when it gets deleted, but due to deleteLater just adding
an event to the event queue the events that are ahead in the queue may
use the stream in question. This would lead to a variant of
'stream not found', or specifically in the case of the bugreport, a
'HEADERS on non-existent stream' stream error.

Amends 6b4e11e63ead46dde5c1002c123ca964bb6aa342

Fixes: QTBUG-137427
Pick-to: 6.10 6.9
Change-Id: I5f2b2d5660866f1ad12aaafbb4e572b08ed5a6e4
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
2025-06-10 17:09:25 +02:00
Laszlo Agocs
97fe141f25 rhi: metal: Handle MSAA backing textures like other textures
...when it comes to dropping them in the swapchain's createOrResize().

There is no wait for command completion normally, unless the
code path that calls destroy() is hit. Therefore, handling msaaTex
like the textures behind any normal QRhiTexture is important. Use the
deferred release mechanism that QRhiTexture's destroy() would use on its
backing textures.

This avoids the occasional validation message when resizing Qt Quick
windows that have both multisampling and Metal validation enabled.

Task-number: QTBUG-112355
Pick-to: 6.10 6.9 6.8
Change-Id: I34549ce47e675d5869239b9330a166b80b40b30d
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
2025-06-10 16:22:28 +02:00
Bartlomiej Moskal
21616e1447 Android-Keyboard: Avoid manual keyboard visibility updates on API 30+
Keyboard visibility is now tracked via OnApplyWindowInsetsListener,
which provides reliable visibility state changes starting from API
level 30. In this setup, manually updating the visibility property
is unnecessary and may lead to inconsistencies.

Task-number: QTBUG-98984
Pick-to: 6.10 6.9 6.8
Change-Id: Ife80898e20d4038efeae3438fb89b593bdaa056a
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-10 15:28:31 +02:00
Bartlomiej Moskal
acbcf992ee Android-Keyboard: Remove redundant code in isKeyboardHidden()
The m_keyboardIsVisible variable already reflects the current
keyboard visibility state. This commit simplifies the
isKeyboardHidden() method by using it directly, removing
unnecessary logic.

Task-number: QTBUG-98984
Pick-to: 6.10 6.9 6.8
Change-Id: I6bba90e6fbfb1191415e7ee812517ca15ac1c937
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-10 15:28:31 +02:00
Bartlomiej Moskal
33cf82c13d Android-Keyboard: Improve keyboard visibility tracking
Starting with API level 30, keyboard visibility can be easly checked
using [0]WindowInsets.isVisible(int). This eliminates the need for
relying on callbacks to detect when the keyboard opens or closes.

This commit updates the logic to track keyboard visibility by
observing changes via OnApplyWindowInsetsListener and checking for
visibility changes using the new API.  From now on, for API 30 and
above, the internal keyboard visibility property should no longer be
updated manually.

[0] https://developer.android.com/reference/android/view/WindowInsets#isVisible(int)

Task-number: QTBUG-98984
Pick-to: 6.10 6.9 6.8
Change-Id: I40f3ccc4e652f1ae0c6c0ebd154d690d1a9d7ca8
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-10 15:28:31 +02:00
Bartlomiej Moskal
3823d99a68 Android-Keyboard: Use new show() / hide() methods for keyboard control
Starting with API level 30, Android introduced new
[0]WindowInsetsController.show(int) and [1]hide(int) methods for
controlling the keyboard visibility. This commit updates the code to use
these methods on devices running API 30 and above.

[0]https://developer.android.com/reference/android/view/WindowInsetsController#show(int)
[1]https://developer.android.com/reference/android/view/WindowInsetsController#hide(int)

Task-number: QTBUG-98984
Pick-to: 6.10 6.9 6.8
Change-Id: Icfcad3430cd269353572f66f72114238045f7756
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-10 15:28:31 +02:00
Fabian Kosmale
f1c0bd2e06 QStringConverter: Introduce finalize()
When doing a streaming conversion, it is not enough to check whether
there are errors. Once all input has been consumed, one must also check
whether there has been any data that was consumed, but not converted
yet. Provide finalize() to do the check, set an error if there was
incomplete data, and to optionally write replacement characters for it
to an output buffer.

[ChangeLog][QtCore][QStringDecoder] Added finalize(), a function to
force the converter to consider the sequence of inputs as complete,
flushing potential partial character sequences.

[ChangeLog][QtCore][QStringEncoder] Added finalize(), a function to
force the converter to consider the sequence of inputs as complete,
flushing potential partial character sequences or restoring state for
stateful text encodings.

Change-Id: I5fe26ae8e5d1477a86b365cc49c430b057876893
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2025-06-10 15:28:31 +02:00
David Boddie
479fb822bf Doc: Fix links in see also documentation
Pick-to: 6.9 6.10
Change-Id: Ie2b6964550ea166def27de311c2b948afba5bf04
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-10 15:28:31 +02:00
Laszlo Agocs
619ea08036 rhi: d3d: Change a warning to categorized logging
It is not that important to warn about the DXGI factory being stale
when a screen gets connected or disconnected. It is not an error,
and happens every time if a screen gets added or removed while the
application is running.

Pick-to: 6.10 6.9 6.8
Change-Id: I414668dc7aa0279f63fc79799ea53101065ab013
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
2025-06-10 10:23:48 +02:00
Marc Mutz
8f4ffb72f9 QEventLoop: fix potential UB in QBasicAtomic initialization
Until C++17 (inclusive), a default-constructed std::atomic object can,
officially, only be initialized with a call to std::atomic_init, for
which QBasicAtomic doesn't have API. It is even unclear whether
zero-initialization of static and thread-local objects will cause the
object to be initialized.

To fix, port from QBasicAtomic to QAtomic (which initializes to zero).

Task-number: QTBUG-137465
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: I31a95b36506c376ef0817ef3d61bd8ca02371585
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-09 20:36:40 +00:00
Marc Mutz
49db71bb19 QContiguousCache: drag the initialization of atomic ref behind ABI boundary
All callers of QContiguousCache<T>::allocateData() followed the call
with a storeRelaxed(1) to the ref member. So we can just drag that
into the function itself.

Next, it's UB to storeRelaxed() into a default-constructed std::atomic
(and, therefore, into a QBasicAtomicInt), because until C++17
(inclusive) you're supposed to use std::atomic_init to assign the
first (and only the first) value to a default-constructed
std::atomic. QBasicAtomic doesn't have API for that, so you can never
assign anything to a default-constructed QBasicAtomic.

To fix, use placement new to be able to create a QBasicAtomic directly
with an initial value (replacing QBasicAtomic with QAtomic wouldn't
help here, either, since a malloc doesn't run ctors).

A proper fix has to wait until we can depend on C++20's atomic_ref,
which decouples the underlying type from the atomic operations
performed on it, letting us depend on malloc's zero-initialization
of an int member properly initializing it even for a following atomic
operation on it.

Task-number: QTBUG-137465
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: Ic22d0766bcffb967a86c8ec28b63ee480aebd4a0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-09 20:36:21 +00:00
Christian Ehrlicher
4896448ffd SQL/ODBC: misc cleanup
Misc cleanup
 - merge qGetIntData and qGetBigIntData
 - remove unused braces
 - properly initialize values

Pick-to: 6.10
Change-Id: I0867dbbfa611087cd470b821f1f8d7ed74ed0aae
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-09 20:33:57 +02:00
Lars Schmertmann
ce101c2c3c Android: Unify behavior of Accessible.description with other platforms
On Windows, macOS and iOS both text and description are read out. On
Android the description is only used, when there is no name/text and
the result is used in AccessibilityNodeInfo::setContentDescription
while AccessibilityNodeInfo::setText is ignored. Using the content
description only is right, because Android will prioritize description
over text. So we need to do our own concatenation to use both.
Using ", " as separator looks like the right way, because Android use
it to separate the text from the role too. This was checked by enabling
TalkBack settings -> Advanced settings -> Developer settings -> Display
speech output.

Fixes: QTBUG-128494
Pick-to: 6.10
Change-Id: Ib25e993ffc8614b9c9ccdc37207f2c3c496ecb1f
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-09 17:58:21 +00:00
Marc Mutz
231069963d QLogging: fix potential UB in QBasicAtomic initialization
Until C++17 (inclusive), a default-constructed std::atomic object can,
officially, only be initialized with a call to std::atomic_init, for
which QBasicAtomic doesn't have API. It is even unclear whether
zero-initialization of static and thread-local objects will cause the
object to be initialized.

But initialization with = {} is definitely fishy, because that, by
definition, invokes the problematic default constructor. So make the
initialization explict with Q_BASIC_ATOMIC_INITIALIZER(0) instead.

Amends 4a154170773199f5b3376496c7b1a1c4530744e9.

Task-number: QTBUG-137465
Pick-to: 6.10
Change-Id: I177e05c09e20e0830af7bf1ccb650afc860ab9d5
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-09 15:18:23 +02:00
Marc Mutz
0ba05ca500 [docs] IPC: don't mention undoc'ed QBasicAtomic
Use Q(non-Basic)Atomic instead.

Amends 7a370838177e581c8a9342808ba86e081951a41c.

Task-number: QTBUG-55421
Pick-to: 6.10 6.9 6.8
Change-Id: Ia8cc059a94acbee667c19b443ed2e2f487b56806
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-09 14:55:09 +02:00
Christian Ehrlicher
bac0226ac3 SQLite: Update SQLite to v3.50.1
[ChangeLog][Third-Party Code] Updated SQLite to v3.50.1

Pick-to: 5.15 6.5 6.8 6.9 6.9.1 6.10
Change-Id: I238e95f3e028731aa871e279f21503d39acdbd2d
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-09 12:41:19 +02:00
Christian Ehrlicher
ccf81822cf SQL/DB2 & ODBC: avoid some code duplication
Avoid some code duplication by using a template parameter for
qMakeError() and qSqlWarning().

Pick-to: 6.10
Change-Id: I698ab063fce6c7be1cb3debdb9e83978eac10409
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-09 12:41:19 +02:00
Assam Boudjelthia
2b4effeec8 Revert "Android: qtbase/src/android/. ./QtAndroidBinder.java security sensitive"
This reverts commit 7796ad3face5246ad62a959b61fdd3a92cea2803.

Reason for revert: the code is not doing critical data parsing.

Pick-to: 6.10 6.9 6.8
Change-Id: Ic07b98c3866b65d0575e29abe97ca6b284c981bb
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-09 06:47:48 +00:00
Dheerendra Purohit
b52c0dafd8 Doc: Modernize QSharedDataPointer Example for Rule of Compliance
Replaced the manually defined copy constructor with = default to
improve clarity and maintainability.Added a default copy assignment
operator to ensure consistency,as copy constructor and copy
assignment should be defined as a pair.Also included defaulted move
constructor and move assignment operator in accordance with the rule
of 6,ensuring the example is modern,complete,and suitable for
educational purposes.

Fixes: QTBUG-111392
Change-Id: Ia7cfccfc46182d8d9102868fc93dc0ebd9649a32
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-08 16:56:07 +00:00
Dheerendra Purohit
045eb2179c Doc: Improve opening description of Qt's Paint System
Clarified the Paint System introduction to better convey
its purpose and highlight its flexibility across different surfaces.

Fixes: QTBUG-136487
Change-Id: Ib636087b9bae4d08541566145c4a0943dccb5432
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-08 22:25:47 +05:30
Christian Ehrlicher
d2cd406b34 SQL/ODBC: fix escaping the username/password
The escaping for '{' was wrong in the previous commit.

Amends 38277a88f1dd69de6e031bc8313c8d5beadf6bd0

Pick-to: 6.8 6.9 6.10
Task-number: QTBUG-122642
Change-Id: Ia363c76b27e527114769b4a923418cddad5586f1
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-08 07:36:11 +00:00
Allan Sandfeld Jensen
51d5b9e258 SSE2 optimize QColorSpace CLUT
Optimize clamping setup for CLUT lookup.

Pick-to: 6.10 6.9
Change-Id: I35d65fc00efcb96a54518466e1e1de169571b862
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-07 17:15:43 +02:00
Marc Mutz
a97ac8507e tst_QMetaObject: add a reproducer for overly eager QVector/QList replacement
The kludge that was added to argumentTypesFromString() for Qt 6 to
support merging QVector into QList—specifically, the replacement of
QVector< with QList<—was unfortunately not removed before the Qt 6.0
release. As a kludge, it has unintended consequences, as Thiago
pointed out in a comment on a related patch.

This change adds a reproducer that demonstrates cases where the
kludge causes correct code to fail incorrectly. We need this test to
ensure that we do not silently change behavior when deprecating and
eventually removing the kludge.

Adapt the MyQList normalization test, which was carefully written to
avoid hitting the kludge, to use template arguments. This will allow
it to trigger the buggy code path and avoid confusing the reader with
the mention of a non-template MyQList, given that MyQList is now a
template.

Reported-by: Thiago Macieira <thiago.macieira@intel.com>
Pick-to: 6.10 6.9 6.8 6.5
Task-number: QTBUG-135572
Change-Id: I91d769d494489fe63dbbb67f849b78fc7aa39ec6
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2025-06-06 22:16:36 +02:00
Michael Weghorn
99ad6a51a5 a11y atspi: Warn on unimplemented Application iface method
As already happens in the implementation for the
handling of all other AT-SPI interfaces
(called from AtSpiAdaptor::handleMessage), also
warn when an unimplemented/unknown method gets called
for the Application interface: increase log level
to warn and align message with the one used for
the other interfaces, so this can be more easily
identified.

Task-number: QTBUG-137344
Pick-to: 6.10
Change-Id: I33d3811fd34ca0f9f4b1ab9d809f505c12c6517c
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-06 18:04:35 +00:00
Mårten Nordheim
1a870f4bf2 tst_QHttp2Connection: fix typo of tested variable
Accidentally used clientStream instead of clientStream2.
Test still passes though.

Pick-to: 6.10 6.9
Change-Id: I118f1e429faa0367f0b4d02c74a221027ecb2b4d
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2025-06-06 19:06:04 +02:00
Marc Mutz
ab7c1386d5 QTestResult: remove unused QTestResultPrivate forward declaration
This class was never pimpled in Qt 5.

Amends the start of the public history.

Pick-to: 6.10 6.9 6.8 6.5
Change-Id: I5761bb0e8401dd654a885b5edcf821be9e4c2694
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2025-06-06 19:06:03 +02:00
Tor Arne Vestbø
965b799c3f Decouple QApplication from QColormap
Initialize the shared QColormapPrivate on first call to
QColormap::instance, in a thread safe manner for good measure,
and clean it up on app exit if needed.

The cleanup now also accounts for the possibility of QColormap
instances outliving the cleanup. We still reset to a new QColormap
on next use, following the existing behavior.

Change-Id: Ia16a84994b3ee05f9431ba24dd9126f2dc271b61
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
2025-06-06 18:10:07 +02:00
Laszlo Agocs
a589ef5cff Revert "rhi: gl: Maintain Qt 5 compat wrt disk cache behavior"
This reverts commit 38279dea558b06cef6c1d345962df3063fd12c5b.

Causes endless complaints about old GPUs (e.g. PowerVR) on Android and
embedded Linux.

Qt 6.8.2 restored the Qt 5 behavior of writing program binaries to files
every time a GL shader program is linked. That is in addition to the Qt
6 pipeline cache, which writes out all collected program binaries once
in one go, when the QQuickWindow is closing.

The Qt 6 abstractions are modeled after the VkPipelineCache-style
system, meaning no way to query and write out individual
program/pipleline binaries, just an ever-growing blob containing
everything encountered so far, which we then want to do rarely due to
the potential cost and the size of the blob, so e.g. when the Quick
scene is shutting down.

Before 6.8.2, Qt 6 did the logical thing and disabled the Qt 5 legacy GL
disk cache code path, since we do not need two caches concurrently. From
6.8.2 on, when running with OpenGL, there are now two parallel disk
caches. Because the Qt 5 style one works even if the application is
killed. Which is unexpectedly common on mobile/embedded.

Pick-to: 6.10 6.9 6.8
Fixes: QTBUG-133904
Fixes: QTBUG-134245
Fixes: QTBUG-134089
Fixes: QTBUG-135411
Fixes: QTBUG-134496
Fixes: QTBUG-135810
Change-Id: Icbd880898941195fcbc2da544e1599867c6d5f51
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
2025-06-06 14:52:39 +00:00
Eskil Abrahamsen Blomfeldt
fb89d498a9 Add support for font features and variable axes to QTextCharFormat
These can be set on the font directly, but had not been added to
QTextCharFormat, so there would be no way to override them by
formatting in a rich text document.

Fixes: QTBUG-134060
Change-Id: I4494e24cb9b99d84fb376ba895e2461fc3cd054b
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
2025-06-06 16:27:54 +02:00
Alexandru Croitor
9b9a2398f3 CMake: Make QT_CMAKE_EXPORT_NAMESPACE available in the top-level scope
Previously QT_CMAKE_EXPORT_NAMESPACE was set by calling
find_package(QtBuildInternals) at repo dir scope, even in a top-level
build.

Starting with ddcafa0a51c65d86f6b5481f06fce5faeb75920d in
qtdeclarative, we now have a deferred call of
_qt_internal_write_deferred_qmlls_build_ini_file in the
CMAKE_BINARY_DIR scope, which lacks the QT_CMAKE_EXPORT_NAMESPACE
variable.
This caused errors in a top-level standalone tests build:
  Error evaluating generator expression $
    No target "::qtpaths"
    CMakeLists.txt:DEFERRED

To avoid the error we now set QT_CMAKE_EXPORT_NAMESPACE in the
top level scope.

To avoid duplicating the code into the QtBaseTopLevelHelpers,
we extract the qt_internal_top_level_setup_cmake_and_export_namespace
function into a new QtBuildInternalsHelpers.cmake file, which is
included by both QtBaseTopLevelHelpers.cmake and
QtBuildInternalsConfig.cmake.

We also copy and install that file.

This has less side effects than trying to call
find_package(QtBuildInternals) in the top-level scope.

Pick-to: 6.10
Change-Id: I8e54e21d3f07ee86860cad49d6e43e0fdefbcee3
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2025-06-06 16:27:54 +02:00
Alexandru Croitor
587649deb7 CMake: Make qt-cmake-standalone-tests work from prefix build dir
We didn't copy the standalone test template files into the build dir
when configuring a prefix build.

We also need to copy the mkspecs.

Pick-to: 6.8 6.9 6.10
Change-Id: I517165b2b8db84b0766935e3d535a7a1ef2b6ad9
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2025-06-06 16:27:54 +02:00
David Edmundson
1ede87a735 wayland: Add unit test for sibling client grabbing popups being created
Task-number: QTBUG-119110
Change-Id: Ie31da8073d0107f6515ce2e0152cb2bbc97c8582
Reviewed-by: David Redondo <qt@david-redondo.de>
2025-06-06 15:13:15 +03:00
Nic Zonta
25fdc044f5 make all convenience functions in QFileDialog open modal dialogs
most convenience functions in qfiledialog.cpp (e.g. getSaveFileUrl, getOpenFileUrl) open modal dialogs, with the exception of getOpenFileContent and saveFileContent. This makes every function consistently open modal dialogs

Fixes: QTBUG-137329
Pick-to: 6.10 6.9
Change-Id: I48952144ed15596b9acba3230c63cece613fb045
Reviewed-by: David Faure <david.faure@kdab.com>
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-06 13:20:27 +02:00
Axel Spoerl
839d569dc2 QCommandLinkButton: Don't reset icon on change to QStyleSheetStyle
d4c518b210ad56cb51c17e6e1b4a81b0deb7253c has implemented a reset of the
icon on a style change.

This has caused a regression, because it overrode an icon set by a
style sheet.

Do not reset the icon if the new style is a QStyleSheetStyle.

Amdends d4c518b210ad56cb51c17e6e1b4a81b0deb7253c.

Fixes: QTBUG-137011
Pick-to: 6.10 6.9 6.8
Change-Id: Ib77faa03c867b2660a45bdc3ab94e7d739eed4f8
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
2025-06-06 06:26:13 +02:00
Santhosh Kumar
2e0dc22bdb Fix regression in drawing table cell border when border-collapse enabled
The patch 732962d604e7469f9a9f02fe0cd3d1fd04caddb8 enables drawing a
border around cells within the table when set through CSS styling. But
this caused a regression when border-collapse is enabled without setting
the cell border. This patch enables drawing borders for table cells
when either of those conditions is satisfied.

Fixes: QTBUG-136590
Pick-to: 6.10 6.9 6.8
Change-Id: Ibf43c404439c9fee1cfd2b40789150edb76c6971
Reviewed-by: Nils Jeisecke <nils.jeisecke@saltation.com>
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
2025-06-05 23:58:00 +02:00
Friedemann Kleint
38ce4ad2f8 QColorDialog: Stop color picking when application is deactivated
Fixes: QTBUG-134143
Pick-to: 6.10
Change-Id: Ibfeff4f861ac5c63f4bdd85db40b25eee51c4d31
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-05 23:58:00 +02:00
Thiago Macieira
4e57583f33 Wayland tests: use initTestCase() instead of init() to set env
Once is fine. We don't need to set the environment before each test
function.

Pick-to: 6.10
Change-Id: Id27938950c196d6d3397fffd2fbf1a66fe7504f9
Reviewed-by: Liang Qi <liang.qi@qt.io>
Reviewed-by: David Redondo <qt@david-redondo.de>
2025-06-05 17:15:28 -03:00
Marc Mutz
687fb92440 tst_QMetaObject: refactor indexOfMethod() test
Removes duplication in preparation of adding more tests.

Pick-to: 6.10 6.9 6.8 6.5
Task-number: QTBUG-135572
Change-Id: I9ebfc40e24256d2d92af3f593f905d97b273e187
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-05 21:26:02 +02:00
Konsta Alajärvi
fd52f868ac CRA: Android: Mark QtLoader.java as security critical
Mark QtLoader as critical with "execute-external-code" due to
library loading in:
-loadQtLibraries()
-loadLibraryHelper()
-loadMainLibrary()
-loadLibraries()
QtLoader also parses library paths in:
-parseNativeLibrariesDir()

Fixes: QTBUG-136726
Task-number: QTBUG-135178
Pick-to: 6.10 6.9 6.8
Change-Id: I58a11fd44ea8159b8399ac7a27fd50eaab8185a6
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-05 14:42:45 +00:00
Konsta Alajärvi
0a4c11633b CRA: Android: Mark qtandroidplatformfiledialoghelper.cpp as security critical
Mark qtandroidplatformfiledialoghelper.cpp as security critical with
"data-parsing" as a reason.

Data parsing in nameFilterExtensions() using QRegularExpression.

Fixes: QTBUG-136820
Task-number: QTBUG-135178
Pick-to: 6.10 6.9 6.8
Change-Id: I378698327a36496317782d6dc0acd092c19de7ca
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-05 14:42:45 +00:00
Ivan Solovev
5b03d9f68b QProperty: fix comparison with comparable type
After e115c60b6da0db7013229e678720f36632c2e614, the comparison with
a type which is different from QProperty::value_type, but is comparable
to it, could result in ambiguous operator==() overloads.

Fix it by adding a new overload for operator==(QProperty<T>, U), where
operator==(T, U) exists.

Explicitly delete operator==(QProperty<T>, QProperty<U>) for such
types T and U, because the implicit conversion might be unwanted here.
The user should manually call .value() at least on one property, if
they want the comparison. Note that GCC does not allow to do it,
treating `= delete` as declaration and complaining about a default
template argument in friend template declaration. So, do it only for
Clang and MSVC.

Amends e115c60b6da0db7013229e678720f36632c2e614.

Task-number: QTBUG-134921
Pick-to: 6.10
Change-Id: Id3ed48738cc462b5b0820fa3b25d80d4d4414548
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2025-06-05 16:42:43 +02:00
Eskil Abrahamsen Blomfeldt
9a950b1ecb Add an envvar restoring Qt 5 behavior for vertical font metrics
As a last resort for users who have existing Qt 5 applications and
see differences in line metrics when porting to Qt 6, we introduce
an environment variable which lets them restore the old behavior
as a last resort.

This is primarily meant as a porting tool, since we do have other
tools, such as QFont::PreferTypoLineMetrics to work around issues
with fonts that by mistake do not explicitly set the
use-typo-metrics flag even if these are valid.

Pick-to: 6.8 6.9 6.10
Fixes: QTBUG-134602
Change-Id: Id1d7829888d55247d2f07ee0a49b91ff34f26889
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
2025-06-05 13:58:49 +00:00
Tor Arne Vestbø
c604f2031a iOS: Always update screen properties on status bar orientation change
If we move from landscape to inverse landscape orientation, the window
will not lay out, so we won't hit viewWillLayoutSubviews, but we still
need to reflect the new orientation of the screen.

Task-number: QTBUG-137249
Pick-to: 6.10 6.9 6.8
Change-Id: I9655052772990ca524c5b94e25b2c58cc058ff67
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
2025-06-05 14:37:54 +02:00
Tor Arne Vestbø
a8dab6eb65 iOS: Report inverted screen orientations via windowScene orientation
In bc014d5fc705e95bb34b7729b2c3bb5f9539d777 we stopped using the device
orientation as source for the QScreen orientation, as the former reports
the orientation independently of any locked orientation, while QScreen
is supposed to reflect the logical window-manager orientation.

However in doing that we lost the inverse orientations, which can be
useful in some cases.

We now use UIWindowScene.interfaceOrientation as input, and fall back
to the primary orientation only if we can't resolve the window scene's
orientation.

Interestingly, for visionOS, UIWindowScene.interfaceOrientation reports
portrait orientation, which should be investigated further, but for now
we trust what the system gives us.

[ChangeLog][iOS] QScreen::orientation() now reflects the inverse
portrait and landscape orientations, as long as system allows
rotating the UI to those orientations.

Fixes: QTBUG-137249
Pick-to: 6.10 6.9 6.8
Change-Id: I8d20f05e72abcec446fd39342c8632960337943a
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Reviewed-by: Doris Verria <doris.verria@qt.io>
2025-06-05 14:37:54 +02:00
Piotr Wiercinski
5618710d63 fusion: Improve visibility of Checkbox in dark mode
Fixes: QTBUG-136960
Pick-to: 6.8 6.9 6.10
Change-Id: I606fd034ba83011624ff9a38a8c973659c241c26
Reviewed-by: Matthias Rauter <matthias.rauter@qt.io>
2025-06-05 12:37:54 +00:00
Volker Hilsheimer
9b9511c354 QTreeView: Delay reset of accessibility when laying out items lazily
QTreeViewPrivate::doItemsLayout might get triggered when accessibility
elements query properties of items, such as the state or geometry. If we
reset the model immediately, then the items that are currently querying
might get destroyed, resulting in crashes.

Instead, use a queued invocation to reset the model only once control
returned to the event queue. This leaves current elements intact.

Amends 6a4afebc5ce8db69a6c9fb398cada31e6bad5e3c and follow-up commit
a86321cb665b1af03b245b3b0fe0b57faa4a678f.

Pick-to: 6.10 6.9 6.8
Fixes: QTBUG-136074
Task-number: QTBUG-133855
Change-Id: I2c6acda3b31105447393a6efcb85ddf737161fe8
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2025-06-05 08:41:39 +02:00
Oliver Eftevaag
4720b592d7 Windowsvista style: Fix hover widget attribute when using contrast theme
The windows vista style sets the widget attribute for certain widgets to
have the Qt::WA_Hover attribute, which makes the widget eligible for
receiving hover events from QApplication::notify(QObject*, QEvent*).

However, if the windows system had enabled a high contrast theme,
the QWindowsVistaStyle::polish(QWidget*) function would return early,
without making any widgets eligible for receiving hover events.

Fix the issue by enabling hover events for select controls first,
before potentially returning early due to using a contrast theme.

Pick-to: 6.10 6.9 6.8
Change-Id: I5562f46385c6f1b498bc659c65e501f9e9376db3
Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
2025-06-05 02:47:23 +02:00
Jani Heikkinen
7f1e6f8079 Bump version to 6.11.0
Change-Id: I14ec3a08bf704535b9b10e33ec8ee0f9415f2d7c
Reviewed-by: Qt Submodule Update Bot <qt_submodule_update_bot@qt-project.org>
2025-06-05 00:07:53 +01:00
Marc Mutz
5c563a98a5 tst_QMetaObject: add more QList/QVector tests
Check that a slot that was declared using QVector ends up stored as,
and can be called with, QList (and QVector).

Also check that the various indexOf*() methods do the QVector</QList<
normalization, even though they're documented to require normalized
input. A subsequent patch will deprecate that behavior, so make sure
we don't break it as we change it.

Amends 1fa31be7ce3a6899f1c1597311d7593648ecd1d8.

Pick-to: 6.10 6.9 6.8 6.5
Task-number: QTBUG-135572
Change-Id: Id28bf3c4163099f07213bfbf7d296b4fd76b71a5
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2025-06-04 23:22:45 +02:00
Marc Mutz
e51675b891 QWaylandGLContext: init fields in default ctor
Coverity complains that the =default'ed default ctor leaves
m_decorationsContext and m_api uninitialized, which is true.

To fix, use NSDMI for the former.

For m_api, initialize it in the default constructor's member
initializer list, because the default value is closely related to the
other constructor's choice of value¹, and so should be more proximal
to the other constructor's initialization of m_api (which is
dynamic). Using NSDMI for m_api would also remove tooling's ability to
detect faults in the other constructor.

¹ I had to track into QSurfaceFormat to verify which of the possible
  values is the correct one (= the one that gets mapped from
  DefaultSurfaceFormat by the switch in the other QWaylandGLContext
  ctor).

Amends 7c0a96785fee4fea8ef1452166b1dde88957445c.

Pick-to: 6.10
Task-number: QTBUG-110758
Coverity-Id: 481857
Change-Id: I837d0a3a63bd6e2948ef1c9757e250bfba7dd957
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
2025-06-04 23:22:45 +02:00
Bartlomiej Moskal
a4850d0e0f Android: Avoid restarting InputMethodManager during IME batch edits
beginBatchEdit() means the start of a batch of related input operations
from the Input Method Editor. We should not restart input until
endBatchEdit() is called. Restarting it before may cause issue with
inactive InputConnection.

This commit fixes an issue where calling
InputMethodManager.restartInput() during a batch edit (e.g., between
beginBatchEdit and endBatchEdit).

Pick-to: 6.10 6.9 6.8
Fixes: QTBUG-136229
Change-Id: I408e6dfd8a91f2d0f1dd8c18dc0dcc2d13cc3e38
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-04 19:24:38 +00:00
Alexandru Croitor
86d843be47 CMake: Improve atmoicfptr error message on failure
Remove the obsolete reference to the atomicfptr directory in the error
message.

With the improved error reporting of the parent change, the build
system will now dump the output of the atomicfptr test in case of
failure, which should provide more information about what goes wrong.

Pick-to: 6.8 6.9 6.10
Fixes: QTBUG-133687
Change-Id: Iaffc992f90c06425113cc2ef721d87d31e97bbc6
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-04 19:08:14 +02:00
Alexandru Croitor
5220685a11 CMake: Fix capturing of x86intrin compile test output
TEST_x86intrin_OUTPUT is not set anymore since we lazily evaluate
compile tests after 605913f9d7a60461939c1a8fb8dac05054cade2d .

Use the new qt_configure_add_report_entry
COMPILE_TESTS_TO_SHOW_ON_ERROR option to dump the test values in case
of an error.

Amends 9e9099865a0881ac5bb6035237e0a0c86962c45f

Pick-to: 6.8 6.9 6.10
Task-number: QTBUG-122596
Change-Id: I48d1c57145ad5d9418631025927581c4eb5ec93c
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-04 19:08:14 +02:00
Alexandru Croitor
a20a40095a CMake: Improve compile test error reporting in configure summary
Starting with 605913f9d7a60461939c1a8fb8dac05054cade2d we run
configure.cmake compile tests lazily during feature evaluation.

This means that qt_config_compile_test() calls will no longer set
TEST_foo_OUTPUT variables in the scope of configure.cmake files and
thus the build output of compile tests is no longer available for
configure summary error reports.

Instead of setting the output variable in the caller scope, save the
output in a global property.

Then, when we add error reports that mention compile tests either in
CONDITION or in a newly introduced COMPILE_TESTS_TO_SHOW_ON_ERROR
option, dump those outputs in the error report.

We continue to set the output in the parent scope, in case if
qt_run_config_compile_test is called manually.

Amends 3334a77ecfb792fba0144e99887f11cd0fa2506d
Amends 605913f9d7a60461939c1a8fb8dac05054cade2d

Pick-to: 6.8 6.9 6.10
Fixes: QTBUG-137198
Change-Id: Idc0470556a053123286983c44063e17b7eb9949d
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2025-06-04 19:08:13 +02:00
Alexandru Croitor
7542aaea60 CMake: Improve error reporting for failed linker no undefined flag
Capture the output of the check_cxx_source_compiles calls in
qt_internal_add_link_flags_no_undefined like we do for
qt_config_compile_test.

Amends 3334a77ecfb792fba0144e99887f11cd0fa2506d

Pick-to: 6.8 6.9 6.10
Task-number: QTBUG-137198
Change-Id: Ic7dd4eae0ac1af0f8293f2ce285d2987e4e26249
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2025-06-04 19:08:13 +02:00
Magdalena Stojek
e94a951862 Mark qtbase/src/corelib/plugin files as security-critical
- quuid.cpp parses the string representation of a UUID
- qfactoryloader.cpp parses metadata from loaded plugin
- qcoffpeparser.cpp, qelfparser_p.cpp and qmachparser.cpp as they are
  binary object files parsers
- qlibrary.cpp, qlibrary_unix.cpp, qlibrary_win.cpp, qpluginloader.cpp
  are responsible for finding and loading plugins from untrusted
  locations.

Fixes: QTBUG-135193
Change-Id: Ibbcefeab80e7455225ade620bdba45dbc592c581
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Matthias Rauter <matthias.rauter@qt.io>
2025-06-04 19:08:13 +02:00
Edward Welbourne
a34195508a Fix WASM build for the recent qtestcrashhandler changes
Amends commit fddb6fceaa28df2a24f7bdd216792985bf8141d1 - the code in
qtestcrashhandler_unix.cpp is written to compile for WASM, and some
declarations in the _p.h aren't excluded on WASM, so the exclusion of
the .cpp when WASM lacks threads lead to linker errors.

Pick-to: 6.10
Change-Id: Idb941643302ed5a4c084d0fd2b4dfc07a44122e3
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Piotr Wierciński <piotr.wiercinski@qt.io>
2025-06-04 16:30:32 +02:00
Edward Welbourne
9be6e51a50 Update QJsonValue(qint64) docs to reflect full precision
Amends commit 35adb74ddd915831789f0175423660f8e898942e (from 5.15) to
reflect the improved precision of 64-bit int when stored as a JSON
value.

Task-number: QTBUG-28560
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: I07915bc190dd7696e58356143e8857f91e888c67
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-04 16:30:32 +02:00
Edward Welbourne
65365e9bb7 Fix typo in qlocale_tools_p.h unicodeForDigit() comment
Got the name of the numeric tokenizer helper wrong, making the
cross-reference comment misleading.

Pick-to: 6.10 6.9 6.8
Change-Id: I88b850975aa77b6175e8d95afa2960e589c42d8d
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-04 16:30:31 +02:00
Tor Arne Vestbø
4d4843df42 Document QT_WARN_DEPRECATED_UP_TO
The default value is 0x070000, via qtdeprecationdefinitions.h

Pick-to: 6.10 6.9 6.8
Change-Id: I78586231e123321a11d41ec8c1324ab928e5fdc8
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2025-06-04 14:07:07 +02:00
Eskil Abrahamsen Blomfeldt
2d82e845cc Revert "dwrite: Support additional font names for system fonts"
This reverts commit 6854ea63365ae419a04a470eb17e5f7662f00931.

This caused errors in a Qt Declarative test. It's possible the test
is depending on assumptions that are not strictly true (such as
QFontDatabase::styles() never returning an empty list), but it's
a surprising side effect and should be investigated. So we revert
until it can be addressed.

Pick-to: 6.10 6.9 6.8
Reopens: QTBUG-135817
Fixes: QTBUG-137398
Change-Id: I2e673b316f3d5fc14342b36095f9983ad55ea796
Reviewed-by: Jani Heikkinen <jani.heikkinen@qt.io>
2025-06-04 14:07:07 +02:00
Eirik Aavitsland
472306523a Doc: Explicitly advise adding svg, if any, before other files to QIcon
Adding in the wrong order yields a QIcon that does not provide the
expected or desired behavior.

Fixes: QTBUG-135652
Pick-to: 6.10 6.9 6.8
Change-Id: Ie1f6e50ee82ddaae8857b076c383ede20ab872df
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
2025-06-04 09:18:44 +02:00
Li Changze
5ee2737d91 qdbus: add call GetConnectionCredentials interface
[ChangeLog][QtDBus][QDBusConnectionInterface] Added method serviceCredentials().
See <https://dbus.freedesktop.org/doc/dbus-specification.html>
section: 'Method: org.freedesktop.DBus.GetConnectionCredentials' for more information.

Pick-to: 6.10
Change-Id: If37687a35278fde8b0afc33eb19f9fa6b8dbe200
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-04 12:58:07 +08:00
Nils Petter Skålerud
cb09be1512 QScreen, iOS: Make grabWindow() use UIGraphicsImageRenderer
Currently the QIOSScreen::grabWindow implementaton relies on
UIGraphicsBeginImageContextWithOptions to do a screenshot. This API
is deprecated and produces a few warnings logs that we can't silence
even when we handle the errors. The current approach also has a memory
leak when taking screenshots in rapid succession (i.e 60 FPS).

This patch modifies grabWindow() to use UIGraphicsImageRenderer, which
replaces the deprecated API. This no longer produces warning logs when
errors are handled. This API can be used in the future to let us take
HDR screenshots once Qt has support for this. This patch solves the
mentioned memory leak.

Pick-to: 6.10 6.9 6.8
Change-Id: Ifbc8503482886246ce9611d0b7a19462fc830ecd
Reviewed-by: Tim Blechmann <tim.blechmann@qt.io>
2025-06-04 02:37:47 +02:00
Ahmad Samir
e67c4c986f QLogging: use std::unique_ptr instead of QScopedPointer
Task-number: QTBUG-132213
Change-Id: I6c5e72108e4ed79e645b8dbd9b2103e13e4849d0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
2025-06-04 02:13:06 +03:00
David Edmundson
a639807a8f wayland: In test lock thread when setting env variables
putenv/setenv are not thread safe. The Qt wrappers lock a mutex
but this only works if all users use it.

Fixes: QTBUG-136450
Pick-to: 6.10
Change-Id: I9a46b5be607c84436864afcf7eb063275e065738
Reviewed-by: Liang Qi <liang.qi@qt.io>
2025-06-04 00:23:23 +03:00
Liang Qi
c72ba39e50 wayland: use qgenericunixtheme_p.h instead of qgenericunixthemes_p.h
This amends 54651971a260d65c987d03973168f7d274ed8930 .

Pick-to: 6.10
Change-Id: Iadeff9a59288934233bbf0f10d26510b5626b4f7
Reviewed-by: David Redondo <qt@david-redondo.de>
2025-06-03 23:23:22 +02:00
Christian Ehrlicher
a66dbb19e6 SQL/MySQL: add option MYSQL_OPT_SSL_VERIFY_SERVER_CERT
Add option MYSQL_OPT_SSL_VERIFY_SERVER_CERT to disable ssl for MySQL
5.7.x and MariaDB. This is needed as MariaDB does not support the
SSL_MODE options but defaults to ssl nowadays.
Also enhance the documentation for MYSQL_OPT_TLS_VERSION and
MYSQL_OPT_SSL_MODE by providing the needed MySQL/MariaDB versions for
those options.

Pick-to: 6.10 6.9 6.8
Fixes: QTBUG-136550
Change-Id: If570cf8e92d0df7c9e2c4d0e009857eaf33f4f2d
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-03 19:39:50 +00:00
Christian Ehrlicher
cc6d78325b SQLite: Update SQLite to v3.50.0
[ChangeLog][Third-Party Code] Updated SQLite to v3.50.0

Pick-to: 5.15 6.5 6.8 6.9 6.10
Change-Id: I20eef45bbb93ae3a50cdd7ffecaa53eec18823f7
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-03 19:39:50 +00:00
Christian Ehrlicher
15c2ec5344 QStyleSheetStyle: avoid creating QString
Don't create a QString when comparing the strings from
knownPseudoElements - a QLatin1StringView is enough.

Pick-to: 6.10 6.9
Change-Id: I69e207bac0fb3d3df12ae9d4bebc9cd30cde30de
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-03 21:39:50 +02:00
Tor Arne Vestbø
b02da5f04a Remove docs claiming QColormap is involved in mapping colors to display
Change-Id: Iebf949d91379fff903b229c631b97a3c8a9ad03a
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-03 21:07:34 +02:00
Tor Arne Vestbø
ecad0ca351 Decouple QColor from QColormap
They don't need to be BFFs.

Change-Id: I7017347b348bd8e63dfb5f664c95597f84190e7c
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-03 21:07:34 +02:00
Tor Arne Vestbø
c7625d14df Decouple QApplication::isEffectEnabled from QColormap
Change-Id: I26468cc528d2c516492db11ca4109e6be63c1b5a
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
2025-06-03 21:07:34 +02:00
Toni Saario
3056da6711 Coin: Sign cross-compiled Windows binaries
Pick-to: 6.8 6.9 6.10
Task-number: QTBUG-137228
Change-Id: Idda7bfd97ac74a87987dcd4c31440b0c2f193c14
Reviewed-by: Simo Fält <simo.falt@qt.io>
2025-06-03 19:07:34 +00:00
Axel Spoerl
36ebec92e8 QCocoaMenu: Explicitly remove NSMenu from supermenu on destruction
The d'tor of QCocoaMenu calls dismiss() to remove the current menu.
dismiss() calls cancelTracking, which doesn't always remove the
menu from its parent.

Remove the menu from its parent in addition.

Fixes: QTBUG-135634
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: Ic8e9b4172c3b2035b7e9ad1b576725923987abf2
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2025-06-03 18:56:07 +00:00
Michael Weghorn
77f02471ed a11y atspi: Create local variable on stack
There is no reason to allocate the OrgA11yAtspiSocketInterface
object only used inside AtSpiAdaptor::registerApplication on
the heap.

Pick-to: 6.10
Change-Id: I2985acb5bd3e2f89c60de2b4ffa77b2a78cb4eff
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-03 18:56:07 +00:00
Lars Schmertmann
36b5854af5 Android: Bump androix dependency to 1.16.0
The Android target API level was bumped to 35 in
997a1fae98d35cd0d4d16f37ab68afe2729ff551 so we can
bumb the version of the androidx dependency too.

Pick-to: 6.10 6.9 6.8
Change-Id: I30d561cc0b74645c939e7d3dd595926b6013caf9
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-03 19:55:47 +02:00
Marc Mutz
c485c07c6d Explain what "junk" means in tst_QDataStream::status_QBitArray_data()
It means the data contains bits outside the [0, size()[ range.

Found while debugging why these data rows fail in the 5.15 cherry-pick
of 78f8dfc5427457783ceef7d85885cddbec035ebe.

Amends the start of the public history.

Pick-to: 6.10 6.9 6.8 6.5 5.15
Change-Id: Ic21d15da25944d4897357dd27e2986d448b5ee60
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2025-06-03 17:13:55 +00:00
Thiago Macieira
ae973dc2de QFileSystemEngine::tempPath: simplify handling of fallbacks
If the environment variable is empty, we have a couple of fallbacks, one
for Apple Darwin systems and one for everyone else. A non-absolute path
in the environment or the Apple API makes no sense, but this code
retains this defensive measure for them; for _PATH_TMP from <paths.h>,
we assume it is absolute.

Pick-to: 6.10 6.9
Change-Id: I3e486f73276a3ae288d1fffdbfe20a74271f73f2
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2025-06-03 11:54:38 +00:00
Thiago Macieira
7bd7df5aa1 QFileSystemEngine::tempPath: bypass QDir and go straight to QFSEngine
Temporary paths coming from the environment must be real filesystem
things, never a Qt file engine, so we don't need to create QDir with its
QDirPrivate, in order to call QFileSystemEngine.

The replacing of canonicalPath() with QFSE::absoluteName() is fine
because canonicalizing *after* cleanPath() is the wrong thing. For
example, if you had:

  $ ln -s $HOME/tmp /tmp/symlink
  $ TMPDIR=/tmp/symlink/..
then
  cleanPath($TMPDIR) = /tmp
  absolute($TMPDIR) = /tmp    # QFSE::absoluteName calls cleanPath
  canonical($TMPDIR) = $HOME
  canonical(cleanPath($TMPDIR)) = /tmp

The lack of canonicalization now only affects when the final path is a
symlink. Doing so bought us little security if it is a symlink and it
could change, because the result is not cached and could change from
call to call. That changing is probably worse than any attack, because
you could end up with

  QDir::tempPath() != QDir::tempPath()

[ChangeLog][QtCore][QDir] tempPath() may now return a non-canonical
path. This means going up from it (cdUp()) may result in different paths
from string manipulation (adding "/..").

Pick-to: 6.10 6.9
Change-Id: Iddf6f46edf6f3b6c3222fffd1e1e5479f0be92a9
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
2025-06-03 11:54:37 +00:00
Jani Heikkinen
05f8abc61d Revert "Android: consider DecorView insets at app startup"
This reverts commit e96a4b84e136d065054600c07bf5fae17f3049ce.

Reason for revert: QTBUG-137306

Pick-to: 6.10 6.9
Change-Id: Id5718737f3f426de49ad109d214af1c920e5ae22
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-03 10:47:14 +00:00
Kai Köhne
95229bb7d0 Doc: Fix broken links in Qt Widgets
The iQRhiWidget API got changed in commits acebb97b5880,  acebb97b58807d1d591.

Pick-to: 6.8 6.9 6.10
Change-Id: I7791b1a61d94f33ba01cfe22e63ecfdc7b81022b
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-03 10:41:10 +00:00
Ilya Fedin
7c25b916dc xcb: mark xcb-image dependent on xcb-aux
Pick-to: 6.10 6.9 6.8 6.5
Fixes: QTBUG-86287
Fixes: QTBUG-137004
Change-Id: Ic4055078dedbbd8fcf1fba3983d6d64b7a06a20e
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2025-06-03 10:41:10 +00:00
Liang Qi
ac2a38d80c Reapply: xcb: add xcb-util dependency for xcb-image
xcb-image includes xcb_aux.h, which is part of xcb-util.

0.3.8 is enough for the dependency, it also make Debian 10
(Buster) satisfied. xcb-image is from xcb-util-image, which
should follow same version number as xcb-util. Not sure how
Debian 10(Buster) got xcb-image 0.3.9 with xcb-util 0.3.8
combination.

See also https://lists.x.org/archives/xorg-announce/2012-May/date.html#1965 .

This reverts 92a57e0b016f811876ec1d62328ca8edfe452a3a .

Fixes: QTBUG-86287
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: I838b1e06a25fa1e45470466de17cbb6b6da851a4
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2025-06-03 10:41:10 +00:00
Jie Liu
1c87e9a60a wayland: fix image copy failed problem on data control
Change-Id: I20d26af8bdbf5f35ae78c984eb21e91f6fcc72b4
Reviewed-by: David Edmundson <davidedmundson@kde.org>
2025-06-03 09:19:03 +00:00
David Edmundson
d687ac6d3e wayland: Drop unused member variable
The only mWaitingForUpdate is checked is to show a debug. The only
public way to call requestUpdate is via QWindow::requestUpdate which has
a guard already.

Change-Id: I542e0f470ec2134f0a9fd415aab6ac7832e77263
Reviewed-by: David Redondo <qt@david-redondo.de>
2025-06-03 12:19:03 +03:00
Michael Weghorn
5e7891f73f a11y atspi: Set correct child index in children-changed:add event
When sending an object:children-changed:add AT-SPI2 event,
set the actual index of the child instead of always using
the child count of its parent.

If the new child were added at the end, its index would be
"[child count] - 1", but the new child doesn't necessarily
have to have been added at the end.

Therefore, use the actual child index either already used as loop
variable or retrieved via QAccessibleInterface::indexOfChild
instead.

The mismatch could e.g. be demonstrated with a simple pyatspi
script when typing Enter in LibreOffice Writer to create
new paragraphs.

Script:

    #!/usr/bin/python3
    import pyatspi
    def listener(e):
        if not e.host_application.name.startswith('soffice'):
            return
        print(e)
        print(f'index in parent set in event: {e.detail1}')
        print(f'index in parent reported by child: {e.any_data.get_index_in_parent()}')
    pyatspi.Registry.registerEventListener(listener, "object:children-changed:add")
    pyatspi.Registry.start()

Sample output without this commit in place:

    object:children-changed:add(4, 0, [paragraph | ])
            source: [document frame | Untitled 1 - LibreOfficeDev Document]
            host_application: [application | soffice.bin]
            sender: [application | soffice.bin]
    index in parent set in event: 4
    index in parent reported by child: 2

Sample output with this commit in place:

    object:children-changed:add(2, 0, [paragraph | ])
            source: [document frame | Untitled 1 - LibreOfficeDev Document]
            host_application: [application | soffice.bin]
            sender: [application | soffice.bin]
    index in parent set in event: 2
    index in parent reported by child: 2

Pick-to: 6.10 6.9 6.8
Change-Id: I30316c59f8ad6fd018089a8dca8e7a8d1d92d7ec
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-03 05:34:43 +00:00
Christian Ehrlicher
e0130876ba QHeaderView: remove unused include, add missing include
Remove unused include of qtableview.h in the source - this also fixes
the compilation with feature_tableview = OFF.
Move the missing include of qlist.h into the header.

Pick-to: 6.10 6.9
Change-Id: Ie443cf6f3bf6b76dedc994bf1b8c16daebf9022d
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-02 20:23:58 +00:00
Rami Potinkara
ea8f19f50b Android: don't disambiguate the convertToJni call with 'template'
There is no non-template overload of LocalFrame::convertToJni, and
clang 18 complains about an explicit .template without a template
argument list. We call convertToJni without either in other places, so
do so here as well.

Pick-to: 6.10
Fixes: QTBUG-136967
Change-Id: I2b4bbc8a4e2056bd2a8bff390ea0847f2e18202e
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-02 20:23:54 +00:00
Michael Weghorn
6cca30bb11 a11y atspi: Support Application iface "AtspiVersion" property
As the AT-SPI XML spec for the Application interface says,
this should currently always be "2.1" [1]:

    <!--
        AtspiVersion: You should return "2.1" here.

        This was intended to be the version of the atspi interfaces
        that the application supports, but atspi will probably move to
        using versioned interface names instead.  Just return "2.1" here.
    -->
    <property name="AtspiVersion" type="s" access="read"/>

This makes the expected value show up in Accerciser with
pending merge request [2] in place instead of triggering a fallback
path in Accerciser handling the null case for Qt applications.

[1] 2d83e3a6df/xml/Application.xml (L19-26)
[2] https://gitlab.gnome.org/GNOME/accerciser/-/merge_requests/95

Pick-to: 6.9 6.10
Change-Id: I0d849d5d6d160c48fd4fc2d443e4fde43cde5606
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
2025-06-02 20:23:54 +00:00
Christian Ehrlicher
db07a03874 StyleSheetStyle: Don't paint CE_ComboBoxLabel when no stylesheet is set
Don't paint through stylesheet code when a combobox label has no
stylesheet set at all.
This should be done also for others but may break existing painting
stuff so only fix this here as it's a regression from
a77a7c157d5cdcc88bf0a02caed2aa5ff8850d06.

Pick-to: 6.10 6.9 6.8
Task-number: QTBUG-131761
Fixes: QTBUG-137108
Change-Id: I462ba198821692aa60e6869df9c8e92332422c44
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
2025-06-02 19:53:35 +00:00
Cristian Le
295b3ca5bd Deprecate FEATURE_regularexpression
There have been places where regex support has been implied and bootstrap
always builds with regex enabled. Therefore, disabling
`FEATURE_regularexpression` currently produces an error. Until a need
for building without regex emerges, we are enforcing it as a
requirement.

Users must either use system or bundled pcre2.

Fixes: QTBUG-136346
Change-Id: I9e92bb4e7f0dfb84884a2a23f45b20d18ddc8985
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2025-06-02 20:54:31 +02:00
Cristian Le
618053e279 Add feature deprecation capability
Emit a warning if `FEATURE_*` variable is set. The "feature" is not
registered as a true feature after deprecation.

Pick-to: 6.10 6.9 6.8
Change-Id: I715af231c228c73d70b037ee31aa61edcd45c21e
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2025-06-02 20:54:31 +02:00
Cristian Le
11fab3d150 Display feature alias information in configure
Pick-to: 6.10 6.9 6.8
Change-Id: Ia7d054436ffcca64d6fecd363795e7439694b3f4
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2025-06-02 20:54:31 +02:00
Joerg Bornemann
eaf87cdfd8 CMake: Add targets for building Android docs from Java sources
One can now run "ninja android_docs" to generate HTML docs for Android
Java sources of Qt. This is done with javadoc.

One can now run "ninja android_source_jars" to generate source jars for
Android. They're supposed to be loaded into an IDE.

The targets are enabled automatically for Android builds.
For non-Android builds, set QT_BUILD_HOST_JAVA_DOCS=ON to create those
targets. In that case you must also set ANDROID_SDK_ROOT.

Fixes: QTBUG-117028
Change-Id: I2df51153359a95870c055d3ee373b8381f10cb51
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Reviewed-by: Nicholas Bennett <nicholas.bennett@qt.io>
2025-06-02 19:18:04 +02:00
Alexandru Croitor
89e7facc2e CMake: Fix location of iOS framework prl files
iOS prl files for static frameworks were previously placed at a path
like
  6.8.3/ios/lib/QtCore.framework/Versions/A/Resources/QtCore.prl

This caused qmake to silently fail to find iOS framework prl files.
The failure could only be seen when calling qmake with -d -d:

  DEBUG 2: QMakeMetaInfo: Cannot find info file for
    6.8.3/ios/lib/QtCore.framework/Resources/QtCore.prl

This in turn can lead to various build failures if a different non-iOS
prl file is found in a system path.

Place the prl file into the root of each framework, e.g. at
  6.8.3/ios/lib/QtCore.framework/QtCore.prl

We didn't have this issue in 6.7 and earlier, because by default iOS
was built with static libraries rather than static frameworks.

Amends 291817b0bf3f351843b0c1d0de237dc8df5c0fa5

Pick-to: 6.8 6.9 6.10
Fixes: QTBUG-137297
Change-Id: Idff8e808e9bfc009f82d2a59e5e6752ed8a55714
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
2025-06-02 19:18:03 +02:00
Lars Schmertmann
577f9ebfe6 Android: Enable all warnings on javac for user code too
In addtion to 1cf03c974c433b7a5330b56bd9e519287fce6f7f we should also
enable all warnings in the template as a recommendation for users.

Pick-to: 6.10
Change-Id: If60a3d9f3c1fd97b49ec7513f781bdfe1775d9d4
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-02 19:18:03 +02:00
David Redondo
1260aaf954 Send synthesized button release event immediately
...not only on the next frame.

Pick-to: 6.10
Change-Id: Iad31a3d80576c5cd8fa3ba7f64a39d7a6a01337a
Reviewed-by: David Edmundson <davidedmundson@kde.org>
2025-06-02 19:18:03 +02:00
Alexandru Croitor
747741119a CMake: Improve Apple SDK name and path reporting
If CMAKE_OSX_SYSROOT or QT_APPLE_SDK was set, we still reported the
default platform sdk path, rather than taking into account the set
value.

Improve the reporting by considering these values.

The implementation is incomplete because we don't handle explicit sdk
paths, but this is not critical for the current use cases, because the
value of the function is only used for reporting purposes.

Amends ab7eb492cba64fe985ea80b2f0be22c1c18f3c5e

Pick-to: 6.8 6.9 6.10
Change-Id: Ic69aec3641d435736018c96f72ba7f75a0f74508
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2025-06-02 19:18:03 +02:00
David Edmundson
602fa3f337 wayland: Ack configure events when suspended
All configure events should be acked, and that acknowledgement is double
buffered with the surface commit.

If a window is not exposed, for example being in a suspended state, us
sending an expose event is semantically wrong. It also ends up not
resulting in a commit as at some point it no-ops, we have to commit
manually.

Change-Id: I020b06f04030c1209f2fc768adc8bd66d57975b1
Reviewed-by: David Redondo <qt@david-redondo.de>
2025-06-02 20:18:03 +03:00
David Edmundson
ca27a661bd wayland: Use modern syntax for method invokation
Change-Id: I4b4d15fcb932460a1b6a132145451fa2990496ad
Reviewed-by: David Redondo <qt@david-redondo.de>
2025-06-02 19:32:47 +03:00
Olli Vuolteenaho
3bf9047a34 Android: Don't reparse same paths in QML to Java codegen
appImports can have the same directory added multiple times - first if
it's found in the xxx_conf.rsp file and secondly for the inner qmldir
scanner. This is because the xxx_conf.rsp file can have both the
qmlModule directory and the parent of that directory as importPaths. For
example like this (the paths are truncated to save characters):

-importPath
.../build/qt_generated/qtquickview/qmlModule
-importPath
.../build/qt_generated/qtquickview

In this case when the "inner qmldir" finder processes the later path,
it would go to ./qmlModule, find the qmldir and add another
.../build/qt_generated/qtquickview/qmlModule to appImports. Also, if
there were other qmldir files somewhere under qmlModule those would
also get added twice, which would increase generation time yet again.

This commits solves the issue by removing duplicates from appImports.

Amends 7ed88eb565d40b195aa868e67777872ef07a5ea2.

Pick-to: 6.10 6.9 6.8
Fixes: QTBUG-137316
Change-Id: I641065479aec0f3d9ae1a8727a03bf62eb169ad6
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
2025-06-02 17:40:54 +03:00
Matthias Rauter
7d163200f9 Mark three files in corelib/mimetype as critical
* qmimeprovider.cpp parses file names to identify the Mimetype,
* qmimemagicrule.cpp parses the file to identify its Mimetype.
* qmimeglobpattern.cpp implements a pattern matching algorithm, i.e.
glob parser.

All involve parsing of data that might come from untrusted sources.

QUIP: 23
Task-number: QTBUG-135191
Pick-to: 6.10 6.9 6.8
Change-Id: I97d4cd8d635f05613d5a979c61038cef9c759989
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
2025-06-02 14:40:54 +00:00
Cristian Le
cebdf1eb1c Introduce INSTALL_QT_SHAREDIR
Normally `INSTALL_DATADIR` is the canonical place for
`share`/`CMAKE_INSTALL_DATADIR`, but this standard is not well
enforced.

In 834d92a, `INSTALL_SHAREDIR` was introduced to better enforce this
standard and allow to install into third-party program's
`CMAKE_INSTALL_DATADIR` (e.g. wayland). This ended up being used as
`INSTALL_SHAREDIR/qt6` instead, but this leaves little room for
configuration and renaming.

This change introduces a namespaced variant that is guaranteed to be
owned by Qt.

Pick-to: 6.10
Change-Id: I25c0e5b47c402b178120e9e628fdfaf4aaad27ad
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
2025-06-02 16:40:54 +02:00
David Edmundson
d08f1d7dbc QVulkanWindow: Force render on paint event
When a paint event is dispatched from the platform, application code
should redraw contents and submit a frame regardless of whether contents
have changed.

This fixes an issue where the window does not always update after being minimized on wayland, and would also be needed for non-composited X11 when exposure changes.

Pick-to: 6.10 6.9 6.8
Change-Id: I506872f439e0c16d71ad13def1c8b58a0491dd73
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
2025-06-02 14:40:54 +00:00
Andreas Eliasson
f27588348b Doc: Add \note to QTest::qWait() to consider QTRY_*() macros instead
There seems to be a case that qWait() is a source of eventual pain.
Add \note to encourage the use of the QTRY_*() macros.

Fixes: QTBUG-136538
Pick-to: 6.10 6.9 6.8
Change-Id: I52daa8c38a55f8db66d8c941c7cbfff7b7060a5b
Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
2025-06-02 14:40:54 +00:00
Tim Blechmann
e6dfd2e9b0 Cocoa: QNSView - fix memory leak of QContainerLayer
setLayer will increment the reference count, so QContainerLayer is
leaked, as it is not autoreleased.

Pick-to: 6.10
Change-Id: I43cef8bbf9ccb9b849322edfb1e7ab75f5ae9898
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2025-06-02 10:29:27 +00:00
Tim Blechmann
c8ebe2e5cd Cocoa: QNSView - fix memory leak of QNSViewMenuHelper
QNSViewMenuHelper is leaked, as dealloc did not nil it to decrement the
reference count.

Pick-to: 6.5 6.8 6.9 6.10
Fixes: QTBUG-131655
Fixes: QTBUG-137161
Change-Id: I783c400d1300046118ad3e12816e84709cc9d793
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
2025-06-02 10:29:23 +00:00
Eskil Abrahamsen Blomfeldt
ab7a80a955 DirectWrite: Avoid infinite recursion with broken font data
If a font has an em square size of 0 it is not going to be useful.
However, if one was encountered we returned a default value to
avoid division by zero. The default implementation called ascent(),
which would depend on the em square size again and we would get an
infinite recursion for these fonts.

To avoid this, we simply return a default value of 16 in the case
of a broken font. (The Apple spec gives the range 64 .. 16384 for
the em square and the Microsoft spec says 16 .. 16384, so we use
the smallest of the two.)

Fixes: QTBUG-137277
Pick-to: 6.5 6.8 6.9
Change-Id: I63779e44c10c7021486787d1e1e818f4c6e47835
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
2025-06-02 11:34:02 +02:00
Samuli Piippo
b23da37d71 CMake: qtwaylandscanner doesn't need Wayland::Client
Remove dependency to Wayland::Client as it's not needed and
prevents building qtwaylandscanner for Windows where Client
is not supported but scanner is needed for cross-compilations.

Change-Id: Ia38dda58c0800799673ae2d1e29626ce6b399f04
Reviewed-by: Liang Qi <liang.qi@qt.io>
2025-06-02 05:22:52 +00:00
84 changed files with 1673 additions and 352 deletions

View File

@ -7,7 +7,7 @@ if (NOT DEFINED QT_SUPERBUILD OR DEFINED QT_REPO_MODULE_VERSION)
set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_LEAN_HEADERS=1") set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_LEAN_HEADERS=1")
endif() endif()
set(QT_REPO_MODULE_VERSION "6.10.0") set(QT_REPO_MODULE_VERSION "6.11.0")
set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1") set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1")
set(QT_COPYRIGHT "Copyright (C) The Qt Company Ltd. and other contributors.") set(QT_COPYRIGHT "Copyright (C) The Qt Company Ltd. and other contributors.")

View File

@ -145,7 +145,7 @@ endforeach()
set(XCB_XCB_component_deps) set(XCB_XCB_component_deps)
set(XCB_COMPOSITE_component_deps XCB XFIXES) set(XCB_COMPOSITE_component_deps XCB XFIXES)
set(XCB_DAMAGE_component_deps XCB XFIXES) set(XCB_DAMAGE_component_deps XCB XFIXES)
set(XCB_IMAGE_component_deps XCB SHM) set(XCB_IMAGE_component_deps XCB SHM AUX)
set(XCB_RENDERUTIL_component_deps XCB RENDER) set(XCB_RENDERUTIL_component_deps XCB RENDER)
set(XCB_XFIXES_component_deps XCB RENDER SHAPE) set(XCB_XFIXES_component_deps XCB RENDER SHAPE)
set(XCB_XVMC_component_deps XCB XV) set(XCB_XVMC_component_deps XCB XV)

View File

@ -287,3 +287,189 @@ function(qt_internal_android_dependencies target)
COMPONENT COMPONENT
Devel) Devel)
endfunction() endfunction()
function(qt_internal_set_up_build_host_java_docs)
if("${ANDROID_SDK_ROOT}" STREQUAL "")
message(FATAL_ERROR
"QT_HOST_DOCUMENT_JAVA_SOURCES=ON requires setting ANDROID_SDK_ROOT."
)
endif()
_qt_internal_locate_android_jar()
set(QT_ANDROID_JAR "${QT_ANDROID_JAR}" PARENT_SCOPE)
set(QT_ANDROID_API_USED_FOR_JAVA "${QT_ANDROID_API_USED_FOR_JAVA}" PARENT_SCOPE)
endfunction()
# Collect the Java source files that were recorded by qt_internal_add_jar.
# If we're not building for Android, qt_internal_add_jar is not called, and we simple collect
# all java files under the current directory.
function(qt_internal_collect_jar_sources out_var)
if(NOT ANDROID)
file(GLOB_RECURSE sources LIST_DIRECTORIES FALSE "*.java")
set("${out_var}" "${sources}" PARENT_SCOPE)
return()
endif()
set(no_value_options "")
set(single_value_options DIRECTORY)
set(multi_value_options "")
cmake_parse_arguments(PARSE_ARGV 1 arg
"${no_value_options}" "${single_value_options}" "${multi_value_options}"
)
_qt_internal_validate_all_args_are_parsed(arg)
set(directory_arg "")
if(DEFINED arg_DIRECTORY)
set(directory_arg DIRECTORY ${arg_DIRECTORY})
endif()
get_directory_property(result ${directory_arg} _qt_jar_sources)
get_directory_property(subdirs ${directory_arg} SUBDIRECTORIES)
foreach(subdir IN LISTS subdirs)
qt_internal_collect_jar_sources(subdir_result DIRECTORY ${subdir})
if(NOT "${subdir_result}" STREQUAL "")
list(APPEND result ${subdir_result})
endif()
endforeach()
set("${out_var}" "${result}" PARENT_SCOPE)
endfunction()
function(qt_internal_add_javadoc_target)
set(no_value_options "")
set(single_value_options
MODULE
OUTPUT_DIR
)
set(multi_value_options
SOURCES
)
cmake_parse_arguments(PARSE_ARGV 0 arg
"${no_value_options}" "${single_value_options}" "${multi_value_options}"
)
_qt_internal_validate_all_args_are_parsed(arg)
if(TARGET ${arg_MODULE})
get_target_property(skip ${arg_MODULE} _qt_skip_javadoc)
if(skip)
message(VERBOSE "Skipping generation of Android HTML docs for ${arg_MODULE}.")
return()
endif()
endif()
# Collect source directories from source file paths.
set(source_dirs "")
foreach(source_path IN LISTS arg_SOURCES)
get_filename_component(dir_path "${source_path}" DIRECTORY)
list(APPEND source_dirs "${dir_path}")
endforeach()
list(REMOVE_DUPLICATES source_dirs)
# Retrieve package names from source dirs.
set(package_names "")
foreach(source_dir IN LISTS source_dirs)
string(REGEX MATCH "/(org/qtproject/qt/android(/.*|$))" package_dir "${source_dir}")
if(package_dir STREQUAL "")
message(VERBOSE "Java source dir is not a package directory: ${source_dir}")
continue()
endif()
# Store package_dir without leading slash.
set(package_dir "${CMAKE_MATCH_1}")
# Use dots instead of slashes for the package name.
string(REPLACE "/" "." package_name "${package_dir}")
list(APPEND package_names "${package_name}")
endforeach()
# Strip package paths from the source dirs.
list(TRANSFORM source_dirs REPLACE "/org/qtproject/qt/android.*" "")
list(REMOVE_DUPLICATES source_dirs)
# Use the correct separator for the --source-path argument.
if(NOT CMAKE_HOST_WIN32)
string(REPLACE ";" ":" source_dirs "${source_dirs}")
endif()
# Use a response file to avoid quoting issues with the space-separated package names.
set(javadoc_output_dir "${arg_OUTPUT_DIR}/android")
set(response_file "${CMAKE_CURRENT_BINARY_DIR}/doc/.javadocargs")
string(REPLACE ";" " " package_names_space_separated "${package_names}")
file(CONFIGURE
OUTPUT "${response_file}"
CONTENT "${package_names_space_separated}
--class-path \"${QT_ANDROID_JAR}\"
-d \"${javadoc_output_dir}\"
--source-path \"${source_dirs}\""
)
set(module ${arg_MODULE})
set(javadoc_target android_html_docs_${module})
add_custom_target(${javadoc_target} ${command_args}
COMMAND ${Java_JAVADOC_EXECUTABLE} "@${response_file}"
COMMENT "Generating Java documentation"
VERBATIM
)
add_dependencies(docs_android ${javadoc_target})
if (QT_WILL_INSTALL)
install(DIRECTORY "${arg_OUTPUT_DIR}/"
DESTINATION "${INSTALL_DOCDIR}/${module}"
COMPONENT _install_docs_android_${module}
EXCLUDE_FROM_ALL
)
add_custom_target(install_docs_android_${module}
COMMAND ${CMAKE_COMMAND}
--install "${CMAKE_BINARY_DIR}"
--component _install_docs_android_${module}
COMMENT "Installing Android html docs for ${module}"
)
else()
add_custom_target(install_docs_android_${module})
endif()
add_dependencies(install_docs_android_${module} ${javadoc_target})
add_dependencies(install_docs_android install_docs_android_${module})
endfunction()
function(qt_internal_create_source_jar)
set(no_value_options "")
set(single_value_options MODULE)
set(multi_value_options SOURCES)
cmake_parse_arguments(PARSE_ARGV 0 arg
"${no_value_options}" "${single_value_options}" "${multi_value_options}"
)
_qt_internal_validate_all_args_are_parsed(arg)
set(module ${arg_MODULE})
set(jar_target android_source_jar_${module})
set(jar_name ${CMAKE_INSTALL_NAMESPACE}AndroidSources${module})
add_jar(${jar_target}
SOURCES ${arg_SOURCES}
VERSION ${PROJECT_VERSION}
INCLUDE_JARS "${QT_ANDROID_JAR}"
OUTPUT_NAME ${jar_name}
)
set_target_properties(${jar_target} PROPERTIES EXCLUDE_FROM_ALL ON)
add_dependencies(android_source_jars ${jar_target})
if(QT_WILL_INSTALL)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${jar_name}-${PROJECT_VERSION}.jar"
DESTINATION "${INSTALL_DATADIR}/android/${module}"
COMPONENT _install_android_source_jar_${module}
EXCLUDE_FROM_ALL
)
add_custom_target(install_android_source_jar_${module}
COMMAND ${CMAKE_COMMAND}
--install "${CMAKE_BINARY_DIR}"
--component _install_android_source_jar_${module}
COMMENT "Installing Android source jar for ${module}"
)
else()
add_custom_target(install_android_source_jar_${module})
endif()
add_dependencies(install_android_source_jar_${module} ${jar_target})
add_dependencies(install_android_source_jars install_android_source_jar_${module})
endfunction()

View File

@ -65,6 +65,11 @@ function(qt_auto_detect_wasm)
endfunction() endfunction()
function(qt_auto_detect_android) function(qt_auto_detect_android)
# Don't assume an Android build if we're requesting to build Java documentation on the host.
if(QT_BUILD_HOST_JAVA_DOCS)
return()
endif()
# We assume an Android build if any of the ANDROID_* cache variables are set. # We assume an Android build if any of the ANDROID_* cache variables are set.
if(DEFINED ANDROID_SDK_ROOT if(DEFINED ANDROID_SDK_ROOT
OR DEFINED ANDROID_NDK_ROOT OR DEFINED ANDROID_NDK_ROOT

View File

@ -449,6 +449,7 @@ macro(qt_internal_setup_build_and_global_variables)
qt_internal_setup_find_host_info_package() qt_internal_setup_find_host_info_package()
qt_internal_setup_build_docs() qt_internal_setup_build_docs()
qt_internal_setup_build_java_docs_on_host()
qt_internal_include_qt_platform_android() qt_internal_include_qt_platform_android()

View File

@ -403,6 +403,16 @@ macro(qt_internal_setup_build_docs)
option(QT_BUILD_DOCS "Generate Qt documentation targets" ON) option(QT_BUILD_DOCS "Generate Qt documentation targets" ON)
endmacro() endmacro()
macro(qt_internal_setup_build_java_docs_on_host)
option(QT_BUILD_HOST_JAVA_DOCS "Generate Java documentation targets on host" OFF)
if(QT_BUILD_HOST_JAVA_DOCS)
find_package(Java)
if(Java_FOUND)
include(UseJava)
endif()
endif()
endmacro()
macro(qt_internal_set_use_ccache) macro(qt_internal_set_use_ccache)
option(QT_USE_CCACHE "Enable the use of ccache") option(QT_USE_CCACHE "Enable the use of ccache")
if(QT_USE_CCACHE) if(QT_USE_CCACHE)

View File

@ -79,6 +79,7 @@ function(qt_internal_add_docs)
set(opt_args set(opt_args
SHOW_INTERNAL SHOW_INTERNAL
SKIP_JAVADOC
) )
set(single_args "") set(single_args "")
set(multi_args set(multi_args
@ -352,9 +353,9 @@ function(qt_internal_add_docs)
if (QT_WILL_INSTALL) if (QT_WILL_INSTALL)
install(DIRECTORY "${qdoc_output_dir}/" install(DIRECTORY "${qdoc_output_dir}/"
DESTINATION "${INSTALL_DOCDIR}/${doc_target}" DESTINATION "${INSTALL_DOCDIR}/${doc_target}"
COMPONENT _install_html_docs_${target} COMPONENT _install_html_docs_${target}
EXCLUDE_FROM_ALL EXCLUDE_FROM_ALL
) )
add_custom_target(install_html_docs_${target} add_custom_target(install_html_docs_${target}
@ -365,9 +366,9 @@ function(qt_internal_add_docs)
) )
install(FILES "${qch_file_path}" install(FILES "${qch_file_path}"
DESTINATION "${INSTALL_DOCDIR}" DESTINATION "${INSTALL_DOCDIR}"
COMPONENT _install_qch_docs_${target} COMPONENT _install_qch_docs_${target}
EXCLUDE_FROM_ALL EXCLUDE_FROM_ALL
) )
add_custom_target(install_qch_docs_${target} add_custom_target(install_qch_docs_${target}
@ -403,4 +404,73 @@ function(qt_internal_add_docs)
qt_internal_add_doc_tool_dependency(prepare_docs_${target} qdoc) qt_internal_add_doc_tool_dependency(prepare_docs_${target} qdoc)
qt_internal_add_doc_tool_dependency(qch_docs_${target} qhelpgenerator) qt_internal_add_doc_tool_dependency(qch_docs_${target} qhelpgenerator)
endif() endif()
_qt_internal_forward_function_args(
FORWARD_PREFIX arg
FORWARD_OUT_VAR add_java_documentation_args
FORWARD_OPTIONS
SKIP_JAVADOC
)
qt_internal_add_java_documentation(${target} ${add_java_documentation_args}
OUTPUT_DIR "${qdoc_output_dir}"
)
endfunction()
function(qt_internal_add_java_documentation target)
if(NOT ANDROID AND NOT QT_BUILD_HOST_JAVA_DOCS)
return()
endif()
set(no_value_options
SKIP_JAVADOC
)
set(single_value_options
OUTPUT_DIR
)
set(multi_value_options "")
cmake_parse_arguments(PARSE_ARGV 1 arg
"${no_value_options}" "${single_value_options}" "${multi_value_options}"
)
_qt_internal_validate_all_args_are_parsed(arg)
# Use a default output directory based on the project name.
if(NOT DEFINED arg_OUTPUT_DIR)
if (QT_WILL_INSTALL)
set(arg_OUTPUT_DIR "${CMAKE_BINARY_DIR}/${INSTALL_DOCDIR}")
else()
set(arg_OUTPUT_DIR "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_DOCDIR}")
endif()
string(APPEND arg_OUTPUT_DIR "/${PROJECT_NAME}")
endif()
qt_internal_collect_jar_sources(sources)
# Bail out if we haven't found relevant sources.
if(sources STREQUAL "")
return()
endif()
if(NOT TARGET docs_android)
add_custom_target(docs_android)
add_custom_target(install_docs_android)
add_dependencies(install_docs_android docs_android)
add_custom_target(android_source_jars)
add_custom_target(install_android_source_jars)
add_dependencies(install_android_source_jars android_source_jars)
endif()
if(NOT ANDROID)
qt_internal_set_up_build_host_java_docs()
endif()
if(NOT arg_SKIP_JAVADOC)
qt_internal_add_javadoc_target(
MODULE ${target}
SOURCES ${sources}
OUTPUT_DIR "${arg_OUTPUT_DIR}"
)
endif()
qt_internal_create_source_jar(SOURCES ${sources} MODULE ${target})
endfunction() endfunction()

View File

@ -28,6 +28,7 @@ function(qt_internal_add_jar target)
get_filename_component(absolute_path "${path}" ABSOLUTE) get_filename_component(absolute_path "${path}" ABSOLUTE)
list(APPEND absolute_sources "${absolute_path}") list(APPEND absolute_sources "${absolute_path}")
endforeach() endforeach()
set_property(DIRECTORY APPEND PROPERTY _qt_jar_sources "${absolute_sources}")
add_jar(${target} SOURCES ${absolute_sources} ${ARGV}) add_jar(${target} SOURCES ${absolute_sources} ${ARGV})

View File

@ -23,32 +23,7 @@ if (NOT IS_DIRECTORY "${ANDROID_SDK_ROOT}")
message(FATAL_ERROR "Could not find ANDROID_SDK_ROOT or path is not a directory: ${ANDROID_SDK_ROOT}") message(FATAL_ERROR "Could not find ANDROID_SDK_ROOT or path is not a directory: ${ANDROID_SDK_ROOT}")
endif() endif()
# This variable specifies the API level used for building Java code, it can be the same as Qt for _qt_internal_locate_android_jar()
# Android's maximum supported Android version or higher.
if(NOT QT_ANDROID_API_USED_FOR_JAVA)
set(QT_ANDROID_API_USED_FOR_JAVA "android-35")
endif()
set(jar_location "${ANDROID_SDK_ROOT}/platforms/${QT_ANDROID_API_USED_FOR_JAVA}/android.jar")
if(NOT EXISTS "${jar_location}")
_qt_internal_detect_latest_android_platform(android_platform_latest)
if(android_platform_latest)
message(NOTICE "The default platform SDK ${QT_ANDROID_API_USED_FOR_JAVA} not found, "
"using the latest installed ${android_platform_latest} instead.")
set(QT_ANDROID_API_USED_FOR_JAVA ${android_platform_latest})
endif()
endif()
set(QT_ANDROID_JAR "${ANDROID_SDK_ROOT}/platforms/${QT_ANDROID_API_USED_FOR_JAVA}/android.jar")
if(NOT EXISTS "${QT_ANDROID_JAR}")
message(FATAL_ERROR
"No suitable Android SDK platform found in '${ANDROID_SDK_ROOT}/platforms'."
" The minimum version required for building Java code is ${QT_ANDROID_API_USED_FOR_JAVA}"
)
endif()
message(STATUS "Using Android SDK API ${QT_ANDROID_API_USED_FOR_JAVA} from "
"${ANDROID_SDK_ROOT}/platforms")
# Locate Java # Locate Java
include(UseJava) include(UseJava)

View File

@ -45,3 +45,36 @@ function(_qt_internal_sort_android_platforms out_var)
endif() endif()
set("${out_var}" "${platforms}" PARENT_SCOPE) set("${out_var}" "${platforms}" PARENT_SCOPE)
endfunction() endfunction()
function(_qt_internal_locate_android_jar)
# This variable specifies the API level used for building Java code, it can be the same as Qt
# for Android's maximum supported Android version or higher.
if(NOT QT_ANDROID_API_USED_FOR_JAVA)
set(QT_ANDROID_API_USED_FOR_JAVA "android-35")
endif()
set(jar_location "${ANDROID_SDK_ROOT}/platforms/${QT_ANDROID_API_USED_FOR_JAVA}/android.jar")
if(NOT EXISTS "${jar_location}")
_qt_internal_detect_latest_android_platform(android_platform_latest)
if(android_platform_latest)
message(NOTICE "The default platform SDK ${QT_ANDROID_API_USED_FOR_JAVA} not found, "
"using the latest installed ${android_platform_latest} instead.")
set(QT_ANDROID_API_USED_FOR_JAVA ${android_platform_latest})
endif()
endif()
set(QT_ANDROID_JAR "${ANDROID_SDK_ROOT}/platforms/${QT_ANDROID_API_USED_FOR_JAVA}/android.jar")
if(NOT EXISTS "${QT_ANDROID_JAR}")
message(FATAL_ERROR
"No suitable Android SDK platform found in '${ANDROID_SDK_ROOT}/platforms'."
" The minimum version required for building Java code is ${QT_ANDROID_API_USED_FOR_JAVA}"
)
endif()
message(STATUS "Using Android SDK API ${QT_ANDROID_API_USED_FOR_JAVA} from "
"${ANDROID_SDK_ROOT}/platforms")
set(QT_ANDROID_JAR "${QT_ANDROID_JAR}" PARENT_SCOPE)
set(QT_ANDROID_API_USED_FOR_JAVA "${QT_ANDROID_API_USED_FOR_JAVA}" PARENT_SCOPE)
endfunction()

View File

@ -11,3 +11,4 @@ if (ANDROID)
add_subdirectory(templates_aar) add_subdirectory(templates_aar)
endif() endif()
qt_internal_add_java_documentation(Global)

View File

@ -919,11 +919,12 @@ qt_feature("vxpipedrv" PRIVATE
AUTODETECT OFF AUTODETECT OFF
CONDITION VXWORKS CONDITION VXWORKS
) )
qt_feature("regularexpression" PUBLIC qt_feature_deprecated("regularexpression" PUBLIC
REMOVE_BY "7.0"
SECTION "Kernel" SECTION "Kernel"
LABEL "QRegularExpression" LABEL "QRegularExpression"
PURPOSE "Provides an API to Perl-compatible regular expressions." PURPOSE "Provides an API to Perl-compatible regular expressions."
CONDITION QT_FEATURE_system_pcre2 OR QT_FEATURE_pcre2 VALUE ON
) )
qt_feature_definition("regularexpression" "QT_NO_REGULAREXPRESSION" NEGATE VALUE "1") qt_feature_definition("regularexpression" "QT_NO_REGULAREXPRESSION" NEGATE VALUE "1")
qt_feature("backtrace" PRIVATE qt_feature("backtrace" PRIVATE
@ -1275,3 +1276,8 @@ qt_configure_add_report_entry(
MESSAGE "Basic cpp/winrt support missing. Some features might not be available." MESSAGE "Basic cpp/winrt support missing. Some features might not be available."
CONDITION WIN32 AND NOT QT_FEATURE_cpp_winrt CONDITION WIN32 AND NOT QT_FEATURE_cpp_winrt
) )
qt_configure_add_report_entry(
TYPE ERROR
MESSAGE "Qt requires pcre2 or system-pcre2 feature"
CONDITION NOT QT_FEATURE_pcre2 AND NOT QT_FEATURE_system_pcre2
)

View File

@ -19,20 +19,28 @@ QByteArray encodedString = fromUtf16(string);
auto toUtf16 = QStringDecoder(QStringDecoder::Utf8); auto toUtf16 = QStringDecoder(QStringDecoder::Utf8);
QString string; QString string;
while (new_data_available()) { while (new_data_available() && !toUtf16.hasError()) {
QByteArray chunk = get_new_data(); QByteArray chunk = get_new_data();
string += toUtf16(chunk); string += toUtf16(chunk);
} }
auto result = toUtf16.finalize();
if (result.error != QStringDecoder::FinalizeResult::NoError) {
// Handle error
}
//! [2] //! [2]
//! [3] //! [3]
auto fromUtf16 = QStringEncoder(QStringEncoder::Utf8); auto fromUtf16 = QStringEncoder(QStringEncoder::Utf8);
QByteArray encoded; QByteArray encoded;
while (new_data_available()) { while (new_data_available() && !fromUtf16.hasError()) {
QString chunk = get_new_data(); QString chunk = get_new_data();
encoded += fromUtf16(chunk); encoded += fromUtf16(chunk);
} }
auto result = fromUtf16.finalize();
if (result.error != QStringEncoder::FinalizeResult::NoError) {
// Handle error
}
//! [3] //! [3]
{ {

View File

@ -6,15 +6,16 @@
//! [0] //! [0]
#include <QSharedData> #include <QSharedData>
#include <QSharedDataPointer>
#include <QString> #include <QString>
class EmployeeData : public QSharedData class EmployeeData : public QSharedData
{ {
public: public:
EmployeeData() : id(-1) { } EmployeeData() : id(-1) {}
EmployeeData(const EmployeeData &other) EmployeeData(const EmployeeData &other)
: QSharedData(other), id(other.id), name(other.name) { } : QSharedData(other), id(other.id), name(other.name) {}
~EmployeeData() { } ~EmployeeData() = default;
int id; int id;
QString name; QString name;
@ -22,34 +23,38 @@ class EmployeeData : public QSharedData
class Employee class Employee
{ {
public: public:
//! [1] //! [1]
Employee() { d = new EmployeeData; } Employee() { d = new EmployeeData; }
//! [1] //! [2] //! [1] //! [2]
Employee(int id, const QString &name) { Employee(int id, const QString &name) {
d = new EmployeeData; d = new EmployeeData;
setId(id); setId(id);
setName(name); setName(name);
} }
//! [2] //! [7] //! [2] //! [7]
Employee(const Employee &other) Employee(const Employee &other) = default;
: d (other.d) Employee &operator=(const Employee &other) = default;
{
} Employee(Employee &&other) = default;
//! [7] Employee &operator=(Employee &&other) = default;
//! [3]
~Employee() = default;
//! [7]
//! [3]
void setId(int id) { d->id = id; } void setId(int id) { d->id = id; }
//! [3] //! [4] //! [3] //! [4]
void setName(const QString &name) { d->name = name; } void setName(const QString &name) { d->name = name; }
//! [4] //! [4]
//! [5] //! [5]
int id() const { return d->id; } int id() const { return d->id; }
//! [5] //! [6] //! [5] //! [6]
QString name() const { return d->name; } QString name() const { return d->name; }
//! [6] //! [6]
private: private:
QSharedDataPointer<EmployeeData> d; QSharedDataPointer<EmployeeData> d;
}; };
//! [0] //! [0]

View File

@ -1492,11 +1492,12 @@ backtraceFramesForLogMessage(int frameCount,
else else
return std::move(function).toUtf8(); // -> QByteArray return std::move(function).toUtf8(); // -> QByteArray
}(); }();
QScopedPointer<char, QScopedPointerPodDeleter> demangled; auto cleanup = [](auto *p) { free(p); };
demangled.reset(abi::__cxa_demangle(fn, nullptr, nullptr, nullptr)); using Ptr = std::unique_ptr<char, decltype(cleanup)>;
auto demangled = Ptr(abi::__cxa_demangle(fn, nullptr, nullptr, nullptr), cleanup);
if (demangled) if (demangled)
return QString::fromUtf8(qCleanupFuncinfo(demangled.data())); return QString::fromUtf8(qCleanupFuncinfo(demangled.get()));
else else
return QString::fromUtf8(fn); // restore return QString::fromUtf8(fn); // restore
}; };
@ -1537,8 +1538,10 @@ backtraceFramesForLogMessage(int frameCount,
static const QRegularExpression rx(QStringLiteral("^(?:[^(]*/)?([^(/]+)\\(([^+]*)(?:[\\+[a-f0-9x]*)?\\) \\[[a-f0-9x]*\\]$")); static const QRegularExpression rx(QStringLiteral("^(?:[^(]*/)?([^(/]+)\\(([^+]*)(?:[\\+[a-f0-9x]*)?\\) \\[[a-f0-9x]*\\]$"));
auto decodeFrame = [&](void *&addr) -> DecodedFrame { auto decodeFrame = [&](void *&addr) -> DecodedFrame {
QScopedPointer<char*, QScopedPointerPodDeleter> strings(backtrace_symbols(&addr, 1)); auto cleanup = [](auto *p) { free(p); };
QString trace = QString::fromUtf8(strings.data()[0]); auto strings =
std::unique_ptr<char *, decltype(cleanup)>(backtrace_symbols(&addr, 1), cleanup);
QString trace = QString::fromUtf8(strings.get()[0]);
QRegularExpressionMatch m = rx.match(trace); QRegularExpressionMatch m = rx.match(trace);
if (!m.hasMatch()) if (!m.hasMatch())
return {}; return {};

View File

@ -900,13 +900,13 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
} }
if (what & QFileSystemMetaData::AliasType) if (what & QFileSystemMetaData::AliasType)
what |= QFileSystemMetaData::LinkType; what |= QFileSystemMetaData::LinkType;
#endif #endif // defined(Q_OS_DARWIN)
#ifdef UF_HIDDEN #ifdef UF_HIDDEN
if (what & QFileSystemMetaData::HiddenAttribute) { if (what & QFileSystemMetaData::HiddenAttribute) {
// OS X >= 10.5: st_flags & UF_HIDDEN // OS X >= 10.5: st_flags & UF_HIDDEN
what |= QFileSystemMetaData::PosixStatFlags; what |= QFileSystemMetaData::PosixStatFlags;
} }
#endif // defined(Q_OS_DARWIN) #endif
// if we're asking for any of the stat(2) flags, then we're getting them all // if we're asking for any of the stat(2) flags, then we're getting them all
if (what & QFileSystemMetaData::PosixStatFlags) if (what & QFileSystemMetaData::PosixStatFlags)
@ -929,7 +929,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
// entry still exist are EACCES, EFAULT, ENOMEM and EOVERFLOW. If we get // entry still exist are EACCES, EFAULT, ENOMEM and EOVERFLOW. If we get
// EACCES or ENOMEM, then we have no choice on how to proceed, so we may // EACCES or ENOMEM, then we have no choice on how to proceed, so we may
// as well conclude it doesn't exist; EFAULT can't happen and EOVERFLOW // as well conclude it doesn't exist; EFAULT can't happen and EOVERFLOW
// shouldn't happen because we build in _LARGEFIE64. // shouldn't happen because we build in _LARGEFILE64.
union { union {
QT_STATBUF statBuffer; QT_STATBUF statBuffer;
struct statx statxBuffer; struct statx statxBuffer;
@ -939,7 +939,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
mode_t mode = 0; mode_t mode = 0;
statResult = qt_lstatx(nativeFilePath, &statxBuffer); statResult = qt_lstatx(nativeFilePath, &statxBuffer);
if (statResult == -ENOSYS) { if (statResult == -ENOSYS) {
// use lstst(2) // use lstat(2)
statResult = QT_LSTAT(nativeFilePath, &statBuffer); statResult = QT_LSTAT(nativeFilePath, &statBuffer);
if (statResult == 0) if (statResult == 0)
mode = statBuffer.st_mode; mode = statBuffer.st_mode;
@ -954,7 +954,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
data.entryFlags |= QFileSystemMetaData::LinkType; data.entryFlags |= QFileSystemMetaData::LinkType;
statResult = -1; // force stat(2) below statResult = -1; // force stat(2) below
} else { } else {
// it's a reagular file and it exists // it's a regular file and it exists
if (statResult) if (statResult)
data.fillFromStatxBuf(statxBuffer); data.fillFromStatxBuf(statxBuffer);
else else
@ -1868,23 +1868,36 @@ QString QFileSystemEngine::rootPath()
return u"/"_s; return u"/"_s;
} }
static constexpr QLatin1StringView nativeTempPath() noexcept
{
// _PATH_TMP usually ends in '/' and we don't want that
QLatin1StringView temp = _PATH_TMP ""_L1;
static_assert(_PATH_TMP[0] == '/', "_PATH_TMP needs to be absolute");
static_assert(_PATH_TMP[1] != '\0', "Are you really sure _PATH_TMP should be the root dir??");
if (temp.endsWith(u'/'))
temp.chop(1);
return temp;
}
QString QFileSystemEngine::tempPath() QString QFileSystemEngine::tempPath()
{ {
#ifdef QT_UNIX_TEMP_PATH_OVERRIDE #ifdef QT_UNIX_TEMP_PATH_OVERRIDE
return QT_UNIX_TEMP_PATH_OVERRIDE ""_L1; return QT_UNIX_TEMP_PATH_OVERRIDE ""_L1;
#else #else
QString temp = qEnvironmentVariable("TMPDIR"); QString temp = qEnvironmentVariable("TMPDIR");
if (temp.isEmpty()) { # if defined(Q_OS_DARWIN) && !defined(QT_BOOTSTRAPPED)
if (false) { if (NSString *nsPath; temp.isEmpty() && (nsPath = NSTemporaryDirectory()))
#if defined(Q_OS_DARWIN) && !defined(QT_BOOTSTRAPPED) temp = QString::fromCFString((CFStringRef)nsPath);
} else if (NSString *nsPath = NSTemporaryDirectory()) { # endif
temp = QString::fromCFString((CFStringRef)nsPath); if (temp.isEmpty())
#endif return nativeTempPath();
} else {
temp = _PATH_TMP ""_L1; // the environment variable may also end in '/'
} if (temp.size() > 1 && temp.endsWith(u'/'))
} temp.chop(1);
return QDir(QDir::cleanPath(temp)).canonicalPath();
QFileSystemEntry e(temp, QFileSystemEntry::FromInternalPath{});
return QFileSystemEngine::absoluteName(e).filePath();
#endif #endif
} }

View File

@ -434,10 +434,10 @@ void QEventDispatcherGlib::registerSocketNotifier(QSocketNotifier *notifier)
p->pollfd.events = G_IO_IN | G_IO_HUP | G_IO_ERR; p->pollfd.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
break; break;
case QSocketNotifier::Write: case QSocketNotifier::Write:
p->pollfd.events = G_IO_OUT | G_IO_ERR; p->pollfd.events = G_IO_OUT | G_IO_HUP | G_IO_ERR;
break; break;
case QSocketNotifier::Exception: case QSocketNotifier::Exception:
p->pollfd.events = G_IO_PRI | G_IO_ERR; p->pollfd.events = G_IO_PRI | G_IO_HUP | G_IO_ERR;
break; break;
} }
p->socketNotifier = notifier; p->socketNotifier = notifier;

View File

@ -832,8 +832,7 @@ static void argumentTypesFromString(const char *str, const char *end,
--level; --level;
++str; ++str;
} }
QByteArray argType(begin, str - begin); types.emplace_back(QByteArrayView{begin, str - begin});
types += QArgumentType(std::move(argType));
} }
} }

View File

@ -45,8 +45,8 @@ public:
QArgumentType(QMetaType metaType) QArgumentType(QMetaType metaType)
: _metaType(metaType) : _metaType(metaType)
{} {}
QArgumentType(const QByteArray &name) explicit QArgumentType(QByteArrayView name)
: _metaType(QMetaType{qMetaTypeTypeInternal(qToByteArrayViewIgnoringNull(name))}), _name(name) : _metaType(QMetaType{qMetaTypeTypeInternal(name)}), _name(name)
{} {}
QMetaType metaType() const noexcept QMetaType metaType() const noexcept
{ return _metaType; } { return _metaType; }
@ -69,7 +69,7 @@ private:
Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QArgumentType) Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(QArgumentType)
QMetaType _metaType; QMetaType _metaType;
QByteArray _name; QByteArrayView _name;
}; };
Q_DECLARE_TYPEINFO(QArgumentType, Q_RELOCATABLE_TYPE); Q_DECLARE_TYPEINFO(QArgumentType, Q_RELOCATABLE_TYPE);

View File

@ -1,5 +1,6 @@
// Copyright (C) 2021 Intel Corporation. // Copyright (C) 2021 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:critical reason:data-parser
#include "qcoffpeparser_p.h" #include "qcoffpeparser_p.h"

View File

@ -1,6 +1,7 @@
// Copyright (C) 2017 The Qt Company Ltd. // Copyright (C) 2017 The Qt Company Ltd.
// Copyright (C) 2021 Intel Corporation. // Copyright (C) 2021 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:critical reason:data-parser
#include "qelfparser_p.h" #include "qelfparser_p.h"

View File

@ -1,6 +1,7 @@
// Copyright (C) 2021 The Qt Company Ltd. // Copyright (C) 2021 The Qt Company Ltd.
// Copyright (C) 2022 Intel Corporation. // Copyright (C) 2022 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:critical reason:data-parser
#include "qfactoryloader_p.h" #include "qfactoryloader_p.h"

View File

@ -1,6 +1,8 @@
// Copyright (C) 2020 The Qt Company Ltd. // Copyright (C) 2020 The Qt Company Ltd.
// Copyright (C) 2021 Intel Corporation. // Copyright (C) 2021 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:critical reason:execute-external-code
#include "qlibrary.h" #include "qlibrary.h"
#include "qlibrary_p.h" #include "qlibrary_p.h"

View File

@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2020 Intel Corporation // Copyright (C) 2020 Intel Corporation
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:critical reason:execute-external-code
#include "qplatformdefs.h" #include "qplatformdefs.h"

View File

@ -1,5 +1,6 @@
// Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:critical reason:execute-external-code
#include "qplatformdefs.h" #include "qplatformdefs.h"
#include "qlibrary_p.h" #include "qlibrary_p.h"

View File

@ -1,5 +1,6 @@
// Copyright (C) 2016 Intel Corporation. // Copyright (C) 2016 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:critical reason:data-parser
#include "qmachparser_p.h" #include "qmachparser_p.h"

View File

@ -1,6 +1,7 @@
// Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 The Qt Company Ltd.
// Copyright (C) 2018 Intel Corporation. // Copyright (C) 2018 Intel Corporation.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:critical reason:execute-external-code
#include "qpluginloader.h" #include "qpluginloader.h"

View File

@ -1,6 +1,7 @@
// Copyright (C) 2020 The Qt Company Ltd. // Copyright (C) 2020 The Qt Company Ltd.
// Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com> // Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:critical reason:data-parser
#include "quuid.h" #include "quuid.h"
#include "quuid_p.h" #include "quuid_p.h"

View File

@ -550,6 +550,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_6_8 Same as Qt_6_7 \value Qt_6_8 Same as Qt_6_7
\value Qt_6_9 Same as Qt_6_7 \value Qt_6_9 Same as Qt_6_7
\value Qt_6_10 Same as Qt_6_7 \value Qt_6_10 Same as Qt_6_7
\value Qt_6_11 Same as Qt_6_10
\omitvalue Qt_DefaultCompiledVersion \omitvalue Qt_DefaultCompiledVersion
\sa setVersion(), version() \sa setVersion(), version()

View File

@ -4,6 +4,7 @@
#ifndef QDATASTREAM_H #ifndef QDATASTREAM_H
#define QDATASTREAM_H #define QDATASTREAM_H
#include <QtCore/qobjectdefs.h>
#include <QtCore/qchar.h> #include <QtCore/qchar.h>
#include <QtCore/qcontainerfwd.h> #include <QtCore/qcontainerfwd.h>
#include <QtCore/qiodevicebase.h> #include <QtCore/qiodevicebase.h>
@ -46,6 +47,8 @@ QDataStream &writeAssociativeMultiContainer(QDataStream &s, const Container &c);
} }
class Q_CORE_EXPORT QDataStream : public QIODeviceBase class Q_CORE_EXPORT QDataStream : public QIODeviceBase
{ {
Q_GADGET
public: public:
enum Version QT7_ONLY(: quint8) { enum Version QT7_ONLY(: quint8) {
Qt_1_0 = 1, Qt_1_0 = 1,
@ -91,11 +94,13 @@ public:
Qt_6_8 = Qt_6_7, Qt_6_8 = Qt_6_7,
Qt_6_9 = Qt_6_7, Qt_6_9 = Qt_6_7,
Qt_6_10 = 23, Qt_6_10 = 23,
Qt_DefaultCompiledVersion = Qt_6_10 Qt_6_11 = 24,
#if QT_VERSION >= QT_VERSION_CHECK(6, 11, 0) Qt_DefaultCompiledVersion = Qt_6_11
#if QT_VERSION >= QT_VERSION_CHECK(6, 12, 0)
#error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion #error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion
#endif #endif
}; };
Q_ENUM(Version)
enum ByteOrder { enum ByteOrder {
BigEndian = QSysInfo::BigEndian, BigEndian = QSysInfo::BigEndian,

View File

@ -39,9 +39,8 @@
#include <QtCore/private/wcharhelpers_win_p.h> #include <QtCore/private/wcharhelpers_win_p.h>
#include <QtCore/q20iterator.h> #include <QtCore/q20iterator.h>
#include <QtCore/q26numeric.h>
#endif // !QT_BOOTSTRAPPED #endif // !QT_BOOTSTRAPPED
#endif #endif // Q_OS_WIN
#include <array> #include <array>
#if __has_include(<bit>) && __cplusplus > 201703L #if __has_include(<bit>) && __cplusplus > 201703L
@ -49,6 +48,9 @@
#endif #endif
#include <string> #include <string>
#include <QtCore/q20utility.h> #include <QtCore/q20utility.h>
#ifndef QT_BOOTSTRAPPED
#include <QtCore/q26numeric.h>
#endif // !QT_BOOTSTRAPPED
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -2517,6 +2519,27 @@ std::optional<QStringConverter::Encoding> QStringConverter::encodingForName(QAny
} }
#ifndef QT_BOOTSTRAPPED #ifndef QT_BOOTSTRAPPED
namespace QtPrivate {
// Note: Check isValid() on the QStringConverter before calling this with its
// state!
static int partiallyParsedDataCount(QStringConverter::State *state)
{
#if QT_CONFIG(icu)
if (state->flags & QStringConverter::Flag::UsesIcu) {
UConverter *converter = static_cast<UConverter *>(state->d[0]);
if (!converter)
return 0;
UErrorCode err = U_ZERO_ERROR;
auto leftOver = ucnv_fromUCountPending(converter, &err);
// If there is an error, leftOver is -1, so no need for an additional
// check.
return std::max(leftOver, 0);
}
#endif
return q26::saturate_cast<int>(state->remainingChars);
}
} // namespace QtPrivate
/*! /*!
Returns the encoding for the content of \a data if it can be determined. Returns the encoding for the content of \a data if it can be determined.
\a expectedFirstCharacter can be passed as an additional hint to help determine \a expectedFirstCharacter can be passed as an additional hint to help determine
@ -2684,6 +2707,205 @@ QStringList QStringConverter::availableCodecs()
return result; return result;
} }
/*!
\class QStringConverter::FinalizeResultBase
\internal
*/
/*!
\class QStringConverter::FinalizeResultChar
\inmodule QtCore
\since 6.11
\reentrant
\brief Holds the result of calling finalize() on QStringDecoder or
QStringEncoder.
This class is used to relay the result of the finalize() call or the reason
why the call did not succeed.
*/
/*!
\enum QStringConverter::FinalizeResultBase::Error
\value NoError No error.
\value InvalidCharacters The encoder successfully finalized, but encountered
invalid characters either during finalization or some time earlier.
\value NotEnoughSpace finalize() did \e{not} succeed, you must grow the
buffer and call finalize() again.
*/
/*!
\variable QStringConverter::FinalizeResultChar::error
Relays errors discovered during finalization.
*/
/*!
\variable QStringConverter::FinalizeResultChar::next
Points to the character position \e{following} the last-written character.
*/
/*!
\variable QStringConverter::FinalizeResultChar::invalidChars
The number of invalid characters that were previously counted in the state
as well as any that were encountered during the call to finalize().
*/
/*!
\typedef QStringDecoder::FinalizeResult
This is an alias for QStringConverter::FinalizeResultChar<char16_t>.
*/
/*!
\typedef QStringDecoder::FinalizeResultQChar
This is an alias for QStringConverter::FinalizeResultChar<QChar>.
*/
/*!
\fn QStringDecoder::FinalizeResultQChar QStringDecoder::finalize(QChar *out, qsizetype maxlen)
\fn QStringDecoder::FinalizeResult QStringDecoder::finalize(char16_t *out, qsizetype maxlen)
\fn QStringDecoder::FinalizeResult QStringDecoder::finalize()
Signals to the decoder that no further data will arrive.
May also provide data from residual content that was pending decoding.
When there is no residual data to account for, the return's \c error
field will be set to \l {QCharConverter::FinalizeResult::Error::}
{NoError}.
If \a out is supplied and non-null, it must have space in which up to
\a maxlen characters may be written. Up to this many characters of
residual output are written to this space, with the end indicated by
the return-value's \c next field. Typically this residual data shall
consist of one replacement character per remaining unconverted input
character.
If all residual content has been delivered via \a out, if \a out is
\nullptr, or if there is no residual data, the decoder is reset on
return from finalize(). Otherwise, the remaining data can be retrieved
or discarded by a further call to finalize().
\since 6.11
\sa hasError(), appendToBuffer()
*/
auto QStringDecoder::finalize(char16_t *out, qsizetype maxlen) -> FinalizeResult
{
int count = 0;
if (isValid())
count = QtPrivate::partiallyParsedDataCount(&state);
using Error = FinalizeResult::Error;
const qint16 invalidChars = q26::saturate_cast<qint16>(state.invalidChars + count);
if (count == 0 || !out) {
resetState();
return { {}, out, invalidChars, invalidChars ? Error::InvalidCharacters : Error::NoError };
}
if (maxlen < count)
return { {}, out, invalidChars, Error::NotEnoughSpace };
const char16_t replacement = (state.flags & QStringConverter::Flag::ConvertInvalidToNull)
? QChar::Null
: QChar::ReplacementCharacter;
out = std::fill_n(out, count, replacement);
resetState();
return { {}, out, invalidChars, invalidChars ? Error::InvalidCharacters : Error::NoError };
}
/*!
\typedef QStringEncoder::FinalizeResult
This is an alias for QStringConverter::FinalizeResultChar<char>.
*/
/*!
\fn QStringEncoder::FinalizeResult QStringEncoder::finalize(char *out, qsizetype maxlen)
\fn QStringEncoder::FinalizeResult QStringEncoder::finalize()
Signals to the decoder that no further data will arrive.
May also provide data from residual content that was pending decoding.
When there is no residual data to account for, the return's \c error
field will be set to \l {QCharConverter::FinalizeResult::Error::}
{NoError}.
If \a out is supplied and non-null, it must have space in which up to
\a maxlen characters may be written. Up to this many characters of
residual output are written to this space, with the end indicated by
the return-value's \c next field. Typically this residual data shall
consist of one replacement character per remaining unconverted input
character. When using a stateful encoding, such as ISO-2022-JP, this may
also write bytes to restore, or end, the current state in the character
stream.
If all residual content has been delivered via \a out, if \a out is
\nullptr, or if there is no residual data, the decoder is reset on
return from finalize(). Otherwise, the remaining data can be retrieved
or discarded by a further call to finalize().
\since 6.11
\sa hasError(), appendToBuffer()
*/
auto QStringEncoder::finalize(char *out, qsizetype maxlen) -> QStringEncoder::FinalizeResult
{
qsizetype count = 0;
if (isValid())
count = QtPrivate::partiallyParsedDataCount(&state);
// For ICU we may be using a stateful codec that need to restore or finalize
// some state, otherwise we have nothing to do with count == 0
using Error = FinalizeResult::Error;
const bool usesIcu = !!(state.flags & QStringConverter::Flag::UsesIcu) && !!state.d[0];
const qint16 invalidChars = q26::saturate_cast<qint16>(state.invalidChars + count);
if (!isValid() || (!count && !usesIcu) || !out) {
resetState();
return { {}, out, invalidChars, invalidChars ? Error::InvalidCharacters : Error::NoError };
}
if ((false)) {
#if defined(QT_USE_ICU_CODECS)
} else if (usesIcu) {
Q_ASSERT(out);
auto *icu_conv = static_cast<UConverter *>(state.d[0]);
Q_ASSERT(icu_conv); // bool usesIcu checks that the pointer is non-null
UErrorCode err = U_ZERO_ERROR;
UBool flush = true;
// If the QStringConverter was moved, the state that we used as a context is stale now.
UConverterFromUCallback action;
const void *context;
ucnv_getFromUCallBack(icu_conv, &action, &context);
if (context != &state)
ucnv_setFromUCallBack(icu_conv, action, &state, nullptr, nullptr, &err);
const UChar *dummyInput = u"";
const char *outEnd = out + maxlen;
ucnv_fromUnicode(icu_conv, &out, outEnd, &dummyInput, dummyInput, nullptr, flush, &err);
if (err == U_BUFFER_OVERFLOW_ERROR)
return { {}, out, invalidChars, Error::NotEnoughSpace };
resetState();
#endif
} else if (!(state.flags & QStringConverter::Flag::ConvertInvalidToNull)) {
/*
We don't really know (in general) how the replacement character
looks like in the target encoding. So we just encode 0xfffd, which
is the Unicode replacement character.
Use 4 as a best-guess for the upper-bound of how many characters
would potentially be produced by the leftover UTF-16 characters in
the state
*/
constexpr QChar replacementCharacter = QChar::ReplacementCharacter;
constexpr char16_t repl = replacementCharacter.unicode();
constexpr std::array<char16_t, 4> replacement{ repl, repl, repl, repl };
const qsizetype charactersToEncode = std::min(count, qsizetype(replacement.size()));
if (maxlen < requiredSpace(charactersToEncode))
return { {}, out, invalidChars, Error::NotEnoughSpace };
// we don't want the incomplete data in the internal buffer; we're
// flushing the buffer after all
resetState();
out = appendToBuffer(out, QStringView(replacement.data(), charactersToEncode));
} else /* outputting Null characters for each remaining unconverted input character */ {
if (maxlen < count)
return { {}, out, invalidChars, Error::NotEnoughSpace };
out = std::fill_n(out, count, '\0');
resetState();
}
return { {}, out, invalidChars, invalidChars ? Error::InvalidCharacters : Error::NoError };
}
/*! /*!
Tries to determine the encoding of the HTML in \a data by looking at leading byte Tries to determine the encoding of the HTML in \a data by looking at leading byte
order marks or a charset specifier in the HTML meta tag and returns a QStringDecoder order marks or a charset specifier in the HTML meta tag and returns a QStringDecoder

View File

@ -63,6 +63,13 @@ public:
} }
return iface->fromUtf16(out, in, &state); return iface->fromUtf16(out, in, &state);
} }
using FinalizeResult = FinalizeResultChar<char>;
Q_REQUIRED_RESULT
Q_CORE_EXPORT FinalizeResult finalize(char *out, qsizetype maxlen);
Q_REQUIRED_RESULT
FinalizeResult finalize() { return finalize(nullptr, 0); }
private: private:
QByteArray encodeAsByteArray(QStringView in) QByteArray encodeAsByteArray(QStringView in)
{ {
@ -128,6 +135,22 @@ public:
char16_t *appendToBuffer(char16_t *out, QByteArrayView ba) char16_t *appendToBuffer(char16_t *out, QByteArrayView ba)
{ return reinterpret_cast<char16_t *>(appendToBuffer(reinterpret_cast<QChar *>(out), ba)); } { return reinterpret_cast<char16_t *>(appendToBuffer(reinterpret_cast<QChar *>(out), ba)); }
using FinalizeResult = FinalizeResultChar<char16_t>;
using FinalizeResultQChar = FinalizeResultChar<QChar>;
FinalizeResultQChar finalize(QChar *out, qsizetype maxlen)
{
auto r = finalize(reinterpret_cast<char16_t *>(out), maxlen);
return { {}, reinterpret_cast<QChar *>(r.next), r.invalidChars, r.error };
}
Q_REQUIRED_RESULT
Q_CORE_EXPORT FinalizeResult finalize(char16_t *out, qsizetype maxlen);
Q_REQUIRED_RESULT
FinalizeResult finalize()
{
return finalize(static_cast<char16_t *>(nullptr), 0);
}
Q_CORE_EXPORT static QStringDecoder decoderForHtml(QByteArrayView data); Q_CORE_EXPORT static QStringDecoder decoderForHtml(QByteArrayView data);
private: private:

View File

@ -169,6 +169,25 @@ public:
Q_CORE_EXPORT static QStringList availableCodecs(); Q_CORE_EXPORT static QStringList availableCodecs();
struct FinalizeResultBase
{
enum Error : quint8 {
NoError,
InvalidCharacters,
NotEnoughSpace,
};
};
template <typename Char>
struct FinalizeResultChar : FinalizeResultBase
{
using Error = FinalizeResultBase::Error;
Char *next;
qint16 invalidChars;
Error error;
};
protected: protected:
const Interface *iface; const Interface *iface;
State state; State state;

View File

@ -286,8 +286,13 @@ public:
[[nodiscard]] constexpr storage_type front() const { return Q_ASSERT(!empty()), m_data[0]; } [[nodiscard]] constexpr storage_type front() const { return Q_ASSERT(!empty()), m_data[0]; }
[[nodiscard]] constexpr storage_type back() const { return Q_ASSERT(!empty()), m_data[m_size - 1]; } [[nodiscard]] constexpr storage_type back() const { return Q_ASSERT(!empty()), m_data[m_size - 1]; }
[[nodiscard]] Q_IMPLICIT operator std::basic_string_view<storage_type>() const noexcept [[nodiscard]] Q_IMPLICIT operator std::string_view() const noexcept
{ return std::basic_string_view<storage_type>(data(), size_t(size())); } { return std::string_view{reinterpret_cast<const char*>(data()), size_t(size())}; }
#ifdef __cpp_lib_char8_t
[[nodiscard]] Q_IMPLICIT operator std::u8string_view() const noexcept
{ return std::u8string_view{utf8(), size_t(size())}; }
#endif
[[nodiscard]] constexpr qsizetype max_size() const noexcept { return maxSize(); } [[nodiscard]] constexpr qsizetype max_size() const noexcept { return maxSize(); }

View File

@ -735,13 +735,24 @@
*/ */
/*! \fn QUtf8StringView::operator std::basic_string_view<storage_type>() const /*!
\fn QUtf8StringView::operator std::string_view() const
\since 6.7 \since 6.7
Converts this QUtf8StringView object to a Converts this QUtf8StringView object to a
\c{std::basic_string_view} object. The returned view will have the \c{std::string_view} object. The returned view will have the
same data pointer and length of this view. The character type of same data pointer and length as this view.
the returned view will be \c{storage_type}. */
/*!
\fn QUtf8StringView::operator std::u8string_view() const
\since 6.10
Converts this QUtf8StringView object to a \c{std::u8string_view}
object. The returned view will have the same data pointer and length
as this view.
This function is only available when compiling in C++20 mode.
*/ */
/*! /*!

View File

@ -5,7 +5,9 @@
#ifndef QSCOPEGUARD_H #ifndef QSCOPEGUARD_H
#define QSCOPEGUARD_H #define QSCOPEGUARD_H
#include <QtCore/qglobal.h> #include <QtCore/qtclasshelpermacros.h>
#include <QtCore/qcompilerdetection.h>
#include <QtCore/qtconfigmacros.h>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>

View File

@ -100,10 +100,14 @@ if((X11_SUPPORTED) OR QT_FIND_ALL_PACKAGES_ALWAYS)
qt_find_package(XCB 0.3.9 COMPONENTS ICCCM PROVIDED_TARGETS XCB::ICCCM MODULE_NAME gui QMAKE_LIB xcb_icccm) qt_find_package(XCB 0.3.9 COMPONENTS ICCCM PROVIDED_TARGETS XCB::ICCCM MODULE_NAME gui QMAKE_LIB xcb_icccm)
endif() endif()
qt_add_qmake_lib_dependency(xcb_icccm xcb) qt_add_qmake_lib_dependency(xcb_icccm xcb)
if((X11_SUPPORTED) OR QT_FIND_ALL_PACKAGES_ALWAYS)
qt_find_package(XCB 0.3.8 COMPONENTS UTIL PROVIDED_TARGETS XCB::UTIL MODULE_NAME gui QMAKE_LIB xcb_util)
endif()
qt_add_qmake_lib_dependency(xcb_util xcb)
if((X11_SUPPORTED) OR QT_FIND_ALL_PACKAGES_ALWAYS) if((X11_SUPPORTED) OR QT_FIND_ALL_PACKAGES_ALWAYS)
qt_find_package(XCB 0.3.9 COMPONENTS IMAGE PROVIDED_TARGETS XCB::IMAGE MODULE_NAME gui QMAKE_LIB xcb_image) qt_find_package(XCB 0.3.9 COMPONENTS IMAGE PROVIDED_TARGETS XCB::IMAGE MODULE_NAME gui QMAKE_LIB xcb_image)
endif() endif()
qt_add_qmake_lib_dependency(xcb_image xcb_shm xcb) qt_add_qmake_lib_dependency(xcb_image xcb_shm xcb_util xcb)
if((X11_SUPPORTED) OR QT_FIND_ALL_PACKAGES_ALWAYS) if((X11_SUPPORTED) OR QT_FIND_ALL_PACKAGES_ALWAYS)
qt_find_package(XCB 0.3.9 COMPONENTS KEYSYMS PROVIDED_TARGETS XCB::KEYSYMS MODULE_NAME gui QMAKE_LIB xcb_keysyms) qt_find_package(XCB 0.3.9 COMPONENTS KEYSYMS PROVIDED_TARGETS XCB::KEYSYMS MODULE_NAME gui QMAKE_LIB xcb_keysyms)
endif() endif()
@ -555,6 +559,7 @@ qt_config_compile_test(xcb_syslibs
LIBRARIES LIBRARIES
XCB::CURSOR XCB::CURSOR
XCB::ICCCM XCB::ICCCM
XCB::UTIL
XCB::IMAGE XCB::IMAGE
XCB::KEYSYMS XCB::KEYSYMS
XCB::RANDR XCB::RANDR
@ -570,6 +575,7 @@ qt_config_compile_test(xcb_syslibs
"// xkb.h is using a variable called 'explicit', which is a reserved keyword in C++ "// xkb.h is using a variable called 'explicit', which is a reserved keyword in C++
#define explicit dont_use_cxx_explicit #define explicit dont_use_cxx_explicit
#include <xcb/xcb.h> #include <xcb/xcb.h>
#include <xcb/xcb_util.h>
#include <xcb/xcb_image.h> #include <xcb/xcb_image.h>
#include <xcb/xcb_keysyms.h> #include <xcb/xcb_keysyms.h>
#include <xcb/xcb_cursor.h> #include <xcb/xcb_cursor.h>

View File

@ -28,8 +28,9 @@
\ingroup qt-basic-concepts \ingroup qt-basic-concepts
Qt's paint system enables painting on screen and print devices Qt's paint system provides a unified and flexible framework for
using the same API, and is primarily based on the QPainter, rendering graphics on various surfaces, such as on-screen widgets,
images, and printed pages. It is primarily built around the QPainter,
QPaintDevice, and QPaintEngine classes. QPaintDevice, and QPaintEngine classes.
QPainter is used to perform drawing operations, QPaintDevice is an QPainter is used to perform drawing operations, QPaintDevice is an
@ -242,8 +243,7 @@
Any color in Qt is represented by the QColor class which supports Any color in Qt is represented by the QColor class which supports
the RGB, HSV and CMYK color models. QColor also support the RGB, HSV and CMYK color models. QColor also support
alpha-blended outlining and filling (specifying the transparency alpha-blended outlining and filling (specifying the transparency
effect), and the class is platform and device independent (the effect), and the class is platform and device independent. For more
colors are mapped to hardware using the QColormap class). For more
information, see the QColor class documentation. information, see the QColor class documentation.
The available fill patterns are described by the Qt::BrushStyle The available fill patterns are described by the Qt::BrushStyle

View File

@ -411,8 +411,7 @@ static QStringList get_colornames()
of the provided QRgb, and the qGray() function calculates and of the provided QRgb, and the qGray() function calculates and
return a gray value based on the given value. return a gray value based on the given value.
QColor is platform and device independent. The QColormap class QColor is platform and device independent.
maps the color to the hardware.
For more information about painting in general, see the \l{Paint For more information about painting in general, see the \l{Paint
System} documentation. System} documentation.

View File

@ -16,7 +16,6 @@ QT_BEGIN_NAMESPACE
class QColor; class QColor;
class QColormap;
class QVariant; class QVariant;
#ifndef QT_NO_DEBUG_STREAM #ifndef QT_NO_DEBUG_STREAM
@ -256,7 +255,6 @@ private:
ushort array[5]; ushort array[5];
} ct; } ct;
friend class QColormap;
#ifndef QT_NO_DATASTREAM #ifndef QT_NO_DATASTREAM
friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QColor &); friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QColor &);
friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QColor &); friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QColor &);

View File

@ -936,16 +936,17 @@ Q_LOGGING_CATEGORY(QRHI_LOG_RUB, "qt.rhi.rub")
avoided as it will not be supported by all backends. The maximum patch avoided as it will not be supported by all backends. The maximum patch
control point count portable between backends is 32. control point count portable between backends is 32.
\value GeometryShader Indicates that the geometry shader stage is \value GeometryShader Indicates that the geometry shader stage is supported.
supported. When supported, a geometry shader can be specified in the When supported, a geometry shader can be specified in the QRhiShaderStage
QRhiShaderStage list. Geometry Shaders are considered an experimental list. Geometry Shaders are considered an experimental feature in QRhi and
feature in QRhi and can only be expected to be supported with Vulkan, can only be expected to be supported with Vulkan, Direct 3D 11 and 12,
Direct 3D, OpenGL (3.2+) and OpenGL ES (3.2+), assuming the implementation OpenGL (3.2+) and OpenGL ES (3.2+), assuming the implementation reports it
reports it as supported at run time. Geometry shaders have portability as supported at run time. Starting with Qt 6.11 geometry shaders are
issues between APIs, and therefore no guarantees can be given for a automatically translated to HLSL, and therefore no injection of handwritten
universal solution. They will never be supported with Metal. Whereas with HLSL geometry shaders is necessary anymore (but note that gl_in and
Direct 3D a handwritten HLSL geometry shader must be injected into each expressions such as gl_in[0].gl_Position are not supported; rather, pass the
QShader for the geometry stage since qsb cannot generate this from SPIR-V. position as an output variable from the vertex shader). Geometry shaders are
not supported with Metal.
\value TextureArrayRange Indicates that for \value TextureArrayRange Indicates that for
\l{QRhi::newTextureArray()}{texture arrays} it is possible to specify a \l{QRhi::newTextureArray()}{texture arrays} it is possible to specify a

View File

@ -388,6 +388,20 @@ void QTextFormatPrivate::recalcFont() const
case QTextFormat::FontKerning: case QTextFormat::FontKerning:
f.setKerning(props.at(i).value.toBool()); f.setKerning(props.at(i).value.toBool());
break; break;
case QTextFormat::FontFeatures:
{
const auto fontFeatures = props.at(i).value.value<QHash<QFont::Tag, quint32>>();
for (auto it = fontFeatures.constBegin(); it != fontFeatures.constEnd(); ++it)
f.setFeature(it.key(), it.value());
break;
}
case QTextFormat::FontVariableAxes:
{
const auto fontVariableAxes = props.at(i).value.value<QHash<QFont::Tag, float>>();
for (auto it = fontVariableAxes.constBegin(); it != fontVariableAxes.constEnd(); ++it)
f.setVariableAxis(it.key(), it.value());
break;
}
default: default:
break; break;
} }
@ -404,6 +418,16 @@ void QTextFormatPrivate::recalcFont() const
Q_GUI_EXPORT QDataStream &operator<<(QDataStream &stream, const QTextFormat &fmt) Q_GUI_EXPORT QDataStream &operator<<(QDataStream &stream, const QTextFormat &fmt)
{ {
QMap<int, QVariant> properties = fmt.properties(); QMap<int, QVariant> properties = fmt.properties();
if (stream.version() < QDataStream::Qt_6_11) {
auto it = properties.constFind(QTextFormat::FontFeatures);
if (it != properties.cend())
properties.erase(it);
it = properties.constFind(QTextFormat::FontVariableAxes);
if (it != properties.cend())
properties.erase(it);
}
if (stream.version() < QDataStream::Qt_6_0) { if (stream.version() < QDataStream::Qt_6_0) {
auto it = properties.constFind(QTextFormat::FontLetterSpacingType); auto it = properties.constFind(QTextFormat::FontLetterSpacingType);
if (it != properties.cend()) { if (it != properties.cend()) {
@ -447,14 +471,17 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextFormat &fmt)
for (QMap<qint32, QVariant>::ConstIterator it = properties.constBegin(); for (QMap<qint32, QVariant>::ConstIterator it = properties.constBegin();
it != properties.constEnd(); ++it) { it != properties.constEnd(); ++it) {
qint32 key = it.key(); qint32 key = it.key();
if (key == QTextFormat::OldFontLetterSpacingType)
key = QTextFormat::FontLetterSpacingType; if (stream.version() < QDataStream::Qt_6_0) {
else if (key == QTextFormat::OldFontStretch) if (key == QTextFormat::OldFontLetterSpacingType)
key = QTextFormat::FontStretch; key = QTextFormat::FontLetterSpacingType;
else if (key == QTextFormat::OldTextUnderlineColor) else if (key == QTextFormat::OldFontStretch)
key = QTextFormat::TextUnderlineColor; key = QTextFormat::FontStretch;
else if (key == QTextFormat::OldFontFamily) else if (key == QTextFormat::OldTextUnderlineColor)
key = QTextFormat::FontFamilies; key = QTextFormat::TextUnderlineColor;
else if (key == QTextFormat::OldFontFamily)
key = QTextFormat::FontFamilies;
}
fmt.d->insertProperty(key, it.value()); fmt.d->insertProperty(key, it.value());
} }
@ -653,6 +680,10 @@ Q_GUI_EXPORT QDataStream &operator>>(QDataStream &stream, QTextTableCellFormat &
\value FontKerning Specifies whether the font has kerning turned on. \value FontKerning Specifies whether the font has kerning turned on.
\value FontHintingPreference Controls the use of hinting according to values \value FontHintingPreference Controls the use of hinting according to values
of the QFont::HintingPreference enum. of the QFont::HintingPreference enum.
\value FontFeatures [since 6.11] Assigns integer numbers to typographical features. See
\l{QFont::setFeature()} for additional information.
\value FontVariableAxes [since 6.11] Assigns floating point numbers to variable axes in variable
fonts. See \l{QFont::setVariableAxis()} for additional information.
\omitvalue FirstFontProperty \omitvalue FirstFontProperty
\omitvalue LastFontProperty \omitvalue LastFontProperty
@ -1809,6 +1840,55 @@ void QTextCharFormat::setUnderlineStyle(UnderlineStyle style)
\sa font(), QFont::hintingPreference() \sa font(), QFont::hintingPreference()
*/ */
/*!
\since 6.11
Sets the typographical features of the text format's font to be \a fontFeatures.
\sa QFont::setFeature()
*/
void QTextCharFormat::setFontFeatures(const QHash<QFont::Tag, quint32> &fontFeatures)
{
setProperty(FontFeatures, QVariant::fromValue(fontFeatures));
}
/*!
\since 6.11
Gets the typographical features of the text format's font.
\sa setFontFeatures()
*/
QHash<QFont::Tag, quint32> QTextCharFormat::fontFeatures() const
{
return property(FontFeatures).value<QHash<QFont::Tag, quint32>>();
}
/*!
\since 6.11
Sets the variable axes of the text format's font to be \a fontVariableAxes.
\sa QFont::setVariableAxis()
*/
void QTextCharFormat::setFontVariableAxes(const QHash<QFont::Tag, float> &fontVariableAxes)
{
setProperty(FontVariableAxes, QVariant::fromValue(fontVariableAxes));
}
/*!
\since 6.11
Gets the variable axes of the text format's font.
\sa setFontVariableAxes()
*/
QHash<QFont::Tag, float> QTextCharFormat::fontVariableAxes() const
{
return property(FontVariableAxes).value<QHash<QFont::Tag, float>>();
}
/*! /*!
\fn QPen QTextCharFormat::textOutline() const \fn QPen QTextCharFormat::textOutline() const
@ -2145,6 +2225,22 @@ void QTextCharFormat::setFont(const QFont &font, FontPropertiesInheritanceBehavi
setFontHintingPreference(font.hintingPreference()); setFontHintingPreference(font.hintingPreference());
if (mask & QFont::KerningResolved) if (mask & QFont::KerningResolved)
setFontKerning(font.kerning()); setFontKerning(font.kerning());
if (mask & QFont::FeaturesResolved) {
const auto tags = font.featureTags();
QHash<QFont::Tag, quint32> fontFeatures;
for (QFont::Tag tag : tags)
fontFeatures.insert(tag, font.featureValue(tag));
setFontFeatures(fontFeatures);
}
if (mask & QFont::VariableAxesResolved) {
const auto tags = font.variableAxisTags();
QHash<QFont::Tag, float> fontVariableAxes;
for (QFont::Tag tag : tags)
fontVariableAxes.insert(tag, font.variableAxisValue(tag));
setFontVariableAxes(fontVariableAxes);
}
} }
/*! /*!

View File

@ -14,6 +14,7 @@
#include <QtCore/qlist.h> #include <QtCore/qlist.h>
#include <QtCore/qshareddata.h> #include <QtCore/qshareddata.h>
#include <QtCore/qvariant.h> #include <QtCore/qvariant.h>
#include <QtCore/qhash.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -159,7 +160,9 @@ public:
FontStrikeOut = 0x2007, FontStrikeOut = 0x2007,
FontFixedPitch = 0x2008, FontFixedPitch = 0x2008,
FontPixelSize = 0x2009, FontPixelSize = 0x2009,
LastFontProperty = FontPixelSize, FontFeatures = 0x2010, // Note: Same as OldTextUnderlineColor
FontVariableAxes = 0x2011,
LastFontProperty = FontVariableAxes,
TextUnderlineColor = 0x2020, TextUnderlineColor = 0x2020,
TextVerticalAlignment = 0x2021, TextVerticalAlignment = 0x2021,
@ -518,6 +521,11 @@ public:
return static_cast<QFont::HintingPreference>(intProperty(FontHintingPreference)); return static_cast<QFont::HintingPreference>(intProperty(FontHintingPreference));
} }
void setFontFeatures(const QHash<QFont::Tag, quint32> &fontFeatures);
QHash<QFont::Tag, quint32> fontFeatures() const;
void setFontVariableAxes(const QHash<QFont::Tag, float> &fontVariableAxes);
QHash<QFont::Tag, float> fontVariableAxes() const;
inline void setFontKerning(bool enable) inline void setFontKerning(bool enable)
{ setProperty(FontKerning, enable); } { setProperty(FontKerning, enable); }
inline bool fontKerning() const inline bool fontKerning() const

View File

@ -385,6 +385,7 @@ qt_internal_extend_target(Network CONDITION QT_FEATURE_ocsp AND QT_FEATURE_opens
qt_internal_add_docs(Network qt_internal_add_docs(Network
doc/qtnetwork.qdocconf doc/qtnetwork.qdocconf
SKIP_JAVADOC
) )
# See mkspecs/common/msvc-desktop.conf # See mkspecs/common/msvc-desktop.conf

View File

@ -1380,7 +1380,7 @@ int QNativeSocketEnginePrivate::nativeSelect(QDeadlineTimer deadline, bool check
} }
static const short read_flags = POLLIN | POLLHUP | POLLERR; static const short read_flags = POLLIN | POLLHUP | POLLERR;
static const short write_flags = POLLOUT | POLLERR; static const short write_flags = POLLOUT | POLLHUP | POLLERR;
*selectForRead = ((pfd.revents & read_flags) != 0); *selectForRead = ((pfd.revents & read_flags) != 0);
*selectForWrite = ((pfd.revents & write_flags) != 0); *selectForWrite = ((pfd.revents & write_flags) != 0);

View File

@ -19,6 +19,57 @@ QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcAndroidBackendRegister) Q_DECLARE_LOGGING_CATEGORY(lcAndroidBackendRegister)
/*
\internal
This class is used to [un]register QJniObjects which implement specific interfaces. These
objects can then be fetched or directly called by using that interface.
This is intended to decouple the Qt C++ code from the underlying Java implementation, as Qt now
has multiple separate usecases, each of which may have different implementations and support
different features.
To use this register, the interface must be declared as a JNI class via Q_DECLARE_JNI_CLASS:
Q_DECLARE_JNI_CLASS(ImaginaryInterface, "org/qtproject/qt/android/ImaginaryInterface")
Where ImaginaryInterface is a Java interface like this:
@UsedFromNativeCode
interface ImaginaryInterface {
void doSomething(int imaginary, int imaginary2);
}
After that, the features provided by that interface can be used in the C++ code in two ways:
Use the convenience method callInterface() to call a method directly:
AndroidBackendRegister *reg = QtAndroid::backendRegister();
int imaginary, imaginary2;
reg->callInterface<QtJniTypes::ImaginaryInterface, void>("doSomething", imaginary, imaginary2);
Or get the QJniObject directly and use it as you would any other QJniObject:
AndroidBackendRegister *reg = QtAndroid::backendRegister();
auto imaginary = reg->getInterface<QtJniTypes::ImaginaryInterface>();
// ... do whatever with QJniObject
In order to register a new interface on the Java side, the BackendRegister class must be used,
with its native functions registerBackend() and unregisterBackend():
BackendRegister.registerBackend(ImaginaryInterface.class, imaginaryInterfaceObject);
and
BackendRegister.unregisterBackend(ImaginaryInterface.class);
Note that only one object can be registered for each interface. If multiple objects are
registered, only the latest one is kept. Thus, you only need to declare the interface you want
to unregister, not the object that implements the interface as well.
If the interface needs to be available as soon as possible, it should be registered immediately
after Qt has started, by using the QtNative app state listener functionality.
*/
template <typename T> template <typename T>
using ValidInterfaceType = std::enable_if_t<std::is_base_of_v<QtJniTypes::JObjectBase, T>, bool>; using ValidInterfaceType = std::enable_if_t<std::is_base_of_v<QtJniTypes::JObjectBase, T>, bool>;
@ -27,6 +78,13 @@ class AndroidBackendRegister
public: public:
static bool registerNatives(); static bool registerNatives();
/*
\internal
Returns a QJniObject which is registered for the given interface.
Requires the type of the requested interface to be registered via
Q_DECLARE_JNI_CLASS. (see ValidInterfaceType).
*/
template <typename T, ValidInterfaceType<T> = true> template <typename T, ValidInterfaceType<T> = true>
[[nodiscard]] T getInterface() [[nodiscard]] T getInterface()
{ {
@ -39,7 +97,15 @@ public:
typename std::disjunction<std::is_base_of<QJniObject, Object>, typename std::disjunction<std::is_base_of<QJniObject, Object>,
std::is_base_of<QtJniTypes::JObjectBase, Object>>; std::is_base_of<QtJniTypes::JObjectBase, Object>>;
template <typename Interface, typename Ret, typename... Args, /*
\internal
Convenience function that calls getInterface<Interface>() and then QJniObject::callMethod()
on the resulting object, forwarding the rest of the parameters to that function.
If the interface is not registered, a warning is printed and an empty object is returned.
*/
template <typename Interface, typename Ret = void, typename... Args,
ValidInterfaceType<Interface> = true> ValidInterfaceType<Interface> = true>
auto callInterface(const char *func, Args... args) auto callInterface(const char *func, Args... args)
{ {

View File

@ -58,14 +58,14 @@ namespace QtAndroidInput
void resetSoftwareKeyboard() void resetSoftwareKeyboard()
{ {
AndroidBackendRegister *reg = QtAndroid::backendRegister(); AndroidBackendRegister *reg = QtAndroid::backendRegister();
reg->callInterface<QtJniTypes::QtInputInterface, void>("resetSoftwareKeyboard"); reg->callInterface<QtJniTypes::QtInputInterface>("resetSoftwareKeyboard");
qCDebug(lcQpaInputMethods) << "@@@ RESETSOFTWAREKEYBOARD"; qCDebug(lcQpaInputMethods) << "@@@ RESETSOFTWAREKEYBOARD";
} }
void hideSoftwareKeyboard() void hideSoftwareKeyboard()
{ {
AndroidBackendRegister *reg = QtAndroid::backendRegister(); AndroidBackendRegister *reg = QtAndroid::backendRegister();
reg->callInterface<QtJniTypes::QtInputInterface, void>("hideSoftwareKeyboard"); reg->callInterface<QtJniTypes::QtInputInterface>("hideSoftwareKeyboard");
qCDebug(lcQpaInputMethods) << "@@@ HIDESOFTWAREKEYBOARD"; qCDebug(lcQpaInputMethods) << "@@@ HIDESOFTWAREKEYBOARD";
} }

View File

@ -183,7 +183,7 @@ namespace QtAndroid
#if QT_CONFIG(accessibility) #if QT_CONFIG(accessibility)
void initializeAccessibility() void initializeAccessibility()
{ {
m_backendRegister->callInterface<QtJniTypes::QtAccessibilityInterface, void>( m_backendRegister->callInterface<QtJniTypes::QtAccessibilityInterface>(
"initializeAccessibility"); "initializeAccessibility");
} }

View File

@ -48,13 +48,13 @@ namespace QtAndroidMenu
void resetMenuBar() void resetMenuBar()
{ {
AndroidBackendRegister *reg = QtAndroid::backendRegister(); AndroidBackendRegister *reg = QtAndroid::backendRegister();
reg->callInterface<QtJniTypes::QtMenuInterface, void>("resetOptionsMenu"); reg->callInterface<QtJniTypes::QtMenuInterface>("resetOptionsMenu");
} }
void openOptionsMenu() void openOptionsMenu()
{ {
AndroidBackendRegister *reg = QtAndroid::backendRegister(); AndroidBackendRegister *reg = QtAndroid::backendRegister();
reg->callInterface<QtJniTypes::QtMenuInterface, void>("openOptionsMenu"); reg->callInterface<QtJniTypes::QtMenuInterface>("openOptionsMenu");
} }
void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect) void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect)
@ -75,7 +75,7 @@ namespace QtAndroidMenu
QMutexLocker lock(&visibleMenuMutex); QMutexLocker lock(&visibleMenuMutex);
if (visibleMenu == menu) { if (visibleMenu == menu) {
AndroidBackendRegister *reg = QtAndroid::backendRegister(); AndroidBackendRegister *reg = QtAndroid::backendRegister();
reg->callInterface<QtJniTypes::QtMenuInterface, void>("closeContextMenu"); reg->callInterface<QtJniTypes::QtMenuInterface>("closeContextMenu");
pendingContextMenus.clear(); pendingContextMenus.clear();
} else { } else {
pendingContextMenus.removeOne(menu); pendingContextMenus.removeOne(menu);

View File

@ -454,7 +454,7 @@ void QWasmAccessibility::setHtmlElementVisibility(QAccessibleInterface *iface, b
container.call<void>("appendChild", element); container.call<void>("appendChild", element);
visible = visible && !iface->state().invisible && !iface->state().disabled; visible = visible && !iface->state().invisible;
setProperty(element, "ariaHidden", !visible); // ariaHidden mean completely hidden; maybe some sort of soft-hidden should be used. setProperty(element, "ariaHidden", !visible); // ariaHidden mean completely hidden; maybe some sort of soft-hidden should be used.
} }
@ -513,6 +513,12 @@ void QWasmAccessibility::setHtmlElementFocus(QAccessibleInterface *iface)
element.call<void>("focus"); element.call<void>("focus");
} }
void QWasmAccessibility::setHtmlElementDisabled(QAccessibleInterface *iface)
{
auto element = ensureHtmlElement(iface);
setAttribute(element, "aria-disabled", iface->state().disabled);
}
void QWasmAccessibility::handleStaticTextUpdate(QAccessibleEvent *event) void QWasmAccessibility::handleStaticTextUpdate(QAccessibleEvent *event)
{ {
switch (event->type()) { switch (event->type()) {
@ -677,6 +683,7 @@ void QWasmAccessibility::populateAccessibilityTree(QAccessibleInterface *iface)
setHtmlElementVisibility(iface, true); setHtmlElementVisibility(iface, true);
setHtmlElementGeometry(iface); setHtmlElementGeometry(iface);
setHtmlElementTextName(iface); setHtmlElementTextName(iface);
setHtmlElementDisabled(iface);
handleIdentifierUpdate(iface); handleIdentifierUpdate(iface);
handleDescriptionChanged(iface); handleDescriptionChanged(iface);
} }
@ -853,6 +860,12 @@ void QWasmAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
// Handle some common event types. See // Handle some common event types. See
// https://doc.qt.io/qt-5/qaccessible.html#Event-enum // https://doc.qt.io/qt-5/qaccessible.html#Event-enum
switch (event->type()) { switch (event->type()) {
case QAccessible::StateChanged: {
QAccessibleStateChangeEvent *stateChangeEvent = (QAccessibleStateChangeEvent *)event;
if (stateChangeEvent->changedStates().disabled)
setHtmlElementDisabled(iface);
} break;
case QAccessible::DescriptionChanged: case QAccessible::DescriptionChanged:
handleDescriptionChanged(iface); handleDescriptionChanged(iface);
return; return;

View File

@ -58,6 +58,7 @@ private:
void setHtmlElementTextName(QAccessibleInterface *iface); void setHtmlElementTextName(QAccessibleInterface *iface);
void setHtmlElementTextNameLE(QAccessibleInterface *iface); void setHtmlElementTextNameLE(QAccessibleInterface *iface);
void setHtmlElementFocus(QAccessibleInterface *iface); void setHtmlElementFocus(QAccessibleInterface *iface);
void setHtmlElementDisabled(QAccessibleInterface *iface);
void handleStaticTextUpdate(QAccessibleEvent *event); void handleStaticTextUpdate(QAccessibleEvent *event);
void handleButtonUpdate(QAccessibleEvent *event); void handleButtonUpdate(QAccessibleEvent *event);

View File

@ -133,7 +133,8 @@ QWaylandDataControlSourceV1::QWaylandDataControlSourceV1(QWaylandDataControlMana
{ {
if (!mimeData) if (!mimeData)
return; return;
for (auto &format : mimeData->formats()) const auto formats = QInternalMimeData::formatsHelper(mimeData);
for (const QString &format : formats)
offer(format); offer(format);
} }

View File

@ -704,7 +704,7 @@ void QWaylandWindow::applyConfigureWhenPossible()
{ {
if (!mWaitingToApplyConfigure) { if (!mWaitingToApplyConfigure) {
mWaitingToApplyConfigure = true; mWaitingToApplyConfigure = true;
QMetaObject::invokeMethod(this, "applyConfigure", Qt::QueuedConnection); QMetaObject::invokeMethod(this, &QWaylandWindow::applyConfigure, Qt::QueuedConnection);
} }
} }
@ -725,8 +725,11 @@ void QWaylandWindow::applyConfigure()
mShellSurface->applyConfigure(); mShellSurface->applyConfigure();
mWaitingToApplyConfigure = false; mWaitingToApplyConfigure = false;
QRect exposeGeometry(QPoint(), geometry().size()); if (mExposed)
sendExposeEvent(exposeGeometry); sendExposeEvent(QRect(QPoint(), geometry().size()));
else
// we still need to commit the configured ack for a hidden surface
commit();
} }
void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y)
@ -881,7 +884,6 @@ bool QWaylandWindow::waitForFrameSync(int timeout)
if (mWaitingForFrameCallback) { if (mWaitingForFrameCallback) {
qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed"; qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed";
mFrameCallbackTimedOut = true; mFrameCallbackTimedOut = true;
mWaitingForUpdate = false;
QMetaObject::invokeMethod(this, &QWaylandWindow::updateExposure, Qt::QueuedConnection); QMetaObject::invokeMethod(this, &QWaylandWindow::updateExposure, Qt::QueuedConnection);
} }
@ -1744,7 +1746,6 @@ void QWaylandWindow::timerEvent(QTimerEvent *event)
qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed"; qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed";
mFrameCallbackTimedOut = true; mFrameCallbackTimedOut = true;
mWaitingForUpdate = false;
updateExposure(); updateExposure();
} }
@ -1760,13 +1761,6 @@ void QWaylandWindow::requestUpdate()
return; return;
} }
// If we've already called deliverUpdateRequest(), but haven't seen any attach+commit/swap yet
// This is a somewhat redundant behavior and might indicate a bug in the calling code, so log
// here so we can get this information when debugging update/frame callback issues.
// Continue as nothing happened, though.
if (mWaitingForUpdate)
qCDebug(lcWaylandBackingstore) << "requestUpdate called twice without committing anything";
// Some applications (such as Qt Quick) depend on updates being delivered asynchronously, // Some applications (such as Qt Quick) depend on updates being delivered asynchronously,
// so use invokeMethod to delay the delivery a bit. // so use invokeMethod to delay the delivery a bit.
QMetaObject::invokeMethod(this, [this] { QMetaObject::invokeMethod(this, [this] {
@ -1804,7 +1798,6 @@ void QWaylandWindow::handleUpdate()
wl_proxy_wrapper_destroy(wrappedSurface); wl_proxy_wrapper_destroy(wrappedSurface);
wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this); wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this);
mWaitingForFrameCallback = true; mWaitingForFrameCallback = true;
mWaitingForUpdate = false;
// Start a timer for handling the case when the compositor stops sending frame callbacks. // Start a timer for handling the case when the compositor stops sending frame callbacks.
if (mFrameCallbackTimeout > 0) { if (mFrameCallbackTimeout > 0) {
@ -1823,7 +1816,6 @@ void QWaylandWindow::handleUpdate()
void QWaylandWindow::deliverUpdateRequest() void QWaylandWindow::deliverUpdateRequest()
{ {
qCDebug(lcWaylandBackingstore) << "deliverUpdateRequest"; qCDebug(lcWaylandBackingstore) << "deliverUpdateRequest";
mWaitingForUpdate = true;
QPlatformWindow::deliverUpdateRequest(); QPlatformWindow::deliverUpdateRequest();
} }

View File

@ -314,8 +314,6 @@ protected:
QMutex mFrameSyncMutex; QMutex mFrameSyncMutex;
QWaitCondition mFrameSyncWait; QWaitCondition mFrameSyncWait;
// True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer
std::atomic_bool mWaitingForUpdate = false;
bool mExposed = false; bool mExposed = false;
std::atomic_bool mExposeEventNeedsAttachedBuffer = false; std::atomic_bool mExposeEventNeedsAttachedBuffer = false;

View File

@ -52,6 +52,7 @@ qt_internal_add_module(XcbQpaPrivate
Qt::GuiPrivate Qt::GuiPrivate
XCB::CURSOR XCB::CURSOR
XCB::ICCCM XCB::ICCCM
XCB::UTIL
XCB::IMAGE XCB::IMAGE
XCB::KEYSYMS XCB::KEYSYMS
XCB::RANDR XCB::RANDR

View File

@ -1 +1 @@
set(QT_REPO_MODULE_VERSION "6.10.0") set(QT_REPO_MODULE_VERSION "6.11.0")

View File

@ -503,6 +503,143 @@ void blockUnixSignals()
pthread_sigmask(SIG_BLOCK, &set, nullptr); pthread_sigmask(SIG_BLOCK, &set, nullptr);
} }
static std::string_view unixSignalCodeToName(int signo, int code) noexcept
{
switch (signo) {
case SIGFPE:
switch (code) {
#ifdef FPE_INTDIV
case FPE_INTDIV: return "FPE_INTDIV"; // Integer divide by zero.
#endif
#ifdef FPE_INTOVF
case FPE_INTOVF: return "FPE_INTOVF"; // Integer overflow.
#endif
#ifdef FPE_FLTDIV
case FPE_FLTDIV: return "FPE_FLTDIV"; // Floating point divide by zero.
#endif
#ifdef FPE_FLTOVF
case FPE_FLTOVF: return "FPE_FLTOVF"; // Floating point overflow.
#endif
#ifdef FPE_FLTUND
case FPE_FLTUND: return "FPE_FLTUND"; // Floating point underflow.
#endif
#ifdef FPE_FLTRES
case FPE_FLTRES: return "FPE_FLTRES"; // Floating point inexact result.
#endif
#ifdef FPE_FLTINV
case FPE_FLTINV: return "FPE_FLTINV"; // Floating point invalid operation.
#endif
#ifdef FPE_FLTSUB
case FPE_FLTSUB: return "FPE_FLTSUB"; // Subscript out of range.
#endif
#ifdef FPE_FLTUNK
case FPE_FLTUNK: return "FPE_FLTUNK"; // Undiagnosed floating-point exception.
#endif
#ifdef FPE_CONDTRAP
case FPE_CONDTRAP: return "FPE_CONDTRAP"; // Trap on condition.
#endif
}
break;
case SIGILL:
switch (code) {
#ifdef ILL_ILLOPC
case ILL_ILLOPC: return "ILL_ILLOPC"; // Illegal opcode.
#endif
#ifdef ILL_ILLOPN
case ILL_ILLOPN: return "ILL_ILLOPN"; // Illegal operand.
#endif
#ifdef ILL_ILLADR
case ILL_ILLADR: return "ILL_ILLADR"; // Illegal addressing mode.
#endif
#ifdef ILL_ILLTRP
case ILL_ILLTRP: return "ILL_ILLTRP"; // Illegal trap.
#endif
#ifdef ILL_PRVOPC
case ILL_PRVOPC: return "ILL_PRVOPC"; // Privileged opcode.
#endif
#ifdef ILL_PRVREG
case ILL_PRVREG: return "ILL_PRVREG"; // Privileged register.
#endif
#ifdef ILL_COPROC
case ILL_COPROC: return "ILL_COPROC"; // Coprocessor error.
#endif
#ifdef ILL_BADSTK
case ILL_BADSTK: return "ILL_BADSTK"; // Internal stack error.
#endif
#ifdef ILL_BADIADDR
case ILL_BADIADDR: return "ILL_BADIADDR"; // Unimplemented instruction address.
#endif
}
break;
case SIGSEGV:
switch (code) {
#ifdef SEGV_MAPERR
case SEGV_MAPERR: return "SEGV_MAPERR"; // Address not mapped to object.
#endif
#ifdef SEGV_ACCERR
case SEGV_ACCERR: return "SEGV_ACCERR"; // Invalid permissions for mapped object.
#endif
#ifdef SEGV_BNDERR
// Intel MPX - deprecated
case SEGV_BNDERR: return "SEGV_BNDERR"; // Bounds checking failure.
#endif
#ifdef SEGV_PKUERR
// Intel PKRU
case SEGV_PKUERR: return "SEGV_PKUERR"; // Protection key checking failure.
#endif
#ifdef Q_PROCESSOR_SPARC
// these seem to be Sparc-specific on Linux
# ifdef SEGV_ACCADI
case SEGV_ACCADI: return "SEGV_ACCADI"; // ADI not enabled for mapped object.
# endif
# ifdef SEGV_ADIDERR
case SEGV_ADIDERR: return "SEGV_ADIDERR"; // Disrupting MCD error.
# endif
# ifdef SEGV_ADIPERR
case SEGV_ADIPERR: return "SEGV_ADIPERR"; // Precise MCD exception.
# endif
#endif
#ifdef Q_PROCESSOR_ARM
# ifdef SEGV_MTEAERR
case SEGV_MTEAERR: return "SEGV_MTEAERR"; // Asynchronous ARM MTE error.
# endif
# ifdef SEGV_MTESERR
case SEGV_MTESERR: return "SEGV_MTESERR"; // Synchronous ARM MTE exception.
# endif
#endif
#ifdef SEGV_CPERR
// seen on both AArch64 and x86 Linux
case SEGV_CPERR: return "SEGV_CPERR"; // Control protection fault
#endif
}
break;
case SIGBUS:
switch (code) {
#ifdef BUS_ADRALN
case BUS_ADRALN: return "BUS_ADRALN"; // Invalid address alignment.
#endif
#ifdef BUS_ADRERR
case BUS_ADRERR: return "BUS_ADRERR"; // Non-existant physical address.
#endif
#ifdef BUS_OBJERR
case BUS_OBJERR: return "BUS_OBJERR"; // Object specific hardware error.
#endif
#ifdef BUS_MCEERR_AR
case BUS_MCEERR_AR: return "BUS_MCEERR_AR"; // Hardware memory error: action required.
#endif
#ifdef BUS_MCEERR_AO
case BUS_MCEERR_AO: return "BUS_MCEERR_AO"; // Hardware memory error: action optional.
#endif
}
break;
}
return {};
}
template <typename T> static template <typename T> static
std::enable_if_t<sizeof(std::declval<T>().si_pid) + sizeof(std::declval<T>().si_uid) >= 1> std::enable_if_t<sizeof(std::declval<T>().si_pid) + sizeof(std::declval<T>().si_uid) >= 1>
printSentSignalInfo(T *info) printSentSignalInfo(T *info)
@ -519,7 +656,9 @@ printCrashingSignalInfo(T *info, quintptr pc)
auto toHexString = [](quintptr u, HexString &&r = {}) { auto toHexString = [](quintptr u, HexString &&r = {}) {
return asyncSafeToHexString(u, r.data()); return asyncSafeToHexString(u, r.data());
}; };
writeToStderr(", code ", asyncSafeToString(info->si_code));
std::string_view name = unixSignalCodeToName(info->si_signo, info->si_code);
writeToStderr(", code ", name.size() ? name : asyncSafeToString(info->si_code));
if (pc) if (pc)
writeToStderr(", at instruction address ", toHexString(pc)); writeToStderr(", at instruction address ", toHexString(pc));
writeToStderr(", accessing address ", toHexString(quintptr(info->si_addr))); writeToStderr(", accessing address ", toHexString(quintptr(info->si_addr)));

View File

@ -3777,25 +3777,84 @@ int generateJavaQmlComponents(const Options &options)
if (methodData["methodType"_L1] != 0) if (methodData["methodType"_L1] != 0)
return; return;
const QJsonArray parameters = methodData["parameters"_L1].toArray(); const QJsonArray parameters = methodData["parameters"_L1].toArray();
if (parameters.size() > 1)
return;
const QString methodName = methodData["name"_L1].toString(); const QString methodName = methodData["name"_L1].toString();
if (methodName.isEmpty()) if (methodName.isEmpty())
return; return;
const QString upperMethodName = firstCharToUpper(methodName);
const QString typeName = !parameters.isEmpty()
? parameters[0].toObject()["typeName"_L1].toString()
: "void"_L1;
const QString javaTypeName = qmlToJavaType.value(typeName, "Object"_L1); const QString upperMethodName = firstCharToUpper(methodName);
stream << indent if (parameters.size() <= 1) { // Generate a QtSignalListener<T> API for this property/signal
<< "public int connect%1Listener(QtSignalListener<%2> signalListener) {\n"_L1.arg( const QString typeName = !parameters.isEmpty()
upperMethodName, javaTypeName) ? parameters[0].toObject()["typeName"_L1].toString()
<< indent : "void"_L1;
<< " return connectSignalListener(\"%1\", %2.class, signalListener);\n"_L1.arg( const QString javaTypeName = qmlToJavaType.value(typeName, "Object"_L1);
methodName, javaTypeName) stream << indent
<< indent << "}\n"; << "public int connect%1Listener(QtSignalListener<%2> signalListener) {\n"_L1
.arg(upperMethodName, javaTypeName)
<< indent
<< " return connectSignalListener(\"%1\", %2.class, signalListener);\n"_L1
.arg(methodName, javaTypeName)
<< indent << "}\n";
} else { // Multi-arg signal; Generate a custom listener interface for this signal
// Returns a comma-separated parameter list of java types deduced from the QML DOM array
const auto getJavaArgsString = [&parameters]() -> QString {
QList<QString> javaArgsList;
for (const auto param : parameters) {
const auto typeName = param["typeName"_L1].toString();
const auto javaTypeName = qmlToJavaType.value(typeName, "Object"_L1);
const auto qmlParamName = param["name"_L1].toString();
javaArgsList.emplace_back(
QStringLiteral("%1%2").arg(javaTypeName, " %1"_L1.arg(qmlParamName)));
}
return javaArgsList.join(", "_L1);
};
// Returns a comma-separated parameter list of java classes deduced from QML DOM array
const auto getJavaClassesString = [&parameters]() -> QString {
QList<QString> javaArgsList;
for (const auto param : parameters) {
const auto typeName = param["typeName"_L1].toString();
const auto javaTypeName = qmlToJavaType.value(typeName, "Object"_L1);
javaArgsList.emplace_back(
QStringLiteral("%1%2").arg(javaTypeName, ".class"_L1));
}
return javaArgsList.join(", "_L1);
};
const auto javaParamsString = getJavaArgsString();
const auto javaParamsClassesString = getJavaClassesString();
// e.g. "{(String) args[0], (Integer) args[1], (Boolean) args[2]}"
QList<QString> objectToTypeConversion;
for (auto i = 0; i < parameters.size(); ++i) {
const auto typeName = parameters.at(i).toObject().value("typeName"_L1).toString();
objectToTypeConversion.emplace_back("(%1) args[%2]"_L1.arg(
qmlToJavaType.value(typeName, "Object"_L1), QString::number(i)));
}
// Generate new interface type for this signal
const auto signalInterfaceName = "%1Listener"_L1.arg(methodName);
const auto objectToTypeConversionString = objectToTypeConversion.join(", "_L1);
stream << indent << "@FunctionalInterface\n"
<< indent << "public interface %1 {\n"_L1.arg(signalInterfaceName) << indent
<< " default void onSignalEmitted(Object[] args) {\n"
<< indent
<< " on%1(%2);\n"_L1.arg(upperMethodName, objectToTypeConversionString)
<< indent << " }\n"
<< indent
<< " void on%1(%2);\n"_L1.arg(upperMethodName, javaParamsString);
stream << indent << "}\n"_L1;
// Generate the connection function with this new interface type
stream << indent
<< "public int connect%1(%2 signalListener) {\n"_L1.arg(
firstCharToUpper(signalInterfaceName), signalInterfaceName)
<< indent
<< " return connectSignalListener(\"%1\", new Class[]{ %2 }, signalListener);\n"_L1
.arg(methodName, javaParamsClassesString)
<< indent << "}\n\n";
}
}; };
constexpr static auto markerFileName = "qml_java_contents"_L1; constexpr static auto markerFileName = "qml_java_contents"_L1;
@ -4037,13 +4096,7 @@ int main(int argc, char *argv[])
if (!createRcc(options)) if (!createRcc(options))
return CannotCreateRcc; return CannotCreateRcc;
if (options.auxMode) { if (options.auxMode || options.build) {
if (!updateAndroidFiles(options))
return CannotUpdateAndroidFiles;
return 0;
}
if (options.build) {
if (!copyAndroidSources(options)) if (!copyAndroidSources(options))
return CannotCopyAndroidSources; return CannotCopyAndroidSources;
@ -4055,7 +4108,12 @@ int main(int argc, char *argv[])
if (Q_UNLIKELY(options.timing)) if (Q_UNLIKELY(options.timing))
fprintf(stdout, "[TIMING] %lld ns: Updated files\n", options.timer.nsecsElapsed()); fprintf(stdout, "[TIMING] %lld ns: Updated files\n", options.timer.nsecsElapsed());
}
if (options.auxMode)
return 0;
if (options.build) {
if (Q_UNLIKELY(options.timing)) if (Q_UNLIKELY(options.timing))
fprintf(stdout, "[TIMING] %lld ns: Created project\n", options.timer.nsecsElapsed()); fprintf(stdout, "[TIMING] %lld ns: Created project\n", options.timer.nsecsElapsed());

View File

@ -31,7 +31,6 @@
#include <private/qdnd_p.h> #include <private/qdnd_p.h>
#endif #endif
#include "private/qguiapplication_p.h" #include "private/qguiapplication_p.h"
#include "qcolormap.h"
#include "qdebug.h" #include "qdebug.h"
#if QT_CONFIG(style_stylesheet) #if QT_CONFIG(style_stylesheet)
#include "private/qstylesheetstyle_p.h" #include "private/qstylesheetstyle_p.h"
@ -480,7 +479,6 @@ void QApplicationPrivate::init()
process_cmdline(); process_cmdline();
// Must be called before initialize() // Must be called before initialize()
QColormap::initialize();
initializeWidgetPalettesFromTheme(); initializeWidgetPalettesFromTheme();
qt_init_tooltip_palette(); qt_init_tooltip_palette();
QApplicationPrivate::initializeWidgetFontHash(); QApplicationPrivate::initializeWidgetFontHash();
@ -712,7 +710,6 @@ QApplication::~QApplication()
d->cleanupMultitouch(); d->cleanupMultitouch();
QPixmapCache::clear(); QPixmapCache::clear();
QColormap::cleanup();
QApplicationPrivate::active_window = nullptr; //### this should not be necessary QApplicationPrivate::active_window = nullptr; //### this should not be necessary
@ -3640,7 +3637,9 @@ void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable)
bool QApplication::isEffectEnabled(Qt::UIEffect effect) bool QApplication::isEffectEnabled(Qt::UIEffect effect)
{ {
CHECK_QAPP_INSTANCE(false) CHECK_QAPP_INSTANCE(false)
return QColormap::instance().depth() >= 16 const auto primaryScreenDepth = QGuiApplication::primaryScreen() ?
QGuiApplication::primaryScreen()->depth() : 24;
return primaryScreenDepth >= 16
&& (QApplicationPrivate::enabledAnimations & QPlatformTheme::GeneralUiEffect) && (QApplicationPrivate::enabledAnimations & QPlatformTheme::GeneralUiEffect)
&& (QApplicationPrivate::enabledAnimations & uiEffectToFlag(effect)); && (QApplicationPrivate::enabledAnimations & uiEffectToFlag(effect));
} }

View File

@ -3377,8 +3377,25 @@ QAction *QWidget::addAction(const QIcon &icon, const QString &text, const QKeySe
void QWidget::setEnabled(bool enable) void QWidget::setEnabled(bool enable)
{ {
Q_D(QWidget); Q_D(QWidget);
#if QT_CONFIG(accessibility)
const bool wasEnabled = !testAttribute(Qt::WA_ForceDisabled);
#endif
setAttribute(Qt::WA_ForceDisabled, !enable); setAttribute(Qt::WA_ForceDisabled, !enable);
d->setEnabled_helper(enable); d->setEnabled_helper(enable);
#if QT_CONFIG(accessibility)
// A widget is enabled if it's parent and itself is enabled.
// We do not send state changed events recursively. It is up
// to the receiver of the events to check children if required.
if (QAccessible::isActive() && wasEnabled != enable) {
QAccessible::State states;
states.disabled = 1;
QAccessibleStateChangeEvent scEvent(this, states);
QAccessible::updateAccessibility(&scEvent);
}
#endif
} }
void QWidgetPrivate::setEnabled_helper(bool enable) void QWidgetPrivate::setEnabled_helper(bool enable)

View File

@ -7,6 +7,8 @@
#include "qscreen.h" #include "qscreen.h"
#include "qguiapplication.h" #include "qguiapplication.h"
#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QColormapPrivate class QColormapPrivate
@ -42,16 +44,26 @@ void QColormap::initialize()
screenMap->mode = QColormap::Direct; screenMap->mode = QColormap::Direct;
screenMap->numcolors = -1; screenMap->numcolors = -1;
} }
qAddPostRoutine(QColormap::cleanup);
} }
void QColormap::cleanup() void QColormap::cleanup()
{ {
delete screenMap; if (screenMap) {
screenMap = nullptr; if (!screenMap->ref.deref())
delete screenMap;
screenMap = nullptr;
}
} }
QColormap QColormap::instance(int /*screen*/) QColormap QColormap::instance(int /*screen*/)
{ {
static QMutex mutex;
QMutexLocker locker(&mutex);
if (!screenMap)
initialize();
return QColormap(); return QColormap();
} }

View File

@ -1 +1 @@
set(QT_REPO_MODULE_VERSION "6.10.0") set(QT_REPO_MODULE_VERSION "6.11.0")

View File

@ -1 +1 @@
set(QT_REPO_MODULE_VERSION "6.10.0") set(QT_REPO_MODULE_VERSION "6.11.0")

View File

@ -1 +1 @@
set(QT_REPO_MODULE_VERSION "6.10.0") set(QT_REPO_MODULE_VERSION "6.11.0")

View File

@ -1240,7 +1240,8 @@ void tst_QDir::current()
#if defined(Q_OS_WIN) #if defined(Q_OS_WIN)
QCOMPARE(newCurrent.absolutePath().toLower(), currentDir.toLower()); QCOMPARE(newCurrent.absolutePath().toLower(), currentDir.toLower());
#else #else
QCOMPARE(newCurrent.absolutePath(), currentDir); // getcwd(2) on Unix returns the canonical path
QCOMPARE(newCurrent.absolutePath(), QDir(currentDir).canonicalPath());
#endif #endif
} }
@ -1254,21 +1255,25 @@ void tst_QDir::cd_data()
QTest::addColumn<bool>("successExpected"); QTest::addColumn<bool>("successExpected");
QTest::addColumn<QString>("newDir"); QTest::addColumn<QString>("newDir");
int index = m_dataPath.lastIndexOf(QLatin1Char('/')); // use the canonical path for m_dataPath here, because if TMPDIR points to
QTest::newRow("cdUp") << m_dataPath << ".." << true << m_dataPath.left(index==0?1:index); // a symlink like what happens on Apple systems (/tmp -> /private/tmp),
// then /tmp/.. will not be the same as / (it's /private).
QString canonicalPath = QDir(m_dataPath).canonicalPath();
int index = canonicalPath.lastIndexOf(QLatin1Char('/'));
QTest::newRow("cdUp") << canonicalPath << ".." << true << canonicalPath.left(index==0?1:index);
QTest::newRow("cdUp non existent (relative dir)") << "anonexistingDir" << ".." QTest::newRow("cdUp non existent (relative dir)") << "anonexistingDir" << ".."
<< true << m_dataPath; << true << canonicalPath;
QTest::newRow("cdUp non existent (absolute dir)") << m_dataPath + "/anonexistingDir" << ".." QTest::newRow("cdUp non existent (absolute dir)") << canonicalPath + "/anonexistingDir" << ".."
<< true << m_dataPath; << true << canonicalPath;
QTest::newRow("noChange") << m_dataPath << "." << true << m_dataPath; QTest::newRow("noChange") << canonicalPath << "." << true << canonicalPath;
#if defined(Q_OS_WIN) // on windows QDir::root() is usually c:/ but cd "/" will not force it to be root #if defined(Q_OS_WIN) // on windows QDir::root() is usually c:/ but cd "/" will not force it to be root
QTest::newRow("absolute") << m_dataPath << "/" << true << "/"; QTest::newRow("absolute") << canonicalPath << "/" << true << "/";
#else #else
QTest::newRow("absolute") << m_dataPath << "/" << true << QDir::root().absolutePath(); QTest::newRow("absolute") << canonicalPath << "/" << true << QDir::root().absolutePath();
#endif #endif
QTest::newRow("non existant") << "." << "../anonexistingdir" << false << m_dataPath; QTest::newRow("non existant") << "." << "../anonexistingdir" << false << canonicalPath;
QTest::newRow("self") << "." << (QString("../") + QFileInfo(m_dataPath).fileName()) << true << m_dataPath; QTest::newRow("self") << "." << (QString("../") + QFileInfo(canonicalPath).fileName()) << true << canonicalPath;
QTest::newRow("file") << "." << "qdir.pro" << false << m_dataPath; QTest::newRow("file") << "." << "qdir.pro" << false << canonicalPath;
} }
void tst_QDir::cd() void tst_QDir::cd()

View File

@ -545,7 +545,7 @@ void tst_QPointer::raceCondition()
for (int i = 0; i < NUM_THREADS; ++i) { for (int i = 0; i < NUM_THREADS; ++i) {
QThread *thread = QThread *thread =
QThread::create([&startSemaphore, &targetObject] { QThread::create([&] {
startSemaphore.acquire(); startSemaphore.acquire();
for (int j = 0; j < ITERATIONS_PER_THREAD; ++j) { for (int j = 0; j < ITERATIONS_PER_THREAD; ++j) {

View File

@ -301,6 +301,7 @@ static constexpr int NColorRoles[] = {
QPalette::Accent + 1, // Qt_6_6 QPalette::Accent + 1, // Qt_6_6
QPalette::Accent + 1, // Qt_6_7 QPalette::Accent + 1, // Qt_6_7
QPalette::Accent + 1, // Qt_6_10 QPalette::Accent + 1, // Qt_6_10
QPalette::Accent + 1, // Qt_6_11
}; };
// +1, because we start from "No Version" // +1, because we start from "No Version"

View File

@ -196,6 +196,9 @@ private slots:
void availableCodesAreAvailable(); void availableCodesAreAvailable();
void finalize();
void finalizeStateful();
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
// On all other systems local 8-bit encoding is UTF-8 // On all other systems local 8-bit encoding is UTF-8
void fromLocal8Bit_data(); void fromLocal8Bit_data();
@ -2491,6 +2494,104 @@ void tst_QStringConverter::availableCodesAreAvailable()
QVERIFY(QStringEncoder(codecName.toLatin1()).isValid()); QVERIFY(QStringEncoder(codecName.toLatin1()).isValid());
} }
void tst_QStringConverter::finalize()
{
// encoder
{
auto fromUtf16 = QStringEncoder(QStringEncoder::Utf8);
QString incompleteInput(QChar(0xd800));
QByteArray buffer("cdcdcdcd");
fromUtf16.appendToBuffer(buffer.data(), incompleteInput);
QVERIFY(!fromUtf16.hasError());
QCOMPARE(buffer, "cdcdcdcd");
QStringEncoder::FinalizeResult r = fromUtf16.finalize(buffer.data(), buffer.size());
QCOMPARE_GT(r.next, buffer.constData());
QCOMPARE(r.error, QStringEncoder::FinalizeResult::Error::InvalidCharacters);
QCOMPARE_GT(r.invalidChars, 0);
QVERIFY(!fromUtf16.hasError());
QVERIFY(buffer.startsWith(QString(QChar(QChar::ReplacementCharacter)).toUtf8()));
// Try calling finalize again, no new bytes should be output
std::array<char, 3> extraBytes;
r = fromUtf16.finalize(extraBytes.data(), extraBytes.size());
// Ugly-cast to void to circumvent smart testlib
QCOMPARE((void *)r.next, (void *)extraBytes.data());
QCOMPARE(r.invalidChars, 0);
QCOMPARE(r.error, QStringEncoder::FinalizeResult::Error::NoError);
}
// decoder
{
auto toUtf16 = QStringDecoder(QStringConverter::Utf8);
QByteArray incompleteInput("\xf0", 1);
QString buffer = u"cdcdcdcd"_s;
toUtf16.appendToBuffer(buffer.data(), incompleteInput);
QVERIFY(!toUtf16.hasError());
QCOMPARE(buffer, u"cdcdcdcd"_s);
auto result = toUtf16.finalize(buffer.data(), buffer.size());
QCOMPARE_GT(result.next, buffer.constData());
QCOMPARE(result.error, QStringDecoder::FinalizeResult::Error::InvalidCharacters);
QVERIFY(buffer.startsWith(QChar(QChar::ReplacementCharacter)));
// Try calling finalize again, no new bytes should be output
std::array<QChar, 3> extraBytes;
result = toUtf16.finalize(extraBytes.data(), extraBytes.size());
// Ugly-cast to void to circumvent smart testlib
QCOMPARE((void *)result.next, (void *)extraBytes.data());
}
}
void tst_QStringConverter::finalizeStateful()
{
#if !QT_CONFIG(icu) && !QT_CONFIG(winsdkicu)
// Technically there is _access_ to stateful encoding on Windows, but only
// through the System encoder.
QSKIP("ICU is not enabled in this build => stateful encoding is not tested.");
#else
{
// Test that calling finalize() restores ASCII mode in this stateful encoding:
static const char expected[] = {
0x1b, 0x24, 0x42, 0x25, 0x26, 0x25, 0x23, 0x25, 0x2d, 0x25, 0x5a, 0x25,
0x47, 0x25, 0x23, 0x25, 0x22, 0x1b, 0x28, 0x42
};
QString input = u"ウィキペディア"_s; // "Wikipedia"
QByteArray buffer(20, '\0');
auto stateful = QStringEncoder("ISO-2022-JP");
if (!stateful.isValid())
QSKIP("ICU without support for ISO-2022-JP, cannot continue test.");
char *out = stateful.appendToBuffer(buffer.data(), input);
QCOMPARE(std::distance(buffer.data(), out), 17);
// First without enough space. We assume ICU may or may not output the
// start of the 1b 28 42 sequence, so we handle either.
char * const end = buffer.end();
QStringEncoder::FinalizeResult result = stateful.finalize(out, 1);
QCOMPARE(result.error, QStringEncoder::FinalizeResult::Error::NotEnoughSpace);
// Then with enough space
result = stateful.finalize(result.next, std::distance(result.next, end));
QCOMPARE((void *)result.next, (void *)buffer.constEnd());
QCOMPARE(buffer.toHex(' '), QByteArrayView(expected).toByteArray().toHex(' '));
QCOMPARE(result.invalidChars, 0);
// Try calling finalize again, no new bytes should be output
std::array<char, 3> extraBytes;
result = stateful.finalize(extraBytes.data(), extraBytes.size());
QCOMPARE((void *)result.next, (void *)extraBytes.data());
QCOMPARE(result.error, QStringEncoder::FinalizeResult::Error::NoError);
QCOMPARE(result.invalidChars, 0);
}
{
// Repeat, but calling finalize() without an output
QString input = u"ウィキペディア"_s; // "Wikipedia"
QByteArray buffer(20, '\0');
auto stateful = QStringEncoder("ISO-2022-JP");
QVERIFY(stateful.isValid());
char *out = stateful.appendToBuffer(buffer.data(), input);
QCOMPARE(std::distance(buffer.data(), out), 17);
// This passes some pointers to ICU, we just shouldn't crash
QStringEncoder::FinalizeResult r = stateful.finalize();
QCOMPARE(r.error, QStringEncoder::FinalizeResult::Error::NoError);
QCOMPARE(r.invalidChars, 0);
QCOMPARE(r.next, nullptr);
}
#endif
}
class LoadAndConvert: public QRunnable class LoadAndConvert: public QRunnable
{ {
public: public:

View File

@ -431,6 +431,30 @@ void tst_QUtf8StringView::std_stringview_conversion()
QCOMPARE(sv.size(), size_t(12)); QCOMPARE(sv.size(), size_t(12));
QCOMPARE(sv, std::basic_string_view<QUtf8StringView::storage_type>("Hello\0world\0", 12)); QCOMPARE(sv, std::basic_string_view<QUtf8StringView::storage_type>("Hello\0world\0", 12));
} }
#ifdef __cpp_lib_char8_t
{
QUtf8StringView s;
std::u8string_view sv(s);
QCOMPARE(sv, std::u8string_view());
s = u8"";
sv = s;
QCOMPARE(s.size(), 0);
QCOMPARE(sv.size(), size_t(0));
QCOMPARE(sv, std::u8string_view());
s = u8"Hello";
sv = s;
QCOMPARE(sv, std::u8string_view(u8"Hello"));
s = QUtf8StringView::fromArray(u8"Hello\0world");
sv = s;
QCOMPARE(s.size(), 12);
QCOMPARE(sv.size(), size_t(12));
QCOMPARE(sv, std::u8string_view(u8"Hello\0world\0", 12));
}
#endif
} }
namespace QUtf8StringViewOverloadResolution { namespace QUtf8StringViewOverloadResolution {

View File

@ -124,9 +124,7 @@ void tst_QCalendar::basic_data()
{ {
QTest::addColumn<QCalendar::System>("system"); QTest::addColumn<QCalendar::System>("system");
QMetaEnum e = QCalendar::staticMetaObject.enumerator(0); const QMetaEnum e = QMetaEnum::fromType<QCalendar::System>();
Q_ASSERT(qstrcmp(e.name(), "System") == 0);
for (int i = 0; i <= int(QCalendar::System::Last); ++i) { for (int i = 0; i <= int(QCalendar::System::Last); ++i) {
// There may be gaps in the enum's numbering; and Last is a duplicate: // There may be gaps in the enum's numbering; and Last is a duplicate:
if (e.value(i) != -1 && qstrcmp(e.key(i), "Last")) if (e.value(i) != -1 && qstrcmp(e.key(i), "Last"))

View File

@ -1161,38 +1161,23 @@ void tst_QDate::operator_insert_extract_data()
QTest::addColumn<QDate>("date"); QTest::addColumn<QDate>("date");
QTest::addColumn<QDataStream::Version>("dataStreamVersion"); QTest::addColumn<QDataStream::Version>("dataStreamVersion");
QMap<QDataStream::Version, QByteArray> versionsToTest; const QMetaEnum e = QMetaEnum::fromType<QDataStream::Version>();
versionsToTest.insert(QDataStream::Qt_1_0, "Qt_1_0"_ba); for (int version = QDataStream::Qt_1_0; version <= QDataStream::Qt_DefaultCompiledVersion;
versionsToTest.insert(QDataStream::Qt_2_0, "Qt_2_0"_ba); ++version) {
versionsToTest.insert(QDataStream::Qt_2_1, "Qt_2_1"_ba); if (e.value(version) == -1 || qstrcmp(e.key(version), "Qt_DefaultCompiledVersion") == 0)
versionsToTest.insert(QDataStream::Qt_3_0, "Qt_3_0"_ba); continue;
versionsToTest.insert(QDataStream::Qt_3_1, "Qt_3_1"_ba); const auto dataStreamVersion = static_cast<QDataStream::Version>(version);
versionsToTest.insert(QDataStream::Qt_3_3, "Qt_3_3"_ba); const char *const tag = e.key(version);
versionsToTest.insert(QDataStream::Qt_4_0, "Qt_4_0"_ba); QTest::addRow("(invalid) %s", tag) << invalidDate() << dataStreamVersion;
versionsToTest.insert(QDataStream::Qt_4_1, "Qt_4_1"_ba); QTest::addRow("(1, 1, 1) %s", tag) << QDate(1, 1, 1) << dataStreamVersion;
versionsToTest.insert(QDataStream::Qt_4_2, "Qt_4_2"_ba); QTest::addRow("(-1, 1, 1) %s", tag) << QDate(-1, 1, 1) << dataStreamVersion;
versionsToTest.insert(QDataStream::Qt_4_3, "Qt_4_3"_ba); QTest::addRow("(1995, 5, 20) %s", tag) << QDate(1995, 5, 20) << dataStreamVersion;
versionsToTest.insert(QDataStream::Qt_4_4, "Qt_4_4"_ba);
versionsToTest.insert(QDataStream::Qt_4_5, "Qt_4_5"_ba);
versionsToTest.insert(QDataStream::Qt_4_6, "Qt_4_6"_ba);
versionsToTest.insert(QDataStream::Qt_4_7, "Qt_4_7"_ba);
versionsToTest.insert(QDataStream::Qt_4_8, "Qt_4_8"_ba);
versionsToTest.insert(QDataStream::Qt_4_9, "Qt_4_9"_ba);
versionsToTest.insert(QDataStream::Qt_5_0, "Qt_5_0"_ba);
for (auto it = versionsToTest.constBegin(); it != versionsToTest.constEnd(); ++it) {
const QByteArray &version(it.value());
const char *const tag = version.constData();
QTest::addRow("(invalid) %s", tag) << invalidDate() << it.key();
QTest::addRow("(1, 1, 1) %s", tag) << QDate(1, 1, 1) << it.key();
QTest::addRow("(-1, 1, 1) %s", tag) << QDate(-1, 1, 1) << it.key();
QTest::addRow("(1995, 5, 20) %s", tag) << QDate(1995, 5, 20) << it.key();
// Test minimums for quint32/qint64. // Test minimums for quint32/qint64.
if (it.key() >= QDataStream::Qt_5_0) if (dataStreamVersion >= QDataStream::Qt_5_0)
QTest::addRow("(-4714, 11, 24) %s", tag) << QDate(-4714, 11, 24) << it.key(); QTest::addRow("(-4714, 11, 24) %s", tag) << QDate(-4714, 11, 24) << dataStreamVersion;
else else
QTest::addRow("(-4713, 1, 2) %s", tag) << QDate(-4713, 1, 2) << it.key(); QTest::addRow("(-4713, 1, 2) %s", tag) << QDate(-4713, 1, 2) << dataStreamVersion;
} }
} }

View File

@ -2631,18 +2631,20 @@ void tst_QDateTime::operator_insert_extract_data()
const QByteArray westernAustralia("AWST-8AWDT-9,M10.5.0,M3.5.0/03:00:00"); const QByteArray westernAustralia("AWST-8AWDT-9,M10.5.0,M3.5.0/03:00:00");
const QByteArray hawaii("HAW10"); const QByteArray hawaii("HAW10");
const QDataStream tmpDataStream; const QMetaEnum e = QMetaEnum::fromType<QDataStream::Version>();
const int thisVersion = tmpDataStream.version(); for (int version = QDataStream::Qt_1_0; version <= QDataStream::Qt_DefaultCompiledVersion;
for (int version = QDataStream::Qt_1_0; version <= thisVersion; ++version) { ++version) {
const QDataStream::Version dataStreamVersion = static_cast<QDataStream::Version>(version); if (e.value(version) == -1 || qstrcmp(e.key(version), "Qt_DefaultCompiledVersion") == 0)
const QByteArray vN = QByteArray::number(dataStreamVersion); continue;
QTest::addRow("v%d WA => HAWAII %d", version, 2012) const auto dataStreamVersion = static_cast<QDataStream::Version>(version);
const char *const tag = e.key(version);
QTest::addRow("%s WA => HAWAII %d", tag, 2012)
<< 2012 << westernAustralia << hawaii << dataStreamVersion; << 2012 << westernAustralia << hawaii << dataStreamVersion;
QTest::addRow("v%d WA => WA %d", version, 2012) QTest::addRow("%s WA => WA %d", tag, 2012)
<< 2012 << westernAustralia << westernAustralia << dataStreamVersion; << 2012 << westernAustralia << westernAustralia << dataStreamVersion;
QTest::addRow("v%d HAWAII => WA %d", version, -2012) QTest::addRow("%s HAWAII => WA %d", tag, -2012)
<< -2012 << hawaii << westernAustralia << dataStreamVersion; << -2012 << hawaii << westernAustralia << dataStreamVersion;
QTest::addRow("v%d HAWAII => HAWAII %d", version, 2012) QTest::addRow("%s HAWAII => HAWAII %d", tag, 2012)
<< 2012 << hawaii << hawaii << dataStreamVersion; << 2012 << hawaii << hawaii << dataStreamVersion;
} }
} }

View File

@ -45,6 +45,8 @@ private slots:
void setFont_collection_data(); void setFont_collection_data();
void setFont_collection(); void setFont_collection();
void clearCollection(); void clearCollection();
void setFontFeatures();
void setFontVariableAxes();
#ifndef QT_NO_DATASTREAM #ifndef QT_NO_DATASTREAM
void dataStreamCompatibility(); void dataStreamCompatibility();
@ -667,6 +669,89 @@ void tst_QTextFormat::clearCollection()
QCOMPARE(collection.defaultFont(), f); // kept, QTextDocument::clear or setPlainText should not reset the font set by setDefaultFont QCOMPARE(collection.defaultFont(), f); // kept, QTextDocument::clear or setPlainText should not reset the font set by setDefaultFont
} }
void tst_QTextFormat::setFontFeatures()
{
{
QFont font;
font.setFeature("abcd", 1234);
font.setFeature("efgh", 5678);
QTextCharFormat format;
format.setFont(font);
QFont resolvedFont = format.font();
QCOMPARE(resolvedFont.featureTags().size(), 2);
QCOMPARE(resolvedFont.featureValue("abcd"), 1234);
QCOMPARE(resolvedFont.featureValue("efgh"), 5678);
QHash<QFont::Tag, quint32> features = format.fontFeatures();
QCOMPARE(features.size(), 2);
QCOMPARE(features.value("abcd"), 1234);
QCOMPARE(features.value("efgh"), 5678);
}
{
QTextCharFormat format;
QHash<QFont::Tag, quint32> features;
features.insert("abcd", 4321);
features.insert("efgh", 8765);
format.setFontFeatures(features);
QFont resolvedFont = format.font();
QCOMPARE(resolvedFont.featureTags().size(), 2);
QCOMPARE(resolvedFont.featureValue("abcd"), 4321);
QCOMPARE(resolvedFont.featureValue("efgh"), 8765);
features = format.fontFeatures();
QCOMPARE(features.size(), 2);
QCOMPARE(features.value("abcd"), 4321);
QCOMPARE(features.value("efgh"), 8765);
}
}
void tst_QTextFormat::setFontVariableAxes()
{
{
QFont font;
font.setVariableAxis("abcd", 12.25);
font.setVariableAxis("efgh", 13.25);
QTextCharFormat format;
format.setFont(font);
QFont resolvedFont = format.font();
QCOMPARE(resolvedFont.variableAxisTags().size(), 2);
QCOMPARE(resolvedFont.variableAxisValue("abcd"), 12.25);
QCOMPARE(resolvedFont.variableAxisValue("efgh"), 13.25);
QHash<QFont::Tag, float> axes = format.fontVariableAxes();
QCOMPARE(axes.size(), 2);
QCOMPARE(axes.value("abcd"), 12.25);
QCOMPARE(axes.value("efgh"), 13.25);
}
{
QTextCharFormat format;
QHash<QFont::Tag, float> axes;
axes.insert("abcd", 12.25);
axes.insert("efgh", 13.25);
format.setFontVariableAxes(axes);
QFont resolvedFont = format.font();
QCOMPARE(resolvedFont.variableAxisTags().size(), 2);
QCOMPARE(resolvedFont.variableAxisValue("abcd"), 12.25);
QCOMPARE(resolvedFont.variableAxisValue("efgh"), 13.25);
axes = format.fontVariableAxes();
QCOMPARE(axes.size(), 2);
QCOMPARE(axes.value("abcd"), 12.25);
QCOMPARE(axes.value("efgh"), 13.25);
}
}
#ifndef QT_NO_DATASTREAM #ifndef QT_NO_DATASTREAM
void tst_QTextFormat::dataStreamCompatibility() void tst_QTextFormat::dataStreamCompatibility()
{ {
@ -795,6 +880,73 @@ void tst_QTextFormat::dataStreamCompatibility()
} }
} }
// Don't mix up FontFeatures and OldTextUnderlineColor
memory.clear();
{
{
QBuffer buffer(&memory);
buffer.open(QIODevice::WriteOnly);
QFont font;
font.setFeature("abcd", 1234);
QTextCharFormat format;
format.setFont(font);
QDataStream stream(&buffer);
stream << format;
}
{
QBuffer buffer(&memory);
buffer.open(QIODevice::ReadOnly);
QDataStream stream(&buffer);
QTextFormat other;
stream >> other;
QMap<int, QVariant> properties = other.properties();
QVERIFY(properties.contains(QTextFormat::FontFeatures));
auto features = other.property(QTextFormat::FontFeatures).value<QHash<QFont::Tag, quint32>>();
QCOMPARE(features.value("abcd"), 1234);
}
}
memory.clear();
{
{
QBuffer buffer(&memory);
buffer.open(QIODevice::WriteOnly);
QFont font;
font.setFeature("abcd", 1234);
QTextCharFormat format;
format.setFont(font);
QDataStream stream(&buffer);
stream.setVersion(QDataStream::Qt_5_15);
stream << format;
}
{
QBuffer buffer(&memory);
buffer.open(QIODevice::ReadOnly);
QDataStream stream(&buffer);
stream.setVersion(QDataStream::Qt_5_15);
QTextFormat other;
stream >> other;
QMap<int, QVariant> properties = other.properties();
QVERIFY(!properties.contains(QTextFormat::FontFeatures));
QVERIFY(!properties.contains(QTextFormat::OldTextUnderlineColor));
}
}
} }
#endif // QT_NO_DATASTREAM #endif // QT_NO_DATASTREAM

View File

@ -3,7 +3,7 @@
** Copyright (C) 2024 Intel Corporation. ** Copyright (C) 2024 Intel Corporation.
** SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only ** SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
** **
** Created by: The Resource Compiler for Qt version 6.10.0 ** Created by: The Resource Compiler for Qt version 6.11.0
** **
** WARNING! All changes made in this file will be lost! ** WARNING! All changes made in this file will be lost!
*****************************************************************************/ *****************************************************************************/

View File

@ -38,6 +38,7 @@ private slots:
void initiallySuspended(); void initiallySuspended();
void modality(); void modality();
void modalityWithoutTransientParent(); void modalityWithoutTransientParent();
void grabbingSiblingPopups();
}; };
void tst_xdgshell::initTestCase() void tst_xdgshell::initTestCase()
@ -845,15 +846,18 @@ void tst_xdgshell::suspended()
QVERIFY(!window.isExposed()); // not exposed until we're configured QVERIFY(!window.isExposed()); // not exposed until we're configured
QCOMPOSITOR_TRY_VERIFY(xdgToplevel()); QCOMPOSITOR_TRY_VERIFY(xdgToplevel());
exec([&] { xdgToplevel()->sendCompleteConfigure(); }); uint serial = 0;
QCOMPOSITOR_TRY_VERIFY(xdgToplevel()->m_xdgSurface->m_committedConfigureSerial); exec([&] { serial = xdgToplevel()->sendCompleteConfigure(); });
QTRY_VERIFY(window.isExposed()); QTRY_VERIFY(window.isExposed());
QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_xdgSurface->m_committedConfigureSerial, serial);
exec([&] { xdgToplevel()->sendCompleteConfigure(QSize(), {XdgToplevel::state_suspended}); }); exec([&] { serial = xdgToplevel()->sendCompleteConfigure(QSize(), {XdgToplevel::state_suspended}); });
QTRY_VERIFY(!window.isExposed()); QTRY_VERIFY(!window.isExposed());
QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_xdgSurface->m_committedConfigureSerial, serial);
exec([&] { xdgToplevel()->sendCompleteConfigure(QSize(), {}); }); exec([&] { serial = xdgToplevel()->sendCompleteConfigure(QSize(), {}); });
QTRY_VERIFY(window.isExposed()); QTRY_VERIFY(window.isExposed());
QCOMPOSITOR_TRY_COMPARE(xdgToplevel()->m_xdgSurface->m_committedConfigureSerial, serial);
} }
void tst_xdgshell::initiallySuspended() void tst_xdgshell::initiallySuspended()
@ -932,5 +936,67 @@ void tst_xdgshell::modalityWithoutTransientParent()
QCOMPOSITOR_TRY_VERIFY(!xdgDialog()); QCOMPOSITOR_TRY_VERIFY(!xdgDialog());
} }
void tst_xdgshell::grabbingSiblingPopups()
{
class Window : public QRasterWindow {
public:
void mousePressEvent(QMouseEvent *event) override
{
QRasterWindow::mousePressEvent(event);
auto popup = new QRasterWindow;
popup->setTransientParent(this);
popup->setFlags(Qt::Popup);
popup->resize(100, 100);
popup->show();
m_popups << popup;
}
QList<QRasterWindow*> m_popups;
};
Window window;
window.resize(200, 200);
window.show();
QCOMPOSITOR_TRY_VERIFY(xdgToplevel());
exec([&] { xdgToplevel()->sendCompleteConfigure(); });
auto triggerPopup = [&](int popupIndex) {
// we need a click to be able to create a grabbing popup
exec([&] {
auto *surface = xdgToplevel()->surface();
auto *p = pointer();
auto *c = client();
p->sendEnter(surface, {100, 100});
p->sendFrame(c);
p->sendButton(c, BTN_LEFT, Pointer::button_state_pressed);
p->sendButton(c, BTN_LEFT, Pointer::button_state_released);
p->sendFrame(c);
});
QCOMPOSITOR_TRY_VERIFY(xdgPopup(popupIndex));
exec([&] {
xdgPopup(popupIndex)->sendConfigure(QRect(100, 100, 100, 100));
xdgPopup(popupIndex)->m_xdgSurface->sendConfigure();
});
};
triggerPopup(0);
// QtWayland will make popup1 a child of popup0, despite them being siblings at a Qt level
triggerPopup(1);
// This is illegal from a wayland POV as popup2 is the latest grabbing popup
// popup2 must be closed first but we should handle it gracefully
// and not trigger an error in the compositor
delete window.m_popups.takeFirst();
// check the compositor does not throw an error when the popup is closed
auto native = qGuiApp->platformNativeInterface();
auto display = static_cast<struct ::wl_display *>(native->nativeResourceForIntegration("wl_display"));
wl_display_roundtrip(display);
// cleanup
delete window.m_popups.takeFirst();
}
QCOMPOSITOR_TEST_MAIN(tst_xdgshell) QCOMPOSITOR_TEST_MAIN(tst_xdgshell)
#include "tst_xdgshell.moc" #include "tst_xdgshell.moc"

View File

@ -7,6 +7,6 @@ macos
[scrollTo] [scrollTo]
android android
[overshoot] [overshoot_segments]
macos #QTBUG-134105 macos #QTBUG-134105
windows #QTBUG-134105 windows #QTBUG-134105

View File

@ -117,6 +117,8 @@ private slots:
void scrollTo(); void scrollTo();
void scroll(); void scroll();
void overshoot(); void overshoot();
void overshoot_data();
void overshoot_segments();
void multipleWindows(); void multipleWindows();
void mouseEventTimestamp(); void mouseEventTimestamp();
@ -400,11 +402,77 @@ void tst_QScroller::scroll()
#endif #endif
} }
void tst_QScroller::overshoot_data()
{
QTest::addColumn<qreal>("dragDistance");
QTest::addColumn<qreal>("scrollDistance");
QTest::addColumn<QVariant>("scrollMetric");
QTest::addColumn<QRectF>("rectangle");
QTest::addColumn<QPointF>("from");
QTest::addColumn<QPoint>("touchStart");
QTest::addColumn<QPoint>("touchUpdate");
QTest::addColumn<QPoint>("touchEnd");
QTest::addColumn<bool>("overshoot");
QTest::addRow("scrollable good case") << qreal(0.2) << qreal(0.2) << QVariant(QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable))
<< QRectF(0, 0, 1000, 1000) << QPointF(500, 500) << QPoint(0, 0) << QPoint(400, 0) << QPoint(490, 0) << bool(true) ;
QTest::addRow("scrollable bad case") << qreal(0.2) << qreal(0.2) << QVariant(QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable))
<< QRectF(0, 0, 0, 1000) << QPointF(0, 500) << QPoint(0, 0) << QPoint(400, 0) << QPoint(490, 0) << bool(false);
QTest::addRow("overshoot always on") << qreal(0.2) << qreal(0.2) << QVariant(QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn))
<< QRectF(0, 0, 0, 1000) << QPointF(0, 500) << QPoint(0, 0) << QPoint(400, 0) << QPoint(490, 0) << bool(true);
QTest::addRow("overshoot always off") << qreal(0.2) << qreal(0.2) << QVariant(QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff))
<< QRectF(0, 0, 1000, 1000) << QPointF(500, 500) << QPoint(0, 0) << QPoint(400, 0) << QPoint(490, 0) << bool(false);
QTest::addRow("max overshoot null") << qreal(0.0) << qreal(0.0) << QVariant(QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn))
<< QRectF(0, 0, 1000, 1000) << QPointF(500, 500) << QPoint(0, 0) << QPoint(400, 0) << QPoint(490, 0) << bool(false) ;
}
void tst_QScroller::overshoot() void tst_QScroller::overshoot()
{ {
#if QT_CONFIG(gestures) && QT_CONFIG(scroller) #if QT_CONFIG(gestures) && QT_CONFIG(scroller)
QScopedPointer<tst_QScrollerWidget> sw(new tst_QScrollerWidget); QScopedPointer<tst_QScrollerWidget> sw(new tst_QScrollerWidget);
sw->scrollArea = QRectF(0, 0, 1000, 1000); QScroller::grabGesture(sw.data(), QScroller::TouchGesture);
sw->setGeometry(100, 100, 400, 300);
sw->show();
if (!QTest::qWaitForWindowExposed(sw.data()) || !QTest::qWaitForWindowActive(sw.data()))
QSKIP("Failed to show and activate window");
QFETCH(const qreal, dragDistance);
QFETCH(const qreal, scrollDistance);
QFETCH(const QVariant, scrollMetric);
QFETCH(const QRectF, rectangle);
QFETCH(const QPointF, from);
QFETCH(const QPoint, touchStart);
QFETCH(const QPoint, touchUpdate);
QFETCH(const QPoint, touchEnd);
QFETCH(const bool, overshoot);
QScroller *s1 = QScroller::scroller(sw.data());
QScrollerProperties sp1 = s1->scrollerProperties();
sp1.setScrollMetric(QScrollerProperties::OvershootDragResistanceFactor, 0.5);
sp1.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, dragDistance);
sp1.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, scrollDistance);
sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, scrollMetric);
s1->setScrollerProperties(sp1);
sw->reset();
sw->scrollArea = rectangle;
kineticScrollNoTest(sw.data(), from, touchStart, touchUpdate, touchEnd);
QTRY_COMPARE(s1->state(), QScroller::Inactive);
QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
QCOMPARE(sw->receivedOvershoot, overshoot);
#endif
}
void tst_QScroller::overshoot_segments()
{
#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
QScopedPointer<tst_QScrollerWidget> sw(new tst_QScrollerWidget);
QScroller::grabGesture(sw.data(), QScroller::TouchGesture); QScroller::grabGesture(sw.data(), QScroller::TouchGesture);
sw->setGeometry(100, 100, 400, 300); sw->setGeometry(100, 100, 400, 300);
sw->show(); sw->show();
@ -418,102 +486,25 @@ void tst_QScroller::overshoot()
sp1.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.2); sp1.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.2);
sp1.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.2); sp1.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.2);
// -- try to scroll with overshoot (when scrollable good case)
sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable));
s1->setScrollerProperties(sp1);
kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));
QTRY_COMPARE(s1->state(), QScroller::Inactive);
//qDebug() << "Overshoot fuzzy: "<<sw->currentPos;
QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
QCOMPARE(sw->receivedOvershoot, true);
// -- try to scroll with overshoot (when scrollable bad case)
sw->reset();
sw->scrollArea = QRectF(0, 0, 0, 1000);
sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable));
s1->setScrollerProperties(sp1);
kineticScrollNoTest(sw.data(), QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));
QTRY_COMPARE(s1->state(), QScroller::Inactive);
//qDebug() << "Overshoot fuzzy: "<<sw->currentPos;
QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
QCOMPARE(sw->receivedOvershoot, false);
// -- try to scroll with overshoot (always on)
sw->reset();
sw->scrollArea = QRectF(0, 0, 0, 1000);
sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn));
s1->setScrollerProperties(sp1);
kineticScrollNoTest(sw.data(), QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));
QTRY_COMPARE(s1->state(), QScroller::Inactive);
//qDebug() << "Overshoot fuzzy: "<<sw->currentPos;
QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
QCOMPARE(sw->receivedOvershoot, true);
// -- try to scroll with overshoot (always off)
sw->reset();
sw->scrollArea = QRectF(0, 0, 1000, 1000);
sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff)); sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff));
s1->setScrollerProperties(sp1); s1->setScrollerProperties(sp1);
kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));
QTRY_COMPARE(s1->state(), QScroller::Inactive);
QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
QCOMPARE(sw->receivedOvershoot, false);
// -- try to scroll with overshoot (always off, slow)
sw->reset();
sw->scrollArea = QRectF(0, 0, 1000, 1000); sw->scrollArea = QRectF(0, 0, 1000, 1000);
sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff));
s1->setScrollerProperties(sp1);
kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(200, 0), QPoint(250, 0)); kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(200, 0), QPoint(250, 0));
// Check that segment parameters are consistent
QScrollerPrivate* priv = s1->d_func(); QScrollerPrivate* priv = s1->d_func();
QVERIFY(priv->xSegments.size() == 1); QVERIFY(priv->xSegments.size() == 1);
const auto& segment = priv->xSegments.head(); const auto& segment = priv->xSegments.head();
QCOMPARE_LT(segment.startPos + segment.deltaPos, segment.stopPos); QCOMPARE_LT(segment.startPos + segment.deltaPos, segment.stopPos);
QTRY_COMPARE(s1->state(), QScroller::Inactive); QTRY_COMPARE(s1->state(), QScroller::Inactive);
QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
QCOMPARE(sw->receivedOvershoot, false);
// -- try to scroll with overshoot (always on but max overshoot = 0)
sp1.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.0);
sp1.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.0);
sw->reset();
sw->scrollArea = QRectF(0, 0, 1000, 1000);
sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn));
s1->setScrollerProperties(sp1);
kineticScrollNoTest(sw.data(), QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0));
QTRY_COMPARE(s1->state(), QScroller::Inactive);
QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0)); QVERIFY(qFuzzyCompare(sw->currentPos.x(), 0));
QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500)); QVERIFY(qFuzzyCompare(sw->currentPos.y(), 500));
QCOMPARE(sw->receivedOvershoot, false); QCOMPARE(sw->receivedOvershoot, false);
#endif #endif
} }
void tst_QScroller::multipleWindows() void tst_QScroller::multipleWindows()
{ {
#if QT_CONFIG(gestures) && QT_CONFIG(scroller) #if QT_CONFIG(gestures) && QT_CONFIG(scroller)

View File

@ -1,6 +1,5 @@
:: Copyright (C) 2024 The Qt Company Ltd. :: Copyright (C) 2024 The Qt Company Ltd.
:: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 :: SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
qsb --glsl 320es,410 --hlsl 50 test.vert -o test.vert.qsb qsb --glsl 320es,410 --hlsl 50 test.vert -o test.vert.qsb
qsb --glsl 320es,410 test.geom -o test.geom.qsb qsb --glsl 320es,410 --hlsl 50 test.geom -o test.geom.qsb
qsb -r hlsl,50,test_geom.hlsl test.geom.qsb
qsb --glsl 320es,410 --hlsl 50 test.frag -o test.frag.qsb qsb --glsl 320es,410 --hlsl 50 test.frag -o test.frag.qsb

View File

@ -4,6 +4,7 @@
layout(points) in; layout(points) in;
layout(line_strip, max_vertices = 7) out; layout(line_strip, max_vertices = 7) out;
layout(location = 0) in vec4 v_position[];
layout(std140, binding = 0) uniform buf { layout(std140, binding = 0) uniform buf {
float radius; float radius;
@ -16,7 +17,7 @@ void main(void)
{ {
float theta = float(i) / 6.0f * 2.0 * M_PI; float theta = float(i) / 6.0f * 2.0 * M_PI;
gl_Position = gl_in[0].gl_Position; gl_Position = v_position[0];
gl_Position.xy += radius * vec2(cos(theta), sin(theta)); gl_Position.xy += radius * vec2(cos(theta), sin(theta));
EmitVertex(); EmitVertex();

View File

@ -1,8 +1,10 @@
#version 440 #version 440
layout(location = 0) in vec3 position; layout(location = 0) in vec3 position;
layout(location = 0) out vec4 v_position;
void main() void main()
{ {
gl_Position = vec4(position, 1.0); v_position = vec4(position, 1.0);
gl_Position = v_position;
} }

View File

@ -1,26 +0,0 @@
struct VertexOutput
{
float4 position : SV_Position;
};
struct PixelInput
{
float4 position : SV_POSITION;
};
cbuffer buf : register(b0)
{
float radius : packoffset(c0);
};
[maxvertexcount(7)]
void main(point VertexOutput input[1], inout LineStream<PixelInput> OutputStream)
{
PixelInput output;
for (int i = 0; i < 7; ++i) {
float theta = float(i) / 6.0f * 2.0 * 3.14159265;
output.position = input[0].position;
output.position.xy += radius * float2(cos(theta), sin(theta));
OutputStream.Append(output);
}
}