From 9f486efcbe5ca0f5bb8ba895c4931a5e30748ed6 Mon Sep 17 00:00:00 2001 From: Marcel Krems Date: Tue, 12 Aug 2014 13:10:08 +0200 Subject: Show the correct cursor for QLineEdit's side buttons. Task-number: QTBUG-40708 Change-Id: I5869f42bab3a27085b5572a4b83b16c39a67f733 Reviewed-by: Marc Mutz --- tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tests') diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index 36f14cb1ba..2d050cd5fa 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -4182,10 +4182,12 @@ void tst_QLineEdit::clearButton() QVERIFY(clearButton); QCOMPARE(filterModel->rowCount(), 3); QTest::keyClick(filterLineEdit, 'a'); + QTRY_COMPARE(clearButton->cursor().shape(), Qt::ArrowCursor); QTRY_COMPARE(filterModel->rowCount(), 2); // matches 'aa', 'ab' QTest::keyClick(filterLineEdit, 'b'); QTRY_COMPARE(filterModel->rowCount(), 1); // matches 'ab' QTest::mouseClick(clearButton, Qt::LeftButton, 0, QRect(QPoint(0, 0), clearButton->size()).center()); + QTRY_COMPARE(clearButton->cursor().shape(), filterLineEdit->cursor().shape()); QTRY_COMPARE(filterModel->rowCount(), 3); filterLineEdit->setReadOnly(true); // QTBUG-34315 @@ -4215,6 +4217,8 @@ void tst_QLineEdit::sideWidgets() testWidget.move(300, 300); testWidget.show(); QVERIFY(QTest::qWaitForWindowExposed(&testWidget)); + foreach (QToolButton *button, lineEdit->findChildren()) + QCOMPARE(button->cursor().shape(), Qt::ArrowCursor); // Arbitrarily add/remove actions, trying to detect crashes. Add QTRY_VERIFY(false) to view the result. delete label3Action; lineEdit->removeAction(label2Action); -- cgit v1.2.3 From 4848796f3e2f4aeebb8cbc0782853f27f93afeec Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 20 Jun 2014 10:37:51 -0700 Subject: Make sure we don't cache old file sizes prior to new writes If we write to a file, its size changes. We should drop previous size caches. Change-Id: Ib687c91e5fc88cab588c89023f23da9622160da9 Reviewed-by: Olivier Goffart Reviewed-by: Rafael Roquetto --- tests/auto/corelib/io/qfile/tst_qfile.cpp | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'tests') diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 60d1517ed3..1afe629dac 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -234,6 +234,8 @@ private slots: void mapResource(); void mapOpenMode_data(); void mapOpenMode(); + void mapWrittenFile_data(); + void mapWrittenFile(); #ifndef Q_OS_WINCE void openStandardStreamsFileDescriptors(); @@ -3079,6 +3081,44 @@ void tst_QFile::mapOpenMode() file.close(); } +void tst_QFile::mapWrittenFile_data() +{ + QTest::addColumn("mode"); + QTest::newRow("buffered") << 0; + QTest::newRow("unbuffered") << int(QIODevice::Unbuffered); +} + +void tst_QFile::mapWrittenFile() +{ + static const char data[128] = "Some data padded with nulls\n"; + QFETCH(int, mode); + + QString fileName = QDir::currentPath() + '/' + "qfile_map_testfile"; + +#ifdef Q_OS_WINCE + fileName = QFileInfo(fileName).absoluteFilePath(); +#endif + + if (QFile::exists(fileName)) { + QVERIFY(QFile::setPermissions(fileName, + QFile::WriteOwner | QFile::ReadOwner | QFile::WriteUser | QFile::ReadUser)); + QFile::remove(fileName); + } + QFile file(fileName); + QVERIFY(file.open(QIODevice::ReadWrite | QFile::OpenMode(mode))); + QCOMPARE(file.write(data, sizeof data), qint64(sizeof data)); + if ((mode & QIODevice::Unbuffered) == 0) + file.flush(); + + // test that we can read the data we've just written, without closing the file + uchar *memory = file.map(0, sizeof data); + QVERIFY(memory); + QVERIFY(memcmp(memory, data, sizeof data) == 0); + + file.close(); + file.remove(); +} + void tst_QFile::openDirectory() { QFile f1(m_resourcesDir); -- cgit v1.2.3 From 45cbbe56bc13216b83215ea148590eccf81f420a Mon Sep 17 00:00:00 2001 From: Matt Broadstone Date: Fri, 15 Aug 2014 09:26:04 -0400 Subject: refactor disconnectFromFtp to remove cached entries when necessary In cases where a cached ftp connection fails to connect, or a file transfer has failed, we should removed the cached connection. Since qnam has an idea of a single internal QFtp per full operation, when file transfers failed previously the cached connection would be reused for subsequent connections and thus fail. [ChangeLog][QtNetwork][QNetworkAccessManager] QNetworkAccessManager now properly handles FTP transfer failures by removing failed cached ftp connections. Task-number: QTBUG-40797 Change-Id: Ie090a39ceddd7e58a0d8baf7d01f2a08c70162e5 Reviewed-by: Richard J. Moore --- .../access/qnetworkreply/tst_qnetworkreply.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'tests') diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 480eeecb63..9988db74c7 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -206,6 +206,7 @@ private Q_SLOTS: void getFromFileSpecial(); void getFromFtp_data(); void getFromFtp(); + void getFromFtpAfterError(); // QTBUG-40797 void getFromHttp_data(); void getFromHttp(); void getErrors_data(); @@ -1753,6 +1754,26 @@ void tst_QNetworkReply::getFromFtp() QCOMPARE(reply->readAll(), reference.readAll()); } +void tst_QNetworkReply::getFromFtpAfterError() +{ + QNetworkRequest invalidRequest(QUrl("ftp://" + QtNetworkSettings::serverName() + "/qtest/invalid.txt")); + QNetworkReplyPtr invalidReply; + invalidReply.reset(manager.get(invalidRequest)); + QSignalSpy spy(invalidReply.data(), SIGNAL(error(QNetworkReply::NetworkError))); + QVERIFY(spy.wait()); + QCOMPARE(invalidReply->error(), QNetworkReply::ContentNotFoundError); + + QFile reference(testDataDir + "/rfc3252.txt"); + QVERIFY(reference.open(QIODevice::ReadOnly)); + QNetworkRequest validRequest(QUrl("ftp://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt")); + QNetworkReplyPtr validReply; + RUN_REQUEST(runSimpleRequest(QNetworkAccessManager::GetOperation, validRequest, validReply)); + QCOMPARE(validReply->url(), validRequest.url()); + QCOMPARE(validReply->error(), QNetworkReply::NoError); + QCOMPARE(validReply->header(QNetworkRequest::ContentLengthHeader).toLongLong(), reference.size()); + QCOMPARE(validReply->readAll(), reference.readAll()); +} + void tst_QNetworkReply::getFromHttp_data() { QTest::addColumn("referenceName"); -- cgit v1.2.3 From 6b6e51e5abf56f938c27d194701e2bb20f3459dd Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 19 Aug 2014 15:00:30 +0200 Subject: OS X - QCollator::compare() returns wrong results. kUCCollateDigitsAsNumberMask works only if kUCCollateDigitsOverrideMask is also set. Update 0: - test added. Task-number: QTBUG-40777 Change-Id: I48bfec78f5f8439a51f8d749f0fc4397a72b29f2 Reviewed-by: Lars Knoll --- .../auto/corelib/tools/qcollator/tst_qcollator.cpp | 62 +++++++++++++--------- 1 file changed, 37 insertions(+), 25 deletions(-) (limited to 'tests') diff --git a/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp b/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp index 3a00ebd505..fc4d51a302 100644 --- a/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp +++ b/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp @@ -98,6 +98,7 @@ void tst_QCollator::compare_data() QTest::addColumn("s2"); QTest::addColumn("result"); QTest::addColumn("caseInsensitiveResult"); + QTest::addColumn("numericMode"); /* A few tests below are commented out on the mac. It's unclear why they fail, @@ -112,57 +113,63 @@ void tst_QCollator::compare_data() comparison of Latin-1 values, although I'm not sure. So I just test digits to make sure that it's not totally broken. */ - QTest::newRow("english1") << QString("en_US") << QString("5") << QString("4") << 1 << 1; - QTest::newRow("english2") << QString("en_US") << QString("4") << QString("6") << -1 << -1; - QTest::newRow("english3") << QString("en_US") << QString("5") << QString("6") << -1 << -1; - QTest::newRow("english4") << QString("en_US") << QString("a") << QString("b") << -1 << -1; + QTest::newRow("english1") << QString("en_US") << QString("5") << QString("4") << 1 << 1 << false; + QTest::newRow("english2") << QString("en_US") << QString("4") << QString("6") << -1 << -1 << false; + QTest::newRow("english3") << QString("en_US") << QString("5") << QString("6") << -1 << -1 << false; + QTest::newRow("english4") << QString("en_US") << QString("a") << QString("b") << -1 << -1 << false; + QTest::newRow("english5") << QString("en_US") << QString("test 9") << QString("test 19") << -1 << -1 << true; + /* In Swedish, a with ring above (E5) comes before a with diaresis (E4), which comes before o diaresis (F6), which all come after z. */ #if !defined(Q_OS_WIN) || defined(QT_USE_ICU) - QTest::newRow("swedish1") << QString("sv_SE") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xe4") << -1 << -1; + QTest::newRow("swedish1") << QString("sv_SE") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xe4") << -1 << -1 << false; #endif - QTest::newRow("swedish2") << QString("sv_SE") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1 << -1; - QTest::newRow("swedish3") << QString("sv_SE") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xf6") << -1 << -1; + QTest::newRow("swedish2") << QString("sv_SE") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1 << -1 << false; + QTest::newRow("swedish3") << QString("sv_SE") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xf6") << -1 << -1 << false; #if !defined(Q_OS_OSX) && (!defined(Q_OS_WIN) || defined(QT_USE_ICU)) - QTest::newRow("swedish4") << QString("sv_SE") << QString::fromLatin1("z") << QString::fromLatin1("\xe5") << -1 << -1; + QTest::newRow("swedish4") << QString("sv_SE") << QString::fromLatin1("z") << QString::fromLatin1("\xe5") << -1 << -1 << false; #endif + QTest::newRow("swedish5") << QString("sv_SE") << QString("9") << QString("19") << -1 << -1 << true; /* In Norwegian, ae (E6) comes before o with stroke (D8), which comes before a with ring above (E5). */ - QTest::newRow("norwegian1") << QString("no_NO") << QString::fromLatin1("\xe6") << QString::fromLatin1("\xd8") << -1 << -1; + QTest::newRow("norwegian1") << QString("no_NO") << QString::fromLatin1("\xe6") << QString::fromLatin1("\xd8") << -1 << -1 << false; #if !defined(Q_OS_WIN) || defined(QT_USE_ICU) # ifndef Q_OS_OSX - QTest::newRow("norwegian2") << QString("no_NO") << QString::fromLatin1("\xd8") << QString::fromLatin1("\xe5") << -1 << -1; + QTest::newRow("norwegian2") << QString("no_NO") << QString::fromLatin1("\xd8") << QString::fromLatin1("\xe5") << -1 << -1 << false; # endif - QTest::newRow("norwegian3") << QString("no_NO") << QString::fromLatin1("\xe6") << QString::fromLatin1("\xe5") << -1 << -1; + QTest::newRow("norwegian3") << QString("no_NO") << QString::fromLatin1("\xe6") << QString::fromLatin1("\xe5") << -1 << -1 << false; #endif // !Q_OS_WIN || QT_USE_ICU + QTest::newRow("norwegian4") << QString("no_NO") << QString("9") << QString("19") << -1 << -1 << true; + /* In German, z comes *after* a with diaresis (E4), which comes before o diaresis (F6). */ - QTest::newRow("german1") << QString("de_DE") << QString::fromLatin1("a") << QString::fromLatin1("\xe4") << -1 << -1; - QTest::newRow("german2") << QString("de_DE") << QString::fromLatin1("b") << QString::fromLatin1("\xe4") << 1 << 1; - QTest::newRow("german3") << QString("de_DE") << QString::fromLatin1("z") << QString::fromLatin1("\xe4") << 1 << 1; - QTest::newRow("german4") << QString("de_DE") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1 << -1; - QTest::newRow("german5") << QString("de_DE") << QString::fromLatin1("z") << QString::fromLatin1("\xf6") << 1 << 1; - QTest::newRow("german6") << QString("de_DE") << QString::fromLatin1("\xc0") << QString::fromLatin1("\xe0") << 1 << 0; - QTest::newRow("german7") << QString("de_DE") << QString::fromLatin1("\xd6") << QString::fromLatin1("\xf6") << 1 << 0; - QTest::newRow("german8") << QString("de_DE") << QString::fromLatin1("oe") << QString::fromLatin1("\xf6") << 1 << 1; - QTest::newRow("german9") << QString("de_DE") << QString("A") << QString("a") << 1 << 0; + QTest::newRow("german1") << QString("de_DE") << QString::fromLatin1("a") << QString::fromLatin1("\xe4") << -1 << -1 << false; + QTest::newRow("german2") << QString("de_DE") << QString::fromLatin1("b") << QString::fromLatin1("\xe4") << 1 << 1 << false; + QTest::newRow("german3") << QString("de_DE") << QString::fromLatin1("z") << QString::fromLatin1("\xe4") << 1 << 1 << false; + QTest::newRow("german4") << QString("de_DE") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1 << -1 << false; + QTest::newRow("german5") << QString("de_DE") << QString::fromLatin1("z") << QString::fromLatin1("\xf6") << 1 << 1 << false; + QTest::newRow("german6") << QString("de_DE") << QString::fromLatin1("\xc0") << QString::fromLatin1("\xe0") << 1 << 0 << false; + QTest::newRow("german7") << QString("de_DE") << QString::fromLatin1("\xd6") << QString::fromLatin1("\xf6") << 1 << 0 << false; + QTest::newRow("german8") << QString("de_DE") << QString::fromLatin1("oe") << QString::fromLatin1("\xf6") << 1 << 1 << false; + QTest::newRow("german9") << QString("de_DE") << QString("A") << QString("a") << 1 << 0 << false; + QTest::newRow("german10") << QString("de_DE") << QString("9") << QString("19") << -1 << -1 << true; /* French sorting of e and e with accent */ - QTest::newRow("french1") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("e") << 1 << 1; - QTest::newRow("french2") << QString("fr_FR") << QString::fromLatin1("\xe9t") << QString::fromLatin1("et") << 1 << 1; - QTest::newRow("french3") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("d") << 1 << 1; - QTest::newRow("french4") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("f") << -1 << -1; - + QTest::newRow("french1") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("e") << 1 << 1 << false; + QTest::newRow("french2") << QString("fr_FR") << QString::fromLatin1("\xe9t") << QString::fromLatin1("et") << 1 << 1 << false; + QTest::newRow("french3") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("d") << 1 << 1 << false; + QTest::newRow("french4") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("f") << -1 << -1 << false; + QTest::newRow("french5") << QString("fr_FR") << QString("9") << QString("19") << -1 << -1 << true; } @@ -173,8 +180,13 @@ void tst_QCollator::compare() QFETCH(QString, s2); QFETCH(int, result); QFETCH(int, caseInsensitiveResult); + QFETCH(bool, numericMode); QCollator collator(locale); + + if (numericMode) + collator.setNumericMode(true); + QCOMPARE(collator.compare(s1, s2), result); collator.setCaseSensitivity(Qt::CaseInsensitive); QCOMPARE(collator.compare(s1, s2), caseInsensitiveResult); -- cgit v1.2.3 From 198009db79a85d3cab7fe3a6432635d36123a2d6 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 15 Aug 2014 15:55:12 +0200 Subject: Fix several regressions in font selection In Qt 5.3.0 a change was added which automatically adapts Common script to surrounding scripts in accordance with the Unicode tr#24. This broke *a lot* of cases of font selection because the font selection algorithm is not prepared for handling characters with adapted scripts. We need to disable this change for now and redo it later with patches to font selection to avoid the regressions. [ChangeLog][Text] Fixed several regressions in font selection when combining different writing systems in the same text. Task-number: QTBUG-39930 Task-number: QTBUG-39860 Change-Id: Id02b5ae2403c06542ed5d81e7c4deb2e0c7d816e Reviewed-by: Konstantin Ritt --- tests/auto/gui/text/qglyphrun/test.ttf | Bin 3712 -> 2008 bytes tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp | 20 ++++++++++++++++++- .../qtextscriptengine/tst_qtextscriptengine.cpp | 22 ++++++++++++++------- 3 files changed, 34 insertions(+), 8 deletions(-) (limited to 'tests') diff --git a/tests/auto/gui/text/qglyphrun/test.ttf b/tests/auto/gui/text/qglyphrun/test.ttf index 9043a576ef..382b2547b0 100644 Binary files a/tests/auto/gui/text/qglyphrun/test.ttf and b/tests/auto/gui/text/qglyphrun/test.ttf differ diff --git a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp index f576627745..8d1ec51c26 100644 --- a/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp +++ b/tests/auto/gui/text/qglyphrun/tst_qglyphrun.cpp @@ -77,6 +77,7 @@ private slots: void setRawData(); void setRawDataAndGetAsVector(); void boundingRect(); + void mixedScripts(); private: int m_testFontId; @@ -399,7 +400,7 @@ void tst_QGlyphRun::setRawDataAndGetAsVector() void tst_QGlyphRun::drawNonExistentGlyphs() { QVector glyphIndexes; - glyphIndexes.append(3); + glyphIndexes.append(4); QVector glyphPositions; glyphPositions.append(QPointF(0, 0)); @@ -725,6 +726,23 @@ void tst_QGlyphRun::boundingRect() QCOMPARE(glyphs.boundingRect(), boundingRect); } +void tst_QGlyphRun::mixedScripts() +{ + QString s; + s += QChar(0x31); // The character '1' + s += QChar(0xbc14); // Hangul character + + QTextLayout layout; + layout.setFont(m_testFont); + layout.setText(s); + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QList glyphRuns = layout.glyphRuns(); + QCOMPARE(glyphRuns.size(), 2); +} + #endif // QT_NO_RAWFONT QTEST_MAIN(tst_QGlyphRun) diff --git a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp index 74eb58670b..5dfb025510 100644 --- a/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp +++ b/tests/auto/gui/text/qtextscriptengine/tst_qtextscriptengine.cpp @@ -1258,21 +1258,29 @@ void tst_QTextScriptEngine::thaiWithZWJ() QTextLayout layout(s, font); QTextEngine *e = layout.engine(); e->itemize(); - QCOMPARE(e->layoutData->items.size(), 3); + QCOMPARE(e->layoutData->items.size(), 11); for (int item = 0; item < e->layoutData->items.size(); ++item) e->shape(item); - QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(15)); // Thai: The ZWJ and ZWNJ characters are inherited, so should be part of the thai script - QCOMPARE(e->layoutData->items[1].num_glyphs, ushort(1)); // Han: Kanji for tree - QCOMPARE(e->layoutData->items[2].num_glyphs, ushort(2)); // Thai: Thai character followed by superscript "a" which is of inherited type + QCOMPARE(e->layoutData->items[0].num_glyphs, ushort(7)); // Thai: The ZWJ and ZWNJ characters are inherited, so should be part of the thai script + QCOMPARE(e->layoutData->items[1].num_glyphs, ushort(1)); // Common: The smart quotes cannot be handled by thai, so should be a separate item + QCOMPARE(e->layoutData->items[2].num_glyphs, ushort(1)); // Thai: Thai character + QCOMPARE(e->layoutData->items[3].num_glyphs, ushort(1)); // Common: Ellipsis + QCOMPARE(e->layoutData->items[4].num_glyphs, ushort(1)); // Thai: Thai character + QCOMPARE(e->layoutData->items[5].num_glyphs, ushort(1)); // Common: Smart quote + QCOMPARE(e->layoutData->items[6].num_glyphs, ushort(1)); // Thai: Thai character + QCOMPARE(e->layoutData->items[7].num_glyphs, ushort(1)); // Common: \xA0 = non-breaking space. Could be useful to have in thai, but not currently implemented + QCOMPARE(e->layoutData->items[8].num_glyphs, ushort(1)); // Thai: Thai character + QCOMPARE(e->layoutData->items[9].num_glyphs, ushort(1)); // Japanese: Kanji for tree + QCOMPARE(e->layoutData->items[10].num_glyphs, ushort(2)); // Thai: Thai character followed by superscript "a" which is of inherited type //A quick sanity check - check all the characters are individual clusters unsigned short *logClusters = e->layoutData->logClustersPtr; - for (int i = 0; i <= 14; i++) + for (int i = 0; i < 7; i++) QCOMPARE(logClusters[i], ushort(i)); - QCOMPARE(logClusters[15], ushort(0)); - QCOMPARE(logClusters[16], ushort(0)); + for (int i = 0; i < 10; i++) + QCOMPARE(logClusters[i+7], ushort(0)); #ifndef Q_OS_MAC // ### Result differs for HarfBuzz-NG QCOMPARE(logClusters[17], ushort(1)); -- cgit v1.2.3 From 9c3a58a913a7e59359146264ee59d40d703d4db2 Mon Sep 17 00:00:00 2001 From: Dyami Caliri Date: Wed, 27 Aug 2014 09:27:50 -0700 Subject: Recreate child windows when changing screens When setting a new screen, the code calls QWindow::destroy(), which recursively destroys all child windows. It then calls create() on the top-level window, leaving child windows destroyed. This causes crashes if you have embedded native widgets. Task-number: QTBUG-40817 Change-Id: Iaace2589f48bbfd5faaf5ff95357ff43b310504a Reviewed-by: Shawn Rutledge Reviewed-by: Laszlo Agocs --- .../kernel/qwidget_window/qwidget_window.pro | 2 +- .../kernel/qwidget_window/tst_qwidget_window.cpp | 37 ++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) mode change 100644 => 100755 tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro mode change 100644 => 100755 tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp (limited to 'tests') diff --git a/tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro b/tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro old mode 100644 new mode 100755 index baa2823f9a..d61681d5cb --- a/tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro +++ b/tests/auto/widgets/kernel/qwidget_window/qwidget_window.pro @@ -1,7 +1,7 @@ CONFIG += testcase CONFIG += parallel_test TARGET = tst_qwidget_window -QT += widgets testlib +QT += widgets testlib core-private gui-private SOURCES += tst_qwidget_window.cpp x11 { diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp old mode 100644 new mode 100755 index d6b7fc20ed..87e1c7a4f3 --- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp +++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp @@ -52,6 +52,9 @@ #include #include #include +#include +#include +#include static inline void setFrameless(QWidget *w) { @@ -96,6 +99,8 @@ private slots: #endif void tst_qtbug35600(); + void tst_recreateWindow_QTBUG40817(); + }; void tst_QWidget_window::initTestCase() @@ -598,5 +603,37 @@ void tst_QWidget_window::tst_qtbug35600() // QTBUG-35600: program may crash here or on exit } +void tst_QWidget_window::tst_recreateWindow_QTBUG40817() +{ + QTabWidget tab; + + QWidget *w = new QWidget; + tab.addTab(w, "Tab1"); + QVBoxLayout *vl = new QVBoxLayout(w); + QLabel *lbl = new QLabel("HELLO1"); + lbl->setObjectName("label1"); + vl->addWidget(lbl); + w = new QWidget; + tab.addTab(w, "Tab2"); + vl = new QVBoxLayout(w); + lbl = new QLabel("HELLO2"); + lbl->setAttribute(Qt::WA_NativeWindow); + lbl->setObjectName("label2"); + vl->addWidget(lbl); + + tab.show(); + + QVERIFY(QTest::qWaitForWindowExposed(&tab)); + + QWindow *win = tab.windowHandle(); + win->destroy(); + QWindowPrivate *p = qt_window_private(win); + p->create(true); + win->show(); + + tab.setCurrentIndex(1); +} + + QTEST_MAIN(tst_QWidget_window) #include "tst_qwidget_window.moc" -- cgit v1.2.3 From eb447679456336d387bb69a56c164b06fbe83166 Mon Sep 17 00:00:00 2001 From: Kevin Funk Date: Thu, 28 Aug 2014 15:46:03 +0200 Subject: Fix crash in QTextLayout::cursorToX When 'cursorPos' is out of bounds ([0, lineEnd]), this method crashed. Change-Id: Ia0540ab3afbffb5c598f7b8515263cce3b3928e4 Task-number: QTBUG-40753 Reviewed-by: Dominik Haumann Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Konstantin Ritt --- .../auto/gui/text/qtextlayout/tst_qtextlayout.cpp | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'tests') diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp index ec698e5db4..e49d8c3b07 100644 --- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp @@ -86,6 +86,7 @@ private slots: void cursorToXForSetColumns(); void cursorToXForTrailingSpaces_data(); void cursorToXForTrailingSpaces(); + void cursorToXInvalidInput(); void horizontalAlignment_data(); void horizontalAlignment(); void horizontalAlignmentMultiline_data(); @@ -674,6 +675,28 @@ void tst_QTextLayout::cursorToXForTrailingSpaces() QCOMPARE(line.cursorToX(6), cursorAt6); } +void tst_QTextLayout::cursorToXInvalidInput() +{ + QTextLayout layout("aaa", testFont); + + layout.beginLayout(); + QTextLine line = layout.createLine(); + line.setLineWidth(5); + layout.endLayout(); + + int cursorPos; + + cursorPos = 0; + layout.lineAt(0).cursorToX(&cursorPos); + QCOMPARE(cursorPos, 0); + cursorPos = -300; + layout.lineAt(0).cursorToX(&cursorPos); + QCOMPARE(cursorPos, 0); + cursorPos = 300; + layout.lineAt(0).cursorToX(&cursorPos); + QCOMPARE(cursorPos, 3); +} + void tst_QTextLayout::horizontalAlignment_data() { qreal width = TESTFONT_SIZE * 4; -- cgit v1.2.3 From 983dde1f2f3db76ab26e949d8c2f4f8b968b36be Mon Sep 17 00:00:00 2001 From: Thomas Fischer Date: Sun, 24 Aug 2014 14:01:26 +0200 Subject: Avoid adding widget to its own layout Widgets and layouts added or inserted to a layout are checked for: - Not being NULL - Not being the parent widget of a layout or the layout itself, respectively Without this commit, adding a widget to its own layout would result in a CPU-hogging infinite loop. Now, a warning is written to stderr and the add or insert function call is ignored. The checks are implemented as public functions of QLayoutPrivate and thus accessible in QLayout's descendants to be used in various "addWidget", "insertWidget", etc functions. Unlike 'classical' layouts like QGridLayout, QFormLayout does indeed accept widgets that are NULL. To not break this behavior, any call for the check functions first tests if the widget or layout, respectively, to test is NULL or not and calls the check only in the latter case. Automated tests for QBoxLayout, QGridLayout, and QFormLayout were added. For an unpatched Qt 5.3, each of those automated tests will freeze as explained in QTBUG-40609. For a fixed version, warning messages about invalid parameters to addWidget/addLayout/... calls will be read by QTest::ignoreMessage, resulting in a passed test. Change-Id: I1522d5727e643da3f7c025755975aca9f482676d Task-number: QTBUG-40609 Reviewed-by: Marc Mutz --- .../widgets/kernel/qboxlayout/tst_qboxlayout.cpp | 32 ++++++++++++++++++++++ .../widgets/kernel/qformlayout/tst_qformlayout.cpp | 24 ++++++++++++++++ .../widgets/kernel/qgridlayout/tst_qgridlayout.cpp | 32 ++++++++++++++++++++++ tests/manual/qlayout/gridwidget.cpp | 8 ++++++ tests/manual/qlayout/hbwidget.cpp | 8 ++++++ tests/manual/qlayout/vbwidget.cpp | 8 ++++++ 6 files changed, 112 insertions(+) (limited to 'tests') diff --git a/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp b/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp index 850bedd9cc..4167d633b0 100644 --- a/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp +++ b/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp @@ -79,6 +79,8 @@ private slots: void taskQTBUG_7103_minMaxWidthNotRespected(); void taskQTBUG_27420_takeAtShouldUnparentLayout(); + void taskQTBUG_40609_addingWidgetToItsOwnLayout(); + void taskQTBUG_40609_addingLayoutToItself(); void replaceWidget(); }; @@ -329,6 +331,36 @@ void tst_QBoxLayout::taskQTBUG_27420_takeAtShouldUnparentLayout() QVERIFY(!inner.isNull()); } +void tst_QBoxLayout::taskQTBUG_40609_addingWidgetToItsOwnLayout(){ + QWidget widget; + widget.setObjectName("347b469225a24a0ef05150a"); + QVBoxLayout layout(&widget); + layout.setObjectName("ef9e2b42298e0e6420105bb"); + + QTest::ignoreMessage(QtWarningMsg, "QLayout: Cannot add a null widget to QVBoxLayout/ef9e2b42298e0e6420105bb"); + layout.addWidget(Q_NULLPTR); + QCOMPARE(layout.count(), 0); + + QTest::ignoreMessage(QtWarningMsg, "QLayout: Cannot add parent widget QWidget/347b469225a24a0ef05150a to its child layout QVBoxLayout/ef9e2b42298e0e6420105bb"); + layout.addWidget(&widget); + QCOMPARE(layout.count(), 0); +} + +void tst_QBoxLayout::taskQTBUG_40609_addingLayoutToItself(){ + QWidget widget; + widget.setObjectName("fe44e5cb6c08006597126a"); + QVBoxLayout layout(&widget); + layout.setObjectName("cc751dd0f50f62b05a62da"); + + QTest::ignoreMessage(QtWarningMsg, "QLayout: Cannot add a null layout to QVBoxLayout/cc751dd0f50f62b05a62da"); + layout.addLayout(Q_NULLPTR); + QCOMPARE(layout.count(), 0); + + QTest::ignoreMessage(QtWarningMsg, "QLayout: Cannot add layout QVBoxLayout/cc751dd0f50f62b05a62da to itself"); + layout.addLayout(&layout); + QCOMPARE(layout.count(), 0); +} + struct Descr { Descr(int min, int sh, int max = -1, bool exp= false, int _stretch = 0, bool _empty = false) diff --git a/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp b/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp index 9df7e1662d..962e472606 100644 --- a/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp +++ b/tests/auto/widgets/kernel/qformlayout/tst_qformlayout.cpp @@ -135,6 +135,8 @@ private slots: */ void taskQTBUG_27420_takeAtShouldUnparentLayout(); + void taskQTBUG_40609_addingWidgetToItsOwnLayout(); + void taskQTBUG_40609_addingLayoutToItself(); }; @@ -949,6 +951,28 @@ void tst_QFormLayout::taskQTBUG_27420_takeAtShouldUnparentLayout() QVERIFY(!inner.isNull()); } +void tst_QFormLayout::taskQTBUG_40609_addingWidgetToItsOwnLayout(){ + QWidget widget; + widget.setObjectName("6435cbada60548b4522cbb6"); + QFormLayout layout(&widget); + layout.setObjectName("c03c0e22c0b6d019a93a248"); + + QTest::ignoreMessage(QtWarningMsg, "QLayout: Cannot add parent widget QWidget/6435cbada60548b4522cbb6 to its child layout QFormLayout/c03c0e22c0b6d019a93a248"); + layout.addRow(QLatin1String("48c81f39b7320082f8"), &widget); + QCOMPARE(layout.count(), 0); +} + +void tst_QFormLayout::taskQTBUG_40609_addingLayoutToItself(){ + QWidget widget; + widget.setObjectName("2bc425637d084c07ce65956"); + QFormLayout layout(&widget); + layout.setObjectName("60e31de0c8800eaba713a4f2"); + + QTest::ignoreMessage(QtWarningMsg, "QLayout: Cannot add layout QFormLayout/60e31de0c8800eaba713a4f2 to itself"); + layout.addRow(QLatin1String("9a2cd4f40c06b489f889"), &layout); + QCOMPARE(layout.count(), 0); +} + void tst_QFormLayout::replaceWidget() { QWidget w; diff --git a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp index 3b7c2ac14d..0dcae2fbcc 100644 --- a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp +++ b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp @@ -101,6 +101,8 @@ private slots: void distributeMultiCell(); void taskQTBUG_27420_takeAtShouldUnparentLayout(); + void taskQTBUG_40609_addingWidgetToItsOwnLayout(); + void taskQTBUG_40609_addingLayoutToItself(); void replaceWidget(); private: @@ -1660,6 +1662,36 @@ void tst_QGridLayout::taskQTBUG_27420_takeAtShouldUnparentLayout() QVERIFY(!inner.isNull()); } +void tst_QGridLayout::taskQTBUG_40609_addingWidgetToItsOwnLayout(){ + QWidget widget; + widget.setObjectName("9bb37ca762aeb7269b8"); + QGridLayout layout(&widget); + layout.setObjectName("d631e91a35f2b66a6dff35"); + + QTest::ignoreMessage(QtWarningMsg, "QLayout: Cannot add a null widget to QGridLayout/d631e91a35f2b66a6dff35"); + layout.addWidget(Q_NULLPTR, 0, 0); + QCOMPARE(layout.count(), 0); + + QTest::ignoreMessage(QtWarningMsg, "QLayout: Cannot add parent widget QWidget/9bb37ca762aeb7269b8 to its child layout QGridLayout/d631e91a35f2b66a6dff35"); + layout.addWidget(&widget, 0, 0); + QCOMPARE(layout.count(), 0); +} + +void tst_QGridLayout::taskQTBUG_40609_addingLayoutToItself(){ + QWidget widget; + widget.setObjectName("0373d417fffe2c59c6fe543"); + QGridLayout layout(&widget); + layout.setObjectName("5d79e1b0aed83f100e3c2"); + + QTest::ignoreMessage(QtWarningMsg, "QLayout: Cannot add a null layout to QGridLayout/5d79e1b0aed83f100e3c2"); + layout.addLayout(Q_NULLPTR, 0, 0); + QCOMPARE(layout.count(), 0); + + QTest::ignoreMessage(QtWarningMsg, "QLayout: Cannot add layout QGridLayout/5d79e1b0aed83f100e3c2 to itself"); + layout.addLayout(&layout, 0, 0); + QCOMPARE(layout.count(), 0); +} + void tst_QGridLayout::replaceWidget() { QWidget wdg; diff --git a/tests/manual/qlayout/gridwidget.cpp b/tests/manual/qlayout/gridwidget.cpp index 31f0094182..6d7de3c763 100644 --- a/tests/manual/qlayout/gridwidget.cpp +++ b/tests/manual/qlayout/gridwidget.cpp @@ -53,6 +53,7 @@ GridWidget::GridWidget(QWidget *parent) : QWidget(parent) { QGridLayout *hb = new QGridLayout(this); + hb->setObjectName("GridWidget"); QComboBox *combo = new QComboBox(); combo->addItem("123"); QComboBox *combo2 = new QComboBox(); @@ -71,4 +72,11 @@ GridWidget::GridWidget(QWidget *parent) : hb->addWidget(new QPushButton("123"), 1, 4); hb->addWidget(new QSpinBox(), 0, 5); hb->addWidget(new QSpinBox(), 1, 5); + + qDebug("There should be four warnings, but no crash or freeze:"); + hb->addWidget(this, 6, 6); ///< This command should print a warning, but should not add "this" + hb->addWidget(Q_NULLPTR, 6, 7); ///< This command should print a warning, but should not add "NULL" + hb->addLayout(hb, 7, 6); ///< This command should print a warning, but should not add "hb" + hb->addLayout(Q_NULLPTR, 7, 7); ///< This command should print a warning, but should not add "NULL" + qDebug("Neither crashed nor frozen"); } diff --git a/tests/manual/qlayout/hbwidget.cpp b/tests/manual/qlayout/hbwidget.cpp index e8bb07f4a4..743b420b0d 100644 --- a/tests/manual/qlayout/hbwidget.cpp +++ b/tests/manual/qlayout/hbwidget.cpp @@ -53,6 +53,7 @@ HbWidget::HbWidget(QWidget *parent) : QWidget(parent) { QHBoxLayout *hb = new QHBoxLayout(this); + hb->setObjectName("HbWidget"); QComboBox *combo = new QComboBox(this); combo->addItem("123"); QComboBox *combo2 = new QComboBox(); @@ -67,4 +68,11 @@ HbWidget::HbWidget(QWidget *parent) : hb->addWidget(new QDateTimeEdit()); hb->addWidget(new QPushButton("123")); hb->addWidget(new QSpinBox()); + + qDebug("There should be four warnings, but no crash or freeze:"); + hb->addWidget(this); ///< This command should print a warning, but should not add "this" + hb->addWidget(Q_NULLPTR); ///< This command should print a warning, but should not add "NULL" + hb->addLayout(hb); ///< This command should print a warning, but should not add "hb" + hb->addLayout(Q_NULLPTR); ///< This command should print a warning, but should not add "NULL" + qDebug("Neither crashed nor frozen"); } diff --git a/tests/manual/qlayout/vbwidget.cpp b/tests/manual/qlayout/vbwidget.cpp index 063176625d..ffd918b955 100644 --- a/tests/manual/qlayout/vbwidget.cpp +++ b/tests/manual/qlayout/vbwidget.cpp @@ -53,6 +53,7 @@ VbWidget::VbWidget(QWidget *parent) : QWidget(parent) { QVBoxLayout *hb = new QVBoxLayout(this); + hb->setObjectName("VbWidget"); QComboBox *combo = new QComboBox(this); combo->addItem("123"); QComboBox *combo2 = new QComboBox(); @@ -67,4 +68,11 @@ VbWidget::VbWidget(QWidget *parent) : hb->addWidget(new QDateTimeEdit()); hb->addWidget(new QPushButton("123")); hb->addWidget(new QSpinBox()); + + qDebug("There should be four warnings, but no crash or freeze:"); + hb->addWidget(this); ///< This command should print a warning, but should not add "this" + hb->addWidget(Q_NULLPTR); ///< This command should print a warning, but should not add "NULL" + hb->addLayout(hb); ///< This command should print a warning, but should not add "hb" + hb->addLayout(Q_NULLPTR); ///< This command should print a warning, but should not add "NULL" + qDebug("Neither crashed nor frozen"); } -- cgit v1.2.3 From 3e804976687ce3dbe424ae5dfa47bba0a6280ce1 Mon Sep 17 00:00:00 2001 From: Eric Lemanissier Date: Mon, 1 Sep 2014 19:57:51 +0200 Subject: Preventing caching of null authenticator In some cases, e.g. when bad credentials are provided in an ftp URI, QNetworkAccessAuthenticationManager::cacheCredentials is called with a null authenticator. This authenticator should not be cached, because it is useless, and leads to inconsistencies in the use of the cache Task-number: QTBUG-40622 Change-Id: If2a0a422b915f268648f5eef1d68601446123371 Reviewed-by: Peter Hartmann --- .../access/qnetworkreply/tst_qnetworkreply.cpp | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'tests') diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 9988db74c7..70c118b681 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -219,6 +219,7 @@ private Q_SLOTS: void putToFile(); void putToFtp_data(); void putToFtp(); + void putToFtpWithInvalidCredentials(); // QTBUG-40622 void putToHttp_data(); void putToHttp(); void putToHttpSynchronous_data(); @@ -2075,6 +2076,28 @@ void tst_QNetworkReply::putToFtp() QObject::disconnect(r, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); } +void tst_QNetworkReply::putToFtpWithInvalidCredentials() +{ + QUrl url("ftp://" + QtNetworkSettings::serverName()); + url.setPath(QString("/qtest/upload/qnetworkaccess-putToFtp-%1-%2") + .arg(QTest::currentDataTag()) + .arg(uniqueExtension)); + url.setUserName("invalidUser"); + url.setPassword("InvalidPassword"); + QNetworkRequest req(url); + QNetworkReplyPtr r; + + for (int i = 0; i < 2; i++) + { + runSimpleRequest(QNetworkAccessManager::PutOperation, req, r, QByteArray()); + + QVERIFY(r->isFinished()); + QCOMPARE(r->url(), url); + QCOMPARE(r->error(), QNetworkReply::AuthenticationRequiredError); + r->close(); + } +} + void tst_QNetworkReply::putToHttp_data() { putToFile_data(); -- cgit v1.2.3 From b2b9fdfda0f7838059d7e826d81740977ef35a6e Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Mon, 15 Sep 2014 16:23:02 +0200 Subject: QSizeGrip: use a QPointer to the tracked TLW And not a normal pointer. The problem is that in certain scenarios, if the TLW containing a QSizeGrip changes and the old TLW gets immediately destroyed, then the mechanism which updates the tracked TLW is run too late, and ends up accessing a dangling pointer. Therefore, we need to protect that pointer via a smart pointer. Task-number: QTBUG-22867 Change-Id: Icfb051132bacde604f660ac7a98bc0a9d1022c68 Reviewed-by: Marc Mutz --- .../widgets/widgets/qsizegrip/tst_qsizegrip.cpp | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'tests') diff --git a/tests/auto/widgets/widgets/qsizegrip/tst_qsizegrip.cpp b/tests/auto/widgets/widgets/qsizegrip/tst_qsizegrip.cpp index f88cd634de..2600348998 100644 --- a/tests/auto/widgets/widgets/qsizegrip/tst_qsizegrip.cpp +++ b/tests/auto/widgets/widgets/qsizegrip/tst_qsizegrip.cpp @@ -46,6 +46,10 @@ #include #include #include +#include +#include +#include +#include static inline Qt::Corner sizeGripCorner(QWidget *parent, QSizeGrip *sizeGrip) { @@ -75,6 +79,7 @@ private slots: void hideAndShowOnWindowStateChange_data(); void hideAndShowOnWindowStateChange(); void orientation(); + void dontCrashOnTLWChange(); private: QLineEdit *dummyWidget; @@ -191,6 +196,26 @@ void tst_QSizeGrip::orientation() QCOMPARE(sizeGripCorner(&widget, sizeGrip), Qt::TopRightCorner); } +void tst_QSizeGrip::dontCrashOnTLWChange() +{ + // QTBUG-22867 + QMdiArea mdiArea; + mdiArea.show(); + + QMainWindow *mw = new QMainWindow(); + QMdiSubWindow *mdi = mdiArea.addSubWindow(mw); + mw->statusBar()->setSizeGripEnabled(true); + mdiArea.removeSubWindow(mw); + delete mdi; + mw->show(); + + // the above setup causes a change of TLW for the size grip, + // and it must not crash. + + QVERIFY(QTest::qWaitForWindowExposed(&mdiArea)); + QVERIFY(QTest::qWaitForWindowExposed(mw)); +} + QTEST_MAIN(tst_QSizeGrip) #include "tst_qsizegrip.moc" -- cgit v1.2.3 From bb3d2ca9f18071537888622310ca0cb7f587e61d Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Tue, 16 Sep 2014 16:33:57 +0200 Subject: QToolButton: properly reset the size hint when a menu is set on it QToolButton::sizeHint() takes into account the presence of a menu. However, setMenu() doesn't retrigger a size hint recalculation. Hence, (un)setting a menu on an already sized tool button won't properly reset the size hint. Since the calculated size hint is cached, delete the cached value and call updateGeometry to cause a recalculation. Task-number: QTBUG-38949 Change-Id: I6e79e5e70e31afdfd129282b3668875eca86f51d Reviewed-by: Marc Mutz --- .../widgets/qtoolbutton/tst_qtoolbutton.cpp | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'tests') diff --git a/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp b/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp index 168a17773e..650f189309 100644 --- a/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp +++ b/tests/auto/widgets/widgets/qtoolbutton/tst_qtoolbutton.cpp @@ -66,6 +66,7 @@ private slots: void task230994_iconSize(); void task176137_autoRepeatOfAction(); void qtbug_26956_popupTimerDone(); + void qtbug_34759_sizeHintResetWhenSettingMenu(); protected slots: void sendMouseClick(); @@ -265,5 +266,32 @@ void tst_QToolButton::qtbug_26956_popupTimerDone() tb->showMenu(); } +void tst_QToolButton::qtbug_34759_sizeHintResetWhenSettingMenu() +{ + // There is no reliable way of checking what's ultimately a style-dependent + // sizing. So the idea is checking if the size is the "correct" size w.r.t. + // another toolbutton which has had a menu set before it was shown for the first time + + QToolButton button1; + QToolButton button2; + + button1.setToolButtonStyle(Qt::ToolButtonIconOnly); + button1.setPopupMode(QToolButton::MenuButtonPopup); + + button2.setToolButtonStyle(Qt::ToolButtonIconOnly); + button2.setPopupMode(QToolButton::MenuButtonPopup); + + button2.setMenu(new QMenu(&button2)); + + button1.show(); + button2.show(); + + QVERIFY(QTest::qWaitForWindowExposed(&button1)); + QVERIFY(QTest::qWaitForWindowExposed(&button2)); + + button1.setMenu(new QMenu(&button1)); + QTRY_COMPARE(button1.sizeHint(), button2.sizeHint()); +} + QTEST_MAIN(tst_QToolButton) #include "tst_qtoolbutton.moc" -- cgit v1.2.3