QDockWidgetGroupWindow (aka "floating tabs") can have a single
QDockWidget child only, when a second QDockWidget is hovering over it.
When the QDockWidgetGroupWindow detects the disappearance of its second
last child, it reparents the last child to the QMainWindow and makes it
floating. It removes its last dock widget child from its own
item_list and itself from its parent's (the main window's) item_list.
Then the QDockWidgetGroupWindow removes itself by calling its
deleteLater() slot.
A removal from an item_list calls the d'tor of QDockAreaLayoutItem,
which deletes the item's subinfo and placeholder item, if they exist.
It does not delete the item's widgetItem. In fact the layout accesses
the widgetItem member to draw placeholders and decorations.
As a consequence, both the QDockWidgetGroupWindowItem and the
QDockWidgetItem are leaked, when the corresponding record is removed.
Implement QDockAreaLayout::takeWidgetItem(), which transfers ownership
of QDockAreaLayoutItem::widgetItem to the caller by returning a
std::unique_ptr.
Call this method in QDockWidgetGroupWindow::destroyOrHideIfEmpty() and
QDockWidgetGroupWindow::reparentToMainWindow().
As a drive-by, use static_cast<QMainWindow *>() and assert a
qobject_cast in debug mode.
Fixes: QTBUG-135442
Pick-to: 6.8 6.5
Change-Id: I055c998f515f2bb461518b7516f56db4673687da
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
(cherry picked from commit 4076638022)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
tst_QSizeGrip::hideAndShowOnWindowStateChange is flaky on Ubuntu where
the widget is not set to fullscreen when it should. Wait for the the
widget to be exposed when shown the first time.
Fix flakiness on Ubuntu 24.04
Pick-to: 6.8 6.5
Change-Id: I9f5ea9ebb58c7505f841e5420dd2c15e5f0f2799
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit 5ced648feb)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
If the interface has a method with a specified return value, the
generated adapter will contain a code like:
bool out;
QMetaObject::invokeMethod(parent(), "Func", Q_RETURN_ARG(bool, out));
return out;
In this case Q_RETURN_ARG macro makes sure that the variable `out` is
properly initialized before being returned from a function, but only
if invokeMethod() call is executed successfully.
Update the generator to zero-initialize (or value-initialize) the
return variable, so that it returns some reasonable value even if
invokeMethod() fails.
Extend the unit-tests to make sure that the generated adapters always
initialize the return variables.
Coverity-Id: 479703
Pick-to: 6.8 6.5
Change-Id: I4d15ccc6844b5ca454ab9f0cf72fd8e3f0c1b704
Reviewed-by: Matthias Rauter <matthias.rauter@qt.io>
(cherry picked from commit 92c2ebdbcc)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
We want tst_qfloat16 to be built in C++20 mode, even if Qt itself is
not built in C++20 mode, which means we can't use QT_FEATURE_cxx20 as
check in tst_qfloat16's CMakeLists.txt.
In addition, even if the compiler supports C++20, the standard library
may not support all features we need. Specifically, due to the
deployment target of macOS being 12 we can't rely on std::to_chars
being available, as is only available since macOS 13.4.
This patch introduces a separate QT_FEATURE_cxx20_format, and
adjusts the tst_qfloat16's CMakeLists.txt to use this feature.
Note that we intentionally do not add QT_FEATURE_cxx20 as a
hard condition to the new check, because it might be disabled
during the Qt configuration, but we still want the test to be
built in C++20 mode.
Note also, that we cannot use the QT_CONFIG(cxx20_format)
check in the qtformat_impl.h header, because the std::format
support is header-only, and user project might be compiled
for a different minimal macOS version, so we do not want to
rely on the Qt-specific config.
Pick-to: 6.8
Change-Id: Ibc43d243dbb24fcb922647fe2d90f61491144eb7
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit f0573e93df)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Currently all the tests are expected to pass because we always
convert everything to UTF-8.
This is a pre-requisite for the follow-up patches that would try to
optimize the internal logic to minimize the number of encoding
conversions.
Task-number: QTBUG-124636
Pick-to: 6.8 6.5
Change-Id: I0ac9212aeb8ccc768393e80c9e0d704fdc227b56
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 900d1daaeb)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The addData(QASV) overload was unconditionally converting UTF-16 and
Latin1 data to UTF-8.
However, if we already started reading the XML document, and we know
that its encoding is UTF-16 or Latin1, then we know for sure that the
new data has to be added as-is.
Amends 6bc227a06a.
[ChangeLog][QtCore][QXmlStreamReader] Fixed a bug when
addData(QAnyStringView) was incorrectly recoding UTF-16 and Latin1
data to UTF-8, thus potentially mangling it.
Fixes: QTBUG-135129
Pick-to: 6.8 6.5
Change-Id: Ie1171a5e5596b72a6f160031a4c5a9df3baae4fd
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit b6b725aef5)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
In some cases the QNX events can be stale ie. referring to a window
object that is already destroyed. This is not necessarily a fatal
condition, but there are some qFatal() statements in this case which
could be removed.
Fixes: QTBUG-135076
Pick-to: 6.8 6.5 5.15
Change-Id: I885fa95c323590a814176b8a70ef5b7ee332012c
Reviewed-by: James McDonnell <jmcdonnell@blackberry.com>
(cherry picked from commit 1e10ede244)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
We don't need to apply QDir::absolutePath() on the diretory that
QLibraryInfo::path() returns, because that is already an absolute path
(and if it weren't, it wouldn't make a difference anyway). That means we
are only doing path concatenation here. For code this low-level, it's
better to stick to QString.
This commit also rejiggles the string variables so we avoid one of the
memory allocations when calling QStandardPaths.
Change-Id: Ic3405877155a15ac4ac6fffdc92463ae0bff0bd9
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
(cherry picked from commit e0cdcf66ca)
Not on values. That is, it indicates whether there is a conversion path
from origin type to the destination type, not that the conversion will
succeed when attempted. For example:
QObject *o = new QAbstractItemModel;
QVariant variant = QVariant::fromValue(o);
qDebug() << variant.canConvert<QAbstractItemModel*>();
This conversion *will* succeed for this particular value of a QObject*,
so canConvert() must return true for conversions between QObject* and
QAbstractItemModel*, despite not all such conversions being possible.
This is also done in preparation of changes being done to the conversion
routines that may cause some FP->integer conversions to fail depending
on the value of the FP.
Fixes: QTBUG-135619
Task-number: QTBUG-135285
Pick-to: 6.8
Change-Id: I138e34fb61a8b8772c8bfffdf75787a2e007d847
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
(cherry picked from commit 7cf49085eb)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
MSVC is pedantic that read() (a POSIX function) is not an ISO C function
so insists that we use the underscored version. As if Microsoft followed
that rule for their own APIs...
Amends e6a6757c14.
Pick-to: 6.8
Change-Id: If51fd8564a3c415e1f7efffd7fde18a830c97e3b
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 9ffbeae50e)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The former will try to normalize the type name, but everything stored
in a QMetaObject is already in normalized form. So, if the first
lookup fails, the normalized one won't succeed either.
Use qMetaTypeTypeInternal(), which doesn't normalize.
At a minimum, this will fail faster. If we're lucky, the missing
round-trip via QMetaType(int).id() will help the positive case, too.
But if it does, it's lost in the statistical noise of the benchmark.
IOW: no measurable performance impact.
Task-number: QTBUG-135572
Change-Id: I23834c201fbcd1780c50e85cf8a15ea5e4a94c74
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit a481a79a97)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The only caller of the function, QArgumentType, passes
QByteArray::constData() to it, and the function then goes around and
performs a strlen() in order to feed it into qMetaTypeTypeInternal().
Pass the name as a QByteArrayView, to save the strlen() over a string
we already knew the length of.
No measurable performance impact.
Task-number: QTBUG-135572
Change-Id: Ifccea7644ce86308df5fb7063c0269a579785504
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
(cherry picked from commit cac63042b1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
QMetaType::fromName() takes a QBAV, so don't feed it rawStringData()
(a const char*, causing the QBAV ctor to run strlen() on it), but
stringDataView() (a QBAV already, whose length is determined by offset
difference in the string offset table and not by strlen()).
No measurable difference in runtime speed.
Pick-to: 6.8 6.5
Change-Id: I583bea9d818deeaac6f62803f7ac5ab4766cb8a5
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 1445a33b6f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Amends 22ce92f804, which apparently
changed the method name stored in the moc data from unqualified to a
qualified name. The original commit message doesn't mention it, but
the change in QMetaMethodPrivate::name() suggests as much.
Unfortunately, the search for the colon causes the name() call to
increase to 25% of the total methodMatch() runtime, up from 6.85%
before the change.
Since name() now always strips a possible prefix, re-add the original
name() as qualifiedName() and use that in methodMatch().
This is faster because we don't need to perform an a-priori search for
colons; instead, we can first check for endsWith(), and only if we
have a match, can we a-posteriori check that the match was preceded by
an (optional) colon.
Results on my machine:
********* Start testing of tst_QObject *********
Config: Using QtTest library 6.10.0, Qt 6.10.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by Clang 15.0.3 (github.com:llvm/llvm-project.git 48b23aa469b8cfdb6cde1c55bf3361cabcdef6bc)), ubuntu 20.04
PASS : tst_QObject::initTestCase()
PASS : tst_QObject::connect_disconnect_benchmark(normalized signature)
RESULT : tst_QObject::connect_disconnect_benchmark():"normalized signature":
- 923.542494 nsecs per iteration (total: 461,771,247, iterations: 500000)
+ 880.558792 nsecs per iteration (total: 440,279,396, iterations: 500000)
- 4,340.832532 CPU cycles per iteration, 4,7 GHz (total: 2,170,416,266, iterations: 500000)
+ 4,093.487614 CPU cycles per iteration, 4,65 GHz (total: 2,046,743,807, iterations: 500000)
- 13,706.07561 instructions per iteration, 3,157 instr/cycle (total: 6,853,037,807, iterations: 500000)
+ 12,779.02463 instructions per iteration, 3,122 instr/cycle (total: 6,389,512,318, iterations: 500000)
- 2,201.185595 branch instructions per iteration, 2,38 G/sec (total: 1,100,592,798, iterations: 500000)
+ 2,208.176500 branch instructions per iteration, 2,51 G/sec (total: 1,104,088,250, iterations: 500000)
For a ~5% overall speedup in both ns/iter and instr/iter, keeping in
mind that this data contains the disconnect() call, too.
As a drive-by, remove a second call of QMetaObjectPrivate::get() on the
same object, and reuse the previous call's result.
Task-number: QTBUG-135572
Change-Id: Ide253b323e7b826f8fa09d2f5f57496861c12f75
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
(cherry picked from commit 8e98a3a826)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
For the thread that calls ::exit() (usually, the main thread).
Otherwise, depending on construction order, it is possible for the
QThreadStorage's destructor list to have been destroyed by the time
destroy_current_thread_data() → QThreadData::finish() calls our
finish().
Fixes: QTBUG-135044
Pick-to: 6.8
Change-Id: Ic5a10367ff31e7faa039fffdc2067eba9642fbf9
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 81a7a4c2d9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
By using QStringView.
Drive-by, explicitly use QBA::constData() to fix the build with
QT_NO_CAST_FROM_BYTEARRAY.
Pick-to: 6.5
Change-Id: I57bcd877048f3b9889ab8d638979f893857af396
Reviewed-by: David Faure <david.faure@kdab.com>
(cherry picked from commit f7db58335b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Specialize the cast template for QGraphicsItem, where we can skip the
runtime comparisons of the type.
In addition, replace the runtime check for QGraphicsItem::Type with a
compile time check in the main template.
We need to do both so that we correctly cast up to QGraphicsItem for
custom item types that don't provide their own Type alias.
Pick-to: 6.8
Change-Id: Ic1bff3404fe890747865ce1349cddbcfebb3b77b
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit 7af5912e61)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Popups aren't automatically positioned, so use the screen at the initial
geometry for scaling. Otherwise we may end up with the wrong geometry on
systems that have multiple screens with different scales.
Pick-to: 6.8
Fixes: QTBUG-134139
Change-Id: I686b1c8ab6cf458d9b849b529ba247ac8c3be064
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit 7dc2532bed)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Got two independent bug reports where people got hit by that and had
to do a long and difficult debugging session to find out what was
happening (and still thought it was a Qt bug).
Fixes: QTBUG-54484
Fixes: QTBUG-50821
Change-Id: I0041fccebbb7070fccf8014288c62d89f117ae7d
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 687422abde)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Building without shortcuts would fail due to a missing QKeySequence.
This was already handled in the implementation but required an ifdef in
the header.
Change-Id: I12c92ca480d0abdb518aae00b5b7e259133ef9ca
Pick-to: 6.8 6.5
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
(cherry picked from commit 0a281beaa7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
QAbstractSlider::sliderChange() is not a signal, but a protected
function, carrying an enum (also protected) to inform subclasses about
changes in the base class.
A user reported (QTBUG-135597) that in 5.15 the function was not
called for SliderOrientationChange.
Add a test that verfies that the function is a) called for all other
enum values and b) add XFAILs for the (still) missing
SliderOrientationChange.
Amends the start of the public history.
Pick-to: 6.8 6.5 5.15
Task-number: QTBUG-135597
Change-Id: I959077f030976937dd279897748025afa06e74dd
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit f4e892d797)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The process by which the QDockAreaLayout changes a QDockAreaLayoutInfo
from representing a QWidget that's being deleted to representing a
QPlaceholderItem involves the construction of the latter from the
former. If a QDockWidget is being deleted, however, at the time the
QDockAreaLayout notices, the ex-QDockWidget has been demoted to a
QObject, causing the calls to QWidget member functions to be UB:
Says UBSan:
qdockarealayout.cpp:46:25: runtime error: member call on address 0x7ffe74a429d0 which does not point to an object of type 'QWidget'
0x7ffe74a429d0: note: object is of type 'QObject'
33 7f 00 00 c0 ea 73 6e 33 7f 00 00 00 12 00 00 70 61 00 00 40 cd 41 83 33 7f 00 00 00 00 00 00
^~~~~~~~~~~~~~~~~~~~~~~
vptr for 'QObject'
#0 0x7f339546e251 in QPlaceHolderItem::QPlaceHolderItem(QWidget*) qdockarealayout.cpp:46
#1 0x7f33955169a8 in QDockAreaLayoutInfo::takeAt(int*, int) qdockarealayout.cpp:1780
#2 0x7f3395517175 in QDockAreaLayout::takeAt(int*, int) qdockarealayout.cpp:3432
#3 0x7f33959e38a8 in QMainWindowLayoutState::takeAt(int, int*) qmainwindowlayout.cpp:927
#4 0x7f33959e38a8 in QMainWindowLayoutState::takeAt(int, int*) qmainwindowlayout.cpp:919
#5 0x7f3395a42cdd in QMainWindowLayout::takeAt(int) qmainwindowlayout.cpp:2238
#6 0x7f3393fae246 in removeWidgetRecursively qlayout.cpp:485
#7 0x7f3393fb8300 in QLayout::widgetEvent(QEvent*) qlayout.cpp:544
#8 0x7f3393bde28a in QApplicationPrivate::notify_helper(QObject*, QEvent*) qapplication.cpp:3298
#9 0x7f3393c5f74a in QApplication::notify(QObject*, QEvent*) qapplication.cpp:3259
#10 0x7f336b784ada in QCoreApplication::notifyInternal2(QObject*, QEvent*) qcoreapplication.cpp:1111
#11 0x7f336b7874e3 in QCoreApplication::sendEvent(QObject*, QEvent*) qcoreapplication.cpp:1551
#12 0x7f336bcc624a in QObjectPrivate::setParent_helper(QObject*) qobject.cpp:2271
#13 0x7f336bccd76c in QObject::~QObject() qobject.cpp:1146
#14 0x7f339434e126 in QWidget::~QWidget() qwidget.cpp:1584
#15 0x7f33955b5815 in QDockWidget::~QDockWidget() qdockwidget.cpp:1362
[...]
qwidget.h:816:25: runtime error: member call on address 0x7ffe74a429d0 which does not point to an object of type 'QWidget'
0x7ffe74a429d0: note: object is of type 'QObject'
33 7f 00 00 c0 ea 73 6e 33 7f 00 00 00 12 00 00 70 61 00 00 40 cd 41 83 33 7f 00 00 00 00 00 00
^~~~~~~~~~~~~~~~~~~~~~~
vptr for 'QObject'
#0 0x7f339546e0bb in QWidget::isWindow() const qwidget.h:816
#1 0x7f339546e0bb in QPlaceHolderItem::QPlaceHolderItem(QWidget*) qdockarealayout.cpp:47
[... rest as above...]
Fix by dragging the setParent(nullptr) up into ~QDockWidget().
Ordinarily, that call happens only in ~QObject(). But that's what
caused the layout to react to the ChildRemoved element too late. When
doing it here, the dock widget is still itself, and all the
QDockAreaLayout machinery can still access its QWidget-ness.
Amends the start of the public history.
After consulting with QtWidgets maintainer, not picking to 5.15,
since, even though slim, there's a non-zero chance this might break
something, somewhere.
Pick-to: 6.8 6.5
Change-Id: I5472bbb0fcab9fb74272a1da6c2a2896226e12bb
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
(cherry picked from commit 2c67d47ea1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
When I ported the QTimer::defaultTypeFor() helper from ms to ns
granularity, I failed to account for MSVC, in which inline functions
of exported classes are themselves exported.
As a consequence, the private QTimer::defaultTypeFor(milliseconds)
symbol went missing.
To fix, re-add it as REMOVED_SINCE API.
We don't need to play tricks with QT6_*_NEW_OVERLOAD here, since the
overloads have a different signature and the only callers¹ are either
passing an exact ms or ns argument² or are in dependent names in
templates³ which removed_api.cpp does not instantiate.
¹ this is a private function, so we don't need to look very far...
² the string-based singleShot() overloads
³ and so name lookup (and therefore overload resolution) happens only
at instantiation time, not at template parse time (so Integrity and
VxWorks compilers will, that is)
Amends a60e341145a3b8a106e556e17ae62d2f45ac5d74.
Pick-to: 6.8
Fixes: QTBUG-135578
Change-Id: I375e6f04a3af3824f980fe59775d3eea94250987
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 27ed0014b4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
GCC, with ubsan and optimization enabled, issues -Warray-bounds for
the cast from &polygonItem to QGraphicsTextItem*, because the latter
is-a QObject and the former is not, so the cast has to adjust the
pointer value to correct for the fact that QGraphicsItem is not the
first base class of QGraphicsTextItem:
qgraphicsitem.h:973:56: warning: array subscript -1 is outside array bounds of ‘QGraphicsPolygonItem [1]’ [-Warray-bounds]
973 | || (item && int(Item::Type) == item->type()) ? static_cast<T>(item) : nullptr;
| ^~~~~~~~~~~~~~~~~~~~
tst_qgraphicsitem.cpp:3193:26: note: while referencing ‘polygonItem’
Check the implementation is correct in this respect by not just
checking for nullptr or non-nullptr, but checking that the result
matches what dynamic_cast produces.
We can assume dynamic_cast works on QGraphicsItems because QPA is
using dynamic_cast, so both QtGui and QtWidgets need to have been
compiled with RTTI enabled.
This doesn't eliminate the GCC warning, but confirms that it is a
False Positive.
Pick-to: 6.8 6.5
Change-Id: Ifc262cb6e715e8e68c180855adc2467960da89a1
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 101427957b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
... instead of QByteArray.
This is part of a quest to improve string-based connect() performance.
Needed to port a few consumers of decodeMethodSignature()'s result
from QByteArray to QByteArrayView, too. All private API, so doesn't
affect users.
This doesn't change anything in tst_bench_qobject's
connect_disconnect_benchmark:normalized signature, yet.
Task-nunber: QTBUG-135572
Change-Id: I1cd5b410ee090ab9c6f3aa8095a4d9efae516ac0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit f2747c62d4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
A QWidget* is not a faithful representation of a QDockWidgetLayout, so
the ctor should be explicit, even if this is but a private class.
Amends the start of the public history.
Pick-to: 6.8 6.5 5.15
Change-Id: Ib69d72540f094542dbcfc0684e2eec5f90aa532a
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
(cherry picked from commit 21c9aac20a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The function can be called from ~QMdiSubwindow(), and we checked for
QWidgetPrivate::data.in_destructor before proceeding with the removal
of buttons from the menubar, but we called
QPointer<QMdiSubwindow>::data()->window(), which, at this point in
time, had already been demoted to a QWidget:
Says UBSan:
qpointer.h:75:14: runtime error: downcast of address 0x6040000aca10 which does not point to an object of type 'QMdiSubWindow'
0x6040000aca10: note: object is of type 'QWidget'
00 00 00 00 28 01 99 bc ff 7e 00 00 80 dc 0f 00 90 61 00 00 d8 02 99 bc ff 7e 00 00 00 00 be be
^~~~~~~~~~~~~~~~~~~~~~~
vptr for 'QWidget'
#0 0x7effb955f95a in QPointer<QMdiSubWindow>::data() const qpointer.h:75
#1 0x7effb955f95a in QPointer<QMdiSubWindow>::operator->() const qpointer.h:79
#2 0x7effb955f95a in QMdi::ControlContainer::removeButtonsFromMenuBar(QMenuBar*) qmdisubwindow.cpp:795
#3 0x7effb9563031 in QMdi::ControlContainer::~ControlContainer() qmdisubwindow.cpp:717
#4 0x7effb9566595 in QMdi::ControlContainer::~ControlContainer() qmdisubwindow.cpp:723
#5 0x7eff8f4f2b7a in QObjectPrivate::deleteChildren() qobject.cpp:2226
#6 0x7effb7bf732d in QWidget::~QWidget() qwidget.cpp:1557
#7 0x7effb95cc02c in QMdiSubWindow::~QMdiSubWindow() qmdisubwindow.cpp:2254
#8 0x7effb95cc1d5 in QMdiSubWindow::~QMdiSubWindow() qmdisubwindow.cpp:2254
#9 0x7eff8f4f2b7a in QObjectPrivate::deleteChildren() qobject.cpp:2226
#10 0x7effb7bf732d in QWidget::~QWidget() qwidget.cpp:1557
#11 0x7effb7bffba5 in QWidget::~QWidget() qwidget.cpp:1584
#12 0x7eff8f4f2b7a in QObjectPrivate::deleteChildren() qobject.cpp:2226
#13 0x7effb7bf732d in QWidget::~QWidget() qwidget.cpp:1557
#14 0x7effb85f0dc5 in QFrame::~QFrame() qframe.cpp:235
#15 0x7effb859c747 in QAbstractScrollArea::~QAbstractScrollArea() qabstractscrollarea.cpp:478
#16 0x7effb93c08a6 in QMdiArea::~QMdiArea() qmdiarea.cpp:1703
#17 0x7effb93c0e55 in QMdiArea::~QMdiArea() qmdiarea.cpp:1703
#18 0x7eff8f4f2b7a in QObjectPrivate::deleteChildren() qobject.cpp:2226
#19 0x7effb7bf732d in QWidget::~QWidget() qwidget.cpp:1557
#20 0x7effb920a425 in QMainWindow::~QMainWindow() qmainwindow.cpp:338
Fix by deleting the ControlContainer already from ~QMdiSubwindow(),
ie. when we have not yet been demoted to QWidget.
Amends the start of the public history.
Pick-to: 6.8 6.5 5.15
Change-Id: Ia43c857bc1842b2b4957cc79e00f790b045d8f94
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
(cherry picked from commit 2e3d39130c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
QVector instead of QList is currently still treated specially, being
considered normalized even if a signature piped through
normalizeSignature() would have changed.
We'd like to get rid of this special treatment, so add some tests for
invokeMethod() + Q_ARG, which we should continue to support.
Pick-to: 6.8 6.5
Task-number: QTBUG-135572
Change-Id: Ie09c80d2a8603a268859f395797196013efd8c0f
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 1fa31be7ce)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Static variables are only initialized once, when control passes over
their definition for the first time¹. If they are initialized with
non-static data, like the contents of a non-static data member, or the
address of one, then all following uses of the object will continue to
use the first control pass' data, even if the data members were from
an object that has since been deleted.
This whole construct appears to have worked merely because these
functions are only executed once, or at least not on different
objects. But better remove the dangerous construct while it hasn't
broken something, yet, and before we e.g. make syncqt a library² or
add a mode that makes it scan multiple modules at once.
Requires to capture more variables in the parseArgument() lambda; more
than fits into an explicit capture list, so use a [&] catch-all
instead.
As a drive-by, use CTAD to not have to mention the number of elements
in a std::array, but have the compiler deduce them, and add const,
where it's missing.
Amends b89d63515b (and maybe a few
in-between, we'll see when cherry-picking).
¹ Except corner-case like when initialization fails by throwing an
exception.
² see similar ideas for moc, e.g.: QTBUG-132820
Pick-to: 6.8 6.5
Change-Id: I65a73059151e3d39341939f613080e6d833a4c30
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
(cherry picked from commit 01ced9d45a)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
QEventStorage<E> will slice if you call store(e) where typeid(e) !=
typeid(E). But if they are the same, no slicing occurs.
So change the code comment from "always slices" to "may slice".
Amends dd264cc9c0.
Task-number: QTBUG-99563
Task-number: QTBUG-133321
Change-Id: Ic69d2d3e6b5491c2d3e61d8da131f4bda628fe95
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
(cherry picked from commit 5d2164382c)
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
QPointer is used to track whether a QObject is still alive, and so
it's unsurprising that checking whether the pointer is null is
sometimes done in situations where the QObject is already in the
process of being destroyed and therefore already demoted from T, the
QPointer template argument, to some base class.
Because of the way we made QPointer SCARY¹, calling data() will cast
from QObject* to T*, which is UB if the T was already demoted.
It's hard to fix this in the general case, but the various ways to
spell isNull() should all be equivalent to isNull() (which does not
cause UB, because it doesn't cast).
This patch fixes the relational operators against nullptr and adds an
explicit operator bool() so that if (p) and if(!p) no longer have to
go through (implicit) operator T*(). This does not appear to cause
disambiguities, so it's SC.
Don't document the operator, it's an implementation detail (and not
documenting it lets us pick it back). A follow-up will add the
documentation for 6.10+.
Add tests, even for stuff that's currently still UB (but marked by an
early return). A follow-up patch will try to make as many of these
other operations non-UB as possible, too.
¹ Originally 3f7741fbe7, then changed in
cc7239da8d and
351c738fc4.
Amends the commits mentioned in the footnote.
[ChangeLog][QtCore][QPointer] For `QPointer<Derived> p`, `!p` and
comparing `p` to nullptr no longer perform invalid downcasts when the
object held in `p` is in the process of being destroyed and has
already been demoted from Derived to one of its base classes. Before,
these expressions invoked data(), which casts from QObject* to
Derived*, a cast which is invalid.
Pick-to: 6.8 6.5 5.15
Task-number: QTBUG-135626
Change-Id: I1b59062345e1b6933958c7e030d9253d69e7591c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 51cd57116b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
... not just 'derivedChild'.
This doesn't change anything for the test right now, but will enable
an extended test to be added on top.
Pick-to: 6.8 6.5 5.15
Change-Id: Id52f785168c97c43433fb15a6a71a9d1fb140036
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 4c610300e3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This updates the documentation for QXmlStreamReader and QXmlStreamWriter
to explicitly state that only XML 1.0 is supported. While the writer
allows specifying arbitrary version strings, it does not implement
XML 1.1 features. The reader strictly enforces XML 1.0 and rejects
unsupported versions.
Fixes: QTBUG-43029
Pick-to: 6.8 6.5
Change-Id: I771de29e7915d7a4daafe2fe14d600adfbbac4ac
Reviewed-by: Mate Barany <mate.barany@qt.io>
(cherry picked from commit 6551bef9d9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Fix the condition that decides whether to build InputSupportPrivate. The
conflict resolution went wrong for
b3b836e703. The point of the commit is to
disable InputSupportPrivate if QT_FEATURE_libinput is enabled but
QT_FEATURE_xkbcommon is not.
Change-Id: I58a924abcf9ab5469e14182d1fdbb3fd69c1e74f
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Avoid the duplicated data tags in removeAt() tests by adding the
orientation to the tag.
Pick-to: 6.8 6.5
Fixes: QTBUG-135294
Change-Id: If31d719e4a9b1c90e591cedc149848bbb9c99657
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 0b668c2f55)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The test function created a parent-less QGraphicsWidget, and while it
added a bunch of child objects to it, that initial graphics-widgets
never got an owner so it and all the children were leaked.
Fix by holding it in a unique_ptr. That is the minimally-invasive fix.
Amends the start of the public history.
Pick-to: 6.6 6.5 5.15
Change-Id: I3ab9db721e1343f2bd8d9fdd0ee6e86733a66da2
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit 2e0988190f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The populateLayout() function adds parent-less QGraphicsWidgets
(RectItems) to the layout. If the layout had a graphics-widget parent,
it would reparent the items added to it onto the parent. But it
didn't, so it didn't.
Therefore, the last part of the test function (as denoted by the
re-creation of `layout`) leaked a lot of items, including `layout`.
To fix, give the layout the existing graphics-widget parent. Then the
layout itself isn't leaked anymore, either.
Amends the start of the public history.
Essentially the same commit for columnCount() that
b9836518a3 was for rowCount().
Pick-to: 6.8 6.5 5.15
Change-Id: Ic38dfccfa41049d96eb0cf5811271ac17f2b1f91
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit d21434d187)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The test function creates a bunch of QGraphicsWidgets without parents,
and adding them to the QGraphicsGridLayout doesn't make them owned by
it. Besides, the layout was without a parent itself, so all these
objects were leaked.
To fix, give the layout a stack-allocated QGraphicsWidget parent. Now,
the layout will reparent the widgets added to it to its own parent
widget, which will delete layout and child widgets when it itself is
deleted on all exists from the test function.
Amends the start of the public history.
Pick-to: 6.8 6.5 5.15
Change-Id: I8d80713f4ff6b1055bc396d855f98bc1873aee3b
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit fe0b29a45c)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The test function created a parent-less QGraphicsWidget on the heap,
and didn't otherwise transfer ownership of it to another object, so
the object was leaked.
The minimal fix is to hold the graphics-widget in a unique_ptr. This
requires to change the following line, too (as would the alternative,
allocation on the stack), but the rest of the function can stay as-is
(unlike with stack allocation, which would require further s/[.]/->/.
Amends 4f072e2d3d.
Pick-to: 6.8 6.5 5.15
Change-Id: Ide305dde7934747dbc3acdb49f5a75e98563828c
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit 45f317fba0)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The test function contains a negative test where we're trying to
remove an item that isn't in the layout.
Unfortunately, the object we're passing is heap-allocated and has no
parent, so was leaked.
To fix, pass the existing `widget` as a parent. This doesn't change
the test's outcome: Like in QWidget, a graphics-widget is not
automatically added to its parent's layout.
Amends the start of the public history.
Pick-to: 6.6 6.5 5.15
Change-Id: Ic110ea7b93aa0023c0903c776a30dc5c377ce0c5
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit 4d0f979610)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The `form` graphics-widget has no parent and is not otherwise added to another
object that would take ownership of it, so it was leaked, together with its children.
To fix, simply create it on the stack. This is the minimally-invasive fix.
Had I held it in unique_ptr instead, I would have had to touch the line
creating `layout`, too. Creating it on the stack is simpler than make_unique(), so do that.
Amends the start of the public history.
Pick-to: 6.8 6.5 5.15
Change-Id: I4027dcb0c0650eb7556de96e6d1d20b98c14dc9a
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit cba8f19ff8)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Both `layout` and `wid` were created without parents, and not otherwise added to
objects that would take their ownership; only `layout` was explicitly deleted
at the end of the function, `wid` was leaked.
The usual solution, giving them a stack-allocated graphics-widget as
parent that will delete them, doesn't work here, because the layout
does refuse to add the widget in some test rows.
Since there are no checks in-between the allocation and de-allocation
(this test is only checking for expected warning messages), do the
minimal fix and explicitly delete `wid`, as it was already done for
`layout`.
Amends the start of the public history.
Pick-to: 6.8 6.5 5.15
Change-Id: I5c7356ac93c04d648eb31888105b480791fbe155
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit b518a385ad)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The deleted 'widget' was added to a stack-allocated QGraphicsScene,
which owns it and will delete it as its child if it itself is deleted.
There's no check following the manual delete, and the test function's
name shows no indication that deleting graphics-widgets from a scene
in a show()n QGraphicsView is being tested here, so it serves no
purpose.
Remove it.
Amends the start of the public history.
Pick-to: 6.8 6.5 5.15
Change-Id: I4e5405cd6212d2a318a567d99ef42c99261d431a
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit fc89096bcb)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The populateLayoutWithSpansAndHoles() function adds parent-less
QGraphicsWidgets (RectItems) to the layout. If the layout had a
graphics-widget parent, it would reparent the items added to it onto
the parent. But it didn't, so it didn't.
Therefore, the last part of the test function (as denoted by the
re-creation of `layout`) leaked a lot of items, including `layout`.
To fix, give the layout the existing graphics-widget parent. Then the
layout itself isn't leaked anymore, either.
Amends the start of the public history.
Pick-to: 6.8 6.5 5.15
Change-Id: I063c0e3336d943a35592fa62a5d16cbddb6b920e
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit b9836518a3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The populateLayout() function adds parent-less QGraphicsWidgets
(RectWidgets) to the layout. If the layout had a graphics-widget
parent, it would reparent them onto the parent. But it didn't, so it
didn't.
Therefore, the 2nd and 3rd part of the test function (as denoted by
the top-level scopes in the function) leaked a lot of items.
The first part of the function already used a widget, itself without
parent, but added to a QGraphicsScene allocated on the stack, so was
not leaking.
To fix, give the layouts a graphics-widget parent. Then the layout
doesn't need to be deleted anymore, either.
Amends the start of the public history.
Pick-to: 6.8 6.5 5.15
Change-Id: I7e63c51cf037818fb1e519dab5394ad75c74d67d
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit 5a559758d1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
The event filter was still active when the QDialogButtonBox in its
destruction process had already been demoted to QWidget. The
ignoreShowAndHide guard came too late, because by the time we check
it, in Private::handleButtonShowAndHide(), we had already cast q_ptr
to QDialogButtonBox.
Says UBSan:
qdialogbuttonbox_p.h:26:5: runtime error: downcast of address 0x7fffefab47e0 which does not point to an object of type 'QDialogButtonBox'
0x7fffefab47e0: note: object is of type 'QWidget'
00 00 00 00 28 c1 5b 6e 6d 7f 00 00 80 22 10 00 90 61 00 00 d8 c2 5b 6e 6d 7f 00 00 00 00 00 00
^~~~~~~~~~~~~~~~~~~~~~~
vptr for 'QWidget'
#0 0x7f6d6b51141d in QDialogButtonBoxPrivate::q_func() qdialogbuttonbox_p.h:26
#1 0x7f6d6b51141d in QDialogButtonBoxPrivate::handleButtonShowAndHide(QAbstractButton*, QEvent*) qdialogbuttonbox.cpp:913
#2 0x7f6d6b51436c in eventFilter qdialogbuttonbox.cpp:127
#3 0x7f6d40c1a8f1 in QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject*, QEvent*) qcoreapplication.cpp:1248
#4 0x7f6d690b23d5 in QApplicationPrivate::notify_helper(QObject*, QEvent*) qapplication.cpp:3303
#5 0x7f6d69132a3a in QApplication::notify(QObject*, QEvent*) qapplication.cpp:3259
#6 0x7f6d40c1da6a in QCoreApplication::notifyInternal2(QObject*, QEvent*) qcoreapplication.cpp:1111
#7 0x7f6d40c20473 in QCoreApplication::sendEvent(QObject*, QEvent*) qcoreapplication.cpp:1551
#8 0x7f6d690fe76c in QApplicationPrivate::setActiveWindow(QWidget*) qapplication.cpp:1857
#9 0x7f6d695ac796 in QWidgetPrivate::deactivateWidgetCleanup() qwidget.cpp:2326
#10 0x7f6d6976f8ce in QWidgetPrivate::hide_sys() qwidget.cpp:8256
#11 0x7f6d69814579 in QWidgetPrivate::hide_helper() qwidget.cpp:8199
#12 0x7f6d69887c1f in QWidgetPrivate::setVisible(bool) qwidget.cpp:8406
#13 0x7f6d69775d23 in QWidget::setVisible(bool) qwidget.cpp:8314
#14 0x7f6d695fb018 in QWidget::hide() qwidget.cpp:8179
#15 0x7f6d6981a183 in QWidgetPrivate::handleClose(QWidgetPrivate::CloseMode) qwidget.cpp:8580
#16 0x7f6d699e6fc6 in QWidgetWindow::closeEvent(QCloseEvent*) qwidgetwindow.cpp:871
#17 0x7f6d52ef9f5d in QWindow::event(QEvent*) qwindow.cpp:2721
#18 0x7f6d69a575f8 in QWidgetWindow::event(QEvent*) qwidgetwindow.cpp:398
#19 0x7f6d690b2491 in QApplicationPrivate::notify_helper(QObject*, QEvent*) qapplication.cpp:3309
#20 0x7f6d69132a3a in QApplication::notify(QObject*, QEvent*) qapplication.cpp:3259
#21 0x7f6d40c1da6a in QCoreApplication::notifyInternal2(QObject*, QEvent*) qcoreapplication.cpp:1111
#22 0x7f6d40c205b3 in QCoreApplication::sendSpontaneousEvent(QObject*, QEvent*) qcoreapplication.cpp:1565
#23 0x7f6d5287415b in QGuiApplicationPrivate::processCloseEvent(QWindowSystemInterfacePrivate::CloseEvent*) qguiapplication.cpp:2911
#24 0x7f6d528b543f in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) qguiapplication.cpp:2259
#25 0x7f6d52fb5b02 in QWindowSystemEventHandler::sendEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) qwindowsysteminterface.cpp:190
#26 0x7f6d52fb5b02 in bool QWindowSystemHelper<QWindowSystemInterface::SynchronousDelivery>::handleEvent<QWindowSystemInterfacePrivate::CloseEvent, QWindow*>(QWindow*) qwindowsysteminterface.cpp:102
#27 0x7f6d52fb5b02 in handleWindowSystemEvent<QWindowSystemInterfacePrivate::CloseEvent, QWindowSystemInterface::SynchronousDelivery, QWindow*> qwindowsysteminterface.cpp:138
#28 0x7f6d52fb5b02 in bool QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(QWindow*) qwindowsysteminterface.cpp:351
#29 0x7f6d52cb6f1e in QPlatformWindow::close() qplatformwindow.cpp:348
#30 0x7f6d52e7e158 in QWindow::close() qwindow.cpp:2449
#31 0x7f6d6981b4d2 in QWidgetPrivate::close() qwidget.cpp:8632
#32 0x7f6d698205c6 in QWidget::~QWidget() qwidget.cpp:1508
#33 0x7f6d6b4f6bf0 in QDialogButtonBox::~QDialogButtonBox() qdialogbuttonbox.cpp:496
To fix, don't delay the Q_Q to until after the ignoreShowAndHide
check, since that woould be brittle. Instead, do as we for signal/slot
connections, which we disconnect explicitly in ~QDialogButtonBox(),
and delete the EventFilter explicitly there, too. This way, it's more
natural, and also prevents all those useless event filter invocations
from having to be processed later on.
Amends aff0915352. The original code,
using QDialogButtonBox::eventFilter(), was not affected, since by the
time QDialogButtonBox was demoted to QWidget, QWidget::eventFilter(),
not QDialogButtonBox::eventFilter() would been invoked. Which just
goes to show that one needs to be very careful with delegating too
much responsibilites to the Private class, as it lives, fully derived,
until ~QWidget() executes.
Pick-to: 6.8 6.5
Change-Id: I04f36fd6d7d160932bfe1494fdff464786b85047
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
(cherry picked from commit dceff0ace4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>