diff options
Diffstat (limited to 'tests')
24 files changed, 717 insertions, 88 deletions
diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index ca58b664a0..2c02fb2264 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -4684,6 +4684,12 @@ void tst_QString::fromUcs4() s = QString::fromUcs4(U"\u221212\U000020AC\U00010000"); QCOMPARE(s, QString::fromUtf8("\342\210\222" "12" "\342\202\254" "\360\220\200\200")); #endif + + // QTBUG-62011: don't mistake ZWNBS for BOM + // Start with one BOM, to ensure we use the right endianness: + const uint text[] = { 0xfeff, 97, 0xfeff, 98, 0xfeff, 99, 0xfeff, 100 }; + s = QString::fromUcs4(text, 8); + QCOMPARE(s, QStringView(u"a\xfeff" u"b\xfeff" u"c\xfeff" "d")); } void tst_QString::toUcs4() diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp index 22d96e76f9..771a4d0a32 100644 --- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp @@ -45,6 +45,8 @@ #include <algorithm> +// #define DEBUG_WRITE_OUTPUT + typedef QMap<QString, QString> QStringMap; typedef QList<int> QIntList; Q_DECLARE_METATYPE(QImage::Format) @@ -462,24 +464,24 @@ void tst_QImageReader::setScaledClipRect_data() QTest::addColumn<QRect>("newRect"); QTest::addColumn<QByteArray>("format"); - QTest::newRow("BMP: colorful") << "colorful" << QRect(0, 0, 50, 50) << QByteArray("bmp"); - QTest::newRow("BMP: test32bfv4") << "test32bfv4" << QRect(0, 0, 50, 50) << QByteArray("bmp"); - QTest::newRow("BMP: test32v5") << "test32v5" << QRect(0, 0, 50, 50) << QByteArray("bmp"); - QTest::newRow("BMP: font") << "font" << QRect(0, 0, 50, 50) << QByteArray("bmp"); - QTest::newRow("XPM: marble") << "marble" << QRect(0, 0, 50, 50) << QByteArray("xpm"); - QTest::newRow("PNG: kollada") << "kollada" << QRect(0, 0, 50, 50) << QByteArray("png"); - QTest::newRow("PPM: teapot") << "teapot" << QRect(0, 0, 50, 50) << QByteArray("ppm"); - QTest::newRow("PPM: runners") << "runners.ppm" << QRect(0, 0, 50, 50) << QByteArray("ppm"); - QTest::newRow("PPM: test") << "test.ppm" << QRect(0, 0, 50, 50) << QByteArray("ppm"); - QTest::newRow("XBM: gnus") << "gnus" << QRect(0, 0, 50, 50) << QByteArray("xbm"); + QTest::newRow("BMP: colorful") << "colorful" << QRect(50, 20, 50, 50) << QByteArray("bmp"); + QTest::newRow("BMP: test32bfv4") << "test32bfv4" << QRect(50, 20, 50, 50) << QByteArray("bmp"); + QTest::newRow("BMP: test32v5") << "test32v5" << QRect(50, 20, 50, 50) << QByteArray("bmp"); + QTest::newRow("BMP: font") << "font" << QRect(50, 20, 50, 50) << QByteArray("bmp"); + QTest::newRow("XPM: marble") << "marble" << QRect(50, 20, 50, 50) << QByteArray("xpm"); + QTest::newRow("PNG: kollada") << "kollada" << QRect(50, 20, 50, 50) << QByteArray("png"); + QTest::newRow("PPM: teapot") << "teapot" << QRect(50, 20, 50, 50) << QByteArray("ppm"); + QTest::newRow("PPM: runners") << "runners.ppm" << QRect(50, 20, 50, 50) << QByteArray("ppm"); + QTest::newRow("PPM: test") << "test.ppm" << QRect(50, 20, 50, 50) << QByteArray("ppm"); + QTest::newRow("XBM: gnus") << "gnus" << QRect(50, 20, 50, 50) << QByteArray("xbm"); - QTest::newRow("JPEG: beavis") << "beavis" << QRect(0, 0, 50, 50) << QByteArray("jpeg"); + QTest::newRow("JPEG: beavis") << "beavis" << QRect(50, 20, 50, 50) << QByteArray("jpeg"); - QTest::newRow("GIF: earth") << "earth" << QRect(0, 0, 50, 50) << QByteArray("gif"); - QTest::newRow("GIF: trolltech") << "trolltech" << QRect(0, 0, 50, 50) << QByteArray("gif"); + QTest::newRow("GIF: earth") << "earth" << QRect(50, 20, 50, 50) << QByteArray("gif"); + QTest::newRow("GIF: trolltech") << "trolltech" << QRect(50, 20, 50, 50) << QByteArray("gif"); - QTest::newRow("SVG: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svg"); - QTest::newRow("SVGZ: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svgz"); + QTest::newRow("SVG: rect") << "rect" << QRect(50, 20, 50, 50) << QByteArray("svg"); + QTest::newRow("SVGZ: rect") << "rect" << QRect(50, 20, 50, 50) << QByteArray("svgz"); } void tst_QImageReader::setScaledClipRect() @@ -495,7 +497,11 @@ void tst_QImageReader::setScaledClipRect() reader.setScaledClipRect(newRect); QImage image = reader.read(); QVERIFY(!image.isNull()); - QCOMPARE(image.rect(), newRect); + QCOMPARE(image.rect().translated(50, 20), newRect); +#ifdef DEBUG_WRITE_OUTPUT + QString tempPath = QDir::temp().filePath(fileName) + QLatin1String(".png"); + image.save(tempPath); +#endif QImageReader originalReader(prefix + fileName); originalReader.setScaledSize(QSize(300, 300)); diff --git a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp index 191260fd41..549481aa21 100644 --- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp +++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp @@ -75,6 +75,8 @@ private slots: void nativeHandles(); void nativeTexture_data(); void nativeTexture(); + void nativeBuffer_data(); + void nativeBuffer(); void resourceUpdateBatchBuffer_data(); void resourceUpdateBatchBuffer(); void resourceUpdateBatchRGBATextureUpload_data(); @@ -294,7 +296,8 @@ void tst_QRhi::create() QRhi::BaseInstance, QRhi::TriangleFanTopology, QRhi::ReadBackNonUniformBuffer, - QRhi::ReadBackNonBaseMipLevel + QRhi::ReadBackNonBaseMipLevel, + QRhi::TexelFetch }; for (size_t i = 0; i <sizeof(features) / sizeof(QRhi::Feature); ++i) rhi->isFeatureSupported(features[i]); @@ -545,6 +548,86 @@ void tst_QRhi::nativeTexture() } } +void tst_QRhi::nativeBuffer_data() +{ + rhiTestData(); +} + +void tst_QRhi::nativeBuffer() +{ + QFETCH(QRhi::Implementation, impl); + QFETCH(QRhiInitParams *, initParams); + + QScopedPointer<QRhi> rhi(QRhi::create(impl, initParams, QRhi::Flags(), nullptr)); + if (!rhi) + QSKIP("QRhi could not be created, skipping testing native buffer query"); + + const QRhiBuffer::Type types[3] = { QRhiBuffer::Immutable, QRhiBuffer::Static, QRhiBuffer::Dynamic }; + const QRhiBuffer::UsageFlags usages[3] = { QRhiBuffer::VertexBuffer, QRhiBuffer::IndexBuffer, QRhiBuffer::UniformBuffer }; + for (int typeUsageIdx = 0; typeUsageIdx < 3; ++typeUsageIdx) { + QScopedPointer<QRhiBuffer> buf(rhi->newBuffer(types[typeUsageIdx], usages[typeUsageIdx], 256)); + QVERIFY(buf->build()); + + const QRhiBuffer::NativeBuffer nativeBuf = buf->nativeBuffer(); + QVERIFY(nativeBuf.slotCount <= rhi->resourceLimit(QRhi::FramesInFlight)); + + switch (impl) { + case QRhi::Null: + break; + #ifdef TST_VK + case QRhi::Vulkan: + { + QVERIFY(nativeBuf.slotCount >= 1); // always backed by native buffers + for (int i = 0; i < nativeBuf.slotCount; ++i) { + auto *buffer = static_cast<const VkBuffer *>(nativeBuf.objects[i]); + QVERIFY(buffer); + QVERIFY(*buffer); + } + } + break; + #endif + #ifdef TST_GL + case QRhi::OpenGLES2: + { + QVERIFY(nativeBuf.slotCount >= 0); // UniformBuffers are not backed by native buffers, so 0 is perfectly valid + for (int i = 0; i < nativeBuf.slotCount; ++i) { + auto *bufferId = static_cast<const uint *>(nativeBuf.objects[i]); + QVERIFY(bufferId); + QVERIFY(*bufferId); + } + } + break; + #endif + #ifdef TST_D3D11 + case QRhi::D3D11: + { + QVERIFY(nativeBuf.slotCount >= 1); // always backed by native buffers + for (int i = 0; i < nativeBuf.slotCount; ++i) { + auto *buffer = static_cast<void * const *>(nativeBuf.objects[i]); + QVERIFY(buffer); + QVERIFY(*buffer); + } + } + break; + #endif + #ifdef TST_MTL + case QRhi::Metal: + { + QVERIFY(nativeBuf.slotCount >= 1); // always backed by native buffers + for (int i = 0; i < nativeBuf.slotCount; ++i) { + void * const * buffer = (void * const *) nativeBuf.objects[i]; + QVERIFY(buffer); + QVERIFY(*buffer); + } + } + break; + #endif + default: + Q_ASSERT(false); + } + } +} + static bool submitResourceUpdates(QRhi *rhi, QRhiResourceUpdateBatch *batch) { QRhiCommandBuffer *cb = nullptr; @@ -1671,9 +1754,9 @@ void tst_QRhi::renderToWindowSimple() QVERIFY(pipeline->build()); - const int framesInFlight = rhi->resourceLimit(QRhi::FramesInFlight); - QVERIFY(framesInFlight >= 1); - const int FRAME_COUNT = framesInFlight + 1; + const int asyncReadbackFrames = rhi->resourceLimit(QRhi::MaxAsyncReadbackFrames); + // one frame issues the readback, then we do MaxAsyncReadbackFrames more to ensure the readback completes + const int FRAME_COUNT = asyncReadbackFrames + 1; bool readCompleted = false; QRhiReadbackResult readResult; QImage result; @@ -1720,8 +1803,8 @@ void tst_QRhi::renderToWindowSimple() } // The readback is asynchronous here. However it is guaranteed that it - // finished at latest after rendering QRhi::FramesInFlight frames after the - // one that enqueues the readback. + // finished at latest after rendering QRhi::MaxAsyncReadbackFrames frames + // after the one that enqueues the readback. QVERIFY(readCompleted); QVERIFY(readbackWidth > 0); diff --git a/tests/auto/gui/text/qfont/tst_qfont.cpp b/tests/auto/gui/text/qfont/tst_qfont.cpp index 9487436336..2d72eef459 100644 --- a/tests/auto/gui/text/qfont/tst_qfont.cpp +++ b/tests/auto/gui/text/qfont/tst_qfont.cpp @@ -314,27 +314,33 @@ void tst_QFont::resolve() void tst_QFont::resetFont() { QWidget parent; + QWidget firstChild(&parent); QFont parentFont = parent.font(); parentFont.setPointSize(parentFont.pointSize() + 2); parent.setFont(parentFont); - QWidget *child = new QWidget(&parent); - - QFont childFont = child->font(); + QFont childFont = firstChild.font(); childFont.setBold(!childFont.bold()); - child->setFont(childFont); + firstChild.setFont(childFont); + + QWidget secondChild(&parent); + secondChild.setFont(childFont); QVERIFY(parentFont.resolve() != 0); QVERIFY(childFont.resolve() != 0); QVERIFY(childFont != parentFont); - child->setFont(QFont()); // reset font + // reset font on both children + firstChild.setFont(QFont()); + secondChild.setFont(QFont()); - QCOMPARE(child->font().resolve(), uint(0)); + QCOMPARE(firstChild.font().resolve(), QFont::SizeResolved); + QCOMPARE(secondChild.font().resolve(), QFont::SizeResolved); #ifdef Q_OS_ANDROID QEXPECT_FAIL("", "QTBUG-69214", Continue); #endif - QCOMPARE(child->font().pointSize(), parent.font().pointSize()); + QCOMPARE(firstChild.font().pointSize(), parent.font().pointSize()); + QCOMPARE(secondChild.font().pointSize(), parent.font().pointSize()); QVERIFY(parent.font().resolve() != 0); } #endif diff --git a/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp b/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp index 59e93d127f..56df69dde8 100644 --- a/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp +++ b/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp @@ -198,6 +198,9 @@ private slots: void shouldGenerateDifferentCodeDependingOnActiveLayers(); void shouldUseGlobalVariableRatherThanTemporaries(); void shouldGenerateTemporariesWisely(); + void shouldHandlePortNamesPrefixingOneAnother(); + void shouldHandleNodesWithMultipleOutputPorts(); + void shouldHandleExpressionsInInputNodes(); }; void tst_QShaderGenerator::shouldHaveDefaultState() @@ -1229,6 +1232,196 @@ void tst_QShaderGenerator::shouldGenerateTemporariesWisely() } } +void tst_QShaderGenerator::shouldHandlePortNamesPrefixingOneAnother() +{ + // GIVEN + const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0); + + auto color1 = createNode({ + createPort(QShaderNodePort::Output, "output") + }); + color1.addRule(gl4, QShaderNode::Rule("vec4 $output = color1;", + QByteArrayList() << "in vec4 color1;")); + + auto color2 = createNode({ + createPort(QShaderNodePort::Output, "output") + }); + color2.addRule(gl4, QShaderNode::Rule("vec4 $output = color2;", + QByteArrayList() << "in vec4 color2;")); + + auto addColor = createNode({ + createPort(QShaderNodePort::Output, "color"), + createPort(QShaderNodePort::Input, "color1"), + createPort(QShaderNodePort::Input, "color2"), + }); + addColor.addRule(gl4, QShaderNode::Rule("vec4 $color = $color1 + $color2;")); + + auto shaderOutput = createNode({ + createPort(QShaderNodePort::Input, "input") + }); + + shaderOutput.addRule(gl4, QShaderNode::Rule("shaderOutput = $input;", + QByteArrayList() << "out vec4 shaderOutput;")); + + // WHEN + const auto graph = [=] { + auto res = QShaderGraph(); + + res.addNode(color1); + res.addNode(color2); + res.addNode(addColor); + res.addNode(shaderOutput); + + res.addEdge(createEdge(color1.uuid(), "output", addColor.uuid(), "color1")); + res.addEdge(createEdge(color2.uuid(), "output", addColor.uuid(), "color2")); + res.addEdge(createEdge(addColor.uuid(), "color", shaderOutput.uuid(), "input")); + + return res; + }(); + + auto generator = QShaderGenerator(); + generator.graph = graph; + generator.format = gl4; + + const auto code = generator.createShaderCode(); + + // THEN + const auto expected = QByteArrayList() + << "#version 400 core" + << "" + << "in vec4 color1;" + << "in vec4 color2;" + << "out vec4 shaderOutput;" + << "" + << "void main()" + << "{" + << " shaderOutput = ((color1 + color2));" + << "}" + << ""; + QCOMPARE(code, expected.join("\n")); +} + +void tst_QShaderGenerator::shouldHandleNodesWithMultipleOutputPorts() +{ + // GIVEN + const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0); + + auto input = createNode({ + createPort(QShaderNodePort::Output, "output0"), + createPort(QShaderNodePort::Output, "output1") + }); + input.addRule(gl4, QShaderNode::Rule("vec4 $output0 = globalIn0;" + "float $output1 = globalIn1;", + QByteArrayList() << "in vec4 globalIn0;" << "in float globalIn1;")); + + auto function = createNode({ + createPort(QShaderNodePort::Input, "input0"), + createPort(QShaderNodePort::Input, "input1"), + createPort(QShaderNodePort::Output, "output0"), + createPort(QShaderNodePort::Output, "output1") + }); + function.addRule(gl4, QShaderNode::Rule("vec4 $output0 = $input0;" + "float $output1 = $input1;")); + + auto output = createNode({ + createPort(QShaderNodePort::Input, "input0"), + createPort(QShaderNodePort::Input, "input1") + }); + + output.addRule(gl4, QShaderNode::Rule("globalOut0 = $input0;" + "globalOut1 = $input1;", + QByteArrayList() << "out vec4 globalOut0;" << "out float globalOut1;")); + + // WHEN + const auto graph = [=] { + auto res = QShaderGraph(); + + res.addNode(input); + res.addNode(function); + res.addNode(output); + + res.addEdge(createEdge(input.uuid(), "output0", function.uuid(), "input0")); + res.addEdge(createEdge(input.uuid(), "output1", function.uuid(), "input1")); + + res.addEdge(createEdge(function.uuid(), "output0", output.uuid(), "input0")); + res.addEdge(createEdge(function.uuid(), "output1", output.uuid(), "input1")); + + return res; + }(); + + auto generator = QShaderGenerator(); + generator.graph = graph; + generator.format = gl4; + + const auto code = generator.createShaderCode(); + + // THEN + const auto expected = QByteArrayList() + << "#version 400 core" + << "" + << "in vec4 globalIn0;" + << "in float globalIn1;" + << "out vec4 globalOut0;" + << "out float globalOut1;" + << "" + << "void main()" + << "{" + << " globalOut0 = globalIn0;" + << " globalOut1 = globalIn1;" + << "}" + << ""; + QCOMPARE(code, expected.join("\n")); +} + +void tst_QShaderGenerator::shouldHandleExpressionsInInputNodes() +{ + // GIVEN + const auto gl4 = createFormat(QShaderFormat::OpenGLCoreProfile, 4, 0); + + auto input = createNode({ + createPort(QShaderNodePort::Output, "output") + }); + input.addRule(gl4, QShaderNode::Rule("float $output = 3 + 4;")); + + auto output = createNode({ + createPort(QShaderNodePort::Input, "input") + }); + + output.addRule(gl4, QShaderNode::Rule("globalOut = $input;", + QByteArrayList() << "out float globalOut;")); + + // WHEN + const auto graph = [=] { + auto res = QShaderGraph(); + + res.addNode(input); + res.addNode(output); + + res.addEdge(createEdge(input.uuid(), "output", output.uuid(), "input")); + + return res; + }(); + + auto generator = QShaderGenerator(); + generator.graph = graph; + generator.format = gl4; + + const auto code = generator.createShaderCode(); + + // THEN + const auto expected = QByteArrayList() + << "#version 400 core" + << "" + << "out float globalOut;" + << "" + << "void main()" + << "{" + << " globalOut = 3 + 4;" + << "}" + << ""; + QCOMPARE(code, expected.join("\n")); +} + QTEST_MAIN(tst_QShaderGenerator) #include "tst_qshadergenerator.moc" diff --git a/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp b/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp index ce2d38c24f..014a163f58 100644 --- a/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp +++ b/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp @@ -114,6 +114,7 @@ private slots: void shouldSurviveCyclesDuringGraphSerialization(); void shouldDealWithEdgesJumpingOverLayers(); void shouldGenerateDifferentStatementsDependingOnActiveLayers(); + void shouldDealWithBranchesWithoutOutput(); }; void tst_QShaderGraph::shouldHaveEdgeDefaultState() @@ -515,12 +516,9 @@ void tst_QShaderGraph::shouldHandleUnboundPortsDuringGraphSerialization() const auto statements = graph.createStatements(); // THEN - // Note that no edge leads to the unbound input + // Note that no statement has any unbound input const auto expected = QVector<QShaderGraph::Statement>() - << createStatement(input, {}, {0}) - << createStatement(function, {-1, 0, -1}, {2, 3, 4}) - << createStatement(unboundOutput, {-1}, {}) - << createStatement(output, {3}, {}); + << createStatement(input, {}, {0}); dumpStatementsIfNeeded(statements, expected); QCOMPARE(statements, expected); } @@ -567,9 +565,8 @@ void tst_QShaderGraph::shouldSurviveCyclesDuringGraphSerialization() const auto statements = graph.createStatements(); // THEN - // Obviously will lead to a compile failure later on since it cuts everything beyond the cycle - const auto expected = QVector<QShaderGraph::Statement>() - << createStatement(output, {2}, {}); + // The cycle is ignored + const auto expected = QVector<QShaderGraph::Statement>(); dumpStatementsIfNeeded(statements, expected); QCOMPARE(statements, expected); } @@ -774,6 +771,50 @@ void tst_QShaderGraph::shouldGenerateDifferentStatementsDependingOnActiveLayers( } } +void tst_QShaderGraph::shouldDealWithBranchesWithoutOutput() +{ + // GIVEN + const auto input = createNode({ + createPort(QShaderNodePort::Output, "input") + }); + const auto output = createNode({ + createPort(QShaderNodePort::Input, "output") + }); + const auto danglingFunction = createNode({ + createPort(QShaderNodePort::Input, "functionInput"), + createPort(QShaderNodePort::Output, "unbound") + }); + const auto function = createNode({ + createPort(QShaderNodePort::Input, "functionInput"), + createPort(QShaderNodePort::Output, "functionOutput") + }); + + const auto graph = [=] { + auto res = QShaderGraph(); + res.addNode(input); + res.addNode(function); + res.addNode(danglingFunction); + res.addNode(output); + res.addEdge(createEdge(input.uuid(), "input", function.uuid(), "functionInput")); + res.addEdge(createEdge(input.uuid(), "input", danglingFunction.uuid(), "functionInput")); + res.addEdge(createEdge(function.uuid(), "functionOutput", output.uuid(), "output")); + return res; + }(); + + // WHEN + const auto statements = graph.createStatements(); + + // THEN + // Note that no edge leads to the unbound input + const auto expected = QVector<QShaderGraph::Statement>() + << createStatement(input, {}, {0}) + << createStatement(function, {0}, {1}) + << createStatement(output, {1}, {}) + << createStatement(danglingFunction, {0}, {2}); + dumpStatementsIfNeeded(statements, expected); + QCOMPARE(statements, expected); +} + QTEST_MAIN(tst_QShaderGraph) #include "tst_qshadergraph.moc" diff --git a/tests/auto/network-settings.h b/tests/auto/network-settings.h index 65d4bb5cea..641bf1d672 100644 --- a/tests/auto/network-settings.h +++ b/tests/auto/network-settings.h @@ -134,6 +134,22 @@ public: return true; } + static bool canBindToLowPorts() + { +#ifdef Q_OS_UNIX + if (geteuid() == 0) + return true; + if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave) + return true; + // ### Which versions of iOS, watchOS and such does Apple's opening of + // all ports apply to? + return false; +#else + // Windows + return true; +#endif + } + #ifdef QT_NETWORK_LIB static bool verifyTestNetworkSettings() diff --git a/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp b/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp index 1ef9382f0a..68c913ecfc 100644 --- a/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp +++ b/tests/auto/network/socket/platformsocketengine/tst_platformsocketengine.cpp @@ -529,18 +529,11 @@ void tst_PlatformSocketEngine::tooManySockets() //--------------------------------------------------------------------------- void tst_PlatformSocketEngine::bind() { -#if !defined Q_OS_WIN -#if defined Q_OS_MACOS - // On macOS >= 10.14 the bind on this port is successful. - if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSMojave) -#endif // Q_OS_MACOS - { - PLATFORMSOCKETENGINE binder; - QVERIFY(binder.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); - QVERIFY(!binder.bind(QHostAddress::AnyIPv4, 82)); + PLATFORMSOCKETENGINE binder; + QVERIFY(binder.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); + QCOMPARE(binder.bind(QHostAddress::AnyIPv4, 82), QtNetworkSettings::canBindToLowPorts()); + if (!QtNetworkSettings::canBindToLowPorts()) QCOMPARE(binder.error(), QAbstractSocket::SocketAccessError); - } -#endif // Q_OS_WIN PLATFORMSOCKETENGINE binder2; QVERIFY(binder2.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv4Protocol)); @@ -552,6 +545,12 @@ void tst_PlatformSocketEngine::bind() QCOMPARE(binder3.error(), QAbstractSocket::AddressInUseError); if (QtNetworkSettings::hasIPv6()) { + PLATFORMSOCKETENGINE binder; + QVERIFY(binder.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv6Protocol)); + QCOMPARE(binder.bind(QHostAddress::AnyIPv6, 82), QtNetworkSettings::canBindToLowPorts()); + if (!QtNetworkSettings::canBindToLowPorts()) + QCOMPARE(binder.error(), QAbstractSocket::SocketAccessError); + PLATFORMSOCKETENGINE binder4; QVERIFY(binder4.initialize(QAbstractSocket::TcpSocket, QAbstractSocket::IPv6Protocol)); QVERIFY(binder4.bind(QHostAddress::AnyIPv6, 31180)); diff --git a/tests/auto/network/socket/qtcpsocket/BLACKLIST b/tests/auto/network/socket/qtcpsocket/BLACKLIST index 07532710b3..129e9f0b4e 100644 --- a/tests/auto/network/socket/qtcpsocket/BLACKLIST +++ b/tests/auto/network/socket/qtcpsocket/BLACKLIST @@ -1,10 +1,3 @@ -[bind] -windows-10 msvc-2015 -windows-7sp1 -[bind:[::]] -windows -[bind:[::]:randomport] -windows [timeoutConnect:ip] windows # QTBUG-66247 diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index bf08d70eb3..099aa5fb51 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -523,7 +523,7 @@ void tst_QTcpSocket::bind_data() continue; // link-local bind will fail, at least on Linux, so skip it. QString ip(entry.ip().toString()); - QTest::newRow(ip.toLatin1().constData()) << ip << 0 << true << ip; + QTest::addRow("%s:0", ip.toLatin1().constData()) << ip << 0 << true << ip; if (!testIpv6 && entry.ip().protocol() == QAbstractSocket::IPv6Protocol) testIpv6 = true; @@ -531,9 +531,9 @@ void tst_QTcpSocket::bind_data() } // test binding to localhost - QTest::newRow("0.0.0.0") << "0.0.0.0" << 0 << true << "0.0.0.0"; + QTest::newRow("0.0.0.0:0") << "0.0.0.0" << 0 << true << "0.0.0.0"; if (testIpv6) - QTest::newRow("[::]") << "::" << 0 << true << "::"; + QTest::newRow("[::]:0") << "::" << 0 << true << "::"; // and binding with a port number... // Since we want to test that we got the port number we asked for, we need a random port number. @@ -551,26 +551,22 @@ void tst_QTcpSocket::bind_data() knownBad << "198.51.100.1"; knownBad << "2001:0DB8::1"; foreach (const QString &badAddress, knownBad) { - QTest::newRow(badAddress.toLatin1().constData()) << badAddress << 0 << false << QString(); + QTest::addRow("%s:0", badAddress.toLatin1().constData()) << badAddress << 0 << false << QString(); } -#ifdef Q_OS_UNIX // try to bind to a privileged ports // we should fail if we're not root (unless the ports are in use!) - QTest::newRow("127.0.0.1:1") << "127.0.0.1" << 1 << !geteuid() << (geteuid() ? QString() : "127.0.0.1"); - if (testIpv6) { #ifdef Q_OS_DARWIN - // This case is faling in different ways, first, it manages to bind to - // port 1 on macOS >= 10.14, but if we change the logic to not fail, - // it's becoming flaky and sometimes fails to bind, with error 'port in use' - // (apparently inflicted by the previous test row with 127.0.0.1). Amen. - if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave) - QTest::qWarn("Skipping [::]:1, see QTBUG-81905", __FILE__, __LINE__); - else + // Alas, some quirk (starting from macOS 10.14): bind with port number 1 + // fails with IPv4 (not IPv6 though, see below). + QTest::newRow("127.0.0.1:1") << "127.0.0.1" << 1 << false << QString(); +#else + QTest::newRow("127.0.0.1:1") << "127.0.0.1" << 1 << QtNetworkSettings::canBindToLowPorts() + << (QtNetworkSettings::canBindToLowPorts() ? "127.0.0.1" : QString()); #endif // Q_OS_DARWIN - QTest::newRow("[::]:1") << "::" << 1 << !geteuid() << (geteuid() ? QString() : "::"); - } -#endif + if (testIpv6) + QTest::newRow("[::]:1") << "::" << 1 << QtNetworkSettings::canBindToLowPorts() + << (QtNetworkSettings::canBindToLowPorts() ? "::" : QString()); } void tst_QTcpSocket::bind() @@ -589,13 +585,13 @@ void tst_QTcpSocket::bind() QTcpSocket dummySocket; // used only to "use up" a file descriptor dummySocket.bind(); - QTcpSocket *socket = newSocket(); + std::unique_ptr<QTcpSocket> socket(newSocket()); quint16 boundPort; qintptr fd; if (successExpected) { bool randomPort = port == -1; - int attemptsLeft = 5; // only used with randomPort + int attemptsLeft = 5; // only used with randomPort or Windows do { if (randomPort) { // try to get a random port number @@ -655,9 +651,24 @@ void tst_QTcpSocket::bind() QCOMPARE(acceptedSocket->peerPort(), boundPort); QCOMPARE(socket->localAddress(), remoteAddr); QCOMPARE(socket->socketDescriptor(), fd); +#ifdef Q_OS_DARWIN + // Normally, we don't see this problem: macOS sometimes does not + // allow us to immediately re-use a port, thinking connection is + // still alive. With fixed port 1 (we testing starting from + // macOS 10.14), this problem shows, making the test flaky: + // we run this 'bind' with port 1 several times (different + // test cases) and the problem manifests itself as + // "The bound address is already in use, tried port 1". + QTestEventLoop cleanupHelper; + auto client = socket.get(); + connect(client, &QTcpSocket::disconnected, [&cleanupHelper, client](){ + client->close(); + cleanupHelper.exitLoop(); + }); + acceptedSocket->close(); + cleanupHelper.enterLoopMSecs(100); +#endif // Q_OS_DARWIN } - - delete socket; } //---------------------------------------------------------------------------------- diff --git a/tests/auto/tools/moc/allmocs_baseline_in.json b/tests/auto/tools/moc/allmocs_baseline_in.json index 4f57fad5a8..9cc06dc7bc 100644 --- a/tests/auto/tools/moc/allmocs_baseline_in.json +++ b/tests/auto/tools/moc/allmocs_baseline_in.json @@ -3,6 +3,7 @@ "classes": [ { "className": "BackslashNewlines", + "object": true, "qualifiedClassName": "BackslashNewlines", "slots": [ { @@ -26,6 +27,7 @@ "classes": [ { "className": "IfdefedClass", + "object": true, "qualifiedClassName": "IfdefedClass", "superClasses": [ { @@ -239,6 +241,7 @@ "classes": [ { "className": "ExplicitOverrideControlBase", + "object": true, "qualifiedClassName": "ExplicitOverrideControlBase", "slots": [ { @@ -271,6 +274,7 @@ }, { "className": "ExplicitOverrideControlFinalQt", + "object": true, "qualifiedClassName": "ExplicitOverrideControlFinalQt", "slots": [ { @@ -303,6 +307,7 @@ }, { "className": "ExplicitOverrideControlFinalCxx11", + "object": true, "qualifiedClassName": "ExplicitOverrideControlFinalCxx11", "slots": [ { @@ -335,6 +340,7 @@ }, { "className": "ExplicitOverrideControlSealed", + "object": true, "qualifiedClassName": "ExplicitOverrideControlSealed", "slots": [ { @@ -367,6 +373,7 @@ }, { "className": "ExplicitOverrideControlOverrideQt", + "object": true, "qualifiedClassName": "ExplicitOverrideControlOverrideQt", "slots": [ { @@ -399,6 +406,7 @@ }, { "className": "ExplicitOverrideControlOverrideCxx11", + "object": true, "qualifiedClassName": "ExplicitOverrideControlOverrideCxx11", "slots": [ { @@ -431,6 +439,7 @@ }, { "className": "ExplicitOverrideControlFinalQtOverrideQt", + "object": true, "qualifiedClassName": "ExplicitOverrideControlFinalQtOverrideQt", "slots": [ { @@ -463,6 +472,7 @@ }, { "className": "ExplicitOverrideControlFinalCxx11OverrideCxx11", + "object": true, "qualifiedClassName": "ExplicitOverrideControlFinalCxx11OverrideCxx11", "slots": [ { @@ -495,6 +505,7 @@ }, { "className": "ExplicitOverrideControlSealedOverride", + "object": true, "qualifiedClassName": "ExplicitOverrideControlSealedOverride", "slots": [ { @@ -533,6 +544,7 @@ "classes": [ { "className": "FinalTestClassQt", + "object": true, "qualifiedClassName": "FinalTestClassQt", "superClasses": [ { @@ -543,6 +555,7 @@ }, { "className": "ExportedFinalTestClassQt", + "object": true, "qualifiedClassName": "ExportedFinalTestClassQt", "superClasses": [ { @@ -553,6 +566,7 @@ }, { "className": "ExportedFinalTestClassQtX", + "object": true, "qualifiedClassName": "ExportedFinalTestClassQtX", "superClasses": [ { @@ -563,6 +577,7 @@ }, { "className": "FinalTestClassCpp11", + "object": true, "qualifiedClassName": "FinalTestClassCpp11", "superClasses": [ { @@ -573,6 +588,7 @@ }, { "className": "ExportedFinalTestClassCpp11", + "object": true, "qualifiedClassName": "ExportedFinalTestClassCpp11", "superClasses": [ { @@ -583,6 +599,7 @@ }, { "className": "ExportedFinalTestClassCpp11X", + "object": true, "qualifiedClassName": "ExportedFinalTestClassCpp11X", "superClasses": [ { @@ -593,6 +610,7 @@ }, { "className": "SealedTestClass", + "object": true, "qualifiedClassName": "SealedTestClass", "superClasses": [ { @@ -603,6 +621,7 @@ }, { "className": "ExportedSealedTestClass", + "object": true, "qualifiedClassName": "ExportedSealedTestClass", "superClasses": [ { @@ -613,6 +632,7 @@ }, { "className": "ExportedSealedTestClassX", + "object": true, "qualifiedClassName": "ExportedSealedTestClassX", "superClasses": [ { @@ -654,7 +674,7 @@ ] } ], - "gadget": true, + "namespace": true, "qualifiedClassName": "CXX17Namespace::A::B::C::D" } ], @@ -673,6 +693,7 @@ } ] ], + "object": true, "qualifiedClassName": "DirInIncludePath", "superClasses": [ { @@ -707,6 +728,7 @@ } ], "className": "StringLiterals", + "object": true, "qualifiedClassName": "StringLiterals", "superClasses": [ { @@ -723,6 +745,7 @@ "classes": [ { "className": "ForwardDeclaredParamClass", + "object": true, "qualifiedClassName": "ForwardDeclaredParamClass", "signals": [ { @@ -923,6 +946,7 @@ "classes": [ { "className": "FunctionWithAttributes", + "object": true, "qualifiedClassName": "FunctionWithAttributes", "slots": [ { @@ -1016,6 +1040,7 @@ "classes": [ { "className": "TestFwdProperties", + "object": true, "properties": [ { "constant": false, @@ -1067,7 +1092,7 @@ }, { "className": "SomeRandomNamespace", - "gadget": true, + "namespace": true, "qualifiedClassName": "SomeRandomNamespace" } ], @@ -1089,7 +1114,7 @@ ] } ], - "gadget": true, + "namespace": true, "qualifiedClassName": "FooNamespace" }, { @@ -1114,7 +1139,7 @@ ] } ], - "gadget": true, + "namespace": true, "qualifiedClassName": "FooNamespace::FooNestedNamespace" }, { @@ -1130,7 +1155,7 @@ ] } ], - "gadget": true, + "namespace": true, "qualifiedClassName": "FooNamespace::FooNestedNamespace::FooMoreNestedNamespace" } ], @@ -1153,6 +1178,7 @@ ] } ], + "object": true, "properties": [ { "constant": false, @@ -1178,6 +1204,7 @@ }, { "className": "Baz", + "object": true, "properties": [ { "constant": false, @@ -1222,6 +1249,7 @@ "classes": [ { "className": "MyBooooooostishClass", + "object": true, "qualifiedClassName": "MyBooooooostishClass", "signals": [ { @@ -1269,6 +1297,7 @@ "classes": [ { "className": "OldStyleCast", + "object": true, "qualifiedClassName": "OldStyleCast", "slots": [ { @@ -1341,6 +1370,7 @@ } ], "className": "ParseDefine", + "object": true, "qualifiedClassName": "PD::ParseDefine", "signals": [ { @@ -1526,6 +1556,7 @@ "classes": [ { "className": "TestPluginMetaData", + "object": true, "qualifiedClassName": "TestPluginMetaData", "superClasses": [ { @@ -1542,6 +1573,7 @@ "classes": [ { "className": "PureVirtualSignalsTest", + "object": true, "qualifiedClassName": "PureVirtualSignalsTest", "signals": [ { @@ -1575,6 +1607,7 @@ }, { "className": "PureVirtualSignalsImpl", + "object": true, "qualifiedClassName": "PureVirtualSignalsImpl", "signals": [ { @@ -1616,6 +1649,7 @@ "returnType": "const char*" } ], + "object": true, "qualifiedClassName": "InvokableBeforeReturnType", "superClasses": [ { @@ -1638,6 +1672,7 @@ "returnType": "void" } ], + "object": true, "qualifiedClassName": "InvokableBeforeInline", "superClasses": [ { @@ -1661,6 +1696,7 @@ "returnType": "void" } ], + "object": true, "qualifiedClassName": "TestQPrivateSlots", "slots": [ { @@ -1705,6 +1741,7 @@ "classes": [ { "className": "B", + "object": true, "properties": [ { "constant": false, @@ -1745,6 +1782,7 @@ ] } ], + "object": true, "qualifiedClassName": "QTBUG_2151::A", "superClasses": [ { @@ -1755,6 +1793,7 @@ }, { "className": "B", + "object": true, "properties": [ { "constant": false, @@ -1810,6 +1849,7 @@ ] } ], + "object": true, "qualifiedClassName": "Unsused::Object", "superClasses": [ { @@ -1845,6 +1885,7 @@ ] } ], + "object": true, "qualifiedClassName": "NS1::Nested::Object", "superClasses": [ { @@ -1880,6 +1921,7 @@ ] } ], + "object": true, "qualifiedClassName": "NS1::NestedUnsused::Object", "superClasses": [ { @@ -1915,6 +1957,7 @@ ] } ], + "object": true, "qualifiedClassName": "NS1::Object", "superClasses": [ { @@ -1925,6 +1968,7 @@ }, { "className": "DependingObject", + "object": true, "properties": [ { "constant": false, @@ -1961,6 +2005,7 @@ }, { "className": "DependingNestedGadget", + "object": true, "properties": [ { "constant": false, @@ -1985,6 +2030,7 @@ }, { "className": "DependingNestedObject", + "object": true, "properties": [ { "constant": false, @@ -2034,6 +2080,7 @@ ] } ], + "object": true, "qualifiedClassName": "NS2::Nested::Object", "superClasses": [ { @@ -2069,6 +2116,7 @@ ] } ], + "object": true, "qualifiedClassName": "NS2::NestedUnsused::Object", "superClasses": [ { @@ -2104,6 +2152,7 @@ ] } ], + "object": true, "qualifiedClassName": "NS2::Object", "superClasses": [ { @@ -2114,6 +2163,7 @@ }, { "className": "DependingObject", + "object": true, "properties": [ { "constant": false, @@ -2150,6 +2200,7 @@ }, { "className": "DependingNestedGadget", + "object": true, "properties": [ { "constant": false, @@ -2174,6 +2225,7 @@ }, { "className": "DependingNestedObject", + "object": true, "properties": [ { "constant": false, @@ -2214,6 +2266,7 @@ ] } ], + "object": true, "qualifiedClassName": "KDAB", "superClasses": [ { @@ -2230,6 +2283,7 @@ "classes": [ { "className": "SingleFunctionKeywordBeforeReturnType", + "object": true, "qualifiedClassName": "SingleFunctionKeywordBeforeReturnType", "signals": [ { @@ -2254,6 +2308,7 @@ }, { "className": "SingleFunctionKeywordBeforeInline", + "object": true, "qualifiedClassName": "SingleFunctionKeywordBeforeInline", "signals": [ { @@ -2278,6 +2333,7 @@ }, { "className": "SingleFunctionKeywordAfterInline", + "object": true, "qualifiedClassName": "SingleFunctionKeywordAfterInline", "signals": [ { @@ -2308,6 +2364,7 @@ "classes": [ { "className": "SlotsWithVoidTemplateTest", + "object": true, "qualifiedClassName": "SlotsWithVoidTemplateTest", "signals": [ { @@ -2373,6 +2430,7 @@ "classes": [ { "className": "Task192552", + "object": true, "qualifiedClassName": "Task192552", "superClasses": [ { @@ -2389,6 +2447,7 @@ "classes": [ { "className": "TestObject", + "object": true, "qualifiedClassName": "NS_A::NS_B::TestObject", "superClasses": [ { @@ -2399,6 +2458,7 @@ }, { "className": "TestMain", + "object": true, "qualifiedClassName": "NS_A::NS_Main::TestMain", "superClasses": [ { @@ -2415,6 +2475,7 @@ "classes": [ { "className": "TypenameWithUnsigned", + "object": true, "qualifiedClassName": "TypenameWithUnsigned", "slots": [ { @@ -2564,6 +2625,7 @@ "classes": [ { "className": "Task87883", + "object": true, "qualifiedClassName": "Task87883", "superClasses": [ { @@ -2580,6 +2642,7 @@ "classes": [ { "className": "Foo", + "object": true, "qualifiedClassName": "BBB::Foo", "signals": [ { diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST b/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST index aae2cacc3b..d9d7786314 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST @@ -8,9 +8,5 @@ b2qt b2qt [dirsBeforeFiles] winrt -b2qt -ubuntu -windows-10 -rhel [drives] winrt diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 8396fd4ec7..7259fa1ab0 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -976,6 +976,7 @@ void tst_QTreeView::indexWidget() QStandardItemModel treeModel; initStandardTreeModel(&treeModel); view.setModel(&treeModel); + view.resize(300, 400); // make sure the width of the view is larger than the widgets below QModelIndex index = view.model()->index(0, 0); @@ -1004,6 +1005,7 @@ void tst_QTreeView::indexWidget() //now let's try to do that later when the widget is already shown view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); index = view.model()->index(1, 0); QVERIFY(!view.indexWidget(index)); diff --git a/tests/auto/widgets/kernel/qwidget/hellotr_la.qm b/tests/auto/widgets/kernel/qwidget/hellotr_la.qm Binary files differnew file mode 100644 index 0000000000..25c0aad583 --- /dev/null +++ b/tests/auto/widgets/kernel/qwidget/hellotr_la.qm diff --git a/tests/auto/widgets/kernel/qwidget/qwidget.qrc b/tests/auto/widgets/kernel/qwidget/qwidget.qrc index 1399c4c9db..597ea872a5 100644 --- a/tests/auto/widgets/kernel/qwidget/qwidget.qrc +++ b/tests/auto/widgets/kernel/qwidget/qwidget.qrc @@ -3,5 +3,6 @@ <file>geometry.dat</file> <file>geometry-maximized.dat</file> <file>geometry-fullscreen.dat</file> + <file>hellotr_la.qm</file> </qresource> </RCC> diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 9c16b1a00a..f0c490b598 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -162,8 +162,10 @@ private slots: void fontPropagation(); void fontPropagation2(); void fontPropagation3(); + void fontPropagationDynamic(); void palettePropagation(); void palettePropagation2(); + void palettePropagationDynamic(); void enabledPropagation(); void ignoreKeyEventsWhenDisabled_QTBUG27417(); void properTabHandlingWhenDisabled_QTBUG27417(); @@ -310,6 +312,8 @@ private slots: void hideOpaqueChildWhileHidden(); void updateWhileMinimized(); void alienWidgets(); + void nativeWindowPosition_data(); + void nativeWindowPosition(); void adjustSize(); void adjustSize_data(); void updateGeometry(); @@ -410,6 +414,7 @@ private slots: void closeWithChildWindow(); void winIdAfterClose(); + void receivesLanguageChangeEvent(); private: bool ensureScreenSize(int width, int height); @@ -828,6 +833,66 @@ void tst_QWidget::fontPropagation3() QCOMPARE(p.font().pointSize(), child->font().pointSize()); } +/*! + This tests that children that are added to a widget with an explicitly + defined font inherit that font correctly, merging (and overriding) + with the font that might be defined by the platform theme. +*/ +void tst_QWidget::fontPropagationDynamic() +{ + // override side effects from previous tests + QFont themedFont; + themedFont.setBold(true); + themedFont.setPointSize(42); + QApplication::setFont(themedFont, "QPropagationTestWidget"); + + QWidget parent; + QWidget firstChild(&parent); + + const QFont defaultFont = parent.font(); + QFont appFont = defaultFont; + appFont.setPointSize(72); + + // sanity check + QVERIFY(themedFont != defaultFont); + QVERIFY(themedFont != appFont); + + // palette propagates to existing children + parent.setFont(appFont); + QCOMPARE(firstChild.font().pointSize(), appFont.pointSize()); + + // palatte propagates to children added later + QWidget secondChild(&parent); + QCOMPARE(secondChild.font().pointSize(), appFont.pointSize()); + QWidget thirdChild; + QCOMPARE(thirdChild.font().pointSize(), defaultFont.pointSize()); + thirdChild.setParent(&parent); + QCOMPARE(thirdChild.font().pointSize(), appFont.pointSize()); + + // even if the child has an override in QApplication::font + QPropagationTestWidget themedChild; + themedChild.ensurePolished(); // needed for default font to be set up + QCOMPARE(themedChild.font().pointSize(), themedFont.pointSize()); + QCOMPARE(themedChild.font().bold(), themedFont.bold()); + themedChild.setParent(&parent); + QCOMPARE(themedChild.font().pointSize(), appFont.pointSize()); + QCOMPARE(themedChild.font().bold(), themedFont.bold()); + + // grand children as well + QPropagationTestWidget themedGrandChild; + themedGrandChild.setParent(&themedChild); + QCOMPARE(themedGrandChild.font().pointSize(), appFont.pointSize()); + QCOMPARE(themedGrandChild.font().bold(), themedFont.bold()); + + // child with own font attribute does not inherit from parent + QFont childFont = defaultFont; + childFont.setPointSize(9); + QWidget modifiedChild; + modifiedChild.setFont(childFont); + modifiedChild.setParent(&parent); + QCOMPARE(modifiedChild.font().pointSize(), childFont.pointSize()); +} + void tst_QWidget::palettePropagation() { QScopedPointer<QWidget> testWidget(new QWidget); @@ -872,8 +937,8 @@ void tst_QWidget::palettePropagation2() // ! Note, the code below is executed in tst_QWidget's constructor. // QPalette palette; - // font.setColor(QPalette::ToolTipBase, QColor(12, 13, 14)); - // font.setColor(QPalette::Text, QColor(21, 22, 23)); + // palette.setColor(QPalette::ToolTipBase, QColor(12, 13, 14)); + // palette.setColor(QPalette::Text, QColor(21, 22, 23)); // qApp->setPalette(palette, "QPropagationTestWidget"); QScopedPointer<QWidget> root(new QWidget); @@ -972,6 +1037,68 @@ void tst_QWidget::palettePropagation2() QCOMPARE(child5->palette().color(QPalette::ToolTipText), sysPalButton); } +/*! + This tests that children that are added to a widget with an explicitly + defined palette inherit that palette correctly, merging (and overriding) + with the palette that might be defined by the platform theme. +*/ +void tst_QWidget::palettePropagationDynamic() +{ + // override side effects from previous tests + QPalette themedPalette; + themedPalette.setColor(QPalette::ToolTipBase, QColor(12, 13, 14)); + themedPalette.setColor(QPalette::Text, QColor(21, 22, 23)); + QApplication::setPalette(themedPalette, "QPropagationTestWidget"); + + QWidget parent; + QWidget firstChild(&parent); + + const QPalette defaultPalette = parent.palette(); + QPalette appPalette = defaultPalette; + const QColor appColor(1, 2, 3); + appPalette.setColor(QPalette::Text, appColor); + + // sanity check + QVERIFY(themedPalette != defaultPalette); + QVERIFY(themedPalette != appPalette); + + // palette propagates to existing children + parent.setPalette(appPalette); + QCOMPARE(firstChild.palette().color(QPalette::Text), appPalette.color(QPalette::Text)); + + // palatte propagates to children added later + QWidget secondChild(&parent); + QCOMPARE(secondChild.palette().color(QPalette::Text), appPalette.color(QPalette::Text)); + QWidget thirdChild; + QCOMPARE(thirdChild.palette().color(QPalette::Text), defaultPalette.color(QPalette::Text)); + thirdChild.setParent(&parent); + QCOMPARE(thirdChild.palette().color(QPalette::Text), appPalette.color(QPalette::Text)); + + // even if the child has an override in QApplication::palette + QPropagationTestWidget themedChild; + themedChild.ensurePolished(); // needed for default palette to be set up + QCOMPARE(themedChild.palette().color(QPalette::Text), themedPalette.color(QPalette::Text)); + QCOMPARE(themedChild.palette().color(QPalette::ToolTipBase), themedPalette.color(QPalette::ToolTipBase)); + themedChild.setParent(&parent); + QCOMPARE(themedChild.palette().color(QPalette::Text), appPalette.color(QPalette::Text)); + QCOMPARE(themedChild.palette().color(QPalette::ToolTipBase), themedPalette.color(QPalette::ToolTipBase)); + + // grand children as well + QPropagationTestWidget themedGrandChild; + themedGrandChild.setParent(&themedChild); + QCOMPARE(themedGrandChild.palette().color(QPalette::Text), appPalette.color(QPalette::Text)); + QCOMPARE(themedGrandChild.palette().color(QPalette::ToolTipBase), themedPalette.color(QPalette::ToolTipBase)); + + // child with own color does not inherit from parent + QPalette childPalette = defaultPalette; + childPalette.setColor(QPalette::Text, Qt::red); + QWidget modifiedChild; + modifiedChild.setPalette(childPalette); + modifiedChild.setParent(&parent); + QCOMPARE(modifiedChild.palette().color(QPalette::Text), childPalette.color(QPalette::Text)); + +} + void tst_QWidget::enabledPropagation() { QScopedPointer<QWidget> testWidget(new QWidget); @@ -8210,6 +8337,40 @@ void tst_QWidget::alienWidgets() } } +using WidgetAttributes = QVector<Qt::WidgetAttribute>; + +void tst_QWidget::nativeWindowPosition_data() +{ + QTest::addColumn<WidgetAttributes>("attributes"); + + QTest::newRow("non-native all the way") + << WidgetAttributes{}; + QTest::newRow("native all the way") + << WidgetAttributes{ Qt::WA_NativeWindow }; + QTest::newRow("native with non-native ancestor") + << WidgetAttributes{ Qt::WA_NativeWindow, Qt::WA_DontCreateNativeAncestors }; +} + +void tst_QWidget::nativeWindowPosition() +{ + QWidget topLevel; + QWidget child(&topLevel); + child.move(5, 5); + + QWidget grandChild(&child); + grandChild.move(10, 10); + + QFETCH(WidgetAttributes, attributes); + for (auto attribute : attributes) + grandChild.setAttribute(attribute); + + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + + QCOMPARE(child.pos(), QPoint(5, 5)); + QCOMPARE(grandChild.pos(), QPoint(10, 10)); +} + class ASWidget : public QWidget { public: @@ -11360,5 +11521,55 @@ void tst_QWidget::winIdAfterClose() delete spy; } +class LanguageChangeEventWidget : public QWidget +{ +public: + LanguageChangeEventWidget(QWidget *parent = nullptr) : QWidget(parent) {} + int languageChangeCount = 0; +protected: + bool event(QEvent *e) override + { + if (e->type() == QEvent::LanguageChange) + languageChangeCount++; + return QWidget::event(e); + } +}; + +class LanguageChangeEventWindow : public QWindow +{ +public: + LanguageChangeEventWindow(QWindow *parent = nullptr) : QWindow(parent) {} + int languageChangeCount = 0; +protected: + bool event(QEvent *e) override + { + if (e->type() == QEvent::LanguageChange) + languageChangeCount++; + return QWindow::event(e); + } +}; + +void tst_QWidget::receivesLanguageChangeEvent() +{ + // Confirm that any QWindow or QWidget only gets a single + // LanguageChange event when a translator is installed + LanguageChangeEventWidget topLevel; + auto childWidget = new LanguageChangeEventWidget(&topLevel); + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + LanguageChangeEventWindow ww; + ww.show(); + QVERIFY(QTest::qWaitForWindowExposed(&ww)); + LanguageChangeEventWidget topLevelNotShown; + QTranslator t; + QVERIFY(t.load("hellotr_la.qm", ":/")); + QVERIFY(qApp->installTranslator(&t)); + QCoreApplication::sendPostedEvents(0, QEvent::LanguageChange); + QCOMPARE(topLevel.languageChangeCount, 1); + QCOMPARE(topLevelNotShown.languageChangeCount, 1); + QCOMPARE(childWidget->languageChangeCount, 1); + QCOMPARE(ww.languageChangeCount, 1); +} + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp index dd3e2f844b..f42e2d777b 100644 --- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp +++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp @@ -968,6 +968,7 @@ void tst_QWidget_window::tst_resize_count() { { ResizeWidget resize; + resize.setWindowFlags(Qt::X11BypassWindowManagerHint); resize.show(); QVERIFY(QTest::qWaitForWindowExposed(&resize)); #ifdef Q_OS_WINRT @@ -1000,6 +1001,7 @@ void tst_QWidget_window::tst_resize_count() } { ResizeWidget parent; + parent.setWindowFlag(Qt::X11BypassWindowManagerHint); ResizeWidget child(&parent); child.resize(m_testWidgetSize); child.winId(); diff --git a/tests/libfuzzer/gui/text/qtextdocument/setHtml/main.cpp b/tests/libfuzzer/gui/text/qtextdocument/sethtml/main.cpp index 51fa3c9e0f..51fa3c9e0f 100644 --- a/tests/libfuzzer/gui/text/qtextdocument/setHtml/main.cpp +++ b/tests/libfuzzer/gui/text/qtextdocument/sethtml/main.cpp diff --git a/tests/libfuzzer/gui/text/qtextdocument/setHtml/setHtml.pro b/tests/libfuzzer/gui/text/qtextdocument/sethtml/sethtml.pro index af5ef9e940..af5ef9e940 100644 --- a/tests/libfuzzer/gui/text/qtextdocument/setHtml/setHtml.pro +++ b/tests/libfuzzer/gui/text/qtextdocument/sethtml/sethtml.pro diff --git a/tests/libfuzzer/gui/text/qtextdocument/setMarkdown/main.cpp b/tests/libfuzzer/gui/text/qtextdocument/setmarkdown/main.cpp index 66ddf738f2..66ddf738f2 100644 --- a/tests/libfuzzer/gui/text/qtextdocument/setMarkdown/main.cpp +++ b/tests/libfuzzer/gui/text/qtextdocument/setmarkdown/main.cpp diff --git a/tests/libfuzzer/gui/text/qtextdocument/setMarkdown/setMarkdown.pro b/tests/libfuzzer/gui/text/qtextdocument/setmarkdown/setmarkdown.pro index 758622e1af..758622e1af 100644 --- a/tests/libfuzzer/gui/text/qtextdocument/setMarkdown/setMarkdown.pro +++ b/tests/libfuzzer/gui/text/qtextdocument/setmarkdown/setmarkdown.pro diff --git a/tests/libfuzzer/gui/text/qtextlayout/beginLayout/beginLayout.pro b/tests/libfuzzer/gui/text/qtextlayout/beginlayout/beginlayout.pro index af5ef9e940..af5ef9e940 100644 --- a/tests/libfuzzer/gui/text/qtextlayout/beginLayout/beginLayout.pro +++ b/tests/libfuzzer/gui/text/qtextlayout/beginlayout/beginlayout.pro diff --git a/tests/libfuzzer/gui/text/qtextlayout/beginLayout/main.cpp b/tests/libfuzzer/gui/text/qtextlayout/beginlayout/main.cpp index dfb9559241..dfb9559241 100644 --- a/tests/libfuzzer/gui/text/qtextlayout/beginLayout/main.cpp +++ b/tests/libfuzzer/gui/text/qtextlayout/beginlayout/main.cpp diff --git a/tests/manual/rhi/hellominimalcrossgfxtriangle/window.cpp b/tests/manual/rhi/hellominimalcrossgfxtriangle/window.cpp index f3f00e0255..fc7bdff3de 100644 --- a/tests/manual/rhi/hellominimalcrossgfxtriangle/window.cpp +++ b/tests/manual/rhi/hellominimalcrossgfxtriangle/window.cpp @@ -167,7 +167,7 @@ void Window::init() #if defined(Q_OS_MACOS) || defined(Q_OS_IOS) if (m_graphicsApi == QRhi::Metal) { QRhiMetalInitParams params; - m_rhi = QRhi::create(QRhi::Metal, ¶ms, rhiFlags); + m_rhi.reset(QRhi::create(QRhi::Metal, ¶ms, rhiFlags)); } #endif |