From e9190eda1a2b16bd6aa07cce4e00f302eeb3562e Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Mon, 9 Sep 2019 10:43:27 +0200 Subject: [PATCH 01/20] Doc: Remove broken example snippet from Q_ENUMS The code snippet is used by both Q_ENUMS and Q_ENUM. Therefore, remove the example snippet from Q_ENUMS documentation, as it is obsolete. Also, move recommendation to use Q_ENUM in new code to the very top of Q_ENUMS' documentation. Fixes: QTBUG-63203 Change-Id: I12a9f45e0b3bd75dfe98e1ecbc45e299a688b80c Reviewed-by: Giuseppe D'Angelo --- src/corelib/kernel/qobject.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 1f5b61c978..598ce75bd4 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -4291,22 +4291,18 @@ QDebug operator<<(QDebug dbg, const QObject *o) \relates QObject \obsolete + In new code, you should prefer the use of the Q_ENUM() macro, which makes the + type available also to the meta type system. + For instance, QMetaEnum::fromType() will not work with types declared with Q_ENUMS(). + This macro registers one or several enum types to the meta-object system. - For example: - - \snippet code/src_corelib_kernel_qobject.cpp 38 - If you want to register an enum that is declared in another class, the enum must be fully qualified with the name of the class defining it. In addition, the class \e defining the enum has to inherit QObject as well as declare the enum using Q_ENUMS(). - In new code, you should prefer the use of the Q_ENUM() macro, which makes the - type available also to the meta type system. - For instance, QMetaEnum::fromType() will not work with types declared with Q_ENUMS(). - \sa {Qt's Property System} */ From 51f1428d3cd782c22226b0ee4bd7145a45762d86 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 19 Sep 2019 11:56:24 +0200 Subject: [PATCH 02/20] qmake: Replace WinRT with UWP in the qmake Manual Remove info about Windows Phone, which is no longer supported. Task-number: QTBUG-61884 Change-Id: Ic330f0f19a4e7314dd175f6c492fa25133185517 Reviewed-by: Oliver Wolff --- qmake/doc/src/qmake-manual.qdoc | 51 ++++++++++++++------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index b178084690..5e54278dd1 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the documentation of the Qt Toolkit. @@ -2891,8 +2891,8 @@ On desktop Windows, the default value is the value of the environment variable \c{WindowsSDKVersion}. - On WinRT, the default value is the value of the environment variable - \c{UCRTVERSION}. + On Universal Windows Platform (UWP), the default value is the value of the + environment variable \c{UCRTVERSION}. \target WINDOWS_TARGET_PLATFORM_MIN_VERSION \section1 WINDOWS_TARGET_PLATFORM_MIN_VERSION @@ -2905,8 +2905,8 @@ \target WINRT_MANIFEST \section1 WINRT_MANIFEST - Specifies parameters to be passed to the application manifest on \l{Qt for WinRT}{Windows - Runtime}. The allowed values are: + Specifies parameters to be passed to the application manifest on + \l{Qt for UWP}{UWP}. The allowed values are: \table \header @@ -2941,7 +2941,6 @@ \row \li foreground \li Tile foreground (text) color. Defaults to \c{light}. - This option is only available for Windows Store apps on Windows 8 and Windows RT. \row \li iconic_tile_icon \li Image file for the \c{iconic} tile template icon. Default provided by @@ -2956,16 +2955,16 @@ manifest's UUID, or generates a new UUID if none is present. \row \li logo_30x30 - \li Logo image file of size 30x30 pixels. This is not supported on Windows Phone. + \li Logo image file of size 30x30 pixels. \row \li logo_41x41 - \li Logo image file of size 41x41 pixels. This is only supported on Windows Phone. + \li Logo image file of size 41x41 pixels. This parameter is obsolete. \row \li logo_70x70 - \li Logo image file of size 70x70 pixels. This is not supported on Windows Phone. + \li Logo image file of size 70x70 pixels. \row \li logo_71x71 - \li Logo image file of size 71x71 pixels. This is only supported on Windows Phone. + \li Logo image file of size 71x71 pixels. This parameter is obsolete. \row \li logo_150x150 \li Logo image file of size 150x150 pixels. This is supported on all Windows @@ -2980,31 +2979,27 @@ Store App platforms. \row \li logo_620x300 - \li Splash screen image file of size 620x300 pixels. This is not supported on - Windows Phone. + \li Splash screen image file of size 620x300 pixels. \row \li logo_480x800 - \li Splash screen image file of size 480x800 pixels. This is only supported on - Windows Phone. + \li Splash screen image file of size 480x800 pixels. + This parameter is obsolete. \row \li logo_large \li Large logo image file. This has to be 150x150 pixels. Supported on all Windows Store App platforms. Default provided by the mkspec. \row \li logo_medium - \li Medium logo image file. For Windows Phone the image must have a pixel size - of 71x71, for other Windows Store App platforms 70x70. Default provided by - the mkspec. + \li Medium logo image file. The image must have a pixel size of 70x70. + Default provided by the mkspec. \row \li logo_small - \li Small logo image file. For Windows Phone the image must have a pixel size - of 44x44, for other Windows Store App platforms 30x30. Default provided by - the mkspec. + \li Small logo image file. The image must have a pixel size of 30x30. + Default provided by the mkspec. \row \li logo_splash - \li Splash screen image file. For Windows Phone the image must have a pixel size - of 480x800, for other Windows Store App platforms 620x300. Default provided - by the mkspec. + \li Splash screen image file. The image must have a pixel size of + 620x300. Default provided by the mkspec. \row \li logo_store \li Logo image file for Windows Store. Default provided by the mkspec. @@ -3017,10 +3012,12 @@ \li The name of the package as displayed to the user. Defaults to TARGET. \row \li phone_product_id - \li The GUID of the product. Defaults to the value of WINRT_MANIFEST.identity. (Windows Phone only) + \li The GUID of the product. + This parameter is obsolete. \row \li phone_publisher_id - \li The GUID of the publisher. Defaults to an invalid GUID. (Windows Phone only) + \li The GUID of the publisher. + This parameter is obsolete. \row \li publisher \li Display name of the publisher. Defaults to \c{Default publisher display name}. @@ -3071,10 +3068,6 @@ WINRT_MANIFEST.CONFIG += verbatim \endcode - \note The required image sizes of \e logo_small, \e logo_medium, and \e logo_large - depend on the target platform. The general descriptions are overwritten if a - description that specifies the size is provided. - \target YACCSOURCES \section1 YACCSOURCES From b8a911fbebfcd297ce08b91fbe85bb1624d257d9 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Wed, 11 Sep 2019 11:46:47 +0200 Subject: [PATCH 03/20] QPainter: Avoid leaking memory on unbalanced save/restore If a QPainter ended without all saved states having been restored, the state stack would leak memory. Fixes: QTBUG-77843 Change-Id: I760904d6391de24a4867be54fa1bebf76be14ba7 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qpainter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 95e6bda78b..f9e9563f10 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1710,8 +1710,8 @@ void QPainter::restore() static inline void qt_cleanup_painter_state(QPainterPrivate *d) { + qDeleteAll(d->states); d->states.clear(); - delete d->state; d->state = 0; d->engine = 0; d->device = 0; From 9b6179cf957c32e0c02547d510dfee2088f02340 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 5 Sep 2019 12:52:43 +0200 Subject: [PATCH 04/20] Ensure all children of a widget get updated when a stylesheet changes Before, only the direct children would get an update when the stylesheet changed, any children below that would be unchanged. Fixes: QTBUG-77006 Change-Id: Id668eaae74a8289d78d66644f077e6a3302960cd Reviewed-by: Frederik Gladhorn --- src/widgets/styles/qstylesheetstyle.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 85b65f39b1..98a9f74f5b 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -2735,6 +2735,11 @@ static void updateObjects(const QList& objects) if (auto widget = qobject_cast(const_cast(object))) { widget->style()->polish(widget); QApplication::sendEvent(widget, &event); + QList children; + children.reserve(widget->children().size() + 1); + for (auto child: qAsConst(widget->children())) + children.append(child); + updateObjects(children); } } } From ac5e198db4eea4670a5a4a22fb44eb8a6acc4c47 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Sat, 21 Sep 2019 02:02:58 +0200 Subject: [PATCH 05/20] Add SQLite specific documentation when specifying a database name Fixes: QTBUG-67847 Change-Id: I3c640233526260b596e8224dc48f713a3f0cff56 Reviewed-by: Paul Wicking --- src/sql/kernel/qsqldatabase.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp index d63a9e59a8..f61c72285a 100644 --- a/src/sql/kernel/qsqldatabase.cpp +++ b/src/sql/kernel/qsqldatabase.cpp @@ -881,6 +881,14 @@ bool QSqlDatabase::rollback() connection name must be passed to addDatabase() at connection object create time. + For the QSQLITE driver, if the database name specified does not + exist, then it will create the file for you unless the + QSQLITE_OPEN_READONLY option is set. + + Additionally, \a name can be set to \c ":memory:" which will + create a temporary database which is only available for the + lifetime of the application. + For the QOCI (Oracle) driver, the database name is the TNS Service Name. From ec0e9f29dfd0b45edf5fd33e8ccf763e604612d7 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Tue, 17 Sep 2019 09:54:28 +0300 Subject: [PATCH 06/20] Android: Fix loading of plugins In 5bb178c479a247720fbc3fbb7f06a32b725193ac, the Android platform plugin was moved from platforms/android to platforms/. The unforeseen consequence of this was that the plugin loader for plugins/platforms would now find it, whereas before it would be ignored. It would therefore be detected as the appropriate plugin, but since it was intended to be loaded as a static plugin, loading it dynamically would fail. Instead of fixing the static plugin loading, we remove this hack. Fixes: QTBUG-78440 Change-Id: Idcb6c075fdebaf67644f32a59d7aaf0d1c0bbe20 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/kernel/qcoreapplication.cpp | 24 ++++--- src/corelib/plugin/qfactoryloader.cpp | 12 +++- src/corelib/plugin/qlibrary_unix.cpp | 8 +++ src/corelib/plugin/qpluginloader.cpp | 10 +++ src/plugins/platforms/android/android.pro | 8 +-- .../platforms/android/androidjnimain.cpp | 2 - src/plugins/platforms/android/main.cpp | 63 +++++++++++++++++++ 7 files changed, 109 insertions(+), 18 deletions(-) create mode 100644 src/plugins/platforms/android/main.cpp diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index c537e8f51b..e25049f821 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -2708,18 +2708,22 @@ QStringList QCoreApplication::libraryPathsLocked() QStringList *app_libpaths = new QStringList; coreappdata()->app_libpaths.reset(app_libpaths); - QString libPathEnv = qEnvironmentVariable("QT_PLUGIN_PATH"); - if (!libPathEnv.isEmpty()) { - QStringList paths = libPathEnv.split(QDir::listSeparator(), QString::SkipEmptyParts); - for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) { - QString canonicalPath = QDir(*it).canonicalPath(); - if (!canonicalPath.isEmpty() - && !app_libpaths->contains(canonicalPath)) { - app_libpaths->append(canonicalPath); + auto setPathsFromEnv = [&](QString libPathEnv) { + if (!libPathEnv.isEmpty()) { + QStringList paths = libPathEnv.split(QDir::listSeparator(), QString::SkipEmptyParts); + for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) { + QString canonicalPath = QDir(*it).canonicalPath(); + if (!canonicalPath.isEmpty() + && !app_libpaths->contains(canonicalPath)) { + app_libpaths->append(canonicalPath); + } } } - } - + }; + setPathsFromEnv(qEnvironmentVariable("QT_PLUGIN_PATH")); +#ifdef Q_OS_ANDROID + setPathsFromEnv(qEnvironmentVariable("QT_BUNDLED_LIBS_PATH")); +#endif #ifdef Q_OS_DARWIN // Check the main bundle's PlugIns directory as this is a standard location for Apple OSes. // Note that the QLibraryInfo::PluginsPath below will coincidentally be the same as this value diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index 6737aeccd2..79315ae50f 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -193,7 +193,11 @@ void QFactoryLoader::update() continue; d->loadedPaths << pluginDir; +#ifdef Q_OS_ANDROID + QString path = pluginDir; +#else QString path = pluginDir + d->suffix; +#endif if (qt_debug_component()) qDebug() << "QFactoryLoader::QFactoryLoader() checking directory path" << path << "..."; @@ -202,8 +206,10 @@ void QFactoryLoader::update() continue; QStringList plugins = QDir(path).entryList( -#ifdef Q_OS_WIN +#if defined(Q_OS_WIN) QStringList(QStringLiteral("*.dll")), +#elif defined(Q_OS_ANDROID) + QStringList(QLatin1String("plugins_%1_*.so").arg(d->suffix)), #endif QDir::Files); QLibraryPrivate *library = 0; @@ -339,6 +345,10 @@ QFactoryLoader::QFactoryLoader(const char *iid, #if QT_CONFIG(library) d->cs = cs; d->suffix = suffix; +# ifdef Q_OS_ANDROID + if (!d->suffix.isEmpty() && d->suffix.at(0) == QLatin1Char('/')) + d->suffix.remove(0, 1); +# endif QMutexLocker locker(qt_factoryloader_mutex()); update(); diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp index 44d5513163..f0de1010d7 100644 --- a/src/corelib/plugin/qlibrary_unix.cpp +++ b/src/corelib/plugin/qlibrary_unix.cpp @@ -236,6 +236,14 @@ bool QLibraryPrivate::load_sys() auto attemptFromBundle = attempt; pHnd = dlopen(QFile::encodeName(attemptFromBundle.replace(QLatin1Char('/'), QLatin1Char('_'))), dlFlags); } + if (pHnd) { + using JniOnLoadPtr = jint (*)(JavaVM *vm, void *reserved); + JniOnLoadPtr jniOnLoad = reinterpret_cast(dlsym(pHnd, "JNI_OnLoad")); + if (jniOnLoad && jniOnLoad(QtAndroidPrivate::javaVM(), nullptr) == JNI_ERR) { + dlclose(pHnd); + pHnd = nullptr; + } + } #endif if (!pHnd && fileName.startsWith(QLatin1Char('/')) && QFile::exists(attempt)) { diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp index 4e0c3a511b..cadff4f32b 100644 --- a/src/corelib/plugin/qpluginloader.cpp +++ b/src/corelib/plugin/qpluginloader.cpp @@ -311,6 +311,16 @@ static QString locatePlugin(const QString& fileName) for (const QString &path : qAsConst(paths)) { for (const QString &prefix : qAsConst(prefixes)) { for (const QString &suffix : qAsConst(suffixes)) { +#ifdef Q_OS_ANDROID + { + QString pluginPath = basePath + prefix + baseName + suffix; + const QString fn = path + QLatin1String("/lib") + pluginPath.replace(QLatin1Char('/'), QLatin1Char('_')); + if (debug) + qDebug() << "Trying..." << fn; + if (QFileInfo(fn).isFile()) + return fn; + } +#endif const QString fn = path + QLatin1Char('/') + basePath + prefix + baseName + suffix; if (debug) qDebug() << "Trying..." << fn; diff --git a/src/plugins/platforms/android/android.pro b/src/plugins/platforms/android/android.pro index 346df84038..730247cd7f 100644 --- a/src/plugins/platforms/android/android.pro +++ b/src/plugins/platforms/android/android.pro @@ -1,9 +1,5 @@ TARGET = qtforandroid -# STATICPLUGIN needed because there's a Q_IMPORT_PLUGIN in androidjnimain.cpp -# Yes, the plugin imports itself statically -DEFINES += QT_STATICPLUGIN - LIBS += -ljnigraphics -landroid QT += \ @@ -19,7 +15,8 @@ INCLUDEPATH += \ $$PWD \ $$QT_SOURCE_TREE/src/3rdparty/android -SOURCES += $$PWD/androidplatformplugin.cpp \ +SOURCES += $$PWD/main.cpp \ + $$PWD/androidplatformplugin.cpp \ $$PWD/androidcontentfileengine.cpp \ $$PWD/androiddeadlockprotector.cpp \ $$PWD/androidjnimain.cpp \ @@ -92,4 +89,5 @@ qtConfig(vulkan) { } PLUGIN_TYPE = platforms +PLUGIN_CLASS_NAME = QAndroidIntegrationPlugin load(qt_plugin) diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 915f7f0f5b..27eb337aaa 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -68,8 +68,6 @@ #include -Q_IMPORT_PLUGIN(QAndroidPlatformIntegrationPlugin) - QT_BEGIN_NAMESPACE static JavaVM *m_javaVM = nullptr; diff --git a/src/plugins/platforms/android/main.cpp b/src/plugins/platforms/android/main.cpp new file mode 100644 index 0000000000..c304fc8d69 --- /dev/null +++ b/src/plugins/platforms/android/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2019 BogDan Vatra +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include "qandroidplatformintegration.h" + +QT_BEGIN_NAMESPACE + +class QAndroidIntegrationPlugin : public QPlatformIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "android.json") + +public: + QPlatformIntegration *create(const QString& system, const QStringList& paramList) override; +}; + +QPlatformIntegration *QAndroidIntegrationPlugin::create(const QString& system, const QStringList& paramList) +{ + if (!system.compare(QLatin1String("android"), Qt::CaseInsensitive)) + return new QAndroidPlatformIntegration(paramList); + + return nullptr; +} + +QT_END_NAMESPACE From bc35941dbbf6cbd09805a2217ecb062c565855ad Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 20 Sep 2019 13:13:17 +0200 Subject: [PATCH 07/20] Add QQuickMultiPointTouchArea as a friend of QTouchEvent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QQuickMultiPointTouchArea needs to understand whether a stationary touchpoint has relevant property changes, to decide whether to emit its updated() signal. Amends 217dd1b3b03cd40b4bb926631464c684f7f84a69 Task-number: QTBUG-77142 Change-Id: I85e031820bef9d687369b7d67a57c67fe2875b4b Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qevent.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index bf00d4a9a3..dc33a83ac0 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -960,6 +960,7 @@ public: friend class QApplication; friend class QApplicationPrivate; friend class QQuickPointerTouchEvent; + friend class QQuickMultiPointTouchArea; }; #if QT_DEPRECATED_SINCE(5, 0) From d0d18b06458edd3b6b0712ea71c787404bbaa7e1 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 4 Dec 2018 15:05:04 +0100 Subject: [PATCH 08/20] Handle transparent pen color in fast text path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switches the text blending to be SourceOver as that is much more common than Source, and means we can now handle semi-transparent text colors there. Task-number: QTBUG-72165 Change-Id: I7b3aedb22412e6fb6f60197596b37f26c6008784 Reviewed-by: Tor Arne Vestbø --- src/gui/painting/qdrawhelper.cpp | 195 ++++++++++++----------- src/gui/painting/qdrawhelper_p.h | 2 + src/gui/painting/qpaintengine_raster.cpp | 4 +- src/gui/painting/qrgba64_p.h | 2 + 4 files changed, 105 insertions(+), 98 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index edb363ac69..3d06a27d8e 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -5658,44 +5658,60 @@ static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcL { if (coverage == 0) { // nothing - } else if (coverage == 255) { - *dst = src; - } else if (!colorProfile) { - *dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage); + } else if (coverage == 255 || !colorProfile) { + blend_pixel(*dst, src, coverage); + } else if (*dst < 0xff000000) { + // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571 + blend_pixel(*dst, src, coverage); + } else if (src >= 0xff000000) { + grayBlendPixel(dst, coverage, srcLinear, colorProfile); } else { - if (*dst >= 0xff000000) { - grayBlendPixel(dst, coverage, srcLinear, colorProfile); - } else { - // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571 - *dst = INTERPOLATE_PIXEL_255(src, coverage, *dst, 255 - coverage); - } + // First do naive blend with text-color + QRgb s = *dst; + blend_pixel(s, src); + // Then gamma-corrected blend with glyph shape + grayBlendPixel(dst, coverage, colorProfile->toLinear64(s), colorProfile); } } #if QT_CONFIG(raster_64bit) + +static inline void grayBlendPixel(QRgba64 &dst, int coverage, QRgba64 srcLinear, const QColorTrcLut *colorProfile) +{ + // Do a gammacorrected gray alphablend... + QRgba64 dstColor = dst; + if (colorProfile) { + if (dstColor.isOpaque()) + dstColor = colorProfile->toLinear(dstColor); + else if (!dstColor.isTransparent()) + dstColor = colorProfile->toLinear(dstColor.unpremultiplied()).premultiplied(); + } + + blend_pixel(dstColor, srcLinear, coverage); + + if (colorProfile) { + if (dstColor.isOpaque()) + dstColor = colorProfile->fromLinear(dstColor); + else if (!dstColor.isTransparent()) + dstColor = colorProfile->fromLinear(dstColor.unpremultiplied()).premultiplied(); + } + dst = dstColor; +} + static inline void alphamapblend_generic(int coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile) { if (coverage == 0) { // nothing } else if (coverage == 255) { - dest[x] = src; + blend_pixel(dest[x], src); + } else if (src.isOpaque()) { + grayBlendPixel(dest[x], coverage, srcLinear, colorProfile); } else { - QRgba64 dstColor = dest[x]; - if (colorProfile) { - if (dstColor.isOpaque()) - dstColor = colorProfile->toLinear(dstColor); - else if (!dstColor.isTransparent()) - dstColor = colorProfile->toLinear(dstColor.unpremultiplied()).premultiplied(); - } - - dstColor = interpolate255(srcLinear, coverage, dstColor, 255 - coverage); - if (colorProfile) { - if (dstColor.isOpaque()) - dstColor = colorProfile->fromLinear(dstColor); - else if (!dstColor.isTransparent()) - dstColor = colorProfile->fromLinear(dstColor.unpremultiplied()).premultiplied(); - } - dest[x] = dstColor; + // First do naive blend with text-color + QRgba64 s = dest[x]; + blend_pixel(s, src); + // Then gamma-corrected blend with glyph shape + grayBlendPixel(dest[x], coverage, colorProfile->toLinear(s), colorProfile); } } @@ -5714,12 +5730,8 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer, colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text(); QRgba64 srcColor = color; - if (colorProfile) { - if (color.isOpaque()) - srcColor = colorProfile->toLinear(srcColor); - else - srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied(); - } + if (colorProfile && color.isOpaque()) + srcColor = colorProfile->toLinear(srcColor); alignas(8) QRgba64 buffer[BufferSize]; const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format]; @@ -5792,12 +5804,8 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer, colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text(); QRgba64 srcColor = color; - if (colorProfile) { - if (color.isOpaque()) - srcColor = colorProfile->toLinear(srcColor); - else - srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied(); - } + if (colorProfile && color.isOpaque()) + srcColor = colorProfile->toLinear(srcColor); quint32 buffer[BufferSize]; const DestFetchProc destFetch = destFetchProc[rasterBuffer->format]; @@ -5872,7 +5880,7 @@ void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer, int mapWidth, int mapHeight, int mapStride, const QClipData *clip, bool useGammaCorrection) { - if (useGammaCorrection) { + if (useGammaCorrection || !color.isOpaque()) { qt_alphamapblit_generic(rasterBuffer, x, y, color, map, mapWidth, mapHeight, mapStride, clip, useGammaCorrection); return; } @@ -5931,12 +5939,8 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer, colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text(); QRgba64 srcColor = color; - if (colorProfile) { - if (color.isOpaque()) - srcColor = colorProfile->toLinear(srcColor); - else - srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied(); - } + if (colorProfile && color.isOpaque()) + srcColor = colorProfile->toLinear(srcColor); if (!clip) { quint32 *dest = reinterpret_cast(rasterBuffer->scanLine(y)) + x; @@ -6031,48 +6035,59 @@ static inline QRgb rgbBlend(QRgb d, QRgb s, uint rgbAlpha) #endif } +static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorTrcLut *colorProfile) +{ + if (coverage == 0xff000000) { + // nothing + } else if (coverage == 0xffffffff && qAlpha(src) == 255) { + blend_pixel(*dst, src); + } else if (!colorProfile) { + *dst = rgbBlend(*dst, src, coverage); + } else if (*dst < 0xff000000) { + // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571 + blend_pixel(*dst, src, qRgbAvg(coverage)); + } else if (srcLinear.isOpaque()) { + rgbBlendPixel(dst, coverage, srcLinear, colorProfile); + } else { + // First do naive blend with text-color + QRgb s = *dst; + blend_pixel(s, src); + // Then gamma-corrected blend with glyph shape + rgbBlendPixel(dst, coverage, colorProfile->toLinear64(s), colorProfile); + } +} + #if QT_CONFIG(raster_64bit) +static inline void rgbBlendPixel(QRgba64 &dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile) +{ + // Do a gammacorrected RGB alphablend... + const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(dst) : dst; + + QRgba64 blend = rgbBlend(dlinear, slinear, coverage); + + dst = colorProfile ? colorProfile->fromLinear(blend) : blend; +} + static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile) { if (coverage == 0xff000000) { // nothing } else if (coverage == 0xffffffff) { - dest[x] = src; + blend_pixel(dest[x], src); + } else if (!dest[x].isOpaque()) { + // Do a gray alphablend. + alphamapblend_generic(qRgbAvg(coverage), dest, x, srcLinear, src, colorProfile); + } else if (src.isOpaque()) { + rgbBlendPixel(dest[x], coverage, srcLinear, colorProfile); } else { - QRgba64 dstColor = dest[x]; - if (dstColor.isOpaque()) { - if (colorProfile) - dstColor = colorProfile->toLinear(dstColor); - dstColor = rgbBlend(dstColor, srcLinear, coverage); - if (colorProfile) - dstColor = colorProfile->fromLinear(dstColor); - dest[x] = dstColor; - } else { - // Do a gray alphablend. - alphamapblend_generic(qRgbAvg(coverage), dest, x, srcLinear, src, colorProfile); - } - } -} -#endif - -static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorTrcLut *colorProfile) -{ - if (coverage == 0xff000000) { - // nothing - } else if (coverage == 0xffffffff) { - *dst = src; - } else if (*dst < 0xff000000) { - // Give up and do a naive gray alphablend. Needed to deal with ARGB32 and invalid ARGB32_premultiplied, see QTBUG-60571 - const int a = qRgbAvg(coverage); - *dst = INTERPOLATE_PIXEL_255(src, a, *dst, 255 - a); - } else if (!colorProfile) { - *dst = rgbBlend(*dst, src, coverage); - } else { - rgbBlendPixel(dst, coverage, srcLinear, colorProfile); + // First do naive blend with text-color + QRgba64 s = dest[x]; + blend_pixel(s, src); + // Then gamma-corrected blend with glyph shape + rgbBlendPixel(dest[x], coverage, colorProfile->toLinear(s), colorProfile); } } -#if QT_CONFIG(raster_64bit) static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer, int x, int y, const QRgba64 &color, const uint *src, int mapWidth, int mapHeight, int srcStride, @@ -6087,12 +6102,8 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer, colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text(); QRgba64 srcColor = color; - if (colorProfile) { - if (color.isOpaque()) - srcColor = colorProfile->toLinear(srcColor); - else - srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied(); - } + if (colorProfile && color.isOpaque()) + srcColor = colorProfile->toLinear(srcColor); alignas(8) QRgba64 buffer[BufferSize]; const DestFetchProc64 destFetch64 = destFetchProc64[rasterBuffer->format]; @@ -6164,12 +6175,8 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer, colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text(); QRgba64 srcColor = color; - if (colorProfile) { - if (color.isOpaque()) - srcColor = colorProfile->toLinear(srcColor); - else - srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied(); - } + if (colorProfile && color.isOpaque()) + srcColor = colorProfile->toLinear(srcColor); quint32 buffer[BufferSize]; const DestFetchProc destFetch = destFetchProc[rasterBuffer->format]; @@ -6242,12 +6249,8 @@ static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer, colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text(); QRgba64 srcColor = color; - if (colorProfile) { - if (color.isOpaque()) - srcColor = colorProfile->toLinear(srcColor); - else - srcColor = colorProfile->toLinear(srcColor.unpremultiplied()).premultiplied(); - } + if (colorProfile && color.isOpaque()) + srcColor = colorProfile->toLinear(srcColor); if (!clip) { quint32 *dst = reinterpret_cast(rasterBuffer->scanLine(y)) + x; diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 9c5d525722..dd42b96d79 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -671,6 +671,8 @@ static Q_ALWAYS_INLINE void blend_pixel(quint32 &dst, const quint32 src) static Q_ALWAYS_INLINE void blend_pixel(quint32 &dst, const quint32 src, const int const_alpha) { + if (const_alpha == 255) + return blend_pixel(dst, src); if (src != 0) { const quint32 s = BYTE_MUL(src, const_alpha); dst = s + BYTE_MUL(dst, qAlpha(~s)); diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 9894da8fe1..447ecb358a 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -842,8 +842,8 @@ void QRasterPaintEngine::updateRasterState() const QPainter::CompositionMode mode = s->composition_mode; s->flags.fast_text = (s->penData.type == QSpanData::Solid) && s->intOpacity == 256 - && (mode == QPainter::CompositionMode_Source - || (mode == QPainter::CompositionMode_SourceOver + && (mode == QPainter::CompositionMode_SourceOver + || (mode == QPainter::CompositionMode_Source && s->penData.solidColor.isOpaque())); } diff --git a/src/gui/painting/qrgba64_p.h b/src/gui/painting/qrgba64_p.h index ca879de27c..d145dbfbea 100644 --- a/src/gui/painting/qrgba64_p.h +++ b/src/gui/painting/qrgba64_p.h @@ -284,6 +284,8 @@ static Q_ALWAYS_INLINE void blend_pixel(QRgba64 &dst, QRgba64 src) static Q_ALWAYS_INLINE void blend_pixel(QRgba64 &dst, QRgba64 src, const int const_alpha) { + if (const_alpha == 255) + return blend_pixel(dst, src); if (!src.isTransparent()) { src = multiplyAlpha255(src, const_alpha); dst = src + multiplyAlpha65535(dst, 65535 - src.alpha()); From 60e20abf19f58c34cb3a878636d955993b81cf2e Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 17 Sep 2019 12:31:50 +0200 Subject: [PATCH 09/20] Add a RPi4 device spec [ChangeLog][Platform Specific Changes][Linux] Added a device spec for Raspberry Pi 4 (32-bit, V3D) Change-Id: Idea889842a89dcc74705f1bb9559953dadc07251 Reviewed-by: Eirik Aavitsland Reviewed-by: Andy Nichols --- .../devices/linux-rasp-pi4-v3d-g++/qmake.conf | 40 +++++++++++++++++++ .../linux-rasp-pi4-v3d-g++/qplatformdefs.h | 40 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 mkspecs/devices/linux-rasp-pi4-v3d-g++/qmake.conf create mode 100644 mkspecs/devices/linux-rasp-pi4-v3d-g++/qplatformdefs.h diff --git a/mkspecs/devices/linux-rasp-pi4-v3d-g++/qmake.conf b/mkspecs/devices/linux-rasp-pi4-v3d-g++/qmake.conf new file mode 100644 index 0000000000..69b0c761a8 --- /dev/null +++ b/mkspecs/devices/linux-rasp-pi4-v3d-g++/qmake.conf @@ -0,0 +1,40 @@ +# qmake configuration for the Raspberry Pi 4 (32-bit) using the Mesa V3D +# graphics stack. (not the Broadcom stack) +# +# This supports accelerated OpenGL both for X11 and DRM/KMS. Perhaps +# Wayland too. +# +# Tested with a sysroot created from Raspbian Buster and a gcc 7.4 +# toolchain from Linaro. +# +# Example configure command line, assuming installation to +# /usr/local/qt5pi on device and ~/rpi/qt5 on the host: +# +# ./configure -release -opengl es2 -device linux-rasp-pi4-v3d-g++ -device-option CROSS_COMPILE=~/rpi/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- \ +# -sysroot ~/rpi/sysroot -opensource -confirm-license -make libs -prefix /usr/local/qt5pi -extprefix ~/rpi/qt5 -v +# +# Check the configure output carefully. EGLFS, EGLFS GBM, and EGL on X11 +# should all be 'yes'. Otherwise something is wrong. +# +# If getting linker errors like "undefined reference to `_dl_stack_flags'" check the +# symlinks in the sysroot, they were probably not adjusted +# correctly. F.ex. sysroot/usr/lib/arm-linux-gnueabihf/libpthread.so must point to +# sysroot/lib/arm-linux-gnueabihf/libpthread.so.0. If it is a broken link instead, bad +# things will happen. + +include(../common/linux_device_pre.conf) + +QMAKE_LIBS_EGL += -lEGL +QMAKE_LIBS_OPENGL_ES2 += -lGLESv2 -lEGL + +QMAKE_CFLAGS = -march=armv8-a -mtune=cortex-a72 -mfpu=crypto-neon-fp-armv8 +QMAKE_CXXFLAGS = $$QMAKE_CFLAGS + +DISTRO_OPTS += hard-float +DISTRO_OPTS += deb-multi-arch + +EGLFS_DEVICE_INTEGRATION = eglfs_kms + +include(../common/linux_arm_device_post.conf) + +load(qt_config) diff --git a/mkspecs/devices/linux-rasp-pi4-v3d-g++/qplatformdefs.h b/mkspecs/devices/linux-rasp-pi4-v3d-g++/qplatformdefs.h new file mode 100644 index 0000000000..4435fb2557 --- /dev/null +++ b/mkspecs/devices/linux-rasp-pi4-v3d-g++/qplatformdefs.h @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../linux-g++/qplatformdefs.h" From 895a786827a0056398c07e3b668f35bd5952849e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Wed, 18 Sep 2019 10:46:58 +0200 Subject: [PATCH 10/20] Fix crash when using signaldumper and sender is deleted Testlib's signaldumper functionality would crash inside testlib as it dereferenced the sender after it was deleted. Change-Id: I6013b75b0a121e2768429d8a3cf0339a940314f2 Reviewed-by: Lars Knoll --- src/corelib/kernel/qobject.cpp | 7 ++++--- .../testlib/selftests/expected_signaldumper.lightxml | 9 ++++++++- .../auto/testlib/selftests/expected_signaldumper.tap | 12 +++++++----- .../testlib/selftests/expected_signaldumper.teamcity | 3 +++ .../auto/testlib/selftests/expected_signaldumper.txt | 6 ++++-- .../auto/testlib/selftests/expected_signaldumper.xml | 9 ++++++++- .../testlib/selftests/expected_signaldumper.xunitxml | 10 +++++++--- .../selftests/signaldumper/tst_signaldumper.cpp | 11 +++++++++++ 8 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 0b396343af..cf107498dd 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3908,11 +3908,12 @@ void doActivate(QObject *sender, int signal_index, void **argv) if (connections->currentConnectionId.loadRelaxed() == 0) senderDeleted = true; } - if (!senderDeleted) + if (!senderDeleted) { sp->connections.loadRelaxed()->cleanOrphanedConnections(sender); - if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr) - signal_spy_set->signal_end_callback(sender, signal_index); + if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr) + signal_spy_set->signal_end_callback(sender, signal_index); + } } /*! diff --git a/tests/auto/testlib/selftests/expected_signaldumper.lightxml b/tests/auto/testlib/selftests/expected_signaldumper.lightxml index f68834e1a2..443f649bb6 100644 --- a/tests/auto/testlib/selftests/expected_signaldumper.lightxml +++ b/tests/auto/testlib/selftests/expected_signaldumper.lightxml @@ -568,11 +568,18 @@ + + + + + + + - + diff --git a/tests/auto/testlib/selftests/expected_signaldumper.tap b/tests/auto/testlib/selftests/expected_signaldumper.tap index 04d7d94745..e2d664f4f1 100644 --- a/tests/auto/testlib/selftests/expected_signaldumper.tap +++ b/tests/auto/testlib/selftests/expected_signaldumper.tap @@ -143,9 +143,11 @@ ok 18 - slotEmittingSignalOldSyntax(queued) # Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant()) # Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant()) ok 19 - variousTypes() -ok 20 - cleanupTestCase() -# Signal: QThread(_POINTER_) finished () -1..20 -# tests 20 -# pass 20 +# Signal: SignalSlotClass(_POINTER_) signalWithoutParameters () +ok 20 - deletingSender() +ok 21 - cleanupTestCase() +# Signal: QThread(_POINTER_) finished () +1..21 +# tests 21 +# pass 21 # fail 0 diff --git a/tests/auto/testlib/selftests/expected_signaldumper.teamcity b/tests/auto/testlib/selftests/expected_signaldumper.teamcity index 3b8cf8c54f..0fc568e086 100644 --- a/tests/auto/testlib/selftests/expected_signaldumper.teamcity +++ b/tests/auto/testlib/selftests/expected_signaldumper.teamcity @@ -56,6 +56,9 @@ ##teamcity[testStarted name='variousTypes()' flowId='tst_Signaldumper'] ##teamcity[testStdOut name='variousTypes()' out='INFO: Signal: SignalSlotClass(_POINTER_) qStringSignal (QString(Test string))|nINFO: Signal: SignalSlotClass(_POINTER_) qStringRefSignal ((QString&)@_POINTER_)|nINFO: Signal: SignalSlotClass(_POINTER_) qStringConstRefSignal (QString(Test string))|nINFO: Signal: SignalSlotClass(_POINTER_) qByteArraySignal (QByteArray(Test bytearray))|nINFO: Signal: SignalSlotClass(_POINTER_) qListSignal (QList())|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorSignal (QVector())|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorRefSignal ((QVector&)@_POINTER_)|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorConstRefSignal (QVector())|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorConstPointerSignal ((const QVector*)_POINTER_)|nINFO: Signal: SignalSlotClass(_POINTER_) qVectorPointerConstSignal ()|nINFO: Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())|nINFO: Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant())' flowId='tst_Signaldumper'] ##teamcity[testFinished name='variousTypes()' flowId='tst_Signaldumper'] +##teamcity[testStarted name='deletingSender()' flowId='tst_Signaldumper'] +##teamcity[testStdOut name='deletingSender()' out='INFO: Signal: SignalSlotClass(_POINTER_) signalWithoutParameters ()' flowId='tst_Signaldumper'] +##teamcity[testFinished name='deletingSender()' flowId='tst_Signaldumper'] ##teamcity[testStarted name='cleanupTestCase()' flowId='tst_Signaldumper'] ##teamcity[testFinished name='cleanupTestCase()' flowId='tst_Signaldumper'] ##teamcity[testSuiteFinished name='tst_Signaldumper' flowId='tst_Signaldumper'] diff --git a/tests/auto/testlib/selftests/expected_signaldumper.txt b/tests/auto/testlib/selftests/expected_signaldumper.txt index f89c31afe5..0ee8cd38a2 100644 --- a/tests/auto/testlib/selftests/expected_signaldumper.txt +++ b/tests/auto/testlib/selftests/expected_signaldumper.txt @@ -143,7 +143,9 @@ INFO : tst_Signaldumper::variousTypes() Signal: SignalSlotClass(_POINTER_) qVe INFO : tst_Signaldumper::variousTypes() Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant()) INFO : tst_Signaldumper::variousTypes() Signal: SignalSlotClass(_POINTER_) qVariantSignal (QVariant()) PASS : tst_Signaldumper::variousTypes() +INFO : tst_Signaldumper::deletingSender() Signal: SignalSlotClass(_POINTER_) signalWithoutParameters () +PASS : tst_Signaldumper::deletingSender() PASS : tst_Signaldumper::cleanupTestCase() -INFO : tst_Signaldumper::UnknownTestFunc() Signal: QThread(_POINTER_) finished () -Totals: 20 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms +INFO : tst_Signaldumper::UnknownTestFunc() Signal: QThread(_POINTER_) finished () +Totals: 21 passed, 0 failed, 0 skipped, 0 blacklisted, 0ms ********* Finished testing of tst_Signaldumper ********* diff --git a/tests/auto/testlib/selftests/expected_signaldumper.xml b/tests/auto/testlib/selftests/expected_signaldumper.xml index 82959c62df..f11a0c3ce6 100644 --- a/tests/auto/testlib/selftests/expected_signaldumper.xml +++ b/tests/auto/testlib/selftests/expected_signaldumper.xml @@ -570,12 +570,19 @@ + + + + + + + - + diff --git a/tests/auto/testlib/selftests/expected_signaldumper.xunitxml b/tests/auto/testlib/selftests/expected_signaldumper.xunitxml index 930dc97262..cbf7075ba1 100644 --- a/tests/auto/testlib/selftests/expected_signaldumper.xunitxml +++ b/tests/auto/testlib/selftests/expected_signaldumper.xunitxml @@ -1,5 +1,5 @@ - + @@ -151,8 +151,11 @@ + + + - + @@ -279,6 +282,7 @@ - + + diff --git a/tests/auto/testlib/selftests/signaldumper/tst_signaldumper.cpp b/tests/auto/testlib/selftests/signaldumper/tst_signaldumper.cpp index f6cd0d510e..08592e222d 100644 --- a/tests/auto/testlib/selftests/signaldumper/tst_signaldumper.cpp +++ b/tests/auto/testlib/selftests/signaldumper/tst_signaldumper.cpp @@ -56,6 +56,8 @@ private slots: void slotEmittingSignalOldSyntax(); void variousTypes(); + + void deletingSender(); }; void tst_Signaldumper::addConnectionTypeData() @@ -413,5 +415,14 @@ void tst_Signaldumper::variousTypes() emit signalSlotOwner.qVariantSignal(variant); } +void tst_Signaldumper::deletingSender() +{ + SignalSlotClass *signalSlotOwner = new SignalSlotClass(); + connect(signalSlotOwner, &SignalSlotClass::signalWithoutParameters, [signalSlotOwner]() { + delete signalSlotOwner; + }); + emit signalSlotOwner->signalWithoutParameters(); +} + QTEST_MAIN(tst_Signaldumper) #include "tst_signaldumper.moc" From 6db83e2584a30b1339adba18279fbfd527a10ce7 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 23 Sep 2019 10:33:20 +0200 Subject: [PATCH 11/20] Fix crash with gamma-corrected text blending disabled Change-Id: I7e3ca78278bf8bf2dda44711eb57d64aa6f455ce Reviewed-by: Eirik Aavitsland --- src/gui/painting/qdrawhelper.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 3d06a27d8e..e5f752b94e 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -5670,7 +5670,8 @@ static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcL QRgb s = *dst; blend_pixel(s, src); // Then gamma-corrected blend with glyph shape - grayBlendPixel(dst, coverage, colorProfile->toLinear64(s), colorProfile); + QRgba64 s64 = colorProfile ? colorProfile->toLinear64(s) : QRgba64::fromArgb32(s); + grayBlendPixel(dst, coverage, s64, colorProfile); } } @@ -5711,7 +5712,9 @@ static inline void alphamapblend_generic(int coverage, QRgba64 *dest, int x, con QRgba64 s = dest[x]; blend_pixel(s, src); // Then gamma-corrected blend with glyph shape - grayBlendPixel(dest[x], coverage, colorProfile->toLinear(s), colorProfile); + if (colorProfile) + s = colorProfile->toLinear(s); + grayBlendPixel(dest[x], coverage, s, colorProfile); } } @@ -6053,7 +6056,8 @@ static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba QRgb s = *dst; blend_pixel(s, src); // Then gamma-corrected blend with glyph shape - rgbBlendPixel(dst, coverage, colorProfile->toLinear64(s), colorProfile); + QRgba64 s64 = colorProfile ? colorProfile->toLinear64(s) : QRgba64::fromArgb32(s); + rgbBlendPixel(dst, coverage, s64, colorProfile); } } @@ -6084,7 +6088,9 @@ static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, co QRgba64 s = dest[x]; blend_pixel(s, src); // Then gamma-corrected blend with glyph shape - rgbBlendPixel(dest[x], coverage, colorProfile->toLinear(s), colorProfile); + if (colorProfile) + s = colorProfile->toLinear(s); + rgbBlendPixel(dest[x], coverage, s, colorProfile); } } From 04dcc902eb64d94653a12005f3aedf32be1011c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 19 Sep 2019 18:09:52 +0200 Subject: [PATCH 12/20] macOS: Handle backing property changes in a single place Change-Id: I70d57632a1756f74249f64d4d4c405cb3120a179 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoawindow.h | 1 - src/plugins/platforms/cocoa/qcocoawindow.mm | 11 ---------- .../platforms/cocoa/qnsview_drawing.mm | 20 +++++++++++-------- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index c6ce6e6819..fef72bc496 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -161,7 +161,6 @@ public: Q_NOTIFICATION_HANDLER(NSWindowDidOrderOffScreenNotification) void windowDidOrderOffScreen(); Q_NOTIFICATION_HANDLER(NSWindowDidChangeOcclusionStateNotification) void windowDidChangeOcclusionState(); Q_NOTIFICATION_HANDLER(NSWindowDidChangeScreenNotification) void windowDidChangeScreen(); - Q_NOTIFICATION_HANDLER(NSWindowDidChangeBackingPropertiesNotification) void windowDidChangeBackingProperties(); Q_NOTIFICATION_HANDLER(NSWindowWillCloseNotification) void windowWillClose(); bool windowShouldClose(); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index db4bc12210..35b7162346 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1262,17 +1262,6 @@ void QCocoaWindow::windowDidChangeScreen() currentScreen->requestUpdate(); } } -/* - The window's backing scale factor or color space has changed. -*/ -void QCocoaWindow::windowDidChangeBackingProperties() -{ - // Ideally we would plumb this thought QPA in a way that lets clients - // invalidate their own caches, and recreate QBackingStore. For now we - // trigger an expose, and let QCocoaBackingStore deal with its own - // buffer invalidation. - [m_view setNeedsDisplay:YES]; -} void QCocoaWindow::windowWillClose() { diff --git a/src/plugins/platforms/cocoa/qnsview_drawing.mm b/src/plugins/platforms/cocoa/qnsview_drawing.mm index d2e6f848a0..de93e03685 100644 --- a/src/plugins/platforms/cocoa/qnsview_drawing.mm +++ b/src/plugins/platforms/cocoa/qnsview_drawing.mm @@ -211,17 +211,21 @@ - (void)viewDidChangeBackingProperties { - CALayer *layer = self.layer; - if (!layer) - return; + qCDebug(lcQpaDrawing) << "Backing properties changed for" << self; - layer.contentsScale = self.window.backingScaleFactor; + if (CALayer *layer = self.layer) { + layer.contentsScale = self.window.backingScaleFactor; - // Metal layers must be manually updated on e.g. screen change - if ([layer isKindOfClass:CAMetalLayer.class]) { - [self updateMetalLayerDrawableSize:static_cast(layer)]; - [self setNeedsDisplay:YES]; + // Metal layers must be manually updated on e.g. screen change + if ([layer isKindOfClass:CAMetalLayer.class]) + [self updateMetalLayerDrawableSize:static_cast(layer)]; } + + // Ideally we would plumb this situation through QPA in a way that lets + // clients invalidate their own caches, recreate QBackingStore, etc. + // For now we trigger an expose, and let QCocoaBackingStore deal with + // buffer invalidation internally. + [self setNeedsDisplay:YES]; } @end From 0642ca3528b1020acf1deadf8bf6d374c0db05f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 19 Sep 2019 18:15:18 +0200 Subject: [PATCH 13/20] macOS: Don't update Metal layer's drawableSize automatically MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Like our other rendering code paths, the Metal path should allow the user to resize their surface when they see fit. This is the case today with e.g QBackingStore::resize() and QOpenGLPaintDevice::setSize(). [ChangeLog][macOS] The drawableSize of Metal layers is no longer updated automatically on window resize or screen change. Update the size manually in response to resizeEvent(), or at the start of each frame, as needed. Change-Id: I9ed6d4326d0e0a3f4e3c63984d3b193e8bb77cae Reviewed-by: Morten Johan Sørvig --- .../platforms/cocoa/qnsview_drawing.mm | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview_drawing.mm b/src/plugins/platforms/cocoa/qnsview_drawing.mm index de93e03685..e72142466b 100644 --- a/src/plugins/platforms/cocoa/qnsview_drawing.mm +++ b/src/plugins/platforms/cocoa/qnsview_drawing.mm @@ -173,20 +173,6 @@ } #endif -- (void)updateMetalLayerDrawableSize:(CAMetalLayer *)layer -{ - CGSize drawableSize = layer.bounds.size; - drawableSize.width *= layer.contentsScale; - drawableSize.height *= layer.contentsScale; - layer.drawableSize = drawableSize; -} - -- (void)layoutSublayersOfLayer:(CALayer *)layer -{ - if ([layer isKindOfClass:CAMetalLayer.class]) - [self updateMetalLayerDrawableSize:static_cast(layer)]; -} - - (void)displayLayer:(CALayer *)layer { if (!NSThread.isMainThread) { @@ -213,13 +199,8 @@ { qCDebug(lcQpaDrawing) << "Backing properties changed for" << self; - if (CALayer *layer = self.layer) { - layer.contentsScale = self.window.backingScaleFactor; - - // Metal layers must be manually updated on e.g. screen change - if ([layer isKindOfClass:CAMetalLayer.class]) - [self updateMetalLayerDrawableSize:static_cast(layer)]; - } + if (self.layer) + self.layer.contentsScale = self.window.backingScaleFactor; // Ideally we would plumb this situation through QPA in a way that lets // clients invalidate their own caches, recreate QBackingStore, etc. From 2dfeea921b8ac9fef92db8fab7b518f3f5994512 Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Mon, 23 Sep 2019 13:48:30 +0200 Subject: [PATCH 14/20] Avoid unused parameter 'grab' warnings Android (5220042 based on r346389c) clang version 8.0.7: src/plugins/platforms/android/qandroidplatformwindow.h:68:35: error: unused parameter 'grab' [-Werror,-Wunused-parameter] bool setMouseGrabEnabled(bool grab) override { return false; } ^ src/plugins/platforms/android/qandroidplatformwindow.h:69:38: error: unused parameter 'grab' [-Werror,-Wunused-parameter] bool setKeyboardGrabEnabled(bool grab) override { return false; } ^ Change-Id: I4d8a18d5e3bfbc13c05b47f0cdfe10370673e359 Reviewed-by: Ville Voutilainen --- src/plugins/platforms/android/qandroidplatformwindow.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/android/qandroidplatformwindow.h b/src/plugins/platforms/android/qandroidplatformwindow.h index 5edd274759..d8eb6b7b7f 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.h +++ b/src/plugins/platforms/android/qandroidplatformwindow.h @@ -65,8 +65,8 @@ public: void setParent(const QPlatformWindow *window) override; WId winId() const override { return m_windowId; } - bool setMouseGrabEnabled(bool grab) override { return false; } - bool setKeyboardGrabEnabled(bool grab) override { return false; } + bool setMouseGrabEnabled(bool grab) override { Q_UNUSED(grab); return false; } + bool setKeyboardGrabEnabled(bool grab) override { Q_UNUSED(grab); return false; } QAndroidPlatformScreen *platformScreen() const; From 35aec918c15d50893dd4e403e400f37e6a2d7c6f Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 18 Sep 2019 11:32:50 +0200 Subject: [PATCH 15/20] Rearrange tst_QNumeric's tests for infinity and (quiet) NaN Separate quiet NaN from infinity and expand the nan-with-payload test to a general test that bits outside the exponent don't break qIsNan(). Generally test more thoroughly and systematically. Tests for signalling NaN shall follow. Change-Id: Ib35dabacc8ebcc9a0761df38f6f419f0398d0e20 Reviewed-by: Erik Verbruggen --- .../corelib/global/qnumeric/tst_qnumeric.cpp | 118 +++++++++++++----- 1 file changed, 88 insertions(+), 30 deletions(-) diff --git a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp index 0a84b1fdd8..5697d21547 100644 --- a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp +++ b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp @@ -42,7 +42,11 @@ class tst_QNumeric: public QObject private slots: void fuzzyCompare_data(); void fuzzyCompare(); - void qNanInf(); + void rawNaN_data(); + void rawNaN(); + void generalNaN_data(); + void generalNaN(); + void infinity(); void classifyfp(); void floatDistance_data(); void floatDistance(); @@ -53,6 +57,8 @@ private slots: void mulOverflow_data(); void mulOverflow(); void signedOverflow(); +private: + void checkNaN(double nan); }; void tst_QNumeric::fuzzyCompare_data() @@ -92,44 +98,89 @@ void tst_QNumeric::fuzzyCompare() # pragma GCC optimize "no-fast-math" #endif -void tst_QNumeric::qNanInf() +void tst_QNumeric::checkNaN(double nan) { -#if defined __FAST_MATH__ && (__GNUC__ * 100 + __GNUC_MINOR__ < 404) - QSKIP("Non-conformant fast math mode is enabled, cannot run test"); -#endif - double nan = qQNaN(); +#define CHECKNAN(value) \ + do { \ + const double v = (value); \ + QCOMPARE(qFpClassify(v), FP_NAN); \ + QVERIFY(qIsNaN(v)); \ + QVERIFY(!qIsFinite(v)); \ + QVERIFY(!qIsInf(v)); \ + } while (0) + QVERIFY(!(0 > nan)); QVERIFY(!(0 < nan)); QVERIFY(!(0 == nan)); QVERIFY(!(nan == nan)); - QVERIFY(qIsNaN(nan)); - QVERIFY(qIsNaN(nan + 1)); - QVERIFY(qIsNaN(-nan)); - QVERIFY(qIsNaN(1.0 / nan)); - QVERIFY(qIsNaN(0.0 / nan)); - QVERIFY(qIsNaN(0.0 * nan)); - QCOMPARE(nan, nan); - QCOMPARE(nan, -nan); - Q_STATIC_ASSERT(sizeof(double) == 8); -#ifdef Q_LITTLE_ENDIAN - const uchar bytes[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f }; -#else - const uchar bytes[] = { 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }; -#endif - memcpy(&nan, bytes, 8); - QVERIFY(!qIsFinite(nan)); - QVERIFY(!qIsInf(nan)); - QVERIFY(qIsNaN(nan)); - QVERIFY(qIsNaN(-nan)); - QVERIFY(!(nan == nan)); - QVERIFY(qIsNaN(0.0 * nan)); - QCOMPARE(qFpClassify(nan), FP_NAN); + CHECKNAN(nan); + CHECKNAN(nan + 1); + CHECKNAN(nan - 1); + CHECKNAN(-nan); + CHECKNAN(nan * 2.0); + CHECKNAN(nan / 2.0); + CHECKNAN(1.0 / nan); + CHECKNAN(0.0 / nan); + CHECKNAN(0.0 * nan); + + // When any NaN is expected, any NaN will do: QCOMPARE(nan, nan); QCOMPARE(nan, -nan); QCOMPARE(nan, qQNaN()); +#undef CHECKNAN +} - double inf = qInf(); +void tst_QNumeric::rawNaN_data() +{ +#if defined __FAST_MATH__ && (__GNUC__ * 100 + __GNUC_MINOR__ < 404) + QSKIP("Non-conformant fast math mode is enabled, cannot run test"); +#endif + QTest::addColumn("nan"); + + QTest::newRow("quiet") << qQNaN(); +} + +void tst_QNumeric::rawNaN() +{ + QFETCH(double, nan); + checkNaN(nan); +} + +void tst_QNumeric::generalNaN_data() +{ + QTest::addColumn("most"); + QTest::addColumn("next"); + QTest::addColumn("least"); + // Every value with every bit of the exponent set is a NaN. + // Sign and mantissa can be anything without interfering with that. + // The 0x7f bits of most and the 0xf0 bits of next are the exponent. + + QTest::newRow("lowload") << 0x7f << 0xf0 << 1; + QTest::newRow("sign-lowload") << 0xff << 0xf0 << 1; + QTest::newRow("highload") << 0x7f << 0xf1 << 0; + QTest::newRow("sign-highload") << 0xff << 0xf1 << 0; +} + +void tst_QNumeric::generalNaN() +{ + QFETCH(int, most); + QFETCH(int, next); + QFETCH(int, least); + double nan; + Q_STATIC_ASSERT(sizeof(double) == 8); +#ifdef Q_LITTLE_ENDIAN + const uchar bytes[] = { uchar(least), 0, 0, 0, 0, 0, uchar(next), uchar(most) }; +#else + const uchar bytes[] = { uchar(most), uchar(next), 0, 0, 0, 0, 0, uchar(least) }; +#endif + memcpy(&nan, bytes, 8); + checkNaN(nan); +} + +void tst_QNumeric::infinity() +{ + const double inf = qInf(); QVERIFY(inf > 0); QVERIFY(-inf < 0); QVERIFY(qIsInf(inf)); @@ -138,16 +189,23 @@ void tst_QNumeric::qNanInf() QVERIFY(qIsInf(-inf)); QVERIFY(qIsInf(inf + 1)); QVERIFY(qIsInf(inf - 1)); + QVERIFY(qIsInf(-inf - 1)); + QVERIFY(qIsInf(-inf + 1)); QVERIFY(qIsInf(inf * 2.0)); + QVERIFY(qIsInf(-inf * 2.0)); QVERIFY(qIsInf(inf / 2.0)); + QVERIFY(qIsInf(-inf / 2.0)); QVERIFY(qFuzzyCompare(1.0 / inf, 0.0)); QCOMPARE(1.0 / inf, 0.0); + QVERIFY(qFuzzyCompare(1.0 / -inf, 0.0)); + QCOMPARE(1.0 / -inf, 0.0); QVERIFY(qIsNaN(0.0 * inf)); + QVERIFY(qIsNaN(0.0 * -inf)); } void tst_QNumeric::classifyfp() { - QCOMPARE(qFpClassify(qQNaN()), FP_NAN); + // NaNs already handled, see checkNaN()'s callers. QCOMPARE(qFpClassify(qInf()), FP_INFINITE); QCOMPARE(qFpClassify(-qInf()), FP_INFINITE); From b8d8e0dfbbf721604eaa340b3bc47e5a574228fb Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 20 Sep 2019 15:58:02 +0200 Subject: [PATCH 16/20] Follow platform plugin change wrt layer size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Have to set the drawableSize ourselves. This is not yet fully correct in the sense that does not ensure what the platform plugin patch tries to enable, namely atomic frames when it comes to the drawable size. Going to fix that up in separate patches, maybe it will need some QRhi API changes as well so won't mix that in here. Change-Id: I47a3816930bc6a87a2c96d4a6c4c85b2577147dc Reviewed-by: Tor Arne Vestbø --- src/gui/rhi/qrhimetal.mm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 0b1ab72c2c..bfd6944cdb 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -3524,7 +3524,10 @@ QSize QMetalSwapChain::surfacePixelSize() if (v) { CAMetalLayer *layer = (CAMetalLayer *) [v layer]; if (layer) { - CGSize size = [layer drawableSize]; + CGSize size = layer.bounds.size; + size.width *= layer.contentsScale; + size.height *= layer.contentsScale; + layer.drawableSize = size; return QSize(int(size.width), int(size.height)); } } From 22742c5f21ba5d9396c08d40c2f4471ae3382387 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 19 Sep 2019 13:51:27 +0200 Subject: [PATCH 17/20] Include missing shbang line in executable shell script Change-Id: I802665c89fcac9e07e745cf6dce1a04404ae764d Reviewed-by: Laszlo Agocs --- tests/manual/rhi/shadowmap/buildshaders.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/manual/rhi/shadowmap/buildshaders.sh b/tests/manual/rhi/shadowmap/buildshaders.sh index c4d17841e6..8991bb074a 100755 --- a/tests/manual/rhi/shadowmap/buildshaders.sh +++ b/tests/manual/rhi/shadowmap/buildshaders.sh @@ -1,3 +1,4 @@ +#!/bin/sh qsb --glsl "120,300 es" --hlsl 50 --msl 12 shadowmap.vert -o shadowmap.vert.qsb qsb --glsl "120,300 es" --hlsl 50 --msl 12 shadowmap.frag -o shadowmap.frag.qsb qsb --glsl "120,300 es" --hlsl 50 --msl 12 main.vert -o main.vert.qsb From da46ea92e537501c932343f65e11032a2f5984f3 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 11 Sep 2019 09:40:17 +0200 Subject: [PATCH 18/20] doc: add a note to QFileSystemWatcher about files saved by re-creation Fixes: QTBUG-46483 Fixes: QTBUG-53607 Change-Id: I434f177b35689d55aa1deea360bf7e6ae009ad68 Reviewed-by: Venugopal Shivashankar --- src/corelib/io/qfilesystemwatcher.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp index a4705136a2..54460aff77 100644 --- a/src/corelib/io/qfilesystemwatcher.cpp +++ b/src/corelib/io/qfilesystemwatcher.cpp @@ -451,6 +451,12 @@ QStringList QFileSystemWatcher::removePaths(const QStringList &paths) This signal is emitted when the file at the specified \a path is modified, renamed or removed from disk. + \note As a safety measure, many applications save an open file by + writing a new file and then deleting the old one. In your slot + function, you can check \c watcher.files().contains(path). + If it returns \c false, check whether the file still exists + and then call \c addPath() to continue watching it. + \sa directoryChanged() */ From 1d1ed017119df2cd28a9e21aee0a8cece5282250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 20 Sep 2019 14:28:49 +0200 Subject: [PATCH 19/20] Xcode: Ensure there's always a CFBundle[Short]Version[String] set Leaving it empty resulted in errors from Xcode when compiling the app. Task-number: QTBUG-25309 Task-number: QTBUG-74872 Change-Id: I61b0f47d754c5f5b181a6f918283d990458cc78d Reviewed-by: Joerg Bornemann --- mkspecs/features/mac/default_post.prf | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf index 26bd3e2e98..993f4d56a9 100644 --- a/mkspecs/features/mac/default_post.prf +++ b/mkspecs/features/mac/default_post.prf @@ -97,21 +97,22 @@ macx-xcode { qmake_pkginfo_typeinfo.value = "????" QMAKE_MAC_XCODE_SETTINGS += qmake_pkginfo_typeinfo - !isEmpty(VERSION) { - l = $$split(VERSION, '.') 0 0 # make sure there are at least three - VER_MAJ = $$member(l, 0, 0) - VER_MIN = $$member(l, 1, 1) - VER_PAT = $$member(l, 2, 2) - unset(l) + bundle_version = $$VERSION + isEmpty(bundle_version): bundle_version = 1.0.0 - qmake_full_version.name = QMAKE_FULL_VERSION - qmake_full_version.value = $${VER_MAJ}.$${VER_MIN}.$${VER_PAT} - QMAKE_MAC_XCODE_SETTINGS += qmake_full_version + l = $$split(bundle_version, '.') 0 0 # make sure there are at least three + VER_MAJ = $$member(l, 0, 0) + VER_MIN = $$member(l, 1, 1) + VER_PAT = $$member(l, 2, 2) + unset(l) - qmake_short_version.name = QMAKE_SHORT_VERSION - qmake_short_version.value = $${VER_MAJ}.$${VER_MIN} - QMAKE_MAC_XCODE_SETTINGS += qmake_short_version - } + qmake_full_version.name = QMAKE_FULL_VERSION + qmake_full_version.value = $${VER_MAJ}.$${VER_MIN}.$${VER_PAT} + QMAKE_MAC_XCODE_SETTINGS += qmake_full_version + + qmake_short_version.name = QMAKE_SHORT_VERSION + qmake_short_version.value = $${VER_MAJ}.$${VER_MIN} + QMAKE_MAC_XCODE_SETTINGS += qmake_short_version !isEmpty(QMAKE_XCODE_DEBUG_INFORMATION_FORMAT) { debug_information_format.name = DEBUG_INFORMATION_FORMAT From 70c053ee684448984b1f762abd3b40884cece2fa Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 20 Sep 2019 22:27:44 +0200 Subject: [PATCH 20/20] QAbstractSpinBox css: properly honor spincontrol-disable-on-bounds The css style 'spincontrol-disable-on-bounds' was not properly honored within QAbstractSpinBox::initStyleOption() because the affected widget was not passed to QStyle::styleHint(). Therefore QStyleSheetStyle did not find the correct render rule. Fix it by passing 'this' as third argument to QStyle::styleHint(). Fixes: QTBUG-18008 Change-Id: Iabcebf0b83143f45309b4e7066bccb8d20bd0419 Reviewed-by: Eirik Aavitsland --- src/widgets/widgets/qabstractspinbox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index d49d9dbd66..fc19e0793e 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -1726,7 +1726,7 @@ void QAbstractSpinBox::initStyleOption(QStyleOptionSpinBox *option) const option->activeSubControls = d->hoverControl; } - option->stepEnabled = style()->styleHint(QStyle::SH_SpinControls_DisableOnBounds) + option->stepEnabled = style()->styleHint(QStyle::SH_SpinControls_DisableOnBounds, nullptr, this) ? stepEnabled() : (QAbstractSpinBox::StepDownEnabled|QAbstractSpinBox::StepUpEnabled);