From 7232c852a6f778fc9b5223c617e3331a2b2716ae Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 14 Feb 2020 17:43:31 +0100 Subject: [PATCH 1/8] qmake: Fix handling of QM_FILES_INSTALL_PATH Do not expect the .qm files to be there at qmake time; they will only be generated at build time. Fixes: QTBUG-77398 Change-Id: If73fdb51d40138e52f62eaee0491a5d73d9fe161 Reviewed-by: Joerg Bornemann --- mkspecs/features/lrelease.prf | 1 + 1 file changed, 1 insertion(+) diff --git a/mkspecs/features/lrelease.prf b/mkspecs/features/lrelease.prf index 1e828b64df..f611c74184 100644 --- a/mkspecs/features/lrelease.prf +++ b/mkspecs/features/lrelease.prf @@ -35,6 +35,7 @@ embed_translations { !isEmpty(QM_FILES_INSTALL_PATH) { qm_files.files = $$QM_FILES qm_files.path = $$QM_FILES_INSTALL_PATH + qm_files.CONFIG = no_check_exist INSTALLS += qm_files } lrelease.CONFIG += target_predeps no_clean From d803534954ec14b850b4f5e73e227a44ac12f118 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 20 Dec 2019 15:43:39 +0100 Subject: [PATCH 2/8] Add 5.14.0 changelog entry about MinGW It's too late for 5.14.0 release, but still good to have it documented. Change-Id: I76f323d80bb878c779caec2622d5917f868f9fc0 Reviewed-by: Joerg Bornemann --- dist/changes-5.14.0 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dist/changes-5.14.0 b/dist/changes-5.14.0 index 77cbb70928..9069663715 100644 --- a/dist/changes-5.14.0 +++ b/dist/changes-5.14.0 @@ -476,6 +476,9 @@ information about a particular change. - MinGW: * [QTBUG-4155] Added a suffix to debug mode pkgconfig files. + * MinGW does not built with -debug-and-release mode anymore. + Instead, the binaries are built with -release -force-debug-info + -separate-debug-info. - macOS: * The drawableSize of Metal layers is no longer updated automatically on From ee73ec0c77dc040771d7f983df16e97ed5ac9cd3 Mon Sep 17 00:00:00 2001 From: Alexander Akulich Date: Fri, 7 Feb 2020 15:36:58 +0300 Subject: [PATCH 3/8] Fix a typo in QLocalSocket doc Change-Id: I3047cb24051c7f25d77d5b2b86ff145a52695107 Reviewed-by: Paul Wicking Reviewed-by: Timur Pocheptsov --- src/network/socket/qlocalsocket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/socket/qlocalsocket.cpp b/src/network/socket/qlocalsocket.cpp index af7cdb76d2..a392a8c75a 100644 --- a/src/network/socket/qlocalsocket.cpp +++ b/src/network/socket/qlocalsocket.cpp @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE On Windows this is a named pipe and on Unix this is a local domain socket. - If an error occurs, socketError() returns the type of error, and + If an error occurs, error() returns the type of error, and errorString() can be called to get a human readable description of what happened. From 379895798eb3db0af30c7db2da01c3f8e187446a Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 13 Feb 2020 12:06:14 +0100 Subject: [PATCH 4/8] QMacStyle - fix tab buttons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit not to have arrows under some conditions. NSPopUpButton had a needed color, except it also has arrow(s). Which looks quite confusing on an inactive window on a tab button. Fixes: QTBUG-82122 Change-Id: I40c57abe9ccae48fa906d592169c412f5f89f712 Reviewed-by: Tor Arne Vestbø (cherry picked from commit 0e643bf7830949ade66e76a6eefa99b4b24c422b) --- src/plugins/styles/mac/qmacstyle_mac.mm | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index ecdde06bb8..71eb88008e 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -3935,7 +3935,20 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter CGContextRotateCTM(ctx, M_PI_2); } + // Now, if it's a trick with a popup button, it has an arrow + // which makes no sense on tabs. + NSPopUpArrowPosition oldPosition = NSPopUpArrowAtCenter; + NSPopUpButtonCell *pbCell = nil; + if (isPopupButton) { + pbCell = static_cast(pb.cell); + oldPosition = pbCell.arrowPosition; + pbCell.arrowPosition = NSPopUpNoArrow; + } + [pb.cell drawBezelWithFrame:r inView:pb.superview]; + + if (pbCell) // Restore, we may reuse it for a ComboBox. + pbCell.arrowPosition = oldPosition; }; if (needsInactiveHack) { From 57af7f2166fde4c5fe0b9fe6e28e518155daa79e Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Mon, 17 Feb 2020 22:07:54 +0300 Subject: [PATCH 5/8] Make libmd4c a private dependency of Qt GUI Otherwise, when Qt is built with system libmd4c, all applications using Qt GUI have to link with it, even if they do not use it. Change-Id: I662dfd4caf29bb692b62c20cef0e99148a87a99a Reviewed-by: Konstantin Ritt Reviewed-by: Shawn Rutledge --- src/gui/text/text.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index 5e97b312f1..464ff3953b 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -99,7 +99,7 @@ qtConfig(textodfwriter) { qtConfig(textmarkdownreader) { qtConfig(system-textmarkdownreader) { - QMAKE_USE += libmd4c + QMAKE_USE_PRIVATE += libmd4c } else { include($$PWD/../../3rdparty/md4c.pri) } From 045a143c2c72c72f264dd40f5da2994e647dc0ee Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 11 Feb 2020 09:44:35 +0100 Subject: [PATCH 6/8] Fix RollEffect misplacements in High DPI setups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pass the correct screen as parent of the roll effect widget. Fixes: QTBUG-82011 Change-Id: I25c163cb2e4c038e60ceced702a1ea6c18aa5424 Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/widgets/qeffects.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/widgets/widgets/qeffects.cpp b/src/widgets/widgets/qeffects.cpp index 7069ef0368..fe1bdac644 100644 --- a/src/widgets/widgets/qeffects.cpp +++ b/src/widgets/widgets/qeffects.cpp @@ -54,6 +54,15 @@ QT_BEGIN_NAMESPACE +static QWidget *effectParent(const QWidget* w) +{ + const int screenNumber = w ? QGuiApplication::screens().indexOf(w->screen()) : 0; + QT_WARNING_PUSH // ### Qt 6: Find a replacement for QDesktopWidget::screen() + QT_WARNING_DISABLE_DEPRECATED + return QApplication::desktop()->screen(screenNumber); + QT_WARNING_POP +} + /* Internal class QAlphaWidget. @@ -98,12 +107,9 @@ static QAlphaWidget* q_blend = 0; /* Constructs a QAlphaWidget. */ -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED // ### Qt 6: Find a replacement for QDesktopWidget::screen() QAlphaWidget::QAlphaWidget(QWidget* w, Qt::WindowFlags f) - : QWidget(QApplication::desktop()->screen(QDesktopWidgetPrivate::screenNumber(w)), f) + : QWidget(effectParent(w), f) { -QT_WARNING_POP #ifndef Q_OS_WIN setEnabled(false); #endif @@ -383,7 +389,7 @@ static QRollEffect* q_roll = 0; Construct a QRollEffect widget. */ QRollEffect::QRollEffect(QWidget* w, Qt::WindowFlags f, DirFlags orient) - : QWidget(0, f), orientation(orient) + : QWidget(effectParent(w), f), orientation(orient) { #ifndef Q_OS_WIN setEnabled(false); From 49dbe760e4e0d8a781b5336efdce4748a7d73a33 Mon Sep 17 00:00:00 2001 From: Nicolas Guichard Date: Fri, 14 Feb 2020 12:50:00 +0100 Subject: [PATCH 7/8] Fix QShaderGenerator crashing when a node port name prefixed another one QShaderGenerator didn't handle substitutions like `vec4 $color = mix($color1, $color2, $fac);` Note that `$color` is a prefix to `$color1` and `$color2`. For the substitution `QByteArray::replace` was used so if `$color` was handled first and replaced by `v1`, `$color1` and `$color2` were never correctly replaced and instead became `v11` and `v12` which caused a crash later on. Change-Id: Idaf800fdac468f33c323eb722701da5f8eb918d6 Reviewed-by: Paul Lemire --- src/gui/util/qshadergenerator.cpp | 42 ++++++++++- .../qshadergenerator/tst_qshadergenerator.cpp | 70 +++++++++++++++++++ 2 files changed, 109 insertions(+), 3 deletions(-) diff --git a/src/gui/util/qshadergenerator.cpp b/src/gui/util/qshadergenerator.cpp index bcb985de54..7ea42a7c9a 100644 --- a/src/gui/util/qshadergenerator.cpp +++ b/src/gui/util/qshadergenerator.cpp @@ -42,6 +42,8 @@ #include "qshaderlanguage_p.h" #include +#include + QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(ShaderGenerator, "ShaderGenerator", QtWarningMsg) @@ -457,6 +459,13 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers) QByteArray line = node.rule(format).substitution; const QVector ports = node.ports(); + struct VariableReplacement { + QByteArray placeholder; + QByteArray variable; + }; + + QVector variableReplacements; + // Generate temporary variable names vN for (const QShaderNodePort &port : ports) { const QString portName = port.name; @@ -472,10 +481,37 @@ QByteArray QShaderGenerator::createShaderCode(const QStringList &enabledLayers) if (variableIndex < 0) continue; - const auto placeholder = QByteArray(QByteArrayLiteral("$") + portName.toUtf8()); - const auto variable = QByteArray(QByteArrayLiteral("v") + QByteArray::number(variableIndex)); + VariableReplacement replacement; + replacement.placeholder = QByteArrayLiteral("$") + portName.toUtf8(); + replacement.variable = QByteArrayLiteral("v") + QByteArray::number(variableIndex); - line.replace(placeholder, variable); + variableReplacements.append(std::move(replacement)); + } + + int begin = 0; + while ((begin = line.indexOf('$', begin)) != -1) { + int end = begin + 1; + char endChar = line.at(end); + const int size = line.size(); + while (end < size && (std::isalnum(endChar) || endChar == '_')) { + ++end; + endChar = line.at(end); + } + + const int placeholderLength = end - begin; + + const QByteArray variableName = line.mid(begin, placeholderLength); + const auto replacementIt = std::find_if(variableReplacements.cbegin(), variableReplacements.cend(), + [&variableName](const VariableReplacement &replacement) { + return variableName == replacement.placeholder; + }); + + if (replacementIt != variableReplacements.cend()) { + line.replace(begin, placeholderLength, replacementIt->variable); + begin += replacementIt->variable.length(); + } else { + begin = end; + } } // Substitute variable names by generated vN variable names diff --git a/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp b/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp index 59e93d127f..2b9b08a18a 100644 --- a/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp +++ b/tests/auto/gui/util/qshadergenerator/tst_qshadergenerator.cpp @@ -198,6 +198,7 @@ private slots: void shouldGenerateDifferentCodeDependingOnActiveLayers(); void shouldUseGlobalVariableRatherThanTemporaries(); void shouldGenerateTemporariesWisely(); + void shouldHandlePortNamesPrefixingOneAnother(); }; void tst_QShaderGenerator::shouldHaveDefaultState() @@ -1229,6 +1230,75 @@ 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")); +} + QTEST_MAIN(tst_QShaderGenerator) #include "tst_qshadergenerator.moc" From 7981dbfaf371a368fbd69e935768b310f42a0e5a Mon Sep 17 00:00:00 2001 From: Nicolas Guichard Date: Wed, 19 Feb 2020 12:38:27 +0100 Subject: [PATCH 8/8] QShaderGraph: don't generate statements with undefined inputs This fixes the shader generation for graphs like this one: Function0 ------> Output0 (with unbound input) Input ------> Function1 ------> Output1 With those graphs, createStatements will not return any statement for nodes Function0 and Output0. Change-Id: Iec32aa51623e176b03ae23e580f06d14df80a194 Reviewed-by: Paul Lemire --- src/gui/util/qshadergraph.cpp | 47 +++++++++++++++++++ .../util/qshadergraph/tst_qshadergraph.cpp | 12 ++--- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/gui/util/qshadergraph.cpp b/src/gui/util/qshadergraph.cpp index 46fe6ac6d6..611bb4b938 100644 --- a/src/gui/util/qshadergraph.cpp +++ b/src/gui/util/qshadergraph.cpp @@ -123,6 +123,50 @@ namespace } return targetStatement; } + + void removeNodesWithUnboundInputs(QVector &statements, + const QVector &allEdges) + { + // A node is invalid if any of its input ports is disconected + // or connected to the output port of another invalid node. + + // Keeps track of the edges from the nodes we know to be valid + // to unvisited nodes + auto currentEdges = QVector(); + + statements.erase(std::remove_if(statements.begin(), + statements.end(), + [¤tEdges, &allEdges] (const QShaderGraph::Statement &statement) { + const QShaderNode &node = statement.node; + const QVector outgoing = outgoingEdges(currentEdges, node.uuid()); + const QVector ports = node.ports(); + + bool allInputsConnected = true; + for (const QShaderNodePort &port : node.ports()) { + if (port.direction == QShaderNodePort::Output) + continue; + + const auto edgeIt = std::find_if(outgoing.cbegin(), + outgoing.cend(), + [&port] (const QShaderGraph::Edge &edge) { + return edge.targetPortName == port.name; + }); + + if (edgeIt != outgoing.cend()) + currentEdges.removeAll(*edgeIt); + else + allInputsConnected = false; + } + + if (allInputsConnected) { + const QVector incoming = incomingEdges(allEdges, node.uuid()); + currentEdges.append(incoming); + } + + return !allInputsConnected; + }), + statements.end()); + } } QUuid QShaderGraph::Statement::uuid() const noexcept @@ -248,6 +292,9 @@ QVector QShaderGraph::createStatements(const QStringLis } std::reverse(result.begin(), result.end()); + + removeNodesWithUnboundInputs(result, enabledEdges); + return result; } diff --git a/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp b/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp index 50c925a111..014a163f58 100644 --- a/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp +++ b/tests/auto/gui/util/qshadergraph/tst_qshadergraph.cpp @@ -516,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() - << 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); } @@ -568,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() - << createStatement(output, {2}, {}); + // The cycle is ignored + const auto expected = QVector(); dumpStatementsIfNeeded(statements, expected); QCOMPARE(statements, expected); }