From 94316192f3d494d2aed884f87ab2a2a971191637 Mon Sep 17 00:00:00 2001 From: Noah Davis Date: Sat, 27 Jan 2024 10:10:10 -0500 Subject: QPainterPath: Fix boundingRect and controlPointRect ignoring start point The boundingRect and controlPointRect did not use the start point from the `QPainterPath(const QPointF &startPoint)` constructor until the `dirtyBounds` or `dirtyControlBounds` member variables were set to true. Those two are false on construction. This bug was fixed by adding a new constructor for QPainterPathPrivate that initializes the `elements`, `bounds` and `controlBounds` member variables with the start point from the constructor. There is also an autotest to verify that the top left of the boundingRect and controlPointRect are at the same position as elementAt(0) when the start point constructor is used. [ChangeLog][QtGui][QPainterPath] boundingRect() and controlPointRect() now use the start point from QPainterPath(const QPointF &startPoint). Change-Id: I7bf30364406c14ed60f75d24b78a9a5535f75d93 Reviewed-by: Eirik Aavitsland Reviewed-by: Qt CI Bot (cherry picked from commit a4f44e06988e91c21c85e0e9f29d656d61f9c68e) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 327dcc078de33bd1601a78e86b71e93a21cb1d20) (cherry picked from commit 3610198ab06964a0d4dfcc0557f2744f7c121f40) --- .../gui/painting/qpainterpath/tst_qpainterpath.cpp | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'tests') diff --git a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp index 20ee6e07c78..cb03d6cf469 100644 --- a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp +++ b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp @@ -81,6 +81,8 @@ private slots: void intersectionEquality(); void intersectionPointOnEdge(); + + void boundsAtStartPoint(); }; void tst_QPainterPath::cleanupTestCase() @@ -1442,6 +1444,32 @@ void tst_QPainterPath::intersectionPointOnEdge() QVERIFY(p.intersects(r)); } +void tst_QPainterPath::boundsAtStartPoint() +{ + const QPointF startPoint(10, 10); + const QPainterPath constructedPath(startPoint); + { + const auto boundingRect = constructedPath.boundingRect(); + const auto topLeft = boundingRect.topLeft(); + QCOMPARE(topLeft, startPoint); + QCOMPARE(topLeft, constructedPath.elementAt(0)); + QCOMPARE(boundingRect, constructedPath.controlPointRect()); + } + + QPainterPath defaultPath; + defaultPath.moveTo(startPoint); + { + const auto boundingRect = defaultPath.boundingRect(); + const auto topLeft = boundingRect.topLeft(); + QCOMPARE(topLeft, startPoint); + QCOMPARE(topLeft, defaultPath.elementAt(0)); + QCOMPARE(boundingRect, defaultPath.controlPointRect()); + } + + QCOMPARE(constructedPath.boundingRect(), defaultPath.boundingRect()); + QCOMPARE(constructedPath.controlPointRect(), defaultPath.controlPointRect()); +} + QTEST_APPLESS_MAIN(tst_QPainterPath) #include "tst_qpainterpath.moc" -- cgit v1.2.3 From bea4d640a25b8606dec7488ff2f12b8f9be7824e Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Tue, 20 Feb 2024 08:07:38 +0100 Subject: QPainter: fix assert when drawing bitmaps at very near to .5 coord The code assumed that the rounding of a floating point value, and the rounding of the sum of that value and an integer, would always snap in the same direction. But because of accuracy limits (independently of the rounding function employed), that is not always the case for fractions very near to .5. Fixes: QTBUG-122451 Pick-to: 6.2 5.15 Change-Id: I0825d42e6be7f6e3397760a5e9be5dddca42dcdc Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Qt CI Bot (cherry picked from commit a43d86fe1c0bc9d352f67c134a9ee5f754aea5e6) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 824d2936010bb46322d29eeb708bee0cee87d081) (cherry picked from commit 0f09f744b093d7bb06451622f0a75cc787b015ad) --- tests/auto/gui/painting/qpainter/tst_qpainter.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'tests') diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 92c3ea4a5a7..65812643f5f 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -62,6 +62,7 @@ private slots: #endif void drawPixmapFragments(); void drawPixmapNegativeScale(); + void drawPixmapRounding(); void drawLine_data(); void drawLine(); @@ -747,6 +748,16 @@ void tst_QPainter::drawPixmapNegativeScale() QVERIFY(resultImage.pixel(12, 8) == qRgba(0, 0, 0, 255)); // and right strip is now black } +void tst_QPainter::drawPixmapRounding() +{ + // Just test that we don't assert + QBitmap bm(8, 8); + QImage out(64, 64, QImage::Format_RGB32); + QPainter p(&out); + qreal y = 26.499999999999996; + p.drawPixmap(QPointF(0, y), bm); +} + void tst_QPainter::drawLine_data() { QTest::addColumn("line"); -- cgit v1.2.3 From 17a59b797748215bcd82715ccb46e3bd8e98d8e8 Mon Sep 17 00:00:00 2001 From: Jonas Karlsson Date: Mon, 26 Feb 2024 12:32:20 +0100 Subject: Revert "QHeaderView: relayout on resetDefaultSectionSize" This reverts commit a8df174369cecd90f14dac85bf162353b7cb25d1. Reason for revert: Caused QTBUG-122109 Fixes: QTBUG-122109 Fixes: QTBUG-120699 Change-Id: Iea185c00f35e17d8eb8e8da70dc2d808ea274b04 Reviewed-by: Axel Spoerl (cherry picked from commit c1921abf65092f4732435a92732c8c11224d31fb) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 6b0cb98478fe4347f05944c8944e7786ec5555a6) (cherry picked from commit 19ba32653431c9dd456fa290c209fd095355bf6f) --- tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'tests') diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index bdfa7ab04dc..5872da6d4f3 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -4922,6 +4922,7 @@ void tst_QTableView::resetDefaultSectionSize() view.verticalHeader()->resetDefaultSectionSize(); view.show(); QVERIFY(QTest::qWaitForWindowExposed(&view)); + QEXPECT_FAIL("", "Reverted fix for QTBUG-116013 due to QTBUG-122109", Continue); QCOMPARE(view.verticalHeader()->logicalIndexAt(9, 45), 1); } -- cgit v1.2.3 From bee3f8ce23af027aa34384bca2c6cfb281895389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Wed, 28 Feb 2024 16:20:57 +0100 Subject: tst_qudpsocket: add helper exe to dependencies Change-Id: I2bea493c5273175746d502e62d1044eca20ece04 Reviewed-by: Thiago Macieira (cherry picked from commit 788ce268820ff8807aefa45293aa5f3ec299052f) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit a05aa394b9faf232cba283f906630a877bc62eea) (cherry picked from commit 660ed4b39b821ebed110f6f939708d7add98441a) --- tests/auto/network/socket/qudpsocket/CMakeLists.txt | 2 +- tests/auto/network/socket/qudpsocket/test/CMakeLists.txt | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/network/socket/qudpsocket/CMakeLists.txt b/tests/auto/network/socket/qudpsocket/CMakeLists.txt index 4d81f852d7b..8b00b9937e1 100644 --- a/tests/auto/network/socket/qudpsocket/CMakeLists.txt +++ b/tests/auto/network/socket/qudpsocket/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: BSD-3-Clause -add_subdirectory(test) add_subdirectory(clientserver) +add_subdirectory(test) diff --git a/tests/auto/network/socket/qudpsocket/test/CMakeLists.txt b/tests/auto/network/socket/qudpsocket/test/CMakeLists.txt index 550ea534388..69b62c2f9fa 100644 --- a/tests/auto/network/socket/qudpsocket/test/CMakeLists.txt +++ b/tests/auto/network/socket/qudpsocket/test/CMakeLists.txt @@ -14,3 +14,7 @@ qt_internal_add_test(tst_qudpsocket Qt::TestPrivate QT_TEST_SERVER_LIST "danted" "echo" ) + +if(QT_FEATURE_process) + add_dependencies(tst_qudpsocket clientserver) +endif() -- cgit v1.2.3 From 98a6de5e99838192d3140a7f9954c4eb0220a693 Mon Sep 17 00:00:00 2001 From: Viktor Arvidsson Date: Wed, 17 Jan 2024 10:19:01 +0100 Subject: QAbstractItemView: Release tab focus when hidden When hiding a widget that has focus we try to focus the next widget in the focus chain by running focusNextPrevChild. The abstract item view overrides this to step the items but does not account for this hide case which makes focusing not only not work, but also by hiding the widget the selection in the item view gets changed. Change-Id: I29d40a1fb86ced60ec742b2753a87383846a89b3 Reviewed-by: Viktor Arvidsson Reviewed-by: Santhosh Kumar Reviewed-by: Volker Hilsheimer (cherry picked from commit d9397479e6dfc2d7b73cab6dcbcda4cccdc20b8a) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 92e1bf8e3b42ff24f86210a4e29ea790bff9fabf) (cherry picked from commit 6326246f0d1e60287f3220df4cf9cfbc014329e5) --- .../qabstractitemview/tst_qabstractitemview.cpp | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'tests') diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp index 30b9e9c4b28..8479e08b38f 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp @@ -150,6 +150,7 @@ private slots: void testSpinBoxAsEditor_data(); void testSpinBoxAsEditor(); void removeIndexWhileEditing(); + void focusNextOnHide(); private: static QAbstractItemView *viewFromString(const QByteArray &viewType, QWidget *parent = nullptr) @@ -3523,5 +3524,32 @@ void tst_QAbstractItemView::removeIndexWhileEditing() } } +void tst_QAbstractItemView::focusNextOnHide() +{ + QWidget widget; + QTableWidget table(10, 10); + table.setTabKeyNavigation(true); + QLineEdit lineEdit; + + QHBoxLayout layout; + layout.addWidget(&table); + layout.addWidget(&lineEdit); + widget.setLayout(&layout); + + widget.setTabOrder(&table, &lineEdit); + + widget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&widget)); + + QVERIFY(table.hasFocus()); + QCOMPARE(table.currentIndex(), table.model()->index(0, 0)); + QTest::keyPress(&table, Qt::Key_Tab); + QCOMPARE(table.currentIndex(), table.model()->index(0, 1)); + + table.hide(); + QCOMPARE(table.currentIndex(), table.model()->index(0, 1)); + QVERIFY(lineEdit.hasFocus()); +} + QTEST_MAIN(tst_QAbstractItemView) #include "tst_qabstractitemview.moc" -- cgit v1.2.3 From 9567399a7c7cd60983bf9296307d164b7f99238f Mon Sep 17 00:00:00 2001 From: David Redondo Date: Wed, 1 Mar 2023 08:47:04 +0100 Subject: Handle device loss for texture widgets Previously the widget stayed black and we printed "QBackingStoreDefaultCompositor: the QRhi has changed unexpectedly, this should not happen". To make it work the compositor is recreated in addition to the rhi and the widgets are informed with the internal events. Change-Id: I982d08bd3530478fe0f827080154c008a92a812e Reviewed-by: Laszlo Agocs Reviewed-by: Qt CI Bot (cherry picked from commit 141d626029776a6b7a6f2fbc29a051221c0742e9) --- .../widgets/qopenglwidget/tst_qopenglwidget.cpp | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'tests') diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp index b95f2b5216c..e0c68e5d8c0 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp +++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -21,7 +22,10 @@ #include #include #include +#include #include +#include +#include class tst_QOpenGLWidget : public QObject { @@ -33,6 +37,9 @@ private slots: void clearAndGrab(); void clearAndResizeAndGrab(); void createNonTopLevel(); +#if QT_CONFIG(egl) + void deviceLoss(); +#endif void painter(); void reparentToAlreadyCreated(); void reparentToNotYetCreated(); @@ -189,6 +196,45 @@ void tst_QOpenGLWidget::createNonTopLevel() QVERIFY(QOpenGLContext::currentContext() == glw->context() && glw->context()); } +#if QT_CONFIG(egl) +void tst_QOpenGLWidget::deviceLoss() +{ + QScopedPointer w(new ClearWidget(0, 640, 480)); + + w->resize(640, 480); + w->show(); + + auto rhi = w->backingStore()->handle()->rhi(); + QNativeInterface::QEGLContext *rhiContext = nullptr; + if (rhi->backend() == QRhi::OpenGLES2) { + auto rhiHandles = static_cast(rhi->nativeHandles()); + rhiContext = rhiHandles->context->nativeInterface(); + } + if (!rhiContext) + QSKIP("deviceLoss needs EGL"); + + QVERIFY(QTest::qWaitForWindowExposed(w.data())); + + QImage image = w->grabFramebuffer(); + QVERIFY(!image.isNull()); + QCOMPARE(image.width(), w->width()); + QCOMPARE(image.height(), w->height()); + QVERIFY(image.pixel(30, 40) == qRgb(255, 0, 0)); + + rhiContext->invalidateContext(); + + w->resize(600, 600); + QSignalSpy frameSwappedSpy(w.get(), &QOpenGLWidget::resized); + QTRY_VERIFY(frameSwappedSpy.size() > 0); + + image = w->grabFramebuffer(); + QVERIFY(!image.isNull()); + QCOMPARE(image.width(), w->width()); + QCOMPARE(image.height(), w->height()); + QVERIFY(image.pixel(30, 40) == qRgb(255, 0, 0)); +} +#endif + class PainterWidget : public QOpenGLWidget, protected QOpenGLFunctions { public: -- cgit v1.2.3 From 7190acbbdae5beb84641b9e4810249eb640d2120 Mon Sep 17 00:00:00 2001 From: Tarja Sundqvist Date: Sun, 3 Mar 2024 01:28:17 +0200 Subject: Bump version to 6.5.6 Change-Id: I712083b0c6df42bfb2771c12238878ba2831b32a Reviewed-by: Tarja Sundqvist --- tests/auto/cmake/mockplugins/.cmake.conf | 2 +- tests/auto/cmake/test_generating_cpp_exports/.cmake.conf | 2 +- tests/auto/cmake/test_static_resources/.cmake.conf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/auto/cmake/mockplugins/.cmake.conf b/tests/auto/cmake/mockplugins/.cmake.conf index 8f509afaa3a..8b61d211171 100644 --- a/tests/auto/cmake/mockplugins/.cmake.conf +++ b/tests/auto/cmake/mockplugins/.cmake.conf @@ -1 +1 @@ -set(QT_REPO_MODULE_VERSION "6.5.5") +set(QT_REPO_MODULE_VERSION "6.5.6") diff --git a/tests/auto/cmake/test_generating_cpp_exports/.cmake.conf b/tests/auto/cmake/test_generating_cpp_exports/.cmake.conf index 8f509afaa3a..8b61d211171 100644 --- a/tests/auto/cmake/test_generating_cpp_exports/.cmake.conf +++ b/tests/auto/cmake/test_generating_cpp_exports/.cmake.conf @@ -1 +1 @@ -set(QT_REPO_MODULE_VERSION "6.5.5") +set(QT_REPO_MODULE_VERSION "6.5.6") diff --git a/tests/auto/cmake/test_static_resources/.cmake.conf b/tests/auto/cmake/test_static_resources/.cmake.conf index 8f509afaa3a..8b61d211171 100644 --- a/tests/auto/cmake/test_static_resources/.cmake.conf +++ b/tests/auto/cmake/test_static_resources/.cmake.conf @@ -1 +1 @@ -set(QT_REPO_MODULE_VERSION "6.5.5") +set(QT_REPO_MODULE_VERSION "6.5.6") -- cgit v1.2.3 From b5df4cae6095bd8af4027e73094dc907c15f1246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 21 Feb 2024 15:26:50 +0100 Subject: Remove QWindowPrivate::compositing It was added for Android in a4f50269f82695fbd0dd344f87b4b355feff4333, for the case of QSurface::RasterGLSurface, but since 6.4 we no longer use QSurface::RasterGLSurface for composition. And the Android usage was removed in 2020ce5fd2478389c56f34742fdeee9cd24ca8a5. Change-Id: I8dafe959c54e09b3a974253e15d184365141d559 Reviewed-by: Axel Spoerl (cherry picked from commit f517e85e906bcfb59dd11d1fb4a1bea84afb1d9a) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit f9f9c648b45014f3277b79ec4098eb3d24937b80) (cherry picked from commit 17e4bd79e387842de5064d49ee86c5136f9d1c40) --- tests/manual/qopenglwidget/openglwidget/main.cpp | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'tests') diff --git a/tests/manual/qopenglwidget/openglwidget/main.cpp b/tests/manual/qopenglwidget/openglwidget/main.cpp index 7ea5a4e7d7a..2cc9458c3ec 100644 --- a/tests/manual/qopenglwidget/openglwidget/main.cpp +++ b/tests/manual/qopenglwidget/openglwidget/main.cpp @@ -31,7 +31,6 @@ public: private slots: void turnNative(); void hideShowAllGL(); - void dumpCompositingStatus(); signals: void aboutToShowGLWidgets(); @@ -83,12 +82,6 @@ void Tools::dumpWidget(QWidget *w, int indent) } } -void Tools::dumpCompositingStatus() -{ - QWindow *w = m_root->window()->windowHandle(); - qDebug() << "Compositing status for" << w << m_root->window() << "is" << QWindowPrivate::get(w)->compositing; -} - class TabWidgetResetter : public QObject { Q_OBJECT @@ -193,10 +186,6 @@ int main(int argc, char *argv[]) toolsMenu->addAction("&Turn widgets (or some parent) into native", &t, SLOT(turnNative())); toolsMenu->addAction("&Hide/show all OpenGL widgets", &t, SLOT(hideShowAllGL())); - QTimer compStatusDumpTimer; - QObject::connect(&compStatusDumpTimer, SIGNAL(timeout()), &t, SLOT(dumpCompositingStatus())); - compStatusDumpTimer.start(5000); - wnd.show(); if (glw->isValid()) -- cgit v1.2.3 From 3231c458b1a5957d24217cf3e13b6f2fcecd4288 Mon Sep 17 00:00:00 2001 From: Axel Spoerl Date: Tue, 5 Mar 2024 08:36:56 +0000 Subject: Revert "QAndroidPlatformInputContext: send composition text and cursor jointly" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit be3b9b2ab12f664c196d649e8c4247d70805d667. Reason for revert: Caused QTBUG-121561 Fixes: QTBUG-121561 Pick-to: 6.2 Change-Id: I4b59d97ede6c50d2575a7d7cebbe2291983dd19f Reviewed-by: Tor Arne Vestbø (cherry picked from commit 46502f9705634f02626ee1057975463d1c0ae1f8) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit c76dd919fd89a9cf4fcbbf162423d12f3b5d6090) (cherry picked from commit cf6f0191be77b17e9e8f78e87b12ba99fbd0006e) --- .../widgets/widgets/qlineedit/tst_qlineedit.cpp | 40 +++------------------- 1 file changed, 5 insertions(+), 35 deletions(-) (limited to 'tests') diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index df65ac932b4..702fd5aab70 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -1593,44 +1593,14 @@ void tst_QLineEdit::textMask() QCOMPARE( testWidget->text(), insertString ); } -class LineEditChangingText : public QLineEdit -{ - Q_OBJECT - -public: - LineEditChangingText(QWidget *parent) : QLineEdit(parent) - { - connect(this, &QLineEdit::textEdited, this, &LineEditChangingText::onTextEdited); - } - -public slots: - void onTextEdited(const QString &text) - { - if (text.length() == 3) - setText(text + "-"); - } -}; - void tst_QLineEdit::setText() { QLineEdit *testWidget = ensureTestWidget(); - { - QSignalSpy editedSpy(testWidget, &QLineEdit::textEdited); - QSignalSpy changedSpy(testWidget, &QLineEdit::textChanged); - testWidget->setText("hello"); - QCOMPARE(editedSpy.size(), 0); - QCOMPARE(changedSpy.value(0).value(0).toString(), QString("hello")); - } - - QTestEventList keys; - keys.addKeyClick(Qt::Key_A); - keys.addKeyClick(Qt::Key_B); - keys.addKeyClick(Qt::Key_C); - - LineEditChangingText lineEdit(nullptr); - keys.simulate(&lineEdit); - QCOMPARE(lineEdit.text(), "abc-"); - QCOMPARE(lineEdit.cursorPosition(), 4); + QSignalSpy editedSpy(testWidget, SIGNAL(textEdited(QString))); + QSignalSpy changedSpy(testWidget, SIGNAL(textChanged(QString))); + testWidget->setText("hello"); + QCOMPARE(editedSpy.size(), 0); + QCOMPARE(changedSpy.value(0).value(0).toString(), QString("hello")); } void tst_QLineEdit::displayText_data() -- cgit v1.2.3 From 25df9bbbe1a255b6085dfd283e2c48929b3836ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 22 Feb 2024 14:56:19 +0100 Subject: UDP: don't disable read notification unless we have a datagram The current logic that we will disable the read notification if we have any data at all doesn't make sense for users who use the receiveDatagram functionality, since they will not make any calls that trigger the read notifier to be re-enabled unless there is a datagram ready for us to hand back. Changes in this cherry-pick: - Changed 10s chrono literal to 10'000 Changes in the 6.5 cherry-pick: - Changed from sleep(20ms) to msleep(20) Fixes: QTBUG-105871 Change-Id: I0a1f1f8babb037d923d1124c2603b1cb466cfe18 Reviewed-by: Thiago Macieira (cherry picked from commit b2ff0c2dc25f640a31fa170dd7cd8964bbcd51d6) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 65406e0be7d5d2b687e3e07930ad60bcae893471) (cherry picked from commit fef939cf879f691b8f487c56897ba54e1c696a1c) Reviewed-by: Edward Welbourne --- .../network/socket/qudpsocket/tst_qudpsocket.cpp | 75 ++++++++++++++++++++++ 1 file changed, 75 insertions(+) (limited to 'tests') diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 4380433899e..d33fd661d3f 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -11,6 +11,7 @@ #endif #include #include +#include #include #include @@ -103,6 +104,8 @@ private slots: void asyncReadDatagram(); void writeInHostLookupState(); + void readyReadConnectionThrottling(); + protected slots: void empty_readyReadSlot(); void empty_connectedSlot(); @@ -1908,5 +1911,77 @@ void tst_QUdpSocket::writeInHostLookupState() QVERIFY(!socket.putChar('0')); } +void tst_QUdpSocket::readyReadConnectionThrottling() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + // QTBUG-105871: + // We have some signal/slot connection throttling in QAbstractSocket, but it + // was caring about the bytes, not about the datagrams. + // Test that we don't disable read notifications until we have at least one + // datagram available. Otherwise our good users who use the datagram APIs + // can get into scenarios where they no longer get the readyRead signal + // unless they call a read function once in a while. + + QUdpSocket receiver; + QVERIFY(receiver.bind(QHostAddress(QHostAddress::LocalHost), 0)); + + QSemaphore semaphore; + + // Repro-ing deterministically eludes me, so we are bruteforcing it: + // The thread acts as a remote sender, flooding the receiver with datagrams, + // and at some point the receiver would get into the broken state mentioned + // earlier. + std::unique_ptr thread(QThread::create([&semaphore, port = receiver.localPort()]() { + QUdpSocket sender; + sender.connectToHost(QHostAddress(QHostAddress::LocalHost), port); + QCOMPARE(sender.state(), QUdpSocket::ConnectedState); + + constexpr qsizetype PayloadSize = 242; + const QByteArray payload(PayloadSize, 'a'); + + semaphore.acquire(); // Wait for main thread to be ready + while (true) { + // We send 100 datagrams at a time, then sleep. + // This is mostly to let the main thread catch up between bursts so + // it doesn't get stuck in the loop. + for (int i = 0; i < 100; ++i) { + [[maybe_unused]] + qsizetype sent = sender.write(payload); + Q_ASSERT(sent > 0); + } + if (QThread::currentThread()->isInterruptionRequested()) + break; + QThread::msleep(20); + } + })); + thread->start(); + auto threadStopAndWaitGuard = qScopeGuard([&thread] { + thread->requestInterruption(); + thread->quit(); + thread->wait(); + }); + + qsizetype count = 0; + QObject::connect(&receiver, &QUdpSocket::readyRead, &receiver, + [&] { + while (receiver.hasPendingDatagrams()) { + receiver.readDatagram(nullptr, 0); + ++count; + } + // If this prints `false, xxxx` we were pretty much guaranteed + // that we would not get called again: + // qDebug() << receiver.hasPendingDatagrams() << receiver.bytesAvailable(); + }, + Qt::QueuedConnection); + + semaphore.release(); + constexpr qsizetype MaxCount = 500; + QVERIFY2(QTest::qWaitFor([&] { return count >= MaxCount; }, 10'000), + QByteArray::number(count).constData()); +} + QTEST_MAIN(tst_QUdpSocket) #include "tst_qudpsocket.moc" -- cgit v1.2.3 From f23efd99756799eb354ea99181902c8108586524 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Fri, 1 Mar 2024 12:52:32 +0100 Subject: Revert "tests: blacklist tst_QWidget::render() on Wayland" This reverts commit c41733b06bd61d4710a9f6ec849f0d913c4497bb. Based on the Grafana data, last flaky was August 14, 2023, and the test works fine on local vm with stressed cpu. Fixes: QTBUG-115598 Change-Id: I634598d20a581d4d1443a3fd81e1e9481bfa2545 Reviewed-by: Inho Lee (cherry picked from commit 4dca61cbdaf070e7789e71669f306042a0dd7fe3) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit a5acbcc92cd03a38dce6a771ddd77902307a7c9b) (cherry picked from commit d68d32190407e078b732db8c6d80ad3a75f3ffd2) --- tests/auto/widgets/kernel/qwidget/BLACKLIST | 2 -- 1 file changed, 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index 00b1248d5d9..2198f8771fa 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -44,8 +44,6 @@ android android [optimizedResize_topLevel] android -[render] -wayland [hoverPosition] macos-14 x86 -- cgit v1.2.3 From 747515c3e8bb628b8f3a2a5dc3f8001ceab7f97f Mon Sep 17 00:00:00 2001 From: Ahmad Samir Date: Mon, 11 Mar 2024 22:39:09 +0200 Subject: tst_qfile: fix GCC 13.2.1 compiler warning [-Wenum-compare] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By using "wt" for all OS's; according to Thiago the 't' is ignored everywhere except on Windows. tests/auto/corelib/io/qfile/tst_qfile.cpp:2846:70: warning: comparison between ‘enum QOperatingSystemVersionBase::OSType’ and ‘enum QOperatingSystemVersion::OSType’ [-Wenum-compare] 2846 | const char *openMode = QOperatingSystemVersion::current().type() != QOperatingSystemVersion::Windows | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Amends 3446313c7a5cd6005089866a7b20c9f28e132a0a Pick-to: 6.2 Change-Id: I310d7d6ce3833756ffdc47b000e052ef3afdfdef Reviewed-by: Thiago Macieira (cherry picked from commit d7340d5c31c8ce79724af9592453d3cf55262fa4) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit b6a55283690dd2579d249652100a5a28a6baccf8) (cherry picked from commit 9b53d3523bf2be53722fea5e2c788f4e8dff5b76) --- tests/auto/corelib/io/qfile/tst_qfile.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 03bfaa8f368..2ecf0f24eb1 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -2673,9 +2673,8 @@ void tst_QFile::socketPair() void tst_QFile::textFile() { - const char *openMode = QOperatingSystemVersion::current().type() != QOperatingSystemVersion::Windows - ? "w" : "wt"; - StdioFileGuard fs(fopen("writeabletextfile", openMode)); + // The "t" is ignored everywhere except on Windows + StdioFileGuard fs(fopen("writeabletextfile", "wt")); QVERIFY(fs); QFile f; QByteArray part1("This\nis\na\nfile\nwith\nnewlines\n"); -- cgit v1.2.3 From 3ae6d5da77f8f79f1fa36a960f16bb0c1d725751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 5 Mar 2024 14:39:15 +0100 Subject: tst_QMutex[qnx]: increase system timer resolution I don't know what it is but it's not 1, because it is quite often flaky in these tests. A single failure leads to deadlock that takes 5 minutes to fail. Then a rerun might do another 5 minutes and fail the integration, or it will pass but take longer to do so. Change-Id: I188276df7800b00a20dbe39edee91c582f0a82a7 Reviewed-by: Thiago Macieira (cherry picked from commit 6aee3342e9d0829bb113583c2b6ecc6c94492d2c) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 3789e5972e6b244fe2e1f80fc794548302ae16b9) (cherry picked from commit 172afa441615593bb5f2811bed9de20a5a9da817) --- tests/auto/corelib/thread/qmutex/tst_qmutex.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp b/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp index e4f98608ae4..dd253d1ff6a 100644 --- a/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp +++ b/tests/auto/corelib/thread/qmutex/tst_qmutex.cpp @@ -61,6 +61,8 @@ static QSemaphore threadsTurn; enum { #ifdef Q_OS_WIN systemTimersResolution = 16, +#elif defined(Q_OS_QNX) + systemTimersResolution = 10, #else systemTimersResolution = 1, #endif -- cgit v1.2.3 From e29d3e984b92bfe76f1dc2feab8bc9605b6e5e8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 12 Mar 2024 09:36:27 +0100 Subject: tst_QFactoryLoader: includemocs For some reason android in CI failed to include the moc file through the mocs_compilation file. It's an issue that needs some investigation, but in the interest of time just include the moc file directly. Change-Id: I079588598a6f4137ef1fccc482795d703b59bc6e Reviewed-by: Alexey Edelev (cherry picked from commit c468dfedd6413994a72c41a53eadd1944eb52e6d) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 1fd6f41eb26f31995412ac2ac1e95578b3b8147f) (cherry picked from commit dab953f3fc018fd33f1f1f157ccee9dba67c1d00) --- tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.cpp | 2 ++ tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.cpp | 2 ++ 2 files changed, 4 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.cpp b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.cpp index 51825f00175..9e73e84364f 100644 --- a/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.cpp +++ b/tests/auto/corelib/plugin/qfactoryloader/plugin1/plugin1.cpp @@ -7,3 +7,5 @@ QString Plugin1::pluginName() const { return QLatin1String("Plugin1 ok"); } + +#include "moc_plugin1.cpp" diff --git a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.cpp b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.cpp index 88a34ac73e0..552b4dd8103 100644 --- a/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.cpp +++ b/tests/auto/corelib/plugin/qfactoryloader/plugin2/plugin2.cpp @@ -7,3 +7,5 @@ QString Plugin2::pluginName() const { return QLatin1String("Plugin2 ok"); } + +#include "moc_plugin2.cpp" -- cgit v1.2.3 From ab9fc9aaea9897c38acce0fe29da703de0648faa Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 13 Mar 2024 10:10:53 +0100 Subject: tests: blacklist tst_QIV::focusNextOnHide() on Wayland MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-107153 Change-Id: I8b79e74369689a549c5481b44830374215acf59b Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Tor Arne Vestbø (cherry picked from commit b0d9b2278b4060185e6bcba25d91a6ed12e5f023) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit fe71df81a85f2ac6a05e536a017fc2725713e976) (cherry picked from commit b1059913c9120d43e424c310cfc391bf4ce3fe52) --- tests/auto/widgets/itemviews/qabstractitemview/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests') diff --git a/tests/auto/widgets/itemviews/qabstractitemview/BLACKLIST b/tests/auto/widgets/itemviews/qabstractitemview/BLACKLIST index c1688a7627e..778a25b2e46 100644 --- a/tests/auto/widgets/itemviews/qabstractitemview/BLACKLIST +++ b/tests/auto/widgets/itemviews/qabstractitemview/BLACKLIST @@ -1,2 +1,4 @@ +[focusNextOnHide] +wayland [selectionAutoScrolling] wayland -- cgit v1.2.3 From f5de357837bc38362642488fe21b321b7e9ea1cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 28 Feb 2024 17:48:17 +0100 Subject: QMessageBox: Respect explicit accept/reject after closing dialog If the dialog is closed by pressing a button, the button will be reflected via clickedButton(), and the result() will reflect either the QMessageBox::StandardButton value, or an opaque value for custom buttons. Depending on the role if the buttons, the accepted or rejected signals are emitted. If the user called accept() or rejecct() on a dialog that had already been closed by a button, we would as a result of 1f70c073d4325bc0eb9b0cec5156c3b89ce1b4df emit a signal based on the original button that was clicked, instead of respecting the newly triggered function. It's a questionable use-case, as the clickedButton() is still the original button e.g., but we should still avoid regressing this, so we now emit the signals based on the newly stored result code instead of using the clicked button as the source of truth. To allow this we had to change the opaque result() value for custom buttons to stay out of the QDialog::DialogCode enum, but this should be fine as the documentation explicitly says that this is an opaque value. Fixes: QTBUG-118226 Change-Id: Ia2966cecc6694efce66493c401854402658332b4 Reviewed-by: Axel Spoerl (cherry picked from commit b30121041c07b1b8613eaf624c9aa55a51001aef) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 8a8481f7eb5479df2944f3238d6fac6d8fde5512) (cherry picked from commit 4266bf601cf08ebab89aea11efa84ce71fd41478) --- .../dialogs/qmessagebox/tst_qmessagebox.cpp | 56 ++++++++++++++++++++-- 1 file changed, 52 insertions(+), 4 deletions(-) (limited to 'tests') diff --git a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp index 02e3cfd05a0..158081fa69b 100644 --- a/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/widgets/dialogs/qmessagebox/tst_qmessagebox.cpp @@ -60,6 +60,8 @@ private slots: void hideNativeByDestruction(); + void explicitDoneAfterButtonClicked(); + void cleanup(); }; @@ -435,7 +437,7 @@ void tst_QMessageBox::shortcut() msgBox.addButton("&Maybe", QMessageBox::YesRole); ExecCloseHelper closeHelper; closeHelper.start(Qt::Key_M, &msgBox); - QCOMPARE(msgBox.exec(), 2); + QCOMPARE(msgBox.exec(), 4); } #endif @@ -514,7 +516,7 @@ QT_WARNING_DISABLE_DEPRECATED // the button text versions closeHelper.start(Qt::Key_Enter); ret = QMessageBox::information(nullptr, "title", "text", "Yes", "No", QString(), 1); - COMPARE(ret, 1); + COMPARE(ret, 3); // Custom button opaque result QVERIFY(closeHelper.done()); if (0) { // don't run these tests since the dialog won't close! @@ -555,9 +557,9 @@ void tst_QMessageBox::instanceSourceCompat() #ifndef Q_OS_MAC // mnemonics are not used on OS X closeHelper.start(QKeyCombination(Qt::ALT | Qt::Key_R).toCombined(), &mb); - QCOMPARE(mb.exec(), 0); + QCOMPARE(mb.exec(), 2); closeHelper.start(QKeyCombination(Qt::ALT | Qt::Key_Z).toCombined(), &mb); - QCOMPARE(mb.exec(), 1); + QCOMPARE(mb.exec(), 3); #endif } @@ -818,5 +820,51 @@ void tst_QMessageBox::hideNativeByDestruction() QVERIFY(QTest::qWaitFor(windowActive)); } +void tst_QMessageBox::explicitDoneAfterButtonClicked() +{ + QMessageBox msgBox; + auto *standardButton = msgBox.addButton(QMessageBox::Ok); + auto *customButton = msgBox.addButton("Custom", QMessageBox::RejectRole); + + QSignalSpy acceptedSpy(&msgBox, &QDialog::accepted); + QSignalSpy rejectedSpy(&msgBox, &QDialog::rejected); + + msgBox.setDefaultButton(standardButton); + ExecCloseHelper closeHelper; + closeHelper.start(Qt::Key_Enter, &msgBox); + msgBox.exec(); + QCOMPARE(msgBox.clickedButton(), standardButton); + QCOMPARE(msgBox.result(), QMessageBox::Ok); + QCOMPARE(acceptedSpy.size(), 1); + QCOMPARE(rejectedSpy.size(), 0); + + msgBox.accept(); + QCOMPARE(msgBox.result(), QDialog::Accepted); + QCOMPARE(acceptedSpy.size(), 2); + QCOMPARE(rejectedSpy.size(), 0); + msgBox.reject(); + QCOMPARE(msgBox.result(), QDialog::Rejected); + QCOMPARE(acceptedSpy.size(), 2); + QCOMPARE(rejectedSpy.size(), 1); + + msgBox.setDefaultButton(customButton); + closeHelper.start(Qt::Key_Enter, &msgBox); + msgBox.exec(); + QCOMPARE(msgBox.clickedButton(), customButton); + QVERIFY(msgBox.result() != QDialog::Accepted); + QVERIFY(msgBox.result() != QDialog::Rejected); + QCOMPARE(acceptedSpy.size(), 2); + QCOMPARE(rejectedSpy.size(), 2); + + msgBox.accept(); + QCOMPARE(msgBox.result(), QDialog::Accepted); + QCOMPARE(acceptedSpy.size(), 3); + QCOMPARE(rejectedSpy.size(), 2); + msgBox.reject(); + QCOMPARE(msgBox.result(), QDialog::Rejected); + QCOMPARE(acceptedSpy.size(), 3); + QCOMPARE(rejectedSpy.size(), 3); +} + QTEST_MAIN(tst_QMessageBox) #include "tst_qmessagebox.moc" -- cgit v1.2.3 From 42185e58f16960d96aa72054d866cbf2c6f3305e Mon Sep 17 00:00:00 2001 From: Axel Spoerl Date: Thu, 25 Jan 2024 17:07:34 +0100 Subject: QDialogButtonBox: Don't set focus in a dialog with StrongFocus children MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A QDialogButtonBox with the first accept button becoming default, didn't explicitly set focus on such a button in a QDialog. d44413d526ec12ed83acd7343c2005782178c7ad implemented this missing functionality. It set focus to the automatic default button, unless the QDialog had a focusWidget() set. That has caused a regression, in cases where - the QDialog has a QWidget child with a Qt::StrongFocus policy, and - the QDialog is not yet visible, so focusWidget() returns nullptr. Amend d44413d526ec12ed83acd7343c2005782178c7ad: Implement a helper in QWidgetPrivate, that returns true, if a child with a given focus policy is found. Do not set focus to a QDialogButtonBox's automatic default button, when - not located inside a QDialog, or - a focusWidget() exists, or - the dialog has QWidget child with Qt::StrongFocus, that is not a child of the QDialogButtonBox. Add an autotest function. Fixes: QTBUG-121514 Fixes: QTBUG-120049 Change-Id: I3c65ae36b56657f9af4a3a4b42f9b66e8bc5c534 Reviewed-by: Tor Arne Vestbø (cherry picked from commit 78a3301372fb9b48dc65b18a19731db37abab75c) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 1e89a6e587637b9ede469f5d49fda62e2f1aa54e) (cherry picked from commit 281a41b81ea52d4744e1344c77534dff3eae1f63) --- .../qdialogbuttonbox/tst_qdialogbuttonbox.cpp | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'tests') diff --git a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp index 9f405a8bebe..83abf0e8e36 100644 --- a/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp +++ b/tests/auto/widgets/widgets/qdialogbuttonbox/tst_qdialogbuttonbox.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -82,6 +83,8 @@ private slots: void task191642_default(); void testDeletedStandardButton(); void automaticDefaultButton(); + void initialFocus_data(); + void initialFocus(); private: qint64 timeStamp; @@ -958,5 +961,39 @@ void tst_QDialogButtonBox::automaticDefaultButton() } } +void tst_QDialogButtonBox::initialFocus_data() +{ + QTest::addColumn("focusPolicy"); + QTest::addColumn("lineEditHasFocus"); + + QTest::addRow("TabFocus") << Qt::FocusPolicy::TabFocus << false; + QTest::addRow("StrongFocus") << Qt::FocusPolicy::StrongFocus << true; + QTest::addRow("NoFocus") << Qt::FocusPolicy::NoFocus << false; + QTest::addRow("ClickFocus") << Qt::FocusPolicy::ClickFocus << false; + QTest::addRow("WheelFocus") << Qt::FocusPolicy::WheelFocus << false; +} + +void tst_QDialogButtonBox::initialFocus() +{ + QFETCH(const Qt::FocusPolicy, focusPolicy); + QFETCH(const bool, lineEditHasFocus); + QDialog dialog; + QVBoxLayout *layout = new QVBoxLayout(&dialog); + QLineEdit *lineEdit = new QLineEdit(&dialog); + lineEdit->setFocusPolicy(focusPolicy); + layout->addWidget(lineEdit); + QDialogButtonBox *dialogButtonBox = new QDialogButtonBox(&dialog); + layout->addWidget(dialogButtonBox); + dialogButtonBox->addButton(QDialogButtonBox::Reset); + const auto *firstAcceptButton = dialogButtonBox->addButton(QDialogButtonBox::Ok); + dialogButtonBox->addButton(QDialogButtonBox::Cancel); + dialog.show(); + dialog.activateWindow(); + if (lineEditHasFocus) + QTRY_VERIFY(lineEdit->hasFocus()); + else + QTRY_VERIFY(firstAcceptButton->hasFocus()); +} + QTEST_MAIN(tst_QDialogButtonBox) #include "tst_qdialogbuttonbox.moc" -- cgit v1.2.3 From 389a26447943074d63950fd8cd8261daa6c16454 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 1 Mar 2024 15:16:54 +0100 Subject: QProperty: Destroy binding when refcount is 0 This has to be done from all places where we deref it. Otherwise we leak memory. Fixes: QTBUG-116086 Change-Id: I57307ac746205578a920d2bb1e159b66ebd9b2cc Reviewed-by: Fabian Kosmale (cherry picked from commit 717dc9450ffc13ef8209a10073552ac4574a4160) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 933d695ecb5d8e2dbe107e5fd15428a7484ede8f) (cherry picked from commit c3d9c40a65100305f2fd56f13e29b68508c81da7) --- .../corelib/kernel/qproperty/tst_qproperty.cpp | 44 ++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp index 09df5d12ed7..fdbf9aca970 100644 --- a/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp +++ b/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp @@ -107,6 +107,8 @@ private slots: void propertyAdaptorBinding(); void propertyUpdateViaSignaledProperty(); + + void derefFromObserver(); }; void tst_QProperty::functorBinding() @@ -261,6 +263,7 @@ void tst_QProperty::bindingAfterUse() void tst_QProperty::bindingFunctionDtorCalled() { + DtorCounter::counter = 0; DtorCounter dc; { QProperty prop; @@ -2469,6 +2472,47 @@ void tst_QProperty::propertyUpdateViaSignaledProperty() QCOMPARE(o.bindable2(), 36); } +void tst_QProperty::derefFromObserver() +{ + int triggered = 0; + QProperty source(11); + + DtorCounter::counter = 0; + DtorCounter dc; + + QProperty target([&triggered, &source, dc]() mutable { + dc.shouldIncrement = true; + return ++triggered + source.value(); + }); + QCOMPARE(triggered, 1); + + { + auto propObserver = std::make_unique(); + QPropertyObserverPointer propObserverPtr { propObserver.get() }; + propObserverPtr.setBindingToNotify(QPropertyBindingPrivate::get(target.binding())); + + QBindingObserverPtr bindingPtr(propObserver.get()); + + QCOMPARE(triggered, 1); + source = 25; + QCOMPARE(triggered, 2); + QCOMPARE(target, 27); + + target.setBinding([]() { return 8; }); + QCOMPARE(target, 8); + + // The QBindingObserverPtr still holds on to the binding. + QCOMPARE(dc.counter, 0); + } + + // The binding is actually gone now. + QCOMPARE(dc.counter, 1); + + source = 26; + QCOMPARE(triggered, 2); + QCOMPARE(target, 8); +} + QTEST_MAIN(tst_QProperty); #undef QT_SOURCE_LOCATION_NAMESPACE -- cgit v1.2.3 From bb3d6f96af6928a8ad6841b2ea5191701ed5710c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 16 Mar 2024 18:41:27 -0700 Subject: QDBusArgument: disambiguate between QMap on std::pair and std::map For QMap on a std::pair, QMap::iterator{}.operator->() would result in a type that has "first" and "second" members: std::pair itself. But it would be wrong to marshall and demarshall the first and second elements thereof as the key and value, so give preference to the .key() and .value() selection, which would store the std::pair as the type. Fixes: QTBUG-123401 Change-Id: I6818d78a57394e37857bfffd17bd69bb692dd03b Reviewed-by: Alexey Edelev (cherry picked from commit 5401a9a6cd3263eda15911c3fbfc81ebea2e798f) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 9ffed81b159e9bdf4aba26dfdbd08ff508ffe8b3) (cherry picked from commit 1e11f8fa80e5bbce11d0dfe7213d8af1e8c10fe3) --- tests/auto/dbus/qdbusmarshall/common.h | 4 ++++ tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp | 11 +++++++++++ 2 files changed, 15 insertions(+) (limited to 'tests') diff --git a/tests/auto/dbus/qdbusmarshall/common.h b/tests/auto/dbus/qdbusmarshall/common.h index 916370c3773..646c46dde24 100644 --- a/tests/auto/dbus/qdbusmarshall/common.h +++ b/tests/auto/dbus/qdbusmarshall/common.h @@ -152,7 +152,9 @@ void commonInit() qDBusRegisterMetaType >(); qDBusRegisterMetaType >(); qDBusRegisterMetaType >(); + qDBusRegisterMetaType>>(); + qDBusRegisterMetaType>(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType >(); @@ -468,6 +470,8 @@ bool compareToArgument(const QDBusArgument &arg, const QVariant &v2) return compare >(arg, v2); else if (id == qMetaTypeId >()) return compare >(arg, v2); + else if (id == qMetaTypeId>>()) + return compare>>(arg, v2); else if (id == qMetaTypeId >()) return compare >(arg, v2); diff --git a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp index aecc958536b..1c9f16ccfeb 100644 --- a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp @@ -475,6 +475,17 @@ void tst_QDBusMarshall::sendMaps_data() QTest::newRow("gs-map") << QVariant::fromValue(gsmap) << "a{gs}" << "[Argument: a{gs} {[Signature: a{gs}] = \"array of dict_entry of (signature, string)\", [Signature: i] = \"int32\", [Signature: s] = \"string\"}]"; + QMap> siimap; + QTest::newRow("empty-sii-map") << QVariant::fromValue(siimap) << "a{s(ii)}" + << "[Argument: a{s(ii)} {}]"; + siimap["0,0"] = { 0, 0 }; + siimap["1,-1"] = { 1, -1 }; + QTest::newRow("sii-map") << QVariant::fromValue(siimap) << "a{s(ii)}" + << "[Argument: a{s(ii)} {" + "\"0,0\" = [Argument: (ii) 0, 0], " + "\"1,-1\" = [Argument: (ii) 1, -1]" + "}]"; + if (fileDescriptorPassing) { svmap["zzfiledescriptor"] = QVariant::fromValue(QDBusUnixFileDescriptor(fileDescriptorForTest())); QTest::newRow("sv-map1-fd") << QVariant::fromValue(svmap) << "a{sv}" -- cgit v1.2.3 From 9e2dcc7491134c9e8830ad3536f466e4943657f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sat, 2 Mar 2024 16:55:43 +0100 Subject: Reparent QWindow children when reparenting QWidget MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a QWidget was reparented, we would take care to reparent its backing QWidgetWindow as well, into the nearest QWindow of the new QWidget parent. However we would only do this for the reparented widget itself, and not any of its child widgets. In the case where the widget has native children with their own QWindows, the widget itself may not (yet) be native, e.g. if it hasn't been shown yet, or if the user has set Qt::WA_DontCreateNativeAncestors. In these scenarios, we would be left with dangling QWindows, still hanging off their original QWindow parents, which would eventually lead to crashes. We now reparent both the QWindow of the reparented widget (as long as it's not about to be destroyed), and any QQWindow children we can reach. For each child hierarchy we can stop once we reach a QWindow, as the QWindow children of that window will follow along once we reparent the QWindow. QWindowContainer widgets don't usually have their own windowHandle(), but still manage a QWindow inside their parent widget hierarchy. These will not be reparented during QWidgetPrivate::setParent_sys(), but instead do their own reparenting later in QWidget::setParent via QWindowContainer::parentWasChanged(). The only exception to this is when the top level is about to be destroyed, in which case we let the window container know during QWidgetPrivate::setParent_sys(). Finally, although there should not be any leftover QWindows in the reparented widget once we have done the QWidgetWindow and QWindowContainer reparenting, we still do a pass over any remaining QWindows and reparent those too, since the original code included this as a possibility. We could make further improvements in this areas, such as moving the QWindowContainer::parentWasChanged() call, but the goal was to keep this change as minimal as possible so we can back-port it. Fixes: QTBUG-122747 Change-Id: I4d1217fce4c3c48cf5f7bfbe9d561ab408ceebb2 Reviewed-by: Volker Hilsheimer (cherry picked from commit c956eb8eddb1b3608d7e3d332fbe55df5ec41578) Reviewed-by: Tor Arne Vestbø (cherry picked from commit 8ee25c66d934850eba4167246cdab2310704c45d) (cherry picked from commit 2c0a4d6c59a5c1eea66e7708b208e98dfd6e0509) Reviewed-by: Qt Cherry-pick Bot --- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 152 ++++++++++++++++++++++ 1 file changed, 152 insertions(+) (limited to 'tests') diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index cbada55a4a6..327b83c2933 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -434,6 +434,9 @@ private slots: void setVisibleDuringDestruction(); + void reparentWindowHandles_data(); + void reparentWindowHandles(); + private: const QString m_platform; QSize m_testWidgetSize; @@ -13393,5 +13396,154 @@ void tst_QWidget::setVisibleDuringDestruction() QTRY_COMPARE(signalSpy.count(), 4); } +void tst_QWidget::reparentWindowHandles_data() +{ + QTest::addColumn("stage"); + QTest::addRow("reparent child") << 1; + QTest::addRow("top level to child") << 2; + QTest::addRow("transient parent") << 3; + QTest::addRow("window container") << 4; +} + +void tst_QWidget::reparentWindowHandles() +{ + const bool nativeSiblingsOriginal = qApp->testAttribute(Qt::AA_DontCreateNativeWidgetSiblings); + qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, true); + auto nativeSiblingGuard = qScopeGuard([&]{ + qApp->setAttribute(Qt::AA_DontCreateNativeWidgetSiblings, nativeSiblingsOriginal); + }); + + QFETCH(int, stage); + + switch (stage) { + case 1: { + // Reparent child widget + + QWidget topLevel; + topLevel.setAttribute(Qt::WA_NativeWindow); + QVERIFY(topLevel.windowHandle()); + QPointer child = new QWidget(&topLevel); + child->setAttribute(Qt::WA_DontCreateNativeAncestors); + child->setAttribute(Qt::WA_NativeWindow); + QVERIFY(child->windowHandle()); + + QWidget anotherTopLevel; + anotherTopLevel.setAttribute(Qt::WA_NativeWindow); + QVERIFY(anotherTopLevel.windowHandle()); + QPointer intermediate = new QWidget(&anotherTopLevel); + QPointer leaf = new QWidget(intermediate); + leaf->setAttribute(Qt::WA_DontCreateNativeAncestors); + leaf->setAttribute(Qt::WA_NativeWindow); + QVERIFY(leaf->windowHandle()); + QVERIFY(!intermediate->windowHandle()); + + // Reparenting a native widget should reparent the QWindow + child->setParent(leaf); + QCOMPARE(child->windowHandle()->parent(), leaf->windowHandle()); + QCOMPARE(child->windowHandle()->transientParent(), nullptr); + QVERIFY(!intermediate->windowHandle()); + + // So should reparenting a non-native widget with native children + intermediate->setParent(&topLevel); + QVERIFY(!intermediate->windowHandle()); + QCOMPARE(leaf->windowHandle()->parent(), topLevel.windowHandle()); + QCOMPARE(leaf->windowHandle()->transientParent(), nullptr); + QCOMPARE(child->windowHandle()->parent(), leaf->windowHandle()); + QCOMPARE(child->windowHandle()->transientParent(), nullptr); + } + break; + case 2: { + // Top level to child + + QWidget topLevel; + topLevel.setAttribute(Qt::WA_NativeWindow); + + // A regular top level loses its nativeness + QPointer regularToplevel = new QWidget; + regularToplevel->show(); + QVERIFY(QTest::qWaitForWindowExposed(regularToplevel)); + QVERIFY(regularToplevel->windowHandle()); + regularToplevel->setParent(&topLevel); + QVERIFY(!regularToplevel->windowHandle()); + + // A regular top level loses its nativeness + QPointer regularToplevelWithNativeChildren = new QWidget; + QPointer nativeChild = new QWidget(regularToplevelWithNativeChildren); + nativeChild->setAttribute(Qt::WA_DontCreateNativeAncestors); + nativeChild->setAttribute(Qt::WA_NativeWindow); + QVERIFY(nativeChild->windowHandle()); + regularToplevelWithNativeChildren->show(); + QVERIFY(QTest::qWaitForWindowExposed(regularToplevelWithNativeChildren)); + QVERIFY(regularToplevelWithNativeChildren->windowHandle()); + regularToplevelWithNativeChildren->setParent(&topLevel); + QVERIFY(!regularToplevelWithNativeChildren->windowHandle()); + // But the native child does not + QVERIFY(nativeChild->windowHandle()); + QCOMPARE(nativeChild->windowHandle()->parent(), topLevel.windowHandle()); + + // An explicitly native top level keeps its nativeness, and the window handle moves + QPointer nativeTopLevel = new QWidget; + nativeTopLevel->setAttribute(Qt::WA_NativeWindow); + QVERIFY(nativeTopLevel->windowHandle()); + nativeTopLevel->setParent(&topLevel); + QVERIFY(nativeTopLevel->windowHandle()); + QCOMPARE(nativeTopLevel->windowHandle()->parent(), topLevel.windowHandle()); + } + break; + case 3: { + // Transient parent + + QWidget topLevel; + topLevel.setAttribute(Qt::WA_NativeWindow); + QVERIFY(topLevel.windowHandle()); + QPointer child = new QWidget(&topLevel); + child->setAttribute(Qt::WA_NativeWindow); + QVERIFY(child->windowHandle()); + + QWidget anotherTopLevel; + anotherTopLevel.setAttribute(Qt::WA_NativeWindow); + QVERIFY(anotherTopLevel.windowHandle()); + + // Make transient child of top level + anotherTopLevel.setParent(&topLevel, Qt::Window); + QCOMPARE(anotherTopLevel.windowHandle()->parent(), nullptr); + QCOMPARE(anotherTopLevel.windowHandle()->transientParent(), topLevel.windowHandle()); + + // Make transient child of child + anotherTopLevel.setParent(child, Qt::Window); + QCOMPARE(anotherTopLevel.windowHandle()->parent(), nullptr); + QCOMPARE(anotherTopLevel.windowHandle()->transientParent(), topLevel.windowHandle()); + } + break; + case 4: { + // Window container + + QWidget topLevel; + topLevel.setAttribute(Qt::WA_NativeWindow); + QVERIFY(topLevel.windowHandle()); + + QPointer child = new QWidget(&topLevel); + QVERIFY(!child->windowHandle()); + + QWindow *window = new QWindow; + QWidget *container = QWidget::createWindowContainer(window); + container->setParent(child); + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + QCOMPARE(window->parent(), topLevel.windowHandle()); + + QWidget anotherTopLevel; + anotherTopLevel.setAttribute(Qt::WA_NativeWindow); + QVERIFY(anotherTopLevel.windowHandle()); + + child->setParent(&anotherTopLevel); + QCOMPARE(window->parent(), anotherTopLevel.windowHandle()); + } + break; + default: + Q_UNREACHABLE(); + } +} + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" -- cgit v1.2.3 From fbdac2cdf034c4a836e1f50c402327991e7a9f35 Mon Sep 17 00:00:00 2001 From: Ahmad Samir Date: Fri, 15 Mar 2024 15:11:56 +0200 Subject: tst_qtemporarydir: refactor a test Instead of using ~/Downloads, which we have no control over (OK for the CI, but not locally), create a parent temp dir, then another temp dir inside it. Also rename it to nestedTempDirs, the issue from the bug report wasn't tested because it relied on a dir being created, then failing to set permissions on it. The code has changed a lot since then. Pick-to: 6.2 Change-Id: I2b03d5d761117aaf436041c13c0dc394b106bf89 Reviewed-by: Thiago Macieira (cherry picked from commit 56ef55eda0b197e975de155815885f310dc2e661) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 11b2047d4c8087419bba8a56ce1e3fb85dfdd14f) (cherry picked from commit 27998d611d43e45f6c39ba304c07498e25a65855) --- tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp index 227c6260d36..e7a505cfd71 100644 --- a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp +++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp @@ -54,7 +54,7 @@ private slots: void QTBUG_4796_data(); void QTBUG_4796(); - void QTBUG43352_failedSetPermissions(); + void nestedTempDirs(); private: QString m_previousCurrent; @@ -555,16 +555,18 @@ void tst_QTemporaryDir::QTBUG_4796() // unicode support cleaner.reset(); } -void tst_QTemporaryDir::QTBUG43352_failedSetPermissions() +void tst_QTemporaryDir::nestedTempDirs() { - QString path = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + QStringLiteral("/"); - int count = QDir(path).entryList().size(); + QTemporaryDir parentDir; + const QString &parentPath = parentDir.path(); { - QTemporaryDir dir(path); + QTemporaryDir tempdir(parentPath); } - QCOMPARE(QDir(path).entryList().size(), count); + QDir dir(parentPath); + dir.setFilter(QDir::NoDotAndDotDot); + QCOMPARE(dir.count(), 0); } QTEST_MAIN(tst_QTemporaryDir) -- cgit v1.2.3 From b018255053cb922ce6251bd420b7c434cabf388c Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 20 Mar 2024 10:33:07 +0100 Subject: tst_QNetworkReply: use QtCore's QScopedPointerDeleteLater MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... instead of rolling your own. Change-Id: I4fee2218eb874bfee34bd3a0abac3f85b0746540 Reviewed-by: Mårten Nordheim (cherry picked from commit 17d2550ed09c564977d4e9414f60c5514ce4f76a) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 2f7cdec2c98be9f7fce3849b951a1869e3072a46) (cherry picked from commit ecfec47c50dae517d8d7da538ac48c77a4f4eab3) --- .../auto/network/access/qnetworkreply/tst_qnetworkreply.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'tests') diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 05ee120f970..cbd3649e086 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -6054,14 +6054,6 @@ struct QThreadCleanup } }; -struct QDeleteLaterCleanup -{ - static inline void cleanup(QObject *o) - { - o->deleteLater(); - } -}; - #if QT_CONFIG(networkproxy) void tst_QNetworkReply::httpProxyCommandsSynchronous() { @@ -6073,7 +6065,7 @@ void tst_QNetworkReply::httpProxyCommandsSynchronous() // the server thread, because the client is never returning to the // event loop QScopedPointer serverThread(new QThread); - QScopedPointer proxyServer(new MiniHttpServer(responseToSend, false, serverThread.data())); + QScopedPointer proxyServer(new MiniHttpServer(responseToSend, false, serverThread.data())); QNetworkProxy proxy(QNetworkProxy::HttpProxy, "127.0.0.1", proxyServer->serverPort()); manager.setProxy(proxy); @@ -8276,7 +8268,7 @@ void tst_QNetworkReply::synchronousAuthenticationCache() // the server thread, because the client is never returning to the // event loop QScopedPointer serverThread(new QThread); - QScopedPointer server(new MiniAuthServer(serverThread.data())); + QScopedPointer server(new MiniAuthServer(serverThread.data())); server->doClose = true; //1) URL without credentials, we are not authenticated -- cgit v1.2.3 From b11256abdf0f9427a6dc3ee7d5c826b0bf749a20 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 19 Mar 2024 18:31:28 +0100 Subject: tst_QNetworkReply: don't use deleteLater() on QSignalSpies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turn the QSignalSpy deletions from deferred (via deleteLater()) into immediate ones. This is ok: QSignalSpy is using itself as a context object in QMetaObject::connect(), so the connection thus established to the monitored signal will be atomically severed if either sender or receiver are destroyed. There never was a need to defer deletion of the signal spy, so don't. Found by making QSignalSpy's inheritance from QObject private. Change-Id: I962d28c3a78f356d234324fed68716f2f1052100 Reviewed-by: Mårten Nordheim (cherry picked from commit eefd8ab1e8e4d6afa64e15c017e1e78fd30c7382) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit b7dd49682bf0cfe205ef774b075a5d98aea84616) (cherry picked from commit d35c2219836277708d6fd7dc9a892e9ccd7b9aa8) --- tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index cbd3649e086..36fe6aaef8f 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -8428,9 +8428,9 @@ void tst_QNetworkReply::emitErrorForAllReplies() // QTBUG-36890 for (int a = 0; a < urls.size(); ++a) { QVERIFY(replies.at(a)->isFinished()); QCOMPARE(errorSpies.at(a)->size(), 1); - errorSpies.at(a)->deleteLater(); + delete errorSpies.at(a); QCOMPARE(finishedSpies.at(a)->size(), 1); - finishedSpies.at(a)->deleteLater(); + delete finishedSpies.at(a); replies.at(a)->deleteLater(); } } -- cgit v1.2.3 From f9e79171b6228de4a223c19c82b76ed1d5b4524b Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 20 Mar 2024 17:14:41 +0100 Subject: QMetaMethod: document that fromSignal(nullptr) is ok MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... and add a test. Pick-to: 6.2 5.15 Change-Id: I907899d7c54349d2fc23ea5ab58a1e67826b622b Reviewed-by: Thiago Macieira Reviewed-by: Mårten Nordheim (cherry picked from commit 78db468f4895911e50849223899abf2c5fb1c72e) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 9f14d0a288ef5355ca92e64fe464735f119b8ec5) (cherry picked from commit fcd465512aa78039123343da86610a36f509878e) --- tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp index 4cc15159e7f..4b502700fd4 100644 --- a/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp +++ b/tests/auto/corelib/kernel/qmetamethod/tst_qmetamethod.cpp @@ -22,6 +22,7 @@ private slots: void comparisonOperators(); void fromSignal(); + void fromSignalOfNullSignalIsInvalid(); void gadget(); void revision(); @@ -719,6 +720,12 @@ void tst_QMetaMethod::fromSignal() #undef FROMSIGNAL_HELPER } +void tst_QMetaMethod::fromSignalOfNullSignalIsInvalid() +{ + constexpr decltype(&QObject::destroyed) ptr = nullptr; + QVERIFY(!QMetaMethod::fromSignal(ptr).isValid()); +} + class MyGadget { Q_GADGET public: -- cgit v1.2.3 From 2cb5c184488fd476576966aa53f01539f8005d4a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 18 Mar 2024 07:44:07 +0100 Subject: tst_QSignalSpy: check (thereby suppress) intended runtime warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use QTest::ignoreMessage() to prevent the runtime warnings being printed, cleaning up the test log, and to document that they're intended. Manual conflict resolutions: - Add using namespace Qt::StringLiterals, which, in 6.5, was not yet present from some other, independent change. Change-Id: Ia0ba888cce83529217642be0e7e321d9406ba386 Reviewed-by: David Faure Reviewed-by: Mårten Nordheim (cherry picked from commit ce913bff5df668787dc904469fca09763acf0f27) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit a6fba6154514fa6e786a7e6b187c5b970f90a8d3) (cherry picked from commit e49fa7171805ca1c2b03c64e1c735fb5de85364b) --- tests/auto/testlib/qsignalspy/tst_qsignalspy.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tests') diff --git a/tests/auto/testlib/qsignalspy/tst_qsignalspy.cpp b/tests/auto/testlib/qsignalspy/tst_qsignalspy.cpp index 8b0319679fb..0e51eb0f981 100644 --- a/tests/auto/testlib/qsignalspy/tst_qsignalspy.cpp +++ b/tests/auto/testlib/qsignalspy/tst_qsignalspy.cpp @@ -9,6 +9,8 @@ #include +using namespace Qt::StringLiterals; + class tst_QSignalSpy : public QObject { Q_OBJECT @@ -460,27 +462,33 @@ void tst_QSignalSpy::spyOnMetaMethod() Q_DECLARE_METATYPE(QMetaMethod); void tst_QSignalSpy::spyOnMetaMethod_invalid() { + QFETCH(const QByteArray, message); QFETCH(QObject*, object); QFETCH(QMetaMethod, signal); + QTest::ignoreMessage(QtWarningMsg, message.data()); QSignalSpy spy(object, signal); QVERIFY(!spy.isValid()); } void tst_QSignalSpy::spyOnMetaMethod_invalid_data() { + QTest::addColumn("message"); QTest::addColumn("object"); QTest::addColumn("signal"); QTest::addRow("Invalid object") + << "QSignalSpy: Cannot spy on a null object"_ba << static_cast(nullptr) << QMetaMethod(); QTest::addRow("Empty signal") + << "QSignalSpy: Not a valid signal: ''"_ba << new QObject(this) << QMetaMethod(); QTest::addRow("Method is not a signal") + << "QSignalSpy: Not a valid signal: 'deleteLater()'"_ba << new QObject(this) << QObject::staticMetaObject.method(QObject::staticMetaObject.indexOfMethod("deleteLater()")); } -- cgit v1.2.3 From 8ca00454bd437018deeba103ea024a055f0885ca Mon Sep 17 00:00:00 2001 From: David Faure Date: Tue, 12 Mar 2024 13:18:02 +0100 Subject: QSignalSpy: fix data race between wait() and emit from another thread Detected by TSAN in tst_QThread::terminateAndPrematureDestruction() but better have a dedicated unittest, with values emitted by the signal and recorded in the spy. Manual conflict resolutions: - No chrono overload of QTestEventLoop::enterLoop() in 6.5, yet. - Ditto QSignalSpy::wait(). Change-Id: I141d47b0ea0b63188f8a4f9d056f72df3457bda5 Reviewed-by: Marc Mutz Reviewed-by: Thiago Macieira (cherry picked from commit c837cd75936cbeeb898dd5808edb9dfaf716a76e) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 3b428d6f28a3664220d4c7eef8f8ee1779d206e2) (cherry picked from commit d9f4fc510d8eef56113c36cd0d3b75eddd206f6b) Reviewed-by: Qt CI Bot --- tests/auto/testlib/qsignalspy/tst_qsignalspy.cpp | 29 +++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/testlib/qsignalspy/tst_qsignalspy.cpp b/tests/auto/testlib/qsignalspy/tst_qsignalspy.cpp index 0e51eb0f981..ecbe5c7576e 100644 --- a/tests/auto/testlib/qsignalspy/tst_qsignalspy.cpp +++ b/tests/auto/testlib/qsignalspy/tst_qsignalspy.cpp @@ -6,7 +6,6 @@ #include #include - #include using namespace Qt::StringLiterals; @@ -50,6 +49,8 @@ private slots: void spyOnMetaMethod_invalid(); void spyOnMetaMethod_invalid_data(); + + void signalSpyDoesNotRaceOnCrossThreadSignal(); }; struct CustomType {}; @@ -493,5 +494,31 @@ void tst_QSignalSpy::spyOnMetaMethod_invalid_data() << QObject::staticMetaObject.method(QObject::staticMetaObject.indexOfMethod("deleteLater()")); } +class EmitSignal_Thread : public QThread +{ + Q_OBJECT +public: + void run() override + { + emit valueChanged(42, u"is the answer"_s); + } + +Q_SIGNALS: + void valueChanged(int value, const QString &str); +}; + +void tst_QSignalSpy::signalSpyDoesNotRaceOnCrossThreadSignal() +{ + EmitSignal_Thread thread; + QSignalSpy valueChangedSpy(&thread, &EmitSignal_Thread::valueChanged); + QVERIFY(valueChangedSpy.isValid()); + + thread.start(); + QVERIFY(valueChangedSpy.wait(5000)); + QCOMPARE(valueChangedSpy[0][0].toInt(), 42); + QCOMPARE(valueChangedSpy[0][1].toString(), u"is the answer"_s); + QVERIFY(thread.wait(5000)); +} + QTEST_MAIN(tst_QSignalSpy) #include "tst_qsignalspy.moc" -- cgit v1.2.3 From 6c299826bfa1e28a2f3797b09fcf426c4fc81267 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 22 Mar 2024 16:45:59 +0100 Subject: Fix warning: remove unused parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I5794e38e1e9871f14c9a8df6483e57c1922dace2 Reviewed-by: Jøger Hansegård Reviewed-by: Artem Dyomin Reviewed-by: Pavel Dubsky (cherry picked from commit 8424a6401469fdfb9fbaad488fdd5fe65050f34a) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 51c0378798b445dd350e162dbe5ce4b9246b4cc6) (cherry picked from commit dc88477793f568e9154e7680866c1647763bdd2b) --- tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp b/tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp index 82fb39ece74..6a750467272 100644 --- a/tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp +++ b/tests/auto/corelib/tools/quniquehandle/tst_quniquehandle.cpp @@ -248,7 +248,7 @@ private slots: { using Type = int; - static bool close(Type handle) + static bool close(Type) { return true; } -- cgit v1.2.3 From f12634262a5263718766d4f754f802749b288532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 28 Feb 2024 20:44:58 +0100 Subject: Decouple rate-limiting of paint-on-screen widgets from top level widget As part of eacd58d4e78e7238ba5fcca90ba960aaf3ebd263, a mechanism was added to prevent posting redundant UpdateRequest events to the top level widget, managed by QWidgetRepaintManager. The mechanism relied on a boolean that was set when posting an update request event, and reset when processing the event for the top level widget, as part of QWidgetRepaintManager::sync(). However, for paint-on-screen widgets, we don't post an update request to the top level, we post it to the paint-on-screen widget directly. And when processing that event, we don't paint the widget though the normal QWidgetRepaintManager machinery, but instead call the paint event via QWidgetPrivate::paintOnScreen(). As a result, an update() on a paint-on-screen widget would result in never receiving updates for non-paint-on-screen widgets, as we assumed there was no reason to send further update requests. We could fix this by clearing the updateRequestSent flag as part of the paintOnScreen() code path, but that's incorrect as the flag represents whether the top level QWidgetRepaintManager needs an update request event or not, and would lead to missed updates to normal widgets until the paint-on-screen widget finishes its update. Instead, we only set updateRequestSent if we're posting update requests for non-paint-on-screen widgets, which in practice means the top level widget. The paint on screen logic in QWidgetRepaintManager::markDirty still takes care of rate-limiting the update requests to the paint-on-screen widget, by comparing the dirty area of the widget. There is definite room for improvement here, especially in the direction of handling update requests via QWindow::requestUpdate instead of manually posted events, but for now this will have to do. Fixes: QTBUG-80167 Pick-to: 6.2 5.15 Change-Id: Ib5685de7ca2fd7cd7883a25bb7bc0255ea242d30 Reviewed-by: Richard Moe Gustavsen (cherry picked from commit 697e1b0397259959e3f555296f87a0d9d923e4b5) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit c198f7124cfb043ee1f04b13fc857bf3d5081bcd) (cherry picked from commit 4e3c55e10da297e38ba45a35d7d0506b9f3bf989) --- .../tst_qwidgetrepaintmanager.cpp | 89 ++++++++++++++++++++++ 1 file changed, 89 insertions(+) (limited to 'tests') diff --git a/tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp b/tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp index f53d5aeb050..96a342eb6ba 100644 --- a/tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp +++ b/tests/auto/widgets/kernel/qwidgetrepaintmanager/tst_qwidgetrepaintmanager.cpp @@ -75,8 +75,11 @@ public: const auto type = event->type(); if (type == QEvent::WindowActivate || type == QEvent::WindowDeactivate) return true; + if (type == QEvent::UpdateRequest) + ++updateRequests; return QWidget::event(event); } + int updateRequests = 0; protected: void paintEvent(QPaintEvent *event) override @@ -254,6 +257,8 @@ private slots: void opaqueChildren(); void staticContents(); void scroll(); + void paintOnScreenUpdates(); + #if defined(QT_BUILD_INTERNAL) void scrollWithOverlap(); void overlappedRegion(); @@ -479,6 +484,90 @@ void tst_QWidgetRepaintManager::scroll() QCOMPARE(widget.takePaintedRegions(), QRegion()); } +class PaintOnScreenWidget : public TestWidget +{ +public: + using TestWidget::TestWidget; + + // Explicit override to prevent noPaintOnScreen on Windows + QPaintEngine *paintEngine() const override + { + return nullptr; + } +}; + +void tst_QWidgetRepaintManager::paintOnScreenUpdates() +{ + { + TestWidget topLevel; + topLevel.setObjectName("TopLevel"); + topLevel.resize(500, 500); + TestWidget renderToTextureWidget(&topLevel); + renderToTextureWidget.setObjectName("RenderToTexture"); + renderToTextureWidget.setGeometry(0, 0, 200, 200); + QWidgetPrivate::get(&renderToTextureWidget)->setRenderToTexture(); + + PaintOnScreenWidget paintOnScreenWidget(&topLevel); + paintOnScreenWidget.setObjectName("PaintOnScreen"); + paintOnScreenWidget.setGeometry(200, 200, 300, 300); + + topLevel.initialShow(); + + // Updating before toggling WA_PaintOnScreen should work fine + paintOnScreenWidget.update(); + paintOnScreenWidget.waitForPainted(); + QVERIFY(paintOnScreenWidget.waitForPainted()); + +#ifdef Q_OS_ANDROID + QEXPECT_FAIL("", "This test fails on Android", Abort); +#endif + QCOMPARE(paintOnScreenWidget.takePaintedRegions(), paintOnScreenWidget.rect()); + + renderToTextureWidget.update(); + QVERIFY(renderToTextureWidget.waitForPainted()); + QCOMPARE(renderToTextureWidget.takePaintedRegions(), renderToTextureWidget.rect()); + + // Then toggle WA_PaintOnScreen + paintOnScreenWidget.setAttribute(Qt::WA_PaintOnScreen); + + // The render-to-texture widget updates fine + renderToTextureWidget.update(); + QVERIFY(renderToTextureWidget.waitForPainted()); + QCOMPARE(renderToTextureWidget.takePaintedRegions(), renderToTextureWidget.rect()); + + // Updating the paint-on-screen texture widget will not result + // in a paint event, but should result in an update request. + paintOnScreenWidget.updateRequests = 0; + paintOnScreenWidget.update(); + QVERIFY(QTest::qWaitFor([&]{ return paintOnScreenWidget.updateRequests > 0; })); + + // And should not prevent the render-to-texture widget from receiving updates + renderToTextureWidget.update(); + QVERIFY(renderToTextureWidget.waitForPainted()); + QCOMPARE(renderToTextureWidget.takePaintedRegions(), renderToTextureWidget.rect()); + } + + { + TestWidget paintOnScreenTopLevel; + paintOnScreenTopLevel.setObjectName("PaintOnScreenTopLevel"); + paintOnScreenTopLevel.setAttribute(Qt::WA_PaintOnScreen); + + paintOnScreenTopLevel.initialShow(); + + paintOnScreenTopLevel.updateRequests = 0; + paintOnScreenTopLevel.update(); + QVERIFY(QTest::qWaitFor([&]{ return paintOnScreenTopLevel.updateRequests > 0; })); + + // Turn off paint on screen and make it a render-to-texture widget. + // This will lead us into a QWidgetRepaintManager::markDirty() code + // path that checks updateRequestSent, which is still set from the + // update above since paint-on-screen handling doesn't reset it. + paintOnScreenTopLevel.setAttribute(Qt::WA_PaintOnScreen, false); + QWidgetPrivate::get(&paintOnScreenTopLevel)->setRenderToTexture(); + paintOnScreenTopLevel.update(); + QVERIFY(QTest::qWaitFor([&]{ return paintOnScreenTopLevel.updateRequests > 1; })); + } +} #if defined(QT_BUILD_INTERNAL) -- cgit v1.2.3 From 0eeb1bdefb1a1556a01439eba7a828865a1a27c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Wed, 13 Mar 2024 18:40:59 +0100 Subject: tst_qfuture: Update EXPECT_FAIL msvc condition It is passing on my machine with Visual Studio 17.10 Preview 1. But only with C++20 enabled. Task-number: QTBUG-101761 Change-Id: Ia5af3d75d35dda1df9b39bdc94f07dd746ff60af Reviewed-by: Thiago Macieira (cherry picked from commit 6c0be8acc44df9eec2c64527696bb137650124ba) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit a3ee0db4bfbaa0f5a3458de81a4bec23ff2b40a4) (cherry picked from commit ed8589e35b44aeb874c4b36f38be4d0bc3c1accd) --- tests/auto/corelib/thread/qfuture/tst_qfuture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp index 33f920368e7..d306af4873f 100644 --- a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp +++ b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp @@ -3833,7 +3833,7 @@ void tst_QFuture::signalConnect() { SenderObject sender; -#if defined(Q_CC_MSVC) && !defined(Q_CC_CLANG) +#if defined(Q_CC_MSVC_ONLY) && (Q_CC_MSVC < 1940 || __cplusplus < 202002L) #define EXPECT_FUTURE_CONNECT_FAIL() QEXPECT_FAIL("", "QTBUG-101761, test fails on Windows/MSVC", Continue) #else QTest::ignoreMessage(QtWarningMsg, "QObject::connect: signal not found in SenderObject"); -- cgit v1.2.3 From 09dd50939a0be89d744588bb3b277289ef5ceb5d Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 10 Apr 2024 15:25:59 +0200 Subject: StyleSheet: respect a font weight set for header sections QCommonStyle sets the font for a selected header section to bold. This overrides the font weight a calling style might already have set, e.g. when a style sheet is applied to explicitly set a weight for a checked header section: QHeaderView::section:checked { font-size: 20px font-weight: normal } Since setting the weight on a font sets the respective resolve-mask bit, we can avoid overwriting a weight that is already set explicitly. Add baseline test coverage using a QTableWidget. Fixes: QTBUG-122180 Change-Id: I8c6279ad2fd8c5718ebea26e27c64ae823625748 Reviewed-by: Axel Spoerl (cherry picked from commit 74e0ed217fdec8e32227f9f845eccac7f1552297) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 294a2646db4412bf9eb65a7c365bb0398d2747c5) --- .../stylesheet/qss/qheaderview/selectedFontWeight.qss | 16 ++++++++++++++++ tests/baseline/stylesheet/tst_baseline_stylesheet.cpp | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 tests/baseline/stylesheet/qss/qheaderview/selectedFontWeight.qss (limited to 'tests') diff --git a/tests/baseline/stylesheet/qss/qheaderview/selectedFontWeight.qss b/tests/baseline/stylesheet/qss/qheaderview/selectedFontWeight.qss new file mode 100644 index 00000000000..1c45a997672 --- /dev/null +++ b/tests/baseline/stylesheet/qss/qheaderview/selectedFontWeight.qss @@ -0,0 +1,16 @@ +QHeaderView::section { + background-color: red; + font-size: 10px; +} + +QHeaderView::section:checked { + background-color: green; + font-size: 20px; + font-weight: bold; +} + +QHeaderView::section:first { + background-color: yellow; + font-size: 20px; + font-weight: normal; +} diff --git a/tests/baseline/stylesheet/tst_baseline_stylesheet.cpp b/tests/baseline/stylesheet/tst_baseline_stylesheet.cpp index 3a4d8e8f15d..dde3dcc7178 100644 --- a/tests/baseline/stylesheet/tst_baseline_stylesheet.cpp +++ b/tests/baseline/stylesheet/tst_baseline_stylesheet.cpp @@ -27,6 +27,9 @@ private slots: void tst_QTreeView_data(); void tst_QTreeView(); + void tst_QHeaderView_data(); + void tst_QHeaderView(); + private: QDir styleSheetDir; }; @@ -205,6 +208,22 @@ void tst_Stylesheet::tst_QTreeView() QBASELINE_CHECK_DEFERRED(takeSnapshot(), "itemSelected"); } +void tst_Stylesheet::tst_QHeaderView_data() +{ + loadTestFiles(); +} + +void tst_Stylesheet::tst_QHeaderView() +{ + QHBoxLayout *layout = new QHBoxLayout; + QTableWidget *tw = new QTableWidget(10, 10); + tw->setCurrentCell(1, 1); + layout->addWidget(tw); + testWindow()->setLayout(layout); + makeVisible(); + QBASELINE_TEST(takeSnapshot()); +} + #define main _realmain QTEST_MAIN(tst_Stylesheet) #undef main -- cgit v1.2.3 From f57899e191acad2dcdf76cfb4d71c96379812c41 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 5 Apr 2024 15:50:19 +0200 Subject: Pass QVariant to QSystemLocale::query() as rvalue reference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QVariant is rather big for passing by value; and no caller has any further use for the QVariant it's passing in. File qlocale_wasm.cpp was added after 6.5, so drop its change. Task-number: QTBUG-122619 Change-Id: I2751745e715aacfa8982ac97b4ae777fde5e88de Reviewed-by: Thiago Macieira (cherry picked from commit b68f1009187fee473f4c6477ec64300650e29904) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 644eca89ed288adbcd7a4a604797be567796711d) Reviewed-by: Mårten Nordheim --- tests/auto/corelib/text/qlocale/tst_qlocale.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp index 4829a361b4d..329c9402140 100644 --- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp @@ -3633,7 +3633,7 @@ public: { } - QVariant query(QueryType type, QVariant /*in*/) const override + QVariant query(QueryType type, QVariant &&/*in*/) const override { switch (type) { case UILanguages: -- cgit v1.2.3 From 4be9bb498fb3618e5953154a11f1653271b7b1f6 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 5 Apr 2024 15:15:13 +0200 Subject: QSystemLocale(): disable copy and move Axivion (SV546) points out (based on a clazy "rule of three" that might be rule of five by now) the lack of move and copy assignment and construction. We don't want those anyway, so tell the compiler not to create them. Task-number: QTBUG-122619 Change-Id: Ie951a2c3d60d76ad3448310d3f9bbda22190015b Reviewed-by: Giuseppe D'Angelo Reviewed-by: Thiago Macieira (cherry picked from commit 21ef6d930ad3eb2fb435cd601692cb5cc1726bd8) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit a07c718c17df4d376c4fcf5caf67e086a4f0bd53) --- tests/auto/corelib/text/qlocale/tst_qlocale.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'tests') diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp index 329c9402140..1f17fdccf9f 100644 --- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp @@ -3627,6 +3627,7 @@ void tst_QLocale::bcp47Name() #ifdef QT_BUILD_INTERNAL class MySystemLocale : public QSystemLocale { + Q_DISABLE_COPY_MOVE(MySystemLocale) public: MySystemLocale(const QString &locale) : m_name(locale), m_id(QLocaleId::fromName(locale)), m_locale(locale) -- cgit v1.2.3 From a6343743425b1c070214039056a8c61cd869fea7 Mon Sep 17 00:00:00 2001 From: Assam Boudjelthia Date: Tue, 2 Apr 2024 19:18:26 +0000 Subject: Revert "Android: SKIP cases failing on Android 12 CI with 16GB RAM" This partially reverts commit eb0d7b5dcf834c856d58637ada8745aee2b040ee. Leaving tst_QRhi::tessellation() skipped because it still fails. Reason for revert: The latest emulator fixed the issue. Fixes: QTBUG-111235 Fixes: QTBUG-111236 Task-number: QTQAINFRA-5971 Change-Id: I9a624be6ba219a4175c0e84ba68d882953422cba Reviewed-by: Ville Voutilainen Reviewed-by: Rami Potinkara (cherry picked from commit 772fd609c6eff09bdaa44cb2ac5f913e58788fa3) Reviewed-by: Qt CI Bot (cherry picked from commit 34d856be264669c855da9d7fb0a6077a78fea8f6) Reviewed-by: Qt Cherry-pick Bot --- tests/auto/gui/qvulkan/tst_qvulkan.cpp | 16 ---------------- .../widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp | 4 ---- 2 files changed, 20 deletions(-) (limited to 'tests') diff --git a/tests/auto/gui/qvulkan/tst_qvulkan.cpp b/tests/auto/gui/qvulkan/tst_qvulkan.cpp index 0afebfba28f..1be39f77a7d 100644 --- a/tests/auto/gui/qvulkan/tst_qvulkan.cpp +++ b/tests/auto/gui/qvulkan/tst_qvulkan.cpp @@ -27,10 +27,6 @@ private slots: void tst_QVulkan::vulkanInstance() { -#ifdef Q_OS_ANDROID - if (QNativeInterface::QAndroidApplication::sdkVersion() >= 31) - QSKIP("Fails on Android 12 (QTBUG-111236)"); -#endif QVulkanInstance inst; if (!inst.create()) QSKIP("Vulkan init failed; skip"); @@ -67,10 +63,6 @@ void tst_QVulkan::vulkanInstance() void tst_QVulkan::vulkanCheckSupported() { -#ifdef Q_OS_ANDROID - if (QNativeInterface::QAndroidApplication::sdkVersion() >= 31) - QSKIP("Fails on Android 12 (QTBUG-111236)"); -#endif // Test the early calls to supportedLayers/extensions/apiVersion that need // the library and some basics, but do not initialize the instance. QVulkanInstance inst; @@ -214,10 +206,6 @@ void tst_QVulkan::vulkanPlainWindow() void tst_QVulkan::vulkanVersionRequest() { -#ifdef Q_OS_ANDROID - if (QNativeInterface::QAndroidApplication::sdkVersion() >= 31) - QSKIP("Fails on Android 12 (QTBUG-111236)"); -#endif QVulkanInstance inst; if (!inst.create()) QSKIP("Vulkan init failed; skip"); @@ -264,10 +252,6 @@ static void waitForUnexposed(QWindow *w) void tst_QVulkan::vulkanWindow() { -#ifdef Q_OS_ANDROID - if (QNativeInterface::QAndroidApplication::sdkVersion() >= 31) - QSKIP("Fails on Android 12 (QTBUG-111236)"); -#endif QVulkanInstance inst; if (!inst.create()) QSKIP("Vulkan init failed; skip"); diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp index e0c68e5d8c0..394409b97b7 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp +++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp @@ -327,10 +327,6 @@ void tst_QOpenGLWidget::reparentToNotYetCreated() void tst_QOpenGLWidget::reparentHidden() { -#ifdef Q_OS_ANDROID - if (QNativeInterface::QAndroidApplication::sdkVersion() >= 31) - QSKIP("Fails on Android 12 (QTBUG-111235)"); -#endif // Tests QTBUG-60896 QWidget topLevel1; -- cgit v1.2.3 From a78a8e7340307709ea644db052004b83ecaa767e Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 18 Mar 2024 07:57:40 +0100 Subject: Revert "Don't do font merging for PUA characters" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit fc33fea999365c36ed446eee0db0d59d94be306b. The change caused issues with system-wide PUA fallbacks on platforms where this is supported. It needs to be replaced by an approach which still falls back, but only for fonts which are explicitly categorized as PUA fallbacks. Task-number: QTBUG-110502 Change-Id: I985a1f8076645593c50e81759872b4227d0fcd0d Reviewed-by: Tor Arne Vestbø (cherry picked from commit 4913511d3bf8ec7838f80fbfe92c0fe900b2f003) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 5b3fd5e9d217a1ed7581e1e08bec2ab9641e7bcd) Reviewed-by: Mårten Nordheim --- .../qtextscriptengine/tst_qtextscriptengine.cpp | 39 ---------------------- 1 file changed, 39 deletions(-) (limited to 'tests') diff --git a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp index 43cb6667ec5..d729cfbf6ee 100644 --- a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp +++ b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp @@ -56,9 +56,6 @@ private slots: void shapingDisabledDevanagari(); void shapingDisabledLatin(); - - void privateUseArea(); - private: bool haveTestFonts; }; @@ -1316,41 +1313,5 @@ void tst_QTextScriptEngine::shapingDisabledDevanagari() QCOMPARE(noShapingRuns.first().glyphIndexes().size(), normalRuns.first().glyphIndexes().size()); } -void tst_QTextScriptEngine::privateUseArea() -{ - QString privateUseAreaString = QString::fromUtf8(""); - - QFont font; - QList withFontMerging; - { - QTextLayout layout; - layout.setText(privateUseAreaString); - layout.setFont(font); - layout.beginLayout(); - layout.createLine(); - layout.endLayout(); - - withFontMerging = layout.glyphRuns(); - } - - font.setStyleStrategy(QFont::NoFontMerging); - QList withoutFontMerging; - { - QTextLayout layout; - layout.setText(privateUseAreaString); - layout.setFont(font); - layout.beginLayout(); - layout.createLine(); - layout.endLayout(); - - withoutFontMerging = layout.glyphRuns(); - } - - QCOMPARE(withFontMerging.size(), withoutFontMerging.size()); - - for (int i = 0; i < withFontMerging.size(); ++i) - QCOMPARE(withFontMerging.at(i).glyphIndexes(), withoutFontMerging.at(i).glyphIndexes()); -} - QTEST_MAIN(tst_QTextScriptEngine) #include "tst_qtextscriptengine.moc" -- cgit v1.2.3 From 301061040a3c5279d28bd327d3ac2883f258d369 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 12 Apr 2024 07:50:30 -0400 Subject: Draw list bullets/numbers with CSS text color, not palette color When CSS has been used to customize the text color, render the bullet with the same color. This is consistent with web browsers, and with Qt Quick rendering. In QTextDocumentLayoutPrivate::drawListItem(), the pen color is the text color, so use it instead of brush color. Add a baseline test for lancelot: the background and general text are customized, then some list items are customized further, and some of them have colored text spans. Repeat with different styles of numbered and bullet lists and checklists. Fixes: QTBUG-2188 Task-number: QTBUG-213 Task-number: QTBUG-57833 Change-Id: I71e84d00172e4b37aef57c8badd2ec43c10113d9 Reviewed-by: Sami Shalayel (cherry picked from commit 7f48c79627663f0777df9c10d06202aea5bedac3) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 2d7972e05950e822ded11a09b79be4db92ce1692) --- tests/baseline/text/data/colored_list.html | 68 ++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 tests/baseline/text/data/colored_list.html (limited to 'tests') diff --git a/tests/baseline/text/data/colored_list.html b/tests/baseline/text/data/colored_list.html new file mode 100644 index 00000000000..d1cca94460f --- /dev/null +++ b/tests/baseline/text/data/colored_list.html @@ -0,0 +1,68 @@ + + + + + + + +
    +
  • disc
  • +
  • bronze
  • +
  • red bullet, pink text
  • +
  • checked
  • +
  • unchecked
  • +
