From 31a971f727ecf0c6651689f052b9fb4c67872b58 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 21 Oct 2019 14:09:00 +0200 Subject: QColorDialog: Fix memory leak when picking screen colors Pass the dialog as parent to the event filter class in QColorDialogPrivate::_q_pickScreenColor(). Fixes: QTBUG-53469 Change-Id: I9110c19a8f49a545a0fbf7cfdb3ded70fea4dcce Reviewed-by: Christian Ehrlicher --- src/widgets/dialogs/qcolordialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 1cb6cb8a2d..197d1d940b 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -499,7 +499,7 @@ void QWellArray::keyPressEvent(QKeyEvent* e) // Event filter to be installed on the dialog while in color-picking mode. class QColorPickingEventFilter : public QObject { public: - explicit QColorPickingEventFilter(QColorDialogPrivate *dp, QObject *parent = 0) : QObject(parent), m_dp(dp) {} + explicit QColorPickingEventFilter(QColorDialogPrivate *dp, QObject *parent) : QObject(parent), m_dp(dp) {} bool eventFilter(QObject *, QEvent *event) override { @@ -1606,7 +1606,7 @@ void QColorDialogPrivate::_q_pickScreenColor() { Q_Q(QColorDialog); if (!colorPickingEventFilter) - colorPickingEventFilter = new QColorPickingEventFilter(this); + colorPickingEventFilter = new QColorPickingEventFilter(this, q); q->installEventFilter(colorPickingEventFilter); // If user pushes Escape, the last color before picking will be restored. beforeScreenColorPicking = cs->currentColor(); -- cgit v1.2.3 From c686e885c004a48c90cff300c0ad1e817e43fb99 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 21 Oct 2019 15:39:50 +0200 Subject: qmake: Disallow building Qt examples inside the source tree Building examples inside a Qt source tree is considered unsupported. Instead of checking, whether the build is done "in source" inside the source directory, we also have to check for "shadowed example builds" as they are done by Creator. An example would be: qtbase/examples/widgets/widgets/build-wiggly as a shadow build for qtbase/examples/widgets/widgets/wiggly. Fixes: QTBUG-76237 Change-Id: Iceb88af006fad249a4c13fa0b0345cf3f7086252 Reviewed-by: Joerg Bornemann --- mkspecs/features/qt_example_installs.prf | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mkspecs/features/qt_example_installs.prf b/mkspecs/features/qt_example_installs.prf index 43b58817fe..72b47bce27 100644 --- a/mkspecs/features/qt_example_installs.prf +++ b/mkspecs/features/qt_example_installs.prf @@ -25,14 +25,16 @@ defineTest(addInstallFiles) { export($$1) } -probase = $$relative_path($$_PRO_FILE_PWD_, $$dirname(_QMAKE_CONF_)/examples) +moduleRoot = $$dirname(_QMAKE_CONF_) +probase = $$relative_path($$_PRO_FILE_PWD_, $$moduleRoot/examples) isEmpty(probase)|contains(probase, ^\\..*): \ return() isEmpty(_QMAKE_CACHE_) { - !equals(OUT_PWD, $$_PRO_FILE_PWD_): \ - return() - error("You cannot build examples inside the Qt source tree, except as part of a proper Qt build.") + moduleRootRelativeToBuildDir = $$relative_path($$moduleRoot, $$OUT_PWD) + # Check if OUT_PWD is inside module root + equals(moduleRootRelativeToBuildDir, .)|contains(moduleRootRelativeToBuildDir, \(\.\./\)+\(\.\.\)?): \ + error("You cannot build examples inside the Qt source tree, except as part of a proper Qt build.") } contains(TEMPLATE, "vc.*"): \ -- cgit v1.2.3 From 9367d966e6c10c95b92f2b55e2cead7e85d80cfe Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Wed, 23 Oct 2019 01:12:48 +0300 Subject: Fix a -Wclass-memaccess problem in qjson MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qtbase/src/corelib/serialization/qjson_p.h:230:38: error: ‘void* memcpy(void*, const void*, size_t)’ copying an object of type ‘QJsonPrivate::qle_ushort’ {aka ‘class QSpecialInteger >’} with ‘private’ member ‘QSpecialInteger >::val’ from an array of ‘const class QChar’; use assignment or copy-initialization instead [-Werror=class-memaccess] 230 | str.length()*sizeof(ushort)); | ^ Change-Id: Ie58e7fe4bae3003227364012ad56ab23bd560d8c Reviewed-by: Simon Hausmann --- src/corelib/serialization/qjson_p.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/serialization/qjson_p.h b/src/corelib/serialization/qjson_p.h index 40b2414e4a..ff010cb902 100644 --- a/src/corelib/serialization/qjson_p.h +++ b/src/corelib/serialization/qjson_p.h @@ -222,7 +222,9 @@ public: for (int i = 0; i < str.length(); ++i) d->utf16[i] = uc[i]; #else - memcpy(d->utf16, str.unicode(), str.length()*sizeof(ushort)); + memcpy(static_cast(d->utf16), + static_cast(str.unicode()), + str.length()*sizeof(ushort)); #endif if (str.length() & 1) d->utf16[str.length()] = 0; -- cgit v1.2.3 From c9b3091be5dc7880e615822f3aac758eacd714f8 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Mon, 21 Oct 2019 08:53:28 +0200 Subject: tst_qgraphicspixmaptiem: Fix undefined behavior in contains See the comment in the test for details. Change-Id: Ie3d356e476ba0419d304bccd396fc18a831a30cd Reviewed-by: Paul Olav Tvete Reviewed-by: Eirik Aavitsland --- .../graphicsview/qgraphicspixmapitem/tst_qgraphicspixmapitem.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/auto/widgets/graphicsview/qgraphicspixmapitem/tst_qgraphicspixmapitem.cpp b/tests/auto/widgets/graphicsview/qgraphicspixmapitem/tst_qgraphicspixmapitem.cpp index 78fe448bdb..843a30df16 100644 --- a/tests/auto/widgets/graphicsview/qgraphicspixmapitem/tst_qgraphicspixmapitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicspixmapitem/tst_qgraphicspixmapitem.cpp @@ -156,6 +156,14 @@ void tst_QGraphicsPixmapItem::contains() QFETCH(QPointF, point); QFETCH(bool, contains); + // At the time of writing, by default pixmaps will have: + // - The same pixel format of the primary screen (which is platform dependent and may contain alpha) + // - Uninitialized pixels, potentially including an alpha channel + // - A ShapeMode of Mask (which mean it will use the alpha channel as a mask for contains()) + // This means that in order to prevent undefined behavior in this test, we either need to set + // the shapeMode to something else, or set the pixels of the pixmap. + pixmap.fill(); // Filling the pixmap to be on the safe side. + SubQGraphicsPixmapItem item(pixmap); QCOMPARE(item.contains(point), contains); } -- cgit v1.2.3 From 59ca056a79eb48fa345d0c5b133ca1e6d28997af Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 21 Oct 2019 14:45:28 +0200 Subject: Exclude tests that need GUI when GUI isn't available Thanks to Dmitriy Purgin for pointing out the serialization one. Task-number: QTBUG-79353 Change-Id: Ia3d750b17ddd8fbb7a83a55df7e4546ca78c358b Reviewed-by: Timur Pocheptsov --- tests/auto/corelib/serialization/serialization.pro | 3 ++- tests/auto/other/other.pro | 5 +---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/auto/corelib/serialization/serialization.pro b/tests/auto/corelib/serialization/serialization.pro index 9638178cdc..f4a5a3c5b1 100644 --- a/tests/auto/corelib/serialization/serialization.pro +++ b/tests/auto/corelib/serialization/serialization.pro @@ -11,7 +11,8 @@ SUBDIRS = \ qxmlstream !qtHaveModule(gui): SUBDIRS -= \ - qdatastream + qdatastream \ + qdatastream_core_pixmap !qtHaveModule(network): SUBDIRS -= \ qtextstream diff --git a/tests/auto/other/other.pro b/tests/auto/other/other.pro index c5426202e8..cc6b1887a3 100644 --- a/tests/auto/other/other.pro +++ b/tests/auto/other/other.pro @@ -68,7 +68,4 @@ winrt|!qtHaveModule(gui)|!qtConfig(accessibility): SUBDIRS -= qaccessibility android: SUBDIRS += \ android -qtConfig(xkbcommon): { - SUBDIRS += \ - xkbkeyboard -} +qtHaveModule(gui):qtConfig(xkbcommon): SUBDIRS += xkbkeyboard -- cgit v1.2.3 From ef9c498215f0eeb73d1ffdcd0d58464c56ea56ac Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 21 Oct 2019 14:48:50 +0200 Subject: Tidy up data-stream test While I was looking into a bug related to problems building the test without GUI, I noticed a lot of spurious #include lines so tidied up a bit. Split some long lines, while I was about it. Change-Id: Id87eb6f612c6b174f8240dfe9c00e0929244fb6c Reviewed-by: Albert Astals Cid --- .../tst_qdatastream_core_pixmap.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp b/tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp index c931016a61..cf5ead1220 100644 --- a/tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp +++ b/tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp @@ -27,13 +27,8 @@ ****************************************************************************/ #include -#include -#include #include -#include -#include -#include -#include +#include class tst_QDataStream : public QObject { @@ -41,16 +36,20 @@ Q_OBJECT private slots: void stream_with_pixmap(); - }; void tst_QDataStream::stream_with_pixmap() { // This is a QVariantMap with a 3x3 red QPixmap and two strings inside - const QByteArray ba = QByteArray::fromBase64("AAAAAwAAAAIAegAAAAoAAAAACgB0AGgAZQByAGUAAAACAHAAAABBAAAAAAGJUE5HDQoaCgAAAA1JSERSAAAAAwAAAAMIAgAAANlKIugAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAQSURBVAiZY/zPAAVMDJgsAB1bAQXZn5ieAAAAAElFTkSuQmCCAAAAAgBhAAAACgAAAAAKAGgAZQBsAGwAbw=="); + const QByteArray ba = QByteArray::fromBase64( + "AAAAAwAAAAIAegAAAAoAAAAACgB0AGgAZQByAGUAAAACAHAAAABBAAAAAAGJUE5H" + "DQoaCgAAAA1JSERSAAAAAwAAAAMIAgAAANlKIugAAAAJcEhZcwAADsQAAA7EAZUr" + "DhsAAAAQSURBVAiZY/zPAAVMDJgsAB1bAQXZn5ieAAAAAElFTkSuQmCCAAAAAgBh" + "AAAACgAAAAAKAGgAZQBsAGwAbw=="); QImage dummy; // Needed to make sure qtGui is loaded - QTest::ignoreMessage(QtWarningMsg, "QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication"); + QTest::ignoreMessage(QtWarningMsg, "QPixmap::fromImageInPlace: " + "QPixmap cannot be created without a QGuiApplication"); QVariantMap map; QDataStream d(ba); @@ -58,11 +57,11 @@ void tst_QDataStream::stream_with_pixmap() d >> map; QCOMPARE(map["a"].toString(), QString("hello")); - QCOMPARE(map["p"].value(), QPixmap()); // the pixmap is null because this is not a QGuiApplication + // The pixmap is null because this is not a QGuiApplication: + QCOMPARE(map["p"].value(), QPixmap()); QCOMPARE(map["z"].toString(), QString("there")); } QTEST_GUILESS_MAIN(tst_QDataStream) #include "tst_qdatastream_core_pixmap.moc" - -- cgit v1.2.3 From 73cb5cb01e9531d2b2249597a64d57fa0029c300 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 18 Oct 2019 15:26:23 +0200 Subject: Fix prefix for non-Windows cross-builds on Windows When one specified a prefix "/usr/qt5" on Windows for a non-Windows target (e.g. QNX) that prefix was translated to "C:/usr/qt5" and passed on to the Makefiles, for example as "-Wl,-rpath,C:/usr/qt5/lib". The reason was that we called $$absolute_path on the user-specified prefix. However, absolute_path operates according to the rules of the host operating system. When cross-building, the prefix is an on-device path. Therefore we must not attempt to make it absolute to the build directory. The check whether we're cross-compiling looks a bit arcane, but we cannot use $$qtConfEvaluate(features.cross_compile) at this stage of configure. Instead, we use XSPEC (set up by qtConfOutput_prepareSpec) and $$[QMAKE_SPEC] which is the right host mkspec. Fixes: QTBUG-79214 Change-Id: Id8664f8512cf1d9e178054a38e72323d7929547d Reviewed-by: Edward Welbourne Reviewed-by: Qt CI Bot --- configure.pri | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/configure.pri b/configure.pri index 3778ece180..16e2fccd77 100644 --- a/configure.pri +++ b/configure.pri @@ -741,7 +741,13 @@ defineTest(qtConfOutput_preparePaths) { } have_prefix = false } else { - config.input.prefix = $$absolute_path($$config.input.prefix, $$OUT_PWD) + equals(XSPEC, $$[QMAKE_SPEC]) { + # Only make the user-specified prefix absolute if we're not cross-compiling. + config.input.prefix = $$absolute_path($$config.input.prefix, $$OUT_PWD) + } else { + # But we still must normalize path separators. + config.input.prefix = $$replace(config.input.prefix, \\\\, /) + } have_prefix = true } -- cgit v1.2.3 From a21d4395f4f9afea52b6c2da359ce6ad21ebc763 Mon Sep 17 00:00:00 2001 From: Yulong Bai Date: Thu, 10 Oct 2019 23:05:16 +0200 Subject: Drag'n'Drop: fix attached Drag object deleted when DnD is progressing The attached Drag object's owner, i.e. its parent, is also the dragged item. So the attached Drag object will also be destroyed as the dragged item is deleted. Fixes: QTBUG-65701 Change-Id: I39b0a3180f205c427deed5c70cd1912524f9324e Reviewed-by: Shawn Rutledge --- src/gui/kernel/qdnd.cpp | 9 +++++---- src/gui/kernel/qdnd_p.h | 4 ++-- src/gui/kernel/qdrag.cpp | 7 +++++-- src/plugins/platforms/xcb/qxcbdrag.cpp | 8 +++++++- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/gui/kernel/qdnd.cpp b/src/gui/kernel/qdnd.cpp index 5c5f166554..dd541af3b8 100644 --- a/src/gui/kernel/qdnd.cpp +++ b/src/gui/kernel/qdnd.cpp @@ -113,11 +113,12 @@ Qt::DropAction QDragManager::drag(QDrag *o) m_object->d_func()->target = 0; - QGuiApplicationPrivate::instance()->notifyDragStarted(o); + QGuiApplicationPrivate::instance()->notifyDragStarted(m_object.data()); const Qt::DropAction result = m_platformDrag->drag(m_object); - m_object = 0; - if (!m_platformDrag->ownsDragObject()) - o->deleteLater(); + if (!m_object.isNull() && !m_platformDrag->ownsDragObject()) + m_object->deleteLater(); + + m_object.clear(); return result; } diff --git a/src/gui/kernel/qdnd_p.h b/src/gui/kernel/qdnd_p.h index 8f8eb03f87..f095fbf7a0 100644 --- a/src/gui/kernel/qdnd_p.h +++ b/src/gui/kernel/qdnd_p.h @@ -101,13 +101,13 @@ public: void setCurrentTarget(QObject *target, bool dropped = false); QObject *currentTarget() const; - QDrag *object() const { return m_object; } + QPointer object() const { return m_object; } QObject *source() const; private: QObject *m_currentDropTarget; QPlatformDrag *m_platformDrag; - QDrag *m_object; + QPointer m_object; static QDragManager *m_instance; Q_DISABLE_COPY_MOVE(QDragManager) diff --git a/src/gui/kernel/qdrag.cpp b/src/gui/kernel/qdrag.cpp index dcd0d13d5c..8e2f7be23e 100644 --- a/src/gui/kernel/qdrag.cpp +++ b/src/gui/kernel/qdrag.cpp @@ -279,8 +279,11 @@ Qt::DropAction QDrag::exec(Qt::DropActions supportedActions, Qt::DropAction defa } d->supported_actions = supportedActions; d->default_action = transformedDefaultDropAction; - d->executed_action = QDragManager::self()->drag(this); - + QPointer self = this; + auto executed_action = QDragManager::self()->drag(self.data()); + if (self.isNull()) + return Qt::IgnoreAction; + d->executed_action = executed_action; return d->executed_action; } diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 1ce947165d..3d525598ca 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -354,6 +354,11 @@ bool QXcbDrag::findXdndAwareTarget(const QPoint &globalPos, xcb_window_t *target void QXcbDrag::move(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardModifiers mods) { + // currentDrag() might be deleted while 'drag' is progressing + if (!currentDrag()) { + cancel(); + return; + } // The source sends XdndEnter and XdndPosition to the target. if (source_sameanswer.contains(globalPos) && source_sameanswer.isValid()) return; @@ -1076,7 +1081,8 @@ void QXcbDrag::cancel() send_leave(); // remove canceled object - currentDrag()->deleteLater(); + if (currentDrag()) + currentDrag()->deleteLater(); canceled = true; } -- cgit v1.2.3