+ +
    +
  • circle
  • +
  • silver
  • +
  • grey bullet, pink text
  • +
  • checked
  • +
  • unchecked
  • +
+ +
    +
  • square
  • +
  • gold
  • +
  • yellow bullet, pink text
  • +
  • checked
  • +
  • unchecked
  • +
+ +
    +
  1. decimal
  2. +
  3. bronze decimal
  4. +
  5. red number, pink text
  6. +
+ +
    +
  1. uppercase
  2. +
  3. bronze uppercase
  4. +
  5. red letter, pink text
  6. +
+ +
    +
  1. lowercase
  2. +
  3. bronze lowercase
  4. +
  5. red letter, pink text
  6. +
+ +
    +
  1. lower roman
  2. +
  3. bronze roman
  4. +
  5. red number, pink text
  6. +
+ +
    +
  1. upper roman
  2. +
  3. bronze roman
  4. +
  5. red number, pink text
  6. +
+ + -- cgit v1.2.3 From 376e1ef4855b75c3f3637f4a2f06cf08ffd81c7d Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Wed, 10 Apr 2024 09:02:09 +0200 Subject: QMovie: fix regression in frame delays The recent addition of support for multi-frame (non-animation) formats had an unwanted side effect of sometimes calling QImageReader::nextImageDelay() when the reader is at a different frame than intended. Fix by effectively reverting to the previous call pattern. Fixes: QTBUG-124227 Change-Id: I735f8d67afb17bd4c77f9b4507a71796b7d66958 Reviewed-by: Paul Olav Tvete (cherry picked from commit 5f0ed0ac0ddffd3779fae0db956df8d48d629f92) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 3516762d73b0325a21b344367da51e29a89a1dbd) --- tests/auto/gui/image/qmovie/tst_qmovie.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'tests') diff --git a/tests/auto/gui/image/qmovie/tst_qmovie.cpp b/tests/auto/gui/image/qmovie/tst_qmovie.cpp index 13014e04daa..ba921a66dc0 100644 --- a/tests/auto/gui/image/qmovie/tst_qmovie.cpp +++ b/tests/auto/gui/image/qmovie/tst_qmovie.cpp @@ -36,6 +36,7 @@ private slots: void playMovie(); void jumpToFrame_data(); void jumpToFrame(); + void frameDelay(); void changeMovieFile(); #ifndef QT_NO_WIDGETS void infiniteLoop(); @@ -181,6 +182,17 @@ void tst_QMovie::jumpToFrame() QCOMPARE(movie.currentFrameNumber(), 0); } +void tst_QMovie::frameDelay() +{ + QMovie movie(QFINDTESTDATA("animations/comicsecard.gif")); + QList frameDelays{ 200, 800, 800, 2000, 2600 }; + for (int i = 0; i < movie.frameCount(); i++) { + movie.jumpToFrame(i); + // Processing may have taken a little time, so round to nearest 100ms + QCOMPARE(100 * qRound(movie.nextFrameDelay() / 100.0f), frameDelays[i]); + } +} + void tst_QMovie::changeMovieFile() { QMovie movie(QFINDTESTDATA("animations/comicsecard.gif")); -- cgit v1.2.3 From 9ea2ff075ea511531a3b73897f80eae66875dd35 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 24 Apr 2024 18:06:52 +0200 Subject: QThread: check various ways users may use start(Priority) Some of these would break if we changed the start(Priority) to say start(QThread::Priority) instead. Manual conflict resolution: - added include and std:chrono_literals using declaration which 6.7 already had in tst_qthread.cpp Pick-to: 6.2 Task-number: QTBUG-124723 Change-Id: Id3ebe73718c8acbc54a2c88158f4062fd0dd5be1 Reviewed-by: Thiago Macieira (cherry picked from commit cf19105e018314d1fb05bc91959f233d3d6747ba) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit a4c271007743719dc74aa333b37bd1ec78831c94) Reviewed-by: Volker Hilsheimer --- tests/auto/corelib/thread/qthread/tst_qthread.cpp | 55 +++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/thread/qthread/tst_qthread.cpp b/tests/auto/corelib/thread/qthread/tst_qthread.cpp index 1cade32545b..953d81cb1e4 100644 --- a/tests/auto/corelib/thread/qthread/tst_qthread.cpp +++ b/tests/auto/corelib/thread/qthread/tst_qthread.cpp @@ -38,6 +38,10 @@ #include +#include + +using namespace std::chrono_literals; + class tst_QThread : public QObject { Q_OBJECT @@ -51,6 +55,7 @@ private slots: void setStackSize(); void exit(); void start(); + void startSlotUsedInStringBasedLookups(); void terminate(); void quit(); void started(); @@ -462,6 +467,56 @@ void tst_QThread::start() } } +class QThreadStarter : public QObject +{ + Q_OBJECT +public: + using QObject::QObject; +Q_SIGNALS: + void start(QThread::Priority); +}; + +class QThreadSelfStarter : public QThread +{ + Q_OBJECT +public: + using QThread::QThread; + + void check() + { + QVERIFY(connect(this, SIGNAL(starting(Priority)), + this, SLOT(start(Priority)))); + QVERIFY(QMetaObject::invokeMethod(this, "start", Q_ARG(Priority, IdlePriority))); + } + +Q_SIGNALS: + void starting(Priority); +}; + +void tst_QThread::startSlotUsedInStringBasedLookups() +{ + // QTBUG-124723 + + QThread thread; + { + QThreadStarter starter; + QVERIFY(QObject::connect(&starter, SIGNAL(start(QThread::Priority)), + &thread, SLOT(start(QThread::Priority)))); + } + { + QThreadSelfStarter selfStarter; + selfStarter.check(); + if (QTest::currentTestFailed()) + return; + selfStarter.exit(); + selfStarter.wait(30s); + } + QVERIFY(QMetaObject::invokeMethod(&thread, "start", + Q_ARG(QThread::Priority, QThread::IdlePriority))); + thread.exit(); + thread.wait(30s); +} + void tst_QThread::terminate() { #if defined(Q_OS_ANDROID) -- cgit v1.2.3 From 47dd5b7aed6ccc623b3c08f74ed89112be112ec4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 15 Feb 2024 15:04:18 -0800 Subject: QXmlStreamWriter: decode UTF-8 into code points We were iterating over code *units* and that yielded wrong results. The one from the bug report was simply caused by the fact that QUtf8StringView::value_type is char, which is signed on x86, so the expression: *it <= u'\x1F' was true for all non-Latin1 content. But in attempting to fix this, I needed to do the proper UTF-8 decoding, as otherwise we wouldn't catch non-Latin1 sequences and such. [ChangeLog][QtCore][QXmlStreamWriter] Fixed a bug that caused the class to fail to write UTF-8 strings with non-US-ASCII content when passed as a QUtf8StringView. Fixes: QTBUG-122241 Change-Id: I83dda2d36c904517b3c0fffd17b42bbf09a493d0 Reviewed-by: Mate Barany (cherry picked from commit 94c62e322264e2e7d61193ae74ba8556a330385c) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 6bef40cb821bcaa0df62c17b7e6d19e95c9cea21) --- .../serialization/qxmlstream/tst_qxmlstream.cpp | 125 +++++++++++++++++++++ 1 file changed, 125 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp index aa35468b936..08de2c36356 100644 --- a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp @@ -569,6 +569,12 @@ private slots: void hasAttribute() const; void writeWithUtf8Codec() const; void writeWithStandalone() const; + void writeCharacters_data() const; + void writeCharacters() const; + void writeAttribute_data() const; + void writeAttribute() const; + void writeBadCharactersUtf8_data() const; + void writeBadCharactersUtf8() const; void entitiesAndWhitespace_1() const; void entitiesAndWhitespace_2() const; void testFalsePrematureError() const; @@ -1368,6 +1374,125 @@ void tst_QXmlStream::writeWithStandalone() const } } +static void writeCharacters_data_common() +{ + QTest::addColumn("input"); + QTest::addColumn("output"); + + QTest::newRow("empty") << QString() << QString(); + + // invalid content + QTest::newRow("null-character") << u"\0"_s << QString(); + QTest::newRow("vertical-tab") << "\v" << QString(); + QTest::newRow("form-feed") << "\f" << QString(); + QTest::newRow("esc") << "\x1f" << QString(); + QTest::newRow("U+FFFE") << u"\xfffe"_s << QString(); + QTest::newRow("U+FFFF") << u"\xffff"_s << QString(); + + // simple strings + QTest::newRow("us-ascii") << "Hello, world" << "Hello, world"; + QTest::newRow("latin1") << "Bokmål" << "Bokmål"; + QTest::newRow("nonlatin1") << "Ελληνικά" << "Ελληνικά"; + QTest::newRow("nonbmp") << u"\U00010000"_s << u"\U00010000"_s; + + // escaped content + QTest::newRow("less-than") << "<" << "<"; + QTest::newRow("greater-than") << ">" << ">"; + QTest::newRow("ampersand") << "&" << "&"; + QTest::newRow("quote") << "\"" << """; +} + +template +static void writeCharacters_common(Execute &&exec, Transform &&transform) +{ + QFETCH(QString, input); + QFETCH(QString, output); + QStringView utf16 = input; + QByteArray utf8ba = input.toUtf8(); + QUtf8StringView utf8(utf8ba); + + // may be invalid if input is not Latin1 + QByteArray l1ba = input.toLatin1(); + QLatin1StringView l1(l1ba); + if (l1 != input) + l1 = {}; + + auto write = [&](auto input) -> std::optional { + QString result; + QXmlStreamWriter writer(&result); + writer.writeStartElement("a"); + exec(writer, input); + writer.writeEndElement(); + if (writer.hasError()) + return std::nullopt; + return result; + }; + + if (input.isNull() != output.isNull()) { + // error + QCOMPARE(write(utf16), std::nullopt); + QCOMPARE(write(utf8), std::nullopt); + if (!l1.isEmpty()) + QCOMPARE(write(l1), std::nullopt); + } else { + output = transform(output); + QCOMPARE(write(utf16), output); + QCOMPARE(write(utf8), output); + if (!l1.isEmpty()) + QCOMPARE(write(l1), output); + } +} + +void tst_QXmlStream::writeCharacters_data() const +{ + writeCharacters_data_common(); + QTest::newRow("tab") << "\t" << "\t"; + QTest::newRow("newline") << "\n" << "\n"; + QTest::newRow("carriage-return") << "\r" << "\r"; +} + +void tst_QXmlStream::writeCharacters() const +{ + auto exec = [](QXmlStreamWriter &writer, auto input) { + writer.writeCharacters(input); + }; + auto transform = [](auto output) { return "" + output + ""; }; + writeCharacters_common(exec, transform); +} + +void tst_QXmlStream::writeAttribute_data() const +{ + writeCharacters_data_common(); + QTest::newRow("tab") << "\t" << " "; + QTest::newRow("newline") << "\n" << " "; + QTest::newRow("carriage-return") << "\r" << " "; +} + +void tst_QXmlStream::writeAttribute() const +{ + auto exec = [](QXmlStreamWriter &writer, auto input) { + writer.writeAttribute("b", input); + }; + auto transform = [](auto output) { return ""; }; + writeCharacters_common(exec, transform); +} + +#include "../../io/qurlinternal/utf8data.cpp" +void tst_QXmlStream::writeBadCharactersUtf8_data() const +{ + QTest::addColumn("input"); + loadInvalidUtf8Rows(); +} + +void tst_QXmlStream::writeBadCharactersUtf8() const +{ + QFETCH(QByteArray, input); + QString target; + QXmlStreamWriter writer(&target); + writer.writeTextElement("a", QUtf8StringView(input)); + QVERIFY(writer.hasError()); +} + void tst_QXmlStream::entitiesAndWhitespace_1() const { QXmlStreamReader reader(QLatin1String("&extEnt;")); -- cgit v1.2.3 From 5cff915e757f990f3dc7e89f6c2678dcfd8d08fe Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 23 Apr 2024 13:36:23 +0200 Subject: test: Don't crash when focusWidget() is null If QApplication::focusWidget() returns null, which was the case on Wayland under some circumstances, then the code collecting the error output would crash when dereferencing the null pointer. This fixes that crash and gets proper test failure output instead. Fixes: QTBUG-124475 Change-Id: Ic34228be953cf42dfe2ebf75957cd48791e6de7d Reviewed-by: Liang Qi (cherry picked from commit 5711aaa0170bd97dab1479c0e6c884289e41da99) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 5310cce3ce8c46706ffa3fd8d6ab3ab2e5dacaa4) --- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 35 ++++++++++++++--------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'tests') diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 327b83c2933..456a1f035b7 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -2233,6 +2233,13 @@ void tst_QWidget::tabOrderWithProxy() QVERIFY(firstEdit->hasFocus()); } +static QString focusWidgetName() +{ + return QApplication::focusWidget() != nullptr + ? QApplication::focusWidget()->objectName() + : QStringLiteral("No focus widget"); +} + void tst_QWidget::tabOrderWithProxyDisabled() { Container container; @@ -2265,23 +2272,23 @@ void tst_QWidget::tabOrderWithProxyDisabled() QSKIP("Window failed to activate, skipping test"); QVERIFY2(lineEdit1.hasFocus(), - qPrintable(QApplication::focusWidget()->objectName())); + qPrintable(focusWidgetName())); container.tab(); QVERIFY2(!lineEdit2.hasFocus(), - qPrintable(QApplication::focusWidget()->objectName())); + qPrintable(focusWidgetName())); QVERIFY2(lineEdit3.hasFocus(), - qPrintable(QApplication::focusWidget()->objectName())); + qPrintable(focusWidgetName())); container.tab(); QVERIFY2(lineEdit1.hasFocus(), - qPrintable(QApplication::focusWidget()->objectName())); + qPrintable(focusWidgetName())); container.backTab(); QVERIFY2(lineEdit3.hasFocus(), - qPrintable(QApplication::focusWidget()->objectName())); + qPrintable(focusWidgetName())); container.backTab(); QVERIFY2(!lineEdit2.hasFocus(), - qPrintable(QApplication::focusWidget()->objectName())); + qPrintable(focusWidgetName())); QVERIFY2(lineEdit1.hasFocus(), - qPrintable(QApplication::focusWidget()->objectName())); + qPrintable(focusWidgetName())); } //#define DEBUG_FOCUS_CHAIN @@ -2595,23 +2602,23 @@ void tst_QWidget::tabOrderWithCompoundWidgetsNoFocusPolicy() QSKIP("Window failed to activate, skipping test"); QVERIFY2(spinbox1.hasFocus(), - qPrintable(QApplication::focusWidget()->objectName())); + qPrintable(focusWidgetName())); container.tab(); QVERIFY2(!spinbox2.hasFocus(), - qPrintable(QApplication::focusWidget()->objectName())); + qPrintable(focusWidgetName())); QVERIFY2(spinbox3.hasFocus(), - qPrintable(QApplication::focusWidget()->objectName())); + qPrintable(focusWidgetName())); container.tab(); QVERIFY2(spinbox1.hasFocus(), - qPrintable(QApplication::focusWidget()->objectName())); + qPrintable(focusWidgetName())); container.backTab(); QVERIFY2(spinbox3.hasFocus(), - qPrintable(QApplication::focusWidget()->objectName())); + qPrintable(focusWidgetName())); container.backTab(); QVERIFY2(!spinbox2.hasFocus(), - qPrintable(QApplication::focusWidget()->objectName())); + qPrintable(focusWidgetName())); QVERIFY2(spinbox1.hasFocus(), - qPrintable(QApplication::focusWidget()->objectName())); + qPrintable(focusWidgetName())); } void tst_QWidget::tabOrderNoChange() -- cgit v1.2.3 From ac21796c2f0859414f3a71e03622e92ba8d603f6 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 8 Feb 2024 11:36:57 +0100 Subject: QList: give the LWG 3346 #ifdef'ery a symbolic name We'll need this in more places, so centralize its definition in qcompilerdetection.h. Amends 595b4e1a9b436a8190964dc41f79621400f5a6be. Change-Id: I87f84cb9ff3ad339c000604423295180176f5799 Reviewed-by: Allan Sandfeld Jensen (cherry picked from commit f4cfc21dec6319c2ae99042be6bb12922a9d336d) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit bfd565a4d300b4227b09fa1e52c18778d997d96c) (cherry picked from commit 0c8e26bbfc5cf58854124ca1f9082aa4c1dbc065) --- tests/auto/corelib/tools/qlist/tst_qlist.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qlist/tst_qlist.cpp b/tests/auto/corelib/tools/qlist/tst_qlist.cpp index 482079b0fea..6dfaea91159 100644 --- a/tests/auto/corelib/tools/qlist/tst_qlist.cpp +++ b/tests/auto/corelib/tools/qlist/tst_qlist.cpp @@ -9,7 +9,7 @@ #include -#if __cplusplus >= 202002L && (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE >= 11) +#ifdef QT_COMPILER_HAS_LWG3346 # if __has_include() # include # if defined(__cpp_lib_concepts) && __cpp_lib_concepts >= 202002L -- cgit v1.2.3 From 72e405b9079707c9c033864aa66d20221b54bb06 Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Thu, 18 Apr 2024 10:25:21 +0200 Subject: QStringConverterICU: Pass correct pointer to callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass the pointer to the current state, not a pointer to a pointer to it. [ChangeLog][QtCore][QStringConverter] Fixed a bug involving moved QStringEncoder/QStringDecoder objects accessing invalid state. Amends 122270d6bea164e6df4357f4d4d77aacfa430470. Done-with: Marc Mutz Change-Id: I70d4dc00e3e0db6cad964579662bcf6d185a4c34 Reviewed-by: Fabian Kosmale Reviewed-by: Mårten Nordheim (cherry picked from commit 39bbfce9b675c9085ef49c9b9c52c146eca55e4a) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 7c4e1357e49baebdd2d20710fccb5604cbb36c0d) --- .../text/qstringconverter/tst_qstringconverter.cpp | 72 +++++++++++++--------- 1 file changed, 42 insertions(+), 30 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp index f37935f6655..ebe6280385a 100644 --- a/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp +++ b/tests/auto/corelib/text/qstringconverter/tst_qstringconverter.cpp @@ -540,11 +540,10 @@ void tst_QStringConverter::charByCharConsistency_data() void tst_QStringConverter::charByCharConsistency() { - QFETCH(QStringView, source); - QFETCH(QByteArray, codec); + QFETCH(const QStringView, source); + QFETCH(const QByteArray, codec); - { - QStringEncoder encoder(codec); + const auto check = [&](QStringEncoder encoder){ if (!encoder.isValid()) QSKIP("Unsupported codec"); @@ -555,19 +554,28 @@ void tst_QStringConverter::charByCharConsistency() stepByStepConverted += encoder.encode(codeUnit); } QCOMPARE(stepByStepConverted, fullyConverted); - } + }; + + check(QStringEncoder(codec)); + if (QTest::currentTestResolved()) return; + + check(QStringEncoder(codec, QStringConverter::Flag::ConvertInvalidToNull)); + if (QTest::currentTestResolved()) return; + + // moved codecs also work: { - QStringEncoder encoder(codec, QStringConverter::Flag::ConvertInvalidToNull); + QStringEncoder dec(codec); + check(std::move(dec)); + } + if (QTest::currentTestResolved()) return; - QByteArray fullyConverted = encoder.encode(source); - encoder.resetState(); - QByteArray stepByStepConverted; - for (const auto& codeUnit: source) { - stepByStepConverted += encoder.encode(codeUnit); - } - QCOMPARE(stepByStepConverted, fullyConverted); + { + QStringEncoder dec(codec, QStringConverter::Flag::ConvertInvalidToNull); + check(std::move(dec)); } + if (QTest::currentTestResolved()) return; + } void tst_QStringConverter::byteByByteConsistency_data() @@ -584,11 +592,10 @@ void tst_QStringConverter::byteByByteConsistency_data() void tst_QStringConverter::byteByByteConsistency() { - QFETCH(QByteArray, source); - QFETCH(QByteArray, codec); + QFETCH(const QByteArray, source); + QFETCH(const QByteArray, codec); - { - QStringDecoder decoder(codec); + const auto check = [&](QStringDecoder decoder) { if (!decoder.isValid()) QSKIP("Unsupported codec"); @@ -601,23 +608,28 @@ void tst_QStringConverter::byteByByteConsistency() stepByStepConverted += decoder.decode(singleChar); } QCOMPARE(stepByStepConverted, fullyConverted); - } + }; + + check(QStringDecoder(codec)); + if (QTest::currentTestResolved()) return; + + check(QStringDecoder(codec, QStringConverter::Flag::ConvertInvalidToNull)); + if (QTest::currentTestResolved()) return; + + // moved codecs also work: { - QStringDecoder decoder(codec, QStringConverter::Flag::ConvertInvalidToNull); - if (!decoder.isValid()) - QSKIP("Unsupported codec"); + QStringDecoder dec(codec); + check(std::move(dec)); + } + if (QTest::currentTestResolved()) return; - QString fullyConverted = decoder.decode(source); - decoder.resetState(); - QString stepByStepConverted; - for (const auto& byte: source) { - QByteArray singleChar; - singleChar.append(byte); - stepByStepConverted += decoder.decode(singleChar); - } - QCOMPARE(stepByStepConverted, fullyConverted); + { + QStringDecoder dec(codec, QStringConverter::Flag::ConvertInvalidToNull); + check(std::move(dec)); } + if (QTest::currentTestResolved()) return; + } void tst_QStringConverter::statefulPieceWise() -- cgit v1.2.3