From 1f451da9d7ec33dd38b13ca4f98d8453cf7814de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 25 Jun 2019 10:01:00 +0200 Subject: [PATCH 001/264] Revert "Temporarily skip tst_QSslSocket::resume" This reverts commit 9a25d27b9d58316dee5d2305135d2d74ad5d51e7. The QSKIP is no longer needed as the imap server's certificate was updated Task-number: QTBUG-76610 Change-Id: I1007ce50d6f7f6258fdeb8894c66678a660b03ca Reviewed-by: Timur Pocheptsov --- tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index 7420cd1296..307e3d82bd 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -2780,7 +2780,6 @@ void tst_QSslSocket::encryptWithoutConnecting() void tst_QSslSocket::resume_data() { - QSKIP("Temporary skip while updating certificates"); QTest::addColumn("ignoreErrorsAfterPause"); QTest::addColumn >("errorsToIgnore"); QTest::addColumn("expectSuccess"); From 1a14f7e91b065ed287a4982d4bea0027121926f4 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Wed, 3 Jul 2019 13:41:13 +0200 Subject: [PATCH 002/264] Windows QPA: Fix Wheel event coordinates In some cases, the wheel event coordinates would be incorrect, as the local coordinates were being determined relative to one window and the event being sent to another window, possibly incorrect. Fixes: QTBUG-75820 Change-Id: I4c3c4c6c4688bd9232d67ce4052d24365f6aea3a Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowspointerhandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 8b88007949..b35629e2ce 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -684,7 +684,7 @@ bool QWindowsPointerHandler::translateMouseWheelEvent(QWindow *window, QPoint localPos = QWindowsGeometryHint::mapFromGlobal(receiver, globalPos); - QWindowSystemInterface::handleWheelEvent(window, localPos, globalPos, QPoint(), angleDelta, keyModifiers); + QWindowSystemInterface::handleWheelEvent(receiver, localPos, globalPos, QPoint(), angleDelta, keyModifiers); return true; } From cc873ec23a98ac32d10ac5fa569792fde2f6b2c8 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Wed, 3 Jul 2019 18:20:17 +0200 Subject: [PATCH 003/264] Windows QPA: Fix blinking dot on Windows 7/8/8.1 A blinking white dot could appear on dark backgrounds on Windows 7/8/8.1. It was caused by a workaround added to trigger the on-screen keyboard on the Microsoft Surface. This change effectively restricts that workaround to Windows 10, where the blinking dot was not an issue. And anyway, impact over the Surface functionality should be minimal, as all models produced since 2015 only support Windows 10 (and it's unknown if the workaround was ever necessary for early models running Windows 8.1). Fixes: QTBUG-74492 Change-Id: Ic9b9c0f71f23b75212054c56a29796cf0efa109a Reviewed-by: Volker Hilsheimer Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowsinputcontext.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index 8adcf56b11..61f971143d 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -279,7 +280,13 @@ void QWindowsInputContext::showInputPanel() // with Windows 10 if the Windows IME is (re)enabled _after_ the caret is shown. if (m_caretCreated) { cursorRectChanged(); - ShowCaret(platformWindow->handle()); + // We only call ShowCaret() on Windows 10 as in earlier versions the caret + // would actually be visible (QTBUG-74492) and the workaround for the + // Surface seems unnecessary there anyway. But leave it hidden for IME. + if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10) + ShowCaret(platformWindow->handle()); + else + HideCaret(platformWindow->handle()); setWindowsImeEnabled(platformWindow, false); setWindowsImeEnabled(platformWindow, true); } From 11d9af5d957ac391a0c6cfdea4819df44b2b1560 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 4 Jul 2019 10:54:21 +0200 Subject: [PATCH 004/264] Unbreak the -silent build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The header clean command must not be prefixed by "@echo ...", because it now starts with "$(CXX)" which already is prefixed. This amends commit 6fa5dfdd. Change-Id: I5c2e0d2c2ed91c7232fce0a4a49db0fccfdc005d Reviewed-by: Tor Arne Vestbø --- mkspecs/features/qt_module_headers.prf | 1 - 1 file changed, 1 deletion(-) diff --git a/mkspecs/features/qt_module_headers.prf b/mkspecs/features/qt_module_headers.prf index 899a40103a..7ee1a956f4 100644 --- a/mkspecs/features/qt_module_headers.prf +++ b/mkspecs/features/qt_module_headers.prf @@ -304,7 +304,6 @@ headersclean:!internal_module { header_check.variable_out = PRE_TARGETDEPS header_check.name = headercheck ${QMAKE_FILE_IN} header_check.commands = $$hcleanCOMMAND - silent:header_check.commands = @echo compiling[header] ${QMAKE_FILE_IN} && $$hcleanCOMMAND QMAKE_EXTRA_COMPILERS += header_check } unset(hcleanCOMMAND) From adaa997ce654bc7d488e887c9b7a971fc037a775 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Bornemann?= Date: Thu, 4 Jul 2019 13:30:23 +0000 Subject: [PATCH 005/264] Revert "Fix determination of source and build roots" This reverts commit 224a60989ed95e8b91ac88a12666af6e5a66e619. Turns out that we cannot just untangle the determination of source root and build root, because this breaks the assumption that every .qmake.conf results in a separate .qmake.cache in the build tree. QTBUG-76140 must be fixed differently. Fixes: QTBUG-76907 Change-Id: I5c0a3719d5e00a0f1cacad51651b47c1f284d22d Reviewed-by: Alexandru Croitor --- qmake/library/qmakeevaluator.cpp | 39 +++++++++++--------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index 09c1f80222..432339d48e 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -1128,48 +1128,35 @@ bool QMakeEvaluator::prepareProject(const QString &inDir) } superdir = qdfi.path(); } + QString sdir = inDir; QString dir = m_outputDir; forever { + conffile = sdir + QLatin1String("/.qmake.conf"); + if (!m_vfs->exists(conffile, flags)) + conffile.clear(); cachefile = dir + QLatin1String("/.qmake.cache"); if (!m_vfs->exists(cachefile, flags)) cachefile.clear(); - if (!cachefile.isEmpty()) { + if (!conffile.isEmpty() || !cachefile.isEmpty()) { + if (dir != sdir) + m_sourceRoot = sdir; m_buildRoot = dir; break; } if (dir == superdir) goto no_cache; - QFileInfo qdfi(dir); - if (qdfi.isRoot()) { - cachefile.clear(); - break; - } - dir = qdfi.path(); - } - QString sdir = inDir; - forever { - conffile = sdir + QLatin1String("/.qmake.conf"); - if (!m_vfs->exists(conffile, flags)) - conffile.clear(); - if (!conffile.isEmpty()) { - if (sdir != m_buildRoot) - m_sourceRoot = sdir; - break; - } QFileInfo qsdfi(sdir); - if (qsdfi.isRoot()) { - conffile.clear(); - break; - } + QFileInfo qdfi(dir); + if (qsdfi.isRoot() || qdfi.isRoot()) + goto no_cache; sdir = qsdfi.path(); + dir = qdfi.path(); } } else { m_buildRoot = QFileInfo(cachefile).path(); } - if (!conffile.isEmpty()) - m_conffile = QDir::cleanPath(conffile); - if (!cachefile.isEmpty()) - m_cachefile = QDir::cleanPath(cachefile); + m_conffile = QDir::cleanPath(conffile); + m_cachefile = QDir::cleanPath(cachefile); } no_cache: From 72ebc7458dabe61c5231456d72a81ec7234a5785 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 28 Jun 2019 10:44:12 +0200 Subject: [PATCH 006/264] Enable ccache for non-Unix target platforms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the config.unix condition from the ccache feature. This enables us to use ccache for non-Unix cross-builds like MinGW on Linux. Change-Id: I3b108c2288754ad5dd05834e3d5a487c2da4ac00 Fixes: QTBUG-76681 Reviewed-by: Kai Koehne Reviewed-by: Tor Arne Vestbø --- configure.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.json b/configure.json index c93bea46bc..525cb5a12c 100644 --- a/configure.json +++ b/configure.json @@ -1230,7 +1230,7 @@ "ccache": { "label": "Using ccache", "autoDetect": false, - "condition": "config.unix && tests.ccache", + "condition": "tests.ccache", "output": [ "privateConfig" ] }, "msvc_mp": { From 78caba7ae637bf4b33631c3425eb92ec3946c99e Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 20 Jun 2019 14:52:19 +0200 Subject: [PATCH 007/264] Support pen color with color fonts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Color fonts may also contain regular alphabet characters that should be rendered with the current pen. In Qt, however, these characters were drawn into the cache with a default pen color of black. Since all characters in a font is currently backed by the same cache, and it would require a lot of plumbing to get around this, a step in the right direction is to include the current pen color in the cache as long as it is an RGB cache. This means that drawing text with the color font with different pen colors will create different caches. There is no API to select font color on Freetype currently, but this problem has also not been observed there, as the fonts in question, with both regular and color glyphs, are not being detected as color fonts (so the text color will be correct). So Freetype will be left out for now. [ChangeLog][QtGui][Text] Fixed bug where regular text rendered with a color font would always display in black. Task-number: QTBUG-55096 Task-number: QTBUG-74761 Change-Id: Icc7dbf73241db1e7cc6a0de18c2de927aeecf713 Reviewed-by: Tor Arne Vestbø --- src/gui/painting/qpaintengine_raster.cpp | 4 +- src/gui/painting/qtextureglyphcache.cpp | 2 +- src/gui/painting/qtextureglyphcache_p.h | 8 ++-- src/gui/text/qfontengine.cpp | 12 ++++-- src/gui/text/qfontengine_p.h | 4 +- src/gui/text/qfontengineglyphcache_p.h | 7 +++- .../fontdatabases/freetype/qfontengine_ft.cpp | 4 +- .../fontdatabases/freetype/qfontengine_ft_p.h | 2 +- .../fontdatabases/mac/qfontengine_coretext.mm | 10 +++-- .../mac/qfontengine_coretext_p.h | 4 +- .../windows/qwindowsfontenginedirectwrite.cpp | 42 ++++++++++++++----- .../windows/qwindowsfontenginedirectwrite_p.h | 4 +- 12 files changed, 69 insertions(+), 34 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 76c5842f58..096e4a5c5b 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -2927,9 +2927,9 @@ bool QRasterPaintEngine::drawCachedGlyphs(int numGlyphs, const glyph_t *glyphs, QFontEngine::GlyphFormat glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None ? fontEngine->glyphFormat : d->glyphCacheFormat; QImageTextureGlyphCache *cache = - static_cast(fontEngine->glyphCache(0, glyphFormat, s->matrix)); + static_cast(fontEngine->glyphCache(0, glyphFormat, s->matrix, QColor(s->penData.solid.color))); if (!cache) { - cache = new QImageTextureGlyphCache(glyphFormat, s->matrix); + cache = new QImageTextureGlyphCache(glyphFormat, s->matrix, QColor(s->penData.solid.color)); fontEngine->setGlyphCache(0, cache); } diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 99b04aaba6..06fa4bf95e 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -267,7 +267,7 @@ QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition case QFontEngine::Format_A32: return m_current_fontengine->alphaRGBMapForGlyph(g, subPixelPosition, m_transform); case QFontEngine::Format_ARGB: - return m_current_fontengine->bitmapForGlyph(g, subPixelPosition, m_transform); + return m_current_fontengine->bitmapForGlyph(g, subPixelPosition, m_transform, color()); default: return m_current_fontengine->alphaMapForGlyph(g, subPixelPosition, m_transform); } diff --git a/src/gui/painting/qtextureglyphcache_p.h b/src/gui/painting/qtextureglyphcache_p.h index 3da28872b1..c105e89e50 100644 --- a/src/gui/painting/qtextureglyphcache_p.h +++ b/src/gui/painting/qtextureglyphcache_p.h @@ -74,8 +74,8 @@ class QTextItemInt; class Q_GUI_EXPORT QTextureGlyphCache : public QFontEngineGlyphCache { public: - QTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix) - : QFontEngineGlyphCache(format, matrix), m_current_fontengine(0), + QTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix, const QColor &color = QColor()) + : QFontEngineGlyphCache(format, matrix, color), m_current_fontengine(0), m_w(0), m_h(0), m_cx(0), m_cy(0), m_currentRowHeight(0) { } @@ -165,8 +165,8 @@ inline uint qHash(const QTextureGlyphCache::GlyphAndSubPixelPosition &g) class Q_GUI_EXPORT QImageTextureGlyphCache : public QTextureGlyphCache { public: - QImageTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix) - : QTextureGlyphCache(format, matrix) { } + QImageTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix, const QColor &color = QColor()) + : QTextureGlyphCache(format, matrix, color) { } ~QImageTextureGlyphCache(); virtual void createTextureData(int width, int height) override; diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index eb7e416dd1..5506d88f02 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -899,7 +899,7 @@ QImage QFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed /*subPixelPosition return rgbMask; } -QImage QFontEngine::bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform&) +QImage QFontEngine::bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform&, const QColor &) { Q_UNUSED(subPixelPosition); @@ -1075,7 +1075,10 @@ void QFontEngine::setGlyphCache(const void *context, QFontEngineGlyphCache *cach } -QFontEngineGlyphCache *QFontEngine::glyphCache(const void *context, GlyphFormat format, const QTransform &transform) const +QFontEngineGlyphCache *QFontEngine::glyphCache(const void *context, + GlyphFormat format, + const QTransform &transform, + const QColor &color) const { const QHash::const_iterator caches = m_glyphCaches.constFind(context); if (caches == m_glyphCaches.cend()) @@ -1083,8 +1086,11 @@ QFontEngineGlyphCache *QFontEngine::glyphCache(const void *context, GlyphFormat for (GlyphCaches::const_iterator it = caches->begin(), end = caches->end(); it != end; ++it) { QFontEngineGlyphCache *cache = it->cache.data(); - if (format == cache->glyphFormat() && qtransform_equals_no_translate(cache->m_transform, transform)) + if (format == cache->glyphFormat() + && (format != Format_ARGB || color == cache->color()) + && qtransform_equals_no_translate(cache->m_transform, transform)) { return cache; + } } return nullptr; diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 708c79c2ae..682395ece6 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -190,7 +190,7 @@ public: virtual QImage alphaMapForGlyph(glyph_t, const QTransform &t); virtual QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t); virtual QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t); - virtual QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t); + virtual QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color = QColor()); virtual QImage *lockedAlphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, GlyphFormat neededFormat, const QTransform &t = QTransform(), @@ -252,7 +252,7 @@ public: void clearGlyphCache(const void *key); void setGlyphCache(const void *key, QFontEngineGlyphCache *data); - QFontEngineGlyphCache *glyphCache(const void *key, GlyphFormat format, const QTransform &transform) const; + QFontEngineGlyphCache *glyphCache(const void *key, GlyphFormat format, const QTransform &transform, const QColor &color = QColor()) const; static const uchar *getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize); static quint32 getTrueTypeGlyphIndex(const uchar *cmap, int cmapSize, uint unicode); diff --git a/src/gui/text/qfontengineglyphcache_p.h b/src/gui/text/qfontengineglyphcache_p.h index fd5db1ecf5..532be10a83 100644 --- a/src/gui/text/qfontengineglyphcache_p.h +++ b/src/gui/text/qfontengineglyphcache_p.h @@ -65,7 +65,10 @@ QT_BEGIN_NAMESPACE class Q_GUI_EXPORT QFontEngineGlyphCache: public QSharedData { public: - QFontEngineGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix) : m_format(format), m_transform(matrix) + QFontEngineGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix, const QColor &color = QColor()) + : m_format(format) + , m_transform(matrix) + , m_color(color) { Q_ASSERT(m_format != QFontEngine::Format_None); } @@ -74,9 +77,11 @@ public: QFontEngine::GlyphFormat glyphFormat() const { return m_format; } const QTransform &transform() const { return m_transform; } + const QColor &color() const { return m_color; } QFontEngine::GlyphFormat m_format; QTransform m_transform; + QColor m_color; }; typedef QHash > GlyphPointerHash; typedef QHash > GlyphIntHash; diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp index 8d6620a55f..ef80d68bfe 100644 --- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp +++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp @@ -2105,8 +2105,10 @@ QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, co return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t); } -QImage QFontEngineFT::bitmapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t) +QImage QFontEngineFT::bitmapForGlyph(glyph_t g, QFixed subPixelPosition, const QTransform &t, const QColor &color) { + Q_UNUSED(color); + Glyph *glyph = loadGlyphFor(g, subPixelPosition, defaultFormat, t); if (glyph == nullptr) return QImage(); diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h b/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h index d498b0ac8b..109bae86e9 100644 --- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h +++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h @@ -236,7 +236,7 @@ private: QImage alphaMapForGlyph(glyph_t, QFixed) override; QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) override; QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override; - QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override; + QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color) override; glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix, diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 25e7c6df72..072dd1a28a 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -747,7 +747,7 @@ qreal QCoreTextFontEngine::fontSmoothingGamma() return 2.0; } -QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix) +QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &matrix, const QColor &color) { glyph_metrics_t br = alphaMapBoundingBox(glyph, subPixelPosition, matrix, glyphFormat); @@ -827,6 +827,8 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition CTFontDrawGlyphs(ctfont, &cgGlyph, &CGPointZero, 1, ctx); } } else { + CGContextSetRGBFillColor(ctx, color.redF(), color.greenF(), color.blueF(), color.alphaF()); + // CGContextSetTextMatrix does not work with color glyphs, so we use // the CTM instead. This means we must translate the CTM as well, to // set the glyph position, instead of using CGContextSetTextPosition. @@ -884,12 +886,12 @@ QImage QCoreTextFontEngine::alphaRGBMapForGlyph(glyph_t glyph, QFixed subPixelPo return imageForGlyph(glyph, subPixelPosition, x); } -QImage QCoreTextFontEngine::bitmapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) +QImage QCoreTextFontEngine::bitmapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t, const QColor &color) { if (t.type() > QTransform::TxScale) - return QFontEngine::bitmapForGlyph(glyph, subPixelPosition, t); + return QFontEngine::bitmapForGlyph(glyph, subPixelPosition, t, color); - return imageForGlyph(glyph, subPixelPosition, t); + return imageForGlyph(glyph, subPixelPosition, t, color); } void QCoreTextFontEngine::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags flags) const diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h index 4064507058..51d839688d 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h @@ -110,7 +110,7 @@ public: QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) override; QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override; glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat) override; - QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override; + QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color) override; QFixed emSquareSize() const override; void doKerning(QGlyphLayout *g, ShaperFlags flags) const override; @@ -137,7 +137,7 @@ public: protected: QCoreTextFontEngine(const QFontDef &def); void init(); - QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &m); + QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &m, const QColor &color = QColor()); void loadAdvancesForGlyphs(QVarLengthArray &cgGlyphs, QGlyphLayout *glyphs) const; bool hasColorGlyphs() const; bool shouldAntialias() const; diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp index 57c41938bc..a7ee65f4b8 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp @@ -650,7 +650,8 @@ bool QWindowsFontEngineDirectWrite::supportsSubPixelPositions() const QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, - const QTransform &originalTransform) + const QTransform &originalTransform, + const QColor &color) { UINT16 glyphIndex = t; FLOAT glyphAdvance = 0; @@ -735,6 +736,7 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t, #if defined(QT_USE_DIRECTWRITE2) BOOL ok = true; + if (SUCCEEDED(hr)) { while (SUCCEEDED(hr) && ok) { const DWRITE_COLOR_GLYPH_RUN *colorGlyphRun = 0; @@ -759,10 +761,18 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t, break; } - float r = qBound(0.0f, colorGlyphRun->runColor.r, 1.0f); - float g = qBound(0.0f, colorGlyphRun->runColor.g, 1.0f); - float b = qBound(0.0f, colorGlyphRun->runColor.b, 1.0f); - float a = qBound(0.0f, colorGlyphRun->runColor.a, 1.0f); + float r, g, b, a; + if (colorGlyphRun->paletteIndex == 0xFFFF) { + r = float(color.redF()); + g = float(color.greenF()); + b = float(color.blueF()); + a = float(color.alphaF()); + } else { + r = qBound(0.0f, colorGlyphRun->runColor.r, 1.0f); + g = qBound(0.0f, colorGlyphRun->runColor.g, 1.0f); + b = qBound(0.0f, colorGlyphRun->runColor.b, 1.0f); + a = qBound(0.0f, colorGlyphRun->runColor.a, 1.0f); + } if (!qFuzzyIsNull(a)) { renderGlyphRun(&image, @@ -784,11 +794,21 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t, } else #endif { + float r, g, b, a; + if (glyphFormat == QFontEngine::Format_ARGB) { + r = float(color.redF()); + g = float(color.greenF()); + b = float(color.blueF()); + a = float(color.alphaF()); + } else { + r = g = b = a = 0.0; + } + renderGlyphRun(&image, - 0.0, - 0.0, - 0.0, - 1.0, + r, + g, + b, + a, glyphAnalysis, boundingRect); } @@ -1001,9 +1021,9 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph } } -QImage QWindowsFontEngineDirectWrite::bitmapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) +QImage QWindowsFontEngineDirectWrite::bitmapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t, const QColor &color) { - return imageForGlyph(glyph, subPixelPosition, glyphMargin(QFontEngine::Format_A32), t); + return imageForGlyph(glyph, subPixelPosition, glyphMargin(QFontEngine::Format_A32), t, color); } QT_END_NAMESPACE diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h index 9326f5aece..9e13474a04 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite_p.h @@ -112,7 +112,7 @@ public: QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition) override; QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, const QTransform &t) override; QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, const QTransform &xform) override; - QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) override; + QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t, const QColor &color) override; QFontEngine *cloneWithSize(qreal pixelSize) const override; Qt::HANDLE handle() const override; @@ -126,7 +126,7 @@ public: void setUniqueFamilyName(const QString &newName) { m_uniqueFamilyName = newName; } private: - QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform); + QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform, const QColor &color = QColor()); void collectMetrics(); void renderGlyphRun(QImage *destination, float r, float g, float b, float a, IDWriteGlyphRunAnalysis *glyphAnalysis, const QRect &boundingRect); static QString filenameFromFontFile(IDWriteFontFile *fontFile); From a4718f1274b62eb1a8e633a5d5cc0c6e22024c11 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Tue, 4 Jun 2019 18:30:17 +0200 Subject: [PATCH 008/264] Fix the appearance of QSpinBox arrows on high-DPI displays A previous change to QLineEdit::sizeHint() has caused the QSpinBox arrows to break the widget frame on a high-DPI display with some particular scale values like 150 or 175%. This change updates QLineEdit::sizeHint() so that it has a minimum height, using the same values used in 5.11. Fixes: QTBUG-76047 Change-Id: I21f3e736da473b10fdf52e5a60e5fc5d07f270a1 Reviewed-by: Friedemann Kleint Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qlineedit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 86c7d35dbc..7515f866fe 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -684,7 +684,7 @@ QSize QLineEdit::sizeHint() const ensurePolished(); QFontMetrics fm(font()); const int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this); - int h = qMax(fm.height(), iconSize - 2) + 2*d->verticalMargin + int h = qMax(fm.height(), qMax(14, iconSize - 2)) + 2*d->verticalMargin + d->topTextMargin + d->bottomTextMargin + d->topmargin + d->bottommargin; int w = fm.horizontalAdvance(QLatin1Char('x')) * 17 + 2*d->horizontalMargin From 94570dc49aa6319c4811dcf37a29f179b6f64391 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 5 Jul 2019 12:41:58 +0200 Subject: [PATCH 009/264] Support pen color in QOpenGLTextureGlyphCache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is an enabler for supporting pen color for color fonts in Qt Quick. Task-number: QTBUG-74761 Change-Id: I3e605f939e6677cbbd4a650ae7998dea8fd2d7a9 Reviewed-by: Tor Arne Vestbø --- src/gui/opengl/qopengltextureglyphcache.cpp | 4 ++-- src/gui/opengl/qopengltextureglyphcache_p.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/opengl/qopengltextureglyphcache.cpp b/src/gui/opengl/qopengltextureglyphcache.cpp index e3cbba955d..490dc99749 100644 --- a/src/gui/opengl/qopengltextureglyphcache.cpp +++ b/src/gui/opengl/qopengltextureglyphcache.cpp @@ -53,8 +53,8 @@ static int next_qopengltextureglyphcache_serial_number() return 1 + serial.fetchAndAddRelaxed(1); } -QOpenGLTextureGlyphCache::QOpenGLTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix) - : QImageTextureGlyphCache(format, matrix) +QOpenGLTextureGlyphCache::QOpenGLTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix, const QColor &color) + : QImageTextureGlyphCache(format, matrix, color) , m_textureResource(0) , pex(0) , m_blitProgram(0) diff --git a/src/gui/opengl/qopengltextureglyphcache_p.h b/src/gui/opengl/qopengltextureglyphcache_p.h index 598cb00ee5..38c9aede7d 100644 --- a/src/gui/opengl/qopengltextureglyphcache_p.h +++ b/src/gui/opengl/qopengltextureglyphcache_p.h @@ -110,7 +110,7 @@ public: class Q_GUI_EXPORT QOpenGLTextureGlyphCache : public QImageTextureGlyphCache { public: - QOpenGLTextureGlyphCache(QFontEngine::GlyphFormat glyphFormat, const QTransform &matrix); + QOpenGLTextureGlyphCache(QFontEngine::GlyphFormat glyphFormat, const QTransform &matrix, const QColor &color = QColor()); ~QOpenGLTextureGlyphCache(); virtual void createTextureData(int width, int height) override; From f66c22ff5b7b9ec81d8c1621850649be8a1ac4d4 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 5 Jul 2019 09:55:46 +0200 Subject: [PATCH 010/264] QWidget::restoreGeometry(): Remove code related to restoredFrameGeometry restoredFrameGeometry is only used for a sanity check in format version 0, add a comment and remove code. Task-number: QTBUG-76900 Change-Id: I797b07d069f8568cb39541bcbe9009935a4a79f7 Reviewed-by: Gatis Paeglis --- src/widgets/kernel/qwidget.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 50745175b4..2f96b95522 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -7505,7 +7505,7 @@ bool QWidget::restoreGeometry(const QByteArray &geometry) quint8 fullScreen; qint32 restoredScreenWidth = 0; - stream >> restoredFrameGeometry + stream >> restoredFrameGeometry // Only used for sanity checks in version 0 >> restoredNormalGeometry >> restoredScreenNumber >> maximized @@ -7535,8 +7535,6 @@ bool QWidget::restoreGeometry(const QByteArray &geometry) } const int frameHeight = 20; - if (!restoredFrameGeometry.isValid()) - restoredFrameGeometry = QRect(QPoint(0,0), sizeHint()); if (!restoredNormalGeometry.isValid()) restoredNormalGeometry = QRect(QPoint(0, frameHeight), sizeHint()); @@ -7556,17 +7554,9 @@ bool QWidget::restoreGeometry(const QByteArray &geometry) // - (Mac only) The window is higher than the available geometry. It must // be possible to bring the size grip on screen by moving the window. #if 0 // Used to be included in Qt4 for Q_WS_MAC - restoredFrameGeometry.setHeight(qMin(restoredFrameGeometry.height(), availableGeometry.height())); restoredNormalGeometry.setHeight(qMin(restoredNormalGeometry.height(), availableGeometry.height() - frameHeight)); #endif - if (!restoredFrameGeometry.intersects(availableGeometry)) { - restoredFrameGeometry.moveBottom(qMin(restoredFrameGeometry.bottom(), availableGeometry.bottom())); - restoredFrameGeometry.moveLeft(qMax(restoredFrameGeometry.left(), availableGeometry.left())); - restoredFrameGeometry.moveRight(qMin(restoredFrameGeometry.right(), availableGeometry.right())); - } - restoredFrameGeometry.moveTop(qMax(restoredFrameGeometry.top(), availableGeometry.top())); - if (!restoredNormalGeometry.intersects(availableGeometry)) { restoredNormalGeometry.moveBottom(qMin(restoredNormalGeometry.bottom(), availableGeometry.bottom())); restoredNormalGeometry.moveLeft(qMax(restoredNormalGeometry.left(), availableGeometry.left())); From 85dc392135feb72eed449e6eaf47cdd023879394 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 5 Jul 2019 09:58:45 +0200 Subject: [PATCH 011/264] QWidget::restoreGeometry(): Fix Windows being restored out of screen area Factor out the screen area check to a separate helper and apply to restoredGeometry, too, fixing an oversight of 2f2bfc4e59cecfdd210663fbf81c000ecddfb822. Change-Id: I795d8d5e3cddb5e986c96c08a342d69063d04970 Fixes: QTBUG-76900 Reviewed-by: Gatis Paeglis --- src/widgets/kernel/qwidget.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 2f96b95522..fdb3872903 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -7451,6 +7451,17 @@ QByteArray QWidget::saveGeometry() const return array; } +static void checkRestoredGeometry(const QRect &availableGeometry, QRect *restoredGeometry, + int frameHeight) +{ + if (!restoredGeometry->intersects(availableGeometry)) { + restoredGeometry->moveBottom(qMin(restoredGeometry->bottom(), availableGeometry.bottom())); + restoredGeometry->moveLeft(qMax(restoredGeometry->left(), availableGeometry.left())); + restoredGeometry->moveRight(qMin(restoredGeometry->right(), availableGeometry.right())); + } + restoredGeometry->moveTop(qMax(restoredGeometry->top(), availableGeometry.top() + frameHeight)); +} + /*! \since 4.2 @@ -7557,12 +7568,8 @@ bool QWidget::restoreGeometry(const QByteArray &geometry) restoredNormalGeometry.setHeight(qMin(restoredNormalGeometry.height(), availableGeometry.height() - frameHeight)); #endif - if (!restoredNormalGeometry.intersects(availableGeometry)) { - restoredNormalGeometry.moveBottom(qMin(restoredNormalGeometry.bottom(), availableGeometry.bottom())); - restoredNormalGeometry.moveLeft(qMax(restoredNormalGeometry.left(), availableGeometry.left())); - restoredNormalGeometry.moveRight(qMin(restoredNormalGeometry.right(), availableGeometry.right())); - } - restoredNormalGeometry.moveTop(qMax(restoredNormalGeometry.top(), availableGeometry.top() + frameHeight)); + checkRestoredGeometry(availableGeometry, &restoredGeometry, frameHeight); + checkRestoredGeometry(availableGeometry, &restoredNormalGeometry, frameHeight); if (maximized || fullScreen) { // set geometry before setting the window state to make From 44602224bfae7bea08e5883768cfeef6629ac503 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Thu, 20 Jun 2019 12:04:31 +0200 Subject: [PATCH 012/264] CMake: Put the static dependencies into the relevant configuration When adding the static dependencies for a module, they should be added to the debug|release configuration as appropriate, otherwise it ends up adding the debug version of the libraries to the release configuration as well as the release version of the libraries. Implementation wise, that means we have to use generator expressions of the form $<$:${dependencies}>, because INTERFACE_LINK_LIBRARIES does not have a INTERFACE_LINK_LIBRARIES_ equivalent that can be set per configuration. Note that the condition part of the generator expression can not explicitly check for Debug or for Release, because a user can configure their application without specifying CMAKE_BUILD_TYPE, which means that both Debug and Relase conditions would fail. So the actual condition has to be isDebug or isNotDebug. The same approach is used for INTERFACE_LINK_OPTIONS. For debug_and_release builds we use the isDebug and isNotDebug conditions for the generator expressions. For singular builds (only release or only debug), we set the generator expression condition to "1" aka always true. This means that the Qt libraries and link options will always be used regardless of the configuration with which the CMake application is configured with. Fixes: QTBUG-76337 Task-number: QTBUG-38913 Change-Id: I5369d8ba083359a4a92253dbd1dabe9d1efa34db Reviewed-by: Andy Shaw --- mkspecs/features/create_cmake.prf | 18 ++++++ .../data/cmake/Qt5BasicConfig.cmake.in | 55 ++++++++++++++----- 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf index 00da9bd33f..68e6b6d265 100644 --- a/mkspecs/features/create_cmake.prf +++ b/mkspecs/features/create_cmake.prf @@ -133,6 +133,24 @@ equals(QMAKE_HOST.os, Windows): CMAKE_BIN_SUFFIX = ".exe" if(build_all|CONFIG(debug, debug|release)): CMAKE_DEBUG_TYPE = debug if(build_all|CONFIG(release, debug|release)): CMAKE_RELEASE_TYPE = release +# CMAKE_DEBUG_AND_RELEASE is used to tell the _populate_$${CMAKE_MODULE_NAME}_target_properties +# functions whether a Configuration specific generator expression needs to be added to the values +# of INTERFACE_LINK_LIBRARIES and INTERFACE_LINK_OPTIONS. For debug_and_release builds, we do need +# configuration specific values. For singular builds (only release or only debug), we want the +# values to be applied regardless of the configuration. +# This would allow on Linux and macOS (and with a recent enough version of CMake on Windows) to +# build a Debug configuration of an application, even if Qt was built in a Release configuration. +# +# All IMPORTED_LOCATION_ paths are automatically considered by CMake if there is no +# equivalent to the value specified by CMAKE_BUILD_TYPE. +# This means that when Qt was built in a Release configuration, and the application in a Debug +# configuration, IMPORTED_LOCATION_RELEASE will be used for the Qt libraries. +debug_and_release { + CMAKE_DEBUG_AND_RELEASE = TRUE +} else { + CMAKE_DEBUG_AND_RELEASE = FALSE +} + contains(CONFIG, plugin) { !isEmpty(PLUGIN_EXTENDS):!equals(PLUGIN_EXTENDS, -) { count(PLUGIN_EXTENDS, 1, greaterThan): \ diff --git a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in index ba7d9575c0..daebbd6554 100644 --- a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in +++ b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in @@ -119,7 +119,8 @@ endfunction() !!ENDIF !!IF !equals(TEMPLATE, aux) -macro(_populate_$${CMAKE_MODULE_NAME}_target_properties Configuration LIB_LOCATION IMPLIB_LOCATION) +macro(_populate_$${CMAKE_MODULE_NAME}_target_properties Configuration LIB_LOCATION IMPLIB_LOCATION + IsDebugAndRelease) set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration}) !!IF isEmpty(CMAKE_DLL_DIR_IS_ABSOLUTE) @@ -130,24 +131,48 @@ macro(_populate_$${CMAKE_MODULE_NAME}_target_properties Configuration LIB_LOCATI _qt5_$${CMAKE_MODULE_NAME}_check_file_exists(${imported_location}) set(_deps ${_Qt5$${CMAKE_MODULE_NAME}_LIB_DEPENDENCIES} + ) + set(_static_deps !!IF !isEmpty(CMAKE_STATIC_TYPE) ${_Qt5$${CMAKE_MODULE_NAME}_STATIC_${Configuration}_LIB_DEPENDENCIES} !!ENDIF ) + set_target_properties(Qt5::$${CMAKE_MODULE_NAME} PROPERTIES - \"INTERFACE_LINK_LIBRARIES\" \"${_deps}\" \"IMPORTED_LOCATION_${Configuration}\" ${imported_location} !!IF !isEmpty(CMAKE_LIB_SONAME) \"IMPORTED_SONAME_${Configuration}\" \"$${CMAKE_LIB_SONAME}\" !!ENDIF # For backward compatibility with CMake < 2.8.12 - \"IMPORTED_LINK_INTERFACE_LIBRARIES_${Configuration}\" \"${_deps}\" + \"IMPORTED_LINK_INTERFACE_LIBRARIES_${Configuration}\" \"${_deps};${_static_deps}\" + ) + set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} APPEND PROPERTY INTERFACE_LINK_LIBRARIES + \"${_deps}\" ) -!!IF !isEmpty(CMAKE_STATIC_TYPE) - if(NOT CMAKE_VERSION VERSION_LESS \"3.13\") - set_target_properties(Qt5::$${CMAKE_MODULE_NAME} PROPERTIES - \"INTERFACE_LINK_OPTIONS\" \"${_Qt5$${CMAKE_MODULE_NAME}_STATIC_${Configuration}_LINK_FLAGS}\" +!!IF !isEmpty(CMAKE_STATIC_TYPE) + if(NOT "${IsDebugAndRelease}") + set(_genex_condition \"1\") + else() + if("${Configuration}" STREQUAL "DEBUG") + set(_genex_condition \"$\") + else() + set(_genex_condition \"$>\") + endif() + endif() + + if(_static_deps) + set(_static_deps_genex \"$<${_genex_condition}:${_static_deps}>\") + set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} APPEND PROPERTY INTERFACE_LINK_LIBRARIES + \"${_static_deps_genex}\" + ) + endif() + + set(_static_link_flags \"${_Qt5$${CMAKE_MODULE_NAME}_STATIC_${Configuration}_LINK_FLAGS}\") + if(NOT CMAKE_VERSION VERSION_LESS \"3.13\" AND _static_link_flags) + set(_static_link_flags_genex \"$<${_genex_condition}:${_static_link_flags}>\") + set_property(TARGET Qt5::$${CMAKE_MODULE_NAME} APPEND PROPERTY INTERFACE_LINK_OPTIONS + \"${_static_link_flags_genex}\" ) endif() !!ENDIF @@ -382,9 +407,9 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME}) !!IF !equals(TEMPLATE, aux) !!IF !isEmpty(CMAKE_RELEASE_TYPE) !!IF !isEmpty(CMAKE_STATIC_WINDOWS_BUILD) - _populate_$${CMAKE_MODULE_NAME}_target_properties(RELEASE \"$${CMAKE_IMPLIB_FILE_LOCATION_RELEASE}\" \"\" ) + _populate_$${CMAKE_MODULE_NAME}_target_properties(RELEASE \"$${CMAKE_IMPLIB_FILE_LOCATION_RELEASE}\" \"\" $${CMAKE_DEBUG_AND_RELEASE}) !!ELSE - _populate_$${CMAKE_MODULE_NAME}_target_properties(RELEASE \"$${CMAKE_LIB_FILE_LOCATION_RELEASE}\" \"$${CMAKE_IMPLIB_FILE_LOCATION_RELEASE}\" ) + _populate_$${CMAKE_MODULE_NAME}_target_properties(RELEASE \"$${CMAKE_LIB_FILE_LOCATION_RELEASE}\" \"$${CMAKE_IMPLIB_FILE_LOCATION_RELEASE}\" $${CMAKE_DEBUG_AND_RELEASE}) !!ENDIF // CMAKE_STATIC_WINDOWS_BUILD !!IF !isEmpty(CMAKE_FIND_OTHER_LIBRARY_BUILD) @@ -395,7 +420,7 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME}) !!ELSE // CMAKE_LIB_DIR_IS_ABSOLUTE if (EXISTS \"$${CMAKE_IMPLIB_FILE_LOCATION_DEBUG}\" ) !!ENDIF // CMAKE_LIB_DIR_IS_ABSOLUTE - _populate_$${CMAKE_MODULE_NAME}_target_properties(DEBUG \"$${CMAKE_IMPLIB_FILE_LOCATION_DEBUG}\" \"\" ) + _populate_$${CMAKE_MODULE_NAME}_target_properties(DEBUG \"$${CMAKE_IMPLIB_FILE_LOCATION_DEBUG}\" \"\" $${CMAKE_DEBUG_AND_RELEASE}) !!ELSE // CMAKE_STATIC_WINDOWS_BUILD if (EXISTS !!IF isEmpty(CMAKE_DLL_DIR_IS_ABSOLUTE) @@ -409,7 +434,7 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME}) !!ELSE \"$${CMAKE_IMPLIB_FILE_LOCATION_DEBUG}\" ) !!ENDIF - _populate_$${CMAKE_MODULE_NAME}_target_properties(DEBUG \"$${CMAKE_LIB_FILE_LOCATION_DEBUG}\" \"$${CMAKE_IMPLIB_FILE_LOCATION_DEBUG}\" ) + _populate_$${CMAKE_MODULE_NAME}_target_properties(DEBUG \"$${CMAKE_LIB_FILE_LOCATION_DEBUG}\" \"$${CMAKE_IMPLIB_FILE_LOCATION_DEBUG}\" $${CMAKE_DEBUG_AND_RELEASE}) !!ENDIF // CMAKE_STATIC_WINDOWS_BUILD endif() !!ENDIF // CMAKE_DEBUG_TYPE @@ -419,9 +444,9 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME}) !!IF !isEmpty(CMAKE_DEBUG_TYPE) !!IF !isEmpty(CMAKE_STATIC_WINDOWS_BUILD) - _populate_$${CMAKE_MODULE_NAME}_target_properties(DEBUG \"$${CMAKE_IMPLIB_FILE_LOCATION_DEBUG}\" \"\" ) + _populate_$${CMAKE_MODULE_NAME}_target_properties(DEBUG \"$${CMAKE_IMPLIB_FILE_LOCATION_DEBUG}\" \"\" $${CMAKE_DEBUG_AND_RELEASE}) !!ELSE - _populate_$${CMAKE_MODULE_NAME}_target_properties(DEBUG \"$${CMAKE_LIB_FILE_LOCATION_DEBUG}\" \"$${CMAKE_IMPLIB_FILE_LOCATION_DEBUG}\" ) + _populate_$${CMAKE_MODULE_NAME}_target_properties(DEBUG \"$${CMAKE_LIB_FILE_LOCATION_DEBUG}\" \"$${CMAKE_IMPLIB_FILE_LOCATION_DEBUG}\" $${CMAKE_DEBUG_AND_RELEASE}) !!ENDIF // CMAKE_STATIC_WINDOWS_BUILD !!IF !isEmpty(CMAKE_FIND_OTHER_LIBRARY_BUILD) @@ -432,7 +457,7 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME}) !!ELSE // CMAKE_LIB_DIR_IS_ABSOLUTE if (EXISTS \"$${CMAKE_IMPLIB_FILE_LOCATION_RELEASE}\" ) !!ENDIF // CMAKE_LIB_DIR_IS_ABSOLUTE - _populate_$${CMAKE_MODULE_NAME}_target_properties(RELEASE \"$${CMAKE_IMPLIB_FILE_LOCATION_RELEASE}\" \"\" ) + _populate_$${CMAKE_MODULE_NAME}_target_properties(RELEASE \"$${CMAKE_IMPLIB_FILE_LOCATION_RELEASE}\" \"\" $${CMAKE_DEBUG_AND_RELEASE}) !!ELSE // CMAKE_STATIC_WINDOWS_BUILD if (EXISTS !!IF isEmpty(CMAKE_DLL_DIR_IS_ABSOLUTE) @@ -446,7 +471,7 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME}) !!ELSE \"$${CMAKE_IMPLIB_FILE_LOCATION_RELEASE}\" ) !!ENDIF - _populate_$${CMAKE_MODULE_NAME}_target_properties(RELEASE \"$${CMAKE_LIB_FILE_LOCATION_RELEASE}\" \"$${CMAKE_IMPLIB_FILE_LOCATION_RELEASE}\" ) + _populate_$${CMAKE_MODULE_NAME}_target_properties(RELEASE \"$${CMAKE_LIB_FILE_LOCATION_RELEASE}\" \"$${CMAKE_IMPLIB_FILE_LOCATION_RELEASE}\" $${CMAKE_DEBUG_AND_RELEASE}) !!ENDIF // CMAKE_STATIC_WINDOWS_BUILD endif() !!ENDIF // CMAKE_RELEASE_TYPE From b55fac3f3763ffae3bf99f2afea7e5d5f8b7c2a8 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 5 Jul 2019 14:15:29 +0200 Subject: [PATCH 013/264] xcb: reduce focus-in delay This patch amends fe63900dc9891dd355ca1f10d6c7e5fd1516f5d5 The previous value of 400ms was a random and seemingly harmless choice. It turns out that 400ms is a bit too long and interferes with x11 async behavior tweaks in the VirtualBox source code. The original aim of specifying a concrete delay was to fix the nondeterministic behavior of the pre-existing code and to avoid flickering on KWin caused by waiting too little. This patch changes 400ms -> 100ms, which seems to work better in practice. Fixes: QTBUG-76742 Change-Id: Ia8168216819ac41d0124622c9472a98a1877262f Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbconnection.cpp | 2 ++ src/plugins/platforms/xcb/qxcbwindow.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 06d1000993..f98b2dfe3a 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -132,7 +132,9 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra if (!m_startupId.isNull()) qunsetenv("DESKTOP_STARTUP_ID"); + const int focusInDelay = 100; m_focusInTimer.setSingleShot(true); + m_focusInTimer.setInterval(focusInDelay); m_focusInTimer.callOnTimeout([]() { // No FocusIn events for us, proceed with FocusOut normally. QWindowSystemInterface::handleWindowActivated(nullptr, Qt::ActiveWindowFocusReason); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 9382488b74..610eca06a5 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -848,7 +848,7 @@ void QXcbWindow::doFocusOut() connection()->setFocusWindow(nullptr); relayFocusToModalWindow(); // Do not set the active window to nullptr if there is a FocusIn coming. - connection()->focusInTimer().start(400); + connection()->focusInTimer().start(); } struct QtMotifWmHints { From 0a37378e7a4aac9b4343f0d257ae05450673e7de Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 5 Jul 2019 15:09:37 +0200 Subject: [PATCH 014/264] doc: Remove erroneous double left brace MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A double left brace in a link command was causing qdoc to fail for the remainder of the qdoc comment. This update just removes one of the left braces. Change-Id: Ie4fc0122e0799955b7804c2b6f61393af01747c7 Reviewed-by: Topi Reiniö --- src/corelib/tools/qdatetime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index a156970ac6..3c23d54565 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -3024,7 +3024,7 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT QDateTime can describe datetimes with respect to \l{Qt::LocalTime}{local time}, to \l{Qt::UTC}{UTC}, to a specified \l{Qt::OffsetFromUTC}{offset - from UTC} or to a specified \l{{Qt::TimeZone}{time zone}, in conjunction + from UTC} or to a specified \l{Qt::TimeZone}{time zone}, in conjunction with the QTimeZone class. For example, a time zone of "Europe/Berlin" will apply the daylight-saving rules as used in Germany since 1970. In contrast, an offset from UTC of +3600 seconds is one hour ahead of UTC (usually From 298f750cdba2bd15e735a47ba8d3b9c093367ba3 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Thu, 4 Jul 2019 18:48:26 +0200 Subject: [PATCH 015/264] QComboBox: revert deprecation of currentIndexChanged(QString) QComboBox::currentIndexChanged(QString) was deprecated due to the fact that there is a currentTextChanged(QString) signal but this signal is not equivalent to the other since it's also emitted when the lineedit text changes. Therefore revert the deprecation of this signal. Fixes: QTBUG-76890 Change-Id: Ia314116a5ac4e43e60383da9e729e24ffb3e8b30 Reviewed-by: Albert Astals Cid Reviewed-by: Giuseppe D'Angelo --- src/widgets/widgets/qcombobox.cpp | 5 ----- src/widgets/widgets/qcombobox.h | 3 --- 2 files changed, 8 deletions(-) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index a93c72a933..a143b2e799 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -896,11 +896,6 @@ QStyleOptionComboBox QComboBoxPrivateContainer::comboStyleOption() const \fn void QComboBox::currentIndexChanged(const QString &text) \since 4.1 - \obsolete - - Use currentTextChanged(const QString &) or currentIndexChanged(int) - instead. - This signal is sent whenever the currentIndex in the combobox changes either through user interaction or programmatically. The item's \a text is passed. diff --git a/src/widgets/widgets/qcombobox.h b/src/widgets/widgets/qcombobox.h index 33686e547d..b2fe921bd8 100644 --- a/src/widgets/widgets/qcombobox.h +++ b/src/widgets/widgets/qcombobox.h @@ -227,10 +227,7 @@ Q_SIGNALS: void highlighted(int index); void highlighted(const QString &); void currentIndexChanged(int index); -#if QT_DEPRECATED_SINCE(5, 13) - QT_DEPRECATED_X("Use currentTextChanged() instead") void currentIndexChanged(const QString &); -#endif void currentTextChanged(const QString &); protected: From 90a29a73f84ffd6386beb37690c328b039423fab Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 4 Jul 2019 14:08:44 +0200 Subject: [PATCH 016/264] QHostInfo: fix a race condition on wasDeleted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The plain bool variable wasDeleted is set to true in the QHostLookupManager dtor before the call to clear(), which calls waitForDone() on the thread pool performing the lookups. All tasks on the thread pool start by checking this variable so as to return early when destruction is in progress. But the check was outside the mutex-protected area, so as a non-atomic load, without a happens-before relation to the write, this is a Data Race, thus UB. Fix by moving the check past the mutex locking into the critical section. This way, tasks that were waiting for the mutex after seeing no wasDeleted before get the message reliably. This does not introduce a dead-lock, since the call to waitForDone() is outside any mutex protection leaving a window for the tasks to obtain the mutex and react on wasDeleted. Change-Id: Ied4b9daa7dc78295b0d36a536839845c4db2fb78 Reviewed-by: Mårten Nordheim Reviewed-by: Timur Pocheptsov Reviewed-by: David Faure --- src/network/kernel/qhostinfo.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index 4d451dfdb7..e9ea6335d2 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -743,7 +743,9 @@ QHostInfoLookupManager::QHostInfoLookupManager() : mutex(QMutex::Recursive), was QHostInfoLookupManager::~QHostInfoLookupManager() { + QMutexLocker locker(&mutex); wasDeleted = true; + locker.unlock(); // don't qDeleteAll currentLookups, the QThreadPool has ownership clear(); @@ -771,6 +773,8 @@ void QHostInfoLookupManager::clear() void QHostInfoLookupManager::work() { + QMutexLocker locker(&mutex); + if (wasDeleted) return; @@ -778,8 +782,6 @@ void QHostInfoLookupManager::work() // - launch new lookups via the thread pool // - make sure only one lookup per host/IP is in progress - QMutexLocker locker(&mutex); - if (!finishedLookups.isEmpty()) { // remove ID from aborted if it is in there for (int i = 0; i < finishedLookups.length(); i++) { @@ -831,10 +833,11 @@ void QHostInfoLookupManager::work() // called by QHostInfo void QHostInfoLookupManager::scheduleLookup(QHostInfoRunnable *r) { + QMutexLocker locker(&this->mutex); + if (wasDeleted) return; - QMutexLocker locker(&this->mutex); scheduledLookups.enqueue(r); work(); } @@ -842,11 +845,11 @@ void QHostInfoLookupManager::scheduleLookup(QHostInfoRunnable *r) // called by QHostInfo void QHostInfoLookupManager::abortLookup(int id) { + QMutexLocker locker(&this->mutex); + if (wasDeleted) return; - QMutexLocker locker(&this->mutex); - #if QT_CONFIG(thread) // is postponed? delete and return for (int i = 0; i < postponedLookups.length(); i++) { @@ -872,20 +875,22 @@ void QHostInfoLookupManager::abortLookup(int id) // called from QHostInfoRunnable bool QHostInfoLookupManager::wasAborted(int id) { + QMutexLocker locker(&this->mutex); + if (wasDeleted) return true; - QMutexLocker locker(&this->mutex); return abortedLookups.contains(id); } // called from QHostInfoRunnable void QHostInfoLookupManager::lookupFinished(QHostInfoRunnable *r) { + QMutexLocker locker(&this->mutex); + if (wasDeleted) return; - QMutexLocker locker(&this->mutex); #if QT_CONFIG(thread) currentLookups.removeOne(r); #endif From 5ca2b081fe8089990dd87c5d9081d90ed170283a Mon Sep 17 00:00:00 2001 From: Nicolas Fella Date: Mon, 17 Jun 2019 21:59:13 +0200 Subject: [PATCH 017/264] [androidcontentfileengine] Catch SecurityException during file opening resolver.openFileDescriptor throws a SecurityException when the caller doesn't have sufficient permissions to access the URL. This will make an application crash. We should handle this case gracefully and report it to the user. I'm unsure if there is a better way to do this than simply logging the exception. Change-Id: I36bfbd3e398c8176e57042a27740aa15bce63a7c Reviewed-by: BogDan Vatra --- src/android/jar/src/org/qtproject/qt5/android/QtNative.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index 9679fd40f4..c33d5016ce 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -178,6 +178,9 @@ public class QtNative return fdDesc.detachFd(); } catch (FileNotFoundException e) { return -1; + } catch (SecurityException e) { + Log.e(QtTAG, "Exception when opening file", e); + return -1; } } From f5745609481dd4f660e196b8438e25615d3dfe0a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 6 Jul 2019 11:04:34 +0200 Subject: [PATCH 018/264] Fix compilation with C++20 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implicit capture of 'this' in [=] is deprecated in C++20. Fix by using explicit captures. Change-Id: I1633446f4670202b0d1aca938d8c27dbc0c1411e Reviewed-by: Mårten Nordheim --- src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp | 2 +- src/platformsupport/input/libinput/qlibinputhandler.cpp | 2 +- src/widgets/dialogs/qcolordialog.cpp | 2 +- src/widgets/itemviews/qlistview.cpp | 2 +- src/widgets/widgets/qmenu.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp b/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp index ae81bca00f..06025c016e 100644 --- a/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp +++ b/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp @@ -102,7 +102,7 @@ QEvdevMouseManager::QEvdevMouseManager(const QString &key, const QString &specif } QInputDeviceManager *manager = QGuiApplicationPrivate::inputDeviceManager(); - connect(manager, &QInputDeviceManager::cursorPositionChangeRequested, [=](const QPoint &pos) { + connect(manager, &QInputDeviceManager::cursorPositionChangeRequested, [this](const QPoint &pos) { m_x = pos.x(); m_y = pos.y(); clampPosition(); diff --git a/src/platformsupport/input/libinput/qlibinputhandler.cpp b/src/platformsupport/input/libinput/qlibinputhandler.cpp index 52eaa18f4b..e5dc182bec 100644 --- a/src/platformsupport/input/libinput/qlibinputhandler.cpp +++ b/src/platformsupport/input/libinput/qlibinputhandler.cpp @@ -115,7 +115,7 @@ QLibInputHandler::QLibInputHandler(const QString &key, const QString &spec) m_touch.reset(new QLibInputTouch); QInputDeviceManager *manager = QGuiApplicationPrivate::inputDeviceManager(); - connect(manager, &QInputDeviceManager::cursorPositionChangeRequested, [=](const QPoint &pos) { + connect(manager, &QInputDeviceManager::cursorPositionChangeRequested, [this](const QPoint &pos) { m_pointer->setPos(pos); }); diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 29178c02c3..4c4e6e23ba 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -1739,7 +1739,7 @@ void QColorDialogPrivate::initWidgets() q->connect(custom, SIGNAL(selected(int,int)), SLOT(_q_newCustom(int,int))); q->connect(custom, SIGNAL(currentChanged(int,int)), SLOT(_q_nextCustom(int,int))); - q->connect(custom, &QWellArray::colorChanged, [=] (int index, QRgb color) { + q->connect(custom, &QWellArray::colorChanged, [this] (int index, QRgb color) { QColorDialogOptions::setCustomColor(index, color); if (custom) custom->update(); diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index e07514f297..1c01bba771 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -1895,7 +1895,7 @@ bool QListViewPrivate::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QMo void QListViewPrivate::removeCurrentAndDisabled(QVector *indexes, const QModelIndex ¤t) const { - auto isCurrentOrDisabled = [=](const QModelIndex &index) { + auto isCurrentOrDisabled = [this, current](const QModelIndex &index) { return !isIndexEnabled(index) || index == current; }; indexes->erase(std::remove_if(indexes->begin(), indexes->end(), diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 2d107de268..8dff2ffc34 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -200,7 +200,7 @@ void QMenuPrivate::init() q->setAttribute(Qt::WA_X11NetWmWindowTypePopupMenu); defaultMenuAction = menuAction = new QAction(q); menuAction->d_func()->menu = q; - QObject::connect(menuAction, &QAction::changed, [=] { + QObject::connect(menuAction, &QAction::changed, [this] { if (!tornPopup.isNull()) tornPopup->updateWindowTitle(); }); From f14db5dd3ab914db1d2e404520c97b0900b582b3 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 4 Jul 2019 22:33:07 +0200 Subject: [PATCH 019/264] qsslsocket_openssl_symbols.cpp: replace mutex pool use with QBasicMutex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The use of QMutexPool caused an #ifdef, because, lacking an object, some OpenSSL function pointer was used as the address required as input for the mutex pool. Sadly, the names of the functions differ between OpenSSL versions, thus the need for an #ifdef. By simply using a QBasicMutex (defined at namespace scope to evade https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79561), the #ifdef can go away. Another level of #ifdefs goes away because, even for non-QT_CONFIG(thread) builds, Q*Mutex etc are defined, just as no-ops. So we can freely use them without QT_CONFIG(thread) guard, unlike QMutexPool. Finally, optimize for the (common?) case of already-loaded libraries by making symbolsResolved an atomic variable, and checking that before taking the mutex (double-checked locking, done right). For reasons of said GCC bug, again, the QBasicAtomic is defined at namespace scope. And then move the other boolean there for symmetry. Change-Id: Ic5f44871fb200e5368b9af327e4d1e852fbc586c Reviewed-by: Mårten Nordheim --- .../ssl/qsslsocket_openssl_symbols.cpp | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 2eb9763e90..5b4e010cf0 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -63,9 +63,6 @@ # include #endif #include -#if QT_CONFIG(thread) -#include -#endif #include #if defined(Q_OS_UNIX) #include @@ -936,18 +933,16 @@ static QPair loadOpenSsl() } #endif +static QBasicMutex symbolResolveMutex; +static QBasicAtomicInt symbolsResolved = Q_BASIC_ATOMIC_INITIALIZER(false); +static bool triedToResolveSymbols = false; + bool q_resolveOpenSslSymbols() { - static bool symbolsResolved = false; - static bool triedToResolveSymbols = false; -#if QT_CONFIG(thread) -#if QT_CONFIG(opensslv11) - QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_OPENSSL_init_ssl)); -#else - QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&q_SSL_library_init)); -#endif -#endif - if (symbolsResolved) + if (symbolsResolved.loadAcquire()) + return true; + QMutexLocker locker(&symbolResolveMutex); + if (symbolsResolved.loadRelaxed()) return true; if (triedToResolveSymbols) return false; @@ -1402,7 +1397,8 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(d2i_PKCS12_bio) RESOLVEFUNC(PKCS12_free) - symbolsResolved = true; + + symbolsResolved.storeRelease(true); delete libs.first; delete libs.second; return true; From b41c9a89969796407b03fd9c5cde1d77999841c1 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 5 Jul 2019 10:53:00 +0200 Subject: [PATCH 020/264] Inline QMutexPool into its only remaining user Also reduce the pool size from 131 to 17, and use QBasicMutex instead of recursive ones. Change-Id: I3bf0374cce5ff2c07427070aba6128a22c9b70e4 Reviewed-by: Lars Knoll Reviewed-by: Timur Pocheptsov Reviewed-by: Volker Hilsheimer --- src/corelib/thread/qmutexpool.cpp | 151 -------------------- src/corelib/thread/qmutexpool_p.h | 88 ------------ src/corelib/thread/thread.pri | 2 - src/network/ssl/qsslcertificate_openssl.cpp | 13 +- 4 files changed, 10 insertions(+), 244 deletions(-) delete mode 100644 src/corelib/thread/qmutexpool.cpp delete mode 100644 src/corelib/thread/qmutexpool_p.h diff --git a/src/corelib/thread/qmutexpool.cpp b/src/corelib/thread/qmutexpool.cpp deleted file mode 100644 index 3ece30c01c..0000000000 --- a/src/corelib/thread/qmutexpool.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module 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 "qatomic.h" -#include "qmutexpool_p.h" - -QT_BEGIN_NAMESPACE - -Q_GLOBAL_STATIC_WITH_ARGS(QMutexPool, globalMutexPool, (QMutex::Recursive)) - -/*! - \class QMutexPool - \inmodule QtCore - \brief The QMutexPool class provides a pool of QMutex objects. - - \internal - - \ingroup thread - - QMutexPool is a convenience class that provides access to a fixed - number of QMutex objects. - - Typical use of a QMutexPool is in situations where it is not - possible or feasible to use one QMutex for every protected object. - The mutex pool will return a mutex based on the address of the - object that needs protection. - - For example, consider this simple class: - - \snippet code/src_corelib_thread_qmutexpool.cpp 0 - - Adding a QMutex member to the Number class does not make sense, - because it is so small. However, in order to ensure that access to - each Number is protected, you need to use a mutex. In this case, a - QMutexPool would be ideal. - - Code to calculate the square of a number would then look something - like this: - - \snippet code/src_corelib_thread_qmutexpool.cpp 1 - - This function will safely calculate the square of a number, since - it uses a mutex from a QMutexPool. The mutex is locked and - unlocked automatically by the QMutexLocker class. See the - QMutexLocker documentation for more details. -*/ - -/*! - Constructs a QMutexPool, reserving space for \a size QMutexes. All - mutexes in the pool are created with \a recursionMode. By default, - all mutexes are non-recursive. - - The QMutexes are created when needed, and deleted when the - QMutexPool is destructed. -*/ -QMutexPool::QMutexPool(QMutex::RecursionMode recursionMode, int size) - : mutexes(size), recursionMode(recursionMode) -{ - for (int index = 0; index < mutexes.count(); ++index) { - mutexes[index].storeRelaxed(0); - } -} - -/*! - Destructs a QMutexPool. All QMutexes that were created by the pool - are deleted. -*/ -QMutexPool::~QMutexPool() -{ - for (int index = 0; index < mutexes.count(); ++index) - delete mutexes[index].loadAcquire(); -} - -/*! - Returns the global QMutexPool instance. -*/ -QMutexPool *QMutexPool::instance() -{ - return globalMutexPool(); -} - -/*! - \fn QMutexPool::get(const void *address) - Returns a QMutex from the pool. QMutexPool uses the value \a address - to determine which mutex is returned from the pool. -*/ - -/*! - \internal - create the mutex for the given index - */ -QMutex *QMutexPool::createMutex(int index) -{ - // mutex not created, create one - QMutex *newMutex = new QMutex(recursionMode); - if (!mutexes[index].testAndSetRelease(nullptr, newMutex)) { - delete newMutex; - return mutexes[index].loadAcquire(); - } else { - return newMutex; - } -} - -/*! - Returns a QMutex from the global mutex pool. -*/ -QMutex *QMutexPool::globalInstanceGet(const void *address) -{ - QMutexPool * const globalInstance = globalMutexPool(); - if (globalInstance == 0) - return 0; - return globalInstance->get(address); -} - -QT_END_NAMESPACE diff --git a/src/corelib/thread/qmutexpool_p.h b/src/corelib/thread/qmutexpool_p.h deleted file mode 100644 index 00710199b8..0000000000 --- a/src/corelib/thread/qmutexpool_p.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module 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$ -** -****************************************************************************/ - -#ifndef QMUTEXPOOL_P_H -#define QMUTEXPOOL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include "QtCore/qatomic.h" -#include "QtCore/qmutex.h" -#include "QtCore/qvarlengtharray.h" - -QT_REQUIRE_CONFIG(thread); - -QT_BEGIN_NAMESPACE - -class Q_CORE_EXPORT QMutexPool -{ -public: - explicit QMutexPool(QMutex::RecursionMode recursionMode = QMutex::NonRecursive, int size = 131); - ~QMutexPool(); - - inline QMutex *get(const void *address) { - int index = uint(quintptr(address)) % mutexes.count(); - QMutex *m = mutexes[index].loadAcquire(); - if (m) - return m; - else - return createMutex(index); - } - static QMutexPool *instance(); - static QMutex *globalInstanceGet(const void *address); - -private: - QMutex *createMutex(int index); - QVarLengthArray, 131> mutexes; - QMutex::RecursionMode recursionMode; -}; - -QT_END_NAMESPACE - -#endif // QMUTEXPOOL_P_H diff --git a/src/corelib/thread/thread.pri b/src/corelib/thread/thread.pri index 22f0de0523..d11e6500ff 100644 --- a/src/corelib/thread/thread.pri +++ b/src/corelib/thread/thread.pri @@ -28,7 +28,6 @@ qtConfig(thread) { thread/qbasicatomic.h \ thread/qfutex_p.h \ thread/qgenericatomic.h \ - thread/qmutexpool_p.h \ thread/qmutex_p.h \ thread/qorderedmutexlocker_p.h \ thread/qreadwritelock_p.h \ @@ -40,7 +39,6 @@ qtConfig(thread) { SOURCES += \ thread/qatomic.cpp \ thread/qmutex.cpp \ - thread/qmutexpool.cpp \ thread/qreadwritelock.cpp \ thread/qsemaphore.cpp \ thread/qthreadpool.cpp \ diff --git a/src/network/ssl/qsslcertificate_openssl.cpp b/src/network/ssl/qsslcertificate_openssl.cpp index 806c6426e4..6f1fb26add 100644 --- a/src/network/ssl/qsslcertificate_openssl.cpp +++ b/src/network/ssl/qsslcertificate_openssl.cpp @@ -45,12 +45,19 @@ #include "qsslcertificateextension_p.h" #include +#include -#if QT_CONFIG(thread) -#include -#endif QT_BEGIN_NAMESPACE +Q_CONSTEXPR int MutexPoolSize = 17; +static QBasicMutex mutexPool[MutexPoolSize]; +namespace QMutexPool { + static QBasicMutex *globalInstanceGet(const void *addr) + { + return mutexPool + (quintptr(addr) % MutexPoolSize); + } +} + // forward declaration static QMultiMap _q_mapFromX509Name(X509_NAME *name); From 9c7ebd191b9862c28e9c96a511ec2878b7a3591d Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Thu, 20 Jun 2019 15:26:39 +0200 Subject: [PATCH 021/264] CMake: Create Config.cmake files for internal modules in static builds This change will create Config.cmake files for internal modules like AccessibilitySupport when doing static builds. They need to be find_package()'ed and linked in when linking in certain qt plugins. Task-number: QTBUG-38913 Task-number: QTBUG-76562 Change-Id: Ia2e446025c87df48f20bb65cfd9da6c6a4354bb1 Reviewed-by: Simon Hausmann --- mkspecs/features/create_cmake.prf | 8 ++++++++ mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in | 4 ++++ mkspecs/features/qt_module.prf | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf index 68e6b6d265..fe9149b1c1 100644 --- a/mkspecs/features/create_cmake.prf +++ b/mkspecs/features/create_cmake.prf @@ -26,6 +26,10 @@ contains(CMAKE_INSTALL_LIBS_DIR, ^(/usr)?/lib(64)?.*): CMAKE_USR_MOVE_WORKAROUND CMAKE_OUT_DIR = $$MODULE_BASE_OUTDIR/lib/cmake +internal_module { + MODULE = "$${MODULE}_private" +} + # Core, Network, an external module named Foo CMAKE_MODULE_NAME = $$cmakeModuleName($${MODULE}) @@ -112,6 +116,10 @@ win32:!static:!staticlib { static|staticlib:CMAKE_STATIC_TYPE = true +internal_module { + CMAKE_INTERNAL_MODULE = true +} + CMAKE_DEBUG_TYPE = CMAKE_RELEASE_TYPE = diff --git a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in index daebbd6554..8a3f202c53 100644 --- a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in +++ b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in @@ -484,6 +484,8 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME}) ) !!ENDIF // TEMPLATE != aux +!!IF isEmpty(CMAKE_INTERNAL_MODULE) + file(GLOB pluginTargets \"${CMAKE_CURRENT_LIST_DIR}/Qt5$${CMAKE_MODULE_NAME}_*Plugin.cmake\") macro(_populate_$${CMAKE_MODULE_NAME}_plugin_properties Plugin Configuration PLUGIN_LOCATION) @@ -506,6 +508,8 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME}) endforeach() endif() +!!ENDIF // isEmpty(CMAKE_INTERNAL_MODULE) + !!IF !isEmpty(CMAKE_MODULE_EXTRAS) include(\"${CMAKE_CURRENT_LIST_DIR}/Qt5$${CMAKE_MODULE_NAME}ConfigExtras.cmake\") diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index ee7de22059..46687f262e 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -117,7 +117,7 @@ unset(QT_FOR_PRIVATE) QMAKE_USE_PRIVATE += $$QMAKE_USE_FOR_PRIVATE unset(QMAKE_USE_FOR_PRIVATE) -!internal_module:CONFIG += create_cmake +CONFIG += create_cmake contains(TARGET, QtAddOn.*): \ DEFINES += QT_BUILD_ADDON_$${ucmodule}_LIB From 011c22116590ffed105e6630d8bc4b802d80484d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Wed, 3 Jul 2019 16:24:35 +0200 Subject: [PATCH 022/264] QNAM: Don't condition connecting QNetworkReplyImpl signals on qnetconmon QNetwork{Status,Connection}Monitor isn't used for QNetworkReplyImpl yet, so we should connect the signal until it is. Change-Id: I40f1483608195418d43c442f46184882f64596ff Reviewed-by: Timur Pocheptsov --- src/network/access/qnetworkaccessmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index a2996e3533..548cfe6593 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -1565,8 +1565,8 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera QNetworkReplyImpl *reply = new QNetworkReplyImpl(this); #ifndef QT_NO_BEARERMANAGEMENT // NETMONTODO: network reply impl must be augmented to use the same monitoring - // capabilities as http network reply impl does. - if (!isLocalFile && !d->statusMonitor.isEnabled()) { + // capabilities as http network reply impl does. Once it does: uncomment the condition below + if (!isLocalFile /*&& !d->statusMonitor.isEnabled()*/) { connect(this, SIGNAL(networkSessionConnected()), reply, SLOT(_q_networkSessionConnected())); } From 682e4795fe7a5ae64268212b23ff96706a0822d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Thu, 4 Jul 2019 14:14:28 +0200 Subject: [PATCH 023/264] QNetworkReply: Skip a test when QNetworkStatusMonitor is enabled QNetworkSession has a concept of UsagePolicy which can disable background* transfers to conserve battery or bandwidth. However, it is only possible to change the policy through QNetworkSessionPrivate::setUsagePolicy which currently doesn't have any callers outside of our auto tests. *background = transfers not initiated directly by the user, but needs to be marked as such by the application developer. Change-Id: I92c4abccaca040612b4795abe7c52d68a2d21749 Reviewed-by: Timur Pocheptsov --- tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 1afd8af7b0..6f00780d81 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -8200,6 +8200,9 @@ void tst_QNetworkReply::backgroundRequestInterruption_data() void tst_QNetworkReply::backgroundRequestInterruption() { #ifndef QT_NO_BEARERMANAGEMENT + if (QNetworkStatusMonitor::isEnabled() && QByteArray(QTest::currentDataTag()).startsWith("http")) + QSKIP("This test (currently) doesn't make any sense when QNetworkStatusMonitor is enabled"); + QFETCH(QUrl, url); QFETCH(bool, background); QFETCH(QNetworkReply::NetworkError, error); From dc431b7e8548e97d19770285a6160ecfa8874815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Fri, 12 Apr 2019 15:46:35 +0200 Subject: [PATCH 024/264] Introduce QNetwork(Connection|Status)Monitor to Windows Currently not available for mingw because it's missing all the interfaces. But should start working once it has them. Change-Id: I231e8b69e008c5300a83087fe9cd071acd0687cb Reviewed-by: Timur Pocheptsov --- src/network/configure.json | 23 + src/network/kernel/kernel.pri | 2 + src/network/kernel/qnetconmonitor_win.cpp | 710 ++++++++++++++++++++++ 3 files changed, 735 insertions(+) create mode 100644 src/network/kernel/qnetconmonitor_win.cpp diff --git a/src/network/configure.json b/src/network/configure.json index 56805da7b2..9652dfd1f7 100644 --- a/src/network/configure.json +++ b/src/network/configure.json @@ -208,6 +208,22 @@ "main": ["gss_ctx_id_t ctx;"], "qmake": "LIBS += -lgssapi_krb5" } + }, + "netlistmgr": { + "label": "Network List Manager", + "type": "compile", + "test": { + "include": [ "netlistmgr.h", "wrl/client.h" ], + "main": [ + "using namespace Microsoft::WRL;", + "ComPtr networkListManager;", + "ComPtr connectionPoint;", + "ComPtr connectionPointContainer;", + "networkListManager.As(&connectionPointContainer);", + "connectionPointContainer->FindConnectionPoint(IID_INetworkConnectionEvents, &connectionPoint);" + ], + "qmake": "LIBS += -lOle32" + } } }, @@ -397,6 +413,13 @@ "section": "Networking", "condition": "config.win32 && !config.winrt", "output": [ "publicFeature", "feature" ] + }, + "netlistmgr": { + "label": "Network List Manager", + "purpose": "Use Network List Manager to keep track of network connectivity", + "section": "Networking", + "condition": "config.win32 && tests.netlistmgr", + "output": [ "privateFeature" ] } }, diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index 0e4cef5e74..a55648dbc7 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -77,6 +77,8 @@ macos | ios { kernel/qnetconmonitor_darwin.mm LIBS_PRIVATE += -framework SystemConfiguration +} else:qtConfig(netlistmgr) { + SOURCES += kernel/qnetconmonitor_win.cpp } else { SOURCES += kernel/qnetconmonitor_stub.cpp } diff --git a/src/network/kernel/qnetconmonitor_win.cpp b/src/network/kernel/qnetconmonitor_win.cpp new file mode 100644 index 0000000000..2eab0a062f --- /dev/null +++ b/src/network/kernel/qnetconmonitor_win.cpp @@ -0,0 +1,710 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtNetwork module 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 "qnetconmonitor_p.h" + +#include "private/qobject_p.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +using namespace Microsoft::WRL; + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcNetMon, "qt.network.monitor"); + +namespace { +QString errorStringFromHResult(HRESULT hr) +{ + _com_error error(hr); + return QString::fromWCharArray(error.ErrorMessage()); +} + +template +bool QueryInterfaceImpl(IUnknown *from, REFIID riid, void **ppvObject) +{ + if (riid == __uuidof(T)) { + *ppvObject = static_cast(from); + from->AddRef(); + return true; + } + return false; +} + +QNetworkInterface getInterfaceFromHostAddress(const QHostAddress &local) +{ + QList interfaces = QNetworkInterface::allInterfaces(); + auto it = std::find_if( + interfaces.cbegin(), interfaces.cend(), [&local](const QNetworkInterface &iface) { + const auto &entries = iface.addressEntries(); + return std::any_of(entries.cbegin(), entries.cend(), + [&local](const QNetworkAddressEntry &entry) { + return entry.ip().isEqual(local, + QHostAddress::TolerantConversion); + }); + }); + if (it == interfaces.cend()) { + qCWarning(lcNetMon, "Could not find the interface for the local address."); + return {}; + } + return *it; +} +} // anonymous namespace + +class QNetworkConnectionEvents final : public INetworkConnectionEvents +{ +public: + QNetworkConnectionEvents(QNetworkConnectionMonitorPrivate *monitor); + ~QNetworkConnectionEvents(); + + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override; + + ULONG STDMETHODCALLTYPE AddRef() override { return ++ref; } + ULONG STDMETHODCALLTYPE Release() override + { + if (--ref == 0) { + delete this; + return 0; + } + return ref; + } + + HRESULT STDMETHODCALLTYPE + NetworkConnectionConnectivityChanged(GUID connectionId, NLM_CONNECTIVITY connectivity) override; + HRESULT STDMETHODCALLTYPE NetworkConnectionPropertyChanged( + GUID connectionId, NLM_CONNECTION_PROPERTY_CHANGE flags) override; + + Q_REQUIRED_RESULT + bool setTarget(const QNetworkInterface &iface); + Q_REQUIRED_RESULT + bool startMonitoring(); + Q_REQUIRED_RESULT + bool stopMonitoring(); + +private: + ComPtr getNetworkConnectionFromAdapterGuid(QUuid guid); + + QUuid currentConnectionId{}; + + ComPtr networkListManager; + ComPtr connectionPoint; + + QNetworkConnectionMonitorPrivate *monitor = nullptr; + + QAtomicInteger ref = 1; // start at 1 for our own initial reference + DWORD cookie = 0; +}; + +class QNetworkConnectionMonitorPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QNetworkConnectionMonitor); + +public: + QNetworkConnectionMonitorPrivate(); + ~QNetworkConnectionMonitorPrivate(); + + Q_REQUIRED_RESULT + bool setTargets(const QHostAddress &local, const QHostAddress &remote); + Q_REQUIRED_RESULT + bool startMonitoring(); + void stopMonitoring(); + + void setConnectivity(NLM_CONNECTIVITY newConnectivity); + +private: + ComPtr connectionEvents; + // We can assume we have access to internet/subnet when this class is created because + // connection has already been established to the peer: + NLM_CONNECTIVITY connectivity = + NLM_CONNECTIVITY(NLM_CONNECTIVITY_IPV4_INTERNET | NLM_CONNECTIVITY_IPV6_INTERNET + | NLM_CONNECTIVITY_IPV4_SUBNET | NLM_CONNECTIVITY_IPV6_SUBNET); + + bool sameSubnet = false; + bool monitoring = false; + bool comInitFailed = false; + bool remoteIsIPv6 = false; +}; + +QNetworkConnectionEvents::QNetworkConnectionEvents(QNetworkConnectionMonitorPrivate *monitor) + : monitor(monitor) +{ + auto hr = CoCreateInstance(CLSID_NetworkListManager, nullptr, CLSCTX_INPROC_SERVER, + IID_INetworkListManager, &networkListManager); + if (FAILED(hr)) { + qCWarning(lcNetMon) << "Could not get a NetworkListManager instance:" + << errorStringFromHResult(hr); + return; + } + + ComPtr connectionPointContainer; + hr = networkListManager.As(&connectionPointContainer); + if (SUCCEEDED(hr)) { + hr = connectionPointContainer->FindConnectionPoint(IID_INetworkConnectionEvents, + &connectionPoint); + } + if (FAILED(hr)) { + qCWarning(lcNetMon) << "Failed to get connection point for network events:" + << errorStringFromHResult(hr); + } +} + +QNetworkConnectionEvents::~QNetworkConnectionEvents() +{ + Q_ASSERT(ref == 0); +} + +ComPtr QNetworkConnectionEvents::getNetworkConnectionFromAdapterGuid(QUuid guid) +{ + ComPtr connections; + auto hr = networkListManager->GetNetworkConnections(connections.GetAddressOf()); + if (FAILED(hr)) { + qCWarning(lcNetMon) << "Failed to enumerate network connections:" + << errorStringFromHResult(hr); + return nullptr; + } + ComPtr connection = nullptr; + do { + hr = connections->Next(1, connection.GetAddressOf(), nullptr); + if (FAILED(hr)) { + qCWarning(lcNetMon) << "Failed to get next network connection in enumeration:" + << errorStringFromHResult(hr); + break; + } + if (connection) { + GUID adapterId; + hr = connection->GetAdapterId(&adapterId); + if (FAILED(hr)) { + qCWarning(lcNetMon) << "Failed to get adapter ID from network connection:" + << errorStringFromHResult(hr); + continue; + } + if (guid == adapterId) + return connection; + } + } while (connection); + return nullptr; +} + +HRESULT STDMETHODCALLTYPE QNetworkConnectionEvents::QueryInterface(REFIID riid, void **ppvObject) +{ + if (!ppvObject) + return E_INVALIDARG; + + return QueryInterfaceImpl(this, riid, ppvObject) + || QueryInterfaceImpl(this, riid, ppvObject) + ? S_OK + : E_NOINTERFACE; +} + +HRESULT STDMETHODCALLTYPE QNetworkConnectionEvents::NetworkConnectionConnectivityChanged( + GUID connectionId, NLM_CONNECTIVITY newConnectivity) +{ + // This function is run on a different thread than 'monitor' is created on, so we need to run + // it on that thread + QMetaObject::invokeMethod(monitor->q_ptr, + [this, connectionId, newConnectivity, monitor = this->monitor]() { + if (connectionId == currentConnectionId) + monitor->setConnectivity(newConnectivity); + }, + Qt::QueuedConnection); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE QNetworkConnectionEvents::NetworkConnectionPropertyChanged( + GUID connectionId, NLM_CONNECTION_PROPERTY_CHANGE flags) +{ + Q_UNUSED(connectionId); + Q_UNUSED(flags); + return E_NOTIMPL; +} + +bool QNetworkConnectionEvents::setTarget(const QNetworkInterface &iface) +{ + // Unset this in case it's already set to something + currentConnectionId = QUuid{}; + + NET_LUID luid; + if (ConvertInterfaceIndexToLuid(iface.index(), &luid) != NO_ERROR) { + qCWarning(lcNetMon, "Could not get the LUID for the interface."); + return false; + } + GUID guid; + if (ConvertInterfaceLuidToGuid(&luid, &guid) != NO_ERROR) { + qCWarning(lcNetMon, "Could not get the GUID for the interface."); + return false; + } + ComPtr connection = getNetworkConnectionFromAdapterGuid(guid); + if (!connection) { + qCWarning(lcNetMon, "Could not get the INetworkConnection instance for the adapter GUID."); + return false; + } + auto hr = connection->GetConnectionId(&guid); + if (FAILED(hr)) { + qCWarning(lcNetMon) << "Failed to get the connection's GUID:" << errorStringFromHResult(hr); + return false; + } + currentConnectionId = guid; + + return true; +} + +bool QNetworkConnectionEvents::startMonitoring() +{ + if (currentConnectionId.isNull()) { + qCWarning(lcNetMon, "Can not start monitoring, set targets first"); + return false; + } + if (!connectionPoint) { + qCWarning(lcNetMon, + "We don't have the connection point, cannot start listening to events!"); + return false; + } + + auto hr = connectionPoint->Advise(this, &cookie); + if (FAILED(hr)) { + qCWarning(lcNetMon) << "Failed to subscribe to network connectivity events:" + << errorStringFromHResult(hr); + return false; + } + return true; +} + +bool QNetworkConnectionEvents::stopMonitoring() +{ + auto hr = connectionPoint->Unadvise(cookie); + if (FAILED(hr)) { + qCWarning(lcNetMon) << "Failed to unsubscribe from network connection events:" + << errorStringFromHResult(hr); + return false; + } + cookie = 0; + currentConnectionId = QUuid{}; + return true; +} + +QNetworkConnectionMonitorPrivate::QNetworkConnectionMonitorPrivate() +{ + auto hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); + if (FAILED(hr)) { + qCWarning(lcNetMon) << "Failed to initialize COM:" << errorStringFromHResult(hr); + comInitFailed = true; + return; + } + + connectionEvents = new QNetworkConnectionEvents(this); +} + +QNetworkConnectionMonitorPrivate::~QNetworkConnectionMonitorPrivate() +{ + if (comInitFailed) + return; + connectionEvents.Reset(); + CoUninitialize(); +} + +bool QNetworkConnectionMonitorPrivate::setTargets(const QHostAddress &local, + const QHostAddress &remote) +{ + if (comInitFailed) + return false; + + QNetworkInterface iface = getInterfaceFromHostAddress(local); + if (!iface.isValid()) + return false; + const auto &addressEntries = iface.addressEntries(); + auto it = std::find_if( + addressEntries.cbegin(), addressEntries.cend(), + [&local](const QNetworkAddressEntry &entry) { return entry.ip() == local; }); + if (Q_UNLIKELY(it == addressEntries.cend())) { + qCWarning(lcNetMon, "The address entry we were working with disappeared"); + return false; + } + sameSubnet = remote.isInSubnet(local, it->prefixLength()); + remoteIsIPv6 = remote.protocol() == QAbstractSocket::IPv6Protocol; + + return connectionEvents->setTarget(iface); +} + +void QNetworkConnectionMonitorPrivate::setConnectivity(NLM_CONNECTIVITY newConnectivity) +{ + Q_Q(QNetworkConnectionMonitor); + const bool reachable = q->isReachable(); + connectivity = newConnectivity; + const bool newReachable = q->isReachable(); + if (reachable != newReachable) + emit q->reachabilityChanged(newReachable); +} + +bool QNetworkConnectionMonitorPrivate::startMonitoring() +{ + Q_ASSERT(connectionEvents); + Q_ASSERT(!monitoring); + if (connectionEvents->startMonitoring()) + monitoring = true; + return monitoring; +} + +void QNetworkConnectionMonitorPrivate::stopMonitoring() +{ + Q_ASSERT(connectionEvents); + Q_ASSERT(monitoring); + if (connectionEvents->stopMonitoring()) + monitoring = false; +} + +QNetworkConnectionMonitor::QNetworkConnectionMonitor() + : QObject(*new QNetworkConnectionMonitorPrivate) +{ +} + +QNetworkConnectionMonitor::QNetworkConnectionMonitor(const QHostAddress &local, + const QHostAddress &remote) + : QObject(*new QNetworkConnectionMonitorPrivate) +{ + setTargets(local, remote); +} + +QNetworkConnectionMonitor::~QNetworkConnectionMonitor() = default; + +bool QNetworkConnectionMonitor::setTargets(const QHostAddress &local, const QHostAddress &remote) +{ + if (isMonitoring()) { + qCWarning(lcNetMon, "Monitor is already active, call stopMonitoring() first"); + return false; + } + if (local.isNull()) { + qCWarning(lcNetMon, "Invalid (null) local address, cannot create a reachability target"); + return false; + } + // Silently return false for loopback addresses instead of printing warnings later + if (remote.isLoopback()) + return false; + + return d_func()->setTargets(local, remote); +} + +bool QNetworkConnectionMonitor::startMonitoring() +{ + Q_D(QNetworkConnectionMonitor); + if (isMonitoring()) { + qCWarning(lcNetMon, "Monitor is already active, call stopMonitoring() first"); + return false; + } + return d->startMonitoring(); +} + +bool QNetworkConnectionMonitor::isMonitoring() const +{ + return d_func()->monitoring; +} + +void QNetworkConnectionMonitor::stopMonitoring() +{ + Q_D(QNetworkConnectionMonitor); + if (!isMonitoring()) { + qCWarning(lcNetMon, "stopMonitoring was called when not monitoring!"); + return; + } + d->stopMonitoring(); +} + +bool QNetworkConnectionMonitor::isReachable() +{ + Q_D(QNetworkConnectionMonitor); + NLM_CONNECTIVITY required = d->sameSubnet + ? (d->remoteIsIPv6 ? NLM_CONNECTIVITY_IPV6_SUBNET : NLM_CONNECTIVITY_IPV4_SUBNET) + : (d->remoteIsIPv6 ? NLM_CONNECTIVITY_IPV6_INTERNET : NLM_CONNECTIVITY_IPV4_INTERNET); + return d_func()->connectivity & required; +} + +class QNetworkListManagerEvents final : public INetworkListManagerEvents +{ +public: + QNetworkListManagerEvents(QNetworkStatusMonitorPrivate *monitor); + ~QNetworkListManagerEvents(); + + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override; + + ULONG STDMETHODCALLTYPE AddRef() override { return ++ref; } + ULONG STDMETHODCALLTYPE Release() override + { + if (--ref == 0) { + delete this; + return 0; + } + return ref; + } + + HRESULT STDMETHODCALLTYPE ConnectivityChanged(NLM_CONNECTIVITY newConnectivity) override; + + Q_REQUIRED_RESULT + bool start(); + Q_REQUIRED_RESULT + bool stop(); + +private: + ComPtr networkListManager = nullptr; + ComPtr connectionPoint = nullptr; + + QNetworkStatusMonitorPrivate *monitor = nullptr; + + QAtomicInteger ref = 1; // start at 1 for our own initial reference + DWORD cookie = 0; +}; + +class QNetworkStatusMonitorPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QNetworkStatusMonitor); + +public: + QNetworkStatusMonitorPrivate(); + ~QNetworkStatusMonitorPrivate(); + + Q_REQUIRED_RESULT + bool start(); + void stop(); + + void setConnectivity(NLM_CONNECTIVITY newConnectivity); + +private: + friend class QNetworkListManagerEvents; + + ComPtr managerEvents; + NLM_CONNECTIVITY connectivity = NLM_CONNECTIVITY_DISCONNECTED; + + bool monitoring = false; + bool comInitFailed = false; +}; + +QNetworkListManagerEvents::QNetworkListManagerEvents(QNetworkStatusMonitorPrivate *monitor) + : monitor(monitor) +{ + auto hr = CoCreateInstance(CLSID_NetworkListManager, nullptr, CLSCTX_INPROC_SERVER, + IID_INetworkListManager, &networkListManager); + if (FAILED(hr)) { + qCWarning(lcNetMon) << "Could not get a NetworkListManager instance:" + << errorStringFromHResult(hr); + return; + } + + // Set initial connectivity + hr = networkListManager->GetConnectivity(&monitor->connectivity); + if (FAILED(hr)) + qCWarning(lcNetMon) << "Could not get connectivity:" << errorStringFromHResult(hr); + + ComPtr connectionPointContainer; + hr = networkListManager.As(&connectionPointContainer); + if (SUCCEEDED(hr)) { + hr = connectionPointContainer->FindConnectionPoint(IID_INetworkListManagerEvents, + &connectionPoint); + } + if (FAILED(hr)) { + qCWarning(lcNetMon) << "Failed to get connection point for network list manager events:" + << errorStringFromHResult(hr); + } +} + +QNetworkListManagerEvents::~QNetworkListManagerEvents() +{ + Q_ASSERT(ref == 0); +} + +HRESULT STDMETHODCALLTYPE QNetworkListManagerEvents::QueryInterface(REFIID riid, void **ppvObject) +{ + if (!ppvObject) + return E_INVALIDARG; + + return QueryInterfaceImpl(this, riid, ppvObject) + || QueryInterfaceImpl(this, riid, ppvObject) + ? S_OK + : E_NOINTERFACE; +} + +HRESULT STDMETHODCALLTYPE +QNetworkListManagerEvents::ConnectivityChanged(NLM_CONNECTIVITY newConnectivity) +{ + // This function is run on a different thread than 'monitor' is created on, so we need to run + // it on that thread + QMetaObject::invokeMethod(monitor->q_ptr, + [newConnectivity, monitor = this->monitor]() { + monitor->setConnectivity(newConnectivity); + }, + Qt::QueuedConnection); + return S_OK; +} + +bool QNetworkListManagerEvents::start() +{ + if (!connectionPoint) { + qCWarning(lcNetMon, "Initialization failed, can't start!"); + return false; + } + auto hr = connectionPoint->Advise(this, &cookie); + if (FAILED(hr)) { + qCWarning(lcNetMon) << "Failed to subscribe to network connectivity events:" + << errorStringFromHResult(hr); + return false; + } + return true; +} + +bool QNetworkListManagerEvents::stop() +{ + Q_ASSERT(connectionPoint); + auto hr = connectionPoint->Unadvise(cookie); + if (FAILED(hr)) { + qCWarning(lcNetMon) << "Failed to unsubscribe from network connectivity events:" + << errorStringFromHResult(hr); + return false; + } + cookie = 0; + return true; +} + +QNetworkStatusMonitorPrivate::QNetworkStatusMonitorPrivate() +{ + auto hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); + if (FAILED(hr)) { + qCWarning(lcNetMon) << "Failed to initialize COM:" << errorStringFromHResult(hr); + comInitFailed = true; + return; + } + managerEvents = new QNetworkListManagerEvents(this); +} + +QNetworkStatusMonitorPrivate::~QNetworkStatusMonitorPrivate() +{ + if (comInitFailed) + return; + if (monitoring) + stop(); + managerEvents.Reset(); + CoUninitialize(); +} + +void QNetworkStatusMonitorPrivate::setConnectivity(NLM_CONNECTIVITY newConnectivity) +{ + Q_Q(QNetworkStatusMonitor); + + const bool oldAccessibility = q->isNetworkAccesible(); + connectivity = newConnectivity; + const bool accessibility = q->isNetworkAccesible(); + if (oldAccessibility != accessibility) + emit q->onlineStateChanged(accessibility); +} + +bool QNetworkStatusMonitorPrivate::start() +{ + if (comInitFailed) + return false; + Q_ASSERT(managerEvents); + Q_ASSERT(!monitoring); + if (managerEvents->start()) + monitoring = true; + return monitoring; +} + +void QNetworkStatusMonitorPrivate::stop() +{ + Q_ASSERT(managerEvents); + Q_ASSERT(monitoring); + if (managerEvents->stop()) + monitoring = false; +} + +QNetworkStatusMonitor::QNetworkStatusMonitor() : QObject(*new QNetworkStatusMonitorPrivate) {} + +QNetworkStatusMonitor::~QNetworkStatusMonitor() {} + +bool QNetworkStatusMonitor::start() +{ + if (isMonitoring()) { + qCWarning(lcNetMon, "Monitor is already active, call stopMonitoring() first"); + return false; + } + + return d_func()->start(); +} + +void QNetworkStatusMonitor::stop() +{ + if (!isMonitoring()) { + qCWarning(lcNetMon, "stopMonitoring was called when not monitoring!"); + return; + } + + d_func()->stop(); +} + +bool QNetworkStatusMonitor::isMonitoring() const +{ + return d_func()->monitoring; +} + +bool QNetworkStatusMonitor::isNetworkAccesible() +{ + return d_func()->connectivity + & (NLM_CONNECTIVITY_IPV4_INTERNET | NLM_CONNECTIVITY_IPV6_INTERNET + | NLM_CONNECTIVITY_IPV4_SUBNET | NLM_CONNECTIVITY_IPV6_SUBNET); +} + +bool QNetworkStatusMonitor::isEnabled() +{ + return true; +} + +void QNetworkStatusMonitor::reachabilityChanged(bool online) +{ + Q_UNUSED(online); + Q_UNREACHABLE(); +} + +QT_END_NAMESPACE From 006baa1c6007abc2c11dc20433f6eeef4cb9cfe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Fri, 10 May 2019 15:08:12 +0200 Subject: [PATCH 025/264] qnetconmonitor: Fix misspelling of accessible Change-Id: Ia898d305f64abb5d3d1de007c764c143b26c7654 Reviewed-by: Timur Pocheptsov --- src/network/access/qnetworkaccessmanager.cpp | 4 ++-- src/network/kernel/qnetconmonitor_darwin.mm | 2 +- src/network/kernel/qnetconmonitor_p.h | 2 +- src/network/kernel/qnetconmonitor_stub.cpp | 2 +- src/network/kernel/qnetconmonitor_win.cpp | 6 +++--- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 548cfe6593..92778acd6a 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -493,9 +493,9 @@ QNetworkAccessManager::QNetworkAccessManager(QObject *parent) connect(&d->statusMonitor, SIGNAL(onlineStateChanged(bool)), SLOT(_q_onlineStateChanged(bool))); #ifdef QT_NO_BEARERMANAGEMENT - d->networkAccessible = d->statusMonitor.isNetworkAccesible(); + d->networkAccessible = d->statusMonitor.isNetworkAccessible(); #else - d->networkAccessible = d->statusMonitor.isNetworkAccesible() ? Accessible : NotAccessible; + d->networkAccessible = d->statusMonitor.isNetworkAccessible() ? Accessible : NotAccessible; } else { // if a session is required, we track online state through // the QNetworkSession's signals if a request is already made. diff --git a/src/network/kernel/qnetconmonitor_darwin.mm b/src/network/kernel/qnetconmonitor_darwin.mm index a64cd6e530..f6daf9ed50 100644 --- a/src/network/kernel/qnetconmonitor_darwin.mm +++ b/src/network/kernel/qnetconmonitor_darwin.mm @@ -376,7 +376,7 @@ bool QNetworkStatusMonitor::isMonitoring() const return d->ipv4Probe.isMonitoring() || d->ipv6Probe.isMonitoring(); } -bool QNetworkStatusMonitor::isNetworkAccesible() +bool QNetworkStatusMonitor::isNetworkAccessible() { // This function is to be executed on the thread that created // and uses 'this'. diff --git a/src/network/kernel/qnetconmonitor_p.h b/src/network/kernel/qnetconmonitor_p.h index 74ee56d422..b26c8e5457 100644 --- a/src/network/kernel/qnetconmonitor_p.h +++ b/src/network/kernel/qnetconmonitor_p.h @@ -99,7 +99,7 @@ public: QNetworkStatusMonitor(); ~QNetworkStatusMonitor(); - bool isNetworkAccesible(); + bool isNetworkAccessible(); bool start(); void stop(); diff --git a/src/network/kernel/qnetconmonitor_stub.cpp b/src/network/kernel/qnetconmonitor_stub.cpp index 7f3a0c44c6..1ad4e9ba5a 100644 --- a/src/network/kernel/qnetconmonitor_stub.cpp +++ b/src/network/kernel/qnetconmonitor_stub.cpp @@ -123,7 +123,7 @@ bool QNetworkStatusMonitor::isMonitoring() const return false; } -bool QNetworkStatusMonitor::isNetworkAccesible() +bool QNetworkStatusMonitor::isNetworkAccessible() { return false; } diff --git a/src/network/kernel/qnetconmonitor_win.cpp b/src/network/kernel/qnetconmonitor_win.cpp index 2eab0a062f..8e3cad59f8 100644 --- a/src/network/kernel/qnetconmonitor_win.cpp +++ b/src/network/kernel/qnetconmonitor_win.cpp @@ -634,9 +634,9 @@ void QNetworkStatusMonitorPrivate::setConnectivity(NLM_CONNECTIVITY newConnectiv { Q_Q(QNetworkStatusMonitor); - const bool oldAccessibility = q->isNetworkAccesible(); + const bool oldAccessibility = q->isNetworkAccessible(); connectivity = newConnectivity; - const bool accessibility = q->isNetworkAccesible(); + const bool accessibility = q->isNetworkAccessible(); if (oldAccessibility != accessibility) emit q->onlineStateChanged(accessibility); } @@ -689,7 +689,7 @@ bool QNetworkStatusMonitor::isMonitoring() const return d_func()->monitoring; } -bool QNetworkStatusMonitor::isNetworkAccesible() +bool QNetworkStatusMonitor::isNetworkAccessible() { return d_func()->connectivity & (NLM_CONNECTIVITY_IPV4_INTERNET | NLM_CONNECTIVITY_IPV6_INTERNET From 8436fa30af3a74ca6bceefd88915f514ca9749d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Mon, 20 May 2019 16:05:14 +0200 Subject: [PATCH 026/264] Add manual test for QNetwork{Connection|Status}Monitor Simplistic console application with one test for each of the two classes. Simply tests that we receive the signal when the connection is disrupted in some way. This patch also exports the classes for tests/developer builds so that we can actually link with them. Change-Id: I8066312274350984110c3f3ad3e94854adca7c2a Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne --- src/network/kernel/qnetconmonitor_p.h | 4 +- tests/manual/manual.pro | 1 + .../manual/qnetconmonitor/qnetconmonitor.pro | 4 + .../qnetconmonitor/tst_qnetconmonitor.cpp | 220 ++++++++++++++++++ 4 files changed, 227 insertions(+), 2 deletions(-) create mode 100644 tests/manual/qnetconmonitor/qnetconmonitor.pro create mode 100644 tests/manual/qnetconmonitor/tst_qnetconmonitor.cpp diff --git a/src/network/kernel/qnetconmonitor_p.h b/src/network/kernel/qnetconmonitor_p.h index b26c8e5457..282bac5081 100644 --- a/src/network/kernel/qnetconmonitor_p.h +++ b/src/network/kernel/qnetconmonitor_p.h @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE class QNetworkConnectionMonitorPrivate; -class QNetworkConnectionMonitor : public QObject +class Q_AUTOTEST_EXPORT QNetworkConnectionMonitor : public QObject { Q_OBJECT @@ -91,7 +91,7 @@ private: }; class QNetworkStatusMonitorPrivate; -class QNetworkStatusMonitor : public QObject +class Q_AUTOTEST_EXPORT QNetworkStatusMonitor : public QObject { Q_OBJECT diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index 63c8eb6538..e688546374 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -23,6 +23,7 @@ qimagereader \ qlayout \ qlocale \ qmimedatabase \ +qnetconmonitor \ qnetworkaccessmanager/qget \ qnetworkconfigurationmanager \ qnetworkconfiguration \ diff --git a/tests/manual/qnetconmonitor/qnetconmonitor.pro b/tests/manual/qnetconmonitor/qnetconmonitor.pro new file mode 100644 index 0000000000..dda88c4cd7 --- /dev/null +++ b/tests/manual/qnetconmonitor/qnetconmonitor.pro @@ -0,0 +1,4 @@ +TEMPLATE = app +QT = network-private testlib +CONFIG += console +SOURCES += tst_qnetconmonitor.cpp diff --git a/tests/manual/qnetconmonitor/tst_qnetconmonitor.cpp b/tests/manual/qnetconmonitor/tst_qnetconmonitor.cpp new file mode 100644 index 0000000000..92daee3348 --- /dev/null +++ b/tests/manual/qnetconmonitor/tst_qnetconmonitor.cpp @@ -0,0 +1,220 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include +#include + +#include + +void testDetectDisconnection(); +void testDetectRouteDisrupted(); + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + if (!QNetworkStatusMonitor::isEnabled()) { + qWarning("QNetworkStatusMonitor is not enabled for this platform!"); + return 0; + } + + while (true) { + + QByteArray indent(" "); + { + QTextStream writer(stdout); + writer << "Manual test for QNetwork{Status|Connection}Monitor\n" + << "The tests are grouped by what they test. Run them in any order\n" + << "- QNetworkStatusMonitor tests:\n" + << indent << "c" << indent << "Test connection and disconnection detection.\n" + << "- QNetworkConnectionMonitor tests:\n" + << indent << "r" << indent << "Test detection of disruption of route to target.\n" + << "- General\n" + << indent << "q" << indent << "Quit the test.\n" + << "> "; + } + + auto getCommand = []() { + char ch; + QTextStream reader(stdin); + reader >> ch; + return ch; + }; + + switch (getCommand()) { + case 'c': + testDetectDisconnection(); + break; + case 'r': + testDetectRouteDisrupted(); + break; + case 'q': + return 0; + } + } + Q_UNREACHABLE(); + return 0; +} + +bool ensureNetworkAccessible(QNetworkStatusMonitor &status, QTextStream &writer) +{ + if (!status.isNetworkAccessible()) { + writer << "Network currently not accessible, please make sure you have an internet " + "connection. Will wait for a connection for 20 seconds.\n"; + writer.flush(); + QDeadlineTimer timer{ 20 * 1000 }; + while (!timer.hasExpired() && !status.isNetworkAccessible()) + QCoreApplication::processEvents(); + if (!status.isNetworkAccessible()) { + writer << "Error: No network in 20 seconds, ending now!\n"; + return false; + } + writer << "Network successfully connected, thanks!\n"; + } + return true; +} + +void testDetectDisconnection() +{ + QTextStream writer(stdout); + QNetworkStatusMonitor status; + + if (!status.start()) { + writer << "Error: Failed to start"; + return; + } + + if (!ensureNetworkAccessible(status, writer)) + return; + + QSignalSpy onlineStateSpy(&status, &QNetworkStatusMonitor::onlineStateChanged); + + writer << "Please disconnect from the internet within 20 seconds\n"; + writer.flush(); + QDeadlineTimer timer{ 20 * 1000 }; + while (!timer.hasExpired() && status.isNetworkAccessible()) + QCoreApplication::processEvents(); + if (status.isNetworkAccessible()) { + writer << "Error: Still connected after 20 seconds, ending now!\n"; + return; + } + if (onlineStateSpy.count() == 0) { + writer << "Error: There was a disconnection but there was no signal emitted!\n"; + return; + } + // Get the final parameter of the final signal emission and make sure it is false. + if (onlineStateSpy.last().last().toBool()) { + writer << "Error: There was a disconnection but the latest signal emitted says we are online!\n"; + return; + } + writer << "Success, connection loss was detected!\n"; +} + +void testDetectRouteDisrupted() +{ + QTextStream writer(stdout); + + { + QNetworkStatusMonitor status; + if (!status.start()) { + writer << "Error: Failed to start"; + return; + } + if (!ensureNetworkAccessible(status, writer)) + return; + } + + QNetworkConnectionMonitor connection; + + auto readLineFromStdin = []() -> QString { + QTextStream in(stdin); + return in.readLine(); + }; + + writer << "Type your local IP address: "; + writer.flush(); + const QHostAddress local{ readLineFromStdin() }; + if (local.isNull()) { + writer << "Error: The address is invalid!\n"; + return; + } + + const QHostAddress defaultAddress{ QString::fromLatin1("1.1.1.1") }; + QHostAddress remote; + do { + writer << "Type a remote IP address [" << defaultAddress.toString() << "]: "; + writer.flush(); + QString address = readLineFromStdin(); + if (address.isEmpty()) { + remote = defaultAddress; + } else { + QHostAddress remoteTemp{ address }; + if (remoteTemp.isNull()) { + writer << "Invalid address\n"; + } else { + remote = remoteTemp; + } + } + } while (remote.isNull()); + + if (!connection.setTargets(local, remote)) { + writer << "Error: Failed to set the targets!\n"; + return; + } + if (!connection.isReachable()) { + writer << "Error: Target is not reachable!\n"; + return; + } + if (!connection.startMonitoring()) { + writer << "Error: Failed to start monitoring!\n"; + return; + } + + QSignalSpy reachabilitySpy(&connection, &QNetworkConnectionMonitor::reachabilityChanged); + + writer << "QNetworkConnectionMonitor might assume the target is initially reachable.\n" + "If it is not reachable then this test might not work correctly.\n" + "Please disrupt the connection between your machine and the target within 20 " + "seconds\n"; + writer.flush(); + reachabilitySpy.wait(20 * 1000); + if (reachabilitySpy.count() == 0) { + writer << "Error: There was a disconnection but there was no signal emitted!\n"; + return; + } + // Get the final parameter of the final signal emission and make sure it is false. + if (reachabilitySpy.last().last().toBool()) { + writer << "Error: There was a disconnection but the latest signal emitted says the target is " + "reachable!\n"; + return; + } + writer << "Success, connection disruption was detected!\n"; +} From 888e49802058f8093c8ff23f724e93e0c4769234 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 4 Jul 2019 14:03:57 +0200 Subject: [PATCH 027/264] QHostInfo: perform deferred cleanup (std::any_of) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code contained a copy of std::any_of from a time when we couldn't rely it's availability in all compilers. We now can, so remove the copy. Change-Id: I356077f58ae6a48b71f2dd98a2dab4e2acf985c7 Reviewed-by: Anton Kudryavtsev Reviewed-by: Mårten Nordheim --- src/network/kernel/qhostinfo.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index 25ff873307..6302ad62eb 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -85,13 +85,6 @@ private: QString m_toBeLookedUp; }; -// ### C++11: remove once we can use std::any_of() -template -bool any_of(InputIt first, InputIt last, UnaryPredicate p) -{ - return std::find_if(first, last, p) != last; -} - template std::pair separate_if(InputIt first, InputIt last, OutputIt1 dest1, OutputIt2 dest2, UnaryPredicate p) { @@ -950,7 +943,7 @@ void QHostInfoLookupManager::work() #if QT_CONFIG(thread) auto isAlreadyRunning = [this](QHostInfoRunnable *lookup) { - return any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp)); + return std::any_of(currentLookups.cbegin(), currentLookups.cend(), ToBeLookedUpEquals(lookup->toBeLookedUp)); }; // Transfer any postponed lookups that aren't currently running to the scheduled list, keeping already-running lookups: From 6c136973fd9b82420c818668086abe93f534993d Mon Sep 17 00:00:00 2001 From: Daniel Smith Date: Fri, 5 Jul 2019 14:55:48 +0200 Subject: [PATCH 028/264] unblacklist passing tests These tests have not failed on the removed platforms for at least 60 days Task-number: QTBUG-76608 Change-Id: If7a9f4db907124e3cd54e3f4b0ad3e20717d1912 Reviewed-by: Volker Hilsheimer --- .../qparallelanimationgroup/BLACKLIST | 1 - .../animation/qpauseanimation/BLACKLIST | 11 +- .../animation/qpropertyanimation/BLACKLIST | 6 - .../qsequentialanimationgroup/BLACKLIST | 8 +- tests/auto/corelib/io/qfile/BLACKLIST | 7 - .../corelib/io/qfilesystemwatcher/BLACKLIST | 5 +- tests/auto/corelib/io/qprocess/BLACKLIST | 8 +- .../corelib/kernel/qelapsedtimer/BLACKLIST | 4 +- .../corelib/kernel/qeventdispatcher/BLACKLIST | 6 - .../auto/corelib/kernel/qeventloop/BLACKLIST | 2 - tests/auto/corelib/kernel/qobject/BLACKLIST | 2 - .../corelib/kernel/qsocketnotifier/BLACKLIST | 5 +- tests/auto/corelib/kernel/qtimer/BLACKLIST | 10 +- .../serialization/qtextstream/BLACKLIST | 3 +- .../auto/corelib/thread/qsemaphore/BLACKLIST | 3 + tests/auto/corelib/thread/qthread/BLACKLIST | 7 +- .../auto/corelib/thread/qthreadpool/BLACKLIST | 8 +- .../corelib/thread/qwaitcondition/BLACKLIST | 2 - tests/auto/corelib/time/qdatetime/BLACKLIST | 2 - tests/auto/corelib/tools/qlocale/BLACKLIST | 2 - tests/auto/corelib/tools/qtimeline/BLACKLIST | 6 +- .../qdbusabstractadaptor/BLACKLIST | 0 .../dbus/qdbusconnection_spyhook/BLACKLIST | 0 .../auto/gui/kernel/qguiapplication/BLACKLIST | 5 +- .../gui/kernel/qguieventdispatcher/BLACKLIST | 4 +- tests/auto/gui/kernel/qguieventloop/BLACKLIST | 2 - tests/auto/gui/kernel/qguitimer/BLACKLIST | 8 + tests/auto/gui/kernel/qtouchevent/BLACKLIST | 6 +- tests/auto/gui/kernel/qwindow/BLACKLIST | 33 +-- tests/auto/gui/qopengl/BLACKLIST | 8 - tests/auto/gui/text/qfont/BLACKLIST | 2 - tests/auto/gui/text/qglyphrun/BLACKLIST | 1 - .../gui/text/qtextdocumentlayout/BLACKLIST | 4 +- .../gui/text/qtextmarkdownwriter/BLACKLIST | 3 +- .../access/qabstractnetworkcache/BLACKLIST | 2 +- tests/auto/network/access/qftp/BLACKLIST | 11 + .../network/access/qnetworkreply/BLACKLIST | 246 ++++++++++++++++-- tests/auto/network/access/spdy/BLACKLIST | 10 +- .../auto/network/kernel/qdnslookup/BLACKLIST | 12 +- .../socket/platformsocketengine/BLACKLIST | 9 +- .../socket/qhttpsocketengine/BLACKLIST | 5 +- .../socket/qsocks5socketengine/BLACKLIST | 11 +- .../auto/network/socket/qtcpserver/BLACKLIST | 25 +- .../auto/network/socket/qtcpsocket/BLACKLIST | 13 +- .../auto/network/socket/qudpsocket/BLACKLIST | 28 +- .../network/ssl/qsslcertificate/BLACKLIST | 12 +- tests/auto/network/ssl/qsslkey/BLACKLIST | 18 +- tests/auto/network/ssl/qsslsocket/BLACKLIST | 18 +- tests/auto/opengl/qgl/BLACKLIST | 31 +-- tests/auto/other/gestures/BLACKLIST | 14 +- tests/auto/other/networkselftest/BLACKLIST | 6 +- tests/auto/other/qaccessibilitymac/BLACKLIST | 2 - tests/auto/other/qfocusevent/BLACKLIST | 3 - .../BLACKLIST | 3 + tests/auto/widgets/dialogs/qdialog/BLACKLIST | 2 +- .../widgets/dialogs/qfiledialog2/BLACKLIST | 4 +- .../dialogs/qfilesystemmodel/BLACKLIST | 16 +- .../widgets/dialogs/qmessagebox/BLACKLIST | 6 +- .../widgets/dialogs/qprogressdialog/BLACKLIST | 2 +- .../widgets/effects/qgraphicseffect/BLACKLIST | 3 +- .../graphicsview/qgraphicsscene/BLACKLIST | 8 +- .../graphicsview/qgraphicsview/BLACKLIST | 28 +- .../widgets/itemviews/qcolumnview/BLACKLIST | 2 - .../widgets/itemviews/qheaderview/BLACKLIST | 2 +- .../widgets/itemviews/qtableview/BLACKLIST | 3 +- .../widgets/kernel/qapplication/BLACKLIST | 4 +- tests/auto/widgets/kernel/qwidget/BLACKLIST | 46 ++-- .../widgets/kernel/qwidget_window/BLACKLIST | 3 +- tests/auto/widgets/util/qcompleter/BLACKLIST | 6 +- .../widgets/widgets/qdoublespinbox/BLACKLIST | 4 +- tests/auto/widgets/widgets/qmdiarea/BLACKLIST | 19 +- .../widgets/widgets/qmdisubwindow/BLACKLIST | 2 - tests/auto/widgets/widgets/qmenu/BLACKLIST | 12 +- tests/auto/widgets/widgets/qmenubar/BLACKLIST | 2 +- .../widgets/widgets/qopenglwidget/BLACKLIST | 6 +- .../auto/widgets/widgets/qscrollbar/BLACKLIST | 3 - tests/auto/widgets/widgets/qspinbox/BLACKLIST | 3 +- .../widgets/widgets/qtoolbutton/BLACKLIST | 2 +- 78 files changed, 540 insertions(+), 311 deletions(-) delete mode 100644 tests/auto/corelib/animation/qpropertyanimation/BLACKLIST delete mode 100644 tests/auto/corelib/io/qfile/BLACKLIST delete mode 100644 tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST delete mode 100644 tests/auto/corelib/kernel/qeventloop/BLACKLIST delete mode 100644 tests/auto/corelib/kernel/qobject/BLACKLIST delete mode 100644 tests/auto/corelib/thread/qwaitcondition/BLACKLIST delete mode 100644 tests/auto/corelib/time/qdatetime/BLACKLIST delete mode 100644 tests/auto/corelib/tools/qlocale/BLACKLIST create mode 100644 tests/auto/dbus/qdbusabstractadaptor/qdbusabstractadaptor/BLACKLIST create mode 100644 tests/auto/dbus/qdbusconnection_spyhook/BLACKLIST delete mode 100644 tests/auto/gui/kernel/qguieventloop/BLACKLIST create mode 100644 tests/auto/gui/kernel/qguitimer/BLACKLIST delete mode 100644 tests/auto/gui/text/qfont/BLACKLIST delete mode 100644 tests/auto/other/qaccessibilitymac/BLACKLIST delete mode 100644 tests/auto/widgets/itemviews/qcolumnview/BLACKLIST delete mode 100644 tests/auto/widgets/widgets/qmdisubwindow/BLACKLIST delete mode 100644 tests/auto/widgets/widgets/qscrollbar/BLACKLIST diff --git a/tests/auto/corelib/animation/qparallelanimationgroup/BLACKLIST b/tests/auto/corelib/animation/qparallelanimationgroup/BLACKLIST index b5b37b4498..3e42a737df 100644 --- a/tests/auto/corelib/animation/qparallelanimationgroup/BLACKLIST +++ b/tests/auto/corelib/animation/qparallelanimationgroup/BLACKLIST @@ -1,3 +1,2 @@ [deleteChildrenWithRunningGroup] -osx-10.12 osx-10.13 diff --git a/tests/auto/corelib/animation/qpauseanimation/BLACKLIST b/tests/auto/corelib/animation/qpauseanimation/BLACKLIST index e223ec82e2..53372ce9ae 100644 --- a/tests/auto/corelib/animation/qpauseanimation/BLACKLIST +++ b/tests/auto/corelib/animation/qpauseanimation/BLACKLIST @@ -1,6 +1,9 @@ [pauseAndPropertyAnimations] -* +osx-10.12 +osx-10.14 +osx-10.13 [multipleSequentialGroups] -osx -[noTimerUpdates] -osx +osx-10.12 +osx-10.14 +osx-10.13 + diff --git a/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST b/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST deleted file mode 100644 index a8719b241a..0000000000 --- a/tests/auto/corelib/animation/qpropertyanimation/BLACKLIST +++ /dev/null @@ -1,6 +0,0 @@ -[statesAndSignals:normal animation] -windows -[startBackwardWithoutEndValue] -windows -[startWithoutStartValue] -osx diff --git a/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST b/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST index 4c999ff88f..e516c0e826 100644 --- a/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST +++ b/tests/auto/corelib/animation/qsequentialanimationgroup/BLACKLIST @@ -1,8 +1,6 @@ -[startGroupWithRunningChild] -windows [finishWithUncontrolledAnimation] -windows -osx-10.12 +windows-10 msvc-2015 osx-10.13 [groupWithZeroDurationAnimations] -osx +osx-10.13 + diff --git a/tests/auto/corelib/io/qfile/BLACKLIST b/tests/auto/corelib/io/qfile/BLACKLIST deleted file mode 100644 index 8366667166..0000000000 --- a/tests/auto/corelib/io/qfile/BLACKLIST +++ /dev/null @@ -1,7 +0,0 @@ -# QTBUG-48455 -[readLineStdin] -msvc-2015 ci -msvc-2017 ci -[readLineStdin_lineByLine] -msvc-2015 ci -msvc-2017 ci diff --git a/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST b/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST index 90b714758a..9b210b0d5f 100644 --- a/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST +++ b/tests/auto/corelib/io/qfilesystemwatcher/BLACKLIST @@ -1,6 +1,9 @@ # QTBUG-33574 QTBUG-30943 [signalsEmittedAfterFileMoved] -windows +windows-10 msvc-2017 +windows-10 msvc-2019 +windows-10 msvc-2015 +windows-7sp1 [watchFileAndItsDirectory:native backend-testfile] osx windows diff --git a/tests/auto/corelib/io/qprocess/BLACKLIST b/tests/auto/corelib/io/qprocess/BLACKLIST index b355bb0f75..aa9fdab64d 100644 --- a/tests/auto/corelib/io/qprocess/BLACKLIST +++ b/tests/auto/corelib/io/qprocess/BLACKLIST @@ -2,8 +2,6 @@ redhatenterpriselinuxworkstation-6.6 # QTBUG-48455 [fileWriterProcess] -msvc-2015 ci -msvc-2017 ci -[softExitInSlots] -# QTBUG-66903 -windows +windows-10 msvc-2015 +windows-10 msvc-2017 + diff --git a/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST b/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST index 4dd71ca9f4..4c9fe53c14 100644 --- a/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST +++ b/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST @@ -1,4 +1,4 @@ [elapsed] -windows -osx-10.12 +windows-10 msvc-2015 osx-10.13 +windows-10 msvc-2017 diff --git a/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST b/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST deleted file mode 100644 index 06588188d4..0000000000 --- a/tests/auto/corelib/kernel/qeventdispatcher/BLACKLIST +++ /dev/null @@ -1,6 +0,0 @@ -[sendPostedEvents] -windows -[registerTimer] -windows -winrt -osx diff --git a/tests/auto/corelib/kernel/qeventloop/BLACKLIST b/tests/auto/corelib/kernel/qeventloop/BLACKLIST deleted file mode 100644 index 6ea6314b0a..0000000000 --- a/tests/auto/corelib/kernel/qeventloop/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[testQuitLock] -windows diff --git a/tests/auto/corelib/kernel/qobject/BLACKLIST b/tests/auto/corelib/kernel/qobject/BLACKLIST deleted file mode 100644 index 0887a73b4c..0000000000 --- a/tests/auto/corelib/kernel/qobject/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[moveToThread] -windows diff --git a/tests/auto/corelib/kernel/qsocketnotifier/BLACKLIST b/tests/auto/corelib/kernel/qsocketnotifier/BLACKLIST index e68bf84268..f3b7fc97b1 100644 --- a/tests/auto/corelib/kernel/qsocketnotifier/BLACKLIST +++ b/tests/auto/corelib/kernel/qsocketnotifier/BLACKLIST @@ -1,3 +1,4 @@ [unexpectedDisconnection] -windows -osx +osx-10.12 +windows-10 msvc-2015 +windows-7sp1 diff --git a/tests/auto/corelib/kernel/qtimer/BLACKLIST b/tests/auto/corelib/kernel/qtimer/BLACKLIST index 16cbab4587..dc8b8987e5 100644 --- a/tests/auto/corelib/kernel/qtimer/BLACKLIST +++ b/tests/auto/corelib/kernel/qtimer/BLACKLIST @@ -1,5 +1,9 @@ [remainingTime] -windows -osx +osx-10.12 +osx-10.14 +osx-10.13 +windows-10 msvc-2017 [basic_chrono] -osx +osx-10.14 +osx-10.13 + diff --git a/tests/auto/corelib/serialization/qtextstream/BLACKLIST b/tests/auto/corelib/serialization/qtextstream/BLACKLIST index b54b53cd74..b8c1b742f4 100644 --- a/tests/auto/corelib/serialization/qtextstream/BLACKLIST +++ b/tests/auto/corelib/serialization/qtextstream/BLACKLIST @@ -1,3 +1,4 @@ [stillOpenWhenAtEnd] -windows +windows-10 msvc-2017 winrt +windows-7sp1 diff --git a/tests/auto/corelib/thread/qsemaphore/BLACKLIST b/tests/auto/corelib/thread/qsemaphore/BLACKLIST index 0786f50417..f61f4c1a3b 100644 --- a/tests/auto/corelib/thread/qsemaphore/BLACKLIST +++ b/tests/auto/corelib/thread/qsemaphore/BLACKLIST @@ -1,3 +1,6 @@ +[tryAcquireWithTimeout] +osx-10.12 +osx-10.13 [tryAcquireWithTimeout:0.2s] windows osx-10.12 diff --git a/tests/auto/corelib/thread/qthread/BLACKLIST b/tests/auto/corelib/thread/qthread/BLACKLIST index ccf530362c..87538a1048 100644 --- a/tests/auto/corelib/thread/qthread/BLACKLIST +++ b/tests/auto/corelib/thread/qthread/BLACKLIST @@ -1,4 +1,7 @@ [wait3_slowDestructor] -windows +windows-10 msvc-2015 +windows-7sp1 +windows-10 msvc-2017 [sleep] -windows ci +windows-7sp1 + diff --git a/tests/auto/corelib/thread/qthreadpool/BLACKLIST b/tests/auto/corelib/thread/qthreadpool/BLACKLIST index fc49731687..e4f2fcd822 100644 --- a/tests/auto/corelib/thread/qthreadpool/BLACKLIST +++ b/tests/auto/corelib/thread/qthreadpool/BLACKLIST @@ -1,3 +1,7 @@ [expiryTimeoutRace] -osx -linux +rhel-7.6 +opensuse-leap +osx-10.13 +ubuntu-18.04 +osx-10.12 +opensuse-42.3 diff --git a/tests/auto/corelib/thread/qwaitcondition/BLACKLIST b/tests/auto/corelib/thread/qwaitcondition/BLACKLIST deleted file mode 100644 index 3ff336576b..0000000000 --- a/tests/auto/corelib/thread/qwaitcondition/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[wakeOne] -windows diff --git a/tests/auto/corelib/time/qdatetime/BLACKLIST b/tests/auto/corelib/time/qdatetime/BLACKLIST deleted file mode 100644 index 3a42ee066b..0000000000 --- a/tests/auto/corelib/time/qdatetime/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[timeZoneAbbreviation] -osx diff --git a/tests/auto/corelib/tools/qlocale/BLACKLIST b/tests/auto/corelib/tools/qlocale/BLACKLIST deleted file mode 100644 index 3eac7c10ed..0000000000 --- a/tests/auto/corelib/tools/qlocale/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[formatTimeZone] -osx diff --git a/tests/auto/corelib/tools/qtimeline/BLACKLIST b/tests/auto/corelib/tools/qtimeline/BLACKLIST index 5611969b4d..b60cab31fa 100644 --- a/tests/auto/corelib/tools/qtimeline/BLACKLIST +++ b/tests/auto/corelib/tools/qtimeline/BLACKLIST @@ -1,9 +1,9 @@ [interpolation] -windows osx-10.12 +windows-10 msvc-2015 osx-10.13 -[duration] -windows +windows-7sp1 [frameRate] osx-10.12 osx-10.13 + diff --git a/tests/auto/dbus/qdbusabstractadaptor/qdbusabstractadaptor/BLACKLIST b/tests/auto/dbus/qdbusabstractadaptor/qdbusabstractadaptor/BLACKLIST new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/auto/dbus/qdbusconnection_spyhook/BLACKLIST b/tests/auto/dbus/qdbusconnection_spyhook/BLACKLIST new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/auto/gui/kernel/qguiapplication/BLACKLIST b/tests/auto/gui/kernel/qguiapplication/BLACKLIST index 9a670237b7..e6ffe78ae3 100644 --- a/tests/auto/gui/kernel/qguiapplication/BLACKLIST +++ b/tests/auto/gui/kernel/qguiapplication/BLACKLIST @@ -1,4 +1,3 @@ [focusObject] -opensuse -opensuse-leap -ubuntu +ubuntu-16.04 +opensuse-42.3 diff --git a/tests/auto/gui/kernel/qguieventdispatcher/BLACKLIST b/tests/auto/gui/kernel/qguieventdispatcher/BLACKLIST index b1590a5ccf..d2c51922a8 100644 --- a/tests/auto/gui/kernel/qguieventdispatcher/BLACKLIST +++ b/tests/auto/gui/kernel/qguieventdispatcher/BLACKLIST @@ -1,5 +1,3 @@ -[sendPostedEvents] -windows [registerTimer] -windows winrt + diff --git a/tests/auto/gui/kernel/qguieventloop/BLACKLIST b/tests/auto/gui/kernel/qguieventloop/BLACKLIST deleted file mode 100644 index 03acb2f5b0..0000000000 --- a/tests/auto/gui/kernel/qguieventloop/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[testQuitLock] -osx-10.12 diff --git a/tests/auto/gui/kernel/qguitimer/BLACKLIST b/tests/auto/gui/kernel/qguitimer/BLACKLIST new file mode 100644 index 0000000000..6ab715b922 --- /dev/null +++ b/tests/auto/gui/kernel/qguitimer/BLACKLIST @@ -0,0 +1,8 @@ +[basic_chrono] +osx-10.13 +[remainingTime] +osx-10.12 +windows-10 msvc-2015 +osx-10.14 +osx-10.13 + diff --git a/tests/auto/gui/kernel/qtouchevent/BLACKLIST b/tests/auto/gui/kernel/qtouchevent/BLACKLIST index 8e78d7e41f..dcda77bce7 100644 --- a/tests/auto/gui/kernel/qtouchevent/BLACKLIST +++ b/tests/auto/gui/kernel/qtouchevent/BLACKLIST @@ -1,6 +1,2 @@ -[basicRawEventTranslation] -linux [multiPointRawEventTranslationOnTouchScreen] -linux -[multiPointRawEventTranslationOnTouchPad] -linux +ubuntu-16.04 diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST index 1820499a53..1bb3917948 100644 --- a/tests/auto/gui/kernel/qwindow/BLACKLIST +++ b/tests/auto/gui/kernel/qwindow/BLACKLIST @@ -1,3 +1,7 @@ +[positioning] +opensuse-leap +ubuntu-16.04 +opensuse-42.3 [positioning:default] linux osx-10.12 ci @@ -6,38 +10,25 @@ winrt osx-10.12 ci [modalWithChildWindow] ubuntu-16.04 -# QTBUG-66851 -opensuse opensuse-leap +# QTBUG-66851 # QTBUG-69160 -android +opensuse-42.3 [setVisible] # QTBUG-69154 android [modalWindowEnterEventOnHide_QTBUG35109] ubuntu-16.04 -osx ci +osx-10.11 +osx-10.13 +osx-10.14 +osx-10.12 [spuriousMouseMove] -windows ci # QTBUG-69162 -android -[modalDialogClosingOneOfTwoModal] -osx -[modalWindowModallity] -osx -# QTBUG-69163 -android -[visibility] -osx-10.12 ci - +windows-10 msvc-2015 +windows-10 msvc-2017 [testInputEvents] rhel-7.4 -[isActive] -# QTBUG-67768 -ubuntu -# QTBUG-69157 -android - [exposeEventOnShrink_QTBUG54040] # QTBUG-69155 android diff --git a/tests/auto/gui/qopengl/BLACKLIST b/tests/auto/gui/qopengl/BLACKLIST index a036106c57..10e0520bd9 100644 --- a/tests/auto/gui/qopengl/BLACKLIST +++ b/tests/auto/gui/qopengl/BLACKLIST @@ -1,10 +1,2 @@ -[fboRendering] -windows -[QTBUG15621_triangulatingStrokerDivZero] -windows -[imageFormatPainting] -windows -[openGLPaintDevice] -windows [wglContextWrap] windows diff --git a/tests/auto/gui/text/qfont/BLACKLIST b/tests/auto/gui/text/qfont/BLACKLIST deleted file mode 100644 index 42cb8408f4..0000000000 --- a/tests/auto/gui/text/qfont/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[defaultFamily] -b2qt diff --git a/tests/auto/gui/text/qglyphrun/BLACKLIST b/tests/auto/gui/text/qglyphrun/BLACKLIST index d8dbdabb4b..57f32c683d 100644 --- a/tests/auto/gui/text/qglyphrun/BLACKLIST +++ b/tests/auto/gui/text/qglyphrun/BLACKLIST @@ -1,4 +1,3 @@ [mixedScripts] ubuntu-18.04 b2qt -windows diff --git a/tests/auto/gui/text/qtextdocumentlayout/BLACKLIST b/tests/auto/gui/text/qtextdocumentlayout/BLACKLIST index b13b2497d3..5c81e74aa0 100644 --- a/tests/auto/gui/text/qtextdocumentlayout/BLACKLIST +++ b/tests/auto/gui/text/qtextdocumentlayout/BLACKLIST @@ -1,2 +1,4 @@ [imageAtRightAlignedTab] -linux +rhel-6.6 +rhel-7.4 +rhel-7.6 diff --git a/tests/auto/gui/text/qtextmarkdownwriter/BLACKLIST b/tests/auto/gui/text/qtextmarkdownwriter/BLACKLIST index fc9e5a9efe..0ce46130ce 100644 --- a/tests/auto/gui/text/qtextmarkdownwriter/BLACKLIST +++ b/tests/auto/gui/text/qtextmarkdownwriter/BLACKLIST @@ -1,3 +1,2 @@ [rewriteDocument] -winrt # QTBUG-54623 - +winrt diff --git a/tests/auto/network/access/qabstractnetworkcache/BLACKLIST b/tests/auto/network/access/qabstractnetworkcache/BLACKLIST index 2ad52f8b31..12f45f0e12 100644 --- a/tests/auto/network/access/qabstractnetworkcache/BLACKLIST +++ b/tests/auto/network/access/qabstractnetworkcache/BLACKLIST @@ -1,2 +1,2 @@ [cacheControl] -windows +windows-10 msvc-2015 diff --git a/tests/auto/network/access/qftp/BLACKLIST b/tests/auto/network/access/qftp/BLACKLIST index 96d9274653..463030a089 100644 --- a/tests/auto/network/access/qftp/BLACKLIST +++ b/tests/auto/network/access/qftp/BLACKLIST @@ -6,5 +6,16 @@ redhatenterpriselinuxworkstation-6.6 [activeMode:WithoutProxyWithSession] redhatenterpriselinuxworkstation-6.6 +[list] +ubuntu-16.04 +opensuse-leap +osx-10.11 +windows-7sp1 +ubuntu-18.04 +osx-10.14 +b2qt +osx-10.12 +windows-10 msvc-2015 +opensuse-42.3 [list:epsvNotSupported] * diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index 4d29a830e9..f9bbdd96c3 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -1,47 +1,249 @@ # See qtbase/src/testlib/qtestblacklist.cpp for format -osx [authenticationCacheAfterCancel] -windows +windows-10 msvc-2017 +windows-10 msvc-2015 +osx-10.13 +windows-7sp1 [httpAbort] -* +ubuntu-16.04 +rhel-7.6 +[backgroundRequestInterruption] +ubuntu-16.04 +opensuse-leap +ubuntu-18.04 +b2qt +osx-10.12 +windows-10 msvc-2015 +opensuse-42.3 [backgroundRequestInterruption:ftp, bg, nobg] * +[getErrors] +osx-10.13 +# QTBUG-71953 [getErrors:ftp-host] linux # QTBUG-71953 +[getFromHttp] +rhel-6.6 +ubuntu-16.04 +rhel-7.6 +opensuse-leap +osx-10.11 +osx-10.13 +windows-7sp1 +ubuntu-18.04 +osx-10.14 +rhel-7.4 +b2qt +windows-10 msvc-2017 +osx-10.12 +windows-10 msvc-2015 +opensuse-42.3 [getFromHttp:success-external] * [getFromHttpIntoBuffer] -windows +osx-10.12 +osx-10.13 [getFromHttpIntoBuffer2] -windows +windows-10 msvc-2015 +windows-10 msvc-2017 [headFromHttp] -windows +osx-10.13 +windows-10 msvc-2017 [ioGetFromHttpWithSocksProxy] -windows +osx-10.12 [ioPostToHttpFromSocket] -windows # QTBUG-66247 +osx-10.13 +windows-7sp1 +windows-10 msvc-2017 +osx-10.12 +windows-10 msvc-2015 [ioHttpRedirect] -windows +windows-10 msvc-2015 # QTBUG-66602 +windows-10 msvc-2017 [ioHttpRedirectMultipartPost] -* +ubuntu-16.04 +rhel-7.6 # QTBUG-66247 +opensuse-leap +osx-10.13 +ubuntu-18.04 +rhel-7.4 +b2qt +osx-10.12 +windows-10 msvc-2015 +opensuse-42.3 [ioHttpRedirectPolicy] -* +ubuntu-16.04 +opensuse-leap +windows-7sp1 +ubuntu-18.04 +b2qt +windows-10 msvc-2017 +windows-10 msvc-2015 +opensuse-42.3 [ioHttpRedirectPostPut] -linux -windows +osx-10.12 +windows-10 msvc-2015 [putToFtp] -windows ci -[putToFtpWithInvalidCredentials] -windows ci +windows-10 msvc-2017 [putWithServerClosingConnectionImmediately] -windows +osx-10.11 +osx-10.13 +windows-7sp1 +windows-10 msvc-2017 +osx-10.12 +windows-10 msvc-2015 [qtbug28035browserDoesNotLoadQtProjectOrgCorrectly] -windows -[getFromUnreachableIp] -windows msvc-2017 -[ioHttpRedirectErrors:too-many-redirects] -rhel-6.6 ci +windows-10 msvc-2015 +windows-7sp1 +[authenticationWithDifferentRealm] +osx-10.13 +[backgroundRequest] +osx-10.12 +[connectToIPv6Address] +osx-10.12 +[deleteFromHttp] +osx-10.12 +[downloadProgress] +osx-10.12 +[emitErrorForAllReplies] +osx-10.12 +[encrypted] +osx-10.13 +[ftpAuthentication] +osx-10.13 +[httpCanReadLine] +osx-10.12 +osx-10.13 +[httpRecursiveCreation] +osx-10.12 +osx-10.13 +[httpWithNoCredentialUsage] +osx-10.12 +[ignoreSslErrorsList] +osx-10.12 +osx-10.13 +[ignoreSslErrorsListWithSlot] +osx-10.12 +osx-10.13 +[ioGetFromBuiltinHttp] +osx-10.12 +osx-10.11 +osx-10.14 +osx-10.13 +[ioGetFromHttp] +osx-10.12 +[ioGetFromHttpWithAuth] +osx-10.12 +osx-10.13 +[ioGetFromHttpWithAuthSynchronous] +osx-10.12 +[ioGetFromHttpWithProxyAuth] +osx-10.12 +[ioGetFromHttpWithReuseParallel] +osx-10.12 +osx-10.13 +[ioGetFromHttpWithReuseSequential] +osx-10.12 +osx-10.13 +[ioGetFromHttpsWithIgnoreSslErrors] +osx-10.12 +[ioGetFromHttpsWithSslErrors] +osx-10.12 +[ioGetFromHttpsWithSslHandshakeError] +osx-10.12 +[ioGetWithManyProxies] +osx-10.12 +[ioPostToHttpFromFile] +osx-10.13 +[ioPostToHttpFromMiddleOfFileFiveBytes] +osx-10.13 +[ioPostToHttpFromMiddleOfFileToEnd] +osx-10.13 +[ioPostToHttpFromMiddleOfQBufferFiveBytes] +osx-10.13 +[ioPostToHttpFromSocketSynchronous] +osx-10.12 +osx-10.13 +[ioPostToHttpNoBufferFlag] +osx-10.13 +[ioPostToHttpUploadProgress] +osx-10.12 +osx-10.11 +osx-10.13 +[ioPutToHttpFromFile] +osx-10.13 +[lastModifiedHeaderForHttp] +osx-10.12 +osx-10.13 +[multipartSkipIndices] +osx-10.12 +osx-10.13 +[nestedEventLoops] +osx-10.12 +osx-10.13 +[pipelining] +osx-10.13 +[postToHttp] +osx-10.12 +osx-10.13 +[postToHttpMultipart] +osx-10.12 +osx-10.13 +[postToHttpSynchronous] +osx-10.12 +osx-10.13 +[postToHttps] +osx-10.12 +osx-10.13 +[postToHttpsMultipart] +osx-10.12 +osx-10.13 +[postToHttpsSynchronous] +osx-10.12 +osx-10.13 +[putGetDeleteGetFromHttp] +osx-10.12 +[putToHttp] +osx-10.12 +osx-10.13 +[putToHttpSynchronous] +osx-10.12 +osx-10.13 +[putToHttps] +osx-10.12 +osx-10.13 +[putToHttpsSynchronous] +osx-10.12 +osx-10.13 +[putWithRateLimiting] +osx-10.12 +osx-10.13 +[qtbug13431replyThrottling] +osx-10.12 +[receiveCookiesFromHttp] +osx-10.12 +osx-10.13 +[receiveCookiesFromHttpSynchronous] +osx-10.12 +osx-10.13 +[sendCookies] +osx-10.12 +osx-10.13 +[sendCookiesSynchronous] +osx-10.12 +osx-10.13 +[sendCustomRequestToHttp] +osx-10.12 +[sslConfiguration] +osx-10.12 +osx-10.13 +[synchronousRequest] +osx-10.12 +osx-10.13 +[backgroundRequestConnectInBackground] +osx-10.12 +osx-10.13 diff --git a/tests/auto/network/access/spdy/BLACKLIST b/tests/auto/network/access/spdy/BLACKLIST index b13eae1000..ce2f7f383f 100644 --- a/tests/auto/network/access/spdy/BLACKLIST +++ b/tests/auto/network/access/spdy/BLACKLIST @@ -1,4 +1,10 @@ [download] -linux +opensuse-leap +ubuntu-18.04 +ubuntu-16.04 +b2qt [upload] -linux +opensuse-leap +ubuntu-18.04 +b2qt + diff --git a/tests/auto/network/kernel/qdnslookup/BLACKLIST b/tests/auto/network/kernel/qdnslookup/BLACKLIST index edf6436384..4461d8b5f7 100644 --- a/tests/auto/network/kernel/qdnslookup/BLACKLIST +++ b/tests/auto/network/kernel/qdnslookup/BLACKLIST @@ -1,2 +1,12 @@ [lookup] -ci +rhel-7.6 +opensuse-leap +osx-10.13 +windows-7sp1 +ubuntu-18.04 +rhel-7.4 +b2qt +windows-10 msvc-2017 +osx-10.12 +windows-10 msvc-2015 +opensuse-42.3 diff --git a/tests/auto/network/socket/platformsocketengine/BLACKLIST b/tests/auto/network/socket/platformsocketengine/BLACKLIST index 154c5cc5b2..f1f88d26d1 100644 --- a/tests/auto/network/socket/platformsocketengine/BLACKLIST +++ b/tests/auto/network/socket/platformsocketengine/BLACKLIST @@ -1,8 +1,11 @@ [tcpLoopbackPerformance] -windows +windows-10 msvc-2015 +windows-7sp1 [receiveUrgentData] -windows +windows-10 msvc-2015 +windows-7sp1 [serverTest] -windows +windows-10 msvc-2015 +windows-7sp1 [tcpLoopbackPerformance] windows diff --git a/tests/auto/network/socket/qhttpsocketengine/BLACKLIST b/tests/auto/network/socket/qhttpsocketengine/BLACKLIST index 991d01dd00..ceb3b7862e 100644 --- a/tests/auto/network/socket/qhttpsocketengine/BLACKLIST +++ b/tests/auto/network/socket/qhttpsocketengine/BLACKLIST @@ -1,6 +1,5 @@ -[passwordAuth] -windows [downloadBigFile] -windows +windows-10 msvc-2015 +windows-7sp1 [ensureEofTriggersNotification] windows diff --git a/tests/auto/network/socket/qsocks5socketengine/BLACKLIST b/tests/auto/network/socket/qsocks5socketengine/BLACKLIST index 8af3cea8dc..f769aafbdd 100644 --- a/tests/auto/network/socket/qsocks5socketengine/BLACKLIST +++ b/tests/auto/network/socket/qsocks5socketengine/BLACKLIST @@ -1,11 +1,12 @@ [udpTest] * [passwordAuth] -* +ubuntu-18.04 # QTBUG-74162 [passwordAuth2] -* -[serverTest] -windows +osx-10.12 +ubuntu-18.04 [downloadBigFile] -windows +windows-10 msvc-2015 +windows-7sp1 + diff --git a/tests/auto/network/socket/qtcpserver/BLACKLIST b/tests/auto/network/socket/qtcpserver/BLACKLIST index f8b61808cc..ad0edf0af1 100644 --- a/tests/auto/network/socket/qtcpserver/BLACKLIST +++ b/tests/auto/network/socket/qtcpserver/BLACKLIST @@ -1,13 +1,24 @@ -windows -[linkLocal] -linux +[listenWhileListening] +windows-10 msvc-2015 [listenWhileListening:WithSocks5Proxy] linux windows +[ipv6Server] +windows-10 msvc-2015 +windows-7sp1 +windows-10 msvc-2017 [ipv6Server:WithoutProxy] windows osx -[clientServerLoop:WithSocks5Proxy] -linux -[crashTests:WithSocks5Proxy] -linux +[addressReusable] +windows-10 msvc-2015 +[eagainBlockingAccept] +windows-10 msvc-2015 +windows-7sp1 +windows-10 msvc-2017 +[proxyFactory] +windows-7sp1 +[serverAddress] +windows-10 msvc-2017 +windows-10 msvc-2015 +windows-7sp1 diff --git a/tests/auto/network/socket/qtcpsocket/BLACKLIST b/tests/auto/network/socket/qtcpsocket/BLACKLIST index d724897b74..8c2f8d2638 100644 --- a/tests/auto/network/socket/qtcpsocket/BLACKLIST +++ b/tests/auto/network/socket/qtcpsocket/BLACKLIST @@ -1,13 +1,14 @@ -[bindThenResolveHost:first-fail] -windows +[bind] +windows-10 msvc-2015 +windows-7sp1 [bind:[::]] windows [bind:[::]:randomport] windows -[invalidProxy:socks5-on-http] -windows +[timeoutConnect] +windows-10 msvc-2015 +# QTBUG-66247 [timeoutConnect:ip] windows # QTBUG-66247 -[taskQtBug5799ConnectionErrorEventLoop] -windows + diff --git a/tests/auto/network/socket/qudpsocket/BLACKLIST b/tests/auto/network/socket/qudpsocket/BLACKLIST index 0d56f6c827..9b5aa8a3fc 100644 --- a/tests/auto/network/socket/qudpsocket/BLACKLIST +++ b/tests/auto/network/socket/qudpsocket/BLACKLIST @@ -1,26 +1,16 @@ [writeDatagramToNonExistingPeer] -windows -osx -[asyncReadDatagram] -osx +windows-10 msvc-2017 +windows-10 msvc-2015 +windows-7sp1 [multicastLeaveAfterClose] -osx -[readyRead] -osx +osx-10.12 +osx-10.11 [readyReadForEmptyDatagram] -osx +opensuse-leap +ubuntu-16.04 [echo] -linux -osx +opensuse-42.3 [ipv6Loop] -osx -[loop] -osx -[broadcasting] -osx -[zeroLengthDatagram] -osx -[linkLocalIPv6] -linux +osx-10.12 [readyReadForEmptyDatagram] linux diff --git a/tests/auto/network/ssl/qsslcertificate/BLACKLIST b/tests/auto/network/ssl/qsslcertificate/BLACKLIST index 25509a5ca8..9494ee2278 100644 --- a/tests/auto/network/ssl/qsslcertificate/BLACKLIST +++ b/tests/auto/network/ssl/qsslcertificate/BLACKLIST @@ -1,3 +1,13 @@ # OpenSSL version is too new. Rich will fix :) [subjectAndIssuerAttributes] -* +ubuntu-16.04 +rhel-7.6 +opensuse-leap +windows-7sp1 +ubuntu-18.04 +rhel-7.4 +b2qt +windows-10 msvc-2017 +windows-10 msvc-2015 +opensuse-42.3 + diff --git a/tests/auto/network/ssl/qsslkey/BLACKLIST b/tests/auto/network/ssl/qsslkey/BLACKLIST index f9bc0af6de..e9723001f5 100644 --- a/tests/auto/network/ssl/qsslkey/BLACKLIST +++ b/tests/auto/network/ssl/qsslkey/BLACKLIST @@ -1,2 +1,16 @@ -redhatenterpriselinuxworkstation -rhel +[constructor] +rhel-6.6 +rhel-7.4 +rhel-7.6 +[length] +rhel-6.6 +rhel-7.4 +rhel-7.6 +[toEncryptedPemOrDer] +rhel-6.6 +rhel-7.4 +rhel-7.6 +[toPemOrDer] +rhel-6.6 +rhel-7.4 +rhel-7.6 diff --git a/tests/auto/network/ssl/qsslsocket/BLACKLIST b/tests/auto/network/ssl/qsslsocket/BLACKLIST index 3ecd3d9dbb..36143691c9 100644 --- a/tests/auto/network/ssl/qsslsocket/BLACKLIST +++ b/tests/auto/network/ssl/qsslsocket/BLACKLIST @@ -1,23 +1,15 @@ [abortOnSslErrors] -windows +windows-10 msvc-2015 [deprecatedProtocols] windows -[disabledProtocols] -windows -[protocol] -windows -[qtbug18498_peek] -windows -[setReadBufferSize] -windows [spontaneousWrite] -windows +windows-7sp1 [sslErrors] -windows +windows-7sp1 [connectToHostEncrypted] osx-10.13 [setSslConfiguration] -windows -osx-10.13 +windows-10 msvc-2015 +windows-7sp1 [connectToHostEncryptedWithVerificationPeerName] osx-10.13 diff --git a/tests/auto/opengl/qgl/BLACKLIST b/tests/auto/opengl/qgl/BLACKLIST index d3165a51e5..ec75ea16eb 100644 --- a/tests/auto/opengl/qgl/BLACKLIST +++ b/tests/auto/opengl/qgl/BLACKLIST @@ -1,25 +1,8 @@ -[glWidgetRendering] -windows -winrt -[glFBORendering] -windows -winrt -[multipleFBOInterleavedRendering] -windows -winrt -[glPBufferRendering] -windows -winrt -[replaceClipping] -windows -winrt -[clipTest] -windows -winrt [graphicsViewClipping] -windows -winrt -linux ci -[glFBOUseInGLWidget] -windows -winrt +ubuntu-16.04 +rhel-7.6 +opensuse-leap +ubuntu-18.04 +rhel-7.4 +opensuse-42.3 + diff --git a/tests/auto/other/gestures/BLACKLIST b/tests/auto/other/gestures/BLACKLIST index c465ff316e..2af5d40359 100644 --- a/tests/auto/other/gestures/BLACKLIST +++ b/tests/auto/other/gestures/BLACKLIST @@ -3,17 +3,25 @@ rhel-7.4 rhel-7.6 ubuntu-18.04 [customGesture] -# QTBUG-67254 -ubuntu -opensuse opensuse-leap +# QTBUG-67254 +opensuse-42.3 [graphicsItemGesture] ubuntu-18.04 +rhel-7.4 +rhel-7.6 [graphicsItemTreeGesture] ubuntu-18.04 [graphicsView] ubuntu-18.04 +rhel-7.4 +rhel-7.6 [explicitGraphicsObjectTarget] ubuntu-18.04 +rhel-7.4 +rhel-7.6 [autoCancelGestures2] ubuntu-18.04 +rhel-7.4 +rhel-7.6 + diff --git a/tests/auto/other/networkselftest/BLACKLIST b/tests/auto/other/networkselftest/BLACKLIST index 4a958b43a5..948081eb78 100644 --- a/tests/auto/other/networkselftest/BLACKLIST +++ b/tests/auto/other/networkselftest/BLACKLIST @@ -1,4 +1,6 @@ # QTBUG-27571 [ftpProxyServer] -windows 32bit -windows 64bit +windows-10 msvc-2017 +windows-10 msvc-2015 +windows-7sp1 + diff --git a/tests/auto/other/qaccessibilitymac/BLACKLIST b/tests/auto/other/qaccessibilitymac/BLACKLIST deleted file mode 100644 index f53fa7e853..0000000000 --- a/tests/auto/other/qaccessibilitymac/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[hierarchyTest] -osx-10.12 ci diff --git a/tests/auto/other/qfocusevent/BLACKLIST b/tests/auto/other/qfocusevent/BLACKLIST index 0b03472587..5af8be91a0 100644 --- a/tests/auto/other/qfocusevent/BLACKLIST +++ b/tests/auto/other/qfocusevent/BLACKLIST @@ -1,6 +1,3 @@ -[checkReason_Shortcut] -osx-10.12 ci [checkReason_ActiveWindow] -osx-10.12 ci winrt diff --git a/tests/auto/other/qnetworkaccessmanager_and_qprogressdialog/BLACKLIST b/tests/auto/other/qnetworkaccessmanager_and_qprogressdialog/BLACKLIST index aea819fc2e..65a939cdcb 100644 --- a/tests/auto/other/qnetworkaccessmanager_and_qprogressdialog/BLACKLIST +++ b/tests/auto/other/qnetworkaccessmanager_and_qprogressdialog/BLACKLIST @@ -1,2 +1,5 @@ +[downloadCheck] +windows-10 msvc-2015 +windows-10 msvc-2017 [downloadCheck:with-zeroCopy] windows diff --git a/tests/auto/widgets/dialogs/qdialog/BLACKLIST b/tests/auto/widgets/dialogs/qdialog/BLACKLIST index dd6a8bfff9..72e3dff6dd 100644 --- a/tests/auto/widgets/dialogs/qdialog/BLACKLIST +++ b/tests/auto/widgets/dialogs/qdialog/BLACKLIST @@ -1,4 +1,4 @@ [snapToDefaultButton] -osx +osx-10.14 [showFullScreen] osx-10.13 ci diff --git a/tests/auto/widgets/dialogs/qfiledialog2/BLACKLIST b/tests/auto/widgets/dialogs/qfiledialog2/BLACKLIST index e0887d8ad1..875855b59e 100644 --- a/tests/auto/widgets/dialogs/qfiledialog2/BLACKLIST +++ b/tests/auto/widgets/dialogs/qfiledialog2/BLACKLIST @@ -1,2 +1,4 @@ [QTBUG4419_lineEditSelectAll] -osx +osx-10.12 +osx-10.14 +osx-10.13 diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST b/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST index f78d23c6b1..f2f0f8d26e 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/BLACKLIST @@ -1,13 +1,19 @@ winrt +[sort] +winrt [sort:QFileDialog usage] ubuntu b2qt [specialFiles] -ubuntu b2qt [dirsBeforeFiles] -ubuntu +ubuntu-16.04 +rhel-7.6 +windows-10 msvc-2017 +ubuntu-18.04 b2qt -windows -rhel -suse-leap +winrt +windows-10 msvc-2015 + +[drives] +winrt diff --git a/tests/auto/widgets/dialogs/qmessagebox/BLACKLIST b/tests/auto/widgets/dialogs/qmessagebox/BLACKLIST index da52809aad..e633e7c0a3 100644 --- a/tests/auto/widgets/dialogs/qmessagebox/BLACKLIST +++ b/tests/auto/widgets/dialogs/qmessagebox/BLACKLIST @@ -1,2 +1,6 @@ [defaultButton] -* +ubuntu-16.04 +rhel-7.6 +opensuse-leap +ubuntu-18.04 +rhel-7.4 diff --git a/tests/auto/widgets/dialogs/qprogressdialog/BLACKLIST b/tests/auto/widgets/dialogs/qprogressdialog/BLACKLIST index 1789f51507..2b784414cd 100644 --- a/tests/auto/widgets/dialogs/qprogressdialog/BLACKLIST +++ b/tests/auto/widgets/dialogs/qprogressdialog/BLACKLIST @@ -1,2 +1,2 @@ [autoShow] -osx ci +osx-10.13 diff --git a/tests/auto/widgets/effects/qgraphicseffect/BLACKLIST b/tests/auto/widgets/effects/qgraphicseffect/BLACKLIST index 4833af527f..64a92d18aa 100644 --- a/tests/auto/widgets/effects/qgraphicseffect/BLACKLIST +++ b/tests/auto/widgets/effects/qgraphicseffect/BLACKLIST @@ -1,3 +1,2 @@ [prepareGeometryChangeInvalidateCache] -opensuse -opensuse-leap +opensuse-42.3 diff --git a/tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST index b8b427b3dd..a3c9e2e421 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST +++ b/tests/auto/widgets/graphicsview/qgraphicsscene/BLACKLIST @@ -3,11 +3,5 @@ opensuse-42.3 ci [removeFullyTransparentItem] osx-10.12 [tabFocus_sceneWithNestedFocusWidgets] -opensuse -opensuse-leap -[inputMethod] -opensuse -opensuse-leap -[hoverEvents_parentChild] -ubuntu +opensuse-42.3 diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST index ee13a37212..22fce8620b 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST +++ b/tests/auto/widgets/graphicsview/qgraphicsview/BLACKLIST @@ -1,20 +1,24 @@ [task255529_transformationAnchorMouseAndViewportMargins] -xcb +opensuse-leap +rhel-7.4 +ubuntu-16.04 +opensuse-42.3 [cursor] -xcb +opensuse-leap +ubuntu-16.04 +opensuse-42.3 [cursor2] -xcb -windows -[rubberBandExtendSelection] -xcb -[rotated_rubberBand] -xcb +ubuntu-16.04 [sendEvent] -xcb -[forwardMousePress] -xcb +ubuntu-16.04 +opensuse-42.3 [resizeAnchor] -xcb +ubuntu-16.04 +rhel-7.6 +opensuse-leap +ubuntu-18.04 +rhel-7.4 +opensuse-42.3 [update2] opensuse-42.3 [itemsInRect_cosmeticAdjust] diff --git a/tests/auto/widgets/itemviews/qcolumnview/BLACKLIST b/tests/auto/widgets/itemviews/qcolumnview/BLACKLIST deleted file mode 100644 index bda01c700c..0000000000 --- a/tests/auto/widgets/itemviews/qcolumnview/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[scrollTo:reverse] -osx diff --git a/tests/auto/widgets/itemviews/qheaderview/BLACKLIST b/tests/auto/widgets/itemviews/qheaderview/BLACKLIST index efb813f7d2..297a6fe7b7 100644 --- a/tests/auto/widgets/itemviews/qheaderview/BLACKLIST +++ b/tests/auto/widgets/itemviews/qheaderview/BLACKLIST @@ -1,3 +1,3 @@ [stretchAndRestoreLastSection] -opensuse opensuse-leap +opensuse-42.3 diff --git a/tests/auto/widgets/itemviews/qtableview/BLACKLIST b/tests/auto/widgets/itemviews/qtableview/BLACKLIST index be90475a6f..9648cef3de 100644 --- a/tests/auto/widgets/itemviews/qtableview/BLACKLIST +++ b/tests/auto/widgets/itemviews/qtableview/BLACKLIST @@ -1,4 +1,3 @@ [moveCursorBiggerJump] osx -[columnViewportPosition] -winrt # QTBUG-72853 + diff --git a/tests/auto/widgets/kernel/qapplication/BLACKLIST b/tests/auto/widgets/kernel/qapplication/BLACKLIST index d7de7bf16e..ac65a97c40 100644 --- a/tests/auto/widgets/kernel/qapplication/BLACKLIST +++ b/tests/auto/widgets/kernel/qapplication/BLACKLIST @@ -1,4 +1,4 @@ [touchEventPropagation] -# QTBUG-66745 -opensuse opensuse-leap +# QTBUG-66745 +opensuse-42.3 diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index 03bec4286b..02e97e4b4e 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -2,30 +2,34 @@ [normalGeometry] ubuntu-16.04 [saveRestoreGeometry] -xcb -b2qt -[restoreVersion1Geometry] -osx -[updateWhileMinimized] +opensuse-leap ubuntu-16.04 +b2qt +opensuse-42.3 +[restoreVersion1Geometry] +ubuntu-16.04 +[updateWhileMinimized] ubuntu-18.04 rhel-7.4 +ubuntu-16.04 rhel-7.6 -osx [focusProxyAndInputMethods] -linux -[raise] -# QTBUG-68175 -opensuse +ubuntu-16.04 +rhel-7.6 opensuse-leap -[setWindowGeometry] -osx -[windowMoveResize] -osx +ubuntu-18.04 +rhel-7.4 +opensuse-42.3 +[raise] +opensuse-leap +# QTBUG-68175 +opensuse-42.3 [childEvents] osx ci [renderInvisible] -osx +osx-10.12 +osx-10.11 +osx-10.14 [optimizedResizeMove] osx [optimizedResize_topLevel] @@ -40,12 +44,14 @@ opensuse opensuse-leap [moveInResizeEvent] ubuntu-16.04 -[moveChild:right] -osx -[activateWindow] -osx-10.12 ci [multipleToplevelFocusCheck] -linux +ubuntu-16.04 +rhel-7.6 +opensuse-leap +ubuntu-18.04 +rhel-7.4 +opensuse-42.3 [windowState] # QTBUG-75270 winrt + diff --git a/tests/auto/widgets/kernel/qwidget_window/BLACKLIST b/tests/auto/widgets/kernel/qwidget_window/BLACKLIST index 381cf76c46..39d7b695f6 100644 --- a/tests/auto/widgets/kernel/qwidget_window/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget_window/BLACKLIST @@ -4,4 +4,5 @@ opensuse-42.3 ubuntu-16.04 [setWindowState] ubuntu-18.04 -rhel +rhel-7.6 + diff --git a/tests/auto/widgets/util/qcompleter/BLACKLIST b/tests/auto/widgets/util/qcompleter/BLACKLIST index fdc424b6ac..367270fdf2 100644 --- a/tests/auto/widgets/util/qcompleter/BLACKLIST +++ b/tests/auto/widgets/util/qcompleter/BLACKLIST @@ -1,2 +1,6 @@ [QTBUG_14292_filesystem] -linux +ubuntu-16.04 +opensuse-leap +rhel-7.4 +rhel-6.6 +opensuse-42.3 diff --git a/tests/auto/widgets/widgets/qdoublespinbox/BLACKLIST b/tests/auto/widgets/widgets/qdoublespinbox/BLACKLIST index c1b6c9693e..8f5648d0f9 100644 --- a/tests/auto/widgets/widgets/qdoublespinbox/BLACKLIST +++ b/tests/auto/widgets/widgets/qdoublespinbox/BLACKLIST @@ -1,2 +1,4 @@ [editingFinished] -* +osx-10.12 +osx-10.14 +osx-10.13 diff --git a/tests/auto/widgets/widgets/qmdiarea/BLACKLIST b/tests/auto/widgets/widgets/qmdiarea/BLACKLIST index b1c8d7dfde..1dd876ea97 100644 --- a/tests/auto/widgets/widgets/qmdiarea/BLACKLIST +++ b/tests/auto/widgets/widgets/qmdiarea/BLACKLIST @@ -1,7 +1,16 @@ -[updateScrollBars] -osx [tileSubWindows] -osx -xcb +ubuntu-16.04 +rhel-7.6 +opensuse-leap +osx-10.11 +osx-10.13 +ubuntu-18.04 +osx-10.14 +rhel-7.4 +osx-10.12 +opensuse-42.3 [resizeTimer] -osx +osx-10.12 +osx-10.14 +osx-10.13 + diff --git a/tests/auto/widgets/widgets/qmdisubwindow/BLACKLIST b/tests/auto/widgets/widgets/qmdisubwindow/BLACKLIST deleted file mode 100644 index 26d1776b0d..0000000000 --- a/tests/auto/widgets/widgets/qmdisubwindow/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[setOpaqueResizeAndMove] -osx-10.12 diff --git a/tests/auto/widgets/widgets/qmenu/BLACKLIST b/tests/auto/widgets/widgets/qmenu/BLACKLIST index bac14ea225..ad6d2f340c 100644 --- a/tests/auto/widgets/widgets/qmenu/BLACKLIST +++ b/tests/auto/widgets/widgets/qmenu/BLACKLIST @@ -1,13 +1,13 @@ [task258920_mouseBorder] -osx -[submenuTearOffDontClose] -osx-10.12 ci +osx-10.14 +osx-10.13 [layoutDirection] +osx-10.12 +osx-10.13 # Fails when enabling synchronous expose events QTBUG-62092 -osx ci [pushButtonPopulateOnAboutToShow] -osx +osx-10.13 [tearOff] -osx +osx-10.14 [activeSubMenuPosition] winrt diff --git a/tests/auto/widgets/widgets/qmenubar/BLACKLIST b/tests/auto/widgets/widgets/qmenubar/BLACKLIST index f897797f00..c9e15e531c 100644 --- a/tests/auto/widgets/widgets/qmenubar/BLACKLIST +++ b/tests/auto/widgets/widgets/qmenubar/BLACKLIST @@ -3,6 +3,6 @@ ubuntu-16.04 #QTBUG-66255 ubuntu-18.04 [activatedCount] -* +opensuse-42.3 [QTBUG_65488_hiddenActionTriggered] winrt diff --git a/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST b/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST index b67c8354e8..b281eca3bf 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST +++ b/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST @@ -1,5 +1,3 @@ -[clearAndGrab] -ubuntu - [stackWidgetOpaqueChildIsVisible] -windows +windows-10 msvc-2017 + diff --git a/tests/auto/widgets/widgets/qscrollbar/BLACKLIST b/tests/auto/widgets/widgets/qscrollbar/BLACKLIST deleted file mode 100644 index 277ae4d260..0000000000 --- a/tests/auto/widgets/widgets/qscrollbar/BLACKLIST +++ /dev/null @@ -1,3 +0,0 @@ -#QTBUG-66321 -[QTBUG_42871] -macos diff --git a/tests/auto/widgets/widgets/qspinbox/BLACKLIST b/tests/auto/widgets/widgets/qspinbox/BLACKLIST index a38511bfb4..96a7732165 100644 --- a/tests/auto/widgets/widgets/qspinbox/BLACKLIST +++ b/tests/auto/widgets/widgets/qspinbox/BLACKLIST @@ -1,3 +1,2 @@ [stepModifierPressAndHold] -opensuse ci # QTBUG-69492 -opensuse-leap ci +opensuse-42.3 diff --git a/tests/auto/widgets/widgets/qtoolbutton/BLACKLIST b/tests/auto/widgets/widgets/qtoolbutton/BLACKLIST index df4fda196f..52ba36562f 100644 --- a/tests/auto/widgets/widgets/qtoolbutton/BLACKLIST +++ b/tests/auto/widgets/widgets/qtoolbutton/BLACKLIST @@ -1,2 +1,2 @@ [task176137_autoRepeatOfAction] -osx ci +osx-10.13 From 1e9355fdf2c03e119c7e546c8bac3947d6c6b0b8 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Thu, 4 Jul 2019 12:35:49 +0200 Subject: [PATCH 029/264] Doc: Fix incorrect enum value referenced in QImageReader::transformation() And remove the \c command to enable auto-linking. Fixes: QTBUG-76878 Change-Id: Ia2352942c7e7040088347becbda07062a9544c98 Reviewed-by: Nico Vertriest --- src/gui/image/qimagereader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 0c75196612..17e1982fcc 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -1074,7 +1074,7 @@ QList QImageReader::supportedSubTypes() const \since 5.5 Returns the transformation metadata of the image, including image orientation. If the format - does not support transformation metadata \c QImageIOHandler::Transformation_None is returned. + does not support transformation metadata, QImageIOHandler::TransformationNone is returned. \sa setAutoTransform(), autoTransform() */ From a41701904e880f58e19b352ade1931d6cd1a7112 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Sun, 7 Jul 2019 13:44:26 +0200 Subject: [PATCH 030/264] xcb: fix thread synchronization issue in QXcbEventQueue::waitForNewEvents() This patch amends 730cbad8824bcfcb7ab60371a6563cfb6dd5658d The issue was that the event reader thread (QXcbEventQueue::run()) can enqueue events sometime between GUI thread has last time peeked at the queue and before it has called waitForNewEvents() and hence started waiting for more events (via QWaitCondition). This scenario is even mentioned in the QWaitCondition documentation: "[..] if some of the threads are still in do_something() when the key is pressed, they won't be woken up (since they're not waiting on the condition variable) and so the task will not be performed for that key press. [..]" And if there are no more events on the X11 connection, the waitForNewEvents() in QXcbClipboard::waitForClipboardEvent() would timeout. Fixes: QTBUG-75319 Change-Id: I8990a2a0c00571dfc334fb57d616dee999042885 Reviewed-by: Igor Kushnir Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbeventqueue.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.cpp b/src/plugins/platforms/xcb/qxcbeventqueue.cpp index acec0486c2..4ca73e3048 100644 --- a/src/plugins/platforms/xcb/qxcbeventqueue.cpp +++ b/src/plugins/platforms/xcb/qxcbeventqueue.cpp @@ -226,11 +226,13 @@ void QXcbEventQueue::run() }; while (!m_closeConnectionDetected && (event = xcb_wait_for_event(connection))) { + m_newEventsMutex.lock(); enqueueEvent(event); while (!m_closeConnectionDetected && (event = xcb_poll_for_queued_event(connection))) enqueueEvent(event); m_newEventsCondition.wakeOne(); + m_newEventsMutex.unlock(); wakeUpDispatcher(); } @@ -350,9 +352,12 @@ bool QXcbEventQueue::peekEventQueue(PeekerCallback peeker, void *peekerData, void QXcbEventQueue::waitForNewEvents(unsigned long time) { - m_newEventsMutex.lock(); + QMutexLocker locker(&m_newEventsMutex); + QXcbEventNode *tailBeforeFlush = m_flushedTail; + flushBufferedEvents(); + if (tailBeforeFlush != m_flushedTail) + return; m_newEventsCondition.wait(&m_newEventsMutex, time); - m_newEventsMutex.unlock(); } void QXcbEventQueue::sendCloseConnectionEvent() const From 8f75910deaf5a41506dc5cb0fe412a8f4674be0d Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 8 Jul 2019 14:59:43 +0200 Subject: [PATCH 031/264] Add mouseDoubleClickDistance and touchDoubleTapDistance to QStyleHints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Amends ca280bfe3bc551f814d59d25079e098798fbdad7 and 705e3f68df83dca165e3cddb914d3816155323f8 which added these enums only to QPlatformTheme::ThemeHint but not to QPlatformIntegration::StyleHint. Those patches did not add accessors to QStyleHints, probably because the accessors in QStyleHints use the themeableHint() function which takes both enums; so to have an accessor implemented this way, we need it in both enums. But it's getting too silly, since the only platform plugin that modifies MouseDoubleClickDistance is Android, implemented by QAndroidPlatformTheme overriding QPlatformTheme::themeHint(), and thus illustrating that adding the enum to QPlatformIntegration::StyleHint is not the only way to allow a platform plugin to customize the hint. So it seems we need a new way of writing these accessors without needing to duplicate the enum value in QPlatformIntegration::StyleHint. The new version of themeableHint(QPlatformTheme::ThemeHint) falls back on the static QPlatformTheme::defaultThemeHint() accessor. Users should at least be able to see what the default value is; and having these getters will also provide link targets for QtQuick's TapHandler docs. Change-Id: I0f8560062bcd0ca5e6d580071d9fbcf3f07f625f Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qstylehints.cpp | 44 ++++++++++++++++++++++++++++++++++ src/gui/kernel/qstylehints.h | 4 ++++ 2 files changed, 48 insertions(+) diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp index 9b5b7a6f1e..732ede90d0 100644 --- a/src/gui/kernel/qstylehints.cpp +++ b/src/gui/kernel/qstylehints.cpp @@ -65,6 +65,20 @@ static inline QVariant themeableHint(QPlatformTheme::ThemeHint th, return QGuiApplicationPrivate::platformIntegration()->styleHint(ih); } +static inline QVariant themeableHint(QPlatformTheme::ThemeHint th) +{ + if (!QCoreApplication::instance()) { + qWarning("Must construct a QGuiApplication before accessing a platform theme hint."); + return QVariant(); + } + if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) { + const QVariant themeHint = theme->themeHint(th); + if (themeHint.isValid()) + return themeHint; + } + return QPlatformTheme::defaultThemeHint(th); +} + class QStyleHintsPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QStyleHints) @@ -80,6 +94,8 @@ public: int m_showShortcutsInContextMenus = -1; int m_wheelScrollLines = -1; int m_mouseQuickSelectionThreshold = -1; + int m_mouseDoubleClickDistance = -1; + int m_touchDoubleTapDistance = -1; }; /*! @@ -132,6 +148,34 @@ int QStyleHints::mouseDoubleClickInterval() const themeableHint(QPlatformTheme::MouseDoubleClickInterval, QPlatformIntegration::MouseDoubleClickInterval).toInt(); } +/*! + \property QStyleHints::mouseDoubleClickDistance + \brief the maximum distance, in pixels, that the mouse can be moved between + two consecutive mouse clicks and still have it detected as a double-click + \since 5.14 +*/ +int QStyleHints::mouseDoubleClickDistance() const +{ + Q_D(const QStyleHints); + return d->m_mouseDoubleClickDistance >= 0 ? + d->m_mouseDoubleClickDistance : + themeableHint(QPlatformTheme::MouseDoubleClickDistance).toInt(); +} + +/*! + \property QStyleHints::touchDoubleTapDistance + \brief the maximum distance, in pixels, that a finger can be moved between + two consecutive taps and still have it detected as a double-tap + \since 5.14 +*/ +int QStyleHints::touchDoubleTapDistance() const +{ + Q_D(const QStyleHints); + return d->m_touchDoubleTapDistance >= 0 ? + d->m_touchDoubleTapDistance : + themeableHint(QPlatformTheme::TouchDoubleTapDistance).toInt(); +} + /*! Sets the \a mousePressAndHoldInterval. \internal diff --git a/src/gui/kernel/qstylehints.h b/src/gui/kernel/qstylehints.h index 9091db9624..30d8fdc64d 100644 --- a/src/gui/kernel/qstylehints.h +++ b/src/gui/kernel/qstylehints.h @@ -74,10 +74,14 @@ class Q_GUI_EXPORT QStyleHints : public QObject Q_PROPERTY(bool useHoverEffects READ useHoverEffects WRITE setUseHoverEffects NOTIFY useHoverEffectsChanged FINAL) Q_PROPERTY(int wheelScrollLines READ wheelScrollLines NOTIFY wheelScrollLinesChanged FINAL) Q_PROPERTY(int mouseQuickSelectionThreshold READ mouseQuickSelectionThreshold WRITE setMouseQuickSelectionThreshold NOTIFY mouseQuickSelectionThresholdChanged FINAL) + Q_PROPERTY(int mouseDoubleClickDistance READ mouseDoubleClickDistance STORED false CONSTANT FINAL) + Q_PROPERTY(int touchDoubleTapDistance READ touchDoubleTapDistance STORED false CONSTANT FINAL) public: void setMouseDoubleClickInterval(int mouseDoubleClickInterval); int mouseDoubleClickInterval() const; + int mouseDoubleClickDistance() const; + int touchDoubleTapDistance() const; void setMousePressAndHoldInterval(int mousePressAndHoldInterval); int mousePressAndHoldInterval() const; void setStartDragDistance(int startDragDistance); From e96cea51da99629b33036e4b06738316a7ca4682 Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Fri, 5 Jul 2019 17:12:18 +0200 Subject: [PATCH 032/264] Fix compilation with disabled deprecated APIs The QImageIOHandler::name() has been deprecated since 5.13, but its overrides weren't. Enabled compilation of the overrides only when the QImageIOHandler::name() is compiled. Task-number: QTBUG-76491 Change-Id: I8fea0032427d25bb0de01be8920c723fc21f6b7a Reviewed-by: Volker Hilsheimer Reviewed-by: Alex Blasche --- src/plugins/imageformats/gif/qgifhandler.cpp | 2 ++ src/plugins/imageformats/gif/qgifhandler_p.h | 2 ++ src/plugins/imageformats/ico/qicohandler.cpp | 3 ++- src/plugins/imageformats/ico/qicohandler.h | 2 ++ src/plugins/imageformats/jpeg/qjpeghandler.cpp | 2 ++ src/plugins/imageformats/jpeg/qjpeghandler_p.h | 2 ++ 6 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/plugins/imageformats/gif/qgifhandler.cpp b/src/plugins/imageformats/gif/qgifhandler.cpp index 1aef1a24d2..a6029b691c 100644 --- a/src/plugins/imageformats/gif/qgifhandler.cpp +++ b/src/plugins/imageformats/gif/qgifhandler.cpp @@ -1215,9 +1215,11 @@ int QGifHandler::currentImageNumber() const return frameNumber; } +#if QT_DEPRECATED_SINCE(5, 13) QByteArray QGifHandler::name() const { return "gif"; } +#endif QT_END_NAMESPACE diff --git a/src/plugins/imageformats/gif/qgifhandler_p.h b/src/plugins/imageformats/gif/qgifhandler_p.h index b004ee610d..c6592043ce 100644 --- a/src/plugins/imageformats/gif/qgifhandler_p.h +++ b/src/plugins/imageformats/gif/qgifhandler_p.h @@ -73,7 +73,9 @@ public: bool read(QImage *image) override; bool write(const QImage &image) override; +#if QT_DEPRECATED_SINCE(5, 13) QByteArray name() const override; +#endif static bool canRead(QIODevice *device); diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp index 4908850cc5..c8e31dceac 100644 --- a/src/plugins/imageformats/ico/qicohandler.cpp +++ b/src/plugins/imageformats/ico/qicohandler.cpp @@ -818,6 +818,7 @@ bool QtIcoHandler::write(const QImage &image) return ICOReader::write(device, imgs); } +#if QT_DEPRECATED_SINCE(5, 13) /*! * Return the common identifier of the format. * For ICO format this will return "ico". @@ -826,7 +827,7 @@ QByteArray QtIcoHandler::name() const { return "ico"; } - +#endif /*! \reimp diff --git a/src/plugins/imageformats/ico/qicohandler.h b/src/plugins/imageformats/ico/qicohandler.h index 435f036113..328dfce47e 100644 --- a/src/plugins/imageformats/ico/qicohandler.h +++ b/src/plugins/imageformats/ico/qicohandler.h @@ -54,7 +54,9 @@ public: bool read(QImage *image) override; bool write(const QImage &image) override; +#if QT_DEPRECATED_SINCE(5, 13) QByteArray name() const override; +#endif int imageCount() const override; bool jumpToImage(int imageNumber) override; diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp index 54fe857908..aed2900356 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp +++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp @@ -1124,9 +1124,11 @@ void QJpegHandler::setOption(ImageOption option, const QVariant &value) } } +#if QT_DEPRECATED_SINCE(5, 13) QByteArray QJpegHandler::name() const { return "jpeg"; } +#endif QT_END_NAMESPACE diff --git a/src/plugins/imageformats/jpeg/qjpeghandler_p.h b/src/plugins/imageformats/jpeg/qjpeghandler_p.h index d832bf82f3..fafa930c11 100644 --- a/src/plugins/imageformats/jpeg/qjpeghandler_p.h +++ b/src/plugins/imageformats/jpeg/qjpeghandler_p.h @@ -68,7 +68,9 @@ public: bool read(QImage *image) override; bool write(const QImage &image) override; +#if QT_DEPRECATED_SINCE(5, 13) QByteArray name() const override; +#endif static bool canRead(QIODevice *device); From 307403f8b4f25f3fa711fb64102c755d50283c2b Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 5 Jul 2019 17:20:14 +0200 Subject: [PATCH 033/264] Stabilize QGraphicsItem::cursor and select_multi tests The tests send QEvent::MouseMove events to the view, but don't fully construct the event with both local and global position. Consequently, QMouseEvent will use QCursor::pos as the global position, which is unreliable, as QTest::mouseMove can not guarantee that the mouse really moves - when running the tests locally on e.g macOS, it never does. So instead construct the QMouseEvent with the trivially calculated global position. Change-Id: Ic4c914e3af7f15751545080d4743b06d3887cce8 Reviewed-by: Andreas Aardal Hanssen --- .../qgraphicsitem/tst_qgraphicsitem.cpp | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index ae0d91dfe3..af4b6c9e4a 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -1811,7 +1811,8 @@ void tst_QGraphicsItem::selected_multi() { // Ctrl-move on item1 - QMouseEvent event(QEvent::MouseMove, view.mapFromScene(item1->scenePos()) + QPoint(1, 0), Qt::LeftButton, Qt::LeftButton, Qt::ControlModifier); + const QPoint item1Point = view.mapFromScene(item1->scenePos()) + QPoint(1, 0); + QMouseEvent event(QEvent::MouseMove, item1Point, view.viewport()->mapToGlobal(item1Point), Qt::LeftButton, Qt::LeftButton, Qt::ControlModifier); QApplication::sendEvent(view.viewport(), &event); QVERIFY(!item1->isSelected()); QVERIFY(!item2->isSelected()); @@ -1832,7 +1833,8 @@ void tst_QGraphicsItem::selected_multi() { // Ctrl-move on item1 - QMouseEvent event(QEvent::MouseMove, view.mapFromScene(item1->scenePos()) + QPoint(1, 0), Qt::LeftButton, Qt::LeftButton, Qt::ControlModifier); + const QPoint item1Point = view.mapFromScene(item1->scenePos()) + QPoint(1, 0); + QMouseEvent event(QEvent::MouseMove, item1Point, view.viewport()->mapToGlobal(item1Point), Qt::LeftButton, Qt::LeftButton, Qt::ControlModifier); QApplication::sendEvent(view.viewport(), &event); QVERIFY(item1->isSelected()); QVERIFY(!item2->isSelected()); @@ -4178,37 +4180,41 @@ void tst_QGraphicsItem::cursor() item1->setCursor(Qt::IBeamCursor); item2->setCursor(Qt::PointingHandCursor); - QTest::mouseMove(&view, view.rect().center()); + QPoint viewCenter = view.rect().center(); + QPoint item1Center = view.mapFromScene(item1->sceneBoundingRect().center()); + QPoint item2Center = view.mapFromScene(item2->sceneBoundingRect().center()); + + QTest::mouseMove(&view, viewCenter); const Qt::CursorShape viewportShape = view.viewport()->cursor().shape(); { QTest::mouseMove(view.viewport(), QPoint(100, 50)); - QMouseEvent event(QEvent::MouseMove, QPoint(100, 50), Qt::NoButton, 0, 0); + QMouseEvent event(QEvent::MouseMove, QPoint(100, 50), view.viewport()->mapToGlobal(QPoint(100, 50)), Qt::NoButton, 0, 0); QApplication::sendEvent(view.viewport(), &event); } QTRY_COMPARE(view.viewport()->cursor().shape(), viewportShape); { - QTest::mouseMove(view.viewport(), view.mapFromScene(item1->sceneBoundingRect().center())); - QMouseEvent event(QEvent::MouseMove, view.mapFromScene(item1->sceneBoundingRect().center()), Qt::NoButton, 0, 0); + QTest::mouseMove(view.viewport(), item1Center); + QMouseEvent event(QEvent::MouseMove, item1Center, view.viewport()->mapToGlobal(item1Center), Qt::NoButton, 0, 0); QApplication::sendEvent(view.viewport(), &event); } QTRY_COMPARE(view.viewport()->cursor().shape(), item1->cursor().shape()); { - QTest::mouseMove(view.viewport(), view.mapFromScene(item2->sceneBoundingRect().center())); - QMouseEvent event(QEvent::MouseMove, view.mapFromScene(item2->sceneBoundingRect().center()), Qt::NoButton, 0, 0); + QTest::mouseMove(view.viewport(), item2Center); + QMouseEvent event(QEvent::MouseMove, item2Center, view.viewport()->mapToGlobal(item2Center), Qt::NoButton, 0, 0); QApplication::sendEvent(view.viewport(), &event); } QTRY_COMPARE(view.viewport()->cursor().shape(), item2->cursor().shape()); { - QTest::mouseMove(view.viewport(), view.rect().center()); - QMouseEvent event(QEvent::MouseMove, QPoint(100, 25), Qt::NoButton, 0, 0); + QTest::mouseMove(view.viewport(), viewCenter); + QMouseEvent event(QEvent::MouseMove, QPoint(100, 25), view.viewport()->mapToGlobal(QPoint(100, 50)), Qt::NoButton, 0, 0); QApplication::sendEvent(view.viewport(), &event); } From d8688d44840dd3f2324769d10b927c442b42e2c0 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 5 Jul 2019 17:24:22 +0200 Subject: [PATCH 034/264] Don't set the mouse cursor for items that are disabled As with widgets, items that are disabled should not receive any input events. Similar to QGraphicsScene, which ignores disabled items when handling mouse presses, the view should also ignore them when handling mouse moves to update the cursor. Since QGraphicsView only adjusts the cursors on mouse moves, reenabling an item that is currently under the mouse will not change the cursor. This is consistent with other changes of item attributes that would position the item under the mouse (such as moving it). The overhead of hit-testing items for every such attribute change would be too large, and applications can generate a mouse move event if they really need to adjust the cursor in all situations. [ChangeLog][QtWidgets][QGraphicsView] Ignore disabled items when setting the mouse cursor. Fixes: QTBUG-76765 Change-Id: Ifcd31fc0581e8421e58eeb436a55b031909eed7e Reviewed-by: Shawn Rutledge --- src/widgets/graphicsview/qgraphicsview.cpp | 4 ++-- .../graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp index 24647dd74c..b14b23909e 100644 --- a/src/widgets/graphicsview/qgraphicsview.cpp +++ b/src/widgets/graphicsview/qgraphicsview.cpp @@ -691,7 +691,7 @@ void QGraphicsViewPrivate::mouseMoveEventHandler(QMouseEvent *event) } // Find the topmost item under the mouse with a cursor. foreach (QGraphicsItem *item, scene->d_func()->cachedItemsUnderMouse) { - if (item->hasCursor()) { + if (item->isEnabled() && item->hasCursor()) { _q_setViewportCursor(item->cursor()); return; } @@ -808,7 +808,7 @@ void QGraphicsViewPrivate::_q_unsetViewportCursor() Q_Q(QGraphicsView); const auto items = q->items(lastMouseEvent.pos()); for (QGraphicsItem *item : items) { - if (item->hasCursor()) { + if (item->isEnabled() && item->hasCursor()) { _q_setViewportCursor(item->cursor()); return; } diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index af4b6c9e4a..3260e09943 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -4219,6 +4219,15 @@ void tst_QGraphicsItem::cursor() } QTRY_COMPARE(view.viewport()->cursor().shape(), viewportShape); + + item1->setEnabled(false); + { + QTest::mouseMove(view.viewport(), item1Center); + QMouseEvent event(QEvent::MouseMove, item1Center, view.viewport()->mapToGlobal(item1Center), Qt::NoButton, 0, 0); + QApplication::sendEvent(view.viewport(), &event); + } + + QTRY_COMPARE(view.viewport()->cursor().shape(), viewportShape); } #endif /* From fc95af3621c8d135d613e1fff82c0613bf281c87 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 21 Jun 2019 18:35:22 +0200 Subject: [PATCH 035/264] QSimpleTextCodec: fix load memory order of atomic pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pointer value is not the only data we're interested in, but instead points to indirect data, so we need a release fence on store (present) and a corresponding acquire fence on load (was missing). Change-Id: I51f8251c0c7f4056192880430f2be5e0836dbed6 Reviewed-by: Thiago Macieira (cherry picked from commit 6f84829031f318bfda1deff5f409b5ea6c6a5c5f) (cherry picked from commit 4cc6e1419294a729e53d698bace2254903c1429b) Reviewed-by: Mårten Nordheim --- src/corelib/codecs/qsimplecodec.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/codecs/qsimplecodec.cpp b/src/corelib/codecs/qsimplecodec.cpp index 9ab545d783..16a9b8a7c3 100644 --- a/src/corelib/codecs/qsimplecodec.cpp +++ b/src/corelib/codecs/qsimplecodec.cpp @@ -610,7 +610,7 @@ QSimpleTextCodec::QSimpleTextCodec(int i) : forwardIndex(i), reverseMap(0) QSimpleTextCodec::~QSimpleTextCodec() { - delete reverseMap.load(); + delete reverseMap.loadAcquire(); } static QByteArray *buildReverseMap(int forwardIndex) @@ -662,12 +662,12 @@ QByteArray QSimpleTextCodec::convertFromUnicode(const QChar *in, int length, Con const char replacement = (state && state->flags & ConvertInvalidToNull) ? 0 : '?'; int invalid = 0; - QByteArray *rmap = reverseMap.load(); + QByteArray *rmap = reverseMap.loadAcquire(); if (!rmap){ rmap = buildReverseMap(this->forwardIndex); if (!reverseMap.testAndSetRelease(0, rmap)) { delete rmap; - rmap = reverseMap.load(); + rmap = reverseMap.loadAcquire(); } } From 1c6828b9d61a5988e91e67342cc0f616fa87949e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 26 Jun 2019 07:24:18 +0200 Subject: [PATCH 036/264] QFreeList: fix memory order on block deletion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Blocks are likely to have been created in a differnt thread from the one performing their deletion, so we need an acquire fence. The rest of the atomics use in the class looks ok, but nevertheless warrants a deeper analysis. Change-Id: I1571ded3a06695b0d58b5bf1d80d6283ac21f959 Reviewed-by: Thiago Macieira (cherry picked from commit 6fa34930c23c7494a3f2703777f46794ff091e2b) (cherry picked from commit 51bcc7e07e2bb5b42bb200dcd5269e9e9e2fe240) Reviewed-by: Mårten Nordheim --- src/corelib/tools/qfreelist_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h index 2f98cf5cc1..665b651e69 100644 --- a/src/corelib/tools/qfreelist_p.h +++ b/src/corelib/tools/qfreelist_p.h @@ -218,7 +218,7 @@ template inline QFreeList::~QFreeList() { for (int i = 0; i < ConstantsType::BlockCount; ++i) - delete [] _v[i].load(); + delete [] _v[i].loadAcquire(); } template From a776d6ec5bd209ece087c446afb6b31eb2c40b26 Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Sun, 7 Jul 2019 12:43:38 +0200 Subject: [PATCH 037/264] QTextObject: One more 0 to nullptr conversion Change-Id: I61446afa882304400d3ae8045e4f17bb7a020600 Reviewed-by: Marc Mutz Reviewed-by: Christian Ehrlicher --- src/gui/text/qtextobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index 547b21c02e..40960c910e 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -1322,7 +1322,7 @@ QTextList *QTextBlock::textList() const QTextBlockUserData *QTextBlock::userData() const { if (!p || !n) - return 0; + return nullptr; const QTextBlockData *b = p->blockMap().fragment(n); return b->userData; From 36f6bd7cf007c27772de5725791b7bc9040a041d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 8 Jul 2019 21:55:14 +0200 Subject: [PATCH 038/264] QHash: mark the equality operator for QHashDummyValue constexpr noexcept Who knows what this may end up being good for. Change-Id: Ib5e73b0170ebba54f87f36e75b7c407f801c52a0 Reviewed-by: Volker Hilsheimer --- src/corelib/tools/qhash.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 4b4cb2d5f0..f4590c6672 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -136,7 +136,7 @@ struct QHashDummyValue { }; -inline bool operator==(const QHashDummyValue & /* v1 */, const QHashDummyValue & /* v2 */) +constexpr bool operator==(const QHashDummyValue &, const QHashDummyValue &) noexcept { return true; } From 60ca2f5f7c38178cfe62d3dbe1b8dacfe43cbac9 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 18 Jun 2019 20:11:18 +0200 Subject: [PATCH 039/264] Be less laissez-faire with implicit conversions to QChar QChar currently is convertible from nearly every integral type. This is bad code hygiene and should be fixed come Qt 6. The present patch is the result of compile fixes from marking these constructors explicit. As is clear from the distribution of fixes, only low-level string handling code used these implicit conversions, an indication that they're not in widespread use elsewhere. Change-Id: Ief5336f21e6d181e03ab92893b3d13a14adc7cb0 Reviewed-by: Volker Hilsheimer --- src/corelib/codecs/qlatincodec.cpp | 18 ++++++++--------- src/corelib/codecs/qutfcodec.cpp | 6 +++--- src/corelib/io/qdir_p.h | 2 +- src/corelib/io/qipaddress.cpp | 2 +- src/corelib/io/qurl.cpp | 2 +- src/corelib/io/qurlidna.cpp | 5 ++--- src/corelib/io/qurlquery.cpp | 8 ++++---- src/corelib/serialization/qtextstream.cpp | 2 +- src/corelib/serialization/qxmlstream.cpp | 2 +- src/corelib/tools/qchar.cpp | 18 ++++++++--------- src/corelib/tools/qchar.h | 10 +++++----- src/corelib/tools/qlocale_p.h | 8 ++++---- src/corelib/tools/qregexp.cpp | 2 +- src/corelib/tools/qstring.cpp | 4 ++-- src/corelib/tools/qstring.h | 10 +++++----- .../evdevkeyboard/qevdevkeyboardhandler.cpp | 2 +- src/xml/sax/qxml.cpp | 20 +++++++++---------- 17 files changed, 60 insertions(+), 61 deletions(-) diff --git a/src/corelib/codecs/qlatincodec.cpp b/src/corelib/codecs/qlatincodec.cpp index 463c5a56ae..55e6f0ba4d 100644 --- a/src/corelib/codecs/qlatincodec.cpp +++ b/src/corelib/codecs/qlatincodec.cpp @@ -62,7 +62,7 @@ QByteArray QLatin1Codec::convertFromUnicode(const QChar *ch, int len, ConverterS char *d = r.data(); int invalid = 0; for (int i = 0; i < len; ++i) { - if (ch[i] > 0xff) { + if (ch[i] > QChar(0xff)) { d[i] = replacement; ++invalid; } else { @@ -112,28 +112,28 @@ QString QLatin15Codec::convertToUnicode(const char* chars, int len, ConverterSta while(len--) { switch(uc->unicode()) { case 0xa4: - *uc = 0x20ac; + *uc = QChar(0x20ac); break; case 0xa6: - *uc = 0x0160; + *uc = QChar(0x0160); break; case 0xa8: - *uc = 0x0161; + *uc = QChar(0x0161); break; case 0xb4: - *uc = 0x017d; + *uc = QChar(0x017d); break; case 0xb8: - *uc = 0x017e; + *uc = QChar(0x017e); break; case 0xbc: - *uc = 0x0152; + *uc = QChar(0x0152); break; case 0xbd: - *uc = 0x0153; + *uc = QChar(0x0153); break; case 0xbe: - *uc = 0x0178; + *uc = QChar(0x0178); break; default: break; diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp index 85736fdf02..af36bd7e2f 100644 --- a/src/corelib/codecs/qutfcodec.cpp +++ b/src/corelib/codecs/qutfcodec.cpp @@ -951,10 +951,10 @@ QString QUtf32::convertToUnicode(const char *chars, int len, QTextCodec::Convert } uint code = (endian == BigEndianness) ? qFromBigEndian(tuple) : qFromLittleEndian(tuple); if (QChar::requiresSurrogates(code)) { - *qch++ = QChar::highSurrogate(code); - *qch++ = QChar::lowSurrogate(code); + *qch++ = QChar(QChar::highSurrogate(code)); + *qch++ = QChar(QChar::lowSurrogate(code)); } else { - *qch++ = code; + *qch++ = QChar(code); } num = 0; } diff --git a/src/corelib/io/qdir_p.h b/src/corelib/io/qdir_p.h index 0f3ab7f899..42218e1ccf 100644 --- a/src/corelib/io/qdir_p.h +++ b/src/corelib/io/qdir_p.h @@ -82,7 +82,7 @@ public: static inline QChar getFilterSepChar(const QString &nameFilter); - static inline QStringList splitFilters(const QString &nameFilter, QChar sep = 0); + static inline QStringList splitFilters(const QString &nameFilter, QChar sep = {}); void setPath(const QString &path); diff --git a/src/corelib/io/qipaddress.cpp b/src/corelib/io/qipaddress.cpp index b3421fca8f..ddc5b6607f 100644 --- a/src/corelib/io/qipaddress.cpp +++ b/src/corelib/io/qipaddress.cpp @@ -312,7 +312,7 @@ void toString(QString &appendTo, const IPv6Address address) } } - const QChar colon = ushort(':'); + const QChar colon = u':'; if (zeroRunLength < 4) zeroRunOffset = -1; else if (zeroRunOffset == 0) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index d9ebc6c750..878e007fb0 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -1010,7 +1010,7 @@ inline bool QUrlPrivate::setScheme(const QString &value, int len, bool doSetErro for (int i = needsLowercasing; i >= 0; --i) { ushort c = schemeData[i].unicode(); if (c >= 'A' && c <= 'Z') - schemeData[i] = c + 0x20; + schemeData[i] = QChar(c + 0x20); } } diff --git a/src/corelib/io/qurlidna.cpp b/src/corelib/io/qurlidna.cpp index 2f89d22660..a2f0caa606 100644 --- a/src/corelib/io/qurlidna.cpp +++ b/src/corelib/io/qurlidna.cpp @@ -2220,9 +2220,8 @@ Q_AUTOTEST_EXPORT void qt_punycodeEncoder(const QChar *s, int ucLength, QString bool skipped = false; // copy all basic code points verbatim to output. for (uint j = 0; j < (uint) ucLength; ++j) { - ushort js = s[j].unicode(); - if (js < 0x80) - *d++ = js; + if (s[j].unicode() < 0x80) + *d++ = s[j]; else skipped = true; } diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp index 36a2880bf1..e6aec9bf45 100644 --- a/src/corelib/io/qurlquery.cpp +++ b/src/corelib/io/qurlquery.cpp @@ -293,9 +293,9 @@ void QUrlQueryPrivate::setQuery(const QString &query) const QChar *delimiter = nullptr; while (pos != end) { // scan for the component parts of this pair - if (!delimiter && pos->unicode() == valueDelimiter) + if (!delimiter && *pos == valueDelimiter) delimiter = pos; - if (pos->unicode() == pairDelimiter) + if (*pos == pairDelimiter) break; ++pos; } @@ -584,8 +584,8 @@ QString QUrlQuery::query(QUrl::ComponentFormattingOptions encoding) const */ void QUrlQuery::setQueryDelimiters(QChar valueDelimiter, QChar pairDelimiter) { - d->valueDelimiter = valueDelimiter.unicode(); - d->pairDelimiter = pairDelimiter.unicode(); + d->valueDelimiter = valueDelimiter; + d->pairDelimiter = pairDelimiter; } /*! diff --git a/src/corelib/serialization/qtextstream.cpp b/src/corelib/serialization/qtextstream.cpp index 9d4bc223ab..a675c3cede 100644 --- a/src/corelib/serialization/qtextstream.cpp +++ b/src/corelib/serialization/qtextstream.cpp @@ -888,7 +888,7 @@ inline bool QTextStreamPrivate::getChar(QChar *ch) if ((string && stringOffset == string->size()) || (device && readBuffer.isEmpty() && !fillReadBuffer())) { if (ch) - *ch = 0; + *ch = QChar(); return false; } if (ch) diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp index be3a476cb2..27a5137fc9 100644 --- a/src/corelib/serialization/qxmlstream.cpp +++ b/src/corelib/serialization/qxmlstream.cpp @@ -1423,7 +1423,7 @@ inline int QXmlStreamReaderPrivate::fastScanNMTOKEN() int n = 0; uint c; while ((c = getChar()) != StreamEOF) { - if (fastDetermineNameChar(c) == NotName) { + if (fastDetermineNameChar(QChar(c)) == NotName) { putChar(c); return n; } else { diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp index e097e4a5fe..0c190c6a3d 100644 --- a/src/corelib/tools/qchar.cpp +++ b/src/corelib/tools/qchar.cpp @@ -1885,11 +1885,11 @@ static void composeHelper(QString *str, QChar::UnicodeVersion version, int from) QChar *d = s.data(); // ligatureHelper() never changes planes if (QChar::requiresSurrogates(ligature)) { - d[starter] = QChar::highSurrogate(ligature); - d[starter + 1] = QChar::lowSurrogate(ligature); + d[starter] = QChar(QChar::highSurrogate(ligature)); + d[starter + 1] = QChar(QChar::lowSurrogate(ligature)); s.remove(i, 2); } else { - d[starter] = ligature; + d[starter] = QChar(ligature); s.remove(i, 1); } continue; @@ -1962,16 +1962,16 @@ static void canonicalOrderHelper(QString *str, QChar::UnicodeVersion version, in int p = pos; // exchange characters if (!QChar::requiresSurrogates(u2)) { - uc[p++] = u2; + uc[p++] = QChar(u2); } else { - uc[p++] = QChar::highSurrogate(u2); - uc[p++] = QChar::lowSurrogate(u2); + uc[p++] = QChar(QChar::highSurrogate(u2)); + uc[p++] = QChar(QChar::lowSurrogate(u2)); } if (!QChar::requiresSurrogates(u1)) { - uc[p++] = u1; + uc[p++] = QChar(u1); } else { - uc[p++] = QChar::highSurrogate(u1); - uc[p++] = QChar::lowSurrogate(u1); + uc[p++] = QChar(QChar::highSurrogate(u1)); + uc[p++] = QChar(QChar::lowSurrogate(u1)); } if (pos > 0) --pos; diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h index 73344ecf52..e028a24c24 100644 --- a/src/corelib/tools/qchar.h +++ b/src/corelib/tools/qchar.h @@ -443,17 +443,17 @@ public: #endif inline unsigned char combiningClass() const noexcept { return QChar::combiningClass(ucs); } - inline QChar mirroredChar() const noexcept { return QChar::mirroredChar(ucs); } + inline QChar mirroredChar() const noexcept { return QChar(QChar::mirroredChar(ucs)); } inline bool hasMirrored() const noexcept { return QChar::hasMirrored(ucs); } QString decomposition() const; inline Decomposition decompositionTag() const noexcept { return QChar::decompositionTag(ucs); } inline int digitValue() const noexcept { return QChar::digitValue(ucs); } - inline QChar toLower() const noexcept { return QChar::toLower(ucs); } - inline QChar toUpper() const noexcept { return QChar::toUpper(ucs); } - inline QChar toTitleCase() const noexcept { return QChar::toTitleCase(ucs); } - inline QChar toCaseFolded() const noexcept { return QChar::toCaseFolded(ucs); } + inline QChar toLower() const noexcept { return QChar(QChar::toLower(ucs)); } + inline QChar toUpper() const noexcept { return QChar(QChar::toUpper(ucs)); } + inline QChar toTitleCase() const noexcept { return QChar(QChar::toTitleCase(ucs)); } + inline QChar toCaseFolded() const noexcept { return QChar(QChar::toCaseFolded(ucs)); } inline Script script() const noexcept { return QChar::script(ucs); } diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h index 1e3da35a02..37afb8542b 100644 --- a/src/corelib/tools/qlocale_p.h +++ b/src/corelib/tools/qlocale_p.h @@ -285,9 +285,9 @@ public: quint16 m_language_id, m_script_id, m_country_id; // FIXME QTBUG-69324: not all unicode code-points map to single-token UTF-16 :-( - quint16 m_decimal, m_group, m_list, m_percent, m_zero, m_minus, m_plus, m_exponential; - quint16 m_quotation_start, m_quotation_end; - quint16 m_alternate_quotation_start, m_alternate_quotation_end; + char16_t m_decimal, m_group, m_list, m_percent, m_zero, m_minus, m_plus, m_exponential; + char16_t m_quotation_start, m_quotation_end; + char16_t m_alternate_quotation_start, m_alternate_quotation_end; quint16 m_list_pattern_part_start_idx, m_list_pattern_part_start_size; quint16 m_list_pattern_part_mid_idx, m_list_pattern_part_mid_size; @@ -417,7 +417,7 @@ inline char QLocaleData::digitToCLocale(QChar in) const if (in == m_group) return ','; - if (in == m_exponential || in == QChar::toUpper(m_exponential)) + if (in == m_exponential || in == QChar(QChar::toUpper(m_exponential))) return 'e'; // In several languages group() is a non-breaking space (U+00A0) or its thin diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp index dd38ba0360..d81826b47b 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -2035,7 +2035,7 @@ bool QRegExpMatchState::matchHere() #ifndef QT_NO_REGEXP_CCLASS const QRegExpCharClass &cc = eng->cl.at(m ^ QRegExpEngine::CharClassBit); if (eng->cs) - inside = cc.in(ch); + inside = cc.in(QChar(ch)); else if (cc.negative()) inside = cc.in(QChar(ch).toLower()) && cc.in(QChar(ch).toUpper()); diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 47db97cdfc..12506afdef 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -3208,7 +3208,7 @@ QString& QString::replace(QChar ch, const QString &after, Qt::CaseSensitivity cs return remove(ch, cs); if (after.d->size == 1) - return replace(ch, after.d->data()[0], cs); + return replace(ch, after.front(), cs); if (d->size == 0) return *this; @@ -6666,7 +6666,7 @@ static QString detachAndConvertCase(T &str, QStringIterator it) } else if (Q_UNLIKELY(QChar::requiresSurrogates(uc))) { // so far, case convertion never changes planes (guaranteed by the qunicodetables generator) pp++; - *pp++ = QChar::lowSurrogate(uc + caseDiff); + *pp++ = QChar(QChar::lowSurrogate(uc + caseDiff)); } else { *pp++ = QChar(uc + caseDiff); } diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 6788e53057..9896553f7d 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -1002,11 +1002,11 @@ inline QString::QString(QLatin1String aLatin1) : d(fromLatin1_helper(aLatin1.lat inline int QString::length() const { return d->size; } inline const QChar QString::at(int i) const -{ Q_ASSERT(uint(i) < uint(size())); return d->data()[i]; } +{ Q_ASSERT(uint(i) < uint(size())); return QChar(d->data()[i]); } inline const QChar QString::operator[](int i) const -{ Q_ASSERT(uint(i) < uint(size())); return d->data()[i]; } +{ Q_ASSERT(uint(i) < uint(size())); return QChar(d->data()[i]); } inline const QChar QString::operator[](uint i) const -{ Q_ASSERT(i < uint(size())); return d->data()[i]; } +{ Q_ASSERT(i < uint(size())); return QChar(d->data()[i]); } inline bool QString::isEmpty() const { return d->size == 0; } inline const QChar *QString::unicode() const @@ -1118,11 +1118,11 @@ public: { using namespace QtPrivate::DeprecatedRefClassBehavior; if (Q_LIKELY(i < s.d->size)) - return s.d->data()[i]; + return QChar(s.d->data()[i]); #ifdef QT_DEBUG warn(WarningType::OutOfRange, EmittingClass::QCharRef); #endif - return 0; + return QChar(); } inline QCharRef &operator=(QChar c) { diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp index bff4a2522c..3555763b89 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp @@ -231,7 +231,7 @@ void QEvdevKeyboardHandler::processKeyEvent(int nativecode, int unicode, int qtc QWindowSystemInterface::handleExtendedKeyEvent(0, (isPress ? QEvent::KeyPress : QEvent::KeyRelease), qtcode, modifiers, nativecode + 8, 0, int(modifiers), - (unicode != 0xffff ) ? QString(unicode) : QString(), autoRepeat); + (unicode != 0xffff ) ? QString(QChar(unicode)) : QString(), autoRepeat); } QEvdevKeyboardHandler::KeycodeAction QEvdevKeyboardHandler::processKeycode(quint16 keycode, bool pressed, bool autorepeat) diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp index 1c45118fb1..1993073cce 100644 --- a/src/xml/sax/qxml.cpp +++ b/src/xml/sax/qxml.cpp @@ -1161,12 +1161,12 @@ QChar QXmlInputSource::next() d->nextReturnedEndOfData = false; fetchData(); if (d->pos >= d->length) { - return EndOfDocument; + return QChar(EndOfDocument); } return next(); } d->nextReturnedEndOfData = true; - return EndOfData; + return QChar(EndOfData); } // QXmlInputSource has no way to signal encoding errors. The best we can do @@ -1174,7 +1174,7 @@ QChar QXmlInputSource::next() // will then just call this function again to get the next char. QChar c = d->unicode[d->pos++]; if (c.unicode() == EndOfData) - c = EndOfDocument; + c = QChar(EndOfDocument); return c; } @@ -1313,8 +1313,8 @@ static QString extractEncodingDecl(const QString &text, bool *needMoreText) return QString(); while (pos < endPos) { - ushort uc = text.at(pos).unicode(); - if (uc == '\'' || uc == '"') + QChar uc = text.at(pos); + if (uc == u'\'' || uc == u'"') break; ++pos; } @@ -1325,8 +1325,8 @@ static QString extractEncodingDecl(const QString &text, bool *needMoreText) QString encoding; ++pos; while (pos < endPos) { - ushort uc = text.at(pos).unicode(); - if (uc == '\'' || uc == '"') + QChar uc = text.at(pos); + if (uc == u'\'' || uc == u'"') break; encoding.append(uc); ++pos; @@ -7800,7 +7800,7 @@ void QXmlSimpleReaderPrivate::next() c = inputSource->next(); // If we are not incremental parsing, we just skip over EndOfData chars to give the // parser an uninterrupted stream of document chars. - if (c == QXmlInputSource::EndOfData && parseStack == nullptr) + if (c == QChar(QXmlInputSource::EndOfData) && parseStack == nullptr) c = inputSource->next(); if (uc == '\n') { lineNr++; @@ -7877,7 +7877,7 @@ void QXmlSimpleReaderPrivate::init(const QXmlInputSource *i) */ void QXmlSimpleReaderPrivate::initData() { - c = QXmlInputSource::EndOfData; + c = QChar(QXmlInputSource::EndOfData); xmlRefStack.clear(); next(); } @@ -7925,7 +7925,7 @@ void QXmlSimpleReaderPrivate::unexpectedEof(ParseFunction where, int state) if (parseStack == nullptr) { reportParseError(QLatin1String(XMLERR_UNEXPECTEDEOF)); } else { - if (c == QXmlInputSource::EndOfDocument) { + if (c == QChar(QXmlInputSource::EndOfDocument)) { reportParseError(QLatin1String(XMLERR_UNEXPECTEDEOF)); } else { pushParseState(where, state); From e6c646a67858f98a255e80994e5920e932298164 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 4 Jul 2019 15:39:36 +0200 Subject: [PATCH 040/264] QHostInfoRunnable: make the lookupFinished() call more robust Use a scope guard to reliably mark the runnable as finished with the manager, lest a deleted runnable lingers in the manager's currentLookups for too long/ever. Change-Id: I89eff49931d0428f4e75789a0a1188edb1f66220 Reviewed-by: Volker Hilsheimer --- src/network/kernel/qhostinfo.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index 6302ad62eb..6caee5e097 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -826,11 +827,10 @@ QHostInfoRunnable::QHostInfoRunnable(const QString &hn, int i, const QObject *re void QHostInfoRunnable::run() { QHostInfoLookupManager *manager = theHostInfoLookupManager(); + const auto sg = qScopeGuard([&] { manager->lookupFinished(this); }); // check aborted - if (manager->wasAborted(id)) { - manager->lookupFinished(this); + if (manager->wasAborted(id)) return; - } QHostInfo hostInfo; @@ -852,10 +852,8 @@ void QHostInfoRunnable::run() } // check aborted again - if (manager->wasAborted(id)) { - manager->lookupFinished(this); + if (manager->wasAborted(id)) return; - } // signal emission hostInfo.setLookupId(id); @@ -879,8 +877,6 @@ void QHostInfoRunnable::run() } #endif - manager->lookupFinished(this); - // thread goes back to QThreadPool } From 4bb975717b0ba2c7b41e1a44192c2d54c919cfee Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Tue, 9 Jul 2019 12:11:03 +0200 Subject: [PATCH 041/264] doc: Add missing class qualifier A glass qualifier was missing in a \fn command. This caused clang to report an error. The class qualifier is added by this ubdate. Change-Id: I1c4928183f4c8eb1b28f0fde2ce659a1feb24175 Reviewed-by: Marc Mutz --- src/corelib/io/qurlquery.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp index 10c3f836c8..73a94cd5d5 100644 --- a/src/corelib/io/qurlquery.cpp +++ b/src/corelib/io/qurlquery.cpp @@ -146,7 +146,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QUrlQuery(std::initializer_list> list) + \fn QUrlQuery::QUrlQuery(std::initializer_list> list) \since 5.13 From 17ac9f8ced6ed351b52966739558abf9e44e1069 Mon Sep 17 00:00:00 2001 From: Ryan Chu Date: Wed, 5 Jun 2019 11:04:14 +0000 Subject: [PATCH 042/264] Revert "Disable Docker-based test servers on Windows temporarily" This reverts commit 17512d497d7eaf01aefe8140f5010818c0103a95. Reason for revert: force vmx instructions to Coin level B virtual Relates to qt/qt5 84ff024609e4eca003c604294b4102e73deba8c3 Change-Id: Id87a5629a5cd6ebc18c676eae390466e280fc600 Reviewed-by: Edward Welbourne --- mkspecs/features/unsupported/testserver.prf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/unsupported/testserver.prf b/mkspecs/features/unsupported/testserver.prf index 32bd4df30c..bca88ea2d8 100644 --- a/mkspecs/features/unsupported/testserver.prf +++ b/mkspecs/features/unsupported/testserver.prf @@ -58,9 +58,9 @@ debug_and_release:!build_pass: return() DOCKER_ENABLED = 1 -equals(QMAKE_HOST.os, Darwin) | equals(QMAKE_HOST.os, Windows) { +equals(QMAKE_HOST.os, Darwin) { DOCKER_ENABLED = 0 - message("Not using docker network test server on macOS and Windows, see QTQAINFRA-2717 and QTQAINFRA-2750") + message("Not using docker network test server on macOS, see QTQAINFRA-2717 and QTQAINFRA-2750") } TESTSERVER_VERSION = "" From 211830b2337aad4776c5c97ffc9bca7a73a26af7 Mon Sep 17 00:00:00 2001 From: Yulong Bai Date: Mon, 15 Oct 2018 15:37:41 +0200 Subject: [PATCH 043/264] QFusionStyle: fix excessive top margin of groupbox The users voted for smaller top margin while there was neither title nor checkbox. Task-number: QTBUG-44056 Change-Id: I5bd5cabb094c9cdec379f20e206196f1b5432182 Reviewed-by: Richard Moe Gustavsen --- src/widgets/styles/qfusionstyle.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index 34cc3c93db..e21ff4bec8 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -469,7 +469,14 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem, case PE_FrameGroupBox: { QPixmap pixmap(QLatin1String(":/qt-project.org/styles/commonstyle/images/fusion_groupbox.png")); - int topMargin = qMax(pixelMetric(PM_ExclusiveIndicatorHeight), option->fontMetrics.height()) + groupBoxTopMargin; + int topMargin = 0; + auto control = dynamic_cast(widget); + if (control && !control->isCheckable() && control->title().isEmpty()) { + // Shrinking the topMargin if Not checkable AND title is empty + topMargin = groupBoxTopMargin; + } else { + topMargin = qMax(pixelMetric(PM_ExclusiveIndicatorHeight), option->fontMetrics.height()) + groupBoxTopMargin; + } QRect frame = option->rect.adjusted(0, topMargin, 0, 0); qDrawBorderPixmap(painter, frame, QMargins(6, 6, 6, 6), pixmap); break; From 0a3107dd302c521c240b273229ba40a358cb0873 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 4 Jul 2019 15:24:13 +0200 Subject: [PATCH 044/264] QHostInfo: fix a race condition on QHostInfoCache::enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In auto-test-enabled builds, QHostInfoCache can be enabled and disabled using qt_qhostinfo_enable_cache() at any time. We cannot rule out that users use this function, or, indeed, that the auto-test never gets a threading stress-test. Under the assumption, then, that QHostInfoCache::enabled can be set by any thread at any time, and is read by any thread using QHostInfo::lookupHost(), we're presented with a data race, thus UB. Fix by making the accesses to QHostInfoCache::enabed atomic. Relaxed operations are suffcient, as the bool is the only data of interest in these situations. In particular, access to the cache itself is protected by the cache's mutex. We use std::atomic because QAtomicInteger doesn't exist on all implementations, but std::atomic must. Commit a0faf9e2366 set the precedent that it works. Change-Id: Ia1766753bb54c5fe8d8447b51a49a96a7a853eef Reviewed-by: Mårten Nordheim --- src/network/kernel/qhostinfo.cpp | 15 +-------------- src/network/kernel/qhostinfo_p.h | 9 ++++++--- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index e9ea6335d2..597c616fe9 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -952,23 +952,10 @@ void qt_qhostinfo_cache_inject(const QString &hostname, const QHostInfo &resolut QHostInfoCache::QHostInfoCache() : max_age(60), enabled(true), cache(128) { #ifdef QT_QHOSTINFO_CACHE_DISABLED_BY_DEFAULT - enabled = false; + enabled.store(false, std::memory_order_relaxed); #endif } -bool QHostInfoCache::isEnabled() -{ - return enabled; -} - -// this function is currently only used for the auto tests -// and not usable by public API -void QHostInfoCache::setEnabled(bool e) -{ - enabled = e; -} - - QHostInfo QHostInfoCache::get(const QString &name, bool *valid) { QMutexLocker locker(&this->mutex); diff --git a/src/network/kernel/qhostinfo_p.h b/src/network/kernel/qhostinfo_p.h index 8cce302166..8898d6ff50 100644 --- a/src/network/kernel/qhostinfo_p.h +++ b/src/network/kernel/qhostinfo_p.h @@ -73,6 +73,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -176,10 +177,12 @@ public: void put(const QString &name, const QHostInfo &info); void clear(); - bool isEnabled(); - void setEnabled(bool e); + bool isEnabled() { return enabled.load(std::memory_order_relaxed); } + // this function is currently only used for the auto tests + // and not usable by public API + void setEnabled(bool e) { enabled.store(e, std::memory_order_relaxed); } private: - bool enabled; + std::atomic enabled; struct QHostInfoCacheElement { QHostInfo info; QElapsedTimer age; From 89984a8a61a7e33a4ff62db98083a0e3c0c7b4b1 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 5 Jul 2019 15:35:34 +0200 Subject: [PATCH 045/264] Fix the systray example to only show an icon when requested MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "None" and "Custom icon" cases where using the same value for icon type, which resulted in both options showing the application icon. Use -1 to indicate the custom option, and treat all other options the same. Task-number: QTBUG-76916 Change-Id: Ib715f5d328175bd6e221b3f507087954fa542838 Reviewed-by: Tor Arne Vestbø --- examples/widgets/desktop/systray/window.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/widgets/desktop/systray/window.cpp b/examples/widgets/desktop/systray/window.cpp index 05944c92a7..28287dc02b 100644 --- a/examples/widgets/desktop/systray/window.cpp +++ b/examples/widgets/desktop/systray/window.cpp @@ -160,9 +160,10 @@ void Window::iconActivated(QSystemTrayIcon::ActivationReason reason) void Window::showMessage() { showIconCheckBox->setChecked(true); - QSystemTrayIcon::MessageIcon msgIcon = QSystemTrayIcon::MessageIcon( - typeComboBox->itemData(typeComboBox->currentIndex()).toInt()); - if (msgIcon == QSystemTrayIcon::NoIcon) { + int selectedIcon = typeComboBox->itemData(typeComboBox->currentIndex()).toInt(); + QSystemTrayIcon::MessageIcon msgIcon = QSystemTrayIcon::MessageIcon(selectedIcon); + + if (selectedIcon == -1) { // custom icon QIcon icon(iconComboBox->itemIcon(iconComboBox->currentIndex())); trayIcon->showMessage(titleEdit->text(), bodyEdit->toPlainText(), icon, durationSpinBox->value() * 1000); @@ -222,7 +223,7 @@ void Window::createMessageGroupBox() QStyle::SP_MessageBoxCritical), tr("Critical"), QSystemTrayIcon::Critical); typeComboBox->addItem(QIcon(), tr("Custom icon"), - QSystemTrayIcon::NoIcon); + -1); typeComboBox->setCurrentIndex(1); durationLabel = new QLabel(tr("Duration:")); From d72ea9cbd3c2bde4645745c5aeba7cc052d87f0d Mon Sep 17 00:00:00 2001 From: Ryan Chu Date: Fri, 21 Jun 2019 15:03:00 +0000 Subject: [PATCH 046/264] Revert "QFtp: Skip the flaky QTestEventLoop::timeout in Coin network" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 33d2715dd34d39a3250d7b66b785f421c7e07719. Reason for revert: Change-Id: I134514e729d7066ab5f67a0536e653868bf15ed7 Reviewed-by: Dimitrios Apostolou Reviewed-by: Mårten Nordheim --- tests/auto/network/access/qftp/tst_qftp.cpp | 80 +++++++++------------ 1 file changed, 32 insertions(+), 48 deletions(-) diff --git a/tests/auto/network/access/qftp/tst_qftp.cpp b/tests/auto/network/access/qftp/tst_qftp.cpp index a04c2ae01d..2068738a67 100644 --- a/tests/auto/network/access/qftp/tst_qftp.cpp +++ b/tests/auto/network/access/qftp/tst_qftp.cpp @@ -134,8 +134,8 @@ private: bool fileExists( const QString &host, quint16 port, const QString &user, const QString &password, const QString &file, const QString &cdDir = QString() ); bool dirExists( const QString &host, quint16 port, const QString &user, const QString &password, const QString &cdDir, const QString &dirToCreate ); - void renameInit( bool &isSuccess, const QString &host, const QString &user, const QString &password, const QString &createFile ); - void renameCleanup( bool &isSuccess, const QString &host, const QString &user, const QString &password, const QString &fileToDelete ); + void renameInit( const QString &host, const QString &user, const QString &password, const QString &createFile ); + void renameCleanup( const QString &host, const QString &user, const QString &password, const QString &fileToDelete ); QFtp *ftp; #ifndef QT_NO_BEARERMANAGEMENT @@ -336,11 +336,7 @@ static QByteArray msgTimedOut(const QString &host, quint16 port = 0) result += ':'; result += QByteArray::number(port); } - - if (host == QtNetworkSettings::ftpServerName()) - return "(QTBUG-75549) Flaky results: " % result; - else - return result; + return result; } void tst_QFtp::connectToHost() @@ -355,7 +351,7 @@ void tst_QFtp::connectToHost() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host, port) ); + QFAIL( msgTimedOut(host, port) ); QTEST( connectToHost_state, "state" ); @@ -438,7 +434,7 @@ void tst_QFtp::login() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host, port) ); + QFAIL( msgTimedOut(host, port) ); ResMapIt it = resultMap.find( QFtp::Login ); QVERIFY( it != resultMap.end() ); @@ -486,7 +482,7 @@ void tst_QFtp::close() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host, port) ); + QFAIL( msgTimedOut(host, port) ); QCOMPARE( close_state, (int)QFtp::Unconnected ); @@ -554,7 +550,7 @@ void tst_QFtp::list() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host, port) ); + QFAIL( msgTimedOut(host, port) ); ResMapIt it = resultMap.find( QFtp::List ); QVERIFY( it != resultMap.end() ); @@ -615,7 +611,7 @@ void tst_QFtp::cd() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) { - QSKIP( msgTimedOut(host, port) ); + QFAIL( msgTimedOut(host, port) ); } ResMapIt it = resultMap.find( QFtp::Cd ); @@ -692,7 +688,7 @@ void tst_QFtp::get() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host, port) ); + QFAIL( msgTimedOut(host, port) ); ResMapIt it = resultMap.find( QFtp::Get ); QVERIFY( it != resultMap.end() ); @@ -819,7 +815,7 @@ void tst_QFtp::put() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host, port) ); + QFAIL( msgTimedOut(host, port) ); it = resultMap.find( QFtp::Put ); QVERIFY( it != resultMap.end() ); @@ -852,7 +848,7 @@ void tst_QFtp::put() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host, port) ); + QFAIL( msgTimedOut(host, port) ); QCOMPARE( done_success, 1 ); QTEST( buf.buffer(), "fileData" ); @@ -870,7 +866,7 @@ void tst_QFtp::put() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host, port) ); + QFAIL( msgTimedOut(host, port) ); it = resultMap.find( QFtp::Remove ); QVERIFY( it != resultMap.end() ); @@ -934,7 +930,7 @@ void tst_QFtp::mkdir() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host, port) ); + QFAIL( msgTimedOut(host, port) ); ResMapIt it = resultMap.find( QFtp::Mkdir ); QVERIFY( it != resultMap.end() ); @@ -959,7 +955,7 @@ void tst_QFtp::mkdir() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host, port) ); + QFAIL( msgTimedOut(host, port) ); it = resultMap.find( QFtp::Mkdir ); QVERIFY( it != resultMap.end() ); @@ -979,7 +975,7 @@ void tst_QFtp::mkdir() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host, port) ); + QFAIL( msgTimedOut(host, port) ); it = resultMap.find( QFtp::Rmdir ); QVERIFY( it != resultMap.end() ); @@ -1077,9 +1073,8 @@ void tst_QFtp::rename_data() << 0; } -void tst_QFtp::renameInit( bool &isSuccess, const QString &host, const QString &user, const QString &password, const QString &createFile ) +void tst_QFtp::renameInit( const QString &host, const QString &user, const QString &password, const QString &createFile ) { - isSuccess = false; if ( !createFile.isNull() ) { // upload the file init(); @@ -1093,7 +1088,7 @@ void tst_QFtp::renameInit( bool &isSuccess, const QString &host, const QString & delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host) ); + QFAIL( msgTimedOut(host) ); ResMapIt it = resultMap.find( QFtp::Put ); QVERIFY( it != resultMap.end() ); @@ -1101,12 +1096,10 @@ void tst_QFtp::renameInit( bool &isSuccess, const QString &host, const QString & QVERIFY( fileExists( host, 21, user, password, createFile ) ); } - isSuccess = true; } -void tst_QFtp::renameCleanup( bool &isSuccess, const QString &host, const QString &user, const QString &password, const QString &fileToDelete ) +void tst_QFtp::renameCleanup( const QString &host, const QString &user, const QString &password, const QString &fileToDelete ) { - isSuccess = false; if ( !fileToDelete.isNull() ) { // cleanup (i.e. remove the file) init(); @@ -1120,7 +1113,7 @@ void tst_QFtp::renameCleanup( bool &isSuccess, const QString &host, const QStrin delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host) ); + QFAIL( msgTimedOut(host) ); ResMapIt it = resultMap.find( QFtp::Remove ); QVERIFY( it != resultMap.end() ); @@ -1128,7 +1121,6 @@ void tst_QFtp::renameCleanup( bool &isSuccess, const QString &host, const QStrin QVERIFY( !fileExists( host, 21, user, password, fileToDelete ) ); } - isSuccess = true; } void tst_QFtp::rename() @@ -1151,10 +1143,7 @@ void tst_QFtp::rename() if(renamedFile.contains('%')) renamedFile = renamedFile.arg(uniqueExtension); - bool isSuccess = true; - renameInit(isSuccess, host, user, password, createFile); - if (!isSuccess) - QSKIP("(QTBUG-75549) abort test when there is an error in helper functions"); + renameInit( host, user, password, createFile ); init(); ftp = newFtp(); @@ -1169,7 +1158,7 @@ void tst_QFtp::rename() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host) ); + QFAIL( msgTimedOut(host) ); ResMapIt it = resultMap.find( QFtp::Rename ); QVERIFY( it != resultMap.end() ); @@ -1184,9 +1173,7 @@ void tst_QFtp::rename() QVERIFY( !fileExists( host, 21, user, password, renamedFile ) ); } - renameCleanup(isSuccess, host, user, password, renamedFile); - if (!isSuccess) - QSKIP("(QTBUG-75549) abort test when there is an error in helper functions"); + renameCleanup( host, user, password, renamedFile ); } /* @@ -1360,7 +1347,7 @@ void tst_QFtp::commandSequence() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host) ); + QFAIL( msgTimedOut(host) ); QTEST( commandSequence_success, "success" ); } @@ -1415,7 +1402,7 @@ void tst_QFtp::abort() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host, port) ); + QFAIL( msgTimedOut(host, port) ); ResMapIt it = resultMap.find( cmd ); QVERIFY( it != resultMap.end() ); @@ -1453,7 +1440,7 @@ void tst_QFtp::abort() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(host, port) ); + QFAIL( msgTimedOut(host, port) ); it = resultMap.find( QFtp::Remove ); QVERIFY( it != resultMap.end() ); @@ -1491,11 +1478,8 @@ void tst_QFtp::bytesAvailable() addCommand( QFtp::Close, ftp->close() ); QTestEventLoop::instance().enterLoop( 40 ); - if ( QTestEventLoop::instance().timeout() ) { - delete ftp; - ftp = 0; - QSKIP( msgTimedOut(host) ); - } + if ( QTestEventLoop::instance().timeout() ) + QFAIL( msgTimedOut(host) ); ResMapIt it = resultMap.find( QFtp::Get ); QVERIFY( it != resultMap.end() ); @@ -1588,7 +1572,7 @@ void tst_QFtp::proxy() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) { - QSKIP( msgTimedOut(host, port) ); + QFAIL( msgTimedOut(host, port) ); } ResMapIt it = resultMap.find( QFtp::Cd ); @@ -1623,7 +1607,7 @@ void tst_QFtp::binaryAscii() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(QtNetworkSettings::ftpServerName()) ); + QFAIL( msgTimedOut(QtNetworkSettings::ftpServerName()) ); ResMapIt it = resultMap.find(QFtp::Put); QVERIFY(it != resultMap.end()); @@ -1645,7 +1629,7 @@ void tst_QFtp::binaryAscii() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(QtNetworkSettings::ftpServerName()) ); + QFAIL( msgTimedOut(QtNetworkSettings::ftpServerName()) ); ResMapIt it2 = resultMap.find(QFtp::Get); QVERIFY(it2 != resultMap.end()); @@ -1668,7 +1652,7 @@ void tst_QFtp::binaryAscii() delete ftp; ftp = 0; if ( QTestEventLoop::instance().timeout() ) - QSKIP( msgTimedOut(QtNetworkSettings::ftpServerName()) ); + QFAIL( msgTimedOut(QtNetworkSettings::ftpServerName()) ); it = resultMap.find( QFtp::Remove ); QVERIFY( it != resultMap.end() ); @@ -2100,7 +2084,7 @@ void tst_QFtp::doneSignal() connect(&ftp, SIGNAL(done(bool)), &(QTestEventLoop::instance()), SLOT(exitLoop())); QTestEventLoop::instance().enterLoop(61); if (QTestEventLoop::instance().timeout()) - QSKIP( msgTimedOut(QtNetworkSettings::ftpServerName()) ); + QFAIL("Network operation timed out"); QCOMPARE(spy.count(), 1); QCOMPARE(spy.first().first().toBool(), false); From e81ece3f8f4f930182f2b415e387691b7fa8c985 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 9 Jul 2019 10:01:01 +0200 Subject: [PATCH 047/264] QFileSystemModel: Improve class structure Use member initialization in private classes and repack members to minimize padding. Use delegating constructors and default constructors/destructors. Task-number: QTBUG-76493 Change-Id: Iaea8880811782ee5846c128590b83c23e6fae445 Reviewed-by: Volker Hilsheimer --- src/widgets/dialogs/qfileinfogatherer.cpp | 10 +---- src/widgets/dialogs/qfileinfogatherer_p.h | 8 ++-- src/widgets/dialogs/qfilesystemmodel.cpp | 13 +++--- src/widgets/dialogs/qfilesystemmodel_p.h | 55 +++++++++-------------- 4 files changed, 32 insertions(+), 54 deletions(-) diff --git a/src/widgets/dialogs/qfileinfogatherer.cpp b/src/widgets/dialogs/qfileinfogatherer.cpp index f39ae2b53e..9ab75e0b0a 100644 --- a/src/widgets/dialogs/qfileinfogatherer.cpp +++ b/src/widgets/dialogs/qfileinfogatherer.cpp @@ -79,14 +79,8 @@ static QString translateDriveName(const QFileInfo &drive) Creates thread */ QFileInfoGatherer::QFileInfoGatherer(QObject *parent) - : QThread(parent), abort(false), -#if QT_CONFIG(filesystemwatcher) - watcher(0), -#endif -#ifdef Q_OS_WIN - m_resolveSymlinks(true), -#endif - m_iconProvider(&defaultProvider) + : QThread(parent) + , m_iconProvider(&defaultProvider) { #if QT_CONFIG(filesystemwatcher) watcher = new QFileSystemWatcher(this); diff --git a/src/widgets/dialogs/qfileinfogatherer_p.h b/src/widgets/dialogs/qfileinfogatherer_p.h index 795f60249f..829c620c1e 100644 --- a/src/widgets/dialogs/qfileinfogatherer_p.h +++ b/src/widgets/dialogs/qfileinfogatherer_p.h @@ -210,13 +210,13 @@ private: QAtomicInt abort; #if QT_CONFIG(filesystemwatcher) - QFileSystemWatcher *watcher; -#endif -#ifdef Q_OS_WIN - bool m_resolveSymlinks; // not accessed by run() + QFileSystemWatcher *watcher = nullptr; #endif QFileIconProvider *m_iconProvider; // not accessed by run() QFileIconProvider defaultProvider; +#ifdef Q_OS_WIN + bool m_resolveSymlinks = true; // not accessed by run() +#endif }; QT_END_NAMESPACE diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index b521f50f40..820fc6e220 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -227,11 +227,9 @@ bool QFileSystemModel::remove(const QModelIndex &aindex) /*! Constructs a file system model with the given \a parent. */ -QFileSystemModel::QFileSystemModel(QObject *parent) - : QAbstractItemModel(*new QFileSystemModelPrivate, parent) +QFileSystemModel::QFileSystemModel(QObject *parent) : + QFileSystemModel(*new QFileSystemModelPrivate, parent) { - Q_D(QFileSystemModel); - d->init(); } /*! @@ -247,9 +245,7 @@ QFileSystemModel::QFileSystemModel(QFileSystemModelPrivate &dd, QObject *parent) /*! Destroys this file system model. */ -QFileSystemModel::~QFileSystemModel() -{ -} +QFileSystemModel::~QFileSystemModel() = default; /*! \reimp @@ -1945,6 +1941,9 @@ QStringList QFileSystemModelPrivate::unwatchPathsAt(const QModelIndex &index) void QFileSystemModelPrivate::init() { Q_Q(QFileSystemModel); + + delayedSortTimer.setSingleShot(true); + qRegisterMetaType > >(); #if QT_CONFIG(filesystemwatcher) q->connect(&fileInfoGatherer, SIGNAL(newListOfFiles(QString,QStringList)), diff --git a/src/widgets/dialogs/qfilesystemmodel_p.h b/src/widgets/dialogs/qfilesystemmodel_p.h index d8f9f2b076..844e417e2d 100644 --- a/src/widgets/dialogs/qfilesystemmodel_p.h +++ b/src/widgets/dialogs/qfilesystemmodel_p.h @@ -99,13 +99,13 @@ public: class QFileSystemNode { public: + Q_DISABLE_COPY_MOVE(QFileSystemNode) + explicit QFileSystemNode(const QString &filename = QString(), QFileSystemNode *p = nullptr) - : fileName(filename), populatedChildren(false), isVisible(false), dirtyChildrenIndex(-1), parent(p), info(nullptr) {} + : fileName(filename), parent(p) {} ~QFileSystemNode() { qDeleteAll(children); delete info; - info = nullptr; - parent = nullptr; } QString fileName; @@ -204,31 +204,16 @@ public: } } - bool populatedChildren; - bool isVisible; QHash children; QList visibleChildren; - int dirtyChildrenIndex; + QExtendedInformation *info = nullptr; QFileSystemNode *parent; - - - QExtendedInformation *info; - + int dirtyChildrenIndex = -1; + bool populatedChildren = false; + bool isVisible = false; }; - QFileSystemModelPrivate() : - forceSort(true), - sortColumn(0), - sortOrder(Qt::AscendingOrder), - readOnly(true), - setRootPath(false), - filters(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs), - nameFilterDisables(true), // false on windows, true on mac and unix - disableRecursiveSort(false) - { - delayedSortTimer.setSingleShot(true); - } - + QFileSystemModelPrivate() = default; void init(); /* \internal @@ -303,18 +288,7 @@ public: QFileInfoGatherer fileInfoGatherer; #endif // filesystemwatcher QTimer delayedSortTimer; - bool forceSort; - int sortColumn; - Qt::SortOrder sortOrder; - bool readOnly; - bool setRootPath; - QDir::Filters filters; QHash bypassFilters; - bool nameFilterDisables; - //This flag is an optimization for the QFileDialog - //It enable a sort which is not recursive, it means - //we sort only what we see. - bool disableRecursiveSort; #if QT_CONFIG(regularexpression) QStringList nameFilters; #endif @@ -322,7 +296,6 @@ public: QFileSystemNode root; - QBasicTimer fetchingTimer; struct Fetching { QString dir; QString file; @@ -330,6 +303,18 @@ public: }; QVector toFetch; + QBasicTimer fetchingTimer; + + QDir::Filters filters = QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs; + int sortColumn = 0; + Qt::SortOrder sortOrder = Qt::AscendingOrder; + bool forceSort = true; + bool readOnly = true; + bool setRootPath = false; + bool nameFilterDisables = true; // false on windows, true on mac and unix + // This flag is an optimization for QFileDialog. It enables a sort which is + // not recursive, meaning we sort only what we see. + bool disableRecursiveSort = false; }; Q_DECLARE_TYPEINFO(QFileSystemModelPrivate::Fetching, Q_MOVABLE_TYPE); From 9c8d1ca18b48dbcc89dda1b9bacdf7d49c7fc754 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 29 May 2019 13:18:14 +0200 Subject: [PATCH 048/264] QTestlib: Check compared images for device pixel ratio When accidentally running a test doing screen-grabbing with High DPI scaling active, sizes of the obtained pixmaps can differ due to the device pixel ratio. Add a check to make that clearer. [ChangeLog][QtTestLib] Comparison of QImage, QPixmap now checks for the device pixel ratio. Change-Id: Id8d5187e99c565c44a7bfb8b9cfb09737815fb15 Reviewed-by: Edward Welbourne --- src/testlib/qtest_gui.h | 16 ++ .../testlib/selftests/cmptest/tst_cmptest.cpp | 6 + .../selftests/expected_cmptest.lightxml | 12 ++ .../testlib/selftests/expected_cmptest.tap | 174 ++++++++++-------- .../selftests/expected_cmptest.teamcity | 6 + .../testlib/selftests/expected_cmptest.txt | 10 +- .../testlib/selftests/expected_cmptest.xml | 12 ++ .../selftests/expected_cmptest.xunitxml | 8 +- 8 files changed, 167 insertions(+), 77 deletions(-) diff --git a/src/testlib/qtest_gui.h b/src/testlib/qtest_gui.h index e5101e6955..d1efde54b1 100644 --- a/src/testlib/qtest_gui.h +++ b/src/testlib/qtest_gui.h @@ -162,6 +162,14 @@ inline bool qCompare(QImage const &t1, QImage const &t2, } if (t1Null && t2Null) return compare_helper(true, nullptr, nullptr, nullptr, actual, expected, file, line); + if (!qFuzzyCompare(t1.devicePixelRatioF(), t2.devicePixelRatioF())) { + qsnprintf(msg, 1024, "Compared QImages differ in device pixel ratio.\n" + " Actual (%s): %g\n" + " Expected (%s): %g", + actual, t1.devicePixelRatioF(), + expected, t2.devicePixelRatioF()); + return compare_helper(false, msg, nullptr, nullptr, actual, expected, file, line); + } if (t1.width() != t2.width() || t1.height() != t2.height()) { qsnprintf(msg, 1024, "Compared QImages differ in size.\n" " Actual (%s): %dx%d\n" @@ -196,6 +204,14 @@ inline bool qCompare(QPixmap const &t1, QPixmap const &t2, const char *actual, c } if (t1Null && t2Null) return compare_helper(true, nullptr, nullptr, nullptr, actual, expected, file, line); + if (!qFuzzyCompare(t1.devicePixelRatioF(), t2.devicePixelRatioF())) { + qsnprintf(msg, 1024, "Compared QPixmaps differ in device pixel ratio.\n" + " Actual (%s): %g\n" + " Expected (%s): %g", + actual, t1.devicePixelRatioF(), + expected, t2.devicePixelRatioF()); + return compare_helper(false, msg, nullptr, nullptr, actual, expected, file, line); + } if (t1.width() != t2.width() || t1.height() != t2.height()) { qsnprintf(msg, 1024, "Compared QPixmaps differ in size.\n" " Actual (%s): %dx%d\n" diff --git a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp index 467c53088e..fb01b19d16 100644 --- a/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp +++ b/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp @@ -466,6 +466,8 @@ void tst_Cmptest::compareQPixmaps_data() const QPixmap pixmap1(xpmPixmapData1); const QPixmap pixmap2(xpmPixmapData2); const QPixmap pixmap3(xpmPixmapData3); + QPixmap pixmapWrongDpr = pixmap1.scaled(2, 2); + pixmapWrongDpr.setDevicePixelRatio(2); QTest::newRow("both null") << QPixmap() << QPixmap(); QTest::newRow("one null") << QPixmap() << pixmap1; @@ -473,6 +475,7 @@ void tst_Cmptest::compareQPixmaps_data() QTest::newRow("equal") << pixmap1 << pixmap1; QTest::newRow("different size") << pixmap1 << pixmap3; QTest::newRow("different pixels") << pixmap1 << pixmap2; + QTest::newRow("different dpr") << pixmap1 << pixmapWrongDpr; } void tst_Cmptest::compareQPixmaps() @@ -492,6 +495,8 @@ void tst_Cmptest::compareQImages_data() const QImage image2(QPixmap(xpmPixmapData2).toImage()); const QImage image1Indexed = image1.convertToFormat(QImage::Format_Indexed8); const QImage image3(QPixmap(xpmPixmapData3).toImage()); + QImage imageWrongDpr = image1.scaled(2, 2); + imageWrongDpr.setDevicePixelRatio(2); QTest::newRow("both null") << QImage() << QImage(); QTest::newRow("one null") << QImage() << image1; @@ -500,6 +505,7 @@ void tst_Cmptest::compareQImages_data() QTest::newRow("different size") << image1 << image3; QTest::newRow("different format") << image1 << image1Indexed; QTest::newRow("different pixels") << image1 << image2; + QTest::newRow("different dpr") << image1 << imageWrongDpr; } void tst_Cmptest::compareQImages() diff --git a/tests/auto/testlib/selftests/expected_cmptest.lightxml b/tests/auto/testlib/selftests/expected_cmptest.lightxml index 58b5a5e530..f108933585 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.lightxml +++ b/tests/auto/testlib/selftests/expected_cmptest.lightxml @@ -208,6 +208,12 @@ + + + + @@ -245,6 +251,12 @@ + + + + diff --git a/tests/auto/testlib/selftests/expected_cmptest.tap b/tests/auto/testlib/selftests/expected_cmptest.tap index 238db2fc2b..dc9cb5c950 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.tap +++ b/tests/auto/testlib/selftests/expected_cmptest.tap @@ -245,9 +245,9 @@ not ok 32 - compareQPixmaps(one null) found: 1 (opA).isNull() expected: 0 (opB).isNull() actual: 1 (opA).isNull() - at: tst_Cmptest::compareQPixmaps() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:483) + at: tst_Cmptest::compareQPixmaps() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:486) file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp - line: 483 + line: 486 ... not ok 33 - compareQPixmaps(other null) --- @@ -257,9 +257,9 @@ not ok 33 - compareQPixmaps(other null) found: 0 (opA).isNull() expected: 1 (opB).isNull() actual: 0 (opA).isNull() - at: tst_Cmptest::compareQPixmaps() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:483) + at: tst_Cmptest::compareQPixmaps() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:486) file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp - line: 483 + line: 486 ... ok 34 - compareQPixmaps(equal) not ok 35 - compareQPixmaps(different size) @@ -270,19 +270,31 @@ not ok 35 - compareQPixmaps(different size) found: 11x20 (opA) expected: 20x20 (opB) actual: 11x20 (opA) - at: tst_Cmptest::compareQPixmaps() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:483) + at: tst_Cmptest::compareQPixmaps() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:486) file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp - line: 483 + line: 486 ... not ok 36 - compareQPixmaps(different pixels) --- # Compared values are not the same - at: tst_Cmptest::compareQPixmaps() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:483) + at: tst_Cmptest::compareQPixmaps() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:486) file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp - line: 483 + line: 486 ... -ok 37 - compareQImages(both null) -not ok 38 - compareQImages(one null) +not ok 37 - compareQPixmaps(different dpr) + --- + type: QCOMPARE + message: Compared QPixmaps differ in device pixel ratio. + wanted: 2 (opB) + found: 1 (opA) + expected: 2 (opB) + actual: 1 (opA) + at: tst_Cmptest::compareQPixmaps() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:486) + file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp + line: 486 + ... +ok 38 - compareQImages(both null) +not ok 39 - compareQImages(one null) --- type: QCOMPARE message: Compared QImages differ. @@ -290,11 +302,11 @@ not ok 38 - compareQImages(one null) found: 1 (opA).isNull() expected: 0 (opB).isNull() actual: 1 (opA).isNull() - at: tst_Cmptest::compareQImages() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:510) + at: tst_Cmptest::compareQImages() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:516) file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp - line: 510 + line: 516 ... -not ok 39 - compareQImages(other null) +not ok 40 - compareQImages(other null) --- type: QCOMPARE message: Compared QImages differ. @@ -302,12 +314,12 @@ not ok 39 - compareQImages(other null) found: 0 (opA).isNull() expected: 1 (opB).isNull() actual: 0 (opA).isNull() - at: tst_Cmptest::compareQImages() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:510) + at: tst_Cmptest::compareQImages() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:516) file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp - line: 510 + line: 516 ... -ok 40 - compareQImages(equal) -not ok 41 - compareQImages(different size) +ok 41 - compareQImages(equal) +not ok 42 - compareQImages(different size) --- type: QCOMPARE message: Compared QImages differ in size. @@ -315,11 +327,11 @@ not ok 41 - compareQImages(different size) found: 11x20 (opA) expected: 20x20 (opB) actual: 11x20 (opA) - at: tst_Cmptest::compareQImages() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:510) + at: tst_Cmptest::compareQImages() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:516) file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp - line: 510 + line: 516 ... -not ok 42 - compareQImages(different format) +not ok 43 - compareQImages(different format) --- type: QCOMPARE message: Compared QImages differ in format. @@ -327,19 +339,31 @@ not ok 42 - compareQImages(different format) found: 6 (opA) expected: 3 (opB) actual: 6 (opA) - at: tst_Cmptest::compareQImages() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:510) + at: tst_Cmptest::compareQImages() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:516) file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp - line: 510 + line: 516 ... -not ok 43 - compareQImages(different pixels) +not ok 44 - compareQImages(different pixels) --- # Compared values are not the same - at: tst_Cmptest::compareQImages() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:510) + at: tst_Cmptest::compareQImages() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:516) file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp - line: 510 + line: 516 ... -ok 44 - compareQRegion(equal-empty) -not ok 45 - compareQRegion(1-empty) +not ok 45 - compareQImages(different dpr) + --- + type: QCOMPARE + message: Compared QImages differ in device pixel ratio. + wanted: 2 (opB) + found: 1 (opA) + expected: 2 (opB) + actual: 1 (opA) + at: tst_Cmptest::compareQImages() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:516) + file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp + line: 516 + ... +ok 46 - compareQRegion(equal-empty) +not ok 47 - compareQRegion(1-empty) --- type: QCOMPARE message: Compared values are not the same @@ -347,12 +371,12 @@ not ok 45 - compareQRegion(1-empty) found: QRegion(200x50+10+10) (rA) expected: QRegion(null) (rB) actual: QRegion(200x50+10+10) (rA) - at: tst_Cmptest::compareQRegion() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:533) + at: tst_Cmptest::compareQRegion() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:539) file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp - line: 533 + line: 539 ... -ok 46 - compareQRegion(equal) -not ok 47 - compareQRegion(different lists) +ok 48 - compareQRegion(equal) +not ok 49 - compareQRegion(different lists) --- type: QCOMPARE message: Compared values are not the same @@ -360,11 +384,11 @@ not ok 47 - compareQRegion(different lists) found: QRegion(200x50+10+10) (rA) expected: QRegion(2 rectangles, 50x200+100+200, 200x50+10+10) (rB) actual: QRegion(200x50+10+10) (rA) - at: tst_Cmptest::compareQRegion() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:533) + at: tst_Cmptest::compareQRegion() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:539) file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp - line: 533 + line: 539 ... -not ok 48 - compareQVector2D() +not ok 50 - compareQVector2D() --- type: QCOMPARE message: Compared values are not the same @@ -372,11 +396,11 @@ not ok 48 - compareQVector2D() found: QVector2D(1, 2) (v2a) expected: QVector2D(1, 3) (v2b) actual: QVector2D(1, 2) (v2a) - at: tst_Cmptest::compareQVector2D() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:542) + at: tst_Cmptest::compareQVector2D() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:548) file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp - line: 542 + line: 548 ... -not ok 49 - compareQVector3D() +not ok 51 - compareQVector3D() --- type: QCOMPARE message: Compared values are not the same @@ -384,11 +408,11 @@ not ok 49 - compareQVector3D() found: QVector3D(1, 2, 3) (v3a) expected: QVector3D(1, 3, 3) (v3b) actual: QVector3D(1, 2, 3) (v3a) - at: tst_Cmptest::compareQVector3D() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:551) + at: tst_Cmptest::compareQVector3D() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:557) file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp - line: 551 + line: 557 ... -not ok 50 - compareQVector4D() +not ok 52 - compareQVector4D() --- type: QCOMPARE message: Compared values are not the same @@ -396,11 +420,11 @@ not ok 50 - compareQVector4D() found: QVector4D(1, 2, 3, 4) (v4a) expected: QVector4D(1, 3, 3, 4) (v4b) actual: QVector4D(1, 2, 3, 4) (v4a) - at: tst_Cmptest::compareQVector4D() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:560) + at: tst_Cmptest::compareQVector4D() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:566) file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp - line: 560 + line: 566 ... -not ok 51 - verify() +not ok 53 - verify() --- type: QVERIFY message: Verification failed @@ -408,35 +432,11 @@ not ok 51 - verify() found: false (opaqueFunc() < 2) expected: true (opaqueFunc() < 2) actual: false (opaqueFunc() < 2) - at: tst_Cmptest::verify() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:572) - file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp - line: 572 - ... -not ok 52 - verify2() - --- - type: QVERIFY - message: 42 - wanted: true (opaqueFunc() < 2) - found: false (opaqueFunc() < 2) - expected: true (opaqueFunc() < 2) - actual: false (opaqueFunc() < 2) - at: tst_Cmptest::verify2() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:578) + at: tst_Cmptest::verify() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:578) file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp line: 578 ... -not ok 53 - tryVerify() - --- - type: QVERIFY - message: Verification failed - wanted: true (opaqueFunc() < 2) - found: false (opaqueFunc() < 2) - expected: true (opaqueFunc() < 2) - actual: false (opaqueFunc() < 2) - at: tst_Cmptest::tryVerify() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:584) - file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp - line: 584 - ... -not ok 54 - tryVerify2() +not ok 54 - verify2() --- type: QVERIFY message: 42 @@ -444,13 +444,37 @@ not ok 54 - tryVerify2() found: false (opaqueFunc() < 2) expected: true (opaqueFunc() < 2) actual: false (opaqueFunc() < 2) - at: tst_Cmptest::tryVerify2() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:590) + at: tst_Cmptest::verify2() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:584) + file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp + line: 584 + ... +not ok 55 - tryVerify() + --- + type: QVERIFY + message: Verification failed + wanted: true (opaqueFunc() < 2) + found: false (opaqueFunc() < 2) + expected: true (opaqueFunc() < 2) + actual: false (opaqueFunc() < 2) + at: tst_Cmptest::tryVerify() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:590) file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp line: 590 ... -ok 55 - verifyExplicitOperatorBool() -ok 56 - cleanupTestCase() -1..56 -# tests 56 +not ok 56 - tryVerify2() + --- + type: QVERIFY + message: 42 + wanted: true (opaqueFunc() < 2) + found: false (opaqueFunc() < 2) + expected: true (opaqueFunc() < 2) + actual: false (opaqueFunc() < 2) + at: tst_Cmptest::tryVerify2() (qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp:596) + file: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp + line: 596 + ... +ok 57 - verifyExplicitOperatorBool() +ok 58 - cleanupTestCase() +1..58 +# tests 58 # pass 18 -# fail 38 +# fail 40 diff --git a/tests/auto/testlib/selftests/expected_cmptest.teamcity b/tests/auto/testlib/selftests/expected_cmptest.teamcity index 422d0cbfdf..426fddb20f 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.teamcity +++ b/tests/auto/testlib/selftests/expected_cmptest.teamcity @@ -95,6 +95,9 @@ ##teamcity[testStarted name='compareQPixmaps(different pixels)' flowId='tst_Cmptest'] ##teamcity[testFailed name='compareQPixmaps(different pixels)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQPixmaps(different pixels)' flowId='tst_Cmptest'] +##teamcity[testStarted name='compareQPixmaps(different dpr)' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQPixmaps(different dpr)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared QPixmaps differ in device pixel ratio.|n Actual (opA): 1|n Expected (opB): 2' flowId='tst_Cmptest'] +##teamcity[testFinished name='compareQPixmaps(different dpr)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQImages(both null)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQImages(both null)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQImages(one null)' flowId='tst_Cmptest'] @@ -114,6 +117,9 @@ ##teamcity[testStarted name='compareQImages(different pixels)' flowId='tst_Cmptest'] ##teamcity[testFailed name='compareQImages(different pixels)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared values are not the same' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQImages(different pixels)' flowId='tst_Cmptest'] +##teamcity[testStarted name='compareQImages(different dpr)' flowId='tst_Cmptest'] +##teamcity[testFailed name='compareQImages(different dpr)' message='Failure! |[Loc: qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)|]' details='Compared QImages differ in device pixel ratio.|n Actual (opA): 1|n Expected (opB): 2' flowId='tst_Cmptest'] +##teamcity[testFinished name='compareQImages(different dpr)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQRegion(equal-empty)' flowId='tst_Cmptest'] ##teamcity[testFinished name='compareQRegion(equal-empty)' flowId='tst_Cmptest'] ##teamcity[testStarted name='compareQRegion(1-empty)' flowId='tst_Cmptest'] diff --git a/tests/auto/testlib/selftests/expected_cmptest.txt b/tests/auto/testlib/selftests/expected_cmptest.txt index e1aa81c1a1..08877ef74d 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.txt +++ b/tests/auto/testlib/selftests/expected_cmptest.txt @@ -104,6 +104,10 @@ FAIL! : tst_Cmptest::compareQPixmaps(different size) Compared QPixmaps differ i Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compareQPixmaps(different pixels) Compared values are not the same Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] +FAIL! : tst_Cmptest::compareQPixmaps(different dpr) Compared QPixmaps differ in device pixel ratio. + Actual (opA): 1 + Expected (opB): 2 + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] PASS : tst_Cmptest::compareQImages(both null) FAIL! : tst_Cmptest::compareQImages(one null) Compared QImages differ. Actual (opA).isNull(): 1 @@ -124,6 +128,10 @@ FAIL! : tst_Cmptest::compareQImages(different format) Compared QImages differ i Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] FAIL! : tst_Cmptest::compareQImages(different pixels) Compared values are not the same Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] +FAIL! : tst_Cmptest::compareQImages(different dpr) Compared QImages differ in device pixel ratio. + Actual (opA): 1 + Expected (opB): 2 + Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] PASS : tst_Cmptest::compareQRegion(equal-empty) FAIL! : tst_Cmptest::compareQRegion(1-empty) Compared values are not the same Actual (rA): QRegion(200x50+10+10) @@ -156,5 +164,5 @@ FAIL! : tst_Cmptest::tryVerify2() 'opaqueFunc() < 2' returned FALSE. (42) Loc: [qtbase/tests/auto/testlib/selftests/cmptest/tst_cmptest.cpp(0)] PASS : tst_Cmptest::verifyExplicitOperatorBool() PASS : tst_Cmptest::cleanupTestCase() -Totals: 18 passed, 38 failed, 0 skipped, 0 blacklisted, 0ms +Totals: 18 passed, 40 failed, 0 skipped, 0 blacklisted, 0ms ********* Finished testing of tst_Cmptest ********* diff --git a/tests/auto/testlib/selftests/expected_cmptest.xml b/tests/auto/testlib/selftests/expected_cmptest.xml index 1c5a17631a..daf2560f1b 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.xml +++ b/tests/auto/testlib/selftests/expected_cmptest.xml @@ -210,6 +210,12 @@ + + + + @@ -247,6 +253,12 @@ + + + + diff --git a/tests/auto/testlib/selftests/expected_cmptest.xunitxml b/tests/auto/testlib/selftests/expected_cmptest.xunitxml index 99823d1c1c..397db4c3e4 100644 --- a/tests/auto/testlib/selftests/expected_cmptest.xunitxml +++ b/tests/auto/testlib/selftests/expected_cmptest.xunitxml @@ -1,5 +1,5 @@ - + @@ -98,6 +98,9 @@ Actual (opA): 11x20 Expected (opB): 20x20" result="fail"/> + + #include +#include #include #include @@ -265,17 +266,54 @@ bool QTestResult::verify(bool statement, const char *statementStr, return checkStatement(statement, msg, file, line); } -bool QTestResult::compare(bool success, const char *failureMsg, - char *val1, char *val2, - const char *actual, const char *expected, - const char *file, int line) +// Format failures using the toString() template +template +void formatFailMessage(char *msg, size_t maxMsgLen, + const char *failureMsg, + const Actual &val1, const Expected &val2, + const char *actual, const char *expected) { - QTEST_ASSERT(expected); - QTEST_ASSERT(actual); + auto val1S = QTest::toString(val1); + auto val2S = QTest::toString(val2); + size_t len1 = mbstowcs(nullptr, actual, maxMsgLen); // Last parameter is not ignored on QNX + size_t len2 = mbstowcs(nullptr, expected, maxMsgLen); // (result is never larger than this). + qsnprintf(msg, maxMsgLen, "%s\n Actual (%s)%*s %s\n Expected (%s)%*s %s", + failureMsg, + actual, qMax(len1, len2) - len1 + 1, ":", val1S ? val1S : "", + expected, qMax(len1, len2) - len2 + 1, ":", val2S ? val2S : ""); + + delete [] val1S; + delete [] val2S; +} + +// Overload to format failures for "const char *" - no need to strdup(). +void formatFailMessage(char *msg, size_t maxMsgLen, + const char *failureMsg, + const char *val1, const char *val2, + const char *actual, const char *expected) +{ + size_t len1 = mbstowcs(nullptr, actual, maxMsgLen); // Last parameter is not ignored on QNX + size_t len2 = mbstowcs(nullptr, expected, maxMsgLen); // (result is never larger than this). + qsnprintf(msg, maxMsgLen, "%s\n Actual (%s)%*s %s\n Expected (%s)%*s %s", + failureMsg, + actual, qMax(len1, len2) - len1 + 1, ":", val1 ? val1 : "", + expected, qMax(len1, len2) - len2 + 1, ":", val2 ? val2 : ""); +} + +template +static bool compareHelper(bool success, const char *failureMsg, + const Actual &val1, const Expected &val2, + const char *actual, const char *expected, + const char *file, int line, + bool hasValues = true) +{ const size_t maxMsgLen = 1024; char msg[maxMsgLen] = {'\0'}; + QTEST_ASSERT(expected); + QTEST_ASSERT(actual); + if (QTestLog::verboseLevel() >= 2) { qsnprintf(msg, maxMsgLen, "QCOMPARE(%s, %s)", actual, expected); QTestLog::info(msg, file, line); @@ -289,20 +327,68 @@ bool QTestResult::compare(bool success, const char *failureMsg, qsnprintf(msg, maxMsgLen, "QCOMPARE(%s, %s) returned TRUE unexpectedly.", actual, expected); } - } else if (val1 || val2) { - size_t len1 = mbstowcs(NULL, actual, maxMsgLen); // Last parameter is not ignored on QNX - size_t len2 = mbstowcs(NULL, expected, maxMsgLen); // (result is never larger than this). - qsnprintf(msg, maxMsgLen, "%s\n Actual (%s)%*s %s\n Expected (%s)%*s %s", - failureMsg, - actual, qMax(len1, len2) - len1 + 1, ":", val1 ? val1 : "", - expected, qMax(len1, len2) - len2 + 1, ":", val2 ? val2 : ""); - } else - qsnprintf(msg, maxMsgLen, "%s", failureMsg); + return checkStatement(success, msg, file, line); + } + + if (!hasValues) { + qsnprintf(msg, maxMsgLen, "%s", failureMsg); + return checkStatement(success, msg, file, line); + } + + formatFailMessage(msg, maxMsgLen, failureMsg, val1, val2, actual, expected); + + return checkStatement(success, msg, file, line); +} + +bool QTestResult::compare(bool success, const char *failureMsg, + char *val1, char *val2, + const char *actual, const char *expected, + const char *file, int line) +{ + const bool result = compareHelper(success, failureMsg, + val1 != nullptr ? val1 : "", + val2 != nullptr ? val2 : "", + actual, expected, file, line, + val1 != nullptr && val2 != nullptr); + + // Our caller got these from QTest::toString() delete [] val1; delete [] val2; - return checkStatement(success, msg, file, line); + return result; +} + +bool QTestResult::compare(bool success, const char *failureMsg, + double val1, double val2, + const char *actual, const char *expected, + const char *file, int line) +{ + return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line); +} + +bool QTestResult::compare(bool success, const char *failureMsg, + float val1, float val2, + const char *actual, const char *expected, + const char *file, int line) +{ + return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line); +} + +bool QTestResult::compare(bool success, const char *failureMsg, + int val1, int val2, + const char *actual, const char *expected, + const char *file, int line) +{ + return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line); +} + +bool QTestResult::compare(bool success, const char *failureMsg, + unsigned val1, unsigned val2, + const char *actual, const char *expected, + const char *file, int line) +{ + return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line); } void QTestResult::addFailure(const char *message, const char *file, int line) diff --git a/src/testlib/qtestresult_p.h b/src/testlib/qtestresult_p.h index 4df75b2805..92f98bb047 100644 --- a/src/testlib/qtestresult_p.h +++ b/src/testlib/qtestresult_p.h @@ -79,7 +79,22 @@ public: char *val1, char *val2, const char *actual, const char *expected, const char *file, int line); - + static bool compare(bool success, const char *failureMsg, + double val1, double val2, + const char *actual, const char *expected, + const char *file, int line); + static bool compare(bool success, const char *failureMsg, + float val1, float val2, + const char *actual, const char *expected, + const char *file, int line); + static bool compare(bool success, const char *failureMsg, + int val1, int val2, + const char *actual, const char *expected, + const char *file, int line); + static bool compare(bool success, const char *failureMsg, + unsigned val1, unsigned val2, + const char *actual, const char *expected, + const char *file, int line); static void setCurrentGlobalTestData(QTestData *data); static void setCurrentTestData(QTestData *data); static void setCurrentTestFunction(const char *func); From d9fb502b20129ef975cc6e20df306dcd84c64142 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 9 Jul 2019 14:59:00 +0200 Subject: [PATCH 050/264] Fix android architecture detection Android is also unix, so can pick up the host 'arch' binary when rerunning configure. This patch splits the names so we don't end up confusing target and host binaries. Task-number: QTBUG-76445 Change-Id: Ib65251a514e45ad8873f523d71c17e13e56ea58a Reviewed-by: Simon Hausmann --- config.tests/arch/arch.pro | 1 - config.tests/arch/arch_host.pro | 2 +- configure.json | 2 ++ configure.pri | 17 +++++++++-------- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/config.tests/arch/arch.pro b/config.tests/arch/arch.pro index 2ffdb2c889..45a7eb33af 100644 --- a/config.tests/arch/arch.pro +++ b/config.tests/arch/arch.pro @@ -1,2 +1 @@ -TARGET = arch SOURCES = arch.cpp diff --git a/config.tests/arch/arch_host.pro b/config.tests/arch/arch_host.pro index f7acef0c5d..cefdbc77ef 100644 --- a/config.tests/arch/arch_host.pro +++ b/config.tests/arch/arch_host.pro @@ -1,2 +1,2 @@ option(host_build) -include(arch.pro) +SOURCES = arch.cpp diff --git a/configure.json b/configure.json index 525cb5a12c..7279259484 100644 --- a/configure.json +++ b/configure.json @@ -233,12 +233,14 @@ "label": "target architecture", "type": "architecture", "test": "arch", + "output": "arch", "log": "arch" }, "host_architecture": { "label": "host architecture", "type": "architecture", "test": "arch", + "output": "arch_host", "host": true, "pro": "arch_host.pro", "log": "arch" diff --git a/configure.pri b/configure.pri index 131aa868c2..da5d22382d 100644 --- a/configure.pri +++ b/configure.pri @@ -267,15 +267,16 @@ defineTest(qtConfTest_architecture) { error("Could not determine $$eval($${1}.label). See config.log for details.") test = $$eval($${1}.test) + output = $$eval($${1}.output) test_out_dir = $$OUT_PWD/$$basename(QMAKE_CONFIG_TESTS_DIR)/$$test - unix:exists($$test_out_dir/arch): \ - content = $$cat($$test_out_dir/arch, blob) - else: win32:exists($$test_out_dir/arch.exe): \ - content = $$cat($$test_out_dir/arch.exe, blob) - else: android:exists($$test_out_dir/libarch.so): \ - content = $$cat($$test_out_dir/libarch.so, blob) - else: wasm:exists($$test_out_dir/arch.wasm): \ - content = $$cat($$test_out_dir/arch.wasm, blob) + unix:exists($$test_out_dir/$$output): \ + content = $$cat($$test_out_dir/$$output, blob) + else: win32:exists($$test_out_dir/$${output}.exe): \ + content = $$cat($$test_out_dir/$${output}.exe, blob) + else: android:exists($$test_out_dir/lib$${output}.so): \ + content = $$cat($$test_out_dir/lib$${output}.so, blob) + else: wasm:exists($$test_out_dir/$${output}.wasm): \ + content = $$cat($$test_out_dir/$${output}.wasm, blob) else: \ error("$$eval($${1}.label) detection binary not found.") From f4b5fa76d76a38c8cd97ac410981a2209d100180 Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Tue, 9 Jul 2019 22:11:47 +0800 Subject: [PATCH 051/264] [Doc] Fix minor typos Change-Id: I7e74806218dcc07d800f4ec08e94abce32483f5e Reviewed-by: Samuel Gaist --- src/corelib/plugin/qpluginloader.cpp | 2 +- src/corelib/serialization/qcborarray.cpp | 6 +++--- src/corelib/serialization/qjsonarray.cpp | 2 +- src/corelib/serialization/qjsoncbor.cpp | 2 +- src/corelib/tools/qalgorithms.qdoc | 4 ++-- src/corelib/tools/qstring.cpp | 4 ++-- src/gui/painting/qpagedpaintdevice.cpp | 2 +- src/widgets/dialogs/qfontdialog.cpp | 2 +- src/widgets/doc/src/widgets-and-layouts/layout.qdoc | 2 +- src/widgets/graphicsview/qgraphicsscene.cpp | 2 +- src/widgets/widgets/qcombobox.cpp | 2 +- src/widgets/widgets/qcommandlinkbutton.cpp | 2 +- 12 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp index 00480198bd..4e0c3a511b 100644 --- a/src/corelib/plugin/qpluginloader.cpp +++ b/src/corelib/plugin/qpluginloader.cpp @@ -92,7 +92,7 @@ QT_BEGIN_NAMESPACE but if other instances of QPluginLoader are using the same library, the call will fail, and unloading will only happen when every instance has called unload(). Right before the unloading - happen, the root component will also be deleted. + happens, the root component will also be deleted. See \l{How to Create Qt Plugins} for more information about how to make your application extensible through plugins. diff --git a/src/corelib/serialization/qcborarray.cpp b/src/corelib/serialization/qcborarray.cpp index 28ae40f3df..ca0156e07d 100644 --- a/src/corelib/serialization/qcborarray.cpp +++ b/src/corelib/serialization/qcborarray.cpp @@ -273,7 +273,7 @@ QCborValue QCborArray::at(qsizetype i) const not be empty. QCborValueRef has the exact same API as \l QCborValue, with one important - difference: if you assign new values to it, this map will be updated with + difference: if you assign new values to it, this array will be updated with that new value. \sa operator[](), at(), last(), insert(), prepend(), append(), @@ -287,7 +287,7 @@ QCborValue QCborArray::at(qsizetype i) const not be empty. QCborValueRef has the exact same API as \l QCborValue, with one important - difference: if you assign new values to it, this map will be updated with + difference: if you assign new values to it, this array will be updated with that new value. \sa operator[](), at(), first(), insert(), prepend(), append(), @@ -302,7 +302,7 @@ QCborValue QCborArray::at(qsizetype i) const with undefined entries, until it has an entry at the specified index. QCborValueRef has the exact same API as \l QCborValue, with one important - difference: if you assign new values to it, this map will be updated with + difference: if you assign new values to it, this array will be updated with that new value. \sa at(), first(), last(), insert(), prepend(), append(), diff --git a/src/corelib/serialization/qjsonarray.cpp b/src/corelib/serialization/qjsonarray.cpp index 7dfa9b43f0..f5f02b886a 100644 --- a/src/corelib/serialization/qjsonarray.cpp +++ b/src/corelib/serialization/qjsonarray.cpp @@ -845,7 +845,7 @@ bool QJsonArray::operator!=(const QJsonArray &other) const The return value is of type QJsonValueRef, a helper class for QJsonArray and QJsonObject. When you get an object of type QJsonValueRef, you can use it as if it were a reference to a QJsonValue. If you assign to it, - the assignment will apply to the character in the QJsonArray of QJsonObject + the assignment will apply to the element in the QJsonArray or QJsonObject from which you got the reference. \sa operator+() diff --git a/src/corelib/serialization/qjsoncbor.cpp b/src/corelib/serialization/qjsoncbor.cpp index e0c390f610..d6a0c8c48a 100644 --- a/src/corelib/serialization/qjsoncbor.cpp +++ b/src/corelib/serialization/qjsoncbor.cpp @@ -421,7 +421,7 @@ QJsonArray QCborArray::toJsonArray() const } /*! - Recursively converts every \l QCborValue value in this array to JSON using + Recursively converts every \l QCborValue value in this map to JSON using QCborValue::toJsonValue() and creates a string key for all keys that aren't strings, then returns the corresponding QJsonObject composed of those associations. diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc index a73ec1e22a..c86e69f9c3 100644 --- a/src/corelib/tools/qalgorithms.qdoc +++ b/src/corelib/tools/qalgorithms.qdoc @@ -155,8 +155,8 @@ \section2 Porting guidelines - Most of the times, an application using the deprecated Qt algorithmic functions - can be easily ported to use the equivalent STL functions. You need to + Most of the time, an application using the deprecated Qt algorithmic functions + can be easily ported to use the equivalent STL functions. You need to: \list 1 \li add the \c{#include } preprocessor directive; diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index a0e33d4e45..b3ea553b51 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -2130,7 +2130,7 @@ int QString::toUcs4_helper(const ushort *uc, int length, uint *out) If \a size is negative, \a unicode is assumed to point to a \\0'-terminated array and its length is determined dynamically. The terminating - nul-character is not considered part of the string. + null character is not considered part of the string. QString makes a deep copy of the string data. The unicode data is copied as is and the Byte Order Mark is preserved if present. @@ -5884,7 +5884,7 @@ QString QString::trimmed_helper(QString &str) The return value is of type QCharRef, a helper class for QString. When you get an object of type QCharRef, you can use it as if it - were a QChar &. If you assign to it, the assignment will apply to + were a reference to a QChar. If you assign to it, the assignment will apply to the character in the QString from which you got the reference. \sa at() diff --git a/src/gui/painting/qpagedpaintdevice.cpp b/src/gui/painting/qpagedpaintdevice.cpp index 72b2834470..0c2123f9a6 100644 --- a/src/gui/painting/qpagedpaintdevice.cpp +++ b/src/gui/painting/qpagedpaintdevice.cpp @@ -85,7 +85,7 @@ QPagedPaintDevicePrivate::~QPagedPaintDevicePrivate() \class QPagedPaintDevice \inmodule QtGui - \brief The QPagedPaintDevice class is a represents a paintdevice that supports + \brief The QPagedPaintDevice class represents a paint device that supports multiple pages. \ingroup painting diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp index 2b81180ecb..d53d57db86 100644 --- a/src/widgets/dialogs/qfontdialog.cpp +++ b/src/widgets/dialogs/qfontdialog.cpp @@ -163,7 +163,7 @@ QFontDialog::QFontDialog(QWidget *parent) \since 4.5 Constructs a standard font dialog with the given \a parent and specified - \a initial color. + \a initial font. */ QFontDialog::QFontDialog(const QFont &initial, QWidget *parent) : QFontDialog(parent) diff --git a/src/widgets/doc/src/widgets-and-layouts/layout.qdoc b/src/widgets/doc/src/widgets-and-layouts/layout.qdoc index e507d66451..65569a9cd2 100644 --- a/src/widgets/doc/src/widgets-and-layouts/layout.qdoc +++ b/src/widgets/doc/src/widgets-and-layouts/layout.qdoc @@ -220,7 +220,7 @@ When you make your own widget class, you should also communicate its layout properties. If the widget uses one of Qt's layouts, this is already taken - care of. If the widget does not have any child widgets, or uses manual + care of. If the widget does not have any child widgets, or uses a manual layout, you can change the behavior of the widget using any or all of the following mechanisms: diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp index 3897823e98..5238ea2f5c 100644 --- a/src/widgets/graphicsview/qgraphicsscene.cpp +++ b/src/widgets/graphicsview/qgraphicsscene.cpp @@ -2805,7 +2805,7 @@ QGraphicsPolygonItem *QGraphicsScene::addPolygon(const QPolygonF &polygon, Note that the item's geometry is provided in item coordinates, and its position is initialized to (0, 0). For example, if a QRect(50, 50, 100, 100) is added, its top-left corner will be at (50, 50) relative to the - origin in the items coordinate system. + origin in the item's coordinate system. If the item is visible (i.e., QGraphicsItem::isVisible() returns \c true), QGraphicsScene will emit changed() once control goes back to the event diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index a143b2e799..483cfd8c55 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -2611,7 +2611,7 @@ bool QComboBoxPrivate::showNativePopup() /*! Displays the list of items in the combobox. If the list is empty - then the no items will be shown. + then no items will be shown. If you reimplement this function to show a custom pop-up, make sure you call hidePopup() to reset the internal state. diff --git a/src/widgets/widgets/qcommandlinkbutton.cpp b/src/widgets/widgets/qcommandlinkbutton.cpp index 68dfefb3b7..2b9258fd91 100644 --- a/src/widgets/widgets/qcommandlinkbutton.cpp +++ b/src/widgets/widgets/qcommandlinkbutton.cpp @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE \ingroup basicwidgets \inmodule QtWidgets - The command link is a new control that was introduced by Windows Vista. It's + The command link is a new control that was introduced by Windows Vista. Its intended use is similar to that of a radio button in that it is used to choose between a set of mutually exclusive options. Command link buttons should not be used by themselves but rather as an alternative to radio buttons in From 59b29d03b2fff8a138382d45077c81fe0d4b8ea8 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 9 Jul 2019 15:18:46 +0200 Subject: [PATCH 052/264] Further stabilization of QGraphicsItem::cursor test The QTest::mouseMove calls are not reliable, and seem to produce flakiness, at least on WinRT. Removing them, and only depending on handling of the synchronously delivered QMouseEVent for simulated mouse moves. Also, initialize the expected cursor shape from an empty scene; this avoids that showing the view with the cursor accidentially on an item results in the wrong default shape. Remove hard coded coordinates, just test what we know. Fixes: QTBUG-73545 Change-Id: I6f81d6b16bb613ec77aaa776d6a80aac739aeb58 Reviewed-by: Volker Hilsheimer --- .../qgraphicsitem/tst_qgraphicsitem.cpp | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index 3260e09943..e071edc332 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -4153,6 +4153,8 @@ void tst_QGraphicsItem::cursor() QGraphicsView view(&scene); view.showFullScreen(); QVERIFY(QTest::qWaitForWindowExposed(&view)); + const Qt::CursorShape viewportShape = view.viewport()->cursor().shape(); + QGraphicsRectItem *item1 = scene.addRect(QRectF(-100, 0, 50, 50)); QGraphicsRectItem *item2 = scene.addRect(QRectF(50, 0, 50, 50)); @@ -4184,50 +4186,41 @@ void tst_QGraphicsItem::cursor() QPoint item1Center = view.mapFromScene(item1->sceneBoundingRect().center()); QPoint item2Center = view.mapFromScene(item2->sceneBoundingRect().center()); - QTest::mouseMove(&view, viewCenter); - - const Qt::CursorShape viewportShape = view.viewport()->cursor().shape(); - { - QTest::mouseMove(view.viewport(), QPoint(100, 50)); - QMouseEvent event(QEvent::MouseMove, QPoint(100, 50), view.viewport()->mapToGlobal(QPoint(100, 50)), Qt::NoButton, 0, 0); + QMouseEvent event(QEvent::MouseMove, viewCenter, view.viewport()->mapToGlobal(viewCenter), Qt::NoButton, 0, 0); QApplication::sendEvent(view.viewport(), &event); } - QTRY_COMPARE(view.viewport()->cursor().shape(), viewportShape); + QCOMPARE(view.viewport()->cursor().shape(), viewportShape); { - QTest::mouseMove(view.viewport(), item1Center); QMouseEvent event(QEvent::MouseMove, item1Center, view.viewport()->mapToGlobal(item1Center), Qt::NoButton, 0, 0); QApplication::sendEvent(view.viewport(), &event); } - QTRY_COMPARE(view.viewport()->cursor().shape(), item1->cursor().shape()); + QCOMPARE(view.viewport()->cursor().shape(), item1->cursor().shape()); { - QTest::mouseMove(view.viewport(), item2Center); QMouseEvent event(QEvent::MouseMove, item2Center, view.viewport()->mapToGlobal(item2Center), Qt::NoButton, 0, 0); QApplication::sendEvent(view.viewport(), &event); } - QTRY_COMPARE(view.viewport()->cursor().shape(), item2->cursor().shape()); + QCOMPARE(view.viewport()->cursor().shape(), item2->cursor().shape()); { - QTest::mouseMove(view.viewport(), viewCenter); - QMouseEvent event(QEvent::MouseMove, QPoint(100, 25), view.viewport()->mapToGlobal(QPoint(100, 50)), Qt::NoButton, 0, 0); + QMouseEvent event(QEvent::MouseMove, viewCenter, view.viewport()->mapToGlobal(viewCenter), Qt::NoButton, 0, 0); QApplication::sendEvent(view.viewport(), &event); } - QTRY_COMPARE(view.viewport()->cursor().shape(), viewportShape); + QCOMPARE(view.viewport()->cursor().shape(), viewportShape); item1->setEnabled(false); { - QTest::mouseMove(view.viewport(), item1Center); QMouseEvent event(QEvent::MouseMove, item1Center, view.viewport()->mapToGlobal(item1Center), Qt::NoButton, 0, 0); QApplication::sendEvent(view.viewport(), &event); } - QTRY_COMPARE(view.viewport()->cursor().shape(), viewportShape); + QCOMPARE(view.viewport()->cursor().shape(), viewportShape); } #endif /* From b426cff1e0363b350f98bc64691b9b279bc6c757 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 3 Jul 2019 16:25:54 +0200 Subject: [PATCH 053/264] Make tst_QGraphicsItem painting tests most robust Counting absolute paint events is fragile, as there are no guarantees that a single call to QApp::processEvents only delivers a single paint event to a widget. As of QTBUG-76566, we see that the items occasionally receive three calls to paint, which can be simulated by activating other windows while the test is running and waiting for events to be processed. Instead, verify that we do receive any paint events as the first test, and then verify increments when we expect updates. This also reverts change 24b9424adcda1ab083fae4ae857007227ba5fee2. Change-Id: Ib51853e918f31acd3aea10d4109c95f34012a29f Fixes: QTBUG-76566 Reviewed-by: Dimitrios Apostolou Reviewed-by: Andreas Aardal Hanssen --- .../qgraphicsitem/tst_qgraphicsitem.cpp | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index e071edc332..872e0b62c5 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -5057,12 +5057,6 @@ public: void tst_QGraphicsItem::paint() { -#if defined(Q_OS_MACOS) - if (QSysInfo::productVersion() == QLatin1String("10.12")) { - QSKIP("Test is very flaky on MacOS_10_12, see QTBUG-76566"); - } -#endif - QGraphicsScene scene; PaintTester paintTester; @@ -5092,22 +5086,25 @@ void tst_QGraphicsItem::paint() PaintTester tester2; scene2.addItem(&tester2); - //First show one paint - QTRY_COMPARE(tester2.painted, 1); + //First show at least one paint + QCOMPARE(tester2.painted, 0); + QTRY_VERIFY(tester2.painted > 0); + int painted = tester2.painted; //nominal case, update call paint tester2.update(); - QTRY_COMPARE(tester2.painted, 2); + QTRY_COMPARE(tester2.painted, painted + 1); + painted = tester2.painted; //we remove the item from the scene, number of updates is still the same tester2.update(); scene2.removeItem(&tester2); - QTRY_COMPARE(tester2.painted, 2); + QTRY_COMPARE(tester2.painted, painted); //We re-add the item, the number of paint should increase scene2.addItem(&tester2); tester2.update(); - QTRY_COMPARE(tester2.painted, 3); + QTRY_COMPARE(tester2.painted, painted + 1); } class HarakiriItem : public QGraphicsRectItem @@ -11377,7 +11374,7 @@ void tst_QGraphicsItem::QTBUG_7714_fullUpdateDiscardingOpacityUpdate2() origView.reset(); childYellow->setOpacity(0.0); - QTRY_COMPARE(origView.repaints, 1); + QTRY_VERIFY(origView.repaints > 0); view.show(); qApp->setActiveWindow(&view); @@ -11392,8 +11389,8 @@ void tst_QGraphicsItem::QTBUG_7714_fullUpdateDiscardingOpacityUpdate2() QEXPECT_FAIL("", "Fails on WinRT. Figure out why - QTBUG-68297", Abort); #endif - QTRY_COMPARE(origView.repaints, 1); - QTRY_COMPARE(view.repaints, 1); + QTRY_VERIFY(origView.repaints > 0); + QTRY_VERIFY(view.repaints > 0); } void tst_QGraphicsItem::QT_2649_focusScope() From 16158e1132da292df6f911df0671c7bf71d145d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 21 May 2019 14:48:57 +0200 Subject: [PATCH 054/264] Win: qdiriterator bench: fix missing null-terminator issues It's not done by toWCharArray. This caused some issues as we were using API requiring a null-terminator. wcslen for instance was measuring the string as being millions of characters long, causing fairly quick crashes when appending. Change-Id: Iedaaf9f195be22a610543ab649da92a87cb71973 Reviewed-by: Edward Welbourne --- .../corelib/io/qdiriterator/main.cpp | 24 +++++++++---------- .../io/qdiriterator/qfilesystemiterator.cpp | 5 ++-- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/tests/benchmarks/corelib/io/qdiriterator/main.cpp b/tests/benchmarks/corelib/io/qdiriterator/main.cpp index e71daccf7d..eae752d99a 100644 --- a/tests/benchmarks/corelib/io/qdiriterator/main.cpp +++ b/tests/benchmarks/corelib/io/qdiriterator/main.cpp @@ -78,24 +78,22 @@ void tst_qdiriterator::data() } #ifdef Q_OS_WIN -static int posix_helper(const wchar_t *dirpath) +static int posix_helper(const wchar_t *dirpath, size_t length) { int count = 0; HANDLE hSearch; WIN32_FIND_DATA fd; - const size_t origDirPathLength = wcslen(dirpath); - wchar_t appendedPath[MAX_PATH]; - wcscpy(appendedPath, dirpath); - wcscat(appendedPath, L"\\*"); + Q_ASSERT(MAX_PATH > length + 3); + wcsncpy(appendedPath, dirpath, length); + wcscpy(appendedPath + length, L"\\*"); #ifndef Q_OS_WINRT hSearch = FindFirstFile(appendedPath, &fd); #else hSearch = FindFirstFileEx(appendedPath, FindExInfoStandard, &fd, FindExSearchNameMatch, NULL, FIND_FIRST_EX_LARGE_FETCH); #endif - appendedPath[origDirPathLength] = 0; if (hSearch == INVALID_HANDLE_VALUE) { qWarning("FindFirstFile failed"); @@ -107,10 +105,12 @@ static int posix_helper(const wchar_t *dirpath) !(fd.cFileName[0] == L'.' && fd.cFileName[1] == L'.' && fd.cFileName[2] == 0)) { if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - wcscat(appendedPath, L"\\"); - wcscat(appendedPath, fd.cFileName); - count += posix_helper(appendedPath); - appendedPath[origDirPathLength] = 0; + // newLength will "point" to where we put a * earlier, so we overwrite that. + size_t newLength = length + 1; // "+ 1" for directory separator + Q_ASSERT(newLength + wcslen(fd.cFileName) + 1 < MAX_PATH); // "+ 1" for null-terminator + wcscpy(appendedPath + newLength, fd.cFileName); + newLength += wcslen(fd.cFileName); + count += posix_helper(appendedPath, newLength); } else { ++count; @@ -164,8 +164,8 @@ void tst_qdiriterator::posix() QBENCHMARK { #ifdef Q_OS_WIN wchar_t wPath[MAX_PATH]; - path.toWCharArray(wPath); - count = posix_helper(wPath); + const int end = path.toWCharArray(wPath); + count = posix_helper(wPath, end); #else count = posix_helper(dirpath.constData()); #endif diff --git a/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp index d68264b78f..6ee8b4e93b 100644 --- a/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp +++ b/tests/benchmarks/corelib/io/qdiriterator/qfilesystemiterator.cpp @@ -218,8 +218,9 @@ void QFileSystemIteratorPrivate::pushSubDirectory(const QByteArray &path) #ifdef Q_OS_WIN wchar_t szSearchPath[MAX_PATH]; - QString::fromLatin1(path).toWCharArray(szSearchPath); - wcscat(szSearchPath, L"\\*"); + const int end = QString::fromLatin1(path + "\\*").toWCharArray(szSearchPath); + Q_ASSERT(end < MAX_PATH); + szSearchPath[end] = L'\0'; #ifndef Q_OS_WINRT HANDLE dir = FindFirstFile(szSearchPath, &m_fileSearchResult); #else From 605062b21fccff919b7894db91b197d120e528f6 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 10 Jul 2019 08:16:56 +0200 Subject: [PATCH 055/264] Fix MinGW cross-build with precompiled headers on Linux We need localtime_r() in several places. To have this function declared when including time.h, _POSIX_THREAD_SAFE_FUNCTIONS must be defined. E.g. qdatetime.cpp includes unistd.h before time.h to define said macro. However, this falls apart when precompiled headers are used, because of the following include chain in qt_pch.h: qcoreapplication.h -> qobject.h -> chrono -> time.h This patch ensures that _POSIX_THREAD_SAFE_FUNCTIONS is defined before including time.h in qt_pch.h by including unistd.h early. Fixes: QTBUG-76680 Change-Id: I3875072edf37f45492f29d84fc297a9682e11db4 Reviewed-by: Oliver Wolff Reviewed-by: Friedemann Kleint --- src/corelib/global/qt_pch.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/global/qt_pch.h b/src/corelib/global/qt_pch.h index 3972991618..0dfd6c745f 100644 --- a/src/corelib/global/qt_pch.h +++ b/src/corelib/global/qt_pch.h @@ -55,6 +55,10 @@ #include #include #ifdef Q_OS_WIN +# ifdef Q_CC_MINGW +// must be included before any other header pulls in . +# include // Define _POSIX_THREAD_SAFE_FUNCTIONS to obtain localtime_r() +# endif # define _POSIX_ # include # undef _POSIX_ From 89aa6e780a28b2c6dc9f57d14afd2c49b743f472 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 10 Jul 2019 10:21:42 +0200 Subject: [PATCH 056/264] Fix determination of host_arch test binary The host architecture detection binary's file extension is determined by the host platform, not the target platform. Respect the host variable that's set in configure.json. This amends commit d9fb502. Change-Id: I134cd7cf12d6a6fe458ac5e37c48dd311d6c4418 Reviewed-by: Simon Hausmann --- configure.pri | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/configure.pri b/configure.pri index da5d22382d..e9fd055854 100644 --- a/configure.pri +++ b/configure.pri @@ -266,17 +266,30 @@ defineTest(qtConfTest_architecture) { !qtConfTest_compile($${1}): \ error("Could not determine $$eval($${1}.label). See config.log for details.") + host = $$eval($${1}.host) + isEmpty(host): host = false + file_prefix = + ext = + $$host { + equals(QMAKE_HOST.os, Windows): \ + ext = .exe + } else { + win32 { + ext = .exe + } else:android { + file_prefix = lib + ext = .so + } else:wasm { + ext = .wasm + } + } + test = $$eval($${1}.test) output = $$eval($${1}.output) test_out_dir = $$OUT_PWD/$$basename(QMAKE_CONFIG_TESTS_DIR)/$$test - unix:exists($$test_out_dir/$$output): \ - content = $$cat($$test_out_dir/$$output, blob) - else: win32:exists($$test_out_dir/$${output}.exe): \ - content = $$cat($$test_out_dir/$${output}.exe, blob) - else: android:exists($$test_out_dir/lib$${output}.so): \ - content = $$cat($$test_out_dir/lib$${output}.so, blob) - else: wasm:exists($$test_out_dir/$${output}.wasm): \ - content = $$cat($$test_out_dir/$${output}.wasm, blob) + test_out_file = $$test_out_dir/$$file_prefix$$output$$ext + exists($$test_out_file): \ + content = $$cat($$test_out_file, blob) else: \ error("$$eval($${1}.label) detection binary not found.") From ffaf3cfc21586febc2bba93c87b130278d07e433 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 10 Jul 2019 11:50:19 +0200 Subject: [PATCH 057/264] doc: Enable a declaration for qdoc A declaration of fromStdVariant() was not visible to qdoc because it was ifdef'ed out. This update ensures that qdoc sees the declaration. Change-Id: I4b00a895aa61175296ec80806b43311eff4f25ca Reviewed-by: Paul Wicking --- src/corelib/kernel/qvariant.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index 3cc6d559c1..bb9db3d1ad 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -367,7 +367,7 @@ class Q_CORE_EXPORT QVariant static inline QVariant fromValue(const T &value) { return qVariantFromValue(value); } -#if QT_HAS_INCLUDE() && __cplusplus >= 201703L +#if (QT_HAS_INCLUDE() && __cplusplus >= 201703L) || defined(Q_CLANG_QDOC) template static inline QVariant fromStdVariant(const std::variant &value) { From 3052e621a4bda42e078dfe20ae51fccd5e64d2fb Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 9 Jul 2019 16:58:16 +0200 Subject: [PATCH 058/264] Fix duplicates in QMAKE_DIR_REPLACE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When building Qt, qt_build_config.prf adds all directory variables but DESTDIR to QMAKE_DIR_REPLACE_SANE. We must not add the content of QMAKE_DIR_REPLACE_SANE unconditionally to QMAKE_DIR_REPLACE in order to avoid duplicate entries. Duplicate entries result in an interesting build folder structure like .obj ├───debug │ └───debug └───release └───release This commit amends 274882a5. Change-Id: Ifa8178410d82f58635babc46d43774bab522fbf8 Reviewed-by: Oliver Wolff --- mkspecs/features/exclusive_builds.prf | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mkspecs/features/exclusive_builds.prf b/mkspecs/features/exclusive_builds.prf index b28e74146a..a41c5ab415 100644 --- a/mkspecs/features/exclusive_builds.prf +++ b/mkspecs/features/exclusive_builds.prf @@ -37,6 +37,9 @@ defineTest(addExclusiveBuilds) { addExclusiveBuildsProper($$join(ARGS, _and_), $$ARGS) } -# Default directories to process -QMAKE_DIR_REPLACE_SANE += QGLTF_DIR TRACEGEN_DIR QMLCACHE_DIR LRELEASE_DIR LEX_DIR YACC_DIR -QMAKE_DIR_REPLACE = OBJECTS_DIR MOC_DIR RCC_DIR PRECOMPILED_DIR DESTDIR $$QMAKE_DIR_REPLACE_SANE +QMAKE_DEFAULT_DIRS_TO_PROCESS = QGLTF_DIR TRACEGEN_DIR QMLCACHE_DIR LRELEASE_DIR LEX_DIR YACC_DIR +QMAKE_DIR_REPLACE_SANE += $$QMAKE_DEFAULT_DIRS_TO_PROCESS +QMAKE_DIR_REPLACE = \ + OBJECTS_DIR MOC_DIR RCC_DIR PRECOMPILED_DIR DESTDIR \ + $$QMAKE_DEFAULT_DIRS_TO_PROCESS +unset(QMAKE_DEFAULT_DIRS_TO_PROCESS) From 2d597c0e1a32dda3f4d2f1c941b8a0d2a4be4735 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Mon, 17 Dec 2018 11:12:50 +0100 Subject: [PATCH 059/264] QPixmapCache: guard against usage from non-main threads Depending on the active QPA plugin, QPixmaps may now be created and used also in non-main threads. But QPixmapCache is not designed to be used from such threads, so add guards to ignore such access attempts, both from application code and from Qt library code. Such unsafe access would often cause a cryptical "~QObject: Timers cannot be stopped from another thread" warning; that also disappears with this fix. [ChangeLog][QtGui][QPixmapCache] Ignore unsafe access from non-main threads Task-number: QTBUG-76694 Task-number: QTBUG-72523 Change-Id: Ia2db37e528aec08bfb48808630bdf5e543689039 Reviewed-by: Volker Hilsheimer --- src/gui/image/qpixmapcache.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index 3d1652f68b..e01a245cff 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -42,6 +42,8 @@ #include "qobject.h" #include "qdebug.h" #include "qpixmapcache_p.h" +#include "qthread.h" +#include "qcoreapplication.h" QT_BEGIN_NAMESPACE @@ -83,6 +85,9 @@ QT_BEGIN_NAMESPACE with QPixmapCache} explains how to use QPixmapCache to speed up applications by caching the results of painting. + \note QPixmapCache is only usable from the application's main thread. + Access from other threads will be ignored and return failure. + \sa QCache, QPixmap */ @@ -98,6 +103,14 @@ static inline int cost(const QPixmap &pixmap) return static_cast(qBound(1LL, costKb, costMax)); } +static inline bool qt_pixmapcache_thread_test() +{ + if (Q_LIKELY(QCoreApplication::instance() && QThread::currentThread() == QCoreApplication::instance()->thread())) + return true; + + return false; +} + /*! \class QPixmapCache::Key \brief The QPixmapCache::Key class can be used for efficient access @@ -487,6 +500,8 @@ QPixmapCacheEntry::~QPixmapCacheEntry() QPixmap *QPixmapCache::find(const QString &key) { + if (!qt_pixmapcache_thread_test()) + return nullptr; return pm_cache()->object(key); } @@ -515,6 +530,8 @@ bool QPixmapCache::find(const QString &key, QPixmap& pixmap) bool QPixmapCache::find(const QString &key, QPixmap* pixmap) { + if (!qt_pixmapcache_thread_test()) + return false; QPixmap *ptr = pm_cache()->object(key); if (ptr && pixmap) *pixmap = *ptr; @@ -532,6 +549,8 @@ bool QPixmapCache::find(const QString &key, QPixmap* pixmap) */ bool QPixmapCache::find(const Key &key, QPixmap* pixmap) { + if (!qt_pixmapcache_thread_test()) + return false; //The key is not valid anymore, a flush happened before probably if (!key.d || !key.d->isValid) return false; @@ -563,6 +582,8 @@ bool QPixmapCache::find(const Key &key, QPixmap* pixmap) bool QPixmapCache::insert(const QString &key, const QPixmap &pixmap) { + if (!qt_pixmapcache_thread_test()) + return false; return pm_cache()->insert(key, pixmap, cost(pixmap)); } @@ -583,6 +604,8 @@ bool QPixmapCache::insert(const QString &key, const QPixmap &pixmap) */ QPixmapCache::Key QPixmapCache::insert(const QPixmap &pixmap) { + if (!qt_pixmapcache_thread_test()) + return QPixmapCache::Key(); return pm_cache()->insert(pixmap, cost(pixmap)); } @@ -597,6 +620,8 @@ QPixmapCache::Key QPixmapCache::insert(const QPixmap &pixmap) */ bool QPixmapCache::replace(const Key &key, const QPixmap &pixmap) { + if (!qt_pixmapcache_thread_test()) + return false; //The key is not valid anymore, a flush happened before probably if (!key.d || !key.d->isValid) return false; @@ -626,6 +651,8 @@ int QPixmapCache::cacheLimit() void QPixmapCache::setCacheLimit(int n) { + if (!qt_pixmapcache_thread_test()) + return; pm_cache()->setMaxCost(n); } @@ -634,6 +661,8 @@ void QPixmapCache::setCacheLimit(int n) */ void QPixmapCache::remove(const QString &key) { + if (!qt_pixmapcache_thread_test()) + return; pm_cache()->remove(key); } @@ -645,6 +674,8 @@ void QPixmapCache::remove(const QString &key) */ void QPixmapCache::remove(const Key &key) { + if (!qt_pixmapcache_thread_test()) + return; //The key is not valid anymore, a flush happened before probably if (!key.d || !key.d->isValid) return; @@ -657,6 +688,8 @@ void QPixmapCache::remove(const Key &key) void QPixmapCache::clear() { + if (!QCoreApplication::closingDown() && !qt_pixmapcache_thread_test()) + return; QT_TRY { if (pm_cache.exists()) pm_cache->clear(); From eb48b3c0e18d071bce73e58a82e31a1437b11f4b Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 4 Jul 2019 22:23:04 +0200 Subject: [PATCH 060/264] qsslsocket_openssl_symbols.cpp: replace manual memory management with std::unique_ptr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also fix the name mismatch between the Windows- and non-Windows versions of loadOpenSsl(), which, presumably, were caused by having two different return values, something easily fixed by defining a small struct instead of using a QPair. Some #ifdef'ery saved, and a lot of brittle deletes on early returns. Change-Id: I77440de2f6fa51759510506ff4ef51917eb5b3ea Reviewed-by: Mårten Nordheim --- .../ssl/qsslsocket_openssl_symbols.cpp | 89 ++++++++----------- 1 file changed, 38 insertions(+), 51 deletions(-) diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 5b4e010cf0..869d6d5959 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -67,6 +67,7 @@ #if defined(Q_OS_UNIX) #include #endif +#include #if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) #include #endif @@ -596,8 +597,8 @@ DEFINEFUNC2(PKCS12 *, d2i_PKCS12_bio, BIO *bio, bio, PKCS12 **pkcs12, pkcs12, re DEFINEFUNC(void, PKCS12_free, PKCS12 *pkcs12, pkcs12, return, DUMMYARG) #define RESOLVEFUNC(func) \ - if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func))) \ - && !(_q_##func = _q_PTR_##func(libs.second->resolve(#func)))) \ + if (!(_q_##func = _q_PTR_##func(libs.ssl->resolve(#func))) \ + && !(_q_##func = _q_PTR_##func(libs.crypto->resolve(#func)))) \ qsslSocketCannotResolveSymbolWarning(#func); #if !defined QT_LINKED_OPENSSL @@ -733,34 +734,31 @@ static QStringList findAllLibCrypto() # endif #ifdef Q_OS_WIN -static bool tryToLoadOpenSslWin32Library(QLatin1String ssleay32LibName, QLatin1String libeay32LibName, QPair &pair) + +struct LoadedOpenSsl { + std::unique_ptr ssl, crypto; +}; + +static bool tryToLoadOpenSslWin32Library(QLatin1String ssleay32LibName, QLatin1String libeay32LibName, LoadedOpenSsl &result) { - pair.first = 0; - pair.second = 0; - - QSystemLibrary *ssleay32 = new QSystemLibrary(ssleay32LibName); + auto ssleay32 = qt_make_unique(ssleay32LibName); if (!ssleay32->load(false)) { - delete ssleay32; return FALSE; } - QSystemLibrary *libeay32 = new QSystemLibrary(libeay32LibName); + auto libeay32 = qt_make_unique(libeay32LibName); if (!libeay32->load(false)) { - delete ssleay32; - delete libeay32; return FALSE; } - pair.first = ssleay32; - pair.second = libeay32; + result.ssl = std::move(ssleay32); + result.crypto = std::move(libeay32); return TRUE; } -static QPair loadOpenSslWin32() +static LoadedOpenSsl loadOpenSsl() { - QPair pair; - pair.first = 0; - pair.second = 0; + LoadedOpenSsl result; #if QT_CONFIG(opensslv11) // With OpenSSL 1.1 the names have changed to libssl-1_1(-x64) and libcrypto-1_1(-x64), for builds using @@ -773,7 +771,7 @@ static QPair loadOpenSslWin32() #endif // !Q_PROCESSOR_x86_64 tryToLoadOpenSslWin32Library(QLatin1String("libssl-1_1" QT_SSL_SUFFIX), - QLatin1String("libcrypto-1_1" QT_SSL_SUFFIX), pair); + QLatin1String("libcrypto-1_1" QT_SSL_SUFFIX), result); #undef QT_SSL_SUFFIX @@ -782,28 +780,30 @@ static QPair loadOpenSslWin32() // When OpenSSL is built using MSVC then the libraries are named 'ssleay32.dll' and 'libeay32'dll'. // When OpenSSL is built using GCC then different library names are used (depending on the OpenSSL version) // The oldest version of a GCC-based OpenSSL which can be detected by the code below is 0.9.8g (released in 2007) - if (!tryToLoadOpenSslWin32Library(QLatin1String("ssleay32"), QLatin1String("libeay32"), pair)) { - if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-10"), QLatin1String("libcrypto-10"), pair)) { - if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-8"), QLatin1String("libcrypto-8"), pair)) { - tryToLoadOpenSslWin32Library(QLatin1String("libssl-7"), QLatin1String("libcrypto-7"), pair); + if (!tryToLoadOpenSslWin32Library(QLatin1String("ssleay32"), QLatin1String("libeay32"), result)) { + if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-10"), QLatin1String("libcrypto-10"), result)) { + if (!tryToLoadOpenSslWin32Library(QLatin1String("libssl-8"), QLatin1String("libcrypto-8"), result)) { + tryToLoadOpenSslWin32Library(QLatin1String("libssl-7"), QLatin1String("libcrypto-7"), result); } } } #endif // !QT_CONFIG(opensslv11) - return pair; + return result; } #else -static QPair loadOpenSsl() +struct LoadedOpenSsl { + std::unique_ptr ssl, crypto; +}; + +static LoadedOpenSsl loadOpenSsl() { - QPair pair; + LoadedOpenSsl result = {qt_make_unique(), qt_make_unique()}; # if defined(Q_OS_UNIX) - QLibrary *&libssl = pair.first; - QLibrary *&libcrypto = pair.second; - libssl = new QLibrary; - libcrypto = new QLibrary; + QLibrary * const libssl = result.ssl.get(); + QLibrary * const libcrypto = result.crypto.get(); // Try to find the libssl library on the system. // @@ -847,7 +847,7 @@ static QPair loadOpenSsl() libcrypto->setFileNameAndVersion(QLatin1String("crypto"), QLatin1String(SHLIB_VERSION_NUMBER)); if (libcrypto->load() && libssl->load()) { // libssl.so. and libcrypto.so. found - return pair; + return result; } else { libssl->unload(); libcrypto->unload(); @@ -866,7 +866,7 @@ static QPair loadOpenSsl() libssl->setFileNameAndVersion(QLatin1String("ssl"), fallbackSoname); libcrypto->setFileNameAndVersion(QLatin1String("crypto"), fallbackSoname); if (libcrypto->load() && libssl->load()) { - return pair; + return result; } else { libssl->unload(); libcrypto->unload(); @@ -886,7 +886,7 @@ static QPair loadOpenSsl() libcrypto->setFileNameAndVersion(QLatin1String("crypto"), -1); if (libcrypto->load() && libssl->load()) { // libssl.so.0 and libcrypto.so.0 found - return pair; + return result; } else { libssl->unload(); libcrypto->unload(); @@ -911,7 +911,7 @@ static QPair loadOpenSsl() if (libssl->load()) { // libssl.so.x and libcrypto.so.x found - return pair; + return result; } else { libssl->unload(); } @@ -921,14 +921,12 @@ static QPair loadOpenSsl() } // failed to load anything - delete libssl; - delete libcrypto; - libssl = libcrypto = 0; - return pair; + result = {}; + return result; # else // not implemented for this platform yet - return pair; + return result; # endif } #endif @@ -948,12 +946,8 @@ bool q_resolveOpenSslSymbols() return false; triedToResolveSymbols = true; -#ifdef Q_OS_WIN - QPair libs = loadOpenSslWin32(); -#else - QPair libs = loadOpenSsl(); -#endif - if (!libs.first || !libs.second) + LoadedOpenSsl libs = loadOpenSsl(); + if (!libs.ssl || !libs.crypto) // failed to load them return false; @@ -1002,8 +996,6 @@ bool q_resolveOpenSslSymbols() if (!_q_OpenSSL_version) { // Apparently, we were built with OpenSSL 1.1 enabled but are now using // a wrong library. - delete libs.first; - delete libs.second; qCWarning(lcSsl, "Incompatible version of OpenSSL"); return false; } @@ -1125,8 +1117,6 @@ bool q_resolveOpenSslSymbols() // OpenSSL 1.1 has deprecated and removed SSLeay. We consider a failure to // resolve this symbol as a failure to resolve symbols. // The right operand of '||' above is ... a bit of paranoia. - delete libs.first; - delete libs.second; qCWarning(lcSsl, "Incompatible version of OpenSSL"); return false; } @@ -1397,10 +1387,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(d2i_PKCS12_bio) RESOLVEFUNC(PKCS12_free) - symbolsResolved.storeRelease(true); - delete libs.first; - delete libs.second; return true; } #endif // QT_CONFIG(library) From ca6a037d95ed1915773bf28f9190a012164c6443 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Tue, 9 Jul 2019 14:53:29 +0900 Subject: [PATCH 061/264] Fix testlib build without features.properties Change-Id: I3ca7f8cdb59a9a1e61d2702e92cd5e2d1420ac84 Reviewed-by: Volker Hilsheimer Reviewed-by: Jason McDonald --- src/testlib/qtestblacklist.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/testlib/qtestblacklist.cpp b/src/testlib/qtestblacklist.cpp index 6642699758..596788e297 100644 --- a/src/testlib/qtestblacklist.cpp +++ b/src/testlib/qtestblacklist.cpp @@ -169,12 +169,14 @@ static QSet keywords() #endif ; +#if QT_CONFIG(properties) QCoreApplication *app = QCoreApplication::instance(); if (app) { const QVariant platformName = app->property("platformName"); if (platformName.isValid()) set << platformName.toByteArray(); } +#endif return set; } From a9aa206b7b8ac4e69f8c46233b4080e00e845ff5 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 27 May 2019 19:13:54 +0200 Subject: [PATCH 062/264] Move text-related code out of corelib/tools/ to corelib/text/ This includes byte array, string, char, unicode, locale, collation and regular expressions. Change-Id: I8b125fa52c8c513eb57a0f1298b91910e5a0d786 Reviewed-by: Volker Hilsheimer --- qmake/Makefile.unix | 40 +++---- qmake/Makefile.win32 | 3 + src/corelib/configure.json | 2 +- src/corelib/corelib.pro | 1 + .../{tools => text}/UNICODE_LICENSE.txt | 0 src/corelib/{tools => text}/qbytearray.cpp | 2 +- src/corelib/{tools => text}/qbytearray.h | 0 src/corelib/{tools => text}/qbytearray_p.h | 2 +- .../{tools => text}/qbytearraylist.cpp | 0 src/corelib/{tools => text}/qbytearraylist.h | 0 .../{tools => text}/qbytearraymatcher.cpp | 0 .../{tools => text}/qbytearraymatcher.h | 0 src/corelib/{tools => text}/qbytedata_p.h | 0 src/corelib/{tools => text}/qchar.cpp | 0 src/corelib/{tools => text}/qchar.h | 0 src/corelib/{tools => text}/qcollator.cpp | 0 src/corelib/{tools => text}/qcollator.h | 0 src/corelib/{tools => text}/qcollator_icu.cpp | 0 .../{tools => text}/qcollator_macx.cpp | 0 src/corelib/{tools => text}/qcollator_p.h | 0 .../{tools => text}/qcollator_posix.cpp | 0 src/corelib/{tools => text}/qcollator_win.cpp | 0 .../{tools => text}/qdoublescanprint_p.h | 0 src/corelib/{tools => text}/qharfbuzz.cpp | 0 src/corelib/{tools => text}/qharfbuzz_p.h | 0 src/corelib/{tools => text}/qlocale.cpp | 0 src/corelib/{tools => text}/qlocale.h | 0 src/corelib/{tools => text}/qlocale.qdoc | 0 src/corelib/{tools => text}/qlocale_data_p.h | 0 src/corelib/{tools => text}/qlocale_icu.cpp | 0 src/corelib/{tools => text}/qlocale_mac.mm | 0 src/corelib/{tools => text}/qlocale_p.h | 0 src/corelib/{tools => text}/qlocale_tools.cpp | 0 src/corelib/{tools => text}/qlocale_tools_p.h | 0 src/corelib/{tools => text}/qlocale_unix.cpp | 0 src/corelib/{tools => text}/qlocale_win.cpp | 0 src/corelib/{tools => text}/qregexp.cpp | 0 src/corelib/{tools => text}/qregexp.h | 0 .../{tools => text}/qregularexpression.cpp | 0 .../{tools => text}/qregularexpression.h | 0 src/corelib/{tools => text}/qstring.cpp | 5 +- src/corelib/{tools => text}/qstring.h | 0 .../{tools => text}/qstring_compat.cpp | 0 .../{tools => text}/qstring_mips_dsp_asm.S | 0 .../{tools => text}/qstringalgorithms.h | 0 .../{tools => text}/qstringalgorithms_p.h | 0 .../{tools => text}/qstringbuilder.cpp | 0 src/corelib/{tools => text}/qstringbuilder.h | 0 .../{tools => text}/qstringiterator.qdoc | 0 .../{tools => text}/qstringiterator_p.h | 0 src/corelib/{tools => text}/qstringlist.cpp | 0 src/corelib/{tools => text}/qstringlist.h | 0 src/corelib/{tools => text}/qstringliteral.h | 0 .../{tools => text}/qstringmatcher.cpp | 0 src/corelib/{tools => text}/qstringmatcher.h | 0 src/corelib/{tools => text}/qstringview.cpp | 0 src/corelib/{tools => text}/qstringview.h | 0 .../{tools => text}/qt_attribution.json | 0 .../{tools => text}/qtextboundaryfinder.cpp | 0 .../{tools => text}/qtextboundaryfinder.h | 0 .../{tools => text}/qunicodetables.cpp | 0 .../{tools => text}/qunicodetables_p.h | 0 src/corelib/{tools => text}/qunicodetools.cpp | 0 src/corelib/{tools => text}/qunicodetools_p.h | 0 src/corelib/{tools => text}/qvsnprintf.cpp | 0 src/corelib/text/text.pri | 100 ++++++++++++++++++ src/corelib/tools/tools.pri | 88 --------------- src/tools/bootstrap/bootstrap.pro | 24 ++--- tests/auto/corelib/corelib.pro | 1 + .../{tools => text}/qbytearray/.gitattributes | 0 .../{tools => text}/qbytearray/.gitignore | 0 .../qbytearray/android_testdata.qrc | 0 .../{tools => text}/qbytearray/qbytearray.pro | 0 .../{tools => text}/qbytearray/rfc3252.txt | 0 .../qbytearray/tst_qbytearray.cpp | 0 .../qbytearray/tst_qbytearray_mac.mm | 0 .../qbytearraylist/qbytearraylist.pro | 0 .../qbytearraylist/tst_qbytearraylist.cpp | 0 .../qbytearraymatcher/qbytearraymatcher.pro | 0 .../tst_qbytearraymatcher.cpp | 0 .../qbytedatabuffer/.gitignore | 0 .../qbytedatabuffer/qbytedatabuffer.pro | 0 .../qbytedatabuffer/tst_qbytedatabuffer.cpp | 0 .../corelib/{tools => text}/qchar/.gitignore | 0 .../qchar/data/NormalizationTest.txt | 0 .../corelib/{tools => text}/qchar/qchar.pro | 0 .../{tools => text}/qchar/testdata.qrc | 0 .../{tools => text}/qchar/tst_qchar.cpp | 0 .../{tools => text}/qcollator/qcollator.pro | 0 .../qcollator/tst_qcollator.cpp | 0 .../{tools => text}/qlatin1string/.gitignore | 0 .../qlatin1string/qlatin1string.pro | 0 .../qlatin1string/tst_qlatin1string.cpp | 0 .../{tools => text}/qlocale/.gitignore | 0 .../{tools => text}/qlocale/qlocale.pro | 0 .../qlocale/syslocaleapp/syslocaleapp.cpp | 0 .../qlocale/syslocaleapp/syslocaleapp.pro | 0 .../{tools => text}/qlocale/test/test.pro | 0 .../{tools => text}/qlocale/tst_qlocale.cpp | 0 .../{tools => text}/qregexp/.gitignore | 0 .../{tools => text}/qregexp/qregexp.pro | 0 .../{tools => text}/qregexp/tst_qregexp.cpp | 0 .../qregularexpression/.gitignore | 0 .../qregularexpression/qregularexpression.pro | 0 .../tst_qregularexpression.cpp | 0 .../{tools => text}/qstring/.gitignore | 0 .../{tools => text}/qstring/double_data.h | 0 .../{tools => text}/qstring/qstring.pro | 0 .../{tools => text}/qstring/tst_qstring.cpp | 0 .../qstring/tst_qstring_mac.mm | 0 .../qstring_no_cast_from_bytearray.pro | 0 .../tst_qstring_no_cast_from_bytearray.cpp | 0 .../qstringapisymmetry/.gitignore | 0 .../qstringapisymmetry/qstringapisymmetry.pro | 0 .../tst_qstringapisymmetry.cpp | 0 .../qstringbuilder/qstringbuilder.pro | 0 .../qstringbuilder1/qstringbuilder1.pro | 0 .../qstringbuilder1/stringbuilder.cpp | 0 .../qstringbuilder1/tst_qstringbuilder1.cpp | 0 .../qstringbuilder2/qstringbuilder2.pro | 0 .../qstringbuilder2/tst_qstringbuilder2.cpp | 0 .../qstringbuilder3/qstringbuilder3.pro | 0 .../qstringbuilder3/tst_qstringbuilder3.cpp | 0 .../qstringbuilder4/qstringbuilder4.pro | 0 .../qstringbuilder4/tst_qstringbuilder4.cpp | 0 .../qstringiterator/qstringiterator.pro | 0 .../qstringiterator/tst_qstringiterator.cpp | 0 .../{tools => text}/qstringlist/.gitignore | 0 .../qstringlist/qstringlist.pro | 0 .../qstringlist/tst_qstringlist.cpp | 0 .../{tools => text}/qstringmatcher/.gitignore | 0 .../qstringmatcher/qstringmatcher.pro | 0 .../qstringmatcher/tst_qstringmatcher.cpp | 0 .../{tools => text}/qstringref/qstringref.pro | 0 .../qstringref/tst_qstringref.cpp | 0 .../{tools => text}/qstringview/.gitignore | 0 .../qstringview/qstringview.pro | 0 .../qstringview/tst_qstringview.cpp | 0 .../qtextboundaryfinder/.gitignore | 0 .../data/GraphemeBreakTest.txt | 0 .../data/LineBreakTest.txt | 0 .../data/SentenceBreakTest.txt | 0 .../data/WordBreakTest.txt | 0 .../qtextboundaryfinder.pro | 0 .../qtextboundaryfinder/testdata.qrc | 0 .../tst_qtextboundaryfinder.cpp | 0 tests/auto/corelib/text/text.pro | 23 ++++ tests/auto/corelib/tools/tools.pro | 20 ---- tests/benchmarks/corelib/corelib.pro | 1 + .../{tools => text}/qbytearray/main.cpp | 0 .../{tools => text}/qbytearray/qbytearray.pro | 0 .../corelib/{tools => text}/qchar/main.cpp | 0 .../corelib/{tools => text}/qchar/qchar.pro | 0 .../corelib/{tools => text}/qlocale/main.cpp | 0 .../{tools => text}/qlocale/qlocale.pro | 0 .../corelib/{tools => text}/qregexp/main.cpp | 0 .../{tools => text}/qregexp/qregexp.pro | 0 .../{tools => text}/qregexp/qregexp.qrc | 0 .../corelib/{tools => text}/qstring/main.cpp | 0 .../{tools => text}/qstring/qstring.pro | 0 .../{tools => text}/qstringbuilder/main.cpp | 0 .../qstringbuilder/qstringbuilder.pro | 0 .../{tools => text}/qstringlist/.gitignore | 0 .../{tools => text}/qstringlist/main.cpp | 0 .../qstringlist/qstringlist.pro | 0 tests/benchmarks/corelib/text/text.pro | 10 ++ .../corelib/tools/qhash/paths_small_data.txt | 56 +++++----- tests/benchmarks/corelib/tools/tools.pro | 7 -- util/locale_database/cldr2qlocalexml.py | 4 +- util/locale_database/qlocalexml2cpp.py | 18 ++-- util/unicode/README | 2 +- util/unicode/main.cpp | 4 +- 172 files changed, 220 insertions(+), 193 deletions(-) rename src/corelib/{tools => text}/UNICODE_LICENSE.txt (100%) rename src/corelib/{tools => text}/qbytearray.cpp (99%) rename src/corelib/{tools => text}/qbytearray.h (100%) rename src/corelib/{tools => text}/qbytearray_p.h (98%) rename src/corelib/{tools => text}/qbytearraylist.cpp (100%) rename src/corelib/{tools => text}/qbytearraylist.h (100%) rename src/corelib/{tools => text}/qbytearraymatcher.cpp (100%) rename src/corelib/{tools => text}/qbytearraymatcher.h (100%) rename src/corelib/{tools => text}/qbytedata_p.h (100%) rename src/corelib/{tools => text}/qchar.cpp (100%) rename src/corelib/{tools => text}/qchar.h (100%) rename src/corelib/{tools => text}/qcollator.cpp (100%) rename src/corelib/{tools => text}/qcollator.h (100%) rename src/corelib/{tools => text}/qcollator_icu.cpp (100%) rename src/corelib/{tools => text}/qcollator_macx.cpp (100%) rename src/corelib/{tools => text}/qcollator_p.h (100%) rename src/corelib/{tools => text}/qcollator_posix.cpp (100%) rename src/corelib/{tools => text}/qcollator_win.cpp (100%) rename src/corelib/{tools => text}/qdoublescanprint_p.h (100%) rename src/corelib/{tools => text}/qharfbuzz.cpp (100%) rename src/corelib/{tools => text}/qharfbuzz_p.h (100%) rename src/corelib/{tools => text}/qlocale.cpp (100%) rename src/corelib/{tools => text}/qlocale.h (100%) rename src/corelib/{tools => text}/qlocale.qdoc (100%) rename src/corelib/{tools => text}/qlocale_data_p.h (100%) rename src/corelib/{tools => text}/qlocale_icu.cpp (100%) rename src/corelib/{tools => text}/qlocale_mac.mm (100%) rename src/corelib/{tools => text}/qlocale_p.h (100%) rename src/corelib/{tools => text}/qlocale_tools.cpp (100%) rename src/corelib/{tools => text}/qlocale_tools_p.h (100%) rename src/corelib/{tools => text}/qlocale_unix.cpp (100%) rename src/corelib/{tools => text}/qlocale_win.cpp (100%) rename src/corelib/{tools => text}/qregexp.cpp (100%) rename src/corelib/{tools => text}/qregexp.h (100%) rename src/corelib/{tools => text}/qregularexpression.cpp (100%) rename src/corelib/{tools => text}/qregularexpression.h (100%) rename src/corelib/{tools => text}/qstring.cpp (99%) rename src/corelib/{tools => text}/qstring.h (100%) rename src/corelib/{tools => text}/qstring_compat.cpp (100%) rename src/corelib/{tools => text}/qstring_mips_dsp_asm.S (100%) rename src/corelib/{tools => text}/qstringalgorithms.h (100%) rename src/corelib/{tools => text}/qstringalgorithms_p.h (100%) rename src/corelib/{tools => text}/qstringbuilder.cpp (100%) rename src/corelib/{tools => text}/qstringbuilder.h (100%) rename src/corelib/{tools => text}/qstringiterator.qdoc (100%) rename src/corelib/{tools => text}/qstringiterator_p.h (100%) rename src/corelib/{tools => text}/qstringlist.cpp (100%) rename src/corelib/{tools => text}/qstringlist.h (100%) rename src/corelib/{tools => text}/qstringliteral.h (100%) rename src/corelib/{tools => text}/qstringmatcher.cpp (100%) rename src/corelib/{tools => text}/qstringmatcher.h (100%) rename src/corelib/{tools => text}/qstringview.cpp (100%) rename src/corelib/{tools => text}/qstringview.h (100%) rename src/corelib/{tools => text}/qt_attribution.json (100%) rename src/corelib/{tools => text}/qtextboundaryfinder.cpp (100%) rename src/corelib/{tools => text}/qtextboundaryfinder.h (100%) rename src/corelib/{tools => text}/qunicodetables.cpp (100%) rename src/corelib/{tools => text}/qunicodetables_p.h (100%) rename src/corelib/{tools => text}/qunicodetools.cpp (100%) rename src/corelib/{tools => text}/qunicodetools_p.h (100%) rename src/corelib/{tools => text}/qvsnprintf.cpp (100%) create mode 100644 src/corelib/text/text.pri rename tests/auto/corelib/{tools => text}/qbytearray/.gitattributes (100%) rename tests/auto/corelib/{tools => text}/qbytearray/.gitignore (100%) rename tests/auto/corelib/{tools => text}/qbytearray/android_testdata.qrc (100%) rename tests/auto/corelib/{tools => text}/qbytearray/qbytearray.pro (100%) rename tests/auto/corelib/{tools => text}/qbytearray/rfc3252.txt (100%) rename tests/auto/corelib/{tools => text}/qbytearray/tst_qbytearray.cpp (100%) rename tests/auto/corelib/{tools => text}/qbytearray/tst_qbytearray_mac.mm (100%) rename tests/auto/corelib/{tools => text}/qbytearraylist/qbytearraylist.pro (100%) rename tests/auto/corelib/{tools => text}/qbytearraylist/tst_qbytearraylist.cpp (100%) rename tests/auto/corelib/{tools => text}/qbytearraymatcher/qbytearraymatcher.pro (100%) rename tests/auto/corelib/{tools => text}/qbytearraymatcher/tst_qbytearraymatcher.cpp (100%) rename tests/auto/corelib/{tools => text}/qbytedatabuffer/.gitignore (100%) rename tests/auto/corelib/{tools => text}/qbytedatabuffer/qbytedatabuffer.pro (100%) rename tests/auto/corelib/{tools => text}/qbytedatabuffer/tst_qbytedatabuffer.cpp (100%) rename tests/auto/corelib/{tools => text}/qchar/.gitignore (100%) rename tests/auto/corelib/{tools => text}/qchar/data/NormalizationTest.txt (100%) rename tests/auto/corelib/{tools => text}/qchar/qchar.pro (100%) rename tests/auto/corelib/{tools => text}/qchar/testdata.qrc (100%) rename tests/auto/corelib/{tools => text}/qchar/tst_qchar.cpp (100%) rename tests/auto/corelib/{tools => text}/qcollator/qcollator.pro (100%) rename tests/auto/corelib/{tools => text}/qcollator/tst_qcollator.cpp (100%) rename tests/auto/corelib/{tools => text}/qlatin1string/.gitignore (100%) rename tests/auto/corelib/{tools => text}/qlatin1string/qlatin1string.pro (100%) rename tests/auto/corelib/{tools => text}/qlatin1string/tst_qlatin1string.cpp (100%) rename tests/auto/corelib/{tools => text}/qlocale/.gitignore (100%) rename tests/auto/corelib/{tools => text}/qlocale/qlocale.pro (100%) rename tests/auto/corelib/{tools => text}/qlocale/syslocaleapp/syslocaleapp.cpp (100%) rename tests/auto/corelib/{tools => text}/qlocale/syslocaleapp/syslocaleapp.pro (100%) rename tests/auto/corelib/{tools => text}/qlocale/test/test.pro (100%) rename tests/auto/corelib/{tools => text}/qlocale/tst_qlocale.cpp (100%) rename tests/auto/corelib/{tools => text}/qregexp/.gitignore (100%) rename tests/auto/corelib/{tools => text}/qregexp/qregexp.pro (100%) rename tests/auto/corelib/{tools => text}/qregexp/tst_qregexp.cpp (100%) rename tests/auto/corelib/{tools => text}/qregularexpression/.gitignore (100%) rename tests/auto/corelib/{tools => text}/qregularexpression/qregularexpression.pro (100%) rename tests/auto/corelib/{tools => text}/qregularexpression/tst_qregularexpression.cpp (100%) rename tests/auto/corelib/{tools => text}/qstring/.gitignore (100%) rename tests/auto/corelib/{tools => text}/qstring/double_data.h (100%) rename tests/auto/corelib/{tools => text}/qstring/qstring.pro (100%) rename tests/auto/corelib/{tools => text}/qstring/tst_qstring.cpp (100%) rename tests/auto/corelib/{tools => text}/qstring/tst_qstring_mac.mm (100%) rename tests/auto/corelib/{tools => text}/qstring_no_cast_from_bytearray/qstring_no_cast_from_bytearray.pro (100%) rename tests/auto/corelib/{tools => text}/qstring_no_cast_from_bytearray/tst_qstring_no_cast_from_bytearray.cpp (100%) rename tests/auto/corelib/{tools => text}/qstringapisymmetry/.gitignore (100%) rename tests/auto/corelib/{tools => text}/qstringapisymmetry/qstringapisymmetry.pro (100%) rename tests/auto/corelib/{tools => text}/qstringapisymmetry/tst_qstringapisymmetry.cpp (100%) rename tests/auto/corelib/{tools => text}/qstringbuilder/qstringbuilder.pro (100%) rename tests/auto/corelib/{tools => text}/qstringbuilder/qstringbuilder1/qstringbuilder1.pro (100%) rename tests/auto/corelib/{tools => text}/qstringbuilder/qstringbuilder1/stringbuilder.cpp (100%) rename tests/auto/corelib/{tools => text}/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp (100%) rename tests/auto/corelib/{tools => text}/qstringbuilder/qstringbuilder2/qstringbuilder2.pro (100%) rename tests/auto/corelib/{tools => text}/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp (100%) rename tests/auto/corelib/{tools => text}/qstringbuilder/qstringbuilder3/qstringbuilder3.pro (100%) rename tests/auto/corelib/{tools => text}/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp (100%) rename tests/auto/corelib/{tools => text}/qstringbuilder/qstringbuilder4/qstringbuilder4.pro (100%) rename tests/auto/corelib/{tools => text}/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp (100%) rename tests/auto/corelib/{tools => text}/qstringiterator/qstringiterator.pro (100%) rename tests/auto/corelib/{tools => text}/qstringiterator/tst_qstringiterator.cpp (100%) rename tests/auto/corelib/{tools => text}/qstringlist/.gitignore (100%) rename tests/auto/corelib/{tools => text}/qstringlist/qstringlist.pro (100%) rename tests/auto/corelib/{tools => text}/qstringlist/tst_qstringlist.cpp (100%) rename tests/auto/corelib/{tools => text}/qstringmatcher/.gitignore (100%) rename tests/auto/corelib/{tools => text}/qstringmatcher/qstringmatcher.pro (100%) rename tests/auto/corelib/{tools => text}/qstringmatcher/tst_qstringmatcher.cpp (100%) rename tests/auto/corelib/{tools => text}/qstringref/qstringref.pro (100%) rename tests/auto/corelib/{tools => text}/qstringref/tst_qstringref.cpp (100%) rename tests/auto/corelib/{tools => text}/qstringview/.gitignore (100%) rename tests/auto/corelib/{tools => text}/qstringview/qstringview.pro (100%) rename tests/auto/corelib/{tools => text}/qstringview/tst_qstringview.cpp (100%) rename tests/auto/corelib/{tools => text}/qtextboundaryfinder/.gitignore (100%) rename tests/auto/corelib/{tools => text}/qtextboundaryfinder/data/GraphemeBreakTest.txt (100%) rename tests/auto/corelib/{tools => text}/qtextboundaryfinder/data/LineBreakTest.txt (100%) rename tests/auto/corelib/{tools => text}/qtextboundaryfinder/data/SentenceBreakTest.txt (100%) rename tests/auto/corelib/{tools => text}/qtextboundaryfinder/data/WordBreakTest.txt (100%) rename tests/auto/corelib/{tools => text}/qtextboundaryfinder/qtextboundaryfinder.pro (100%) rename tests/auto/corelib/{tools => text}/qtextboundaryfinder/testdata.qrc (100%) rename tests/auto/corelib/{tools => text}/qtextboundaryfinder/tst_qtextboundaryfinder.cpp (100%) create mode 100644 tests/auto/corelib/text/text.pro rename tests/benchmarks/corelib/{tools => text}/qbytearray/main.cpp (100%) rename tests/benchmarks/corelib/{tools => text}/qbytearray/qbytearray.pro (100%) rename tests/benchmarks/corelib/{tools => text}/qchar/main.cpp (100%) rename tests/benchmarks/corelib/{tools => text}/qchar/qchar.pro (100%) rename tests/benchmarks/corelib/{tools => text}/qlocale/main.cpp (100%) rename tests/benchmarks/corelib/{tools => text}/qlocale/qlocale.pro (100%) rename tests/benchmarks/corelib/{tools => text}/qregexp/main.cpp (100%) rename tests/benchmarks/corelib/{tools => text}/qregexp/qregexp.pro (100%) rename tests/benchmarks/corelib/{tools => text}/qregexp/qregexp.qrc (100%) rename tests/benchmarks/corelib/{tools => text}/qstring/main.cpp (100%) rename tests/benchmarks/corelib/{tools => text}/qstring/qstring.pro (100%) rename tests/benchmarks/corelib/{tools => text}/qstringbuilder/main.cpp (100%) rename tests/benchmarks/corelib/{tools => text}/qstringbuilder/qstringbuilder.pro (100%) rename tests/benchmarks/corelib/{tools => text}/qstringlist/.gitignore (100%) rename tests/benchmarks/corelib/{tools => text}/qstringlist/main.cpp (100%) rename tests/benchmarks/corelib/{tools => text}/qstringlist/qstringlist.pro (100%) create mode 100644 tests/benchmarks/corelib/text/text.pro diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index 069cb0f12d..68f173cd1b 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -105,24 +105,24 @@ DEPEND_SRC = \ $(SOURCE_PATH)/src/corelib/serialization/qtextstream.cpp \ $(SOURCE_PATH)/src/corelib/serialization/qxmlstream.cpp \ $(SOURCE_PATH)/src/corelib/serialization/qxmlutils.cpp \ + $(SOURCE_PATH)/src/corelib/text/qbytearray.cpp\ + $(SOURCE_PATH)/src/corelib/text/qbytearraymatcher.cpp \ + $(SOURCE_PATH)/src/corelib/text/qlocale.cpp \ + $(SOURCE_PATH)/src/corelib/text/qlocale_tools.cpp \ + $(SOURCE_PATH)/src/corelib/text/qregexp.cpp \ + $(SOURCE_PATH)/src/corelib/text/qstringbuilder.cpp \ + $(SOURCE_PATH)/src/corelib/text/qstring.cpp \ + $(SOURCE_PATH)/src/corelib/text/qstringlist.cpp \ + $(SOURCE_PATH)/src/corelib/text/qvsnprintf.cpp \ $(SOURCE_PATH)/src/corelib/time/qdatetime.cpp \ $(SOURCE_PATH)/src/corelib/tools/qarraydata.cpp \ $(SOURCE_PATH)/src/corelib/tools/qbitarray.cpp \ - $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp\ - $(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp \ $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp \ $(SOURCE_PATH)/src/corelib/tools/qhash.cpp \ $(SOURCE_PATH)/src/corelib/tools/qlist.cpp \ - $(SOURCE_PATH)/src/corelib/tools/qlocale.cpp \ - $(SOURCE_PATH)/src/corelib/tools/qlocale_tools.cpp \ $(SOURCE_PATH)/src/corelib/tools/qmap.cpp \ - $(SOURCE_PATH)/src/corelib/tools/qregexp.cpp \ $(SOURCE_PATH)/src/corelib/tools/qringbuffer.cpp \ - $(SOURCE_PATH)/src/corelib/tools/qstringbuilder.cpp \ - $(SOURCE_PATH)/src/corelib/tools/qstring.cpp \ - $(SOURCE_PATH)/src/corelib/tools/qstringlist.cpp \ $(SOURCE_PATH)/src/corelib/tools/qversionnumber.cpp \ - $(SOURCE_PATH)/src/corelib/tools/qvsnprintf.cpp \ $(QTSRCS) $(QTSRCS2) # QTSRCS and QTSRCS2 come from Makefile.unix.* (concatenated with this # by configure); QTSRCS2 may include *.mm entries on macOS. @@ -302,13 +302,13 @@ qglobal.o: $(SOURCE_PATH)/src/corelib/global/qglobal.cpp qarraydata.o: $(SOURCE_PATH)/src/corelib/tools/qarraydata.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< -qbytearray.o: $(SOURCE_PATH)/src/corelib/tools/qbytearray.cpp +qbytearray.o: $(SOURCE_PATH)/src/corelib/text/qbytearray.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< -qvsnprintf.o: $(SOURCE_PATH)/src/corelib/tools/qvsnprintf.cpp +qvsnprintf.o: $(SOURCE_PATH)/src/corelib/text/qvsnprintf.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< -qbytearraymatcher.o: $(SOURCE_PATH)/src/corelib/tools/qbytearraymatcher.cpp +qbytearraymatcher.o: $(SOURCE_PATH)/src/corelib/text/qbytearraymatcher.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< qmetatype.o: $(SOURCE_PATH)/src/corelib/kernel/qmetatype.cpp @@ -338,22 +338,22 @@ qcore_foundation.o: $(SOURCE_PATH)/src/corelib/kernel/qcore_foundation.mm qutfcodec.o: $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< -qstring.o: $(SOURCE_PATH)/src/corelib/tools/qstring.cpp +qstring.o: $(SOURCE_PATH)/src/corelib/text/qstring.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< -qstringbuilder.o: $(SOURCE_PATH)/src/corelib/tools/qstringbuilder.cpp +qstringbuilder.o: $(SOURCE_PATH)/src/corelib/text/qstringbuilder.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< -qlocale.o: $(SOURCE_PATH)/src/corelib/tools/qlocale.cpp +qlocale.o: $(SOURCE_PATH)/src/corelib/text/qlocale.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< -qlocale_tools.o: $(SOURCE_PATH)/src/corelib/tools/qlocale_tools.cpp +qlocale_tools.o: $(SOURCE_PATH)/src/corelib/text/qlocale_tools.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< -qlocale_unix.o: $(SOURCE_PATH)/src/corelib/tools/qlocale_unix.cpp +qlocale_unix.o: $(SOURCE_PATH)/src/corelib/text/qlocale_unix.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< -qlocale_win.o: $(SOURCE_PATH)/src/corelib/tools/qlocale_win.cpp +qlocale_win.o: $(SOURCE_PATH)/src/corelib/text/qlocale_win.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< qversionnumber.o: $(SOURCE_PATH)/src/corelib/tools/qversionnumber.cpp @@ -407,7 +407,7 @@ qabstractfileengine.o: $(SOURCE_PATH)/src/corelib/io/qabstractfileengine.cpp qtemporaryfile.o: $(SOURCE_PATH)/src/corelib/io/qtemporaryfile.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< -qregexp.o: $(SOURCE_PATH)/src/corelib/tools/qregexp.cpp +qregexp.o: $(SOURCE_PATH)/src/corelib/text/qregexp.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< qbitarray.o: $(SOURCE_PATH)/src/corelib/tools/qbitarray.cpp @@ -428,7 +428,7 @@ qfileinfo.o: $(SOURCE_PATH)/src/corelib/io/qfileinfo.cpp qdatetime.o: $(SOURCE_PATH)/src/corelib/time/qdatetime.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< -qstringlist.o: $(SOURCE_PATH)/src/corelib/tools/qstringlist.cpp +qstringlist.o: $(SOURCE_PATH)/src/corelib/text/qstringlist.cpp $(CXX) -c -o $@ $(CXXFLAGS) $< qmap.o: $(SOURCE_PATH)/src/corelib/tools/qmap.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index d300e49215..43059f9af0 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -196,6 +196,9 @@ qmake_pch.obj: {$(SOURCE_PATH)\src\corelib\serialization}.cpp{}.obj:: $(CXX) $(CXXFLAGS) $< +{$(SOURCE_PATH)\src\corelib\text}.cpp{}.obj:: + $(CXX) $(CXXFLAGS) $< + {$(SOURCE_PATH)\src\corelib\time}.cpp{}.obj:: $(CXX) $(CXXFLAGS) $< diff --git a/src/corelib/configure.json b/src/corelib/configure.json index 88c7bbfbed..83c30fb47b 100644 --- a/src/corelib/configure.json +++ b/src/corelib/configure.json @@ -596,7 +596,7 @@ "qDoubleSnprintf(argv[0], 1, invalidLocale, \"invalid format\", a);", "qDoubleSscanf(argv[0], invalidLocale, \"invalid format\", &a, &argc);" ], - "qmake": "DEFINES += QDSP_P_H=$$shell_quote(\\\"@PWD@/tools/qdoublescanprint_p.h\\\")" + "qmake": "DEFINES += QDSP_P_H=$$shell_quote(\\\"@PWD@/text/qdoublescanprint_p.h\\\")" } } }, diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index 521f840292..b9bcc70e17 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -36,6 +36,7 @@ qtConfig(animation): include(animation/animation.pri) include(global/global.pri) include(thread/thread.pri) include(tools/tools.pri) +include(text/text.pri) include(time/time.pri) include(io/io.pri) include(itemmodels/itemmodels.pri) diff --git a/src/corelib/tools/UNICODE_LICENSE.txt b/src/corelib/text/UNICODE_LICENSE.txt similarity index 100% rename from src/corelib/tools/UNICODE_LICENSE.txt rename to src/corelib/text/UNICODE_LICENSE.txt diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/text/qbytearray.cpp similarity index 99% rename from src/corelib/tools/qbytearray.cpp rename to src/corelib/text/qbytearray.cpp index ecbb4743af..fcf7b5e709 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/text/qbytearray.cpp @@ -40,7 +40,7 @@ #include "qbytearray.h" #include "qbytearraymatcher.h" -#include "qtools_p.h" +#include "private/qtools_p.h" #include "qstring.h" #include "qlist.h" #include "qlocale.h" diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/text/qbytearray.h similarity index 100% rename from src/corelib/tools/qbytearray.h rename to src/corelib/text/qbytearray.h diff --git a/src/corelib/tools/qbytearray_p.h b/src/corelib/text/qbytearray_p.h similarity index 98% rename from src/corelib/tools/qbytearray_p.h rename to src/corelib/text/qbytearray_p.h index 6ebff739cd..3c6257f786 100644 --- a/src/corelib/tools/qbytearray_p.h +++ b/src/corelib/text/qbytearray_p.h @@ -52,7 +52,7 @@ // #include -#include "qtools_p.h" +#include "private/qtools_p.h" QT_BEGIN_NAMESPACE diff --git a/src/corelib/tools/qbytearraylist.cpp b/src/corelib/text/qbytearraylist.cpp similarity index 100% rename from src/corelib/tools/qbytearraylist.cpp rename to src/corelib/text/qbytearraylist.cpp diff --git a/src/corelib/tools/qbytearraylist.h b/src/corelib/text/qbytearraylist.h similarity index 100% rename from src/corelib/tools/qbytearraylist.h rename to src/corelib/text/qbytearraylist.h diff --git a/src/corelib/tools/qbytearraymatcher.cpp b/src/corelib/text/qbytearraymatcher.cpp similarity index 100% rename from src/corelib/tools/qbytearraymatcher.cpp rename to src/corelib/text/qbytearraymatcher.cpp diff --git a/src/corelib/tools/qbytearraymatcher.h b/src/corelib/text/qbytearraymatcher.h similarity index 100% rename from src/corelib/tools/qbytearraymatcher.h rename to src/corelib/text/qbytearraymatcher.h diff --git a/src/corelib/tools/qbytedata_p.h b/src/corelib/text/qbytedata_p.h similarity index 100% rename from src/corelib/tools/qbytedata_p.h rename to src/corelib/text/qbytedata_p.h diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/text/qchar.cpp similarity index 100% rename from src/corelib/tools/qchar.cpp rename to src/corelib/text/qchar.cpp diff --git a/src/corelib/tools/qchar.h b/src/corelib/text/qchar.h similarity index 100% rename from src/corelib/tools/qchar.h rename to src/corelib/text/qchar.h diff --git a/src/corelib/tools/qcollator.cpp b/src/corelib/text/qcollator.cpp similarity index 100% rename from src/corelib/tools/qcollator.cpp rename to src/corelib/text/qcollator.cpp diff --git a/src/corelib/tools/qcollator.h b/src/corelib/text/qcollator.h similarity index 100% rename from src/corelib/tools/qcollator.h rename to src/corelib/text/qcollator.h diff --git a/src/corelib/tools/qcollator_icu.cpp b/src/corelib/text/qcollator_icu.cpp similarity index 100% rename from src/corelib/tools/qcollator_icu.cpp rename to src/corelib/text/qcollator_icu.cpp diff --git a/src/corelib/tools/qcollator_macx.cpp b/src/corelib/text/qcollator_macx.cpp similarity index 100% rename from src/corelib/tools/qcollator_macx.cpp rename to src/corelib/text/qcollator_macx.cpp diff --git a/src/corelib/tools/qcollator_p.h b/src/corelib/text/qcollator_p.h similarity index 100% rename from src/corelib/tools/qcollator_p.h rename to src/corelib/text/qcollator_p.h diff --git a/src/corelib/tools/qcollator_posix.cpp b/src/corelib/text/qcollator_posix.cpp similarity index 100% rename from src/corelib/tools/qcollator_posix.cpp rename to src/corelib/text/qcollator_posix.cpp diff --git a/src/corelib/tools/qcollator_win.cpp b/src/corelib/text/qcollator_win.cpp similarity index 100% rename from src/corelib/tools/qcollator_win.cpp rename to src/corelib/text/qcollator_win.cpp diff --git a/src/corelib/tools/qdoublescanprint_p.h b/src/corelib/text/qdoublescanprint_p.h similarity index 100% rename from src/corelib/tools/qdoublescanprint_p.h rename to src/corelib/text/qdoublescanprint_p.h diff --git a/src/corelib/tools/qharfbuzz.cpp b/src/corelib/text/qharfbuzz.cpp similarity index 100% rename from src/corelib/tools/qharfbuzz.cpp rename to src/corelib/text/qharfbuzz.cpp diff --git a/src/corelib/tools/qharfbuzz_p.h b/src/corelib/text/qharfbuzz_p.h similarity index 100% rename from src/corelib/tools/qharfbuzz_p.h rename to src/corelib/text/qharfbuzz_p.h diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/text/qlocale.cpp similarity index 100% rename from src/corelib/tools/qlocale.cpp rename to src/corelib/text/qlocale.cpp diff --git a/src/corelib/tools/qlocale.h b/src/corelib/text/qlocale.h similarity index 100% rename from src/corelib/tools/qlocale.h rename to src/corelib/text/qlocale.h diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/text/qlocale.qdoc similarity index 100% rename from src/corelib/tools/qlocale.qdoc rename to src/corelib/text/qlocale.qdoc diff --git a/src/corelib/tools/qlocale_data_p.h b/src/corelib/text/qlocale_data_p.h similarity index 100% rename from src/corelib/tools/qlocale_data_p.h rename to src/corelib/text/qlocale_data_p.h diff --git a/src/corelib/tools/qlocale_icu.cpp b/src/corelib/text/qlocale_icu.cpp similarity index 100% rename from src/corelib/tools/qlocale_icu.cpp rename to src/corelib/text/qlocale_icu.cpp diff --git a/src/corelib/tools/qlocale_mac.mm b/src/corelib/text/qlocale_mac.mm similarity index 100% rename from src/corelib/tools/qlocale_mac.mm rename to src/corelib/text/qlocale_mac.mm diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/text/qlocale_p.h similarity index 100% rename from src/corelib/tools/qlocale_p.h rename to src/corelib/text/qlocale_p.h diff --git a/src/corelib/tools/qlocale_tools.cpp b/src/corelib/text/qlocale_tools.cpp similarity index 100% rename from src/corelib/tools/qlocale_tools.cpp rename to src/corelib/text/qlocale_tools.cpp diff --git a/src/corelib/tools/qlocale_tools_p.h b/src/corelib/text/qlocale_tools_p.h similarity index 100% rename from src/corelib/tools/qlocale_tools_p.h rename to src/corelib/text/qlocale_tools_p.h diff --git a/src/corelib/tools/qlocale_unix.cpp b/src/corelib/text/qlocale_unix.cpp similarity index 100% rename from src/corelib/tools/qlocale_unix.cpp rename to src/corelib/text/qlocale_unix.cpp diff --git a/src/corelib/tools/qlocale_win.cpp b/src/corelib/text/qlocale_win.cpp similarity index 100% rename from src/corelib/tools/qlocale_win.cpp rename to src/corelib/text/qlocale_win.cpp diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/text/qregexp.cpp similarity index 100% rename from src/corelib/tools/qregexp.cpp rename to src/corelib/text/qregexp.cpp diff --git a/src/corelib/tools/qregexp.h b/src/corelib/text/qregexp.h similarity index 100% rename from src/corelib/tools/qregexp.h rename to src/corelib/text/qregexp.h diff --git a/src/corelib/tools/qregularexpression.cpp b/src/corelib/text/qregularexpression.cpp similarity index 100% rename from src/corelib/tools/qregularexpression.cpp rename to src/corelib/text/qregularexpression.cpp diff --git a/src/corelib/tools/qregularexpression.h b/src/corelib/text/qregularexpression.h similarity index 100% rename from src/corelib/tools/qregularexpression.h rename to src/corelib/text/qregularexpression.h diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/text/qstring.cpp similarity index 99% rename from src/corelib/tools/qstring.cpp rename to src/corelib/text/qstring.cpp index 12506afdef..2a98b169f3 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -49,8 +49,8 @@ #include #endif #include -#include -#include "qsimd_p.h" +#include "qlocale_tools_p.h" +#include "private/qsimd_p.h" #include #include #include @@ -59,7 +59,6 @@ #include "qstringbuilder.h" #include "qstringmatcher.h" #include "qvarlengtharray.h" -#include "qtools_p.h" #include "qdebug.h" #include "qendian.h" #include "qcollator.h" diff --git a/src/corelib/tools/qstring.h b/src/corelib/text/qstring.h similarity index 100% rename from src/corelib/tools/qstring.h rename to src/corelib/text/qstring.h diff --git a/src/corelib/tools/qstring_compat.cpp b/src/corelib/text/qstring_compat.cpp similarity index 100% rename from src/corelib/tools/qstring_compat.cpp rename to src/corelib/text/qstring_compat.cpp diff --git a/src/corelib/tools/qstring_mips_dsp_asm.S b/src/corelib/text/qstring_mips_dsp_asm.S similarity index 100% rename from src/corelib/tools/qstring_mips_dsp_asm.S rename to src/corelib/text/qstring_mips_dsp_asm.S diff --git a/src/corelib/tools/qstringalgorithms.h b/src/corelib/text/qstringalgorithms.h similarity index 100% rename from src/corelib/tools/qstringalgorithms.h rename to src/corelib/text/qstringalgorithms.h diff --git a/src/corelib/tools/qstringalgorithms_p.h b/src/corelib/text/qstringalgorithms_p.h similarity index 100% rename from src/corelib/tools/qstringalgorithms_p.h rename to src/corelib/text/qstringalgorithms_p.h diff --git a/src/corelib/tools/qstringbuilder.cpp b/src/corelib/text/qstringbuilder.cpp similarity index 100% rename from src/corelib/tools/qstringbuilder.cpp rename to src/corelib/text/qstringbuilder.cpp diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/text/qstringbuilder.h similarity index 100% rename from src/corelib/tools/qstringbuilder.h rename to src/corelib/text/qstringbuilder.h diff --git a/src/corelib/tools/qstringiterator.qdoc b/src/corelib/text/qstringiterator.qdoc similarity index 100% rename from src/corelib/tools/qstringiterator.qdoc rename to src/corelib/text/qstringiterator.qdoc diff --git a/src/corelib/tools/qstringiterator_p.h b/src/corelib/text/qstringiterator_p.h similarity index 100% rename from src/corelib/tools/qstringiterator_p.h rename to src/corelib/text/qstringiterator_p.h diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/text/qstringlist.cpp similarity index 100% rename from src/corelib/tools/qstringlist.cpp rename to src/corelib/text/qstringlist.cpp diff --git a/src/corelib/tools/qstringlist.h b/src/corelib/text/qstringlist.h similarity index 100% rename from src/corelib/tools/qstringlist.h rename to src/corelib/text/qstringlist.h diff --git a/src/corelib/tools/qstringliteral.h b/src/corelib/text/qstringliteral.h similarity index 100% rename from src/corelib/tools/qstringliteral.h rename to src/corelib/text/qstringliteral.h diff --git a/src/corelib/tools/qstringmatcher.cpp b/src/corelib/text/qstringmatcher.cpp similarity index 100% rename from src/corelib/tools/qstringmatcher.cpp rename to src/corelib/text/qstringmatcher.cpp diff --git a/src/corelib/tools/qstringmatcher.h b/src/corelib/text/qstringmatcher.h similarity index 100% rename from src/corelib/tools/qstringmatcher.h rename to src/corelib/text/qstringmatcher.h diff --git a/src/corelib/tools/qstringview.cpp b/src/corelib/text/qstringview.cpp similarity index 100% rename from src/corelib/tools/qstringview.cpp rename to src/corelib/text/qstringview.cpp diff --git a/src/corelib/tools/qstringview.h b/src/corelib/text/qstringview.h similarity index 100% rename from src/corelib/tools/qstringview.h rename to src/corelib/text/qstringview.h diff --git a/src/corelib/tools/qt_attribution.json b/src/corelib/text/qt_attribution.json similarity index 100% rename from src/corelib/tools/qt_attribution.json rename to src/corelib/text/qt_attribution.json diff --git a/src/corelib/tools/qtextboundaryfinder.cpp b/src/corelib/text/qtextboundaryfinder.cpp similarity index 100% rename from src/corelib/tools/qtextboundaryfinder.cpp rename to src/corelib/text/qtextboundaryfinder.cpp diff --git a/src/corelib/tools/qtextboundaryfinder.h b/src/corelib/text/qtextboundaryfinder.h similarity index 100% rename from src/corelib/tools/qtextboundaryfinder.h rename to src/corelib/text/qtextboundaryfinder.h diff --git a/src/corelib/tools/qunicodetables.cpp b/src/corelib/text/qunicodetables.cpp similarity index 100% rename from src/corelib/tools/qunicodetables.cpp rename to src/corelib/text/qunicodetables.cpp diff --git a/src/corelib/tools/qunicodetables_p.h b/src/corelib/text/qunicodetables_p.h similarity index 100% rename from src/corelib/tools/qunicodetables_p.h rename to src/corelib/text/qunicodetables_p.h diff --git a/src/corelib/tools/qunicodetools.cpp b/src/corelib/text/qunicodetools.cpp similarity index 100% rename from src/corelib/tools/qunicodetools.cpp rename to src/corelib/text/qunicodetools.cpp diff --git a/src/corelib/tools/qunicodetools_p.h b/src/corelib/text/qunicodetools_p.h similarity index 100% rename from src/corelib/tools/qunicodetools_p.h rename to src/corelib/text/qunicodetools_p.h diff --git a/src/corelib/tools/qvsnprintf.cpp b/src/corelib/text/qvsnprintf.cpp similarity index 100% rename from src/corelib/tools/qvsnprintf.cpp rename to src/corelib/text/qvsnprintf.cpp diff --git a/src/corelib/text/text.pri b/src/corelib/text/text.pri new file mode 100644 index 0000000000..e279679655 --- /dev/null +++ b/src/corelib/text/text.pri @@ -0,0 +1,100 @@ +# Qt text / string / character / unicode / byte array module + +HEADERS += \ + text/qbytearray.h \ + text/qbytearray_p.h \ + text/qbytearraylist.h \ + text/qbytearraymatcher.h \ + text/qbytedata_p.h \ + text/qchar.h \ + text/qcollator.h \ + text/qcollator_p.h \ + tools/qdoublescanprint_p.h \ + text/qlocale.h \ + text/qlocale_p.h \ + text/qlocale_tools_p.h \ + text/qlocale_data_p.h \ + text/qregexp.h \ + text/qstring.h \ + text/qstringalgorithms.h \ + text/qstringalgorithms_p.h \ + text/qstringbuilder.h \ + text/qstringiterator_p.h \ + text/qstringlist.h \ + text/qstringliteral.h \ + text/qstringmatcher.h \ + text/qstringview.h \ + text/qtextboundaryfinder.h \ + text/qunicodetables_p.h \ + text/qunicodetools_p.h + + +SOURCES += \ + text/qbytearray.cpp \ + text/qbytearraylist.cpp \ + text/qbytearraymatcher.cpp \ + text/qcollator.cpp \ + text/qlocale.cpp \ + text/qlocale_tools.cpp \ + text/qregexp.cpp \ + text/qstring.cpp \ + text/qstringbuilder.cpp \ + text/qstringlist.cpp \ + text/qstringview.cpp \ + text/qtextboundaryfinder.cpp \ + text/qunicodetools.cpp \ + text/qvsnprintf.cpp + +NO_PCH_SOURCES += text/qstring_compat.cpp +false: SOURCES += $$NO_PCH_SOURCES # Hack for QtCreator + +!nacl:macos: { + SOURCES += text/qlocale_mac.mm +} +else:unix { + SOURCES += text/qlocale_unix.cpp +} +else:win32 { + SOURCES += text/qlocale_win.cpp +} else:integrity { + SOURCES += text/qlocale_unix.cpp +} + +qtConfig(icu) { + QMAKE_USE_PRIVATE += icu + + SOURCES += text/qlocale_icu.cpp \ + text/qcollator_icu.cpp +} else: win32 { + SOURCES += text/qcollator_win.cpp +} else: macos { + SOURCES += text/qcollator_macx.cpp +} else { + SOURCES += text/qcollator_posix.cpp +} + +qtConfig(regularexpression) { + QMAKE_USE_PRIVATE += pcre2 + + HEADERS += \ + text/qregularexpression.h + SOURCES += text/qregularexpression.cpp +} + +INCLUDEPATH += ../3rdparty/harfbuzz/src +HEADERS += ../3rdparty/harfbuzz/src/harfbuzz.h +SOURCES += ../3rdparty/harfbuzz/src/harfbuzz-buffer.c \ + ../3rdparty/harfbuzz/src/harfbuzz-gdef.c \ + ../3rdparty/harfbuzz/src/harfbuzz-gsub.c \ + ../3rdparty/harfbuzz/src/harfbuzz-gpos.c \ + ../3rdparty/harfbuzz/src/harfbuzz-impl.c \ + ../3rdparty/harfbuzz/src/harfbuzz-open.c \ + ../3rdparty/harfbuzz/src/harfbuzz-stream.c \ + ../3rdparty/harfbuzz/src/harfbuzz-shaper-all.cpp \ + text/qharfbuzz.cpp +HEADERS += text/qharfbuzz_p.h + +TR_EXCLUDE += ../3rdparty/* + +# MIPS DSP +MIPS_DSP_ASM += text/qstring_mips_dsp_asm.S diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index 52eddd5d6b..a2236f90f2 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -8,19 +8,10 @@ HEADERS += \ tools/qarraydataops.h \ tools/qarraydatapointer.h \ tools/qbitarray.h \ - tools/qbytearray.h \ - tools/qbytearray_p.h \ - tools/qbytearraylist.h \ - tools/qbytearraymatcher.h \ - tools/qbytedata_p.h \ tools/qcache.h \ - tools/qchar.h \ - tools/qcollator.h \ - tools/qcollator_p.h \ tools/qcontainerfwd.h \ tools/qcontainertools_impl.h \ tools/qcryptographichash.h \ - tools/qdoublescanprint_p.h \ tools/qeasingcurve.h \ tools/qfreelist_p.h \ tools/qhash.h \ @@ -29,10 +20,6 @@ HEADERS += \ tools/qline.h \ tools/qlinkedlist.h \ tools/qlist.h \ - tools/qlocale.h \ - tools/qlocale_p.h \ - tools/qlocale_tools_p.h \ - tools/qlocale_data_p.h \ tools/qmakearray_p.h \ tools/qmap.h \ tools/qmargins.h \ @@ -43,7 +30,6 @@ HEADERS += \ tools/qpoint.h \ tools/qqueue.h \ tools/qrect.h \ - tools/qregexp.h \ tools/qringbuffer_p.h \ tools/qrefcount.h \ tools/qscopeguard.h \ @@ -57,20 +43,8 @@ HEADERS += \ tools/qsimd_p.h \ tools/qsize.h \ tools/qstack.h \ - tools/qstring.h \ - tools/qstringalgorithms.h \ - tools/qstringalgorithms_p.h \ - tools/qstringbuilder.h \ - tools/qstringiterator_p.h \ - tools/qstringlist.h \ - tools/qstringliteral.h \ - tools/qstringmatcher.h \ - tools/qstringview.h \ - tools/qtextboundaryfinder.h \ tools/qtimeline.h \ tools/qtools_p.h \ - tools/qunicodetables_p.h \ - tools/qunicodetools_p.h \ tools/qvarlengtharray.h \ tools/qvector.h \ tools/qversionnumber.h @@ -79,10 +53,6 @@ HEADERS += \ SOURCES += \ tools/qarraydata.cpp \ tools/qbitarray.cpp \ - tools/qbytearray.cpp \ - tools/qbytearraylist.cpp \ - tools/qbytearraymatcher.cpp \ - tools/qcollator.cpp \ tools/qcryptographichash.cpp \ tools/qeasingcurve.cpp \ tools/qfreelist.cpp \ @@ -90,47 +60,24 @@ SOURCES += \ tools/qline.cpp \ tools/qlinkedlist.cpp \ tools/qlist.cpp \ - tools/qlocale.cpp \ - tools/qlocale_tools.cpp \ tools/qpoint.cpp \ tools/qmap.cpp \ tools/qmargins.cpp \ tools/qmessageauthenticationcode.cpp \ tools/qcontiguouscache.cpp \ tools/qrect.cpp \ - tools/qregexp.cpp \ tools/qrefcount.cpp \ tools/qringbuffer.cpp \ tools/qshareddata.cpp \ tools/qsharedpointer.cpp \ tools/qsimd.cpp \ tools/qsize.cpp \ - tools/qstring.cpp \ - tools/qstringbuilder.cpp \ - tools/qstringlist.cpp \ - tools/qstringview.cpp \ - tools/qtextboundaryfinder.cpp \ tools/qtimeline.cpp \ - tools/qunicodetools.cpp \ - tools/qvsnprintf.cpp \ tools/qversionnumber.cpp -NO_PCH_SOURCES = tools/qstring_compat.cpp msvc: NO_PCH_SOURCES += tools/qvector_msvc.cpp false: SOURCES += $$NO_PCH_SOURCES # Hack for QtCreator -!nacl:mac: { - SOURCES += tools/qlocale_mac.mm -} -else:unix { - SOURCES += tools/qlocale_unix.cpp -} -else:win32 { - SOURCES += tools/qlocale_win.cpp -} else:integrity { - SOURCES += tools/qlocale_unix.cpp -} - qtConfig(system-zlib) { include($$PWD/../../3rdparty/zlib_dependency.pri) } else { @@ -138,27 +85,6 @@ qtConfig(system-zlib) { include($$PWD/../../3rdparty/zlib.pri) } -qtConfig(icu) { - QMAKE_USE_PRIVATE += icu - - SOURCES += tools/qlocale_icu.cpp \ - tools/qcollator_icu.cpp -} else: win32 { - SOURCES += tools/qcollator_win.cpp -} else: macx { - SOURCES += tools/qcollator_macx.cpp -} else { - SOURCES += tools/qcollator_posix.cpp -} - -qtConfig(regularexpression) { - QMAKE_USE_PRIVATE += pcre2 - - HEADERS += \ - tools/qregularexpression.h - SOURCES += tools/qregularexpression.cpp -} - qtConfig(commandlineparser) { HEADERS += \ tools/qcommandlineoption.h \ @@ -168,19 +94,6 @@ qtConfig(commandlineparser) { tools/qcommandlineparser.cpp } -INCLUDEPATH += ../3rdparty/harfbuzz/src -HEADERS += ../3rdparty/harfbuzz/src/harfbuzz.h -SOURCES += ../3rdparty/harfbuzz/src/harfbuzz-buffer.c \ - ../3rdparty/harfbuzz/src/harfbuzz-gdef.c \ - ../3rdparty/harfbuzz/src/harfbuzz-gsub.c \ - ../3rdparty/harfbuzz/src/harfbuzz-gpos.c \ - ../3rdparty/harfbuzz/src/harfbuzz-impl.c \ - ../3rdparty/harfbuzz/src/harfbuzz-open.c \ - ../3rdparty/harfbuzz/src/harfbuzz-stream.c \ - ../3rdparty/harfbuzz/src/harfbuzz-shaper-all.cpp \ - tools/qharfbuzz.cpp -HEADERS += tools/qharfbuzz_p.h - INCLUDEPATH += ../3rdparty/md5 \ ../3rdparty/md4 \ ../3rdparty/sha3 @@ -197,5 +110,4 @@ unix:!macx-icc:!vxworks:!haiku:!integrity:!wasm: LIBS_PRIVATE += -lm TR_EXCLUDE += ../3rdparty/* # MIPS DSP -MIPS_DSP_ASM += tools/qstring_mips_dsp_asm.S MIPS_DSP_HEADERS += ../gui/painting/qt_mips_asm_dsp_p.h diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 757460393e..f4d930babb 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -74,32 +74,32 @@ SOURCES += \ ../../corelib/serialization/qtextstream.cpp \ ../../corelib/serialization/qxmlutils.cpp \ ../../corelib/serialization/qxmlstream.cpp \ + ../../corelib/text/qbytearray.cpp \ + ../../corelib/text/qbytearraymatcher.cpp \ + ../../corelib/text/qlocale.cpp \ + ../../corelib/text/qlocale_tools.cpp \ + ../../corelib/text/qregexp.cpp \ + ../../corelib/text/qstring.cpp \ + ../../corelib/text/qstringbuilder.cpp \ + ../../corelib/text/qstring_compat.cpp \ + ../../corelib/text/qstringlist.cpp \ + ../../corelib/text/qstringview.cpp \ + ../../corelib/text/qvsnprintf.cpp \ ../../corelib/time/qdatetime.cpp \ - ../../corelib/tools/qbitarray.cpp \ - ../../corelib/tools/qbytearray.cpp \ ../../corelib/tools/qarraydata.cpp \ - ../../corelib/tools/qbytearraymatcher.cpp \ + ../../corelib/tools/qbitarray.cpp \ ../../corelib/tools/qcommandlineparser.cpp \ ../../corelib/tools/qcommandlineoption.cpp \ ../../corelib/tools/qcryptographichash.cpp \ ../../corelib/tools/qhash.cpp \ ../../corelib/tools/qlist.cpp \ - ../../corelib/tools/qlocale.cpp \ - ../../corelib/tools/qlocale_tools.cpp \ ../../corelib/tools/qmap.cpp \ - ../../corelib/tools/qregexp.cpp \ ../../corelib/tools/qringbuffer.cpp \ ../../corelib/tools/qpoint.cpp \ ../../corelib/tools/qrect.cpp \ ../../corelib/tools/qsize.cpp \ ../../corelib/tools/qline.cpp \ - ../../corelib/tools/qstring.cpp \ - ../../corelib/tools/qstringbuilder.cpp \ - ../../corelib/tools/qstring_compat.cpp \ - ../../corelib/tools/qstringlist.cpp \ - ../../corelib/tools/qstringview.cpp \ ../../corelib/tools/qversionnumber.cpp \ - ../../corelib/tools/qvsnprintf.cpp \ ../../xml/dom/qdom.cpp \ ../../xml/sax/qxml.cpp diff --git a/tests/auto/corelib/corelib.pro b/tests/auto/corelib/corelib.pro index 1d76e1549b..d696e174aa 100644 --- a/tests/auto/corelib/corelib.pro +++ b/tests/auto/corelib/corelib.pro @@ -13,6 +13,7 @@ SUBDIRS = \ plugin \ serialization \ statemachine \ + text \ thread \ time \ tools diff --git a/tests/auto/corelib/tools/qbytearray/.gitattributes b/tests/auto/corelib/text/qbytearray/.gitattributes similarity index 100% rename from tests/auto/corelib/tools/qbytearray/.gitattributes rename to tests/auto/corelib/text/qbytearray/.gitattributes diff --git a/tests/auto/corelib/tools/qbytearray/.gitignore b/tests/auto/corelib/text/qbytearray/.gitignore similarity index 100% rename from tests/auto/corelib/tools/qbytearray/.gitignore rename to tests/auto/corelib/text/qbytearray/.gitignore diff --git a/tests/auto/corelib/tools/qbytearray/android_testdata.qrc b/tests/auto/corelib/text/qbytearray/android_testdata.qrc similarity index 100% rename from tests/auto/corelib/tools/qbytearray/android_testdata.qrc rename to tests/auto/corelib/text/qbytearray/android_testdata.qrc diff --git a/tests/auto/corelib/tools/qbytearray/qbytearray.pro b/tests/auto/corelib/text/qbytearray/qbytearray.pro similarity index 100% rename from tests/auto/corelib/tools/qbytearray/qbytearray.pro rename to tests/auto/corelib/text/qbytearray/qbytearray.pro diff --git a/tests/auto/corelib/tools/qbytearray/rfc3252.txt b/tests/auto/corelib/text/qbytearray/rfc3252.txt similarity index 100% rename from tests/auto/corelib/tools/qbytearray/rfc3252.txt rename to tests/auto/corelib/text/qbytearray/rfc3252.txt diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp similarity index 100% rename from tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp rename to tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray_mac.mm b/tests/auto/corelib/text/qbytearray/tst_qbytearray_mac.mm similarity index 100% rename from tests/auto/corelib/tools/qbytearray/tst_qbytearray_mac.mm rename to tests/auto/corelib/text/qbytearray/tst_qbytearray_mac.mm diff --git a/tests/auto/corelib/tools/qbytearraylist/qbytearraylist.pro b/tests/auto/corelib/text/qbytearraylist/qbytearraylist.pro similarity index 100% rename from tests/auto/corelib/tools/qbytearraylist/qbytearraylist.pro rename to tests/auto/corelib/text/qbytearraylist/qbytearraylist.pro diff --git a/tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp b/tests/auto/corelib/text/qbytearraylist/tst_qbytearraylist.cpp similarity index 100% rename from tests/auto/corelib/tools/qbytearraylist/tst_qbytearraylist.cpp rename to tests/auto/corelib/text/qbytearraylist/tst_qbytearraylist.cpp diff --git a/tests/auto/corelib/tools/qbytearraymatcher/qbytearraymatcher.pro b/tests/auto/corelib/text/qbytearraymatcher/qbytearraymatcher.pro similarity index 100% rename from tests/auto/corelib/tools/qbytearraymatcher/qbytearraymatcher.pro rename to tests/auto/corelib/text/qbytearraymatcher/qbytearraymatcher.pro diff --git a/tests/auto/corelib/tools/qbytearraymatcher/tst_qbytearraymatcher.cpp b/tests/auto/corelib/text/qbytearraymatcher/tst_qbytearraymatcher.cpp similarity index 100% rename from tests/auto/corelib/tools/qbytearraymatcher/tst_qbytearraymatcher.cpp rename to tests/auto/corelib/text/qbytearraymatcher/tst_qbytearraymatcher.cpp diff --git a/tests/auto/corelib/tools/qbytedatabuffer/.gitignore b/tests/auto/corelib/text/qbytedatabuffer/.gitignore similarity index 100% rename from tests/auto/corelib/tools/qbytedatabuffer/.gitignore rename to tests/auto/corelib/text/qbytedatabuffer/.gitignore diff --git a/tests/auto/corelib/tools/qbytedatabuffer/qbytedatabuffer.pro b/tests/auto/corelib/text/qbytedatabuffer/qbytedatabuffer.pro similarity index 100% rename from tests/auto/corelib/tools/qbytedatabuffer/qbytedatabuffer.pro rename to tests/auto/corelib/text/qbytedatabuffer/qbytedatabuffer.pro diff --git a/tests/auto/corelib/tools/qbytedatabuffer/tst_qbytedatabuffer.cpp b/tests/auto/corelib/text/qbytedatabuffer/tst_qbytedatabuffer.cpp similarity index 100% rename from tests/auto/corelib/tools/qbytedatabuffer/tst_qbytedatabuffer.cpp rename to tests/auto/corelib/text/qbytedatabuffer/tst_qbytedatabuffer.cpp diff --git a/tests/auto/corelib/tools/qchar/.gitignore b/tests/auto/corelib/text/qchar/.gitignore similarity index 100% rename from tests/auto/corelib/tools/qchar/.gitignore rename to tests/auto/corelib/text/qchar/.gitignore diff --git a/tests/auto/corelib/tools/qchar/data/NormalizationTest.txt b/tests/auto/corelib/text/qchar/data/NormalizationTest.txt similarity index 100% rename from tests/auto/corelib/tools/qchar/data/NormalizationTest.txt rename to tests/auto/corelib/text/qchar/data/NormalizationTest.txt diff --git a/tests/auto/corelib/tools/qchar/qchar.pro b/tests/auto/corelib/text/qchar/qchar.pro similarity index 100% rename from tests/auto/corelib/tools/qchar/qchar.pro rename to tests/auto/corelib/text/qchar/qchar.pro diff --git a/tests/auto/corelib/tools/qchar/testdata.qrc b/tests/auto/corelib/text/qchar/testdata.qrc similarity index 100% rename from tests/auto/corelib/tools/qchar/testdata.qrc rename to tests/auto/corelib/text/qchar/testdata.qrc diff --git a/tests/auto/corelib/tools/qchar/tst_qchar.cpp b/tests/auto/corelib/text/qchar/tst_qchar.cpp similarity index 100% rename from tests/auto/corelib/tools/qchar/tst_qchar.cpp rename to tests/auto/corelib/text/qchar/tst_qchar.cpp diff --git a/tests/auto/corelib/tools/qcollator/qcollator.pro b/tests/auto/corelib/text/qcollator/qcollator.pro similarity index 100% rename from tests/auto/corelib/tools/qcollator/qcollator.pro rename to tests/auto/corelib/text/qcollator/qcollator.pro diff --git a/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp b/tests/auto/corelib/text/qcollator/tst_qcollator.cpp similarity index 100% rename from tests/auto/corelib/tools/qcollator/tst_qcollator.cpp rename to tests/auto/corelib/text/qcollator/tst_qcollator.cpp diff --git a/tests/auto/corelib/tools/qlatin1string/.gitignore b/tests/auto/corelib/text/qlatin1string/.gitignore similarity index 100% rename from tests/auto/corelib/tools/qlatin1string/.gitignore rename to tests/auto/corelib/text/qlatin1string/.gitignore diff --git a/tests/auto/corelib/tools/qlatin1string/qlatin1string.pro b/tests/auto/corelib/text/qlatin1string/qlatin1string.pro similarity index 100% rename from tests/auto/corelib/tools/qlatin1string/qlatin1string.pro rename to tests/auto/corelib/text/qlatin1string/qlatin1string.pro diff --git a/tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp b/tests/auto/corelib/text/qlatin1string/tst_qlatin1string.cpp similarity index 100% rename from tests/auto/corelib/tools/qlatin1string/tst_qlatin1string.cpp rename to tests/auto/corelib/text/qlatin1string/tst_qlatin1string.cpp diff --git a/tests/auto/corelib/tools/qlocale/.gitignore b/tests/auto/corelib/text/qlocale/.gitignore similarity index 100% rename from tests/auto/corelib/tools/qlocale/.gitignore rename to tests/auto/corelib/text/qlocale/.gitignore diff --git a/tests/auto/corelib/tools/qlocale/qlocale.pro b/tests/auto/corelib/text/qlocale/qlocale.pro similarity index 100% rename from tests/auto/corelib/tools/qlocale/qlocale.pro rename to tests/auto/corelib/text/qlocale/qlocale.pro diff --git a/tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.cpp b/tests/auto/corelib/text/qlocale/syslocaleapp/syslocaleapp.cpp similarity index 100% rename from tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.cpp rename to tests/auto/corelib/text/qlocale/syslocaleapp/syslocaleapp.cpp diff --git a/tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.pro b/tests/auto/corelib/text/qlocale/syslocaleapp/syslocaleapp.pro similarity index 100% rename from tests/auto/corelib/tools/qlocale/syslocaleapp/syslocaleapp.pro rename to tests/auto/corelib/text/qlocale/syslocaleapp/syslocaleapp.pro diff --git a/tests/auto/corelib/tools/qlocale/test/test.pro b/tests/auto/corelib/text/qlocale/test/test.pro similarity index 100% rename from tests/auto/corelib/tools/qlocale/test/test.pro rename to tests/auto/corelib/text/qlocale/test/test.pro diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp similarity index 100% rename from tests/auto/corelib/tools/qlocale/tst_qlocale.cpp rename to tests/auto/corelib/text/qlocale/tst_qlocale.cpp diff --git a/tests/auto/corelib/tools/qregexp/.gitignore b/tests/auto/corelib/text/qregexp/.gitignore similarity index 100% rename from tests/auto/corelib/tools/qregexp/.gitignore rename to tests/auto/corelib/text/qregexp/.gitignore diff --git a/tests/auto/corelib/tools/qregexp/qregexp.pro b/tests/auto/corelib/text/qregexp/qregexp.pro similarity index 100% rename from tests/auto/corelib/tools/qregexp/qregexp.pro rename to tests/auto/corelib/text/qregexp/qregexp.pro diff --git a/tests/auto/corelib/tools/qregexp/tst_qregexp.cpp b/tests/auto/corelib/text/qregexp/tst_qregexp.cpp similarity index 100% rename from tests/auto/corelib/tools/qregexp/tst_qregexp.cpp rename to tests/auto/corelib/text/qregexp/tst_qregexp.cpp diff --git a/tests/auto/corelib/tools/qregularexpression/.gitignore b/tests/auto/corelib/text/qregularexpression/.gitignore similarity index 100% rename from tests/auto/corelib/tools/qregularexpression/.gitignore rename to tests/auto/corelib/text/qregularexpression/.gitignore diff --git a/tests/auto/corelib/tools/qregularexpression/qregularexpression.pro b/tests/auto/corelib/text/qregularexpression/qregularexpression.pro similarity index 100% rename from tests/auto/corelib/tools/qregularexpression/qregularexpression.pro rename to tests/auto/corelib/text/qregularexpression/qregularexpression.pro diff --git a/tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp similarity index 100% rename from tests/auto/corelib/tools/qregularexpression/tst_qregularexpression.cpp rename to tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp diff --git a/tests/auto/corelib/tools/qstring/.gitignore b/tests/auto/corelib/text/qstring/.gitignore similarity index 100% rename from tests/auto/corelib/tools/qstring/.gitignore rename to tests/auto/corelib/text/qstring/.gitignore diff --git a/tests/auto/corelib/tools/qstring/double_data.h b/tests/auto/corelib/text/qstring/double_data.h similarity index 100% rename from tests/auto/corelib/tools/qstring/double_data.h rename to tests/auto/corelib/text/qstring/double_data.h diff --git a/tests/auto/corelib/tools/qstring/qstring.pro b/tests/auto/corelib/text/qstring/qstring.pro similarity index 100% rename from tests/auto/corelib/tools/qstring/qstring.pro rename to tests/auto/corelib/text/qstring/qstring.pro diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp similarity index 100% rename from tests/auto/corelib/tools/qstring/tst_qstring.cpp rename to tests/auto/corelib/text/qstring/tst_qstring.cpp diff --git a/tests/auto/corelib/tools/qstring/tst_qstring_mac.mm b/tests/auto/corelib/text/qstring/tst_qstring_mac.mm similarity index 100% rename from tests/auto/corelib/tools/qstring/tst_qstring_mac.mm rename to tests/auto/corelib/text/qstring/tst_qstring_mac.mm diff --git a/tests/auto/corelib/tools/qstring_no_cast_from_bytearray/qstring_no_cast_from_bytearray.pro b/tests/auto/corelib/text/qstring_no_cast_from_bytearray/qstring_no_cast_from_bytearray.pro similarity index 100% rename from tests/auto/corelib/tools/qstring_no_cast_from_bytearray/qstring_no_cast_from_bytearray.pro rename to tests/auto/corelib/text/qstring_no_cast_from_bytearray/qstring_no_cast_from_bytearray.pro diff --git a/tests/auto/corelib/tools/qstring_no_cast_from_bytearray/tst_qstring_no_cast_from_bytearray.cpp b/tests/auto/corelib/text/qstring_no_cast_from_bytearray/tst_qstring_no_cast_from_bytearray.cpp similarity index 100% rename from tests/auto/corelib/tools/qstring_no_cast_from_bytearray/tst_qstring_no_cast_from_bytearray.cpp rename to tests/auto/corelib/text/qstring_no_cast_from_bytearray/tst_qstring_no_cast_from_bytearray.cpp diff --git a/tests/auto/corelib/tools/qstringapisymmetry/.gitignore b/tests/auto/corelib/text/qstringapisymmetry/.gitignore similarity index 100% rename from tests/auto/corelib/tools/qstringapisymmetry/.gitignore rename to tests/auto/corelib/text/qstringapisymmetry/.gitignore diff --git a/tests/auto/corelib/tools/qstringapisymmetry/qstringapisymmetry.pro b/tests/auto/corelib/text/qstringapisymmetry/qstringapisymmetry.pro similarity index 100% rename from tests/auto/corelib/tools/qstringapisymmetry/qstringapisymmetry.pro rename to tests/auto/corelib/text/qstringapisymmetry/qstringapisymmetry.pro diff --git a/tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp b/tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp similarity index 100% rename from tests/auto/corelib/tools/qstringapisymmetry/tst_qstringapisymmetry.cpp rename to tests/auto/corelib/text/qstringapisymmetry/tst_qstringapisymmetry.cpp diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder.pro b/tests/auto/corelib/text/qstringbuilder/qstringbuilder.pro similarity index 100% rename from tests/auto/corelib/tools/qstringbuilder/qstringbuilder.pro rename to tests/auto/corelib/text/qstringbuilder/qstringbuilder.pro diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/qstringbuilder1.pro b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/qstringbuilder1.pro similarity index 100% rename from tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/qstringbuilder1.pro rename to tests/auto/corelib/text/qstringbuilder/qstringbuilder1/qstringbuilder1.pro diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp similarity index 100% rename from tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp rename to tests/auto/corelib/text/qstringbuilder/qstringbuilder1/stringbuilder.cpp diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp similarity index 100% rename from tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp rename to tests/auto/corelib/text/qstringbuilder/qstringbuilder1/tst_qstringbuilder1.cpp diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder2/qstringbuilder2.pro b/tests/auto/corelib/text/qstringbuilder/qstringbuilder2/qstringbuilder2.pro similarity index 100% rename from tests/auto/corelib/tools/qstringbuilder/qstringbuilder2/qstringbuilder2.pro rename to tests/auto/corelib/text/qstringbuilder/qstringbuilder2/qstringbuilder2.pro diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp similarity index 100% rename from tests/auto/corelib/tools/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp rename to tests/auto/corelib/text/qstringbuilder/qstringbuilder2/tst_qstringbuilder2.cpp diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder3/qstringbuilder3.pro b/tests/auto/corelib/text/qstringbuilder/qstringbuilder3/qstringbuilder3.pro similarity index 100% rename from tests/auto/corelib/tools/qstringbuilder/qstringbuilder3/qstringbuilder3.pro rename to tests/auto/corelib/text/qstringbuilder/qstringbuilder3/qstringbuilder3.pro diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp similarity index 100% rename from tests/auto/corelib/tools/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp rename to tests/auto/corelib/text/qstringbuilder/qstringbuilder3/tst_qstringbuilder3.cpp diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder4/qstringbuilder4.pro b/tests/auto/corelib/text/qstringbuilder/qstringbuilder4/qstringbuilder4.pro similarity index 100% rename from tests/auto/corelib/tools/qstringbuilder/qstringbuilder4/qstringbuilder4.pro rename to tests/auto/corelib/text/qstringbuilder/qstringbuilder4/qstringbuilder4.pro diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp b/tests/auto/corelib/text/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp similarity index 100% rename from tests/auto/corelib/tools/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp rename to tests/auto/corelib/text/qstringbuilder/qstringbuilder4/tst_qstringbuilder4.cpp diff --git a/tests/auto/corelib/tools/qstringiterator/qstringiterator.pro b/tests/auto/corelib/text/qstringiterator/qstringiterator.pro similarity index 100% rename from tests/auto/corelib/tools/qstringiterator/qstringiterator.pro rename to tests/auto/corelib/text/qstringiterator/qstringiterator.pro diff --git a/tests/auto/corelib/tools/qstringiterator/tst_qstringiterator.cpp b/tests/auto/corelib/text/qstringiterator/tst_qstringiterator.cpp similarity index 100% rename from tests/auto/corelib/tools/qstringiterator/tst_qstringiterator.cpp rename to tests/auto/corelib/text/qstringiterator/tst_qstringiterator.cpp diff --git a/tests/auto/corelib/tools/qstringlist/.gitignore b/tests/auto/corelib/text/qstringlist/.gitignore similarity index 100% rename from tests/auto/corelib/tools/qstringlist/.gitignore rename to tests/auto/corelib/text/qstringlist/.gitignore diff --git a/tests/auto/corelib/tools/qstringlist/qstringlist.pro b/tests/auto/corelib/text/qstringlist/qstringlist.pro similarity index 100% rename from tests/auto/corelib/tools/qstringlist/qstringlist.pro rename to tests/auto/corelib/text/qstringlist/qstringlist.pro diff --git a/tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp b/tests/auto/corelib/text/qstringlist/tst_qstringlist.cpp similarity index 100% rename from tests/auto/corelib/tools/qstringlist/tst_qstringlist.cpp rename to tests/auto/corelib/text/qstringlist/tst_qstringlist.cpp diff --git a/tests/auto/corelib/tools/qstringmatcher/.gitignore b/tests/auto/corelib/text/qstringmatcher/.gitignore similarity index 100% rename from tests/auto/corelib/tools/qstringmatcher/.gitignore rename to tests/auto/corelib/text/qstringmatcher/.gitignore diff --git a/tests/auto/corelib/tools/qstringmatcher/qstringmatcher.pro b/tests/auto/corelib/text/qstringmatcher/qstringmatcher.pro similarity index 100% rename from tests/auto/corelib/tools/qstringmatcher/qstringmatcher.pro rename to tests/auto/corelib/text/qstringmatcher/qstringmatcher.pro diff --git a/tests/auto/corelib/tools/qstringmatcher/tst_qstringmatcher.cpp b/tests/auto/corelib/text/qstringmatcher/tst_qstringmatcher.cpp similarity index 100% rename from tests/auto/corelib/tools/qstringmatcher/tst_qstringmatcher.cpp rename to tests/auto/corelib/text/qstringmatcher/tst_qstringmatcher.cpp diff --git a/tests/auto/corelib/tools/qstringref/qstringref.pro b/tests/auto/corelib/text/qstringref/qstringref.pro similarity index 100% rename from tests/auto/corelib/tools/qstringref/qstringref.pro rename to tests/auto/corelib/text/qstringref/qstringref.pro diff --git a/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp b/tests/auto/corelib/text/qstringref/tst_qstringref.cpp similarity index 100% rename from tests/auto/corelib/tools/qstringref/tst_qstringref.cpp rename to tests/auto/corelib/text/qstringref/tst_qstringref.cpp diff --git a/tests/auto/corelib/tools/qstringview/.gitignore b/tests/auto/corelib/text/qstringview/.gitignore similarity index 100% rename from tests/auto/corelib/tools/qstringview/.gitignore rename to tests/auto/corelib/text/qstringview/.gitignore diff --git a/tests/auto/corelib/tools/qstringview/qstringview.pro b/tests/auto/corelib/text/qstringview/qstringview.pro similarity index 100% rename from tests/auto/corelib/tools/qstringview/qstringview.pro rename to tests/auto/corelib/text/qstringview/qstringview.pro diff --git a/tests/auto/corelib/tools/qstringview/tst_qstringview.cpp b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp similarity index 100% rename from tests/auto/corelib/tools/qstringview/tst_qstringview.cpp rename to tests/auto/corelib/text/qstringview/tst_qstringview.cpp diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/.gitignore b/tests/auto/corelib/text/qtextboundaryfinder/.gitignore similarity index 100% rename from tests/auto/corelib/tools/qtextboundaryfinder/.gitignore rename to tests/auto/corelib/text/qtextboundaryfinder/.gitignore diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/data/GraphemeBreakTest.txt b/tests/auto/corelib/text/qtextboundaryfinder/data/GraphemeBreakTest.txt similarity index 100% rename from tests/auto/corelib/tools/qtextboundaryfinder/data/GraphemeBreakTest.txt rename to tests/auto/corelib/text/qtextboundaryfinder/data/GraphemeBreakTest.txt diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/data/LineBreakTest.txt b/tests/auto/corelib/text/qtextboundaryfinder/data/LineBreakTest.txt similarity index 100% rename from tests/auto/corelib/tools/qtextboundaryfinder/data/LineBreakTest.txt rename to tests/auto/corelib/text/qtextboundaryfinder/data/LineBreakTest.txt diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/data/SentenceBreakTest.txt b/tests/auto/corelib/text/qtextboundaryfinder/data/SentenceBreakTest.txt similarity index 100% rename from tests/auto/corelib/tools/qtextboundaryfinder/data/SentenceBreakTest.txt rename to tests/auto/corelib/text/qtextboundaryfinder/data/SentenceBreakTest.txt diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/data/WordBreakTest.txt b/tests/auto/corelib/text/qtextboundaryfinder/data/WordBreakTest.txt similarity index 100% rename from tests/auto/corelib/tools/qtextboundaryfinder/data/WordBreakTest.txt rename to tests/auto/corelib/text/qtextboundaryfinder/data/WordBreakTest.txt diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/qtextboundaryfinder.pro b/tests/auto/corelib/text/qtextboundaryfinder/qtextboundaryfinder.pro similarity index 100% rename from tests/auto/corelib/tools/qtextboundaryfinder/qtextboundaryfinder.pro rename to tests/auto/corelib/text/qtextboundaryfinder/qtextboundaryfinder.pro diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/testdata.qrc b/tests/auto/corelib/text/qtextboundaryfinder/testdata.qrc similarity index 100% rename from tests/auto/corelib/tools/qtextboundaryfinder/testdata.qrc rename to tests/auto/corelib/text/qtextboundaryfinder/testdata.qrc diff --git a/tests/auto/corelib/tools/qtextboundaryfinder/tst_qtextboundaryfinder.cpp b/tests/auto/corelib/text/qtextboundaryfinder/tst_qtextboundaryfinder.cpp similarity index 100% rename from tests/auto/corelib/tools/qtextboundaryfinder/tst_qtextboundaryfinder.cpp rename to tests/auto/corelib/text/qtextboundaryfinder/tst_qtextboundaryfinder.cpp diff --git a/tests/auto/corelib/text/text.pro b/tests/auto/corelib/text/text.pro new file mode 100644 index 0000000000..09d58bd74c --- /dev/null +++ b/tests/auto/corelib/text/text.pro @@ -0,0 +1,23 @@ +TEMPLATE = subdirs + +SUBDIRS = \ + qbytearray \ + qbytearraylist \ + qbytearraymatcher \ + qbytedatabuffer \ + qchar \ + qcollator \ + qlatin1string \ + qlocale \ + qregexp \ + qregularexpression \ + qstring \ + qstring_no_cast_from_bytearray \ + qstringapisymmetry \ + qstringbuilder \ + qstringiterator \ + qstringlist \ + qstringmatcher \ + qstringref \ + qstringview \ + qtextboundaryfinder diff --git a/tests/auto/corelib/tools/tools.pro b/tests/auto/corelib/tools/tools.pro index 243e7e96f5..49b2a1f075 100644 --- a/tests/auto/corelib/tools/tools.pro +++ b/tests/auto/corelib/tools/tools.pro @@ -6,13 +6,7 @@ SUBDIRS=\ qarraydata \ qarraydata_strictiterators \ qbitarray \ - qbytearray \ - qbytearraylist \ - qbytearraymatcher \ - qbytedatabuffer \ qcache \ - qchar \ - qcollator \ qcommandlineparser \ qcontiguouscache \ qcryptographichash \ @@ -22,12 +16,10 @@ SUBDIRS=\ qhash \ qhash_strictiterators \ qhashfunctions \ - qlatin1string \ qline \ qlinkedlist \ qlist \ qlist_strictiterators \ - qlocale \ qmakearray \ qmap \ qmap_strictiterators \ @@ -39,8 +31,6 @@ SUBDIRS=\ qpointf \ qqueue \ qrect \ - qregexp \ - qregularexpression \ qringbuffer \ qscopedpointer \ qscopedvaluerollback \ @@ -50,16 +40,6 @@ SUBDIRS=\ qsize \ qsizef \ qstl \ - qstring \ - qstring_no_cast_from_bytearray \ - qstringapisymmetry \ - qstringbuilder \ - qstringiterator \ - qstringlist \ - qstringmatcher \ - qstringref \ - qstringview \ - qtextboundaryfinder \ qtimeline \ qvarlengtharray \ qvector \ diff --git a/tests/benchmarks/corelib/corelib.pro b/tests/benchmarks/corelib/corelib.pro index 99af4c138f..010abd7751 100644 --- a/tests/benchmarks/corelib/corelib.pro +++ b/tests/benchmarks/corelib/corelib.pro @@ -4,6 +4,7 @@ SUBDIRS = \ json \ mimetypes \ kernel \ + text \ thread \ time \ tools \ diff --git a/tests/benchmarks/corelib/tools/qbytearray/main.cpp b/tests/benchmarks/corelib/text/qbytearray/main.cpp similarity index 100% rename from tests/benchmarks/corelib/tools/qbytearray/main.cpp rename to tests/benchmarks/corelib/text/qbytearray/main.cpp diff --git a/tests/benchmarks/corelib/tools/qbytearray/qbytearray.pro b/tests/benchmarks/corelib/text/qbytearray/qbytearray.pro similarity index 100% rename from tests/benchmarks/corelib/tools/qbytearray/qbytearray.pro rename to tests/benchmarks/corelib/text/qbytearray/qbytearray.pro diff --git a/tests/benchmarks/corelib/tools/qchar/main.cpp b/tests/benchmarks/corelib/text/qchar/main.cpp similarity index 100% rename from tests/benchmarks/corelib/tools/qchar/main.cpp rename to tests/benchmarks/corelib/text/qchar/main.cpp diff --git a/tests/benchmarks/corelib/tools/qchar/qchar.pro b/tests/benchmarks/corelib/text/qchar/qchar.pro similarity index 100% rename from tests/benchmarks/corelib/tools/qchar/qchar.pro rename to tests/benchmarks/corelib/text/qchar/qchar.pro diff --git a/tests/benchmarks/corelib/tools/qlocale/main.cpp b/tests/benchmarks/corelib/text/qlocale/main.cpp similarity index 100% rename from tests/benchmarks/corelib/tools/qlocale/main.cpp rename to tests/benchmarks/corelib/text/qlocale/main.cpp diff --git a/tests/benchmarks/corelib/tools/qlocale/qlocale.pro b/tests/benchmarks/corelib/text/qlocale/qlocale.pro similarity index 100% rename from tests/benchmarks/corelib/tools/qlocale/qlocale.pro rename to tests/benchmarks/corelib/text/qlocale/qlocale.pro diff --git a/tests/benchmarks/corelib/tools/qregexp/main.cpp b/tests/benchmarks/corelib/text/qregexp/main.cpp similarity index 100% rename from tests/benchmarks/corelib/tools/qregexp/main.cpp rename to tests/benchmarks/corelib/text/qregexp/main.cpp diff --git a/tests/benchmarks/corelib/tools/qregexp/qregexp.pro b/tests/benchmarks/corelib/text/qregexp/qregexp.pro similarity index 100% rename from tests/benchmarks/corelib/tools/qregexp/qregexp.pro rename to tests/benchmarks/corelib/text/qregexp/qregexp.pro diff --git a/tests/benchmarks/corelib/tools/qregexp/qregexp.qrc b/tests/benchmarks/corelib/text/qregexp/qregexp.qrc similarity index 100% rename from tests/benchmarks/corelib/tools/qregexp/qregexp.qrc rename to tests/benchmarks/corelib/text/qregexp/qregexp.qrc diff --git a/tests/benchmarks/corelib/tools/qstring/main.cpp b/tests/benchmarks/corelib/text/qstring/main.cpp similarity index 100% rename from tests/benchmarks/corelib/tools/qstring/main.cpp rename to tests/benchmarks/corelib/text/qstring/main.cpp diff --git a/tests/benchmarks/corelib/tools/qstring/qstring.pro b/tests/benchmarks/corelib/text/qstring/qstring.pro similarity index 100% rename from tests/benchmarks/corelib/tools/qstring/qstring.pro rename to tests/benchmarks/corelib/text/qstring/qstring.pro diff --git a/tests/benchmarks/corelib/tools/qstringbuilder/main.cpp b/tests/benchmarks/corelib/text/qstringbuilder/main.cpp similarity index 100% rename from tests/benchmarks/corelib/tools/qstringbuilder/main.cpp rename to tests/benchmarks/corelib/text/qstringbuilder/main.cpp diff --git a/tests/benchmarks/corelib/tools/qstringbuilder/qstringbuilder.pro b/tests/benchmarks/corelib/text/qstringbuilder/qstringbuilder.pro similarity index 100% rename from tests/benchmarks/corelib/tools/qstringbuilder/qstringbuilder.pro rename to tests/benchmarks/corelib/text/qstringbuilder/qstringbuilder.pro diff --git a/tests/benchmarks/corelib/tools/qstringlist/.gitignore b/tests/benchmarks/corelib/text/qstringlist/.gitignore similarity index 100% rename from tests/benchmarks/corelib/tools/qstringlist/.gitignore rename to tests/benchmarks/corelib/text/qstringlist/.gitignore diff --git a/tests/benchmarks/corelib/tools/qstringlist/main.cpp b/tests/benchmarks/corelib/text/qstringlist/main.cpp similarity index 100% rename from tests/benchmarks/corelib/tools/qstringlist/main.cpp rename to tests/benchmarks/corelib/text/qstringlist/main.cpp diff --git a/tests/benchmarks/corelib/tools/qstringlist/qstringlist.pro b/tests/benchmarks/corelib/text/qstringlist/qstringlist.pro similarity index 100% rename from tests/benchmarks/corelib/tools/qstringlist/qstringlist.pro rename to tests/benchmarks/corelib/text/qstringlist/qstringlist.pro diff --git a/tests/benchmarks/corelib/text/text.pro b/tests/benchmarks/corelib/text/text.pro new file mode 100644 index 0000000000..8c15d0b0c5 --- /dev/null +++ b/tests/benchmarks/corelib/text/text.pro @@ -0,0 +1,10 @@ +TEMPLATE = subdirs +SUBDIRS = \ + qbytearray \ + qchar \ + qlocale \ + qregexp \ + qstringbuilder \ + qstringlist + +*g++*: SUBDIRS += qstring diff --git a/tests/benchmarks/corelib/tools/qhash/paths_small_data.txt b/tests/benchmarks/corelib/tools/qhash/paths_small_data.txt index d5acd28820..662285296f 100644 --- a/tests/benchmarks/corelib/tools/qhash/paths_small_data.txt +++ b/tests/benchmarks/corelib/tools/qhash/paths_small_data.txt @@ -47,13 +47,38 @@ ./codecs/.obj/debug-shared ./.pch ./.pch/debug-shared +./text +./text/text.pro +./text/qregexp +./text/qregexp/qregexp.qrc +./text/qregexp/main.cpp +./text/qregexp/Makefile +./text/qregexp/qregexp.pro +./text/qstringbuilder +./text/qstringbuilder/main.cpp +./text/qstringbuilder/Makefile +./text/qstringbuilder/qstringbuilder.pro +./text/qstring +./text/qstring/generatelist.pl +./text/qstring/data.h +./text/qstring/qstring.pro +./text/qstring/main.cpp +./text/qstring/data.cpp +./text/qstring/Makefile +./text/qstring/utf-8.txt +./text/qstringlist +./text/qstringlist/qstringlist.pro +./text/qstringlist/main.cpp +./text/qstringlist/.gitignore +./text/qstringlist/Makefile +./text/qbytearray +./text/qbytearray/qbytearray.pro +./text/qbytearray/main.cpp +./text/qbytearray/Makefile +./text/.pch +./text/.pch/debug-shared ./tools ./tools/tools.pro -./tools/qregexp -./tools/qregexp/qregexp.qrc -./tools/qregexp/main.cpp -./tools/qregexp/Makefile -./tools/qregexp/qregexp.pro ./tools/qvector ./tools/qvector/tst_vector ./tools/qvector/.pch @@ -72,31 +97,10 @@ ./tools/qvector/qvector.pro ./tools/.pch ./tools/.pch/debug-shared -./tools/qstringbuilder -./tools/qstringbuilder/main.cpp -./tools/qstringbuilder/Makefile -./tools/qstringbuilder/qstringbuilder.pro ./tools/containers-sequential ./tools/containers-sequential/containers-sequential.pro ./tools/containers-sequential/main.cpp ./tools/containers-sequential/Makefile -./tools/qstring -./tools/qstring/generatelist.pl -./tools/qstring/data.h -./tools/qstring/qstring.pro -./tools/qstring/main.cpp -./tools/qstring/data.cpp -./tools/qstring/Makefile -./tools/qstring/utf-8.txt -./tools/qstringlist -./tools/qstringlist/qstringlist.pro -./tools/qstringlist/main.cpp -./tools/qstringlist/.gitignore -./tools/qstringlist/Makefile -./tools/qbytearray -./tools/qbytearray/qbytearray.pro -./tools/qbytearray/main.cpp -./tools/qbytearray/Makefile ./tools/containers-associative ./tools/containers-associative/containers-associative.pro ./tools/containers-associative/main.cpp diff --git a/tests/benchmarks/corelib/tools/tools.pro b/tests/benchmarks/corelib/tools/tools.pro index 33cbe00438..b4ee0520a6 100644 --- a/tests/benchmarks/corelib/tools/tools.pro +++ b/tests/benchmarks/corelib/tools/tools.pro @@ -2,19 +2,12 @@ TEMPLATE = subdirs SUBDIRS = \ containers-associative \ containers-sequential \ - qbytearray \ qcontiguouscache \ qcryptographichash \ qlist \ - qlocale \ qmap \ qrect \ qringbuffer \ qstack \ - qstring \ - qstringbuilder \ - qstringlist \ qvector \ qalgorithms - -!*g++*: SUBDIRS -= qstring diff --git a/util/locale_database/cldr2qlocalexml.py b/util/locale_database/cldr2qlocalexml.py index 5560d8b43f..1982e3ba27 100755 --- a/util/locale_database/cldr2qlocalexml.py +++ b/util/locale_database/cldr2qlocalexml.py @@ -38,11 +38,11 @@ command-line argument. Save its standard output (but not error) to a file for later processing by ``./qlocalexml2cpp.py`` When you update the CLDR data, be sure to also update -src/corelib/tools/qt_attribution.json's entry for unicode-cldr. Check +src/corelib/text/qt_attribution.json's entry for unicode-cldr. Check this script's output for unknown language, country or script messages; if any can be resolved, use their entry in common/main/en.xml to append new entries to enumdata.py's lists and update documentation in -src/corelib/tools/qlocale.qdoc, adding the new entries in alphabetic +src/corelib/text/qlocale.qdoc, adding the new entries in alphabetic order. While updating the locale data, check also for updates to MS-Win's diff --git a/util/locale_database/qlocalexml2cpp.py b/util/locale_database/qlocalexml2cpp.py index 2dad2dd57a..ea89288b4f 100755 --- a/util/locale_database/qlocalexml2cpp.py +++ b/util/locale_database/qlocalexml2cpp.py @@ -339,7 +339,7 @@ def main(): (data_temp_file, data_temp_file_path) = tempfile.mkstemp("qlocale_data_p", dir=qtsrcdir) data_temp_file = os.fdopen(data_temp_file, "w") - qlocaledata_file = open(qtsrcdir + "/src/corelib/tools/qlocale_data_p.h", "r") + qlocaledata_file = open(qtsrcdir + "/src/corelib/text/qlocale_data_p.h", "r") s = qlocaledata_file.readline() while s and s != GENERATED_BLOCK_START: data_temp_file.write(s) @@ -735,14 +735,14 @@ def main(): data_temp_file.close() qlocaledata_file.close() - os.remove(qtsrcdir + "/src/corelib/tools/qlocale_data_p.h") - os.rename(data_temp_file_path, qtsrcdir + "/src/corelib/tools/qlocale_data_p.h") + os.remove(qtsrcdir + "/src/corelib/text/qlocale_data_p.h") + os.rename(data_temp_file_path, qtsrcdir + "/src/corelib/text/qlocale_data_p.h") # qlocale.h (qlocaleh_temp_file, qlocaleh_temp_file_path) = tempfile.mkstemp("qlocale.h", dir=qtsrcdir) qlocaleh_temp_file = os.fdopen(qlocaleh_temp_file, "w") - qlocaleh_file = open(qtsrcdir + "/src/corelib/tools/qlocale.h", "r") + qlocaleh_file = open(qtsrcdir + "/src/corelib/text/qlocale.h", "r") s = qlocaleh_file.readline() while s and s != GENERATED_BLOCK_START: qlocaleh_temp_file.write(s) @@ -808,14 +808,14 @@ def main(): qlocaleh_temp_file.close() qlocaleh_file.close() - os.remove(qtsrcdir + "/src/corelib/tools/qlocale.h") - os.rename(qlocaleh_temp_file_path, qtsrcdir + "/src/corelib/tools/qlocale.h") + os.remove(qtsrcdir + "/src/corelib/text/qlocale.h") + os.rename(qlocaleh_temp_file_path, qtsrcdir + "/src/corelib/text/qlocale.h") # qlocale.qdoc (qlocaleqdoc_temp_file, qlocaleqdoc_temp_file_path) = tempfile.mkstemp("qlocale.qdoc", dir=qtsrcdir) qlocaleqdoc_temp_file = os.fdopen(qlocaleqdoc_temp_file, "w") - qlocaleqdoc_file = open(qtsrcdir + "/src/corelib/tools/qlocale.qdoc", "r") + qlocaleqdoc_file = open(qtsrcdir + "/src/corelib/text/qlocale.qdoc", "r") s = qlocaleqdoc_file.readline() DOCSTRING = " QLocale's data is based on Common Locale Data Repository " while s: @@ -827,8 +827,8 @@ def main(): qlocaleqdoc_temp_file.close() qlocaleqdoc_file.close() - os.remove(qtsrcdir + "/src/corelib/tools/qlocale.qdoc") - os.rename(qlocaleqdoc_temp_file_path, qtsrcdir + "/src/corelib/tools/qlocale.qdoc") + os.remove(qtsrcdir + "/src/corelib/text/qlocale.qdoc") + os.rename(qlocaleqdoc_temp_file_path, qtsrcdir + "/src/corelib/text/qlocale.qdoc") if __name__ == "__main__": main() diff --git a/util/unicode/README b/util/unicode/README index e52f26175a..87f055d42d 100644 --- a/util/unicode/README +++ b/util/unicode/README @@ -19,7 +19,7 @@ To update: need to be expanded, for example. In some cases QChar may need additions to some of its enums. * Build with the modified code, fix any compilation issues. -* That may have updated qtbase/src/corelib/tools/qunicodetables.cpp; +* That may have updated qtbase/src/corelib/text/qunicodetables.cpp; if so the update matters; be sure to commit the changes to data/ at the same time and update tools/qt_attribution.json to match; use the UCD Revision number, rather than the Unicode standard number, as the diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp index ec84667ee5..84231c6277 100644 --- a/util/unicode/main.cpp +++ b/util/unicode/main.cpp @@ -3096,7 +3096,7 @@ int main(int, char **) "// We mean it.\n" "//\n\n"; - QFile f("../../src/corelib/tools/qunicodetables.cpp"); + QFile f("../../src/corelib/text/qunicodetables.cpp"); f.open(QFile::WriteOnly|QFile::Truncate); f.write(header); f.write(note); @@ -3116,7 +3116,7 @@ int main(int, char **) f.write("QT_END_NAMESPACE\n"); f.close(); - f.setFileName("../../src/corelib/tools/qunicodetables_p.h"); + f.setFileName("../../src/corelib/text/qunicodetables_p.h"); f.open(QFile::WriteOnly | QFile::Truncate); f.write(header); f.write(note); From f6d815922d66c4239c8158d00fe9bfeecf4f4b6e Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Fri, 31 May 2019 19:46:24 +0900 Subject: [PATCH 063/264] Fix build without feature.temporaryfile Change-Id: I096b6a7d9cc8e17165e07657f6647a14baafefa5 Reviewed-by: Volker Hilsheimer --- src/gui/opengl/qopenglprogrambinarycache.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/opengl/qopenglprogrambinarycache.cpp b/src/gui/opengl/qopenglprogrambinarycache.cpp index c96021a969..74b91086ee 100644 --- a/src/gui/opengl/qopenglprogrambinarycache.cpp +++ b/src/gui/opengl/qopenglprogrambinarycache.cpp @@ -398,10 +398,16 @@ void QOpenGLProgramBinaryCache::save(const QByteArray &cacheKey, uint programId) writeUInt(&blobFormatPtr, blobFormat); +#if QT_CONFIG(temporaryfile) QSaveFile f(cacheFileName(cacheKey)); if (f.open(QIODevice::WriteOnly | QIODevice::Truncate)) { f.write(blob); if (!f.commit()) +#else + QFile f(cacheFileName(cacheKey)); + if (f.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + if (f.write(blob) < blob.length()) +#endif qCDebug(DBG_SHADER_CACHE, "Failed to write %s to shader cache", qPrintable(f.fileName())); } else { qCDebug(DBG_SHADER_CACHE, "Failed to create %s in shader cache", qPrintable(f.fileName())); From fc15cdb4d0a50f8bf021a93d97435bddee351d0f Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Thu, 11 Jul 2019 03:33:34 +0900 Subject: [PATCH 064/264] return value in QOrderedMutexLocker::relock when thread is disabled Change-Id: Ic96e777491cc8d304be056a3476a4de4c4700a0f Reviewed-by: Volker Hilsheimer --- src/corelib/thread/qorderedmutexlocker_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/thread/qorderedmutexlocker_p.h b/src/corelib/thread/qorderedmutexlocker_p.h index e0a67388d4..570c526225 100644 --- a/src/corelib/thread/qorderedmutexlocker_p.h +++ b/src/corelib/thread/qorderedmutexlocker_p.h @@ -159,7 +159,7 @@ public: void relock() {} void unlock() {} - static bool relock(QBasicMutex *, QBasicMutex *) {} + static bool relock(QBasicMutex *, QBasicMutex *) { return false; } }; using QBasicMutexLocker = QMutexLocker; From 36a15a87de2b954b1cef24acd4a8cd4ef5aef6cd Mon Sep 17 00:00:00 2001 From: Felix Barz Date: Sat, 6 Jul 2019 20:28:48 +0200 Subject: [PATCH 065/264] syncqt: Fix module header install target creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modified a regular expression in syncqt.pl so that the special case of a class beginning with another class does not lead to the exclusion of the first one. This affects the generation of the install target for generated class headers of Qt modules. Now the expression verifies the class names are not identical. Fixes: QTBUG-71323 Change-Id: I210b4d4c3ed64cf189594b95b10aa0e8495a19d2 Reviewed-by: Jörg Bornemann --- bin/syncqt.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/syncqt.pl b/bin/syncqt.pl index 7793811c9f..8226edfb76 100755 --- a/bin/syncqt.pl +++ b/bin/syncqt.pl @@ -1092,7 +1092,7 @@ foreach my $lib (@modules_to_sync) { # } my $class_header = "$class "; $pri_install_gfiles .= $class_header - unless ($shadow || $pri_install_gfiles =~ $class_header); + unless ($shadow || $pri_install_gfiles =~ m/\b$class_header/); $injection .= ":$class"; } From cc32226e647854a02ecd0775787bb08b85e2a014 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 2 Jul 2019 14:28:58 +0200 Subject: [PATCH 066/264] Windows: handle errors correctly when connecting to unreachable host MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous code handled only some error codes, in a very inefficient way, for some code paths. This change standardizes error handling using a helper function that maps winsock WSAE* codes to Qt error codes. The test for connecting to unreachable hosts or ports is now more generic, and enabled on Windows, where it passes in local tests, but dependency on network configuration still makes it fragile, so ignoring some failures without completely skipping the test. [ChangeLog][Network][Windows] Correctly emit errors when trying to reach unreachable hosts or services Change-Id: Icaca3e6fef88621d683f6d6fa3016212847de4ea Fixes: QTBUG-42567 Reviewed-by: Mårten Nordheim --- .../socket/qnativesocketengine_win.cpp | 115 +++++++++--------- .../socket/qtcpsocket/tst_qtcpsocket.cpp | 39 ++++-- 2 files changed, 84 insertions(+), 70 deletions(-) diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 986b0b4861..897f9e24bb 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -623,6 +623,53 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters() } +static void setErrorFromWSAError(int error, QNativeSocketEnginePrivate *d) +{ + Q_ASSERT(d); + switch (error) { + case WSAEISCONN: + d->socketState = QAbstractSocket::ConnectedState; + break; + case WSAEHOSTUNREACH: + d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::HostUnreachableErrorString); + d->socketState = QAbstractSocket::UnconnectedState; + break; + case WSAEADDRNOTAVAIL: + d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::AddressNotAvailableErrorString); + d->socketState = QAbstractSocket::UnconnectedState; + break; + case WSAEINPROGRESS: + d->setError(QAbstractSocket::UnfinishedSocketOperationError, QNativeSocketEnginePrivate::InvalidSocketErrorString); + d->socketState = QAbstractSocket::ConnectingState; + break; + case WSAEADDRINUSE: + d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::AddressInuseErrorString); + break; + case WSAECONNREFUSED: + d->setError(QAbstractSocket::ConnectionRefusedError, QNativeSocketEnginePrivate::ConnectionRefusedErrorString); + d->socketState = QAbstractSocket::UnconnectedState; + break; + case WSAETIMEDOUT: + d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::ConnectionTimeOutErrorString); + d->socketState = QAbstractSocket::UnconnectedState; + break; + case WSAEACCES: + d->setError(QAbstractSocket::SocketAccessError, QNativeSocketEnginePrivate::AccessErrorString); + d->socketState = QAbstractSocket::UnconnectedState; + break; + case WSAENETUNREACH: + d->setError(QAbstractSocket::NetworkError, QNativeSocketEnginePrivate::NetworkUnreachableErrorString); + d->socketState = QAbstractSocket::UnconnectedState; + break; + case WSAEINVAL: + case WSAEALREADY: + d->setError(QAbstractSocket::UnfinishedSocketOperationError, QNativeSocketEnginePrivate::InvalidSocketErrorString); + break; + default: + break; + } +} + bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quint16 port) { @@ -651,9 +698,6 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin case WSANOTINITIALISED: //### break; - case WSAEISCONN: - socketState = QAbstractSocket::ConnectedState; - break; case WSAEWOULDBLOCK: { // If WSAConnect returns WSAEWOULDBLOCK on the second // connection attempt, we have to check SO_ERROR's @@ -668,82 +712,33 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &address, quin do { if (::getsockopt(socketDescriptor, SOL_SOCKET, SO_ERROR, (char *) &value, &valueSize) == 0) { if (value != NOERROR) { + WS_ERROR_DEBUG(value); + errorDetected = true; // MSDN says getsockopt with SO_ERROR clears the error, but it's not actually cleared // and this can affect all subsequent WSAConnect attempts, so clear it now. const int val = NO_ERROR; ::setsockopt(socketDescriptor, SOL_SOCKET, SO_ERROR, reinterpret_cast(&val), sizeof val); - } - - if (value == WSAECONNREFUSED) { - setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString); - socketState = QAbstractSocket::UnconnectedState; - errorDetected = true; - break; - } - if (value == WSAETIMEDOUT) { - setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString); - socketState = QAbstractSocket::UnconnectedState; - errorDetected = true; - break; - } - if (value == WSAEHOSTUNREACH) { - setError(QAbstractSocket::NetworkError, HostUnreachableErrorString); - socketState = QAbstractSocket::UnconnectedState; - errorDetected = true; - break; - } - if (value == WSAEADDRNOTAVAIL) { - setError(QAbstractSocket::NetworkError, AddressNotAvailableErrorString); - socketState = QAbstractSocket::UnconnectedState; - errorDetected = true; - break; - } - if (value == NOERROR) { + } else { // When we get WSAEWOULDBLOCK the outcome was not known, so a // NOERROR might indicate that the result of the operation // is still unknown. We try again to increase the chance that we did // get the correct result. tryAgain = !tryAgain; } + setErrorFromWSAError(value, this); } tries++; } while (tryAgain && (tries < 2)); if (errorDetected) break; + // fall through to unfinished operation error handling + err = WSAEINPROGRESS; Q_FALLTHROUGH(); } - case WSAEINPROGRESS: - setError(QAbstractSocket::UnfinishedSocketOperationError, InvalidSocketErrorString); - socketState = QAbstractSocket::ConnectingState; - break; - case WSAEADDRINUSE: - setError(QAbstractSocket::NetworkError, AddressInuseErrorString); - break; - case WSAECONNREFUSED: - setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString); - socketState = QAbstractSocket::UnconnectedState; - break; - case WSAETIMEDOUT: - setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString); - break; - case WSAEACCES: - setError(QAbstractSocket::SocketAccessError, AccessErrorString); - socketState = QAbstractSocket::UnconnectedState; - break; - case WSAEHOSTUNREACH: - setError(QAbstractSocket::NetworkError, HostUnreachableErrorString); - socketState = QAbstractSocket::UnconnectedState; - break; - case WSAENETUNREACH: - setError(QAbstractSocket::NetworkError, NetworkUnreachableErrorString); - socketState = QAbstractSocket::UnconnectedState; - break; - case WSAEINVAL: - case WSAEALREADY: - setError(QAbstractSocket::UnfinishedSocketOperationError, InvalidSocketErrorString); - break; + default: + setErrorFromWSAError(err, this); break; } if (socketState != QAbstractSocket::ConnectedState) { diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index 2d64714f92..10b09629bc 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -164,9 +164,8 @@ private slots: void waitForReadyReadInASlot(); void remoteCloseError(); void nestedEventLoopInErrorSlot(); -#ifndef Q_OS_WIN - void connectToLocalHostNoService(); -#endif + void connectToHostError_data(); + void connectToHostError(); void waitForConnectedInHostLookupSlot(); void waitForConnectedInHostLookupSlot2(); void readyReadSignalsAfterWaitForReadyRead(); @@ -2040,18 +2039,38 @@ void tst_QTcpSocket::nestedEventLoopInErrorSlot() } //---------------------------------------------------------------------------------- -#ifndef Q_OS_WIN -void tst_QTcpSocket::connectToLocalHostNoService() + +void tst_QTcpSocket::connectToHostError_data() +{ + QTest::addColumn("host"); + QTest::addColumn("port"); + QTest::addColumn("expectedError"); + + QTest::newRow("localhost no service") << QStringLiteral("localhost") << 31415 << QAbstractSocket::ConnectionRefusedError; + QTest::newRow("unreachable") << QStringLiteral("0.0.0.1") << 65000 << QAbstractSocket::NetworkError; +} + + +void tst_QTcpSocket::connectToHostError() { - // This test was created after we received a report that claimed - // QTcpSocket would crash if trying to connect to "localhost" on a random - // port with no service listening. QTcpSocket *socket = newSocket(); - socket->connectToHost("localhost", 31415); // no service running here, one suspects + + QAbstractSocket::SocketError error = QAbstractSocket::UnknownSocketError; + + QFETCH(QString, host); + QFETCH(int, port); + QFETCH(QAbstractSocket::SocketError, expectedError); + + connect(socket, QOverload::of(&QAbstractSocket::error),[&](QAbstractSocket::SocketError socketError){ + error = socketError; + }); + socket->connectToHost(host, port); // no service running here, one suspects QTRY_COMPARE(socket->state(), QTcpSocket::UnconnectedState); + if (error != expectedError && error == QAbstractSocket::ConnectionRefusedError) + QEXPECT_FAIL("unreachable", "CI firewall interfers with this test", Continue); + QCOMPARE(error, expectedError); delete socket; } -#endif //---------------------------------------------------------------------------------- void tst_QTcpSocket::waitForConnectedInHostLookupSlot() From de8bd9ec6b21e3b43b08c4c2588b5116a7ca8ece Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 9 Jul 2019 17:19:26 +0200 Subject: [PATCH 067/264] Fix build with -no-feature-printer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Skip printsupport subdirectory if printer feature is disabled. Also removed android-embedded condition for the plugin: Such a configuration should just disable the printer feature. Fixes: QTBUG-76941 Change-Id: Ifca7d2311a575c1589ad6a87a775bd016591ee2c Reviewed-by: Jörg Bornemann --- src/src.pro | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/src.pro b/src/src.pro index 1c76a2e46f..b704ccd7ab 100644 --- a/src/src.pro +++ b/src/src.pro @@ -1,8 +1,10 @@ TEMPLATE = subdirs -QT_FOR_CONFIG += core-private gui-private +QT_FOR_CONFIG += core-private gui-private printsupport + include($$OUT_PWD/corelib/qtcore-config.pri) include($$OUT_PWD/gui/qtgui-config.pri) +include($$OUT_PWD/printsupport/qtprintsupport-config.pri) force_bootstrap|!qtConfig(commandlineparser): \ CONFIG += force_dbus_bootstrap @@ -221,11 +223,13 @@ qtConfig(gui) { src_testlib.depends += src_gui # if QtGui is enabled, QtTest requires QtGui's headers qtConfig(widgets) { SUBDIRS += src_tools_uic src_widgets - !android-embedded: SUBDIRS += src_printsupport TOOLS += src_tools_uic src_plugins.depends += src_widgets - !android-embedded: src_plugins.depends += src_printsupport src_testlib.depends += src_widgets # if QtWidgets is enabled, QtTest requires QtWidgets's headers + qtConfig(printer) { + SUBDIRS += src_printsupport + src_plugins.depends += src_printsupport + } qtConfig(opengl) { SUBDIRS += src_opengl src_plugins.depends += src_opengl From 3bee5a470a20fcfb46528b020d18f2210519bd41 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Thu, 20 Jun 2019 12:54:49 +0200 Subject: [PATCH 068/264] Fix typos in readme Change-Id: Ifecb1bac475512241de9bcf195955409bb3adaff Reviewed-by: Edward Welbourne Reviewed-by: Paul Wicking --- tests/libfuzzer/README | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/libfuzzer/README b/tests/libfuzzer/README index 7327e76eff..57140cebfb 100644 --- a/tests/libfuzzer/README +++ b/tests/libfuzzer/README @@ -7,7 +7,7 @@ of the test and track the code execution. Should the test crash, libFuzzer will data which triggered the crash. You can then use this to debug and fix the called code. ! Please note: The purpose of fuzz testing is to find unexpected code paths. Running fuzz tests may! -! result in unforeseen bevavior, including loss of data. Consider running the tests in an isolated ! +! result in unforeseen behavior, including loss of data. Consider running the tests in an isolated ! ! environment, e.g. on a virtual machine. You have been warned. ! To run a test with libFuzzer: @@ -21,7 +21,7 @@ To run a test with libFuzzer: to add the needed code coverage instrumentation. Since speed of execution is crucial for fuzz testing, it's recommendable to also use the switches -release -static - It might also make sense to add sanitzers by passing + It might also make sense to add sanitizers by passing -sanitize <...> 4. Build Qt. 5. Build one of the tests using this Qt build. @@ -29,7 +29,7 @@ To run a test with libFuzzer: Depending on the expected input format of the tested function, you will get results faster if you: * provide a set of interesting input data by passing the path of a directory which contains - these data, each in one file. You can find such datasets in the subdirectory "testcases". + these data, each in one file. You can find such data sets in the subdirectory "testcases". * pass a so-called dictionary listing keywords of the input format using -dict= A couple of such dictionaries are provided by AFL (http://lcamtuf.coredump.cx/afl/) From 2d8d738657b64c853316b605176e002b9e616fcf Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 13 Jun 2019 11:16:14 +0200 Subject: [PATCH 069/264] QTestLib: Use member initialization Apply Fixits by Qt Creator with some amendments. Task-number: QTBUG-69413 Change-Id: Iba0834dc89cbfc215acc5873f31fa6eeed74177d Reviewed-by: Frederik Gladhorn --- src/testlib/qabstracttestlogger_p.h | 5 ++- src/testlib/qbenchmark.cpp | 13 +------- src/testlib/qbenchmark_p.h | 44 ++++++++++++--------------- src/testlib/qbenchmarkevent.cpp | 5 +-- src/testlib/qbenchmarkevent_p.h | 2 +- src/testlib/qbenchmarkperfevents.cpp | 5 +-- src/testlib/qbenchmarkperfevents_p.h | 2 +- src/testlib/qtestcoreelement_p.h | 4 +-- src/testlib/qtestdata.cpp | 10 +++--- src/testlib/qtestelement.cpp | 2 -- src/testlib/qtestelement_p.h | 4 +-- src/testlib/qtestelementattribute.cpp | 6 +--- src/testlib/qtestelementattribute_p.h | 4 +-- src/testlib/qtesteventloop.h | 9 +++--- src/testlib/qtestlog.cpp | 4 +-- src/testlib/qtesttable.cpp | 6 ++-- src/testlib/qxunittestlogger.cpp | 7 ----- src/testlib/qxunittestlogger_p.h | 14 ++++----- 18 files changed, 53 insertions(+), 93 deletions(-) diff --git a/src/testlib/qabstracttestlogger_p.h b/src/testlib/qabstracttestlogger_p.h index 9bb1d1e80c..e5a1404c16 100644 --- a/src/testlib/qabstracttestlogger_p.h +++ b/src/testlib/qabstracttestlogger_p.h @@ -117,8 +117,7 @@ struct QTestCharBuffer { enum { InitialSize = 512 }; - inline QTestCharBuffer() - : _size(InitialSize), buf(staticBuf) + inline QTestCharBuffer() : buf(staticBuf) { staticBuf[0] = '\0'; } @@ -170,7 +169,7 @@ struct QTestCharBuffer } private: - int _size; + int _size = InitialSize; char* buf; char staticBuf[InitialSize]; }; diff --git a/src/testlib/qbenchmark.cpp b/src/testlib/qbenchmark.cpp index cbc009c993..19abd16284 100644 --- a/src/testlib/qbenchmark.cpp +++ b/src/testlib/qbenchmark.cpp @@ -51,14 +51,6 @@ QT_BEGIN_NAMESPACE QBenchmarkGlobalData *QBenchmarkGlobalData::current; QBenchmarkGlobalData::QBenchmarkGlobalData() - : measurer(0) - , walltimeMinimum(-1) - , iterationCount(-1) - , medianIterationCount(-1) - , createChart(false) - , verboseOutput(false) - , minimumTotal(-1) - , mode_(WallTime) { setMode(mode_); } @@ -116,10 +108,7 @@ int QBenchmarkGlobalData::adjustMedianIterationCount() QBenchmarkTestMethodData *QBenchmarkTestMethodData::current; -QBenchmarkTestMethodData::QBenchmarkTestMethodData() -:resultAccepted(false), runOnce(false), iterationCount(-1) -{ -} +QBenchmarkTestMethodData::QBenchmarkTestMethodData() = default; QBenchmarkTestMethodData::~QBenchmarkTestMethodData() { diff --git a/src/testlib/qbenchmark_p.h b/src/testlib/qbenchmark_p.h index 49868ac23a..93b5becb2b 100644 --- a/src/testlib/qbenchmark_p.h +++ b/src/testlib/qbenchmark_p.h @@ -81,7 +81,7 @@ struct QBenchmarkContext QString slotName; QString tag; // from _data() function - int checkpointIndex; + int checkpointIndex = -1; QString toString() const { @@ -89,7 +89,7 @@ struct QBenchmarkContext .arg(slotName, tag, QString::number(checkpointIndex)); } - QBenchmarkContext() : checkpointIndex(-1) {} + QBenchmarkContext() = default; }; Q_DECLARE_TYPEINFO(QBenchmarkContext, Q_MOVABLE_TYPE); @@ -97,19 +97,13 @@ class QBenchmarkResult { public: QBenchmarkContext context; - qreal value; - int iterations; - QTest::QBenchmarkMetric metric; - bool setByMacro; - bool valid; + qreal value = -1; + int iterations = -1; + QTest::QBenchmarkMetric metric = QTest::FramesPerSecond; + bool setByMacro = true; + bool valid = false; - QBenchmarkResult() - : value(-1) - , iterations(-1) - , metric(QTest::FramesPerSecond) - , setByMacro(true) - , valid(false) - { } + QBenchmarkResult() = default; QBenchmarkResult( const QBenchmarkContext &context, const qreal value, const int iterations, @@ -147,17 +141,17 @@ public: QBenchmarkMeasurerBase *createMeasurer(); int adjustMedianIterationCount(); - QBenchmarkMeasurerBase *measurer; + QBenchmarkMeasurerBase *measurer = nullptr; QBenchmarkContext context; - int walltimeMinimum; - int iterationCount; - int medianIterationCount; - bool createChart; - bool verboseOutput; + int walltimeMinimum = -1; + int iterationCount = -1; + int medianIterationCount = -1; + bool createChart = false; + bool verboseOutput = false; QString callgrindOutFileBase; - int minimumTotal; + int minimumTotal = -1; private: - Mode mode_; + Mode mode_ = WallTime; }; /* @@ -184,9 +178,9 @@ public: void setResult(qreal value, QTest::QBenchmarkMetric metric, bool setByMacro = true); QBenchmarkResult result; - bool resultAccepted; - bool runOnce; - int iterationCount; + bool resultAccepted = false; + bool runOnce = false; + int iterationCount = -1; }; // low-level API: diff --git a/src/testlib/qbenchmarkevent.cpp b/src/testlib/qbenchmarkevent.cpp index a8270219e4..41be9fa468 100644 --- a/src/testlib/qbenchmarkevent.cpp +++ b/src/testlib/qbenchmarkevent.cpp @@ -44,10 +44,7 @@ QT_BEGIN_NAMESPACE -QBenchmarkEvent::QBenchmarkEvent() - : eventCounter(0) -{ -} +QBenchmarkEvent::QBenchmarkEvent() = default; QBenchmarkEvent::~QBenchmarkEvent() { diff --git a/src/testlib/qbenchmarkevent_p.h b/src/testlib/qbenchmarkevent_p.h index 0f47aa475c..9fe3daa33b 100644 --- a/src/testlib/qbenchmarkevent_p.h +++ b/src/testlib/qbenchmarkevent_p.h @@ -76,7 +76,7 @@ public: #else bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override; #endif - qint64 eventCounter; + qint64 eventCounter = 0; }; QT_END_NAMESPACE diff --git a/src/testlib/qbenchmarkperfevents.cpp b/src/testlib/qbenchmarkperfevents.cpp index 91f0792338..ea27f29711 100644 --- a/src/testlib/qbenchmarkperfevents.cpp +++ b/src/testlib/qbenchmarkperfevents.cpp @@ -500,10 +500,7 @@ void QBenchmarkPerfEventsMeasurer::listCounters() "Attributes can be combined, for example: -perfcounter branch-mispredicts:kh\n"); } -QBenchmarkPerfEventsMeasurer::QBenchmarkPerfEventsMeasurer() - : fd(-1) -{ -} +QBenchmarkPerfEventsMeasurer::QBenchmarkPerfEventsMeasurer() = default; QBenchmarkPerfEventsMeasurer::~QBenchmarkPerfEventsMeasurer() { diff --git a/src/testlib/qbenchmarkperfevents_p.h b/src/testlib/qbenchmarkperfevents_p.h index 86ba556549..47af4db9f8 100644 --- a/src/testlib/qbenchmarkperfevents_p.h +++ b/src/testlib/qbenchmarkperfevents_p.h @@ -76,7 +76,7 @@ public: static void setCounter(const char *name); static void listCounters(); private: - int fd; + int fd = -1; qint64 readValue(); }; diff --git a/src/testlib/qtestcoreelement_p.h b/src/testlib/qtestcoreelement_p.h index 84406fed85..a101ab5ea3 100644 --- a/src/testlib/qtestcoreelement_p.h +++ b/src/testlib/qtestcoreelement_p.h @@ -74,13 +74,13 @@ class QTestCoreElement: public QTestCoreList QTest::LogElementType elementType() const; private: - QTestElementAttribute *listOfAttributes; + QTestElementAttribute *listOfAttributes = nullptr; QTest::LogElementType type; }; template QTestCoreElement::QTestCoreElement(int t) - :listOfAttributes(nullptr), type(QTest::LogElementType(t)) + : type(QTest::LogElementType(t)) { } diff --git a/src/testlib/qtestdata.cpp b/src/testlib/qtestdata.cpp index a8ee130a7d..3a1c6d7e7b 100644 --- a/src/testlib/qtestdata.cpp +++ b/src/testlib/qtestdata.cpp @@ -51,12 +51,10 @@ QT_BEGIN_NAMESPACE class QTestDataPrivate { public: - QTestDataPrivate() : tag(0), parent(0), data(0), dataCount(0) {} - - char *tag; - QTestTable *parent; - void **data; - int dataCount; + char *tag = nullptr; + QTestTable *parent = nullptr; + void **data = nullptr; + int dataCount = 0; }; QTestData::QTestData(const char *tag, QTestTable *parent) diff --git a/src/testlib/qtestelement.cpp b/src/testlib/qtestelement.cpp index 622e5344f3..b468295917 100644 --- a/src/testlib/qtestelement.cpp +++ b/src/testlib/qtestelement.cpp @@ -43,8 +43,6 @@ QT_BEGIN_NAMESPACE QTestElement::QTestElement(int type) : QTestCoreElement(type) - , listOfChildren(0) - , parent(0) { } diff --git a/src/testlib/qtestelement_p.h b/src/testlib/qtestelement_p.h index dacbe6c106..a6b2791a42 100644 --- a/src/testlib/qtestelement_p.h +++ b/src/testlib/qtestelement_p.h @@ -69,8 +69,8 @@ class QTestElement: public QTestCoreElement void setParent(const QTestElement *p); private: - QTestElement *listOfChildren; - const QTestElement * parent; + QTestElement *listOfChildren = nullptr; + const QTestElement * parent = nullptr; }; diff --git a/src/testlib/qtestelementattribute.cpp b/src/testlib/qtestelementattribute.cpp index 9d752bf26a..1aa54d767f 100644 --- a/src/testlib/qtestelementattribute.cpp +++ b/src/testlib/qtestelementattribute.cpp @@ -104,11 +104,7 @@ QT_BEGIN_NAMESPACE \value LET_SystemError */ -QTestElementAttribute::QTestElementAttribute() - :attributeValue(0), - attributeIndex(QTest::AI_Undefined) -{ -} +QTestElementAttribute::QTestElementAttribute() = default; QTestElementAttribute::~QTestElementAttribute() { diff --git a/src/testlib/qtestelementattribute_p.h b/src/testlib/qtestelementattribute_p.h index cb4dbb5f16..f3815b72d1 100644 --- a/src/testlib/qtestelementattribute_p.h +++ b/src/testlib/qtestelementattribute_p.h @@ -106,8 +106,8 @@ class QTestElementAttribute: public QTestCoreList bool setPair(QTest::AttributeIndex attributeIndex, const char *value); private: - char *attributeValue; - QTest::AttributeIndex attributeIndex; + char *attributeValue = nullptr; + QTest::AttributeIndex attributeIndex = QTest::AI_Undefined; }; QT_END_NAMESPACE diff --git a/src/testlib/qtesteventloop.h b/src/testlib/qtesteventloop.h index a77b47cd7f..b194e24c3a 100644 --- a/src/testlib/qtesteventloop.h +++ b/src/testlib/qtesteventloop.h @@ -56,8 +56,7 @@ class Q_TESTLIB_EXPORT QTestEventLoop : public QObject Q_OBJECT public: - inline QTestEventLoop(QObject *aParent = nullptr) - : QObject(aParent), inLoop(false), _timeout(false), timerId(-1), loop(nullptr) {} + using QObject::QObject; inline void enterLoopMSecs(int ms); inline void enterLoop(int secs) { enterLoopMSecs(secs * 1000); } @@ -84,10 +83,10 @@ protected: private: Q_DECL_UNUSED_MEMBER bool inLoop; // ### Qt 6: remove - bool _timeout; - int timerId; + bool _timeout = false; + int timerId = -1; - QEventLoop *loop; + QEventLoop *loop = nullptr; }; inline void QTestEventLoop::enterLoopMSecs(int ms) diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp index 14543c3cde..ddebf1105f 100644 --- a/src/testlib/qtestlog.cpp +++ b/src/testlib/qtestlog.cpp @@ -111,7 +111,7 @@ namespace QTest { struct IgnoreResultList { inline IgnoreResultList(QtMsgType tp, const QVariant &patternIn) - : type(tp), pattern(patternIn), next(0) {} + : type(tp), pattern(patternIn) {} static inline void clearList(IgnoreResultList *&list) { @@ -163,7 +163,7 @@ namespace QTest { QtMsgType type; QVariant pattern; - IgnoreResultList *next; + IgnoreResultList *next = nullptr; }; static IgnoreResultList *ignoreResultList = 0; diff --git a/src/testlib/qtesttable.cpp b/src/testlib/qtesttable.cpp index 20e0702d44..e2e72b125f 100644 --- a/src/testlib/qtesttable.cpp +++ b/src/testlib/qtesttable.cpp @@ -58,11 +58,11 @@ public: } struct Element { - Element() : name(nullptr), type(0) {} + Element() = default; Element(const char *n, int t) : name(n), type(t) {} - const char *name; - int type; + const char *name = nullptr; + int type = 0; }; using ElementList = std::vector; diff --git a/src/testlib/qxunittestlogger.cpp b/src/testlib/qxunittestlogger.cpp index 336edb5994..cae959a349 100644 --- a/src/testlib/qxunittestlogger.cpp +++ b/src/testlib/qxunittestlogger.cpp @@ -59,13 +59,6 @@ QT_BEGIN_NAMESPACE QXunitTestLogger::QXunitTestLogger(const char *filename) : QAbstractTestLogger(filename) - , listOfTestcases(0) - , currentLogElement(0) - , errorLogElement(0) - , logFormatter(0) - , testCounter(0) - , failureCounter(0) - , errorCounter(0) { } diff --git a/src/testlib/qxunittestlogger_p.h b/src/testlib/qxunittestlogger_p.h index 48f07ddcf2..518ba098f4 100644 --- a/src/testlib/qxunittestlogger_p.h +++ b/src/testlib/qxunittestlogger_p.h @@ -79,14 +79,14 @@ class QXunitTestLogger : public QAbstractTestLogger const char *file = nullptr, int line = 0) override; private: - QTestElement *listOfTestcases; - QTestElement *currentLogElement; - QTestElement *errorLogElement; - QTestXunitStreamer *logFormatter; + QTestElement *listOfTestcases = nullptr; + QTestElement *currentLogElement = nullptr; + QTestElement *errorLogElement = nullptr; + QTestXunitStreamer *logFormatter = nullptr; - int testCounter; - int failureCounter; - int errorCounter; + int testCounter = 0; + int failureCounter = 0; + int errorCounter = 0; }; QT_END_NAMESPACE From 225dd568af0c594dd0efacbad7b6568309a9cb7c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 13 Jun 2019 11:42:26 +0200 Subject: [PATCH 070/264] QTestLib: Introduce nullptr Apply Fixits by Qt Creator with some amendments. Task-number: QTBUG-69413 Change-Id: I620e40a277dc2b20b0ec26fc32577e66b0456bb3 Reviewed-by: Frederik Gladhorn --- src/testlib/qabstracttestlogger.cpp | 2 +- src/testlib/qbenchmark.cpp | 4 +-- src/testlib/qbenchmarkperfevents.cpp | 2 +- src/testlib/qsignaldumper.cpp | 4 +-- src/testlib/qtestblacklist.cpp | 2 +- src/testlib/qtestcase.cpp | 43 +++++++++++++-------------- src/testlib/qtestelementattribute.cpp | 4 +-- src/testlib/qtestlog.cpp | 10 +++---- src/testlib/qtestresult.cpp | 36 +++++++++++----------- src/testlib/qtesttable.cpp | 8 ++--- src/testlib/qtestxunitstreamer.cpp | 2 +- src/testlib/qxunittestlogger.cpp | 4 +-- 12 files changed, 59 insertions(+), 62 deletions(-) diff --git a/src/testlib/qabstracttestlogger.cpp b/src/testlib/qabstracttestlogger.cpp index 2b54cd410b..ff05dd88c7 100644 --- a/src/testlib/qabstracttestlogger.cpp +++ b/src/testlib/qabstracttestlogger.cpp @@ -87,7 +87,7 @@ QAbstractTestLogger::~QAbstractTestLogger() if (stream != stdout) { fclose(stream); } - stream = 0; + stream = nullptr; } void QAbstractTestLogger::filterUnprintable(char *str) const diff --git a/src/testlib/qbenchmark.cpp b/src/testlib/qbenchmark.cpp index 19abd16284..9730e001be 100644 --- a/src/testlib/qbenchmark.cpp +++ b/src/testlib/qbenchmark.cpp @@ -73,7 +73,7 @@ void QBenchmarkGlobalData::setMode(Mode mode) QBenchmarkMeasurerBase * QBenchmarkGlobalData::createMeasurer() { - QBenchmarkMeasurerBase *measurer = 0; + QBenchmarkMeasurerBase *measurer = nullptr; if (0) { #if QT_CONFIG(valgrind) } else if (mode_ == CallgrindChildProcess || mode_ == CallgrindParentProcess) { @@ -112,7 +112,7 @@ QBenchmarkTestMethodData::QBenchmarkTestMethodData() = default; QBenchmarkTestMethodData::~QBenchmarkTestMethodData() { - QBenchmarkTestMethodData::current = 0; + QBenchmarkTestMethodData::current = nullptr; } void QBenchmarkTestMethodData::beginDataRun() diff --git a/src/testlib/qbenchmarkperfevents.cpp b/src/testlib/qbenchmarkperfevents.cpp index ea27f29711..e8c6969d4a 100644 --- a/src/testlib/qbenchmarkperfevents.cpp +++ b/src/testlib/qbenchmarkperfevents.cpp @@ -147,7 +147,7 @@ bool QBenchmarkPerfEventsMeasurer::isAvailable() { // this generates an EFAULT because attr == NULL if perf_event_open is available // if the kernel is too old, it generates ENOSYS - return perf_event_open(0, 0, 0, 0, 0) == -1 && errno != ENOSYS; + return perf_event_open(nullptr, 0, 0, 0, 0) == -1 && errno != ENOSYS; } /* Event list structure diff --git a/src/testlib/qsignaldumper.cpp b/src/testlib/qsignaldumper.cpp index d0b6d0dd3f..70f4d5e63d 100644 --- a/src/testlib/qsignaldumper.cpp +++ b/src/testlib/qsignaldumper.cpp @@ -56,7 +56,7 @@ namespace QTest inline static void qPrintMessage(const QByteArray &ba) { - QTestLog::info(ba.constData(), 0, 0); + QTestLog::info(ba.constData(), nullptr, 0); } Q_GLOBAL_STATIC(QList, ignoreClasses) @@ -169,7 +169,7 @@ static void qSignalDumperCallbackEndSignal(QObject *caller, int /*signal_index*/ void QSignalDumper::startDump() { static QSignalSpyCallbackSet set = { QTest::qSignalDumperCallback, - QTest::qSignalDumperCallbackSlot, QTest::qSignalDumperCallbackEndSignal, 0 }; + QTest::qSignalDumperCallbackSlot, QTest::qSignalDumperCallbackEndSignal, nullptr }; qt_register_signal_spy_callbacks(&set); } diff --git a/src/testlib/qtestblacklist.cpp b/src/testlib/qtestblacklist.cpp index 596788e297..73757a844c 100644 --- a/src/testlib/qtestblacklist.cpp +++ b/src/testlib/qtestblacklist.cpp @@ -224,7 +224,7 @@ static bool checkCondition(const QByteArray &condition) } static bool ignoreAll = false; -static std::set *ignoredTests = 0; +static std::set *ignoredTests = nullptr; namespace QTestPrivate { diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index ce0abba17b..a3141ba067 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -289,7 +289,7 @@ namespace QTest { class WatchDog; -static QObject *currentTestObject = 0; +static QObject *currentTestObject = nullptr; static QString mainSourcePath; #if defined(Q_OS_MACOS) @@ -423,7 +423,7 @@ Q_TESTLIB_EXPORT bool printAvailableFunctions = false; Q_TESTLIB_EXPORT QStringList testFunctions; Q_TESTLIB_EXPORT QStringList testTags; -static void qPrintTestSlots(FILE *stream, const char *filter = 0) +static void qPrintTestSlots(FILE *stream, const char *filter = nullptr) { for (int i = 0; i < QTest::currentTestObject->metaObject()->methodCount(); ++i) { QMetaMethod sl = QTest::currentTestObject->metaObject()->method(i); @@ -516,7 +516,7 @@ static int qToInt(const char *str) Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, const char *const argv[], bool qml) { int logFormat = -1; // Not set - const char *logFilename = 0; + const char *logFilename = nullptr; QTest::testFunctions.clear(); QTest::testTags.clear(); @@ -897,7 +897,7 @@ struct QTestDataSetter } ~QTestDataSetter() { - QTestResult::setCurrentTestData(0); + QTestResult::setCurrentTestData(nullptr); } }; @@ -974,11 +974,11 @@ void TestMethods::invokeTestOnData(int index) const if (i == -1) { QTestLog::info(qPrintable( QString::fromLatin1("warmup stage result : %1") - .arg(QBenchmarkTestMethodData::current->result.value)), 0, 0); + .arg(QBenchmarkTestMethodData::current->result.value)), nullptr, 0); } else { QTestLog::info(qPrintable( QString::fromLatin1("accumulation stage result: %1") - .arg(QBenchmarkTestMethodData::current->result.value)), 0, 0); + .arg(QBenchmarkTestMethodData::current->result.value)), nullptr, 0); } } } @@ -1115,7 +1115,7 @@ bool TestMethods::invokeTest(int index, const char *data, WatchDog *watchDog) co if (data && !dataCount) { // Let empty data tag through. if (!*data) - data = 0; + data = nullptr; else { fprintf(stderr, "Unknown testdata for function %s(): '%s'\n", name.constData(), data); fprintf(stderr, "Function has no testdata.\n"); @@ -1130,10 +1130,9 @@ bool TestMethods::invokeTest(int index, const char *data, WatchDog *watchDog) co if (!data || !qstrcmp(data, table.testData(curDataIndex)->dataTag())) { foundFunction = true; - QTestPrivate::checkBlackLists(name.constData(), dataCount ? table.testData(curDataIndex)->dataTag() : 0); + QTestPrivate::checkBlackLists(name.constData(), dataCount ? table.testData(curDataIndex)->dataTag() : nullptr); - QTestDataSetter s(curDataIndex >= dataCount ? static_cast(0) - : table.testData(curDataIndex)); + QTestDataSetter s(curDataIndex >= dataCount ? nullptr : table.testData(curDataIndex)); QTestPrivate::qtestMouseButtons = Qt::NoButton; if (watchDog) @@ -1156,14 +1155,14 @@ bool TestMethods::invokeTest(int index, const char *data, WatchDog *watchDog) co return false; } - QTestResult::setCurrentGlobalTestData(0); + QTestResult::setCurrentGlobalTestData(nullptr); ++curGlobalDataIndex; } while (curGlobalDataIndex < globalDataCount); QTestResult::finishedCurrentTestFunction(); QTestResult::setSkipCurrentTest(false); QTestResult::setBlacklistCurrentTest(false); - QTestResult::setCurrentTestData(0); + QTestResult::setCurrentTestData(nullptr); return true; } @@ -1241,7 +1240,7 @@ char *toHexRepresentation(const char *ba, int length) * */ const int maxLen = 50; const int len = qMin(maxLen, length); - char *result = 0; + char *result = nullptr; if (length > maxLen) { const int size = len * 3 + 4; @@ -1497,7 +1496,7 @@ void TestMethods::invokeTests(QObject *testObject) const QTestResult::finishedCurrentTestDataCleanup(); } QTestResult::finishedCurrentTestFunction(); - QTestResult::setCurrentTestFunction(0); + QTestResult::setCurrentTestFunction(nullptr); } #if defined(Q_OS_UNIX) @@ -1567,7 +1566,7 @@ FatalSignalHandler::FatalSignalHandler() stack.ss_flags = 0; stack.ss_size = sizeof alternate_stack; stack.ss_sp = alternate_stack; - sigaltstack(&stack, 0); + sigaltstack(&stack, nullptr); act.sa_flags |= SA_ONSTACK; #endif @@ -1586,7 +1585,7 @@ FatalSignalHandler::FatalSignalHandler() oldact.sa_flags & SA_SIGINFO || #endif oldact.sa_handler != SIG_DFL) { - sigaction(fatalSignals[i], &oldact, 0); + sigaction(fatalSignals[i], &oldact, nullptr); } else { sigaddset(&handledSignals, fatalSignals[i]); @@ -1611,7 +1610,7 @@ FatalSignalHandler::~FatalSignalHandler() // If someone overwrote it in the mean time, put it back if (oldact.sa_handler != FatalSignalHandler::signal) - sigaction(i, &oldact, 0); + sigaction(i, &oldact, nullptr); } } @@ -1927,7 +1926,7 @@ int QTest::qRun() QTestResult::addFailure("Caught unhandled exception", __FILE__, __LINE__); if (QTestResult::currentTestFunction()) { QTestResult::finishedCurrentTestFunction(); - QTestResult::setCurrentTestFunction(0); + QTestResult::setCurrentTestFunction(nullptr); } QTestLog::stopLogging(); @@ -1936,7 +1935,7 @@ int QTest::qRun() IOPMAssertionRelease(powerID); } #endif - currentTestObject = 0; + currentTestObject = nullptr; // Rethrow exception to make debugging easier. throw; @@ -1957,13 +1956,13 @@ int QTest::qRun() */ void QTest::qCleanup() { - currentTestObject = 0; + currentTestObject = nullptr; QTestTable::clearGlobalTestTable(); QTestLog::stopLogging(); delete QBenchmarkGlobalData::current; - QBenchmarkGlobalData::current = 0; + QBenchmarkGlobalData::current = nullptr; QSignalDumper::endDump(); @@ -2727,7 +2726,7 @@ template <> Q_TESTLIB_EXPORT char *QTest::toString(const char &t) char *QTest::toString(const char *str) { if (!str) - return 0; + return nullptr; char *msg = new char[strlen(str) + 1]; return qstrcpy(msg, str); } diff --git a/src/testlib/qtestelementattribute.cpp b/src/testlib/qtestelementattribute.cpp index 1aa54d767f..e194ee50f7 100644 --- a/src/testlib/qtestelementattribute.cpp +++ b/src/testlib/qtestelementattribute.cpp @@ -141,7 +141,7 @@ const char *QTestElementAttribute::name() const if (attributeIndex != QTest::AI_Undefined) return AttributeNames[attributeIndex]; - return 0; + return nullptr; } QTest::AttributeIndex QTestElementAttribute::index() const @@ -164,7 +164,7 @@ bool QTestElementAttribute::setPair(QTest::AttributeIndex index, const char *val attributeIndex = index; attributeValue = qstrdup(value); - return attributeValue != 0; + return attributeValue != nullptr; } QT_END_NAMESPACE diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp index ddebf1105f..f3ebf343c5 100644 --- a/src/testlib/qtestlog.cpp +++ b/src/testlib/qtestlog.cpp @@ -166,7 +166,7 @@ namespace QTest { IgnoreResultList *next = nullptr; }; - static IgnoreResultList *ignoreResultList = 0; + static IgnoreResultList *ignoreResultList = nullptr; static QVector loggers; static bool loggerUsingStdout = false; @@ -181,7 +181,7 @@ namespace QTest { { if (!ignoreResultList) return false; - IgnoreResultList *last = 0; + IgnoreResultList *last = nullptr; IgnoreResultList *list = ignoreResultList; while (list) { if (list->matches(type, message)) { @@ -191,7 +191,7 @@ namespace QTest { else if (list->next) ignoreResultList = list->next; else - ignoreResultList = 0; + ignoreResultList = nullptr; delete list; return true; @@ -438,11 +438,11 @@ void QTestLog::stopLogging() void QTestLog::addLogger(LogMode mode, const char *filename) { if (filename && strcmp(filename, "-") == 0) - filename = 0; + filename = nullptr; if (!filename) QTest::loggerUsingStdout = true; - QAbstractTestLogger *logger = 0; + QAbstractTestLogger *logger = nullptr; switch (mode) { case QTestLog::Plain: logger = new QPlainTestLogger(filename); diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp index 8d65bff5c4..eeae7ef0f4 100644 --- a/src/testlib/qtestresult.cpp +++ b/src/testlib/qtestresult.cpp @@ -49,33 +49,33 @@ #include #include -static const char *currentAppName = 0; +static const char *currentAppName = nullptr; QT_BEGIN_NAMESPACE namespace QTest { - static QTestData *currentTestData = 0; - static QTestData *currentGlobalTestData = 0; - static const char *currentTestFunc = 0; - static const char *currentTestObjectName = 0; + static QTestData *currentTestData = nullptr; + static QTestData *currentGlobalTestData = nullptr; + static const char *currentTestFunc = nullptr; + static const char *currentTestObjectName = nullptr; static bool failed = false; static bool skipCurrentTest = false; static bool blacklistCurrentTest = false; - static const char *expectFailComment = 0; + static const char *expectFailComment = nullptr; static int expectFailMode = 0; } void QTestResult::reset() { - QTest::currentTestData = 0; - QTest::currentGlobalTestData = 0; - QTest::currentTestFunc = 0; - QTest::currentTestObjectName = 0; + QTest::currentTestData = nullptr; + QTest::currentGlobalTestData = nullptr; + QTest::currentTestFunc = nullptr; + QTest::currentTestObjectName = nullptr; QTest::failed = false; - QTest::expectFailComment = 0; + QTest::expectFailComment = nullptr; QTest::expectFailMode = 0; QTest::blacklistCurrentTest = false; @@ -127,18 +127,18 @@ static void clearExpectFail() { QTest::expectFailMode = 0; delete [] const_cast(QTest::expectFailComment); - QTest::expectFailComment = 0; + QTest::expectFailComment = nullptr; } void QTestResult::finishedCurrentTestData() { if (QTest::expectFailMode) - addFailure("QEXPECT_FAIL was called without any subsequent verification statements", 0, 0); + addFailure("QEXPECT_FAIL was called without any subsequent verification statements", nullptr, 0); clearExpectFail(); if (!QTest::failed && QTestLog::unhandledIgnoreMessages()) { QTestLog::printUnhandledIgnoreMessages(); - addFailure("Not all expected messages were received", 0, 0); + addFailure("Not all expected messages were received", nullptr, 0); } QTestLog::clearIgnoreMessages(); } @@ -158,7 +158,7 @@ void QTestResult::finishedCurrentTestDataCleanup() void QTestResult::finishedCurrentTestFunction() { - QTest::currentTestFunc = 0; + QTest::currentTestFunc = nullptr; QTest::failed = false; QTestLog::leaveTestFunction(); @@ -171,14 +171,12 @@ const char *QTestResult::currentTestFunction() const char *QTestResult::currentDataTag() { - return QTest::currentTestData ? QTest::currentTestData->dataTag() - : static_cast(0); + return QTest::currentTestData ? QTest::currentTestData->dataTag() : nullptr; } const char *QTestResult::currentGlobalDataTag() { - return QTest::currentGlobalTestData ? QTest::currentGlobalTestData->dataTag() - : static_cast(0); + return QTest::currentGlobalTestData ? QTest::currentGlobalTestData->dataTag() : nullptr; } static bool isExpectFailData(const char *dataIndex) diff --git a/src/testlib/qtesttable.cpp b/src/testlib/qtesttable.cpp index e2e72b125f..85dff17017 100644 --- a/src/testlib/qtesttable.cpp +++ b/src/testlib/qtesttable.cpp @@ -78,8 +78,8 @@ public: static QTestTable *gTable; }; -QTestTable *QTestTablePrivate::currentTestTable = 0; -QTestTable *QTestTablePrivate::gTable = 0; +QTestTable *QTestTablePrivate::currentTestTable = nullptr; +QTestTable *QTestTablePrivate::gTable = nullptr; void QTestTable::addColumn(int type, const char *name) { @@ -119,7 +119,7 @@ QTestTable::QTestTable() QTestTable::~QTestTable() { - QTestTablePrivate::currentTestTable = 0; + QTestTablePrivate::currentTestTable = nullptr; delete d; } @@ -172,7 +172,7 @@ QTestTable *QTestTable::globalTestTable() void QTestTable::clearGlobalTestTable() { delete QTestTablePrivate::gTable; - QTestTablePrivate::gTable = 0; + QTestTablePrivate::gTable = nullptr; } QTestTable *QTestTable::currentTestTable() diff --git a/src/testlib/qtestxunitstreamer.cpp b/src/testlib/qtestxunitstreamer.cpp index fe9a6e21cc..6b0619d847 100644 --- a/src/testlib/qtestxunitstreamer.cpp +++ b/src/testlib/qtestxunitstreamer.cpp @@ -129,7 +129,7 @@ void QTestXunitStreamer::formatAttributes(const QTestElement* element, const QTe return; } - char const* key = 0; + char const* key = nullptr; if (attrindex == QTest::AI_Description) key = "message"; else if (attrindex != QTest::AI_File && attrindex != QTest::AI_Line) diff --git a/src/testlib/qxunittestlogger.cpp b/src/testlib/qxunittestlogger.cpp index cae959a349..b3cac9cb82 100644 --- a/src/testlib/qxunittestlogger.cpp +++ b/src/testlib/qxunittestlogger.cpp @@ -148,7 +148,7 @@ void QXunitTestLogger::leaveTestFunction() void QXunitTestLogger::addIncident(IncidentTypes type, const char *description, const char *file, int line) { - const char *typeBuf = 0; + const char *typeBuf = nullptr; char buf[100]; switch (type) { @@ -292,7 +292,7 @@ void QXunitTestLogger::addTag(QTestElement* element) void QXunitTestLogger::addMessage(MessageTypes type, const QString &message, const char *file, int line) { QTestElement *errorElement = new QTestElement(QTest::LET_Error); - const char *typeBuf = 0; + const char *typeBuf = nullptr; switch (type) { case QAbstractTestLogger::Warn: From 6aa662343778727d460f8657d3187e407492cdd3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 13 Jun 2019 11:23:26 +0200 Subject: [PATCH 071/264] QTestLib: Fix class declarations/structure - Remove virtual from functions declared as override - Use " = default" for trivial constructors/destructors - Remove all special functions from QTestLog Apply Fixits by Qt Creator with some amendments. Task-number: QTBUG-69413 Change-Id: I812b8116e5b4c927e4e5cee44e63bc705385d866 Reviewed-by: Frederik Gladhorn --- src/testlib/qbenchmarkevent.cpp | 4 +--- src/testlib/qbenchmarkmeasurement_p.h | 2 +- src/testlib/qbenchmarkperfevents_p.h | 20 ++++++++++---------- src/testlib/qcsvbenchmarklogger.cpp | 4 +--- src/testlib/qplaintestlogger.cpp | 4 +--- src/testlib/qtaptestlogger.cpp | 4 +--- src/testlib/qteamcitylogger.cpp | 4 +--- src/testlib/qtestlog_p.h | 7 ++++--- src/testlib/qtestxunitstreamer.cpp | 3 +-- src/testlib/qxmltestlogger.cpp | 4 +--- 10 files changed, 22 insertions(+), 34 deletions(-) diff --git a/src/testlib/qbenchmarkevent.cpp b/src/testlib/qbenchmarkevent.cpp index 41be9fa468..bcae9325cd 100644 --- a/src/testlib/qbenchmarkevent.cpp +++ b/src/testlib/qbenchmarkevent.cpp @@ -46,9 +46,7 @@ QT_BEGIN_NAMESPACE QBenchmarkEvent::QBenchmarkEvent() = default; -QBenchmarkEvent::~QBenchmarkEvent() -{ -} +QBenchmarkEvent::~QBenchmarkEvent() = default; void QBenchmarkEvent::start() { diff --git a/src/testlib/qbenchmarkmeasurement_p.h b/src/testlib/qbenchmarkmeasurement_p.h index 8dbfd4b618..cecf97963b 100644 --- a/src/testlib/qbenchmarkmeasurement_p.h +++ b/src/testlib/qbenchmarkmeasurement_p.h @@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE class QBenchmarkMeasurerBase { public: - virtual ~QBenchmarkMeasurerBase() {} + virtual ~QBenchmarkMeasurerBase() = default; virtual void init() {} virtual void start() = 0; virtual qint64 checkpoint() = 0; diff --git a/src/testlib/qbenchmarkperfevents_p.h b/src/testlib/qbenchmarkperfevents_p.h index 47af4db9f8..15b946ad26 100644 --- a/src/testlib/qbenchmarkperfevents_p.h +++ b/src/testlib/qbenchmarkperfevents_p.h @@ -60,16 +60,16 @@ class QBenchmarkPerfEventsMeasurer : public QBenchmarkMeasurerBase public: QBenchmarkPerfEventsMeasurer(); ~QBenchmarkPerfEventsMeasurer(); - virtual void init() override; - virtual void start() override; - virtual qint64 checkpoint() override; - virtual qint64 stop() override; - virtual bool isMeasurementAccepted(qint64 measurement) override; - virtual int adjustIterationCount(int suggestion) override; - virtual int adjustMedianCount(int suggestion) override; - virtual bool repeatCount() override { return 1; } - virtual bool needsWarmupIteration() override { return true; } - virtual QTest::QBenchmarkMetric metricType() override; + void init() override; + void start() override; + qint64 checkpoint() override; + qint64 stop() override; + bool isMeasurementAccepted(qint64 measurement) override; + int adjustIterationCount(int suggestion) override; + int adjustMedianCount(int suggestion) override; + bool repeatCount() override { return 1; } + bool needsWarmupIteration() override { return true; } + QTest::QBenchmarkMetric metricType() override; static bool isAvailable(); static QTest::QBenchmarkMetric metricForEvent(quint32 type, quint64 event_id); diff --git a/src/testlib/qcsvbenchmarklogger.cpp b/src/testlib/qcsvbenchmarklogger.cpp index ee7270b634..f410ec6e3d 100644 --- a/src/testlib/qcsvbenchmarklogger.cpp +++ b/src/testlib/qcsvbenchmarklogger.cpp @@ -46,9 +46,7 @@ QCsvBenchmarkLogger::QCsvBenchmarkLogger(const char *filename) { } -QCsvBenchmarkLogger::~QCsvBenchmarkLogger() -{ -} +QCsvBenchmarkLogger::~QCsvBenchmarkLogger() = default; void QCsvBenchmarkLogger::startLogging() { diff --git a/src/testlib/qplaintestlogger.cpp b/src/testlib/qplaintestlogger.cpp index ed53dcdde8..c2e0bebaa0 100644 --- a/src/testlib/qplaintestlogger.cpp +++ b/src/testlib/qplaintestlogger.cpp @@ -316,9 +316,7 @@ QPlainTestLogger::QPlainTestLogger(const char *filename) { } -QPlainTestLogger::~QPlainTestLogger() -{ -} +QPlainTestLogger::~QPlainTestLogger() = default; void QPlainTestLogger::startLogging() { diff --git a/src/testlib/qtaptestlogger.cpp b/src/testlib/qtaptestlogger.cpp index 476761e602..5b5a3c4875 100644 --- a/src/testlib/qtaptestlogger.cpp +++ b/src/testlib/qtaptestlogger.cpp @@ -55,9 +55,7 @@ QTapTestLogger::QTapTestLogger(const char *filename) { } -QTapTestLogger::~QTapTestLogger() -{ -} +QTapTestLogger::~QTapTestLogger() = default; void QTapTestLogger::startLogging() { diff --git a/src/testlib/qteamcitylogger.cpp b/src/testlib/qteamcitylogger.cpp index 88c83d1269..6c0605130b 100644 --- a/src/testlib/qteamcitylogger.cpp +++ b/src/testlib/qteamcitylogger.cpp @@ -103,9 +103,7 @@ QTeamCityLogger::QTeamCityLogger(const char *filename) { } -QTeamCityLogger::~QTeamCityLogger() -{ -} +QTeamCityLogger::~QTeamCityLogger() = default; void QTeamCityLogger::startLogging() { diff --git a/src/testlib/qtestlog_p.h b/src/testlib/qtestlog_p.h index e63e89a78e..fff36f290d 100644 --- a/src/testlib/qtestlog_p.h +++ b/src/testlib/qtestlog_p.h @@ -66,6 +66,10 @@ class QTestData; class Q_TESTLIB_EXPORT QTestLog { public: + QTestLog() = delete; + ~QTestLog() = delete; + Q_DISABLE_COPY_MOVE(QTestLog) + enum LogMode { Plain = 0, XML, LightXML, XunitXML, CSV, TeamCity, TAP #if defined(QT_USE_APPLE_UNIFIED_LOGGING) @@ -135,9 +139,6 @@ public: static qreal msecsFunctionTime() { return QTestLog::nsecsFunctionTime() / 1000000.; } private: - QTestLog(); - ~QTestLog(); - static bool printAvailableTags; }; diff --git a/src/testlib/qtestxunitstreamer.cpp b/src/testlib/qtestxunitstreamer.cpp index 6b0619d847..bdbdfa9610 100644 --- a/src/testlib/qtestxunitstreamer.cpp +++ b/src/testlib/qtestxunitstreamer.cpp @@ -54,8 +54,7 @@ QTestXunitStreamer::QTestXunitStreamer(QXunitTestLogger *logger) QTEST_ASSERT(testLogger); } -QTestXunitStreamer::~QTestXunitStreamer() -{} +QTestXunitStreamer::~QTestXunitStreamer() = default; void QTestXunitStreamer::indentForElement(const QTestElement* element, char* buf, int size) { diff --git a/src/testlib/qxmltestlogger.cpp b/src/testlib/qxmltestlogger.cpp index c47042c3a0..84126c10eb 100644 --- a/src/testlib/qxmltestlogger.cpp +++ b/src/testlib/qxmltestlogger.cpp @@ -107,9 +107,7 @@ QXmlTestLogger::QXmlTestLogger(XmlMode mode, const char *filename) { } -QXmlTestLogger::~QXmlTestLogger() -{ -} +QXmlTestLogger::~QXmlTestLogger() = default; void QXmlTestLogger::startLogging() { From 3f8e754f07db944dc74d84cc1c24d3e11677ad09 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 11 Jul 2019 14:08:59 +0200 Subject: [PATCH 072/264] CMake: Properly escape '.lib' in regex In a CMake regex, you need two backslashes to escape a character. The .in file therefore needs four backslashes ... This amends ba4fdd99fff80 Fixes: QTBUG-76698 Change-Id: Ic757354ba596bf020c3ee5e90ee6d2d0fe3ba352 Reviewed-by: Alexandru Croitor --- mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in index 8a3f202c53..d4fd057682 100644 --- a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in +++ b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in @@ -75,7 +75,7 @@ function(_qt5_$${CMAKE_MODULE_NAME}_process_prl_file prl_file_location Configura # Handle normal libraries passed as -lfoo set(_lib \"${CMAKE_MATCH_1}\") foreach(_standard_library ${_standard_libraries}) - if(_standard_library MATCHES \"^${_lib}(\\.lib)?$\") + if(_standard_library MATCHES \"^${_lib}(\\\\.lib)?$\") set(_lib_is_default_linked TRUE) break() endif() From 786c58817187bb18552934c807ba7a7ea845f49e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20de=20la=20Rocha?= Date: Wed, 10 Jul 2019 18:09:38 +0200 Subject: [PATCH 073/264] Windows QPA: Fix handling of mouse messages synthesized by the OS The old handler only marked mouse events associated with mouse messages synthesized by the OS with Qt::MouseEventSynthesizedBySystem when these messages resulted from touch screen, not tablet input. Quick seems to depend on this behavior. Fixes: QTBUG-76617 Change-Id: Ib863d73ae9325f9a19d8a175817fef4e82f7df0b Reviewed-by: Friedemann Kleint --- .../platforms/windows/qwindowspointerhandler.cpp | 11 +++++++---- .../platforms/windows/qwindowspointerhandler.h | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index b35629e2ce..71a09304c5 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -80,13 +80,12 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q *result = 0; const quint32 pointerId = GET_POINTERID_WPARAM(msg.wParam); - POINTER_INPUT_TYPE pointerType; - if (!QWindowsContext::user32dll.getPointerType(pointerId, &pointerType)) { + if (!QWindowsContext::user32dll.getPointerType(pointerId, &m_pointerType)) { qWarning() << "GetPointerType() failed:" << qt_error_string(); return false; } - switch (pointerType) { + switch (m_pointerType) { case QT_PT_POINTER: case QT_PT_MOUSE: case QT_PT_TOUCHPAD: { @@ -728,7 +727,11 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, } Qt::MouseEventSource source = Qt::MouseEventNotSynthesized; - if (isMouseEventSynthesizedFromPenOrTouch()) { + // Following the logic of the old mouse handler, only events synthesized + // for touch screen are marked as such. On some systems, using the bit 7 of + // the extra msg info for checking if synthesized for touch does not work, + // so we use the pointer type of the last pointer message. + if (isMouseEventSynthesizedFromPenOrTouch() && m_pointerType == QT_PT_TOUCH) { if (QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch) return false; source = Qt::MouseEventSynthesizedBySystem; diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.h b/src/plugins/platforms/windows/qwindowspointerhandler.h index ccbb1d3939..b6b89cefed 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.h +++ b/src/plugins/platforms/windows/qwindowspointerhandler.h @@ -82,6 +82,7 @@ private: bool m_needsEnterOnPointerUpdate = false; QEvent::Type m_lastEventType = QEvent::None; Qt::MouseButton m_lastEventButton = Qt::NoButton; + DWORD m_pointerType = 0; }; QT_END_NAMESPACE From d01693733f6c1ebe6b3709f9c1284239ce3b5354 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 20 Jun 2019 16:57:50 -0700 Subject: [PATCH 074/264] QDirIterator: don't require NFD normalization on Darwin for validity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HFS+ filesystems do enforce NFD normalization, so the test worked for those filesystems. But on APFS, the filesystem is normalization- insensitive but preserves it, so our transformation caused valid files to be rejected. This commit also optimizes the solution for all systems too. Instead of converting from 8-bit to UTF-16 then back to 8-bit (allocating memory in both steps), we only convert to UTF-16. And if we detect the locale is UTF-8, then we use the further optimized QUtf8::isValidUtf8 function that doesn't allocate any memory at all (ditto for US-ASCII, the case of someone running with LANG=C). Fixes: QTBUG-76522 Change-Id: Ief874765cd7b43798de3fffd15aa0d81620ad317 Reviewed-by: Tor Arne Vestbø Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/corelib/io/qfilesystemiterator_unix.cpp | 47 +++++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp index a9acf542d4..92ebdf0341 100644 --- a/src/corelib/io/qfilesystemiterator_unix.cpp +++ b/src/corelib/io/qfilesystemiterator_unix.cpp @@ -40,13 +40,54 @@ #include "qplatformdefs.h" #include "qfilesystemiterator_p.h" +#if QT_CONFIG(textcodec) +# include +# include +#endif + #ifndef QT_NO_FILESYSTEMITERATOR +#include + #include #include QT_BEGIN_NAMESPACE +static bool checkNameDecodable(const char *d_name, qsizetype len) +{ + // This function is called in a loop from advance() below, but the loop is + // usually run only once. + +#if QT_CONFIG(textcodec) + // We identify the codecs by their RFC 2978 MIBenum values. In this + // function: + // 3 US-ASCII (ANSI X3.4-1986) + // 4 Latin1 (ISO-8859-1) + // 106 UTF-8 + QTextCodec *codec = QTextCodec::codecForLocale(); +# ifdef QT_LOCALE_IS_UTF8 + int mibEnum = 106; +# else + int mibEnum = codec->mibEnum(); +# endif + if (Q_LIKELY(mibEnum == 106)) // UTF-8 + return QUtf8::isValidUtf8(d_name, len).isValidUtf8; + if (mibEnum == 3) // US-ASCII + return QtPrivate::isAscii(QLatin1String(d_name, len)); + if (mibEnum == 4) // Latin 1 + return true; + + // fall back to generic QTextCodec + QTextCodec::ConverterState cs(QTextCodec::IgnoreHeader); + codec->toUnicode(d_name, len, &cs); + return cs.invalidChars == 0 && cs.remainingChars == 0; +#else + // if we have no text codecs, then QString::fromLocal8Bit is fromLatin1 + return true; +#endif +} + QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, const QStringList &nameFilters, QDirIterator::IteratorFlags flags) : nativePath(entry.nativeFilePath()) @@ -81,9 +122,9 @@ bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaDa dirEntry = QT_READDIR(dir); if (dirEntry) { - // process entries with correct UTF-8 names only - if (QFile::encodeName(QFile::decodeName(dirEntry->d_name)) == dirEntry->d_name) { - fileEntry = QFileSystemEntry(nativePath + QByteArray(dirEntry->d_name), QFileSystemEntry::FromNativePath()); + qsizetype len = strlen(dirEntry->d_name); + if (checkNameDecodable(dirEntry->d_name, len)) { + fileEntry = QFileSystemEntry(nativePath + QByteArray(dirEntry->d_name, len), QFileSystemEntry::FromNativePath()); metaData.fillFromDirEnt(*dirEntry); return true; } From 54684f10e90b2ab1705cad97dd0a5d3942f06cc3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 11 Jul 2019 13:35:45 +0200 Subject: [PATCH 075/264] QSaveFile: Fix changing the file name after hitting on readonly file The call to QFileDevice::unsetError() in QSaveFile::open() does not clear QSaveFilePrivate::writeError. Clear it in addition. Fixes: QTBUG-77007 Change-Id: I5e5009750f1726d1c74c1b4eb1c33f3a5393fe4f Reviewed-by: David Faure --- src/corelib/io/qsavefile.cpp | 1 + .../corelib/io/qsavefile/tst_qsavefile.cpp | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp index 0cbc8c2234..fac8892da2 100644 --- a/src/corelib/io/qsavefile.cpp +++ b/src/corelib/io/qsavefile.cpp @@ -197,6 +197,7 @@ bool QSaveFile::open(OpenMode mode) return false; } unsetError(); + d->writeError = QFileDevice::NoError; if ((mode & (ReadOnly | WriteOnly)) == 0) { qWarning("QSaveFile::open: Open mode not specified"); return false; diff --git a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp index 96970421d3..f1327933c4 100644 --- a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp +++ b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp @@ -72,6 +72,7 @@ public slots: private slots: void transactionalWrite(); + void retryTransactionalWrite(); void textStreamManualFlush(); void textStreamAutoFlush(); void saveTwice(); @@ -129,6 +130,39 @@ void tst_QSaveFile::transactionalWrite() QCOMPARE(QFile::permissions(targetFile), QFile::permissions(otherFile)); } +// QTBUG-77007: Simulate the case of an application with a loop prompting +// to retry saving on failure. Create a read-only file first (Unix only) +void tst_QSaveFile::retryTransactionalWrite() +{ +#ifndef Q_OS_UNIX + QSKIP("This test is Unix only"); +#endif + QTemporaryDir dir; + QVERIFY2(dir.isValid(), qPrintable(dir.errorString())); + + QString targetFile = dir.path() + QLatin1String("/outfile"); + const QString readOnlyName = targetFile + QLatin1String(".ro"); + { + QFile readOnlyFile(readOnlyName); + QVERIFY2(readOnlyFile.open(QIODevice::WriteOnly), msgCannotOpen(readOnlyFile).constData()); + readOnlyFile.write("Hello"); + readOnlyFile.close(); + auto permissions = readOnlyFile.permissions(); + permissions &= ~(QFileDevice::WriteOwner | QFileDevice::WriteGroup | QFileDevice::WriteUser); + QVERIFY(readOnlyFile.setPermissions(permissions)); + } + + QSaveFile file(readOnlyName); + QVERIFY(!file.open(QIODevice::WriteOnly)); + + file.setFileName(targetFile); + QVERIFY2(file.open(QIODevice::WriteOnly), msgCannotOpen(file).constData()); + QVERIFY(file.isOpen()); + QCOMPARE(file.write("Hello"), Q_INT64_C(5)); + QCOMPARE(file.error(), QFile::NoError); + QVERIFY(file.commit()); +} + void tst_QSaveFile::saveTwice() { // Check that we can reuse a QSaveFile object From 987dde2965f4fba32984041a0f2709127e9edd93 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 21 Jun 2019 22:53:14 +0200 Subject: [PATCH 076/264] Optimize and fix handling of QtMessageHandlers A function may almost always have static storage duration, but that does not necessarily mean that we can store and load pointers to them without memory ordering. Play it safe and use store-release and load-acquire for them (which combines to ordered for the fetchAndSet call in qInstall*Handler(), as we don't know what the caller will do with the returned function pointer). Also change the initial value of the atomic pointer to nullptr. Nullptr already signified the default handler in qInstall*Handler(), so the API doesn't change. But by using nullptr to mean default, we place these variables in the BSS segment instead of TEXT, save dynamic init, or at least a relocation, and we dodge the smelly comparison of function pointers, using comparison against nullptr instead. Also, as a drive-by, put the call to ungrabMessageHandler() in a scope-guard. Both the message handler, as well as the Qt code calling it (toLocal8Bit()!), may throw, and that would stop all further logging. In Qt 5.9, we can't use qScopeGuard(), yet, so use a local struct calling ungrabMessageHandler() in its dtor. The code still has one problem: When a logging action is underway, and another thread exchanges the message handler, we might still execute code in the old handler. This is probably not a problem in practice, since no-one will use a dynamically-compiled function for logging (right? :), but should probably be documented or fixed. This patch does not address this issue, though. Change-Id: I21aa907288b9c8c6646787b4001002d145b114a5 Reviewed-by: Thiago Macieira (cherry picked from commit cd401b74a13cd9d9a47d977f195c7985cf725d55) (cherry picked from commit ea16c860bd75a35134ebb1d4f3be5db58f4a4e21) --- src/corelib/global/qlogging.cpp | 35 +++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 30232170fb..1a74757032 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1512,9 +1512,9 @@ static void qDefaultMsgHandler(QtMsgType type, const char *buf); static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &buf); // pointer to QtMsgHandler debug handler (without context) -static QBasicAtomicPointer msgHandler = Q_BASIC_ATOMIC_INITIALIZER(qDefaultMsgHandler); +static QBasicAtomicPointer msgHandler = Q_BASIC_ATOMIC_INITIALIZER(nullptr); // pointer to QtMessageHandler debug handler (with context) -static QBasicAtomicPointer messageHandler = Q_BASIC_ATOMIC_INITIALIZER(qDefaultMessageHandler); +static QBasicAtomicPointer messageHandler = Q_BASIC_ATOMIC_INITIALIZER(nullptr); // ------------------------ Alternate logging sinks ------------------------- @@ -1826,14 +1826,17 @@ static void qt_message_print(QtMsgType msgType, const QMessageLogContext &contex // prevent recursion in case the message handler generates messages // itself, e.g. by using Qt API if (grabMessageHandler()) { + struct Ungrabber { + ~Ungrabber() { ungrabMessageHandler(); } + } ungrabber; + auto oldStyle = msgHandler.loadAcquire(); + auto newStye = messageHandler.loadAcquire(); // prefer new message handler over the old one - if (msgHandler.load() == qDefaultMsgHandler - || messageHandler.load() != qDefaultMessageHandler) { - (*messageHandler.load())(msgType, context, message); + if (newStye || !oldStyle) { + (newStye ? newStye : qDefaultMessageHandler)(msgType, context, message); } else { - (*msgHandler.load())(msgType, message.toLocal8Bit().constData()); + (oldStyle ? oldStyle : qDefaultMsgHandler)(msgType, message.toLocal8Bit().constData()); } - ungrabMessageHandler(); } else { fprintf(stderr, "%s\n", message.toLocal8Bit().constData()); } @@ -2084,18 +2087,20 @@ void qErrnoWarning(int code, const char *msg, ...) QtMessageHandler qInstallMessageHandler(QtMessageHandler h) { - if (!h) - h = qDefaultMessageHandler; - //set 'h' and return old message handler - return messageHandler.fetchAndStoreRelaxed(h); + const auto old = messageHandler.fetchAndStoreOrdered(h); + if (old) + return old; + else + return qDefaultMessageHandler; } QtMsgHandler qInstallMsgHandler(QtMsgHandler h) { - if (!h) - h = qDefaultMsgHandler; - //set 'h' and return old message handler - return msgHandler.fetchAndStoreRelaxed(h); + const auto old = msgHandler.fetchAndStoreOrdered(h); + if (old) + return old; + else + return qDefaultMsgHandler; } void qSetMessagePattern(const QString &pattern) From 135aa77021519ef833c807d49d4fe3428ab970e5 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 1 Jul 2019 13:52:44 +0200 Subject: [PATCH 077/264] Revert "QDistanceField: add missing copy assignment operator" The reverts commit 0624c99ea3d52f07c93378fcf75c3121df1b3928, which fixed a GCC 9 -Wdeprecated-copy warning by adding the copy assignment operator. The 5.12 change 0e162315 fixed the same warning by removing the copy ctor. The merge ef37ab99 removed the copy ctor, but kept the assignment operator added by 0624c99e, bringing the original warning back, but with the roles of copy ctor and assignment operator reversed. One has to give. Change-Id: Ib32841df94a5ff80402a68b5fe776eb82e94136f Reviewed-by: Giuseppe D'Angelo Reviewed-by: Thiago Macieira --- src/gui/text/qdistancefield.cpp | 3 --- src/gui/text/qdistancefield_p.h | 1 - 2 files changed, 4 deletions(-) diff --git a/src/gui/text/qdistancefield.cpp b/src/gui/text/qdistancefield.cpp index 17824a5ba1..d8a971c7b7 100644 --- a/src/gui/text/qdistancefield.cpp +++ b/src/gui/text/qdistancefield.cpp @@ -899,9 +899,6 @@ QDistanceField::QDistanceField(int width, int height) { } -QDistanceField &QDistanceField::operator=(const QDistanceField &) - = default; - QDistanceField::QDistanceField(const QRawFont &font, glyph_t glyph, bool doubleResolution) { setGlyph(font, glyph, doubleResolution); diff --git a/src/gui/text/qdistancefield_p.h b/src/gui/text/qdistancefield_p.h index d6d8edd85d..823bfaf1c6 100644 --- a/src/gui/text/qdistancefield_p.h +++ b/src/gui/text/qdistancefield_p.h @@ -94,7 +94,6 @@ public: QDistanceField(const QRawFont &font, glyph_t glyph, bool doubleResolution = false); QDistanceField(QFontEngine *fontEngine, glyph_t glyph, bool doubleResolution = false); QDistanceField(const QPainterPath &path, glyph_t glyph, bool doubleResolution = false); - QDistanceField &operator=(const QDistanceField &other); bool isNull() const; From ae972a19288ddd47ceac2ee2b7b090c4d12f4731 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 5 Jul 2019 15:41:35 +0200 Subject: [PATCH 078/264] macOS: show QSystemTrayIcon message icons in notification popups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The icon provided was ignored, even though NSUserNotification provides the option to specify a contentImage. The message popping up will show that image on the right side of the notification; it will not repace the application icon on the left side. [ChangeLog][Widgets][QSystemTrayIcon] On macOS, show the icon passed into showMessage in the notification popup Change-Id: I8ecda7f893006e74a4f35f37ddc07063ebfe4e83 Fixes: QTBUG-76916 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm index 4982f5ee05..16543bfb8c 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm @@ -264,7 +264,6 @@ bool QCocoaSystemTrayIcon::supportsMessages() const void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &message, const QIcon& icon, MessageIcon, int) { - Q_UNUSED(icon); if (!m_sys) return; @@ -272,6 +271,12 @@ void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &mess notification.title = [NSString stringWithUTF8String:title.toUtf8().data()]; notification.informativeText = [NSString stringWithUTF8String:message.toUtf8().data()]; + if (!icon.isNull()) { + auto *nsimage = qt_mac_create_nsimage(icon); + [nsimage setTemplate:icon.isMask()]; + notification.contentImage = [nsimage autorelease]; + } + [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; } QT_END_NAMESPACE From 7d4c9a6f8f459747678b87ea4e2bd2e93d686115 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Thu, 11 Jul 2019 20:05:52 +0200 Subject: [PATCH 079/264] Doc: Ensure macOS-specific widget docs are generated on other platforms The Clang parser in QDoc fails to parse the .mm source files if their include files are not found. Add a dummy 'AppKit.h' file under the /doc directory for this purpose, and add its include path to qtwidgets.qdocconf. Task-number: QTBUG-77009 Change-Id: Iaa984cb8f860367cbb7aa95808d26fb69d7da349 Reviewed-by: Paul Wicking --- src/widgets/doc/macOS/AppKit/AppKit.h | 1 + src/widgets/doc/qtwidgets.qdocconf | 3 +++ 2 files changed, 4 insertions(+) create mode 100644 src/widgets/doc/macOS/AppKit/AppKit.h diff --git a/src/widgets/doc/macOS/AppKit/AppKit.h b/src/widgets/doc/macOS/AppKit/AppKit.h new file mode 100644 index 0000000000..29e2004423 --- /dev/null +++ b/src/widgets/doc/macOS/AppKit/AppKit.h @@ -0,0 +1 @@ +// Dummy header used in documentation build diff --git a/src/widgets/doc/qtwidgets.qdocconf b/src/widgets/doc/qtwidgets.qdocconf index 6e04372a8b..548224bf61 100644 --- a/src/widgets/doc/qtwidgets.qdocconf +++ b/src/widgets/doc/qtwidgets.qdocconf @@ -5,6 +5,9 @@ project = QtWidgets description = Qt Widgets Reference Documentation version = $QT_VERSION +# dummy macOS headers for generating docs under non-mac platforms +includepaths += -I./macOS + examplesinstallpath = widgets qhp.projects = QtWidgets From f5840944a6c29df162c5bdcaf488647f17877fab Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Mon, 8 Jul 2019 21:27:14 +0200 Subject: [PATCH 080/264] QByteArray: Clarify that QByteArrays always use the Latin-1 encoding ... irrespective from the users current locale. Fixes: QTBUG-76938 Change-Id: I78810a75ecf9e9f1067363ce56656124b6ddcefd Reviewed-by: Thiago Macieira --- src/corelib/tools/qbytearray.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index c2c2b9de28..2337d9f9c6 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -1072,12 +1072,11 @@ QByteArray qUncompress(const uchar* data, int nbytes) \section2 8-bit Character Comparisons In QByteArray, the notion of uppercase and lowercase and of which - character is greater than or less than another character is - locale dependent. This affects functions that support a case + character is greater than or less than another character is done + in the Latin-1 locale. This affects functions that support a case insensitive option or that compare or lowercase or uppercase their arguments. Case insensitive operations and comparisons will - be accurate if both strings contain only ASCII characters. (If \c - $LC_CTYPE is set, most Unix systems do "the right thing".) + be accurate if both strings contain only Latin-1 characters. Functions that this affects include contains(), indexOf(), lastIndexOf(), operator<(), operator<=(), operator>(), operator>=(), isLower(), isUpper(), toLower() and toUpper(). From e936c2a9a29f4ec1767836a268ea398d6ef4aeeb Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 10 Jul 2019 09:12:11 +0200 Subject: [PATCH 081/264] tst_QObbject: Fix very annoying -Wdeprecated-copy warnings There's like three pages of this when compiling the test :) Change-Id: I923f2c4f5eff7c709977026666cc5b2a2cbfaa72 Reviewed-by: Volker Hilsheimer --- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 1778bf24bc..a805bfb747 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -1401,6 +1401,7 @@ struct CustomType CustomType(const CustomType &other): i1(other.i1), i2(other.i2), i3(other.i3) { ++instanceCount; playWithObjects(); } ~CustomType() { --instanceCount; playWithObjects(); } + CustomType &operator=(const CustomType &) = default; int i1, i2, i3; int value() { return i1 + i2 + i3; } From 56fbcfd2b78bc62eca953a5cd3af831a8964e9e1 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 7 Jun 2019 23:48:53 +0200 Subject: [PATCH 082/264] QPdfWriter: replace a QHash with a static_cast MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The QHash was mapping equivalent values of different enums to each other. The enums have the same enumerators, though, so if we take care to keep the two in sync in the future, we can just static_cast them into each other via int. Change-Id: Ie67978604f8c3b9477419bc6029bbb869061e938 Reviewed-by: Giuseppe D'Angelo Reviewed-by: Mårten Nordheim --- src/gui/painting/qpagedpaintdevice.h | 1 + src/gui/painting/qpdf_p.h | 1 + src/gui/painting/qpdfwriter.cpp | 8 +------- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/gui/painting/qpagedpaintdevice.h b/src/gui/painting/qpagedpaintdevice.h index 1c37c17fa3..21e23e0eb4 100644 --- a/src/gui/painting/qpagedpaintdevice.h +++ b/src/gui/painting/qpagedpaintdevice.h @@ -213,6 +213,7 @@ public: Envelope10 = Comm10E }; + // keep in sync with QPdfEngine::PdfVersion! enum PdfVersion { PdfVersion_1_4, PdfVersion_A1b, PdfVersion_1_6 }; // ### Qt6 Make these virtual diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h index e337c61f64..e5649eb9dc 100644 --- a/src/gui/painting/qpdf_p.h +++ b/src/gui/painting/qpdf_p.h @@ -168,6 +168,7 @@ class Q_GUI_EXPORT QPdfEngine : public QPaintEngine Q_DECLARE_PRIVATE(QPdfEngine) friend class QPdfWriter; public: + // keep in sync with QPagedPaintDevice::PdfVersion! enum PdfVersion { Version_1_4, diff --git a/src/gui/painting/qpdfwriter.cpp b/src/gui/painting/qpdfwriter.cpp index 7f18ce42be..bf7e2d3dca 100644 --- a/src/gui/painting/qpdfwriter.cpp +++ b/src/gui/painting/qpdfwriter.cpp @@ -170,17 +170,11 @@ void QPdfWriter::setPdfVersion(PdfVersion version) { Q_D(QPdfWriter); - static const QHash engineMapping { - {QPdfWriter::PdfVersion_1_4, QPdfEngine::Version_1_4}, - {QPdfWriter::PdfVersion_A1b, QPdfEngine::Version_A1b}, - {QPdfWriter::PdfVersion_1_6, QPdfEngine::Version_1_6} - }; - if (d->pdfVersion == version) return; d->pdfVersion = version; - d->engine->setPdfVersion(engineMapping.value(version, QPdfEngine::Version_1_4)); + d->engine->setPdfVersion(static_cast(static_cast(version))); } /*! From 46d257b19d677e4e4b2a24624716af2207dd9759 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 8 Jun 2019 00:17:53 +0200 Subject: [PATCH 083/264] QPdfEngine: replace a QHash with a C array The mapping is completely static and the key is the index, so just use a const char array. The only twist here is that to avoid relocations, we use an array of const char[4] instead of const char*[]. Change-Id: I001b4db833f14e000676125f6f1be4484d996e0b Reviewed-by: Giuseppe D'Angelo --- src/gui/painting/qpdf.cpp | 12 +++++++----- src/gui/painting/qpdf_p.h | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 25d488961c..f560e1f0f0 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1570,12 +1570,14 @@ void QPdfEnginePrivate::writeHeader() { addXrefEntry(0,false); - static const QHash mapping { - {QPdfEngine::Version_1_4, "1.4"}, - {QPdfEngine::Version_A1b, "1.4"}, - {QPdfEngine::Version_1_6, "1.6"} + // Keep in sync with QPdfEngine::PdfVersion! + static const char mapping[][4] = { + "1.4", // Version_1_4 + "1.4", // Version_A1b + "1.6", // Version_1_6 }; - const char *verStr = mapping.value(pdfVersion, "1.4"); + static const size_t numMappings = sizeof mapping / sizeof *mapping; + const char *verStr = mapping[size_t(pdfVersion) < numMappings ? pdfVersion : 0]; xprintf("%%PDF-%s\n", verStr); xprintf("%%\303\242\303\243\n"); diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h index e5649eb9dc..89e549614a 100644 --- a/src/gui/painting/qpdf_p.h +++ b/src/gui/painting/qpdf_p.h @@ -168,7 +168,7 @@ class Q_GUI_EXPORT QPdfEngine : public QPaintEngine Q_DECLARE_PRIVATE(QPdfEngine) friend class QPdfWriter; public: - // keep in sync with QPagedPaintDevice::PdfVersion! + // keep in sync with QPagedPaintDevice::PdfVersion and QPdfEnginePrivate::writeHeader()::mapping! enum PdfVersion { Version_1_4, From 3c0ba6675b01118aac2fe551470afa3b72a7e969 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Mon, 24 Jun 2019 15:02:34 +0200 Subject: [PATCH 084/264] Fix warnings as errors on macOS with new Xcode 10.2.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A switch statement was comparing enum values of a different enum. Change-Id: I578f79b15b1007afaa64cd3a2a80d6a75d3bed77 Reviewed-by: Qt CI Bot Reviewed-by: Tor Arne Vestbø Reviewed-by: Leander Beernaert --- src/plugins/platforms/cocoa/qprintengine_mac.mm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm index f2f29b26ee..58ad53a6e1 100644 --- a/src/plugins/platforms/cocoa/qprintengine_mac.mm +++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm @@ -522,16 +522,16 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va if (mode == property(PPK_Duplex).toInt() || !d->m_printDevice->supportedDuplexModes().contains(mode)) break; switch (mode) { - case QPrinter::DuplexNone: + case QPrint::DuplexNone: PMSetDuplex(d->settings(), kPMDuplexNone); break; - case QPrinter::DuplexAuto: + case QPrint::DuplexAuto: PMSetDuplex(d->settings(), d->m_pageLayout.orientation() == QPageLayout::Landscape ? kPMDuplexTumble : kPMDuplexNoTumble); break; - case QPrinter::DuplexLongSide: + case QPrint::DuplexLongSide: PMSetDuplex(d->settings(), kPMDuplexNoTumble); break; - case QPrinter::DuplexShortSide: + case QPrint::DuplexShortSide: PMSetDuplex(d->settings(), kPMDuplexTumble); break; default: From 79f9adffc5158b906830dcd7dbdf0e5d44f7ba22 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 12 Jul 2019 10:55:30 +0200 Subject: [PATCH 085/264] Remove QColorTransform::isNull It is an undocumented and unused method with an obscure name. Change-Id: Ife27bf836447865cd305c8c7fc9c438759b439cb Reviewed-by: Marc Mutz --- src/gui/painting/qcolortransform.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/painting/qcolortransform.h b/src/gui/painting/qcolortransform.h index 9274387b97..a83611d666 100644 --- a/src/gui/painting/qcolortransform.h +++ b/src/gui/painting/qcolortransform.h @@ -73,8 +73,6 @@ public: return *this; } - bool isNull() const { return d_ptr.isNull(); } - QRgb map(const QRgb &argb) const; QRgba64 map(const QRgba64 &rgba64) const; QColor map(const QColor &color) const; From 389988c42f901f2d8f75a023039d641cf5fba9de Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 11 Jul 2019 17:51:15 +0200 Subject: [PATCH 086/264] QColorTransform: make fit for release - Unexport the value class, export only out-of-line public member functions to give us more leeway in changing code later (otherwise, we'd be bound by BC with MSVC debug builds, which call even inline methods from the DLL. - Don't use QSharedPointer as the d_ptr. It's twice the size of a pointer. Use a naked pointer-to-const. Derive Private from QSharedData. This requires some changes in QColorSpace, and, as usual, an out-of-line copy ctor. - Add member-swap(), Q_DECLARE_SHARED(). - Drop noexcept from the dtor. It implicitly is, adding it explicitly looks weird. - Pass QRgb and QRgba64 by value, not by cref. They're trivially-copyable, so passed in registers if passed by value. Passing by cref forces them onto the stack. Change-Id: I669643d219ede6b7d07f15afbf8728e16150b3b2 Reviewed-by: Allan Sandfeld Jensen --- src/gui/image/qimage.cpp | 4 ++-- src/gui/painting/qcolorspace.cpp | 9 +++++---- src/gui/painting/qcolortransform.cpp | 27 ++++++++++++++++---------- src/gui/painting/qcolortransform.h | 29 ++++++++++++++-------------- src/gui/painting/qcolortransform_p.h | 4 +++- 5 files changed, 42 insertions(+), 31 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 61d32b0dec..cd2fe5bc10 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -5067,12 +5067,12 @@ void QImage::applyColorTransform(const QColorTransform &transform) if (depth() > 32) { for (int i = 0; i < height(); ++i) { QRgba64 *scanline = reinterpret_cast(scanLine(i)); - transform.d_func()->apply(scanline, scanline, width(), flags); + transform.d->apply(scanline, scanline, width(), flags); } } else { for (int i = 0; i < height(); ++i) { QRgb *scanline = reinterpret_cast(scanLine(i)); - transform.d_func()->apply(scanline, scanline, width(), flags); + transform.d->apply(scanline, scanline, width(), flags); } } diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp index 8d3bbbe412..72c236bc50 100644 --- a/src/gui/painting/qcolorspace.cpp +++ b/src/gui/painting/qcolorspace.cpp @@ -355,10 +355,11 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace { Q_ASSERT(out); QColorTransform combined; - combined.d_ptr.reset(new QColorTransformPrivate); - combined.d_ptr->colorSpaceIn = this; - combined.d_ptr->colorSpaceOut = out; - combined.d_ptr->colorMatrix = out->toXyz.inverted() * toXyz; + auto ptr = new QColorTransformPrivate; + combined.d = ptr; + ptr->colorSpaceIn = this; + ptr->colorSpaceOut = out; + ptr->colorMatrix = out->toXyz.inverted() * toXyz; return combined; } diff --git a/src/gui/painting/qcolortransform.cpp b/src/gui/painting/qcolortransform.cpp index de08bf4221..53fd1dfbaa 100644 --- a/src/gui/painting/qcolortransform.cpp +++ b/src/gui/painting/qcolortransform.cpp @@ -134,8 +134,18 @@ void QColorTransformPrivate::updateLutsOut() const */ -QColorTransform::~QColorTransform() noexcept +QColorTransform::QColorTransform(const QColorTransform &colorTransform) noexcept + : d(colorTransform.d) { + if (d) + d->ref.ref(); +} + + +QColorTransform::~QColorTransform() +{ + if (d && !d->ref.deref()) + delete d; } /*! @@ -143,11 +153,10 @@ QColorTransform::~QColorTransform() noexcept The input should be opaque or unpremultiplied. */ -QRgb QColorTransform::map(const QRgb &argb) const +QRgb QColorTransform::map(QRgb argb) const { - if (!d_ptr) + if (!d) return argb; - Q_D(const QColorTransform); constexpr float f = 1.0f / 255.0f; QColorVector c = { qRed(argb) * f, qGreen(argb) * f, qBlue(argb) * f }; c.x = d->colorSpaceIn->trc[0].apply(c.x); @@ -175,11 +184,10 @@ QRgb QColorTransform::map(const QRgb &argb) const The input should be opaque or unpremultiplied. */ -QRgba64 QColorTransform::map(const QRgba64 &rgba64) const +QRgba64 QColorTransform::map(QRgba64 rgba64) const { - if (!d_ptr) + if (!d) return rgba64; - Q_D(const QColorTransform); constexpr float f = 1.0f / 65535.0f; QColorVector c = { rgba64.red() * f, rgba64.green() * f, rgba64.blue() * f }; c.x = d->colorSpaceIn->trc[0].apply(c.x); @@ -208,9 +216,8 @@ QRgba64 QColorTransform::map(const QRgba64 &rgba64) const */ QColor QColorTransform::map(const QColor &color) const { - if (!d_ptr) + if (!d) return color; - Q_D(const QColorTransform); QColor clr = color; if (color.spec() != QColor::ExtendedRgb || color.spec() != QColor::Rgb) clr = clr.toRgb(); @@ -228,7 +235,7 @@ QColor QColorTransform::map(const QColor &color) const c = d->colorMatrix.map(c); bool inGamut = c.x >= 0.0f && c.x <= 1.0f && c.y >= 0.0f && c.y <= 1.0f && c.z >= 0.0f && c.z <= 1.0f; if (inGamut) { - if (d_ptr->colorSpaceOut->lut.generated.loadAcquire()) { + if (d->colorSpaceOut->lut.generated.loadAcquire()) { c.x = d->colorSpaceOut->lut[0]->fromLinear(c.x); c.y = d->colorSpaceOut->lut[1]->fromLinear(c.y); c.z = d->colorSpaceOut->lut[2]->fromLinear(c.z); diff --git a/src/gui/painting/qcolortransform.h b/src/gui/painting/qcolortransform.h index a83611d666..5fb51739a7 100644 --- a/src/gui/painting/qcolortransform.h +++ b/src/gui/painting/qcolortransform.h @@ -51,41 +51,42 @@ class QRgba64; class QColorSpacePrivate; class QColorTransformPrivate; -class Q_GUI_EXPORT QColorTransform +class QColorTransform { public: - QColorTransform() noexcept : d_ptr(nullptr) { } - ~QColorTransform() noexcept; - QColorTransform(const QColorTransform &colorTransform) noexcept - : d_ptr(colorTransform.d_ptr) - { } + QColorTransform() noexcept : d(nullptr) { } + Q_GUI_EXPORT ~QColorTransform(); + Q_GUI_EXPORT QColorTransform(const QColorTransform &colorTransform) noexcept; QColorTransform(QColorTransform &&colorTransform) noexcept - : d_ptr(std::move(colorTransform.d_ptr)) + : d{qExchange(colorTransform.d, nullptr)} { } QColorTransform &operator=(const QColorTransform &other) noexcept { - d_ptr = other.d_ptr; + QColorTransform{other}.swap(*this); return *this; } QColorTransform &operator=(QColorTransform &&other) noexcept { - d_ptr = std::move(other.d_ptr); + QColorTransform{std::move(other)}.swap(*this); return *this; } - QRgb map(const QRgb &argb) const; - QRgba64 map(const QRgba64 &rgba64) const; - QColor map(const QColor &color) const; + void swap(QColorTransform &other) noexcept { qSwap(d, other.d); } + + Q_GUI_EXPORT QRgb map(QRgb argb) const; + Q_GUI_EXPORT QRgba64 map(QRgba64 rgba64) const; + Q_GUI_EXPORT QColor map(const QColor &color) const; private: friend class QColorSpace; friend class QColorSpacePrivate; friend class QImage; - Q_DECLARE_PRIVATE(QColorTransform) - QSharedPointer d_ptr; + const QColorTransformPrivate *d; }; +Q_DECLARE_SHARED(QColorTransform) + QT_END_NAMESPACE #endif // QCOLORTRANSFORM_H diff --git a/src/gui/painting/qcolortransform_p.h b/src/gui/painting/qcolortransform_p.h index 74a1e7fe0a..5d7116248d 100644 --- a/src/gui/painting/qcolortransform_p.h +++ b/src/gui/painting/qcolortransform_p.h @@ -54,9 +54,11 @@ #include "qcolormatrix_p.h" #include "qcolorspace_p.h" +#include + QT_BEGIN_NAMESPACE -class QColorTransformPrivate +class QColorTransformPrivate : public QSharedData { public: QColorMatrix colorMatrix; From deac052a40c93633041da058d5c73c9e91aa76c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 12 Jul 2019 12:28:29 +0200 Subject: [PATCH 087/264] Revert "Reset QWidget's winId when backing window surface is destroyed" This reverts commit a9246c7132a2c8864d3ae6cebd260bb9ee711fcb. The QWidget machinery is way to fragile to reset the winId under the feet of QWidget like that. We would potentially need to include all the logic in QWidget::destroy. This also ties into the flow between QtGui and QtWidgets during window closing, which is still unresolved. Change-Id: I168048a63c89796398eb5331a80ce3e5c8d9a208 Fixes: QTBUG-76588 Task-number: QTBUG-69289 Reviewed-by: Friedemann Kleint Reviewed-by: Volker Hilsheimer --- src/widgets/kernel/qwidget.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index fdb3872903..6f0f39a344 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -9382,12 +9382,6 @@ bool QWidget::event(QEvent *event) d->renderToTextureReallyDirty = 1; #endif break; - case QEvent::PlatformSurface: { - auto surfaceEvent = static_cast(event); - if (surfaceEvent->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed) - d->setWinId(0); - break; - } #ifndef QT_NO_PROPERTIES case QEvent::DynamicPropertyChange: { const QByteArray &propName = static_cast(event)->propertyName(); From 0a724ac74c5aa22a65ff0b81b762433b5d1e2002 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 2 Jul 2019 12:36:13 +0200 Subject: [PATCH 088/264] Introduce QT_NO_LINKED_LIST and mark QtBase (almost) free of it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QLinkedList is still used in several tests. Add exceptions for these subdirs. Change-Id: I50ccd2a0892129d4a47aa4e2400211690da9a82d Reviewed-by: Mårten Nordheim Reviewed-by: Volker Hilsheimer --- .qmake.conf | 1 + src/corelib/kernel/qmetatype.h | 2 +- src/corelib/tools/qcontainerfwd.h | 2 ++ src/corelib/tools/qlinkedlist.cpp | 4 ++++ src/corelib/tools/qlinkedlist.h | 8 ++++++++ .../concurrent/qtconcurrentfilter/qtconcurrentfilter.pro | 1 + tests/auto/concurrent/qtconcurrentmap/qtconcurrentmap.pro | 1 + tests/auto/corelib/kernel/qmetatype/qmetatype.pro | 1 + tests/auto/corelib/kernel/qvariant/qvariant.pro | 1 + .../corelib/serialization/qdatastream/qdatastream.pro | 2 ++ tests/auto/corelib/tools/collections/collections.pro | 1 + .../tools/containerapisymmetry/containerapisymmetry.pro | 1 + tests/auto/corelib/tools/qlinkedlist/qlinkedlist.pro | 1 + 13 files changed, 25 insertions(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 5c64c10981..0bfd71facc 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -2,6 +2,7 @@ load(qt_build_config) CONFIG += warning_clean DEFINES += QT_NO_JAVA_STYLE_ITERATORS +DEFINES += QT_NO_LINKED_LIST QT_SOURCE_TREE = $$PWD QT_BUILD_TREE = $$shadowed($$PWD) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 9fe2b9733b..a6c90fc3ed 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -216,7 +216,7 @@ inline Q_DECL_CONSTEXPR int qMetaTypeId(); F(QQueue) \ F(QStack) \ F(QSet) \ - F(QLinkedList) + /*end*/ #define QT_FOR_EACH_AUTOMATIC_TEMPLATE_2ARG(F) \ F(QHash, class) \ diff --git a/src/corelib/tools/qcontainerfwd.h b/src/corelib/tools/qcontainerfwd.h index 646d8908c3..532b4c95ce 100644 --- a/src/corelib/tools/qcontainerfwd.h +++ b/src/corelib/tools/qcontainerfwd.h @@ -47,7 +47,9 @@ QT_BEGIN_NAMESPACE template class QCache; template class QHash; +#ifndef QT_NO_LINKED_LIST template class QLinkedList; +#endif template class QList; template class QMap; template class QMultiHash; diff --git a/src/corelib/tools/qlinkedlist.cpp b/src/corelib/tools/qlinkedlist.cpp index d239fe0ef4..3b1bc8aab1 100644 --- a/src/corelib/tools/qlinkedlist.cpp +++ b/src/corelib/tools/qlinkedlist.cpp @@ -37,6 +37,10 @@ ** ****************************************************************************/ +#ifdef QT_NO_LINKED_LIST +# undef QT_NO_LINKED_LIST +#endif + #include "qlinkedlist.h" QT_BEGIN_NAMESPACE diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h index d4e5bca0ed..996a50fd1b 100644 --- a/src/corelib/tools/qlinkedlist.h +++ b/src/corelib/tools/qlinkedlist.h @@ -40,6 +40,10 @@ #ifndef QLINKEDLIST_H #define QLINKEDLIST_H +#include + +#ifndef QT_NO_LINKED_LIST + #include #include #include @@ -581,4 +585,8 @@ inline QDataStream &operator<<(QDataStream &s, const QLinkedList &l) QT_END_NAMESPACE +Q_DECLARE_SEQUENTIAL_CONTAINER_METATYPE(QLinkedList) + +#endif // QT_NO_LINKED_LIST + #endif // QLINKEDLIST_H diff --git a/tests/auto/concurrent/qtconcurrentfilter/qtconcurrentfilter.pro b/tests/auto/concurrent/qtconcurrentfilter/qtconcurrentfilter.pro index f3684faa61..15345d40db 100644 --- a/tests/auto/concurrent/qtconcurrentfilter/qtconcurrentfilter.pro +++ b/tests/auto/concurrent/qtconcurrentfilter/qtconcurrentfilter.pro @@ -3,3 +3,4 @@ TARGET = tst_qtconcurrentfilter QT = core testlib concurrent SOURCES = tst_qtconcurrentfilter.cpp DEFINES += QT_STRICT_ITERATORS +DEFINES -= QT_NO_LINKED_LIST diff --git a/tests/auto/concurrent/qtconcurrentmap/qtconcurrentmap.pro b/tests/auto/concurrent/qtconcurrentmap/qtconcurrentmap.pro index fd8fd0a74a..717d103e44 100644 --- a/tests/auto/concurrent/qtconcurrentmap/qtconcurrentmap.pro +++ b/tests/auto/concurrent/qtconcurrentmap/qtconcurrentmap.pro @@ -3,6 +3,7 @@ TARGET = tst_qtconcurrentmap QT = core testlib concurrent SOURCES = tst_qtconcurrentmap.cpp DEFINES += QT_STRICT_ITERATORS +DEFINES -= QT_NO_LINKED_LIST # Force C++17 if available contains(QT_CONFIG, c++1z): CONFIG += c++1z diff --git a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro index 56b8c071c3..4856b138c3 100644 --- a/tests/auto/corelib/kernel/qmetatype/qmetatype.pro +++ b/tests/auto/corelib/kernel/qmetatype/qmetatype.pro @@ -5,6 +5,7 @@ INCLUDEPATH += $$PWD/../../../other/qvariant_common SOURCES = tst_qmetatype.cpp TESTDATA=./typeFlags.bin DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 +DEFINES -= QT_NO_LINKED_LIST msvc|winrt { # Prevents "fatal error C1128: number of sections exceeded object file format limit". diff --git a/tests/auto/corelib/kernel/qvariant/qvariant.pro b/tests/auto/corelib/kernel/qvariant/qvariant.pro index a620be0091..0b5280df86 100644 --- a/tests/auto/corelib/kernel/qvariant/qvariant.pro +++ b/tests/auto/corelib/kernel/qvariant/qvariant.pro @@ -5,6 +5,7 @@ INCLUDEPATH += $$PWD/../../../other/qvariant_common SOURCES = tst_qvariant.cpp RESOURCES += qvariant.qrc DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 +DEFINES -= QT_NO_LINKED_LIST qtConfig(c++14): CONFIG += c++14 qtConfig(c++1z): CONFIG += c++1z !qtConfig(doubleconversion):!qtConfig(system-doubleconversion) { diff --git a/tests/auto/corelib/serialization/qdatastream/qdatastream.pro b/tests/auto/corelib/serialization/qdatastream/qdatastream.pro index 25f8b889a0..469d689f3f 100644 --- a/tests/auto/corelib/serialization/qdatastream/qdatastream.pro +++ b/tests/auto/corelib/serialization/qdatastream/qdatastream.pro @@ -3,6 +3,8 @@ TARGET = tst_qdatastream QT += testlib SOURCES = tst_qdatastream.cpp +DEFINES -= QT_NO_LINKED_LIST + TESTDATA += datastream.q42 android:!android-embedded { diff --git a/tests/auto/corelib/tools/collections/collections.pro b/tests/auto/corelib/tools/collections/collections.pro index b074fa9338..e0f9f0a0ea 100644 --- a/tests/auto/corelib/tools/collections/collections.pro +++ b/tests/auto/corelib/tools/collections/collections.pro @@ -4,5 +4,6 @@ SOURCES += tst_collections.cpp QT = core testlib # This test does not work with strict iterators +DEFINES -= QT_NO_LINKED_LIST DEFINES -= QT_STRICT_ITERATORS DEFINES -= QT_NO_JAVA_STYLE_ITERATORS diff --git a/tests/auto/corelib/tools/containerapisymmetry/containerapisymmetry.pro b/tests/auto/corelib/tools/containerapisymmetry/containerapisymmetry.pro index 30dc8026ef..e46d51761e 100644 --- a/tests/auto/corelib/tools/containerapisymmetry/containerapisymmetry.pro +++ b/tests/auto/corelib/tools/containerapisymmetry/containerapisymmetry.pro @@ -5,3 +5,4 @@ QT = core testlib # This test does not work with strict iterators DEFINES -= QT_STRICT_ITERATORS +DEFINES -= QT_NO_LINKED_LIST diff --git a/tests/auto/corelib/tools/qlinkedlist/qlinkedlist.pro b/tests/auto/corelib/tools/qlinkedlist/qlinkedlist.pro index 80630f78ad..378c574eb0 100644 --- a/tests/auto/corelib/tools/qlinkedlist/qlinkedlist.pro +++ b/tests/auto/corelib/tools/qlinkedlist/qlinkedlist.pro @@ -2,3 +2,4 @@ CONFIG += testcase TARGET = tst_qlinkedlist QT = core testlib SOURCES = tst_qlinkedlist.cpp +DEFINES -= QT_NO_LINKED_LIST From 7d29807296cb7ccc7f3459e106d74f93a321c493 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 3 Jul 2019 13:28:58 +0200 Subject: [PATCH 089/264] Finish deprecating obsolete members of QWheelEvent In Qt 5.0, delta() and orientation() were already marked obsolete, but Widgets and tests have kept on depending on them all this time. We now start using alternative API so they can really be deprecated. All constructors except the newest one are also deprecated. The plan is for all events from pointing devices to have QPointF position() and globalPosition(), so we deprecate the other position accessors. [ChangeLog][QtGui] Obsolete constructors and accessors in QWheelEvent now have proper deprecation macros. What is left is intended to be compatible with planned changes in Qt 6. Change-Id: I26250dc90922b60a6ed20d7f65f38019da3e139e Reviewed-by: Richard Moe Gustavsen --- src/gui/kernel/qevent.cpp | 218 +++--------------- src/gui/kernel/qevent.h | 30 ++- src/gui/kernel/qguiapplication.cpp | 5 + .../graphicsview/qgraphicsproxywidget.cpp | 11 +- src/widgets/graphicsview/qgraphicsview.cpp | 9 +- src/widgets/itemviews/qlistview.cpp | 10 +- src/widgets/kernel/qapplication.cpp | 14 +- src/widgets/kernel/qwidgetwindow.cpp | 9 +- src/widgets/widgets/qabstractscrollarea.cpp | 2 +- src/widgets/widgets/qabstractslider.cpp | 5 +- src/widgets/widgets/qcalendarwidget.cpp | 2 +- src/widgets/widgets/qcombobox.cpp | 5 +- src/widgets/widgets/qmenu.cpp | 4 +- src/widgets/widgets/qscrollbar.cpp | 10 +- src/widgets/widgets/qtabbar.cpp | 4 +- .../qgraphicsview/tst_qgraphicsview.cpp | 4 +- .../itemviews/qlistview/tst_qlistview.cpp | 6 +- .../itemviews/qtableview/tst_qtableview.cpp | 10 +- .../qabstractslider/tst_qabstractslider.cpp | 22 +- .../widgets/qcombobox/tst_qcombobox.cpp | 8 +- .../qdatetimeedit/tst_qdatetimeedit.cpp | 8 +- .../qdoublespinbox/tst_qdoublespinbox.cpp | 8 +- .../widgets/qscrollbar/tst_qscrollbar.cpp | 7 +- .../widgets/widgets/qspinbox/tst_qspinbox.cpp | 8 +- .../widgets/qtextedit/tst_qtextedit.cpp | 6 +- 25 files changed, 172 insertions(+), 253 deletions(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index e1d685b1b0..2ec90433d6 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -754,31 +754,15 @@ QHoverEvent::~QHoverEvent() \fn Qt::Orientation QWheelEvent::orientation() const \obsolete - Returns the wheel's orientation. - Use angleDelta() instead. */ +#if QT_CONFIG(wheelevent) +#if QT_DEPRECATED_SINCE(5, 14) /*! \obsolete - Constructs a wheel event object. - - Use the constructor taking \e angleDelta and \e pixelDelta QPoints instead. - - The position, \a pos, is the location of the mouse cursor within - the widget. The globalPos() is initialized to QCursor::pos() - which is usually, but not always, correct. - Use the other constructor if you need to specify the global - position explicitly. - - The \a buttons describe the state of the mouse buttons at the time - of the event, \a delta contains the rotation distance, - \a modifiers holds the keyboard modifier flags at the time of the - event, and \a orient holds the wheel's orientation. - - \sa pos(), pixelDelta(), angleDelta() + This constructor has been deprecated. */ -#if QT_CONFIG(wheelevent) QWheelEvent::QWheelEvent(const QPointF &pos, int delta, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::Orientation orient) @@ -792,27 +776,9 @@ QWheelEvent::QWheelEvent(const QPointF &pos, int delta, angleD = QPoint(delta, 0); } -/*! - \internal -*/ -QWheelEvent::~QWheelEvent() -{ -} - /*! \obsolete - Constructs a wheel event object. - - Use the constructor taking \e angleDelta and \e pixelDelta QPoints instead. - - The \a pos provides the location of the mouse cursor - within the widget. The position in global coordinates is specified - by \a globalPos. \a delta contains the rotation distance, \a modifiers - holds the keyboard modifier flags at the time of the event, and - \a orient holds the wheel's orientation. - - - \sa pos(), pixelDelta(), angleDelta() + This constructor has been deprecated. */ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, @@ -827,27 +793,8 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta } /*! - Constructs a wheel event object. - - The \a pos provides the location of the mouse cursor - within the window. The position in global coordinates is specified - by \a globalPos. - - \a pixelDelta contains the scrolling distance in pixels on screen, while - \a angleDelta contains the wheel rotation distance. \a pixelDelta is - optional and can be null. - - The mouse and keyboard states at the time of the event are specified by - \a buttons and \a modifiers. - - For backwards compatibility, the event can also hold monodirectional wheel - event data: \a qt4Delta specifies the rotation, and \a qt4Orientation the - direction. - - The phase() is initialized to Qt::ScrollUpdate. Use the other constructor - to specify the phase explicitly. - - \sa posF(), globalPosF(), angleDelta(), pixelDelta() + \obsolete + This constructor has been deprecated. */ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, @@ -858,26 +805,8 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, {} /*! - Constructs a wheel event object. - - The \a pos provides the location of the mouse cursor - within the window. The position in global coordinates is specified - by \a globalPos. - - \a pixelDelta contains the scrolling distance in pixels on screen, while - \a angleDelta contains the wheel rotation distance. \a pixelDelta is - optional and can be null. - - The mouse and keyboard states at the time of the event are specified by - \a buttons and \a modifiers. - - For backwards compatibility, the event can also hold monodirectional wheel - event data: \a qt4Delta specifies the rotation, and \a qt4Orientation the - direction. - - The scrolling phase of the event is specified by \a phase. - - \sa posF(), globalPosF(), angleDelta(), pixelDelta(), phase() + \obsolete + This constructor has been deprecated. */ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, @@ -888,31 +817,8 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, {} /*! - Constructs a wheel event object. - - The \a pos provides the location of the mouse cursor within the window. The - position in global coordinates is specified by \a globalPos. - - \a pixelDelta contains the scrolling distance in pixels on screen, while - \a angleDelta contains the wheel rotation distance. \a pixelDelta is - optional and can be null. - - The mouse and keyboard states at the time of the event are specified by - \a buttons and \a modifiers. - - For backwards compatibility, the event can also hold monodirectional wheel - event data: \a qt4Delta specifies the rotation, and \a qt4Orientation the - direction. - - The scrolling phase of the event is specified by \a phase. - - If the wheel event comes from a physical mouse wheel, \a source is set to - Qt::MouseEventNotSynthesized. If it comes from a gesture detected by the - operating system, or from a non-mouse hardware device, such that \a pixelDelta is - directly related to finger movement, \a source is set to Qt::MouseEventSynthesizedBySystem. - If it comes from Qt, source would be set to Qt::MouseEventSynthesizedByQt. - - \sa posF(), globalPosF(), angleDelta(), pixelDelta(), phase() + \obsolete + This constructor has been deprecated. */ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, @@ -923,37 +829,8 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, {} /*! - Constructs a wheel event object. - - The \a pos provides the location of the mouse cursor - within the window. The position in global coordinates is specified - by \a globalPos. - - \a pixelDelta contains the scrolling distance in pixels on screen, while - \a angleDelta contains the wheel rotation distance. \a pixelDelta is - optional and can be null. - - The mouse and keyboard states at the time of the event are specified by - \a buttons and \a modifiers. - - For backwards compatibility, the event can also hold monodirectional wheel - event data: \a qt4Delta specifies the rotation, and \a qt4Orientation the - direction. - - The scrolling phase of the event is specified by \a phase. - - If the wheel event comes from a physical mouse wheel, \a source is set to - Qt::MouseEventNotSynthesized. If it comes from a gesture detected by the - operating system, or from a non-mouse hardware device, such that \a - pixelDelta is directly related to finger movement, \a source is set to - Qt::MouseEventSynthesizedBySystem. If it comes from Qt, source would be set - to Qt::MouseEventSynthesizedByQt. - - If the system is configured to invert the delta values delivered with the - event (such as natural scrolling of the touchpad on OS X), \a inverted - should be \c true. Otherwise, \a inverted is \c false - - \sa posF(), globalPosF(), angleDelta(), pixelDelta(), phase() + \obsolete + This constructor has been deprecated. */ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation, @@ -962,6 +839,7 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, angleD(angleDelta), qt4D(qt4Delta), qt4O(qt4Orientation), mouseState(buttons), src(source), invertedScrolling(inverted), ph(phase) {} +#endif // QT_DEPRECATED_SINCE(5, 14) /*! Constructs a wheel event object. @@ -990,7 +868,7 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, event (such as natural scrolling of the touchpad on macOS), \a inverted should be \c true. Otherwise, \a inverted is \c false - \sa posF(), globalPosF(), angleDelta(), pixelDelta(), phase() + \sa position(), globalPosition(), angleDelta(), pixelDelta(), phase(), inverted(), source() */ QWheelEvent::QWheelEvent(QPointF pos, QPointF globalPos, QPoint pixelDelta, QPoint angleDelta, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase, @@ -1002,6 +880,12 @@ QWheelEvent::QWheelEvent(QPointF pos, QPointF globalPos, QPoint pixelDelta, QPoi qt4D = (qt4O == Qt::Horizontal ? angleDelta.x() : angleDelta.y()); } +/*! + \internal +*/ +QWheelEvent::~QWheelEvent() +{ +} #endif // QT_CONFIG(wheelevent) /*! @@ -1061,87 +945,59 @@ QWheelEvent::QWheelEvent(QPointF pos, QPointF globalPos, QPoint pixelDelta, QPoi /*! \fn QPoint QWheelEvent::pos() const + \obsolete - Returns the position of the mouse cursor relative to the widget - that received the event. - - If you move your widgets around in response to mouse events, - use globalPos() instead of this function. - - \sa x(), y(), globalPos() + This function has been deprecated, use position() instead. */ /*! \fn int QWheelEvent::x() const + \obsolete - Returns the x position of the mouse cursor, relative to the - widget that received the event. - - \sa y(), pos() + This function has been deprecated, use position() instead. */ /*! \fn int QWheelEvent::y() const + \obsolete - Returns the y position of the mouse cursor, relative to the - widget that received the event. - - \sa x(), pos() + This function has been deprecated, use position() instead. */ /*! \fn QPoint QWheelEvent::globalPos() const + \obsolete - Returns the global position of the mouse pointer \e{at the time - of the event}. This is important on asynchronous window systems - such as X11; whenever you move your widgets around in response to - mouse events, globalPos() can differ a lot from the current - cursor position returned by QCursor::pos(). - - \sa globalX(), globalY() + This function has been deprecated, use globalPosition() instead. */ /*! \fn int QWheelEvent::globalX() const + \obsolete - Returns the global x position of the mouse cursor at the time of - the event. - - \sa globalY(), globalPos() + This function has been deprecated, use globalPosition() instead. */ /*! \fn int QWheelEvent::globalY() const + \obsolete - Returns the global y position of the mouse cursor at the time of - the event. - - \sa globalX(), globalPos() + This function has been deprecated, use globalPosition() instead. */ /*! \fn const QPointF &QWheelEvent::posF() const + \obsolete - Returns the position of the mouse cursor relative to the widget - that received the event. - - If you move your widgets around in response to mouse events, - use globalPosF() instead of this function. - - \sa globalPosF() + This function has been deprecated, use position() instead. */ /*! \fn const QPointF &QWheelEvent::globalPosF() const + \obsolete - Returns the global position of the mouse pointer \e{at the time - of the event}. This is important on asynchronous window systems - such as X11; whenever you move your widgets around in response to - mouse events, globalPosF() can differ a lot from the current - cursor position returned by QCursor::pos(). - - \sa posF() + This function has been deprecated, use globalPosition() instead. */ /*! @@ -4074,8 +3930,10 @@ QDebug operator<<(QDebug dbg, const QEvent *e) dbg << "QWheelEvent(" << we->phase(); if (!we->pixelDelta().isNull() || !we->angleDelta().isNull()) dbg << ", pixelDelta=" << we->pixelDelta() << ", angleDelta=" << we->angleDelta(); +#if QT_DEPRECATED_SINCE(5, 14) else if (int qt4Delta = we->delta()) dbg << ", delta=" << qt4Delta << ", orientation=" << we->orientation(); +#endif dbg << ')'; } break; diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index eb0a6208a9..d110529927 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -175,24 +175,34 @@ class Q_GUI_EXPORT QWheelEvent : public QInputEvent public: enum { DefaultDeltasPerStep = 120 }; +#if QT_DEPRECATED_SINCE(5, 14) + // Actually deprecated since 5.0, in docs + QT_DEPRECATED_X("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") QWheelEvent(const QPointF &pos, int delta, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::Orientation orient = Qt::Vertical); + // Actually deprecated since 5.0, in docs + QT_DEPRECATED_X("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::Orientation orient = Qt::Vertical); + QT_DEPRECATED_X("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") QWheelEvent(const QPointF &pos, const QPointF& globalPos, QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers); + QT_DEPRECATED_X("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") QWheelEvent(const QPointF &pos, const QPointF& globalPos, QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase); + QT_DEPRECATED_X("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") QWheelEvent(const QPointF &pos, const QPointF &globalPos, QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase, Qt::MouseEventSource source); + QT_DEPRECATED_X("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") QWheelEvent(const QPointF &pos, const QPointF &globalPos, QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase, Qt::MouseEventSource source, bool inverted); +#endif QWheelEvent(QPointF pos, QPointF globalPos, QPoint pixelDelta, QPoint angleDelta, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase, @@ -203,19 +213,35 @@ public: inline QPoint pixelDelta() const { return pixelD; } inline QPoint angleDelta() const { return angleD; } +#if QT_DEPRECATED_SINCE(5, 14) + // Actually deprecated since 5.0, in docs + QT_DEPRECATED_X("Use angleDelta()") inline int delta() const { return qt4D; } + // Actually deprecated since 5.0, in docs + QT_DEPRECATED_X("Use angleDelta()") inline Qt::Orientation orientation() const { return qt4O; } - #ifndef QT_NO_INTEGER_EVENT_COORDINATES + QT_DEPRECATED_X("Use position()") inline QPoint pos() const { return p.toPoint(); } + QT_DEPRECATED_X("Use globalPosition()") inline QPoint globalPos() const { return g.toPoint(); } + QT_DEPRECATED_X("Use position()") inline int x() const { return int(p.x()); } + QT_DEPRECATED_X("Use position()") inline int y() const { return int(p.y()); } + QT_DEPRECATED_X("Use globalPosition()") inline int globalX() const { return int(g.x()); } + QT_DEPRECATED_X("Use globalPosition()") inline int globalY() const { return int(g.y()); } #endif + QT_DEPRECATED_X("Use position()") inline const QPointF &posF() const { return p; } + QT_DEPRECATED_X("Use globalPosition()") inline const QPointF &globalPosF() const { return g; } +#endif // QT_DEPRECATED_SINCE(5, 14) + + inline QPointF position() const { return p; } + inline QPointF globalPosition() const { return g; } inline Qt::MouseButtons buttons() const { return mouseState; } @@ -231,7 +257,7 @@ protected: QPoint angleD; int qt4D = 0; Qt::Orientation qt4O = Qt::Vertical; - Qt::MouseButtons mouseState; + Qt::MouseButtons mouseState = Qt::NoButton; uint _unused_ : 2; // Kept for binary compatibility uint src: 2; bool invertedScrolling : 1; diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index ceb5055a9d..426f2aeece 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -2239,8 +2239,13 @@ void QGuiApplicationPrivate::processWheelEvent(QWindowSystemInterfacePrivate::Wh return; } +#if QT_DEPRECATED_SINCE(5, 14) QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta, e->qt4Delta, e->qt4Orientation, mouse_buttons, e->modifiers, e->phase, e->source, e->inverted); +#else + QWheelEvent ev(localPoint, globalPoint, e->pixelDelta, e->angleDelta, + mouse_buttons, e->modifiers, e->phase, e->inverted, e->source); +#endif ev.setTimestamp(e->timestamp); QGuiApplication::sendSpontaneousEvent(window, &ev); #else diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp index f1b01fbb4d..dec9e7a268 100644 --- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp +++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp @@ -1293,8 +1293,15 @@ void QGraphicsProxyWidget::wheelEvent(QGraphicsSceneWheelEvent *event) pos = d->mapToReceiver(pos, receiver); // Send mouse event. - QWheelEvent wheelEvent(pos.toPoint(), event->screenPos(), event->delta(), - event->buttons(), event->modifiers(), event->orientation()); + QPoint angleDelta; + if (event->orientation() == Qt::Horizontal) + angleDelta.setX(event->delta()); + else + angleDelta.setY(event->delta()); + // pixelDelta, inverted, scrollPhase and source from the original QWheelEvent + // were not preserved in the QGraphicsSceneWheelEvent unfortunately + QWheelEvent wheelEvent(pos, event->screenPos(), QPoint(), angleDelta, + event->buttons(), event->modifiers(), Qt::NoScrollPhase, false); QPointer focusWidget = d->widget->focusWidget(); extern bool qt_sendSpontaneousEvent(QObject *, QEvent *); qt_sendSpontaneousEvent(receiver, &wheelEvent); diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp index 3ec9668cde..d5919eb55f 100644 --- a/src/widgets/graphicsview/qgraphicsview.cpp +++ b/src/widgets/graphicsview/qgraphicsview.cpp @@ -3426,12 +3426,13 @@ void QGraphicsView::wheelEvent(QWheelEvent *event) QGraphicsSceneWheelEvent wheelEvent(QEvent::GraphicsSceneWheel); wheelEvent.setWidget(viewport()); - wheelEvent.setScenePos(mapToScene(event->pos())); - wheelEvent.setScreenPos(event->globalPos()); + wheelEvent.setScenePos(mapToScene(event->position().toPoint())); + wheelEvent.setScreenPos(event->globalPosition().toPoint()); wheelEvent.setButtons(event->buttons()); wheelEvent.setModifiers(event->modifiers()); - wheelEvent.setDelta(event->delta()); - wheelEvent.setOrientation(event->orientation()); + const bool horizontal = qAbs(event->angleDelta().x()) > qAbs(event->angleDelta().y()); + wheelEvent.setDelta(horizontal ? event->angleDelta().x() : event->angleDelta().y()); + wheelEvent.setOrientation(horizontal ? Qt::Horizontal : Qt::Vertical); wheelEvent.setAccepted(false); QCoreApplication::sendEvent(d->scene, &wheelEvent); event->setAccepted(wheelEvent.isAccepted()); diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 25facd1484..0415dc4e56 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -810,14 +810,14 @@ void QListView::mouseReleaseEvent(QMouseEvent *e) void QListView::wheelEvent(QWheelEvent *e) { Q_D(QListView); - if (e->orientation() == Qt::Vertical) { + if (qAbs(e->angleDelta().y()) > qAbs(e->angleDelta().x())) { if (e->angleDelta().x() == 0 - && ((d->flow == TopToBottom && d->wrap) || (d->flow == LeftToRight && !d->wrap)) - && d->vbar->minimum() == 0 && d->vbar->maximum() == 0) { + && ((d->flow == TopToBottom && d->wrap) || (d->flow == LeftToRight && !d->wrap)) + && d->vbar->minimum() == 0 && d->vbar->maximum() == 0) { QPoint pixelDelta(e->pixelDelta().y(), e->pixelDelta().x()); QPoint angleDelta(e->angleDelta().y(), e->angleDelta().x()); - QWheelEvent hwe(e->pos(), e->globalPos(), pixelDelta, angleDelta, e->delta(), - Qt::Horizontal, e->buttons(), e->modifiers(), e->phase(), e->source(), e->inverted()); + QWheelEvent hwe(e->position(), e->globalPosition(), pixelDelta, angleDelta, + e->buttons(), e->modifiers(), e->phase(), e->inverted(), e->source()); if (e->spontaneous()) qt_sendSpontaneousEvent(d->hbar, &hwe); else diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index c922aecceb..7feb18e839 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -3240,13 +3240,18 @@ bool QApplication::notify(QObject *receiver, QEvent *e) if (spontaneous && phase == Qt::ScrollBegin) QApplicationPrivate::wheel_widget = nullptr; - const QPoint &relpos = wheel->pos(); + QPoint relpos = wheel->position().toPoint(); if (spontaneous && (phase == Qt::NoScrollPhase || phase == Qt::ScrollUpdate)) QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, e, relpos); +#if QT_DEPRECATED_SINCE(5, 14) QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(), wheel->modifiers(), phase, wheel->source(), wheel->inverted()); +#else + QWheelEvent we(relpos, wheel->globalPosition(), wheel->pixelDelta(), wheel->angleDelta(), wheel->buttons(), + wheel->modifiers(), phase, wheel->inverted(), wheel->source()); +#endif we.setTimestamp(wheel->timestamp()); bool eventAccepted; do { @@ -3281,9 +3286,14 @@ bool QApplication::notify(QObject *receiver, QEvent *e) // is set. Since it accepted the wheel event previously, we continue // sending those events until we get a ScrollEnd, which signifies // the end of the natural scrolling sequence. - const QPoint &relpos = QApplicationPrivate::wheel_widget->mapFromGlobal(wheel->globalPos()); + const QPoint &relpos = QApplicationPrivate::wheel_widget->mapFromGlobal(wheel->globalPosition().toPoint()); +#if QT_DEPRECATED_SINCE(5, 0) QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(), wheel->modifiers(), wheel->phase(), wheel->source()); +#else + QWheelEvent we(relpos, wheel->globalPosition(), wheel->pixelDelta(), wheel->angleDelta(), wheel->buttons(), + wheel->modifiers(), wheel->phase(), wheel->inverted(), wheel->source()); +#endif we.setTimestamp(wheel->timestamp()); we.spont = true; we.ignore(); diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index ba10083829..5537ff497a 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -828,14 +828,14 @@ void QWidgetWindow::handleWheelEvent(QWheelEvent *event) return; QWidget *rootWidget = m_widget; - QPoint pos = event->pos(); + QPoint pos = event->position().toPoint(); // Use proper popup window for wheel event. Some QPA sends the wheel // event to the root menu, so redirect it to the proper popup window. QWidget *activePopupWidget = QApplication::activePopupWidget(); if (activePopupWidget && activePopupWidget != m_widget) { rootWidget = activePopupWidget; - pos = rootWidget->mapFromGlobal(event->globalPos()); + pos = rootWidget->mapFromGlobal(event->globalPosition().toPoint()); } // which child should have it? @@ -846,7 +846,12 @@ void QWidgetWindow::handleWheelEvent(QWheelEvent *event) QPoint mapped = widget->mapFrom(rootWidget, pos); +#if QT_DEPRECATED_SINCE(5, 0) QWheelEvent translated(mapped, event->globalPos(), event->pixelDelta(), event->angleDelta(), event->delta(), event->orientation(), event->buttons(), event->modifiers(), event->phase(), event->source(), event->inverted()); +#else + QWheelEvent translated(QPointF(mapped), event->globalPosition(), event->pixelDelta(), event->angleDelta(), + event->buttons(), event->modifiers(), event->phase(), event->inverted(), event->source()); +#endif translated.setTimestamp(event->timestamp()); QGuiApplication::forwardEvent(widget, &translated, event); } diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp index b9e0d3280f..8f50ec1584 100644 --- a/src/widgets/widgets/qabstractscrollarea.cpp +++ b/src/widgets/widgets/qabstractscrollarea.cpp @@ -1324,7 +1324,7 @@ void QAbstractScrollArea::mouseMoveEvent(QMouseEvent *e) void QAbstractScrollArea::wheelEvent(QWheelEvent *e) { Q_D(QAbstractScrollArea); - if (e->orientation() == Qt::Horizontal) + if (qAbs(e->angleDelta().x()) > qAbs(e->angleDelta().y())) QCoreApplication::sendEvent(d->hbar, e); else QCoreApplication::sendEvent(d->vbar, e); diff --git a/src/widgets/widgets/qabstractslider.cpp b/src/widgets/widgets/qabstractslider.cpp index 2172ebc99c..1c1aec6035 100644 --- a/src/widgets/widgets/qabstractslider.cpp +++ b/src/widgets/widgets/qabstractslider.cpp @@ -764,10 +764,11 @@ void QAbstractSlider::wheelEvent(QWheelEvent * e) { Q_D(QAbstractSlider); e->ignore(); - int delta = e->delta(); + bool vertical = bool(e->angleDelta().y()); + int delta = vertical ? e->angleDelta().y() : e->angleDelta().x(); if (e->inverted()) delta = -delta; - if (d->scrollByDelta(e->orientation(), e->modifiers(), delta)) + if (d->scrollByDelta(vertical ? Qt::Vertical : Qt::Horizontal, e->modifiers(), delta)) e->accept(); } diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp index 510b34cb18..f07b42c181 100644 --- a/src/widgets/widgets/qcalendarwidget.cpp +++ b/src/widgets/widgets/qcalendarwidget.cpp @@ -1418,7 +1418,7 @@ void QCalendarView::keyPressEvent(QKeyEvent *event) #if QT_CONFIG(wheelevent) void QCalendarView::wheelEvent(QWheelEvent *event) { - const int numDegrees = event->delta() / 8; + const int numDegrees = event->angleDelta().y() / 8; const int numSteps = numDegrees / 15; const QModelIndex index = currentIndex(); QDate currentDate = static_cast(model())->dateForCell(index.row(), index.column()); diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 90d55f9688..83c472b51a 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -3378,12 +3378,13 @@ void QComboBox::wheelEvent(QWheelEvent *e) !d->viewContainer()->isVisible()) { const int rowCount = count(); int newIndex = currentIndex(); + int delta = e->angleDelta().y(); - if (e->delta() > 0) { + if (delta > 0) { newIndex--; while ((newIndex >= 0) && !(d->model->flags(d->model->index(newIndex,d->modelColumn,d->root)) & Qt::ItemIsEnabled)) newIndex--; - } else if (e->delta() < 0) { + } else if (delta < 0) { newIndex++; while (newIndex < rowCount && !(d->model->index(newIndex, d->modelColumn, d->root).flags() & Qt::ItemIsEnabled)) newIndex++; diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 72653b377d..7ec33acbbf 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -2847,8 +2847,8 @@ void QMenu::paintEvent(QPaintEvent *e) void QMenu::wheelEvent(QWheelEvent *e) { Q_D(QMenu); - if (d->scroll && rect().contains(e->pos())) - d->scrollMenu(e->delta() > 0 ? + if (d->scroll && rect().contains(e->position().toPoint())) + d->scrollMenu(e->angleDelta().y() > 0 ? QMenuPrivate::QMenuScroller::ScrollUp : QMenuPrivate::QMenuScroller::ScrollDown); } #endif diff --git a/src/widgets/widgets/qscrollbar.cpp b/src/widgets/widgets/qscrollbar.cpp index b4168268a0..08d771a27a 100644 --- a/src/widgets/widgets/qscrollbar.cpp +++ b/src/widgets/widgets/qscrollbar.cpp @@ -497,16 +497,14 @@ bool QScrollBar::event(QEvent *event) void QScrollBar::wheelEvent(QWheelEvent *event) { event->ignore(); - int delta = event->delta(); // scrollbar is a special case - in vertical mode it reaches minimum // value in the upper position, however QSlider's minimum value is on - // the bottom. So we need to invert a value, but since the scrollbar is - // inverted by default, we need to inverse the delta value for the + // the bottom. So we need to invert the value, but since the scrollbar is + // inverted by default, we need to invert the delta value only for the // horizontal orientation. - if (event->orientation() == Qt::Horizontal) - delta = -delta; + int delta = (orientation() == Qt::Horizontal ? -event->angleDelta().x() : event->angleDelta().y()); Q_D(QScrollBar); - if (d->scrollByDelta(event->orientation(), event->modifiers(), delta)) + if (d->scrollByDelta(orientation(), event->modifiers(), delta)) event->accept(); if (event->phase() == Qt::ScrollBegin) diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index f6f56c12d1..1be1729684 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -2210,7 +2210,9 @@ void QTabBar::wheelEvent(QWheelEvent *event) { #ifndef Q_OS_MAC Q_D(QTabBar); - int offset = event->delta() > 0 ? -1 : 1; + int delta = (qAbs(event->angleDelta().x()) > qAbs(event->angleDelta().y()) ? + event->angleDelta().x() : event->angleDelta().y()); + int offset = delta > 0 ? -1 : 1; d->setCurrentNextEnabledIndex(offset); QWidget::wheelEvent(event); #else diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index 52cc7ed128..7a385a230e 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -2219,7 +2219,7 @@ void tst_QGraphicsView::wheelEvent() { QWheelEvent event(view.mapFromScene(widget->boundingRect().center()), view.mapToGlobal(view.mapFromScene(widget->boundingRect().center())), - 120, 0, 0, Qt::Horizontal); + QPoint(), QPoint(120, 0), Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); QApplication::sendEvent(view.viewport(), &event); QCOMPARE(scene.orientation, Qt::Horizontal); } @@ -2228,7 +2228,7 @@ void tst_QGraphicsView::wheelEvent() { QWheelEvent event(view.mapFromScene(widget->boundingRect().center()), view.mapToGlobal(view.mapFromScene(widget->boundingRect().center())), - 120, 0, 0, Qt::Vertical); + QPoint(), QPoint(0, 120), Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); QApplication::sendEvent(view.viewport(), &event); QCOMPARE(scene.orientation, Qt::Vertical); } diff --git a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp index 0b828b8484..3a60b3b7c6 100644 --- a/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp +++ b/tests/auto/widgets/itemviews/qlistview/tst_qlistview.cpp @@ -2516,9 +2516,9 @@ void tst_QListView::horizontalScrollingByVerticalWheelEvents() QPoint globalPos = lv.geometry().center(); QPoint pos = lv.viewport()->geometry().center(); - QWheelEvent wheelDownEvent(pos, globalPos, QPoint(0, 0), QPoint(0, -120), -120, Qt::Vertical, 0, 0); - QWheelEvent wheelUpEvent(pos, globalPos, QPoint(0, 0), QPoint(0, 120), 120, Qt::Vertical, 0, 0); - QWheelEvent wheelLeftDownEvent(pos, globalPos, QPoint(0, 0), QPoint(120, -120), -120, Qt::Vertical, 0, 0); + QWheelEvent wheelDownEvent(pos, globalPos, QPoint(0, 0), QPoint(0, -120), Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); + QWheelEvent wheelUpEvent(pos, globalPos, QPoint(0, 0), QPoint(0, 120), Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); + QWheelEvent wheelLeftDownEvent(pos, globalPos, QPoint(0, 0), QPoint(120, -120), Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); int hValue = lv.horizontalScrollBar()->value(); QApplication::sendEvent(lv.viewport(), &wheelDownEvent); diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index bf87408056..6bbb30a6db 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -4074,8 +4074,10 @@ void tst_QTableView::mouseWheel() view.verticalScrollBar()->setValue(10); QPoint pos = view.viewport()->geometry().center(); - QWheelEvent verticalEvent(pos, delta, 0, 0, Qt::Vertical); - QWheelEvent horizontalEvent(pos, delta, 0, 0, Qt::Horizontal); + QWheelEvent verticalEvent(pos, view.mapToGlobal(pos), QPoint(), QPoint(0, delta), + Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); + QWheelEvent horizontalEvent(pos, view.mapToGlobal(pos), QPoint(), QPoint(delta, 0), + Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); QApplication::sendEvent(view.viewport(), &horizontalEvent); QVERIFY(qAbs(view.horizontalScrollBar()->value() - horizontalPositon) < 15); QApplication::sendEvent(view.viewport(), &verticalEvent); @@ -4350,7 +4352,9 @@ void tst_QTableView::taskQTBUG_5237_wheelEventOnHeader() int sbValueBefore = view.verticalScrollBar()->value(); QHeaderView *header = view.verticalHeader(); QTest::mouseMove(header); - QWheelEvent wheelEvent(header->geometry().center(), -720, 0, 0); + QPoint pos = header->geometry().center(); + QWheelEvent wheelEvent(pos, header->viewport()->mapToGlobal(pos), QPoint(), QPoint(0, -720), + Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); QApplication::sendEvent(header->viewport(), &wheelEvent); int sbValueAfter = view.verticalScrollBar()->value(); QVERIFY(sbValueBefore != sbValueAfter); diff --git a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp index d8fbb8e041..f77efe036a 100644 --- a/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp +++ b/tests/auto/widgets/widgets/qabstractslider/tst_qabstractslider.cpp @@ -1662,8 +1662,12 @@ void tst_QAbstractSlider::wheelEvent() slider->setOrientation(sliderOrientation); Qt::KeyboardModifier k = withModifiers ? Qt::ControlModifier : Qt::NoModifier; - QWheelEvent event(slider->rect().bottomRight() + distanceFromBottomRight, WHEEL_DELTA * deltaMultiple, - Qt::NoButton, k, wheelOrientation); + + const QPoint wheelPoint = slider->rect().bottomRight() + distanceFromBottomRight; + const QPoint angleDelta(wheelOrientation == Qt::Horizontal ? WHEEL_DELTA * deltaMultiple : 0, + wheelOrientation == Qt::Vertical ? WHEEL_DELTA * deltaMultiple : 0); + QWheelEvent event(wheelPoint, slider->mapToGlobal(wheelPoint), QPoint(), angleDelta, + Qt::NoButton, k, Qt::NoScrollPhase, false); QVERIFY(applicationInstance->sendEvent(slider,&event)); #ifdef Q_OS_MAC QEXPECT_FAIL("Normal data page", "QTBUG-23679", Continue); @@ -1674,8 +1678,8 @@ void tst_QAbstractSlider::wheelEvent() slider->setSliderPosition(initialSliderPosition); k = withModifiers ? Qt::ShiftModifier : Qt::NoModifier; - event = QWheelEvent(slider->rect().bottomRight() + distanceFromBottomRight, WHEEL_DELTA * deltaMultiple, - Qt::NoButton, k, wheelOrientation); + event = QWheelEvent(wheelPoint, slider->mapToGlobal(wheelPoint), QPoint(), angleDelta, + Qt::NoButton, k, Qt::NoScrollPhase, false); QSignalSpy spy1(slider, SIGNAL(actionTriggered(int))); QSignalSpy spy2(slider, SIGNAL(valueChanged(int))); QVERIFY(applicationInstance->sendEvent(slider,&event)); @@ -1715,16 +1719,16 @@ void tst_QAbstractSlider::fineGrainedWheelEvent() slider->setSliderPosition(0); const int singleStepDelta = invertedControls ? (-WHEEL_DELTA / 3) : (WHEEL_DELTA / 3); - - QWheelEvent eventDown(slider->rect().bottomRight(), singleStepDelta / 2, - Qt::NoButton, Qt::NoModifier, Qt::Vertical); + const QPoint wheelPoint = slider->rect().bottomRight(); + QWheelEvent eventDown(wheelPoint, slider->mapToGlobal(wheelPoint), QPoint(), QPoint(0, singleStepDelta / 2), + Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); QVERIFY(applicationInstance->sendEvent(slider,&eventDown)); QCOMPARE(slider->sliderPosition(), 0); QVERIFY(applicationInstance->sendEvent(slider,&eventDown)); QCOMPARE(slider->sliderPosition(), 1); - QWheelEvent eventUp(slider->rect().bottomRight(), -singleStepDelta / 2, - Qt::NoButton, Qt::NoModifier, Qt::Vertical); + QWheelEvent eventUp(wheelPoint, slider->mapToGlobal(wheelPoint), QPoint(), QPoint(0, -singleStepDelta / 2), + Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); QVERIFY(applicationInstance->sendEvent(slider,&eventUp)); QCOMPARE(slider->sliderPosition(), 1); QVERIFY(applicationInstance->sendEvent(slider,&eventUp)); diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index a576770811..8a46211714 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -2102,7 +2102,9 @@ void tst_QComboBox::mouseWheel() box.setEditable(i==0?false:true); box.setCurrentIndex(startIndex); - QWheelEvent event = QWheelEvent(box.rect().bottomRight() , WHEEL_DELTA * wheelDirection, Qt::NoButton, Qt::NoModifier); + const QPoint wheelPoint = box.rect().bottomRight(); + QWheelEvent event(wheelPoint, box.mapToGlobal(wheelPoint), QPoint(), QPoint(0, WHEEL_DELTA * wheelDirection), + Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); QVERIFY(applicationInstance->sendEvent(&box,&event)); QCOMPARE(box.currentIndex(), expectedIndex); @@ -2131,7 +2133,9 @@ void tst_QComboBox::popupWheelHandling() comboBox->showPopup(); QTRY_VERIFY(comboBox->view() && comboBox->view()->isVisible()); const QPoint popupPos = comboBox->view()->pos(); - QWheelEvent event(QPointF(10, 10), WHEEL_DELTA, Qt::NoButton, Qt::NoModifier); + const QPoint wheelPoint(10, 10); + QWheelEvent event(wheelPoint, scrollArea.mapToGlobal(wheelPoint), QPoint(), QPoint(0, WHEEL_DELTA), + Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); QVERIFY(QCoreApplication::sendEvent(scrollArea.windowHandle(), &event)); QCoreApplication::processEvents(); QVERIFY(comboBox->view()->isVisible()); diff --git a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp index cd045e476c..810f081b73 100644 --- a/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp +++ b/tests/auto/widgets/widgets/qdatetimeedit/tst_qdatetimeedit.cpp @@ -3141,7 +3141,6 @@ void tst_QDateTimeEdit::wheelEvent_data() { #if QT_CONFIG(wheelevent) QTest::addColumn("angleDelta"); - QTest::addColumn("qt4Delta"); QTest::addColumn("stepModifier"); QTest::addColumn("modifiers"); QTest::addColumn("source"); @@ -3255,7 +3254,6 @@ void tst_QDateTimeEdit::wheelEvent_data() modifierName.latin1(), sourceName.latin1()) << angleDelta - << units << static_cast(stepModifier) << modifiers << source @@ -3277,7 +3275,6 @@ void tst_QDateTimeEdit::wheelEvent() { #if QT_CONFIG(wheelevent) QFETCH(QPoint, angleDelta); - QFETCH(int, qt4Delta); QFETCH(int, stepModifier); QFETCH(Qt::KeyboardModifiers, modifiers); QFETCH(Qt::MouseEventSource, source); @@ -3294,9 +3291,8 @@ void tst_QDateTimeEdit::wheelEvent() style->stepModifier = static_cast(stepModifier); edit.setStyle(style.data()); - QWheelEvent event(QPointF(), QPointF(), QPoint(), angleDelta, qt4Delta, - Qt::Vertical, Qt::NoButton, modifiers, Qt::NoScrollPhase, - source); + QWheelEvent event(QPointF(), QPointF(), QPoint(), angleDelta, + Qt::NoButton, modifiers, Qt::NoScrollPhase, false, source); QCOMPARE(edit.date(), startDate); for (QDate expected : expectedDates) { diff --git a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp index a20b5568da..fed4d6f147 100644 --- a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp +++ b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp @@ -1377,7 +1377,6 @@ void tst_QDoubleSpinBox::wheelEvents_data() { #if QT_CONFIG(wheelevent) QTest::addColumn("angleDelta"); - QTest::addColumn("qt4Delta"); QTest::addColumn("stepModifier"); QTest::addColumn("modifier"); QTest::addColumn("source"); @@ -1476,7 +1475,6 @@ void tst_QDoubleSpinBox::wheelEvents_data() modifierName.latin1(), sourceName.latin1()) << angleDelta - << units << static_cast(stepModifier) << modifiers << source @@ -1496,7 +1494,6 @@ void tst_QDoubleSpinBox::wheelEvents() { #if QT_CONFIG(wheelevent) QFETCH(QPoint, angleDelta); - QFETCH(int, qt4Delta); QFETCH(int, stepModifier); QFETCH(Qt::KeyboardModifiers, modifier); QFETCH(Qt::MouseEventSource, source); @@ -1512,9 +1509,8 @@ void tst_QDoubleSpinBox::wheelEvents() style->stepModifier = static_cast(stepModifier); spinBox.setStyle(style.data()); - QWheelEvent event(QPointF(), QPointF(), QPoint(), angleDelta, qt4Delta, - Qt::Vertical, Qt::NoButton, modifier, Qt::NoScrollPhase, - source); + QWheelEvent event(QPointF(), QPointF(), QPoint(), angleDelta, + Qt::NoButton, modifier, Qt::NoScrollPhase, source); for (int expected : expectedValues) { qApp->sendEvent(&spinBox, &event); QCOMPARE(spinBox.value(), expected); diff --git a/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp b/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp index 278f5cdd68..339ff293f4 100644 --- a/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp +++ b/tests/auto/widgets/widgets/qscrollbar/tst_qscrollbar.cpp @@ -151,8 +151,11 @@ void tst_QScrollBar::QTBUG_27308() testWidget.setValue(testWidget.minimum()); testWidget.setEnabled(false); - QWheelEvent event(testWidget.rect().center(), - -WHEEL_DELTA, Qt::NoButton, Qt::NoModifier, testWidget.orientation()); + const QPoint wheelPoint = testWidget.rect().center(); + const QPoint angleDelta(testWidget.orientation() == Qt::Horizontal ? -WHEEL_DELTA : 0, + testWidget.orientation() == Qt::Vertical ? -WHEEL_DELTA : 0); + QWheelEvent event(wheelPoint, testWidget.mapToGlobal(wheelPoint), QPoint(), angleDelta, + Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); qApp->sendEvent(&testWidget, &event); QCOMPARE(testWidget.value(), testWidget.minimum()); } diff --git a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp index 3dd29b0214..cfa8db1fcc 100644 --- a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp +++ b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp @@ -1331,7 +1331,6 @@ void tst_QSpinBox::wheelEvents_data() { #if QT_CONFIG(wheelevent) QTest::addColumn("angleDelta"); - QTest::addColumn("qt4Delta"); QTest::addColumn("stepModifier"); QTest::addColumn("modifier"); QTest::addColumn("source"); @@ -1430,7 +1429,6 @@ void tst_QSpinBox::wheelEvents_data() modifierName.latin1(), sourceName.latin1()) << angleDelta - << units << static_cast(stepModifier) << modifiers << source @@ -1450,7 +1448,6 @@ void tst_QSpinBox::wheelEvents() { #if QT_CONFIG(wheelevent) QFETCH(QPoint, angleDelta); - QFETCH(int, qt4Delta); QFETCH(int, stepModifier); QFETCH(Qt::KeyboardModifiers, modifier); QFETCH(Qt::MouseEventSource, source); @@ -1466,9 +1463,8 @@ void tst_QSpinBox::wheelEvents() style->stepModifier = static_cast(stepModifier); spinBox.setStyle(style.data()); - QWheelEvent event(QPointF(), QPointF(), QPoint(), angleDelta, qt4Delta, - Qt::Vertical, Qt::NoButton, modifier, Qt::NoScrollPhase, - source); + QWheelEvent event(QPointF(), QPointF(), QPoint(), angleDelta, + Qt::NoButton, modifier, Qt::NoScrollPhase, source); for (int expected : expectedValues) { qApp->sendEvent(&spinBox, &event); QCOMPARE(spinBox.value(), expected); diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp index 81682dc027..c2cf31bfa4 100644 --- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp @@ -2669,12 +2669,14 @@ void tst_QTextEdit::wheelEvent() ed.setReadOnly(true); float defaultFontSize = ed.font().pointSizeF(); - QWheelEvent wheelUp(QPointF(), QPointF(), QPoint(), QPoint(0, 120), 120, Qt::Vertical, Qt::NoButton, Qt::ControlModifier); + QWheelEvent wheelUp(QPointF(), QPointF(), QPoint(), QPoint(0, 120), + Qt::NoButton, Qt::ControlModifier, Qt::NoScrollPhase, Qt::MouseEventNotSynthesized); ed.wheelEvent(&wheelUp); QCOMPARE(defaultFontSize + 1, ed.font().pointSizeF()); - QWheelEvent wheelHalfDown(QPointF(), QPointF(), QPoint(), QPoint(0, -60), -60, Qt::Vertical, Qt::NoButton, Qt::ControlModifier); + QWheelEvent wheelHalfDown(QPointF(), QPointF(), QPoint(), QPoint(0, -60), + Qt::NoButton, Qt::ControlModifier, Qt::NoScrollPhase, Qt::MouseEventNotSynthesized); ed.wheelEvent(&wheelHalfDown); QCOMPARE(defaultFontSize + 0.5, ed.font().pointSizeF()); From 2d2e16d3ef267d0a130f84fc1f0a67476545a2b1 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 12 Jul 2019 14:58:54 +0200 Subject: [PATCH 090/264] Fix a couple more uses of QWheelEvent constructors in tests Change-Id: I0c9f08a243a823aff0bf21dfc14f78680e95d80f Reviewed-by: Shawn Rutledge --- .../auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp | 2 +- tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp index fed4d6f147..c760d9cc99 100644 --- a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp +++ b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp @@ -1510,7 +1510,7 @@ void tst_QDoubleSpinBox::wheelEvents() spinBox.setStyle(style.data()); QWheelEvent event(QPointF(), QPointF(), QPoint(), angleDelta, - Qt::NoButton, modifier, Qt::NoScrollPhase, source); + Qt::NoButton, modifier, Qt::NoScrollPhase, false, source); for (int expected : expectedValues) { qApp->sendEvent(&spinBox, &event); QCOMPARE(spinBox.value(), expected); diff --git a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp index cfa8db1fcc..d75e701d1c 100644 --- a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp +++ b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp @@ -1464,7 +1464,7 @@ void tst_QSpinBox::wheelEvents() spinBox.setStyle(style.data()); QWheelEvent event(QPointF(), QPointF(), QPoint(), angleDelta, - Qt::NoButton, modifier, Qt::NoScrollPhase, source); + Qt::NoButton, modifier, Qt::NoScrollPhase, false, source); for (int expected : expectedValues) { qApp->sendEvent(&spinBox, &event); QCOMPARE(spinBox.value(), expected); From 0fec7417ca305e52cfd1382b3f9f8e4adcb597de Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 10 Jul 2019 19:40:06 +0200 Subject: [PATCH 091/264] QHash: optimize equality operator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - First compare the d-pointer before dipping into *d - Keep a running count as we calculate thisEqualRange, as std::distance() on QHash::iterator is very expensive. - Skip the pointless first comparison of the unadvanced iterator's key() with itself (found by Mårten Nordheim) Also rename (it, thisEqualRangeEnd) → (thisEqualRangeStart, it), to keep advancing `it`, which is more natural than advancing an `end` and later resetting it = end. Change-Id: I2c27c071b9ee23425a763328402dad9efee4cbd0 Reviewed-by: Mårten Nordheim Reviewed-by: Volker Hilsheimer --- src/corelib/tools/qhash.h | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index f4590c6672..ee754a79d5 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -957,23 +957,27 @@ Q_OUTOFLINE_TEMPLATE typename QHash::Node **QHash::findNode(cons template Q_OUTOFLINE_TEMPLATE bool QHash::operator==(const QHash &other) const { - if (size() != other.size()) - return false; if (d == other.d) return true; + if (size() != other.size()) + return false; const_iterator it = begin(); while (it != end()) { // Build two equal ranges for i.key(); one for *this and one for other. // For *this we can avoid a lookup via equal_range, as we know the beginning of the range. - auto thisEqualRangeEnd = it; - while (thisEqualRangeEnd != end() && it.key() == thisEqualRangeEnd.key()) - ++thisEqualRangeEnd; + auto thisEqualRangeStart = it; + const Key &thisEqualRangeKey = it.key(); + size_type n = 0; + do { + ++it; + ++n; + } while (it != end() && it.key() == thisEqualRangeKey); - const auto otherEqualRange = other.equal_range(it.key()); + const auto otherEqualRange = other.equal_range(thisEqualRangeKey); - if (std::distance(it, thisEqualRangeEnd) != std::distance(otherEqualRange.first, otherEqualRange.second)) + if (n != std::distance(otherEqualRange.first, otherEqualRange.second)) return false; // Keys in the ranges are equal by construction; this checks only the values. @@ -986,15 +990,13 @@ Q_OUTOFLINE_TEMPLATE bool QHash::operator==(const QHash &other) const // is supported since MSVC 2015). // // ### Qt 6: if C++14 library support is a mandated minimum, remove the ifdef for MSVC. - if (!std::is_permutation(it, thisEqualRangeEnd, otherEqualRange.first + if (!std::is_permutation(thisEqualRangeStart, it, otherEqualRange.first #ifdef Q_CC_MSVC , otherEqualRange.second #endif )) { return false; } - - it = thisEqualRangeEnd; } return true; From 7d3a55cbd219bee4e071df5588c87723d9c8f7c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 12 Jul 2019 11:45:07 +0200 Subject: [PATCH 092/264] Remove unused arguments from QWidgetPrivate::create_sys The public QWidget::create still has them, but we don't need to propagate them on - that just makes debugging the window creation flow harder. The window argument to QWidget::create is technically used to guard an early exit in the function, but to keep behavior the same we leave it for now. Change-Id: Ic0287575aa25f1272e216adc1b75e34d6f55f6d9 Reviewed-by: Simon Hausmann --- src/widgets/kernel/qapplication.cpp | 2 +- src/widgets/kernel/qwidget.cpp | 34 ++++++------------- src/widgets/kernel/qwidget_p.h | 2 +- .../widgets/kernel/qwidget/tst_qwidget.cpp | 6 ++-- 4 files changed, 16 insertions(+), 28 deletions(-) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 8e01cb17c5..f564475698 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1962,7 +1962,7 @@ bool QApplication::event(QEvent *e) */ // ### FIXME: topLevelWindows does not contain QWidgets without a parent -// until create_sys is called. So we have to override the +// until QWidgetPrivate::create is called. So we have to override the // QGuiApplication::notifyLayoutDirectionChange // to do the right thing. void QApplicationPrivate::notifyLayoutDirectionChange() diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 6f0f39a344..bf339ca5c5 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1190,7 +1190,7 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) q->setAttribute(Qt::WA_ContentsMarginsRespectsSafeArea); q->setAttribute(Qt::WA_WState_Hidden); - //give potential windows a bigger "pre-initial" size; create_sys() will give them a new size later + //give potential windows a bigger "pre-initial" size; create() will give them a new size later data.crect = parentWidget ? QRect(0,0,100,30) : QRect(0,0,640,480); focus_next = focus_prev = q; @@ -1255,27 +1255,19 @@ void QWidgetPrivate::createRecursively() /*! Creates a new widget window. - The parameter \a window is ignored in Qt 5. Please use - QWindow::fromWinId() to create a QWindow wrapping a foreign - window and pass it to QWidget::createWindowContainer() instead. - - Initializes the window (sets the geometry etc.) if \a - initializeWindow is true. If \a initializeWindow is false, no - initialization is performed. This parameter only makes sense if \a - window is a valid window. - - Destroys the old window if \a destroyOldWindow is true. If \a - destroyOldWindow is false, you are responsible for destroying the - window yourself (using platform native code). - - The QWidget constructor calls create(0,true,true) to create a - window for this widget. + The parameters \a window, \a initializeWindow, and \a destroyOldWindow + are ignored in Qt 5. Please use QWindow::fromWinId() to create a + QWindow wrapping a foreign window and pass it to + QWidget::createWindowContainer() instead. \sa createWindowContainer(), QWindow::fromWinId() */ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) { + Q_UNUSED(initializeWindow); + Q_UNUSED(destroyOldWindow); + Q_D(QWidget); if (Q_UNLIKELY(window)) qWarning("QWidget::create(): Parameter 'window' does not have any effect."); @@ -1335,7 +1327,7 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) d->updateIsOpaque(); setAttribute(Qt::WA_WState_Created); // set created flag - d->create_sys(window, initializeWindow, destroyOldWindow); + d->create(); // a real toplevel window needs a backing store if (isWindow() && windowType() != Qt::Desktop) { @@ -1404,14 +1396,10 @@ void q_createNativeChildrenAndSetParent(const QWidget *parentWidget) } -void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow) +void QWidgetPrivate::create() { Q_Q(QWidget); - Q_UNUSED(window); - Q_UNUSED(initializeWindow); - Q_UNUSED(destroyOldWindow); - if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow()) return; // we only care about real toplevels @@ -11340,7 +11328,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) // windowModality property and then reshown. } if (testAttribute(Qt::WA_WState_Created)) { - // don't call setModal_sys() before create_sys() + // don't call setModal_sys() before create() d->setModal_sys(); } break; diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 64bc463ae2..142d5ef9bb 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -352,7 +352,7 @@ public: void update(T t); void init(QWidget *desktopWidget, Qt::WindowFlags f); - void create_sys(WId window, bool initializeWindow, bool destroyOldWindow); + void create(); void createRecursively(); void createWinId(); diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 7edca2017d..58c61d746a 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -6139,7 +6139,7 @@ void tst_QWidget::minAndMaxSizeWithX11BypassWindowManagerHint() { if (m_platform != QStringLiteral("xcb")) QSKIP("This test is for X11 only."); - // Same size as in QWidget::create_sys(). + // Same size as in QWidgetPrivate::create. const QSize desktopSize = QApplication::desktop()->size(); const QSize originalSize(desktopSize.width() / 2, desktopSize.height() * 4 / 10); @@ -9415,7 +9415,7 @@ void tst_QWidget::initialPosForDontShowOnScreenWidgets() const QPoint expectedPos(0, 0); QWidget widget; widget.setAttribute(Qt::WA_DontShowOnScreen); - widget.winId(); // Make sure create_sys is called. + widget.winId(); // Make sure QWidgetPrivate::create is called. QCOMPARE(widget.pos(), expectedPos); QCOMPARE(widget.geometry().topLeft(), expectedPos); } @@ -9425,7 +9425,7 @@ void tst_QWidget::initialPosForDontShowOnScreenWidgets() QWidget widget; widget.setAttribute(Qt::WA_DontShowOnScreen); widget.move(expectedPos); - widget.winId(); // Make sure create_sys is called. + widget.winId(); // Make sure QWidgetPrivate::create is called. QCOMPARE(widget.pos(), expectedPos); QCOMPARE(widget.geometry().topLeft(), expectedPos); } From 4c61544aa84f08a28829abe8db28dd23a178c0cb Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 12 Jul 2019 11:15:41 +0200 Subject: [PATCH 093/264] ABI fixups for QColorSpace Declare it shared to Qt and make the move method noexcept. Change-Id: I25d5d255d300fda109ffa1a08e1849b15e9ff29c Reviewed-by: Marc Mutz --- src/gui/painting/qcolorspace.cpp | 10 ++++++++-- src/gui/painting/qcolorspace.h | 9 +++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp index 72c236bc50..881a02ee67 100644 --- a/src/gui/painting/qcolorspace.cpp +++ b/src/gui/painting/qcolorspace.cpp @@ -502,7 +502,7 @@ QColorSpace::~QColorSpace() { } -QColorSpace::QColorSpace(QColorSpace &&colorSpace) +QColorSpace::QColorSpace(QColorSpace &&colorSpace) noexcept : d_ptr(std::move(colorSpace.d_ptr)) { } @@ -512,7 +512,7 @@ QColorSpace::QColorSpace(const QColorSpace &colorSpace) { } -QColorSpace &QColorSpace::operator=(QColorSpace &&colorSpace) +QColorSpace &QColorSpace::operator=(QColorSpace &&colorSpace) noexcept { d_ptr = std::move(colorSpace.d_ptr); return *this; @@ -524,6 +524,12 @@ QColorSpace &QColorSpace::operator=(const QColorSpace &colorSpace) return *this; } +/*! \fn void QColorSpace::swap(QColorSpace &other) + + Swaps color space \a other with this color space. This operation is very fast and + never fails. +*/ + /*! Returns the id of the predefined color space this object represents or \c Unknown if it doesn't match any of them. diff --git a/src/gui/painting/qcolorspace.h b/src/gui/painting/qcolorspace.h index 56676826a9..6f1a806b60 100644 --- a/src/gui/painting/qcolorspace.h +++ b/src/gui/painting/qcolorspace.h @@ -90,11 +90,14 @@ public: TransferFunction fun, float gamma = 0.0f); ~QColorSpace(); - QColorSpace(QColorSpace &&colorSpace); + QColorSpace(QColorSpace &&colorSpace) noexcept; QColorSpace(const QColorSpace &colorSpace); - QColorSpace &operator=(QColorSpace &&colorSpace); + QColorSpace &operator=(QColorSpace &&colorSpace) noexcept; QColorSpace &operator=(const QColorSpace &colorSpace); + void swap(QColorSpace &colorSpace) noexcept + { qSwap(d_ptr, colorSpace.d_ptr); } + ColorSpaceId colorSpaceId() const noexcept; Gamut gamut() const noexcept; TransferFunction transferFunction() const noexcept; @@ -124,6 +127,8 @@ inline bool operator!=(const QColorSpace &colorSpace1, const QColorSpace &colorS return !(colorSpace1 == colorSpace2); } +Q_DECLARE_SHARED(QColorSpace) + // QColorSpace stream functions #if !defined(QT_NO_DATASTREAM) Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QColorSpace &); From e89b2f72c7147e46dcf606c3dcc507e2ae2841ce Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 10 Jul 2019 19:46:45 +0200 Subject: [PATCH 094/264] Centralize the MSVC work-around for std::is_permutation There's currently only one user, but another one is coming up, so apply DRY and centralize the work-around for the MSVC warning C4996 on use of 3-arg STL algorithms in one place. The code is prepared to handle other algorithms with ease, should any more crop up. Change-Id: Ia881888d6a2b5286c6d8d823bc2b76788efad624 Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.h | 23 +++++++++++++++++++++++ src/corelib/tools/qhash.h | 16 +--------------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 15f4621cc0..80f59d92d0 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1001,6 +1001,29 @@ QT_WARNING_DISABLE_MSVC(4530) /* C++ exception handler used, but unwind semantic # endif #endif +// Work around MSVC warning about use of 3-arg algorithms +// until we can depend on the C++14 4-arg ones. +// +// These algortithms do NOT check for equal length. +// They need to be treated as if they called the 3-arg version (which they do)! +#ifdef Q_CC_MSVC +# define QT_3ARG_ALG(alg, f1, l1, f2, l2) \ + std::alg(f1, l1, f2, l2) +#else +# define QT_3ARG_ALG(alg, f1, l1, f2, l2) \ + [&f1, &l1, &f2, &l2]() { \ + Q_UNUSED(l2); \ + return std::alg(f1, l1, f2); \ + }() +#endif +template +inline bool qt_is_permutation(ForwardIterator1 first1, ForwardIterator1 last1, + ForwardIterator2 first2, ForwardIterator2 last2) +{ + return QT_3ARG_ALG(is_permutation, first1, last1, first2, last2); +} +#undef QT_3ARG_ALG + // this adds const to non-const objects (like std::as_const) template Q_DECL_CONSTEXPR typename std::add_const::type &qAsConst(T &t) noexcept { return t; } diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index ee754a79d5..236e433101 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -981,22 +981,8 @@ Q_OUTOFLINE_TEMPLATE bool QHash::operator==(const QHash &other) const return false; // Keys in the ranges are equal by construction; this checks only the values. - // - // When using the 3-arg std::is_permutation, MSVC will emit warning C4996, - // passing an unchecked iterator to a Standard Library algorithm. We don't - // want to suppress the warning, and we can't use stdext::make_checked_array_iterator - // because QHash::(const_)iterator does not work with size_t and thus will - // emit more warnings. Use the 4-arg std::is_permutation instead (which - // is supported since MSVC 2015). - // - // ### Qt 6: if C++14 library support is a mandated minimum, remove the ifdef for MSVC. - if (!std::is_permutation(thisEqualRangeStart, it, otherEqualRange.first -#ifdef Q_CC_MSVC - , otherEqualRange.second -#endif - )) { + if (!qt_is_permutation(thisEqualRangeStart, it, otherEqualRange.first, otherEqualRange.second)) return false; - } } return true; From 2f33e030b8c80b4665cc2c120df7833469c05145 Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Wed, 10 Jul 2019 17:04:42 +0200 Subject: [PATCH 095/264] Remove usages of deprecated APIs of qtbase/gui - Replaced the usages of deprecated APIs by corresponding alternatives in the library code and documentation. - Modified the tests to make them build when deprecated APIs disabled: * Made the the parts of the tests testing the deprecated APIs to be compiled conditionally, only when the corresponding methods are enabled. * If the test-case tests only the deprecated API, but not the corresponding replacement, added tests for the replacement. Change-Id: Ic38245015377fc0c8127eb5458c184ffd4b450f1 Reviewed-by: Volker Hilsheimer --- examples/opengl/legacy/hellogl/glwidget.cpp | 4 +- .../opengl/legacy/overpainting/glwidget.cpp | 4 +- .../widgets/painting/shared/arthurstyle.cpp | 4 +- .../widgets/painting/shared/arthurwidgets.cpp | 2 +- src/gui/painting/qpagedpaintdevice.cpp | 1 + src/gui/util/qdesktopservices.cpp | 2 + .../corelib/io/qsettings/tst_qsettings.cpp | 4 +- .../qdatastream/tst_qdatastream.cpp | 8 +-- .../image/qpixmapcache/tst_qpixmapcache.cpp | 44 +++++++++--- tests/auto/gui/kernel/qdrag/tst_qdrag.cpp | 9 ++- .../kernel/qguimetatype/tst_qguimetatype.cpp | 2 +- .../gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp | 4 ++ .../math3d/qquaternion/tst_qquaternion.cpp | 3 + .../gui/painting/qpainter/tst_qpainter.cpp | 68 +++++++++++++++++-- .../auto/gui/painting/qpathclipper/paths.cpp | 2 +- tests/auto/gui/text/qfont/tst_qfont.cpp | 4 ++ tests/auto/gui/text/qtexttable/qtexttable.pro | 2 +- .../gui/text/qtexttable/tst_qtexttable.cpp | 42 +++++++++++- .../qdesktopservices/tst_qdesktopservices.cpp | 4 ++ tests/auto/other/lancelot/paintcommands.cpp | 2 +- .../qgraphicswidget/tst_qgraphicswidget.cpp | 2 +- .../image/qpixmapcache/tst_qpixmapcache.cpp | 4 +- .../tst_qgraphicsanchorlayout.cpp | 2 +- .../qgraphicslayout/tst_qgraphicslayout.cpp | 2 +- .../qgraphicsview/chiptester/chip.cpp | 6 +- tests/manual/qgraphicslayout/flicker/window.h | 2 +- 26 files changed, 190 insertions(+), 43 deletions(-) diff --git a/examples/opengl/legacy/hellogl/glwidget.cpp b/examples/opengl/legacy/hellogl/glwidget.cpp index 22934136e5..059a9bb96d 100644 --- a/examples/opengl/legacy/hellogl/glwidget.cpp +++ b/examples/opengl/legacy/hellogl/glwidget.cpp @@ -140,10 +140,10 @@ void GLWidget::initializeGL() { initializeOpenGLFunctions(); - qglClearColor(qtPurple.dark()); + qglClearColor(qtPurple.darker()); logo = new QtLogo(this, 64); - logo->setColor(qtGreen.dark()); + logo->setColor(qtGreen.darker()); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); diff --git a/examples/opengl/legacy/overpainting/glwidget.cpp b/examples/opengl/legacy/overpainting/glwidget.cpp index 0094f8ead7..c4558ce785 100644 --- a/examples/opengl/legacy/overpainting/glwidget.cpp +++ b/examples/opengl/legacy/overpainting/glwidget.cpp @@ -130,7 +130,7 @@ void GLWidget::initializeGL() glEnable(GL_MULTISAMPLE); logo = new QtLogo(this); - logo->setColor(qtGreen.dark()); + logo->setColor(qtGreen.darker()); } //! [2] @@ -163,7 +163,7 @@ void GLWidget::paintEvent(QPaintEvent *event) //! [4] //! [6] - qglClearColor(qtPurple.dark()); + qglClearColor(qtPurple.darker()); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); diff --git a/examples/widgets/painting/shared/arthurstyle.cpp b/examples/widgets/painting/shared/arthurstyle.cpp index 3fc461bbd2..31be899357 100644 --- a/examples/widgets/painting/shared/arthurstyle.cpp +++ b/examples/widgets/painting/shared/arthurstyle.cpp @@ -457,7 +457,7 @@ void ArthurStyle::polish(QWidget *widget) QPalette pal = widget->palette(); if (widget->isWindow()) { - pal.setColor(QPalette::Background, QColor(241, 241, 241)); + pal.setColor(QPalette::Window, QColor(241, 241, 241)); widget->setPalette(pal); } @@ -474,7 +474,7 @@ void ArthurStyle::unpolish(QWidget *widget) void ArthurStyle::polish(QPalette &palette) { - palette.setColor(QPalette::Background, QColor(241, 241, 241)); + palette.setColor(QPalette::Window, QColor(241, 241, 241)); } QRect ArthurStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const diff --git a/examples/widgets/painting/shared/arthurwidgets.cpp b/examples/widgets/painting/shared/arthurwidgets.cpp index bdac5de13c..285be99d20 100644 --- a/examples/widgets/painting/shared/arthurwidgets.cpp +++ b/examples/widgets/painting/shared/arthurwidgets.cpp @@ -153,7 +153,7 @@ void ArthurFrame::paintEvent(QPaintEvent *e) int o = 10; - QBrush bg = palette().brush(QPalette::Background); + QBrush bg = palette().brush(QPalette::Window); painter.fillRect(0, 0, o, o, bg); painter.fillRect(width() - o, 0, o, o, bg); painter.fillRect(0, height() - o, o, o, bg); diff --git a/src/gui/painting/qpagedpaintdevice.cpp b/src/gui/painting/qpagedpaintdevice.cpp index 0c2123f9a6..3fdd0206b7 100644 --- a/src/gui/painting/qpagedpaintdevice.cpp +++ b/src/gui/painting/qpagedpaintdevice.cpp @@ -42,6 +42,7 @@ QT_BEGIN_NAMESPACE +// ### Qt 6: remove when the deprecated constructor is removed class QDummyPagedPaintDevicePrivate : public QPagedPaintDevicePrivate { bool setPageLayout(const QPageLayout &newPageLayout) override diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp index ee0ff4c6ef..99214c4960 100644 --- a/src/gui/util/qdesktopservices.cpp +++ b/src/gui/util/qdesktopservices.cpp @@ -290,6 +290,7 @@ void QDesktopServices::unsetUrlHandler(const QString &scheme) setUrlHandler(scheme, 0, 0); } +#if QT_DEPRECATED_SINCE(5, 0) /*! \enum QDesktopServices::StandardLocation \since 4.4 @@ -344,6 +345,7 @@ void QDesktopServices::unsetUrlHandler(const QString &scheme) \obsolete Use QStandardPaths::displayName() */ +#endif extern Q_CORE_EXPORT QString qt_applicationName_noFallback(); diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index a71a68e457..289590a233 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -1366,7 +1366,9 @@ void tst_QSettings::testVariantTypes() if (format >= QSettings::InvalidFormat) { testVal("keysequence", QKeySequence(Qt::ControlModifier + Qt::Key_F1), QKeySequence, KeySequence); } else { - testVal("keysequence", QKeySequence(Qt::ControlModifier + Qt::Key_F1), QString, String); + testVal("keysequence", + QKeySequence(Qt::ControlModifier + Qt::Key_F1).toString(QKeySequence::NativeText), + QString, String); } #undef testVal diff --git a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp index b8778e4e98..8197c386c5 100644 --- a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp @@ -2391,10 +2391,10 @@ void tst_QDataStream::setVersion() if (vers == 1) { for (int grp = 0; grp < (int)QPalette::NColorGroups; ++grp) { - QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Foreground) - == inPal1.color((QPalette::ColorGroup)grp, QPalette::Foreground)); - QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Background) - == inPal1.color((QPalette::ColorGroup)grp, QPalette::Background)); + QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::WindowText) + == inPal1.color((QPalette::ColorGroup)grp, QPalette::WindowText)); + QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Window) + == inPal1.color((QPalette::ColorGroup)grp, QPalette::Window)); QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Light) == inPal1.color((QPalette::ColorGroup)grp, QPalette::Light)); QVERIFY(pal1.color((QPalette::ColorGroup)grp, QPalette::Dark) diff --git a/tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp b/tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp index 158530428d..3158883ef5 100644 --- a/tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp +++ b/tests/auto/gui/image/qpixmapcache/tst_qpixmapcache.cpp @@ -104,18 +104,28 @@ void tst_QPixmapCache::cacheLimit() void tst_QPixmapCache::setCacheLimit() { + QPixmap res; QPixmap *p1 = new QPixmap(2, 3); QPixmapCache::insert("P1", *p1); +#if QT_DEPRECATED_SINCE(5, 13) QVERIFY(QPixmapCache::find("P1") != 0); +#endif + QVERIFY(QPixmapCache::find("P1", &res)); delete p1; QPixmapCache::setCacheLimit(0); +#if QT_DEPRECATED_SINCE(5, 13) QVERIFY(!QPixmapCache::find("P1")); +#endif + QVERIFY(!QPixmapCache::find("P1", &res)); p1 = new QPixmap(2, 3); QPixmapCache::setCacheLimit(1000); QPixmapCache::insert("P1", *p1); +#if QT_DEPRECATED_SINCE(5, 13) QVERIFY(QPixmapCache::find("P1") != 0); +#endif + QVERIFY(QPixmapCache::find("P1", &res)); delete p1; @@ -200,6 +210,7 @@ void tst_QPixmapCache::find() QVERIFY(QPixmapCache::insert("P1", p1)); QPixmap p2; +#if QT_DEPRECATED_SINCE(5, 13) QVERIFY(QPixmapCache::find("P1", p2)); QCOMPARE(p2.width(), 10); QCOMPARE(p2.height(), 10); @@ -209,6 +220,12 @@ void tst_QPixmapCache::find() QPixmap *p3 = QPixmapCache::find("P1"); QVERIFY(p3); QCOMPARE(p1, *p3); +#endif + + QVERIFY(QPixmapCache::find("P1", &p2)); + QCOMPARE(p2.width(), 10); + QCOMPARE(p2.height(), 10); + QCOMPARE(p1, p2); //The int part of the API QPixmapCache::Key key = QPixmapCache::insert(p1); @@ -261,6 +278,7 @@ void tst_QPixmapCache::insert() } int num = 0; +#if QT_DEPRECATED_SINCE(5, 13) for (int k = 0; k < numberOfKeys; ++k) { if (QPixmapCache::find(QString::number(k))) ++num; @@ -268,6 +286,16 @@ void tst_QPixmapCache::insert() if (QPixmapCache::find("0")) ++num; + num = 0; +#endif + QPixmap res; + for (int k = 0; k < numberOfKeys; ++k) { + if (QPixmapCache::find(QString::number(k), &res)) + ++num; + } + + if (QPixmapCache::find("0", &res)) + ++num; QVERIFY(num <= estimatedNum); QPixmap p3; @@ -340,17 +368,17 @@ void tst_QPixmapCache::remove() p1.fill(Qt::yellow); QPixmap p2; - QVERIFY(QPixmapCache::find("red", p2)); + QVERIFY(QPixmapCache::find("red", &p2)); QVERIFY(p1.toImage() != p2.toImage()); QVERIFY(p1.toImage() == p1.toImage()); // sanity check QPixmapCache::remove("red"); - QVERIFY(!QPixmapCache::find("red")); + QVERIFY(!QPixmapCache::find("red", &p2)); QPixmapCache::remove("red"); - QVERIFY(!QPixmapCache::find("red")); + QVERIFY(!QPixmapCache::find("red", &p2)); QPixmapCache::remove("green"); - QVERIFY(!QPixmapCache::find("green")); + QVERIFY(!QPixmapCache::find("green", &p2)); //The int part of the API QPixmapCache::clear(); @@ -392,7 +420,7 @@ void tst_QPixmapCache::remove() key = QPixmapCache::insert(p1); QPixmapCache::remove(key); QVERIFY(QPixmapCache::find(key, &p1) == 0); - QVERIFY(QPixmapCache::find("red") != 0); + QVERIFY(QPixmapCache::find("red", &p1) != 0); } void tst_QPixmapCache::clear() @@ -408,14 +436,14 @@ void tst_QPixmapCache::clear() const int numberOfKeys = estimatedNum + 1000; for (int i = 0; i < numberOfKeys; ++i) - QVERIFY(QPixmapCache::find("x" + QString::number(i)) == 0); + QVERIFY(!QPixmapCache::find("x" + QString::number(i), &p1)); for (int j = 0; j < numberOfKeys; ++j) QPixmapCache::insert(QString::number(j), p1); int num = 0; for (int k = 0; k < numberOfKeys; ++k) { - if (QPixmapCache::find(QString::number(k), p1)) + if (QPixmapCache::find(QString::number(k), &p1)) ++num; } QVERIFY(num > 0); @@ -423,7 +451,7 @@ void tst_QPixmapCache::clear() QPixmapCache::clear(); for (int k = 0; k < numberOfKeys; ++k) - QVERIFY(!QPixmapCache::find(QString::number(k))); + QVERIFY(!QPixmapCache::find(QString::number(k), &p1)); //The int part of the API QPixmap p2(10, 10); diff --git a/tests/auto/gui/kernel/qdrag/tst_qdrag.cpp b/tests/auto/gui/kernel/qdrag/tst_qdrag.cpp index 68852f5a3f..d67b17fd43 100644 --- a/tests/auto/gui/kernel/qdrag/tst_qdrag.cpp +++ b/tests/auto/gui/kernel/qdrag/tst_qdrag.cpp @@ -68,10 +68,17 @@ void tst_QDrag::getSetCheck() QCOMPARE((QMimeData *)0, obj1.mimeData()); // delete var1; // No delete, since QDrag takes ownership - Qt::DropAction result = obj1.start(); + Qt::DropAction result = obj1.exec(); + QCOMPARE(result, Qt::IgnoreAction); + result = obj1.exec(Qt::MoveAction | Qt::LinkAction); + QCOMPARE(result, Qt::IgnoreAction); + +#if QT_DEPRECATED_SINCE(5, 13) + result = obj1.start(); QCOMPARE(result, Qt::IgnoreAction); result = obj1.start(Qt::MoveAction | Qt::LinkAction); QCOMPARE(result, Qt::IgnoreAction); +#endif } QTEST_MAIN(tst_QDrag) diff --git a/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp b/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp index b2572188b9..3ce65a6785 100644 --- a/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp +++ b/tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp @@ -191,7 +191,7 @@ template<> struct TestValueFactory { static QTextLength *create() { return new QTextLength(QTextLength::PercentageLength, 50); } }; template<> struct TestValueFactory { - static QTextFormat *create() { return new QTextFormat(QTextFormat::TableFormat); } + static QTextFormat *create() { return new QTextFormat(QTextFormat::FrameFormat); } }; template<> struct TestValueFactory { static QMatrix *create() { return new QMatrix(10, 20, 30, 40, 50, 60); } diff --git a/tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp b/tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp index 96d983c8f7..e19f76d830 100644 --- a/tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp +++ b/tests/auto/gui/math3d/qmatrixnxn/tst_qmatrixnxn.cpp @@ -2861,8 +2861,10 @@ void tst_QMatrixNxN::convertGeneric() QMatrix4x4 m4(m1); QVERIFY(isSame(m4, unique4x4)); +#if QT_DEPRECATED_SINCE(5, 0) QMatrix4x4 m5 = qGenericMatrixToMatrix4x4(m1); QVERIFY(isSame(m5, unique4x4)); +#endif static float const conv4x4[12] = { 1.0f, 2.0f, 3.0f, 4.0f, @@ -2874,8 +2876,10 @@ void tst_QMatrixNxN::convertGeneric() QMatrix4x3 m10 = m9.toGenericMatrix<4, 3>(); QVERIFY(isSame(m10, conv4x4)); +#if QT_DEPRECATED_SINCE(5, 0) QMatrix4x3 m11 = qGenericMatrixFromMatrix4x4<4, 3>(m9); QVERIFY(isSame(m11, conv4x4)); +#endif } // Copy of "flagBits" in qmatrix4x4.h. diff --git a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp index 097dd111d3..8041fb5439 100644 --- a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp +++ b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp @@ -778,7 +778,10 @@ void tst_QQuaternion::conjugate() QQuaternion v1(w1, x1, y1, z1); QQuaternion v2(w1, -x1, -y1, -z1); +#if QT_DEPRECATED_SINCE(5, 5) QCOMPARE(v1.conjugate(), v2); +#endif + QCOMPARE(v1.conjugated(), v2); } // Test quaternion creation from an axis and an angle. diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 2b53169a45..0efeb9b356 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -123,14 +123,18 @@ private slots: void drawPath2(); void drawPath3(); +#if QT_DEPRECATED_SINCE(5, 13) void drawRoundRect_data() { fillData(); } void drawRoundRect(); +#endif + void drawRoundedRect_data() { fillData(); } + void drawRoundedRect(); void qimageFormats_data(); void qimageFormats(); void textOnTransparentImage(); -#ifndef QT_NO_WIDGETS +#if !defined(QT_NO_WIDGETS) && QT_DEPRECATED_SINCE(5, 13) void initFrom(); #endif @@ -679,12 +683,14 @@ static QRect getPaintedSize(const QPixmap &pm, const QColor &background) } #ifndef QT_NO_WIDGETS + +#if QT_DEPRECATED_SINCE(5, 13) void tst_QPainter::initFrom() { QWidget *widget = new QWidget(); QPalette pal = widget->palette(); - pal.setColor(QPalette::Foreground, QColor(255, 0, 0)); - pal.setBrush(QPalette::Background, QColor(0, 255, 0)); + pal.setColor(QPalette::WindowText, QColor(255, 0, 0)); + pal.setBrush(QPalette::Window, QColor(0, 255, 0)); widget->setPalette(pal); widget->show(); @@ -698,11 +704,12 @@ void tst_QPainter::initFrom() p.initFrom(widget); QCOMPARE(p.font(), font); - QCOMPARE(p.pen().color(), pal.color(QPalette::Foreground)); + QCOMPARE(p.pen().color(), pal.color(QPalette::WindowText)); QCOMPARE(p.background(), pal.window()); delete widget; } +#endif void tst_QPainter::drawBorderPixmap() { @@ -1546,6 +1553,7 @@ void tst_QPainter::drawClippedEllipse() } +#if QT_DEPRECATED_SINCE(5, 13) void tst_QPainter::drawRoundRect() { QFETCH(QRect, rect); @@ -1580,6 +1588,42 @@ void tst_QPainter::drawRoundRect() QCOMPARE(painted.height(), rect.height() + increment); } } +#endif + +void tst_QPainter::drawRoundedRect() +{ + QFETCH(QRect, rect); + QFETCH(bool, usePen); + +#ifdef Q_OS_DARWIN + if (QTest::currentDataTag() == QByteArray("rect(6, 12, 3, 14) with pen") || + QTest::currentDataTag() == QByteArray("rect(6, 17, 3, 25) with pen") || + QTest::currentDataTag() == QByteArray("rect(10, 6, 10, 3) with pen") || + QTest::currentDataTag() == QByteArray("rect(10, 12, 10, 14) with pen") || + QTest::currentDataTag() == QByteArray("rect(13, 45, 17, 80) with pen") || + QTest::currentDataTag() == QByteArray("rect(13, 50, 17, 91) with pen") || + QTest::currentDataTag() == QByteArray("rect(17, 6, 24, 3) with pen") || + QTest::currentDataTag() == QByteArray("rect(24, 12, 38, 14) with pen")) + QSKIP("The Mac paint engine is off-by-one on certain rect sizes"); +#endif + QPixmap pixmap(rect.x() + rect.width() + 10, + rect.y() + rect.height() + 10); + { + pixmap.fill(Qt::white); + QPainter p(&pixmap); + p.setRenderHint(QPainter::Qt4CompatiblePainting); + p.setPen(usePen ? QPen(Qt::black) : QPen(Qt::NoPen)); + p.setBrush(Qt::black); + p.drawRoundedRect(rect, 25, 25, Qt::RelativeSize); + p.end(); + + int increment = usePen ? 1 : 0; + + const QRect painted = getPaintedSize(pixmap, Qt::white); + QCOMPARE(painted.width(), rect.width() + increment); + QCOMPARE(painted.height(), rect.height() + increment); + } +} void tst_QPainter::qimageFormats_data() { @@ -1662,9 +1706,13 @@ void tst_QPainter::combinedMatrix() p.translate(0.5, 0.5); + QTransform ct = p.combinedTransform(); +#if QT_DEPRECATED_SINCE(5, 13) QMatrix cm = p.combinedMatrix(); + QCOMPARE(cm, ct.toAffine()); +#endif - QPointF pt = QPointF(0, 0) * cm; + QPointF pt = QPointF(0, 0) * ct.toAffine(); QCOMPARE(pt.x(), 48.0); QCOMPARE(pt.y(), 16.0); @@ -1979,7 +2027,7 @@ void tst_QPainter::clippedFillPath_data() << pen2; path = QPainterPath(); - path.addRoundRect(QRect(15, 15, 50, 50), 20); + path.addRoundedRect(QRect(15, 15, 50, 50), 20, Qt::RelativeSize); QTest::newRow("round rect 0") << QSize(100, 100) << path << QRect(15, 15, 49, 49) << QBrush(Qt::NoBrush) @@ -4088,14 +4136,18 @@ void tst_QPainter::inactivePainter() p.setClipRegion(region); p.setClipping(true); +#if QT_DEPRECATED_SINCE(5, 13) p.combinedMatrix(); +#endif p.combinedTransform(); p.compositionMode(); p.setCompositionMode(QPainter::CompositionMode_Plus); p.device(); +#if QT_DEPRECATED_SINCE(5, 13) p.deviceMatrix(); +#endif p.deviceTransform(); p.font(); @@ -4119,7 +4171,9 @@ void tst_QPainter::inactivePainter() p.setRenderHint(QPainter::Antialiasing, true); p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, false); +#if QT_DEPRECATED_SINCE(5, 13) p.resetMatrix(); +#endif p.resetTransform(); p.rotate(1); p.scale(2, 2); @@ -4135,8 +4189,10 @@ void tst_QPainter::inactivePainter() p.window(); p.setWindow(QRect(10, 10, 620, 460)); +#if QT_DEPRECATED_SINCE(5, 13) p.worldMatrix(); p.setWorldMatrix(QMatrix().translate(43, 21), true); +#endif p.setWorldMatrixEnabled(true); p.transform(); diff --git a/tests/auto/gui/painting/qpathclipper/paths.cpp b/tests/auto/gui/painting/qpathclipper/paths.cpp index 077527e1a0..1328befd1b 100644 --- a/tests/auto/gui/painting/qpathclipper/paths.cpp +++ b/tests/auto/gui/painting/qpathclipper/paths.cpp @@ -578,7 +578,7 @@ QPainterPath Paths::node() m_rect.setHeight(100); QPainterPath shape; - shape.addRoundRect(m_rect, 25); + shape.addRoundedRect(m_rect, 25, Qt::RelativeSize); const int conWidth = 10; const int xOffset = 7; diff --git a/tests/auto/gui/text/qfont/tst_qfont.cpp b/tests/auto/gui/text/qfont/tst_qfont.cpp index 901284e131..96f3b1c1d7 100644 --- a/tests/auto/gui/text/qfont/tst_qfont.cpp +++ b/tests/auto/gui/text/qfont/tst_qfont.cpp @@ -58,7 +58,9 @@ private slots: void insertAndRemoveSubstitutions(); void serialize_data(); void serialize(); +#if QT_DEPRECATED_SINCE(5, 13) void lastResortFont(); +#endif void styleName(); void defaultFamily_data(); void defaultFamily(); @@ -484,6 +486,7 @@ void tst_QFont::serialize() } } +#if QT_DEPRECATED_SINCE(5, 13) // QFont::lastResortFont() may abort with qFatal() on QWS/QPA // if absolutely no font is found. Just as ducumented for QFont::lastResortFont(). // This happens on our CI machines which run QWS autotests. @@ -494,6 +497,7 @@ void tst_QFont::lastResortFont() QFont font; QVERIFY(!font.lastResortFont().isEmpty()); } +#endif void tst_QFont::styleName() { diff --git a/tests/auto/gui/text/qtexttable/qtexttable.pro b/tests/auto/gui/text/qtexttable/qtexttable.pro index 2faadfcb0d..73e94d5735 100644 --- a/tests/auto/gui/text/qtexttable/qtexttable.pro +++ b/tests/auto/gui/text/qtexttable/qtexttable.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qtexttable -QT += testlib +QT += testlib gui-private qtHaveModule(widgets): QT += widgets SOURCES += tst_qtexttable.cpp diff --git a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp index 22f00c677d..f21b969aa7 100644 --- a/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp +++ b/tests/auto/gui/text/qtexttable/tst_qtexttable.cpp @@ -44,6 +44,7 @@ #include #include #endif +#include typedef QList IntList; @@ -91,7 +92,7 @@ private slots: void QTBUG11282_insertBeforeMergedEnding(); #endif void QTBUG22011_insertBeforeRowSpan(); -#ifndef QT_NO_PRINTER +#if !defined(QT_NO_PRINTER) && defined(QT_BUILD_INTERNAL) void QTBUG31330_renderBackground(); #endif @@ -1025,7 +1026,7 @@ void tst_QTextTable::QTBUG22011_insertBeforeRowSpan() QCOMPARE(table->columns(), 6); } -#ifndef QT_NO_PRINTER +#if !defined(QT_NO_PRINTER) && defined(QT_BUILD_INTERNAL) namespace { class QTBUG31330_PaintDevice : public QPagedPaintDevice { @@ -1065,11 +1066,46 @@ public: {} }; + class QDummyPagedPaintDevicePrivate : public QPagedPaintDevicePrivate + { + bool setPageLayout(const QPageLayout &newPageLayout) override + { + m_pageLayout = newPageLayout; + return m_pageLayout.isEquivalentTo(newPageLayout); + } + + bool setPageSize(const QPageSize &pageSize) override + { + m_pageLayout.setPageSize(pageSize); + return m_pageLayout.pageSize().isEquivalentTo(pageSize); + } + + bool setPageOrientation(QPageLayout::Orientation orientation) override + { + m_pageLayout.setOrientation(orientation); + return m_pageLayout.orientation() == orientation; + } + + bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) override + { + m_pageLayout.setUnits(units); + m_pageLayout.setMargins(margins); + return m_pageLayout.margins() == margins && m_pageLayout.units() == units; + } + + QPageLayout pageLayout() const override + { + return m_pageLayout; + } + + QPageLayout m_pageLayout; + }; + int pages; QPaintEngine* engine; QTBUG31330_PaintDevice(QPaintEngine* engine) - : pages(1), engine(engine) + : QPagedPaintDevice(new QDummyPagedPaintDevicePrivate), pages(1), engine(engine) { QPageLayout layout = pageLayout(); layout.setUnits(QPageLayout::Point); diff --git a/tests/auto/gui/util/qdesktopservices/tst_qdesktopservices.cpp b/tests/auto/gui/util/qdesktopservices/tst_qdesktopservices.cpp index add23d46cf..4d95345de9 100644 --- a/tests/auto/gui/util/qdesktopservices/tst_qdesktopservices.cpp +++ b/tests/auto/gui/util/qdesktopservices/tst_qdesktopservices.cpp @@ -39,7 +39,9 @@ class tst_qdesktopservices : public QObject private slots: void openUrl(); void handlers(); +#if QT_DEPRECATED_SINCE(5, 0) void testDataLocation(); +#endif }; void tst_qdesktopservices::openUrl() @@ -89,6 +91,7 @@ void tst_qdesktopservices::handlers() #define Q_XDG_PLATFORM #endif +#if QT_DEPRECATED_SINCE(5, 0) void tst_qdesktopservices::testDataLocation() { // This is the one point where QDesktopServices and QStandardPaths differ. @@ -115,6 +118,7 @@ void tst_qdesktopservices::testDataLocation() #endif } } +#endif QTEST_MAIN(tst_qdesktopservices) diff --git a/tests/auto/other/lancelot/paintcommands.cpp b/tests/auto/other/lancelot/paintcommands.cpp index 8a2934049e..dc71253f3e 100644 --- a/tests/auto/other/lancelot/paintcommands.cpp +++ b/tests/auto/other/lancelot/paintcommands.cpp @@ -1202,7 +1202,7 @@ void PaintCommands::command_drawRoundRect(QRegularExpressionMatch re) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED - m_painter->drawRoundRect(x, y, w, h, xs, ys); + m_painter->drawRoundedRect(x, y, w, h, xs, ys, Qt::RelativeSize); QT_WARNING_POP } diff --git a/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp index 85b42e54fe..d3477be986 100644 --- a/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicswidget/tst_qgraphicswidget.cpp @@ -2905,7 +2905,7 @@ public: Q_UNUSED(widget); qreal w = rect().width(); QRectF box(0, 0, w, 2400/w); - painter->drawRoundRect(box); + painter->drawRoundedRect(box, 25, 25, Qt::RelativeSize); painter->drawLine(box.topLeft(), box.bottomRight()); painter->drawLine(box.bottomLeft(), box.topRight()); } diff --git a/tests/benchmarks/gui/image/qpixmapcache/tst_qpixmapcache.cpp b/tests/benchmarks/gui/image/qpixmapcache/tst_qpixmapcache.cpp index d4be85b5ad..2ded426cdd 100644 --- a/tests/benchmarks/gui/image/qpixmapcache/tst_qpixmapcache.cpp +++ b/tests/benchmarks/gui/image/qpixmapcache/tst_qpixmapcache.cpp @@ -106,7 +106,7 @@ void tst_QPixmapCache::find() if (cacheType) { QBENCHMARK { for (int i = 0 ; i <= 10000 ; i++) - QPixmapCache::find(QString::asprintf("my-key-%d", i), p); + QPixmapCache::find(QString::asprintf("my-key-%d", i), &p); } } else { QBENCHMARK { @@ -155,7 +155,7 @@ void tst_QPixmapCache::styleUseCaseComplexKey() QPixmapCache::insert(QString::asprintf("%s-%d-%d-%d-%d-%d-%d", QString("my-progressbar-%1").arg(i).toLatin1().constData(), 5, 3, 0, 358, 100, 200), p); for (int i = 0 ; i <= 10000 ; i++) - QPixmapCache::find(QString::asprintf("%s-%d-%d-%d-%d-%d-%d", QString("my-progressbar-%1").arg(i).toLatin1().constData(), 5, 3, 0, 358, 100, 200), p); + QPixmapCache::find(QString::asprintf("%s-%d-%d-%d-%d-%d-%d", QString("my-progressbar-%1").arg(i).toLatin1().constData(), 5, 3, 0, 358, 100, 200), &p); } } else { QHash hash; diff --git a/tests/benchmarks/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index b15aad04cd..e0c5a7f683 100644 --- a/tests/benchmarks/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/benchmarks/widgets/graphicsview/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -60,7 +60,7 @@ public: { Q_UNUSED(option); Q_UNUSED(widget); - painter->drawRoundRect(rect()); + painter->drawRoundedRect(rect(), 25, 25, Qt::RelativeSize); painter->drawLine(rect().topLeft(), rect().bottomRight()); painter->drawLine(rect().bottomLeft(), rect().topRight()); } diff --git a/tests/benchmarks/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp index 5c97d7f738..caf5455a80 100644 --- a/tests/benchmarks/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp +++ b/tests/benchmarks/widgets/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp @@ -53,7 +53,7 @@ public: { Q_UNUSED(option); Q_UNUSED(widget); - painter->drawRoundRect(rect()); + painter->drawRoundedRect(rect(), 25, 25, Qt::RelativeSize); painter->drawLine(rect().topLeft(), rect().bottomRight()); painter->drawLine(rect().bottomLeft(), rect().topRight()); } diff --git a/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chip.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chip.cpp index cf82282bfe..21eb622f15 100644 --- a/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chip.cpp +++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chip.cpp @@ -57,9 +57,9 @@ void Chip::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid { Q_UNUSED(widget); - QColor fillColor = (option->state & QStyle::State_Selected) ? color.dark(150) : color; + QColor fillColor = (option->state & QStyle::State_Selected) ? color.darker(150) : color; if (option->state & QStyle::State_MouseOver) - fillColor = fillColor.light(125); + fillColor = fillColor.lighter(125); if (option->levelOfDetail < 0.2) { if (option->levelOfDetail < 0.125) { @@ -82,7 +82,7 @@ void Chip::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid pen.setWidth(width); QBrush b = painter->brush(); - painter->setBrush(QBrush(fillColor.dark(option->state & QStyle::State_Sunken ? 120 : 100))); + painter->setBrush(QBrush(fillColor.darker(option->state & QStyle::State_Sunken ? 120 : 100))); painter->drawRect(QRect(14, 14, 79, 39)); painter->setBrush(b); diff --git a/tests/manual/qgraphicslayout/flicker/window.h b/tests/manual/qgraphicslayout/flicker/window.h index 22a53585d1..3e7bc61731 100644 --- a/tests/manual/qgraphicslayout/flicker/window.h +++ b/tests/manual/qgraphicslayout/flicker/window.h @@ -107,7 +107,7 @@ public: Q_UNUSED(option); Q_UNUSED(widget); painter->setBrush(m_brush); - painter->drawRoundRect(rect()); + painter->drawRoundedRect(rect(), Qt::RelativeSize); painter->drawLine(rect().topLeft(), rect().bottomRight()); painter->drawLine(rect().bottomLeft(), rect().topRight()); } From eaf2e6daf6cba6a479d102f3d904c389ca2294e3 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 13 Jul 2019 00:21:42 +0200 Subject: [PATCH 096/264] QFilesystemEngine: fix unused variable warning-turned-error on WASM ... and, presumably, Integrity. Change-Id: I54d35fd11b7df139022e2575c29b2d832f80f761 Reviewed-by: Thiago Macieira --- src/corelib/io/qfilesystemengine_unix.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 066a7c3f01..74865fe31f 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -822,6 +822,8 @@ QString QFileSystemEngine::resolveUserName(uint userId) #endif if (pw) return QFile::decodeName(QByteArray(pw->pw_name)); +#else // Integrity || WASM + Q_UNUSED(userId); #endif return QString(); } @@ -859,6 +861,8 @@ QString QFileSystemEngine::resolveGroupName(uint groupId) #endif if (gr) return QFile::decodeName(QByteArray(gr->gr_name)); +#else // Integrity || WASM + Q_UNUSED(groupId); #endif return QString(); } From 319e0f097d125dfcaf3933e57bc650d112170035 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 13 Jul 2019 14:27:49 +0200 Subject: [PATCH 097/264] QNativeSocketEngine: disable sign-compare warning-turned-error on Clang On the WASM platform, the macro CMDG_NEXTHDR, which is not under our control, emits a warning about comparing ulong and long with each other, which -Werror turns into an error: qnativesocketengine_unix.cpp:1004:24: error: comparison of integers of different signs: 'unsigned long' and 'long' [-Werror,-Wsign-compare] cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { ^~~~~~~~~~~~~~~~~~~~~~~~~~ emsdk/emscripten/1.38.30/system/include/libc/sys/socket.h:286:44: note: expanded from macro 'CMSG_NXTHDR' __CMSG_LEN(cmsg) + sizeof(struct cmsghdr) >= __MHDR_END(mhdr) - (unsigned char *)(cmsg) \ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Fix by locally disabling the warning. Change-Id: Ia2ed4318b2ef679b84ac8544835d1e383568ccac Reviewed-by: Thiago Macieira --- src/network/socket/qnativesocketengine_unix.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 24c17124dc..3ca586e247 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -1000,8 +1000,11 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxS // parse the ancillary data struct cmsghdr *cmsgptr; + QT_WARNING_PUSH + QT_WARNING_DISABLE_CLANG("-Wsign-compare") for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) { + QT_WARNING_POP if (cmsgptr->cmsg_level == IPPROTO_IPV6 && cmsgptr->cmsg_type == IPV6_PKTINFO && cmsgptr->cmsg_len >= CMSG_LEN(sizeof(in6_pktinfo))) { in6_pktinfo *info = reinterpret_cast(CMSG_DATA(cmsgptr)); From 944c5f40b3ca48f89456abeb821b3fe7ba6babf4 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 13 Jul 2019 00:22:54 +0200 Subject: [PATCH 098/264] QAbstractMetaCallEvent: fix compilation with out feature.thread on Clang Clang warns that the private field semaphore_ is unused, and is correct, of course. Change-Id: Ic1372cedd3f4b2facca9f6f6be398d26f406b379 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/kernel/qobject_p.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 9cf1bfed08..95ffc1b2e8 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -486,8 +486,11 @@ class Q_CORE_EXPORT QAbstractMetaCallEvent : public QEvent { public: QAbstractMetaCallEvent(const QObject *sender, int signalId, QSemaphore *semaphore = nullptr) - : QEvent(MetaCall), signalId_(signalId), sender_(sender), semaphore_(semaphore) - {} + : QEvent(MetaCall), signalId_(signalId), sender_(sender) +#if QT_CONFIG(thread) + , semaphore_(semaphore) +#endif + { Q_UNUSED(semaphore); } ~QAbstractMetaCallEvent(); virtual void placeMetaCall(QObject *object) = 0; @@ -498,7 +501,9 @@ public: private: int signalId_; const QObject *sender_; +#if QT_CONFIG(thread) QSemaphore *semaphore_; +#endif }; class Q_CORE_EXPORT QMetaCallEvent : public QAbstractMetaCallEvent From 205824103eb974f59a92a3d8f231f5b189176939 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 5 Jul 2019 17:36:01 +0200 Subject: [PATCH 099/264] QVarLengthArray: optimize pop_back() Don't call realloc() with all its machinery when we know exactly what to do: destroy the last element and decrease the size by one. Extend the test, removing the unused Foo class for a new Tracker one. Change-Id: I568eef4f6335669689fb16fd23af92cb4d6464bd Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qvarlengtharray.h | 4 +- .../qvarlengtharray/tst_qvarlengtharray.cpp | 37 ++++++++++++++----- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index ba65ae7ef2..2f62526076 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -112,7 +112,9 @@ public: inline void removeLast() { Q_ASSERT(s > 0); - realloc(s - 1, a); + if (QTypeInfo::isComplex) + ptr[s - 1].~T(); + --s; } inline int size() const { return s; } inline int count() const { return s; } diff --git a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp index 070c25368b..3d90644aa3 100644 --- a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp +++ b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp @@ -64,21 +64,21 @@ private: void initializeList(); }; -int fooCtor = 0; -int fooDtor = 0; - -struct Foo +struct Tracker { - int *p; + static int count; + Tracker() { ++count; } + Tracker(const Tracker &) { ++count; } + Tracker(Tracker &&) { ++count; } - Foo() { p = new int; ++fooCtor; } - Foo(const Foo &/*other*/) { p = new int; ++fooCtor; } + Tracker &operator=(const Tracker &) = default; + Tracker &operator=(Tracker &&) = default; - void operator=(const Foo & /* other */) { } - - ~Foo() { delete p; ++fooDtor; } + ~Tracker() { --count; } }; +int Tracker::count = 0; + void tst_QVarLengthArray::append() { QVarLengthArray v; @@ -130,6 +130,23 @@ void tst_QVarLengthArray::removeLast() v.removeLast(); QCOMPARE(v.size(), 2); } + + { + Tracker t; + QCOMPARE(Tracker::count, 1); + QVarLengthArray v; + v.append(t); + v.append({}); + QCOMPARE(Tracker::count, 3); + v.removeLast(); + QCOMPARE(Tracker::count, 2); + v.append(t); + v.append({}); + QCOMPARE(Tracker::count, 4); + v.removeLast(); + QCOMPARE(Tracker::count, 3); + } + QCOMPARE(Tracker::count, 0); } void tst_QVarLengthArray::oldTests() From aa698bc3c45a7269ff17b8e7cd068e4ef078520d Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Mon, 15 Jul 2019 02:20:56 +0900 Subject: [PATCH 100/264] Fix qdoublescanprint_p.h path in corelib The qdoublescanprint_p.h header moved from tools/ to text/ when text/ was introduced. Amends a9aa206b7b8ac4e69f8c46233b4080e00e845ff5. Change-Id: Ia7167fc3c4cdb05d4f2e56c0a0427a80e3cee362 Reviewed-by: Marc Mutz Reviewed-by: Volker Hilsheimer --- src/corelib/text/text.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/text/text.pri b/src/corelib/text/text.pri index e279679655..25e281f37a 100644 --- a/src/corelib/text/text.pri +++ b/src/corelib/text/text.pri @@ -9,7 +9,7 @@ HEADERS += \ text/qchar.h \ text/qcollator.h \ text/qcollator_p.h \ - tools/qdoublescanprint_p.h \ + text/qdoublescanprint_p.h \ text/qlocale.h \ text/qlocale_p.h \ text/qlocale_tools_p.h \ From 72d9222f7bda744f80d3602d3bfe5769ed1f19a8 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 13 Jul 2019 10:33:31 +0200 Subject: [PATCH 101/264] QWasmFontDatabase: replace QStringList with a C array of strings The content is static, so a dynamic container is overkill. Use a C array. Don't make it static, as that creates more problems than is solves (static initialization). Change-Id: I07534c3336efbb6bbc19bfa1b8dad0c578d4e274 Reviewed-by: Volker Hilsheimer Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qwasmfontdatabase.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmfontdatabase.cpp b/src/plugins/platforms/wasm/qwasmfontdatabase.cpp index dc6bb5847e..53e875ead6 100644 --- a/src/plugins/platforms/wasm/qwasmfontdatabase.cpp +++ b/src/plugins/platforms/wasm/qwasmfontdatabase.cpp @@ -38,10 +38,13 @@ void QWasmFontDatabase::populateFontDatabase() // Load font file from resources. Currently // all fonts needs to be bundled with the nexe // as Qt resources. - QStringList fontFileNames = QStringList() << QStringLiteral(":/fonts/DejaVuSansMono.ttf") - << QStringLiteral(":/fonts/Vera.ttf") - << QStringLiteral(":/fonts/DejaVuSans.ttf"); - foreach (const QString &fontFileName, fontFileNames) { + + const QString fontFileNames[] = { + QStringLiteral(":/fonts/DejaVuSansMono.ttf"), + QStringLiteral(":/fonts/Vera.ttf"), + QStringLiteral(":/fonts/DejaVuSans.ttf"), + }; + for (const QString &fontFileName : fontFileNames) { QFile theFont(fontFileName); if (!theFont.open(QIODevice::ReadOnly)) break; From 8155d0693f596c6b73d0acd977d5077dd7a6e6ea Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 13 Jul 2019 14:31:36 +0200 Subject: [PATCH 102/264] Eradicate Q_FOREACH in the WASM plugin and mark the plugin free of them The first one is trivially correct: it clearly doesn't modify the container under iteration. The second is a bit more subtle, because drawWindow() could be expected to call a paintEvent and this could theoretically lead to lowering, closing, or opening of a window. But this function just ends up blit()ting, so it doesn't call into user code. Change-Id: Id15e0102e9c8aa12516af27d771104e9993c48a1 Reviewed-by: Volker Hilsheimer Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qwasmcompositor.cpp | 4 ++-- src/plugins/platforms/wasm/wasm.pro | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp index 6d211667be..a810880c43 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.cpp +++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp @@ -681,7 +681,7 @@ void QWasmCompositor::frame() QWasmWindow *someWindow = nullptr; - foreach (QWasmWindow *window, m_windowStack) { + for (QWasmWindow *window : qAsConst(m_windowStack)) { if (window->window()->surfaceClass() == QSurface::Window && qt_window_private(static_cast(window->window()))->receivedExpose) { someWindow = window; @@ -715,7 +715,7 @@ void QWasmCompositor::frame() m_blitter->bind(); m_blitter->setRedBlueSwizzle(true); - foreach (QWasmWindow *window, m_windowStack) { + for (QWasmWindow *window : qAsConst(m_windowStack)) { QWasmCompositedWindow &compositedWindow = m_compositedWindows[window]; if (!compositedWindow.visible) diff --git a/src/plugins/platforms/wasm/wasm.pro b/src/plugins/platforms/wasm/wasm.pro index c28df8f893..f8c8175525 100644 --- a/src/plugins/platforms/wasm/wasm.pro +++ b/src/plugins/platforms/wasm/wasm.pro @@ -7,6 +7,8 @@ QT += \ # Avoid X11 header collision, use generic EGL native types DEFINES += QT_EGL_NO_X11 +DEFINES += QT_NO_FOREACH + SOURCES = \ main.cpp \ qwasmintegration.cpp \ From 0ca7c0a5757a496af24d621ce54a3c93f24be976 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 18 Jun 2019 20:11:18 +0200 Subject: [PATCH 103/264] QMake: be less laissez-faire with implicit conversions to QChar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QChar currently is convertible from nearly every integral type. This is bad code hygiene and should be fixed come Qt 6. The present patch is the result of compile fixes from marking these constructors explicit. Amends 60ca2f5f7c38178cfe62d3dbe1b8dacfe43cbac9. Change-Id: I06887104d42f8327eb6196afcde5f942a74a6a78 Reviewed-by: Friedemann Kleint Reviewed-by: Mårten Nordheim --- qmake/library/proitems.cpp | 4 ++-- qmake/library/qmakeevaluator.cpp | 4 ++-- qmake/library/qmakeparser.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/qmake/library/proitems.cpp b/qmake/library/proitems.cpp index 41bed69f00..9330c2b1bf 100644 --- a/qmake/library/proitems.cpp +++ b/qmake/library/proitems.cpp @@ -238,7 +238,7 @@ ProString &ProString::append(const ProString &other, bool *pending) QChar *ptr; if (pending && !*pending) { ptr = prepareExtend(1 + other.m_length, 0, m_length); - *ptr++ = 32; + *ptr++ = QLatin1Char(' '); } else { ptr = prepareExtend(other.m_length, 0, m_length); } @@ -276,7 +276,7 @@ ProString &ProString::append(const ProStringList &other, bool *pending, bool ski QChar *ptr = prepareExtend(totalLength, 0, m_length); for (int i = startIdx; i < sz; ++i) { if (putSpace) - *ptr++ = 32; + *ptr++ = QLatin1Char(' '); else putSpace = true; const ProString &str = other.at(i); diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index ba617932ce..e15a4bfc50 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -1583,8 +1583,8 @@ void QMakeEvaluator::updateFeaturePaths() } for (int i = 0; i < feature_roots.count(); ++i) - if (!feature_roots.at(i).endsWith((ushort)'/')) - feature_roots[i].append((ushort)'/'); + if (!feature_roots.at(i).endsWith(QLatin1Char('/'))) + feature_roots[i].append(QLatin1Char('/')); feature_roots.removeDuplicates(); diff --git a/qmake/library/qmakeparser.cpp b/qmake/library/qmakeparser.cpp index 4c8360b459..ffe90ebda7 100644 --- a/qmake/library/qmakeparser.cpp +++ b/qmake/library/qmakeparser.cpp @@ -621,7 +621,7 @@ void QMakeParser::read(ProFile *pro, const QStringRef &in, int line, SubGrammar if (c != term) { parseError(fL1S("Missing %1 terminator [found %2]") .arg(QChar(term)) - .arg(c ? QString(c) : QString::fromLatin1("end-of-line"))); + .arg(c ? QString(QChar(c)) : QString::fromLatin1("end-of-line"))); m_inError = true; // Just parse on, as if there was a terminator ... } else { From efa183309e69f317189ef06fb1f13b60da9d7c63 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 11 Jul 2019 16:59:03 +0200 Subject: [PATCH 104/264] QMake: fix GCC 9 -Wdeprecated-copy warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not visible in QMake, because of too old C++ standard used to compile it, but in the qttools copy. Fix here, as the authorative source, first. Change-Id: I2552eccfaab2cef0863686dcd888f2a5f25ca29f Reviewed-by: Friedemann Kleint Reviewed-by: Mårten Nordheim --- qmake/library/proitems.h | 1 + qmake/library/qmakeparser.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h index cc65421556..ff7c8b92f7 100644 --- a/qmake/library/proitems.h +++ b/qmake/library/proitems.h @@ -68,6 +68,7 @@ class ProString { public: ProString(); ProString(const ProString &other); + ProString &operator=(const ProString &) = default; PROITEM_EXPLICIT ProString(const QString &str); PROITEM_EXPLICIT ProString(const QStringRef &str); PROITEM_EXPLICIT ProString(const char *str); diff --git a/qmake/library/qmakeparser.h b/qmake/library/qmakeparser.h index 7b96d4e88f..c8c5c7718e 100644 --- a/qmake/library/qmakeparser.h +++ b/qmake/library/qmakeparser.h @@ -111,7 +111,6 @@ private: struct BlockScope { BlockScope() : start(nullptr), braceLevel(0), special(false), inBranch(false), nest(NestNone) {} - BlockScope(const BlockScope &other) { *this = other; } ushort *start; // Where this block started; store length here int braceLevel; // Nesting of braces in scope bool special; // Single-line conditionals inside loops, etc. cannot have else branches From a7383b4b6dde54569e6fdfa0888e474a37416a51 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 13 Jul 2019 22:52:30 +0200 Subject: [PATCH 105/264] QNetworkRequest: make the default ctor implicit As in QVarLengthArray (c34242c679aaea6ee1badf6c1e5f274f925f5f50), this will probably bite someone someday, so fix it before there's a bug report. Use ctor delegation to keep code size increase small. There's also the benefit that default-constructing a QNetworkRequest now no longer creates an expensive QUrl object just to destroy it unused again. Add an auto-test. Change-Id: I5ceb5402ca3946048d695244d1b1c36564a1e80a Reviewed-by: Timur Pocheptsov --- src/network/access/qnetworkrequest.cpp | 13 ++++++++++++- src/network/access/qnetworkrequest.h | 3 ++- .../access/qnetworkrequest/tst_qnetworkrequest.cpp | 7 +++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index ba36c75419..c82eb8fe9f 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -467,6 +467,17 @@ public: QString peerVerifyName; }; +/*! + Constructs a QNetworkRequest object with no URL to be requested. + Use setUrl() to set one. + + \sa url(), setUrl() +*/ +QNetworkRequest::QNetworkRequest() + : d(new QNetworkRequestPrivate) +{ +} + /*! Constructs a QNetworkRequest object with \a url as the URL to be requested. @@ -474,7 +485,7 @@ public: \sa url(), setUrl() */ QNetworkRequest::QNetworkRequest(const QUrl &url) - : d(new QNetworkRequestPrivate) + : QNetworkRequest() { d->url = url; } diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h index 846ead1592..8ad4ab41c0 100644 --- a/src/network/access/qnetworkrequest.h +++ b/src/network/access/qnetworkrequest.h @@ -128,7 +128,8 @@ public: }; - explicit QNetworkRequest(const QUrl &url = QUrl()); + QNetworkRequest(); + explicit QNetworkRequest(const QUrl &url); QNetworkRequest(const QNetworkRequest &other); ~QNetworkRequest(); QNetworkRequest &operator=(QNetworkRequest &&other) noexcept { swap(other); return *this; } diff --git a/tests/auto/network/access/qnetworkrequest/tst_qnetworkrequest.cpp b/tests/auto/network/access/qnetworkrequest/tst_qnetworkrequest.cpp index 7a3def410a..6637be0174 100644 --- a/tests/auto/network/access/qnetworkrequest/tst_qnetworkrequest.cpp +++ b/tests/auto/network/access/qnetworkrequest/tst_qnetworkrequest.cpp @@ -41,6 +41,7 @@ class tst_QNetworkRequest: public QObject private slots: void ctor_data(); void ctor(); + void implicitDefaultCtor(); void setUrl_data(); void setUrl(); void setRawHeader_data(); @@ -78,6 +79,12 @@ void tst_QNetworkRequest::ctor() } } +void tst_QNetworkRequest::implicitDefaultCtor() +{ + QNetworkRequest r = {}; + Q_UNUSED(r); +} + void tst_QNetworkRequest::setUrl_data() { ctor_data(); From 2e5b8032a27f678b1f514c7402fe2a808e7fcdcc Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 11 Jul 2019 21:52:01 +0200 Subject: [PATCH 106/264] Optimize QInotifyFileSystemWatcherEngine::getPathFromID() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code basically wants to get the last element of equal_range(id). The problem is that backwards iteration on QHash is very expensive, because it's implemented as forward search with wrap-around at bucket end. So it was implementing its own equal_range with look-ahead. The problem is that it compared each key in the equal_range twice: once in the if, and once more in the following while iteration. I expect to see this kind of algorithm more as we move away from the fake bidirectionalism of QHash, so I decided to implement it in a generic way. We can copy it somewhere else when we find more users. Change-Id: I7951652107ab897f6a456035f02e0339835e078d Reviewed-by: Volker Hilsheimer Reviewed-by: Friedemann Kleint Reviewed-by: Mårten Nordheim --- src/corelib/io/qfilesystemwatcher_inotify.cpp | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp index 5fb5685f42..ca1f6cc359 100644 --- a/src/corelib/io/qfilesystemwatcher_inotify.cpp +++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp @@ -422,16 +422,27 @@ void QInotifyFileSystemWatcherEngine::readFromInotify() } } +template +typename Hash::const_iterator +find_last_in_equal_range(const Hash &c, const Key &key) +{ + // find c.equal_range(key).second - 1 without backwards iteration: + auto i = c.find(key); + const auto end = c.cend(); + if (i == end) + return end; + decltype(i) prev; + do { + prev = i; + ++i; + } while (i != end && i.key() == key); + return prev; +} + QString QInotifyFileSystemWatcherEngine::getPathFromID(int id) const { - QHash::const_iterator i = idToPath.find(id); - while (i != idToPath.constEnd() && i.key() == id) { - if ((i + 1) == idToPath.constEnd() || (i + 1).key() != id) { - return i.value(); - } - ++i; - } - return QString(); + auto i = find_last_in_equal_range(idToPath, id); + return i == idToPath.cend() ? QString() : i.value() ; } QT_END_NAMESPACE From 2a15ec72c0d088a5dca344df163fac73c24caa1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Fri, 12 Jul 2019 10:26:35 +0200 Subject: [PATCH 107/264] QHttpSocketEngine: The 'Connection' options are case insensitive As noted in RFC7230 Section 6.1 the 'Connection' options are case insensitive. https://tools.ietf.org/html/rfc7230#section-6.1 Change-Id: I80b98d82eaa5572d38a6c3f99383bc059ec91c54 Fixes: QTBUG-76990 Reviewed-by: Timur Pocheptsov --- src/network/socket/qhttpsocketengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp index 9427c3b00d..4cfc8e3555 100644 --- a/src/network/socket/qhttpsocketengine.cpp +++ b/src/network/socket/qhttpsocketengine.cpp @@ -627,7 +627,7 @@ void QHttpSocketEngine::slotSocketReadNotification() // from http spec is also allowed. if (proxyConnectionHeader.isEmpty()) proxyConnectionHeader = d->reply->headerField("Connection"); - if (proxyConnectionHeader.compare("close", Qt::CaseSensitive) == 0) { + if (proxyConnectionHeader.compare("close", Qt::CaseInsensitive) == 0) { willClose = true; } else if (proxyConnectionHeader.compare("keep-alive", Qt::CaseInsensitive) == 0) { willClose = false; From 7a61cb46e69a3997e935d46f0c01d5cd36946245 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 15 Jul 2019 16:11:31 +0200 Subject: [PATCH 108/264] tst_http2::flowControlServerSide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix the bloody test for good - the idea to have a shared QNAM (shared by test cases in this test) was somewhat wrong to start with. Fixes: QTBUG-77053 Change-Id: I5755e96ec988e2dd546f527f3f902fc43914b0b7 Reviewed-by: Mårten Nordheim --- tests/auto/network/access/http2/tst_http2.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp index 76eb431af6..579eb89c0a 100644 --- a/tests/auto/network/access/http2/tst_http2.cpp +++ b/tests/auto/network/access/http2/tst_http2.cpp @@ -70,6 +70,8 @@ class tst_Http2 : public QObject public: tst_Http2(); ~tst_Http2(); +public slots: + void init(); private slots: // Tests: void singleRequest_data(); @@ -173,6 +175,11 @@ tst_Http2::~tst_Http2() } } +void tst_Http2::init() +{ + manager.clearConnectionCache(); +} + void tst_Http2::singleRequest_data() { QTest::addColumn("h2Attribute"); From c5d6b263c204cb09db2be36826e19acb03dc24fb Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 14 Jul 2019 10:13:41 +0200 Subject: [PATCH 109/264] QProcessEnvironment: simplify locking The mutex is only protecting 'nameMap'. Proof: it's only defined on platforms on which there is a 'nameMap'. Also, nothing else is mutable, so no lazy init going on here. So, drop all the mutex protection, except where we access 'nameMap', and draw the mutex as close as possible to the nameMap uses, iow: copy ctor, prepareName() and nameToString(). As a consequence, the old (Ordered)MutexLocker class only needs to be defined on Unix. Change-Id: Ic969313bc48ad7ebf24c5dca7fd48359956b048d Reviewed-by: Thiago Macieira --- src/corelib/io/qprocess.cpp | 7 +---- src/corelib/io/qprocess_p.h | 52 ++++++++++++++------------------ src/corelib/io/qprocess_unix.cpp | 2 -- 3 files changed, 23 insertions(+), 38 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 0b964e6a21..35ca2542f7 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -202,6 +202,7 @@ void QProcessEnvironmentPrivate::insert(const QProcessEnvironmentPrivate &other) vars.insert(it.key(), it.value()); #ifdef Q_OS_UNIX + const OrderedNameMapMutexLocker locker(this, &other); auto nit = other.nameMap.constBegin(); const auto nend = other.nameMap.constEnd(); for ( ; nit != nend; ++nit) @@ -275,7 +276,6 @@ bool QProcessEnvironment::operator==(const QProcessEnvironment &other) const return true; if (d) { if (other.d) { - QProcessEnvironmentPrivate::OrderedMutexLocker locker(d, other.d); return d->vars == other.d->vars; } else { return isEmpty(); @@ -322,7 +322,6 @@ bool QProcessEnvironment::contains(const QString &name) const { if (!d) return false; - QProcessEnvironmentPrivate::MutexLocker locker(d); return d->vars.contains(d->prepareName(name)); } @@ -373,7 +372,6 @@ QString QProcessEnvironment::value(const QString &name, const QString &defaultVa if (!d) return defaultValue; - QProcessEnvironmentPrivate::MutexLocker locker(d); const auto it = d->vars.constFind(d->prepareName(name)); if (it == d->vars.constEnd()) return defaultValue; @@ -398,7 +396,6 @@ QStringList QProcessEnvironment::toStringList() const { if (!d) return QStringList(); - QProcessEnvironmentPrivate::MutexLocker locker(d); return d->toList(); } @@ -412,7 +409,6 @@ QStringList QProcessEnvironment::keys() const { if (!d) return QStringList(); - QProcessEnvironmentPrivate::MutexLocker locker(d); return d->keys(); } @@ -429,7 +425,6 @@ void QProcessEnvironment::insert(const QProcessEnvironment &e) return; // our re-impl of detach() detaches from null - QProcessEnvironmentPrivate::MutexLocker locker(e.d); d->insert(*e.d); } diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index d02e87837c..2587530c09 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -146,16 +146,22 @@ public: inline QString nameToString(const Key &name) const { return name; } inline Value prepareValue(const QString &value) const { return value; } inline QString valueToString(const Value &value) const { return value; } - struct MutexLocker { - MutexLocker(const QProcessEnvironmentPrivate *) {} - }; - struct OrderedMutexLocker { - OrderedMutexLocker(const QProcessEnvironmentPrivate *, - const QProcessEnvironmentPrivate *) {} - }; #else + struct NameMapMutexLocker : public QMutexLocker + { + NameMapMutexLocker(const QProcessEnvironmentPrivate *d) : QMutexLocker(&d->nameMapMutex) {} + }; + struct OrderedNameMapMutexLocker : public QOrderedMutexLocker + { + OrderedNameMapMutexLocker(const QProcessEnvironmentPrivate *d1, + const QProcessEnvironmentPrivate *d2) + : QOrderedMutexLocker(&d1->nameMapMutex, &d2->nameMapMutex) + {} + }; + inline Key prepareName(const QString &name) const { + const NameMapMutexLocker locker(this); Key &ent = nameMap[name]; if (ent.isEmpty()) ent = name.toLocal8Bit(); @@ -164,40 +170,27 @@ public: inline QString nameToString(const Key &name) const { const QString sname = QString::fromLocal8Bit(name); - nameMap[sname] = name; + { + const NameMapMutexLocker locker(this); + nameMap[sname] = name; + } return sname; } inline Value prepareValue(const QString &value) const { return Value(value); } inline QString valueToString(const Value &value) const { return value.string(); } - struct MutexLocker : public QMutexLocker - { - MutexLocker(const QProcessEnvironmentPrivate *d) : QMutexLocker(&d->mutex) {} - }; - struct OrderedMutexLocker : public QOrderedMutexLocker - { - OrderedMutexLocker(const QProcessEnvironmentPrivate *d1, - const QProcessEnvironmentPrivate *d2) : - QOrderedMutexLocker(&d1->mutex, &d2->mutex) - {} - }; - QProcessEnvironmentPrivate() : QSharedData() {} QProcessEnvironmentPrivate(const QProcessEnvironmentPrivate &other) : - QSharedData() + QSharedData(), vars(other.vars) { - // This being locked ensures that the functions that only assign - // d pointers don't need explicit locking. // We don't need to lock our own mutex, as this object is new and // consequently not shared. For the same reason, non-const methods // do not need a lock, as they detach objects (however, we need to // ensure that they really detach before using prepareName()). - MutexLocker locker(&other); - vars = other.vars; + NameMapMutexLocker locker(&other); nameMap = other.nameMap; - // We need to detach our members, so that our mutex can protect them. - // As we are being detached, they likely would be detached a moment later anyway. - vars.detach(); + // We need to detach our nameMap, so that our mutex can protect it. + // As we are being detached, it likely would be detached a moment later anyway. nameMap.detach(); } #endif @@ -208,8 +201,7 @@ public: #ifdef Q_OS_UNIX typedef QHash NameHash; mutable NameHash nameMap; - - mutable QMutex mutex; + mutable QMutex nameMapMutex; #endif static QProcessEnvironment fromList(const QStringList &list); diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 1d5b76a8a4..951fc4ccaa 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -438,7 +438,6 @@ void QProcessPrivate::startProcess() int envc = 0; char **envp = 0; if (environment.d.constData()) { - QProcessEnvironmentPrivate::MutexLocker locker(environment.d); envp = _q_dupEnvironment(environment.d.constData()->vars, &envc); } @@ -970,7 +969,6 @@ bool QProcessPrivate::startDetached(qint64 *pid) int envc = 0; char **envp = nullptr; if (environment.d.constData()) { - QProcessEnvironmentPrivate::MutexLocker locker(environment.d); envp = _q_dupEnvironment(environment.d.constData()->vars, &envc); } From 4f26f05869e0de9e1e1b3f324b666f5b44193f60 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Tue, 16 Jul 2019 08:05:05 +0200 Subject: [PATCH 110/264] Doc: Add trailing "." to all \brief commands in QLineEdit Minor housekeeping. Task-number: QTBUG-77063 Change-Id: I9c04dd4220c0c2ad2afa51f88df197f5992752ff Reviewed-by: Andy Shaw --- src/widgets/widgets/qlineedit.cpp | 32 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 7515f866fe..ac7820ac09 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -293,7 +293,7 @@ QLineEdit::~QLineEdit() /*! \property QLineEdit::text - \brief the line edit's text + \brief the line edit's text. Setting this property clears the selection, clears the undo/redo history, moves the cursor to the end of the line and resets the @@ -322,7 +322,7 @@ void QLineEdit::setText(const QString& text) \since 4.7 \property QLineEdit::placeholderText - \brief the line edit's placeholder text + \brief the line edit's placeholder text. Setting this property makes the line edit display a grayed-out placeholder text as long as the line edit is empty. @@ -354,7 +354,7 @@ void QLineEdit::setPlaceholderText(const QString& placeholderText) /*! \property QLineEdit::displayText - \brief the displayed text + \brief the displayed text. If \l echoMode is \l Normal this returns the same as text(); if \l EchoMode is \l Password or \l PasswordEchoOnEdit it returns a string of @@ -375,7 +375,7 @@ QString QLineEdit::displayText() const /*! \property QLineEdit::maxLength - \brief the maximum permitted length of the text + \brief the maximum permitted length of the text. If the text is too long, it is truncated at the limit. @@ -405,7 +405,7 @@ void QLineEdit::setMaxLength(int maxLength) /*! \property QLineEdit::frame - \brief whether the line edit draws itself with a frame + \brief whether the line edit draws itself with a frame. If enabled (the default) the line edit draws itself inside a frame, otherwise the line edit draws itself without any frame. @@ -544,7 +544,7 @@ void QLineEdit::setFrame(bool enable) /*! \property QLineEdit::echoMode - \brief the line edit's echo mode + \brief the line edit's echo mode. The echo mode determines how the text entered in the line edit is displayed (or echoed) to the user. @@ -723,7 +723,7 @@ QSize QLineEdit::minimumSizeHint() const /*! \property QLineEdit::cursorPosition - \brief the current cursor position for this line edit + \brief the current cursor position for this line edit. Setting the cursor position causes a repaint when appropriate. @@ -756,7 +756,7 @@ int QLineEdit::cursorPositionAt(const QPoint &pos) /*! \property QLineEdit::alignment - \brief the alignment of the line edit + \brief the alignment of the line edit. Both horizontal and vertical alignment is allowed here, Qt::AlignJustify will map to Qt::AlignLeft. @@ -894,7 +894,7 @@ void QLineEdit::end(bool mark) /*! \property QLineEdit::modified - \brief whether the line edit's contents has been modified by the user + \brief whether the line edit's contents has been modified by the user. The modified flag is never read by QLineEdit; it has a default value of false and is changed to true whenever the user changes the line @@ -924,7 +924,7 @@ void QLineEdit::setModified(bool modified) /*! \property QLineEdit::hasSelectedText - \brief whether there is any text selected + \brief whether there is any text selected. hasSelectedText() returns \c true if some or all of the text has been selected by the user; otherwise returns \c false. @@ -943,7 +943,7 @@ bool QLineEdit::hasSelectedText() const /*! \property QLineEdit::selectedText - \brief the selected text + \brief the selected text. If there is no selected text this property's value is an empty string. @@ -1030,7 +1030,7 @@ void QLineEdit::setSelection(int start, int length) /*! \property QLineEdit::undoAvailable - \brief whether undo is available + \brief whether undo is available. Undo becomes available once the user has modified the text in the line edit. @@ -1045,7 +1045,7 @@ bool QLineEdit::isUndoAvailable() const /*! \property QLineEdit::redoAvailable - \brief whether redo is available + \brief whether redo is available. Redo becomes available once the user has performed one or more undo operations on text in the line edit. @@ -1062,7 +1062,7 @@ bool QLineEdit::isRedoAvailable() const /*! \property QLineEdit::dragEnabled \brief whether the lineedit starts a drag if the user presses and - moves the mouse on some selected text + moves the mouse on some selected text. Dragging is disabled by default. */ @@ -1081,7 +1081,7 @@ void QLineEdit::setDragEnabled(bool b) /*! \property QLineEdit::cursorMoveStyle - \brief the movement style of cursor in this line edit + \brief the movement style of cursor in this line edit. \since 4.8 When this property is set to Qt::VisualMoveStyle, the line edit will use visual @@ -1184,7 +1184,7 @@ QMargins QLineEdit::textMargins() const /*! \property QLineEdit::inputMask - \brief The validation input mask + \brief The validation input mask. If no mask is set, inputMask() returns an empty string. From aeaf5d87ed0a41dd9f8265f9d88b34e233a89f74 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 13 Jul 2019 20:33:49 +0200 Subject: [PATCH 111/264] QAbstractItemModel: don't inherit QHash just to add elements Now that we can depend on C++11, use _WITH_ARGS and std::initializer_list. Saves ~400B in text size on optimized AMD64 GCC 9.1 Linux LTO builds. Change-Id: I37fce1c63a5f74f6dfc059febf0152ac93c8be7f Reviewed-by: David Faure --- src/corelib/itemmodels/qabstractitemmodel.cpp | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index 3e74e5a0c8..c5fb5b9fc5 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -532,21 +532,16 @@ void QAbstractItemModelPrivate::invalidatePersistentIndex(const QModelIndex &ind } } -namespace { - struct DefaultRoleNames : public QHash +using DefaultRoleNames = QHash; +Q_GLOBAL_STATIC_WITH_ARGS(DefaultRoleNames, qDefaultRoleNames, ( { - DefaultRoleNames() { - (*this)[Qt::DisplayRole] = "display"; - (*this)[Qt::DecorationRole] = "decoration"; - (*this)[Qt::EditRole] = "edit"; - (*this)[Qt::ToolTipRole] = "toolTip"; - (*this)[Qt::StatusTipRole] = "statusTip"; - (*this)[Qt::WhatsThisRole] = "whatsThis"; - } - }; -} - -Q_GLOBAL_STATIC(DefaultRoleNames, qDefaultRoleNames) + { Qt::DisplayRole, "display" }, + { Qt::DecorationRole, "decoration" }, + { Qt::EditRole, "edit" }, + { Qt::ToolTipRole, "toolTip" }, + { Qt::StatusTipRole, "statusTip" }, + { Qt::WhatsThisRole, "whatsThis" }, + })) const QHash &QAbstractItemModelPrivate::defaultRoleNames() { From c563e5b3c7f483684da0759a28393b2140541771 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 13 Jul 2019 10:29:36 +0200 Subject: [PATCH 112/264] QWasmEventTranslator: replace five QHash with constexpr C arrays The mapping is static, but a dynamic (even mutable) container was used. Fix by using C tables and liner scan, which will be just as fast or faster than a hash lookup, for the maximum of six entries of each table. Change-Id: I899d5b1428dc82cf58862f238595a266aef8279f Reviewed-by: Volker Hilsheimer Reviewed-by: Lorn Potter --- .../platforms/wasm/qwasmeventtranslator.cpp | 64 +++++++++++++++++-- .../platforms/wasm/qwasmeventtranslator.h | 36 ----------- 2 files changed, 59 insertions(+), 41 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index 3895646b89..d165ee5839 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -779,6 +779,60 @@ quint64 QWasmEventTranslator::getTimestamp() return QDeadlineTimer::current().deadlineNSecs() / 1000; } +struct KeyMapping { Qt::Key from, to; }; + +constexpr KeyMapping tildeKeyTable[] = { // ~ + { Qt::Key_A, Qt::Key_Atilde }, + { Qt::Key_N, Qt::Key_Ntilde }, + { Qt::Key_O, Qt::Key_Otilde }, +}; +constexpr KeyMapping graveKeyTable[] = { // ` + { Qt::Key_A, Qt::Key_Agrave }, + { Qt::Key_E, Qt::Key_Egrave }, + { Qt::Key_I, Qt::Key_Igrave }, + { Qt::Key_O, Qt::Key_Ograve }, + { Qt::Key_U, Qt::Key_Ugrave }, +}; +constexpr KeyMapping acuteKeyTable[] = { // ' + { Qt::Key_A, Qt::Key_Aacute }, + { Qt::Key_E, Qt::Key_Eacute }, + { Qt::Key_I, Qt::Key_Iacute }, + { Qt::Key_O, Qt::Key_Oacute }, + { Qt::Key_U, Qt::Key_Uacute }, + { Qt::Key_Y, Qt::Key_Yacute }, +}; +constexpr KeyMapping diaeresisKeyTable[] = { // umlaut ¨ + { Qt::Key_A, Qt::Key_Adiaeresis }, + { Qt::Key_E, Qt::Key_Ediaeresis }, + { Qt::Key_I, Qt::Key_Idiaeresis }, + { Qt::Key_O, Qt::Key_Odiaeresis }, + { Qt::Key_U, Qt::Key_Udiaeresis }, + { Qt::Key_Y, Qt::Key_ydiaeresis }, +}; +constexpr KeyMapping circumflexKeyTable[] = { // ^ + { Qt::Key_A, Qt::Key_Acircumflex }, + { Qt::Key_E, Qt::Key_Ecircumflex }, + { Qt::Key_I, Qt::Key_Icircumflex }, + { Qt::Key_O, Qt::Key_Ocircumflex }, + { Qt::Key_U, Qt::Key_Ucircumflex }, +}; + +static Qt::Key find_impl(const KeyMapping *first, const KeyMapping *last, Qt::Key key) noexcept +{ + while (first != last) { + if (first->from == key) + return first->to; + ++first; + } + return {}; +} + +template +static Qt::Key find(const KeyMapping (&map)[N], Qt::Key key) noexcept +{ + return find_impl(map, map + N, key); +} + Qt::Key QWasmEventTranslator::translateDeadKey(Qt::Key deadKey, Qt::Key accentBaseKey) { Qt::Key wasmKey = Qt::Key_unknown; @@ -788,25 +842,25 @@ Qt::Key QWasmEventTranslator::translateDeadKey(Qt::Key deadKey, Qt::Key accentBa #else case Qt::Key_O: // ´ Key_Dead_Grave #endif - wasmKey = graveKeyTable.value(accentBaseKey); + wasmKey = find(graveKeyTable, accentBaseKey); break; case Qt::Key_E: // ´ Key_Dead_Acute - wasmKey = acuteKeyTable.value(accentBaseKey); + wasmKey = find(acuteKeyTable, accentBaseKey); break; case Qt::Key_AsciiTilde: case Qt::Key_N:// Key_Dead_Tilde - wasmKey = tildeKeyTable.value(accentBaseKey); + wasmKey = find(tildeKeyTable, accentBaseKey); break; #ifndef Q_OS_MACOS case Qt::Key_QuoteLeft: #endif case Qt::Key_U:// ¨ Key_Dead_Diaeresis - wasmKey = diaeresisKeyTable.value(accentBaseKey); + wasmKey = find(diaeresisKeyTable, accentBaseKey); break; case Qt::Key_I:// macOS Key_Dead_Circumflex case Qt::Key_6:// linux case Qt::Key_Apostrophe:// linux - wasmKey = circumflexKeyTable.value(accentBaseKey); + wasmKey = find(circumflexKeyTable, accentBaseKey); break; break; default: diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.h b/src/plugins/platforms/wasm/qwasmeventtranslator.h index 1655b7226a..568ae00732 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.h +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.h @@ -77,42 +77,6 @@ private: Qt::Key translateDeadKey(Qt::Key deadKey, Qt::Key accentBaseKey); - QHash tildeKeyTable { // ~ - { Qt::Key_A, Qt::Key_Atilde}, - { Qt::Key_N, Qt::Key_Ntilde}, - { Qt::Key_O, Qt::Key_Otilde} - }; - QHash graveKeyTable { // ` - { Qt::Key_A, Qt::Key_Agrave}, - { Qt::Key_E, Qt::Key_Egrave}, - { Qt::Key_I, Qt::Key_Igrave}, - { Qt::Key_O, Qt::Key_Ograve}, - { Qt::Key_U, Qt::Key_Ugrave} - }; - QHash acuteKeyTable { // ' - { Qt::Key_A, Qt::Key_Aacute}, - { Qt::Key_E, Qt::Key_Eacute}, - { Qt::Key_I, Qt::Key_Iacute}, - { Qt::Key_O, Qt::Key_Oacute}, - { Qt::Key_U, Qt::Key_Uacute}, - { Qt::Key_Y, Qt::Key_Yacute} - }; - QHash diaeresisKeyTable { // umlaut ¨ - { Qt::Key_A, Qt::Key_Adiaeresis}, - { Qt::Key_E, Qt::Key_Ediaeresis}, - { Qt::Key_I, Qt::Key_Idiaeresis}, - { Qt::Key_O, Qt::Key_Odiaeresis}, - { Qt::Key_U, Qt::Key_Udiaeresis}, - { Qt::Key_Y, Qt::Key_ydiaeresis} - }; - QHash circumflexKeyTable { // ^ - { Qt::Key_A, Qt::Key_Acircumflex}, - { Qt::Key_E, Qt::Key_Ecircumflex}, - { Qt::Key_I, Qt::Key_Icircumflex}, - { Qt::Key_O, Qt::Key_Ocircumflex}, - { Qt::Key_U, Qt::Key_Ucircumflex} - }; - QMap pressedTouchIds; private: From 8b34296e6a86ce5ad9dba6ac54c84a64cec09b96 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 13 Jul 2019 09:50:16 +0200 Subject: [PATCH 113/264] Fix more implicit QAtomic <-> T conversions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These were hidden in !QT_CONFIG(thread) code. The irony! This patch does not change the semantics of the operations. It just makes the implicit operations explicit. Any fixes or optimizations are left for follow-up patches, if any. Change-Id: I014eb71745532dae2efe7963aa87321f61b1bd7a Reviewed-by: Mårten Nordheim --- src/corelib/thread/qthread.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index 280c785049..9fd1dd059d 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -851,7 +851,7 @@ Qt::HANDLE QThread::currentThreadId() noexcept QThread *QThread::currentThread() { - return QThreadData::current()->thread; + return QThreadData::current()->thread.loadAcquire(); } int QThread::idealThreadCount() noexcept @@ -883,11 +883,11 @@ QThreadData *QThreadData::current(bool createIfNecessary) if (!data && createIfNecessary) { data = new QThreadData; data->thread = new QAdoptedThread(data); - data->threadId.storeRelaxed(Qt::HANDLE(data->thread)); + data->threadId.storeRelaxed(Qt::HANDLE(data->thread.loadAcquire())); data->deref(); data->isAdopted = true; - if (!QCoreApplicationPrivate::theMainThread) - QCoreApplicationPrivate::theMainThread = data->thread.loadRelaxed(); + if (!QCoreApplicationPrivate::theMainThread.loadAcquire()) + QCoreApplicationPrivate::theMainThread.storeRelease(data->thread.loadRelaxed()); } return data; } From 05bb156aaad8b539e9b28a6c7577e48319e281ba Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 12 Jul 2019 15:28:14 +0200 Subject: [PATCH 114/264] Windows QPA: Fix emitting of QScreen's changed signals When changing the primary screen, the various changed signals of QScreen were out of order. Most notably, the wrong DPI value was emitted since QGuiApplicationPrivate::processScreenGeometryChange() checks and emits DPI and orientation as well. Rearrange the code to assign new the values and emit DPI first. Task-number: QTBUG-76902 Change-Id: If4037108391c36ab3a8bfcb9b2989d5bea41202f Reviewed-by: Oliver Wolff --- .../platforms/windows/qwindowsscreen.cpp | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index cc0f3c1a6e..4137a4bd9a 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -303,23 +303,28 @@ void QWindowsScreen::handleChanges(const QWindowsScreenData &newData) m_data.hMonitor = newData.hMonitor; } - if (m_data.geometry != newData.geometry || m_data.availableGeometry != newData.availableGeometry) { - m_data.geometry = newData.geometry; - m_data.availableGeometry = newData.availableGeometry; - QWindowSystemInterface::handleScreenGeometryChange(screen(), - newData.geometry, newData.availableGeometry); - } - if (!qFuzzyCompare(m_data.dpi.first, newData.dpi.first) - || !qFuzzyCompare(m_data.dpi.second, newData.dpi.second)) { - m_data.dpi = newData.dpi; + // QGuiApplicationPrivate::processScreenGeometryChange() checks and emits + // DPI and orientation as well, so, assign new values and emit DPI first. + const bool geometryChanged = m_data.geometry != newData.geometry + || m_data.availableGeometry != newData.availableGeometry; + const bool dpiChanged = !qFuzzyCompare(m_data.dpi.first, newData.dpi.first) + || !qFuzzyCompare(m_data.dpi.second, newData.dpi.second); + const bool orientationChanged = m_data.orientation != newData.orientation; + m_data.dpi = newData.dpi; + m_data.orientation = newData.orientation; + m_data.geometry = newData.geometry; + m_data.availableGeometry = newData.availableGeometry; + + if (dpiChanged) { QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), newData.dpi.first, newData.dpi.second); } - if (m_data.orientation != newData.orientation) { - m_data.orientation = newData.orientation; - QWindowSystemInterface::handleScreenOrientationChange(screen(), - newData.orientation); + if (orientationChanged) + QWindowSystemInterface::handleScreenOrientationChange(screen(), newData.orientation); + if (geometryChanged) { + QWindowSystemInterface::handleScreenGeometryChange(screen(), + newData.geometry, newData.availableGeometry); } } From 8abbbb4c482c32cd5342f5f8576cee8cbacc3737 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 15 Jul 2019 15:28:47 -0700 Subject: [PATCH 115/264] Fix regression causing QVector::fill w/ same size to not detach Caused by commit 01301b0b340df736dd1b0a54b3026e00b49c5ea3, which made vector.resize(vector.size()) not to detach, which was used by fill() and assumed that detaching happened. The test does not test the resize() behavior, only that fill() is not broken anymore. [ChangeLog][QtCore][QVector] Fixed a regression that caused fill() not to detach, corrupting shared copies. Fixes: QTBUG-77058 Change-Id: I6aed4df6a12e43c3ac8efffd15b1b527a8007bf3 Reviewed-by: Marc Mutz --- src/corelib/tools/qvector.h | 2 +- tests/auto/corelib/tools/qvector/tst_qvector.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 988d5a9e1b..57cf6e51ce 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -416,7 +416,7 @@ template void QVector::resize(int asize) { if (asize == d->size) - return; + return detach(); if (asize > int(d->alloc) || !isDetached()) { // there is not enough space QArrayData::AllocationOptions opt = asize > int(d->alloc) ? QArrayData::Grow : QArrayData::Default; realloc(qMax(int(d->alloc), asize), opt); diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index a7faeb5ca5..383318979d 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -250,6 +250,7 @@ private slots: void fillInt() const; void fillMovable() const; void fillCustom() const; + void fillDetaches() const; void first() const; void fromListInt() const; void fromListMovable() const; @@ -1272,6 +1273,16 @@ void tst_QVector::fillCustom() const QCOMPARE(instancesCount, Custom::counter.loadAcquire()); } +void tst_QVector::fillDetaches() const +{ + QVector test = { 1, 2, 3 }; + QVector copy = test; + copy.fill(42); + + QCOMPARE(test, QVector({1, 2, 3})); + QCOMPARE(copy, QVector({42, 42, 42})); +} + void tst_QVector::first() const { QVector myvec; From 9b8493314dd77f3e96b353187816bb7ef4dedbb5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 21 Mar 2017 22:26:09 -0700 Subject: [PATCH 116/264] Qt6: Fix uninitialized meta objects on Windows Windows has a problem relating to cross-DLL variable relocations: they are not supported. Since QMetaObject's link to the parent class is done via a pointer, every QMetaObject in a DLL or in the EXE that derives from a class from another DLL (such as QObject) will be dynamically initialized. This commit changes the meta object pointers in QMetaObject::d from raw pointers to a wrapper class SuperData, which is almost entirely source- compatible with the pointer itself. On all systems except for Windows with Qt 6, it's binary compatible with the current implementation. But for Windows with Qt 6, this commit will store both the raw pointer and a pointer to a function that returns the QMetaObject, with one of them non-null only. For all meta objects constructed by moc, we store the function pointer, which allows the staticMetaObject to be statically intialized. For dynamic meta objects (QMetaObjectBuilder, QtDBus, QtQml, ActiveQt), we'll store the actual raw pointer. [ChangeLog][QtCore][QMetaObject] Some internal members of the QMetaObject class have changed types. Those members are not public API and thus should not cause source incompatibilities. The macro QT_NO_DATA_RELOCATION existed in Qt 4 but was called Q_NO_DATA_RELOCATION and only applied to Symbian. It was removed in commit 24a72c4efa929648d3afd95b3c269a95ecf46e57 ("qglobal: Remove symbian specific features"). Task-number: QTBUG-38876 Fixes: QTBUG-69963 Change-Id: Id92f4a61915b49ddaee6fffd14ae1cf615525e92 Reviewed-by: Simon Hausmann --- src/corelib/global/qglobal.h | 7 ++-- src/corelib/global/qsystemdetection.h | 9 ++++- src/corelib/kernel/qmetaobject.cpp | 2 +- src/corelib/kernel/qmetaobjectbuilder.cpp | 12 +++--- src/corelib/kernel/qobjectdefs.h | 37 +++++++++++++++++-- src/tools/moc/generator.cpp | 11 ++++-- .../tst_qmetaobjectbuilder.cpp | 6 +-- tests/auto/tools/moc/tst_moc.cpp | 7 ++-- 8 files changed, 66 insertions(+), 25 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 80f59d92d0..77ca63803f 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2019 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -612,7 +612,8 @@ using qsizetype = QIntegerForSizeof::Signed; # define Q_ALWAYS_INLINE inline #endif -#if defined(Q_CC_GNU) && defined(Q_OS_WIN) +#if defined(Q_CC_GNU) && defined(Q_OS_WIN) && !defined(QT_NO_DATA_RELOCATION) +// ### Qt6: you can remove me # define QT_INIT_METAOBJECT __attribute__((init_priority(101))) #else # define QT_INIT_METAOBJECT diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h index 02e2f77c6b..4ebbe16ead 100644 --- a/src/corelib/global/qsystemdetection.h +++ b/src/corelib/global/qsystemdetection.h @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2019 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -180,6 +181,12 @@ #if defined(Q_OS_WIN32) || defined(Q_OS_WIN64) || defined(Q_OS_WINRT) # define Q_OS_WINDOWS # define Q_OS_WIN +# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +// On Windows, pointers to dllimport'ed variables are not constant expressions, +// so to keep to certain initializations (like QMetaObject) constexpr, we need +// to use functions instead. +# define QT_NO_DATA_RELOCATION +# endif #endif #if defined(Q_OS_WIN) diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 56217262f2..acb1f54bdf 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -953,7 +953,7 @@ static const QMetaObject *QMetaObject_findMetaObject(const QMetaObject *self, co return self; if (self->d.relatedMetaObjects) { Q_ASSERT(priv(self->d.data)->revision >= 2); - const QMetaObject * const *e = self->d.relatedMetaObjects; + const auto *e = self->d.relatedMetaObjects; if (e) { while (*e) { if (const QMetaObject *m =QMetaObject_findMetaObject((*e), name)) diff --git a/src/corelib/kernel/qmetaobjectbuilder.cpp b/src/corelib/kernel/qmetaobjectbuilder.cpp index d2030f0275..f77c4ce32f 100644 --- a/src/corelib/kernel/qmetaobjectbuilder.cpp +++ b/src/corelib/kernel/qmetaobjectbuilder.cpp @@ -747,7 +747,7 @@ void QMetaObjectBuilder::addMetaObject if ((members & RelatedMetaObjects) != 0) { Q_ASSERT(priv(prototype->d.data)->revision >= 2); - const QMetaObject * const *objects = prototype->d.relatedMetaObjects; + const auto *objects = prototype->d.relatedMetaObjects; if (objects) { while (*objects != 0) { addRelatedMetaObject(*objects); @@ -1464,16 +1464,16 @@ static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, // Create the relatedMetaObjects block if we need one. if (d->relatedMetaObjects.size() > 0) { - ALIGN(size, QMetaObject *); - const QMetaObject **objects = - reinterpret_cast(buf + size); + using SuperData = QMetaObject::SuperData; + ALIGN(size, SuperData); + auto objects = reinterpret_cast(buf + size); if (buf) { meta->d.relatedMetaObjects = objects; for (index = 0; index < d->relatedMetaObjects.size(); ++index) objects[index] = d->relatedMetaObjects[index]; - objects[index] = 0; + objects[index] = nullptr; } - size += sizeof(QMetaObject *) * (d->relatedMetaObjects.size() + 1); + size += sizeof(SuperData) * (d->relatedMetaObjects.size() + 1); } // Align the final size and return it. diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index ef22b6e67f..dc2d832fe5 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2019 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -572,13 +572,42 @@ struct Q_CORE_EXPORT QMetaObject int static_metacall(Call, int, void **) const; static int metacall(QObject *, Call, int, void **); + template static constexpr const QMetaObject *staticMetaObject() + { + return &MO; + } + + struct SuperData { + const QMetaObject *direct; + SuperData() = default; + constexpr SuperData(std::nullptr_t) : direct(nullptr) {} + constexpr SuperData(const QMetaObject *mo) : direct(mo) {} + + constexpr const QMetaObject *operator->() const { return operator const QMetaObject *(); } + +#ifdef QT_NO_DATA_RELOCATION + using Getter = const QMetaObject *(*)(); + Getter indirect = nullptr; + constexpr SuperData(Getter g) : direct(nullptr), indirect(g) {} + constexpr operator const QMetaObject *() const + { return indirect ? indirect() : direct; } + template static constexpr SuperData link() + { return SuperData(QMetaObject::staticMetaObject); } +#else + constexpr operator const QMetaObject *() const + { return direct; } + template static constexpr SuperData link() + { return SuperData(QMetaObject::staticMetaObject()); } +#endif + }; + struct { // private data - const QMetaObject *superdata; + SuperData superdata; const QByteArrayData *stringdata; const uint *data; typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **); StaticMetacallFunction static_metacall; - const QMetaObject * const *relatedMetaObjects; + const SuperData *relatedMetaObjects; void *extradata; //reserved for future use } d; diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 41d0bbf2a1..6a74e739e6 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -518,10 +518,15 @@ void Generator::generateCode() } } +// +// Generate meta object link to parent meta objects +// + if (!extraList.isEmpty()) { - fprintf(out, "static const QMetaObject * const qt_meta_extradata_%s[] = {\n ", qualifiedClassNameIdentifier.constData()); + fprintf(out, "static const QMetaObject::SuperData qt_meta_extradata_%s[] = {\n", + qualifiedClassNameIdentifier.constData()); for (int i = 0; i < extraList.count(); ++i) { - fprintf(out, " &%s::staticMetaObject,\n", extraList.at(i).constData()); + fprintf(out, " QMetaObject::SuperData::link<%s::staticMetaObject>(),\n", extraList.at(i).constData()); } fprintf(out, " nullptr\n};\n\n"); } @@ -537,7 +542,7 @@ void Generator::generateCode() if (isQObject) fprintf(out, " nullptr,\n"); else if (cdef->superclassList.size() && (!cdef->hasQGadget || knownGadgets.contains(purestSuperClass))) - fprintf(out, " &%s::staticMetaObject,\n", purestSuperClass.constData()); + fprintf(out, " QMetaObject::SuperData::link<%s::staticMetaObject>(),\n", purestSuperClass.constData()); else fprintf(out, " nullptr,\n"); fprintf(out, " qt_meta_stringdata_%s.data,\n" diff --git a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index 56623773a2..9fe7d63727 100644 --- a/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/corelib/kernel/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -1322,8 +1322,8 @@ bool tst_QMetaObjectBuilder::sameMetaObject return false; } - const QMetaObject * const *objects1 = meta1->d.relatedMetaObjects; - const QMetaObject * const *objects2 = meta2->d.relatedMetaObjects; + const auto *objects1 = meta1->d.relatedMetaObjects; + const auto *objects2 = meta2->d.relatedMetaObjects; if (objects1 && !objects2) return false; if (objects2 && !objects1) @@ -1391,7 +1391,7 @@ private: }; QMetaObject TestObject::staticMetaObject = { - { 0, 0, 0, 0, 0, 0 } + { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr } }; TestObject::TestObject(QObject *parent) diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index b88d929ca9..89f563f11d 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -1053,7 +1053,7 @@ void tst_Moc::testExtraDataForEnum() const QMetaObject *mobjUser = &EnumUserClass::staticMetaObject; QCOMPARE(mobjUser->enumeratorCount(), 0); - const QMetaObject * const *objects = mobjUser->d.relatedMetaObjects; + const auto *objects = mobjUser->d.relatedMetaObjects; QVERIFY(objects); QCOMPARE(objects[0], mobjSource); QVERIFY(!objects[1]); @@ -3579,10 +3579,9 @@ namespace QTBUG32933_relatedObjectsDontIncludeItself { void tst_Moc::QTBUG32933_relatedObjectsDontIncludeItself() { const QMetaObject *mo = &QTBUG32933_relatedObjectsDontIncludeItself::NS::Obj::staticMetaObject; - const QMetaObject * const *objects = mo->d.relatedMetaObjects; + const auto *objects = mo->d.relatedMetaObjects; // the related objects should be empty because the enums is in the same object. QVERIFY(!objects); - } class UnrelatedClass : public QObject @@ -3688,7 +3687,7 @@ void tst_Moc::relatedMetaObjectsNameConflict() // load all specified metaobjects int a set QSet dependency; - const QMetaObject *const *i = dependingObject->d.relatedMetaObjects; + const auto *i = dependingObject->d.relatedMetaObjects; while (*i) { dependency.insert(*i); ++i; From a5da01c0449c4237280021a11271cd433707a523 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 30 Jan 2019 20:16:42 -0800 Subject: [PATCH 117/264] Remove useless null pointer checks Cache can't be null, since it's a member of an extant object. Change-Id: Id98140e1c2f0426cabbefffd157ed3cdd62a8bba Reviewed-by: Lars Knoll --- src/corelib/codecs/qtextcodec.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 85cfcdbf48..8639e4f2f0 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -544,11 +544,9 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name) #if !QT_CONFIG(icu) QTextCodecCache *cache = &globalData->codecCache; QTextCodec *codec; - if (cache) { - codec = cache->value(name); - if (codec) - return codec; - } + codec = cache->value(name); + if (codec) + return codec; for (TextCodecListConstIt it = globalData->allCodecs.constBegin(), cend = globalData->allCodecs.constEnd(); it != cend; ++it) { QTextCodec *cursor = *it; @@ -560,8 +558,7 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name) QList aliases = cursor->aliases(); for (ByteArrayListConstIt ait = aliases.constBegin(), acend = aliases.constEnd(); ait != acend; ++ait) { if (qTextCodecNameMatch(*ait, name)) { - if (cache) - cache->insert(name, cursor); + cache->insert(name, cursor); return cursor; } } From d80bd2f54876c2e4c0593d3d5d4d0e01824dc301 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 20 Jun 2019 09:44:20 -0700 Subject: [PATCH 118/264] QResource: deprecate isCompressed() Current codebases assume isCompressed() implies ZlibCompression, since there was no compressionAlgorithm() getter. In order to force codebases to change, deprecate isCompressed() and force handling of the algorithm. The replacement API is being introduced in 5.14, which is why the warning is being emitted in 5.15 only. Change-Id: Ief874765cd7b43798de3fffd15a9f5d978951ea5 Reviewed-by: Edward Welbourne --- src/corelib/io/qresource.cpp | 46 ++++++++++++------- src/corelib/io/qresource.h | 5 +- src/corelib/kernel/qtranslator.cpp | 3 +- .../qresourceengine/tst_qresourceengine.cpp | 10 ++-- 4 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index fcc5b69179..747f153f48 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2018 The Qt Company Ltd. -** Copyright (C) 2018 Intel Corporation. +** Copyright (C) 2019 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -279,14 +279,14 @@ static inline QStringList *resourceSearchPaths() This enum is used by compressionAlgorithm() to indicate which algorithm the RCC tool used to compress the payload. - \value NoCompression Contents are not compressed (isCompressed() is false). + \value NoCompression Contents are not compressed \value ZlibCompression Contents are compressed using \l{zlib}{https://zlib.net} and can be decompressed using the qUncompress() function. \value ZstdCompression Contents are compressed using \l{zstd}{https://zstd.net}. To decompress, use the \c{ZSTD_decompress} function from the zstd library. - \sa compressionAlgorithm(), isCompressed() + \sa compressionAlgorithm() */ class QResourcePrivate { @@ -551,13 +551,20 @@ bool QResource::isValid() const \sa isDir() */ - +#if QT_DEPRECATED_SINCE(5, 13) /*! + \obsolete + Returns \c true if the resource represents a file and the data backing it is in a compressed format, false otherwise. If the data is compressed, check compressionAlgorithm() to verify what algorithm to use to decompress the data. + \note This function is deprecated and can be replaced with + \code + compressionAlgorithm() != NoCompression + \endcode + \sa data(), compressionAlgorithm(), isFile() */ @@ -565,6 +572,7 @@ bool QResource::isCompressed() const { return compressionAlgorithm() != NoCompression; } +#endif /*! \since 5.13 @@ -582,7 +590,7 @@ bool QResource::isCompressed() const See \l{http://facebook.github.io/zstd/zstd_manual.html}{Zstandard manual}. - \sa isCompressed(), data(), isFile() + \sa data(), isFile() */ QResource::Compression QResource::compressionAlgorithm() const { @@ -606,11 +614,11 @@ qint64 QResource::size() const /*! Returns direct access to a read only segment of data that this resource - represents. If the resource is compressed the data returns is - compressed and qUncompress() must be used to access the data. If the - resource is a directory \nullptr is returned. + represents. If the resource is compressed the data returned is compressed + and the appropriate library functions must be used to access the data. If + the resource is a directory \nullptr is returned. - \sa size(), isCompressed(), isFile() + \sa size(), compressionAlgorithm(), isFile() */ const uchar *QResource::data() const @@ -1366,9 +1374,15 @@ bool QResourceFileEngine::open(QIODevice::OpenMode flags) qWarning("QResourceFileEngine::open: Missing file name"); return false; } - if(flags & QIODevice::WriteOnly) + if (flags & QIODevice::WriteOnly) return false; - d->uncompress(); + if (d->resource.compressionAlgorithm() != QResource::NoCompression) { + d->uncompress(); + if (d->uncompressed.isNull()) { + d->errorString = QSystemError::stdString(EIO); + return false; + } + } if (!d->resource.isValid()) { d->errorString = QSystemError::stdString(ENOENT); return false; @@ -1395,7 +1409,7 @@ qint64 QResourceFileEngine::read(char *data, qint64 len) len = size()-d->offset; if(len <= 0) return 0; - if(d->resource.isCompressed()) + if (!d->uncompressed.isNull()) memcpy(data, d->uncompressed.constData()+d->offset, len); else memcpy(data, d->resource.data()+d->offset, len); @@ -1431,9 +1445,9 @@ bool QResourceFileEngine::link(const QString &) qint64 QResourceFileEngine::size() const { Q_D(const QResourceFileEngine); - if(!d->resource.isValid()) + if (!d->resource.isValid()) return 0; - if (d->resource.isCompressed()) { + if (d->resource.compressionAlgorithm() != QResource::NoCompression) { d->uncompress(); return d->uncompressed.size(); } @@ -1596,7 +1610,7 @@ uchar *QResourceFileEnginePrivate::map(qint64 offset, qint64 size, QFile::Memory Q_UNUSED(flags); qint64 max = resource.size(); - if (resource.isCompressed()) { + if (resource.compressionAlgorithm() != QResource::NoCompression) { uncompress(); max = uncompressed.size(); } @@ -1609,7 +1623,7 @@ uchar *QResourceFileEnginePrivate::map(qint64 offset, qint64 size, QFile::Memory } const uchar *address = resource.data(); - if (resource.isCompressed()) + if (resource.compressionAlgorithm() != QResource::NoCompression) address = reinterpret_cast(uncompressed.constData()); return const_cast(address) + offset; diff --git a/src/corelib/io/qresource.h b/src/corelib/io/qresource.h index 5e798de436..5ee8d5d266 100644 --- a/src/corelib/io/qresource.h +++ b/src/corelib/io/qresource.h @@ -72,7 +72,6 @@ public: bool isValid() const; - bool isCompressed() const; Compression compressionAlgorithm() const; qint64 size() const; const uchar *data() const; @@ -84,6 +83,10 @@ public: QT_DEPRECATED_X("Use QDir::searchPaths() instead") static QStringList searchPaths(); #endif +#if QT_DEPRECATED_SINCE(5, 15) + QT_DEPRECATED_VERSION_X_5_15("Use QResource::compressionAlgorithm() instead") + bool isCompressed() const; +#endif static bool registerResource(const QString &rccFilename, const QString &resourceRoot=QString()); static bool unregisterResource(const QString &rccFilename, const QString &resourceRoot=QString()); diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 637ef84d21..ddb96ecad6 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -528,7 +528,8 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo // memory, so no need to use QFile to copy it again. Q_ASSERT(!d->resource); d->resource = new QResource(realname); - if (resource->isValid() && !resource->isCompressed() && resource->size() >= MagicLength + if (resource->isValid() && resource->compressionAlgorithm() == QResource::NoCompression + && resource->size() >= MagicLength && !memcmp(resource->data(), magic, MagicLength)) { d->unmapLength = resource->size(); d->unmapPointer = reinterpret_cast(const_cast(resource->data())); diff --git a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp index df1dbebbf2..44c8c4b681 100644 --- a/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp +++ b/tests/auto/corelib/io/qresourceengine/tst_qresourceengine.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2018 Intel Corporation. +** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2019 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -563,15 +563,15 @@ void tst_QResourceEngine::setLocale() // default constructed QResource gets the default locale QResource resource; resource.setFileName("aliasdir/aliasdir.txt"); - QVERIFY(!resource.isCompressed()); + QCOMPARE(resource.compressionAlgorithm(), QResource::NoCompression); // change the default locale and make sure it doesn't affect the resource QLocale::setDefault(QLocale("de_CH")); - QVERIFY(!resource.isCompressed()); + QCOMPARE(resource.compressionAlgorithm(), QResource::NoCompression); // then explicitly set the locale on qresource resource.setLocale(QLocale("de_CH")); - QVERIFY(resource.isCompressed()); + QVERIFY(resource.compressionAlgorithm() != QResource::NoCompression); // the reset the default locale back QLocale::setDefault(QLocale::system()); From 6bd35e47080b3ddfe14543f805e744846e245c2f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 May 2019 07:48:49 -0700 Subject: [PATCH 119/264] Work around Apple Clang's -Wshadow warning Well, yeah, it technically does... qcborstream.h:245:15: warning: declaration shadows a typedef in the global namespace [-Wshadow] /usr/include/libkern/OSTypes.h:36:26: note: previous declaration is here Fixes: QTBUG-75825 Change-Id: Idce141629dd34287808bfffd159ee2a75428bf12 Reviewed-by: Volker Hilsheimer --- src/corelib/serialization/qcborstream.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/serialization/qcborstream.h b/src/corelib/serialization/qcborstream.h index 3b13a309ab..7a451e63ac 100644 --- a/src/corelib/serialization/qcborstream.h +++ b/src/corelib/serialization/qcborstream.h @@ -242,8 +242,8 @@ private: template FP _toFloatingPoint() const noexcept { - using UInt = typename QIntegerForSizeof::Unsigned; - UInt u = UInt(value64); + using UIntFP = typename QIntegerForSizeof::Unsigned; + UIntFP u = UIntFP(value64); FP f; memcpy(static_cast(&f), &u, sizeof(f)); return f; From e0a486c77d49f4410820aa6f4139ff00d7668a7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 16 Jul 2019 23:18:09 +0200 Subject: [PATCH 120/264] Tie QPlatformOpenGLContext to its QOpenGLContext before initializing So that the context can be referenced during initialization. Change-Id: I9ec69b2431ba1ac6256cb2e969a76f515497e247 Reviewed-by: Timur Pocheptsov --- src/gui/kernel/qopenglcontext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 9a6f879431..499d16c109 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -612,8 +612,8 @@ bool QOpenGLContext::create() d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformOpenGLContext(this); if (!d->platformGLContext) return false; - d->platformGLContext->initialize(); d->platformGLContext->setContext(this); + d->platformGLContext->initialize(); if (!d->platformGLContext->isSharing()) d->shareContext = 0; d->shareGroup = d->shareContext ? d->shareContext->shareGroup() : new QOpenGLContextGroup; From 7a7fe9dbb3be042b42a559e734df40ffdea7ebbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 16 Jul 2019 23:19:19 +0200 Subject: [PATCH 121/264] macOS: Move QCocoaGLContext initialization into dedicated method Change-Id: I9dc2c400c3d26e9fcfaac04b61c1503229f59dba Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoaglcontext.h | 2 ++ src/plugins/platforms/cocoa/qcocoaglcontext.mm | 16 ++++++++++++---- src/plugins/platforms/cocoa/qcocoaintegration.mm | 4 +--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h index c1041ac2da..bb309c0713 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.h +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h @@ -56,6 +56,8 @@ public: QCocoaGLContext(QOpenGLContext *context); ~QCocoaGLContext(); + void initialize() override; + bool makeCurrent(QPlatformSurface *surface) override; void swapBuffers(QPlatformSurface *surface) override; void doneCurrent() override; diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index d0100d0410..c0579c7c1e 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -76,9 +76,14 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQpaOpenGLContext, "qt.qpa.openglcontext", QtWarningMsg); QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context) - : QPlatformOpenGLContext(), m_format(context->format()) + : QPlatformOpenGLContext() + , m_format(context->format()) { - QVariant nativeHandle = context->nativeHandle(); +} + +void QCocoaGLContext::initialize() +{ + QVariant nativeHandle = context()->nativeHandle(); if (!nativeHandle.isNull()) { if (!nativeHandle.canConvert()) { qCWarning(lcQpaOpenGLContext, "QOpenGLContext native handle must be a QCocoaNativeContext"); @@ -95,7 +100,7 @@ QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context) // Note: We have no way of knowing whether the NSOpenGLContext was created with the // share context as reported by the QOpenGLContext, but we just have to trust that // it was. It's okey, as the only thing we're using it for is to report isShared(). - if (QPlatformOpenGLContext *shareContext = context->shareHandle()) + if (QPlatformOpenGLContext *shareContext = context()->shareHandle()) m_shareContext = static_cast(shareContext)->nativeContext(); updateSurfaceFormat(); @@ -110,7 +115,7 @@ QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context) if (m_format.renderableType() != QSurfaceFormat::OpenGL) return; - if (QPlatformOpenGLContext *shareContext = context->shareHandle()) { + if (QPlatformOpenGLContext *shareContext = context()->shareHandle()) { m_shareContext = static_cast(shareContext)->nativeContext(); // Allow sharing between 3.2 Core and 4.1 Core profile versions in @@ -150,6 +155,9 @@ QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context) return; } + // The native handle should reflect the underlying context, even if we created it + context()->setNativeHandle(QVariant::fromValue(m_context)); + // --------------------- Set NSOpenGLContext properties --------------------- const GLint interval = m_format.swapInterval() >= 0 ? m_format.swapInterval() : 1; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index b5d63f8331..dd2d1ba0f1 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -418,9 +418,7 @@ QPlatformOffscreenSurface *QCocoaIntegration::createPlatformOffscreenSurface(QOf #ifndef QT_NO_OPENGL QPlatformOpenGLContext *QCocoaIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { - QCocoaGLContext *glContext = new QCocoaGLContext(context); - context->setNativeHandle(QVariant::fromValue(glContext->nativeContext())); - return glContext; + return new QCocoaGLContext(context); } #endif From d2e4bde5d09816ebedb1a5cc9ec7c0af20fd1242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 16 Jul 2019 23:43:35 +0200 Subject: [PATCH 122/264] macOS: Use lambdas instead of Obj-C categories for GL helper functions Allows us to reference captured variables and keeps the function local to where it's used. Change-Id: I609892888720202021862d26a74ceb50e232f356 Reviewed-by: Timur Pocheptsov --- .../platforms/cocoa/qcocoaglcontext.mm | 46 ++++++++----------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index c0579c7c1e..c5f0762ac2 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -53,24 +53,6 @@ static inline QByteArray getGlString(GLenum param) return QByteArray(); } -@implementation NSOpenGLPixelFormat (QtHelpers) -- (GLint)qt_getAttribute:(NSOpenGLPixelFormatAttribute)attribute -{ - int value = 0; - [self getValues:&value forAttribute:attribute forVirtualScreen:0]; - return value; -} -@end - -@implementation NSOpenGLContext (QtHelpers) -- (GLint)qt_getParameter:(NSOpenGLContextParameter)parameter -{ - int value = 0; - [self getValues:&value forParameter:parameter]; - return value; -} -@end - QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQpaOpenGLContext, "qt.qpa.openglcontext", QtWarningMsg); @@ -293,7 +275,13 @@ void QCocoaGLContext::updateSurfaceFormat() NSOpenGLPixelFormat *pixelFormat = m_context.pixelFormat; - int colorSize = [pixelFormat qt_getAttribute:NSOpenGLPFAColorSize]; + auto pixelFormatAttribute = [&](NSOpenGLPixelFormatAttribute attribute) { + int value = 0; + [pixelFormat getValues:&value forAttribute:attribute forVirtualScreen:0]; + return value; + }; + + int colorSize = pixelFormatAttribute(NSOpenGLPFAColorSize); colorSize /= 4; // The attribute includes the alpha component m_format.setRedBufferSize(colorSize); m_format.setGreenBufferSize(colorSize); @@ -305,22 +293,28 @@ void QCocoaGLContext::updateSurfaceFormat() // size, as that will make the user believe the alpha channel can be used for // something useful, when in reality it can't, due to the surface being opaque. if (m_format.alphaBufferSize() > 0) - m_format.setAlphaBufferSize([pixelFormat qt_getAttribute:NSOpenGLPFAAlphaSize]); + m_format.setAlphaBufferSize(pixelFormatAttribute(NSOpenGLPFAAlphaSize)); - m_format.setDepthBufferSize([pixelFormat qt_getAttribute:NSOpenGLPFADepthSize]); - m_format.setStencilBufferSize([pixelFormat qt_getAttribute:NSOpenGLPFAStencilSize]); - m_format.setSamples([pixelFormat qt_getAttribute:NSOpenGLPFASamples]); + m_format.setDepthBufferSize(pixelFormatAttribute(NSOpenGLPFADepthSize)); + m_format.setStencilBufferSize(pixelFormatAttribute(NSOpenGLPFAStencilSize)); + m_format.setSamples(pixelFormatAttribute(NSOpenGLPFASamples)); - if ([pixelFormat qt_getAttribute:NSOpenGLPFATripleBuffer]) + if (pixelFormatAttribute(NSOpenGLPFATripleBuffer)) m_format.setSwapBehavior(QSurfaceFormat::TripleBuffer); - else if ([pixelFormat qt_getAttribute:NSOpenGLPFADoubleBuffer]) + else if (pixelFormatAttribute(NSOpenGLPFADoubleBuffer)) m_format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); else m_format.setSwapBehavior(QSurfaceFormat::SingleBuffer); // ------------------- Query the context ------------------- - m_format.setSwapInterval([m_context qt_getParameter:NSOpenGLCPSwapInterval]); + auto glContextParameter = [&](NSOpenGLContextParameter parameter) { + int value = 0; + [m_context getValues:&value forParameter:parameter]; + return value; + }; + + m_format.setSwapInterval(glContextParameter(NSOpenGLCPSwapInterval)); if (oldContext) [oldContext makeCurrentContext]; From d224c762bc9530236d255cc5cb851112fcc7cee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 16 Jul 2019 23:45:48 +0200 Subject: [PATCH 123/264] macOS: Use correct virtual screen when resolving GL surface format Change-Id: I8288db85c8e99bf9fccfcfbca7f9e3594d00fa48 Reviewed-by: Timur Pocheptsov --- .../platforms/cocoa/qcocoaglcontext.mm | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index c5f0762ac2..e45ea7efd3 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -40,6 +40,8 @@ #include "qcocoaglcontext.h" #include "qcocoawindow.h" #include "qcocoahelpers.h" +#include "qcocoascreen.h" + #include #include #include @@ -275,9 +277,28 @@ void QCocoaGLContext::updateSurfaceFormat() NSOpenGLPixelFormat *pixelFormat = m_context.pixelFormat; + GLint virtualScreen = [&, this]() { + auto *platformScreen = static_cast(context()->screen()->handle()); + auto displayId = platformScreen->nativeScreen().qt_displayId; + auto requestedDisplay = CGDisplayIDToOpenGLDisplayMask(displayId); + for (int i = 0; i < pixelFormat.numberOfVirtualScreens; ++i) { + GLint supportedDisplays; + [pixelFormat getValues:&supportedDisplays forAttribute:NSOpenGLPFAScreenMask forVirtualScreen:i]; + // Note: The mask returned for NSOpenGLPFAScreenMask is a bit mask of + // physical displays that the renderer can drive, while the one returned + // from CGDisplayIDToOpenGLDisplayMask has a single bit set, representing + // that particular display. + if (requestedDisplay & supportedDisplays) + return i; + } + qCWarning(lcQpaOpenGLContext) << "Could not find virtual screen for" + << platformScreen << "with displayId" << displayId; + return 0; + }(); + auto pixelFormatAttribute = [&](NSOpenGLPixelFormatAttribute attribute) { int value = 0; - [pixelFormat getValues:&value forAttribute:attribute forVirtualScreen:0]; + [pixelFormat getValues:&value forAttribute:attribute forVirtualScreen:virtualScreen]; return value; }; From 19e45ee4c1007ddb9de4c0be9c4423e75ebe9330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 16 Jul 2019 10:36:57 +0200 Subject: [PATCH 124/264] Win: qnetconmon: Use CoInitialize instead of CoInitializeEx Somehow I didn't test using QNetwork{Status,Connection}Monitor together with Gui. In qwindowstheme.cpp we call CoInitialize and as such we cannot use CoInitializeEx with a different thread mode. Change-Id: If4a4441cc2616371d8b7cda72cfad11187d8f153 Reviewed-by: Timur Pocheptsov --- src/network/kernel/qnetconmonitor_win.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/kernel/qnetconmonitor_win.cpp b/src/network/kernel/qnetconmonitor_win.cpp index 8e3cad59f8..b543508169 100644 --- a/src/network/kernel/qnetconmonitor_win.cpp +++ b/src/network/kernel/qnetconmonitor_win.cpp @@ -332,7 +332,7 @@ bool QNetworkConnectionEvents::stopMonitoring() QNetworkConnectionMonitorPrivate::QNetworkConnectionMonitorPrivate() { - auto hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); + auto hr = CoInitialize(nullptr); if (FAILED(hr)) { qCWarning(lcNetMon) << "Failed to initialize COM:" << errorStringFromHResult(hr); comInitFailed = true; @@ -611,7 +611,7 @@ bool QNetworkListManagerEvents::stop() QNetworkStatusMonitorPrivate::QNetworkStatusMonitorPrivate() { - auto hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); + auto hr = CoInitialize(nullptr); if (FAILED(hr)) { qCWarning(lcNetMon) << "Failed to initialize COM:" << errorStringFromHResult(hr); comInitFailed = true; From 1d8c9978fa1baafa17c95713bd5d04f245eeb76f Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 15 Jul 2019 14:45:01 +0200 Subject: [PATCH 125/264] QDateTime docs: don't encourage use of deprecated textdate functions The textdate API methods are deprecated in favor of QLocale; so suggest use of QLocale in place of them. Don't credit the deprecated methods as being used where they aren't. Change-Id: I0abcb1f69729760ae1b86cb8088e4158c0ad6010 Reviewed-by: Paul Wicking Reviewed-by: Tasuku Suzuki --- src/corelib/tools/qdatetime.cpp | 34 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 9b0ed18742..8536743cee 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -338,11 +338,10 @@ static int fromOffsetString(const QStringRef &offsetString, bool *valid) Q_DECL_ setDate(). The fromString() function returns a QDate given a string and a date format which is used to interpret the date within the string. - The year(), month(), and day() functions provide access to the - year, month, and day numbers. Also, dayOfWeek() and dayOfYear() - functions are provided. The same information is provided in - textual format by the toString(), shortDayName(), longDayName(), - shortMonthName(), and longMonthName() functions. + The year(), month(), and day() functions provide access to the year, month, + and day numbers. Also, dayOfWeek() and dayOfYear() functions are + provided. The same information is provided in textual format by + toString(). The day and month numbers can be mapped to names using QLocal. QDate provides a full set of operators to compare two QDate objects where smaller means earlier, and larger means later. @@ -807,11 +806,10 @@ static QString toStringIsoDate(qint64 jd) Returns the date as a string. The \a format parameter determines the format of the string. - If the \a format is Qt::TextDate, the string is formatted in - the default way. QDate::shortDayName() and QDate::shortMonthName() - are used to generate the string, so the day and month names will - be localized names using the system locale, i.e. QLocale::system(). An - example of this formatting is "Sat May 20 1995". + If the \a format is Qt::TextDate, the string is formatted in the default + way. The day and month names will be localized names using the system + locale, i.e. QLocale::system(). An example of this formatting + is "Sat May 20 1995". If the \a format is Qt::ISODate, the string format corresponds to the ISO 8601 extended specification for representations of @@ -843,7 +841,7 @@ static QString toStringIsoDate(qint64 jd) range 0 to 9999. This restriction may apply to locale-aware formats as well, depending on the locale settings. - \sa fromString(), shortDayName(), shortMonthName(), QLocale::toString() + \sa fromString(), QLocale::toString() */ QString QDate::toString(Qt::DateFormat format) const { @@ -3802,12 +3800,10 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC) Returns the datetime as a string in the \a format given. - If the \a format is Qt::TextDate, the string is formatted in - the default way. QDate::shortDayName(), QDate::shortMonthName(), - and QTime::toString() are used to generate the string, so the - day and month names will be localized names using the system locale, - i.e. QLocale::system(). An example of this formatting is - "Wed May 20 03:40:13 1998". + If the \a format is Qt::TextDate, the string is formatted in the default + way. The day and month names will be localized names using the system + locale, i.e. QLocale::system(). An example of this formatting is "Wed May 20 + 03:40:13 1998". If the \a format is Qt::ISODate, the string format corresponds to the ISO 8601 extended specification for representations of @@ -4983,18 +4979,14 @@ QDateTime QDateTime::fromString(const QString& string, Qt::DateFormat format) \row \li dd \li the day as number with a leading zero (01 to 31) \row \li ddd \li the abbreviated localized day name (e.g. 'Mon' to 'Sun'). - Uses QDate::shortDayName(). \row \li dddd \li the long localized day name (e.g. 'Monday' to 'Sunday'). - Uses QDate::longDayName(). \row \li M \li the month as number without a leading zero (1-12) \row \li MM \li the month as number with a leading zero (01-12) \row \li MMM \li the abbreviated localized month name (e.g. 'Jan' to 'Dec'). - Uses QDate::shortMonthName(). \row \li MMMM \li the long localized month name (e.g. 'January' to 'December'). - Uses QDate::longMonthName(). \row \li yy \li the year as two digit number (00-99) \row \li yyyy \li the year as four digit number \endtable From a7d7f7155098d7c8e9d457ac411077b5d9121afb Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 15 Jul 2019 07:35:46 +0200 Subject: [PATCH 126/264] QWasmEventTranslator: return Key_unknown, not 0x00, when a key isn't found This matches what translateDeadKey() returns for unhandled keys, and processKeyboard() checks for when replacing qtKey with the result of translateDeadKey(). Change-Id: I1500576b7b31047a7a35633a15cd6975b77d842d Reviewed-by: Volker Hilsheimer --- src/plugins/platforms/wasm/qwasmeventtranslator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index d165ee5839..a34b957537 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -824,7 +824,7 @@ static Qt::Key find_impl(const KeyMapping *first, const KeyMapping *last, Qt::Ke return first->to; ++first; } - return {}; + return Qt::Key_unknown; } template From 3966b571ff54100923a479050a38ac906e0ed1e3 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 9 Jul 2019 16:50:15 +0200 Subject: [PATCH 127/264] QDir: strip Windows' long-path markers when converting from native Applications might receive paths with Windows' '\\?\' markers, which indicates a long path to Win32 APIs, when the application is opened by explorer via file association. Qt not ignoring those markers will fail to open such files. By stripping the marker in QDir::fromNativeSeparators, QFile, QFileInfo etc automatically are able to handle such paths. QDir::cleanPath is also documented to normalize separators, so it needs to be done there as well. [ChangeLog][QtCore][QDir] Remove Windows specific long path markers when handling file paths with native separators. Change-Id: I526a890614edee8c85b39fc12c98e7ddb6e0d793 Fixes: QTBUG-75117 Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff Reviewed-by: Edward Welbourne --- src/corelib/io/qdir.cpp | 11 +++++++++++ tests/auto/corelib/io/qdir/tst_qdir.cpp | 2 ++ 2 files changed, 13 insertions(+) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 62dae3577c..47fac66c4f 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -947,6 +947,12 @@ QString QDir::fromNativeSeparators(const QString &pathName) int i = pathName.indexOf(QLatin1Char('\\')); if (i != -1) { QString n(pathName); + if (n.startsWith(QLatin1String("\\\\?\\"))) { + n.remove(0, 4); + i = n.indexOf(QLatin1Char('\\')); + if (i == -1) + return n; + } QChar * const data = n.data(); data[i++] = QLatin1Char('/'); @@ -2339,6 +2345,11 @@ static QString qt_cleanPath(const QString &path, bool *ok) if (path.isEmpty()) return path; QString name = path; +#if defined (Q_OS_WIN) + if (name.startsWith(QLatin1String("\\\\?\\"))) + name.remove(0, 4); +#endif + QChar dir_separator = QDir::separator(); if (dir_separator != QLatin1Char('/')) name.replace(dir_separator, QLatin1Char('/')); diff --git a/tests/auto/corelib/io/qdir/tst_qdir.cpp b/tests/auto/corelib/io/qdir/tst_qdir.cpp index 2aebc67dcf..52e7ebadb1 100644 --- a/tests/auto/corelib/io/qdir/tst_qdir.cpp +++ b/tests/auto/corelib/io/qdir/tst_qdir.cpp @@ -1268,6 +1268,7 @@ tst_QDir::cleanPath_data() QTest::newRow("drive-above-root") << "A:/.." << "A:/.."; QTest::newRow("unc-server-up") << "//server/path/.." << "//server"; QTest::newRow("unc-server-above-root") << "//server/.." << "//server/.."; + QTest::newRow("longpath") << "\\\\?\\d:\\" << "d:/"; #else QTest::newRow("data15") << "//c:/foo" << "/c:/foo"; #endif // non-windows @@ -1745,6 +1746,7 @@ void tst_QDir::nativeSeparators() QCOMPARE(QDir::toNativeSeparators(QLatin1String("\\")), QString("\\")); QCOMPARE(QDir::fromNativeSeparators(QLatin1String("/")), QString("/")); QCOMPARE(QDir::fromNativeSeparators(QLatin1String("\\")), QString("/")); + QCOMPARE(QDir::fromNativeSeparators(QLatin1String("\\\\?\\C:\\")), QString("C:/")); #else QCOMPARE(QDir::toNativeSeparators(QLatin1String("/")), QString("/")); QCOMPARE(QDir::toNativeSeparators(QLatin1String("\\")), QString("\\")); From 69ef6e821287d324459336dd1292d19d272386b8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 6 Jul 2019 09:46:00 -0300 Subject: [PATCH 128/264] QStandardPaths: update docs to what $HOME is on iOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's not (any more, or was ever). Fixes: QTBUG-76911 Change-Id: I6aed4df6a12e43c3ac8efffd15aed22128862c23 Reviewed-by: Tor Arne Vestbø --- src/corelib/io/qstandardpaths.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp index dbf650d5f6..f56fef7f8e 100644 --- a/src/corelib/io/qstandardpaths.cpp +++ b/src/corelib/io/qstandardpaths.cpp @@ -297,7 +297,7 @@ QT_BEGIN_NAMESPACE \li "/tmp" \row \li HomeLocation \li "/files" - \li "" (not writable) + \li system defined \row \li DataLocation \li "/files", "//files" \li "/Library/Application Support" From 334f09b585b9a90bc3dde0fcda4ebec67478d7a3 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Tue, 16 Jul 2019 12:27:34 +0200 Subject: [PATCH 129/264] tst_http2 - make the test less rough in general 1. Use per-case QNAM objects 2. In a slots (connected to QNetworkReplies) - if an error detected - stop the event loop (no reason to continue waiting) and then do normal QVERIFY/QCOMPARE things. 3. In tests, check QTest::currentTestFailed after the event loop returned - if an error was detected by a slot, no need to continue with QCOMPARE/QVERIFY in the test itself. Task-number: QTBUG-77053 Change-Id: I3827a629a2749becd3dc6eee7fd6994d96441e65 Reviewed-by: Edward Welbourne --- tests/auto/network/access/http2/tst_http2.cpp | 51 +++++++++++++++---- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp index 579eb89c0a..f7d74e66b2 100644 --- a/tests/auto/network/access/http2/tst_http2.cpp +++ b/tests/auto/network/access/http2/tst_http2.cpp @@ -46,6 +46,7 @@ #endif // NO_SSL #include +#include #include #include "emulationdetector.h" @@ -116,7 +117,7 @@ private: quint16 serverPort = 0; QThread *workerThread = nullptr; - QNetworkAccessManager manager; + std::unique_ptr manager; QTestEventLoop eventLoop; @@ -130,6 +131,10 @@ private: static const Http2::RawSettings defaultServerSettings; }; +#define STOP_ON_FAILURE \ + if (QTest::currentTestFailed()) \ + return; + const Http2::RawSettings tst_Http2::defaultServerSettings{{Http2::Settings::MAX_CONCURRENT_STREAMS_ID, 100}}; namespace { @@ -177,7 +182,7 @@ tst_Http2::~tst_Http2() void tst_Http2::init() { - manager.clearConnectionCache(); + manager.reset(new QNetworkAccessManager); } void tst_Http2::singleRequest_data() @@ -234,13 +239,14 @@ void tst_Http2::singleRequest() QFETCH(const QNetworkRequest::Attribute, h2Attribute); request.setAttribute(h2Attribute, QVariant(true)); - auto reply = manager.get(request); + auto reply = manager->get(request); connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished); // Since we're using self-signed certificates, // ignore SSL errors: reply->ignoreSslErrors(); runEventLoop(); + STOP_ON_FAILURE QVERIFY(nRequests == 0); QVERIFY(prefaceOK); @@ -276,6 +282,7 @@ void tst_Http2::multipleRequests() sendRequest(i, priorities[QRandomGenerator::global()->bounded(3)]); runEventLoop(); + STOP_ON_FAILURE QVERIFY(nRequests == 0); QVERIFY(prefaceOK); @@ -305,7 +312,7 @@ void tst_Http2::flowControlClientSide() params.maxSessionReceiveWindowSize = Http2::defaultSessionWindowSize * 5; params.settingsFrameData[Settings::INITIAL_WINDOW_SIZE_ID] = Http2::defaultSessionWindowSize; // Inform our manager about non-default settings: - manager.setProperty(Http2::http2ParametersPropertyName, QVariant::fromValue(params)); + manager->setProperty(Http2::http2ParametersPropertyName, QVariant::fromValue(params)); const Http2::RawSettings serverSettings = {{Settings::MAX_CONCURRENT_STREAMS_ID, quint32(3)}}; ServerPtr srv(newServer(serverSettings, defaultConnectionType(), params)); @@ -323,6 +330,7 @@ void tst_Http2::flowControlClientSide() sendRequest(i); runEventLoop(120000); + STOP_ON_FAILURE QVERIFY(nRequests == 0); QVERIFY(prefaceOK); @@ -363,6 +371,7 @@ void tst_Http2::flowControlServerSide() sendRequest(i, QNetworkRequest::NormalPriority, payload); runEventLoop(120000); + STOP_ON_FAILURE QVERIFY(nRequests == 0); QVERIFY(prefaceOK); @@ -383,7 +392,7 @@ void tst_Http2::pushPromise() Http2::ProtocolParameters params; // Defaults are good, except ENABLE_PUSH: params.settingsFrameData[Settings::ENABLE_PUSH_ID] = 1; - manager.setProperty(Http2::http2ParametersPropertyName, QVariant::fromValue(params)); + manager->setProperty(Http2::http2ParametersPropertyName, QVariant::fromValue(params)); ServerPtr srv(newServer(defaultServerSettings, defaultConnectionType(), params)); srv->enablePushPromise(true, QByteArray("/script.js")); @@ -399,12 +408,13 @@ void tst_Http2::pushPromise() QNetworkRequest request(url); request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, QVariant(true)); - auto reply = manager.get(request); + auto reply = manager->get(request); connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished); // Since we're using self-signed certificates, ignore SSL errors: reply->ignoreSslErrors(); runEventLoop(); + STOP_ON_FAILURE QVERIFY(nRequests == 0); QVERIFY(prefaceOK); @@ -422,7 +432,7 @@ void tst_Http2::pushPromise() url.setPath("/script.js"); QNetworkRequest promisedRequest(url); promisedRequest.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, QVariant(true)); - reply = manager.get(promisedRequest); + reply = manager->get(promisedRequest); connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished); reply->ignoreSslErrors(); @@ -473,7 +483,7 @@ void tst_Http2::goaway() url.setPath(QString("/%1").arg(i)); QNetworkRequest request(url); request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, QVariant(true)); - replies[i] = manager.get(request); + replies[i] = manager->get(request); QCOMPARE(replies[i]->error(), QNetworkReply::NoError); void (QNetworkReply::*errorSignal)(QNetworkReply::NetworkError) = &QNetworkReply::error; @@ -483,6 +493,7 @@ void tst_Http2::goaway() } runEventLoop(5000 + responseTimeoutMS); + STOP_ON_FAILURE // No request processed, no 'replyFinished' slot calls: QCOMPARE(nRequests, 0); @@ -526,6 +537,7 @@ void tst_Http2::earlyResponse() sendRequest(1, QNetworkRequest::NormalPriority, {1000000, Qt::Uninitialized}); runEventLoop(); + STOP_ON_FAILURE QVERIFY(nRequests == 0); QVERIFY(prefaceOK); @@ -543,7 +555,7 @@ void tst_Http2::clearHTTP2State() windowUpdates = 0; prefaceOK = false; serverGotSettingsACK = false; - manager.setProperty(Http2::http2ParametersPropertyName, QVariant()); + manager->setProperty(Http2::http2ParametersPropertyName, QVariant()); } void tst_Http2::runEventLoop(int ms) @@ -596,9 +608,9 @@ void tst_Http2::sendRequest(int streamNumber, QNetworkReply *reply = nullptr; if (payload.size()) - reply = manager.post(request, payload); + reply = manager->post(request, payload); else - reply = manager.get(request); + reply = manager->get(request); reply->ignoreSslErrors(); connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished); @@ -690,14 +702,29 @@ void tst_Http2::replyFinished() QVERIFY(nRequests); if (const auto reply = qobject_cast(sender())) { + if (reply->error() != QNetworkReply::NoError) + stopEventLoop(); + QCOMPARE(reply->error(), QNetworkReply::NoError); + const QVariant http2Used(reply->attribute(QNetworkRequest::HTTP2WasUsedAttribute)); + if (!http2Used.isValid() || !http2Used.toBool()) + stopEventLoop(); + QVERIFY(http2Used.isValid()); QVERIFY(http2Used.toBool()); + const QVariant spdyUsed(reply->attribute(QNetworkRequest::SpdyWasUsedAttribute)); + if (!spdyUsed.isValid() || spdyUsed.toBool()) + stopEventLoop(); + QVERIFY(spdyUsed.isValid()); QVERIFY(!spdyUsed.toBool()); + const QVariant code(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute)); + if (!code.isValid() || !code.canConvert() || code.value() != 200) + stopEventLoop(); + QVERIFY(code.isValid()); QVERIFY(code.canConvert()); QCOMPARE(code.value(), 200); @@ -715,6 +742,8 @@ void tst_Http2::replyFinishedWithError() if (const auto reply = qobject_cast(sender())) { // For now this is a 'generic' code, it just verifies some error was // reported without testing its type. + if (reply->error() == QNetworkReply::NoError) + stopEventLoop(); QVERIFY(reply->error() != QNetworkReply::NoError); } From c187d5824487b1d5f04bc504c04608c562922d4a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 27 Jun 2019 19:24:49 +0200 Subject: [PATCH 130/264] QtNetwork: ssl: port from QMutex::Recursive to QRecursiveMutex Change-Id: I78913fee6720f6ad9b196824b35de189567340be Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslsocket_mac.cpp | 2 +- src/network/ssl/qsslsocket_openssl11.cpp | 2 +- src/network/ssl/qsslsocket_schannel.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp index 487e975db6..1725937bc2 100644 --- a/src/network/ssl/qsslsocket_mac.cpp +++ b/src/network/ssl/qsslsocket_mac.cpp @@ -215,7 +215,7 @@ void QSecureTransportContext::reset(SSLContextRef newContext) context = newContext; } -Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_securetransport_mutex, (QMutex::Recursive)) +Q_GLOBAL_STATIC(QRecursiveMutex, qt_securetransport_mutex) //#define QSSLSOCKET_DEBUG diff --git a/src/network/ssl/qsslsocket_openssl11.cpp b/src/network/ssl/qsslsocket_openssl11.cpp index cc2d6ea2d9..28be4f2e79 100644 --- a/src/network/ssl/qsslsocket_openssl11.cpp +++ b/src/network/ssl/qsslsocket_openssl11.cpp @@ -72,7 +72,7 @@ QT_BEGIN_NAMESPACE -Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_opensslInitMutex, (QMutex::Recursive)) +Q_GLOBAL_STATIC(QRecursiveMutex, qt_opensslInitMutex) void QSslSocketPrivate::deinitialize() { diff --git a/src/network/ssl/qsslsocket_schannel.cpp b/src/network/ssl/qsslsocket_schannel.cpp index 1314b432a4..c254659a33 100644 --- a/src/network/ssl/qsslsocket_schannel.cpp +++ b/src/network/ssl/qsslsocket_schannel.cpp @@ -431,7 +431,7 @@ QByteArray createAlpnString(const QByteArrayList &nextAllowedProtocols) bool QSslSocketPrivate::s_loadRootCertsOnDemand = true; bool QSslSocketPrivate::s_loadedCiphersAndCerts = false; -Q_GLOBAL_STATIC_WITH_ARGS(QMutex, qt_schannel_mutex, (QMutex::Recursive)) +Q_GLOBAL_STATIC(QRecursiveMutex, qt_schannel_mutex) void QSslSocketPrivate::ensureInitialized() { From 8abef0277797724b153cb08c11bf498efc6d460d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 8 Jul 2019 14:33:15 +0200 Subject: [PATCH 131/264] QHostInfo: add nothrow move constructor QHostInfo isn't implicitly shared. The more important to optimize away copies by providing a move constructor. Port from QScopedPointer to Q_DECLARE_PRIVATE, as otherwise the move ctor can't be inline, and we don't implement move ctors out-of-line in Qt. [ChangeLog][QtNetwork][QHostInfo] Added move contructor. Change-Id: I6b63a04e36f63e299205830fdc590ff7e2af338b Reviewed-by: Timur Pocheptsov --- src/network/kernel/qhostinfo.cpp | 31 ++++++++++++++++++++++++++++--- src/network/kernel/qhostinfo.h | 6 ++++-- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index c17ba38e36..a5e50ff21b 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -594,8 +594,9 @@ QHostInfo QHostInfoAgent::lookup(const QString &hostName) \sa lookupId() */ QHostInfo::QHostInfo(int id) - : d(new QHostInfoPrivate) + : d_ptr(new QHostInfoPrivate) { + Q_D(QHostInfo); d->lookupId = id; } @@ -603,17 +604,30 @@ QHostInfo::QHostInfo(int id) Constructs a copy of \a other. */ QHostInfo::QHostInfo(const QHostInfo &other) - : d(new QHostInfoPrivate(*other.d.data())) + : d_ptr(new QHostInfoPrivate(*other.d_ptr)) { } +/*! + Move-constucts a new QHostInfo from \a other. + + \note The moved-from object \a other is placed in a + partially-formed state, in which the only valid operations are + destruction and assignment of a new value. + + \since 5.14 +*/ + /*! Assigns the data of the \a other object to this host info object, and returns a reference to it. */ QHostInfo &QHostInfo::operator=(const QHostInfo &other) { - *d.data() = *other.d.data(); + if (d_ptr) + *d_ptr = *other.d_ptr; + else + d_ptr = new QHostInfoPrivate(*other.d_ptr); return *this; } @@ -622,6 +636,7 @@ QHostInfo &QHostInfo::operator=(const QHostInfo &other) */ QHostInfo::~QHostInfo() { + delete d_ptr; } /*! @@ -636,6 +651,7 @@ QHostInfo::~QHostInfo() */ QList QHostInfo::addresses() const { + Q_D(const QHostInfo); return d->addrs; } @@ -646,6 +662,7 @@ QList QHostInfo::addresses() const */ void QHostInfo::setAddresses(const QList &addresses) { + Q_D(QHostInfo); d->addrs = addresses; } @@ -656,6 +673,7 @@ void QHostInfo::setAddresses(const QList &addresses) */ QString QHostInfo::hostName() const { + Q_D(const QHostInfo); return d->hostName; } @@ -666,6 +684,7 @@ QString QHostInfo::hostName() const */ void QHostInfo::setHostName(const QString &hostName) { + Q_D(QHostInfo); d->hostName = hostName; } @@ -677,6 +696,7 @@ void QHostInfo::setHostName(const QString &hostName) */ QHostInfo::HostInfoError QHostInfo::error() const { + Q_D(const QHostInfo); return d->err; } @@ -687,6 +707,7 @@ QHostInfo::HostInfoError QHostInfo::error() const */ void QHostInfo::setError(HostInfoError error) { + Q_D(QHostInfo); d->err = error; } @@ -697,6 +718,7 @@ void QHostInfo::setError(HostInfoError error) */ int QHostInfo::lookupId() const { + Q_D(const QHostInfo); return d->lookupId; } @@ -707,6 +729,7 @@ int QHostInfo::lookupId() const */ void QHostInfo::setLookupId(int id) { + Q_D(QHostInfo); d->lookupId = id; } @@ -718,6 +741,7 @@ void QHostInfo::setLookupId(int id) */ QString QHostInfo::errorString() const { + Q_D(const QHostInfo); return d->errorStr; } @@ -729,6 +753,7 @@ QString QHostInfo::errorString() const */ void QHostInfo::setErrorString(const QString &str) { + Q_D(QHostInfo); d->errorStr = str; } diff --git a/src/network/kernel/qhostinfo.h b/src/network/kernel/qhostinfo.h index dc31cc08e4..cda286b423 100644 --- a/src/network/kernel/qhostinfo.h +++ b/src/network/kernel/qhostinfo.h @@ -62,11 +62,12 @@ public: explicit QHostInfo(int lookupId = -1); QHostInfo(const QHostInfo &d); + QHostInfo(QHostInfo &&other) noexcept : d_ptr(qExchange(other.d_ptr, nullptr)) {} QHostInfo &operator=(const QHostInfo &d); QHostInfo &operator=(QHostInfo &&other) noexcept { swap(other); return *this; } ~QHostInfo(); - void swap(QHostInfo &other) noexcept { qSwap(d, other.d); } + void swap(QHostInfo &other) noexcept { qSwap(d_ptr, other.d_ptr); } QString hostName() const; void setHostName(const QString &name); @@ -147,7 +148,8 @@ public: #endif // Q_QDOC private: - QScopedPointer d; + QHostInfoPrivate *d_ptr; + Q_DECLARE_PRIVATE(QHostInfo) static int lookupHostImpl(const QString &name, const QObject *receiver, From a7de860cfd3f86fb8df8795e0322f67fd04c4ef0 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 11 Jul 2019 23:38:47 +0200 Subject: [PATCH 132/264] QMovie: move-enable QFrameInfo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All users of the QPixmap ctor can pass rvalues, so take by rvalue-ref and move into place. Adapt callers to actually pass rvalues. Change-Id: Iacff2ed893ceaa1665b270ce466ffdc21ba800f1 Reviewed-by: Mårten Nordheim --- src/gui/image/qmovie.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/gui/image/qmovie.cpp b/src/gui/image/qmovie.cpp index 4b588527ae..3e975115ab 100644 --- a/src/gui/image/qmovie.cpp +++ b/src/gui/image/qmovie.cpp @@ -207,8 +207,8 @@ public: : pixmap(QPixmap()), delay(QMOVIE_INVALID_DELAY), endMark(false) { } - inline QFrameInfo(const QPixmap &pixmap, int delay) - : pixmap(pixmap), delay(delay), endMark(false) + inline QFrameInfo(QPixmap &&pixmap, int delay) + : pixmap(std::move(pixmap)), delay(delay), endMark(false) { } inline bool isValid() @@ -222,6 +222,7 @@ public: static inline QFrameInfo endMarker() { return QFrameInfo(true); } }; +Q_DECLARE_TYPEINFO(QFrameInfo, Q_MOVABLE_TYPE); class QMoviePrivate : public QObjectPrivate { @@ -380,9 +381,7 @@ QFrameInfo QMoviePrivate::infoForFrame(int frameNumber) } if (frameNumber > greatestFrameNumber) greatestFrameNumber = frameNumber; - QPixmap aPixmap = QPixmap::fromImage(std::move(anImage)); - int aDelay = reader->nextImageDelay(); - return QFrameInfo(aPixmap, aDelay); + return QFrameInfo(QPixmap::fromImage(std::move(anImage)), reader->nextImageDelay()); } else if (frameNumber != 0) { // We've read all frames now. Return an end marker haveReadAll = true; @@ -406,9 +405,7 @@ QFrameInfo QMoviePrivate::infoForFrame(int frameNumber) return QFrameInfo(); // Invalid } greatestFrameNumber = i; - QPixmap aPixmap = QPixmap::fromImage(std::move(anImage)); - int aDelay = reader->nextImageDelay(); - QFrameInfo info(aPixmap, aDelay); + QFrameInfo info(QPixmap::fromImage(std::move(anImage)), reader->nextImageDelay()); // Cache it! frameMap.insert(i, info); if (i == frameNumber) { From e0ea987994fb33e367ddfc237180863b8bb3a401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Wed, 17 Jul 2019 09:33:55 +0200 Subject: [PATCH 133/264] tst_qnetworkreply: skip ssl session sharing tests with schannel It's not implemented Change-Id: I56abb0a5fe0e6d5c2f5f678adadafed395456902 Reviewed-by: Timur Pocheptsov Reviewed-by: Edward Welbourne --- .../network/access/qnetworkreply/tst_qnetworkreply.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 6f00780d81..edf345685f 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -6474,8 +6474,8 @@ void tst_QNetworkReply::sslSessionSharing_data() void tst_QNetworkReply::sslSessionSharing() { -#ifdef QT_SECURETRANSPORT - QSKIP("Not implemented with SecureTransport"); +#if QT_CONFIG(schannel) || defined(QT_SECURETRANSPORT) + QSKIP("Not implemented with SecureTransport/Schannel"); #endif QString urlString("https://" + QtNetworkSettings::httpServerName()); @@ -6542,8 +6542,8 @@ void tst_QNetworkReply::sslSessionSharingFromPersistentSession_data() void tst_QNetworkReply::sslSessionSharingFromPersistentSession() { -#ifdef QT_SECURETRANSPORT - QSKIP("Not implemented with SecureTransport"); +#if QT_CONFIG(schannel) || defined(QT_SECURETRANSPORT) + QSKIP("Not implemented with SecureTransport/Schannel"); #endif QString urlString("https://" + QtNetworkSettings::httpServerName()); From d35aedc1253ec99997f99e422a66c29e51e331b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Wed, 17 Jul 2019 09:34:45 +0200 Subject: [PATCH 134/264] tst_qnetworkreply: Use object.connect() to get rid of warning warning C4573: the usage of 'tst_QNetworkReply::connect' requires the compiler to capture 'this' but the current default capture mode does not allow it Change-Id: Ic9fd526fedf7c52e53e2b1136834c10bf4cd0ea9 Reviewed-by: Timur Pocheptsov Reviewed-by: Marc Mutz --- tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index edf345685f..418e1caf68 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -6426,7 +6426,8 @@ void tst_QNetworkReply::abortOnEncrypted() QSKIP("Server fails to listen. Skipping since QTcpServer is covered in another test."); server.connect(&server, &SslServer::newEncryptedConnection, [&server]() { - connect(server.socket, &QTcpSocket::readyRead, server.socket, []() { + // MSVC 201X C4573-misunderstands connect() or QObject::connect(), so use server.connect(): + server.connect(server.socket, &QTcpSocket::readyRead, server.socket, []() { // This slot must not be invoked! QVERIFY(false); }); From eaceabe9ac0dbc659ba4683a0dd66effcec461f6 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 4 Jul 2019 16:59:32 +0200 Subject: [PATCH 135/264] QHostInfo: port from recursive to non-recursive mutex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It turns out that the only reason a recursive mutex is used was because work() was locking it. But work() was only ever called from functions that already had locked the mutex themselves, and kept it locked across the call to work(). Clearly mark work() as expecting to be called with the mutex held (by renaming the function to rescheduleWithMutexHeld(), then drop the mutex locking from it. After this change, a non-recursive mutex suffices, so save the memory allocation and extra complexity involved with recursive mutexes. Looking at the non-QT_CONFIG(thread) code in rescheduleWithMutexHeld(), one might be tempted to expect a recursive mutex, since that code calls QHostInfoRunnable::run() directly, which, in turn, recurses into QHostInfoLookupManager whence control came, under mutex lock. But in non-QT_CONFIG(thread) builds, QMutex is but an empty shell, all of its operations are no-ops, so no possibility for deadlock, either. Change-Id: Ic01d90c2ed3995b66ccf946d146fdaa6f9af3d8b Reviewed-by: Mårten Nordheim --- src/network/kernel/qhostinfo.cpp | 9 ++++----- src/network/kernel/qhostinfo_p.h | 6 ++++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index a5e50ff21b..483ab875c6 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -944,10 +944,9 @@ void QHostInfoLookupManager::clear() cache.clear(); } -void QHostInfoLookupManager::work() +// assumes mutex is locked by caller +void QHostInfoLookupManager::rescheduleWithMutexHeld() { - QMutexLocker locker(&mutex); - if (wasDeleted) return; @@ -1012,7 +1011,7 @@ void QHostInfoLookupManager::scheduleLookup(QHostInfoRunnable *r) return; scheduledLookups.enqueue(r); - work(); + rescheduleWithMutexHeld(); } // called by QHostInfo @@ -1068,7 +1067,7 @@ void QHostInfoLookupManager::lookupFinished(QHostInfoRunnable *r) currentLookups.removeOne(r); #endif finishedLookups.append(r); - work(); + rescheduleWithMutexHeld(); } // This function returns immediately when we had a result in the cache, else it will later emit a signal diff --git a/src/network/kernel/qhostinfo_p.h b/src/network/kernel/qhostinfo_p.h index 0433d1d17b..f5b630346c 100644 --- a/src/network/kernel/qhostinfo_p.h +++ b/src/network/kernel/qhostinfo_p.h @@ -232,7 +232,6 @@ public: ~QHostInfoLookupManager(); void clear() override; - void work(); // called from QHostInfo void scheduleLookup(QHostInfoRunnable *r); @@ -255,10 +254,13 @@ protected: #if QT_CONFIG(thread) QThreadPool threadPool; #endif - QRecursiveMutex mutex; + QMutex mutex; bool wasDeleted; +private: + void rescheduleWithMutexHeld(); + private slots: #if QT_CONFIG(thread) void waitForThreadPoolDone() { threadPool.waitForDone(); } From 7f948d9effad983477977c3274231401f260c531 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Thu, 4 Jul 2019 13:56:44 +0200 Subject: [PATCH 136/264] Disable experimental xcb native painting config option by default Saves 13% on the binary size. Change-Id: I3be0957b80eec5d3c8b75b4d3f1784e4bd6b5e2a Reviewed-by: Gatis Paeglis --- src/gui/configure.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/configure.json b/src/gui/configure.json index 764e92a729..5aac1f221a 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -1550,6 +1550,7 @@ }, "xcb-native-painting": { "label": "Native painting (experimental)", + "autoDetect": false, "emitIf": "features.xcb", "condition": "features.xcb-xlib && features.fontconfig && libs.xrender", "output": [ "privateFeature" ] From 907923b7cafad8cff6f0f5c8764e9181ac1531bd Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 17 Jul 2019 18:03:19 +0200 Subject: [PATCH 137/264] qmake: fix move semantics ProFunctionDef is move-enabled, meaning its `m_pro` field can become nullptr. Its usage in the assignment operator and the dtor must therefore be protected with a check. Amends 9c63ad562bf0a44807f41ce49e4fe1b5ff181a63. Change-Id: I0c77b07dc83969565480bbb9d9fc80751d4246b1 Reviewed-by: Marc Mutz --- qmake/library/proitems.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h index 0e0bebddc7..936c729ff8 100644 --- a/qmake/library/proitems.h +++ b/qmake/library/proitems.h @@ -432,11 +432,12 @@ public: ProFunctionDef(const ProFunctionDef &o) : m_pro(o.m_pro), m_offset(o.m_offset) { m_pro->ref(); } ProFunctionDef(ProFunctionDef &&other) Q_DECL_NOTHROW : m_pro(other.m_pro), m_offset(other.m_offset) { other.m_pro = nullptr; } - ~ProFunctionDef() { m_pro->deref(); } + ~ProFunctionDef() { if (m_pro) m_pro->deref(); } ProFunctionDef &operator=(const ProFunctionDef &o) { if (this != &o) { - m_pro->deref(); + if (m_pro) + m_pro->deref(); m_pro = o.m_pro; m_pro->ref(); m_offset = o.m_offset; From de775f2e62157a6d572b4c363bee48b84d3be630 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 12 Jul 2019 12:22:30 +0200 Subject: [PATCH 138/264] macOS: activate correct object when using multiple QSystemTrayIcons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we need to set the delegate on the defaultUserNotificationCenter, which is a gobal object, we have to update the delegate when we show the message. Otherwise, the last delegate created and set will receive the notification, and the last QSystemTrayIcon created will emit the activated signal. Before clearing the delegate upon destruction, make sure that it's the right item first. Also updating coding style in the respective parts of the code, and plugging a memory leak. Change-Id: Ife62ae0776a5a610a6fd735b2959b807c3a410c7 Fixes: QTBUG-77003 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm index 16543bfb8c..597cfa8318 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm @@ -118,11 +118,13 @@ class QSystemTrayIconSys public: QSystemTrayIconSys(QCocoaSystemTrayIcon *sys) { item = [[QNSStatusItem alloc] initWithSysTray:sys]; - [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:item]; + NSUserNotificationCenter.defaultUserNotificationCenter.delegate = item; } ~QSystemTrayIconSys() { [[[item item] view] setHidden: YES]; - [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:nil]; + NSUserNotificationCenter *center = NSUserNotificationCenter.defaultUserNotificationCenter; + if (center.delegate == item) + center.delegate = nil; [item release]; } QNSStatusItem *item; @@ -277,7 +279,10 @@ void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &mess notification.contentImage = [nsimage autorelease]; } - [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; + NSUserNotificationCenter *center = NSUserNotificationCenter.defaultUserNotificationCenter; + center.delegate = m_sys->item; + [center deliverNotification:notification]; + [notification release]; } QT_END_NAMESPACE From 92563a24534c7579b20be0275cd5d8da9e0cd085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 18 Jul 2019 15:19:25 +0200 Subject: [PATCH 139/264] macOS: Allow overriding NSKeyValueObservingOptions for QMacKeyValueObserver Change-Id: I6dc0f7c542ccfb768c1cd8688168c415e2c8a087 Reviewed-by: Volker Hilsheimer --- src/corelib/kernel/qcore_mac_objc.mm | 5 ++--- src/corelib/kernel/qcore_mac_p.h | 10 +++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 9139b372a8..266faca0ed 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -514,10 +514,9 @@ Q_CONSTRUCTOR_FUNCTION(qt_apple_check_os_version); // ------------------------------------------------------------------------- -void QMacKeyValueObserver::addObserver() +void QMacKeyValueObserver::addObserver(NSKeyValueObservingOptions options) { - [object addObserver:observer forKeyPath:keyPath - options:NSKeyValueObservingOptionNew context:callback.get()]; + [object addObserver:observer forKeyPath:keyPath options:options context:callback.get()]; } void QMacKeyValueObserver::removeObserver() { diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index 8f4c96bbd6..168e0418e4 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -350,8 +350,12 @@ public: QMacKeyValueObserver() {} // Note: QMacKeyValueObserver must not outlive the object observed! - QMacKeyValueObserver(id object, NSString *keyPath, Callback callback) - : object(object), keyPath(keyPath), callback(new Callback(callback)) { addObserver(); } + QMacKeyValueObserver(id object, NSString *keyPath, Callback callback, + NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew) + : object(object), keyPath(keyPath), callback(new Callback(callback)) + { + addObserver(options); + } QMacKeyValueObserver(const QMacKeyValueObserver &other) : QMacKeyValueObserver(other.object, other.keyPath, *other.callback.get()) {} @@ -381,7 +385,7 @@ private: std::swap(first.callback, second.callback); } - void addObserver(); + void addObserver(NSKeyValueObservingOptions options); id object = nil; NSString *keyPath = nullptr; From 82aabafadad2010f0f20abeeb7234057e3c10e9f Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Fri, 11 Jan 2019 15:57:56 +0100 Subject: [PATCH 140/264] Fix loading of image files with wrong, but known, file name extension If QImageReader recognized the suffix of a file, it would by default not check if the file contents matched the claimed format. Hence, a valid but misnamed image file would fail to load. Fix by adding contents check for suffix-recognized files. [ChangeLog][QtGui][Image] Loading of image files having a file name suffix for a different image file type has been fixed. QImageReader will now ask the suffix format handler to confirm the file contents (canRead()), and fall back to normal file content recognition on failure. This implies a slight behavior change in QImageReader::loopCount(), ::imageCount() and ::nextImageDelay(): For an unreadable file with a recognized suffix, they would earlier return 0, while they now will return -1, i.e. error as per the documentation. Fixes: QTBUG-42540 Fixes: QTBUG-68787 Change-Id: I205e83f29ed7190cbcae95dab960232544d012f6 Reviewed-by: Allan Sandfeld Jensen --- src/gui/image/qimagereader.cpp | 27 +++++++++++++++++-- .../qicoimageformat/tst_qicoimageformat.cpp | 8 +++--- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 25b9698559..6a0763e696 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -197,7 +197,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device, #ifdef QIMAGEREADER_DEBUG qDebug() << "QImageReader::createReadHandler( device =" << (void *)device << ", format =" << format << ")," - << keyMap.size() << "plugins available: " << keyMap.values(); + << keyMap.uniqueKeys().size() << "plugins available: " << keyMap; #endif int suffixPluginIndex = -1; @@ -325,6 +325,29 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device, #endif } + if (handler && device && !suffix.isEmpty()) { + Q_ASSERT(qobject_cast(device)); + // We have a file claiming to be of a recognized format. Now confirm that + // the handler also recognizes the file contents. + const qint64 pos = device->pos(); + handler->setDevice(device); + if (!form.isEmpty()) + handler->setFormat(form); + bool canRead = handler->canRead(); + device->seek(pos); + if (canRead) { + // ok, we're done. + return handler; + } +#ifdef QIMAGEREADER_DEBUG + qDebug() << "QImageReader::createReadHandler: the" << suffix << "handler can not read this file"; +#endif + // File may still be valid, just with wrong suffix, so fall back to + // finding a handler based on contents, below. + delete handler; + handler = nullptr; + } + #ifndef QT_NO_IMAGEFORMATPLUGIN if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) { // check if any of our plugins recognize the file from its contents. @@ -336,7 +359,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device, if (plugin && plugin->capabilities(device, QByteArray()) & QImageIOPlugin::CanRead) { handler = plugin->create(device, testFormat); #ifdef QIMAGEREADER_DEBUG - qDebug() << "QImageReader::createReadHandler: the" << keyMap.keys().at(i) << "plugin can read this data"; + qDebug() << "QImageReader::createReadHandler: the" << keyMap.value(i) << "plugin can read this data"; #endif break; } diff --git a/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp b/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp index 2dbb078ae0..fe12175081 100644 --- a/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp +++ b/tests/auto/gui/image/qicoimageformat/tst_qicoimageformat.cpp @@ -164,7 +164,7 @@ void tst_QIcoImageFormat::imageCount_data() QTest::newRow("16px,32px - 16 colors") << "valid/TIMER01.ICO" << 2; QTest::newRow("16px16c, 32px32c, 32px256c 1") << "valid/WORLD.ico" << 3; QTest::newRow("16px16c, 32px32c, 32px256c 2") << "valid/WORLDH.ico" << 3; - QTest::newRow("invalid floppy (first 8 bytes = 0xff)") << "invalid/35floppy.ico" << 0; + QTest::newRow("invalid floppy (first 8 bytes = 0xff)") << "invalid/35floppy.ico" << -1; QTest::newRow("includes 32BPP w/alpha") << "valid/semitransparent.ico" << 9; QTest::newRow("PNG compression") << "valid/Qt.ico" << 4; QTest::newRow("CUR file") << "valid/yellow.cur" << 1; @@ -177,7 +177,6 @@ void tst_QIcoImageFormat::imageCount() QImageReader reader(m_IconPath + QLatin1Char('/') + fileName); QCOMPARE(reader.imageCount(), count); - } void tst_QIcoImageFormat::jumpToNextImage_data() @@ -218,7 +217,7 @@ void tst_QIcoImageFormat::loopCount_data() QTest::addColumn("count"); QTest::newRow("floppy (16px,32px - 16 colors)") << "valid/35FLOPPY.ICO" << 0; - QTest::newRow("invalid floppy (first 8 bytes = 0xff)") << "invalid/35floppy.ico" << 0; + QTest::newRow("invalid floppy (first 8 bytes = 0xff)") << "invalid/35floppy.ico" << -1; } void tst_QIcoImageFormat::loopCount() @@ -228,6 +227,7 @@ void tst_QIcoImageFormat::loopCount() QImageReader reader(m_IconPath + QLatin1Char('/') + fileName); QCOMPARE(reader.loopCount(), count); + QCOMPARE(reader.canRead(), count < 0 ? false : true); } void tst_QIcoImageFormat::nextImageDelay_data() @@ -256,7 +256,7 @@ void tst_QIcoImageFormat::nextImageDelay() QImageReader reader(m_IconPath + QLatin1Char('/') + fileName); if (count == -1) { - QCOMPARE(reader.nextImageDelay(), 0); + QCOMPARE(reader.nextImageDelay(), -1); } else { int i; for (i = 0; i < count; i++) { From af683471bde93d1859544e7fd4c0638995b1fd5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 17 Jul 2019 18:09:47 +0200 Subject: [PATCH 141/264] macOS: Add QCocoaWindowManager for dealing with window levels Moves and improves the logic for lowering splash screens to a dedicated window manager, which will learn more tricks in patches to come. Change-Id: I8b8fd1dd78fdaf6f106a59c84d2a59254f3539c3 Reviewed-by: Volker Hilsheimer Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/cocoa.pro | 2 + .../platforms/cocoa/qcocoaintegration.mm | 19 --- .../platforms/cocoa/qcocoawindowmanager.h | 63 ++++++++++ .../platforms/cocoa/qcocoawindowmanager.mm | 108 ++++++++++++++++++ 4 files changed, 173 insertions(+), 19 deletions(-) create mode 100644 src/plugins/platforms/cocoa/qcocoawindowmanager.h create mode 100644 src/plugins/platforms/cocoa/qcocoawindowmanager.mm diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro index 083b7c1655..02e00039ae 100644 --- a/src/plugins/platforms/cocoa/cocoa.pro +++ b/src/plugins/platforms/cocoa/cocoa.pro @@ -6,6 +6,7 @@ SOURCES += main.mm \ qcocoatheme.mm \ qcocoabackingstore.mm \ qcocoawindow.mm \ + qcocoawindowmanager.mm \ qnsview.mm \ qnswindow.mm \ qnswindowdelegate.mm \ @@ -41,6 +42,7 @@ HEADERS += qcocoaintegration.h \ qcocoatheme.h \ qcocoabackingstore.h \ qcocoawindow.h \ + qcocoawindowmanager.h \ qnsview.h \ qnswindow.h \ qnswindowdelegate.h \ diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index dd2d1ba0f1..1eed6b5582 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -217,25 +217,6 @@ QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList) connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &QCocoaIntegration::focusWindowChanged); - - static auto splashScreenHider = QMacKeyValueObserver(NSApp, @"modalWindow", []{ - const QWindowList allWindows = QGuiApplication::topLevelWindows(); - for (QWindow *window : allWindows) { - if ((window->flags() & Qt::SplashScreen) == Qt::SplashScreen) { - QCocoaWindow *platformWindow = static_cast(window->handle()); - NSWindow *splashWindow = platformWindow->view().window; - if (!splashWindow) - continue; - if (NSApp.modalWindow) { - NSInteger originalLevel = splashWindow.level; - splashWindow.level = NSNormalWindowLevel; - window->setProperty("_q_levelBeforeModalSession", (qlonglong)originalLevel); - } else if (NSInteger originalLevel = window->property("_q_levelBeforeModalSession").toLongLong()) { - splashWindow.level = originalLevel; - } - } - } - }); } QCocoaIntegration::~QCocoaIntegration() diff --git a/src/plugins/platforms/cocoa/qcocoawindowmanager.h b/src/plugins/platforms/cocoa/qcocoawindowmanager.h new file mode 100644 index 0000000000..54f17eeccd --- /dev/null +++ b/src/plugins/platforms/cocoa/qcocoawindowmanager.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** 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$ +** +****************************************************************************/ + +#ifndef QCOCOAWINDOWMANAGER_H +#define QCOCOAWINDOWMANAGER_H + +#include + +#include + +QT_BEGIN_NAMESPACE + +class QCocoaWindowManager +{ +public: + static QCocoaWindowManager *instance(); + +private: + QCocoaWindowManager(); + void initialize(); + + void modalSessionChanged(); +}; + +QT_END_NAMESPACE + +#endif // QCOCOAWINDOWMANAGER_H diff --git a/src/plugins/platforms/cocoa/qcocoawindowmanager.mm b/src/plugins/platforms/cocoa/qcocoawindowmanager.mm new file mode 100644 index 0000000000..879bfaa546 --- /dev/null +++ b/src/plugins/platforms/cocoa/qcocoawindowmanager.mm @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** 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 "qcocoawindowmanager.h" +#include "qcocoawindow.h" + +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +QCocoaWindowManager *QCocoaWindowManager::instance() +{ + static auto *instance = new QCocoaWindowManager; + return instance; +} + +QCocoaWindowManager::QCocoaWindowManager() +{ + if (NSApp) { + initialize(); + } else { + static auto applicationDidFinishLaunching(QMacNotificationObserver(nil, + NSApplicationDidFinishLaunchingNotification, [this] { initialize(); })); + } +} + +void QCocoaWindowManager::initialize() +{ + Q_ASSERT(NSApp); + + // Whenever the modalWindow property of NSApplication changes we have a new + // modal session running. Observing the app modal window instead of our own + // event dispatcher sessions allows us to track session started by native + // APIs as well. We need to check the initial state as well, in case there + // is already a modal session running. + static auto modalSessionObserver(QMacKeyValueObserver( + NSApp, @"modalWindow", [this] { modalSessionChanged(); }, + NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew)); +} + +void QCocoaWindowManager::modalSessionChanged() +{ + // Make sure that no window is overlapping the modal window. This can + // happen for e.g. splash screens, which have the NSPopUpMenuWindowLevel. + for (auto *window : QGuiApplication::topLevelWindows()) { + auto *platformWindow = static_cast(window->handle()); + if (!platformWindow) + continue; + + auto naturalWindowLevel = platformWindow->windowLevel(window->flags()); + if (naturalWindowLevel > NSModalPanelWindowLevel) { + NSWindow *nativeWindow = platformWindow->nativeWindow(); + if (NSApp.modalWindow) { + // Lower window to that of the modal windows, but no less + nativeWindow.level = NSModalPanelWindowLevel; + [nativeWindow orderBack:nil]; + } else { + // Restore window's natural window level, whatever that was + nativeWindow.level = naturalWindowLevel; + } + } + } +} + +static void initializeWindowManager() { Q_UNUSED(QCocoaWindowManager::instance()); } +Q_CONSTRUCTOR_FUNCTION(initializeWindowManager) + +QT_END_NAMESPACE + From 5c351da046992f745d63d86be6d45b3620b7ce95 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 28 Jun 2019 12:28:38 +0200 Subject: [PATCH 142/264] Protect against integer overflow in painting transformed images Makes it safe to sample pixel coordinates above 32767. Fixes: QTBUG-76829 Change-Id: I5965afef1bd65106fcfc130dd37572309eacbe42 Reviewed-by: Friedemann Kleint Reviewed-by: Eirik Aavitsland --- src/gui/painting/qdrawhelper.cpp | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 1f7ab5006c..6265d51037 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1991,6 +1991,23 @@ inline void fetchTransformed_pixelBounds(int max, int l1, int l2, int &v) } } +static inline bool canUseFastMatrixPath(const qreal cx, const qreal cy, const qsizetype length, const QSpanData *data) +{ + if (Q_UNLIKELY(!data->fast_matrix)) + return false; + + qreal fx = (data->m21 * cy + data->m11 * cx + data->dx) * fixed_scale; + qreal fy = (data->m22 * cy + data->m12 * cx + data->dy) * fixed_scale; + qreal minc = std::min(fx, fy); + qreal maxc = std::max(fx, fy); + fx += std::trunc(data->m11 * fixed_scale) * length; + fy += std::trunc(data->m12 * fixed_scale) * length; + minc = std::min(minc, std::min(fx, fy)); + maxc = std::max(maxc, std::max(fx, fy)); + + return minc >= std::numeric_limits::min() && maxc <= std::numeric_limits::max(); +} + template static void QT_FASTCALL fetchTransformed_fetcher(T *buffer, const QSpanData *data, int y, int x, int length) @@ -2008,7 +2025,7 @@ static void QT_FASTCALL fetchTransformed_fetcher(T *buffer, const QSpanData *dat // When templated 'fetch' should be inlined at compile time: const FetchPixelFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : FetchPixelFunc(fetchPixel); - if (data->fast_matrix) { + if (canUseFastMatrixPath(cx, cy, length, data)) { // The increment pr x in the scanline int fdx = (int)(data->m11 * fixed_scale); int fdy = (int)(data->m12 * fixed_scale); @@ -2962,7 +2979,7 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c uint *end = buffer + length; uint *b = buffer; - if (data->fast_matrix) { + if (canUseFastMatrixPath(cx, cy, length, data)) { // The increment pr x in the scanline int fdx = (int)(data->m11 * fixed_scale); int fdy = (int)(data->m12 * fixed_scale); @@ -3319,7 +3336,7 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper const qreal cx = x + qreal(0.5); const qreal cy = y + qreal(0.5); - if (data->fast_matrix) { + if (canUseFastMatrixPath(cx, cy, length, data)) { // The increment pr x in the scanline int fdx = (int)(data->m11 * fixed_scale); int fdy = (int)(data->m12 * fixed_scale); @@ -3505,7 +3522,7 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint32(QRgba64 *buf QRgba64 *end = buffer + length; QRgba64 *b = buffer; - if (data->fast_matrix) { + if (canUseFastMatrixPath(cx, cy, length, data)) { // The increment pr x in the scanline const int fdx = (int)(data->m11 * fixed_scale); const int fdy = (int)(data->m12 * fixed_scale); @@ -3663,7 +3680,7 @@ static const QRgba64 *QT_FASTCALL fetchTransformedBilinear64_uint64(QRgba64 *buf QRgba64 *end = buffer + length; QRgba64 *b = buffer; - if (data->fast_matrix) { + if (canUseFastMatrixPath(cx, cy, length, data)) { // The increment pr x in the scanline const int fdx = (int)(data->m11 * fixed_scale); const int fdy = (int)(data->m12 * fixed_scale); From c5ab86976b8836f3c4beff22a5138eb6f72c2c1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 18 Jul 2019 13:35:35 +0200 Subject: [PATCH 143/264] macOS: Modernize and clarify transient parent window level inheritance Task-number: QTBUG-71480 Change-Id: Ia026427844a674f6b36804571a897dc6f16364fa Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoawindow.mm | 36 +++++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index dc7319484e..42b662cfe4 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -453,13 +453,35 @@ NSInteger QCocoaWindow::windowLevel(Qt::WindowFlags flags) if (type == Qt::ToolTip) windowLevel = NSScreenSaverWindowLevel; - // Any "special" window should be in at least the same level as its parent. - if (type != Qt::Window) { - const QWindow * const transientParent = window()->transientParent(); - const QCocoaWindow * const transientParentWindow = transientParent ? - static_cast(transientParent->handle()) : nullptr; - if (transientParentWindow) - windowLevel = qMax([transientParentWindow->nativeWindow() level], windowLevel); + auto *transientParent = window()->transientParent(); + if (transientParent && transientParent->handle()) { + // We try to keep windows in at least the same window level as + // their transient parent. Unfortunately this only works when the + // window is created. If the window level changes after that, as + // a result of a call to setWindowFlags, or by changing the level + // of the native window, we will not pick this up, and the window + // will be left behind (or in a different window level than) its + // parent. We could KVO-observe the window level of our transient + // parent, but that requires us to know when the parent goes away + // so that we can unregister the observation before the parent is + // dealloced, something we can't do for generic NSWindows. Another + // way would be to override [NSWindow setLevel:] and notify child + // windows about the change, but that doesn't work for foreign + // windows, which can still be transient parents via fromWinId(). + // One area where this problem is apparent is when AppKit tweaks + // the window level of modal windows during application activation + // and deactivation. Since we don't pick up on these window level + // changes in a generic way, we need to add logic explicitly to + // re-evaluate the window level after AppKit has done its tweaks. + + auto *transientCocoaWindow = static_cast(transientParent->handle()); + auto *nsWindow = transientCocoaWindow->nativeWindow(); + + // We only upgrade the window level for "special" windows, to work + // around Qt Designer parenting the designer windows to the widget + // palette window (QTBUG-31779). This should be fixed in designer. + if (type != Qt::Window) + windowLevel = qMax(windowLevel, nsWindow.level); } return windowLevel; From 89e0c2854a9dc098380e5286b26de187d04f9826 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 15 Jul 2019 17:02:19 -0700 Subject: [PATCH 144/264] Fix QStorageInfo inability to parse really long mountinfo lines Docker creates really long lines due to the multiple levels of overlays in the overlayfs. Our limit of 1024 bytes was too short. [ChangeLog][QtCore][QStorageInfo] Fixed a bug that caused QStorageInfo to be unable to report all filesystems if the options to mounted filesystems were too long (over 900 characters, roughly), such as those found in Docker overlay mounts. Fixes: QTBUG-77059 Change-Id: I6aed4df6a12e43c3ac8efffd15b1ba4231e60b4a Reviewed-by: Edward Welbourne --- src/corelib/io/qstorageinfo_unix.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index 11b5af069a..812e965927 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -468,8 +468,18 @@ inline bool QStorageIterator::next() size_t len = strlen(buffer.data()); if (len == 0) return false; - if (ptr[len - 1] == '\n') - ptr[len - 1] = '\0'; + while (Q_UNLIKELY(ptr[len - 1] != '\n' && !feof(fp))) { + // buffer wasn't large enough. Enlarge and try again. + // (we're readidng from the kernel, so OOM is unlikely) + buffer.resize((buffer.size() + 4096) & ~4095); + ptr = buffer.data(); + if (fgets(ptr + len, buffer.size() - len, fp) == nullptr) + return false; + + len += strlen(ptr + len); + Q_ASSERT(len < size_t(buffer.size())); + } + ptr[len - 1] = '\0'; // parse the line bool ok; From f0f46ade9e9cee586ed6b3965e87e7e2f428e03b Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Fri, 19 Jul 2019 09:23:14 +0900 Subject: [PATCH 145/264] Fix SOURCES duplication in tools/bootstrap on macOS Three *_unix.cpp are added twice for unix and for mac Makefile:14766: warning: overriding commands for target `.obj/ qfilesystemengine_unix.o' Makefile:14037: warning: ignoring old commands for target `.obj/ qfilesystemengine_unix.o' Makefile:14913: warning: overriding commands for target `.obj/ qfilesystemiterator_unix.o' Makefile:14184: warning: ignoring old commands for target `.obj/ qfilesystemiterator_unix.o' Makefile:15071: warning: overriding commands for target `.obj/ qfsfileengine_unix.o' Makefile:14342: warning: ignoring old commands for target `.obj/ qfsfileengine_unix.o' Change-Id: Ia5f9d2873f738081c2d1e763efbdfc64209aaf7d Reviewed-by: BogDan Vatra --- src/tools/bootstrap/bootstrap.pro | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index f4d930babb..32e36cefa0 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -126,10 +126,7 @@ win32:SOURCES += ../../corelib/global/qoperatingsystemversion_win.cpp \ mac { SOURCES += \ ../../corelib/kernel/qcoreapplication_mac.cpp \ - ../../corelib/kernel/qcore_mac.cpp \ - ../../corelib/io/qfilesystemengine_unix.cpp \ - ../../corelib/io/qfilesystemiterator_unix.cpp \ - ../../corelib/io/qfsfileengine_unix.cpp + ../../corelib/kernel/qcore_mac.cpp OBJECTIVE_SOURCES += \ ../../corelib/global/qoperatingsystemversion_darwin.mm \ From 34e457e873f2b699cf50ce613348e355332b9133 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 4 Jul 2019 18:06:29 +0200 Subject: [PATCH 146/264] Parse PNG cHRM chunks Used for setting primaries without a full ICC profile. Change-Id: I6dd8e62ca15bf1f86e7bbc01aaf8e0bd85803071 Reviewed-by: Eirik Aavitsland --- src/gui/image/qpnghandler.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 864a944fcb..cd1c1d5433 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -628,11 +628,25 @@ bool QPngHandlerPrivate::readPngHeader() png_get_gAMA(png_ptr, info_ptr, &file_gamma); fileGamma = file_gamma; if (fileGamma > 0.0f && colorSpaceState <= GammaChrm) { - QColorSpacePrivate *csPrivate = colorSpace.d_func(); - csPrivate->gamut = QColorSpace::Gamut::SRgb; - csPrivate->transferFunction = QColorSpace::TransferFunction::Gamma; - csPrivate->gamma = fileGamma; - csPrivate->initialize(); + QColorSpacePrimaries primaries; + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_cHRM)) { + double white_x, white_y, red_x, red_y; + double green_x, green_y, blue_x, blue_y; + png_get_cHRM(png_ptr, info_ptr, + &white_x, &white_y, &red_x, &red_y, + &green_x, &green_y, &blue_x, &blue_y); + primaries.whitePoint = QPointF(white_x, white_y); + primaries.redPoint = QPointF(red_x, red_y); + primaries.greenPoint = QPointF(green_x, green_y); + primaries.bluePoint = QPointF(blue_x, blue_y); + } + if (primaries.areValid()) { + colorSpace = QColorSpace(primaries.whitePoint, primaries.redPoint, primaries.greenPoint, primaries.bluePoint, + QColorSpace::TransferFunction::Gamma, fileGamma); + } else { + colorSpace = QColorSpace(QColorSpace::Gamut::SRgb, + QColorSpace::TransferFunction::Gamma, fileGamma); + } colorSpaceState = GammaChrm; } } @@ -666,7 +680,7 @@ bool QPngHandlerPrivate::readPngImage(QImage *outImage) QColorSpacePrivate *csPrivate = colorSpace.d_func(); csPrivate->transferFunction = QColorSpace::TransferFunction::Gamma; csPrivate->gamma = gamma; - csPrivate->initialize(); + csPrivate->setTransferFunction(); colorSpaceState = GammaChrm; } From cab920d52cde7053caab05fd835855c1e3d8127b Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 5 Jun 2019 16:24:00 +0200 Subject: [PATCH 147/264] QSharedNetworkSessionManager: prune expired QNetworkSessions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Equality for QNetworkConfiguration is defined by identity of the Private object, so even if there are QNCs with the same properties, they will not compare equal. This probably happens when a user roams through different WLANs (e.g. from work via public transport to home and then back), and each time the home WLAN pops up, it will beget a new QNetworkConfiguration, not comparing equal to the previous one. So, over time, we might collect a sizeable amount of QNetworkConfiguration objects just sitting in the cache without ever being able to actually use an associated network session, because they all have long since expired. To fix, prune expired network sessions, and thus their associated QNetworkConfigurations, from the cache. To not run every time, prune only when this size of the cache is larger than 16 (arbitrary number). Change-Id: I11a636f45ccf67420f84b1c79a4453a144de7c5c Reviewed-by: Mårten Nordheim --- src/network/bearer/qsharednetworksession.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/network/bearer/qsharednetworksession.cpp b/src/network/bearer/qsharednetworksession.cpp index af543f77e3..b3e9892f4b 100644 --- a/src/network/bearer/qsharednetworksession.cpp +++ b/src/network/bearer/qsharednetworksession.cpp @@ -64,9 +64,23 @@ struct DeleteLater { } }; +template +static void maybe_prune_expired(Container &c) +{ + if (c.size() > 16) { + for (auto it = c.cbegin(), end = c.cend(); it != end; /*erasing*/) { + if (!it->second.lock()) + it = c.erase(it); + else + ++it; + } + } +} + QSharedPointer QSharedNetworkSessionManager::getSession(const QNetworkConfiguration &config) { QSharedNetworkSessionManager *m = sharedNetworkSessionManager(); + maybe_prune_expired(m->sessions); auto &entry = m->sessions[config]; //if already have a session, return it if (auto p = entry.toStrongRef()) From 2851f6eae918a0c8c61e7a02d5bc48c9aa37f900 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 4 Jul 2019 18:27:45 +0200 Subject: [PATCH 148/264] QHostInfo: remove unused QAbstractHostInfoLookupManager If it was used in the past, it no longer is, and can't be, because it's not exported. Change-Id: Ifb9c353e756add5b57bf0c5706c075bb2eb41d83 Reviewed-by: Timur Pocheptsov --- src/network/kernel/qhostinfo.cpp | 17 ++++++----------- src/network/kernel/qhostinfo_p.h | 22 ++++------------------ 2 files changed, 10 insertions(+), 29 deletions(-) diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index 483ab875c6..b9e386b526 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -392,7 +392,7 @@ QHostInfo QHostInfo::fromName(const QString &name) #endif QHostInfo hostInfo = QHostInfoAgent::fromName(name); - QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager(); + QHostInfoLookupManager* manager = theHostInfoLookupManager(); manager->cache.put(name, hostInfo); return hostInfo; } @@ -405,7 +405,7 @@ QHostInfo QHostInfoPrivate::fromName(const QString &name, QSharedPointercache.put(name, hostInfo); return hostInfo; } @@ -1077,7 +1077,7 @@ QHostInfo qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *id = -1; // check cache - QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager(); + QHostInfoLookupManager* manager = theHostInfoLookupManager(); if (manager && manager->cache.isEnabled()) { QHostInfo info = manager->cache.get(name, valid); if (*valid) { @@ -1094,7 +1094,7 @@ QHostInfo qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char void qt_qhostinfo_clear_cache() { - QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager(); + QHostInfoLookupManager* manager = theHostInfoLookupManager(); if (manager) { manager->clear(); } @@ -1103,7 +1103,7 @@ void qt_qhostinfo_clear_cache() #ifdef QT_BUILD_INTERNAL void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e) { - QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager(); + QHostInfoLookupManager* manager = theHostInfoLookupManager(); if (manager) { manager->cache.setEnabled(e); } @@ -1111,7 +1111,7 @@ void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e) void qt_qhostinfo_cache_inject(const QString &hostname, const QHostInfo &resolution) { - QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager(); + QHostInfoLookupManager* manager = theHostInfoLookupManager(); if (!manager || !manager->cache.isEnabled()) return; @@ -1167,9 +1167,4 @@ void QHostInfoCache::clear() cache.clear(); } -QAbstractHostInfoLookupManager* QAbstractHostInfoLookupManager::globalInstance() -{ - return theHostInfoLookupManager(); -} - QT_END_NAMESPACE diff --git a/src/network/kernel/qhostinfo_p.h b/src/network/kernel/qhostinfo_p.h index f5b630346c..747069a2c6 100644 --- a/src/network/kernel/qhostinfo_p.h +++ b/src/network/kernel/qhostinfo_p.h @@ -208,30 +208,14 @@ public: }; -class QAbstractHostInfoLookupManager : public QObject -{ - Q_OBJECT - -public: - ~QAbstractHostInfoLookupManager() {} - virtual void clear() = 0; - - QHostInfoCache cache; - -protected: - QAbstractHostInfoLookupManager() {} - static QAbstractHostInfoLookupManager* globalInstance(); - -}; - -class QHostInfoLookupManager : public QAbstractHostInfoLookupManager +class QHostInfoLookupManager : public QObject { Q_OBJECT public: QHostInfoLookupManager(); ~QHostInfoLookupManager(); - void clear() override; + void clear(); // called from QHostInfo void scheduleLookup(QHostInfoRunnable *r); @@ -241,6 +225,8 @@ public: void lookupFinished(QHostInfoRunnable *r); bool wasAborted(int id); + QHostInfoCache cache; + friend class QHostInfoRunnable; protected: #if QT_CONFIG(thread) From 315ac36e5dce548fef1907e50271ed2412d445cc Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 25 May 2019 13:32:48 +0200 Subject: [PATCH 149/264] QFile: hold engine by unique_ptr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unfortunately, we can't, yet, change QAbstractFileEngine::create() to return a unique_ptr. But we should do it in Qt 6. Change-Id: If18ff766bce73ecd4143274ac9f9a5a7b9d5912c Reviewed-by: Mårten Nordheim --- src/corelib/io/qfile.cpp | 25 ++++++++++----------- src/corelib/io/qfiledevice.cpp | 14 ++++++------ src/corelib/io/qfiledevice_p.h | 4 +++- src/corelib/io/qsavefile.cpp | 36 ++++++++++++------------------- src/corelib/io/qtemporaryfile.cpp | 16 +++++++------- 5 files changed, 42 insertions(+), 53 deletions(-) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 9f9a9e3040..95f03ef816 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -55,6 +55,8 @@ # include "qcoreapplication.h" #endif +#include + #ifdef QT_NO_QOBJECT #define tr(X) QString::fromLatin1(X) #endif @@ -85,10 +87,9 @@ QFilePrivate::openExternalFile(int flags, int fd, QFile::FileHandleFlags handleF Q_UNUSED(fd); return false; #else - delete fileEngine; - fileEngine = nullptr; - QFSFileEngine *fe = new QFSFileEngine; - fileEngine = fe; + auto fs = qt_make_unique(); + auto fe = fs.get(); + fileEngine = std::move(fs); return fe->open(QIODevice::OpenMode(flags), fd, handleFlags); #endif } @@ -101,10 +102,9 @@ QFilePrivate::openExternalFile(int flags, FILE *fh, QFile::FileHandleFlags handl Q_UNUSED(fh); return false; #else - delete fileEngine; - fileEngine = nullptr; - QFSFileEngine *fe = new QFSFileEngine; - fileEngine = fe; + auto fs = qt_make_unique(); + auto fe = fs.get(); + fileEngine = std::move(fs); return fe->open(QIODevice::OpenMode(flags), fh, handleFlags); #endif } @@ -112,8 +112,8 @@ QFilePrivate::openExternalFile(int flags, FILE *fh, QFile::FileHandleFlags handl QAbstractFileEngine *QFilePrivate::engine() const { if (!fileEngine) - fileEngine = QAbstractFileEngine::create(fileName); - return fileEngine; + fileEngine.reset(QAbstractFileEngine::create(fileName)); + return fileEngine.get(); } //************* QFile @@ -334,10 +334,7 @@ QFile::setFileName(const QString &name) file_already_open(*this, "setFileName"); close(); } - if(d->fileEngine) { //get a new file engine later - delete d->fileEngine; - d->fileEngine = nullptr; - } + d->fileEngine.reset(); //get a new file engine later d->fileName = name; } diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp index 2f74547054..ee619d99cc 100644 --- a/src/corelib/io/qfiledevice.cpp +++ b/src/corelib/io/qfiledevice.cpp @@ -42,6 +42,8 @@ #include "qfiledevice_p.h" #include "qfsfileengine_p.h" +#include + #ifdef QT_NO_QOBJECT #define tr(X) QString::fromLatin1(X) #endif @@ -53,24 +55,20 @@ QT_BEGIN_NAMESPACE #endif QFileDevicePrivate::QFileDevicePrivate() - : fileEngine(nullptr), - cachedSize(0), + : cachedSize(0), error(QFile::NoError), lastWasWrite(false) { writeBufferChunkSize = QFILE_WRITEBUFFER_SIZE; } QFileDevicePrivate::~QFileDevicePrivate() -{ - delete fileEngine; - fileEngine = nullptr; -} + = default; QAbstractFileEngine * QFileDevicePrivate::engine() const { if (!fileEngine) - fileEngine = new QFSFileEngine; - return fileEngine; + fileEngine = qt_make_unique(); + return fileEngine.get(); } void QFileDevicePrivate::setError(QFileDevice::FileError err) diff --git a/src/corelib/io/qfiledevice_p.h b/src/corelib/io/qfiledevice_p.h index 47053d01b7..aef3fca811 100644 --- a/src/corelib/io/qfiledevice_p.h +++ b/src/corelib/io/qfiledevice_p.h @@ -53,6 +53,8 @@ #include "private/qiodevice_p.h" +#include + QT_BEGIN_NAMESPACE class QAbstractFileEngine; @@ -75,7 +77,7 @@ protected: void setError(QFileDevice::FileError err, const QString &errorString); void setError(QFileDevice::FileError err, int errNum); - mutable QAbstractFileEngine *fileEngine; + mutable std::unique_ptr fileEngine; mutable qint64 cachedSize; QFileDevice::FileHandleFlags handleFlags; diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp index 04f440fea2..f41e6302a2 100644 --- a/src/corelib/io/qsavefile.cpp +++ b/src/corelib/io/qsavefile.cpp @@ -150,8 +150,7 @@ QSaveFile::~QSaveFile() QFileDevice::close(); if (d->fileEngine) { d->fileEngine->remove(); - delete d->fileEngine; - d->fileEngine = nullptr; + d->fileEngine.reset(); } } @@ -235,7 +234,7 @@ bool QSaveFile::open(OpenMode mode) } auto openDirectly = [&]() { - d->fileEngine = QAbstractFileEngine::create(d->finalFileName); + d->fileEngine.reset(QAbstractFileEngine::create(d->finalFileName)); if (d->fileEngine->open(mode | QIODevice::Unbuffered)) { d->useTemporaryFile = false; QFileDevice::open(mode); @@ -252,8 +251,7 @@ bool QSaveFile::open(OpenMode mode) if (openDirectly()) return true; d->setError(d->fileEngine->error(), d->fileEngine->errorString()); - delete d->fileEngine; - d->fileEngine = nullptr; + d->fileEngine.reset(); } else { QString msg = QSaveFile::tr("QSaveFile cannot open '%1' without direct write fallback " @@ -265,18 +263,17 @@ bool QSaveFile::open(OpenMode mode) } #endif - d->fileEngine = new QTemporaryFileEngine(&d->finalFileName, QTemporaryFileEngine::Win32NonShared); + d->fileEngine.reset(new QTemporaryFileEngine(&d->finalFileName, QTemporaryFileEngine::Win32NonShared)); // if the target file exists, we'll copy its permissions below, // but until then, let's ensure the temporary file is not accessible // to a third party int perm = (existingFile.exists() ? 0600 : 0666); - static_cast(d->fileEngine)->initialize(d->finalFileName, perm); + static_cast(d->fileEngine.get())->initialize(d->finalFileName, perm); // Same as in QFile: QIODevice provides the buffering, so there's no need to request it from the file engine. if (!d->fileEngine->open(mode | QIODevice::Unbuffered)) { QFileDevice::FileError err = d->fileEngine->error(); #ifdef Q_OS_UNIX if (d->directWriteFallback && err == QFileDevice::OpenError && errno == EACCES) { - delete d->fileEngine; if (openDirectly()) return true; err = d->fileEngine->error(); @@ -285,8 +282,7 @@ bool QSaveFile::open(OpenMode mode) if (err == QFileDevice::UnspecifiedError) err = QFileDevice::OpenError; d->setError(err, d->fileEngine->errorString()); - delete d->fileEngine; - d->fileEngine = nullptr; + d->fileEngine.reset(); return false; } @@ -332,30 +328,26 @@ bool QSaveFile::commit() } QFileDevice::close(); // calls flush() + const auto fe = std::move(d->fileEngine); + // Sync to disk if possible. Ignore errors (e.g. not supported). - d->fileEngine->syncToDisk(); + fe->syncToDisk(); if (d->useTemporaryFile) { if (d->writeError != QFileDevice::NoError) { - d->fileEngine->remove(); + fe->remove(); d->writeError = QFileDevice::NoError; - delete d->fileEngine; - d->fileEngine = nullptr; return false; } // atomically replace old file with new file // Can't use QFile::rename for that, must use the file engine directly - Q_ASSERT(d->fileEngine); - if (!d->fileEngine->renameOverwrite(d->finalFileName)) { - d->setError(d->fileEngine->error(), d->fileEngine->errorString()); - d->fileEngine->remove(); - delete d->fileEngine; - d->fileEngine = nullptr; + Q_ASSERT(fe); + if (!fe->renameOverwrite(d->finalFileName)) { + d->setError(fe->error(), fe->errorString()); + fe->remove(); return false; } } - delete d->fileEngine; - d->fileEngine = nullptr; return true; } diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index c89ad06a1f..acd31f4d84 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -544,10 +544,10 @@ QTemporaryFilePrivate::~QTemporaryFilePrivate() QAbstractFileEngine *QTemporaryFilePrivate::engine() const { if (!fileEngine) { - fileEngine = new QTemporaryFileEngine(&templateName); + fileEngine.reset(new QTemporaryFileEngine(&templateName)); resetFileEngine(); } - return fileEngine; + return fileEngine.get(); } void QTemporaryFilePrivate::resetFileEngine() const @@ -555,7 +555,7 @@ void QTemporaryFilePrivate::resetFileEngine() const if (!fileEngine) return; - QTemporaryFileEngine *tef = static_cast(fileEngine); + QTemporaryFileEngine *tef = static_cast(fileEngine.get()); if (fileName.isEmpty()) tef->initialize(templateName, 0600); else @@ -568,7 +568,7 @@ void QTemporaryFilePrivate::materializeUnnamedFile() if (!fileName.isEmpty() || !fileEngine) return; - auto *tef = static_cast(fileEngine); + auto *tef = static_cast(fileEngine.get()); fileName = tef->fileName(QAbstractFileEngine::DefaultName); #endif } @@ -792,7 +792,7 @@ void QTemporaryFile::setAutoRemove(bool b) QString QTemporaryFile::fileName() const { Q_D(const QTemporaryFile); - auto tef = static_cast(d->fileEngine); + auto tef = static_cast(d->fileEngine.get()); if (tef && tef->isReallyOpen()) const_cast(d)->materializeUnnamedFile(); @@ -841,7 +841,7 @@ void QTemporaryFile::setFileTemplate(const QString &name) bool QTemporaryFile::rename(const QString &newName) { Q_D(QTemporaryFile); - auto tef = static_cast(d->fileEngine); + auto tef = static_cast(d->fileEngine.get()); if (!tef || !tef->isReallyOpen() || !tef->filePathWasTemplate) return QFile::rename(newName); @@ -947,7 +947,7 @@ QTemporaryFile *QTemporaryFile::createNativeFile(QFile &file) bool QTemporaryFile::open(OpenMode flags) { Q_D(QTemporaryFile); - auto tef = static_cast(d->fileEngine); + auto tef = static_cast(d->fileEngine.get()); if (tef && tef->isReallyOpen()) { setOpenMode(flags); return true; @@ -961,7 +961,7 @@ bool QTemporaryFile::open(OpenMode flags) d->resetFileEngine(); if (QFile::open(flags)) { - tef = static_cast(d->fileEngine); + tef = static_cast(d->fileEngine.get()); if (tef->isUnnamedFile()) d->fileName.clear(); else From 65f9646583d74c97aab7f8ea90197e370d7bfede Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 17 Jul 2019 09:41:31 -0700 Subject: [PATCH 150/264] Fix QCborStreamReader not flushing QIODevices due to internal buffering When successfully finishing a parse, it's reasonable to expect that the QIODevice was advanced to the end of the input data. [ChangeLog][QtCore][QCborStreamReader] Fixed a bug that caused the QIODevice that the data was being read from not to show the entire CBOR message as consumed. This allows the user to consume data that may follow the CBOR payload. Fixes: QTBUG-77076 Change-Id: I1024ee42da0c4323953afffd15b23f5d8fcc6f50 Reviewed-by: Edward Welbourne Reviewed-by: BogDan Vatra --- src/corelib/serialization/qcborstream.cpp | 10 +- .../tst_qcborstreamreader.cpp | 108 ++++++++++++++++-- .../qcborvalue/tst_qcborvalue.cpp | 79 +++++++++++-- 3 files changed, 177 insertions(+), 20 deletions(-) diff --git a/src/corelib/serialization/qcborstream.cpp b/src/corelib/serialization/qcborstream.cpp index 87ae316041..dc00118cfd 100644 --- a/src/corelib/serialization/qcborstream.cpp +++ b/src/corelib/serialization/qcborstream.cpp @@ -1956,7 +1956,15 @@ inline void QCborStreamReader::preparse() if (lastError() == QCborError::NoError) { type_ = cbor_value_get_type(&d->currentElement); - if (type_ != CborInvalidType) { + if (type_ == CborInvalidType) { + // We may have reached the end. + if (d->device && d->containerStack.isEmpty()) { + d->buffer.clear(); + if (d->bufferStart) + d->device->skip(d->bufferStart); + d->bufferStart = 0; + } + } else { d->lastError = {}; // Undo the type mapping that TinyCBOR does (we have an explicit type // for negative integer and we don't have separate types for Boolean, diff --git a/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp b/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp index 3dd4b5114c..28d29168fb 100644 --- a/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp +++ b/tests/auto/corelib/serialization/qcborstreamreader/tst_qcborstreamreader.cpp @@ -80,6 +80,11 @@ private Q_SLOTS: void addData_singleElement(); void addData_complex_data() { arrays_data(); } void addData_complex(); + + void duplicatedData_data() { arrays_data(); } + void duplicatedData(); + void extraData_data() { arrays_data(); } + void extraData(); }; #define FOR_CBOR_TYPE(F) \ @@ -480,6 +485,28 @@ static QString parseOne(QCborStreamReader &reader) return result; } +static QString parse(QCborStreamReader &reader, const QByteArray &data) +{ + qint64 oldPos = 0; + if (QIODevice *dev = reader.device()) + oldPos = dev->pos(); + + QString r = parseOne(reader); + if (r.isEmpty()) + return r; + + if (reader.currentOffset() - oldPos != data.size()) + r = QString("Number of parsed bytes (%1) not expected (%2)") + .arg(reader.currentOffset()).arg(data.size()); + if (QIODevice *dev = reader.device()) { + if (dev->pos() - oldPos != data.size()) + r = QString("QIODevice not advanced (%1) as expected (%2)") + .arg(dev->pos()).arg(data.size()); + } + + return r; +} + bool parseNonRecursive(QString &result, bool &printingStringChunks, QCborStreamReader &reader) { while (reader.lastError() == QCborError::NoError) { @@ -612,13 +639,13 @@ void tst_QCborStreamReader::fixed() } QVERIFY(reader.isValid()); QCOMPARE(reader.lastError(), QCborError::NoError); - QCOMPARE(parseOne(reader), expected); + QCOMPARE(parse(reader, data), expected); // verify that we can re-read reader.reset(); QVERIFY(reader.isValid()); QCOMPARE(reader.lastError(), QCborError::NoError); - QCOMPARE(parseOne(reader), expected); + QCOMPARE(parse(reader, data), expected); } void tst_QCborStreamReader::strings_data() @@ -721,7 +748,7 @@ void tst_QCborStreamReader::emptyContainers() QCOMPARE(reader.lastError(), QCborError::NoError); if (reader.isLengthKnown()) QCOMPARE(reader.length(), 0U); - QCOMPARE(parseOne(reader), expected); + QCOMPARE(parse(reader, data), expected); // verify that we can re-read reader.reset(); @@ -729,7 +756,7 @@ void tst_QCborStreamReader::emptyContainers() QCOMPARE(reader.lastError(), QCborError::NoError); if (reader.isLengthKnown()) QCOMPARE(reader.length(), 0U); - QCOMPARE(parseOne(reader), expected); + QCOMPARE(parse(reader, data), expected); } void tst_QCborStreamReader::arrays_data() @@ -758,7 +785,7 @@ static void checkContainer(int len, const QByteArray &data, const QString &expec QVERIFY(reader.isLengthKnown()); QCOMPARE(reader.length(), uint(len)); } - QCOMPARE(parseOne(reader), expected); + QCOMPARE(parse(reader, data), expected); // verify that we can re-read reader.reset(); @@ -768,7 +795,7 @@ static void checkContainer(int len, const QByteArray &data, const QString &expec QVERIFY(reader.isLengthKnown()); QCOMPARE(reader.length(), uint(len)); } - QCOMPARE(parseOne(reader), expected); + QCOMPARE(parse(reader, data), expected); } void tst_QCborStreamReader::arrays() @@ -892,7 +919,7 @@ void tst_QCborStreamReader::validation() buffer.open(QIODevice::ReadOnly); reader.setDevice(&buffer); } - parseOne(reader); + parse(reader, data); QVERIFY(reader.lastError() != QCborError::NoError); // next() should fail @@ -997,7 +1024,7 @@ void tst_QCborStreamReader::addData_singleElement() reader.addData(data.constData() + i, 1); } - parseOne(reader); + parse(reader, data); QCOMPARE(reader.lastError(), QCborError::EndOfFile); } @@ -1009,7 +1036,7 @@ void tst_QCborStreamReader::addData_singleElement() reader.addData(data.right(1)); } QCOMPARE(reader.lastError(), QCborError::NoError); - QCOMPARE(parseOne(reader), expected); + QCOMPARE(parse(reader, data), expected); } void tst_QCborStreamReader::addData_complex() @@ -1085,6 +1112,69 @@ void tst_QCborStreamReader::addData_complex() "{1, [" + expected + ", " + expected + "]}"); } +void tst_QCborStreamReader::duplicatedData() +{ + QFETCH_GLOBAL(bool, useDevice); + QFETCH(QByteArray, data); + QFETCH(QString, expected); + removeIndicators(expected); + + // double the data up + QByteArray doubledata = data + data; + + QBuffer buffer(&doubledata); + QCborStreamReader reader(doubledata); + if (useDevice) { + buffer.open(QIODevice::ReadOnly); + reader.setDevice(&buffer); + } + QVERIFY(reader.isValid()); + QCOMPARE(reader.lastError(), QCborError::NoError); + QCOMPARE(parse(reader, data), expected); // yes, data + + QVERIFY(reader.currentOffset() < doubledata.size()); + if (useDevice) { + reader.setDevice(&buffer); + QVERIFY(reader.isValid()); + QCOMPARE(reader.lastError(), QCborError::NoError); + QCOMPARE(parse(reader, data), expected); + QCOMPARE(buffer.pos(), doubledata.size()); + } else { + // there's no reader.setData() + } +} + +void tst_QCborStreamReader::extraData() +{ + QFETCH_GLOBAL(bool, useDevice); + QFETCH(QByteArray, data); + QFETCH(QString, expected); + removeIndicators(expected); + + QByteArray extension(9, '\0'); + + // stress test everything with extra bytes (just one byte changing; + // TinyCBOR used to have a bug where the next byte got sometimes read) + for (int c = '\0'; c < 0x100; ++c) { + extension[0] = c; + QByteArray extendeddata = data + extension; + + QBuffer buffer(&extendeddata); + QCborStreamReader reader(extendeddata); + if (useDevice) { + buffer.open(QIODevice::ReadOnly); + reader.setDevice(&buffer); + } + QVERIFY(reader.isValid()); + QCOMPARE(reader.lastError(), QCborError::NoError); + QCOMPARE(parse(reader, data), expected); // yes, data + + // if we were a parser, we could parse the next payload + if (useDevice) + QCOMPARE(buffer.readAll(), extension); + } +} + QTEST_MAIN(tst_QCborStreamReader) diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index 4b753eab6b..9d453bd38e 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -91,8 +91,14 @@ private slots: void toCbor_data(); void toCbor(); + void toCborStreamWriter_data() { toCbor_data(); } + void toCborStreamWriter(); void fromCbor_data(); void fromCbor(); + void fromCborStreamReaderByteArray_data() { fromCbor_data(); } + void fromCborStreamReaderByteArray(); + void fromCborStreamReaderIODevice_data() { fromCbor_data(); } + void fromCborStreamReaderIODevice(); void validation_data(); void validation(); void toDiagnosticNotation_data(); @@ -1395,6 +1401,22 @@ void tst_QCborValue::toCbor() "\xa1\x01\xd9\xd9\xf7" + result); } +void tst_QCborValue::toCborStreamWriter() +{ + QFETCH(QCborValue, v); + QFETCH(QByteArray, result); + QFETCH(QCborValue::EncodingOptions, options); + + QByteArray output; + QBuffer buffer(&output); + buffer.open(QIODevice::WriteOnly); + QCborStreamWriter writer(&buffer); + + v.toCbor(writer, options); + QCOMPARE(buffer.pos(), result.size()); + QCOMPARE(output, result); +} + void tst_QCborValue::fromCbor_data() { addCommonCborData(); @@ -1425,20 +1447,11 @@ void tst_QCborValue::fromCbor_data() << raw("\xd8\x25\x51" "\1\2\3\4""\4\3\2\0""\0\0\0\0""\0\0\0\1""\2"); } -void tst_QCborValue::fromCbor() +void fromCbor_common(void (*doCheck)(const QCborValue &, const QByteArray &)) { QFETCH(QCborValue, v); QFETCH(QByteArray, result); - auto doCheck = [](const QCborValue &v, const QByteArray &result) { - QCborParserError error; - QCborValue decoded = QCborValue::fromCbor(result, &error); - QVERIFY2(error.error == QCborError(), qPrintable(error.errorString())); - QCOMPARE(error.offset, result.size()); - QVERIFY(decoded == v); - QVERIFY(v == decoded); - }; - doCheck(v, result); if (QTest::currentTestFailed()) return; @@ -1489,6 +1502,52 @@ void tst_QCborValue::fromCbor() return; } +void tst_QCborValue::fromCbor() +{ + auto doCheck = [](const QCborValue &v, const QByteArray &result) { + QCborParserError error; + QCborValue decoded = QCborValue::fromCbor(result, &error); + QVERIFY2(error.error == QCborError(), qPrintable(error.errorString())); + QCOMPARE(error.offset, result.size()); + QVERIFY(decoded == v); + QVERIFY(v == decoded); + }; + + fromCbor_common(doCheck); +} + +void tst_QCborValue::fromCborStreamReaderByteArray() +{ + auto doCheck = [](const QCborValue &expected, const QByteArray &data) { + QCborStreamReader reader(data); + QCborValue decoded = QCborValue::fromCbor(reader); + QCOMPARE(reader.lastError(), QCborError()); + QCOMPARE(reader.currentOffset(), data.size()); + QVERIFY(decoded == expected); + QVERIFY(expected == decoded); + }; + + fromCbor_common(doCheck); +} + +void tst_QCborValue::fromCborStreamReaderIODevice() +{ + auto doCheck = [](const QCborValue &expected, const QByteArray &data) { + QBuffer buffer; + buffer.setData(data); + buffer.open(QIODevice::ReadOnly); + QCborStreamReader reader(&buffer); + QCborValue decoded = QCborValue::fromCbor(reader); + QCOMPARE(reader.lastError(), QCborError()); + QCOMPARE(reader.currentOffset(), data.size()); + QVERIFY(decoded == expected); + QVERIFY(expected == decoded); + QCOMPARE(buffer.pos(), reader.currentOffset()); + }; + + fromCbor_common(doCheck); +} + void tst_QCborValue::validation_data() { addValidationColumns(); From a96a64be2dc3110d140e43d2cf85454d9fc998b8 Mon Sep 17 00:00:00 2001 From: Yulong Bai Date: Thu, 18 Jul 2019 17:21:23 +0200 Subject: [PATCH 151/264] qmake: fix variable naming conflicts with C++20 keyword It conflicts with 'requires' keyword. Fixes: QTBUG-77093 Change-Id: I85e8f530dd1e2bf9a31906dd6c5123b947235b01 Reviewed-by: Marc Mutz --- qmake/generators/makefile.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index bc59eaaea2..11623cd147 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -3418,9 +3418,9 @@ MakefileGenerator::writePkgConfigFile() t << endl; // requires - const QString requires = project->values("QMAKE_PKGCONFIG_REQUIRES").join(' '); - if (!requires.isEmpty()) { - t << "Requires: " << requires << endl; + const QString requiresString = project->values("QMAKE_PKGCONFIG_REQUIRES").join(' '); + if (!requiresString.isEmpty()) { + t << "Requires: " << requiresString << endl; } t << endl; From ce86c3373e0271ffad4ce645663e63a468158c1a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 4 Jul 2019 21:09:09 +0200 Subject: [PATCH 152/264] QHostInfo: un-QObject-ify QHostInfoLookupManager QObjects are not even reentrant, but this class must be thread-safe, so it's always ... icky ... to have to analyze a "thread-safe QObject", because for all intents and purposes, that's an oxymoron. The QObject-ness isn't even used, except for defining a private slot, connected to QCoreApplication::destroyed(). That slot just calls waitForDone() on QThreadPool, which is a QObject itself, so use it as the context object for the signal-slot connection, using a lambda as slot. So, strip the class of it's base class, convert the private slot to a lambda and connect to that. Finally, remove the moveToThread() call, because this new class can be destroyed from any thread, not just the main one. Change-Id: I0e33983aa7afd0ad621ece4afd10d9e4adad38c1 Reviewed-by: Volker Hilsheimer --- src/network/kernel/qhostinfo.cpp | 5 +++-- src/network/kernel/qhostinfo_p.h | 8 +------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index b9e386b526..0dbb2cefb1 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -907,9 +907,10 @@ void QHostInfoRunnable::run() QHostInfoLookupManager::QHostInfoLookupManager() : wasDeleted(false) { - moveToThread(QCoreApplicationPrivate::mainThread()); #if QT_CONFIG(thread) - connect(QCoreApplication::instance(), SIGNAL(destroyed()), SLOT(waitForThreadPoolDone()), Qt::DirectConnection); + QObject::connect(QCoreApplication::instance(), &QObject::destroyed, + &threadPool, [&](QObject *) { threadPool.waitForDone(); }, + Qt::DirectConnection); threadPool.setMaxThreadCount(20); // do up to 20 DNS lookups in parallel #endif } diff --git a/src/network/kernel/qhostinfo_p.h b/src/network/kernel/qhostinfo_p.h index 747069a2c6..ee052b86d3 100644 --- a/src/network/kernel/qhostinfo_p.h +++ b/src/network/kernel/qhostinfo_p.h @@ -208,9 +208,8 @@ public: }; -class QHostInfoLookupManager : public QObject +class QHostInfoLookupManager { - Q_OBJECT public: QHostInfoLookupManager(); ~QHostInfoLookupManager(); @@ -246,11 +245,6 @@ protected: private: void rescheduleWithMutexHeld(); - -private slots: -#if QT_CONFIG(thread) - void waitForThreadPoolDone() { threadPool.waitForDone(); } -#endif }; QT_END_NAMESPACE From 857e4881c66b5db5c8cab654d33fafe5db55396c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 26 Jun 2019 12:56:12 +0200 Subject: [PATCH 153/264] macOS: Properly unpolish font and palette Explicitly setting the application font and palette will actually persist the current state of the application font and palette to the widget, and it will stop reacting to system style changes. Change-Id: Ib856fe86cd3edb618b7ee5819d6c6c892c61fd1d Reviewed-by: Timur Pocheptsov --- src/plugins/styles/mac/qmacstyle_mac.mm | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index ce08725684..e10aa33623 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -2139,10 +2139,9 @@ void QMacStyle::unpolish(QWidget* w) #if QT_CONFIG(menu) qobject_cast(w) && #endif - !w->testAttribute(Qt::WA_SetPalette)) { - QPalette pal = qApp->palette(w); - w->setPalette(pal); - w->setAttribute(Qt::WA_SetPalette, false); + !w->testAttribute(Qt::WA_SetPalette)) + { + w->setPalette(QPalette()); w->setWindowOpacity(1.0); } @@ -2158,9 +2157,9 @@ void QMacStyle::unpolish(QWidget* w) #if QT_CONFIG(tabbar) if (qobject_cast(w)) { if (!w->testAttribute(Qt::WA_SetFont)) - w->setFont(qApp->font(w)); + w->setFont(QFont()); if (!w->testAttribute(Qt::WA_SetPalette)) - w->setPalette(qApp->palette(w)); + w->setPalette(QPalette()); } #endif From 8010e906d3612aface0daccde41d1a65fca04b0c Mon Sep 17 00:00:00 2001 From: Mat Sutcliffe Date: Tue, 2 Jul 2019 02:16:41 +0100 Subject: [PATCH 154/264] Optimize non-const overload of QJsonObject::operator[] Refactored parts of insert() into a new private method insertAt(), which can also be called by operator[]() to avoid a redundant key lookup. This is in preparation for overloading QJsonObject's non-const methods on QLatin1String. As a bonus, this also avoids a redundant key lookup in QJsonValueRef::operator=(). Change-Id: Ic481981d838e50bc55fb8e7844536749781899ce Reviewed-by: Marc Mutz Reviewed-by: Anton Kudryavtsev Reviewed-by: Thiago Macieira --- src/corelib/serialization/qjsonobject.cpp | 19 +++++++++++++------ src/corelib/serialization/qjsonobject.h | 1 + 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/corelib/serialization/qjsonobject.cpp b/src/corelib/serialization/qjsonobject.cpp index c1a6328b2f..a13dd3f9e7 100644 --- a/src/corelib/serialization/qjsonobject.cpp +++ b/src/corelib/serialization/qjsonobject.cpp @@ -446,11 +446,10 @@ QJsonValue QJsonObject::operator [](const QString &key) const */ QJsonValueRef QJsonObject::operator [](const QString &key) { - // ### somewhat inefficient, as we lookup the key twice if it doesn't yet exist bool keyExists = false; - int index = o ? o->indexOf(key, &keyExists) : -1; + int index = o ? o->indexOf(key, &keyExists) : 0; if (!keyExists) { - iterator i = insert(key, QJsonValue()); + iterator i = insertAt(index, key, QJsonValue(), false); index = i.i; } return QJsonValueRef(this, index); @@ -485,6 +484,16 @@ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue & remove(key); return end(); } + bool keyExists = false; + int pos = o ? o->indexOf(key, &keyExists) : 0; + return insertAt(pos, key, value, keyExists); +} + +/*! + \internal + */ +QJsonObject::iterator QJsonObject::insertAt(int pos, const QString &key, const QJsonValue &value, bool keyExists) +{ QJsonValue val = value; bool latinOrIntValue; @@ -500,8 +509,6 @@ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue & if (!o->length) o->tableOffset = sizeof(QJsonPrivate::Object); - bool keyExists = false; - int pos = o->indexOf(key, &keyExists); if (keyExists) ++d->compactionCounter; @@ -1289,7 +1296,7 @@ void QJsonObject::setValueAt(int i, const QJsonValue &val) Q_ASSERT(o && i >= 0 && i < (int)o->length); QJsonPrivate::Entry *e = o->entryAt(i); - insert(e->key(), val); + insertAt(i, e->key(), val, true); } uint qHash(const QJsonObject &object, uint seed) diff --git a/src/corelib/serialization/qjsonobject.h b/src/corelib/serialization/qjsonobject.h index d8e2ab9ca7..7f7a17e259 100644 --- a/src/corelib/serialization/qjsonobject.h +++ b/src/corelib/serialization/qjsonobject.h @@ -251,6 +251,7 @@ private: QString keyAt(int i) const; QJsonValue valueAt(int i) const; void setValueAt(int i, const QJsonValue &val); + iterator insertAt(int i, const QString &key, const QJsonValue &val, bool exists); QJsonPrivate::Data *d; QJsonPrivate::Object *o; From a4e9fa03cabfc11105e700e38184a70888da4e7a Mon Sep 17 00:00:00 2001 From: Mat Sutcliffe Date: Tue, 2 Jul 2019 02:30:26 +0100 Subject: [PATCH 155/264] QJsonObject: minor refactoring Applied DRY principle. Change-Id: Ic3035552c6174167b4fe19fd4c825500dff16ded Reviewed-by: Marc Mutz Reviewed-by: Anton Kudryavtsev Reviewed-by: Thiago Macieira --- src/corelib/serialization/qjsonobject.cpp | 40 ++++++++++++++--------- src/corelib/serialization/qjsonobject.h | 2 ++ 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/corelib/serialization/qjsonobject.cpp b/src/corelib/serialization/qjsonobject.cpp index a13dd3f9e7..e800d76ab6 100644 --- a/src/corelib/serialization/qjsonobject.cpp +++ b/src/corelib/serialization/qjsonobject.cpp @@ -525,8 +525,7 @@ QJsonObject::iterator QJsonObject::insertAt(int pos, const QString &key, const Q if (valueSize) QJsonPrivate::Value::copyData(val, (char *)e + valueOffset, latinOrIntValue); - if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) - compact(); + compactIfNeeded(); return iterator(this, pos); } @@ -546,11 +545,7 @@ void QJsonObject::remove(const QString &key) if (!keyExists) return; - detach2(); - o->removeItems(index, 1); - ++d->compactionCounter; - if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) - compact(); + removeAt(index); } /*! @@ -573,11 +568,7 @@ QJsonValue QJsonObject::take(const QString &key) return QJsonValue(QJsonValue::Undefined); QJsonValue v(d, o, o->entryAt(index)->value); - detach2(); - o->removeItems(index, 1); - ++d->compactionCounter; - if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) - compact(); + removeAt(index); return v; } @@ -659,10 +650,7 @@ QJsonObject::iterator QJsonObject::erase(QJsonObject::iterator it) int index = it.i; - o->removeItems(index, 1); - ++d->compactionCounter; - if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) - compact(); + removeAt(index); // iterator hasn't changed return it; @@ -1265,6 +1253,15 @@ void QJsonObject::compact() o = static_cast(d->header->root()); } +/*! + \internal + */ +void QJsonObject::compactIfNeeded() +{ + if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(o->length) / 2u) + compact(); +} + /*! \internal */ @@ -1299,6 +1296,17 @@ void QJsonObject::setValueAt(int i, const QJsonValue &val) insertAt(i, e->key(), val, true); } +/*! + \internal + */ +void QJsonObject::removeAt(int index) +{ + detach2(); + o->removeItems(index, 1); + ++d->compactionCounter; + compactIfNeeded(); +} + uint qHash(const QJsonObject &object, uint seed) { QtPrivate::QHashCombine hash; diff --git a/src/corelib/serialization/qjsonobject.h b/src/corelib/serialization/qjsonobject.h index 7f7a17e259..b12769d3d3 100644 --- a/src/corelib/serialization/qjsonobject.h +++ b/src/corelib/serialization/qjsonobject.h @@ -247,10 +247,12 @@ private: void detach(uint reserve = 0); bool detach2(uint reserve = 0); void compact(); + void compactIfNeeded(); QString keyAt(int i) const; QJsonValue valueAt(int i) const; void setValueAt(int i, const QJsonValue &val); + void removeAt(int i); iterator insertAt(int i, const QString &key, const QJsonValue &val, bool exists); QJsonPrivate::Data *d; From 7f8e3aab2d5aca5349fd0f0da6245465dc7db5e0 Mon Sep 17 00:00:00 2001 From: Mat Sutcliffe Date: Fri, 12 Jul 2019 20:22:49 +0100 Subject: [PATCH 156/264] JSON: add some QStringView overloads [ChangeLog][QtCore][JSON] Added overloads of functions taking key strings as QStringView; in QJsonObject, QJsonValue and QJsonDocument. Change-Id: I78b40aba8200003acfae257ff06f5f15737005e7 Reviewed-by: Thiago Macieira Reviewed-by: Anton Kudryavtsev --- src/corelib/serialization/qjson.cpp | 6 +- src/corelib/serialization/qjson_p.h | 46 ++++---- src/corelib/serialization/qjsondocument.cpp | 11 ++ src/corelib/serialization/qjsondocument.h | 3 + src/corelib/serialization/qjsonobject.cpp | 109 +++++++++++++++++- src/corelib/serialization/qjsonobject.h | 28 ++++- src/corelib/serialization/qjsonvalue.cpp | 11 ++ src/corelib/serialization/qjsonvalue.h | 3 + .../corelib/serialization/json/tst_qtjson.cpp | 18 +++ 9 files changed, 198 insertions(+), 37 deletions(-) diff --git a/src/corelib/serialization/qjson.cpp b/src/corelib/serialization/qjson.cpp index d74ffb2a20..76f1eae1ce 100644 --- a/src/corelib/serialization/qjson.cpp +++ b/src/corelib/serialization/qjson.cpp @@ -175,7 +175,7 @@ void Base::removeItems(int pos, int numItems) length -= numItems; } -int Object::indexOf(const QString &key, bool *exists) const +int Object::indexOf(QStringView key, bool *exists) const { int min = 0; int n = length; @@ -257,7 +257,7 @@ bool Array::isValid(int maxSize) const } -bool Entry::operator ==(const QString &key) const +bool Entry::operator ==(QStringView key) const { if (value.latinKey) return (shallowLatin1Key() == key); @@ -270,7 +270,7 @@ bool Entry::operator==(QLatin1String key) const if (value.latinKey) return shallowLatin1Key() == key; else - return shallowKey() == key; + return shallowKey() == QString(key); // ### conversion to QString } bool Entry::operator ==(const Entry &other) const diff --git a/src/corelib/serialization/qjson_p.h b/src/corelib/serialization/qjson_p.h index 9de53d5b74..78082a920d 100644 --- a/src/corelib/serialization/qjson_p.h +++ b/src/corelib/serialization/qjson_p.h @@ -153,14 +153,14 @@ typedef qle_uint offset; // round the size up to the next 4 byte boundary inline int alignedSize(int size) { return (size + 3) & ~3; } -static inline bool useCompressed(const QString &s) +static inline bool useCompressed(QStringView s) { if (s.length() >= 0x8000) return false; return QtPrivate::isLatin1(s); } -static inline int qStringSize(const QString &string, bool compress) +static inline int qStringSize(QStringView string, bool compress) { int l = 2 + string.length(); if (!compress) @@ -214,37 +214,31 @@ public: return maxSize >= 0 && uint(d->length) <= maxSize / sizeof(ushort); } - inline String &operator=(const QString &str) + inline String &operator=(QStringView str) { d->length = str.length(); -#if Q_BYTE_ORDER == Q_BIG_ENDIAN - const ushort *uc = (const ushort *)str.unicode(); - for (int i = 0; i < str.length(); ++i) - d->utf16[i] = uc[i]; -#else - memcpy(d->utf16, str.unicode(), str.length()*sizeof(ushort)); -#endif + qToLittleEndian(str.utf16(), str.length(), d->utf16); if (str.length() & 1) d->utf16[str.length()] = 0; return *this; } - inline bool operator ==(const QString &str) const { + inline bool operator ==(QStringView str) const { int slen = str.length(); int l = d->length; if (slen != l) return false; - const ushort *s = (const ushort *)str.constData(); + const ushort *s = (const ushort *)str.utf16(); const qle_ushort *a = d->utf16; const ushort *b = s; while (l-- && *a == *b) a++,b++; return (l == -1); } - inline bool operator !=(const QString &str) const { + inline bool operator !=(QStringView str) const { return !operator ==(str); } - inline bool operator >=(const QString &str) const { + inline bool operator >=(QStringView str) const { // ### return toString() >= str; } @@ -292,11 +286,11 @@ public: return byteSize() <= maxSize; } - inline Latin1String &operator=(const QString &str) + inline Latin1String &operator=(QStringView str) { int len = d->length = str.length(); uchar *l = (uchar *)d->latin1; - const ushort *uc = (const ushort *)str.unicode(); + const ushort *uc = (const ushort *)str.utf16(); qt_to_latin1_unchecked(l, uc, len); for ( ; (quintptr)(l+len) & 0x3; ++len) @@ -351,11 +345,11 @@ public: { \ return lhs.toQLatin1String() op rhs; \ } \ - inline bool operator op(const QString &lhs, Latin1String rhs) noexcept \ + inline bool operator op(QStringView lhs, Latin1String rhs) noexcept \ { \ return lhs op rhs.toQLatin1String(); \ } \ - inline bool operator op(Latin1String lhs, const QString &rhs) noexcept \ + inline bool operator op(Latin1String lhs, QStringView rhs) noexcept \ { \ return lhs.toQLatin1String() op rhs; \ } \ @@ -419,7 +413,7 @@ inline bool String::operator<(const Latin1String &str) const } -static inline void copyString(char *dest, const QString &str, bool compress) +static inline void copyString(char *dest, QStringView str, bool compress) { if (compress) { Latin1String string(dest); @@ -469,7 +463,7 @@ public: Entry *entryAt(int i) const { return reinterpret_cast(((char *)this) + table()[i]); } - int indexOf(const QString &key, bool *exists) const; + int indexOf(QStringView key, bool *exists) const; int indexOf(QLatin1String key, bool *exists) const; bool isValid(int maxSize) const; @@ -577,9 +571,9 @@ public: return shallowKey().isValid(maxSize); } - bool operator ==(const QString &key) const; - inline bool operator !=(const QString &key) const { return !operator ==(key); } - inline bool operator >=(const QString &key) const; + bool operator ==(QStringView key) const; + inline bool operator !=(QStringView key) const { return !operator ==(key); } + inline bool operator >=(QStringView key) const; bool operator==(QLatin1String key) const; inline bool operator!=(QLatin1String key) const { return !operator ==(key); } @@ -589,7 +583,7 @@ public: bool operator >=(const Entry &other) const; }; -inline bool Entry::operator >=(const QString &key) const +inline bool Entry::operator >=(QStringView key) const { if (value.latinKey) return (shallowLatin1Key() >= key); @@ -602,10 +596,10 @@ inline bool Entry::operator >=(QLatin1String key) const if (value.latinKey) return shallowLatin1Key() >= key; else - return shallowKey() >= key; + return shallowKey() >= QString(key); // ### conversion to QString } -inline bool operator <(const QString &key, const Entry &e) +inline bool operator <(QStringView key, const Entry &e) { return e >= key; } inline bool operator<(QLatin1String key, const Entry &e) diff --git a/src/corelib/serialization/qjsondocument.cpp b/src/corelib/serialization/qjsondocument.cpp index f8027efb58..193b80ee22 100644 --- a/src/corelib/serialization/qjsondocument.cpp +++ b/src/corelib/serialization/qjsondocument.cpp @@ -544,6 +544,7 @@ void QJsonDocument::setArray(const QJsonArray &array) d->ref.ref(); } +#if QT_STRINGVIEW_LEVEL < 2 /*! Returns a QJsonValue representing the value for the key \a key. @@ -557,6 +558,16 @@ void QJsonDocument::setArray(const QJsonArray &array) \sa QJsonValue, QJsonValue::isUndefined(), QJsonObject */ const QJsonValue QJsonDocument::operator[](const QString &key) const +{ + return (*this)[QStringView(key)]; +} +#endif + +/*! + \overload + \since 5.14 +*/ +const QJsonValue QJsonDocument::operator[](QStringView key) const { if (!isObject()) return QJsonValue(QJsonValue::Undefined); diff --git a/src/corelib/serialization/qjsondocument.h b/src/corelib/serialization/qjsondocument.h index a8006a6cc5..a8e7485f5d 100644 --- a/src/corelib/serialization/qjsondocument.h +++ b/src/corelib/serialization/qjsondocument.h @@ -146,7 +146,10 @@ public: void setObject(const QJsonObject &object); void setArray(const QJsonArray &array); +#if QT_STRINGVIEW_LEVEL < 2 const QJsonValue operator[](const QString &key) const; +#endif + const QJsonValue operator[](QStringView key) const; const QJsonValue operator[](QLatin1String key) const; const QJsonValue operator[](int i) const; diff --git a/src/corelib/serialization/qjsonobject.cpp b/src/corelib/serialization/qjsonobject.cpp index e800d76ab6..19a16d8537 100644 --- a/src/corelib/serialization/qjsonobject.cpp +++ b/src/corelib/serialization/qjsonobject.cpp @@ -377,6 +377,7 @@ bool QJsonObject::isEmpty() const return !o->length; } +#if QT_STRINGVIEW_LEVEL < 2 /*! Returns a QJsonValue representing the value for the key \a key. @@ -385,6 +386,16 @@ bool QJsonObject::isEmpty() const \sa QJsonValue, QJsonValue::isUndefined() */ QJsonValue QJsonObject::value(const QString &key) const +{ + return value(QStringView(key)); +} +#endif + +/*! + \overload + \since 5.14 +*/ +QJsonValue QJsonObject::value(QStringView key) const { if (!d) return QJsonValue(QJsonValue::Undefined); @@ -412,6 +423,7 @@ QJsonValue QJsonObject::value(QLatin1String key) const return QJsonValue(d, o, o->entryAt(i)->value); } +#if QT_STRINGVIEW_LEVEL < 2 /*! Returns a QJsonValue representing the value for the key \a key. @@ -423,8 +435,16 @@ QJsonValue QJsonObject::value(QLatin1String key) const */ QJsonValue QJsonObject::operator [](const QString &key) const { - return value(key); + return (*this)[QStringView(key)]; } +#endif + +/*! + \fn QJsonValue QJsonObject::operator [](QStringView key) const + + \overload + \since 5.14 +*/ /*! \fn QJsonValue QJsonObject::operator [](QLatin1String key) const @@ -433,6 +453,7 @@ QJsonValue QJsonObject::operator [](const QString &key) const \since 5.7 */ +#if QT_STRINGVIEW_LEVEL < 2 /*! Returns a reference to the value for \a key. @@ -445,6 +466,16 @@ QJsonValue QJsonObject::operator [](const QString &key) const \sa value() */ QJsonValueRef QJsonObject::operator [](const QString &key) +{ + return (*this)[QStringView(key)]; +} +#endif + +/*! + \overload + \since 5.14 +*/ +QJsonValueRef QJsonObject::operator [](QStringView key) { bool keyExists = false; int index = o ? o->indexOf(key, &keyExists) : 0; @@ -465,6 +496,7 @@ QJsonValueRef QJsonObject::operator [](QLatin1String key) return operator[](QString(key)); } +#if QT_STRINGVIEW_LEVEL < 2 /*! Inserts a new item with the key \a key and a value of \a value. @@ -479,6 +511,16 @@ QJsonValueRef QJsonObject::operator [](QLatin1String key) \sa remove(), take(), QJsonObject::iterator, end() */ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue &value) +{ + return insert(QStringView(key), value); +} +#endif + +/*! + \overload + \since 5.14 +*/ +QJsonObject::iterator QJsonObject::insert(QStringView key, const QJsonValue &value) { if (value.t == QJsonValue::Undefined) { remove(key); @@ -492,7 +534,7 @@ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue & /*! \internal */ -QJsonObject::iterator QJsonObject::insertAt(int pos, const QString &key, const QJsonValue &value, bool keyExists) +QJsonObject::iterator QJsonObject::insertAt(int pos, QStringView key, const QJsonValue &value, bool keyExists) { QJsonValue val = value; @@ -530,12 +572,23 @@ QJsonObject::iterator QJsonObject::insertAt(int pos, const QString &key, const Q return iterator(this, pos); } +#if QT_STRINGVIEW_LEVEL < 2 /*! Removes \a key from the object. \sa insert(), take() */ void QJsonObject::remove(const QString &key) +{ + remove(QStringView(key)); +} +#endif + +/*! + \overload + \since 5.14 +*/ +void QJsonObject::remove(QStringView key) { if (!d) return; @@ -548,6 +601,7 @@ void QJsonObject::remove(const QString &key) removeAt(index); } +#if QT_STRINGVIEW_LEVEL < 2 /*! Removes \a key from the object. @@ -558,6 +612,16 @@ void QJsonObject::remove(const QString &key) \sa insert(), remove(), QJsonValue */ QJsonValue QJsonObject::take(const QString &key) +{ + return take(QStringView(key)); +} +#endif + +/*! + \overload + \since 5.14 +*/ +QJsonValue QJsonObject::take(QStringView key) { if (!o) return QJsonValue(QJsonValue::Undefined); @@ -573,12 +637,23 @@ QJsonValue QJsonObject::take(const QString &key) return v; } +#if QT_STRINGVIEW_LEVEL < 2 /*! Returns \c true if the object contains key \a key. \sa insert(), remove(), take() */ bool QJsonObject::contains(const QString &key) const +{ + return contains(QStringView(key)); +} +#endif + +/*! + \overload + \since 5.14 +*/ +bool QJsonObject::contains(QStringView key) const { if (!o) return false; @@ -656,6 +731,7 @@ QJsonObject::iterator QJsonObject::erase(QJsonObject::iterator it) return it; } +#if QT_STRINGVIEW_LEVEL < 2 /*! Returns an iterator pointing to the item with key \a key in the map. @@ -664,6 +740,16 @@ QJsonObject::iterator QJsonObject::erase(QJsonObject::iterator it) returns end(). */ QJsonObject::iterator QJsonObject::find(const QString &key) +{ + return find(QStringView(key)); +} +#endif + +/*! + \overload + \since 5.14 +*/ +QJsonObject::iterator QJsonObject::find(QStringView key) { bool keyExists = false; int index = o ? o->indexOf(key, &keyExists) : 0; @@ -687,10 +773,18 @@ QJsonObject::iterator QJsonObject::find(QLatin1String key) return iterator(this, index); } +#if QT_STRINGVIEW_LEVEL < 2 /*! \fn QJsonObject::const_iterator QJsonObject::find(const QString &key) const \overload */ +#endif + +/*! \fn QJsonObject::const_iterator QJsonObject::find(QStringView key) const + + \overload + \since 5.14 +*/ /*! \fn QJsonObject::const_iterator QJsonObject::find(QLatin1String key) const @@ -698,6 +792,7 @@ QJsonObject::iterator QJsonObject::find(QLatin1String key) \since 5.7 */ +#if QT_STRINGVIEW_LEVEL < 2 /*! Returns a const iterator pointing to the item with key \a key in the map. @@ -706,6 +801,16 @@ QJsonObject::iterator QJsonObject::find(QLatin1String key) returns constEnd(). */ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const +{ + return constFind(QStringView(key)); +} +#endif + +/*! + \overload + \since 5.14 +*/ +QJsonObject::const_iterator QJsonObject::constFind(QStringView key) const { bool keyExists = false; int index = o ? o->indexOf(key, &keyExists) : 0; diff --git a/src/corelib/serialization/qjsonobject.h b/src/corelib/serialization/qjsonobject.h index b12769d3d3..bdaf85b460 100644 --- a/src/corelib/serialization/qjsonobject.h +++ b/src/corelib/serialization/qjsonobject.h @@ -100,16 +100,26 @@ public: inline int length() const { return size(); } bool isEmpty() const; +#if QT_STRINGVIEW_LEVEL < 2 QJsonValue value(const QString &key) const; - QJsonValue value(QLatin1String key) const; QJsonValue operator[] (const QString &key) const; - QJsonValue operator[] (QLatin1String key) const { return value(key); } QJsonValueRef operator[] (const QString &key); +#endif + QJsonValue value(QStringView key) const; + QJsonValue value(QLatin1String key) const; + QJsonValue operator[] (QStringView key) const { return value(key); } + QJsonValue operator[] (QLatin1String key) const { return value(key); } + QJsonValueRef operator[] (QStringView key); QJsonValueRef operator[] (QLatin1String key); +#if QT_STRINGVIEW_LEVEL < 2 void remove(const QString &key); QJsonValue take(const QString &key); bool contains(const QString &key) const; +#endif + void remove(QStringView key); + QJsonValue take(QStringView key); + bool contains(QStringView key) const; bool contains(QLatin1String key) const; bool operator==(const QJsonObject &other) const; @@ -218,13 +228,19 @@ public: // more Qt typedef iterator Iterator; typedef const_iterator ConstIterator; +#if QT_STRINGVIEW_LEVEL < 2 iterator find(const QString &key); - iterator find(QLatin1String key); const_iterator find(const QString &key) const { return constFind(key); } - const_iterator find(QLatin1String key) const { return constFind(key); } const_iterator constFind(const QString &key) const; - const_iterator constFind(QLatin1String key) const; iterator insert(const QString &key, const QJsonValue &value); +#endif + iterator find(QStringView key); + iterator find(QLatin1String key); + const_iterator find(QStringView key) const { return constFind(key); } + const_iterator find(QLatin1String key) const { return constFind(key); } + const_iterator constFind(QStringView key) const; + const_iterator constFind(QLatin1String key) const; + iterator insert(QStringView key, const QJsonValue &value); // STL compatibility typedef QJsonValue mapped_type; @@ -253,7 +269,7 @@ private: QJsonValue valueAt(int i) const; void setValueAt(int i, const QJsonValue &val); void removeAt(int i); - iterator insertAt(int i, const QString &key, const QJsonValue &val, bool exists); + iterator insertAt(int i, QStringView key, const QJsonValue &val, bool exists); QJsonPrivate::Data *d; QJsonPrivate::Object *o; diff --git a/src/corelib/serialization/qjsonvalue.cpp b/src/corelib/serialization/qjsonvalue.cpp index 0bd28581f3..5f07a6a03e 100644 --- a/src/corelib/serialization/qjsonvalue.cpp +++ b/src/corelib/serialization/qjsonvalue.cpp @@ -694,6 +694,7 @@ QJsonObject QJsonValue::toObject() const return toObject(QJsonObject()); } +#if QT_STRINGVIEW_LEVEL < 2 /*! Returns a QJsonValue representing the value for the key \a key. @@ -707,6 +708,16 @@ QJsonObject QJsonValue::toObject() const \sa QJsonValue, QJsonValue::isUndefined(), QJsonObject */ const QJsonValue QJsonValue::operator[](const QString &key) const +{ + return (*this)[QStringView(key)]; +} +#endif + +/*! + \overload + \since 5.14 +*/ +const QJsonValue QJsonValue::operator[](QStringView key) const { if (!isObject()) return QJsonValue(QJsonValue::Undefined); diff --git a/src/corelib/serialization/qjsonvalue.h b/src/corelib/serialization/qjsonvalue.h index 37d84f9e60..430fa06c0f 100644 --- a/src/corelib/serialization/qjsonvalue.h +++ b/src/corelib/serialization/qjsonvalue.h @@ -137,7 +137,10 @@ public: QJsonObject toObject() const; QJsonObject toObject(const QJsonObject &defaultValue) const; +#if QT_STRINGVIEW_LEVEL < 2 const QJsonValue operator[](const QString &key) const; +#endif + const QJsonValue operator[](QStringView key) const; const QJsonValue operator[](QLatin1String key) const; const QJsonValue operator[](int i) const; diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp index 1cbe0cae48..28c84fd30f 100644 --- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp +++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp @@ -436,6 +436,7 @@ void tst_QtJson::testObjectSimple() object.insert("boolean", true); QCOMPARE(object.value("boolean").toBool(), true); QCOMPARE(object.value(QLatin1String("boolean")).toBool(), true); + QJsonObject object2 = object; QStringList keys = object.keys(); QVERIFY2(keys.contains("number"), "key number not found"); @@ -461,6 +462,23 @@ void tst_QtJson::testObjectSimple() object.insert("string", QString::fromLatin1("foo")); QVERIFY2(object.value(QLatin1String("string")).toString() != before, "value should have been updated"); + // same tests again but with QStringView keys + object2.insert(QStringView(u"value"), value); + QCOMPARE(object2.value("value"), value); + + size = object2.size(); + object2.remove(QStringView(u"boolean")); + QCOMPARE(object2.size(), size - 1); + QVERIFY2(!object2.contains(QStringView(u"boolean")), "key boolean should have been removed"); + + taken = object2.take(QStringView(u"value")); + QCOMPARE(taken, value); + QVERIFY2(!object2.contains("value"), "key value should have been removed"); + + before = object2.value("string").toString(); + object2.insert(QStringView(u"string"), QString::fromLatin1("foo")); + QVERIFY2(object2.value(QStringView(u"string")).toString() != before, "value should have been updated"); + size = object.size(); QJsonObject subobject; subobject.insert("number", 42); From 0652bdcf5e60461cd9a513d64be00b8830826fad Mon Sep 17 00:00:00 2001 From: Mat Sutcliffe Date: Tue, 16 Jul 2019 21:00:24 +0100 Subject: [PATCH 157/264] QJsonObject: add QLatin1String overloads of non-const methods Also optimized the existing QL1S overload of non-const operator[](), and applied Extract Method refactoring to the other existing QL1S overloads. [ChangeLog][QtCore][QJsonObject] Added insert(), remove(), and take() overloads taking QLatin1String. Change-Id: I5e737cf2d7d9ffb325d6981db1e4a6a9f093657b Reviewed-by: Thiago Macieira Reviewed-by: Anton Kudryavtsev --- src/corelib/serialization/qjson_p.h | 61 +++++++- src/corelib/serialization/qjsonobject.cpp | 148 +++++++++++++----- src/corelib/serialization/qjsonobject.h | 14 +- .../corelib/serialization/json/tst_qtjson.cpp | 42 +++++ 4 files changed, 221 insertions(+), 44 deletions(-) diff --git a/src/corelib/serialization/qjson_p.h b/src/corelib/serialization/qjson_p.h index 78082a920d..7978bed7da 100644 --- a/src/corelib/serialization/qjson_p.h +++ b/src/corelib/serialization/qjson_p.h @@ -66,11 +66,13 @@ #include #include +#include QT_BEGIN_NAMESPACE // in qstring.cpp void qt_to_latin1_unchecked(uchar *dst, const ushort *uc, qsizetype len); +void qt_from_latin1(ushort *dst, const char *str, size_t size) noexcept; /* This defines a binary data structure for Json data. The data structure is optimised for fast reading @@ -153,16 +155,24 @@ typedef qle_uint offset; // round the size up to the next 4 byte boundary inline int alignedSize(int size) { return (size + 3) & ~3; } +const int MaxLatin1Length = 0x7fff; + static inline bool useCompressed(QStringView s) { - if (s.length() >= 0x8000) + if (s.length() > MaxLatin1Length) return false; return QtPrivate::isLatin1(s); } -static inline int qStringSize(QStringView string, bool compress) +static inline bool useCompressed(QLatin1String s) { - int l = 2 + string.length(); + return s.size() <= MaxLatin1Length; +} + +template +static inline int qStringSize(T string, bool compress) +{ + int l = 2 + string.size(); if (!compress) l *= 2; return alignedSize(l); @@ -218,11 +228,29 @@ public: { d->length = str.length(); qToLittleEndian(str.utf16(), str.length(), d->utf16); - if (str.length() & 1) - d->utf16[str.length()] = 0; + fillTrailingZeros(); return *this; } + inline String &operator=(QLatin1String str) + { + d->length = str.size(); +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + for (int i = 0; i < str.size(); ++i) + d->utf16[i] = str[i].unicode(); +#else + qt_from_latin1((ushort *)d->utf16, str.data(), str.size()); +#endif + fillTrailingZeros(); + return *this; + } + + void fillTrailingZeros() + { + if (d->length & 1) + d->utf16[d->length] = 0; + } + inline bool operator ==(QStringView str) const { int slen = str.length(); int l = d->length; @@ -293,11 +321,27 @@ public: const ushort *uc = (const ushort *)str.utf16(); qt_to_latin1_unchecked(l, uc, len); - for ( ; (quintptr)(l+len) & 0x3; ++len) - l[len] = 0; + fillTrailingZeros(); return *this; } + inline Latin1String &operator=(QLatin1String str) + { + int len = d->length = str.size(); + uchar *l = (uchar *)d->latin1; + memcpy(l, str.data(), len); + + fillTrailingZeros(); + return *this; + } + + void fillTrailingZeros() + { + uchar *l = (uchar *)d->latin1; + for (int len = d->length; (quintptr)(l + len) & 0x3; ++len) + l[len] = 0; + } + QLatin1String toQLatin1String() const noexcept { return QLatin1String(d->latin1, d->length); } @@ -413,7 +457,8 @@ inline bool String::operator<(const Latin1String &str) const } -static inline void copyString(char *dest, QStringView str, bool compress) +template +static inline void copyString(char *dest, T str, bool compress) { if (compress) { Latin1String string(dest); diff --git a/src/corelib/serialization/qjsonobject.cpp b/src/corelib/serialization/qjsonobject.cpp index 19a16d8537..99ab25f265 100644 --- a/src/corelib/serialization/qjsonobject.cpp +++ b/src/corelib/serialization/qjsonobject.cpp @@ -397,14 +397,7 @@ QJsonValue QJsonObject::value(const QString &key) const */ QJsonValue QJsonObject::value(QStringView key) const { - if (!d) - return QJsonValue(QJsonValue::Undefined); - - bool keyExists; - int i = o->indexOf(key, &keyExists); - if (!keyExists) - return QJsonValue(QJsonValue::Undefined); - return QJsonValue(d, o, o->entryAt(i)->value); + return valueImpl(key); } /*! @@ -412,6 +405,15 @@ QJsonValue QJsonObject::value(QStringView key) const \since 5.7 */ QJsonValue QJsonObject::value(QLatin1String key) const +{ + return valueImpl(key); +} + +/*! + \internal +*/ +template +QJsonValue QJsonObject::valueImpl(T key) const { if (!d) return QJsonValue(QJsonValue::Undefined); @@ -477,13 +479,7 @@ QJsonValueRef QJsonObject::operator [](const QString &key) */ QJsonValueRef QJsonObject::operator [](QStringView key) { - bool keyExists = false; - int index = o ? o->indexOf(key, &keyExists) : 0; - if (!keyExists) { - iterator i = insertAt(index, key, QJsonValue(), false); - index = i.i; - } - return QJsonValueRef(this, index); + return atImpl(key); } /*! @@ -492,8 +488,22 @@ QJsonValueRef QJsonObject::operator [](QStringView key) */ QJsonValueRef QJsonObject::operator [](QLatin1String key) { - // ### optimize me - return operator[](QString(key)); + return atImpl(key); +} + +/*! + \internal +*/ +template +QJsonValueRef QJsonObject::atImpl(T key) +{ + bool keyExists = false; + int index = o ? o->indexOf(key, &keyExists) : 0; + if (!keyExists) { + iterator i = insertAt(index, key, QJsonValue(), false); + index = i.i; + } + return QJsonValueRef(this, index); } #if QT_STRINGVIEW_LEVEL < 2 @@ -521,6 +531,24 @@ QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue & \since 5.14 */ QJsonObject::iterator QJsonObject::insert(QStringView key, const QJsonValue &value) +{ + return insertImpl(key, value); +} + +/*! + \overload + \since 5.14 +*/ +QJsonObject::iterator QJsonObject::insert(QLatin1String key, const QJsonValue &value) +{ + return insertImpl(key, value); +} + +/*! + \internal +*/ +template +QJsonObject::iterator QJsonObject::insertImpl(T key, const QJsonValue &value) { if (value.t == QJsonValue::Undefined) { remove(key); @@ -534,7 +562,8 @@ QJsonObject::iterator QJsonObject::insert(QStringView key, const QJsonValue &val /*! \internal */ -QJsonObject::iterator QJsonObject::insertAt(int pos, QStringView key, const QJsonValue &value, bool keyExists) +template +QJsonObject::iterator QJsonObject::insertAt(int pos, T key, const QJsonValue &value, bool keyExists) { QJsonValue val = value; @@ -589,6 +618,24 @@ void QJsonObject::remove(const QString &key) \since 5.14 */ void QJsonObject::remove(QStringView key) +{ + removeImpl(key); +} + +/*! + \overload + \since 5.14 +*/ +void QJsonObject::remove(QLatin1String key) +{ + removeImpl(key); +} + +/*! + \internal +*/ +template +void QJsonObject::removeImpl(T key) { if (!d) return; @@ -622,6 +669,24 @@ QJsonValue QJsonObject::take(const QString &key) \since 5.14 */ QJsonValue QJsonObject::take(QStringView key) +{ + return takeImpl(key); +} + +/*! + \overload + \since 5.14 +*/ +QJsonValue QJsonObject::take(QLatin1String key) +{ + return takeImpl(key); +} + +/*! + \internal +*/ +template +QJsonValue QJsonObject::takeImpl(T key) { if (!o) return QJsonValue(QJsonValue::Undefined); @@ -655,12 +720,7 @@ bool QJsonObject::contains(const QString &key) const */ bool QJsonObject::contains(QStringView key) const { - if (!o) - return false; - - bool keyExists; - o->indexOf(key, &keyExists); - return keyExists; + return containsImpl(key); } /*! @@ -668,6 +728,15 @@ bool QJsonObject::contains(QStringView key) const \since 5.7 */ bool QJsonObject::contains(QLatin1String key) const +{ + return containsImpl(key); +} + +/*! + \internal +*/ +template +bool QJsonObject::containsImpl(T key) const { if (!o) return false; @@ -751,12 +820,7 @@ QJsonObject::iterator QJsonObject::find(const QString &key) */ QJsonObject::iterator QJsonObject::find(QStringView key) { - bool keyExists = false; - int index = o ? o->indexOf(key, &keyExists) : 0; - if (!keyExists) - return end(); - detach2(); - return iterator(this, index); + return findImpl(key); } /*! @@ -764,6 +828,15 @@ QJsonObject::iterator QJsonObject::find(QStringView key) \since 5.7 */ QJsonObject::iterator QJsonObject::find(QLatin1String key) +{ + return findImpl(key); +} + +/*! + \internal +*/ +template +QJsonObject::iterator QJsonObject::findImpl(T key) { bool keyExists = false; int index = o ? o->indexOf(key, &keyExists) : 0; @@ -812,11 +885,7 @@ QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const */ QJsonObject::const_iterator QJsonObject::constFind(QStringView key) const { - bool keyExists = false; - int index = o ? o->indexOf(key, &keyExists) : 0; - if (!keyExists) - return end(); - return const_iterator(this, index); + return constFindImpl(key); } /*! @@ -824,6 +893,15 @@ QJsonObject::const_iterator QJsonObject::constFind(QStringView key) const \since 5.7 */ QJsonObject::const_iterator QJsonObject::constFind(QLatin1String key) const +{ + return constFindImpl(key); +} + +/*! + \internal +*/ +template +QJsonObject::const_iterator QJsonObject::constFindImpl(T key) const { bool keyExists = false; int index = o ? o->indexOf(key, &keyExists) : 0; diff --git a/src/corelib/serialization/qjsonobject.h b/src/corelib/serialization/qjsonobject.h index bdaf85b460..05463f6f36 100644 --- a/src/corelib/serialization/qjsonobject.h +++ b/src/corelib/serialization/qjsonobject.h @@ -118,7 +118,9 @@ public: bool contains(const QString &key) const; #endif void remove(QStringView key); + void remove(QLatin1String key); QJsonValue take(QStringView key); + QJsonValue take(QLatin1String key); bool contains(QStringView key) const; bool contains(QLatin1String key) const; @@ -241,6 +243,7 @@ public: const_iterator constFind(QStringView key) const; const_iterator constFind(QLatin1String key) const; iterator insert(QStringView key, const QJsonValue &value); + iterator insert(QLatin1String key, const QJsonValue &value); // STL compatibility typedef QJsonValue mapped_type; @@ -265,11 +268,20 @@ private: void compact(); void compactIfNeeded(); + template QJsonValue valueImpl(T key) const; + template QJsonValueRef atImpl(T key); + template void removeImpl(T key); + template QJsonValue takeImpl(T key); + template bool containsImpl(T key) const; + template iterator findImpl(T key); + template const_iterator constFindImpl(T key) const; + template iterator insertImpl(T key, const QJsonValue &value); + QString keyAt(int i) const; QJsonValue valueAt(int i) const; void setValueAt(int i, const QJsonValue &val); void removeAt(int i); - iterator insertAt(int i, QStringView key, const QJsonValue &val, bool exists); + template iterator insertAt(int i, T key, const QJsonValue &val, bool exists); QJsonPrivate::Data *d; QJsonPrivate::Object *o; diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp index 28c84fd30f..7b055b5b63 100644 --- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp +++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp @@ -437,6 +437,7 @@ void tst_QtJson::testObjectSimple() QCOMPARE(object.value("boolean").toBool(), true); QCOMPARE(object.value(QLatin1String("boolean")).toBool(), true); QJsonObject object2 = object; + QJsonObject object3 = object; QStringList keys = object.keys(); QVERIFY2(keys.contains("number"), "key number not found"); @@ -479,6 +480,23 @@ void tst_QtJson::testObjectSimple() object2.insert(QStringView(u"string"), QString::fromLatin1("foo")); QVERIFY2(object2.value(QStringView(u"string")).toString() != before, "value should have been updated"); + // same tests again but with QLatin1String keys + object3.insert(QLatin1String("value"), value); + QCOMPARE(object3.value("value"), value); + + size = object3.size(); + object3.remove(QLatin1String("boolean")); + QCOMPARE(object3.size(), size - 1); + QVERIFY2(!object3.contains("boolean"), "key boolean should have been removed"); + + taken = object3.take(QLatin1String("value")); + QCOMPARE(taken, value); + QVERIFY2(!object3.contains("value"), "key value should have been removed"); + + before = object3.value("string").toString(); + object3.insert(QLatin1String("string"), QString::fromLatin1("foo")); + QVERIFY2(object3.value(QLatin1String("string")).toString() != before, "value should have been updated"); + size = object.size(); QJsonObject subobject; subobject.insert("number", 42); @@ -2716,6 +2734,8 @@ void tst_QtJson::longStrings() // test around 15 and 16 bit boundaries, as these are limits // in the data structures (for Latin1String in qjson_p.h) QString s(0x7ff0, 'a'); + QByteArray ba(0x7ff0, 'a'); + ba.append(0x8010 - 0x7ff0, 'c'); for (int i = 0x7ff0; i < 0x8010; i++) { s.append(QLatin1Char('c')); @@ -2732,9 +2752,21 @@ void tst_QtJson::longStrings() /* ... and a QByteArray from the QJsonDocument */ QByteArray a2 = d2.toJson(); QCOMPARE(a1, a2); + + // Test long keys + QJsonObject o1, o2; + o1[s] = 42; + o2[QLatin1String(ba.data(), i + 1)] = 42; + d1.setObject(o1); + d2.setObject(o2); + a1 = d1.toJson(); + a2 = d2.toJson(); + QCOMPARE(a1, a2); } s = QString(0xfff0, 'a'); + ba = QByteArray(0xfff0, 'a'); + ba.append(0x10010 - 0xfff0, 'c'); for (int i = 0xfff0; i < 0x10010; i++) { s.append(QLatin1Char('c')); @@ -2751,6 +2783,16 @@ void tst_QtJson::longStrings() /* ... and a QByteArray from the QJsonDocument */ QByteArray a2 = d2.toJson(); QCOMPARE(a1, a2); + + // Test long keys + QJsonObject o1, o2; + o1[s] = 42; + o2[QLatin1String(ba.data(), i + 1)] = 42; + d1.setObject(o1); + d2.setObject(o2); + a1 = d1.toJson(); + a2 = d2.toJson(); + QCOMPARE(a1, a2); } } From b202d45026229e0517e80a6e82041d5fc89d9d23 Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Fri, 19 Jul 2019 16:00:57 +0100 Subject: [PATCH 158/264] Make simulator detection work with Xcode 11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Beta version of Xcode 11 changes the format of the json object returned by simctl and used to detect running simulators. While multiple versions of Xcode can coexist on the same system, they share the same simulator infrastructure so installing Xcode 11 Beta affects projects using previous versions. Change-Id: Icf06a794aa5ba3624163ace2ce827c0ecf97c38c Reviewed-by: Frank Osterfeld Reviewed-by: Tor Arne Vestbø --- mkspecs/features/uikit/devices.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/uikit/devices.py b/mkspecs/features/uikit/devices.py index 0443e838f2..8cdcb370a0 100755 --- a/mkspecs/features/uikit/devices.py +++ b/mkspecs/features/uikit/devices.py @@ -46,11 +46,17 @@ import json import subprocess from distutils.version import StrictVersion +def is_available(object): + if "isAvailable" in object: + return object["isAvailable"] # introduced in Xcode 11 + else: + return "unavailable" not in object["availability"] + def is_suitable_runtime(runtimes, runtime_name, platform, min_version): for runtime in runtimes: identifier = runtime["identifier"] if (runtime["name"] == runtime_name or identifier == runtime_name) \ - and "unavailable" not in runtime["availability"] \ + and is_available(runtime) \ and identifier.startswith("com.apple.CoreSimulator.SimRuntime.{}".format(platform)) \ and StrictVersion(runtime["version"]) >= min_version: return True @@ -77,6 +83,6 @@ if __name__ == "__main__": for runtime_name in device_dict: if is_suitable_runtime(runtimes, runtime_name, args.platform, args.minimum_deployment_target): for device in device_dict[runtime_name]: - if "unavailable" not in device["availability"] \ + if is_available(device) \ and (args.state is None or device["state"].lower() in args.state): print(device["udid"]) From f4e0dda205d2a5c69caa3a7e423ef15f6565c983 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 1 Jul 2019 11:12:45 +0200 Subject: [PATCH 159/264] rhi: gl: Fix feature version check logic It was somewhat incorrect in a few places. Some of these should be moved to QOpenGLFunctions/Extensions later. Change-Id: Ibc7a6409f16ddf1ad71230671dcad558dac1b86f Reviewed-by: Lars Knoll --- src/gui/rhi/qrhigles2.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 22cb030c27..e56710a4bf 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -400,9 +400,9 @@ bool QRhiGles2::create(QRhi::Flags flags) caps.gles = actualFormat.renderableType() == QSurfaceFormat::OpenGLES; if (caps.gles) - caps.fixedIndexPrimitiveRestart = caps.ctxMajor >= 3; + caps.fixedIndexPrimitiveRestart = caps.ctxMajor >= 3; // ES 3.0 else - caps.fixedIndexPrimitiveRestart = caps.ctxMajor > 4 || (caps.ctxMajor == 4 && caps.ctxMinor >= 3); + caps.fixedIndexPrimitiveRestart = caps.ctxMajor > 4 || (caps.ctxMajor == 4 && caps.ctxMinor >= 3); // 4.3 if (caps.fixedIndexPrimitiveRestart) f->glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX); @@ -411,8 +411,8 @@ bool QRhiGles2::create(QRhi::Flags flags) caps.bgraInternalFormat = caps.bgraExternalFormat && caps.gles; caps.r8Format = f->hasOpenGLFeature(QOpenGLFunctions::TextureRGFormats); caps.r16Format = f->hasOpenGLExtension(QOpenGLExtensions::Sized16Formats); - caps.floatFormats = caps.ctxMajor >= 3; - caps.depthTexture = caps.ctxMajor >= 3; + caps.floatFormats = caps.ctxMajor >= 3; // 3.0 or ES 3.0 + caps.depthTexture = caps.ctxMajor >= 3; // 3.0 or ES 3.0 caps.packedDepthStencil = f->hasOpenGLExtension(QOpenGLExtensions::PackedDepthStencil); #ifdef Q_OS_WASM caps.needsDepthStencilCombinedAttach = true; @@ -421,12 +421,22 @@ bool QRhiGles2::create(QRhi::Flags flags) #endif caps.srgbCapableDefaultFramebuffer = f->hasOpenGLExtension(QOpenGLExtensions::SRGBFrameBuffer); caps.coreProfile = actualFormat.profile() == QSurfaceFormat::CoreProfile; - caps.uniformBuffers = caps.ctxMajor >= 3 && (caps.gles || caps.ctxMinor >= 1); + + if (caps.gles) + caps.uniformBuffers = caps.ctxMajor >= 3; // ES 3.0 + else + caps.uniformBuffers = caps.ctxMajor > 3 || (caps.ctxMajor == 3 && caps.ctxMinor >= 1); // 3.1 + caps.elementIndexUint = f->hasOpenGLExtension(QOpenGLExtensions::ElementIndexUint); caps.depth24 = f->hasOpenGLExtension(QOpenGLExtensions::Depth24); caps.rgba8Format = f->hasOpenGLExtension(QOpenGLExtensions::Sized8Formats); - caps.instancing = caps.ctxMajor >= 3 && (caps.gles || caps.ctxMinor >= 3); - caps.baseVertex = caps.ctxMajor >= 3 && caps.ctxMinor >= 2; + + if (caps.gles) + caps.instancing = caps.ctxMajor >= 3; // ES 3.0 + else + caps.instancing = caps.ctxMajor > 3 || (caps.ctxMajor == 3 && caps.ctxMinor >= 3); // 3.3 + + caps.baseVertex = caps.ctxMajor > 3 || (caps.ctxMajor == 3 && caps.ctxMinor >= 2); // 3.2 or ES 3.2 nativeHandlesStruct.context = ctx; From 86f91bf0f707e34392fbdf424d6914e7cf6bb4e6 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Sun, 21 Jul 2019 22:15:45 +0200 Subject: [PATCH 160/264] Make the warning in QBackingStore::endPaint() a little more helpful MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Amends 2aa9908e24611fa6d321e694b8415ba7e8d364b0 Change-Id: I2883ca27b06b2b414b4991b2dab3f84100b4c853 Reviewed-by: Tor Arne Vestbø --- src/gui/painting/qbackingstore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index d935deb4d6..b9ed3d4995 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -186,7 +186,7 @@ QPaintDevice *QBackingStore::paintDevice() void QBackingStore::endPaint() { if (paintDevice()->paintingActive()) - qWarning() << "QBackingStore::endPaint() called with active painter on backingstore paint device"; + qWarning("QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?"); handle()->endPaint(); } From 547f216efdef3667b0b23ecddce93e5184806800 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Tue, 16 Jul 2019 14:51:02 +1000 Subject: [PATCH 161/264] wasm: fix international dead keys Emscripten has changed the key code to include the string 'Digit' on numerals. We use this to detect and translate any Dead keys that may be pressed. Fixes: QTBUG-77041 Change-Id: I054e98a6cf66390b1154f25fe385e5b12840851f Reviewed-by: Volker Hilsheimer --- .../platforms/wasm/qwasmeventtranslator.cpp | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index 3895646b89..43e82435cf 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -138,16 +138,16 @@ static constexpr const auto KeyTbl = qMakeArray( Emkb2Qt< Qt::Key_Minus, '-' >, Emkb2Qt< Qt::Key_Period, '.' >, Emkb2Qt< Qt::Key_Slash, '/' >, - Emkb2Qt< Qt::Key_0, '0' >, - Emkb2Qt< Qt::Key_1, '1' >, - Emkb2Qt< Qt::Key_2, '2' >, - Emkb2Qt< Qt::Key_3, '3' >, - Emkb2Qt< Qt::Key_4, '4' >, - Emkb2Qt< Qt::Key_5, '5' >, - Emkb2Qt< Qt::Key_6, '6' >, - Emkb2Qt< Qt::Key_7, '7' >, - Emkb2Qt< Qt::Key_8, '8' >, - Emkb2Qt< Qt::Key_9, '9' >, + Emkb2Qt< Qt::Key_0, 'D','i','g','i','t','0' >, + Emkb2Qt< Qt::Key_1, 'D','i','g','i','t','1' >, + Emkb2Qt< Qt::Key_2, 'D','i','g','i','t','2' >, + Emkb2Qt< Qt::Key_3, 'D','i','g','i','t','3' >, + Emkb2Qt< Qt::Key_4, 'D','i','g','i','t','4' >, + Emkb2Qt< Qt::Key_5, 'D','i','g','i','t','5' >, + Emkb2Qt< Qt::Key_6, 'D','i','g','i','t','6' >, + Emkb2Qt< Qt::Key_7, 'D','i','g','i','t','7' >, + Emkb2Qt< Qt::Key_8, 'D','i','g','i','t','8' >, + Emkb2Qt< Qt::Key_9, 'D','i','g','i','t','9' >, Emkb2Qt< Qt::Key_Semicolon, ';' >, Emkb2Qt< Qt::Key_Equal, '=' >, Emkb2Qt< Qt::Key_A, 'K','e','y','A' >, @@ -432,7 +432,8 @@ Qt::Key QWasmEventTranslator::translateEmscriptKey(const EmscriptenKeyboardEvent { Qt::Key qtKey = Qt::Key_unknown; - if (qstrncmp(emscriptKey->code, "Key", 3) == 0 || qstrncmp(emscriptKey->code, "Numpad", 6) == 0) { + if (qstrncmp(emscriptKey->code, "Key", 3) == 0 || qstrncmp(emscriptKey->code, "Numpad", 6) == 0 || + qstrncmp(emscriptKey->code, "Digit", 5) == 0) { emkb2qt_t searchKey{emscriptKey->code, 0}; // search emcsripten code auto it1 = std::lower_bound(KeyTbl.cbegin(), KeyTbl.cend(), searchKey); @@ -808,11 +809,10 @@ Qt::Key QWasmEventTranslator::translateDeadKey(Qt::Key deadKey, Qt::Key accentBa case Qt::Key_Apostrophe:// linux wasmKey = circumflexKeyTable.value(accentBaseKey); break; - break; default: break; - }; + }; return wasmKey; } From c21cc647e98327856006701ee59b798ef2723e85 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 22 Jul 2019 14:00:20 +0200 Subject: [PATCH 162/264] Fix lancebench results oddness Imports were expanded in the list of commands every time they were evaluated. This meant any test with imports ran slower and slower the more iterations it got through. Fixed by creating a new PaintCommands object every time and living with initialization of it being part of the benchmark results. Change-Id: Ib53a3a25f1393437452bc5aede04ccb63e8715a6 Reviewed-by: Eirik Aavitsland --- .../painting/lancebench/tst_lancebench.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/benchmarks/gui/painting/lancebench/tst_lancebench.cpp b/tests/benchmarks/gui/painting/lancebench/tst_lancebench.cpp index bd0889bf4a..d26ac016b9 100644 --- a/tests/benchmarks/gui/painting/lancebench/tst_lancebench.cpp +++ b/tests/benchmarks/gui/painting/lancebench/tst_lancebench.cpp @@ -305,17 +305,17 @@ void tst_LanceBench::runTestSuite(GraphicsEngine engine, QImage::Format format, void tst_LanceBench::paint(QPaintDevice *device, GraphicsEngine engine, QImage::Format format, const QStringList &script, const QString &filePath) { - PaintCommands pcmd(script, 800, 800, format); - switch (engine) { - case OpenGL: - pcmd.setType(OpenGLBufferType); // version/profile is communicated through the context's format() - break; - case Raster: - pcmd.setType(ImageType); - break; - } - pcmd.setFilePath(filePath); QBENCHMARK { + PaintCommands pcmd(script, 800, 800, format); + switch (engine) { + case OpenGL: + pcmd.setType(OpenGLBufferType); // version/profile is communicated through the context's format() + break; + case Raster: + pcmd.setType(ImageType); + break; + } + pcmd.setFilePath(filePath); QPainter p(device); pcmd.setPainter(&p); pcmd.runCommands(); From aa4470943d0fafb20c8e90d5f5a71369a990189a Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Fri, 19 Jul 2019 18:06:27 +0200 Subject: [PATCH 163/264] Procrastinate QWheelEvent deprecations until 5.15 It turns out that Qt3D has uses of x() and y() in a header, which is an error rather than just a warning. So we need more time to do a qt5.git submodule update, then fix Qt3D. Amends 7d29807296cb7ccc7f3459e106d74f93a321c493 Change-Id: Ibead628e7094316bb17d5924f6c6f75dbda5826b Reviewed-by: Liang Qi Reviewed-by: Edward Welbourne --- src/gui/kernel/qevent.cpp | 4 ++-- src/gui/kernel/qevent.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 2ec90433d6..ec52791010 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -758,7 +758,7 @@ QHoverEvent::~QHoverEvent() */ #if QT_CONFIG(wheelevent) -#if QT_DEPRECATED_SINCE(5, 14) +#if QT_DEPRECATED_SINCE(5, 15) /*! \obsolete This constructor has been deprecated. @@ -839,7 +839,7 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, angleD(angleDelta), qt4D(qt4Delta), qt4O(qt4Orientation), mouseState(buttons), src(source), invertedScrolling(inverted), ph(phase) {} -#endif // QT_DEPRECATED_SINCE(5, 14) +#endif // QT_DEPRECATED_SINCE(5, 15) /*! Constructs a wheel event object. diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index d110529927..7653cc97e2 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -175,7 +175,7 @@ class Q_GUI_EXPORT QWheelEvent : public QInputEvent public: enum { DefaultDeltasPerStep = 120 }; -#if QT_DEPRECATED_SINCE(5, 14) +#if QT_DEPRECATED_SINCE(5, 15) // Actually deprecated since 5.0, in docs QT_DEPRECATED_X("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") QWheelEvent(const QPointF &pos, int delta, @@ -213,7 +213,7 @@ public: inline QPoint pixelDelta() const { return pixelD; } inline QPoint angleDelta() const { return angleD; } -#if QT_DEPRECATED_SINCE(5, 14) +#if QT_DEPRECATED_SINCE(5, 15) // Actually deprecated since 5.0, in docs QT_DEPRECATED_X("Use angleDelta()") inline int delta() const { return qt4D; } @@ -238,7 +238,7 @@ public: inline const QPointF &posF() const { return p; } QT_DEPRECATED_X("Use globalPosition()") inline const QPointF &globalPosF() const { return g; } -#endif // QT_DEPRECATED_SINCE(5, 14) +#endif // QT_DEPRECATED_SINCE(5, 15) inline QPointF position() const { return p; } inline QPointF globalPosition() const { return g; } From 181e96cae2db8ec0b87adc18db1c603bf41fc0ed Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 12 Jul 2019 10:33:07 +0200 Subject: [PATCH 164/264] Remove public d_func from QColorSpace Replaced with getter in private. Change-Id: I968eb45052a80b45750213cf6a0c08b5973dfc4d Reviewed-by: Eirik Aavitsland --- src/gui/image/qpnghandler.cpp | 5 +++-- src/gui/painting/qcolorspace.cpp | 14 -------------- src/gui/painting/qcolorspace.h | 4 +--- src/gui/painting/qcolorspace_p.h | 11 +++++++++++ src/gui/painting/qicc.cpp | 4 ++-- .../gui/painting/qcolorspace/tst_qcolorspace.cpp | 10 +++++----- 6 files changed, 22 insertions(+), 26 deletions(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index cd1c1d5433..4b72888414 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -607,7 +607,8 @@ bool QPngHandlerPrivate::readPngHeader() #endif png_uint_32 profLen; png_get_iCCP(png_ptr, info_ptr, &name, &compressionType, &profileData, &profLen); - if (!QIcc::fromIccProfile(QByteArray::fromRawData((const char *)profileData, profLen), &colorSpace)) { + colorSpace = QColorSpace::fromIccProfile(QByteArray::fromRawData((const char *)profileData, profLen)); + if (!colorSpace.isValid()) { qWarning() << "QPngHandler: Failed to parse ICC profile"; } else { colorSpaceState = Icc; @@ -677,7 +678,7 @@ bool QPngHandlerPrivate::readPngImage(QImage *outImage) // This configuration forces gamma correction and // thus changes the output colorspace png_set_gamma(png_ptr, 1.0f / gamma, fileGamma); - QColorSpacePrivate *csPrivate = colorSpace.d_func(); + QColorSpacePrivate *csPrivate = QColorSpacePrivate::getWritable(colorSpace); csPrivate->transferFunction = QColorSpace::TransferFunction::Gamma; csPrivate->gamma = gamma; csPrivate->setTransferFunction(); diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp index 881a02ee67..3c336c9fe7 100644 --- a/src/gui/painting/qcolorspace.cpp +++ b/src/gui/painting/qcolorspace.cpp @@ -683,20 +683,6 @@ QColorTransform QColorSpace::transformationToColorSpace(const QColorSpace &color return d_ptr->transformationToColorSpace(colorspace.d_ptr.constData()); } -/*! - \internal -*/ -QColorSpacePrivate *QColorSpace::d_func() -{ - d_ptr.detach(); - return d_ptr.data(); -} - -/*! - \fn const QColorSpacePrivate* QColorSpacePrivate::d_func() const - \internal -*/ - /***************************************************************************** QColorSpace stream functions *****************************************************************************/ diff --git a/src/gui/painting/qcolorspace.h b/src/gui/painting/qcolorspace.h index 6f1a806b60..709ce38916 100644 --- a/src/gui/painting/qcolorspace.h +++ b/src/gui/painting/qcolorspace.h @@ -113,11 +113,9 @@ public: QColorTransform transformationToColorSpace(const QColorSpace &colorspace) const; - QColorSpacePrivate *d_func(); - inline const QColorSpacePrivate *d_func() const { return d_ptr.constData(); } private: - friend class QColorSpacePrivate; + Q_DECLARE_PRIVATE(QColorSpace) QExplicitlySharedDataPointer d_ptr; }; diff --git a/src/gui/painting/qcolorspace_p.h b/src/gui/painting/qcolorspace_p.h index 95e0655d0c..75b74f062f 100644 --- a/src/gui/painting/qcolorspace_p.h +++ b/src/gui/painting/qcolorspace_p.h @@ -95,6 +95,17 @@ public: QColorSpacePrivate(const QColorSpacePrimaries &primaries, QColorSpace::TransferFunction fun, float gamma); QColorSpacePrivate(const QColorSpacePrivate &other) = default; + static QColorSpacePrivate *getWritable(QColorSpace &colorSpace) + { + colorSpace.d_ptr.detach(); + return colorSpace.d_ptr.data(); + } + + static const QColorSpacePrivate *get(const QColorSpace &colorSpace) + { + return colorSpace.d_ptr.data(); + } + void initialize(); void setToXyzMatrix(); void setTransferFunction(); diff --git a/src/gui/painting/qicc.cpp b/src/gui/painting/qicc.cpp index d88b005782..2abb42993b 100644 --- a/src/gui/painting/qicc.cpp +++ b/src/gui/painting/qicc.cpp @@ -288,7 +288,7 @@ QByteArray toIccProfile(const QColorSpace &space) if (!space.isValid()) return QByteArray(); - const QColorSpacePrivate *spaceDPtr = space.d_func(); + const QColorSpacePrivate *spaceDPtr = QColorSpacePrivate::get(space); constexpr int tagCount = 9; constexpr uint profileDataOffset = 128 + 4 + 12 * tagCount; @@ -569,7 +569,7 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace) qCWarning(lcIcc) << "fromIccProfile: Bad XYZ data type"; return false; } - QColorSpacePrivate *colorspaceDPtr = colorSpace->d_func(); + QColorSpacePrivate *colorspaceDPtr = QColorSpacePrivate::getWritable(*colorSpace); colorspaceDPtr->toXyz.r = fromXyzData(rXyz); colorspaceDPtr->toXyz.g = fromXyzData(gXyz); diff --git a/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp b/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp index 7a88eb18b2..b82a56dbf8 100644 --- a/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp +++ b/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp @@ -304,11 +304,11 @@ void tst_QColorSpace::primariesXyz() QColorSpace bt2020 = QColorSpace::Bt2020; // Check if our calculated matrices, match the precalculated ones. - QCOMPARE(sRgb.d_func()->toXyz, QColorMatrix::toXyzFromSRgb()); - QCOMPARE(adobeRgb.d_func()->toXyz, QColorMatrix::toXyzFromAdobeRgb()); - QCOMPARE(displayP3.d_func()->toXyz, QColorMatrix::toXyzFromDciP3D65()); - QCOMPARE(proPhotoRgb.d_func()->toXyz, QColorMatrix::toXyzFromProPhotoRgb()); - QCOMPARE(bt2020.d_func()->toXyz, QColorMatrix::toXyzFromBt2020()); + QCOMPARE(QColorSpacePrivate::get(sRgb)->toXyz, QColorMatrix::toXyzFromSRgb()); + QCOMPARE(QColorSpacePrivate::get(adobeRgb)->toXyz, QColorMatrix::toXyzFromAdobeRgb()); + QCOMPARE(QColorSpacePrivate::get(displayP3)->toXyz, QColorMatrix::toXyzFromDciP3D65()); + QCOMPARE(QColorSpacePrivate::get(proPhotoRgb)->toXyz, QColorMatrix::toXyzFromProPhotoRgb()); + QCOMPARE(QColorSpacePrivate::get(bt2020)->toXyz, QColorMatrix::toXyzFromBt2020()); } void tst_QColorSpace::primaries2_data() From 19f72c17c03b5065b98e0a7f3aae08ef7ca1ef03 Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Wed, 17 Jul 2019 10:37:36 +0200 Subject: [PATCH 165/264] Make network tests build and pass with disabled deprecated APIs Deprecated APIs of network lib are used only in tests. This change makes sure, that the tests build and pass with those deprecated APIs removed or disabled, by: - Making the parts of the tests testing the deprecated APIs to be compiled conditionally, only when the corresponding methods are enabled. - If the test-case tests only the deprecated API, but not the corresponding replacement, added tests for the replacement. Task-number: QTBUG-76541 Change-Id: I78c4913155007fd1d0df2c38e1b9a8b80066adeb Reviewed-by: Volker Hilsheimer Reviewed-by: Alex Blasche Reviewed-by: Timur Pocheptsov --- .../kernel/qhostaddress/tst_qhostaddress.cpp | 3 + .../network/ssl/qsslsocket/tst_qsslsocket.cpp | 245 ++++++++++++++---- ...qsslsocket_onDemandCertificates_member.cpp | 30 ++- ...qsslsocket_onDemandCertificates_static.cpp | 2 + 4 files changed, 230 insertions(+), 50 deletions(-) diff --git a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp index 224e4d61a9..48f05a4604 100644 --- a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp +++ b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp @@ -375,11 +375,14 @@ QT_WARNING_DISABLE_DEPRECATED void tst_QHostAddress::assignment() { QHostAddress address; + +#if QT_DEPRECATED_SINCE(5, 8) address = "127.0.0.1"; QCOMPARE(address, QHostAddress("127.0.0.1")); address = "::1"; QCOMPARE(address, QHostAddress("::1")); +#endif // WinRT does not support sockaddr_in #ifndef Q_OS_WINRT diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index 9924688bdf..4e02320362 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -546,6 +546,7 @@ void tst_QSslSocket::constructing() // verify that changing the default config doesn't affect this socket // (on Unix, the ca certs might be empty, depending on whether we load // them on demand or not, so set them explicitly) +#if QT_DEPRECATED_SINCE(5, 5) socket.setCaCertificates(QSslSocket::systemCaCertificates()); QSslSocket::setDefaultCaCertificates(QList()); QSslSocket::setDefaultCiphers(QList()); @@ -556,6 +557,25 @@ void tst_QSslSocket::constructing() QVERIFY(QSslConfiguration::defaultConfiguration().caCertificates().isEmpty()); QVERIFY(QSslConfiguration::defaultConfiguration().ciphers().isEmpty()); + QSslConfiguration::setDefaultConfiguration(savedDefault); +#endif + + auto sslConfig = socket.sslConfiguration(); + sslConfig.setCaCertificates(QSslConfiguration::systemCaCertificates()); + socket.setSslConfiguration(sslConfig); + + auto defaultConfig = QSslConfiguration::defaultConfiguration(); + defaultConfig.setCaCertificates(QList()); + defaultConfig.setCiphers(QList()); + QSslConfiguration::setDefaultConfiguration(defaultConfig); + + QVERIFY(!socket.sslConfiguration().caCertificates().isEmpty()); + QVERIFY(!socket.sslConfiguration().ciphers().isEmpty()); + + // verify the default as well: + QVERIFY(QSslConfiguration::defaultConfiguration().caCertificates().isEmpty()); + QVERIFY(QSslConfiguration::defaultConfiguration().ciphers().isEmpty()); + QSslConfiguration::setDefaultConfiguration(savedDefault); } @@ -756,18 +776,41 @@ void tst_QSslSocket::ciphers() { if (!QSslSocket::supportsSsl()) return; +#if QT_DEPRECATED_SINCE(5, 5) + { + QSslSocket socket; + QCOMPARE(socket.ciphers(), QSslSocket::defaultCiphers()); + socket.setCiphers(QList()); + QVERIFY(socket.ciphers().isEmpty()); + socket.setCiphers(socket.defaultCiphers()); + QCOMPARE(socket.ciphers(), QSslSocket::defaultCiphers()); + socket.setCiphers(socket.defaultCiphers()); + QCOMPARE(socket.ciphers(), QSslSocket::defaultCiphers()); + // Task 164356 + socket.setCiphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + } +#endif QSslSocket socket; - QCOMPARE(socket.ciphers(), QSslSocket::defaultCiphers()); - socket.setCiphers(QList()); - QVERIFY(socket.ciphers().isEmpty()); - socket.setCiphers(socket.defaultCiphers()); - QCOMPARE(socket.ciphers(), QSslSocket::defaultCiphers()); - socket.setCiphers(socket.defaultCiphers()); - QCOMPARE(socket.ciphers(), QSslSocket::defaultCiphers()); + QCOMPARE(socket.sslConfiguration().ciphers(), QSslConfiguration::defaultConfiguration().ciphers()); + + auto sslConfig = socket.sslConfiguration(); + sslConfig.setCiphers(QList()); + socket.setSslConfiguration(sslConfig); + QVERIFY(socket.sslConfiguration().ciphers().isEmpty()); + + sslConfig.setCiphers(QSslConfiguration::defaultConfiguration().ciphers()); + socket.setSslConfiguration(sslConfig); + QCOMPARE(socket.sslConfiguration().ciphers(), QSslConfiguration::defaultConfiguration().ciphers()); + + sslConfig.setCiphers(QSslConfiguration::defaultConfiguration().ciphers()); + socket.setSslConfiguration(sslConfig); + QCOMPARE(socket.sslConfiguration().ciphers(), QSslConfiguration::defaultConfiguration().ciphers()); // Task 164356 - socket.setCiphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); + sslConfig.setCiphers({QSslCipher("ALL"), QSslCipher("!ADH"), QSslCipher("!LOW"), + QSslCipher("!EXP"), QSslCipher("!MD5"), QSslCipher("@STRENGTH")}); + socket.setSslConfiguration(sslConfig); } void tst_QSslSocket::connectToHostEncrypted() @@ -858,11 +901,14 @@ void tst_QSslSocket::sessionCipher() QSKIP("Skipping flaky test - See QTBUG-29941"); QVERIFY(!socket->sessionCipher().isNull()); - qDebug() << "Supported Ciphers:" << QSslSocket::supportedCiphers(); - qDebug() << "Default Ciphers:" << QSslSocket::defaultCiphers(); + qDebug() << "Supported Ciphers:" << QSslConfiguration::supportedCiphers(); + qDebug() << "Default Ciphers:" << QSslConfiguration::defaultConfiguration().ciphers(); qDebug() << "Session Cipher:" << socket->sessionCipher(); +#if QT_DEPRECATED_SINCE(5, 5) QVERIFY(QSslSocket::supportedCiphers().contains(socket->sessionCipher())); +#endif + QVERIFY(QSslConfiguration::supportedCiphers().contains(socket->sessionCipher())); socket->disconnectFromHost(); QVERIFY(socket->waitForDisconnected()); } @@ -886,7 +932,11 @@ void tst_QSslSocket::localCertificate() QSslSocketPtr socket = newSocket(); QList localCert = QSslCertificate::fromPath(httpServerCertChainPath()); - socket->setCaCertificates(localCert); + + auto sslConfig = socket->sslConfiguration(); + sslConfig.setCaCertificates(localCert); + socket->setSslConfiguration(sslConfig); + socket->setLocalCertificate(testDataDir + "certs/fluke.cert"); socket->setPrivateKey(testDataDir + "certs/fluke.key"); @@ -990,7 +1040,11 @@ void tst_QSslSocket::privateKeyOpaque() QSslSocketPtr socket = newSocket(); QList localCert = QSslCertificate::fromPath(httpServerCertChainPath()); - socket->setCaCertificates(localCert); + + auto sslConfig = socket->sslConfiguration(); + sslConfig.setCaCertificates(localCert); + socket->setSslConfiguration(sslConfig); + socket->setLocalCertificate(testDataDir + "certs/fluke.cert"); socket->setPrivateKey(QSslKey(reinterpret_cast(pkey))); @@ -1011,7 +1065,10 @@ void tst_QSslSocket::protocol() this->socket = socket.data(); QList certs = QSslCertificate::fromPath(httpServerCertChainPath()); - socket->setCaCertificates(certs); + auto sslConfig = socket->sslConfiguration(); + sslConfig.setCaCertificates(certs); + socket->setSslConfiguration(sslConfig); + #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND connect(socket, SIGNAL(sslErrors(QList)), this, SLOT(untrustedWorkaroundSlot(QList))); @@ -1159,7 +1216,7 @@ public: QString m_keyFile; QString m_certFile; QString m_interFile; - QString ciphers; + QList ciphers; signals: void socketError(QAbstractSocket::SocketError); @@ -1209,7 +1266,9 @@ protected: } if (!ciphers.isEmpty()) { - socket->setCiphers(ciphers); + auto sslConfig = socket->sslConfiguration(); + sslConfig.setCiphers(ciphers); + socket->setSslConfiguration(sslConfig); } QVERIFY(socket->setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState)); @@ -1359,7 +1418,7 @@ void tst_QSslSocket::serverCipherPreferences() // First using the default (server preference) { SslServer server; - server.ciphers = QString("AES128-SHA:AES256-SHA"); + server.ciphers = {QSslCipher("AES128-SHA"), QSslCipher("AES256-SHA")}; QVERIFY(server.listen()); QEventLoop loop; @@ -1367,7 +1426,10 @@ void tst_QSslSocket::serverCipherPreferences() QSslSocket client; socket = &client; - socket->setCiphers("AES256-SHA:AES128-SHA"); + + auto sslConfig = socket->sslConfiguration(); + sslConfig.setCiphers({QSslCipher("AES256-SHA"), QSslCipher("AES128-SHA")}); + socket->setSslConfiguration(sslConfig); // upon SSL wrong version error, error will be triggered, not sslErrors connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), &loop, SLOT(quit())); @@ -1388,7 +1450,7 @@ void tst_QSslSocket::serverCipherPreferences() QSslConfiguration config = QSslConfiguration::defaultConfiguration(); config.setSslOption(QSsl::SslOptionDisableServerCipherPreference, true); server.config = config; - server.ciphers = QString("AES128-SHA:AES256-SHA"); + server.ciphers = {QSslCipher("AES128-SHA"), QSslCipher("AES256-SHA")}; QVERIFY(server.listen()); QEventLoop loop; @@ -1396,7 +1458,10 @@ void tst_QSslSocket::serverCipherPreferences() QSslSocket client; socket = &client; - socket->setCiphers("AES256-SHA:AES128-SHA"); + + auto sslConfig = socket->sslConfiguration(); + sslConfig.setCiphers({QSslCipher("AES256-SHA"), QSslCipher("AES128-SHA")}); + socket->setSslConfiguration(sslConfig); // upon SSL wrong version error, error will be triggered, not sslErrors connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), &loop, SLOT(quit())); @@ -1420,12 +1485,30 @@ void tst_QSslSocket::setCaCertificates() if (!QSslSocket::supportsSsl()) return; +#if QT_DEPRECATED_SINCE(5, 5) + { + QSslSocket socket; + QCOMPARE(socket.caCertificates(), QSslSocket::defaultCaCertificates()); + socket.setCaCertificates(QSslCertificate::fromPath(testDataDir + "certs/qt-test-server-cacert.pem")); + QCOMPARE(socket.caCertificates().size(), 1); + socket.setCaCertificates(socket.defaultCaCertificates()); + QCOMPARE(socket.caCertificates(), QSslSocket::defaultCaCertificates()); + } +#endif QSslSocket socket; - QCOMPARE(socket.caCertificates(), QSslSocket::defaultCaCertificates()); - socket.setCaCertificates(QSslCertificate::fromPath(testDataDir + "certs/qt-test-server-cacert.pem")); - QCOMPARE(socket.caCertificates().size(), 1); - socket.setCaCertificates(socket.defaultCaCertificates()); - QCOMPARE(socket.caCertificates(), QSslSocket::defaultCaCertificates()); + QCOMPARE(socket.sslConfiguration().caCertificates(), + QSslConfiguration::defaultConfiguration().caCertificates()); + + auto sslConfig = socket.sslConfiguration(); + sslConfig.setCaCertificates( + QSslCertificate::fromPath(testDataDir + "certs/qt-test-server-cacert.pem")); + socket.setSslConfiguration(sslConfig); + QCOMPARE(socket.sslConfiguration().caCertificates().size(), 1); + + sslConfig.setCaCertificates(QSslConfiguration::defaultConfiguration().caCertificates()); + socket.setSslConfiguration(sslConfig); + QCOMPARE(socket.sslConfiguration().caCertificates(), + QSslConfiguration::defaultConfiguration().caCertificates()); } void tst_QSslSocket::setLocalCertificate() @@ -1638,19 +1721,43 @@ void tst_QSslSocket::addDefaultCaCertificate() if (!QSslSocket::supportsSsl()) return; +#if QT_DEPRECATED_SINCE(5, 5) + { + // Reset the global CA chain + QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates()); + + QList flukeCerts = QSslCertificate::fromPath(httpServerCertChainPath()); + QCOMPARE(flukeCerts.size(), 1); + QList globalCerts = QSslSocket::defaultCaCertificates(); + QVERIFY(!globalCerts.contains(flukeCerts.first())); + QSslSocket::addDefaultCaCertificate(flukeCerts.first()); + QCOMPARE(QSslSocket::defaultCaCertificates().size(), globalCerts.size() + 1); + QVERIFY(QSslSocket::defaultCaCertificates().contains(flukeCerts.first())); + + // Restore the global CA chain + QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates()); + } +#endif + // Reset the global CA chain - QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates()); + auto sslConfig = QSslConfiguration::defaultConfiguration(); + sslConfig.setCaCertificates(QSslConfiguration::systemCaCertificates()); + QSslConfiguration::setDefaultConfiguration(sslConfig); QList flukeCerts = QSslCertificate::fromPath(httpServerCertChainPath()); QCOMPARE(flukeCerts.size(), 1); - QList globalCerts = QSslSocket::defaultCaCertificates(); + QList globalCerts = QSslConfiguration::defaultConfiguration().caCertificates(); QVERIFY(!globalCerts.contains(flukeCerts.first())); QSslSocket::addDefaultCaCertificate(flukeCerts.first()); - QCOMPARE(QSslSocket::defaultCaCertificates().size(), globalCerts.size() + 1); - QVERIFY(QSslSocket::defaultCaCertificates().contains(flukeCerts.first())); + QCOMPARE(QSslConfiguration::defaultConfiguration().caCertificates().size(), + globalCerts.size() + 1); + QVERIFY(QSslConfiguration::defaultConfiguration().caCertificates() + .contains(flukeCerts.first())); // Restore the global CA chain - QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates()); + sslConfig = QSslConfiguration::defaultConfiguration(); + sslConfig.setCaCertificates(QSslConfiguration::systemCaCertificates()); + QSslConfiguration::setDefaultConfiguration(sslConfig); } void tst_QSslSocket::addDefaultCaCertificates() @@ -1666,9 +1773,16 @@ void tst_QSslSocket::defaultCaCertificates() if (!QSslSocket::supportsSsl()) return; - QList certs = QSslSocket::defaultCaCertificates(); +#if QT_DEPRECATED_SINCE(5, 5) + { + QList certs = QSslSocket::defaultCaCertificates(); + QVERIFY(certs.size() > 1); + QCOMPARE(certs, QSslSocket::systemCaCertificates()); + } +#endif + QList certs = QSslConfiguration::defaultConfiguration().caCertificates(); QVERIFY(certs.size() > 1); - QCOMPARE(certs, QSslSocket::systemCaCertificates()); + QCOMPARE(certs, QSslConfiguration::systemCaCertificates()); } void tst_QSslSocket::defaultCiphers() @@ -1676,12 +1790,22 @@ void tst_QSslSocket::defaultCiphers() if (!QSslSocket::supportsSsl()) return; - QList ciphers = QSslSocket::defaultCiphers(); +#if QT_DEPRECATED_SINCE(5, 5) + { + QList ciphers = QSslSocket::defaultCiphers(); + QVERIFY(ciphers.size() > 1); + + QSslSocket socket; + QCOMPARE(socket.defaultCiphers(), ciphers); + QCOMPARE(socket.ciphers(), ciphers); + } +#endif + QList ciphers = QSslConfiguration::defaultConfiguration().ciphers(); QVERIFY(ciphers.size() > 1); QSslSocket socket; - QCOMPARE(socket.defaultCiphers(), ciphers); - QCOMPARE(socket.ciphers(), ciphers); + QCOMPARE(socket.sslConfiguration().defaultConfiguration().ciphers(), ciphers); + QCOMPARE(socket.sslConfiguration().ciphers(), ciphers); } void tst_QSslSocket::resetDefaultCiphers() @@ -1701,11 +1825,21 @@ void tst_QSslSocket::supportedCiphers() if (!QSslSocket::supportsSsl()) return; - QList ciphers = QSslSocket::supportedCiphers(); +#if QT_DEPRECATED_SINCE(5, 5) + { + QList ciphers = QSslSocket::supportedCiphers(); + QVERIFY(ciphers.size() > 1); + + QSslSocket socket; + QCOMPARE(socket.supportedCiphers(), ciphers); + } +#endif + + QList ciphers = QSslConfiguration::supportedCiphers(); QVERIFY(ciphers.size() > 1); QSslSocket socket; - QCOMPARE(socket.supportedCiphers(), ciphers); + QCOMPARE(socket.sslConfiguration().supportedCiphers(), ciphers); } void tst_QSslSocket::systemCaCertificates() @@ -1713,9 +1847,16 @@ void tst_QSslSocket::systemCaCertificates() if (!QSslSocket::supportsSsl()) return; - QList certs = QSslSocket::systemCaCertificates(); +#if QT_DEPRECATED_SINCE(5, 5) + { + QList certs = QSslSocket::systemCaCertificates(); + QVERIFY(certs.size() > 1); + QCOMPARE(certs, QSslSocket::defaultCaCertificates()); + } +#endif + QList certs = QSslConfiguration::systemCaCertificates(); QVERIFY(certs.size() > 1); - QCOMPARE(certs, QSslSocket::defaultCaCertificates()); + QCOMPARE(certs, QSslConfiguration::defaultConfiguration().systemCaCertificates()); } void tst_QSslSocket::wildcardCertificateNames() @@ -2779,7 +2920,9 @@ void tst_QSslSocket::resume() { // make sure the server certificate is not in the list of accepted certificates, // we want to trigger the sslErrors signal - QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates()); + auto sslConfig = QSslConfiguration::defaultConfiguration(); + sslConfig.setCaCertificates(QSslConfiguration::systemCaCertificates()); + QSslConfiguration::setDefaultConfiguration(sslConfig); QFETCH(bool, ignoreErrorsAfterPause); QFETCH(QList, errorsToIgnore); @@ -3099,7 +3242,7 @@ void tst_QSslSocket::dhServer() return; SslServer server; - server.ciphers = QLatin1String("DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA"); + server.ciphers = {QSslCipher("DHE-RSA-AES256-SHA"), QSslCipher("DHE-DSS-AES256-SHA")}; QVERIFY(server.listen()); QEventLoop loop; @@ -3128,7 +3271,7 @@ void tst_QSslSocket::dhServerCustomParamsNull() return; SslServer server; - server.ciphers = QLatin1String("DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA"); + server.ciphers = {QSslCipher("DHE-RSA-AES256-SHA"), QSslCipher("DHE-DSS-AES256-SHA")}; QSslConfiguration cfg = server.config; cfg.setDiffieHellmanParameters(QSslDiffieHellmanParameters()); @@ -3164,7 +3307,7 @@ void tst_QSslSocket::dhServerCustomParams() return; SslServer server; - server.ciphers = QLatin1String("DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA"); + server.ciphers = {QSslCipher("DHE-RSA-AES256-SHA"), QSslCipher("DHE-DSS-AES256-SHA")}; QSslConfiguration cfg = server.config; @@ -3213,7 +3356,7 @@ void tst_QSslSocket::ecdhServer() return; SslServer server; - server.ciphers = QLatin1String("ECDHE-RSA-AES128-SHA"); + server.ciphers = {QSslCipher("ECDHE-RSA-AES128-SHA")}; QVERIFY(server.listen()); QEventLoop loop; @@ -3583,7 +3726,7 @@ public: bool ignoreSslErrors; QSslSocket::PeerVerifyMode peerVerifyMode; QSsl::SslProtocol protocol; - QString ciphers; + QList ciphers; PskProvider m_pskProvider; protected: @@ -3597,7 +3740,9 @@ protected: connect(socket, SIGNAL(sslErrors(QList)), this, SLOT(ignoreErrorSlot())); if (!ciphers.isEmpty()) { - socket->setCiphers(ciphers); + auto sslConfig = socket->sslConfiguration(); + sslConfig.setCiphers(ciphers); + socket->setSslConfiguration(sslConfig); } QVERIFY(socket->setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState)); @@ -3639,7 +3784,7 @@ void tst_QSslSocket::simplePskConnect() QSKIP("No SSL support"); bool pskCipherFound = false; - const QList supportedCiphers = QSslSocket::supportedCiphers(); + const QList supportedCiphers = QSslConfiguration::supportedCiphers(); for (const QSslCipher &cipher : supportedCiphers) { if (cipher.name() == PSK_CIPHER_WITHOUT_AUTH) { pskCipherFound = true; @@ -3691,7 +3836,9 @@ void tst_QSslSocket::simplePskConnect() connect(&socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(exitLoop())); // force a PSK cipher w/o auth - socket.setCiphers(PSK_CIPHER_WITHOUT_AUTH); + auto sslConfig = socket.sslConfiguration(); + sslConfig.setCiphers({QSslCipher(PSK_CIPHER_WITHOUT_AUTH)}); + socket.setSslConfiguration(sslConfig); PskProvider provider; @@ -3960,7 +4107,9 @@ void tst_QSslSocket::pskServer() connect(&socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(exitLoop())); // force a PSK cipher w/o auth - socket.setCiphers(PSK_CIPHER_WITHOUT_AUTH); + auto sslConfig = socket.sslConfiguration(); + sslConfig.setCiphers({QSslCipher(PSK_CIPHER_WITHOUT_AUTH)}); + socket.setSslConfiguration(sslConfig); PskProvider provider; provider.setIdentity(PSK_CLIENT_IDENTITY); diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp index 4199c0f465..3b28e7a803 100644 --- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp +++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp @@ -211,10 +211,23 @@ void tst_QSslSocket_onDemandCertificates_member::onDemandRootCertLoadingMemberMe { const QString host("www.qt.io"); +#if QT_DEPRECATED_SINCE(5, 5) + { + // not using any root certs -> should not work + QSslSocketPtr socket2 = newSocket(); + this->socket = socket2.data(); + socket2->setCaCertificates(QList()); + socket2->connectToHostEncrypted(host, 443); + QVERIFY(!waitForEncrypted(socket2.data())); + } +#endif + // not using any root certs -> should not work QSslSocketPtr socket2 = newSocket(); this->socket = socket2.data(); - socket2->setCaCertificates(QList()); + auto sslConfig = socket2->sslConfiguration(); + sslConfig.setCaCertificates(QList()); + socket2->setSslConfiguration(sslConfig); socket2->connectToHostEncrypted(host, 443); QVERIFY(!waitForEncrypted(socket2.data())); @@ -224,10 +237,23 @@ void tst_QSslSocket_onDemandCertificates_member::onDemandRootCertLoadingMemberMe socket->connectToHostEncrypted(host, 443); QVERIFY2(waitForEncrypted(socket.data()), qPrintable(socket->errorString())); +#if QT_DEPRECATED_SINCE(5, 5) + { + // not using any root certs again -> should not work + QSslSocketPtr socket3 = newSocket(); + this->socket = socket3.data(); + socket3->setCaCertificates(QList()); + socket3->connectToHostEncrypted(host, 443); + QVERIFY(!waitForEncrypted(socket3.data())); + } +#endif + // not using any root certs again -> should not work QSslSocketPtr socket3 = newSocket(); this->socket = socket3.data(); - socket3->setCaCertificates(QList()); + sslConfig = socket3->sslConfiguration(); + sslConfig.setCaCertificates(QList()); + socket3->setSslConfiguration(sslConfig); socket3->connectToHostEncrypted(host, 443); QVERIFY(!waitForEncrypted(socket3.data())); diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp index 671a21b1c2..a441d13619 100644 --- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp +++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp @@ -178,6 +178,7 @@ void tst_QSslSocket_onDemandCertificates_static::onDemandRootCertLoadingStaticMe { QString host("www.qt.io"); +#if QT_DEPRECATED_SINCE(5, 5) // not using any root certs -> should not work QSslSocket::setDefaultCaCertificates(QList()); QSslSocketPtr socket = newSocket(); @@ -200,6 +201,7 @@ void tst_QSslSocket_onDemandCertificates_static::onDemandRootCertLoadingStaticMe QVERIFY(!socket3->waitForEncrypted()); QSslSocket::setDefaultCaCertificates(QSslSocket::systemCaCertificates()); +#endif // setting empty default configuration -> should not work QSslConfiguration conf; From 9c2f18d35764fe4c5452d3aa500bd2824ebe7564 Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Mon, 22 Jul 2019 11:12:38 +0200 Subject: [PATCH 166/264] Remove usages of deprecated QApplication::keypadNavigationEnabled Added QApplicationPrivate::keypadNavigationEnabled() as a replacement of deprecated QApplication::keypadNavigationEnabled(), for the internal usage. Task-number: QTBUG-76491 Change-Id: I75f4c628b72d86b5e428e7e285a786d23abbf3f2 Reviewed-by: Volker Hilsheimer --- src/widgets/dialogs/qfiledialog.cpp | 3 ++- src/widgets/itemviews/qabstractitemview.cpp | 14 +++++----- src/widgets/itemviews/qlistview.cpp | 5 ++-- src/widgets/itemviews/qtableview.cpp | 5 ++-- src/widgets/itemviews/qtreeview.cpp | 5 ++-- src/widgets/kernel/qapplication.cpp | 4 --- src/widgets/kernel/qapplication_p.h | 7 +++++ src/widgets/kernel/qwidget.cpp | 4 +-- src/widgets/util/qcompleter.cpp | 9 ++++--- src/widgets/widgets/qabstractbutton.cpp | 7 ++--- src/widgets/widgets/qabstractscrollarea.cpp | 6 ++--- src/widgets/widgets/qabstractslider.cpp | 18 +++++++------ src/widgets/widgets/qabstractspinbox.cpp | 13 ++++----- src/widgets/widgets/qcalendarwidget.cpp | 5 ++-- src/widgets/widgets/qcombobox.cpp | 24 ++++++++--------- src/widgets/widgets/qdatetimeedit.cpp | 29 +++++++++++---------- src/widgets/widgets/qlineedit.cpp | 20 +++++++------- src/widgets/widgets/qmenu.cpp | 2 +- src/widgets/widgets/qplaintextedit.cpp | 23 ++++++++-------- src/widgets/widgets/qscrollarea.cpp | 5 ++-- src/widgets/widgets/qslider.cpp | 3 ++- src/widgets/widgets/qtabbar.cpp | 3 ++- src/widgets/widgets/qtabwidget.cpp | 7 ++--- src/widgets/widgets/qtextbrowser.cpp | 7 ++--- src/widgets/widgets/qtextedit.cpp | 21 ++++++++------- src/widgets/widgets/qwidgetlinecontrol.cpp | 5 ++-- src/widgets/widgets/qwidgettextcontrol.cpp | 11 ++++---- 27 files changed, 145 insertions(+), 120 deletions(-) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 2f45635298..c85b56d4f5 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -44,6 +44,7 @@ #include "qfiledialog.h" #include "qfiledialog_p.h" +#include #include #include #include @@ -4035,7 +4036,7 @@ bool QFileDialogPrivate::itemViewKeyboardEvent(QKeyEvent *event) { return true; case Qt::Key_Back: #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) + if (QApplicationPrivate::keypadNavigationEnabled()) return false; #endif case Qt::Key_Left: diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 6ff0fe8132..c985b945f8 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #ifndef QT_NO_ACCESSIBILITY @@ -2290,7 +2291,7 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) #ifdef QT_KEYPAD_NAVIGATION switch (event->key()) { case Qt::Key_Select: - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (!hasEditFocus()) { setEditFocus(true); return; @@ -2298,7 +2299,7 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) } break; case Qt::Key_Back: - if (QApplication::keypadNavigationEnabled() && hasEditFocus()) { + if (QApplicationPrivate::keypadNavigationEnabled() && hasEditFocus()) { setEditFocus(false); } else { event->ignore(); @@ -2309,7 +2310,7 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) // Let's ignore vertical navigation events, only if there is no other widget // what can take the focus in vertical direction. This means widget can handle navigation events // even the widget don't have edit focus, and there is no other widget in requested direction. - if(QApplication::keypadNavigationEnabled() && !hasEditFocus() + if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical)) { event->ignore(); return; @@ -2318,14 +2319,14 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) case Qt::Key_Left: case Qt::Key_Right: // Similar logic as in up and down events - if(QApplication::keypadNavigationEnabled() && !hasEditFocus() + if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus() && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) || QWidgetPrivate::inTabWidget(this))) { event->ignore(); return; } break; default: - if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) { + if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) { event->ignore(); return; } @@ -2413,7 +2414,8 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) case Qt::Key_Down: case Qt::Key_Up: #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical)) { + if (QApplicationPrivate::keypadNavigationEnabled() + && QWidgetPrivate::canKeypadNavigate(Qt::Vertical)) { event->accept(); // don't change focus break; } diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 7d18c06def..04cddf2926 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -54,6 +54,7 @@ #if QT_CONFIG(rubberband) #include #endif +#include #include #include #include @@ -1185,7 +1186,7 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie rect.translate(0, -rect.height()); if (rect.bottom() <= 0) { #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { int row = d->batchStartRow() - 1; while (row >= 0 && d->isHiddenOrDisabled(row)) --row; @@ -1214,7 +1215,7 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie rect.translate(0, rect.height()); if (rect.top() >= contents.height()) { #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { int rowCount = d->model->rowCount(d->root); int row = 0; while (row < rowCount && d->isHiddenOrDisabled(row)) diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index 8860ef208d..e706af1a42 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -51,6 +51,7 @@ #if QT_CONFIG(abstractbutton) #include #endif +#include #include #include #include @@ -1710,7 +1711,7 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi case MoveUp: { int originalRow = visualRow; #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled() && visualRow == 0) + if (QApplicationPrivate::keypadNavigationEnabled() && visualRow == 0) visualRow = d->visualRow(model()->rowCount() - 1) + 1; // FIXME? visualRow = bottom + 1; #endif @@ -1739,7 +1740,7 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi visualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height())); } #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled() && visualRow >= bottom) + if (QApplicationPrivate::keypadNavigationEnabled() && visualRow >= bottom) visualRow = -1; #endif int r = d->logicalRow(visualRow); diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 55b10d13c1..23a530821f 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -55,6 +55,7 @@ #include #endif +#include #include #include @@ -2214,14 +2215,14 @@ QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie case MoveNext: case MoveDown: #ifdef QT_KEYPAD_NAVIGATION - if (vi == d->viewItems.count()-1 && QApplication::keypadNavigationEnabled()) + if (vi == d->viewItems.count()-1 && QApplicationPrivate::keypadNavigationEnabled()) return d->model->index(0, current.column(), d->root); #endif return d->modelIndex(d->below(vi), current.column()); case MovePrevious: case MoveUp: #ifdef QT_KEYPAD_NAVIGATION - if (vi == 0 && QApplication::keypadNavigationEnabled()) + if (vi == 0 && QApplicationPrivate::keypadNavigationEnabled()) return d->modelIndex(d->viewItems.count() - 1, current.column()); #endif return d->modelIndex(d->above(vi), current.column()); diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 19ef76fe4d..97175f2134 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -3843,8 +3843,6 @@ void QApplicationPrivate::openPopup(QWidget *popup) This feature is available in Qt for Embedded Linux only. \since 4.6 - - \sa keypadNavigationEnabled() */ void QApplication::setNavigationMode(Qt::NavigationMode mode) { @@ -3857,8 +3855,6 @@ void QApplication::setNavigationMode(Qt::NavigationMode mode) This feature is available in Qt for Embedded Linux only. \since 4.6 - - \sa keypadNavigationEnabled() */ Qt::NavigationMode QApplication::navigationMode() { diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index 98eb9b73c6..36c0ba8739 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -136,6 +136,13 @@ public: static QWidget *tryModalHelper_sys(QWidget *top); bool canQuit(); #endif +#ifdef QT_KEYPAD_NAVIGATION + static bool keypadNavigationEnabled() + { + return navigationMode == Qt::NavigationModeKeypadTabOrder || + navigationMode == Qt::NavigationModeKeypadDirectional; + } +#endif bool notify_helper(QObject *receiver, QEvent * e); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 3dad7dad1e..f0230f4f32 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -393,7 +393,7 @@ QPointer QWidgetPrivate::editingWidget; This feature is only available in Qt for Embedded Linux. - \sa setEditFocus(), QApplication::keypadNavigationEnabled() + \sa setEditFocus(), QApplication::navigationMode() */ bool QWidget::hasEditFocus() const { @@ -413,7 +413,7 @@ bool QWidget::hasEditFocus() const This feature is only available in Qt for Embedded Linux. - \sa hasEditFocus(), QApplication::keypadNavigationEnabled() + \sa hasEditFocus(), QApplication::navigationMode() */ void QWidget::setEditFocus(bool on) { diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp index ee0418b5b8..7b69eff30c 100644 --- a/src/widgets/util/qcompleter.cpp +++ b/src/widgets/util/qcompleter.cpp @@ -161,6 +161,7 @@ #include "QtWidgets/qapplication.h" #include "QtGui/qevent.h" #include "QtWidgets/qdesktopwidget.h" +#include #include #if QT_CONFIG(lineedit) #include "QtWidgets/qlineedit.h" @@ -1416,7 +1417,7 @@ bool QCompleter::eventFilter(QObject *o, QEvent *e) // widget lost focus, hide the popup if (d->widget && (!d->widget->hasFocus() #ifdef QT_KEYPAD_NAVIGATION - || (QApplication::keypadNavigationEnabled() && !d->widget->hasEditFocus()) + || (QApplicationPrivate::keypadNavigationEnabled() && !d->widget->hasEditFocus()) #endif )) d->popup->hide(); @@ -1434,7 +1435,7 @@ bool QCompleter::eventFilter(QObject *o, QEvent *e) switch (key) { #ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Select: - if (!QApplication::keypadNavigationEnabled()) + if (!QApplicationPrivate::keypadNavigationEnabled()) break; #endif case Qt::Key_Return: @@ -1464,7 +1465,7 @@ bool QCompleter::eventFilter(QObject *o, QEvent *e) #ifdef QT_KEYPAD_NAVIGATION case QEvent::KeyRelease: { QKeyEvent *ke = static_cast(e); - if (QApplication::keypadNavigationEnabled() && ke->key() == Qt::Key_Back) { + if (QApplicationPrivate::keypadNavigationEnabled() && ke->key() == Qt::Key_Back) { // Send the event to the 'widget'. This is what we did for KeyPress, so we need // to do the same for KeyRelease, in case the widget's KeyPress event set // up something (such as a timer) that is relying on also receiving the @@ -1481,7 +1482,7 @@ bool QCompleter::eventFilter(QObject *o, QEvent *e) case QEvent::MouseButtonPress: { #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { // if we've clicked in the widget (or its descendant), let it handle the click QWidget *source = qobject_cast(o); if (source) { diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp index f30a3bc7b8..d956d2ba23 100644 --- a/src/widgets/widgets/qabstractbutton.cpp +++ b/src/widgets/widgets/qabstractbutton.cpp @@ -44,6 +44,7 @@ #endif #if QT_CONFIG(buttongroup) #include "qbuttongroup.h" +#include "private/qapplication_p.h" #include "private/qbuttongroup_p.h" #endif #include "qabstractbutton_p.h" @@ -319,7 +320,7 @@ void QAbstractButtonPrivate::moveFocus(int key) if (exclusive #ifdef QT_KEYPAD_NAVIGATION - && !QApplication::keypadNavigationEnabled() + && !QApplicationPrivate::keypadNavigationEnabled() #endif && candidate && fb->d_func()->checked @@ -1063,7 +1064,7 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e) case Qt::Key_Right: case Qt::Key_Down: { #ifdef QT_KEYPAD_NAVIGATION - if ((QApplication::keypadNavigationEnabled() + if ((QApplicationPrivate::keypadNavigationEnabled() && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right)) || (!QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional || (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down))) { @@ -1159,7 +1160,7 @@ void QAbstractButton::focusInEvent(QFocusEvent *e) { Q_D(QAbstractButton); #ifdef QT_KEYPAD_NAVIGATION - if (!QApplication::keypadNavigationEnabled()) + if (!QApplicationPrivate::keypadNavigationEnabled()) #endif d->fixFocusPolicy(); QWidget::focusInEvent(e); diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp index 8f50ec1584..55b2dcd662 100644 --- a/src/widgets/widgets/qabstractscrollarea.cpp +++ b/src/widgets/widgets/qabstractscrollarea.cpp @@ -1362,7 +1362,7 @@ void QAbstractScrollArea::keyPressEvent(QKeyEvent * e) #endif } else { #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) { + if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) { e->ignore(); return; } @@ -1376,7 +1376,7 @@ void QAbstractScrollArea::keyPressEvent(QKeyEvent * e) break; case Qt::Key_Left: #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled() && hasEditFocus() + if (QApplicationPrivate::keypadNavigationEnabled() && hasEditFocus() && (!d->hbar->isVisible() || d->hbar->value() == d->hbar->minimum())) { //if we aren't using the hbar or we are already at the leftmost point ignore e->ignore(); @@ -1389,7 +1389,7 @@ void QAbstractScrollArea::keyPressEvent(QKeyEvent * e) break; case Qt::Key_Right: #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled() && hasEditFocus() + if (QApplicationPrivate::keypadNavigationEnabled() && hasEditFocus() && (!d->hbar->isVisible() || d->hbar->value() == d->hbar->maximum())) { //if we aren't using the hbar or we are already at the rightmost point ignore e->ignore(); diff --git a/src/widgets/widgets/qabstractslider.cpp b/src/widgets/widgets/qabstractslider.cpp index 1c1aec6035..129d540f50 100644 --- a/src/widgets/widgets/qabstractslider.cpp +++ b/src/widgets/widgets/qabstractslider.cpp @@ -47,6 +47,8 @@ #endif #include +#include + QT_BEGIN_NAMESPACE /*! @@ -816,13 +818,13 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev) switch (ev->key()) { #ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Select: - if (QApplication::keypadNavigationEnabled()) + if (QApplicationPrivate::keypadNavigationEnabled()) setEditFocus(!hasEditFocus()); else ev->ignore(); break; case Qt::Key_Back: - if (QApplication::keypadNavigationEnabled() && hasEditFocus()) { + if (QApplicationPrivate::keypadNavigationEnabled() && hasEditFocus()) { setValue(d->origValue); setEditFocus(false); } else @@ -835,7 +837,7 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev) // In QApplication::KeypadNavigationDirectional, we want to change the slider // value if there is no left/right navigation possible and if this slider is not // inside a tab widget. - if (QApplication::keypadNavigationEnabled() + if (QApplicationPrivate::keypadNavigationEnabled() && (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder || d->orientation == Qt::Vertical || !hasEditFocus() @@ -843,7 +845,7 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev) ev->ignore(); return; } - if (QApplication::keypadNavigationEnabled() && d->orientation == Qt::Vertical) + if (QApplicationPrivate::keypadNavigationEnabled() && d->orientation == Qt::Vertical) action = d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd; else #endif @@ -855,7 +857,7 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev) case Qt::Key_Right: #ifdef QT_KEYPAD_NAVIGATION // Same logic as in Qt::Key_Left - if (QApplication::keypadNavigationEnabled() + if (QApplicationPrivate::keypadNavigationEnabled() && (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder || d->orientation == Qt::Vertical || !hasEditFocus() @@ -863,7 +865,7 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev) ev->ignore(); return; } - if (QApplication::keypadNavigationEnabled() && d->orientation == Qt::Vertical) + if (QApplicationPrivate::keypadNavigationEnabled() && d->orientation == Qt::Vertical) action = d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub; else #endif @@ -876,7 +878,7 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev) #ifdef QT_KEYPAD_NAVIGATION // In QApplication::KeypadNavigationDirectional, we want to change the slider // value if there is no up/down navigation possible. - if (QApplication::keypadNavigationEnabled() + if (QApplicationPrivate::keypadNavigationEnabled() && (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder || d->orientation == Qt::Horizontal || !hasEditFocus() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical))) { @@ -889,7 +891,7 @@ void QAbstractSlider::keyPressEvent(QKeyEvent *ev) case Qt::Key_Down: #ifdef QT_KEYPAD_NAVIGATION // Same logic as in Qt::Key_Up - if (QApplication::keypadNavigationEnabled() + if (QApplicationPrivate::keypadNavigationEnabled() && (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder || d->orientation == Qt::Horizontal || !hasEditFocus() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical))) { diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index e6e9939a10..f5708788b8 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -39,6 +39,7 @@ #include #include +#include #if QT_CONFIG(datetimeparser) #include #endif @@ -803,7 +804,7 @@ bool QAbstractSpinBox::event(QEvent *event) #ifdef QT_KEYPAD_NAVIGATION case QEvent::EnterEditFocus: case QEvent::LeaveEditFocus: - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { const bool b = d->edit->event(event); d->edit->setSelection(d->edit->displayText().size() - d->suffix.size(),0); if (event->type() == QEvent::LeaveEditFocus) @@ -1025,7 +1026,7 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event) case Qt::Key_Up: case Qt::Key_Down: { #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { // Reserve up/down for nav - use left/right for edit. if (!hasEditFocus() && (event->key() == Qt::Key_Up || event->key() == Qt::Key_Down)) { @@ -1061,13 +1062,13 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event) #ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Left: case Qt::Key_Right: - if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) { + if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) { event->ignore(); return; } break; case Qt::Key_Back: - if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) { + if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) { event->ignore(); return; } @@ -1085,7 +1086,7 @@ void QAbstractSpinBox::keyPressEvent(QKeyEvent *event) #ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Select: - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { // Toggles between left/right moving cursor and inc/dec. setEditFocus(!hasEditFocus()); } @@ -1221,7 +1222,7 @@ void QAbstractSpinBox::focusOutEvent(QFocusEvent *event) #ifdef QT_KEYPAD_NAVIGATION // editingFinished() is already emitted on LeaveEditFocus - if (!QApplication::keypadNavigationEnabled()) + if (!QApplicationPrivate::keypadNavigationEnabled()) #endif emit editingFinished(); } diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp index f07b42c181..78706b1854 100644 --- a/src/widgets/widgets/qcalendarwidget.cpp +++ b/src/widgets/widgets/qcalendarwidget.cpp @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -1384,14 +1385,14 @@ void QCalendarView::keyPressEvent(QKeyEvent *event) { #ifdef QT_KEYPAD_NAVIGATION if (event->key() == Qt::Key_Select) { - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (!hasEditFocus()) { setEditFocus(true); return; } } } else if (event->key() == Qt::Key_Back) { - if (QApplication::keypadNavigationEnabled() && hasEditFocus()) { + if (QApplicationPrivate::keypadNavigationEnabled() && hasEditFocus()) { if (qobject_cast(model())) { emit changeDate(origDate, true); //changes selection back to origDate, but doesn't activate setEditFocus(false); diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 83c472b51a..5c368db83a 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -223,7 +223,7 @@ void QComboBoxPrivate::_q_completerActivated(const QModelIndex &index) } # ifdef QT_KEYPAD_NAVIGATION - if ( QApplication::keypadNavigationEnabled() + if ( QApplicationPrivate::keypadNavigationEnabled() && q->isEditable() && q->completer() && q->completer()->completionMode() == QCompleter::UnfilteredPopupCompletion ) { @@ -1534,7 +1534,7 @@ void QComboBox::setAutoCompletion(bool enable) Q_D(QComboBox); #ifdef QT_KEYPAD_NAVIGATION - if (Q_UNLIKELY(QApplication::keypadNavigationEnabled() && !enable && isEditable())) + if (Q_UNLIKELY(QApplicationPrivate::keypadNavigationEnabled() && !enable && isEditable())) qWarning("QComboBox::setAutoCompletion: auto completion is mandatory when combo box editable"); #endif @@ -1881,7 +1881,7 @@ void QComboBox::setLineEdit(QLineEdit *edit) setAutoCompletion(d->autoCompletion); #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { // Editable combo boxes will have a completer that is set to UnfilteredPopupCompletion. // This means that when the user enters edit mode they are immediately presented with a // list of possible completions. @@ -2653,7 +2653,7 @@ void QComboBox::showPopup() #ifdef QT_KEYPAD_NAVIGATION #if QT_CONFIG(completer) - if (QApplication::keypadNavigationEnabled() && d->completer) { + if (QApplicationPrivate::keypadNavigationEnabled() && d->completer) { // editable combo box is line edit plus completer setEditFocus(true); d->completer->complete(); // show popup @@ -2859,7 +2859,7 @@ void QComboBox::showPopup() container->update(); #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) + if (QApplicationPrivate::keypadNavigationEnabled()) view()->setEditFocus(true); #endif if (startTimer) { @@ -2931,7 +2931,7 @@ void QComboBox::hidePopup() d->container->hide(); } #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled() && isEditable() && hasFocus()) + if (QApplicationPrivate::keypadNavigationEnabled() && isEditable() && hasFocus()) setEditFocus(true); #endif d->_q_resetButton(); @@ -3190,7 +3190,7 @@ void QComboBoxPrivate::showPopupFromMouseEvent(QMouseEvent *e) } } else { #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled() && sc == QStyle::SC_ComboBoxEditField && lineEdit) { + if (QApplicationPrivate::keypadNavigationEnabled() && sc == QStyle::SC_ComboBoxEditField && lineEdit) { lineEdit->event(e); //so lineedit can move cursor, etc return; } @@ -3239,7 +3239,7 @@ void QComboBox::keyPressEvent(QKeyEvent *e) Q_FALLTHROUGH(); case Qt::Key_PageUp: #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) + if (QApplicationPrivate::keypadNavigationEnabled()) e->ignore(); else #endif @@ -3254,7 +3254,7 @@ void QComboBox::keyPressEvent(QKeyEvent *e) Q_FALLTHROUGH(); case Qt::Key_PageDown: #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) + if (QApplicationPrivate::keypadNavigationEnabled()) e->ignore(); else #endif @@ -3288,7 +3288,7 @@ void QComboBox::keyPressEvent(QKeyEvent *e) break; #ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Select: - if (QApplication::keypadNavigationEnabled() + if (QApplicationPrivate::keypadNavigationEnabled() && (!hasEditFocus() || !d->lineEdit)) { showPopup(); return; @@ -3296,11 +3296,11 @@ void QComboBox::keyPressEvent(QKeyEvent *e) break; case Qt::Key_Left: case Qt::Key_Right: - if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) + if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) e->ignore(); break; case Qt::Key_Back: - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (!hasEditFocus() || !d->lineEdit) e->ignore(); } else { diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index 45c72e24d4..3c92d4be0e 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -37,6 +37,7 @@ ** ****************************************************************************/ +#include #include #include #include @@ -642,7 +643,7 @@ QDateTimeEdit::Section QDateTimeEdit::currentSection() const { Q_D(const QDateTimeEdit); #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled() && d->focusOnButton) + if (QApplicationPrivate::keypadNavigationEnabled() && d->focusOnButton) return NoSection; #endif return QDateTimeEditPrivate::convertToPublic(d->sectionType(d->currentSectionIndex)); @@ -1055,7 +1056,7 @@ void QDateTimeEdit::keyPressEvent(QKeyEvent *event) switch (event->key()) { #ifdef QT_KEYPAD_NAVIGATION case Qt::Key_NumberSign: //shortcut to popup calendar - if (QApplication::keypadNavigationEnabled() && d->calendarPopupEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled() && d->calendarPopupEnabled()) { d->initCalendarPopup(); d->positionCalendarPopup(); d->monthCalendar->show(); @@ -1063,7 +1064,7 @@ void QDateTimeEdit::keyPressEvent(QKeyEvent *event) } break; case Qt::Key_Select: - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (hasEditFocus()) { if (d->focusOnButton) { d->initCalendarPopup(); @@ -1095,7 +1096,7 @@ void QDateTimeEdit::keyPressEvent(QKeyEvent *event) return; default: #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled() && !hasEditFocus() + if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus() && !event->text().isEmpty() && event->text().at(0).isLetterOrNumber()) { setEditFocus(true); @@ -1117,8 +1118,8 @@ void QDateTimeEdit::keyPressEvent(QKeyEvent *event) if (event->key() == Qt::Key_Left || event->key() == Qt::Key_Right) { if ( #ifdef QT_KEYPAD_NAVIGATION - QApplication::keypadNavigationEnabled() && !hasEditFocus() - || !QApplication::keypadNavigationEnabled() && + QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus() + || !QApplicationPrivate::keypadNavigationEnabled() && #endif !(event->modifiers() & Qt::ControlModifier)) { select = false; @@ -1127,7 +1128,7 @@ void QDateTimeEdit::keyPressEvent(QKeyEvent *event) #if 0 // Used to be included in Qt4 for Q_WS_MAC else #ifdef QT_KEYPAD_NAVIGATION - if (!QApplication::keypadNavigationEnabled()) + if (!QApplicationPrivate::keypadNavigationEnabled()) #endif { select = (event->modifiers() & Qt::ShiftModifier); @@ -1147,7 +1148,7 @@ void QDateTimeEdit::keyPressEvent(QKeyEvent *event) && (event->key() != Qt::Key_Tab || !(event->modifiers() & Qt::ShiftModifier)); #ifdef QT_KEYPAD_NAVIGATION int newSection = d->nextPrevSection(d->currentSectionIndex, forward); - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (d->focusOnButton) { newSection = forward ? 0 : d->sectionNodes.size() - 1; d->focusOnButton = false; @@ -1290,7 +1291,7 @@ void QDateTimeEdit::stepBy(int steps) Q_D(QDateTimeEdit); #ifdef QT_KEYPAD_NAVIGATION // with keypad navigation and not editFocus, left right change the date/time by a fixed amount. - if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) { + if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) { // if date based, shift by day. else shift by 15min if (d->sections & DateSections_Mask) { setDateTime(dateTime().addDays(steps)); @@ -1417,7 +1418,7 @@ QDateTimeEdit::StepEnabled QDateTimeEdit::stepEnabled() const QAbstractSpinBox::StepEnabled ret = 0; #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) { + if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) { if (d->wrapping) return StepEnabled(StepUpEnabled | StepDownEnabled); // 3 cases. date, time, datetime. each case look @@ -1702,7 +1703,7 @@ void QDateTimeEditPrivate::updateEdit() if (!specialValue() #ifdef QT_KEYPAD_NAVIGATION - && !(QApplication::keypadNavigationEnabled() && !edit->hasEditFocus()) + && !(QApplicationPrivate::keypadNavigationEnabled() && !edit->hasEditFocus()) #endif ) { int cursor = sectionPos(currentSectionIndex); @@ -1731,7 +1732,7 @@ void QDateTimeEditPrivate::setSelected(int sectionIndex, bool forward) { if (specialValue() #ifdef QT_KEYPAD_NAVIGATION - || (QApplication::keypadNavigationEnabled() && !edit->hasEditFocus()) + || (QApplicationPrivate::keypadNavigationEnabled() && !edit->hasEditFocus()) #endif ) { edit->selectAll(); @@ -2426,7 +2427,7 @@ void QDateTimeEditPrivate::init(const QVariant &var) break; } #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) + if (QApplicationPrivate::keypadNavigationEnabled()) q->setCalendarPopup(true); #endif q->setInputMethodHints(Qt::ImhPreferNumbers); @@ -2602,7 +2603,7 @@ QCalendarWidget *QCalendarPopup::verifyCalendarInstance() QCalendarWidget *cw = new QCalendarWidget(this); cw->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader); #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) + if (QApplicationPrivate::keypadNavigationEnabled()) cw->setHorizontalHeaderFormat(QCalendarWidget::SingleLetterDayNames); #endif setCalendarWidget(cw); diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 23e2611fca..0fedb65f0c 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -1481,7 +1481,7 @@ bool QLineEdit::event(QEvent * e) d->initMouseYThreshold(); } #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (e->type() == QEvent::EnterEditFocus) { end(false); d->setCursorVisible(true); @@ -1513,7 +1513,7 @@ void QLineEdit::mousePressEvent(QMouseEvent* e) if (e->button() == Qt::RightButton) return; #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) { + if (QApplication::QApplicationPrivate() && !hasEditFocus()) { setEditFocus(true); // Get the completion list to pop up. if (d->control->completer()) @@ -1722,7 +1722,7 @@ void QLineEdit::keyPressEvent(QKeyEvent *event) bool select = false; switch (event->key()) { case Qt::Key_Select: - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (hasEditFocus()) { setEditFocus(false); if (d->control->completer() && d->control->completer()->popup()->isVisible()) @@ -1733,13 +1733,13 @@ void QLineEdit::keyPressEvent(QKeyEvent *event) break; case Qt::Key_Back: case Qt::Key_No: - if (!QApplication::keypadNavigationEnabled() || !hasEditFocus()) { + if (!QApplicationPrivate::keypadNavigationEnabled() || !hasEditFocus()) { event->ignore(); return; } break; default: - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (!hasEditFocus() && !(event->modifiers() & Qt::ControlModifier)) { if (!event->text().isEmpty() && event->text().at(0).isPrint() && !isReadOnly()) @@ -1754,7 +1754,7 @@ void QLineEdit::keyPressEvent(QKeyEvent *event) - if (QApplication::keypadNavigationEnabled() && !select && !hasEditFocus()) { + if (QApplicationPrivate::keypadNavigationEnabled() && !select && !hasEditFocus()) { setEditFocus(true); if (event->key() == Qt::Key_Select) return; // Just start. No action. @@ -1801,7 +1801,7 @@ void QLineEdit::inputMethodEvent(QInputMethodEvent *e) // Focus in if currently in navigation focus on the widget // Only focus in on preedits, to allow input methods to // commit text as they focus out without interfering with focus - if (QApplication::keypadNavigationEnabled() + if (QApplicationPrivate::keypadNavigationEnabled() && hasFocus() && !hasEditFocus() && !e->preeditString().isEmpty()) setEditFocus(true); @@ -1874,7 +1874,7 @@ void QLineEdit::focusInEvent(QFocusEvent *e) d->clickCausedFocus = 1; } #ifdef QT_KEYPAD_NAVIGATION - if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && ( e->reason() == Qt::PopupFocusReason))) { + if (!QApplicationPrivate::keypadNavigationEnabled() || (hasEditFocus() && ( e->reason() == Qt::PopupFocusReason))) { #endif d->control->setBlinkingCursorEnabled(true); QStyleOptionFrame opt; @@ -1918,7 +1918,7 @@ void QLineEdit::focusOutEvent(QFocusEvent *e) d->control->setBlinkingCursorEnabled(false); #ifdef QT_KEYPAD_NAVIGATION // editingFinished() is already emitted on LeaveEditFocus - if (!QApplication::keypadNavigationEnabled()) + if (!QApplicationPrivate::keypadNavigationEnabled()) #endif if (reason != Qt::PopupFocusReason || !(QApplication::activePopupWidget() && QApplication::activePopupWidget()->parentWidget() == this)) { @@ -2041,7 +2041,7 @@ void QLineEdit::paintEvent(QPaintEvent *) int flags = QWidgetLineControl::DrawText; #ifdef QT_KEYPAD_NAVIGATION - if (!QApplication::keypadNavigationEnabled() || hasEditFocus()) + if (!QApplicationPrivate::keypadNavigationEnabled() || hasEditFocus()) #endif if (d->control->hasSelectedText() || (d->cursorVisible && !d->control->inputMask().isEmpty() && !d->control->isReadOnly())){ flags |= QWidgetLineControl::DrawSelections; diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 53964303fc..310c865f52 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -2392,7 +2392,7 @@ void QMenu::popup(const QPoint &p, QAction *atAction) } #ifdef QT_KEYPAD_NAVIGATION - if (!atAction && QApplication::keypadNavigationEnabled()) { + if (!atAction && QApplicationPrivate::keypadNavigationEnabled()) { // Try to have one item activated if (d->defaultAction && d->defaultAction->isEnabled()) { atAction = d->defaultAction; diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp index 397304ec44..8843797430 100644 --- a/src/widgets/widgets/qplaintextedit.cpp +++ b/src/widgets/widgets/qplaintextedit.cpp @@ -54,6 +54,7 @@ #endif #include #include +#include "private/qapplication_p.h" #include "private/qtextdocumentlayout_p.h" #include "private/qabstracttextdocumentlayout_p.h" #include "qtextdocument.h" @@ -1573,7 +1574,7 @@ bool QPlainTextEdit::event(QEvent *e) } #ifdef QT_KEYPAD_NAVIGATION else if (e->type() == QEvent::EnterEditFocus || e->type() == QEvent::LeaveEditFocus) { - if (QApplication::keypadNavigationEnabled()) + if (QApplicationPrivate::keypadNavigationEnabled()) d->sendControlEvent(e); } #endif @@ -1691,7 +1692,7 @@ void QPlainTextEdit::keyPressEvent(QKeyEvent *e) #ifdef QT_KEYPAD_NAVIGATION switch (e->key()) { case Qt::Key_Select: - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (!(d->control->textInteractionFlags() & Qt::LinksAccessibleByKeyboard)) setEditFocus(!hasEditFocus()); else { @@ -1709,14 +1710,14 @@ void QPlainTextEdit::keyPressEvent(QKeyEvent *e) break; case Qt::Key_Back: case Qt::Key_No: - if (!QApplication::keypadNavigationEnabled() - || (QApplication::keypadNavigationEnabled() && !hasEditFocus())) { + if (!QApplicationPrivate::keypadNavigationEnabled() + || (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus())) { e->ignore(); return; } break; default: - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (!hasEditFocus() && !(e->modifiers() & Qt::ControlModifier)) { if (e->text()[0].isPrint()) { setEditFocus(true); @@ -1792,7 +1793,7 @@ void QPlainTextEdit::keyPressEvent(QKeyEvent *e) switch (e->key()) { case Qt::Key_Up: case Qt::Key_Down: - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { // Cursor position didn't change, so we want to leave // these keys to change focus. e->ignore(); @@ -1801,7 +1802,7 @@ void QPlainTextEdit::keyPressEvent(QKeyEvent *e) break; case Qt::Key_Left: case Qt::Key_Right: - if (QApplication::keypadNavigationEnabled() + if (QApplicationPrivate::keypadNavigationEnabled() && QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) { // Same as for Key_Up and Key_Down. e->ignore(); @@ -1810,7 +1811,7 @@ void QPlainTextEdit::keyPressEvent(QKeyEvent *e) break; case Qt::Key_Back: if (!e->isAutoRepeat()) { - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (document()->isEmpty()) { setEditFocus(false); e->accept(); @@ -1836,7 +1837,7 @@ void QPlainTextEdit::keyReleaseEvent(QKeyEvent *e) { #ifdef QT_KEYPAD_NAVIGATION Q_D(QPlainTextEdit); - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (!e->isAutoRepeat() && e->key() == Qt::Key_Back && d->deleteAllTimer.isActive()) { d->deleteAllTimer.stop(); @@ -2080,7 +2081,7 @@ void QPlainTextEdit::mousePressEvent(QMouseEvent *e) { Q_D(QPlainTextEdit); #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) + if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) setEditFocus(true); #endif d->sendControlEvent(e); @@ -2212,7 +2213,7 @@ void QPlainTextEdit::inputMethodEvent(QInputMethodEvent *e) Q_D(QPlainTextEdit); #ifdef QT_KEYPAD_NAVIGATION if (d->control->textInteractionFlags() & Qt::TextEditable - && QApplication::keypadNavigationEnabled() + && QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) { setEditFocus(true); selectAll(); // so text is replaced rather than appended to diff --git a/src/widgets/widgets/qscrollarea.cpp b/src/widgets/widgets/qscrollarea.cpp index 9994344d79..68aa545082 100644 --- a/src/widgets/widgets/qscrollarea.cpp +++ b/src/widgets/widgets/qscrollarea.cpp @@ -46,6 +46,7 @@ #include "qapplication.h" #include "qvariant.h" #include "qdebug.h" +#include "private/qapplication_p.h" #include "private/qlayoutengine_p.h" QT_BEGIN_NAMESPACE @@ -300,7 +301,7 @@ bool QScrollArea::event(QEvent *e) d->updateScrollBars(); } #ifdef QT_KEYPAD_NAVIGATION - else if (QApplication::keypadNavigationEnabled()) { + else if (QApplicationPrivate::keypadNavigationEnabled()) { if (e->type() == QEvent::Show) QApplication::instance()->installEventFilter(this); else if (e->type() == QEvent::Hide) @@ -319,7 +320,7 @@ bool QScrollArea::eventFilter(QObject *o, QEvent *e) Q_D(QScrollArea); #ifdef QT_KEYPAD_NAVIGATION if (d->widget && o != d->widget && e->type() == QEvent::FocusIn - && QApplication::keypadNavigationEnabled()) { + && QApplicationPrivate::keypadNavigationEnabled()) { if (o->isWidgetType()) ensureWidgetVisible(static_cast(o)); } diff --git a/src/widgets/widgets/qslider.cpp b/src/widgets/widgets/qslider.cpp index 47d3b2fb81..161e4ba27a 100644 --- a/src/widgets/widgets/qslider.cpp +++ b/src/widgets/widgets/qslider.cpp @@ -46,6 +46,7 @@ #include "qpainter.h" #include "qstyle.h" #include "qstyleoption.h" +#include "private/qapplication_p.h" #include "private/qabstractslider_p.h" #include "qdebug.h" @@ -360,7 +361,7 @@ void QSlider::mousePressEvent(QMouseEvent *ev) return; } #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) + if (QApplicationPrivate::keypadNavigationEnabled()) setEditFocus(true); #endif ev->accept(); diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index 1be1729684..18fda11ddf 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -65,6 +65,7 @@ #endif #include "qdebug.h" +#include "private/qapplication_p.h" #include "private/qtabbar_p.h" #if 0 // Used to be included in Qt4 for Q_WS_MAC @@ -415,7 +416,7 @@ void QTabBarPrivate::init() QObject::connect(rightB, SIGNAL(clicked()), q, SLOT(_q_scrollTabs())); rightB->hide(); #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { leftB->setFocusPolicy(Qt::NoFocus); rightB->setFocusPolicy(Qt::NoFocus); q->setFocusPolicy(Qt::NoFocus); diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp index 547b8a82f9..4d7b39ae01 100644 --- a/src/widgets/widgets/qtabwidget.cpp +++ b/src/widgets/widgets/qtabwidget.cpp @@ -39,6 +39,7 @@ #include "qtabwidget.h" +#include "private/qapplication_p.h" #include "private/qwidget_p.h" #include "private/qtabbar_p.h" #include "qapplication.h" @@ -241,7 +242,7 @@ void QTabWidgetPrivate::init() q->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, QSizePolicy::TabWidget)); #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled()) + if (QApplicationPrivate::keypadNavigationEnabled()) q->setFocusPolicy(Qt::NoFocus); else #endif @@ -1108,14 +1109,14 @@ void QTabWidget::keyPressEvent(QKeyEvent *e) if (((e->key() == Qt::Key_Tab || e->key() == Qt::Key_Backtab) && count() > 1 && e->modifiers() & Qt::ControlModifier) #ifdef QT_KEYPAD_NAVIGATION - || QApplication::keypadNavigationEnabled() && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right) && count() > 1 + || QApplicationPrivate::keypadNavigationEnabled() && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right) && count() > 1 #endif ) { int pageCount = d->tabs->count(); int page = currentIndex(); int dx = (e->key() == Qt::Key_Backtab || e->modifiers() & Qt::ShiftModifier) ? -1 : 1; #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled() && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right)) + if (QApplicationPrivate::keypadNavigationEnabled() && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right)) dx = e->key() == (isRightToLeft() ? Qt::Key_Right : Qt::Key_Left) ? -1 : 1; #endif for (int pass = 0; pass < pageCount; ++pass) { diff --git a/src/widgets/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp index 7a77f86de2..3e49390315 100644 --- a/src/widgets/widgets/qtextbrowser.cpp +++ b/src/widgets/widgets/qtextbrowser.cpp @@ -42,6 +42,7 @@ #include #include +#include #include #include #include @@ -1016,7 +1017,7 @@ void QTextBrowser::keyPressEvent(QKeyEvent *ev) Q_D(QTextBrowser); switch (ev->key()) { case Qt::Key_Select: - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (!hasEditFocus()) { setEditFocus(true); return; @@ -1031,7 +1032,7 @@ void QTextBrowser::keyPressEvent(QKeyEvent *ev) } break; case Qt::Key_Back: - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (hasEditFocus()) { setEditFocus(false); ev->accept(); @@ -1041,7 +1042,7 @@ void QTextBrowser::keyPressEvent(QKeyEvent *ev) QTextEdit::keyPressEvent(ev); return; default: - if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) { + if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) { ev->ignore(); return; } diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp index 8599573e5a..bd9e5f8159 100644 --- a/src/widgets/widgets/qtextedit.cpp +++ b/src/widgets/widgets/qtextedit.cpp @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -1116,7 +1117,7 @@ bool QTextEdit::event(QEvent *e) #endif // QT_NO_CONTEXTMENU #ifdef QT_KEYPAD_NAVIGATION if (e->type() == QEvent::EnterEditFocus || e->type() == QEvent::LeaveEditFocus) { - if (QApplication::keypadNavigationEnabled()) + if (QApplicationPrivate::keypadNavigationEnabled()) d->sendControlEvent(e); } #endif @@ -1301,7 +1302,7 @@ void QTextEdit::keyPressEvent(QKeyEvent *e) #ifdef QT_KEYPAD_NAVIGATION switch (e->key()) { case Qt::Key_Select: - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { // code assumes linksaccessible + editable isn't meaningful if (d->control->textInteractionFlags() & Qt::TextEditable) { setEditFocus(!hasEditFocus()); @@ -1322,14 +1323,14 @@ void QTextEdit::keyPressEvent(QKeyEvent *e) break; case Qt::Key_Back: case Qt::Key_No: - if (!QApplication::keypadNavigationEnabled() - || (QApplication::keypadNavigationEnabled() && !hasEditFocus())) { + if (!QApplicationPrivate::keypadNavigationEnabled() + || (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus())) { e->ignore(); return; } break; default: - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (!hasEditFocus() && !(e->modifiers() & Qt::ControlModifier)) { if (e->text()[0].isPrint()) setEditFocus(true); @@ -1418,7 +1419,7 @@ void QTextEdit::keyPressEvent(QKeyEvent *e) switch (e->key()) { case Qt::Key_Up: case Qt::Key_Down: - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { // Cursor position didn't change, so we want to leave // these keys to change focus. e->ignore(); @@ -1427,7 +1428,7 @@ void QTextEdit::keyPressEvent(QKeyEvent *e) break; case Qt::Key_Back: if (!e->isAutoRepeat()) { - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (document()->isEmpty() || !(d->control->textInteractionFlags() & Qt::TextEditable)) { setEditFocus(false); e->accept(); @@ -1453,7 +1454,7 @@ void QTextEdit::keyReleaseEvent(QKeyEvent *e) { #ifdef QT_KEYPAD_NAVIGATION Q_D(QTextEdit); - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (!e->isAutoRepeat() && e->key() == Qt::Key_Back && d->deleteAllTimer.isActive()) { d->deleteAllTimer.stop(); @@ -1665,7 +1666,7 @@ void QTextEdit::mousePressEvent(QMouseEvent *e) { Q_D(QTextEdit); #ifdef QT_KEYPAD_NAVIGATION - if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) + if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) setEditFocus(true); #endif d->sendControlEvent(e); @@ -1796,7 +1797,7 @@ void QTextEdit::inputMethodEvent(QInputMethodEvent *e) Q_D(QTextEdit); #ifdef QT_KEYPAD_NAVIGATION if (d->control->textInteractionFlags() & Qt::TextEditable - && QApplication::keypadNavigationEnabled() + && QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) setEditFocus(true); #endif diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp index 56dba1dd32..46bc29eed7 100644 --- a/src/widgets/widgets/qwidgetlinecontrol.cpp +++ b/src/widgets/widgets/qwidgetlinecontrol.cpp @@ -54,6 +54,7 @@ #endif #include "qapplication.h" +#include "private/qapplication_p.h" #if QT_CONFIG(graphicsview) #include "qgraphicssceneevent.h" #endif @@ -1662,7 +1663,7 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event) case Qt::Key_F4: #ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Select: - if (!QApplication::keypadNavigationEnabled()) + if (!QApplicationPrivate::keypadNavigationEnabled()) break; #endif if (!m_completer->currentCompletion().isEmpty() && hasSelectedText() @@ -1912,7 +1913,7 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event) break; #ifdef QT_KEYPAD_NAVIGATION case Qt::Key_Back: - if (QApplication::keypadNavigationEnabled() && !event->isAutoRepeat() + if (QApplicationPrivate::keypadNavigationEnabled() && !event->isAutoRepeat() && !isReadOnly()) { if (text().length() == 0) { setText(m_cancelText); diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index 70e1c148a1..fdbaf29dd8 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -55,6 +55,7 @@ #endif #include #include +#include "private/qapplication_p.h" #include "private/qtextdocumentlayout_p.h" #include "private/qabstracttextdocumentlayout_p.h" #include "qtextdocument.h" @@ -294,7 +295,7 @@ bool QWidgetTextControlPrivate::cursorMoveKeyEvent(QKeyEvent *e) bool isNavigationEvent = e->key() == Qt::Key_Up || e->key() == Qt::Key_Down; #ifdef QT_KEYPAD_NAVIGATION - ignoreNavigationEvents = ignoreNavigationEvents || QApplication::keypadNavigationEnabled(); + ignoreNavigationEvents = ignoreNavigationEvents || QApplicationPrivate::keypadNavigationEnabled(); isNavigationEvent = isNavigationEvent || (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional && (e->key() == Qt::Key_Left || e->key() == Qt::Key_Right)); @@ -1159,7 +1160,7 @@ void QWidgetTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget #ifdef QT_KEYPAD_NAVIGATION case QEvent::EnterEditFocus: case QEvent::LeaveEditFocus: - if (QApplication::keypadNavigationEnabled()) + if (QApplicationPrivate::keypadNavigationEnabled()) d->editFocusEvent(e); break; #endif @@ -2218,7 +2219,7 @@ void QWidgetTextControlPrivate::focusEvent(QFocusEvent *e) emit q->updateRequest(q->selectionRect()); if (e->gotFocus()) { #ifdef QT_KEYPAD_NAVIGATION - if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && (e->reason() == Qt::PopupFocusReason))) { + if (!QApplicationPrivate::keypadNavigationEnabled() || (hasEditFocus && (e->reason() == Qt::PopupFocusReason))) { #endif cursorOn = (interactionFlags & (Qt::TextSelectableByKeyboard | Qt::TextEditable)); if (interactionFlags & Qt::TextEditable) { @@ -2259,7 +2260,7 @@ void QWidgetTextControlPrivate::editFocusEvent(QEvent *e) { Q_Q(QWidgetTextControl); - if (QApplication::keypadNavigationEnabled()) { + if (QApplicationPrivate::keypadNavigationEnabled()) { if (e->type() == QEvent::EnterEditFocus && interactionFlags & Qt::TextEditable) { const QTextCursor oldSelection = cursor; const int oldCursorPos = cursor.position(); @@ -3280,7 +3281,7 @@ QAbstractTextDocumentLayout::PaintContext QWidgetTextControl::getPaintContext(QW if (!d->dndFeedbackCursor.isNull()) ctx.cursorPosition = d->dndFeedbackCursor.position(); #ifdef QT_KEYPAD_NAVIGATION - if (!QApplication::keypadNavigationEnabled() || d->hasEditFocus) + if (!QApplicationPrivate::keypadNavigationEnabled() || d->hasEditFocus) #endif if (d->cursor.hasSelection()) { QAbstractTextDocumentLayout::Selection selection; From b6f7efba4831c411456400e2df87df99877f67ae Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Thu, 18 Jul 2019 10:39:01 +0200 Subject: [PATCH 167/264] Make sql tests build and pass with disabled deprecated APIs Deprecated APIs of sql lib are used only in tests. This change makes sure, that the tests build and pass with those deprecated APIs removed or disabled, by: - Making the parts of the tests testing the deprecated APIs to be compiled conditionally, only when the corresponding methods are enabled. - If the test-case tests only the deprecated API, but not the corresponding replacement, added tests for the replacement. Task-number: QTBUG-76541 Change-Id: I93ed6ff92c7aa7af2c106b1a9d92d3704c7d9105 Reviewed-by: Alex Blasche --- .../sql/kernel/qsqlerror/tst_qsqlerror.cpp | 63 +++++++++++++++---- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp b/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp index be0285537e..871ac24be4 100644 --- a/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp +++ b/tests/auto/sql/kernel/qsqlerror/tst_qsqlerror.cpp @@ -42,7 +42,9 @@ public: virtual ~tst_QSqlError(); private slots: +#if QT_DEPRECATED_SINCE(5, 1) void getSetCheck(); +#endif void construction(); void moveOperator(); void operators(); @@ -57,6 +59,7 @@ tst_QSqlError::~tst_QSqlError() { } +#if QT_DEPRECATED_SINCE(5, 1) // Testing get/set functions void tst_QSqlError::getSetCheck() { @@ -83,14 +86,28 @@ void tst_QSqlError::getSetCheck() obj1.setNumber(INT_MAX); QCOMPARE(INT_MAX, obj1.number()); } +#endif void tst_QSqlError::construction() { - QSqlError obj1("drivertext", "databasetext", QSqlError::UnknownError, 123); +#if QT_DEPRECATED_SINCE(5, 3) + { + QSqlError obj1("drivertext", "databasetext", QSqlError::UnknownError, 123); + QCOMPARE(obj1.driverText(), QString("drivertext")); + QCOMPARE(obj1.databaseText(), QString("databasetext")); + QCOMPARE(obj1.type(), QSqlError::UnknownError); + QCOMPARE(obj1.number(), 123); + QCOMPARE(obj1.nativeErrorCode(), QStringLiteral("123")); + QVERIFY(obj1.isValid()); + } +#endif + QSqlError obj1("drivertext", "databasetext", QSqlError::UnknownError, QStringLiteral("123")); QCOMPARE(obj1.driverText(), QString("drivertext")); QCOMPARE(obj1.databaseText(), QString("databasetext")); QCOMPARE(obj1.type(), QSqlError::UnknownError); +#if QT_DEPRECATED_SINCE(5, 3) QCOMPARE(obj1.number(), 123); +#endif QCOMPARE(obj1.nativeErrorCode(), QStringLiteral("123")); QVERIFY(obj1.isValid()); @@ -98,7 +115,9 @@ void tst_QSqlError::construction() QCOMPARE(obj2.driverText(), obj1.driverText()); QCOMPARE(obj2.databaseText(), obj1.databaseText()); QCOMPARE(obj2.type(), obj1.type()); +#if QT_DEPRECATED_SINCE(5, 3) QCOMPARE(obj2.number(), obj1.number()); +#endif QCOMPARE(obj2.nativeErrorCode(), obj1.nativeErrorCode()); QVERIFY(obj2.isValid()); @@ -106,7 +125,9 @@ void tst_QSqlError::construction() QCOMPARE(obj3.driverText(), obj2.driverText()); QCOMPARE(obj3.databaseText(), obj2.databaseText()); QCOMPARE(obj3.type(), obj2.type()); +#if QT_DEPRECATED_SINCE(5, 3) QCOMPARE(obj3.number(), obj2.number()); +#endif QCOMPARE(obj3.nativeErrorCode(), obj2.nativeErrorCode()); QVERIFY(obj3.isValid()); @@ -116,7 +137,9 @@ void tst_QSqlError::construction() QCOMPARE(obj4.databaseText(), QString()); QCOMPARE(obj4.text(), QString()); QCOMPARE(obj4.type(), QSqlError::NoError); +#if QT_DEPRECATED_SINCE(5, 3) QCOMPARE(obj4.number(), -1); +#endif QCOMPARE(obj4.nativeErrorCode(), QString()); QSqlError obj5(QStringLiteral("drivertext"), QStringLiteral("databasetext"), @@ -124,7 +147,9 @@ void tst_QSqlError::construction() QCOMPARE(obj5.driverText(), QString("drivertext")); QCOMPARE(obj5.databaseText(), QString("databasetext")); QCOMPARE(obj5.type(), QSqlError::UnknownError); +#if QT_DEPRECATED_SINCE(5, 3) QCOMPARE(obj5.number(), 123); +#endif QCOMPARE(obj5.nativeErrorCode(), QStringLiteral("123")); QVERIFY(obj5.isValid()); @@ -133,17 +158,31 @@ void tst_QSqlError::construction() QCOMPARE(obj6.driverText(), QString("drivertext")); QCOMPARE(obj6.databaseText(), QString("databasetext")); QCOMPARE(obj6.type(), QSqlError::UnknownError); +#if QT_DEPRECATED_SINCE(5, 3) QCOMPARE(obj6.number(), 0); +#endif QCOMPARE(obj6.nativeErrorCode(), QStringLiteral("Err123")); QVERIFY(obj6.isValid()); - // Default constructed object as constructed before Qt 5.3 - QSqlError obj7(QString(), QString(), QSqlError::NoError, -1); +#if QT_DEPRECATED_SINCE(5, 3) + { + // Default constructed object as constructed before Qt 5.3 + QSqlError obj7(QString(), QString(), QSqlError::NoError, -1); + QVERIFY(!obj7.isValid()); + QCOMPARE(obj7.driverText(), QString()); + QCOMPARE(obj7.databaseText(), QString()); + QCOMPARE(obj7.type(), QSqlError::NoError); + QCOMPARE(obj7.number(), -1); + QCOMPARE(obj7.nativeErrorCode(), QString()); + } +#endif + + // Default constructed object + QSqlError obj7; QVERIFY(!obj7.isValid()); QCOMPARE(obj7.driverText(), QString()); QCOMPARE(obj7.databaseText(), QString()); QCOMPARE(obj7.type(), QSqlError::NoError); - QCOMPARE(obj7.number(), -1); QCOMPARE(obj7.nativeErrorCode(), QString()); // Move constructor @@ -151,32 +190,32 @@ void tst_QSqlError::construction() QCOMPARE(obj8.driverText(), obj2.driverText()); QCOMPARE(obj8.databaseText(), obj2.databaseText()); QCOMPARE(obj8.type(), obj2.type()); +#if QT_DEPRECATED_SINCE(5, 3) QCOMPARE(obj8.number(), obj2.number()); +#endif QCOMPARE(obj8.nativeErrorCode(), obj2.nativeErrorCode()); QVERIFY(obj8.isValid()); } void tst_QSqlError::moveOperator() { - QSqlError obj1("drivertext", "databasetext", QSqlError::UnknownError, 123), obj2; + QSqlError obj1("drivertext", "databasetext", QSqlError::UnknownError, QStringLiteral("123")), obj2; obj2 = std::move(obj1); QCOMPARE(obj2.driverText(), QString("drivertext")); QCOMPARE(obj2.databaseText(), QString("databasetext")); QCOMPARE(obj2.type(), QSqlError::UnknownError); +#if QT_DEPRECATED_SINCE(5, 3) QCOMPARE(obj2.number(), 123); +#endif QCOMPARE(obj2.nativeErrorCode(), QStringLiteral("123")); QVERIFY(obj2.isValid()); } void tst_QSqlError::operators() { - QSqlError error1; - QSqlError error2; - QSqlError error3; - - error1.setType(QSqlError::NoError); - error2.setType(QSqlError::NoError); - error3.setType(QSqlError::UnknownError); + QSqlError error1(QString(), QString(), QSqlError::NoError); + QSqlError error2(QString(), QString(), QSqlError::NoError); + QSqlError error3(QString(), QString(), QSqlError::UnknownError); QCOMPARE(error1, error2); QVERIFY(error1 != error3); From 733ca2230c283cdfaae424eac481ddc33593f44f Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 19 Jul 2019 11:30:29 +0200 Subject: [PATCH 168/264] Fix comparisons of image with different color spaces Take color space into account when comparing images, and fix gamma comparison that was trying to be too accurate. Change-Id: I3674653abb21b66aaacb557addc4afb4ee75cfdd Reviewed-by: Eirik Aavitsland --- src/gui/image/qimage.cpp | 4 +++- src/gui/painting/qcolorspace.cpp | 2 +- tests/auto/gui/image/qimage/tst_qimage.cpp | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index cd2fe5bc10..7ac4b3546e 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -3834,7 +3834,9 @@ bool QImage::operator==(const QImage & i) const return false; // obviously different stuff? - if (i.d->height != d->height || i.d->width != d->width || i.d->format != d->format) + if (i.d->height != d->height || i.d->width != d->width) + return false; + if (i.d->format != d->format || i.d->colorSpace != d->colorSpace) return false; if (d->format != Format_RGB32) { diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp index 3c336c9fe7..d058505e68 100644 --- a/src/gui/painting/qcolorspace.cpp +++ b/src/gui/painting/qcolorspace.cpp @@ -651,7 +651,7 @@ bool operator==(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2) if (colorSpace1.transferFunction() != colorSpace2.transferFunction()) return false; if (colorSpace1.transferFunction() == QColorSpace::TransferFunction::Gamma) - return colorSpace1.gamma() == colorSpace2.gamma(); + return (qAbs(colorSpace1.gamma() - colorSpace2.gamma()) <= (1.0f / 512.0f)); return true; } diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 441ec17412..e007a15419 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -232,6 +232,8 @@ private slots: void wideImage(); + void colorspaceEquality(); + #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) void toWinHBITMAP_data(); void toWinHBITMAP(); @@ -3618,6 +3620,22 @@ void tst_QImage::wideImage() // Qt6: Test that it actually works on 64bit architectures. } +void tst_QImage::colorspaceEquality() +{ + QImage image1(10, 10, QImage::Format_RGB32); + image1.fill(Qt::red); + QImage image2(image1); + QCOMPARE(image1, image2); + image1.setColorSpace(QColorSpace::SRgbLinear); + QVERIFY(image1 != image2); + image2.setColorSpace(QColorSpace::SRgbLinear); + QVERIFY(image1 == image2); + image1.setColorSpace(QColorSpace(QColorSpace::Gamut::DciP3D65, QColorSpace::TransferFunction::Gamma, 2.2f)); + QVERIFY(image1 != image2); + image2.setColorSpace(QColorSpace(QColorSpace::Gamut::DciP3D65, QColorSpace::TransferFunction::Gamma, 2.2001f)); + QVERIFY(image1 == image2); +} + #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) QT_BEGIN_NAMESPACE Q_GUI_EXPORT HBITMAP qt_imageToWinHBITMAP(const QImage &p, int hbitmapFormat = 0); From 83de6d0ce5baceb7739b89254cba4acc6fdab47d Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 19 Jul 2019 11:46:07 +0200 Subject: [PATCH 169/264] Add support for saving colorspace to PNGs Also fixes interaction with QImageReader gamma correction Change-Id: I108f253697f7ff60be6940bca17faa9f9ceb577b Reviewed-by: Eirik Aavitsland --- src/gui/image/qpnghandler.cpp | 24 ++++++++++++-- .../image/qimagereader/tst_qimagereader.cpp | 31 +++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 4b72888414..023696a401 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -611,6 +611,9 @@ bool QPngHandlerPrivate::readPngHeader() if (!colorSpace.isValid()) { qWarning() << "QPngHandler: Failed to parse ICC profile"; } else { + QColorSpacePrivate *csD = QColorSpacePrivate::getWritable(colorSpace); + if (csD->description.isEmpty()) + csD->description = QString::fromLatin1((const char *)name); colorSpaceState = Icc; } } @@ -680,7 +683,7 @@ bool QPngHandlerPrivate::readPngImage(QImage *outImage) png_set_gamma(png_ptr, 1.0f / gamma, fileGamma); QColorSpacePrivate *csPrivate = QColorSpacePrivate::getWritable(colorSpace); csPrivate->transferFunction = QColorSpace::TransferFunction::Gamma; - csPrivate->gamma = gamma; + csPrivate->gamma = 1.0f / gamma; csPrivate->setTransferFunction(); colorSpaceState = GammaChrm; } @@ -977,7 +980,24 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i bpc, // per channel color_type, 0, 0, 0); // sets #channels - if (gamma != 0.0) { + if (image.colorSpace().isValid()) { + QColorSpace cs = image.colorSpace(); + // Support the old gamma making it override transferfunction. + if (gamma != 0.0 && !qFuzzyCompare(cs.gamma(), 1.0f / gamma)) { + QColorSpacePrivate *csPrivate = QColorSpacePrivate::getWritable(cs); + csPrivate->transferFunction = QColorSpace::TransferFunction::Gamma; + csPrivate->gamma = 1.0f / gamma; + csPrivate->setTransferFunction(); + csPrivate->iccProfile.clear(); + csPrivate->description.clear(); + } + QByteArray iccProfileName = QColorSpacePrivate::get(cs)->description.toLatin1(); + if (iccProfileName.isEmpty()) + iccProfileName = QByteArrayLiteral("Custom"); + QByteArray iccProfile = cs.iccProfile(); + png_set_iCCP(png_ptr, info_ptr, (png_const_charp)iccProfileName.constData(), + PNG_COMPRESSION_TYPE_BASE, (png_const_bytep)iccProfile.constData(), iccProfile.length()); + } else if (gamma != 0.0) { png_set_gAMA(png_ptr, info_ptr, 1.0/gamma); } diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp index d17a171728..8b42b139a3 100644 --- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp +++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -158,6 +159,9 @@ private slots: void saveFormat_data(); void saveFormat(); + void saveColorSpace_data(); + void saveColorSpace(); + void readText_data(); void readText(); @@ -1883,6 +1887,33 @@ void tst_QImageReader::saveFormat() QCOMPARE(stored, converted); } +void tst_QImageReader::saveColorSpace_data() +{ + QTest::addColumn("colorspaceId"); + + QTest::newRow("Undefined") << QColorSpace::Undefined; + QTest::newRow("sRGB") << QColorSpace::SRgb; + QTest::newRow("sRGB(linear)") << QColorSpace::SRgbLinear; + QTest::newRow("AdobeRGB") << QColorSpace::AdobeRgb; + QTest::newRow("DisplayP3") << QColorSpace::DisplayP3; + QTest::newRow("ProPhotoRgb") << QColorSpace::ProPhotoRgb; +} + +void tst_QImageReader::saveColorSpace() +{ + QFETCH(QColorSpace::ColorSpaceId, colorspaceId); + + QImage orig(":/images/kollada.png"); + + orig.setColorSpace(colorspaceId); + QBuffer buf; + buf.open(QIODevice::WriteOnly); + QVERIFY(orig.save(&buf, "png")); + buf.close(); + QImage stored = QImage::fromData(buf.buffer(), "png"); + + QCOMPARE(stored, orig); +} void tst_QImageReader::readText_data() { From 3bbbc8510af7ee70db20212291c87a405f44eec4 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Tue, 23 Jul 2019 11:03:51 +0900 Subject: [PATCH 170/264] Fix typo in configure script Change-Id: Icc979dd58e061c62d45305e00580d27d0cd4af69 Reviewed-by: Edward Welbourne --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index ef7bad1bfc..19016d5c12 100755 --- a/configure +++ b/configure @@ -358,7 +358,7 @@ if [ -z "$QT_MAJOR_VERSION" ]; then fi #------------------------------------------------------------------------------- -# initalize variables +# initialize variables #------------------------------------------------------------------------------- # QTDIR may be set and point to an old or system-wide Qt installation From ca5fc087bdc94fad14f8edce89cfe171858260dc Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 23 Jul 2019 22:14:50 +0300 Subject: [PATCH 171/264] Re-apply 'Skip old benchmark that doesn't build automatically' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit re-applies commit f8efe8e0c91905d5077131d343f2ae2b3ca7daa2, which was lost in the recent tools → text changes. Change-Id: I03ce35fcb89840e5607776d67578fb75b66f6eb2 Reviewed-by: Allan Sandfeld Jensen --- tests/benchmarks/corelib/text/text.pro | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/benchmarks/corelib/text/text.pro b/tests/benchmarks/corelib/text/text.pro index 8c15d0b0c5..a2397b37fe 100644 --- a/tests/benchmarks/corelib/text/text.pro +++ b/tests/benchmarks/corelib/text/text.pro @@ -3,7 +3,6 @@ SUBDIRS = \ qbytearray \ qchar \ qlocale \ - qregexp \ qstringbuilder \ qstringlist From 589d96b9b06a4a7d0dca03a06c80716318761277 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 24 Jun 2019 15:38:45 +0200 Subject: [PATCH 172/264] winrt: Remove QWinrtScreen::pixelDensity so that the default of 1.0 is used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Winrt does device independent scaling by default so that overwriting pixelDensity for QWinrtScreen will break the use case of setting Qt::AA_EnableHighDpiScaling. That mode is basically always active on winrt. Task-number: QTBUG-76363 Change-Id: Ib522201850d17757be4a80aa819c3f1245ca7147 Reviewed-by: Maurice Kalinowski Reviewed-by: André de la Rocha --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 6 ------ src/plugins/platforms/winrt/qwinrtscreen.h | 1 - 2 files changed, 7 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index e611c7be24..342e142a74 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -669,12 +669,6 @@ QDpi QWinRTScreen::logicalDpi() const return QDpi(d->logicalDpi, d->logicalDpi); } -qreal QWinRTScreen::pixelDensity() const -{ - Q_D(const QWinRTScreen); - return qMax(1, qRound(d->logicalDpi / 96)); -} - qreal QWinRTScreen::scaleFactor() const { Q_D(const QWinRTScreen); diff --git a/src/plugins/platforms/winrt/qwinrtscreen.h b/src/plugins/platforms/winrt/qwinrtscreen.h index 63c254940d..6b57780fa1 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.h +++ b/src/plugins/platforms/winrt/qwinrtscreen.h @@ -96,7 +96,6 @@ public: QImage::Format format() const override; QSizeF physicalSize() const override; QDpi logicalDpi() const override; - qreal pixelDensity() const override; qreal scaleFactor() const; QPlatformCursor *cursor() const override; Qt::KeyboardModifiers keyboardModifiers() const; From e4c1feae5c0bec21e24edbf5acacd248dd121634 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 17 Jul 2019 15:10:49 +0200 Subject: [PATCH 173/264] Implement 'preconnect-https' and 'preconnect-http' for H2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QNetworkAccessManager::connectToHostEncrypted()/connectToHost() creates 'fake' requests with pseudo-schemes 'preconnect-https'/ 'preconnect-http'. QHttp2ProtocolHandler should handle this requests in a special way - reporting them immediately as finished (so that QNAM emits finished as it does in case of HTTP/1.1) and not trying to send anything. We also have to properly cache the connection - 'https' or 'http' scheme is too generic - it allows (unfortunately) mixing H2/HTTP/1.1 in a single connection in case an attribute was missing on a request, which is wrong. h2c is more complicated, since it needs a real request to negotiate the protocol switch to H2, with the current QNetworkHttpConnection(Channel)'s design it's not possible without large changes (aka regressions and new bugs introduced). Auto-test extended. Fixes: QTBUG-77082 Change-Id: I03467673a620c89784c2d36521020dc9d08aced7 Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim --- src/network/access/qhttp2protocolhandler.cpp | 25 +++- src/network/access/qhttpthreaddelegate.cpp | 36 +++-- src/network/access/qnetworkaccessmanager.cpp | 9 +- tests/auto/network/access/http2/tst_http2.cpp | 123 ++++++++++++++++++ 4 files changed, 175 insertions(+), 18 deletions(-) diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp index 87a70d8a55..5d7fc7506e 100644 --- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -170,7 +170,6 @@ QHttp2ProtocolHandler::QHttp2ProtocolHandler(QHttpNetworkConnectionChannel *chan encoder(HPack::FieldLookupTable::DefaultSize, true) { Q_ASSERT(channel && m_connection); - continuedFrames.reserve(20); const ProtocolParameters params(m_connection->http2Parameters()); @@ -322,10 +321,32 @@ bool QHttp2ProtocolHandler::sendRequest() return false; } + // Process 'fake' (created by QNetworkAccessManager::connectToHostEncrypted()) + // requests first: + auto &requests = m_channel->spdyRequestsToSend; + for (auto it = requests.begin(), endIt = requests.end(); it != endIt;) { + const auto &pair = *it; + const QString scheme(pair.first.url().scheme()); + if (scheme == QLatin1String("preconnect-http") + || scheme == QLatin1String("preconnect-https")) { + m_connection->preConnectFinished(); + emit pair.second->finished(); + it = requests.erase(it); + if (!requests.size()) { + // Normally, after a connection was established and H2 + // was negotiated, we send a client preface. connectToHostEncrypted + // though is not meant to send any data, it's just a 'preconnect'. + // Thus we return early: + return true; + } + } else { + ++it; + } + } + if (!prefaceSent && !sendClientPreface()) return false; - auto &requests = m_channel->spdyRequestsToSend; if (!requests.size()) return true; diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp index 0e97acdd9d..86ee6fd2eb 100644 --- a/src/network/access/qhttpthreaddelegate.cpp +++ b/src/network/access/qhttpthreaddelegate.cpp @@ -128,7 +128,8 @@ static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy) QString result; QUrl copy = url; QString scheme = copy.scheme(); - bool isEncrypted = scheme == QLatin1String("https"); + bool isEncrypted = scheme == QLatin1String("https") + || scheme == QLatin1String("preconnect-https"); copy.setPort(copy.port(isEncrypted ? 443 : 80)); if (scheme == QLatin1String("preconnect-http")) { copy.setScheme(QLatin1String("http")); @@ -295,17 +296,29 @@ void QHttpThreadDelegate::startRequest() connectionType = QHttpNetworkConnection::ConnectionTypeHTTP2Direct; } + const bool isH2 = httpRequest.isHTTP2Allowed() || httpRequest.isHTTP2Direct(); + if (isH2) { +#if QT_CONFIG(ssl) + if (ssl) { + if (!httpRequest.isHTTP2Direct()) { + QList protocols; + protocols << QSslConfiguration::ALPNProtocolHTTP2 + << QSslConfiguration::NextProtocolHttp1_1; + incomingSslConfiguration->setAllowedNextProtocols(protocols); + } + urlCopy.setScheme(QStringLiteral("h2s")); + } else +#endif // QT_CONFIG(ssl) + { + urlCopy.setScheme(QStringLiteral("h2")); + } + } + #ifndef QT_NO_SSL if (ssl && !incomingSslConfiguration.data()) incomingSslConfiguration.reset(new QSslConfiguration); - if (httpRequest.isHTTP2Allowed() && ssl) { - // With HTTP2Direct we do not try any protocol negotiation. - QList protocols; - protocols << QSslConfiguration::ALPNProtocolHTTP2 - << QSslConfiguration::NextProtocolHttp1_1; - incomingSslConfiguration->setAllowedNextProtocols(protocols); - } else if (httpRequest.isSPDYAllowed() && ssl) { + if (!isH2 && httpRequest.isSPDYAllowed() && ssl) { connectionType = QHttpNetworkConnection::ConnectionTypeSPDY; urlCopy.setScheme(QStringLiteral("spdy")); // to differentiate SPDY requests from HTTPS requests QList nextProtocols; @@ -322,12 +335,11 @@ void QHttpThreadDelegate::startRequest() cacheKey = makeCacheKey(urlCopy, &cacheProxy); else #endif - cacheKey = makeCacheKey(urlCopy, 0); - + cacheKey = makeCacheKey(urlCopy, nullptr); // the http object is actually a QHttpNetworkConnection httpConnection = static_cast(connections.localData()->requestEntryNow(cacheKey)); - if (httpConnection == 0) { + if (!httpConnection) { // no entry in cache; create an object // the http object is actually a QHttpNetworkConnection #ifdef QT_NO_BEARERMANAGEMENT @@ -357,7 +369,7 @@ void QHttpThreadDelegate::startRequest() connections.localData()->addEntry(cacheKey, httpConnection); } else { if (httpRequest.withCredentials()) { - QNetworkAuthenticationCredential credential = authenticationManager->fetchCachedCredentials(httpRequest.url(), 0); + QNetworkAuthenticationCredential credential = authenticationManager->fetchCachedCredentials(httpRequest.url(), nullptr); if (!credential.user.isEmpty() && !credential.password.isEmpty()) { QAuthenticator auth; auth.setUser(credential.user); diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 85e2c492e4..31b1dbf2a5 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -1192,10 +1192,11 @@ void QNetworkAccessManager::connectToHostEncrypted(const QString &hostName, quin if (sslConfiguration != QSslConfiguration::defaultConfiguration()) request.setSslConfiguration(sslConfiguration); - // There is no way to enable SPDY via a request, so we need to check - // the ssl configuration whether SPDY is allowed here. - if (sslConfiguration.allowedNextProtocols().contains( - QSslConfiguration::NextProtocolSpdy3_0)) + // There is no way to enable SPDY/HTTP2 via a request, so we need to check + // the ssl configuration whether SPDY/HTTP2 is allowed here. + if (sslConfiguration.allowedNextProtocols().contains(QSslConfiguration::ALPNProtocolHTTP2)) + request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true); + else if (sslConfiguration.allowedNextProtocols().contains(QSslConfiguration::NextProtocolSpdy3_0)) request.setAttribute(QNetworkRequest::SpdyAllowedAttribute, true); get(request); diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp index f7d74e66b2..ce685a1b1c 100644 --- a/tests/auto/network/access/http2/tst_http2.cpp +++ b/tests/auto/network/access/http2/tst_http2.cpp @@ -84,6 +84,8 @@ private slots: void goaway_data(); void goaway(); void earlyResponse(); + void connectToHost_data(); + void connectToHost(); protected slots: // Slots to listen to our in-process server: @@ -544,6 +546,127 @@ void tst_Http2::earlyResponse() QVERIFY(serverGotSettingsACK); } +void tst_Http2::connectToHost_data() +{ + // The attribute to set on a new request: + QTest::addColumn("requestAttribute"); + // The corresponding (to the attribute above) connection type the + // server will use: + QTest::addColumn("connectionType"); + +#if QT_CONFIG(ssl) + QTest::addRow("encrypted-h2-direct") << QNetworkRequest::Http2DirectAttribute << H2Type::h2Direct; + if (!clearTextHTTP2) + QTest::addRow("encrypted-h2-ALPN") << QNetworkRequest::HTTP2AllowedAttribute << H2Type::h2Alpn; +#endif // QT_CONFIG(ssl) + // This works for all configurations, tests 'preconnect-http' scheme: + // h2 with protocol upgrade is not working for now (the logic is a bit + // complicated there ...). + QTest::addRow("h2-direct") << QNetworkRequest::Http2DirectAttribute << H2Type::h2cDirect; +} + +void tst_Http2::connectToHost() +{ + // QNetworkAccessManager::connectToHostEncrypted() and connectToHost() + // creates a special request with 'preconnect-https' or 'preconnect-http' + // schemes. At the level of the protocol handler we are supposed to report + // these requests as finished and wait for the real requests. This test will + // connect to a server with the first reply 'finished' signal meaning we + // indeed connected. At this point we check that a client preface was not + // sent yet, and no response received. Then we send the second (the real) + // request and do our usual checks. Since our server closes its listening + // socket on the first incoming connection (would not accept a new one), + // the successful completion of the second requests also means we were able + // to find a cached connection and re-use it. + + QFETCH(const QNetworkRequest::Attribute, requestAttribute); + QFETCH(const H2Type, connectionType); + + clearHTTP2State(); + + serverPort = 0; + nRequests = 2; + + ServerPtr targetServer(newServer(defaultServerSettings, connectionType)); + +#if QT_CONFIG(ssl) + Q_ASSERT(!clearTextHTTP2 || connectionType != H2Type::h2Alpn); +#else + Q_ASSERT(connectionType == H2Type::h2c || connectionType == H2Type::h2cDirect); + Q_ASSERT(targetServer->isClearText()); +#endif // QT_CONFIG(ssl) + + QMetaObject::invokeMethod(targetServer.data(), "startServer", Qt::QueuedConnection); + runEventLoop(); + + QVERIFY(serverPort != 0); + + auto url = requestUrl(connectionType); + url.setPath("/index.html"); + + QNetworkReply *reply = nullptr; + // Here some mess with how we create this first reply: +#if QT_CONFIG(ssl) + if (!targetServer->isClearText()) { + // Let's emulate what QNetworkAccessManager::connectToHostEncrypted() does. + // Alas, we cannot use it directly, since it does not return the reply and + // also does not know the difference between H2 with ALPN or direct. + auto copyUrl = url; + copyUrl.setScheme(QLatin1String("preconnect-https")); + QNetworkRequest request(copyUrl); + request.setAttribute(requestAttribute, true); + reply = manager->get(request); + // Since we're using self-signed certificates, ignore SSL errors: + reply->ignoreSslErrors(); + } else +#endif // QT_CONFIG(ssl) + { + // Emulating what QNetworkAccessManager::connectToHost() does with + // additional information that it cannot provide (the attribute). + auto copyUrl = url; + copyUrl.setScheme(QLatin1String("preconnect-http")); + QNetworkRequest request(copyUrl); + request.setAttribute(requestAttribute, true); + reply = manager->get(request); + } + + connect(reply, &QNetworkReply::finished, [this, reply]() { + --nRequests; + eventLoop.exitLoop(); + QCOMPARE(reply->error(), QNetworkReply::NoError); + QVERIFY(reply->isFinished()); + // Nothing must be sent yet: + QVERIFY(!prefaceOK); + QVERIFY(!serverGotSettingsACK); + // Nothing received back: + QVERIFY(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).isNull()); + QCOMPARE(reply->readAll().size(), 0); + }); + + runEventLoop(); + STOP_ON_FAILURE + + QCOMPARE(nRequests, 1); + + QNetworkRequest request(url); + request.setAttribute(requestAttribute, QVariant(true)); + reply = manager->get(request); + connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished); + // Note, unlike the first request, when the connection is ecnrytped, we + // do not ignore TLS errors on this reply - we should re-use existing + // connection, there TLS errors were already ignored. + + runEventLoop(); + STOP_ON_FAILURE + + QVERIFY(nRequests == 0); + QVERIFY(prefaceOK); + QVERIFY(serverGotSettingsACK); + + QCOMPARE(reply->error(), QNetworkReply::NoError); + QVERIFY(reply->isFinished()); +} + void tst_Http2::serverStarted(quint16 port) { serverPort = port; From fd42589b14041d620c51fd7d23877c2749767fb3 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 7 Jan 2017 21:58:01 +0100 Subject: [PATCH 174/264] Extend QString::arg(QString, ..., QString) to more than 9 arguments Now that we have QStringView::arg(), we can use it to implement a similarly flexible QString::arg(). It's not as straight-forward as in QStringView, though: QString has existing arg() overloads that all become worse matches with the introduction of the new, perfectly-forwarding overload. So in order to allow calling of the other arg() functions, first constrain the new arg() function to arguments that are convertible to QString, QStringView, or QLatin1String, and then delegate to the QStringView version. To stay compatible with the previous overloads, which accepted anything that implicitly converts to QString (in particular, QStringBuilder expressions), add a new overload of qStringLikeToView, taking const QString &. This benefits the existing QStringView and QLatin1View versions, too. [ChangeLog][QtCore][QString] QString::arg(QString, ..., QString) can now be called with more than nine arguments, as well as with QStringViews. Change-Id: I1e717a1bc696346808bcae45dc47762a492c8714 Reviewed-by: Qt CI Bot Reviewed-by: Volker Hilsheimer --- src/corelib/text/qstring.h | 35 ++++++++++++++++++++++++++++++++ src/corelib/text/qstringview.cpp | 5 +++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h index 9896553f7d..08930f73b5 100644 --- a/src/corelib/text/qstring.h +++ b/src/corelib/text/qstring.h @@ -89,6 +89,10 @@ class QTextCodec; class QStringRef; template class QVector; +namespace QtPrivate { +template class BoolList; +} + class QLatin1String { public: @@ -333,6 +337,7 @@ public: QChar fillChar = QLatin1Char(' ')) const; Q_REQUIRED_RESULT QString arg(QLatin1String a, int fieldWidth = 0, QChar fillChar = QLatin1Char(' ')) const; +#if QT_STRINGVIEW_LEVEL < 2 Q_REQUIRED_RESULT QString arg(const QString &a1, const QString &a2) const; Q_REQUIRED_RESULT QString arg(const QString &a1, const QString &a2, const QString &a3) const; Q_REQUIRED_RESULT QString arg(const QString &a1, const QString &a2, const QString &a3, @@ -350,6 +355,33 @@ public: Q_REQUIRED_RESULT QString arg(const QString &a1, const QString &a2, const QString &a3, const QString &a4, const QString &a5, const QString &a6, const QString &a7, const QString &a8, const QString &a9) const; +#endif +private: + template + struct is_convertible_to_view_or_qstring_helper + : std::integral_constant::value || + std::is_convertible::value || + std::is_convertible::value> {}; + template + struct is_convertible_to_view_or_qstring + : is_convertible_to_view_or_qstring_helper::type> {}; +public: + template + Q_REQUIRED_RESULT +#ifdef Q_CLANG_QDOC + QString +#else + typename std::enable_if< + sizeof...(Args) >= 2 && std::is_same< + QtPrivate::BoolList::value..., true>, + QtPrivate::BoolList::value...> + >::value, + QString + >::type +#endif + arg(Args &&...args) const + { return qToStringViewIgnoringNull(*this).arg(std::forward(args)...); } #if QT_DEPRECATED_SINCE(5, 14) QT_DEPRECATED_X("Use vasprintf(), arg() or QTextStream instead") @@ -1053,6 +1085,7 @@ inline QString QString::arg(short a, int fieldWidth, int base, QChar fillChar) c { return arg(qlonglong(a), fieldWidth, base, fillChar); } inline QString QString::arg(ushort a, int fieldWidth, int base, QChar fillChar) const { return arg(qulonglong(a), fieldWidth, base, fillChar); } +#if QT_STRINGVIEW_LEVEL < 2 inline QString QString::arg(const QString &a1, const QString &a2) const { return qToStringViewIgnoringNull(*this).arg(a1, a2); } inline QString QString::arg(const QString &a1, const QString &a2, const QString &a3) const @@ -1078,6 +1111,7 @@ inline QString QString::arg(const QString &a1, const QString &a2, const QString const QString &a4, const QString &a5, const QString &a6, const QString &a7, const QString &a8, const QString &a9) const { return qToStringViewIgnoringNull(*this).arg(a1, a2, a3, a4, a5, a6, a7, a8, a9); } +#endif inline QString QString::section(QChar asep, int astart, int aend, SectionFlags aflags) const { return section(QString(asep), astart, aend, aflags); } @@ -2014,6 +2048,7 @@ Q_REQUIRED_RESULT Q_ALWAYS_INLINE QString argToQStringDispatch(StringView patter return QtPrivate::argToQString(pattern, sizeof...(Args), argBases); } + inline QStringViewArg qStringLikeToArg(const QString &s) noexcept { return QStringViewArg{qToStringViewIgnoringNull(s)}; } Q_DECL_CONSTEXPR inline QStringViewArg qStringLikeToArg(QStringView s) noexcept { return QStringViewArg{s}; } inline QStringViewArg qStringLikeToArg(const QChar &c) noexcept { return QStringViewArg{QStringView{&c, 1}}; } Q_DECL_CONSTEXPR inline QLatin1StringArg qStringLikeToArg(QLatin1String s) noexcept { return QLatin1StringArg{s}; } diff --git a/src/corelib/text/qstringview.cpp b/src/corelib/text/qstringview.cpp index cc852dd042..8442bcdf1b 100644 --- a/src/corelib/text/qstringview.cpp +++ b/src/corelib/text/qstringview.cpp @@ -532,6 +532,7 @@ QT_BEGIN_NAMESPACE /*! \fn QString QStringView::arg(Args &&...args) const \fn QString QLatin1String::arg(Args &&...args) const + \fn QString QString::arg(Args &&...args) const \since 5.14 Replaces occurrences of \c{%N} in this string with the corresponding @@ -539,8 +540,8 @@ QT_BEGIN_NAMESPACE the \a args replaces the \c{%N} with the lowest \c{N} (all of them), the second of the \a args the \c{%N} with the next-lowest \c{N} etc. - \c Args can consist of anything that implicitly converts to QStringView - or QLatin1String. + \c Args can consist of anything that implicitly converts to QString, + QStringView or QLatin1String. In addition, the following types are also supported: QChar, QLatin1Char. From c13bb2a66aa2eda89cbb437ea7c7a8c2c0fe8cc6 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 13 May 2019 15:10:36 +0200 Subject: [PATCH 175/264] QObject: replace QScopedPointer with std::unique_ptr in the implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the standard tool instead of self-made stuff that cannot decide whether it wants to be a scoped pointer (why take()?) or a movable one (why no move special member functions?). Take advantage of C++11 local structs for pulling the custom deleter into the scope where its only user is located, too. Change-Id: I7e097a59edef9adc8455504ae94b8df0f8b9e5d2 Reviewed-by: Thiago Macieira Reviewed-by: Mårten Nordheim --- src/corelib/kernel/qobject.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 5c1ae8aa43..d364ae1087 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -93,12 +93,6 @@ QAbstractDynamicMetaObject::~QAbstractDynamicMetaObject() { } - -struct QSlotObjectBaseDeleter { // for use with QScopedPointer - static void cleanup(QtPrivate::QSlotObjectBase *slot) { - if (slot) slot->destroyIfLastRef(); - } -}; static int *queuedConnectionTypes(const QList &typeNames) { int *types = new int [typeNames.count() + 1]; @@ -3380,7 +3374,7 @@ QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender, type &= Qt::UniqueConnection - 1; } - QScopedPointer c(new QObjectPrivate::Connection); + std::unique_ptr c{new QObjectPrivate::Connection}; c->sender = s; c->signal_index = signal_index; c->receiver.storeRelaxed(r); @@ -3394,14 +3388,14 @@ QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender, c->argumentTypes.storeRelaxed(types); c->callFunction = callFunction; - QObjectPrivate::get(s)->addConnection(signal_index, c.data()); + QObjectPrivate::get(s)->addConnection(signal_index, c.get()); locker.unlock(); QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index); if (smethod.isValid()) s->connectNotify(smethod); - return c.take(); + return c.release(); } /*! @@ -3791,10 +3785,16 @@ void doActivate(QObject *sender, int signal_index, void **argv) if (c->isSlotObject) { c->slotObj->ref(); - QScopedPointer obj(c->slotObj); + + struct Deleter { + void operator()(QtPrivate::QSlotObjectBase *slot) const { + if (slot) slot->destroyIfLastRef(); + } + }; + const std::unique_ptr obj{c->slotObj}; { - Q_TRACE_SCOPE(QMetaObject_activate_slot_functor, obj.data()); + Q_TRACE_SCOPE(QMetaObject_activate_slot_functor, obj.get()); obj->call(receiver, argv); } } else if (c->callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) { @@ -4947,7 +4947,7 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s type = static_cast(type ^ Qt::UniqueConnection); } - QScopedPointer c(new QObjectPrivate::Connection); + std::unique_ptr c{new QObjectPrivate::Connection}; c->sender = s; c->signal_index = signal_index; QThreadData *td = r->d_func()->threadData; @@ -4962,8 +4962,8 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s c->ownArgumentTypes = false; } - QObjectPrivate::get(s)->addConnection(signal_index, c.data()); - QMetaObject::Connection ret(c.take()); + QObjectPrivate::get(s)->addConnection(signal_index, c.get()); + QMetaObject::Connection ret(c.release()); locker.unlock(); QMetaMethod method = QMetaObjectPrivate::signal(senderMetaObject, signal_index); From 65cdd0f36678a6b77caf9cf0007ad44c51f7f7af Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Tue, 4 Jun 2019 14:42:31 -0500 Subject: [PATCH 176/264] Enable shader cache for ES2 when GL_OES_get_program_binary is present Change-Id: I4fb71471a7dd22441def1eb837857d245c3e3c5a Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopenglprogrambinarycache.cpp | 31 ++++++++++++++++++-- src/gui/opengl/qopenglprogrambinarycache_p.h | 6 ++++ src/gui/opengl/qopenglshaderprogram.cpp | 8 ++++- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/gui/opengl/qopenglprogrambinarycache.cpp b/src/gui/opengl/qopenglprogrambinarycache.cpp index c96021a969..7029cd5455 100644 --- a/src/gui/opengl/qopenglprogrambinarycache.cpp +++ b/src/gui/opengl/qopenglprogrambinarycache.cpp @@ -168,12 +168,19 @@ bool QOpenGLProgramBinaryCache::verifyHeader(const QByteArray &buf) const bool QOpenGLProgramBinaryCache::setProgramBinary(uint programId, uint blobFormat, const void *p, uint blobSize) { - QOpenGLExtraFunctions *funcs = QOpenGLContext::currentContext()->extraFunctions(); + QOpenGLContext *context = QOpenGLContext::currentContext(); + QOpenGLExtraFunctions *funcs = context->extraFunctions(); while (true) { GLenum error = funcs->glGetError(); if (error == GL_NO_ERROR || error == GL_CONTEXT_LOST) break; } +#if defined(QT_OPENGL_ES_2) + if (context->isOpenGLES() && context->format().majorVersion() < 3) { + initializeProgramBinaryOES(context); + programBinaryOES(programId, blobFormat, p, blobSize); + } else +#endif funcs->glProgramBinary(programId, blobFormat, p, blobSize); GLenum err = funcs->glGetError(); @@ -347,7 +354,8 @@ void QOpenGLProgramBinaryCache::save(const QByteArray &cacheKey, uint programId) GLEnvInfo info; - QOpenGLExtraFunctions *funcs = QOpenGLContext::currentContext()->extraFunctions(); + QOpenGLContext *context = QOpenGLContext::currentContext(); + QOpenGLExtraFunctions *funcs = context->extraFunctions(); GLint blobSize = 0; while (true) { GLenum error = funcs->glGetError(); @@ -390,6 +398,12 @@ void QOpenGLProgramBinaryCache::save(const QByteArray &cacheKey, uint programId) *p++ = 0; GLint outSize = 0; +#if defined(QT_OPENGL_ES_2) + if (context->isOpenGLES() && context->format().majorVersion() < 3) { + initializeProgramBinaryOES(context); + getProgramBinaryOES(programId, blobSize, &outSize, &blobFormat, p); + } else +#endif funcs->glGetProgramBinary(programId, blobSize, &outSize, &blobFormat, p); if (blobSize != outSize) { qCDebug(DBG_SHADER_CACHE, "glGetProgramBinary returned size %d instead of %d", outSize, blobSize); @@ -408,4 +422,17 @@ void QOpenGLProgramBinaryCache::save(const QByteArray &cacheKey, uint programId) } } +#if defined(QT_OPENGL_ES_2) +void QOpenGLProgramBinaryCache::initializeProgramBinaryOES(QOpenGLContext *context) +{ + if (m_programBinaryOESInitialized) + return; + m_programBinaryOESInitialized = true; + + Q_ASSERT(context); + getProgramBinaryOES = (void (QOPENGLF_APIENTRYP)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary))context->getProcAddress("glGetProgramBinaryOES"); + programBinaryOES = (void (QOPENGLF_APIENTRYP)(GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length))context->getProcAddress("glProgramBinaryOES"); +} +#endif + QT_END_NAMESPACE diff --git a/src/gui/opengl/qopenglprogrambinarycache_p.h b/src/gui/opengl/qopenglprogrambinarycache_p.h index a0e1f91e25..9fade08e66 100644 --- a/src/gui/opengl/qopenglprogrambinarycache_p.h +++ b/src/gui/opengl/qopenglprogrambinarycache_p.h @@ -93,6 +93,12 @@ private: uint format; }; QCache m_memCache; +#if defined(QT_OPENGL_ES_2) + void (QOPENGLF_APIENTRYP programBinaryOES)(GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length); + void (QOPENGLF_APIENTRYP getProgramBinaryOES)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); + void initializeProgramBinaryOES(QOpenGLContext *context); + bool m_programBinaryOESInitialized = false; +#endif }; QT_END_NAMESPACE diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp index c39177080d..3ce0cf230b 100644 --- a/src/gui/opengl/qopenglshaderprogram.cpp +++ b/src/gui/opengl/qopenglshaderprogram.cpp @@ -3753,8 +3753,14 @@ QOpenGLProgramBinarySupportCheck::QOpenGLProgramBinarySupportCheck(QOpenGLContex if (ctx) { if (ctx->isOpenGLES()) { qCDebug(DBG_SHADER_CACHE, "OpenGL ES v%d context", ctx->format().majorVersion()); - if (ctx->format().majorVersion() >= 3) + if (ctx->format().majorVersion() >= 3) { m_supported = true; + } else { + const bool hasExt = ctx->hasExtension("GL_OES_get_program_binary"); + qCDebug(DBG_SHADER_CACHE, "GL_OES_get_program_binary support = %d", hasExt); + if (hasExt) + m_supported = true; + } } else { const bool hasExt = ctx->hasExtension("GL_ARB_get_program_binary"); qCDebug(DBG_SHADER_CACHE, "GL_ARB_get_program_binary support = %d", hasExt); From 0ce3f7d62b93427ca5d0f4284ba774691cbbd4a7 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 24 Jul 2019 15:47:28 +0200 Subject: [PATCH 177/264] QMacStyle: workaround NSSliderCell's cached/stale geometry It's a bit cheesy solution, but works as I've noticed first on QSlider's with a ticks direction 'both'. Works because we were already using numberOfTickMarks property to trigger a special behavior for HIG non-compliant widgets. Works for our case too - we trigger a geometry update. Fixes: QTBUG-76811 Change-Id: I2cbf00d42d98e78519b281d138a2f74227ef5449 Reviewed-by: Volker Hilsheimer --- src/plugins/styles/mac/qmacstyle_mac.mm | 35 +++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index e10aa33623..1d88d2c647 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -137,6 +137,8 @@ #include #include +#include + QT_USE_NAMESPACE static QWindow *qt_getWindow(const QWidget *widget) @@ -514,6 +516,37 @@ static bool setupSlider(NSSlider *slider, const QStyleOptionSlider *sl) return true; } +static void fixStaleGeometry(NSSlider *slider) +{ + // If it's later fixed in AppKit, this function is not needed. + // On macOS Mojave we suddenly have NSSliderCell with a cached + // (and stale) geometry, thus its -drawKnob, -drawBarInside:flipped:, + // -drawTickMarks fail to render the slider properly. Setting the number + // of tickmarks triggers an update in geometry. + + Q_ASSERT(slider); + + if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSMojave) + return; + + NSSliderCell *cell = slider.cell; + const NSRect barRect = [cell barRectFlipped:NO]; + const NSSize sliderSize = slider.frame.size; + CGFloat difference = 0.; + if (slider.vertical) + difference = std::abs(sliderSize.height - barRect.size.height); + else + difference = std::abs(sliderSize.width - barRect.size.width); + + if (difference > 6.) { + // Stale ... + const auto nOfTicks = slider.numberOfTickMarks; + // Non-zero, different from nOfTicks to force update + slider.numberOfTickMarks = nOfTicks + 10; + slider.numberOfTickMarks = nOfTicks; + } +} + static bool isInMacUnifiedToolbarArea(QWindow *window, int windowY) { QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); @@ -5318,6 +5351,8 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex #endif { [slider calcSize]; + if (!hasDoubleTicks) + fixStaleGeometry(slider); NSSliderCell *cell = slider.cell; const int numberOfTickMarks = slider.numberOfTickMarks; From 7303218e42ea03a8e163d57935b01472de76748a Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 24 Jul 2019 14:41:21 +0200 Subject: [PATCH 178/264] Split all the over-long lines in qlocale.cpp There were many. Reflowed some documentation to 80 columns, split all code lines that exceeded 100 columns. Revised the splitting in a few cases that were inelegant or conflicted with our coding style. Added braces to some bodies of split control lines. Change-Id: I56eb9632f6399f0db1293477966f7d553f196a5b Reviewed-by: Paul Wicking --- src/corelib/text/qlocale.cpp | 166 +++++++++++++++++++++++------------ 1 file changed, 110 insertions(+), 56 deletions(-) diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp index 939f8eb34d..270eac8610 100644 --- a/src/corelib/text/qlocale.cpp +++ b/src/corelib/text/qlocale.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Copyright (C) 2019 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** @@ -304,7 +304,8 @@ QByteArray QLocaleId::name(char separator) const (script_id != QLocale::AnyScript ? script_code_list + 4 * script_id : nullptr); const unsigned char *country = (country_id != QLocale::AnyCountry ? country_code_list + 3 * country_id : nullptr); - char len = (lang[2] != 0 ? 3 : 2) + (script ? 4+1 : 0) + (country ? (country[2] != 0 ? 3 : 2)+1 : 0); + char len = (lang[2] != 0 ? 3 : 2) + (script ? 4 + 1 : 0) + + (country ? (country[2] != 0 ? 3 : 2) + 1 : 0); QByteArray name(len, Qt::Uninitialized); char *uc = name.data(); *uc++ = lang[0]; @@ -335,7 +336,8 @@ QByteArray QLocalePrivate::bcp47Name(char separator) const if (m_data->m_language_id == QLocale::C) return QByteArrayLiteral("en"); - QLocaleId localeId = QLocaleId::fromIds(m_data->m_language_id, m_data->m_script_id, m_data->m_country_id); + QLocaleId localeId = QLocaleId::fromIds(m_data->m_language_id, m_data->m_script_id, + m_data->m_country_id); return localeId.withLikelySubtagsRemoved().name(separator); } @@ -367,8 +369,10 @@ static const QLocaleData *findLocaleDataById(const QLocaleId &localeId) } while (data->m_language_id && data->m_language_id == localeId.language_id); } else { do { - if (data->m_script_id == localeId.script_id && data->m_country_id == localeId.country_id) + if (data->m_script_id == localeId.script_id + && data->m_country_id == localeId.country_id) { return data; + } ++data; } while (data->m_language_id && data->m_language_id == localeId.language_id); } @@ -376,7 +380,8 @@ static const QLocaleData *findLocaleDataById(const QLocaleId &localeId) return nullptr; } -const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLocale::Script script, QLocale::Country country) +const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLocale::Script script, + QLocale::Country country) { QLocaleId localeId = QLocaleId::fromIds(language, script, country); QLocaleId likelyId = localeId.withLikelySubtagsAdded(); @@ -438,7 +443,8 @@ const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLoca return locale_data + idx; } -static bool parse_locale_tag(const QString &input, int &i, QString *result, const QString &separators) +static bool parse_locale_tag(const QString &input, int &i, QString *result, + const QString &separators) { *result = QString(8, Qt::Uninitialized); // worst case according to BCP47 QChar *pch = result->data(); @@ -487,7 +493,8 @@ bool qt_splitLocaleName(const QString &name, QString &lang, QString &script, QSt state = ScriptState; break; case ScriptState: { - QString scripts = QString::fromLatin1((const char *)script_code_list, sizeof(script_code_list) - 1); + QString scripts = QString::fromLatin1((const char *)script_code_list, + sizeof(script_code_list) - 1); if (value.length() == 4 && scripts.indexOf(value) % 4 == 0) { // script name is always 4 characters script = value; @@ -610,7 +617,8 @@ static QLocale::NumberOptions default_number_options = QLocale::DefaultNumberOpt static const QLocaleData *const c_data = locale_data; static QLocalePrivate *c_private() { - static QLocalePrivate c_locale = { c_data, Q_BASIC_ATOMIC_INITIALIZER(1), QLocale::OmitGroupSeparator }; + static QLocalePrivate c_locale = + { c_data, Q_BASIC_ATOMIC_INITIALIZER(1), QLocale::OmitGroupSeparator }; return &c_locale; } @@ -833,9 +841,11 @@ QLocale::QLocale(QLocalePrivate &dd) "language[_script][_country][.codeset][@modifier]" or "C", where: \list - \li language is a lowercase, two-letter, ISO 639 language code (also some three-letter codes), + \li language is a lowercase, two-letter, ISO 639 language code (also some + three-letter codes), \li script is a titlecase, four-letter, ISO 15924 script code, - \li country is an uppercase, two-letter, ISO 3166 country code (also "419" as defined by United Nations), + \li country is an uppercase, two-letter, ISO 3166 country code + (also "419" as defined by United Nations), \li and codeset and modifier are ignored. \endlist @@ -1036,9 +1046,11 @@ QString QLocale::quoteString(const QStringRef &str, QuotationStyle style) const if (d->m_data == systemData()) { QVariant res; if (style == QLocale::AlternateQuotation) - res = systemLocale()->query(QSystemLocale::StringToAlternateQuotation, QVariant::fromValue(str)); + res = systemLocale()->query(QSystemLocale::StringToAlternateQuotation, + QVariant::fromValue(str)); if (res.isNull() || style == QLocale::StandardQuotation) - res = systemLocale()->query(QSystemLocale::StringToStandardQuotation, QVariant::fromValue(str)); + res = systemLocale()->query(QSystemLocale::StringToStandardQuotation, + QVariant::fromValue(str)); if (!res.isNull()) return res.toString(); } @@ -1046,8 +1058,9 @@ QString QLocale::quoteString(const QStringRef &str, QuotationStyle style) const if (style == QLocale::StandardQuotation) return QChar(d->m_data->m_quotation_start) % str % QChar(d->m_data->m_quotation_end); - else - return QChar(d->m_data->m_alternate_quotation_start) % str % QChar(d->m_data->m_alternate_quotation_end); + + return QChar(d->m_data->m_alternate_quotation_start) + % str % QChar(d->m_data->m_alternate_quotation_end); } /*! @@ -1060,8 +1073,8 @@ QString QLocale::createSeparatedList(const QStringList &list) const { #ifndef QT_NO_SYSTEMLOCALE if (d->m_data == systemData()) { - QVariant res; - res = systemLocale()->query(QSystemLocale::ListToSeparatedString, QVariant::fromValue(list)); + QVariant res = + systemLocale()->query(QSystemLocale::ListToSeparatedString, QVariant::fromValue(list)); if (!res.isNull()) return res.toString(); @@ -1072,12 +1085,20 @@ QString QLocale::createSeparatedList(const QStringList &list) const if (size == 1) { return list.at(0); } else if (size == 2) { - QString format = getLocaleData(list_pattern_part_data + d->m_data->m_list_pattern_part_two_idx, d->m_data->m_list_pattern_part_two_size); + QString format = getLocaleData( + list_pattern_part_data + d->m_data->m_list_pattern_part_two_idx, + d->m_data->m_list_pattern_part_two_size); return format.arg(list.at(0), list.at(1)); } else if (size > 2) { - QString formatStart = getLocaleData(list_pattern_part_data + d->m_data->m_list_pattern_part_start_idx, d->m_data->m_list_pattern_part_start_size); - QString formatMid = getLocaleData(list_pattern_part_data + d->m_data->m_list_pattern_part_mid_idx, d->m_data->m_list_pattern_part_mid_size); - QString formatEnd = getLocaleData(list_pattern_part_data + d->m_data->m_list_pattern_part_end_idx, d->m_data->m_list_pattern_part_end_size); + QString formatStart = getLocaleData( + list_pattern_part_data + d->m_data->m_list_pattern_part_start_idx, + d->m_data->m_list_pattern_part_start_size); + QString formatMid = getLocaleData( + list_pattern_part_data + d->m_data->m_list_pattern_part_mid_idx, + d->m_data->m_list_pattern_part_mid_size); + QString formatEnd = getLocaleData( + list_pattern_part_data + d->m_data->m_list_pattern_part_end_idx, + d->m_data->m_list_pattern_part_end_size); QString result = formatStart.arg(list.at(0), list.at(1)); for (int i = 2; i < size - 1; ++i) result = formatMid.arg(result, list.at(i)); @@ -1187,7 +1208,8 @@ static qulonglong toIntegral_helper(const QLocaleData *d, QStringView str, bool template static inline T toIntegral_helper(const QLocalePrivate *d, QStringView str, bool *ok) { - using Int64 = typename std::conditional::value, qulonglong, qlonglong>::type; + using Int64 = + typename std::conditional::value, qulonglong, qlonglong>::type; // we select the right overload by the last, unused parameter Int64 val = toIntegral_helper(d->m_data, str, ok, d->m_numberOptions, Int64()); @@ -1203,8 +1225,8 @@ T toIntegral_helper(const QLocalePrivate *d, QStringView str, bool *ok) /*! \since 4.8 - Returns the dash-separated language, script and country (and possibly other BCP47 fields) - of this locale as a string. + Returns the dash-separated language, script and country (and possibly other + BCP47 fields) of this locale as a string. Unlike the uiLanguages() the returned value of the bcp47Name() represents the locale name of the QLocale data but not the language the user-interface @@ -1966,7 +1988,8 @@ QString QLocale::toString(const QDate &date, FormatType format) const #ifndef QT_NO_SYSTEMLOCALE if (d->m_data == systemData()) { QVariant res = systemLocale()->query(format == LongFormat - ? QSystemLocale::DateToStringLong : QSystemLocale::DateToStringShort, + ? QSystemLocale::DateToStringLong + : QSystemLocale::DateToStringShort, date); if (!res.isNull()) return res.toString(); @@ -2094,7 +2117,8 @@ QString QLocale::toString(const QTime &time, FormatType format) const #ifndef QT_NO_SYSTEMLOCALE if (d->m_data == systemData()) { QVariant res = systemLocale()->query(format == LongFormat - ? QSystemLocale::TimeToStringLong : QSystemLocale::TimeToStringShort, + ? QSystemLocale::TimeToStringLong + : QSystemLocale::TimeToStringShort, time); if (!res.isNull()) return res.toString(); @@ -2121,7 +2145,8 @@ QString QLocale::dateFormat(FormatType format) const #ifndef QT_NO_SYSTEMLOCALE if (d->m_data == systemData()) { QVariant res = systemLocale()->query(format == LongFormat - ? QSystemLocale::DateFormatLong : QSystemLocale::DateFormatShort, + ? QSystemLocale::DateFormatLong + : QSystemLocale::DateFormatShort, QVariant()); if (!res.isNull()) return res.toString(); @@ -2158,7 +2183,8 @@ QString QLocale::timeFormat(FormatType format) const #ifndef QT_NO_SYSTEMLOCALE if (d->m_data == systemData()) { QVariant res = systemLocale()->query(format == LongFormat - ? QSystemLocale::TimeFormatLong : QSystemLocale::TimeFormatShort, + ? QSystemLocale::TimeFormatLong + : QSystemLocale::TimeFormatShort, QVariant()); if (!res.isNull()) return res.toString(); @@ -2499,8 +2525,8 @@ QString QLocale::toString(double i, char f, int prec) const /*! Returns a QLocale object initialized to the system locale. - On Windows and Mac, this locale will use the decimal/grouping characters and date/time - formats specified in the system configuration panel. + On Windows and Mac, this locale will use the decimal/grouping characters and + date/time formats specified in the system configuration panel. \sa c() */ @@ -2521,10 +2547,12 @@ QLocale QLocale::system() script and \a country. Getting a list of all locales: - QList allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry); + QList allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, + QLocale::AnyCountry); Getting a list of locales suitable for Russia: - QList locales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::Russia); + QList locales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, + QLocale::Russia); */ QList QLocale::matchingLocales(QLocale::Language language, QLocale::Script script, @@ -2538,8 +2566,10 @@ QList QLocale::matchingLocales(QLocale::Language language, return QList() << QLocale(QLocale::C); QList result; - if (language == QLocale::AnyLanguage && script == QLocale::AnyScript && country == QLocale::AnyCountry) + if (language == QLocale::AnyLanguage && script == QLocale::AnyScript + && country == QLocale::AnyCountry) { result.reserve(locale_data_size); + } const QLocaleData *data = locale_data + locale_index[language]; while ( (data != locale_data + locale_data_size) && (language == QLocale::AnyLanguage || data->m_language_id == uint(language))) { @@ -2599,7 +2629,8 @@ QString QLocale::monthName(int month, FormatType type) const #ifndef QT_NO_SYSTEMLOCALE if (d->m_data == systemData()) { QVariant res = systemLocale()->query(type == LongFormat - ? QSystemLocale::MonthNameLong : QSystemLocale::MonthNameShort, + ? QSystemLocale::MonthNameLong + : QSystemLocale::MonthNameShort, month); if (!res.isNull()) return res.toString(); @@ -2645,7 +2676,8 @@ QString QLocale::standaloneMonthName(int month, FormatType type) const #ifndef QT_NO_SYSTEMLOCALE if (d->m_data == systemData()) { QVariant res = systemLocale()->query(type == LongFormat - ? QSystemLocale::StandaloneMonthNameLong : QSystemLocale::StandaloneMonthNameShort, + ? QSystemLocale::StandaloneMonthNameLong + : QSystemLocale::StandaloneMonthNameShort, month); if (!res.isNull()) return res.toString(); @@ -2692,7 +2724,8 @@ QString QLocale::dayName(int day, FormatType type) const #ifndef QT_NO_SYSTEMLOCALE if (d->m_data == systemData()) { QVariant res = systemLocale()->query(type == LongFormat - ? QSystemLocale::DayNameLong : QSystemLocale::DayNameShort, + ? QSystemLocale::DayNameLong + : QSystemLocale::DayNameShort, day); if (!res.isNull()) return res.toString(); @@ -2741,7 +2774,8 @@ QString QLocale::standaloneDayName(int day, FormatType type) const #ifndef QT_NO_SYSTEMLOCALE if (d->m_data == systemData()) { QVariant res = systemLocale()->query(type == LongFormat - ? QSystemLocale::DayNameLong : QSystemLocale::DayNameShort, + ? QSystemLocale::DayNameLong + : QSystemLocale::DayNameShort, day); if (!res.isNull()) return res.toString(); @@ -3025,7 +3059,8 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da case 4: { const int yr = date.year(); const int len = (yr < 0) ? 5 : 4; - result.append(m_data->longLongToString(yr, -1, 10, len, QLocaleData::ZeroPadded)); + result.append(m_data->longLongToString(yr, -1, 10, len, + QLocaleData::ZeroPadded)); break; } case 2: @@ -3047,7 +3082,8 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da result.append(m_data->longLongToString(date.month())); break; case 2: - result.append(m_data->longLongToString(date.month(), -1, 10, 2, QLocaleData::ZeroPadded)); + result.append(m_data->longLongToString(date.month(), -1, 10, 2, + QLocaleData::ZeroPadded)); break; case 3: result.append(q->monthName(date.month(), QLocale::ShortFormat)); @@ -3066,7 +3102,8 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da result.append(m_data->longLongToString(date.day())); break; case 2: - result.append(m_data->longLongToString(date.day(), -1, 10, 2, QLocaleData::ZeroPadded)); + result.append(m_data->longLongToString(date.day(), -1, 10, 2, + QLocaleData::ZeroPadded)); break; case 3: result.append(q->dayName(date.dayOfWeek(), QLocale::ShortFormat)); @@ -3099,7 +3136,8 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da result.append(m_data->longLongToString(hour)); break; case 2: - result.append(m_data->longLongToString(hour, -1, 10, 2, QLocaleData::ZeroPadded)); + result.append(m_data->longLongToString(hour, -1, 10, 2, + QLocaleData::ZeroPadded)); break; } break; @@ -3112,7 +3150,8 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da result.append(m_data->longLongToString(time.hour())); break; case 2: - result.append(m_data->longLongToString(time.hour(), -1, 10, 2, QLocaleData::ZeroPadded)); + result.append(m_data->longLongToString(time.hour(), -1, 10, 2, + QLocaleData::ZeroPadded)); break; } break; @@ -3125,7 +3164,8 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da result.append(m_data->longLongToString(time.minute())); break; case 2: - result.append(m_data->longLongToString(time.minute(), -1, 10, 2, QLocaleData::ZeroPadded)); + result.append(m_data->longLongToString(time.minute(), -1, 10, 2, + QLocaleData::ZeroPadded)); break; } break; @@ -3138,7 +3178,8 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da result.append(m_data->longLongToString(time.second())); break; case 2: - result.append(m_data->longLongToString(time.second(), -1, 10, 2, QLocaleData::ZeroPadded)); + result.append(m_data->longLongToString(time.second(), -1, 10, 2, + QLocaleData::ZeroPadded)); break; } break; @@ -3173,7 +3214,8 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da // note: the millisecond component is treated like the decimal part of the seconds // so ms == 2 is always printed as "002", but ms == 200 can be either "2" or "200" - result.append(m_data->longLongToString(time.msec(), -1, 10, 3, QLocaleData::ZeroPadded)); + result.append(m_data->longLongToString(time.msec(), -1, 10, 3, + QLocaleData::ZeroPadded)); if (repeat == 1) { if (result.endsWith(zero())) result.chop(1); @@ -3216,7 +3258,8 @@ QString QLocaleData::doubleToString(double d, int precision, DoubleForm form, QString QLocaleData::doubleToString(const QChar _zero, const QChar plus, const QChar minus, const QChar exponential, const QChar group, const QChar decimal, - double d, int precision, DoubleForm form, int width, unsigned flags) + double d, int precision, DoubleForm form, int width, + unsigned flags) { if (precision != QLocale::FloatingPointShortest && precision < 0) precision = 6; @@ -3589,11 +3632,14 @@ bool QLocaleData::numberToCLocale(QStringView s, QLocale::NumberOptions number_o return false; // check distance from the last separator or from the beginning of the digits - // ### FIXME: Some locales allow other groupings! See https://en.wikipedia.org/wiki/Thousands_separator + // ### FIXME: Some locales allow other groupings! + // See https://en.wikipedia.org/wiki/Thousands_separator if (last_separator_idx != -1 && idx - last_separator_idx != 4) return false; - if (last_separator_idx == -1 && (start_of_digits_idx == -1 || idx - start_of_digits_idx > 3)) + if (last_separator_idx == -1 + && (start_of_digits_idx == -1 || idx - start_of_digits_idx > 3)) { return false; + } last_separator_idx = idx; ++group_cnt; @@ -3603,7 +3649,8 @@ bool QLocaleData::numberToCLocale(QStringView s, QLocale::NumberOptions number_o continue; } else if (out == '.' || out == 'e' || out == 'E') { // check distance from the last separator - // ### FIXME: Some locales allow other groupings! See https://en.wikipedia.org/wiki/Thousands_separator + // ### FIXME: Some locales allow other groupings! + // See https://en.wikipedia.org/wiki/Thousands_separator if (last_separator_idx != -1 && idx - last_separator_idx != 4) return false; @@ -3663,9 +3710,10 @@ bool QLocaleData::validateChars(QStringView str, NumberMode numMode, QByteArray // The only non-digit character after the 'e' can be '+' or '-'. // If a zero is directly after that, then the exponent is zero-padded. - if ((number_options & QLocale::RejectLeadingZeroInExponent) && c == '0' && eCnt > 0 && - !lastWasDigit) + if ((number_options & QLocale::RejectLeadingZeroInExponent) + && c == '0' && eCnt > 0 && !lastWasDigit) { return false; + } lastWasDigit = true; } else { @@ -3917,7 +3965,8 @@ QString QLocale::toCurrencyString(qlonglong value, const QString &symbol) const #ifndef QT_NO_SYSTEMLOCALE if (d->m_data == systemData()) { QSystemLocale::CurrencyToStringArgument arg(value, symbol); - QVariant res = systemLocale()->query(QSystemLocale::CurrencyToString, QVariant::fromValue(arg)); + QVariant res = + systemLocale()->query(QSystemLocale::CurrencyToString, QVariant::fromValue(arg)); if (!res.isNull()) return res.toString(); } @@ -3947,7 +3996,8 @@ QString QLocale::toCurrencyString(qulonglong value, const QString &symbol) const #ifndef QT_NO_SYSTEMLOCALE if (d->m_data == systemData()) { QSystemLocale::CurrencyToStringArgument arg(value, symbol); - QVariant res = systemLocale()->query(QSystemLocale::CurrencyToString, QVariant::fromValue(arg)); + QVariant res = + systemLocale()->query(QSystemLocale::CurrencyToString, QVariant::fromValue(arg)); if (!res.isNull()) return res.toString(); } @@ -3989,7 +4039,8 @@ QString QLocale::toCurrencyString(double value, const QString &symbol, int preci #ifndef QT_NO_SYSTEMLOCALE if (d->m_data == systemData()) { QSystemLocale::CurrencyToStringArgument arg(value, symbol); - QVariant res = systemLocale()->query(QSystemLocale::CurrencyToString, QVariant::fromValue(arg)); + QVariant res = + systemLocale()->query(QSystemLocale::CurrencyToString, QVariant::fromValue(arg)); if (!res.isNull()) return res.toString(); } @@ -4126,7 +4177,8 @@ QStringList QLocale::uiLanguages() const } } #endif - QLocaleId id = QLocaleId::fromIds(d->m_data->m_language_id, d->m_data->m_script_id, d->m_data->m_country_id); + QLocaleId id = QLocaleId::fromIds(d->m_data->m_language_id, d->m_data->m_script_id, + d->m_data->m_country_id); const QLocaleId max = id.withLikelySubtagsAdded(); const QLocaleId min = max.withLikelySubtagsRemoved(); @@ -4182,7 +4234,8 @@ QString QLocale::nativeLanguageName() const return res.toString(); } #endif - return getLocaleData(endonyms_data + d->m_data->m_language_endonym_idx, d->m_data->m_language_endonym_size); + return getLocaleData(endonyms_data + d->m_data->m_language_endonym_idx, + d->m_data->m_language_endonym_size); } /*! @@ -4202,7 +4255,8 @@ QString QLocale::nativeCountryName() const return res.toString(); } #endif - return getLocaleData(endonyms_data + d->m_data->m_country_endonym_idx, d->m_data->m_country_endonym_size); + return getLocaleData(endonyms_data + d->m_data->m_country_endonym_idx, + d->m_data->m_country_endonym_size); } #ifndef QT_NO_DEBUG_STREAM From 082f10c9eb12972efb7f194e49eb2b11928e1337 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 14 May 2019 20:42:01 +0200 Subject: [PATCH 179/264] QOpenGLWindow example: use std::unique_ptr instead of QScopedPointer QScopedPointer is scheduled for deprecation, and can't decide whether it wants to be a scoped, or a unique pointer. The use of a unique_ptr members requires that the destructor be out-of-line, since the payload classes are only forward-declared in the header file. Change-Id: Id0dcdde52cb3adc30d3051d2eed1d24c76154921 Reviewed-by: Edward Welbourne --- examples/opengl/qopenglwindow/background_renderer.cpp | 11 +++++++---- examples/opengl/qopenglwindow/background_renderer.h | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/examples/opengl/qopenglwindow/background_renderer.cpp b/examples/opengl/qopenglwindow/background_renderer.cpp index 9da1b9bf99..acbbe74841 100644 --- a/examples/opengl/qopenglwindow/background_renderer.cpp +++ b/examples/opengl/qopenglwindow/background_renderer.cpp @@ -91,6 +91,9 @@ FragmentToy::FragmentToy(const QString &fragmentSource, QObject *parent) } } +FragmentToy::~FragmentToy() + = default; + void FragmentToy::draw(const QSize &windowSize) { if (!m_program) @@ -120,7 +123,7 @@ void FragmentToy::draw(const QSize &windowSize) if (!m_vertex_shader->compileSourceCode(vertex_shader)) { qWarning() << "Failed to compile the vertex shader:" << m_vertex_shader->log(); } - if (!m_program->addShader(m_vertex_shader.data())) { + if (!m_program->addShader(m_vertex_shader.get())) { qWarning() << "Failed to add vertex shader to program:" << m_program->log(); } } @@ -153,7 +156,7 @@ void FragmentToy::draw(const QSize &windowSize) } if (m_fragment_shader) { - if (!m_program->addShader(m_fragment_shader.data())) { + if (!m_program->addShader(m_fragment_shader.get())) { qWarning() << "Failed to add fragment shader to program:" << m_program->log(); } } @@ -197,14 +200,14 @@ void FragmentToy::fileChanged(const QString &path) m_fragment_file_last_modified = fragment_source.lastModified(); m_recompile_shaders = true; if (m_program) { - m_program->removeShader(m_fragment_shader.data()); + m_program->removeShader(m_fragment_shader.get()); m_fragment_shader.reset(nullptr); } } } else { m_recompile_shaders = true; if (m_program) { - m_program->removeShader(m_fragment_shader.data()); + m_program->removeShader(m_fragment_shader.get()); m_fragment_shader.reset(nullptr); } } diff --git a/examples/opengl/qopenglwindow/background_renderer.h b/examples/opengl/qopenglwindow/background_renderer.h index d99b7ddbeb..0e3caf5981 100644 --- a/examples/opengl/qopenglwindow/background_renderer.h +++ b/examples/opengl/qopenglwindow/background_renderer.h @@ -62,11 +62,14 @@ #include #include +#include + class FragmentToy : public QObject, protected QOpenGLFunctions { Q_OBJECT public: - FragmentToy(const QString &fragmentSource, QObject *parent = 0); + explicit FragmentToy(const QString &fragmentSource, QObject *parent = nullptr); + ~FragmentToy(); void draw(const QSize &windowSize); @@ -79,9 +82,9 @@ private: QString m_fragment_file; QDateTime m_fragment_file_last_modified; - QScopedPointer m_program; - QScopedPointer m_vertex_shader; - QScopedPointer m_fragment_shader; + std::unique_ptr m_program; + std::unique_ptr m_vertex_shader; + std::unique_ptr m_fragment_shader; QOpenGLVertexArrayObject m_vao; QOpenGLBuffer m_vertex_buffer; GLuint m_vertex_coord_pos; From fc2ed2361c32f6ab3f89adeb414fa8929f667476 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 23 Jul 2019 16:31:56 +0200 Subject: [PATCH 180/264] Tidy up some messy code in QLocale It was using if/else with extraneous braces, where simple ternary operators will do. It was doing a StringView content check clumsily when mid() and startsWith() suffice. Change-Id: I693f29ce5b425d53469d2c756fe27459f36470e9 Reviewed-by: Marc Mutz --- src/corelib/text/qlocale.cpp | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp index 270eac8610..5685d87c85 100644 --- a/src/corelib/text/qlocale.cpp +++ b/src/corelib/text/qlocale.cpp @@ -567,8 +567,8 @@ QString qt_readEscapedFormatString(QStringView format, int *idx) while (i < format.size()) { if (format.at(i).unicode() == '\'') { - if (i + 1 < format.size() && format.at(i + 1).unicode() == '\'') { - // "''" inside of a quoted string + if (format.mid(i + 1).startsWith(QLatin1Char('\''))) { + // "''" inside a quoted string result.append(QLatin1Char('\'')); i += 2; } else { @@ -3186,31 +3186,19 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da case 'a': used = true; - if (i + 1 < format.size() && format.at(i + 1).unicode() == 'p') { - repeat = 2; - } else { - repeat = 1; - } + repeat = format.mid(i + 1).startsWith(QLatin1Char('p')) ? 2 : 1; result.append(time.hour() < 12 ? q->amText().toLower() : q->pmText().toLower()); break; case 'A': used = true; - if (i + 1 < format.size() && format.at(i + 1).unicode() == 'P') { - repeat = 2; - } else { - repeat = 1; - } + repeat = format.mid(i + 1).startsWith(QLatin1Char('P')) ? 2 : 1; result.append(time.hour() < 12 ? q->amText().toUpper() : q->pmText().toUpper()); break; case 'z': used = true; - if (repeat >= 3) { - repeat = 3; - } else { - repeat = 1; - } + repeat = (repeat >= 3) ? 3 : 1; // note: the millisecond component is treated like the decimal part of the seconds // so ms == 2 is always printed as "002", but ms == 200 can be either "2" or "200" @@ -3229,20 +3217,16 @@ QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &da used = true; repeat = 1; // If we have a QDateTime use the time spec otherwise use the current system tzname - if (formatDate) { - result.append(datetime.timeZoneAbbreviation()); - } else { - result.append(QDateTime::currentDateTime().timeZoneAbbreviation()); - } + result.append(formatDate ? datetime.timeZoneAbbreviation() + : QDateTime::currentDateTime().timeZoneAbbreviation()); break; default: break; } } - if (!used) { + if (!used) result.append(QString(repeat, c)); - } i += repeat; } From 6bc7309135ea6fc6c5d881e988b560e09825059d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 23 Jul 2019 08:21:28 +0300 Subject: [PATCH 181/264] QResource: fix nullptr-check gone tautological Amends 136c5b9338f71775eb42528cfc7c23b2b4e5dff9. Before that change, each of the three members was a separate Q_GLOBAL_STATIC, so checking resourceList() for nullptr was the correct thing to do to find out whether the static was already destroyed. After the change, the resourceList() function will never return nullptr. Either resourceGlobalData.isDestroyed(), in which case dereferencing it asserts, or it isn't, in which case resourceList() returns a valid pointer. An explicit isDestroyed() check was added to the unregister function, but the register one was also checking resourceList() for nullptr, and this was left unprotected. Add the check and remove the now-tautological checks for nullptr resourceList(). Change-Id: I41fe66939ce858a77802b8af04c1de6e4fafe048 Reviewed-by: Edward Welbourne --- src/corelib/io/qresource.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 564a3e5f51..6c458da77a 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -852,8 +852,10 @@ bool QResourceRoot::mappingRootSubdir(const QString &path, QString *match) const Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree, const unsigned char *name, const unsigned char *data) { + if (resourceGlobalData.isDestroyed()) + return false; QMutexLocker lock(resourceMutex()); - if ((version == 0x01 || version == 0x2) && resourceList()) { + if (version == 0x01 || version == 0x2) { bool found = false; QResourceRoot res(version, tree, name, data); for(int i = 0; i < resourceList()->size(); ++i) { @@ -879,7 +881,7 @@ Q_CORE_EXPORT bool qUnregisterResourceData(int version, const unsigned char *tre return false; QMutexLocker lock(resourceMutex()); - if ((version == 0x01 || version == 0x02) && resourceList()) { + if (version == 0x01 || version == 0x02) { QResourceRoot res(version, tree, name, data); for(int i = 0; i < resourceList()->size(); ) { if(*resourceList()->at(i) == res) { From 698faf7b6de08bed2aa7e345982cedd907353e11 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Sat, 6 Jul 2019 12:30:00 +0300 Subject: [PATCH 182/264] Android: Fix SSL 1.1 support on API-21 OpenSSL 1.1.x libs must be suffixed otherwise it will use the system ones which on API-21 are OpenSSL 1.0 not 1.1 Fixes: QTBUG-76884 Change-Id: I7d4052be68cf7dc65f74a48da8e1e37182056a5e Reviewed-by: Volker Hilsheimer --- src/network/ssl/qsslsocket_openssl_symbols.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 483a2cbad0..c303e266ba 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -891,8 +891,25 @@ static QPair loadOpenSsl() // macOS's /usr/lib/libssl.dylib, /usr/lib/libcrypto.dylib will be picked up in the third // attempt, _after_ /Contents/Frameworks has been searched. // iOS does not ship a system libssl.dylib, libcrypto.dylib in the first place. +# if defined(Q_OS_ANDROID) + // OpenSSL 1.1.x must be suffixed otherwise it will use the system libcrypto.so libssl.so which on API-21 are OpenSSL 1.0 not 1.1 + auto openSSLSuffix = [](const QByteArray &defaultSuffix = {}) { + auto suffix = qgetenv("ANDROID_OPENSSL_SUFFIX"); + if (suffix.isEmpty()) + return defaultSuffix; + return suffix; + }; +# if QT_CONFIG(opensslv11) + static QString suffix = QString::fromLatin1(openSSLSuffix("_1_1")); +# else + static QString suffix = QString::fromLatin1(openSSLSuffix()); +# endif + libssl->setFileNameAndVersion(QLatin1String("ssl") + suffix, -1); + libcrypto->setFileNameAndVersion(QLatin1String("crypto") + suffix, -1); +# else libssl->setFileNameAndVersion(QLatin1String("ssl"), -1); libcrypto->setFileNameAndVersion(QLatin1String("crypto"), -1); +# endif if (libcrypto->load() && libssl->load()) { // libssl.so.0 and libcrypto.so.0 found return pair; From a2fa624c793e0c571ac2f56d6a4786060d70bc47 Mon Sep 17 00:00:00 2001 From: Dominik Holland Date: Wed, 24 Jul 2019 14:22:46 +0200 Subject: [PATCH 183/264] Revert "eglfs: Add vsync support when using NVIDIA eglstreams" This reverts commit df2b76046de4af7a47fa8303d5f261e3c5d120fe. The patches causes high cpu load and it looks like vsync is done by newer NVIDIA drivers out of the box without such a implementation. Change-Id: I41c9cfcf1bbdf7da9b764394e4442768084e9a35 Fixes: QTBUG-74866 Reviewed-by: Laszlo Agocs --- .../eglconvenience/qeglstreamconvenience_p.h | 11 ---- .../qeglfskmsegldeviceintegration.cpp | 50 ------------------- .../qeglfskmsegldeviceintegration.h | 2 - 3 files changed, 63 deletions(-) diff --git a/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h index 31a79dbc6c..c3d3070210 100644 --- a/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h +++ b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h @@ -131,12 +131,6 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer); #endif -#ifndef EGL_EXT_stream_acquire_mode -#define EGL_EXT_stream_acquire_mode 1 -#define EGL_CONSUMER_AUTO_ACQUIRE_EXT 0x332B -#define EGL_RESOURCE_BUSY_EXT 0x3353 -#endif - #ifndef EGL_EXT_platform_device #define EGL_PLATFORM_DEVICE_EXT 0x313F #endif @@ -162,11 +156,6 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREATTRIBNVPROC) (EGLDi typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEATTRIBNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); #endif -#ifndef EGL_NV_output_drm_flip_event -#define EGL_NV_output_drm_flip_event 1 -#define EGL_DRM_FLIP_EVENT_DATA_NV 0x333E -#endif - QT_BEGIN_NAMESPACE class QEGLStreamConvenience diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp index 2c6b4245b7..3e78196227 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp @@ -114,20 +114,16 @@ public: : QEglFSWindow(w) , m_integration(integration) , m_egl_stream(EGL_NO_STREAM_KHR) - , m_framePending(false) { } ~QEglFSKmsEglDeviceWindow() { destroy(); } void invalidateSurface() override; void resetSurface() override; - void flip(); - static void pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data); const QEglFSKmsEglDeviceIntegration *m_integration; EGLStreamKHR m_egl_stream; EGLint m_latency; - bool m_framePending; }; void QEglFSKmsEglDeviceWindow::invalidateSurface() @@ -148,9 +144,6 @@ void QEglFSKmsEglDeviceWindow::resetSurface() streamAttribs[streamAttribCount++] = EGL_STREAM_FIFO_LENGTH_KHR; streamAttribs[streamAttribCount++] = fifoLength; } - - streamAttribs[streamAttribCount++] = EGL_CONSUMER_AUTO_ACQUIRE_EXT; - streamAttribs[streamAttribCount++] = EGL_FALSE; streamAttribs[streamAttribCount++] = EGL_NONE; m_egl_stream = m_integration->m_funcs->create_stream(display, streamAttribs); @@ -248,49 +241,6 @@ void QEglFSKmsEglDeviceWindow::resetSurface() qCDebug(qLcEglfsKmsDebug, "Created stream producer surface %p", m_surface); } -void QEglFSKmsEglDeviceWindow::flip() -{ - EGLDisplay display = screen()->display(); - - EGLAttrib acquire_attribs[3] = { EGL_NONE }; - - acquire_attribs[0] = EGL_DRM_FLIP_EVENT_DATA_NV; - acquire_attribs[1] = (EGLAttrib)this; - acquire_attribs[2] = EGL_NONE; - - if (m_egl_stream != EGL_NO_STREAM_KHR) - if (!m_integration->m_funcs->acquire_stream_attrib_nv(display, m_egl_stream, acquire_attribs)) - qWarning("eglStreamConsumerAcquireAttribNV failed: eglError: %x", eglGetError()); - - m_framePending = true; - - while (m_framePending) { - drmEventContext drmEvent; - memset(&drmEvent, 0, sizeof(drmEvent)); - drmEvent.version = 3; - drmEvent.vblank_handler = nullptr; - drmEvent.page_flip_handler = pageFlipHandler; - drmHandleEvent(m_integration->m_device->fd(), &drmEvent); - } -} - -void QEglFSKmsEglDeviceWindow::pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) -{ - Q_UNUSED(fd); - Q_UNUSED(sequence); - Q_UNUSED(tv_sec); - Q_UNUSED(tv_usec); - - QEglFSKmsEglDeviceWindow *window = static_cast(user_data); - window->m_framePending = false; -} - -void QEglFSKmsEglDeviceIntegration::presentBuffer(QPlatformSurface *surface) -{ - QEglFSKmsEglDeviceWindow *eglWindow = static_cast(surface); - eglWindow->flip(); -} - QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const { QEglFSKmsEglDeviceWindow *eglWindow = new QEglFSKmsEglDeviceWindow(window, this); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h index a5697ec831..5819d82ebf 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h @@ -62,8 +62,6 @@ public: bool supportsPBuffers() const override; QEglFSWindow *createWindow(QWindow *window) const override; - void presentBuffer(QPlatformSurface *surface) override; - EGLDeviceEXT eglDevice() const { return m_egl_device; } protected: From 84a58e514b080236cb117104fad4b3374115975d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 9 Jul 2019 10:15:41 +0200 Subject: [PATCH 184/264] QFileSystemModel: Brush up the test - Use nullptr - Instantiate test helpers on the stack or use QScopedPointer - Remove C-style casts of enumerations/flags, use meta types - Port to Qt 5 connection syntax - Fix static method invocation - Use initializer lists for QStringList - Introduce a logging category for all debug output - Streamline code - Refactor cleanup() to operate on QFileInfoList which is faster and streamline - Remove unused variables Task-number: QTBUG-76493 Change-Id: I3a033af7c9ec4dac3149d2016104daad07797a4f Reviewed-by: Edward Welbourne Reviewed-by: Frederik Gladhorn --- .../qfilesystemmodel/tst_qfilesystemmodel.cpp | 291 +++++++++--------- 1 file changed, 148 insertions(+), 143 deletions(-) diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp index 665a116a3a..9b6b159e5b 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -65,6 +65,11 @@ } \ } while(0) +Q_DECLARE_METATYPE(QDir::Filters) +Q_DECLARE_METATYPE(QFileDevice::Permissions) + +Q_LOGGING_CATEGORY(lcFileSystemModel, "qt.widgets.tests.qfilesystemmodel") + class tst_QFileSystemModel : public QObject { Q_OBJECT @@ -128,7 +133,7 @@ private slots: void fileInfo(); protected: - bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &intial_dirs = QStringList()); + bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &initial_dirs = QStringList()); QModelIndex prepareTestModelRoot(const QString &test_path, QSignalSpy **spy2 = nullptr, QSignalSpy **spy3 = nullptr); @@ -153,23 +158,20 @@ void tst_QFileSystemModel::cleanup() { delete model; model = 0; - QString tmp = flatDirTestPath; - QDir dir(tmp); - if (dir.exists(tmp)) { - QStringList list = dir.entryList(QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot); - for (int i = 0; i < list.count(); ++i) { - QFileInfo fi(dir.path() + '/' + list.at(i)); - if (fi.exists() && fi.isFile()) { - QFile p(fi.absoluteFilePath()); - p.setPermissions(QFile::ReadUser | QFile::ReadOwner | QFile::ExeOwner | QFile::ExeUser | QFile::WriteUser | QFile::WriteOwner | QFile::WriteOther); - QFile dead(dir.path() + '/' + list.at(i)); - dead.remove(); + QDir dir(flatDirTestPath); + if (dir.exists()) { + const QDir::Filters filters = QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot; + const QFileInfoList list = dir.entryInfoList(filters); + for (const QFileInfo &fi : list) { + if (fi.isDir()) { + QVERIFY(dir.rmdir(fi.fileName())); + } else { + QFile dead(fi.absoluteFilePath()); + dead.setPermissions(QFile::ReadUser | QFile::ReadOwner | QFile::ExeOwner | QFile::ExeUser | QFile::WriteUser | QFile::WriteOwner | QFile::WriteOther); + QVERIFY(dead.remove()); } - if (fi.exists() && fi.isDir()) - QVERIFY(dir.rmdir(list.at(i))); } - list = dir.entryList(QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot); - QCOMPARE(list.count(), 0); + QVERIFY(dir.entryInfoList(filters).isEmpty()); } } @@ -197,7 +199,7 @@ void tst_QFileSystemModel::rootPath() { QCOMPARE(model->rootPath(), QString(QDir().path())); - QSignalSpy rootChanged(model, SIGNAL(rootPathChanged(QString))); + QSignalSpy rootChanged(model, &QFileSystemModel::rootPathChanged); QModelIndex root = model->setRootPath(model->rootPath()); root = model->setRootPath("this directory shouldn't exist"); QCOMPARE(rootChanged.count(), 0); @@ -263,19 +265,21 @@ void tst_QFileSystemModel::readOnly() class CustomFileIconProvider : public QFileIconProvider { public: - CustomFileIconProvider() : QFileIconProvider() { - mb = qApp->style()->standardIcon(QStyle::SP_MessageBoxCritical); - dvd = qApp->style()->standardIcon(QStyle::SP_DriveDVDIcon); + CustomFileIconProvider() : QFileIconProvider() + { + auto style = QApplication::style(); + mb = style->standardIcon(QStyle::SP_MessageBoxCritical); + dvd = style->standardIcon(QStyle::SP_DriveDVDIcon); } - virtual QIcon icon(const QFileInfo &info) const + QIcon icon(const QFileInfo &info) const override { if (info.isDir()) return mb; return QFileIconProvider::icon(info); } - virtual QIcon icon(IconType type) const + QIcon icon(IconType type) const override { if (type == QFileIconProvider::Folder) return dvd; @@ -290,68 +294,63 @@ private: void tst_QFileSystemModel::iconProvider() { QVERIFY(model->iconProvider()); - QFileIconProvider *p = new QFileIconProvider(); - model->setIconProvider(p); - QCOMPARE(model->iconProvider(), p); - model->setIconProvider(0); - delete p; + QScopedPointer provider(new QFileIconProvider); + model->setIconProvider(provider.data()); + QCOMPARE(model->iconProvider(), provider.data()); + model->setIconProvider(nullptr); + provider.reset(); - QFileSystemModel *myModel = new QFileSystemModel(); + QScopedPointer myModel(new QFileSystemModel); const QStringList documentPaths = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation); QVERIFY(!documentPaths.isEmpty()); - const QString documentPath = documentPaths.front(); - myModel->setRootPath(documentPath); + myModel->setRootPath(documentPaths.constFirst()); //We change the provider, icons must be updated - CustomFileIconProvider *custom = new CustomFileIconProvider(); - myModel->setIconProvider(custom); + provider.reset(new CustomFileIconProvider); + myModel->setIconProvider(provider.data()); - QPixmap mb = qApp->style()->standardIcon(QStyle::SP_MessageBoxCritical).pixmap(50, 50); + QPixmap mb = QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical).pixmap(50, 50); QCOMPARE(myModel->fileIcon(myModel->index(QDir::homePath())).pixmap(50, 50), mb); - delete myModel; - delete custom; } bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount, const QStringList &initial_dirs) { - //qDebug() << (model->rowCount(model->index(test_path))) << existingFileCount << initial_files; + qCDebug(lcFileSystemModel) << (model->rowCount(model->index(test_path))) << existingFileCount << initial_files; bool timedOut = false; TRY_WAIT((model->rowCount(model->index(test_path)) == existingFileCount), &timedOut); if (timedOut) return false; - for (int i = 0; i < initial_dirs.count(); ++i) { - QDir dir(test_path); - if (!dir.exists()) { - qWarning() << "error" << test_path << "doesn't exists"; - return false; - } - if(!dir.mkdir(initial_dirs.at(i))) { - qWarning() << "error" << "failed to make" << initial_dirs.at(i); - return false; - } - //qDebug() << test_path + '/' + initial_dirs.at(i) << (QFile::exists(test_path + '/' + initial_dirs.at(i))); + QDir dir(test_path); + if (!dir.exists()) { + qWarning() << "error" << test_path << "doesn't exist"; + return false; } - for (int i = 0; i < initial_files.count(); ++i) { - QFile file(test_path + '/' + initial_files.at(i)); + for (const auto &initial_dir : initial_dirs) { + if (!dir.mkdir(initial_dir)) { + qWarning() << "error" << "failed to make" << initial_dir; + return false; + } + qCDebug(lcFileSystemModel) << test_path + '/' + initial_dir << (QFile::exists(test_path + '/' + initial_dir)); + } + for (const auto &initial_file : initial_files) { + QFile file(test_path + '/' + initial_file); if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) { - qDebug() << "failed to open file" << initial_files.at(i); + qDebug() << "failed to open file" << initial_file; return false; } if (!file.resize(1024 + file.size())) { - qDebug() << "failed to resize file" << initial_files.at(i); + qDebug() << "failed to resize file" << initial_file; return false; } if (!file.flush()) { - qDebug() << "failed to flush file" << initial_files.at(i); + qDebug() << "failed to flush file" << initial_file; return false; } file.close(); #if defined(Q_OS_WIN) - if (initial_files.at(i)[0] == '.') { - QString hiddenFile = QDir::toNativeSeparators(file.fileName()); - wchar_t nativeHiddenFile[MAX_PATH]; - memset(nativeHiddenFile, 0, sizeof(nativeHiddenFile)); - hiddenFile.toWCharArray(nativeHiddenFile); + if (initial_file[0] == '.') { + const QString hiddenFile = QDir::toNativeSeparators(file.fileName()); + const auto nativeHiddenFile = reinterpret_cast(hiddenFile.utf16()); #ifndef Q_OS_WINRT DWORD currentAttributes = ::GetFileAttributes(nativeHiddenFile); #else // !Q_OS_WINRT @@ -370,7 +369,7 @@ bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringLi } } #endif - //qDebug() << test_path + '/' + initial_files.at(i) << (QFile::exists(test_path + '/' + initial_files.at(i))); + qCDebug(lcFileSystemModel) << test_path + '/' + initial_file << (QFile::exists(test_path + '/' + initial_file)); } return true; } @@ -387,7 +386,6 @@ QModelIndex tst_QFileSystemModel::prepareTestModelRoot(const QString &test_path, *spy3 = new QSignalSpy(model, &QFileSystemModel::rowsAboutToBeInserted); QStringList files = { "b", "d", "f", "h", "j", ".a", ".c", ".e", ".g" }; - QString l = "b,d,f,h,j,.a,.c,.e,.g"; if (!createFiles(test_path, files)) return QModelIndex(); @@ -406,7 +404,6 @@ QModelIndex tst_QFileSystemModel::prepareTestModelRoot(const QString &test_path, void tst_QFileSystemModel::rowCount() { - const QString tmp = flatDirTestPath; QSignalSpy *spy2 = nullptr; QSignalSpy *spy3 = nullptr; QModelIndex root = prepareTestModelRoot(flatDirTestPath, &spy2, &spy3); @@ -419,11 +416,11 @@ void tst_QFileSystemModel::rowCount() void tst_QFileSystemModel::rowsInserted_data() { QTest::addColumn("count"); - QTest::addColumn("ascending"); + QTest::addColumn("ascending"); for (int i = 0; i < 4; ++i) { const QByteArray iB = QByteArray::number(i); - QTest::newRow(("Qt::AscendingOrder " + iB).constData()) << i << (int)Qt::AscendingOrder; - QTest::newRow(("Qt::DescendingOrder " + iB).constData()) << i << (int)Qt::DescendingOrder; + QTest::newRow(("Qt::AscendingOrder " + iB).constData()) << i << Qt::AscendingOrder; + QTest::newRow(("Qt::DescendingOrder " + iB).constData()) << i << Qt::DescendingOrder; } } @@ -439,12 +436,12 @@ void tst_QFileSystemModel::rowsInserted() QModelIndex root = prepareTestModelRoot(tmp); QVERIFY(root.isValid()); - QFETCH(int, ascending); + QFETCH(Qt::SortOrder, ascending); QFETCH(int, count); - model->sort(0, (Qt::SortOrder)ascending); + model->sort(0, ascending); - QSignalSpy spy0(model, SIGNAL(rowsInserted(QModelIndex,int,int))); - QSignalSpy spy1(model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int))); + QSignalSpy spy0(model, &QAbstractItemModel::rowsInserted); + QSignalSpy spy1(model, &QAbstractItemModel::rowsAboutToBeInserted); int oldCount = model->rowCount(root); QStringList files; for (int i = 0; i < count; ++i) @@ -493,15 +490,16 @@ void tst_QFileSystemModel::rowsRemoved() QVERIFY(root.isValid()); QFETCH(int, count); - QFETCH(int, ascending); - model->sort(0, (Qt::SortOrder)ascending); + QFETCH(Qt::SortOrder, ascending); + model->sort(0, ascending); - QSignalSpy spy0(model, SIGNAL(rowsRemoved(QModelIndex,int,int))); - QSignalSpy spy1(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int))); + QSignalSpy spy0(model, &QAbstractItemModel::rowsRemoved); + QSignalSpy spy1(model, &QAbstractItemModel::rowsAboutToBeRemoved); int oldCount = model->rowCount(root); for (int i = count - 1; i >= 0; --i) { - //qDebug() << "removing" << model->index(i, 0, root).data().toString(); - QVERIFY(QFile::remove(tmp + '/' + model->index(i, 0, root).data().toString())); + const QString fileName = model->index(i, 0, root).data().toString(); + qCDebug(lcFileSystemModel) << "removing" << fileName; + QVERIFY(QFile::remove(tmp + QLatin1Char('/') + fileName)); } for (int i = 0 ; i < 10; ++i) { if (count != 0) { @@ -520,18 +518,23 @@ void tst_QFileSystemModel::rowsRemoved() lst.append(model->index(i, 0, root).data().toString()); if (model->rowCount(root) == oldCount - count) break; - qDebug() << "still have:" << lst << QFile::exists(tmp + '/' + QString(".a")); + qCDebug(lcFileSystemModel) << "still have:" << lst << QFile::exists(tmp + QLatin1String("/.a")); QDir tmpLister(tmp); - qDebug() << tmpLister.entryList(); + qCDebug(lcFileSystemModel) << tmpLister.entryList(); } QTRY_COMPARE(model->rowCount(root), oldCount - count); - QVERIFY(QFile::exists(tmp + '/' + QString(".a"))); - QVERIFY(QFile::remove(tmp + '/' + QString(".a"))); - QVERIFY(QFile::remove(tmp + '/' + QString(".c"))); + QVERIFY(QFile::exists(tmp + QLatin1String("/.a"))); + QVERIFY(QFile::remove(tmp + QLatin1String("/.a"))); + QVERIFY(QFile::remove(tmp + QLatin1String("/.c"))); - if (count != 0) QVERIFY(spy0.count() >= 1); else QCOMPARE(spy0.count(), 0); - if (count != 0) QVERIFY(spy1.count() >= 1); else QCOMPARE(spy1.count(), 0); + if (count != 0) { + QVERIFY(spy0.count() >= 1); + QVERIFY(spy1.count() >= 1); + } else { + QCOMPARE(spy0.count(), 0); + QCOMPARE(spy1.count(), 0); + } } void tst_QFileSystemModel::dataChanged_data() @@ -548,10 +551,10 @@ void tst_QFileSystemModel::dataChanged() QVERIFY(root.isValid()); QFETCH(int, count); - QFETCH(int, assending); - model->sort(0, (Qt::SortOrder)assending); + QFETCH(Qt::SortOrder, ascending); + model->sort(0, ascending); - QSignalSpy spy(model, SIGNAL(dataChanged(QModelIndex,QModelIndex))); + QSignalSpy spy(model, &QAbstractItemModel::dataChanged); QStringList files; for (int i = 0; i < count; ++i) files.append(model->index(i, 0, root).data().toString()); @@ -566,34 +569,38 @@ void tst_QFileSystemModel::filters_data() { QTest::addColumn("files"); QTest::addColumn("dirs"); - QTest::addColumn("dirFilters"); + QTest::addColumn("dirFilters"); QTest::addColumn("nameFilters"); QTest::addColumn("rowCount"); - QTest::newRow("no dirs") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs) << QStringList() << 2; - QTest::newRow("no dirs - dot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 1; - QTest::newRow("no dirs - dotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 1; - QTest::newRow("no dirs - dotanddotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 0; - QTest::newRow("one dir - dot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 2; - QTest::newRow("one dir - dotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 2; - QTest::newRow("one dir - dotanddotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 1; - QTest::newRow("one dir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs) << QStringList() << 3; - QTest::newRow("no dir + hidden") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::Hidden) << QStringList() << 2; - QTest::newRow("dir+hid+files") << (QStringList() << "a" << "b" << "c") << QStringList() << - (int)(QDir::Dirs | QDir::Files | QDir::Hidden) << QStringList() << 5; - QTest::newRow("dir+file+hid-dot .A") << (QStringList() << "a" << "b" << "c") << (QStringList() << ".A") << - (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot) << QStringList() << 4; - QTest::newRow("dir+files+hid+dot A") << (QStringList() << "a" << "b" << "c") << (QStringList() << "AFolder") << - (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot) << (QStringList() << "A*") << 2; - QTest::newRow("dir+files+hid+dot+cas1") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << - (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive) << (QStringList() << "Z") << 1; - QTest::newRow("dir+files+hid+dot+cas2") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << - (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive) << (QStringList() << "a") << 1; - QTest::newRow("dir+files+hid+dot+cas+alldir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << - (int)(QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive | QDir::AllDirs) << (QStringList() << "Z") << 1; - QTest::newRow("case sensitive") << (QStringList() << "Antiguagdb" << "Antiguamtd" - << "Antiguamtp" << "afghanistangdb" << "afghanistanmtd") - << QStringList() << (int)(QDir::Files) << QStringList() << 5; + const QStringList abcList{QLatin1String("a"), QLatin1String("b"), QLatin1String("c")}; + const QStringList zList{QLatin1String("Z")}; + + QTest::newRow("no dirs") << abcList << QStringList() << QDir::Filters(QDir::Dirs) << QStringList() << 2; + QTest::newRow("no dirs - dot") << abcList << QStringList() << (QDir::Dirs | QDir::NoDot) << QStringList() << 1; + QTest::newRow("no dirs - dotdot") << abcList << QStringList() << (QDir::Dirs | QDir::NoDotDot) << QStringList() << 1; + QTest::newRow("no dirs - dotanddotdot") << abcList << QStringList() << (QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 0; + QTest::newRow("one dir - dot") << abcList << zList << (QDir::Dirs | QDir::NoDot) << QStringList() << 2; + QTest::newRow("one dir - dotdot") << abcList << zList << (QDir::Dirs | QDir::NoDotDot) << QStringList() << 2; + QTest::newRow("one dir - dotanddotdot") << abcList << zList << (QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 1; + QTest::newRow("one dir") << abcList << zList << QDir::Filters(QDir::Dirs) << QStringList() << 3; + QTest::newRow("no dir + hidden") << abcList << QStringList() << (QDir::Dirs | QDir::Hidden) << QStringList() << 2; + QTest::newRow("dir+hid+files") << abcList << QStringList() << + (QDir::Dirs | QDir::Files | QDir::Hidden) << QStringList() << 5; + QTest::newRow("dir+file+hid-dot .A") << abcList << QStringList{QLatin1String(".A")} << + (QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot) << QStringList() << 4; + QTest::newRow("dir+files+hid+dot A") << abcList << QStringList{QLatin1String("AFolder")} << + (QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot) << QStringList{QLatin1String("A*")} << 2; + QTest::newRow("dir+files+hid+dot+cas1") << abcList << zList << + (QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive) << zList << 1; + QTest::newRow("dir+files+hid+dot+cas2") << abcList << zList << + (QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive) << QStringList{QLatin1String("a")} << 1; + QTest::newRow("dir+files+hid+dot+cas+alldir") << abcList << zList << + (QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot | QDir::CaseSensitive | QDir::AllDirs) << zList << 1; + + QTest::newRow("case sensitive") << QStringList{QLatin1String("Antiguagdb"), QLatin1String("Antiguamtd"), + QLatin1String("Antiguamtp"), QLatin1String("afghanistangdb"), QLatin1String("afghanistanmtd")} + << QStringList() << QDir::Filters(QDir::Files) << QStringList() << 5; } void tst_QFileSystemModel::filters() @@ -603,27 +610,26 @@ void tst_QFileSystemModel::filters() QModelIndex root = model->setRootPath(tmp); QFETCH(QStringList, files); QFETCH(QStringList, dirs); - QFETCH(int, dirFilters); + QFETCH(QDir::Filters, dirFilters); QFETCH(QStringList, nameFilters); QFETCH(int, rowCount); if (nameFilters.count() > 0) model->setNameFilters(nameFilters); model->setNameFilterDisables(false); - model->setFilter((QDir::Filters)dirFilters); + model->setFilter(dirFilters); QVERIFY(createFiles(tmp, files, 0, dirs)); QTRY_COMPARE(model->rowCount(root), rowCount); // Make sure that we do what QDir does QDir xFactor(tmp); - QDir::Filters filters = (QDir::Filters)dirFilters; QStringList dirEntries; if (nameFilters.count() > 0) - dirEntries = xFactor.entryList(nameFilters, filters); + dirEntries = xFactor.entryList(nameFilters, dirFilters); else - dirEntries = xFactor.entryList(filters); + dirEntries = xFactor.entryList(dirFilters); QCOMPARE(dirEntries.count(), rowCount); @@ -693,15 +699,17 @@ void tst_QFileSystemModel::setData_data() << QDir::temp().absolutePath() + '/' + "a" << false; */ + + const QStringList abcList{QLatin1String("a"), QLatin1String("b"), QLatin1String("c")}; QTest::newRow("in current dir") << QString() - << (QStringList() << "a" << "b" << "c") + << abcList << "a" << "d" << true; QTest::newRow("in subdir") << "s" - << (QStringList() << "a" << "b" << "c") + << abcList << "a" << "d" << true; @@ -709,7 +717,7 @@ void tst_QFileSystemModel::setData_data() void tst_QFileSystemModel::setData() { - QSignalSpy spy(model, SIGNAL(fileRenamed(QString,QString,QString))); + QSignalSpy spy(model, &QFileSystemModel::fileRenamed); QFETCH(QString, subdirName); QFETCH(QStringList, files); QFETCH(QString, oldFileName); @@ -786,8 +794,9 @@ void tst_QFileSystemModel::sort() { QFETCH(bool, fileDialogMode); - MyFriendFileSystemModel *myModel = new MyFriendFileSystemModel(); - QTreeView *tree = new QTreeView(); + QScopedPointer myModel(new MyFriendFileSystemModel); + QTreeView tree; + tree.setWindowTitle(QTest::currentTestFunction()); if (fileDialogMode && EmulationDetector::isRunningArmOnX86()) QSKIP("Crashes in QEMU. QTBUG-70572"); @@ -816,24 +825,23 @@ void tst_QFileSystemModel::sort() myModel->setRootPath(""); myModel->setFilter(QDir::AllEntries | QDir::System | QDir::Hidden); - tree->setSortingEnabled(true); - tree->setModel(myModel); - tree->show(); - tree->resize(800, 800); - QVERIFY(QTest::qWaitForWindowActive(tree)); - tree->header()->setSortIndicator(1,Qt::DescendingOrder); - tree->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); + tree.setSortingEnabled(true); + tree.setModel(myModel.data()); + tree.show(); + tree.resize(800, 800); + QVERIFY(QTest::qWaitForWindowActive(&tree)); + tree.header()->setSortIndicator(1, Qt::DescendingOrder); + tree.header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); QStringList dirsToOpen; - do - { - dirsToOpen< 0 ; --i) { QString path = dirsToOpen[i]; - tree->expand(myModel->index(path, 0)); + tree.expand(myModel->index(path, 0)); } - tree->expand(myModel->index(dirPath, 0)); + tree.expand(myModel->index(dirPath, 0)); QModelIndex parent = myModel->index(dirPath, 0); QList expectedOrder; expectedOrder << tempFile2.fileName() << tempFile.fileName() << dirPath + QChar('/') + ".." << dirPath + QChar('/') + "."; @@ -859,9 +867,6 @@ void tst_QFileSystemModel::sort() QTRY_COMPARE(dirPath + QChar('/') + myModel->index(i, 1, parent).data(QFileSystemModel::FileNameRole).toString(), expectedOrder.at(i)); } } - - delete tree; - delete myModel; } void tst_QFileSystemModel::mkdir() @@ -1013,10 +1018,10 @@ void tst_QFileSystemModel::dirsBeforeFiles() const int itemCount = 3; for (int i = 0; i < itemCount; ++i) { - QLatin1Char c('a' + i); - dir.mkdir(c + QLatin1String("-dir")); + QLatin1Char c('a' + char(i)); + QVERIFY(dir.mkdir(c + QLatin1String("-dir"))); QFile file(flatDirTestPath + QLatin1Char('/') + c + QLatin1String("-file")); - file.open(QIODevice::ReadWrite); + QVERIFY(file.open(QIODevice::ReadWrite)); file.close(); } @@ -1073,7 +1078,7 @@ static inline QByteArray permissionRowName(bool readOnly, int permission) void tst_QFileSystemModel::permissions_data() { - QTest::addColumn("permissions"); + QTest::addColumn("permissions"); QTest::addColumn("readOnly"); static const int permissions[] = { @@ -1081,22 +1086,22 @@ void tst_QFileSystemModel::permissions_data() QFile::ReadOwner, QFile::WriteOwner|QFile::ReadOwner, }; - for (size_t i = 0; i < sizeof permissions / sizeof *permissions; ++i) { - QTest::newRow(permissionRowName(false, permissions[i]).constData()) << permissions[i] << false; - QTest::newRow(permissionRowName(true, permissions[i]).constData()) << permissions[i] << true; + for (int permission : permissions) { + QTest::newRow(permissionRowName(false, permission).constData()) << QFileDevice::Permissions(permission) << false; + QTest::newRow(permissionRowName(true, permission).constData()) << QFileDevice::Permissions(permission) << true; } } void tst_QFileSystemModel::permissions() // checks QTBUG-20503 { - QFETCH(int, permissions); + QFETCH(QFileDevice::Permissions, permissions); QFETCH(bool, readOnly); const QString tmp = flatDirTestPath; const QString file = tmp + QLatin1String("/f"); - QVERIFY(createFiles(tmp, QStringList() << "f")); + QVERIFY(createFiles(tmp, QStringList{QLatin1String("f")})); - QVERIFY(QFile::setPermissions(file, QFile::Permissions(permissions))); + QVERIFY(QFile::setPermissions(file, permissions)); const QModelIndex root = model->setRootPath(tmp); From 5b3c09e35f71b5d848ee7554517d95deb9b577c7 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 26 Jul 2019 09:30:01 +0200 Subject: [PATCH 185/264] QMacStyle - another slider fix As a follow-up to fixed resize handling: the trick Gabriel wanted to use to enforce a specific look on a slider's bar, never actually worked due to misplaced statement which essentially is cancelling the 'magic' before the bar is drawn. Now it's fixed: bar is centered (between the rows of tickmarks above and below) + it's had a nice blue filling back! Change-Id: I3021c2b86e4c25981eeee015e32baa24ccebc3bd Reviewed-by: Volker Hilsheimer --- src/plugins/styles/mac/qmacstyle_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 1d88d2c647..1ff1c22788 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -5362,10 +5362,10 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex const CGRect barRect = [cell barRectFlipped:hasTicks]; if (drawBar) { + [cell drawBarInside:barRect flipped:!verticalFlip]; // This ain't HIG kosher: force unfilled bar look. if (hasDoubleTicks) slider.numberOfTickMarks = numberOfTickMarks; - [cell drawBarInside:barRect flipped:!verticalFlip]; } if (hasTicks && drawTicks) { From e6498362fde937259295e9b2ddbe9b59136f47ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Thu, 25 Jul 2019 16:06:02 +0200 Subject: [PATCH 186/264] macOS: Respect color space set on NSWindow when flushing backingstore By default Qt tries to avoid potentially costly color matching by not assigning an sRGB color space to our backingstore, even if that's what we in practice fill it with. We used to do this by assigning the display's color space, which effectively opts out of color matching, similar to the old behavior of the device RGB color space (which nowadays implies sRGB). By picking up the color space from the NSWindow instead, we allow the user to override the color space to trigger color matching, for example by explicitly setting it to NSColorSpace.sRGBColorSpace. NSWindow will fall back to the screen's color space if the window doesn't have one set. Task-number: QTBUG-47660 Change-Id: Iac8177e85e86fe9044a41eb2c93fbf26bb83c248 Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Timur Pocheptsov Reviewed-by: Simon Hausmann --- .../platforms/cocoa/qcocoabackingstore.h | 11 +++++-- .../platforms/cocoa/qcocoabackingstore.mm | 30 ++++++++++++------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h index 2398e6351e..9be6814ae7 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.h +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h @@ -49,7 +49,14 @@ QT_BEGIN_NAMESPACE -class QNSWindowBackingStore : public QRasterBackingStore +class QCocoaBackingStore : public QRasterBackingStore +{ +protected: + QCocoaBackingStore(QWindow *window); + QCFType colorSpace() const; +}; + +class QNSWindowBackingStore : public QCocoaBackingStore { public: QNSWindowBackingStore(QWindow *window); @@ -64,7 +71,7 @@ private: void redrawRoundedBottomCorners(CGRect) const; }; -class QCALayerBackingStore : public QPlatformBackingStore +class QCALayerBackingStore : public QCocoaBackingStore { public: QCALayerBackingStore(QWindow *window); diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index 78aa98094c..af50aabe15 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -48,11 +48,24 @@ QT_BEGIN_NAMESPACE -QNSWindowBackingStore::QNSWindowBackingStore(QWindow *window) +QCocoaBackingStore::QCocoaBackingStore(QWindow *window) : QRasterBackingStore(window) { } +QCFType QCocoaBackingStore::colorSpace() const +{ + NSView *view = static_cast(window()->handle())->view(); + return QCFType::constructFromGet(view.window.colorSpace.CGColorSpace); +} + +// ---------------------------------------------------------------------------- + +QNSWindowBackingStore::QNSWindowBackingStore(QWindow *window) + : QCocoaBackingStore(window) +{ +} + QNSWindowBackingStore::~QNSWindowBackingStore() { } @@ -175,11 +188,10 @@ void QNSWindowBackingStore::flush(QWindow *window, const QRegion ®ion, const Q_ASSERT_X(graphicsContext, "QCocoaBackingStore", "Focusing the view should give us a current graphics context"); - // Prevent potentially costly color conversion by assigning the display color space - // to the backingstore image. This does not copy the underlying image data. - CGColorSpaceRef displayColorSpace = view.window.screen.colorSpace.CGColorSpace; + // Tag backingstore image with color space based on the window. + // Note: This does not copy the underlying image data. QCFType cgImage = CGImageCreateCopyWithColorSpace( - QCFType(m_image.toCGImage()), displayColorSpace); + QCFType(m_image.toCGImage()), colorSpace()); // Create temporary image to use for blitting, without copying image data NSImage *backingStoreImage = [[[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize] autorelease]; @@ -305,7 +317,7 @@ template constexpr backwards_t backwards(R&& r) { return {std::forward(r)}; } QCALayerBackingStore::QCALayerBackingStore(QWindow *window) - : QPlatformBackingStore(window) + : QCocoaBackingStore(window) { qCDebug(lcQpaBackingStore) << "Creating QCALayerBackingStore for" << window; m_buffers.resize(1); @@ -444,11 +456,7 @@ bool QCALayerBackingStore::recreateBackBufferIfNeeded() << "based on requested" << m_requestedSize << "and dpr =" << devicePixelRatio; static auto pixelFormat = QImage::toPixelFormat(QImage::Format_ARGB32_Premultiplied); - - NSView *view = static_cast(window()->handle())->view(); - auto colorSpace = QCFType::constructFromGet(view.window.screen.colorSpace.CGColorSpace); - - m_buffers.back().reset(new GraphicsBuffer(requestedBufferSize, devicePixelRatio, pixelFormat, colorSpace)); + m_buffers.back().reset(new GraphicsBuffer(requestedBufferSize, devicePixelRatio, pixelFormat, colorSpace())); return true; } From e24a4976bebd7ca90deac2b40c08900625773a99 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 24 Jul 2019 15:05:23 +0200 Subject: [PATCH 187/264] QHostInfo: Always post results through the event loop to the receiver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lookups performed via QHostInfoRunnable must not synchronously call the user-code's receiver objects, as that would execute user-code in the wrong thread. Instead, post a metacall event through the event loop of the receiver object, or the thread that initiated the lookup. This was done correctly for the trivial cases of empty host name or cached results, so the code generally existed. By moving it from a global function into a member function of QHostInfoResult, we can simply access the required data to construct and post the event. As we process that posted event, we need to check that the context object (which is already guarded via QPointer) is still alive, if we had one in the first place. If we had one, and it's deleted, then abort. [ChangeLog][QtNetwork][QHostInfo] Functors used in the lookupHost overloads are now called correctly in the thread of the context object. When used without context object, the thread that initiates the lookup will run the functor, and is required to run an event loop. Change-Id: I9b38d4f9a23cfc4d9e07bc72de2d2cefe5d0d033 Fixes: QTBUG-76276 Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim --- src/network/kernel/qhostinfo.cpp | 50 +++++++++++++++---- src/network/kernel/qhostinfo_p.h | 9 +++- .../kernel/qhostinfo/tst_qhostinfo.cpp | 13 +++++ 3 files changed, 62 insertions(+), 10 deletions(-) diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index 597c616fe9..7c82637564 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -106,11 +106,39 @@ int get_signal_index() return signal_index + QMetaObjectPrivate::signalOffset(senderMetaObject); } -void emit_results_ready(const QHostInfo &hostInfo, const QObject *receiver, - QtPrivate::QSlotObjectBase *slotObj) +} + +/* + The calling thread is likely the one that executes the lookup via + QHostInfoRunnable. Unless we operate with a queued connection already, + posts the QHostInfo to a dedicated QHostInfoResult object that lives in + the same thread as the user-provided receiver, or (if there is none) in + the thread that made the call to lookupHost. That QHostInfoResult object + then calls the user code in the correct thread. + + The 'result' object deletes itself (via deleteLater) when the metacall + event is received. +*/ +void QHostInfoResult::postResultsReady(const QHostInfo &info) { + // queued connection will take care of dispatching to right thread + if (!slotObj) { + emitResultsReady(info); + return; + } static const int signal_index = get_signal_index(); + + // we used to have a context object, but it's already destroyed + if (withContextObject && !receiver) + return; + + /* QHostInfoResult c'tor moves the result object to the thread of receiver. + If we don't have a receiver, then the result object will not live in a + thread that runs an event loop - so move it to this' thread, which is the thread + that initiated the lookup, and required to have a running event loop. */ auto result = new QHostInfoResult(receiver, slotObj); + if (!receiver) + result->moveToThread(thread()); Q_CHECK_PTR(result); const int nargs = 2; auto types = reinterpret_cast(malloc(nargs * sizeof(int))); @@ -120,15 +148,13 @@ void emit_results_ready(const QHostInfo &hostInfo, const QObject *receiver, auto args = reinterpret_cast(malloc(nargs * sizeof(void *))); Q_CHECK_PTR(args); args[0] = 0; - args[1] = QMetaType::create(types[1], &hostInfo); + args[1] = QMetaType::create(types[1], &info); Q_CHECK_PTR(args[1]); auto metaCallEvent = new QMetaCallEvent(slotObj, nullptr, signal_index, nargs, types, args); Q_CHECK_PTR(metaCallEvent); qApp->postEvent(result, metaCallEvent); } -} - /*! \class QHostInfo \brief The QHostInfo class provides static functions for host name lookups. @@ -335,6 +361,10 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver, ready, the \a functor is called with a QHostInfo argument. The QHostInfo object can then be inspected to get the results of the lookup. + + The \a functor will be run in the thread that makes the call to lookupHost; + that thread must have a running Qt event loop. + \note There is no guarantee on the order the signals will be emitted if you start multiple requests with lookupHost(). @@ -632,7 +662,8 @@ int QHostInfo::lookupHostImpl(const QString &name, QHostInfo hostInfo(id); hostInfo.setError(QHostInfo::HostNotFound); hostInfo.setErrorString(QCoreApplication::translate("QHostInfo", "No host name given")); - emit_results_ready(hostInfo, receiver, slotObj); + QHostInfoResult result(receiver, slotObj); + result.postResultsReady(hostInfo); return id; } @@ -646,7 +677,8 @@ int QHostInfo::lookupHostImpl(const QString &name, QHostInfo info = manager->cache.get(name, &valid); if (valid) { info.setLookupId(id); - emit_results_ready(info, receiver, slotObj); + QHostInfoResult result(receiver, slotObj); + result.postResultsReady(info); return id; } } @@ -707,7 +739,7 @@ void QHostInfoRunnable::run() // signal emission hostInfo.setLookupId(id); - resultEmitter.emitResultsReady(hostInfo); + resultEmitter.postResultsReady(hostInfo); #if QT_CONFIG(thread) // now also iterate through the postponed ones @@ -720,7 +752,7 @@ void QHostInfoRunnable::run() QHostInfoRunnable* postponed = *it; // we can now emit hostInfo.setLookupId(postponed->id); - postponed->resultEmitter.emitResultsReady(hostInfo); + postponed->resultEmitter.postResultsReady(hostInfo); delete postponed; } manager->postponedLookups.erase(partitionBegin, partitionEnd); diff --git a/src/network/kernel/qhostinfo_p.h b/src/network/kernel/qhostinfo_p.h index 8898d6ff50..bbf4cc36d1 100644 --- a/src/network/kernel/qhostinfo_p.h +++ b/src/network/kernel/qhostinfo_p.h @@ -84,12 +84,14 @@ class QHostInfoResult : public QObject QPointer receiver = nullptr; QtPrivate::QSlotObjectBase *slotObj = nullptr; + const bool withContextObject = false; public: QHostInfoResult() = default; QHostInfoResult(const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj) : receiver(receiver), - slotObj(slotObj) + slotObj(slotObj), + withContextObject(slotObj && receiver) { connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &QObject::deleteLater); @@ -97,10 +99,15 @@ public: moveToThread(receiver->thread()); } + void postResultsReady(const QHostInfo &info); + public Q_SLOTS: inline void emitResultsReady(const QHostInfo &info) { if (slotObj) { + // we used to have a context object, but it's already destroyed + if (withContextObject && !receiver) + return; QHostInfo copy = info; void *args[2] = { 0, reinterpret_cast(©) }; slotObj->call(const_cast(receiver.data()), args); diff --git a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp index 0a130d363e..9905cfe075 100644 --- a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp +++ b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp @@ -92,6 +92,7 @@ private slots: void lookupIPv6(); void lookupConnectToFunctionPointer_data(); void lookupConnectToFunctionPointer(); + void lookupConnectToFunctionPointerDeleted(); void lookupConnectToLambda_data(); void lookupConnectToLambda(); void reverseLookup_data(); @@ -361,6 +362,17 @@ void tst_QHostInfo::lookupConnectToFunctionPointer() QCOMPARE(tmp.join(' '), expected.join(' ')); } +void tst_QHostInfo::lookupConnectToFunctionPointerDeleted() +{ + { + QObject contextObject; + QHostInfo::lookupHost("localhost", &contextObject, [](const QHostInfo){ + QFAIL("This should never be called!"); + }); + } + QTestEventLoop::instance().enterLoop(3); +} + void tst_QHostInfo::lookupConnectToLambda_data() { lookupIPv4_data(); @@ -708,6 +720,7 @@ void tst_QHostInfo::cache() void tst_QHostInfo::resultsReady(const QHostInfo &hi) { + QVERIFY(QThread::currentThread() == thread()); lookupDone = true; lookupResults = hi; lookupsDoneCounter++; From 15fd596fdd995754d9e13f6b903dd8693c4f474c Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 26 Jul 2019 17:00:10 +0200 Subject: [PATCH 188/264] Fix typo: s/QLocal/QLocale/ This amends commit 1d8c9978fa1baafa17c95713bd5d04f245eeb76f in which I perpetrated this typo. Change-Id: Iccfc14aff7c4f3976b92919c8e8dc4b7906642ae Reviewed-by: Marc Mutz Reviewed-by: Paul Wicking --- src/corelib/time/qdatetime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index b2532be49d..5142d2442c 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -349,7 +349,7 @@ static constexpr int daysInUsualMonth(int month) // (February isn't usual.) The year(), month(), and day() functions provide access to the year, month, and day numbers. Also, dayOfWeek() and dayOfYear() functions are provided. The same information is provided in textual format by - toString(). The day and month numbers can be mapped to names using QLocal. + toString(). The day and month numbers can be mapped to names using QLocale. QDate provides a full set of operators to compare two QDate objects where smaller means earlier, and larger means later. From 82d24b43883732ae0cff1f52ea4ecae9dd734c73 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 9 Jul 2019 11:00:50 +0200 Subject: [PATCH 189/264] QFileSystemModel: Remove model member variable from test The test instantiated and deleted a model in each test which is wasteful since not all tests use it. Remove it and introduce per-test variables instead. Task-number: QTBUG-76493 Change-Id: I1684ea5b8eac7b52bb99e830f723693c51e8b9a5 Reviewed-by: Christian Ehrlicher Reviewed-by: Edward Welbourne --- .../qfilesystemmodel/tst_qfilesystemmodel.cpp | 98 ++++++++++--------- 1 file changed, 50 insertions(+), 48 deletions(-) diff --git a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp index 9b6b159e5b..f8f40e8488 100644 --- a/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/widgets/dialogs/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -73,15 +73,10 @@ Q_LOGGING_CATEGORY(lcFileSystemModel, "qt.widgets.tests.qfilesystemmodel") class tst_QFileSystemModel : public QObject { Q_OBJECT -public: - tst_QFileSystemModel(); - -public Q_SLOTS: - void init(); - void cleanup(); - private slots: void initTestCase(); + void cleanup(); + void indexPath(); void rootPath(); @@ -133,31 +128,19 @@ private slots: void fileInfo(); protected: - bool createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount = 0, const QStringList &initial_dirs = QStringList()); - QModelIndex prepareTestModelRoot(const QString &test_path, QSignalSpy **spy2 = nullptr, - QSignalSpy **spy3 = nullptr); + bool createFiles(QFileSystemModel *model, const QString &test_path, + const QStringList &initial_files, int existingFileCount = 0, + const QStringList &initial_dirs = QStringList()); + QModelIndex prepareTestModelRoot(QFileSystemModel *model, const QString &test_path, + QSignalSpy **spy2 = nullptr, QSignalSpy **spy3 = nullptr); private: - QFileSystemModel *model; QString flatDirTestPath; QTemporaryDir m_tempDir; }; -tst_QFileSystemModel::tst_QFileSystemModel() : model(0) -{ -} - -void tst_QFileSystemModel::init() -{ - cleanup(); - QCOMPARE(model, nullptr); - model = new QFileSystemModel; -} - void tst_QFileSystemModel::cleanup() { - delete model; - model = 0; QDir dir(flatDirTestPath); if (dir.exists()) { const QDir::Filters filters = QDir::AllEntries | QDir::System | QDir::Hidden | QDir::NoDotAndDotDot; @@ -184,6 +167,7 @@ void tst_QFileSystemModel::initTestCase() void tst_QFileSystemModel::indexPath() { #if !defined(Q_OS_WIN) + QScopedPointer model(new QFileSystemModel); int depth = QDir::currentPath().count('/'); model->setRootPath(QDir::currentPath()); QString backPath; @@ -197,9 +181,10 @@ void tst_QFileSystemModel::indexPath() void tst_QFileSystemModel::rootPath() { + QScopedPointer model(new QFileSystemModel); QCOMPARE(model->rootPath(), QString(QDir().path())); - QSignalSpy rootChanged(model, &QFileSystemModel::rootPathChanged); + QSignalSpy rootChanged(model.data(), &QFileSystemModel::rootPathChanged); QModelIndex root = model->setRootPath(model->rootPath()); root = model->setRootPath("this directory shouldn't exist"); QCOMPARE(rootChanged.count(), 0); @@ -245,6 +230,7 @@ void tst_QFileSystemModel::rootPath() void tst_QFileSystemModel::readOnly() { + QScopedPointer model(new QFileSystemModel); QCOMPARE(model->isReadOnly(), true); QTemporaryFile file(flatDirTestPath + QStringLiteral("/XXXXXX.dat")); QVERIFY2(file.open(), qPrintable(file.errorString())); @@ -293,6 +279,7 @@ private: void tst_QFileSystemModel::iconProvider() { + QScopedPointer model(new QFileSystemModel); QVERIFY(model->iconProvider()); QScopedPointer provider(new QFileIconProvider); model->setIconProvider(provider.data()); @@ -312,7 +299,9 @@ void tst_QFileSystemModel::iconProvider() QCOMPARE(myModel->fileIcon(myModel->index(QDir::homePath())).pixmap(50, 50), mb); } -bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringList &initial_files, int existingFileCount, const QStringList &initial_dirs) +bool tst_QFileSystemModel::createFiles(QFileSystemModel *model, const QString &test_path, + const QStringList &initial_files, int existingFileCount, + const QStringList &initial_dirs) { qCDebug(lcFileSystemModel) << (model->rowCount(model->index(test_path))) << existingFileCount << initial_files; bool timedOut = false; @@ -374,8 +363,8 @@ bool tst_QFileSystemModel::createFiles(const QString &test_path, const QStringLi return true; } -QModelIndex tst_QFileSystemModel::prepareTestModelRoot(const QString &test_path, QSignalSpy **spy2, - QSignalSpy **spy3) +QModelIndex tst_QFileSystemModel::prepareTestModelRoot(QFileSystemModel *model, const QString &test_path, + QSignalSpy **spy2, QSignalSpy **spy3) { if (model->rowCount(model->index(test_path)) != 0) return QModelIndex(); @@ -387,7 +376,7 @@ QModelIndex tst_QFileSystemModel::prepareTestModelRoot(const QString &test_path, QStringList files = { "b", "d", "f", "h", "j", ".a", ".c", ".e", ".g" }; - if (!createFiles(test_path, files)) + if (!createFiles(model, test_path, files)) return QModelIndex(); QModelIndex root = model->setRootPath(test_path); @@ -406,7 +395,8 @@ void tst_QFileSystemModel::rowCount() { QSignalSpy *spy2 = nullptr; QSignalSpy *spy3 = nullptr; - QModelIndex root = prepareTestModelRoot(flatDirTestPath, &spy2, &spy3); + QScopedPointer model(new QFileSystemModel); + QModelIndex root = prepareTestModelRoot(model.data(), flatDirTestPath, &spy2, &spy3); QVERIFY(root.isValid()); QVERIFY(spy2 && spy2->count() > 0); @@ -433,20 +423,21 @@ static inline QString lastEntry(const QModelIndex &root) void tst_QFileSystemModel::rowsInserted() { const QString tmp = flatDirTestPath; - QModelIndex root = prepareTestModelRoot(tmp); + QScopedPointer model(new QFileSystemModel); + QModelIndex root = prepareTestModelRoot(model.data(), tmp); QVERIFY(root.isValid()); QFETCH(Qt::SortOrder, ascending); QFETCH(int, count); model->sort(0, ascending); - QSignalSpy spy0(model, &QAbstractItemModel::rowsInserted); - QSignalSpy spy1(model, &QAbstractItemModel::rowsAboutToBeInserted); + QSignalSpy spy0(model.data(), &QAbstractItemModel::rowsInserted); + QSignalSpy spy1(model.data(), &QAbstractItemModel::rowsAboutToBeInserted); int oldCount = model->rowCount(root); QStringList files; for (int i = 0; i < count; ++i) files.append(QLatin1Char('c') + QString::number(i)); - QVERIFY(createFiles(tmp, files, 5)); + QVERIFY(createFiles(model.data(), tmp, files, 5)); QTRY_COMPARE(model->rowCount(root), oldCount + count); int totalRowsInserted = 0; for (int i = 0; i < spy0.count(); ++i) { @@ -466,7 +457,7 @@ void tst_QFileSystemModel::rowsInserted() } if (count == 0) QCOMPARE(spy1.count(), 0); else QVERIFY(spy1.count() >= 1); - QVERIFY(createFiles(tmp, QStringList(".hidden_file"), 5 + count)); + QVERIFY(createFiles(model.data(), tmp, QStringList(".hidden_file"), 5 + count)); if (count != 0) QTRY_VERIFY(spy0.count() >= 1); @@ -486,15 +477,16 @@ void tst_QFileSystemModel::rowsRemoved_data() void tst_QFileSystemModel::rowsRemoved() { const QString tmp = flatDirTestPath; - QModelIndex root = prepareTestModelRoot(tmp); + QScopedPointer model(new QFileSystemModel); + QModelIndex root = prepareTestModelRoot(model.data(), tmp); QVERIFY(root.isValid()); QFETCH(int, count); QFETCH(Qt::SortOrder, ascending); model->sort(0, ascending); - QSignalSpy spy0(model, &QAbstractItemModel::rowsRemoved); - QSignalSpy spy1(model, &QAbstractItemModel::rowsAboutToBeRemoved); + QSignalSpy spy0(model.data(), &QAbstractItemModel::rowsRemoved); + QSignalSpy spy1(model.data(), &QAbstractItemModel::rowsAboutToBeRemoved); int oldCount = model->rowCount(root); for (int i = count - 1; i >= 0; --i) { const QString fileName = model->index(i, 0, root).data().toString(); @@ -547,18 +539,19 @@ void tst_QFileSystemModel::dataChanged() QSKIP("This can't be tested right now since we don't watch files, only directories."); const QString tmp = flatDirTestPath; - QModelIndex root = prepareTestModelRoot(tmp); + QScopedPointer model(new QFileSystemModel); + QModelIndex root = prepareTestModelRoot(model.data(), tmp); QVERIFY(root.isValid()); QFETCH(int, count); QFETCH(Qt::SortOrder, ascending); model->sort(0, ascending); - QSignalSpy spy(model, &QAbstractItemModel::dataChanged); + QSignalSpy spy(model.data(), &QAbstractItemModel::dataChanged); QStringList files; for (int i = 0; i < count; ++i) files.append(model->index(i, 0, root).data().toString()); - createFiles(tmp, files); + createFiles(model.data(), tmp, files); QTest::qWait(WAITTIME); @@ -606,7 +599,8 @@ void tst_QFileSystemModel::filters_data() void tst_QFileSystemModel::filters() { QString tmp = flatDirTestPath; - QVERIFY(createFiles(tmp, QStringList())); + QScopedPointer model(new QFileSystemModel); + QVERIFY(createFiles(model.data(), tmp, QStringList())); QModelIndex root = model->setRootPath(tmp); QFETCH(QStringList, files); QFETCH(QStringList, dirs); @@ -619,7 +613,7 @@ void tst_QFileSystemModel::filters() model->setNameFilterDisables(false); model->setFilter(dirFilters); - QVERIFY(createFiles(tmp, files, 0, dirs)); + QVERIFY(createFiles(model.data(), tmp, files, 0, dirs)); QTRY_COMPARE(model->rowCount(root), rowCount); // Make sure that we do what QDir does @@ -673,12 +667,13 @@ void tst_QFileSystemModel::nameFilters() { QStringList list; list << "a" << "b" << "c"; + QScopedPointer model(new QFileSystemModel); model->setNameFilters(list); model->setNameFilterDisables(false); QCOMPARE(model->nameFilters(), list); QString tmp = flatDirTestPath; - QVERIFY(createFiles(tmp, list)); + QVERIFY(createFiles(model.data(), tmp, list)); QModelIndex root = model->setRootPath(tmp); QTRY_COMPARE(model->rowCount(root), 3); @@ -717,7 +712,8 @@ void tst_QFileSystemModel::setData_data() void tst_QFileSystemModel::setData() { - QSignalSpy spy(model, &QFileSystemModel::fileRenamed); + QScopedPointer model(new QFileSystemModel); + QSignalSpy spy(model.data(), &QFileSystemModel::fileRenamed); QFETCH(QString, subdirName); QFETCH(QStringList, files); QFETCH(QString, oldFileName); @@ -730,7 +726,7 @@ void tst_QFileSystemModel::setData() QVERIFY(dir.mkdir(subdirName)); tmp.append('/' + subdirName); } - QVERIFY(createFiles(tmp, files)); + QVERIFY(createFiles(model.data(), tmp, files)); QModelIndex tmpIdx = model->setRootPath(flatDirTestPath); if (!subdirName.isEmpty()) { tmpIdx = model->index(tmp); @@ -768,6 +764,7 @@ void tst_QFileSystemModel::sortPersistentIndex() const QFileInfo fileInfo(file.fileName()); file.close(); QTRY_VERIFY(QDir(flatDirTestPath).entryInfoList().contains(fileInfo)); + QScopedPointer model(new QFileSystemModel); QModelIndex root = model->setRootPath(flatDirTestPath); QTRY_VERIFY(model->rowCount(root) > 0); @@ -873,6 +870,7 @@ void tst_QFileSystemModel::mkdir() { QString tmp = flatDirTestPath; QString newFolderPath = QDir::toNativeSeparators(tmp + '/' + "NewFoldermkdirtest4"); + QScopedPointer model(new QFileSystemModel); QModelIndex tmpDir = model->index(tmp); QVERIFY(tmpDir.isValid()); QDir bestatic(newFolderPath); @@ -907,6 +905,7 @@ void tst_QFileSystemModel::deleteFile() qWarning() << "unable to create" << newFilePath; } newFile.close(); + QScopedPointer model(new QFileSystemModel); QModelIndex idx = model->index(newFilePath); QVERIFY(idx.isValid()); QVERIFY(model->remove(idx)); @@ -968,7 +967,8 @@ void tst_QFileSystemModel::caseSensitivity() QString tmp = flatDirTestPath; QStringList files; files << "a" << "c" << "C"; - QVERIFY(createFiles(tmp, files)); + QScopedPointer model(new QFileSystemModel); + QVERIFY(createFiles(model.data(), tmp, files)); QModelIndex root = model->index(tmp); QStringList paths; QModelIndexList indexes; @@ -1025,6 +1025,7 @@ void tst_QFileSystemModel::dirsBeforeFiles() file.close(); } + QScopedPointer model(new QFileSystemModel); QModelIndex root = model->setRootPath(flatDirTestPath); // Wait for model to be notified by the file system watcher QTRY_COMPARE(model->rowCount(root), 2 * itemCount); @@ -1099,7 +1100,8 @@ void tst_QFileSystemModel::permissions() // checks QTBUG-20503 const QString tmp = flatDirTestPath; const QString file = tmp + QLatin1String("/f"); - QVERIFY(createFiles(tmp, QStringList{QLatin1String("f")})); + QScopedPointer model(new QFileSystemModel); + QVERIFY(createFiles(model.data(), tmp, QStringList{QLatin1String("f")})); QVERIFY(QFile::setPermissions(file, permissions)); From 80d7ba4c49a6e1c9651695719d84e3952898f1d5 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 25 Jul 2019 14:18:09 +0300 Subject: [PATCH 190/264] QGradientCache: fix use of deprecated QHash::iterator::operator+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use std::next, which will transparently loop over ++it instead of calling op+, whenever the time has come to do so. Change-Id: Icee38bd96894488cf53c1596cd611c61cc68ace8 Reviewed-by: Mårten Nordheim --- src/gui/painting/qpaintengine_raster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 8ff77c8063..0a440e5b75 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -4295,7 +4295,7 @@ protected: QSharedPointer addCacheElement(quint64 hash_val, const QGradient &gradient, int opacity) { if (cache.size() == maxCacheSize()) { // may remove more than 1, but OK - cache.erase(cache.begin() + QRandomGenerator::global()->bounded(maxCacheSize())); + cache.erase(std::next(cache.begin(), QRandomGenerator::global()->bounded(maxCacheSize()))); } auto cache_entry = QSharedPointer::create(gradient.stops(), opacity, gradient.interpolationMode()); generateGradientColorTable(gradient, cache_entry->buffer64, paletteSize(), opacity); From 186bdec01a62dcc407e21873a6c6a0c484d5df62 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 25 May 2019 23:42:45 +0200 Subject: [PATCH 191/264] Standardize on unique_ptr to hold QAbstractFileEngine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will make it possible to return it from functions in an owner, as exemplified in the QFileInfoPrivate ctor, unlike QScopedPointer, which lacks move special member functions. Change-Id: I179ffa4f656e1b83c23e0f67d1542834460ff382 Reviewed-by: Mårten Nordheim --- src/corelib/io/qdir.cpp | 26 +++++++++++++------------- src/corelib/io/qdir_p.h | 4 +++- src/corelib/io/qdiriterator.cpp | 6 ++++-- src/corelib/io/qfileinfo.cpp | 6 +++--- src/corelib/io/qfileinfo_p.h | 8 +++++--- 5 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 47fac66c4f..fae935fc24 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -153,7 +153,7 @@ QDirPrivate::QDirPrivate(const QDirPrivate ©) bool QDirPrivate::exists() const { - if (fileEngine.isNull()) { + if (!fileEngine) { QFileSystemEngine::fillMetaData(dirEntry, metaData, QFileSystemMetaData::ExistsAttribute | QFileSystemMetaData::DirectoryType); // always stat return metaData.exists() && metaData.isDirectory(); @@ -226,7 +226,7 @@ inline void QDirPrivate::resolveAbsoluteEntry() const return; QString absoluteName; - if (fileEngine.isNull()) { + if (!fileEngine) { if (!dirEntry.isRelative() && dirEntry.isClean()) { absoluteDirEntry = dirEntry; return; @@ -693,7 +693,7 @@ QString QDir::absolutePath() const QString QDir::canonicalPath() const { const QDirPrivate* d = d_ptr.constData(); - if (d->fileEngine.isNull()) { + if (!d->fileEngine) { QFileSystemEntry answer = QFileSystemEngine::canonicalName(d->dirEntry, d->metaData); return answer.filePath(); } @@ -1502,7 +1502,7 @@ bool QDir::mkdir(const QString &dirName) const } QString fn = filePath(dirName); - if (d->fileEngine.isNull()) + if (!d->fileEngine) return QFileSystemEngine::createDirectory(QFileSystemEntry(fn), false); return d->fileEngine->mkdir(fn, false); } @@ -1526,7 +1526,7 @@ bool QDir::rmdir(const QString &dirName) const } QString fn = filePath(dirName); - if (d->fileEngine.isNull()) + if (!d->fileEngine) return QFileSystemEngine::removeDirectory(QFileSystemEntry(fn), false); return d->fileEngine->rmdir(fn, false); @@ -1554,7 +1554,7 @@ bool QDir::mkpath(const QString &dirPath) const } QString fn = filePath(dirPath); - if (d->fileEngine.isNull()) + if (!d->fileEngine) return QFileSystemEngine::createDirectory(QFileSystemEntry(fn), true); return d->fileEngine->mkdir(fn, true); } @@ -1580,7 +1580,7 @@ bool QDir::rmpath(const QString &dirPath) const } QString fn = filePath(dirPath); - if (d->fileEngine.isNull()) + if (!d->fileEngine) return QFileSystemEngine::removeDirectory(QFileSystemEntry(fn), true); return d->fileEngine->rmdir(fn, true); } @@ -1653,7 +1653,7 @@ bool QDir::isReadable() const { const QDirPrivate* d = d_ptr.constData(); - if (d->fileEngine.isNull()) { + if (!d->fileEngine) { if (!d->metaData.hasFlags(QFileSystemMetaData::UserReadPermission)) QFileSystemEngine::fillMetaData(d->dirEntry, d->metaData, QFileSystemMetaData::UserReadPermission); @@ -1698,7 +1698,7 @@ bool QDir::exists() const */ bool QDir::isRoot() const { - if (d_ptr->fileEngine.isNull()) + if (!d_ptr->fileEngine) return d_ptr->dirEntry.isRoot(); return d_ptr->fileEngine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::RootFlag; } @@ -1730,7 +1730,7 @@ bool QDir::isRoot() const */ bool QDir::isRelative() const { - if (d_ptr->fileEngine.isNull()) + if (!d_ptr->fileEngine) return d_ptr->dirEntry.isRelative(); return d_ptr->fileEngine->isRelativePath(); } @@ -1747,7 +1747,7 @@ bool QDir::makeAbsolute() { const QDirPrivate *d = d_ptr.constData(); QScopedPointer dir; - if (!d->fileEngine.isNull()) { + if (!!d->fileEngine) { QString absolutePath = d->fileEngine->fileName(QAbstractFileEngine::AbsoluteName); if (QDir::isRelativePath(absolutePath)) return false; @@ -1780,8 +1780,8 @@ bool QDir::operator==(const QDir &dir) const if (d == other) return true; Qt::CaseSensitivity sensitive; - if (d->fileEngine.isNull() || other->fileEngine.isNull()) { - if (d->fileEngine.data() != other->fileEngine.data()) // one is native, the other is a custom file-engine + if (!d->fileEngine || !other->fileEngine) { + if (d->fileEngine.get() != other->fileEngine.get()) // one is native, the other is a custom file-engine return false; sensitive = QFileSystemEngine::isCaseSensitive() ? Qt::CaseSensitive : Qt::CaseInsensitive; diff --git a/src/corelib/io/qdir_p.h b/src/corelib/io/qdir_p.h index 42218e1ccf..af105de8db 100644 --- a/src/corelib/io/qdir_p.h +++ b/src/corelib/io/qdir_p.h @@ -54,6 +54,8 @@ #include "qfilesystementry_p.h" #include "qfilesystemmetadata_p.h" +#include + QT_BEGIN_NAMESPACE class QDirPrivate : public QSharedData @@ -98,7 +100,7 @@ public: QDir::SortFlags sort; QDir::Filters filters; - QScopedPointer fileEngine; + std::unique_ptr fileEngine; QFileSystemEntry dirEntry; mutable QFileSystemEntry absoluteDirEntry; diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 303caf29a4..ce436b06e3 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -107,6 +107,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE template @@ -132,7 +134,7 @@ public: void checkAndPushDirectory(const QFileInfo &); bool matchesFilters(const QString &fileName, const QFileInfo &fi) const; - QScopedPointer engine; + std::unique_ptr engine; QFileSystemEntry dirEntry; const QStringList nameFilters; @@ -435,7 +437,7 @@ bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInf QDirIterator::QDirIterator(const QDir &dir, IteratorFlags flags) { const QDirPrivate *other = dir.d_ptr.constData(); - d.reset(new QDirIteratorPrivate(other->dirEntry, other->nameFilters, other->filters, flags, !other->fileEngine.isNull())); + d.reset(new QDirIteratorPrivate(other->dirEntry, other->nameFilters, other->filters, flags, bool(other->fileEngine))); } /*! diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index f5b398feae..a5a3bc8b3e 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -707,11 +707,11 @@ bool QFileInfo::exists(const QString &file) return false; QFileSystemEntry entry(file); QFileSystemMetaData data; - QAbstractFileEngine *engine = - QFileSystemEngine::resolveEntryAndCreateLegacyEngine(entry, data); + std::unique_ptr engine + {QFileSystemEngine::resolveEntryAndCreateLegacyEngine(entry, data)}; // Expensive fallback to non-QFileSystemEngine implementation if (engine) - return QFileInfo(new QFileInfoPrivate(entry, data, engine)).exists(); + return QFileInfo(new QFileInfoPrivate(entry, data, std::move(engine))).exists(); QFileSystemEngine::fillMetaData(entry, data, QFileSystemMetaData::ExistsAttribute); return data.exists(); diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h index 36f440812f..333ea70adc 100644 --- a/src/corelib/io/qfileinfo_p.h +++ b/src/corelib/io/qfileinfo_p.h @@ -61,6 +61,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE class QFileInfoPrivate : public QSharedData @@ -126,10 +128,10 @@ public: metaData = QFileSystemMetaData(); } - inline QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data, QAbstractFileEngine *engine) + inline QFileInfoPrivate(const QFileSystemEntry &file, const QFileSystemMetaData &data, std::unique_ptr engine) : fileEntry(file), metaData(data), - fileEngine(engine), + fileEngine{std::move(engine)}, cachedFlags(0), #ifndef QT_NO_FSFILEENGINE isDefaultConstructed(false), @@ -163,7 +165,7 @@ public: QFileSystemEntry fileEntry; mutable QFileSystemMetaData metaData; - QScopedPointer const fileEngine; + std::unique_ptr const fileEngine; mutable QString fileNames[QAbstractFileEngine::NFileNames]; mutable QString fileOwners[2]; // QAbstractFileEngine::FileOwner: OwnerUser and OwnerGroup From 570fb55a334d77959ed158fc55ac66814bd33f15 Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Thu, 6 Jun 2019 16:47:18 +1000 Subject: [PATCH 192/264] wasm: fix wide character data download Need to pass correct buffer size Change-Id: I19cb65114f49decc225cd807d59f1f08ad6b70c9 Fixes: QTBUG-76212 Reviewed-by: Volker Hilsheimer --- src/network/access/qnetworkreplywasmimpl.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkreplywasmimpl.cpp b/src/network/access/qnetworkreplywasmimpl.cpp index ee91dc20b3..53784407d8 100644 --- a/src/network/access/qnetworkreplywasmimpl.cpp +++ b/src/network/access/qnetworkreplywasmimpl.cpp @@ -135,8 +135,10 @@ static void q_loadCallback(val event) if (readyState == 4) { // done reply->setReplyAttributes(xhr["data-handler"].as(), status, statusText); - if (!responseString.isEmpty()) - reply->dataReceived(responseString.toUtf8(), responseString.size()); + if (!responseString.isEmpty()) { + QByteArray responseStringArray = responseString.toUtf8(); + reply->dataReceived(responseStringArray, responseStringArray.size()); + } } } if (status >= 400 && !statusText.isEmpty()) From 7138d6fd6bba2c2e55d02bccf7fd0c6c287eab29 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 22 Jul 2019 15:50:49 +0200 Subject: [PATCH 193/264] QWinRTFileEngine: Implement setSize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTBUG-77132 Change-Id: Ic0410297a2215f1b7b656966cbe84b925706532f Reviewed-by: André de la Rocha Reviewed-by: Maurice Kalinowski --- .../platforms/winrt/qwinrtfileengine.cpp | 23 +++++++++++++++++++ .../platforms/winrt/qwinrtfileengine.h | 1 + 2 files changed, 24 insertions(+) diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp index 3014b30c38..e9b2a82763 100644 --- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp +++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp @@ -257,6 +257,29 @@ qint64 QWinRTFileEngine::size() const return qint64(size); } +bool QWinRTFileEngine::setSize(qint64 size) +{ + Q_D(QWinRTFileEngine); + if (!d->stream) { + setError(QFileDevice::ResizeError, QLatin1String("File must be open to be resized")); + return false; + } + + if (size < 0) { + setError(QFileDevice::ResizeError, QLatin1String("File size cannot be negative")); + return false; + } + + HRESULT hr = d->stream->put_Size(static_cast(size)); + RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ResizeError, false); + if (!flush()) { + setError(QFileDevice::ResizeError, QLatin1String("Could not flush file")); + return false; + } + + return true; +} + qint64 QWinRTFileEngine::pos() const { Q_D(const QWinRTFileEngine); diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.h b/src/plugins/platforms/winrt/qwinrtfileengine.h index 4485917c9e..453565a95a 100644 --- a/src/plugins/platforms/winrt/qwinrtfileengine.h +++ b/src/plugins/platforms/winrt/qwinrtfileengine.h @@ -79,6 +79,7 @@ public: bool close() override; bool flush() override; qint64 size() const override; + bool setSize(qint64 size) override; qint64 pos() const override; bool seek(qint64 pos) override; bool remove() override; From fe8cd567dd3499d144f46ebba1a82a4ff85ff408 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Sat, 27 Jul 2019 15:31:03 +0200 Subject: [PATCH 194/264] Add IPv6 data to the reverseLookup test Passes locally, and there is no reason why it shoulnd't. Use IPv6 addresses for Google and Cloudflare DNS servers, and as with the IPv4 tests, rely on Python and (as a fallback) nslookup to produce the reference. Change-Id: I584f8ae9bc89c66a1f59d7b1e7493d0ed8033e8a Fixes: QTBUG-22287 Reviewed-by: Timur Pocheptsov --- tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp index 0a130d363e..5db6eb000d 100644 --- a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp +++ b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp @@ -467,7 +467,9 @@ void tst_QHostInfo::reverseLookup_data() QTest::newRow("dns.google") << QString("8.8.8.8") << reverseLookupHelper("8.8.8.8") << 0 << false; QTest::newRow("one.one.one.one") << QString("1.1.1.1") << reverseLookupHelper("1.1.1.1") << 0 << false; - QTest::newRow("bogus-name") << QString("1::2::3::4") << QStringList() << 1 << true; + QTest::newRow("dns.google IPv6") << QString("2001:4860:4860::8888") << reverseLookupHelper("2001:4860:4860::8888") << 0 << true; + QTest::newRow("cloudflare IPv6") << QString("2606:4700:4700::1111") << reverseLookupHelper("2606:4700:4700::1111") << 0 << true; + QTest::newRow("bogus-name IPv6") << QString("1::2::3::4") << QStringList() << 1 << true; } void tst_QHostInfo::reverseLookup() From eb39185acba01250240c289b1b3e64892f615357 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 24 May 2019 21:50:50 +0200 Subject: [PATCH 195/264] QGraphicsWidget: replace manual memory management with unique_ptr Change-Id: Ib63812cf1e63e33dff5016d37a37f18bf9aa6ee0 Reviewed-by: Giuseppe D'Angelo --- src/widgets/graphicsview/qgraphicswidget_p.cpp | 4 +--- src/widgets/graphicsview/qgraphicswidget_p.h | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/widgets/graphicsview/qgraphicswidget_p.cpp b/src/widgets/graphicsview/qgraphicswidget_p.cpp index cc08b1c566..fd47f444ea 100644 --- a/src/widgets/graphicsview/qgraphicswidget_p.cpp +++ b/src/widgets/graphicsview/qgraphicswidget_p.cpp @@ -110,8 +110,6 @@ QGraphicsWidgetPrivate::QGraphicsWidgetPrivate() QGraphicsWidgetPrivate::~QGraphicsWidgetPrivate() { - // Remove any lazily allocated data - delete windowData; } /*! @@ -147,7 +145,7 @@ void QGraphicsWidgetPrivate::ensureWindowFrameMargins() const void QGraphicsWidgetPrivate::ensureWindowData() { if (!windowData) - windowData = new WindowData; + windowData = qt_make_unique(); } void QGraphicsWidgetPrivate::setPalette_helper(const QPalette &palette) diff --git a/src/widgets/graphicsview/qgraphicswidget_p.h b/src/widgets/graphicsview/qgraphicswidget_p.h index 5e0fdb693b..e4cc2c3016 100644 --- a/src/widgets/graphicsview/qgraphicswidget_p.h +++ b/src/widgets/graphicsview/qgraphicswidget_p.h @@ -190,7 +190,8 @@ public: , buttonMouseOver(false) , buttonSunken(false) {} - } *windowData; + }; + std::unique_ptr windowData; void ensureWindowData(); bool setWindowFrameMargins; From adab531771a1ddce7df6652449b7977f340ebfc7 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 26 Jul 2019 22:18:40 +0300 Subject: [PATCH 196/264] Port from QStringViewLiteral to u"" Now that all our supported compilers know char16_t, we no longer need QStringViewLiteral, whose only purpose in life was to turn u"" into L"" for MSVC < 2015. Change-Id: I25a094fe7992d9d5dbeb4a524d9e99e043dcb8ce Reviewed-by: Volker Hilsheimer --- src/corelib/io/qtldurl.cpp | 6 +++--- src/corelib/serialization/qxmlstream.cpp | 4 ++-- src/corelib/time/qdatetime.cpp | 8 ++++---- src/network/access/qnetworkrequest.cpp | 2 +- src/plugins/sqldrivers/psql/qsql_psql.cpp | 4 ++-- src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp | 2 +- src/plugins/sqldrivers/tds/qsql_tds.cpp | 2 +- src/printsupport/kernel/qcups.cpp | 2 +- src/testlib/qtest.h | 6 +++--- .../corelib/codecs/qtextcodec/tst_qtextcodec.cpp | 2 +- tests/auto/corelib/io/qdebug/tst_qdebug.cpp | 2 +- tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp | 2 +- .../serialization/qtextstream/tst_qtextstream.cpp | 2 +- tests/auto/corelib/text/qlocale/tst_qlocale.cpp | 4 ++-- tests/auto/corelib/text/qstring/tst_qstring.cpp | 6 +++--- .../corelib/text/qstringview/tst_qstringview.cpp | 12 ++++++------ 16 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/corelib/io/qtldurl.cpp b/src/corelib/io/qtldurl.cpp index a934d19fa2..912609ec91 100644 --- a/src/corelib/io/qtldurl.cpp +++ b/src/corelib/io/qtldurl.cpp @@ -59,9 +59,9 @@ enum TLDMatchType { static bool containsTLDEntry(QStringView entry, TLDMatchType match) { const QStringView matchSymbols[] = { - QStringViewLiteral(""), - QStringViewLiteral("*"), - QStringViewLiteral("!"), + u"", + u"*", + u"!", }; const auto symbol = matchSymbols[match]; int index = qt_hash(entry, qt_hash(symbol)) % tldCount; diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp index 27a5137fc9..500e0aa6be 100644 --- a/src/corelib/serialization/qxmlstream.cpp +++ b/src/corelib/serialization/qxmlstream.cpp @@ -782,8 +782,8 @@ QXmlStreamPrivateTagStack::QXmlStreamPrivateTagStack() tagStackStringStorage.reserve(32); tagStackStringStorageSize = 0; NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push(); - namespaceDeclaration.prefix = addToStringStorage(QStringViewLiteral("xml")); - namespaceDeclaration.namespaceUri = addToStringStorage(QStringViewLiteral("http://www.w3.org/XML/1998/namespace")); + namespaceDeclaration.prefix = addToStringStorage(u"xml"); + namespaceDeclaration.namespaceUri = addToStringStorage(u"http://www.w3.org/XML/1998/namespace"); initialTagStackStringStorageSize = tagStackStringStorageSize; } diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index 5142d2442c..64943bdaaf 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -1129,7 +1129,7 @@ QString QDate::toString(Qt::DateFormat format) const case Qt::DefaultLocaleLongDate: return QLocale().toString(*this, QLocale::LongFormat); case Qt::RFC2822Date: - return QLocale::c().toString(*this, QStringViewLiteral("dd MMM yyyy")); + return QLocale::c().toString(*this, u"dd MMM yyyy"); default: #if QT_CONFIG(textdate) case Qt::TextDate: @@ -4122,7 +4122,7 @@ QString QDateTime::toString(Qt::DateFormat format) const case Qt::DefaultLocaleLongDate: return QLocale().toString(*this, QLocale::LongFormat); case Qt::RFC2822Date: { - buf = QLocale::c().toString(*this, QStringViewLiteral("dd MMM yyyy hh:mm:ss ")); + buf = QLocale::c().toString(*this, u"dd MMM yyyy hh:mm:ss "); buf += toOffsetString(Qt::TextDate, offsetFromUtc()); return buf; } @@ -5622,7 +5622,7 @@ QDebug operator<<(QDebug dbg, const QTime &time) QDebugStateSaver saver(dbg); dbg.nospace() << "QTime("; if (time.isValid()) - dbg.nospace() << time.toString(QStringViewLiteral("HH:mm:ss.zzz")); + dbg.nospace() << time.toString(u"HH:mm:ss.zzz"); else dbg.nospace() << "Invalid"; dbg.nospace() << ')'; @@ -5635,7 +5635,7 @@ QDebug operator<<(QDebug dbg, const QDateTime &date) dbg.nospace() << "QDateTime("; if (date.isValid()) { const Qt::TimeSpec ts = date.timeSpec(); - dbg.noquote() << date.toString(QStringViewLiteral("yyyy-MM-dd HH:mm:ss.zzz t")) + dbg.noquote() << date.toString(u"yyyy-MM-dd HH:mm:ss.zzz t") << ' ' << ts; switch (ts) { case Qt::UTC: diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index c82eb8fe9f..37f64c3f52 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -1355,7 +1355,7 @@ QDateTime QNetworkHeadersPrivate::fromHttpDate(const QByteArray &value) QByteArray QNetworkHeadersPrivate::toHttpDate(const QDateTime &dt) { - return QLocale::c().toString(dt, QStringViewLiteral("ddd, dd MMM yyyy hh:mm:ss 'GMT'")) + return QLocale::c().toString(dt, u"ddd, dd MMM yyyy hh:mm:ss 'GMT'") .toLatin1(); } diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp index bf9424897d..0bae45382d 100644 --- a/src/plugins/sqldrivers/psql/qsql_psql.cpp +++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp @@ -1506,7 +1506,7 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const // this is safe since postgresql stores only the UTC value and not the timezone offset (only used // while parsing), so we have correct behavior in both case of with timezone and without tz r = QStringLiteral("TIMESTAMP WITH TIME ZONE ") + QLatin1Char('\'') + - QLocale::c().toString(field.value().toDateTime().toUTC(), QStringViewLiteral("yyyy-MM-ddThh:mm:ss.zzz")) + + QLocale::c().toString(field.value().toDateTime().toUTC(), u"yyyy-MM-ddThh:mm:ss.zzz") + QLatin1Char('Z') + QLatin1Char('\''); } else { r = nullStr(); @@ -1518,7 +1518,7 @@ QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const case QVariant::Time: #if QT_CONFIG(datestring) if (field.value().toTime().isValid()) { - r = QLatin1Char('\'') + field.value().toTime().toString(QStringViewLiteral("hh:mm:ss.zzz")) + QLatin1Char('\''); + r = QLatin1Char('\'') + field.value().toTime().toString(u"hh:mm:ss.zzz") + QLatin1Char('\''); } else #endif { diff --git a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp index f1a003ddcd..001bd673fc 100644 --- a/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp +++ b/src/plugins/sqldrivers/sqlite/qsql_sqlite.cpp @@ -531,7 +531,7 @@ bool QSQLiteResult::exec() } case QVariant::Time: { const QTime time = value.toTime(); - const QString str = time.toString(QStringViewLiteral("hh:mm:ss.zzz")); + const QString str = time.toString(u"hh:mm:ss.zzz"); res = sqlite3_bind_text16(d->stmt, i + 1, str.utf16(), str.size() * sizeof(ushort), SQLITE_TRANSIENT); break; diff --git a/src/plugins/sqldrivers/tds/qsql_tds.cpp b/src/plugins/sqldrivers/tds/qsql_tds.cpp index 603372230d..9c8d242028 100644 --- a/src/plugins/sqldrivers/tds/qsql_tds.cpp +++ b/src/plugins/sqldrivers/tds/qsql_tds.cpp @@ -813,7 +813,7 @@ QString QTDSDriver::formatValue(const QSqlField &field, r = QLatin1String("NULL"); else if (field.type() == QVariant::DateTime) { if (field.value().toDateTime().isValid()){ - r = field.value().toDateTime().toString(QStringViewLiteral("yyyyMMdd hh:mm:ss")); + r = field.value().toDateTime().toString(u"yyyyMMdd hh:mm:ss"); r.prepend(QLatin1String("'")); r.append(QLatin1String("'")); } else diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp index 5236b8c8fa..2fc4621960 100644 --- a/src/printsupport/kernel/qcups.cpp +++ b/src/printsupport/kernel/qcups.cpp @@ -106,7 +106,7 @@ static inline QString jobHoldToString(const QCUPSSupport::JobHoldUntil jobHold, if (holdUntilTime < localDateTime.time()) localDateTime = localDateTime.addDays(1); localDateTime.setTime(holdUntilTime); - return localDateTime.toUTC().time().toString(QStringViewLiteral("HH:mm")); + return localDateTime.toUTC().time().toString(u"HH:mm"); } // else fall through: Q_FALLTHROUGH(); diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index 7affdcb8b4..bff8f292a5 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -95,21 +95,21 @@ template<> inline char *toString(const QByteArray &ba) template<> inline char *toString(const QTime &time) { return time.isValid() - ? qstrdup(qPrintable(time.toString(QStringViewLiteral("hh:mm:ss.zzz")))) + ? qstrdup(qPrintable(time.toString(u"hh:mm:ss.zzz"))) : qstrdup("Invalid QTime"); } template<> inline char *toString(const QDate &date) { return date.isValid() - ? qstrdup(qPrintable(date.toString(QStringViewLiteral("yyyy/MM/dd")))) + ? qstrdup(qPrintable(date.toString(u"yyyy/MM/dd"))) : qstrdup("Invalid QDate"); } template<> inline char *toString(const QDateTime &dateTime) { return dateTime.isValid() - ? qstrdup(qPrintable(dateTime.toString(QStringViewLiteral("yyyy/MM/dd hh:mm:ss.zzz[t]")))) + ? qstrdup(qPrintable(dateTime.toString(u"yyyy/MM/dd hh:mm:ss.zzz[t]"))) : qstrdup("Invalid QDateTime"); } #endif // datestring diff --git a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp index 6cadebfd7f..78b6449a69 100644 --- a/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp +++ b/tests/auto/corelib/codecs/qtextcodec/tst_qtextcodec.cpp @@ -263,7 +263,7 @@ void tst_QTextCodec::fromUnicode() If the encoding is a superset of ASCII, test that the byte array is correct (no off by one, no trailing '\0'). */ - QByteArray result = codec->fromUnicode(QStringViewLiteral("abc")); + QByteArray result = codec->fromUnicode(u"abc"); if (result.startsWith('a')) { QCOMPARE(result.size(), 3); QCOMPARE(result, QByteArray("abc")); diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp index a818c6c09d..584e66a7db 100644 --- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp +++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp @@ -506,7 +506,7 @@ void tst_QDebug::qDebugQStringView() const { QLatin1String file, function; int line = 0; - const QStringView inView = QStringViewLiteral("input"); + const QStringView inView = u"input"; MessageHandlerSetter mhs(myMessageHandler); { qDebug() << inView; } diff --git a/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp b/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp index 569c610e24..b05c89a8bb 100644 --- a/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp +++ b/tests/auto/corelib/io/qnodebug/tst_qnodebug.cpp @@ -65,7 +65,7 @@ void tst_QNoDebug::noDebugOutput() const void tst_QNoDebug::streaming() const { QDateTime dt(QDate(1,2,3),QTime(4,5,6)); - const QByteArray debugString = dt.toString(QStringViewLiteral("yyyy-MM-dd HH:mm:ss.zzz t")).toLatin1(); + const QByteArray debugString = dt.toString(u"yyyy-MM-dd HH:mm:ss.zzz t").toLatin1(); const QByteArray message = "QDateTime(" + debugString + " Qt::LocalTime)"; QTest::ignoreMessage(QtWarningMsg, message.constData()); qWarning() << dt; diff --git a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp index 32306e8003..6381ce5ed0 100644 --- a/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp +++ b/tests/auto/corelib/serialization/qtextstream/tst_qtextstream.cpp @@ -2586,7 +2586,7 @@ void tst_QTextStream::stringview_write_operator_ToDevice() QBuffer buf; buf.open(QBuffer::WriteOnly); QTextStream stream(&buf); - const QStringView expected = QStringViewLiteral("expectedStringView"); + const QStringView expected = u"expectedStringView"; stream << expected; stream.flush(); QCOMPARE(buf.buffer().constData(), "expectedStringView"); diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp index ec8f2fc047..676c66df3e 100644 --- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp @@ -1459,8 +1459,8 @@ void tst_QLocale::dayOfWeek() QCOMPARE(QLocale::c().toString(date, "ddd"), shortName); QCOMPARE(QLocale::c().toString(date, "dddd"), longName); - QCOMPARE(QLocale::c().toString(date, QStringViewLiteral("ddd")), shortName); - QCOMPARE(QLocale::c().toString(date, QStringViewLiteral("dddd")), longName); + QCOMPARE(QLocale::c().toString(date, u"ddd"), shortName); + QCOMPARE(QLocale::c().toString(date, u"dddd"), longName); } void tst_QLocale::formatDate_data() diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index e4aa00f500..cce3e601cd 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -4763,7 +4763,7 @@ void tst_QString::arg() QCOMPARE( s4.arg("foo"), QLatin1String("[foo]") ); QCOMPARE( s5.arg(QLatin1String("foo")), QLatin1String("[foo]") ); - QCOMPARE( s6.arg(QStringViewLiteral("foo")), QLatin1String("[foo]") ); + QCOMPARE( s6.arg(u"foo"), QLatin1String("[foo]") ); QCOMPARE( s7.arg("foo"), QLatin1String("[foo]") ); QCOMPARE( s8.arg("foo"), QLatin1String("[foo %1]") ); QCOMPARE( s8.arg("foo").arg("bar"), QLatin1String("[foo bar]") ); @@ -4825,10 +4825,10 @@ void tst_QString::arg() QCOMPARE( QString("%1").arg("hello", -10), QLatin1String("hello ") ); QCOMPARE( QString("%1").arg(QLatin1String("hello"), -5), QLatin1String("hello") ); - QCOMPARE( QString("%1").arg(QStringViewLiteral("hello"), -2), QLatin1String("hello") ); + QCOMPARE( QString("%1").arg(u"hello", -2), QLatin1String("hello") ); QCOMPARE( QString("%1").arg("hello", 0), QLatin1String("hello") ); QCOMPARE( QString("%1").arg(QLatin1String("hello"), 2), QLatin1String("hello") ); - QCOMPARE( QString("%1").arg(QStringViewLiteral("hello"), 5), QLatin1String("hello") ); + QCOMPARE( QString("%1").arg(u"hello", 5), QLatin1String("hello") ); QCOMPARE( QString("%1").arg("hello", 10), QLatin1String(" hello") ); QCOMPARE( QString("%1%1").arg("hello"), QLatin1String("hellohello") ); QCOMPARE( QString("%2%1").arg("hello"), QLatin1String("%2hello") ); diff --git a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp index 794f39708a..5d95f43d6a 100644 --- a/tests/auto/corelib/text/qstringview/tst_qstringview.cpp +++ b/tests/auto/corelib/text/qstringview/tst_qstringview.cpp @@ -251,7 +251,7 @@ void tst_QStringView::constExpr() const Q_STATIC_ASSERT(sv2.empty()); } { - constexpr QStringView sv = QStringViewLiteral(""); + constexpr QStringView sv = u""; Q_STATIC_ASSERT(sv.size() == 0); Q_STATIC_ASSERT(!sv.isNull()); Q_STATIC_ASSERT(sv.empty()); @@ -263,7 +263,7 @@ void tst_QStringView::constExpr() const Q_STATIC_ASSERT(sv2.empty()); } { - constexpr QStringView sv = QStringViewLiteral("Hello"); + constexpr QStringView sv = u"Hello"; Q_STATIC_ASSERT(sv.size() == 5); Q_STATIC_ASSERT(!sv.empty()); Q_STATIC_ASSERT(!sv.isEmpty()); @@ -465,7 +465,7 @@ void tst_QStringView::arg() const #undef CHECK2 #undef CHECK1 - QCOMPARE(QStringViewLiteral(" %2 %2 %1 %3 ").arg(QLatin1Char('c'), QChar::CarriageReturn, u'C'), " \r \r c C "); + QCOMPARE(QStringView(u" %2 %2 %1 %3 ").arg(QLatin1Char('c'), QChar::CarriageReturn, u'C'), " \r \r c C "); } void tst_QStringView::fromQString() const @@ -662,9 +662,9 @@ void tst_QStringView::conversion_tests(String string) const void tst_QStringView::comparison() { - const QStringView aa = QStringViewLiteral("aa"); - const QStringView upperAa = QStringViewLiteral("AA"); - const QStringView bb = QStringViewLiteral("bb"); + const QStringView aa = u"aa"; + const QStringView upperAa = u"AA"; + const QStringView bb = u"bb"; QVERIFY(aa == aa); QVERIFY(aa != bb); From 7301e44161d8bb25410219a31405584c9492b83e Mon Sep 17 00:00:00 2001 From: Aapo Keskimolo Date: Mon, 29 Jul 2019 11:17:10 +0300 Subject: [PATCH 197/264] Convert dependencies.yaml to dict from list Change-Id: I8a9df23c5cc66568d17f3c53af40ace97cfe7ab6 Reviewed-by: Toni Saario Reviewed-by: Aapo Keskimolo --- dependencies.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies.yaml b/dependencies.yaml index 32cf5dda7e..c093387ce0 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -1 +1 @@ -dependencies: [] +dependencies: {} From 10611038900842061bfef8516b1a994b7ac05877 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Mon, 22 Jul 2019 21:24:19 +0300 Subject: [PATCH 198/264] qmake: Use a simple response file for ar on mingw MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change allows using custom flags for ar. For instance, it is now possible to create a thin archive by setting QMAKE_LIB += -T. This uses and extends commit d92c25b1b4ac0423a824715a08b2db2def4b6e25 which served a similar purpose for the linker. Change-Id: Ie1d6a0b957dc4809957726de00911c8d91647fab Reviewed-by: Jörg Bornemann --- qmake/generators/win32/mingw_make.cpp | 36 +++++++-------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index 746f3e9008..2175841264 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -131,7 +131,7 @@ QString MingwMakefileGenerator::installRoot() const return QStringLiteral("$(INSTALL_ROOT:@msyshack@%=%)"); } -void createLdResponseFile(const QString &fileName, const ProStringList &objList) +static void createResponseFile(const QString &fileName, const ProStringList &objList) { QString filePath = Option::output_dir + QDir::separator() + fileName; QFile file(filePath); @@ -155,23 +155,6 @@ void createLdResponseFile(const QString &fileName, const ProStringList &objList) } } -void createArObjectScriptFile(const QString &fileName, const QString &target, const ProStringList &objList) -{ - QString filePath = Option::output_dir + QDir::separator() + fileName; - QFile file(filePath); - if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { - QTextStream t(&file); - // ### quoting? - t << "CREATE " << target << endl; - for (ProStringList::ConstIterator it = objList.constBegin(); it != objList.constEnd(); ++it) { - t << "ADDMOD " << *it << endl; - } - t << "SAVE\n"; - t.flush(); - file.close(); - } -} - void MingwMakefileGenerator::writeMingwParts(QTextStream &t) { writeStandardParts(t); @@ -298,26 +281,25 @@ void MingwMakefileGenerator::writeObjectsPart(QTextStream &t) if (objmax.isEmpty() || project->values("OBJECTS").count() < objmax.toInt()) { objectsLinkLine = "$(OBJECTS)"; } else if (project->isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") { - QString ar_script_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET"); + QString ar_response_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET"); if (!var("BUILD_NAME").isEmpty()) { - ar_script_file += "." + var("BUILD_NAME"); + ar_response_file += "." + var("BUILD_NAME"); } if (!var("MAKEFILE").isEmpty()) - ar_script_file += "." + var("MAKEFILE"); + ar_response_file += "." + var("MAKEFILE"); // QMAKE_LIB is used for win32, including mingw, whereas QMAKE_AR is used on Unix. - // Strip off any options since the ar commands will be read from file. - QString ar_cmd = var("QMAKE_LIB").section(" ", 0, 0); + QString ar_cmd = var("QMAKE_LIB"); if (ar_cmd.isEmpty()) - ar_cmd = "ar"; - createArObjectScriptFile(ar_script_file, var("DEST_TARGET"), project->values("OBJECTS")); - objectsLinkLine = ar_cmd + " -M < " + escapeFilePath(ar_script_file); + ar_cmd = "ar -rc"; + createResponseFile(ar_response_file, project->values("OBJECTS")); + objectsLinkLine = ar_cmd + ' ' + var("DEST_TARGET") + " @" + escapeFilePath(ar_response_file); } else { QString ld_response_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET"); if (!var("BUILD_NAME").isEmpty()) ld_response_file += "." + var("BUILD_NAME"); if (!var("MAKEFILE").isEmpty()) ld_response_file += "." + var("MAKEFILE"); - createLdResponseFile(ld_response_file, project->values("OBJECTS")); + createResponseFile(ld_response_file, project->values("OBJECTS")); objectsLinkLine = "@" + escapeFilePath(ld_response_file); } Win32MakefileGenerator::writeObjectsPart(t); From 3fbb6a957227968951283107813271218058b719 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 23 Jul 2019 07:48:46 +0200 Subject: [PATCH 199/264] QWinRTFileEngine: Handle QIODevice::Truncate when opening files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTBUG-77095 Change-Id: I45b38fab779518c49b22077c493d8640572d40d9 Reviewed-by: André de la Rocha Reviewed-by: Maurice Kalinowski --- src/plugins/platforms/winrt/qwinrtfileengine.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp index e9b2a82763..962e4ab938 100644 --- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp +++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -196,7 +197,19 @@ bool QWinRTFileEngine::open(QIODevice::OpenMode openMode) hr = QWinRTFunctions::await(op, d->stream.GetAddressOf()); RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::OpenError, false); - d->openMode = openMode; + const ProcessOpenModeResult res = processOpenModeFlags(openMode); + if (!res.ok) { + setError(QFileDevice::OpenError, res.error); + return false; + } + d->openMode = res.openMode; + if (d->openMode & QIODevice::Truncate) { + if (!setSize(0)) { + close(); + setError(QFileDevice::OpenError, QLatin1String("Could not truncate file")); + return false; + } + } return SUCCEEDED(hr); } From 56b1cb0b040887c7f7a39561c1dc22c82af9ae7b Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 23 Jul 2019 11:10:59 +0200 Subject: [PATCH 200/264] Move processOpenModeFlags out of QFSFileEngine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The same logic is needed for QWinRTFileEngine. To be able to reuse the code, it was moved out of the class. Task-number: QTBUG-77095 Change-Id: If52b2fc8a0f3056d32fc693775565a1c3803b7d4 Reviewed-by: André de la Rocha Reviewed-by: Edward Welbourne --- src/corelib/io/qfsfileengine.cpp | 45 ++++++++++++++++++++------------ src/corelib/io/qfsfileengine_p.h | 10 ++++--- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 387990ed79..5d3bef9e70 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -167,19 +167,21 @@ QFSFileEngine::QFSFileEngine(QFSFileEnginePrivate &dd) /*! \internal */ -bool QFSFileEngine::processOpenModeFlags(QIODevice::OpenMode *mode) +ProcessOpenModeResult processOpenModeFlags(QIODevice::OpenMode openMode) { - QIODevice::OpenMode &openMode = *mode; + ProcessOpenModeResult result; + result.ok = false; if ((openMode & QFile::NewOnly) && (openMode & QFile::ExistingOnly)) { qWarning("NewOnly and ExistingOnly are mutually exclusive"); - setError(QFile::OpenError, QLatin1String("NewOnly and ExistingOnly are mutually exclusive")); - return false; + result.error = QLatin1String("NewOnly and ExistingOnly are mutually exclusive"); + return result; } if ((openMode & QFile::ExistingOnly) && !(openMode & (QFile::ReadOnly | QFile::WriteOnly))) { qWarning("ExistingOnly must be specified alongside ReadOnly, WriteOnly, or ReadWrite"); - setError(QFile::OpenError, QLatin1String("ExistingOnly must be specified alongside ReadOnly, WriteOnly, or ReadWrite")); - return false; + result.error = QLatin1String( + "ExistingOnly must be specified alongside ReadOnly, WriteOnly, or ReadWrite"); + return result; } // Either Append or NewOnly implies WriteOnly @@ -190,7 +192,9 @@ bool QFSFileEngine::processOpenModeFlags(QIODevice::OpenMode *mode) if ((openMode & QFile::WriteOnly) && !(openMode & (QFile::ReadOnly | QFile::Append | QFile::NewOnly))) openMode |= QFile::Truncate; - return true; + result.ok = true; + result.openMode = openMode; + return result; } /*! @@ -234,16 +238,19 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode) return false; } - if (!processOpenModeFlags(&openMode)) + const ProcessOpenModeResult res = processOpenModeFlags(openMode); + if (!res.ok) { + setError(QFileDevice::OpenError, res.error); return false; + } - d->openMode = openMode; + d->openMode = res.openMode; d->lastFlushFailed = false; d->tried_stat = 0; d->fh = 0; d->fd = -1; - return d->nativeOpen(openMode); + return d->nativeOpen(d->openMode); } /*! @@ -262,17 +269,20 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, FILE *fh, QFile::FileHand Q_D(QFSFileEngine); - if (!processOpenModeFlags(&openMode)) + const ProcessOpenModeResult res = processOpenModeFlags(openMode); + if (!res.ok) { + setError(QFileDevice::OpenError, res.error); return false; + } - d->openMode = openMode; + d->openMode = res.openMode; d->lastFlushFailed = false; d->closeFileHandle = (handleFlags & QFile::AutoCloseHandle); d->fileEntry.clear(); d->tried_stat = 0; d->fd = -1; - return d->openFh(openMode, fh); + return d->openFh(d->openMode, fh); } /*! @@ -321,10 +331,13 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, int fd, QFile::FileHandle { Q_D(QFSFileEngine); - if (!processOpenModeFlags(&openMode)) + const ProcessOpenModeResult res = processOpenModeFlags(openMode); + if (!res.ok) { + setError(QFileDevice::OpenError, res.error); return false; + } - d->openMode = openMode; + d->openMode = res.openMode; d->lastFlushFailed = false; d->closeFileHandle = (handleFlags & QFile::AutoCloseHandle); d->fileEntry.clear(); @@ -332,7 +345,7 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, int fd, QFile::FileHandle d->fd = -1; d->tried_stat = 0; - return d->openFd(openMode, fd); + return d->openFd(d->openMode, fd); } diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 6b091a8eef..5231b4fe6f 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -61,6 +61,13 @@ QT_BEGIN_NAMESPACE +struct ProcessOpenModeResult { + bool ok; + QIODevice::OpenMode openMode; + QString error; +}; +inline Q_CORE_EXPORT ProcessOpenModeResult processOpenModeFlags(QIODevice::OpenMode mode); + class QFSFileEnginePrivate; class Q_CORE_EXPORT QFSFileEngine : public QAbstractFileEngine @@ -131,9 +138,6 @@ public: protected: QFSFileEngine(QFSFileEnginePrivate &dd); - -private: - inline bool processOpenModeFlags(QIODevice::OpenMode *mode); }; class Q_AUTOTEST_EXPORT QFSFileEnginePrivate : public QAbstractFileEnginePrivate From c8bb8cb7614768156f9cc4bccc2df928d5430067 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Fri, 26 Jul 2019 18:16:33 +0200 Subject: [PATCH 201/264] Windows QPA: Fix detection of the Surface Pen eraser button The Surface Pen eraser button generates Meta+F18/19/20 keystrokes, but when it is not touching the screen the Fn WM_KEYDOWN message is eaten and only a Fn WM_KEYUP message with the previous state as "not pressed" is generated, which would be ignored. With this patch we detect this case and synthesize the expected key events to allow the button to be used in applications. Fixes: QTBUG-77153 Change-Id: I075f5cbb903cb36c9ec241ee1bb31d436b725e3a Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff --- .../platforms/windows/qwindowskeymapper.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp index c5af4d8042..da630005d6 100644 --- a/src/plugins/platforms/windows/qwindowskeymapper.cpp +++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp @@ -1301,7 +1301,23 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, MSG msg, || code == Qt::Key_Control || code == Qt::Key_Meta || code == Qt::Key_Alt)) { - // Someone ate the key down event + + // Workaround for QTBUG-77153: + // The Surface Pen eraser button generates Meta+F18/19/20 keystrokes, + // but when it is not touching the screen the Fn Down is eaten and only + // a Fn Up with the previous state as "not pressed" is generated, which + // would be ignored. We detect this case and synthesize the expected events. + if ((msg.lParam & 0x40000000) == 0 && + Qt::KeyboardModifier(state) == Qt::NoModifier && + ((code == Qt::Key_F18) || (code == Qt::Key_F19) || (code == Qt::Key_F20))) { + QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyPress, code, + Qt::MetaModifier, scancode, + quint32(msg.wParam), MetaLeft); + QWindowSystemInterface::handleExtendedKeyEvent(receiver, QEvent::KeyRelease, code, + Qt::NoModifier, scancode, + quint32(msg.wParam), 0); + result = true; + } } else { if (!code) code = asciiToKeycode(rec->ascii ? char(rec->ascii) : char(msg.wParam), state); From 93b845464fa7ac29c26e1835fd3a6cfac33d9a9d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 27 Jul 2019 11:06:59 +0300 Subject: [PATCH 202/264] QStringView: two fixes for newly-added toWCharArray() Amends e89fbd8c3aa50a24e5fc02ab710ccca67fce98e2. - While QString::data() never returns nullptr, QStringView::data() may, which makes calling QStringView{}.toWCharArray() UB on Windows (since memcpy's 2nd argument must never be nullptr, even if the size is zero). Fix by protecting the memcpy call. - QStringView, by design, does not use out-of-line member functions, because calling these forces the QStringView object onto the stack. Fix by making inline. Also use the more efficient qToStringViewIgnoringNull(), as the result does not depend on QString::isNull() (no characters are written either way), and add a missing article to the function's docs. Change-Id: I5d6b31361522812b0db8303b93c43d4b9ed11933 Reviewed-by: Edward Welbourne --- src/corelib/text/qstring.h | 14 +++++++++++++- src/corelib/text/qstringview.cpp | 14 ++------------ src/corelib/text/qstringview.h | 2 +- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h index 08930f73b5..06ebb05fc7 100644 --- a/src/corelib/text/qstring.h +++ b/src/corelib/text/qstring.h @@ -1122,7 +1122,19 @@ QT_WARNING_DISABLE_INTEL(111) // "statement is unreachable" inline int QString::toWCharArray(wchar_t *array) const { - return QStringView(*this).toWCharArray(array); + return qToStringViewIgnoringNull(*this).toWCharArray(array); +} + +int QStringView::toWCharArray(wchar_t *array) const +{ + if (sizeof(wchar_t) == sizeof(QChar)) { + if (auto src = data()) + memcpy(array, src, sizeof(QChar) * size()); + return size(); + } else { + return QString::toUcs4_helper(reinterpret_cast(data()), int(size()), + reinterpret_cast(array)); + } } QT_WARNING_POP diff --git a/src/corelib/text/qstringview.cpp b/src/corelib/text/qstringview.cpp index 8442bcdf1b..89cb4b32c0 100644 --- a/src/corelib/text/qstringview.cpp +++ b/src/corelib/text/qstringview.cpp @@ -867,11 +867,12 @@ QT_BEGIN_NAMESPACE */ /*! + \fn QStringView::toWCharArray(wchar_t *array) const \since 5.14 Transcribes this string into the given \a array. - Caller is responsible for ensuring \a array is large enough to hold the + The caller is responsible for ensuring \a array is large enough to hold the \c wchar_t encoding of this string (allocating the array with the same length as the string is always sufficient). The array is encoded in UTF-16 on platforms where \c wchar_t is 2 bytes wide (e.g. Windows); otherwise (Unix @@ -885,15 +886,4 @@ QT_BEGIN_NAMESPACE \sa QString::toWCharArray() */ -int QStringView::toWCharArray(wchar_t *array) const -{ - if (sizeof(wchar_t) == sizeof(QChar)) { - memcpy(array, data(), sizeof(QChar) * size()); - return size(); - } else { - return QString::toUcs4_helper(reinterpret_cast(data()), int(size()), - reinterpret_cast(array)); - } -} - QT_END_NAMESPACE diff --git a/src/corelib/text/qstringview.h b/src/corelib/text/qstringview.h index b84b2995b9..5a3acaa8c0 100644 --- a/src/corelib/text/qstringview.h +++ b/src/corelib/text/qstringview.h @@ -294,7 +294,7 @@ public: Q_REQUIRED_RESULT bool isRightToLeft() const noexcept { return QtPrivate::isRightToLeft(*this); } - Q_REQUIRED_RESULT Q_CORE_EXPORT int toWCharArray(wchar_t *array) const; + Q_REQUIRED_RESULT inline int toWCharArray(wchar_t *array) const; // defined in qstring.h // // STL compatibility API: From ce99361cc0260f9672ebfe92918f2a9727a6db3d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 26 May 2019 17:23:42 +0200 Subject: [PATCH 203/264] QEasingCurve: fix missing copy() override MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TCBEase is-a BezierEase, but overrides value(). It only performs additional checks and then calls the base class' implementation, but it feels wrong, like a bug waiting to manifest itself, that slicing should occur on cloning a TCBEase. Fix by adding the missing reimplmentation. Change-Id: I2524f51fec1850ff36ed706bc79e9592734d8680 Reviewed-by: Jan Arve Sæther --- src/corelib/tools/qeasingcurve.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp index 9169b5c7f1..2ae63fe135 100644 --- a/src/corelib/tools/qeasingcurve.cpp +++ b/src/corelib/tools/qeasingcurve.cpp @@ -907,6 +907,10 @@ struct TCBEase : public BezierEase return BezierEase::value(x); } + QEasingCurveFunction *copy() const override + { + return new TCBEase{*this}; + } }; struct ElasticEase : public QEasingCurveFunction From ac885a34ecd56b32788c6ca67ef657852bfa2308 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Mon, 29 Jul 2019 10:04:23 +0200 Subject: [PATCH 204/264] Revert "Fix comparisons of image with different color spaces" QImage comparison has always ignored differences in metadata. Introducing colorspace comparison can break backwards compatibility, as not all image formats or handlers have colorspace capability. This partially reverts commit 733ca2230c283cdfaae424eac481ddc33593f44f. Fixes: QTBUG-77205 Change-Id: I1d525a9727e84502624cd118f503eec7be306c99 Reviewed-by: Allan Sandfeld Jensen --- src/gui/image/qimage.cpp | 4 +--- tests/auto/gui/image/qimage/tst_qimage.cpp | 18 ------------------ 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 7ac4b3546e..cd2fe5bc10 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -3834,9 +3834,7 @@ bool QImage::operator==(const QImage & i) const return false; // obviously different stuff? - if (i.d->height != d->height || i.d->width != d->width) - return false; - if (i.d->format != d->format || i.d->colorSpace != d->colorSpace) + if (i.d->height != d->height || i.d->width != d->width || i.d->format != d->format) return false; if (d->format != Format_RGB32) { diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index e007a15419..441ec17412 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -232,8 +232,6 @@ private slots: void wideImage(); - void colorspaceEquality(); - #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) void toWinHBITMAP_data(); void toWinHBITMAP(); @@ -3620,22 +3618,6 @@ void tst_QImage::wideImage() // Qt6: Test that it actually works on 64bit architectures. } -void tst_QImage::colorspaceEquality() -{ - QImage image1(10, 10, QImage::Format_RGB32); - image1.fill(Qt::red); - QImage image2(image1); - QCOMPARE(image1, image2); - image1.setColorSpace(QColorSpace::SRgbLinear); - QVERIFY(image1 != image2); - image2.setColorSpace(QColorSpace::SRgbLinear); - QVERIFY(image1 == image2); - image1.setColorSpace(QColorSpace(QColorSpace::Gamut::DciP3D65, QColorSpace::TransferFunction::Gamma, 2.2f)); - QVERIFY(image1 != image2); - image2.setColorSpace(QColorSpace(QColorSpace::Gamut::DciP3D65, QColorSpace::TransferFunction::Gamma, 2.2001f)); - QVERIFY(image1 == image2); -} - #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) QT_BEGIN_NAMESPACE Q_GUI_EXPORT HBITMAP qt_imageToWinHBITMAP(const QImage &p, int hbitmapFormat = 0); From 7cf9f4e3d36dda31d1339990d6454dcf62e93055 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Mon, 1 Jul 2019 12:38:46 +0900 Subject: [PATCH 205/264] kms: Try to preserve existing output routing as weston would do This is basically a backport from weston: https://github.com/wayland-project/weston/commit/75487c2560dfca033d8d23649914efb4199356dd It states that: - preserving the existing CRTC -> encoder -> connector routing will make the startup faster - the existing routing may be set according to some device limitations Since the QtWayland implementation appears to be based off an old version of weston (maybe pre-2.0), this patch might look different from the latest weston implementation. But the idea stays the same. FWIW, this works around the issue I've seen on Renesas R-Car E3 (aka Ebisu) board. Without this patch, VGA1+HDMI1 setup would fail because the device reported possible_crtcs=1 (meaning {crtcs[0]}) for the second screen "HDMI1", but the crtcs[0] was already taken by the first screen "VGA1". No usable crtc/encoder pair for connector "HDMI1" With this patch, the crtcs[1] is paired with "VGA1" (as it is the existing routing), so the crtcs[0] can be allocated for "HDMI1". Change-Id: Ibd304a8b5efbe4a8aa94b2c5697fe2b399386280 Reviewed-by: Laszlo Agocs --- .../kmsconvenience/qkmsdevice.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/platformsupport/kmsconvenience/qkmsdevice.cpp b/src/platformsupport/kmsconvenience/qkmsdevice.cpp index 8cc7a539b5..1ba32895f8 100644 --- a/src/platformsupport/kmsconvenience/qkmsdevice.cpp +++ b/src/platformsupport/kmsconvenience/qkmsdevice.cpp @@ -66,6 +66,8 @@ enum OutputConfiguration { int QKmsDevice::crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector) { + int candidate = -1; + for (int i = 0; i < connector->count_encoders; i++) { drmModeEncoderPtr encoder = drmModeGetEncoder(m_dri_fd, connector->encoders[i]); if (!encoder) { @@ -73,19 +75,30 @@ int QKmsDevice::crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr co continue; } + quint32 encoderId = encoder->encoder_id; + quint32 crtcId = encoder->crtc_id; quint32 possibleCrtcs = encoder->possible_crtcs; drmModeFreeEncoder(encoder); for (int j = 0; j < resources->count_crtcs; j++) { bool isPossible = possibleCrtcs & (1 << j); bool isAvailable = !(m_crtc_allocator & (1 << j)); + // Preserve the existing CRTC -> encoder -> connector routing if + // any. It makes the initialization faster, and may be better + // since we have a very dumb picking algorithm. + bool isBestChoice = (!connector->encoder_id || + (connector->encoder_id == encoderId && + resources->crtcs[j] == crtcId)); - if (isPossible && isAvailable) + if (isPossible && isAvailable && isBestChoice) { return j; + } else if (isPossible && isAvailable) { + candidate = j; + } } } - return -1; + return candidate; } static const char * const connector_type_names[] = { // must match DRM_MODE_CONNECTOR_* From f4647b40ca9319508468ead8144116d0a5718ea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 29 Jul 2019 15:13:02 +0200 Subject: [PATCH 206/264] macOS: Respect QSurfaceFormat color space when creating NSWindow Task-number: QTBUG-47660 Change-Id: I90a2956bfaa52c361a3eba32f0ea19c0eca8c277 Reviewed-by: Simon Hausmann --- src/plugins/platforms/cocoa/qcocoawindow.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 42b662cfe4..b609fb3995 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -1647,6 +1647,9 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel) [nsWindow setDepthLimit:NSWindowDepthTwentyfourBitRGB]; } + if (format().colorSpace() == QSurfaceFormat::sRGBColorSpace) + nsWindow.colorSpace = NSColorSpace.sRGBColorSpace; + return nsWindow; } From 3e7463411e549100eee7abe2a8fae16fd965f8f6 Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 29 Jul 2019 14:27:16 +0200 Subject: [PATCH 207/264] Fix crash when the focus widget gets a focus proxy after the fact QApplicationPrivate::focus_widget became a dangling pointer in the following scenario: A widget first gets focus and later on gets a focus proxy. QApplicationPrivate::focus_widget was still pointing to the initial widget. Upon destruction, QWidget::hasFocus() [which follows to the focus proxy and then compares with focus_widget] was therefore false for both widgets. So QWidget::clearFocus() didn't call QApplicationPrivate::setFocusWidget(0) for either of them. As a result, focus_widget remained set, and became dangling. In real life, this happened with a QWebEngineView, which the application gave focus to upon creation. At that time it doesn't have a focus proxy yet. That happens later, in QWebEngineViewPrivate::widgetChanged. https://bugs.kde.org/show_bug.cgi?id=381793 Change-Id: Ifee610bb76a2d4d2797b98ece9bffe5fffe3c6a6 Reviewed-by: Volker Hilsheimer --- src/widgets/kernel/qwidget.cpp | 10 ++++ .../widgets/kernel/qwidget/tst_qwidget.cpp | 47 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 353a80d1c5..04290a4ce1 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -6436,8 +6436,18 @@ void QWidget::setFocusProxy(QWidget * w) } } + QWidget *oldDeepestFocusProxy = d_func()->deepestFocusProxy(); + if (!oldDeepestFocusProxy) + oldDeepestFocusProxy = this; + const bool changingAppFocusWidget = (QApplicationPrivate::focus_widget == oldDeepestFocusProxy); + d->createExtra(); d->extra->focus_proxy = w; + + if (changingAppFocusWidget) { + QWidget *newDeepestFocusProxy = d_func()->deepestFocusProxy(); + QApplicationPrivate::focus_widget = newDeepestFocusProxy ? newDeepestFocusProxy : this; + } } diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 73b1fd1865..a95d6e76b3 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -181,6 +181,8 @@ private slots: void tabOrderWithCompoundWidgets(); void tabOrderNoChange(); void tabOrderNoChange2(); + void appFocusWidgetWithFocusProxyLater(); + void appFocusWidgetWhenLosingFocusProxy(); #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) void activation(); #endif @@ -2031,6 +2033,51 @@ void tst_QWidget::tabOrderNoChange2() QCOMPARE(focusChainBackward, getFocusChain(&w, false)); } +void tst_QWidget::appFocusWidgetWithFocusProxyLater() +{ + // Given a lineedit without a focus proxy + QWidget window; + window.setWindowTitle(QTest::currentTestFunction()); + QLineEdit *lineEditFocusProxy = new QLineEdit(&window); + QLineEdit *lineEdit = new QLineEdit(&window); + lineEdit->setFocus(); + window.show(); + QApplication::setActiveWindow(&window); + QVERIFY(QTest::qWaitForWindowActive(&window)); + QCOMPARE(QApplication::focusWidget(), lineEdit); + + // When setting a focus proxy for the focus widget (like QWebEngineView does) + lineEdit->setFocusProxy(lineEditFocusProxy); + + // Then the focus widget should be updated + QCOMPARE(QApplication::focusWidget(), lineEditFocusProxy); + + // So that deleting the lineEdit and later the window, doesn't crash + delete lineEdit; + QCOMPARE(QApplication::focusWidget(), nullptr); +} + +void tst_QWidget::appFocusWidgetWhenLosingFocusProxy() +{ + // Given a lineedit with a focus proxy + QWidget window; + window.setWindowTitle(QTest::currentTestFunction()); + QLineEdit *lineEditFocusProxy = new QLineEdit(&window); + QLineEdit *lineEdit = new QLineEdit(&window); + lineEdit->setFocusProxy(lineEditFocusProxy); + lineEdit->setFocus(); + window.show(); + QApplication::setActiveWindow(&window); + QVERIFY(QTest::qWaitForWindowActive(&window)); + QCOMPARE(QApplication::focusWidget(), lineEditFocusProxy); + + // When unsetting the focus proxy + lineEdit->setFocusProxy(nullptr); + + // Then the application focus widget should be back to the lineedit + QCOMPARE(QApplication::focusWidget(), lineEdit); +} + #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) void tst_QWidget::activation() { From 080fbb55b5a4c78a24a1411ae2925d03add3cd17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 29 Jul 2019 16:00:43 +0200 Subject: [PATCH 208/264] qmake: Don't allow -framework without second argument when merging flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The linker doesn't support -framworkFoo, so neither should we. The correct syntax is -framework Foo. Change-Id: I3f39ffc067871ce058542bf0068274b35f7b51f6 Reviewed-by: Jörg Bornemann --- qmake/generators/unix/unixmake.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index b809bb6c19..3b6e87a2b6 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -498,14 +498,10 @@ UnixMakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags) // Make sure we keep the dependency order of libraries lflags[arch].removeAll(opt); lflags[arch].append(opt); - } else if (target_mode == TARG_MAC_MODE && opt.startsWith("-framework")) { - if (opt.length() > 10) { - opt = opt.mid(10).trimmed(); - } else { - opt = l.at(++lit); - if (opt.startsWith("-Xarch")) - opt = l.at(++lit); // The user has done the right thing and prefixed each part - } + } else if (target_mode == TARG_MAC_MODE && opt == "-framework") { + opt = l.at(++lit); + if (opt.startsWith("-Xarch")) + opt = l.at(++lit); // The user has done the right thing and prefixed each part for(int x = 0; x < lflags[arch].size(); ++x) { if (lflags[arch].at(x) == "-framework" && lflags[arch].at(++x) == opt) { lflags[arch].remove(x - 1, 2); From c2f041203f8cd8fec50e716872608ba1835243f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 16 Jan 2018 14:41:28 +0100 Subject: [PATCH 209/264] qmake: Keep -force_load with library when merging linker flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without treating -force_load as an option with an argument, we end up leaving stray -force_loads in the linker line, resulting in build failures when the following option is a random library then treated as a file path. Task-number: QTBUG-66091 Change-Id: I352c50ab67e32ef6b2b5c6a4f90455b20034e207 Reviewed-by: Jörg Bornemann --- qmake/generators/unix/unixmake.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index 3b6e87a2b6..d7c9413290 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -498,17 +498,20 @@ UnixMakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags) // Make sure we keep the dependency order of libraries lflags[arch].removeAll(opt); lflags[arch].append(opt); - } else if (target_mode == TARG_MAC_MODE && opt == "-framework") { + } else if (target_mode == TARG_MAC_MODE + && (opt == "-framework" || opt == "-force_load")) { + // Handle space separated options + ProString dashOpt = opt; opt = l.at(++lit); if (opt.startsWith("-Xarch")) opt = l.at(++lit); // The user has done the right thing and prefixed each part for(int x = 0; x < lflags[arch].size(); ++x) { - if (lflags[arch].at(x) == "-framework" && lflags[arch].at(++x) == opt) { + if (lflags[arch].at(x) == dashOpt && lflags[arch].at(++x) == opt) { lflags[arch].remove(x - 1, 2); break; } } - lflags[arch].append("-framework"); + lflags[arch].append(dashOpt); lflags[arch].append(opt); } else { lflags[arch].append(opt); From 036e9d66f50f829299ac98debbf42b255f3b810c Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Fri, 11 Jan 2019 23:48:11 +0100 Subject: [PATCH 210/264] Fix CC_Slider rendering on macOS QSlider rendering is currently broken as the context used to render it is not properly translated. This patch fixes that. Fixes: QTBUG-72970 Change-Id: I30896ceee1f37f6dfcf01a342d10af3bb279ac8a Reviewed-by: Timur Pocheptsov --- src/plugins/styles/mac/qmacstyle_mac.mm | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 258aba2cda..c162cca048 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -5273,9 +5273,20 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex } d->drawNSViewInRect(slider, opt->rect, p, ^(CGContextRef ctx, const CGRect &rect) { - if (isHorizontal && sl->upsideDown) { - CGContextTranslateCTM(ctx, rect.size.width, 0); - CGContextScaleCTM(ctx, -1, 1); + + // Since the GC is flipped, upsideDown means *not* inverted when vertical. + const bool verticalFlip = !isHorizontal && !sl->upsideDown; // FIXME: && !isSierraOrLater + + if (isHorizontal) { + if (sl->upsideDown) { + CGContextTranslateCTM(ctx, rect.size.width, rect.origin.y); + CGContextScaleCTM(ctx, -1, 1); + } else { + CGContextTranslateCTM(ctx, 0, rect.origin.y); + } + } else if (verticalFlip) { + CGContextTranslateCTM(ctx, rect.origin.x, rect.size.height); + CGContextScaleCTM(ctx, 1, -1); } if (hasDoubleTicks) { @@ -5286,9 +5297,6 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex CGContextTranslateCTM(ctx, 1, 0); } - // Since the GC is flipped, upsideDown means *not* inverted when vertical. - const bool verticalFlip = !isHorizontal && !sl->upsideDown; // FIXME: && !isSierraOrLater - #if 0 // FIXME: Sadly, this part doesn't work. It seems to somehow polute the // NSSlider's internal state and, when we need to use the "else" part, @@ -5352,9 +5360,6 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex // This ain't HIG kosher: force round knob look. if (hasDoubleTicks) slider.numberOfTickMarks = 0; - // Draw the knob in the symmetrical position instead of flipping. - if (verticalFlip) - slider.intValue = slider.maxValue - slider.intValue + slider.minValue; [cell drawKnob]; } } From 889b1c4b28644c6112924cde751f4df38f697027 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Mon, 10 Jun 2019 09:30:10 +0200 Subject: [PATCH 211/264] test: migrate QSqlDatabase test to QRegularExpression This is part of the migration of qtbase from QRexExp to QRegularExpression. Task-number: QTBUG-72587 Change-Id: Id82e103d4076fed63c871385b2b0f21c04735d00 Reviewed-by: Andy Shaw Reviewed-by: Edward Welbourne --- tests/auto/sql/kernel/qsqldatabase/tst_databases.h | 13 +++++++------ .../sql/kernel/qsqldatabase/tst_qsqldatabase.cpp | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h index 55875359ff..174db2863e 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h +++ b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h @@ -34,7 +34,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -511,13 +512,13 @@ public: QSqlQuery q( "SELECT banner FROM v$version", db ); q.next(); - QRegExp vers( "([0-9]+)\\.[0-9\\.]+[0-9]" ); - - if ( vers.indexIn( q.value( 0 ).toString() ) ) { + QRegularExpression vers("([0-9]+)\\.[0-9\\.]+[0-9]"); + QRegularExpressionMatch match = vers.match(q.value(0).toString()); + if (match.hasMatch()) { bool ok; - ver = vers.cap( 1 ).toInt( &ok ); + ver = match.captured(1).toInt(&ok); - if ( !ok ) + if (!ok) ver = -1; } diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp index f309231b10..c59250e36e 100644 --- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -228,7 +228,7 @@ struct FieldDef { QString fieldName() const { QString rt = typeName; - rt.replace(QRegExp("\\s"), QString("_")); + rt.replace(QRegularExpression("\\s"), QString("_")); int i = rt.indexOf(QLatin1Char('(')); if (i == -1) i = rt.length(); From 1fcd8345ac5fcc47883c082fa1d39110e4b2cb55 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 25 Jul 2019 14:00:04 +0300 Subject: [PATCH 212/264] QPNGImageWriter: fix compilation with libpng 1.4 Amends 83de6d0ce5baceb7739b89254cba4acc6fdab47d. The interface of png_set_iCCP() changed source-incompatibly from 1.4 to 1.5. #ifdef on the version as is done elsewhere in the code. Drop a no-op C cast. Also add PNG_iCCP_SUPPORTED around the new code, as that check is used elsewhere in the code. Change-Id: Ie203bd9eebea5697f426fa3e95591f86346b2685 Reviewed-by: Eirik Aavitsland --- src/gui/image/qpnghandler.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 023696a401..8cfcbdb2d2 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -980,6 +980,7 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i bpc, // per channel color_type, 0, 0, 0); // sets #channels +#ifdef PNG_iCCP_SUPPORTED if (image.colorSpace().isValid()) { QColorSpace cs = image.colorSpace(); // Support the old gamma making it override transferfunction. @@ -995,9 +996,17 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i if (iccProfileName.isEmpty()) iccProfileName = QByteArrayLiteral("Custom"); QByteArray iccProfile = cs.iccProfile(); - png_set_iCCP(png_ptr, info_ptr, (png_const_charp)iccProfileName.constData(), - PNG_COMPRESSION_TYPE_BASE, (png_const_bytep)iccProfile.constData(), iccProfile.length()); - } else if (gamma != 0.0) { + png_set_iCCP(png_ptr, info_ptr, + #if PNG_LIBPNG_VER < 10500 + iccProfileName.data(), PNG_COMPRESSION_TYPE_BASE, iccProfile.data(), + #else + iccProfileName.constData(), PNG_COMPRESSION_TYPE_BASE, + (png_const_bytep)iccProfile.constData(), + #endif + iccProfile.length()); + } else +#endif + if (gamma != 0.0) { png_set_gAMA(png_ptr, info_ptr, 1.0/gamma); } From 4628351c3f53e3239e304b906a0f6f9a6daab985 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 7 Jun 2019 18:54:33 +0200 Subject: [PATCH 213/264] QStandardPaths: don't build a QHash just to look up one key The code parses a file, looking for XDG_*_DIR entries and stores each one's key and raw value in a QHash. After parsing, it, however, looked up exactly once, by a key it could have known all along. So, move the key computation before the opening of the file, and look for the correct key directly, consciously striving to continue to find, as the old code implicitly did, the last entry, since man 5 user-dirs.dirs explains: > The format of user-dirs.dirs is designed to allow direct sourcing of > this file in shell scripts. Which means last one wins. Port to QStringView API of QRegularExpression, too. Change-Id: Ie92b689b5b9221df918c67b96f2f6a09827e7b1e Reviewed-by: Volker Hilsheimer Reviewed-by: David Faure --- src/corelib/io/qstandardpaths_unix.cpp | 75 ++++++++++++-------------- 1 file changed, 34 insertions(+), 41 deletions(-) diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp index f4f8787968..6425890e3f 100644 --- a/src/corelib/io/qstandardpaths_unix.cpp +++ b/src/corelib/io/qstandardpaths_unix.cpp @@ -71,6 +71,28 @@ static void appendOrganizationAndApp(QString &path) #endif } +#if QT_CONFIG(regularexpression) +static QLatin1String xdg_key_name(QStandardPaths::StandardLocation type) +{ + switch (type) { + case QStandardPaths::DesktopLocation: + return QLatin1String("DESKTOP"); + case QStandardPaths::DocumentsLocation: + return QLatin1String("DOCUMENTS"); + case QStandardPaths::PicturesLocation: + return QLatin1String("PICTURES"); + case QStandardPaths::MusicLocation: + return QLatin1String("MUSIC"); + case QStandardPaths::MoviesLocation: + return QLatin1String("VIDEOS"); + case QStandardPaths::DownloadLocation: + return QLatin1String("DOWNLOAD"); + default: + return QLatin1String(); + } +} +#endif + QString QStandardPaths::writableLocation(StandardLocation type) { switch (type) { @@ -182,61 +204,32 @@ QString QStandardPaths::writableLocation(StandardLocation type) if (xdgConfigHome.isEmpty()) xdgConfigHome = QDir::homePath() + QLatin1String("/.config"); QFile file(xdgConfigHome + QLatin1String("/user-dirs.dirs")); - if (!isTestModeEnabled() && file.open(QIODevice::ReadOnly)) { - QHash lines; + const QLatin1String key = xdg_key_name(type); + if (!key.isEmpty() && !isTestModeEnabled() && file.open(QIODevice::ReadOnly)) { QTextStream stream(&file); // Only look for lines like: XDG_DESKTOP_DIR="$HOME/Desktop" QRegularExpression exp(QLatin1String("^XDG_(.*)_DIR=(.*)$")); + QString result; while (!stream.atEnd()) { const QString &line = stream.readLine(); QRegularExpressionMatch match = exp.match(line); - if (match.hasMatch()) { - const QStringList lst = match.capturedTexts(); - const QString key = lst.at(1); - QString value = lst.at(2); + if (match.hasMatch() && match.capturedView(1) == key) { + QStringView value = match.capturedView(2); if (value.length() > 2 && value.startsWith(QLatin1Char('\"')) && value.endsWith(QLatin1Char('\"'))) value = value.mid(1, value.length() - 2); - // Store the key and value: "DESKTOP", "$HOME/Desktop" - lines[key] = value; - } - } - - QString key; - switch (type) { - case DesktopLocation: - key = QLatin1String("DESKTOP"); - break; - case DocumentsLocation: - key = QLatin1String("DOCUMENTS"); - break; - case PicturesLocation: - key = QLatin1String("PICTURES"); - break; - case MusicLocation: - key = QLatin1String("MUSIC"); - break; - case MoviesLocation: - key = QLatin1String("VIDEOS"); - break; - case DownloadLocation: - key = QLatin1String("DOWNLOAD"); - break; - default: - break; - } - if (!key.isEmpty()) { - QString value = lines.value(key); - if (!value.isEmpty()) { // value can start with $HOME if (value.startsWith(QLatin1String("$HOME"))) - value = QDir::homePath() + value.midRef(5); - if (value.length() > 1 && value.endsWith(QLatin1Char('/'))) - value.chop(1); - return value; + result = QDir::homePath() + value.mid(5); + else + result = value.toString(); + if (result.length() > 1 && result.endsWith(QLatin1Char('/'))) + result.chop(1); } } + if (!result.isNull()) + return result; } #endif // QT_CONFIG(regularexpression) From 353a6946b19c5e4ee54cc37e4b34685cacd77a3c Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 27 Jul 2019 12:30:08 +0300 Subject: [PATCH 214/264] qstringalgorithms.h: add pure, noexcept, constexpr ... where they were missing. Change-Id: I58c32e57675b5d5ee500722933ef4a356a679e46 Reviewed-by: Volker Hilsheimer --- src/corelib/text/qstring.cpp | 2 +- src/corelib/text/qstring.h | 2 +- src/corelib/text/qstringalgorithms.h | 11 ++++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 44c6582d63..375843e36e 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -11438,7 +11438,7 @@ bool QStringRef::isRightToLeft() const \sa QString::isRightToLeft() */ -bool QtPrivate::isRightToLeft(QStringView string) +bool QtPrivate::isRightToLeft(QStringView string) noexcept { const ushort *p = reinterpret_cast(string.data()); const ushort * const end = p + string.size(); diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h index 06ebb05fc7..88286b902a 100644 --- a/src/corelib/text/qstring.h +++ b/src/corelib/text/qstring.h @@ -235,7 +235,7 @@ QT_DEPRECATED_X("Use QLatin1String") typedef QLatin1String QLatin1Literal; // // QLatin1String inline implementations // -inline bool QtPrivate::isLatin1(QLatin1String) noexcept +Q_DECL_CONSTEXPR bool QtPrivate::isLatin1(QLatin1String) noexcept { return true; } // diff --git a/src/corelib/text/qstringalgorithms.h b/src/corelib/text/qstringalgorithms.h index 2b480b1e4c..d54e376aa9 100644 --- a/src/corelib/text/qstringalgorithms.h +++ b/src/corelib/text/qstringalgorithms.h @@ -92,12 +92,13 @@ Q_REQUIRED_RESULT Q_CORE_EXPORT QByteArray convertToLatin1(QStringView str); Q_REQUIRED_RESULT Q_CORE_EXPORT QByteArray convertToUtf8(QStringView str); Q_REQUIRED_RESULT Q_CORE_EXPORT QByteArray convertToLocal8Bit(QStringView str); Q_REQUIRED_RESULT Q_CORE_EXPORT QVector convertToUcs4(QStringView str); -Q_REQUIRED_RESULT Q_CORE_EXPORT bool isRightToLeft(QStringView string); -Q_REQUIRED_RESULT Q_CORE_EXPORT bool isAscii(QLatin1String s) noexcept; -Q_REQUIRED_RESULT Q_CORE_EXPORT bool isAscii(QStringView s) noexcept; -Q_REQUIRED_RESULT bool isLatin1(QLatin1String s) noexcept; // in qstring.h -Q_REQUIRED_RESULT Q_CORE_EXPORT bool isLatin1(QStringView s) noexcept; +Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isRightToLeft(QStringView string) noexcept; + +Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isAscii(QLatin1String s) noexcept; +Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isAscii(QStringView s) noexcept; +Q_REQUIRED_RESULT Q_DECL_CONSTEXPR inline bool isLatin1(QLatin1String s) noexcept; +Q_REQUIRED_RESULT Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isLatin1(QStringView s) noexcept; } // namespace QtPRivate From afb8ba3fd22ca86ec3438a04c08353c9ddcaca1a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 27 Jul 2019 11:00:48 +0300 Subject: [PATCH 215/264] QStringView: clean up storage_type Now that all supported compilers support char16_t, we don't need the storage_type == wchar_t hack for MSVC anymore. Remove it. Adapt docs. Change-Id: I55df6c8a9fa5a9c7e6f53ba89f3850956b369061 Reviewed-by: Edward Welbourne Reviewed-by: Ville Voutilainen --- src/corelib/text/qstringview.cpp | 8 +++----- src/corelib/text/qstringview.h | 6 ------ 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/corelib/text/qstringview.cpp b/src/corelib/text/qstringview.cpp index 89cb4b32c0..75de827583 100644 --- a/src/corelib/text/qstringview.cpp +++ b/src/corelib/text/qstringview.cpp @@ -57,9 +57,8 @@ QT_BEGIN_NAMESPACE The UTF-16 string may be represented as an array (or an array-compatible data-structure such as QString, - std::basic_string, etc.) of QChar, \c ushort, \c char16_t (on compilers that - support C++11 Unicode strings) or (on platforms, such as Windows, - where it is a 16-bit type) \c wchar_t. + std::basic_string, etc.) of QChar, \c ushort, \c char16_t or + (on platforms, such as Windows, where it is a 16-bit type) \c wchar_t. QStringView is designed as an interface type; its main use-case is as a function parameter type. When QStringViews are used as automatic @@ -115,8 +114,7 @@ QT_BEGIN_NAMESPACE /*! \typedef QStringView::storage_type - Alias for \c{char16_t} for non-Windows or if Q_COMPILER_UNICODE_STRINGS - is defined. Otherwise, alias for \c{wchar_t}. + Alias for \c{char16_t}. */ /*! diff --git a/src/corelib/text/qstringview.h b/src/corelib/text/qstringview.h index 5a3acaa8c0..0a82ac4201 100644 --- a/src/corelib/text/qstringview.h +++ b/src/corelib/text/qstringview.h @@ -62,9 +62,7 @@ struct IsCompatibleCharTypeHelper : std::integral_constant::value || std::is_same::value || -#if defined(Q_COMPILER_UNICODE_STRINGS) std::is_same::value || -#endif (std::is_same::value && sizeof(wchar_t) == sizeof(QChar))> {}; template struct IsCompatibleCharType @@ -105,11 +103,7 @@ struct IsCompatibleStdBasicString class QStringView { public: -#if defined(Q_OS_WIN) && !defined(Q_COMPILER_UNICODE_STRINGS) - typedef wchar_t storage_type; -#else typedef char16_t storage_type; -#endif typedef const QChar value_type; typedef std::ptrdiff_t difference_type; typedef qsizetype size_type; From 111df3b5e04ffc6467be08bb84990aba48bf6b5a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 13 Jun 2019 12:55:17 +0200 Subject: [PATCH 216/264] QTestLib: Fix various clang warnings - Fix else after return/break - Fix use of int as boolean literal - Use range-based for in some cases - Avoid copies by using const-ref - Remove unnecessary null-check before delete Task-number: QTBUG-69413 Change-Id: I69f46e6deaa55ef70a8b3a61e6539c79a64aaa23 Reviewed-by: Edward Welbourne --- src/testlib/qbenchmark.cpp | 10 +++------- src/testlib/qbenchmarkmeasurement_p.h | 2 +- src/testlib/qbenchmarkperfevents_p.h | 2 +- src/testlib/qbenchmarkvalgrind.cpp | 4 ++-- src/testlib/qteamcitylogger.cpp | 4 +--- src/testlib/qtestblacklist.cpp | 5 ++--- src/testlib/qtestcase.cpp | 8 +++----- src/testlib/qxmltestlogger.cpp | 25 +++++++++++-------------- 8 files changed, 24 insertions(+), 36 deletions(-) diff --git a/src/testlib/qbenchmark.cpp b/src/testlib/qbenchmark.cpp index 9730e001be..aafdc64831 100644 --- a/src/testlib/qbenchmark.cpp +++ b/src/testlib/qbenchmark.cpp @@ -66,8 +66,7 @@ void QBenchmarkGlobalData::setMode(Mode mode) { mode_ = mode; - if (measurer) - delete measurer; + delete measurer; measurer = createMeasurer(); } @@ -98,11 +97,8 @@ QBenchmarkMeasurerBase * QBenchmarkGlobalData::createMeasurer() int QBenchmarkGlobalData::adjustMedianIterationCount() { - if (medianIterationCount != -1) { - return medianIterationCount; - } else { - return measurer->adjustMedianCount(1); - } + return medianIterationCount != -1 + ? medianIterationCount : measurer->adjustMedianCount(1); } diff --git a/src/testlib/qbenchmarkmeasurement_p.h b/src/testlib/qbenchmarkmeasurement_p.h index cecf97963b..1e2b82c25d 100644 --- a/src/testlib/qbenchmarkmeasurement_p.h +++ b/src/testlib/qbenchmarkmeasurement_p.h @@ -66,7 +66,7 @@ public: virtual bool isMeasurementAccepted(qint64 measurement) = 0; virtual int adjustIterationCount(int suggestion) = 0; virtual int adjustMedianCount(int suggestion) = 0; - virtual bool repeatCount() { return 1; } + virtual bool repeatCount() { return true; } virtual bool needsWarmupIteration() { return false; } virtual QTest::QBenchmarkMetric metricType() = 0; }; diff --git a/src/testlib/qbenchmarkperfevents_p.h b/src/testlib/qbenchmarkperfevents_p.h index 15b946ad26..3f27161ef5 100644 --- a/src/testlib/qbenchmarkperfevents_p.h +++ b/src/testlib/qbenchmarkperfevents_p.h @@ -67,7 +67,7 @@ public: bool isMeasurementAccepted(qint64 measurement) override; int adjustIterationCount(int suggestion) override; int adjustMedianCount(int suggestion) override; - bool repeatCount() override { return 1; } + bool repeatCount() override { return true; } bool needsWarmupIteration() override { return true; } QTest::QBenchmarkMetric metricType() override; diff --git a/src/testlib/qbenchmarkvalgrind.cpp b/src/testlib/qbenchmarkvalgrind.cpp index 0dac804338..44888c4d30 100644 --- a/src/testlib/qbenchmarkvalgrind.cpp +++ b/src/testlib/qbenchmarkvalgrind.cpp @@ -168,7 +168,7 @@ QString QBenchmarkValgrindUtils::outFileBase(qint64 pid) // Returns \c true upon success, otherwise false. bool QBenchmarkValgrindUtils::runCallgrindSubProcess(const QStringList &origAppArgs, int &exitCode) { - const QString execFile(origAppArgs.at(0)); + const QString &execFile = origAppArgs.at(0); QStringList args; args << QLatin1String("--tool=callgrind") << QLatin1String("--instr-atstart=yes") << QLatin1String("--quiet") @@ -177,7 +177,7 @@ bool QBenchmarkValgrindUtils::runCallgrindSubProcess(const QStringList &origAppA // pass on original arguments that make sense (e.g. avoid wasting time producing output // that will be ignored anyway) ... for (int i = 1; i < origAppArgs.size(); ++i) { - const QString arg(origAppArgs.at(i)); + const QString &arg = origAppArgs.at(i); if (arg == QLatin1String("-callgrind")) continue; args << arg; // ok to pass on diff --git a/src/testlib/qteamcitylogger.cpp b/src/testlib/qteamcitylogger.cpp index 6c0605130b..8a77143454 100644 --- a/src/testlib/qteamcitylogger.cpp +++ b/src/testlib/qteamcitylogger.cpp @@ -222,9 +222,7 @@ QString QTeamCityLogger::tcEscapedString(const QString &str) const { QString formattedString; - for (int i = 0; i < str.length(); i++) { - QChar ch = str.at(i); - + for (QChar ch : str) { switch (ch.toLatin1()) { case '\n': formattedString.append(QLatin1String("|n")); diff --git a/src/testlib/qtestblacklist.cpp b/src/testlib/qtestblacklist.cpp index 73757a844c..9b7c2495d4 100644 --- a/src/testlib/qtestblacklist.cpp +++ b/src/testlib/qtestblacklist.cpp @@ -210,11 +210,10 @@ static bool checkCondition(const QByteArray &condition) static const QSet matchedConditions = activeConditions(); QList conds = condition.split(' '); - for (int i = 0; i < conds.size(); ++i) { - QByteArray c = conds.at(i); + for (QByteArray c : conds) { bool result = c.startsWith('!'); if (result) - c = c.mid(1); + c.remove(0, 1); result ^= matchedConditions.contains(c); if (!result) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index a3141ba067..52eb04b109 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1040,7 +1040,7 @@ public: void run() override { QMutexLocker locker(&mutex); waitCondition.wakeAll(); - while (1) { + while (true) { int t = timeout.loadRelaxed(); if (!t) break; @@ -1273,10 +1273,8 @@ char *toHexRepresentation(const char *ba, int length) ++o; if (i == len) break; - else { - result[o] = ' '; - ++o; - } + result[o] = ' '; + ++o; } return result; diff --git a/src/testlib/qxmltestlogger.cpp b/src/testlib/qxmltestlogger.cpp index 84126c10eb..763cea327b 100644 --- a/src/testlib/qxmltestlogger.cpp +++ b/src/testlib/qxmltestlogger.cpp @@ -180,23 +180,20 @@ inline static bool isEmpty(const char *str) static const char *incidentFormatString(bool noDescription, bool noTag) { if (noDescription) { - if (noTag) - return "\n"; - else - return "\n" + return noTag + ? "\n" + : "\n" " \n" "\n"; - } else { - if (noTag) - return "\n" - " \n" - "\n"; - else - return "\n" - " \n" - " \n" - "\n"; } + return noTag + ? "\n" + " \n" + "\n" + : "\n" + " \n" + " \n" + "\n"; } static const char *benchmarkResultFormatString() From 31753adebe0f19b90f332e81e1a9b063b40f982d Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 30 Jul 2019 08:59:15 +0200 Subject: [PATCH 217/264] Revert "Fontconfig font database: Short-circuit matching by filename" This reverts commit eea99e1e8f3eb67fda35dd3a656fe9b5a9be84f2. The call to FcFreeTypeQuery() takes over 300 ms for NotoSansCJK-Regular.ttc and friends, so in the current state, this change cannot be used. I am not sure why these file in particular takes so long, but it might be because it is large (around 19MB) or because it is a font collection. The original fix was intended to be a smaller performance optimization, but it has added over 2 seconds startup time to simple applications showing Chinese text, so we revert it for now and it can be resubmitted later when the problems have been ironed out. Task-number: QTBUG-77108 Change-Id: Ibb2ef799573d7effd1595d788939fe33d82cc923 Reviewed-by: Allan Sandfeld Jensen --- .../fontconfig/qfontconfigdatabase.cpp | 88 +++++++------------ 1 file changed, 30 insertions(+), 58 deletions(-) diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index e28b40c240..7abf295782 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -927,66 +927,38 @@ void QFontconfigDatabase::setupFontEngine(QFontEngineFT *engine, const QFontDef antialias = antialiasingEnabled - 1; } - // try to find a match for fid - const QFontEngine::FaceId fid = engine->faceId(); - FcPattern *pattern = FcPatternCreate(); - FcPattern *match = nullptr; - - // try a trivial match by filename - FC_FILE is highest priority, so if it matches, FcFontMatch - // will just find the file (fine) and spend a millisecond or so doing unnecessary work (bad). - if (!fid.filename.isEmpty() && QFile::exists(QString::fromUtf8(fid.filename))) { - FcBlanks *blanks = FcConfigGetBlanks(nullptr); - int count = 0; - FcPattern *fileMatch = FcFreeTypeQuery((const FcChar8 *)fid.filename.data(), fid.index, - blanks, &count); - if (fileMatch) { - // Apply Fontconfig configuration - FcFreeTypeQuery only returns information stored in - // the font file, we also want to respect system and user settings. - FcConfigSubstitute(0, pattern, FcMatchPattern); - FcDefaultSubstitute(pattern); - match = FcFontRenderPrepare(0, pattern, fileMatch); - FcPatternDestroy(fileMatch); - } - } - - if (!match) { - FcValue value; - - // Fontconfig rules might process this information for arbitrary purposes, so add it, - // even though we already know that it doesn't match an existing file. - if (!fid.filename.isEmpty()) { - value.type = FcTypeString; - value.u.s = (const FcChar8 *)fid.filename.data(); - FcPatternAdd(pattern, FC_FILE, value, true); - - value.type = FcTypeInteger; - value.u.i = fid.index; - FcPatternAdd(pattern, FC_INDEX, value, true); - } - - const QByteArray cs = fontDef.family.toUtf8(); - value.type = FcTypeString; - value.u.s = (const FcChar8 *)cs.data(); - FcPatternAdd(pattern, FC_FAMILY, value, true); - - if (fontDef.pixelSize > 0.1) { - value.type = FcTypeDouble; - value.u.d = fontDef.pixelSize; - FcPatternAdd(pattern, FC_PIXEL_SIZE, value, true); - } - - FcResult result; - - FcConfigSubstitute(0, pattern, FcMatchPattern); - FcDefaultSubstitute(pattern); - - match = FcFontMatch(0, pattern, &result); - } - QFontEngine::GlyphFormat format; + // try and get the pattern + FcPattern *pattern = FcPatternCreate(); + + FcValue value; + value.type = FcTypeString; + QByteArray cs = fontDef.family.toUtf8(); + value.u.s = (const FcChar8 *)cs.data(); + FcPatternAdd(pattern,FC_FAMILY,value,true); + + QFontEngine::FaceId fid = engine->faceId(); + + if (!fid.filename.isEmpty()) { + value.u.s = (const FcChar8 *)fid.filename.data(); + FcPatternAdd(pattern,FC_FILE,value,true); + + value.type = FcTypeInteger; + value.u.i = fid.index; + FcPatternAdd(pattern,FC_INDEX,value,true); + } + + if (fontDef.pixelSize > 0.1) + FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontDef.pixelSize); + + FcResult result; + + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + + FcPattern *match = FcFontMatch(0, pattern, &result); if (match) { - engine->setDefaultHintStyle(defaultHintStyleFromMatch( - (QFont::HintingPreference)fontDef.hintingPreference, match, useXftConf)); + engine->setDefaultHintStyle(defaultHintStyleFromMatch((QFont::HintingPreference)fontDef.hintingPreference, match, useXftConf)); FcBool fc_autohint; if (FcPatternGetBool(match, FC_AUTOHINT,0, &fc_autohint) == FcResultMatch) From 4fa0b415237040d806758ab5374055ab2c32d84c Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 23 Jul 2019 12:03:27 +0200 Subject: [PATCH 218/264] uic: Avoid use of Q_UNUSED in the generated code Instead, use (void)x; directly. The current use of Q_UNUSED(x); generates warnings for an empty statement the expansion of Q_UNUSED contains a semicolon already. Emitting Q_UNUSED(x) without the extra semicolon would be an option, too, but as the future of Q_UNUSED's embedded semicolon seems unclear right now, avoid its use altogether. The change affects only generated code that's barely ever read by a human, so the overall utility of "improved readability" of Q_UNUSED in that place is questionable anyway. Change-Id: I332527ed7c202f779bd82290517837e3ecf09a08 Reviewed-by: Jarek Kobus --- src/tools/uic/cpp/cppwriteinitialization.cpp | 5 +++-- tests/auto/tools/uic/baseline/qfiledialog.ui.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index d16c859eed..fd5f8c9017 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -547,10 +547,11 @@ void WriteInitialization::acceptUI(DomUI *node) m_output << m_option.indent << language::endFunctionDefinition("setupUi"); if (!m_mainFormUsedInRetranslateUi && language::language() == Language::Cpp) { + // Mark varName as unused to avoid compiler warnings. m_refreshInitialization += m_indent; - m_refreshInitialization += QLatin1String("Q_UNUSED("); + m_refreshInitialization += QLatin1String("(void)"); m_refreshInitialization += varName ; - m_refreshInitialization += QLatin1String(");\n"); + m_refreshInitialization += QLatin1String(";\n"); } m_output << m_option.indent diff --git a/tests/auto/tools/uic/baseline/qfiledialog.ui.h b/tests/auto/tools/uic/baseline/qfiledialog.ui.h index 9e51ee6a7c..52f8d25c75 100644 --- a/tests/auto/tools/uic/baseline/qfiledialog.ui.h +++ b/tests/auto/tools/uic/baseline/qfiledialog.ui.h @@ -291,7 +291,7 @@ public: detailModeButton->setToolTip(QCoreApplication::translate("QFileDialog", "Detail View", nullptr)); #endif // QT_CONFIG(tooltip) fileTypeLabel->setText(QCoreApplication::translate("QFileDialog", "Files of type:", nullptr)); - Q_UNUSED(QFileDialog); + (void)QFileDialog; } // retranslateUi }; From 23841083e33c85baed3441c7cc80dafcf5bea0d9 Mon Sep 17 00:00:00 2001 From: Paul Wicking Date: Tue, 23 Jul 2019 13:32:31 +0200 Subject: [PATCH 219/264] Doc build: overcome command-line length limitation on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Windows, create a file containing include paths for QDoc in cases where number of include paths exceed 30. Based on how moc does this. Task-number: QTBUG-68259 Change-Id: I0d03fab4b809174cb6b48c36ee9f8880ff294ff4 Reviewed-by: Edward Welbourne Reviewed-by: Jörg Bornemann Reviewed-by: Martin Smith --- mkspecs/features/qt_docs.prf | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/mkspecs/features/qt_docs.prf b/mkspecs/features/qt_docs.prf index 3b74cd4dd5..deb4ac2829 100644 --- a/mkspecs/features/qt_docs.prf +++ b/mkspecs/features/qt_docs.prf @@ -27,6 +27,24 @@ QT_TOOL_ENV = qtver qtmver qtvertag qtdocs builddir qtPrepareTool(QDOC, qdoc) QT_TOOL_ENV = +# On Windows, put the includes into a .inc file which QDoc will read, if the project +# has too many includes. We do this to overcome a command-line limit on Windows. +WIN_INCLUDETEMP= +INCLUDE_PATHS=$$INCPATH +win32:count(INCLUDE_PATHS, 30, >) { + WIN_INCLUDETEMP = $$OUT_PWD/qdocincludepaths.inc + WIN_INCLUDETEMP_CONTENT = + for (inc, INCLUDE_PATHS): \ + WIN_INCLUDETEMP_CONTENT += -I$$inc + write_file($$absolute_path($$WIN_INCLUDETEMP, $$OUT_PWD), WIN_INCLUDETEMP_CONTENT)|error() +} + +isEmpty(WIN_INCLUDETEMP) { + QDOC_INCLUDE_PATHS=$(INCPATH) +} else { + QDOC_INCLUDE_PATHS=@$$shell_quote($$WIN_INCLUDETEMP) +} + !build_online_docs: qtPrepareTool(QHELPGENERATOR, qhelpgenerator) qtPrepareTool(QTATTRIBUTIONSSCANNER, qtattributionsscanner) @@ -75,12 +93,13 @@ qtattributionsscanner.CONFIG += phony QMAKE_EXTRA_TARGETS += qtattributionsscanner doc_command = $$QDOC $$QMAKE_DOCS + prepare_docs { - prepare_docs.commands += $$doc_command -prepare $$PREP_DOC_INDEXES -no-link-errors $(INCPATH) - generate_docs.commands += $$doc_command -generate $$DOC_INDEXES $(INCPATH) + prepare_docs.commands += $$doc_command -prepare $$PREP_DOC_INDEXES -no-link-errors $$QDOC_INCLUDE_PATHS + generate_docs.commands += $$doc_command -generate $$DOC_INDEXES $$QDOC_INCLUDE_PATHS prepare_docs.depends += qtattributionsscanner } else { - html_docs.commands += $$doc_command $$DOC_INDEXES $(INCPATH) + html_docs.commands += $$doc_command $$DOC_INDEXES $(QDOC_INCLUDE_PATHS) html_docs.depends += qtattributionsscanner } From 31ffc7bf2a0efe40116764a8c84939d2df4cdeae Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 30 Jul 2019 10:51:52 +0200 Subject: [PATCH 220/264] Fix removal of QJsonObject properties when assigning undefined Commit 8010e906d3612aface0daccde41d1a65fca04b0c accidentally ended up removing the removal-on-undefined-insertion check by calling insertAt instead of insert, which had it. This patch moves the check back into setValueAt. Change-Id: Ic381e284d3da37e31c4eb29f79dfab9c55c2e3e9 Fixes: QTBUG-77204 Reviewed-by: Liang Qi Reviewed-by: Edward Welbourne --- src/corelib/serialization/qjsonobject.cpp | 5 ++++- tests/auto/corelib/serialization/json/tst_qtjson.cpp | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/corelib/serialization/qjsonobject.cpp b/src/corelib/serialization/qjsonobject.cpp index 99ab25f265..329bc4d2c9 100644 --- a/src/corelib/serialization/qjsonobject.cpp +++ b/src/corelib/serialization/qjsonobject.cpp @@ -1476,7 +1476,10 @@ void QJsonObject::setValueAt(int i, const QJsonValue &val) Q_ASSERT(o && i >= 0 && i < (int)o->length); QJsonPrivate::Entry *e = o->entryAt(i); - insertAt(i, e->key(), val, true); + if (val.t == QJsonValue::Undefined) + removeAt(i); + else + insertAt(i, e->key(), val, true); } /*! diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp index 7b055b5b63..57aa67c142 100644 --- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp +++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp @@ -1132,6 +1132,8 @@ void tst_QtJson::undefinedValues() QJsonObject object; object.insert("Key", QJsonValue(QJsonValue::Undefined)); QCOMPARE(object.size(), 0); + object["Key"] = QJsonValue(QJsonValue::Undefined); + QCOMPARE(object.size(), 0); object.insert("Key", QLatin1String("Value")); QCOMPARE(object.size(), 1); From 7940bc32a1a4256a9ab4c032f2123c9fea8c6202 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 26 May 2019 07:22:13 +0200 Subject: [PATCH 221/264] QLineEdit: use QMargins internally instead of 4 x int Replace the four ints xTextMargin with one QMargins member, and the effectiveXTextMargin() function with effectiveTextMargins(). The left and right effective margins were always used together, so this in no case leads to extra work, compared to separate functions. Change-Id: I46d061919ffac297142213ccb4033caa0288b554 Reviewed-by: Volker Hilsheimer Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qlineedit.cpp | 40 +++++++++++++---------------- src/widgets/widgets/qlineedit_p.cpp | 17 +++++------- src/widgets/widgets/qlineedit_p.h | 11 +++----- 3 files changed, 28 insertions(+), 40 deletions(-) diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 0fedb65f0c..28d18872ce 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -684,11 +684,12 @@ QSize QLineEdit::sizeHint() const ensurePolished(); QFontMetrics fm(font()); const int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this); + const QMargins tm = d->effectiveTextMargins(); int h = qMax(fm.height(), qMax(14, iconSize - 2)) + 2 * QLineEditPrivate::verticalMargin - + d->topTextMargin + d->bottomTextMargin + + tm.top() + tm.bottom() + d->topmargin + d->bottommargin; int w = fm.horizontalAdvance(QLatin1Char('x')) * 17 + 2 * QLineEditPrivate::horizontalMargin - + d->effectiveLeftTextMargin() + d->effectiveRightTextMargin() + + tm.left() + tm.right() + d->leftmargin + d->rightmargin; // "some" QStyleOptionFrame opt; initStyleOption(&opt); @@ -708,11 +709,12 @@ QSize QLineEdit::minimumSizeHint() const Q_D(const QLineEdit); ensurePolished(); QFontMetrics fm = fontMetrics(); + const QMargins tm = d->effectiveTextMargins(); int h = fm.height() + qMax(2 * QLineEditPrivate::verticalMargin, fm.leading()) - + d->topTextMargin + d->bottomTextMargin + + tm.top() + tm.bottom() + d->topmargin + d->bottommargin; int w = fm.maxWidth() - + d->effectiveLeftTextMargin() + d->effectiveRightTextMargin() + + tm.left() + tm.right() + d->leftmargin + d->rightmargin; QStyleOptionFrame opt; initStyleOption(&opt); @@ -1131,13 +1133,7 @@ bool QLineEdit::hasAcceptableInput() const */ void QLineEdit::setTextMargins(int left, int top, int right, int bottom) { - Q_D(QLineEdit); - d->leftTextMargin = left; - d->topTextMargin = top; - d->rightTextMargin = right; - d->bottomTextMargin = bottom; - updateGeometry(); - update(); + setTextMargins({left, top, right, bottom}); } /*! @@ -1148,7 +1144,10 @@ void QLineEdit::setTextMargins(int left, int top, int right, int bottom) */ void QLineEdit::setTextMargins(const QMargins &margins) { - setTextMargins(margins.left(), margins.top(), margins.right(), margins.bottom()); + Q_D(QLineEdit); + d->textMargins = margins; + updateGeometry(); + update(); } /*! @@ -1159,15 +1158,15 @@ void QLineEdit::setTextMargins(const QMargins &margins) */ void QLineEdit::getTextMargins(int *left, int *top, int *right, int *bottom) const { - Q_D(const QLineEdit); + QMargins m = textMargins(); if (left) - *left = d->leftTextMargin; + *left = m.left(); if (top) - *top = d->topTextMargin; + *top = m.top(); if (right) - *right = d->rightTextMargin; + *right = m.right(); if (bottom) - *bottom = d->bottomTextMargin; + *bottom = m.bottom(); } /*! @@ -1179,7 +1178,7 @@ void QLineEdit::getTextMargins(int *left, int *top, int *right, int *bottom) con QMargins QLineEdit::textMargins() const { Q_D(const QLineEdit); - return QMargins(d->leftTextMargin, d->topTextMargin, d->rightTextMargin, d->bottomTextMargin); + return d->textMargins; } /*! @@ -1950,10 +1949,7 @@ void QLineEdit::paintEvent(QPaintEvent *) initStyleOption(&panel); style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this); QRect r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this); - r.setX(r.x() + d->effectiveLeftTextMargin()); - r.setY(r.y() + d->topTextMargin); - r.setRight(r.right() - d->effectiveRightTextMargin()); - r.setBottom(r.bottom() - d->bottomTextMargin); + r = r.marginsRemoved(d->effectiveTextMargins()); p.setClipRect(r); QFontMetrics fm = fontMetrics(); diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index 7d580e50a5..d2b5f87906 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -254,10 +254,7 @@ QRect QLineEditPrivate::adjustedContentsRect() const QStyleOptionFrame opt; q->initStyleOption(&opt); QRect r = q->style()->subElementRect(QStyle::SE_LineEditContents, &opt, q); - r.setX(r.x() + effectiveLeftTextMargin()); - r.setY(r.y() + topTextMargin); - r.setRight(r.right() - effectiveRightTextMargin()); - r.setBottom(r.bottom() - bottomTextMargin); + r = r.marginsRemoved(effectiveTextMargins()); return r; } @@ -672,14 +669,12 @@ static int effectiveTextMargin(int defaultMargin, const QLineEditPrivate::SideWi return e.widget->isVisibleTo(e.widget->parentWidget()); })); } -int QLineEditPrivate::effectiveLeftTextMargin() const +QMargins QLineEditPrivate::effectiveTextMargins() const { - return effectiveTextMargin(leftTextMargin, leftSideWidgetList(), sideWidgetParameters()); -} - -int QLineEditPrivate::effectiveRightTextMargin() const -{ - return effectiveTextMargin(rightTextMargin, rightSideWidgetList(), sideWidgetParameters()); + return {effectiveTextMargin(textMargins.left(), leftSideWidgetList(), sideWidgetParameters()), + textMargins.top(), + effectiveTextMargin(textMargins.right(), rightSideWidgetList(), sideWidgetParameters()), + textMargins.bottom()}; } diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h index 3f98aab901..a11fea6bbe 100644 --- a/src/widgets/widgets/qlineedit_p.h +++ b/src/widgets/widgets/qlineedit_p.h @@ -67,6 +67,7 @@ #endif #include "QtCore/qpointer.h" #include "QtCore/qmimedata.h" +#include #include "private/qwidgetlinecontrol_p.h" @@ -153,7 +154,7 @@ public: : control(0), frame(1), contextMenuEnabled(1), cursorVisible(0), dragEnabled(0), clickCausedFocus(0), edited(0), hscroll(0), vscroll(0), alignment(Qt::AlignLeading | Qt::AlignVCenter), - leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0), + textMargins{0, 0, 0, 0}, lastTextSize(0), mouseYThreshold(0) { } @@ -233,10 +234,7 @@ public: void _q_textChanged(const QString &); void _q_clearButtonClicked(); - int leftTextMargin; // use effectiveLeftTextMargin() in case of icon. - int topTextMargin; - int rightTextMargin; // use effectiveRightTextMargin() in case of icon. - int bottomTextMargin; + QMargins textMargins; // use effectiveTextMargins() in case of icon. QString placeholderText; @@ -252,8 +250,7 @@ public: inline const SideWidgetEntryList &rightSideWidgetList() const { return q_func()->layoutDirection() == Qt::LeftToRight ? trailingSideWidgets : leadingSideWidgets; } - int effectiveLeftTextMargin() const; - int effectiveRightTextMargin() const; + QMargins effectiveTextMargins() const; private: struct SideWidgetLocation { From bcf6f992370c34e2e89a964aaa92a2dfdff5bd77 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 27 May 2019 09:20:03 +0200 Subject: [PATCH 222/264] QEasingCurve: remove a default case label A default: case label turns off compiler warnings for missing enumeration values, which we'd like to have, so remove it. Change-Id: I96247a7fc46e91a29591a907e52841a90df62f10 Reviewed-by: Edward Welbourne --- src/corelib/tools/qtimeline.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/corelib/tools/qtimeline.cpp b/src/corelib/tools/qtimeline.cpp index fa6c45aa11..e3c3836764 100644 --- a/src/corelib/tools/qtimeline.cpp +++ b/src/corelib/tools/qtimeline.cpp @@ -529,7 +529,6 @@ QTimeLine::CurveShape QTimeLine::curveShape() const void QTimeLine::setCurveShape(CurveShape shape) { switch (shape) { - default: case EaseInOutCurve: setEasingCurve(QEasingCurve(QEasingCurve::InOutSine)); break; From 76be819345228d589cbc4f5129617151ea604750 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 27 May 2019 09:30:29 +0200 Subject: [PATCH 223/264] QEasingCurve: reduce code duplication in setCurveShape() Instead of creating an explicit QEasingCurve object in each switched-over case, extract the conversion between the enums involved into a helper and just call setEasingCurve() with the result (implicitly converted to QEasingCurve). Saves 0.5KiB in text size on optimized AMD64 Linux GCC 9.1 builds. Change-Id: I81b5d7199d9dd99ba3735c910a50e371e0b99838 Reviewed-by: Volker Hilsheimer Reviewed-by: Edward Welbourne --- src/corelib/tools/qtimeline.cpp | 34 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/corelib/tools/qtimeline.cpp b/src/corelib/tools/qtimeline.cpp index e3c3836764..0b11e7c77b 100644 --- a/src/corelib/tools/qtimeline.cpp +++ b/src/corelib/tools/qtimeline.cpp @@ -526,28 +526,24 @@ QTimeLine::CurveShape QTimeLine::curveShape() const return EaseInOutCurve; } -void QTimeLine::setCurveShape(CurveShape shape) +static QEasingCurve::Type convert(QTimeLine::CurveShape shape) { switch (shape) { - case EaseInOutCurve: - setEasingCurve(QEasingCurve(QEasingCurve::InOutSine)); - break; - case EaseInCurve: - setEasingCurve(QEasingCurve(QEasingCurve::InCurve)); - break; - case EaseOutCurve: - setEasingCurve(QEasingCurve(QEasingCurve::OutCurve)); - break; - case LinearCurve: - setEasingCurve(QEasingCurve(QEasingCurve::Linear)); - break; - case SineCurve: - setEasingCurve(QEasingCurve(QEasingCurve::SineCurve)); - break; - case CosineCurve: - setEasingCurve(QEasingCurve(QEasingCurve::CosineCurve)); - break; +#define CASE(x, y) case QTimeLine::x: return QEasingCurve::y + CASE(EaseInOutCurve, InOutSine); + CASE(EaseInCurve, InCurve); + CASE(EaseOutCurve, OutCurve); + CASE(LinearCurve, Linear); + CASE(SineCurve, SineCurve); + CASE(CosineCurve, CosineCurve); +#undef CASE } + Q_UNREACHABLE(); +} + +void QTimeLine::setCurveShape(CurveShape shape) +{ + setEasingCurve(convert(shape)); } /*! From 652085c5c2f843b1345e741352b4e2e8328f13fe Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 30 Jul 2019 12:47:33 +0200 Subject: [PATCH 224/264] qfsfileengine_p.h: Un-inline processOpenModeFlags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An inlined exported function does not make sense and will cause a warning. Fixes: QTBUG-77242 Change-Id: I016b93d6b39c4db82148fdc5a8a92bc9d5751885 Reviewed-by: Jörg Bornemann --- src/corelib/io/qfsfileengine_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 5231b4fe6f..22109ac5bc 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -66,7 +66,7 @@ struct ProcessOpenModeResult { QIODevice::OpenMode openMode; QString error; }; -inline Q_CORE_EXPORT ProcessOpenModeResult processOpenModeFlags(QIODevice::OpenMode mode); +Q_CORE_EXPORT ProcessOpenModeResult processOpenModeFlags(QIODevice::OpenMode mode); class QFSFileEnginePrivate; From 305f2c3aa6a2405f8fdeaa33f5d8c684e425f4ee Mon Sep 17 00:00:00 2001 From: Heikki Halmet Date: Tue, 30 Jul 2019 14:01:56 +0300 Subject: [PATCH 225/264] BLACKLIST insert_remove_loop for msvc-2019 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-77239 Change-Id: Ie1a08db0b4c4e1bbcb7981f24bcf12d5e6d33e48 Reviewed-by: Tony Sarajärvi --- tests/auto/corelib/tools/collections/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/auto/corelib/tools/collections/BLACKLIST diff --git a/tests/auto/corelib/tools/collections/BLACKLIST b/tests/auto/corelib/tools/collections/BLACKLIST new file mode 100644 index 0000000000..c6e289aadb --- /dev/null +++ b/tests/auto/corelib/tools/collections/BLACKLIST @@ -0,0 +1,2 @@ +[insert_remove_loop] +msvc-2019 From 130fd22d399624c863bbaad2f72d2213a48e9e13 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 24 May 2019 19:51:38 +0200 Subject: [PATCH 226/264] QWidget/QLineEdit: deprecate get{Contents,Text}Margins() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have contentsMargins() and textMargins() methods since 4.6 which are much more efficient and easier to use. [ChangeLog][QtWidgets][QLineEdit] The getTextMargins() member function has been deprecated in favor of textMargins(). [ChangeLog][QtWidgets][QWidget] The getContentsMargins() member function has been deprecated in favor of contentsMargins(). Change-Id: Ifdb890af6198fc682b94701786c67a5b945a4b4c Reviewed-by: Mårten Nordheim Reviewed-by: Lars Knoll --- src/widgets/accessible/simplewidgets.cpp | 3 +-- src/widgets/graphicsview/qgraphicsproxywidget.cpp | 4 +--- src/widgets/itemviews/qitemeditorfactory.cpp | 8 +++----- src/widgets/kernel/qwidget.cpp | 13 +++++++++---- src/widgets/kernel/qwidget.h | 3 +++ src/widgets/widgets/qcombobox.cpp | 13 ++++++------- src/widgets/widgets/qlineedit.cpp | 7 ++++++- src/widgets/widgets/qlineedit.h | 3 +++ src/widgets/widgets/qmenu.cpp | 4 +--- src/widgets/widgets/qsplitter.cpp | 7 +++---- 10 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/widgets/accessible/simplewidgets.cpp b/src/widgets/accessible/simplewidgets.cpp index 716c833fc9..ca74ee4b12 100644 --- a/src/widgets/accessible/simplewidgets.cpp +++ b/src/widgets/accessible/simplewidgets.cpp @@ -779,8 +779,7 @@ int QAccessibleLineEdit::cursorPosition() const QRect QAccessibleLineEdit::characterRect(int offset) const { int x = lineEdit()->d_func()->control->cursorToX(offset); - int y; - lineEdit()->getTextMargins(0, &y, 0, 0); + int y = lineEdit()->textMargins().top(); QFontMetrics fm(lineEdit()->font()); const QString ch = text(offset, offset + 1); if (ch.isEmpty()) diff --git a/src/widgets/graphicsview/qgraphicsproxywidget.cpp b/src/widgets/graphicsview/qgraphicsproxywidget.cpp index dec9e7a268..2b6712075f 100644 --- a/src/widgets/graphicsview/qgraphicsproxywidget.cpp +++ b/src/widgets/graphicsview/qgraphicsproxywidget.cpp @@ -697,9 +697,7 @@ void QGraphicsProxyWidgetPrivate::setWidget_helper(QWidget *newWidget, bool auto if (!newWidget->testAttribute(Qt::WA_Resized)) newWidget->adjustSize(); - int left, top, right, bottom; - newWidget->getContentsMargins(&left, &top, &right, &bottom); - q->setContentsMargins(left, top, right, bottom); + q->setContentsMargins(newWidget->contentsMargins()); q->setWindowTitle(newWidget->windowTitle()); // size policies and constraints.. diff --git a/src/widgets/itemviews/qitemeditorfactory.cpp b/src/widgets/itemviews/qitemeditorfactory.cpp index 2d49dd4421..8ed2ee5f28 100644 --- a/src/widgets/itemviews/qitemeditorfactory.cpp +++ b/src/widgets/itemviews/qitemeditorfactory.cpp @@ -570,11 +570,9 @@ void QExpandingLineEdit::changeEvent(QEvent *e) void QExpandingLineEdit::updateMinimumWidth() { - int left, right; - getTextMargins(&left, 0, &right, 0); - int width = left + right + 4 /*horizontalMargin in qlineedit.cpp*/; - getContentsMargins(&left, 0, &right, 0); - width += left + right; + const QMargins tm = textMargins(); + const QMargins cm = contentsMargins(); + const int width = tm.left() + tm.right() + cm.left() + cm.right() + 4 /*horizontalMargin in qlineedit.cpp*/; QStyleOptionFrame opt; initStyleOption(&opt); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index f0230f4f32..209a4407a0 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -7634,7 +7634,7 @@ bool QWidget::restoreGeometry(const QByteArray &geometry) Changing the margins will trigger a resizeEvent(). - \sa contentsRect(), getContentsMargins() + \sa contentsRect(), contentsMargins() */ void QWidget::setContentsMargins(int left, int top, int right, int bottom) { @@ -7664,7 +7664,7 @@ void QWidget::setContentsMargins(int left, int top, int right, int bottom) Changing the margins will trigger a resizeEvent(). - \sa contentsRect(), getContentsMargins() + \sa contentsRect(), contentsMargins() */ void QWidget::setContentsMargins(const QMargins &margins) { @@ -7693,7 +7693,11 @@ void QWidgetPrivate::updateContentsRect() QCoreApplication::sendEvent(q, &e); } +#if QT_DEPRECATED_SINCE(5, 14) /*! + \obsolete + Use contentsMargins(). + Returns the widget's contents margins for \a left, \a top, \a right, and \a bottom. @@ -7711,6 +7715,7 @@ void QWidget::getContentsMargins(int *left, int *top, int *right, int *bottom) c if (bottom) *bottom = m.bottom(); } +#endif // FIXME: Move to qmargins.h for next minor Qt release QMargins operator|(const QMargins &m1, const QMargins &m2) @@ -7724,7 +7729,7 @@ QMargins operator|(const QMargins &m1, const QMargins &m2) \brief The contentsMargins function returns the widget's contents margins. - \sa getContentsMargins(), setContentsMargins(), contentsRect() + \sa setContentsMargins(), contentsRect() */ QMargins QWidget::contentsMargins() const { @@ -7737,7 +7742,7 @@ QMargins QWidget::contentsMargins() const /*! Returns the area inside the widget's margins. - \sa setContentsMargins(), getContentsMargins() + \sa setContentsMargins(), contentsMargins() */ QRect QWidget::contentsRect() const { diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index e47deb5d0d..0777bed65c 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -524,7 +524,10 @@ public: void setContentsMargins(int left, int top, int right, int bottom); void setContentsMargins(const QMargins &margins); +#if QT_DEPRECATED_SINCE(5, 14) + QT_DEPRECATED_X("use contentsMargins()") void getContentsMargins(int *left, int *top, int *right, int *bottom) const; +#endif QMargins contentsMargins() const; QRect contentsRect() const; diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 5c368db83a..8b54d61e8e 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -2714,15 +2714,14 @@ void QComboBox::showPopup() int heightMargin = container->topMargin() + container->bottomMargin(); // add the frame of the container - int marginTop, marginBottom; - container->getContentsMargins(0, &marginTop, 0, &marginBottom); - heightMargin += marginTop + marginBottom; + const QMargins cm = container->contentsMargins(); + heightMargin += cm.top() + cm.bottom(); //add the frame of the view - view()->getContentsMargins(0, &marginTop, 0, &marginBottom); - marginTop += static_cast(QObjectPrivate::get(view()))->top; - marginBottom += static_cast(QObjectPrivate::get(view()))->bottom; - heightMargin += marginTop + marginBottom; + const QMargins vm = view()->contentsMargins(); + heightMargin += vm.top() + vm.bottom(); + heightMargin += static_cast(QObjectPrivate::get(view()))->top; + heightMargin += static_cast(QObjectPrivate::get(view()))->bottom; listRect.setHeight(listRect.height() + heightMargin); } diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 28d18872ce..7f482a6a4e 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -1129,7 +1129,7 @@ bool QLineEdit::hasAcceptableInput() const sizes \a left, \a top, \a right, and \a bottom. \since 4.5 - See also getTextMargins(). + See also textMargins(). */ void QLineEdit::setTextMargins(int left, int top, int right, int bottom) { @@ -1150,7 +1150,11 @@ void QLineEdit::setTextMargins(const QMargins &margins) update(); } +#if QT_DEPRECATED_SINCE(5, 14) /*! + \obsolete + Use textMargins() + Returns the widget's text margins for \a left, \a top, \a right, and \a bottom. \since 4.5 @@ -1168,6 +1172,7 @@ void QLineEdit::getTextMargins(int *left, int *top, int *right, int *bottom) con if (bottom) *bottom = m.bottom(); } +#endif /*! \since 4.6 diff --git a/src/widgets/widgets/qlineedit.h b/src/widgets/widgets/qlineedit.h index de82927f74..1cf1f24449 100644 --- a/src/widgets/widgets/qlineedit.h +++ b/src/widgets/widgets/qlineedit.h @@ -172,7 +172,10 @@ public: void setTextMargins(int left, int top, int right, int bottom); void setTextMargins(const QMargins &margins); +#if QT_DEPRECATED_SINCE(5, 14) + QT_DEPRECATED_X("use textMargins()") void getTextMargins(int *left, int *top, int *right, int *bottom) const; +#endif QMargins textMargins() const; #if QT_CONFIG(action) diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 310c865f52..e38490dabd 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -142,9 +142,7 @@ public: #endif if (style() != p->style()) setStyle(p->style()); - int leftMargin, topMargin, rightMargin, bottomMargin; - p->getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin); - setContentsMargins(leftMargin, topMargin, rightMargin, bottomMargin); + setContentsMargins(p->contentsMargins()); setLayoutDirection(p->layoutDirection()); //QObject::connect(this, SIGNAL(triggered(QAction*)), this, SLOT(onTrigger(QAction*))); //QObject::connect(this, SIGNAL(hovered(QAction*)), this, SLOT(onHovered(QAction*))); diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp index 08533040a7..e7a4889996 100644 --- a/src/widgets/widgets/qsplitter.cpp +++ b/src/widgets/widgets/qsplitter.cpp @@ -771,14 +771,13 @@ void QSplitterPrivate::setGeo(QSplitterLayoutStruct *sls, int p, int s, bool all if (!sls->handle->isHidden()) { QSplitterHandle *h = sls->handle; QSize hs = h->sizeHint(); - int left, top, right, bottom; - h->getContentsMargins(&left, &top, &right, &bottom); + const QMargins m = h->contentsMargins(); if (orient==Qt::Horizontal) { if (q->isRightToLeft()) p = contents.width() - p + hs.width(); - h->setGeometry(p-hs.width() - left, contents.y(), hs.width() + left + right, contents.height()); + h->setGeometry(p-hs.width() - m.left(), contents.y(), hs.width() + m.left() + m.right(), contents.height()); } else { - h->setGeometry(contents.x(), p-hs.height() - top, contents.width(), hs.height() + top + bottom); + h->setGeometry(contents.x(), p-hs.height() - m.top(), contents.width(), hs.height() + m.top() + m.bottom()); } } } From 7adc1d329ff85d4dd03cb950f06132b03a5df9ed Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 30 Jul 2019 14:19:10 +0200 Subject: [PATCH 227/264] Remove dead code from metamakefile.cpp Remove usage of the 'if (0 && ...)' pattern that was presumably used to temporarily disable code paths. The disabling of the two code paths was introduced in 356a677b386648710efc4db9a8a1b4a975f95c48 (old internal history, 2004) and 0326e3511928d90329152b9b0493da76e9caa442 (old internal history, 2006). It can be deduced that it's pretty safe to remove both. Change-Id: I88aee65b1286701241b5b80fbac0c65cd99ecd5e Reviewed-by: Edward Welbourne --- qmake/generators/metamakefile.cpp | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp index f9159ccd75..0fa3e29ad3 100644 --- a/qmake/generators/metamakefile.cpp +++ b/qmake/generators/metamakefile.cpp @@ -95,9 +95,6 @@ BuildsMetaMakefileGenerator::init() if(builds.count() > 1 && Option::output.fileName() == "-") { use_single_build = true; warn_msg(WarnLogic, "Cannot direct to stdout when using multiple BUILDS."); - } else if(0 && !use_single_build && project->first("TEMPLATE") == "subdirs") { - use_single_build = true; - warn_msg(WarnLogic, "Cannot specify multiple builds with TEMPLATE subdirs."); } if(!use_single_build) { for(int i = 0; i < builds.count(); i++) { @@ -327,17 +324,13 @@ SubdirsMetaMakefileGenerator::init() hasError |= tmpError; } sub->makefile = MetaMakefileGenerator::createMetaGenerator(sub_proj, sub_name); - if(0 && sub->makefile->type() == SUBDIRSMETATYPE) { - subs.append(sub); - } else { - const QString output_name = Option::output.fileName(); - Option::output.setFileName(sub->output_file); - hasError |= !sub->makefile->write(); - delete sub; - qmakeClearCaches(); - sub = nullptr; - Option::output.setFileName(output_name); - } + const QString output_name = Option::output.fileName(); + Option::output.setFileName(sub->output_file); + hasError |= !sub->makefile->write(); + delete sub; + qmakeClearCaches(); + sub = nullptr; + Option::output.setFileName(output_name); Option::output_dir = old_output_dir; qmake_setpwd(oldpwd); From f84ea9a6bddecd2d8831b4449c7fbcb913ffe435 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 30 Jul 2019 14:31:50 +0200 Subject: [PATCH 228/264] Rename MakefileGenerator::build_args() to ...::fullBuildArgs() ...because - it calls the properly camel-cased member function buildArgs(bool), which is slightly confusing - it returns buildArgs(true) plus input and output We also let it return only the arguments, excluding the qmake executable. This is consistent with the function's name and saves us a string replacement stunt at one call site. Change-Id: I8bea65900bd51962962e4cfd425ffbc26e3a52fe Reviewed-by: Edward Welbourne --- qmake/generators/makefile.cpp | 8 ++++---- qmake/generators/makefile.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index be282d7260..5ccd1aea83 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2299,9 +2299,9 @@ QString MakefileGenerator::buildArgs(bool withExtra) //could get stored argv, but then it would have more options than are //probably necesary this will try to guess the bare minimum.. -QString MakefileGenerator::build_args() +QString MakefileGenerator::fullBuildArgs() { - QString ret = "$(QMAKE)"; + QString ret; //output QString ofile = fileFixify(Option::output.fileName()); @@ -2326,7 +2326,7 @@ MakefileGenerator::writeHeader(QTextStream &t) t << "# Project: " << fileFixify(project->projectFile()) << Qt::endl; t << "# Template: " << var("TEMPLATE") << Qt::endl; if(!project->isActiveConfig("build_pass")) - t << "# Command: " << build_args().replace(QLatin1String("$(QMAKE)"), var("QMAKE_QMAKE")) << Qt::endl; + t << "# Command: " << var("QMAKE_QMAKE") << fullBuildArgs() << Qt::endl; t << "#############################################################################\n"; t << Qt::endl; QString ofile = Option::fixPathToTargetOS(Option::output.fileName()); @@ -2792,7 +2792,7 @@ MakefileGenerator::writeMakeQmake(QTextStream &t, bool noDummyQmakeAll) << "@$(QMAKE) -prl " << files.join(' ') << ' ' << buildArgs(true) << Qt::endl; } - QString qmake = build_args(); + QString qmake = "$(QMAKE)" + fullBuildArgs(); if(!ofile.isEmpty() && !project->isActiveConfig("no_autoqmake")) { t << escapeDependencyPath(ofile) << ": " << escapeDependencyPath(fileFixify(project->projectFile())) << " "; diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index c7b2bee0b4..4d1b998197 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -58,7 +58,7 @@ class MakefileGenerator : protected QMakeSourceFileInfo bool resolveDependenciesInFrameworks = false; QHash init_compiler_already; QString makedir, chkexists; - QString build_args(); + QString fullBuildArgs(); //internal caches mutable QHash depHeuristicsCache; From a093e4e3c2058b4662ff27473bcfba3c141f0924 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 29 Jul 2019 10:20:57 +0200 Subject: [PATCH 229/264] rhi: vulkan: Fix glitches on resize on X11 ...by notifying QVulkanInstance about the present. With the xcb platform this then gets turned into updating the sync request counter. Change-Id: Iecfb6d10ead3befcb24c19433d4712ed73a84bb4 Reviewed-by: Andy Nichols --- src/gui/rhi/qrhivulkan.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index 7c4eeaf226..2caa6cdec4 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -1661,6 +1661,10 @@ QRhi::FrameOpResult QRhiVulkan::endFrame(QRhiSwapChain *swapChain, QRhi::EndFram } } + // Do platform-specific WM notification. F.ex. essential on X11 in + // order to prevent glitches on resizing the window. + inst->presentQueued(swapChainD->window); + // mark the current swapchain buffer as unused from our side frame.imageAcquired = false; // and move on to the next buffer From c95542694527d66361b9882ad39db5eb06cca3fe Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 26 Jul 2019 13:16:57 +0200 Subject: [PATCH 230/264] rhi: metal: Do not hold on to the drawable when not presenting The Quick render loops do SkipPresent occasionally, and it all seemed to work with the threaded one because we lack an autorelease pool on the SG render thread. (to be corrected separately) The basic one ended up crashing sometimes, however. Holding on to the drawable is incorrect. Fixes: QTBUG-76953 Change-Id: I0d0ec6d09aa209d2c848d7a9dbd9b15916fe23ab Reviewed-by: Andy Nichols --- src/gui/rhi/qrhi.cpp | 6 ++++++ src/gui/rhi/qrhimetal.mm | 11 +++++++---- .../rhi/multiwindow_threaded/multiwindow_threaded.cpp | 4 ++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index d7c1607e57..a29c7e263e 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -260,6 +260,12 @@ QT_BEGIN_NAMESPACE tied to those concepts, however, and is thus a topic that is currently out of scope, but may be introduced in the future. + \note The Metal backend requires that an autorelease pool is available on + the rendering thread, ideally wrapping each iteration of the render loop. + This needs no action from the users of QRhi when rendering on the main + (gui) thread, but becomes important when a separate, dedicated render + thread is used. + \section3 Resource synchronization QRhi does not expose APIs for resource barriers or image layout diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index fa537a504b..98b2a9bcac 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -57,7 +57,8 @@ QT_BEGIN_NAMESPACE Textures are Private (device local) and a host visible staging buffer is used to upload data to them. Does not rely on strong objects refs from command buffers but does rely on the automatic resource tracking of the - command encoders. + command encoders. Assumes that an autorelease pool (ideally per frame) is + available on the thread on which QRhi is used. */ #if __has_feature(objc_arc) @@ -1214,10 +1215,12 @@ QRhi::FrameOpResult QRhiMetal::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame Q_ASSERT(currentSwapChain == swapChainD); const bool needsPresent = !flags.testFlag(QRhi::SkipPresent); - if (needsPresent) { + if (needsPresent) [swapChainD->cbWrapper.d->cb presentDrawable: swapChainD->d->curDrawable]; - swapChainD->d->curDrawable = nil; - } + + // Must not hold on to the drawable, regardless of needsPresent. + // (internally it is autoreleased or something, it seems) + swapChainD->d->curDrawable = nil; __block int thisFrameSlot = currentFrameSlot; [swapChainD->cbWrapper.d->cb addCompletedHandler: ^(id) { diff --git a/tests/manual/rhi/multiwindow_threaded/multiwindow_threaded.cpp b/tests/manual/rhi/multiwindow_threaded/multiwindow_threaded.cpp index 8fda2b73c8..53185bddb2 100644 --- a/tests/manual/rhi/multiwindow_threaded/multiwindow_threaded.cpp +++ b/tests/manual/rhi/multiwindow_threaded/multiwindow_threaded.cpp @@ -290,6 +290,10 @@ struct Renderer void Thread::run() { while (active) { +#ifdef Q_OS_DARWIN + QMacAutoReleasePool autoReleasePool; +#endif + if (pendingRender) { pendingRender = false; renderer->render(pendingRenderIsNewExpose, false); From 493ce2f3d40d23682a9492e8995067f50f9edeea Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 1 Jul 2019 11:18:10 +0200 Subject: [PATCH 231/264] rhi: gl: Add support for compute ...and storage buffers and images. Change-Id: If38a51322e3187088a13cf4e9b88cb40c8af8621 Reviewed-by: Andy Nichols --- src/gui/rhi/qrhi.cpp | 28 + src/gui/rhi/qrhi_p_p.h | 3 + src/gui/rhi/qrhigles2.cpp | 871 ++++++++++++++---- src/gui/rhi/qrhigles2_p_p.h | 148 ++- src/gui/rhi/qrhivulkan.cpp | 36 +- .../manual/rhi/computeimage/computeimage.cpp | 2 +- 6 files changed, 833 insertions(+), 255 deletions(-) diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index a29c7e263e..3576b30349 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -5337,4 +5337,32 @@ void QRhiPassResourceTracker::registerTexture(QRhiTexture *tex, TextureAccess *a m_textures.append(t); } +QRhiPassResourceTracker::BufferStage QRhiPassResourceTracker::toPassTrackerBufferStage(QRhiShaderResourceBinding::StageFlags stages) +{ + // pick the earlier stage (as this is going to be dstAccessMask) + if (stages.testFlag(QRhiShaderResourceBinding::VertexStage)) + return QRhiPassResourceTracker::BufVertexStage; + if (stages.testFlag(QRhiShaderResourceBinding::FragmentStage)) + return QRhiPassResourceTracker::BufFragmentStage; + if (stages.testFlag(QRhiShaderResourceBinding::ComputeStage)) + return QRhiPassResourceTracker::BufComputeStage; + + Q_UNREACHABLE(); + return QRhiPassResourceTracker::BufVertexStage; +} + +QRhiPassResourceTracker::TextureStage QRhiPassResourceTracker::toPassTrackerTextureStage(QRhiShaderResourceBinding::StageFlags stages) +{ + // pick the earlier stage (as this is going to be dstAccessMask) + if (stages.testFlag(QRhiShaderResourceBinding::VertexStage)) + return QRhiPassResourceTracker::TexVertexStage; + if (stages.testFlag(QRhiShaderResourceBinding::FragmentStage)) + return QRhiPassResourceTracker::TexFragmentStage; + if (stages.testFlag(QRhiShaderResourceBinding::ComputeStage)) + return QRhiPassResourceTracker::TexComputeStage; + + Q_UNREACHABLE(); + return QRhiPassResourceTracker::TexVertexStage; +} + QT_END_NAMESPACE diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h index 83d521f441..d87c4372ca 100644 --- a/src/gui/rhi/qrhi_p_p.h +++ b/src/gui/rhi/qrhi_p_p.h @@ -553,6 +553,9 @@ public: }; const QVector *textures() const { return &m_textures; } + static BufferStage toPassTrackerBufferStage(QRhiShaderResourceBinding::StageFlags stages); + static TextureStage toPassTrackerTextureStage(QRhiShaderResourceBinding::StageFlags stages); + private: QVector m_buffers; QVector m_textures; diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index e56710a4bf..3ef4bb3a07 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -47,12 +47,13 @@ QT_BEGIN_NAMESPACE OpenGL backend. Binding vertex attribute locations and decomposing uniform buffers into uniforms are handled transparently to the application via the reflection data (QShaderDescription). Real uniform buffers are never used, - regardless of the GLSL version. Textures and buffers feature no special logic, - it's all just glTexSubImage2D and glBufferSubData (with "dynamic" buffers set - to GL_DYNAMIC_DRAW). The swapchain and the associated renderbuffer for - depth-stencil will be dummies since we have no control over the underlying - buffers here. While we try to keep this backend clean GLES 2.0, some GL(ES) - 3.0 features like multisample renderbuffers and blits are used when available. + regardless of the GLSL version. Textures and buffers feature no special + logic, it's all just glTexSubImage2D and glBufferSubData (with "dynamic" + buffers set to GL_DYNAMIC_DRAW). The swapchain and the associated + renderbuffer for depth-stencil will be dummies since we have no control over + the underlying buffers here. While the baseline here is plain GLES 2.0, some + modern GL(ES) features like multisample renderbuffers, blits, and compute are + used when available. Also functional with core profile contexts. */ /*! @@ -239,6 +240,34 @@ QT_BEGIN_NAMESPACE #define GL_MAX_SAMPLES 0x8D57 #endif +#ifndef GL_SHADER_STORAGE_BUFFER +#define GL_SHADER_STORAGE_BUFFER 0x90D2 +#endif + +#ifndef GL_READ_ONLY +#define GL_READ_ONLY 0x88B8 +#endif + +#ifndef GL_WRITE_ONLY +#define GL_WRITE_ONLY 0x88B9 +#endif + +#ifndef GL_READ_WRITE +#define GL_READ_WRITE 0x88BA +#endif + +#ifndef GL_COMPUTE_SHADER +#define GL_COMPUTE_SHADER 0x91B9 +#endif + +#ifndef GL_ALL_BARRIER_BITS +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#endif + +#ifndef GL_VERTEX_PROGRAM_POINT_SIZE +#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 +#endif + /*! Constructs a new QRhiGles2InitParams. @@ -438,6 +467,15 @@ bool QRhiGles2::create(QRhi::Flags flags) caps.baseVertex = caps.ctxMajor > 3 || (caps.ctxMajor == 3 && caps.ctxMinor >= 2); // 3.2 or ES 3.2 + if (caps.gles) + caps.compute = caps.ctxMajor > 3 || (caps.ctxMajor == 3 && caps.ctxMinor >= 1); // ES 3.1 + else + caps.compute = caps.ctxMajor > 4 || (caps.ctxMajor == 4 && caps.ctxMinor >= 3); // 4.3 + + if (!caps.gles) + f->glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + // else (with gles) this is always on + nativeHandlesStruct.context = ctx; return true; @@ -693,7 +731,7 @@ bool QRhiGles2::isFeatureSupported(QRhi::Feature feature) const case QRhi::ElementIndexUint: return caps.elementIndexUint; case QRhi::Compute: - return false; + return caps.compute; case QRhi::WideLines: return true; case QRhi::VertexShaderPointSize: @@ -788,10 +826,11 @@ void QRhiGles2::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass); QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, ps); - const bool pipelineChanged = cbD->currentPipeline != ps || cbD->currentPipelineGeneration != psD->generation; + const bool pipelineChanged = cbD->currentGraphicsPipeline != ps || cbD->currentPipelineGeneration != psD->generation; if (pipelineChanged) { - cbD->currentPipeline = ps; + cbD->currentGraphicsPipeline = ps; + cbD->currentComputePipeline = nullptr; cbD->currentPipelineGeneration = psD->generation; QGles2CommandBuffer::Command cmd; @@ -806,35 +845,92 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind const QRhiCommandBuffer::DynamicOffset *dynamicOffsets) { QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb); - Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass); - Q_ASSERT(cbD->currentPipeline); + Q_ASSERT(cbD->recordingPass != QGles2CommandBuffer::NoPass); + QGles2GraphicsPipeline *gfxPsD = QRHI_RES(QGles2GraphicsPipeline, cbD->currentGraphicsPipeline); + QGles2ComputePipeline *compPsD = QRHI_RES(QGles2ComputePipeline, cbD->currentComputePipeline); - if (!srb) - srb = QRHI_RES(QGles2GraphicsPipeline, cbD->currentPipeline)->m_shaderResourceBindings; + if (!srb) { + if (gfxPsD) + srb = gfxPsD->m_shaderResourceBindings; + else + srb = compPsD->m_shaderResourceBindings; + } + QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]); QGles2ShaderResourceBindings *srbD = QRHI_RES(QGles2ShaderResourceBindings, srb); bool hasDynamicOffsetInSrb = false; for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) { const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&srbD->m_bindings[i]); switch (b->type) { case QRhiShaderResourceBinding::UniformBuffer: + // no BufUniformRead / AccessUniform because no real uniform buffers are used if (b->u.ubuf.hasDynamicOffset) hasDynamicOffsetInSrb = true; break; + case QRhiShaderResourceBinding::SampledTexture: + trackedRegisterTexture(&passResTracker, + QRHI_RES(QGles2Texture, b->u.stex.tex), + QRhiPassResourceTracker::TexSample, + QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage)); + break; + case QRhiShaderResourceBinding::ImageLoad: + Q_FALLTHROUGH(); + case QRhiShaderResourceBinding::ImageStore: + Q_FALLTHROUGH(); + case QRhiShaderResourceBinding::ImageLoadStore: + { + QGles2Texture *texD = QRHI_RES(QGles2Texture, b->u.simage.tex); + QRhiPassResourceTracker::TextureAccess access; + if (b->type == QRhiShaderResourceBinding::ImageLoad) + access = QRhiPassResourceTracker::TexStorageLoad; + else if (b->type == QRhiShaderResourceBinding::ImageStore) + access = QRhiPassResourceTracker::TexStorageStore; + else + access = QRhiPassResourceTracker::TexStorageLoadStore; + trackedRegisterTexture(&passResTracker, texD, access, + QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage)); + } + break; + case QRhiShaderResourceBinding::BufferLoad: + Q_FALLTHROUGH(); + case QRhiShaderResourceBinding::BufferStore: + Q_FALLTHROUGH(); + case QRhiShaderResourceBinding::BufferLoadStore: + { + QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.sbuf.buf); + QRhiPassResourceTracker::BufferAccess access; + if (b->type == QRhiShaderResourceBinding::BufferLoad) + access = QRhiPassResourceTracker::BufStorageLoad; + else if (b->type == QRhiShaderResourceBinding::BufferStore) + access = QRhiPassResourceTracker::BufStorageStore; + else + access = QRhiPassResourceTracker::BufStorageLoadStore; + trackedRegisterBuffer(&passResTracker, bufD, access, + QRhiPassResourceTracker::toPassTrackerBufferStage(b->stage)); + } + break; default: break; } } - const bool srbChanged = cbD->currentSrb != srb || cbD->currentSrbGeneration != srbD->generation; + const bool srbChanged = gfxPsD ? (cbD->currentGraphicsSrb != srb) : (cbD->currentComputeSrb != srb); + const bool srbRebuilt = cbD->currentSrbGeneration != srbD->generation; - if (srbChanged || hasDynamicOffsetInSrb) { - cbD->currentSrb = srb; + if (srbChanged || srbRebuilt || hasDynamicOffsetInSrb) { + if (gfxPsD) { + cbD->currentGraphicsSrb = srb; + cbD->currentComputeSrb = nullptr; + } else { + cbD->currentGraphicsSrb = nullptr; + cbD->currentComputeSrb = srb; + } cbD->currentSrbGeneration = srbD->generation; QGles2CommandBuffer::Command cmd; cmd.cmd = QGles2CommandBuffer::Command::BindShaderResources; - cmd.args.bindShaderResources.ps = cbD->currentPipeline; + cmd.args.bindShaderResources.maybeGraphicsPs = gfxPsD; + cmd.args.bindShaderResources.maybeComputePs = compPsD; cmd.args.bindShaderResources.srb = srb; cmd.args.bindShaderResources.dynamicOffsetCount = 0; if (hasDynamicOffsetInSrb) { @@ -861,30 +957,39 @@ void QRhiGles2::setVertexInput(QRhiCommandBuffer *cb, { QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb); Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::RenderPass); + QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]); for (int i = 0; i < bindingCount; ++i) { QRhiBuffer *buf = bindings[i].first; quint32 ofs = bindings[i].second; QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, buf); Q_ASSERT(bufD->m_usage.testFlag(QRhiBuffer::VertexBuffer)); + QGles2CommandBuffer::Command cmd; cmd.cmd = QGles2CommandBuffer::Command::BindVertexBuffer; - cmd.args.bindVertexBuffer.ps = cbD->currentPipeline; + cmd.args.bindVertexBuffer.ps = cbD->currentGraphicsPipeline; cmd.args.bindVertexBuffer.buffer = bufD->buffer; cmd.args.bindVertexBuffer.offset = ofs; cmd.args.bindVertexBuffer.binding = startBinding + i; cbD->commands.append(cmd); + + trackedRegisterBuffer(&passResTracker, bufD, QRhiPassResourceTracker::BufVertexInput, + QRhiPassResourceTracker::BufVertexInputStage); } if (indexBuf) { QGles2Buffer *ibufD = QRHI_RES(QGles2Buffer, indexBuf); Q_ASSERT(ibufD->m_usage.testFlag(QRhiBuffer::IndexBuffer)); + QGles2CommandBuffer::Command cmd; cmd.cmd = QGles2CommandBuffer::Command::BindIndexBuffer; cmd.args.bindIndexBuffer.buffer = ibufD->buffer; cmd.args.bindIndexBuffer.offset = indexOffset; cmd.args.bindIndexBuffer.type = indexFormat == QRhiCommandBuffer::IndexUInt16 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; cbD->commands.append(cmd); + + trackedRegisterBuffer(&passResTracker, ibufD, QRhiPassResourceTracker::BufIndexRead, + QRhiPassResourceTracker::BufVertexInputStage); } } @@ -942,7 +1047,7 @@ void QRhiGles2::setStencilRef(QRhiCommandBuffer *cb, quint32 refValue) QGles2CommandBuffer::Command cmd; cmd.cmd = QGles2CommandBuffer::Command::StencilRef; cmd.args.stencilRef.ref = refValue; - cmd.args.stencilRef.ps = cbD->currentPipeline; + cmd.args.stencilRef.ps = cbD->currentGraphicsPipeline; cbD->commands.append(cmd); } @@ -954,7 +1059,7 @@ void QRhiGles2::draw(QRhiCommandBuffer *cb, quint32 vertexCount, QGles2CommandBuffer::Command cmd; cmd.cmd = QGles2CommandBuffer::Command::Draw; - cmd.args.draw.ps = cbD->currentPipeline; + cmd.args.draw.ps = cbD->currentGraphicsPipeline; cmd.args.draw.vertexCount = vertexCount; cmd.args.draw.firstVertex = firstVertex; cmd.args.draw.instanceCount = instanceCount; @@ -970,7 +1075,7 @@ void QRhiGles2::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount, QGles2CommandBuffer::Command cmd; cmd.cmd = QGles2CommandBuffer::Command::DrawIndexed; - cmd.args.drawIndexed.ps = cbD->currentPipeline; + cmd.args.drawIndexed.ps = cbD->currentGraphicsPipeline; cmd.args.drawIndexed.indexCount = indexCount; cmd.args.drawIndexed.firstIndex = firstIndex; cmd.args.drawIndexed.instanceCount = instanceCount; @@ -1136,9 +1241,48 @@ QRhi::FrameOpResult QRhiGles2::flushCommandBuffer() return QRhi::FrameOpSuccess; } +void QRhiGles2::trackedBufferBarrier(QGles2CommandBuffer *cbD, QGles2Buffer *bufD, QGles2Buffer::Access access) +{ + Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::NoPass); // this is for resource updates only + const QGles2Buffer::Access prevAccess = bufD->usageState.access; + if (access == prevAccess) + return; + + if (prevAccess == QGles2Buffer::AccessStorageWrite || prevAccess == QGles2Buffer::AccessStorageReadWrite) { + // Generating the minimal barrier set is way too complicated to do + // correctly (prevAccess is overwritten so we won't have proper + // tracking across multiple passes) so setting all barrier bits will do + // for now. + QGles2CommandBuffer::Command cmd; + cmd.cmd = QGles2CommandBuffer::Command::Barrier; + cmd.args.barrier.barriers = GL_ALL_BARRIER_BITS; + cbD->commands.append(cmd); + } + + bufD->usageState.access = access; +} + +void QRhiGles2::trackedImageBarrier(QGles2CommandBuffer *cbD, QGles2Texture *texD, QGles2Texture::Access access) +{ + Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::NoPass); // this is for resource updates only + const QGles2Texture::Access prevAccess = texD->usageState.access; + if (access == prevAccess) + return; + + if (prevAccess == QGles2Texture::AccessStorageWrite || prevAccess == QGles2Texture::AccessStorageReadWrite) { + QGles2CommandBuffer::Command cmd; + cmd.cmd = QGles2CommandBuffer::Command::Barrier; + cmd.args.barrier.barriers = GL_ALL_BARRIER_BITS; + cbD->commands.append(cmd); + } + + texD->usageState.access = access; +} + void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cbD, int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc) { + trackedImageBarrier(cbD, texD, QGles2Texture::AccessUpdate); const bool isCompressed = isCompressedFormat(texD->m_format); const bool isCubeMap = texD->m_flags.testFlag(QRhiTexture::CubeMap); const GLenum faceTargetBase = isCubeMap ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : texD->target; @@ -1239,9 +1383,10 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) { memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), u.data.size()); } else { + trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate); QGles2CommandBuffer::Command cmd; cmd.cmd = QGles2CommandBuffer::Command::BufferSubData; - cmd.args.bufferSubData.target = bufD->target; + cmd.args.bufferSubData.target = bufD->targetForDataOps; cmd.args.bufferSubData.buffer = bufD->buffer; cmd.args.bufferSubData.offset = u.offset; cmd.args.bufferSubData.size = u.data.size(); @@ -1257,9 +1402,10 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate if (bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)) { memcpy(bufD->ubuf.data() + u.offset, u.data.constData(), u.data.size()); } else { + trackedBufferBarrier(cbD, bufD, QGles2Buffer::AccessUpdate); QGles2CommandBuffer::Command cmd; cmd.cmd = QGles2CommandBuffer::Command::BufferSubData; - cmd.args.bufferSubData.target = bufD->target; + cmd.args.bufferSubData.target = bufD->targetForDataOps; cmd.args.bufferSubData.buffer = bufD->buffer; cmd.args.bufferSubData.offset = u.offset; cmd.args.bufferSubData.size = u.data.size(); @@ -1283,6 +1429,9 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate QGles2Texture *srcD = QRHI_RES(QGles2Texture, u.copy.src); QGles2Texture *dstD = QRHI_RES(QGles2Texture, u.copy.dst); + trackedImageBarrier(cbD, srcD, QGles2Texture::AccessRead); + trackedImageBarrier(cbD, dstD, QGles2Texture::AccessUpdate); + const QSize size = u.copy.desc.pixelSize().isEmpty() ? srcD->m_pixelSize : u.copy.desc.pixelSize(); // do not translate coordinates, even if sp is bottom-left from gl's pov const QPoint sp = u.copy.desc.sourceTopLeft(); @@ -1318,6 +1467,7 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate cmd.cmd = QGles2CommandBuffer::Command::ReadPixels; cmd.args.readPixels.result = u.read.result; QGles2Texture *texD = QRHI_RES(QGles2Texture, u.read.rb.texture()); + trackedImageBarrier(cbD, texD, QGles2Texture::AccessRead); cmd.args.readPixels.texture = texD ? texD->texture : 0; if (texD) { cmd.args.readPixels.w = texD->m_pixelSize.width(); @@ -1330,9 +1480,10 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate } cbD->commands.append(cmd); } else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::MipGen) { + QGles2Texture *texD = QRHI_RES(QGles2Texture, u.mipgen.tex); + trackedImageBarrier(cbD, texD, QGles2Texture::AccessFramebuffer); QGles2CommandBuffer::Command cmd; cmd.cmd = QGles2CommandBuffer::Command::GenMip; - QGles2Texture *texD = QRHI_RES(QGles2Texture, u.mipgen.tex); cmd.args.genMip.target = texD->target; cmd.args.genMip.texture = texD->texture; cbD->commands.append(cmd); @@ -1581,6 +1732,88 @@ static inline GLenum toGlTextureCompareFunc(QRhiSampler::CompareOp op) } } +static inline QGles2Buffer::Access toGlAccess(QRhiPassResourceTracker::BufferAccess access) +{ + switch (access) { + case QRhiPassResourceTracker::BufVertexInput: + return QGles2Buffer::AccessVertex; + case QRhiPassResourceTracker::BufIndexRead: + return QGles2Buffer::AccessIndex; + case QRhiPassResourceTracker::BufUniformRead: + return QGles2Buffer::AccessUniform; + case QRhiPassResourceTracker::BufStorageLoad: + return QGles2Buffer::AccessStorageRead; + case QRhiPassResourceTracker::BufStorageStore: + return QGles2Buffer::AccessStorageWrite; + case QRhiPassResourceTracker::BufStorageLoadStore: + return QGles2Buffer::AccessStorageReadWrite; + default: + Q_UNREACHABLE(); + break; + } + return QGles2Buffer::AccessNone; +} + +static inline QRhiPassResourceTracker::UsageState toPassTrackerUsageState(const QGles2Buffer::UsageState &bufUsage) +{ + QRhiPassResourceTracker::UsageState u; + u.layout = 0; // N/A + u.access = bufUsage.access; + u.stage = 0; // N/A + return u; +} + +static inline QGles2Texture::Access toGlAccess(QRhiPassResourceTracker::TextureAccess access) +{ + switch (access) { + case QRhiPassResourceTracker::TexSample: + return QGles2Texture::AccessSample; + case QRhiPassResourceTracker::TexColorOutput: + return QGles2Texture::AccessFramebuffer; + case QRhiPassResourceTracker::TexDepthOutput: + return QGles2Texture::AccessFramebuffer; + case QRhiPassResourceTracker::TexStorageLoad: + return QGles2Texture::AccessStorageRead; + case QRhiPassResourceTracker::TexStorageStore: + return QGles2Texture::AccessStorageWrite; + case QRhiPassResourceTracker::TexStorageLoadStore: + return QGles2Texture::AccessStorageReadWrite; + default: + Q_UNREACHABLE(); + break; + } + return QGles2Texture::AccessNone; +} + +static inline QRhiPassResourceTracker::UsageState toPassTrackerUsageState(const QGles2Texture::UsageState &texUsage) +{ + QRhiPassResourceTracker::UsageState u; + u.layout = 0; // N/A + u.access = texUsage.access; + u.stage = 0; // N/A + return u; +} + +void QRhiGles2::trackedRegisterBuffer(QRhiPassResourceTracker *passResTracker, + QGles2Buffer *bufD, + QRhiPassResourceTracker::BufferAccess access, + QRhiPassResourceTracker::BufferStage stage) +{ + QGles2Buffer::UsageState &u(bufD->usageState); + passResTracker->registerBuffer(bufD, 0, &access, &stage, toPassTrackerUsageState(u)); + u.access = toGlAccess(access); +} + +void QRhiGles2::trackedRegisterTexture(QRhiPassResourceTracker *passResTracker, + QGles2Texture *texD, + QRhiPassResourceTracker::TextureAccess access, + QRhiPassResourceTracker::TextureStage stage) +{ + QGles2Texture::UsageState &u(texD->usageState); + passResTracker->registerTexture(texD, &access, &stage, toPassTrackerUsageState(u)); + u.access = toGlAccess(access); +} + void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) { QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb); @@ -1757,7 +1990,8 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) executeBindGraphicsPipeline(cmd.args.bindGraphicsPipeline.ps); break; case QGles2CommandBuffer::Command::BindShaderResources: - bindShaderResources(cmd.args.bindShaderResources.ps, + bindShaderResources(cmd.args.bindShaderResources.maybeGraphicsPs, + cmd.args.bindShaderResources.maybeComputePs, cmd.args.bindShaderResources.srb, cmd.args.bindShaderResources.dynamicOffsetPairs, cmd.args.bindShaderResources.dynamicOffsetCount); @@ -1900,6 +2134,51 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) f->glBindTexture(cmd.args.genMip.target, cmd.args.genMip.texture); f->glGenerateMipmap(cmd.args.genMip.target); break; + case QGles2CommandBuffer::Command::BindComputePipeline: + { + QGles2ComputePipeline *psD = QRHI_RES(QGles2ComputePipeline, cmd.args.bindComputePipeline.ps); + f->glUseProgram(psD->program); + } + break; + case QGles2CommandBuffer::Command::Dispatch: + f->glDispatchCompute(cmd.args.dispatch.x, cmd.args.dispatch.y, cmd.args.dispatch.z); + break; + case QGles2CommandBuffer::Command::BarriersForPass: + { + GLbitfield barriers = 0; + QRhiPassResourceTracker &tracker(cbD->passResTrackers[cmd.args.barriersForPass.trackerIndex]); + const QVector *buffers = tracker.buffers(); + // we only care about after-write, not any other accesses, and + // cannot tell if something was written in a shader several passes + // ago: now the previously written resource may be used with an + // access that was not in the previous passes, result in a missing + // barrier in theory. Hence setting all barrier bits whenever + // something previously written is used for the first time in a + // subsequent pass. + for (const QRhiPassResourceTracker::Buffer &b : *buffers) { + QGles2Buffer::Access accessBeforePass = QGles2Buffer::Access(b.stateAtPassBegin.access); + if (accessBeforePass == QGles2Buffer::AccessStorageWrite + || accessBeforePass == QGles2Buffer::AccessStorageReadWrite) + { + barriers |= GL_ALL_BARRIER_BITS; + } + } + const QVector *textures = tracker.textures(); + for (const QRhiPassResourceTracker::Texture &t : *textures) { + QGles2Texture::Access accessBeforePass = QGles2Texture::Access(t.stateAtPassBegin.access); + if (accessBeforePass == QGles2Texture::AccessStorageWrite + || accessBeforePass == QGles2Texture::AccessStorageReadWrite) + { + barriers |= GL_ALL_BARRIER_BITS; + } + } + if (barriers) + f->glMemoryBarrier(barriers); + } + break; + case QGles2CommandBuffer::Command::Barrier: + f->glMemoryBarrier(cmd.args.barrier.barriers); + break; default: break; } @@ -1979,10 +2258,10 @@ void QRhiGles2::executeBindGraphicsPipeline(QRhiGraphicsPipeline *ps) f->glUseProgram(psD->program); } -void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *ps, QRhiShaderResourceBindings *srb, +void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiComputePipeline *maybeComputePs, + QRhiShaderResourceBindings *srb, const uint *dynOfsPairs, int dynOfsCount) { - QGles2GraphicsPipeline *psD = QRHI_RES(QGles2GraphicsPipeline, ps); QGles2ShaderResourceBindings *srbD = QRHI_RES(QGles2ShaderResourceBindings, srb); int texUnit = 0; @@ -2004,7 +2283,9 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *ps, QRhiShaderResource QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.ubuf.buf); const QByteArray bufView = QByteArray::fromRawData(bufD->ubuf.constData() + viewOffset, b->u.ubuf.maybeSize ? b->u.ubuf.maybeSize : bufD->m_size); - for (QGles2GraphicsPipeline::Uniform &uniform : psD->uniforms) { + QVector &uniforms(maybeGraphicsPs ? QRHI_RES(QGles2GraphicsPipeline, maybeGraphicsPs)->uniforms + : QRHI_RES(QGles2ComputePipeline, maybeComputePs)->uniforms); + for (QGles2UniformDescription &uniform : uniforms) { if (uniform.binding == b->binding) { // in a uniform buffer everything is at least 4 byte aligned // so this should not cause unaligned reads @@ -2044,6 +2325,18 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *ps, QRhiShaderResource case QShaderDescription::Int4: f->glUniform4iv(uniform.glslLocation, 1, reinterpret_cast(src)); break; + case QShaderDescription::Uint: + f->glUniform1ui(uniform.glslLocation, *reinterpret_cast(src)); + break; + case QShaderDescription::Uint2: + f->glUniform2uiv(uniform.glslLocation, 1, reinterpret_cast(src)); + break; + case QShaderDescription::Uint3: + f->glUniform3uiv(uniform.glslLocation, 1, reinterpret_cast(src)); + break; + case QShaderDescription::Uint4: + f->glUniform4uiv(uniform.glslLocation, 1, reinterpret_cast(src)); + break; // ### more types default: break; @@ -2056,8 +2349,10 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *ps, QRhiShaderResource { QGles2Texture *texD = QRHI_RES(QGles2Texture, b->u.stex.tex); QGles2Sampler *samplerD = QRHI_RES(QGles2Sampler, b->u.stex.sampler); + QVector &samplers(maybeGraphicsPs ? QRHI_RES(QGles2GraphicsPipeline, maybeGraphicsPs)->samplers + : QRHI_RES(QGles2ComputePipeline, maybeComputePs)->samplers); - for (QGles2GraphicsPipeline::Sampler &sampler : psD->samplers) { + for (QGles2SamplerDescription &sampler : samplers) { if (sampler.binding == b->binding) { f->glActiveTexture(GL_TEXTURE0 + texUnit); f->glBindTexture(texD->target, texD->texture); @@ -2084,6 +2379,38 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *ps, QRhiShaderResource } } break; + case QRhiShaderResourceBinding::ImageLoad: + Q_FALLTHROUGH(); + case QRhiShaderResourceBinding::ImageStore: + Q_FALLTHROUGH(); + case QRhiShaderResourceBinding::ImageLoadStore: + { + QGles2Texture *texD = QRHI_RES(QGles2Texture, b->u.simage.tex); + const bool layered = texD->m_flags.testFlag(QRhiTexture::CubeMap); + GLenum access = GL_READ_WRITE; + if (b->type == QRhiShaderResourceBinding::ImageLoad) + access = GL_READ_ONLY; + else if (b->type == QRhiShaderResourceBinding::ImageStore) + access = GL_WRITE_ONLY; + f->glBindImageTexture(b->binding, texD->texture, + b->u.simage.level, layered, 0, + access, texD->glsizedintformat); + } + break; + case QRhiShaderResourceBinding::BufferLoad: + Q_FALLTHROUGH(); + case QRhiShaderResourceBinding::BufferStore: + Q_FALLTHROUGH(); + case QRhiShaderResourceBinding::BufferLoadStore: + { + QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.sbuf.buf); + if (b->u.sbuf.offset == 0 && b->u.sbuf.maybeSize == 0) + f->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, b->binding, bufD->buffer); + else + f->glBindBufferRange(GL_SHADER_STORAGE_BUFFER, b->binding, bufD->buffer, + b->u.sbuf.offset, b->u.sbuf.maybeSize ? b->u.sbuf.maybeSize : bufD->m_size); + } + break; default: Q_UNREACHABLE(); break; @@ -2105,8 +2432,11 @@ QGles2RenderTargetData *QRhiGles2::enqueueBindFramebuffer(QRhiRenderTarget *rt, bool *wantsColorClear, bool *wantsDsClear) { QGles2RenderTargetData *rtD = nullptr; + QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]); + QGles2CommandBuffer::Command fbCmd; fbCmd.cmd = QGles2CommandBuffer::Command::BindFramebuffer; + switch (rt->resourceType()) { case QRhiResource::RenderTarget: rtD = &QRHI_RES(QGles2ReferenceRenderTarget, rt)->d; @@ -2127,14 +2457,39 @@ QGles2RenderTargetData *QRhiGles2::enqueueBindFramebuffer(QRhiRenderTarget *rt, *wantsDsClear = !rtTex->m_flags.testFlag(QRhiTextureRenderTarget::PreserveDepthStencilContents); fbCmd.args.bindFramebuffer.fbo = rtTex->framebuffer; fbCmd.args.bindFramebuffer.colorAttCount = rtD->colorAttCount; + + const QVector colorAttachments = rtTex->m_desc.colorAttachments(); + for (const QRhiColorAttachment &colorAttachment : colorAttachments) { + QGles2Texture *texD = QRHI_RES(QGles2Texture, colorAttachment.texture()); + QGles2Texture *resolveTexD = QRHI_RES(QGles2Texture, colorAttachment.resolveTexture()); + if (texD) { + trackedRegisterTexture(&passResTracker, texD, + QRhiPassResourceTracker::TexColorOutput, + QRhiPassResourceTracker::TexColorOutputStage); + } + if (resolveTexD) { + trackedRegisterTexture(&passResTracker, resolveTexD, + QRhiPassResourceTracker::TexColorOutput, + QRhiPassResourceTracker::TexColorOutputStage); + } + // renderbuffers cannot be written in shaders (no image store) so + // they do not matter here + } + if (rtTex->m_desc.depthTexture()) { + trackedRegisterTexture(&passResTracker, QRHI_RES(QGles2Texture, rtTex->m_desc.depthTexture()), + QRhiPassResourceTracker::TexDepthOutput, + QRhiPassResourceTracker::TexDepthOutputStage); + } } break; default: Q_UNREACHABLE(); break; } + fbCmd.args.bindFramebuffer.srgb = rtD->srgbUpdateAndBlend; cbD->commands.append(fbCmd); + return rtD; } @@ -2150,6 +2505,15 @@ void QRhiGles2::beginPass(QRhiCommandBuffer *cb, if (resourceUpdates) enqueueResourceUpdates(cb, resourceUpdates); + // Get a new resource tracker. Then add a command that will generate + // glMemoryBarrier() calls based on that tracker when submitted. + cbD->passResTrackers.append(QRhiPassResourceTracker()); + cbD->currentPassResTrackerIndex = cbD->passResTrackers.count() - 1; + QGles2CommandBuffer::Command cmd; + cmd.cmd = QGles2CommandBuffer::Command::BarriersForPass; + cmd.args.barriersForPass.trackerIndex = cbD->currentPassResTrackerIndex; + cbD->commands.append(cmd); + bool wantsColorClear, wantsDsClear; QGles2RenderTargetData *rtD = enqueueBindFramebuffer(rt, cbD, &wantsColorClear, &wantsDsClear); @@ -2170,6 +2534,8 @@ void QRhiGles2::beginPass(QRhiCommandBuffer *cb, cbD->recordingPass = QGles2CommandBuffer::RenderPass; cbD->currentTarget = rt; + + cbD->resetCachedState(); } void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) @@ -2222,7 +2588,16 @@ void QRhiGles2::beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch if (resourceUpdates) enqueueResourceUpdates(cb, resourceUpdates); + cbD->passResTrackers.append(QRhiPassResourceTracker()); + cbD->currentPassResTrackerIndex = cbD->passResTrackers.count() - 1; + QGles2CommandBuffer::Command cmd; + cmd.cmd = QGles2CommandBuffer::Command::BarriersForPass; + cmd.args.barriersForPass.trackerIndex = cbD->currentPassResTrackerIndex; + cbD->commands.append(cmd); + cbD->recordingPass = QGles2CommandBuffer::ComputePass; + + cbD->resetCachedState(); } void QRhiGles2::endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) @@ -2238,16 +2613,189 @@ void QRhiGles2::endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *r void QRhiGles2::setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) { - Q_UNUSED(cb); - Q_UNUSED(ps); + QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb); + Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::ComputePass); + QGles2ComputePipeline *psD = QRHI_RES(QGles2ComputePipeline, ps); + const bool pipelineChanged = cbD->currentComputePipeline != ps || cbD->currentPipelineGeneration != psD->generation; + + if (pipelineChanged) { + cbD->currentGraphicsPipeline = nullptr; + cbD->currentComputePipeline = ps; + cbD->currentPipelineGeneration = psD->generation; + + QGles2CommandBuffer::Command cmd; + cmd.cmd = QGles2CommandBuffer::Command::BindComputePipeline; + cmd.args.bindComputePipeline.ps = ps; + cbD->commands.append(cmd); + } } void QRhiGles2::dispatch(QRhiCommandBuffer *cb, int x, int y, int z) { - Q_UNUSED(cb); - Q_UNUSED(x); - Q_UNUSED(y); - Q_UNUSED(z); + QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb); + Q_ASSERT(cbD->recordingPass == QGles2CommandBuffer::ComputePass); + + QGles2CommandBuffer::Command cmd; + cmd.cmd = QGles2CommandBuffer::Command::Dispatch; + cmd.args.dispatch.x = x; + cmd.args.dispatch.y = y; + cmd.args.dispatch.z = z; + cbD->commands.append(cmd); +} + +static inline GLenum toGlShaderType(QRhiShaderStage::Type type) +{ + switch (type) { + case QRhiShaderStage::Vertex: + return GL_VERTEX_SHADER; + case QRhiShaderStage::Fragment: + return GL_FRAGMENT_SHADER; + case QRhiShaderStage::Compute: + return GL_COMPUTE_SHADER; + default: + Q_UNREACHABLE(); + return GL_VERTEX_SHADER; + } +} + +bool QRhiGles2::compileShader(GLuint program, const QRhiShaderStage &shaderStage, + QShaderDescription *desc, int *glslVersionUsed) +{ + GLuint shader = f->glCreateShader(toGlShaderType(shaderStage.type())); + const QShader bakedShader = shaderStage.shader(); + QVector versionsToTry; + QByteArray source; + if (caps.gles) { + if (caps.ctxMajor > 3 || (caps.ctxMajor == 3 && caps.ctxMinor >= 2)) { + versionsToTry << 320 << 310 << 300 << 100; + } else if (caps.ctxMajor == 3 && caps.ctxMinor == 1) { + versionsToTry << 310 << 300 << 100; + } else if (caps.ctxMajor == 3 && caps.ctxMinor == 0) { + versionsToTry << 300 << 100; + } else { + versionsToTry << 100; + } + for (int v : versionsToTry) { + QShaderVersion ver(v, QShaderVersion::GlslEs); + source = bakedShader.shader({ QShader::GlslShader, ver, shaderStage.shaderVariant() }).shader(); + if (!source.isEmpty()) { + if (glslVersionUsed) + *glslVersionUsed = v; + break; + } + } + } else { + if (caps.ctxMajor > 4 || (caps.ctxMajor == 4 && caps.ctxMinor >= 6)) { + versionsToTry << 460 << 450 << 440 << 430 << 420 << 410 << 400 << 330 << 150; + } else if (caps.ctxMajor == 4 && caps.ctxMinor == 5) { + versionsToTry << 450 << 440 << 430 << 420 << 410 << 400 << 330 << 150; + } else if (caps.ctxMajor == 4 && caps.ctxMinor == 4) { + versionsToTry << 440 << 430 << 420 << 410 << 400 << 330 << 150; + } else if (caps.ctxMajor == 4 && caps.ctxMinor == 3) { + versionsToTry << 430 << 420 << 410 << 400 << 330 << 150; + } else if (caps.ctxMajor == 4 && caps.ctxMinor == 2) { + versionsToTry << 420 << 410 << 400 << 330 << 150; + } else if (caps.ctxMajor == 4 && caps.ctxMinor == 1) { + versionsToTry << 410 << 400 << 330 << 150; + } else if (caps.ctxMajor == 4 && caps.ctxMinor == 0) { + versionsToTry << 400 << 330 << 150; + } else if (caps.ctxMajor == 3 && caps.ctxMinor == 3) { + versionsToTry << 330 << 150; + } else if (caps.ctxMajor == 3 && caps.ctxMinor == 2) { + versionsToTry << 150; + } + if (!caps.coreProfile) + versionsToTry << 120; + for (int v : versionsToTry) { + source = bakedShader.shader({ QShader::GlslShader, v, shaderStage.shaderVariant() }).shader(); + if (!source.isEmpty()) { + if (glslVersionUsed) + *glslVersionUsed = v; + break; + } + } + } + if (source.isEmpty()) { + qWarning() << "No GLSL shader code found (versions tried: " << versionsToTry + << ") in baked shader" << bakedShader; + return false; + } + + const char *srcStr = source.constData(); + const GLint srcLength = source.count(); + f->glShaderSource(shader, 1, &srcStr, &srcLength); + f->glCompileShader(shader); + GLint compiled = 0; + f->glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) { + GLint infoLogLength = 0; + f->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); + QByteArray log; + if (infoLogLength > 1) { + GLsizei length = 0; + log.resize(infoLogLength); + f->glGetShaderInfoLog(shader, infoLogLength, &length, log.data()); + } + qWarning("Failed to compile shader: %s\nSource was:\n%s", log.constData(), source.constData()); + return false; + } + + f->glAttachShader(program, shader); + f->glDeleteShader(shader); + + *desc = bakedShader.description(); + return true; +} + +bool QRhiGles2::linkProgram(GLuint program) +{ + f->glLinkProgram(program); + GLint linked = 0; + f->glGetProgramiv(program, GL_LINK_STATUS, &linked); + if (!linked) { + GLint infoLogLength = 0; + f->glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength); + QByteArray log; + if (infoLogLength > 1) { + GLsizei length = 0; + log.resize(infoLogLength); + f->glGetProgramInfoLog(program, infoLogLength, &length, log.data()); + } + qWarning("Failed to link shader program: %s", log.constData()); + return false; + } + return true; +} + +void QRhiGles2::gatherUniforms(GLuint program, const QShaderDescription::UniformBlock &ub, + QVector *dst) +{ + const QByteArray prefix = ub.structName.toUtf8() + '.'; + for (const QShaderDescription::BlockVariable &blockMember : ub.members) { + // ### no array support for now + QGles2UniformDescription uniform; + uniform.type = blockMember.type; + const QByteArray name = prefix + blockMember.name.toUtf8(); + uniform.glslLocation = f->glGetUniformLocation(program, name.constData()); + if (uniform.glslLocation >= 0) { + uniform.binding = ub.binding; + uniform.offset = blockMember.offset; + uniform.size = blockMember.size; + dst->append(uniform); + } + } +} + +void QRhiGles2::gatherSamplers(GLuint program, const QShaderDescription::InOutVariable &v, + QVector *dst) +{ + QGles2SamplerDescription sampler; + const QByteArray name = v.name.toUtf8(); + sampler.glslLocation = f->glGetUniformLocation(program, name.constData()); + if (sampler.glslLocation >= 0) { + sampler.binding = v.binding; + dst->append(sampler); + } } QGles2Buffer::QGles2Buffer(QRhiImplementation *rhi, Type type, UsageFlags usage, int size) @@ -2288,7 +2836,7 @@ bool QGles2Buffer::build() QRHI_PROF; if (m_usage.testFlag(QRhiBuffer::UniformBuffer)) { - if (m_usage.testFlag(QRhiBuffer::VertexBuffer) || m_usage.testFlag(QRhiBuffer::IndexBuffer)) { + if (int(m_usage) != QRhiBuffer::UniformBuffer) { qWarning("Uniform buffer: multiple usages specified, this is not supported by the OpenGL backend"); return false; } @@ -2300,19 +2848,17 @@ bool QGles2Buffer::build() if (!rhiD->ensureContext()) return false; - if (m_usage.testFlag(QRhiBuffer::VertexBuffer)) { - if (m_usage.testFlag(QRhiBuffer::IndexBuffer)) { - qWarning("Vertex buffer: multiple usages specified, this is not supported by the OpenGL backend"); - return false; - } - target = GL_ARRAY_BUFFER; - } + targetForDataOps = GL_ARRAY_BUFFER; if (m_usage.testFlag(QRhiBuffer::IndexBuffer)) - target = GL_ELEMENT_ARRAY_BUFFER; + targetForDataOps = GL_ELEMENT_ARRAY_BUFFER; + else if (m_usage.testFlag(QRhiBuffer::StorageBuffer)) + targetForDataOps = GL_SHADER_STORAGE_BUFFER; rhiD->f->glGenBuffers(1, &buffer); - rhiD->f->glBindBuffer(target, buffer); - rhiD->f->glBufferData(target, m_size, nullptr, m_type == Dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); + rhiD->f->glBindBuffer(targetForDataOps, buffer); + rhiD->f->glBufferData(targetForDataOps, m_size, nullptr, m_type == Dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); + + usageState.access = AccessNone; QRHI_PROF_F(newBuffer(this, m_size, 1, 0)); rhiD->registerResource(this); @@ -2483,58 +3029,73 @@ bool QGles2Texture::prepareBuild(QSize *adjustedSize) gltype = GL_UNSIGNED_BYTE; if (isCompressed) { + if (m_flags.testFlag(UsedWithLoadStore)) { + qWarning("Compressed texture cannot be used with image load/store"); + return false; + } glintformat = toGlCompressedTextureFormat(m_format, m_flags); if (!glintformat) { qWarning("Compressed format %d not mappable to GL compressed format", m_format); return false; } + glsizedintformat = glintformat; glformat = GL_RGBA; } else { switch (m_format) { case QRhiTexture::RGBA8: glintformat = GL_RGBA; + glsizedintformat = rhiD->caps.rgba8Format ? GL_RGBA8 : GL_RGBA; glformat = GL_RGBA; break; case QRhiTexture::BGRA8: glintformat = rhiD->caps.bgraInternalFormat ? GL_BGRA : GL_RGBA; + glsizedintformat = rhiD->caps.rgba8Format ? GL_RGBA8 : GL_RGBA; glformat = GL_BGRA; break; case QRhiTexture::R16: glintformat = GL_R16; + glsizedintformat = glintformat; glformat = GL_RED; gltype = GL_UNSIGNED_SHORT; break; case QRhiTexture::R8: glintformat = GL_R8; + glsizedintformat = glintformat; glformat = GL_RED; break; case QRhiTexture::RED_OR_ALPHA8: glintformat = rhiD->caps.coreProfile ? GL_R8 : GL_ALPHA; + glsizedintformat = glintformat; glformat = rhiD->caps.coreProfile ? GL_RED : GL_ALPHA; break; case QRhiTexture::RGBA16F: glintformat = GL_RGBA16F; + glsizedintformat = glintformat; glformat = GL_RGBA; gltype = GL_HALF_FLOAT; break; case QRhiTexture::RGBA32F: glintformat = GL_RGBA32F; + glsizedintformat = glintformat; glformat = GL_RGBA; gltype = GL_FLOAT; break; case QRhiTexture::D16: glintformat = GL_DEPTH_COMPONENT16; + glsizedintformat = glintformat; glformat = GL_DEPTH_COMPONENT; gltype = GL_UNSIGNED_SHORT; break; case QRhiTexture::D32F: glintformat = GL_DEPTH_COMPONENT32F; + glsizedintformat = glintformat; glformat = GL_DEPTH_COMPONENT; gltype = GL_FLOAT; break; default: Q_UNREACHABLE(); glintformat = GL_RGBA; + glsizedintformat = rhiD->caps.rgba8Format ? GL_RGBA8 : GL_RGBA; glformat = GL_RGBA; break; } @@ -2542,6 +3103,8 @@ bool QGles2Texture::prepareBuild(QSize *adjustedSize) samplerState = QGles2SamplerData(); + usageState.access = AccessNone; + if (adjustedSize) *adjustedSize = size; @@ -2562,18 +3125,25 @@ bool QGles2Texture::build() const bool isCompressed = rhiD->isCompressedFormat(m_format); if (!isCompressed) { rhiD->f->glBindTexture(target, texture); - if (hasMipMaps || isCube) { - const GLenum faceTargetBase = isCube ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target; - for (int layer = 0, layerCount = isCube ? 6 : 1; layer != layerCount; ++layer) { - for (int level = 0; level != mipLevelCount; ++level) { - const QSize mipSize = rhiD->q->sizeForMipLevel(level, size); - rhiD->f->glTexImage2D(faceTargetBase + layer, level, glintformat, - mipSize.width(), mipSize.height(), 0, - glformat, gltype, nullptr); + if (!m_flags.testFlag(UsedWithLoadStore)) { + if (hasMipMaps || isCube) { + const GLenum faceTargetBase = isCube ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target; + for (int layer = 0, layerCount = isCube ? 6 : 1; layer != layerCount; ++layer) { + for (int level = 0; level != mipLevelCount; ++level) { + const QSize mipSize = rhiD->q->sizeForMipLevel(level, size); + rhiD->f->glTexImage2D(faceTargetBase + layer, level, glsizedintformat, + mipSize.width(), mipSize.height(), 0, + glformat, gltype, nullptr); + } } + } else { + rhiD->f->glTexImage2D(target, 0, glsizedintformat, size.width(), size.height(), + 0, glformat, gltype, nullptr); } } else { - rhiD->f->glTexImage2D(target, 0, glintformat, size.width(), size.height(), 0, glformat, gltype, nullptr); + // Must be specified with immutable storage functions otherwise + // bindImageTexture may fail. + rhiD->f->glTexStorage2D(target, mipLevelCount, glsizedintformat, size.width(), size.height()); } specified = true; } else { @@ -2910,161 +3480,39 @@ bool QGles2GraphicsPipeline::build() program = rhiD->f->glCreateProgram(); - int sourceVer = 0; + QShaderDescription vsDesc; + QShaderDescription fsDesc; for (const QRhiShaderStage &shaderStage : qAsConst(m_shaderStages)) { const bool isVertex = shaderStage.type() == QRhiShaderStage::Vertex; const bool isFragment = shaderStage.type() == QRhiShaderStage::Fragment; - if (!isVertex && !isFragment) - continue; - - GLuint shader = rhiD->f->glCreateShader(isVertex ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER); - const QShader bakedShader = shaderStage.shader(); - QVector versionsToTry; - QByteArray source; - if (rhiD->caps.gles) { - if (rhiD->caps.ctxMajor > 3 || (rhiD->caps.ctxMajor == 3 && rhiD->caps.ctxMinor >= 2)) { - versionsToTry << 320 << 310 << 300 << 100; - } else if (rhiD->caps.ctxMajor == 3 && rhiD->caps.ctxMinor == 1) { - versionsToTry << 310 << 300 << 100; - } else if (rhiD->caps.ctxMajor == 3 && rhiD->caps.ctxMinor == 0) { - versionsToTry << 300 << 100; - } else { - versionsToTry << 100; - } - for (int v : versionsToTry) { - QShaderVersion ver(v, QShaderVersion::GlslEs); - source = bakedShader.shader({ QShader::GlslShader, ver, shaderStage.shaderVariant() }).shader(); - if (!source.isEmpty()) { - sourceVer = v; - break; - } - } - } else { - if (rhiD->caps.ctxMajor > 4 || (rhiD->caps.ctxMajor == 4 && rhiD->caps.ctxMinor >= 6)) { - versionsToTry << 460 << 450 << 440 << 430 << 420 << 410 << 400 << 330 << 150; - } else if (rhiD->caps.ctxMajor == 4 && rhiD->caps.ctxMinor == 5) { - versionsToTry << 450 << 440 << 430 << 420 << 410 << 400 << 330 << 150; - } else if (rhiD->caps.ctxMajor == 4 && rhiD->caps.ctxMinor == 4) { - versionsToTry << 440 << 430 << 420 << 410 << 400 << 330 << 150; - } else if (rhiD->caps.ctxMajor == 4 && rhiD->caps.ctxMinor == 3) { - versionsToTry << 430 << 420 << 410 << 400 << 330 << 150; - } else if (rhiD->caps.ctxMajor == 4 && rhiD->caps.ctxMinor == 2) { - versionsToTry << 420 << 410 << 400 << 330 << 150; - } else if (rhiD->caps.ctxMajor == 4 && rhiD->caps.ctxMinor == 1) { - versionsToTry << 410 << 400 << 330 << 150; - } else if (rhiD->caps.ctxMajor == 4 && rhiD->caps.ctxMinor == 0) { - versionsToTry << 400 << 330 << 150; - } else if (rhiD->caps.ctxMajor == 3 && rhiD->caps.ctxMinor == 3) { - versionsToTry << 330 << 150; - } else if (rhiD->caps.ctxMajor == 3 && rhiD->caps.ctxMinor == 2) { - versionsToTry << 150; - } - if (!rhiD->caps.coreProfile) - versionsToTry << 120; - for (int v : versionsToTry) { - source = bakedShader.shader({ QShader::GlslShader, v, shaderStage.shaderVariant() }).shader(); - if (!source.isEmpty()) { - sourceVer = v; - break; - } - } + if (isVertex) { + if (!rhiD->compileShader(program, shaderStage, &vsDesc, nullptr)) + return false; + } else if (isFragment) { + if (!rhiD->compileShader(program, shaderStage, &fsDesc, nullptr)) + return false; } - if (source.isEmpty()) { - qWarning() << "No GLSL shader code found (versions tried: " << versionsToTry - << ") in baked shader" << bakedShader; - return false; - } - - const char *srcStr = source.constData(); - const GLint srcLength = source.count(); - rhiD->f->glShaderSource(shader, 1, &srcStr, &srcLength); - rhiD->f->glCompileShader(shader); - GLint compiled = 0; - rhiD->f->glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); - if (!compiled) { - GLint infoLogLength = 0; - rhiD->f->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); - QByteArray log; - if (infoLogLength > 1) { - GLsizei length = 0; - log.resize(infoLogLength); - rhiD->f->glGetShaderInfoLog(shader, infoLogLength, &length, log.data()); - } - qWarning("Failed to compile shader: %s\nSource was:\n%s", log.constData(), source.constData()); - return false; - } - - rhiD->f->glAttachShader(program, shader); - rhiD->f->glDeleteShader(shader); - - if (isVertex) - vsDesc = bakedShader.description(); - else - fsDesc = bakedShader.description(); } - // not very useful atm since we assume the qsb-generated GLSL shaders never use uniform blocks - canUseUniformBuffers = rhiD->caps.uniformBuffers && sourceVer >= 140; - for (auto inVar : vsDesc.inputVariables()) { const QByteArray name = inVar.name.toUtf8(); rhiD->f->glBindAttribLocation(program, inVar.location, name.constData()); } - rhiD->f->glLinkProgram(program); - GLint linked = 0; - rhiD->f->glGetProgramiv(program, GL_LINK_STATUS, &linked); - if (!linked) { - GLint infoLogLength = 0; - rhiD->f->glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength); - QByteArray log; - if (infoLogLength > 1) { - GLsizei length = 0; - log.resize(infoLogLength); - rhiD->f->glGetProgramInfoLog(program, infoLogLength, &length, log.data()); - } - qWarning("Failed to link shader program: %s", log.constData()); + if (!rhiD->linkProgram(program)) return false; - } - - auto lookupUniforms = [this, rhiD](const QShaderDescription::UniformBlock &ub) { - const QByteArray prefix = ub.structName.toUtf8() + '.'; - for (const QShaderDescription::BlockVariable &blockMember : ub.members) { - // ### no array support for now - Uniform uniform; - uniform.type = blockMember.type; - const QByteArray name = prefix + blockMember.name.toUtf8(); - uniform.glslLocation = rhiD->f->glGetUniformLocation(program, name.constData()); - if (uniform.glslLocation >= 0) { - uniform.binding = ub.binding; - uniform.offset = blockMember.offset; - uniform.size = blockMember.size; - uniforms.append(uniform); - } - } - }; for (const QShaderDescription::UniformBlock &ub : vsDesc.uniformBlocks()) - lookupUniforms(ub); + rhiD->gatherUniforms(program, ub, &uniforms); for (const QShaderDescription::UniformBlock &ub : fsDesc.uniformBlocks()) - lookupUniforms(ub); - - auto lookupSamplers = [this, rhiD](const QShaderDescription::InOutVariable &v) { - Sampler sampler; - const QByteArray name = v.name.toUtf8(); - sampler.glslLocation = rhiD->f->glGetUniformLocation(program, name.constData()); - if (sampler.glslLocation >= 0) { - sampler.binding = v.binding; - samplers.append(sampler); - } - }; + rhiD->gatherUniforms(program, ub, &uniforms); for (const QShaderDescription::InOutVariable &v : vsDesc.combinedImageSamplers()) - lookupSamplers(v); + rhiD->gatherSamplers(program, v, &samplers); for (const QShaderDescription::InOutVariable &v : fsDesc.combinedImageSamplers()) - lookupSamplers(v); + rhiD->gatherSamplers(program, v, &samplers); generation += 1; rhiD->registerResource(this); @@ -3083,11 +3531,52 @@ QGles2ComputePipeline::~QGles2ComputePipeline() void QGles2ComputePipeline::release() { + if (!program) + return; + + QRhiGles2::DeferredReleaseEntry e; + e.type = QRhiGles2::DeferredReleaseEntry::Pipeline; + + e.pipeline.program = program; + + program = 0; + uniforms.clear(); + samplers.clear(); + + QRHI_RES_RHI(QRhiGles2); + rhiD->releaseQueue.append(e); + + rhiD->unregisterResource(this); } bool QGles2ComputePipeline::build() { - return false; + QRHI_RES_RHI(QRhiGles2); + + if (program) + release(); + + if (!rhiD->ensureContext()) + return false; + + program = rhiD->f->glCreateProgram(); + QShaderDescription csDesc; + + if (!rhiD->compileShader(program, m_shaderStage, &csDesc, nullptr)) + return false; + if (!rhiD->linkProgram(program)) + return false; + + for (const QShaderDescription::UniformBlock &ub : csDesc.uniformBlocks()) + rhiD->gatherUniforms(program, ub, &uniforms); + for (const QShaderDescription::InOutVariable &v : csDesc.combinedImageSamplers()) + rhiD->gatherSamplers(program, v, &samplers); + + // storage images and buffers need no special steps here + + generation += 1; + rhiD->registerResource(this); + return true; } QGles2CommandBuffer::QGles2CommandBuffer(QRhiImplementation *rhi) diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h index d6682977ff..88a6144b42 100644 --- a/src/gui/rhi/qrhigles2_p_p.h +++ b/src/gui/rhi/qrhigles2_p_p.h @@ -66,8 +66,22 @@ struct QGles2Buffer : public QRhiBuffer bool build() override; GLuint buffer = 0; - GLenum target; + GLenum targetForDataOps; QByteArray ubuf; + enum Access { + AccessNone, + AccessVertex, + AccessIndex, + AccessUniform, + AccessStorageRead, + AccessStorageWrite, + AccessStorageReadWrite, + AccessUpdate + }; + struct UsageState { + Access access; + }; + UsageState usageState; friend class QRhiGles2; }; @@ -127,12 +141,27 @@ struct QGles2Texture : public QRhiTexture bool owns = true; GLenum target; GLenum glintformat; + GLenum glsizedintformat; GLenum glformat; GLenum gltype; QGles2SamplerData samplerState; bool specified = false; int mipLevelCount = 0; QRhiGles2TextureNativeHandles nativeHandlesStruct; + enum Access { + AccessNone, + AccessSample, + AccessFramebuffer, + AccessStorageRead, + AccessStorageWrite, + AccessStorageReadWrite, + AccessUpdate, + AccessRead + }; + struct UsageState { + Access access; + }; + UsageState usageState; uint generation = 0; friend class QRhiGles2; @@ -213,6 +242,25 @@ struct QGles2ShaderResourceBindings : public QRhiShaderResourceBindings friend class QRhiGles2; }; +struct QGles2UniformDescription +{ + QShaderDescription::VariableType type; + int glslLocation; + int binding; + uint offset; + int size; +}; + +Q_DECLARE_TYPEINFO(QGles2UniformDescription, Q_MOVABLE_TYPE); + +struct QGles2SamplerDescription +{ + int glslLocation; + int binding; +}; + +Q_DECLARE_TYPEINFO(QGles2SamplerDescription, Q_MOVABLE_TYPE); + struct QGles2GraphicsPipeline : public QRhiGraphicsPipeline { QGles2GraphicsPipeline(QRhiImplementation *rhi); @@ -222,38 +270,24 @@ struct QGles2GraphicsPipeline : public QRhiGraphicsPipeline GLuint program = 0; GLenum drawMode = GL_TRIANGLES; - QShaderDescription vsDesc; - QShaderDescription fsDesc; - bool canUseUniformBuffers = false; - - struct Uniform { - QShaderDescription::VariableType type; - int glslLocation; - int binding; - uint offset; - int size; - }; - QVector uniforms; - - struct Sampler { - int glslLocation; - int binding; - }; - QVector samplers; - + QVector uniforms; + QVector samplers; uint generation = 0; friend class QRhiGles2; }; -Q_DECLARE_TYPEINFO(QGles2GraphicsPipeline::Uniform, Q_MOVABLE_TYPE); -Q_DECLARE_TYPEINFO(QGles2GraphicsPipeline::Sampler, Q_MOVABLE_TYPE); - struct QGles2ComputePipeline : public QRhiComputePipeline { QGles2ComputePipeline(QRhiImplementation *rhi); ~QGles2ComputePipeline(); void release() override; bool build() override; + + GLuint program = 0; + QVector uniforms; + QVector samplers; + uint generation = 0; + friend class QRhiGles2; }; struct QGles2CommandBuffer : public QRhiCommandBuffer @@ -286,7 +320,11 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer CompressedImage, CompressedSubImage, BlitFromRenderbuffer, - GenMip + GenMip, + BindComputePipeline, + Dispatch, + BarriersForPass, + Barrier }; Cmd cmd; @@ -339,7 +377,8 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer QRhiGraphicsPipeline *ps; } bindGraphicsPipeline; struct { - QRhiGraphicsPipeline *ps; + QRhiGraphicsPipeline *maybeGraphicsPs; + QRhiComputePipeline *maybeComputePs; QRhiShaderResourceBindings *srb; int dynamicOffsetCount; uint dynamicOffsetPairs[MAX_UBUF_BINDINGS * 2]; // binding, offsetInConstants @@ -436,6 +475,20 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer GLenum target; GLuint texture; } genMip; + struct { + QRhiComputePipeline *ps; + } bindComputePipeline; + struct { + GLuint x; + GLuint y; + GLuint z; + } dispatch; + struct { + int trackerIndex; + } barriersForPass; + struct { + GLbitfield barriers; + } barrier; } args; }; @@ -446,11 +499,16 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer }; QVector commands; + QVarLengthArray passResTrackers; + int currentPassResTrackerIndex; + PassType recordingPass; QRhiRenderTarget *currentTarget; - QRhiGraphicsPipeline *currentPipeline; + QRhiGraphicsPipeline *currentGraphicsPipeline; + QRhiComputePipeline *currentComputePipeline; uint currentPipelineGeneration; - QRhiShaderResourceBindings *currentSrb; + QRhiShaderResourceBindings *currentGraphicsSrb; + QRhiShaderResourceBindings *currentComputeSrb; uint currentSrbGeneration; QVector dataRetainPool; @@ -467,6 +525,12 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer } void resetCommands() { commands.clear(); + // beginExternal() can lead to calling resetCommands() inside a pass, + // hence the condition + if (recordingPass == NoPass) { + passResTrackers.clear(); + currentPassResTrackerIndex = -1; + } dataRetainPool.clear(); imageRetainPool.clear(); } @@ -477,9 +541,11 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer resetCachedState(); } void resetCachedState() { - currentPipeline = nullptr; + currentGraphicsPipeline = nullptr; + currentComputePipeline = nullptr; currentPipelineGeneration = 0; - currentSrb = nullptr; + currentGraphicsSrb = nullptr; + currentComputeSrb = nullptr; currentSrbGeneration = 0; } }; @@ -606,17 +672,35 @@ public: bool ensureContext(QSurface *surface = nullptr) const; void executeDeferredReleases(); QRhi::FrameOpResult flushCommandBuffer(); + void trackedBufferBarrier(QGles2CommandBuffer *cbD, QGles2Buffer *bufD, QGles2Buffer::Access access); + void trackedImageBarrier(QGles2CommandBuffer *cbD, QGles2Texture *texD, QGles2Texture::Access access); void enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cbD, int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc); void enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates); + void trackedRegisterBuffer(QRhiPassResourceTracker *passResTracker, + QGles2Buffer *bufD, + QRhiPassResourceTracker::BufferAccess access, + QRhiPassResourceTracker::BufferStage stage); + void trackedRegisterTexture(QRhiPassResourceTracker *passResTracker, + QGles2Texture *texD, + QRhiPassResourceTracker::TextureAccess access, + QRhiPassResourceTracker::TextureStage stage); void executeCommandBuffer(QRhiCommandBuffer *cb); void executeBindGraphicsPipeline(QRhiGraphicsPipeline *ps); - void bindShaderResources(QRhiGraphicsPipeline *ps, QRhiShaderResourceBindings *srb, + void bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiComputePipeline *maybeComputePs, + QRhiShaderResourceBindings *srb, const uint *dynOfsPairs, int dynOfsCount); QGles2RenderTargetData *enqueueBindFramebuffer(QRhiRenderTarget *rt, QGles2CommandBuffer *cbD, bool *wantsColorClear = nullptr, bool *wantsDsClear = nullptr); int effectiveSampleCount(int sampleCount) const; QSize safeTextureSize(const QSize &size) const; + bool compileShader(GLuint program, const QRhiShaderStage &shaderStage, + QShaderDescription *desc, int *glslVersionUsed); + bool linkProgram(GLuint program); + void gatherUniforms(GLuint program, const QShaderDescription::UniformBlock &ub, + QVector *dst); + void gatherSamplers(GLuint program, const QShaderDescription::InOutVariable &v, + QVector *dst); QOpenGLContext *ctx = nullptr; bool importedContext = false; @@ -652,7 +736,8 @@ public: depth24(false), rgba8Format(false), instancing(false), - baseVertex(false) + baseVertex(false), + compute(false) { } int ctxMajor; int ctxMinor; @@ -682,6 +767,7 @@ public: uint rgba8Format : 1; uint instancing : 1; uint baseVertex : 1; + uint compute : 1; } caps; QGles2SwapChain *currentSwapChain = nullptr; QVector supportedCompressedFormats; diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index 2caa6cdec4..f48a8a3cfe 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -3664,34 +3664,6 @@ void QRhiVulkan::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline psD->lastActiveFrameSlot = currentFrameSlot; } -QRhiPassResourceTracker::BufferStage toPassTrackerBufferStage(QRhiShaderResourceBinding::StageFlags stages) -{ - // pick the earlier stage (as this is going to be dstAccessMask) - if (stages.testFlag(QRhiShaderResourceBinding::VertexStage)) - return QRhiPassResourceTracker::BufVertexStage; - if (stages.testFlag(QRhiShaderResourceBinding::FragmentStage)) - return QRhiPassResourceTracker::BufFragmentStage; - if (stages.testFlag(QRhiShaderResourceBinding::ComputeStage)) - return QRhiPassResourceTracker::BufComputeStage; - - Q_UNREACHABLE(); - return QRhiPassResourceTracker::BufVertexStage; -} - -QRhiPassResourceTracker::TextureStage toPassTrackerTextureStage(QRhiShaderResourceBinding::StageFlags stages) -{ - // pick the earlier stage (as this is going to be dstAccessMask) - if (stages.testFlag(QRhiShaderResourceBinding::VertexStage)) - return QRhiPassResourceTracker::TexVertexStage; - if (stages.testFlag(QRhiShaderResourceBinding::FragmentStage)) - return QRhiPassResourceTracker::TexFragmentStage; - if (stages.testFlag(QRhiShaderResourceBinding::ComputeStage)) - return QRhiPassResourceTracker::TexComputeStage; - - Q_UNREACHABLE(); - return QRhiPassResourceTracker::TexVertexStage; -} - void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBindings *srb, int dynamicOffsetCount, const QRhiCommandBuffer::DynamicOffset *dynamicOffsets) @@ -3747,7 +3719,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin bufD->lastActiveFrameSlot = currentFrameSlot; trackedRegisterBuffer(&passResTracker, bufD, bufD->m_type == QRhiBuffer::Dynamic ? currentFrameSlot : 0, QRhiPassResourceTracker::BufUniformRead, - toPassTrackerBufferStage(b->stage)); + QRhiPassResourceTracker::toPassTrackerBufferStage(b->stage)); // Check both the "local" id (the generation counter) and the // global id. The latter is relevant when a newly allocated @@ -3768,7 +3740,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin samplerD->lastActiveFrameSlot = currentFrameSlot; trackedRegisterTexture(&passResTracker, texD, QRhiPassResourceTracker::TexSample, - toPassTrackerTextureStage(b->stage)); + QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage)); if (texD->generation != bd.stex.texGeneration || texD->m_id != bd.stex.texId @@ -3801,7 +3773,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin access = QRhiPassResourceTracker::TexStorageLoadStore; trackedRegisterTexture(&passResTracker, texD, access, - toPassTrackerTextureStage(b->stage)); + QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage)); if (texD->generation != bd.simage.generation || texD->m_id != bd.simage.id) { rewriteDescSet = true; @@ -3832,7 +3804,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin access = QRhiPassResourceTracker::BufStorageLoadStore; trackedRegisterBuffer(&passResTracker, bufD, bufD->m_type == QRhiBuffer::Dynamic ? currentFrameSlot : 0, access, - toPassTrackerBufferStage(b->stage)); + QRhiPassResourceTracker::toPassTrackerBufferStage(b->stage)); if (bufD->generation != bd.sbuf.generation || bufD->m_id != bd.sbuf.id) { rewriteDescSet = true; diff --git a/tests/manual/rhi/computeimage/computeimage.cpp b/tests/manual/rhi/computeimage/computeimage.cpp index 7bc05fc04f..51bf216c5a 100644 --- a/tests/manual/rhi/computeimage/computeimage.cpp +++ b/tests/manual/rhi/computeimage/computeimage.cpp @@ -146,7 +146,7 @@ void Window::customInit() d.ubuf->build(); d.releasePool << d.ubuf; - qint32 flip = m_r->isYUpInFramebuffer() ? 1 : 0; + qint32 flip = 0; // regardless of isYUpInFramebuffer() since the input is not flipped so the end result is good for GL too d.initialUpdates->updateDynamicBuffer(d.ubuf, 64, 4, &flip); d.sampler = m_r->newSampler(QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None, From 3f201f988f5ddffb8deb16c8eb764c2917e16f52 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 26 Jul 2019 09:54:18 +0200 Subject: [PATCH 232/264] rhi: Fix clear value in offscreen test Leftover from the migration to QColor as color clear value. Change-Id: Ibf49d65234a1e14d53035b46249753a5929ca22b Reviewed-by: Andy Nichols --- tests/manual/rhi/offscreen/offscreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/manual/rhi/offscreen/offscreen.cpp b/tests/manual/rhi/offscreen/offscreen.cpp index 678d6ffe48..79e50d3dd4 100644 --- a/tests/manual/rhi/offscreen/offscreen.cpp +++ b/tests/manual/rhi/offscreen/offscreen.cpp @@ -307,7 +307,7 @@ int main(int argc, char **argv) opacity = qBound(0.0f, opacity, 1.0f); } - cb->beginPass(rt, { 0, 1, 0, 1 }, { 1, 0 }, u); + cb->beginPass(rt, QColor::fromRgbF(0.0f, 1.0f, 0.0f, 1.0f), { 1, 0 }, u); cb->setGraphicsPipeline(ps); cb->setViewport({ 0, 0, 1280, 720 }); cb->setShaderResources(); From 25c38601de3e44f2f43418143904574dd8941bd1 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 31 Jul 2019 08:48:14 +0300 Subject: [PATCH 233/264] QWheelEvent: use QT_DEPRECATED_VERSION_X_5_15 ... in an attempt to get qt5 integration going. Change-Id: I22dd6ff2cb9a6d11620878c432905bd07292220b Reviewed-by: Friedemann Kleint Reviewed-by: Simon Hausmann --- src/gui/kernel/qevent.h | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 7653cc97e2..b73d90529a 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -177,28 +177,28 @@ public: #if QT_DEPRECATED_SINCE(5, 15) // Actually deprecated since 5.0, in docs - QT_DEPRECATED_X("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") + QT_DEPRECATED_VERSION_X_5_15("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") QWheelEvent(const QPointF &pos, int delta, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::Orientation orient = Qt::Vertical); // Actually deprecated since 5.0, in docs - QT_DEPRECATED_X("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") + QT_DEPRECATED_VERSION_X_5_15("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::Orientation orient = Qt::Vertical); - QT_DEPRECATED_X("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") + QT_DEPRECATED_VERSION_X_5_15("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") QWheelEvent(const QPointF &pos, const QPointF& globalPos, QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers); - QT_DEPRECATED_X("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") + QT_DEPRECATED_VERSION_X_5_15("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") QWheelEvent(const QPointF &pos, const QPointF& globalPos, QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase); - QT_DEPRECATED_X("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") + QT_DEPRECATED_VERSION_X_5_15("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") QWheelEvent(const QPointF &pos, const QPointF &globalPos, QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase, Qt::MouseEventSource source); - QT_DEPRECATED_X("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") + QT_DEPRECATED_VERSION_X_5_15("Use the last QWheelEvent constructor taking pixelDelta, angleDelta, phase, and inverted") QWheelEvent(const QPointF &pos, const QPointF &globalPos, QPoint pixelDelta, QPoint angleDelta, int qt4Delta, Qt::Orientation qt4Orientation, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers, Qt::ScrollPhase phase, Qt::MouseEventSource source, bool inverted); @@ -215,28 +215,28 @@ public: #if QT_DEPRECATED_SINCE(5, 15) // Actually deprecated since 5.0, in docs - QT_DEPRECATED_X("Use angleDelta()") + QT_DEPRECATED_VERSION_X_5_15("Use angleDelta()") inline int delta() const { return qt4D; } // Actually deprecated since 5.0, in docs - QT_DEPRECATED_X("Use angleDelta()") + QT_DEPRECATED_VERSION_X_5_15("Use angleDelta()") inline Qt::Orientation orientation() const { return qt4O; } #ifndef QT_NO_INTEGER_EVENT_COORDINATES - QT_DEPRECATED_X("Use position()") + QT_DEPRECATED_VERSION_X_5_15("Use position()") inline QPoint pos() const { return p.toPoint(); } - QT_DEPRECATED_X("Use globalPosition()") + QT_DEPRECATED_VERSION_X_5_15("Use globalPosition()") inline QPoint globalPos() const { return g.toPoint(); } - QT_DEPRECATED_X("Use position()") + QT_DEPRECATED_VERSION_X_5_15("Use position()") inline int x() const { return int(p.x()); } - QT_DEPRECATED_X("Use position()") + QT_DEPRECATED_VERSION_X_5_15("Use position()") inline int y() const { return int(p.y()); } - QT_DEPRECATED_X("Use globalPosition()") + QT_DEPRECATED_VERSION_X_5_15("Use globalPosition()") inline int globalX() const { return int(g.x()); } - QT_DEPRECATED_X("Use globalPosition()") + QT_DEPRECATED_VERSION_X_5_15("Use globalPosition()") inline int globalY() const { return int(g.y()); } #endif - QT_DEPRECATED_X("Use position()") + QT_DEPRECATED_VERSION_X_5_15("Use position()") inline const QPointF &posF() const { return p; } - QT_DEPRECATED_X("Use globalPosition()") + QT_DEPRECATED_VERSION_X_5_15("Use globalPosition()") inline const QPointF &globalPosF() const { return g; } #endif // QT_DEPRECATED_SINCE(5, 15) From 697910e5fbd382e78bc1bcbac3f5824aded059b4 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Fri, 28 Jun 2019 14:40:04 +0200 Subject: [PATCH 234/264] Fix assert in QPainterPath after clear() The newly introduced clear() method left the path in an undefined state: d_ptr allocated, but no elements. The elements vector is otherwise never empty, since ensureData() inserts a dummy initial moveTo element. Fix by making sure that clear() leaves the path in the same state as ensureData() (i.e. "empty" but not "null"), except possibly more capacity allocated in the elements vector. Fixes: QTBUG-76534 Change-Id: I7ad8b312913f5eb6e22023f5d2fd873e54b1e23c Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qpainterpath.cpp | 9 +++++---- src/gui/painting/qpainterpath_p.h | 2 +- .../gui/painting/qpainterpath/tst_qpainterpath.cpp | 10 +++++++++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index d20faf89a2..8516d73537 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -661,6 +661,7 @@ void QPainterPath::clear() detach(); d_func()->clear(); + d_func()->elements.append( {0, 0, MoveToElement} ); } /*! @@ -2337,12 +2338,12 @@ bool QPainterPath::operator==(const QPainterPath &path) const { QPainterPathData *d = reinterpret_cast(d_func()); QPainterPathData *other_d = path.d_func(); - if (other_d == d) + if (other_d == d) { return true; - else if (!d || !other_d) { - if (!d && other_d->elements.empty() && other_d->fillRule == Qt::OddEvenFill) + } else if (!d || !other_d) { + if (!other_d && isEmpty() && elementAt(0) == QPointF() && d->fillRule == Qt::OddEvenFill) return true; - if (!other_d && d && d->elements.empty() && d->fillRule == Qt::OddEvenFill) + if (!d && path.isEmpty() && path.elementAt(0) == QPointF() && other_d->fillRule == Qt::OddEvenFill) return true; return false; } diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h index a36c8005bc..567f155210 100644 --- a/src/gui/painting/qpainterpath_p.h +++ b/src/gui/painting/qpainterpath_p.h @@ -298,7 +298,7 @@ inline void QPainterPathData::clear() elements.clear(); cStart = 0; - + fillRule = Qt::OddEvenFill; bounds = {}; controlBounds = {}; diff --git a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp index c90348e91a..67cf9a321a 100644 --- a/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp +++ b/tests/auto/gui/painting/qpainterpath/tst_qpainterpath.cpp @@ -161,10 +161,18 @@ void tst_QPainterPath::clear() p1.clear(); QCOMPARE(p1, p2); + p1.lineTo(50, 50); + QPainterPath p3; + QCOMPARE(p1.elementCount(), 2); + p3.lineTo(50, 50); + QCOMPARE(p1, p3); + QCOMPARE(p1.fillRule(), Qt::OddEvenFill); p1.setFillRule(Qt::WindingFill); + QVERIFY(p1 != p3); p1.clear(); - QCOMPARE(p1.fillRule(), Qt::WindingFill); + QCOMPARE(p1.fillRule(), Qt::OddEvenFill); + QCOMPARE(p1, p2); } void tst_QPainterPath::reserveAndCapacity() From 2dddc1c9f46f942491343654854ebe07858cd774 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 31 Jul 2019 15:39:37 +0200 Subject: [PATCH 235/264] Fix erroneous missing-cmake-tests errors After commit 9c7ebd191b9862c28e9c96a511ec2878b7a3591d, qmake would complain about missing cmake tests even for internal modules that have no application side C++ linkage that needs testing. Change-Id: I23b23c81dbe6be2b6da5672cbd7b8f8454ec2f66 Reviewed-by: Alexandru Croitor --- mkspecs/features/create_cmake.prf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf index fe9149b1c1..376a7ded5d 100644 --- a/mkspecs/features/create_cmake.prf +++ b/mkspecs/features/create_cmake.prf @@ -367,7 +367,7 @@ cmake_qt5_module_files.path = $$[QT_INSTALL_LIBS]/cmake/Qt5$${CMAKE_MODULE_NAME} # Other modules should either create proper tests in tests/auto/cmake or, as # a temporary measure, disable the generation of cmake files # with 'CONFIG -= create_cmake' -!equals(CMAKE_MODULE_TESTS, -) { +!internal_module:!equals(CMAKE_MODULE_TESTS, -) { isEmpty(CMAKE_MODULE_TESTS): CMAKE_MODULE_TESTS = $$MODULE_BASE_INDIR/tests/auto/cmake !exists($$CMAKE_MODULE_TESTS): \ error("Missing CMake tests. Either create tests in tests/auto/cmake," \ From 4d7271087e84096abd75fa806bea234daee0cd94 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Tue, 30 Jul 2019 21:11:16 +0200 Subject: [PATCH 236/264] QAbstractItemView: refine documentation for SingleSelection Since Qt5.1 it is possible to deselect the current selected item in SingleSelection mode when pressing the Ctrl key during the click but this was not mentioned in the docs. Change-Id: I86652308215bf218ea959f869334b6077e4634f9 Reviewed-by: Paul Wicking --- src/widgets/itemviews/qabstractitemview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 95631ffa5f..cb99214d4e 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -343,7 +343,7 @@ void QAbstractItemViewPrivate::_q_scrollerStateChanged() \value SingleSelection When the user selects an item, any already-selected item becomes unselected. It is possible for the user to deselect the selected - item. + item by pressing the Ctrl key when clicking the selected item. \value ContiguousSelection When the user selects an item in the usual way, the selection is cleared and the new item selected. However, if the user From 4583555b8cae63a91e25d61936cef3a30446fbc8 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Tue, 30 Jul 2019 20:57:13 +0200 Subject: [PATCH 237/264] QSortFilterProxyModel: avoid some unnecessary copies Clean up QSortFilterProxyModel by using const refs instead copies and range-based for loops instead plain loops Change-Id: Ic1250f33e7c311a9e1d3c19cc5dc7a9578423e74 Reviewed-by: Marc Mutz --- .../itemmodels/qsortfilterproxymodel.cpp | 64 +++++++++---------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index d13e6199db..675bf4b8c3 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -64,11 +64,7 @@ struct QSortFilterProxyModelDataChanged static inline QSet qVectorToSet(const QVector &vector) { - QSet set; - set.reserve(vector.size()); - for(int i=0; i < vector.size(); ++i) - set << vector.at(i); - return set; + return {vector.begin(), vector.end()}; } class QSortFilterProxyModelLessThan @@ -130,7 +126,7 @@ struct QRowsRemoval { } - bool contains(QModelIndex parent, int row) + bool contains(QModelIndex parent, int row) const { do { if (parent == parent_source) @@ -470,8 +466,8 @@ bool QSortFilterProxyModelPrivate::filterRecursiveAcceptsRow(int source_row, con void QSortFilterProxyModelPrivate::remove_from_mapping(const QModelIndex &source_parent) { if (Mapping *m = source_index_mapping.take(source_parent)) { - for (int i = 0; i < m->mapped_children.size(); ++i) - remove_from_mapping(m->mapped_children.at(i)); + for (const QModelIndex &mappedIdx : qAsConst(m->mapped_children)) + remove_from_mapping(mappedIdx); delete m; } } @@ -607,9 +603,9 @@ void QSortFilterProxyModelPrivate::sort() Q_Q(QSortFilterProxyModel); emit q->layoutAboutToBeChanged(QList(), QAbstractItemModel::VerticalSortHint); QModelIndexPairList source_indexes = store_persistent_indexes(); - IndexMap::const_iterator it = source_index_mapping.constBegin(); - for (; it != source_index_mapping.constEnd(); ++it) { - QModelIndex source_parent = it.key(); + const auto end = source_index_mapping.constEnd(); + for (auto it = source_index_mapping.constBegin(); it != end; ++it) { + const QModelIndex &source_parent = it.key(); Mapping *m = it.value(); sort_source_rows(m->source_rows, source_parent); build_source_to_proxy_mapping(m->source_rows, m->proxy_rows); @@ -735,13 +731,14 @@ void QSortFilterProxyModelPrivate::remove_source_items( if (!proxy_parent.isValid() && source_parent.isValid()) return; // nothing to do (already removed) - QVector > proxy_intervals; - proxy_intervals = proxy_intervals_for_source_items(source_to_proxy, source_items); + const auto proxy_intervals = proxy_intervals_for_source_items( + source_to_proxy, source_items); - for (int i = proxy_intervals.size()-1; i >= 0; --i) { - QPair interval = proxy_intervals.at(i); - int proxy_start = interval.first; - int proxy_end = interval.second; + const auto end = proxy_intervals.rend(); + for (auto it = proxy_intervals.rbegin(); it != end; ++it) { + const QPair &interval = *it; + const int proxy_start = interval.first; + const int proxy_end = interval.second; remove_proxy_interval(source_to_proxy, proxy_to_source, proxy_start, proxy_end, proxy_parent, orient, emit_signal); } @@ -875,15 +872,15 @@ void QSortFilterProxyModelPrivate::insert_source_items( if (!proxy_parent.isValid() && source_parent.isValid()) return; // nothing to do (source_parent is not mapped) - QVector > > proxy_intervals; - proxy_intervals = proxy_intervals_for_source_items_to_add( + const auto proxy_intervals = proxy_intervals_for_source_items_to_add( proxy_to_source, source_items, source_parent, orient); - for (int i = proxy_intervals.size()-1; i >= 0; --i) { - QPair > interval = proxy_intervals.at(i); - int proxy_start = interval.first; - QVector source_items = interval.second; - int proxy_end = proxy_start + source_items.size() - 1; + const auto end = proxy_intervals.rend(); + for (auto it = proxy_intervals.rbegin(); it != end; ++it) { + const QPair > &interval = *it; + const int proxy_start = interval.first; + const QVector &source_items = interval.second; + const int proxy_end = proxy_start + source_items.size() - 1; if (emit_signal) { if (orient == Qt::Vertical) @@ -1195,8 +1192,8 @@ QModelIndexPairList QSortFilterProxyModelPrivate::store_persistent_indexes() con Q_Q(const QSortFilterProxyModel); QModelIndexPairList source_indexes; source_indexes.reserve(persistent.indexes.count()); - for (QPersistentModelIndexData *data : qAsConst(persistent.indexes)) { - QModelIndex proxy_index = data->index; + for (const QPersistentModelIndexData *data : qAsConst(persistent.indexes)) { + const QModelIndex &proxy_index = data->index; QModelIndex source_index = q->mapToSource(proxy_index); source_indexes.append(qMakePair(proxy_index, QPersistentModelIndex(source_index))); } @@ -1217,9 +1214,9 @@ void QSortFilterProxyModelPrivate::update_persistent_indexes( const int numSourceIndexes = source_indexes.count(); from.reserve(numSourceIndexes); to.reserve(numSourceIndexes); - for (int i = 0; i < numSourceIndexes; ++i) { - QModelIndex source_index = source_indexes.at(i).second; - QModelIndex old_proxy_index = source_indexes.at(i).first; + for (const auto &indexPair : source_indexes) { + const QPersistentModelIndex &source_index = indexPair.second; + const QModelIndex &old_proxy_index = indexPair.first; create_mapping(source_index.parent()); QModelIndex proxy_index = q->mapFromSource(source_index); from << old_proxy_index; @@ -1264,7 +1261,7 @@ void QSortFilterProxyModelPrivate::filter_changed(const QModelIndex &source_pare const QVector mappedChildren = m->mapped_children; QVector indexesToRemove; for (int i = 0; i < mappedChildren.size(); ++i) { - const QModelIndex source_child_index = mappedChildren.at(i); + const QModelIndex &source_child_index = mappedChildren.at(i); if (rows_removed.contains(source_child_index.row()) || columns_removed.contains(source_child_index.column())) { indexesToRemove.push_back(i); remove_from_mapping(source_child_index); @@ -2296,10 +2293,9 @@ QMimeData *QSortFilterProxyModel::mimeData(const QModelIndexList &indexes) const { Q_D(const QSortFilterProxyModel); QModelIndexList source_indexes; - const int numIndexes = indexes.count(); - source_indexes.reserve(numIndexes); - for (int i = 0; i < numIndexes; ++i) - source_indexes << mapToSource(indexes.at(i)); + source_indexes.reserve(indexes.count()); + for (const QModelIndex &idx : indexes) + source_indexes << mapToSource(idx); return d->model->mimeData(source_indexes); } From a2c1109152a8afe40d420342cf20a3f84f483e92 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 30 Jul 2019 10:40:47 +0200 Subject: [PATCH 238/264] Harden ICC parser Add missing implicit size checks of tags by passing the already checked explicitly given size forward. Also adds my fuzzing test for the ICC parser as it is security critical, by being used by multiple image formats. Change-Id: Ieb632ccb78f9b445a276959ffbd66fa04a7a5b45 Reviewed-by: Eirik Aavitsland --- src/gui/painting/qicc.cpp | 142 +++++++++++++------- tests/libfuzzer/gui/iccparser/iccparser.pro | 3 + tests/libfuzzer/gui/iccparser/main.cpp | 37 +++++ 3 files changed, 130 insertions(+), 52 deletions(-) create mode 100644 tests/libfuzzer/gui/iccparser/iccparser.pro create mode 100644 tests/libfuzzer/gui/iccparser/main.cpp diff --git a/src/gui/painting/qicc.cpp b/src/gui/painting/qicc.cpp index 2abb42993b..53055b426c 100644 --- a/src/gui/painting/qicc.cpp +++ b/src/gui/painting/qicc.cpp @@ -190,23 +190,17 @@ static float fromFixedS1516(int x) return x * (1.0f / 65536.0f); } -QColorVector fromXyzData(const XYZTagData *xyz) -{ - const float x = fromFixedS1516(xyz->fixedX); - const float y = fromFixedS1516(xyz->fixedY); - const float z = fromFixedS1516(xyz->fixedZ); - qCDebug(lcIcc) << "XYZ_ " << x << y << z; - - return QColorVector(x, y, z); -} - static bool isValidIccProfile(const ICCProfileHeader &header) { if (header.signature != uint(Tag::acsp)) { qCWarning(lcIcc, "Failed ICC signature test"); return false; } - if (header.profileSize < (sizeof(ICCProfileHeader) + header.tagCount * sizeof(TagTableEntry))) { + + // Don't overflow 32bit integers: + if (header.tagCount >= INT32_MAX / sizeof(TagTableEntry)) + return false; + if (header.profileSize - sizeof(ICCProfileHeader) < header.tagCount * sizeof(TagTableEntry)) { qCWarning(lcIcc, "Failed basic size sanity"); return false; } @@ -413,17 +407,44 @@ QByteArray toIccProfile(const QColorSpace &space) return iccProfile; } -bool parseTRC(const GenericTagData *trcData, QColorTrc &gamma) +struct TagEntry { + quint32 offset; + quint32 size; +}; + +bool parseXyzData(const QByteArray &data, const TagEntry &tagEntry, QColorVector &colorVector) { + if (tagEntry.size < sizeof(XYZTagData)) { + qCWarning(lcIcc) << "Undersized XYZ tag"; + return false; + } + const XYZTagData *xyz = reinterpret_cast(data.constData() + tagEntry.offset); + if (xyz->type != quint32(Tag::XYZ_)) { + qCWarning(lcIcc) << "Bad XYZ content type"; + return false; + } + const float x = fromFixedS1516(xyz->fixedX); + const float y = fromFixedS1516(xyz->fixedY); + const float z = fromFixedS1516(xyz->fixedZ); + + colorVector = QColorVector(x, y, z); + return true; +} + +bool parseTRC(const QByteArray &data, const TagEntry &tagEntry, QColorTrc &gamma) +{ + const GenericTagData *trcData = reinterpret_cast(data.constData() + tagEntry.offset); if (trcData->type == quint32(Tag::curv)) { - const CurvTagData *curv = reinterpret_cast(trcData); - qCDebug(lcIcc) << "curv" << uint(curv->valueCount); + const CurvTagData *curv = static_cast(trcData); + if (curv->valueCount > (1 << 16)) + return false; + if (tagEntry.size - 12 < 2 * curv->valueCount) + return false; if (curv->valueCount == 0) { gamma.m_type = QColorTrc::Type::Function; gamma.m_fun = QColorTransferFunction(); // Linear } else if (curv->valueCount == 1) { float g = curv->value[0] * (1.0f / 256.0f); - qCDebug(lcIcc) << g; gamma.m_type = QColorTrc::Type::Function; gamma.m_fun = QColorTransferFunction::fromGamma(g); } else { @@ -445,49 +466,54 @@ bool parseTRC(const GenericTagData *trcData, QColorTrc &gamma) return true; } if (trcData->type == quint32(Tag::para)) { - const ParaTagData *para = reinterpret_cast(trcData); - qCDebug(lcIcc) << "para" << uint(para->curveType); + if (tagEntry.size < sizeof(ParaTagData)) + return false; + const ParaTagData *para = static_cast(trcData); switch (para->curveType) { case 0: { float g = fromFixedS1516(para->parameter[0]); - qCDebug(lcIcc) << g; gamma.m_type = QColorTrc::Type::Function; gamma.m_fun = QColorTransferFunction::fromGamma(g); break; } case 1: { + if (tagEntry.size < sizeof(ParaTagData) + 2 * 4) + return false; float g = fromFixedS1516(para->parameter[0]); float a = fromFixedS1516(para->parameter[1]); float b = fromFixedS1516(para->parameter[2]); float d = -b / a; - qCDebug(lcIcc) << g << a << b; gamma.m_type = QColorTrc::Type::Function; gamma.m_fun = QColorTransferFunction(a, b, 0.0f, d, 0.0f, 0.0f, g); break; } case 2: { + if (tagEntry.size < sizeof(ParaTagData) + 3 * 4) + return false; float g = fromFixedS1516(para->parameter[0]); float a = fromFixedS1516(para->parameter[1]); float b = fromFixedS1516(para->parameter[2]); float c = fromFixedS1516(para->parameter[3]); float d = -b / a; - qCDebug(lcIcc) << g << a << b << c; gamma.m_type = QColorTrc::Type::Function; gamma.m_fun = QColorTransferFunction(a, b, 0.0f, d, c, c, g); break; } case 3: { + if (tagEntry.size < sizeof(ParaTagData) + 4 * 4) + return false; float g = fromFixedS1516(para->parameter[0]); float a = fromFixedS1516(para->parameter[1]); float b = fromFixedS1516(para->parameter[2]); float c = fromFixedS1516(para->parameter[3]); float d = fromFixedS1516(para->parameter[4]); - qCDebug(lcIcc) << g << a << b << c << d; gamma.m_type = QColorTrc::Type::Function; gamma.m_fun = QColorTransferFunction(a, b, c, d, 0.0f, 0.0f, g); break; } case 4: { + if (tagEntry.size < sizeof(ParaTagData) + 6 * 4) + return false; float g = fromFixedS1516(para->parameter[0]); float a = fromFixedS1516(para->parameter[1]); float b = fromFixedS1516(para->parameter[2]); @@ -495,7 +521,6 @@ bool parseTRC(const GenericTagData *trcData, QColorTrc &gamma) float d = fromFixedS1516(para->parameter[4]); float e = fromFixedS1516(para->parameter[5]); float f = fromFixedS1516(para->parameter[6]); - qCDebug(lcIcc) << g << a << b << c << d << e << f; gamma.m_type = QColorTrc::Type::Function; gamma.m_fun = QColorTransferFunction(a, b, c, d, e, f, g); break; @@ -529,8 +554,12 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace) // Read tag index const TagTableEntry *tagTable = (const TagTableEntry *)(data.constData() + sizeof(ICCProfileHeader)); const qsizetype offsetToData = sizeof(ICCProfileHeader) + header->tagCount * sizeof(TagTableEntry); + if (offsetToData > data.size()) { + qCWarning(lcIcc) << "fromIccProfile: failed index size sanity"; + return false; + } - QHash tagIndex; + QHash tagIndex; for (uint i = 0; i < header->tagCount; ++i) { // Sanity check tag sizes and offsets: if (qsizetype(tagTable[i].offset) < offsetToData) { @@ -542,15 +571,24 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace) qCWarning(lcIcc) << "fromIccProfile: failed tag offset sanity 2"; return false; } - if ((tagTable[i].offset + tagTable[i].size) > header->profileSize) { + if (tagTable[i].size < 12) { + qCWarning(lcIcc) << "fromIccProfile: failed minimal tag size sanity"; + return false; + } + if (tagTable[i].size > header->profileSize - tagTable[i].offset) { qCWarning(lcIcc) << "fromIccProfile: failed tag offset + size sanity"; return false; } + if (tagTable[i].offset & 0x03) { + qCWarning(lcIcc) << "fromIccProfile: invalid tag offset alignment"; + return false; + } // printf("'%4s' %d %d\n", (const char *)&tagTable[i].signature, // quint32(tagTable[i].offset), // quint32(tagTable[i].size)); - tagIndex.insert(Tag(quint32(tagTable[i].signature)), tagTable[i].offset); + tagIndex.insert(Tag(quint32(tagTable[i].signature)), { tagTable[i].offset, tagTable[i].size }); } + // Check the profile is three-component matrix based (what we currently support): if (!tagIndex.contains(Tag::rXYZ) || !tagIndex.contains(Tag::gXYZ) || !tagIndex.contains(Tag::bXYZ) || !tagIndex.contains(Tag::rTRC) || !tagIndex.contains(Tag::gTRC) || !tagIndex.contains(Tag::bTRC) || @@ -559,23 +597,17 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace) return false; } - // Parse XYZ tags - const XYZTagData *rXyz = (const XYZTagData *)(data.constData() + tagIndex[Tag::rXYZ]); - const XYZTagData *gXyz = (const XYZTagData *)(data.constData() + tagIndex[Tag::gXYZ]); - const XYZTagData *bXyz = (const XYZTagData *)(data.constData() + tagIndex[Tag::bXYZ]); - const XYZTagData *wXyz = (const XYZTagData *)(data.constData() + tagIndex[Tag::wtpt]); - if (rXyz->type != quint32(Tag::XYZ_) || gXyz->type != quint32(Tag::XYZ_) || - wXyz->type != quint32(Tag::XYZ_) || wXyz->type != quint32(Tag::XYZ_)) { - qCWarning(lcIcc) << "fromIccProfile: Bad XYZ data type"; - return false; - } QColorSpacePrivate *colorspaceDPtr = QColorSpacePrivate::getWritable(*colorSpace); - colorspaceDPtr->toXyz.r = fromXyzData(rXyz); - colorspaceDPtr->toXyz.g = fromXyzData(gXyz); - colorspaceDPtr->toXyz.b = fromXyzData(bXyz); - QColorVector whitePoint = fromXyzData(wXyz); - colorspaceDPtr->whitePoint = whitePoint; + // Parse XYZ tags + if (!parseXyzData(data, tagIndex[Tag::rXYZ], colorspaceDPtr->toXyz.r)) + return false; + if (!parseXyzData(data, tagIndex[Tag::gXYZ], colorspaceDPtr->toXyz.g)) + return false; + if (!parseXyzData(data, tagIndex[Tag::bXYZ], colorspaceDPtr->toXyz.b)) + return false; + if (!parseXyzData(data, tagIndex[Tag::wtpt], colorspaceDPtr->whitePoint)) + return false; colorspaceDPtr->gamut = QColorSpace::Gamut::Custom; if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromSRgb()) { @@ -600,29 +632,35 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace) colorspaceDPtr->setToXyzMatrix(); // Parse TRC tags - const GenericTagData *rTrc; - const GenericTagData *gTrc; - const GenericTagData *bTrc; + TagEntry rTrc; + TagEntry gTrc; + TagEntry bTrc; if (tagIndex.contains(Tag::aarg) && tagIndex.contains(Tag::aagg) && tagIndex.contains(Tag::aabg)) { // Apple extension for parametric version of TRCs in ICCv2: - rTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::aarg]); - gTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::aagg]); - bTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::aabg]); + rTrc = tagIndex[Tag::aarg]; + gTrc = tagIndex[Tag::aagg]; + bTrc = tagIndex[Tag::aabg]; } else { - rTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::rTRC]); - gTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::gTRC]); - bTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::bTRC]); + rTrc = tagIndex[Tag::rTRC]; + gTrc = tagIndex[Tag::gTRC]; + bTrc = tagIndex[Tag::bTRC]; } QColorTrc rCurve; QColorTrc gCurve; QColorTrc bCurve; - if (!parseTRC(rTrc, rCurve)) + if (!parseTRC(data, rTrc, rCurve)) { + qCWarning(lcIcc) << "fromIccProfile: Invalid rTRC"; return false; - if (!parseTRC(gTrc, gCurve)) + } + if (!parseTRC(data, gTrc, gCurve)) { + qCWarning(lcIcc) << "fromIccProfile: Invalid gTRC"; return false; - if (!parseTRC(bTrc, bCurve)) + } + if (!parseTRC(data, bTrc, bCurve)) { + qCWarning(lcIcc) << "fromIccProfile: Invalid bTRC"; return false; + } if (rCurve == gCurve && gCurve == bCurve && rCurve.m_type == QColorTrc::Type::Function) { if (rCurve.m_fun.isLinear()) { qCDebug(lcIcc) << "fromIccProfile: Linear gamma detected"; diff --git a/tests/libfuzzer/gui/iccparser/iccparser.pro b/tests/libfuzzer/gui/iccparser/iccparser.pro new file mode 100644 index 0000000000..bf4037eae7 --- /dev/null +++ b/tests/libfuzzer/gui/iccparser/iccparser.pro @@ -0,0 +1,3 @@ +QT += gui +SOURCES += main.cpp +LIBS += -fsanitize=fuzzer diff --git a/tests/libfuzzer/gui/iccparser/main.cpp b/tests/libfuzzer/gui/iccparser/main.cpp new file mode 100644 index 0000000000..ba4f70ef3b --- /dev/null +++ b/tests/libfuzzer/gui/iccparser/main.cpp @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const char *data, size_t size) { + static int c = 0; + static QGuiApplication a(c, nullptr); + QColorSpace cs = QColorSpace::fromIccProfile(QByteArray(data, size)); + return 0; +} From dcc4d54fc9340fcbed3ffddbe1cf99e6ca70d4f9 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 19 Jul 2019 14:46:20 +0200 Subject: [PATCH 239/264] Parse color space name from ICC profile Adds parsing of ICCv2 and ICCv4 description tags. Change-Id: I8647e1529d4127950624f16c475d8dba610149b6 Reviewed-by: Eirik Aavitsland --- src/gui/painting/qcolorspace.cpp | 21 +++-- src/gui/painting/qicc.cpp | 77 +++++++++++++++++- .../qcolorspace/resources/HP_ZR30w.icc | Bin 0 -> 1856 bytes .../painting/qcolorspace/tst_qcolorspace.cpp | 38 ++++++--- 4 files changed, 117 insertions(+), 19 deletions(-) create mode 100644 tests/auto/gui/painting/qcolorspace/resources/HP_ZR30w.icc diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp index d058505e68..4a1ed373f5 100644 --- a/src/gui/painting/qcolorspace.cpp +++ b/src/gui/painting/qcolorspace.cpp @@ -247,12 +247,14 @@ bool QColorSpacePrivate::identifyColorSpace() case QColorSpace::Gamut::SRgb: if (transferFunction == QColorSpace::TransferFunction::SRgb) { id = QColorSpace::SRgb; - description = QStringLiteral("sRGB"); + if (description.isEmpty()) + description = QStringLiteral("sRGB"); return true; } if (transferFunction == QColorSpace::TransferFunction::Linear) { id = QColorSpace::SRgbLinear; - description = QStringLiteral("Linear sRGB"); + if (description.isEmpty()) + description = QStringLiteral("Linear sRGB"); return true; } break; @@ -260,7 +262,8 @@ bool QColorSpacePrivate::identifyColorSpace() if (transferFunction == QColorSpace::TransferFunction::Gamma) { if (qAbs(gamma - 2.19921875f) < (1/1024.0f)) { id = QColorSpace::AdobeRgb; - description = QStringLiteral("Adobe RGB"); + if (description.isEmpty()) + description = QStringLiteral("Adobe RGB"); return true; } } @@ -268,21 +271,24 @@ bool QColorSpacePrivate::identifyColorSpace() case QColorSpace::Gamut::DciP3D65: if (transferFunction == QColorSpace::TransferFunction::SRgb) { id = QColorSpace::DisplayP3; - description = QStringLiteral("Display P3"); + if (description.isEmpty()) + description = QStringLiteral("Display P3"); return true; } break; case QColorSpace::Gamut::ProPhotoRgb: if (transferFunction == QColorSpace::TransferFunction::ProPhotoRgb) { id = QColorSpace::ProPhotoRgb; - description = QStringLiteral("ProPhoto RGB"); + if (description.isEmpty()) + description = QStringLiteral("ProPhoto RGB"); return true; } if (transferFunction == QColorSpace::TransferFunction::Gamma) { // ProPhoto RGB's curve is effectively gamma 1.8 for 8bit precision. if (qAbs(gamma - 1.8f) < (1/1024.0f)) { id = QColorSpace::ProPhotoRgb; - description = QStringLiteral("ProPhoto RGB"); + if (description.isEmpty()) + description = QStringLiteral("ProPhoto RGB"); return true; } } @@ -290,7 +296,8 @@ bool QColorSpacePrivate::identifyColorSpace() case QColorSpace::Gamut::Bt2020: if (transferFunction == QColorSpace::TransferFunction::Bt2020) { id = QColorSpace::Bt2020; - description = QStringLiteral("BT.2020"); + if (description.isEmpty()) + description = QStringLiteral("BT.2020"); return true; } break; diff --git a/src/gui/painting/qicc.cpp b/src/gui/painting/qicc.cpp index 53055b426c..1941981d30 100644 --- a/src/gui/painting/qicc.cpp +++ b/src/gui/painting/qicc.cpp @@ -42,8 +42,9 @@ #include #include #include -#include #include +#include +#include #include "qcolorspace_p.h" #include "qcolortrc_p.h" @@ -117,6 +118,7 @@ enum class Tag : quint32 { bkpt = IccTag('b', 'k', 'p', 't'), mft1 = IccTag('m', 'f', 't', '1'), mft2 = IccTag('m', 'f', 't', '2'), + mluc = IccTag('m', 'l', 'u', 'c'), mAB_ = IccTag('m', 'A', 'B', ' '), mBA_ = IccTag('m', 'B', 'A', ' '), chad = IccTag('c', 'h', 'a', 'd'), @@ -164,6 +166,25 @@ struct ParaTagData : GenericTagData { quint32_be parameter[1]; }; +struct DescTagData : GenericTagData { + quint32_be asciiDescriptionLength; + char asciiDescription[1]; + // .. we ignore the rest +}; + +struct MlucTagRecord { + quint16_be languageCode; + quint16_be countryCode; + quint32_be size; + quint32_be offset; +}; + +struct MlucTagData : GenericTagData { + quint32_be recordCount; + quint32_be recordSize; // = sizeof(MlucTagRecord) + MlucTagRecord records[1]; +}; + // For both mAB and mBA struct mABTagData : GenericTagData { quint8 inputChannels; @@ -535,6 +556,53 @@ bool parseTRC(const QByteArray &data, const TagEntry &tagEntry, QColorTrc &gamma return false; } +bool parseDesc(const QByteArray &data, const TagEntry &tagEntry, QString &descName) +{ + const GenericTagData *tag = (const GenericTagData *)(data.constData() + tagEntry.offset); + + // Either 'desc' (ICCv2) or 'mluc' (ICCv4) + if (tag->type == quint32(Tag::desc)) { + if (tagEntry.size < sizeof(DescTagData)) + return false; + const DescTagData *desc = (const DescTagData *)(data.constData() + tagEntry.offset); + const quint32 len = desc->asciiDescriptionLength; + if (len < 1) + return false; + if (tagEntry.size - 12 < len) + return false; + if (desc->asciiDescription[len - 1] != '\0') + return false; + descName = QString::fromLatin1(desc->asciiDescription, len - 1); + return true; + } + if (tag->type != quint32(Tag::mluc)) + return false; + + if (tagEntry.size < sizeof(MlucTagData)) + return false; + const MlucTagData *mluc = (const MlucTagData *)(data.constData() + tagEntry.offset); + if (mluc->recordCount < 1) + return false; + if (mluc->recordSize < 12) + return false; + // We just use the primary record regardless of language or country. + const quint32 stringOffset = mluc->records[0].offset; + const quint32 stringSize = mluc->records[0].size; + if (tagEntry.size < stringOffset || tagEntry.size - stringOffset < stringSize ) + return false; + if ((stringSize | stringOffset) & 1) + return false; + quint32 stringLen = stringSize / 2; + const ushort *unicodeString = (const ushort *)(data.constData() + tagEntry.offset + stringOffset); + // The given length shouldn't include 0-termination, but might. + if (stringLen > 1 && unicodeString[stringLen - 1] == 0) + --stringLen; + QVarLengthArray utf16hostendian(stringLen); + qFromBigEndian(unicodeString, stringLen, utf16hostendian.data()); + descName = QString::fromUtf16(utf16hostendian.data(), stringLen); + return true; +} + bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace) { if (data.size() < qsizetype(sizeof(ICCProfileHeader))) { @@ -690,7 +758,12 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace) colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::Custom; } - // FIXME: try to parse the description.. + if (tagIndex.contains(Tag::desc)) { + if (!parseDesc(data, tagIndex[Tag::desc], colorspaceDPtr->description)) + qCWarning(lcIcc) << "fromIccProfile: Failed to parse description"; + else + qCDebug(lcIcc) << "fromIccProfile: Description" << colorspaceDPtr->description; + } if (!colorspaceDPtr->identifyColorSpace()) colorspaceDPtr->id = QColorSpace::Unknown; diff --git a/tests/auto/gui/painting/qcolorspace/resources/HP_ZR30w.icc b/tests/auto/gui/painting/qcolorspace/resources/HP_ZR30w.icc new file mode 100644 index 0000000000000000000000000000000000000000..b3f860714c5cd7e71ea3830af395d0b19282c6f0 GIT binary patch literal 1856 zcmb7^--{bn6vw}ttgc{NYAsTvNRSq>Y?fq`?k3>F)@|(;e}#3cbrsghOp*$Md_L6P3yf+V#2pqsDCT`>bgl zy>aRBYiBQ~ziTaj`O(@NAM83U9@rPuy1q0vi96|cq8|1+?28wA9kYMMKIpG{0rnrp ziCCbN%2>P_+eNb*vAtk+w6r)6=S}SWjS;&#V*9I62&V<-NDv0-r{2My48peAUt>QL z)_NZHpVIh3*y^)R_tP)>X%A zsfHg%>qKkLx3P@Y)P{9|cSb%|N1HI3YM|32X6!DO#eA>{r%hx^va=*7PjW`xdSTjy z#vcAcdf?r`;MS|s#M9E9YlFexpAQCiE=%d3q^;Y@{P&)cPE|RBx0BeBtJ2T_?GnPoOBf2yR}Q*?x)5X#ph9@Vpi3j zt5HQBwOQjGiPH_5K6lGKkMKr+ECW6U&Va|jx4?s-@yvf8wDHft2f?qvC&BCBA{(UI zHl8{OJ_OqLg08!RbKoU>^irRI`#@^v_&*HeH^BqM{{qo>MM6JK*Aw6z$o%vYh;Eu) zIDcd4UmW_D$HuRKhrn-!zU49hx1s+J$a=@gY5Z}^V}8l`^LkOwX=Qjr1NGg_>T|D} z)N@l=?pIvfCb0%ymb!YxLU;SN=U3skUDY?yxZm05(TmWIZ*-m;onu`m_|_^qqnC7= z6$Wt5!|=fsFwh2bJaPqKmM`;OH^Ih7zuc_m(Jj&nw7h2YJnbYom*^|3Wu1LQE?bQZ zmhTkfXXq>JJnwi@f**0OwM+6=W#v_^Tc-YmQvoHCjT duS(VWtZiE@PqtZiKBH<0E7r=PQGl0M{$DnICFTGC literal 0 HcmV?d00001 diff --git a/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp b/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp index b82a56dbf8..291a25fede 100644 --- a/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp +++ b/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp @@ -53,6 +53,7 @@ private slots: void toIccProfile_data(); void toIccProfile(); + void fromIccProfile_data(); void fromIccProfile(); void imageConversion_data(); @@ -142,21 +143,38 @@ void tst_QColorSpace::toIccProfile() QCOMPARE(iccProfile2, iccProfile); } +void tst_QColorSpace::fromIccProfile_data() +{ + QTest::addColumn("testProfile"); + QTest::addColumn("colorSpaceId"); + QTest::addColumn("transferFunction"); + QTest::addColumn("description"); + + QString prefix = QFINDTESTDATA("resources/"); + // Read the official sRGB ICCv2 profile: + QTest::newRow("sRGB2014 (ICCv2)") << prefix + "sRGB2014.icc" << QColorSpace::SRgb + << QColorSpace::TransferFunction::SRgb << QString("sRGB2014"); + // My monitor's profile: + QTest::newRow("HP ZR30w (ICCv4)") << prefix + "HP_ZR30w.icc" << QColorSpace::Unknown + << QColorSpace::TransferFunction::Gamma << QString("HP Z30i"); +} + void tst_QColorSpace::fromIccProfile() { - // Read the official sRGB ICCv2 profile: - QString prefix = QFINDTESTDATA("resources/"); - QFile file(prefix + "sRGB2014.icc"); + QFETCH(QString, testProfile); + QFETCH(QColorSpace::ColorSpaceId, colorSpaceId); + QFETCH(QColorSpace::TransferFunction, transferFunction); + QFETCH(QString, description); + + QFile file(testProfile); file.open(QIODevice::ReadOnly); QByteArray iccProfile = file.readAll(); - QColorSpace stdSRgb = QColorSpace::fromIccProfile(iccProfile); - QVERIFY(stdSRgb.isValid()); + QColorSpace fileColorSpace = QColorSpace::fromIccProfile(iccProfile); + QVERIFY(fileColorSpace.isValid()); - QCOMPARE(stdSRgb.gamut(), QColorSpace::Gamut::SRgb); - QCOMPARE(stdSRgb.transferFunction(), QColorSpace::TransferFunction::SRgb); - QCOMPARE(stdSRgb.colorSpaceId(), QColorSpace::SRgb); - - QCOMPARE(stdSRgb, QColorSpace(QColorSpace::SRgb)); + QCOMPARE(fileColorSpace.colorSpaceId(), colorSpaceId); + QCOMPARE(fileColorSpace.transferFunction(), transferFunction); + QCOMPARE(QColorSpacePrivate::get(fileColorSpace)->description, description); } void tst_QColorSpace::imageConversion_data() From 0642444e7277a7fd8177f0a610e54f80bacc538e Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Tue, 9 Jul 2019 15:27:21 +0900 Subject: [PATCH 240/264] Fix spdy build without features.properties Move location of stream ID from a dynamic property to an internal QHash. Change-Id: I9bab4cbfaebe6a04d54afa7889aac748070e1f2e Reviewed-by: Timur Pocheptsov --- src/network/access/qspdyprotocolhandler.cpp | 15 +++++++++++---- src/network/access/qspdyprotocolhandler_p.h | 2 ++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/network/access/qspdyprotocolhandler.cpp b/src/network/access/qspdyprotocolhandler.cpp index 403c01e974..f845235bf7 100644 --- a/src/network/access/qspdyprotocolhandler.cpp +++ b/src/network/access/qspdyprotocolhandler.cpp @@ -305,7 +305,7 @@ bool QSpdyProtocolHandler::sendRequest() currentReply->setSpdyWasUsed(true); qint32 streamID = generateNextStreamID(); - currentReply->setProperty("SPDYStreamID", streamID); + m_streamIDs.insert(currentReply, streamID); currentReply->setRequest(currentRequest); currentReply->d_func()->connection = m_connection; @@ -322,7 +322,7 @@ bool QSpdyProtocolHandler::sendRequest() void QSpdyProtocolHandler::_q_replyDestroyed(QObject* reply) { - qint32 streamID = reply->property("SPDYStreamID").toInt(); + qint32 streamID = m_streamIDs.take(reply); if (m_inFlightStreams.remove(streamID)) sendRST_STREAM(streamID, RST_STREAM_CANCEL); } @@ -624,10 +624,12 @@ void QSpdyProtocolHandler::sendSYN_STREAM(const HttpMessagePair &messagePair, // hack: set the stream ID on the device directly, so when we get // the signal for uploading we know which stream we are sending on - request.uploadByteDevice()->setProperty("SPDYStreamID", streamID); + m_streamIDs.insert(request.uploadByteDevice(), streamID); QObject::connect(request.uploadByteDevice(), SIGNAL(readyRead()), this, SLOT(_q_uploadDataReadyRead()), Qt::QueuedConnection); + QObject::connect(request.uploadByteDevice(), SIGNAL(destroyed(QObject*)), this, + SLOT(_q_uploadDataDestroyed(QObject *))); } QByteArray namesAndValues = composeHeader(request); @@ -663,6 +665,11 @@ void QSpdyProtocolHandler::sendSYN_STREAM(const HttpMessagePair &messagePair, uploadData(streamID); } +void QSpdyProtocolHandler::_q_uploadDataDestroyed(QObject *uploadData) +{ + m_streamIDs.remove(uploadData); +} + void QSpdyProtocolHandler::sendRST_STREAM(qint32 streamID, RST_STREAM_STATUS_CODE statusCode) { char wireData[8]; @@ -756,7 +763,7 @@ void QSpdyProtocolHandler::_q_uploadDataReadyRead() { QNonContiguousByteDevice *device = qobject_cast(sender()); Q_ASSERT(device); - qint32 streamID = device->property("SPDYStreamID").toInt(); + qint32 streamID = m_streamIDs.value(device); Q_ASSERT(streamID > 0); uploadData(streamID); } diff --git a/src/network/access/qspdyprotocolhandler_p.h b/src/network/access/qspdyprotocolhandler_p.h index dd93a9aba2..14e2ff388a 100644 --- a/src/network/access/qspdyprotocolhandler_p.h +++ b/src/network/access/qspdyprotocolhandler_p.h @@ -110,6 +110,7 @@ public: private slots: void _q_uploadDataReadyRead(); void _q_replyDestroyed(QObject*); + void _q_uploadDataDestroyed(QObject *); private: @@ -216,6 +217,7 @@ private: bool m_waitingForCompleteStream; z_stream m_deflateStream; z_stream m_inflateStream; + QHash m_streamIDs; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QSpdyProtocolHandler::DataFrameFlags) From 6e8dd46a6f4e81617f69c5ba4eca0a74b548290a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 23 Jul 2019 08:38:47 +0300 Subject: [PATCH 241/264] QResource: consistently cache resourceList() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each call to reourceList() uses atomic operations to check whether resourceGLobalData has not expired, yet. Some functions already cached the value, but then went on to use the function directly afterwards. In some cases, this was due to the cached value being a pointer-to-const and the function later deciding to mutate the list. But all the code is safe from detaches, so this distinction need not be made. Standardize on caching, and using the cached value, except in functions which call it only once. Change-Id: I79780b990da539bf7beaa8104e13cb8187f84812 Reviewed-by: Edward Welbourne Reviewed-by: Mårten Nordheim --- src/corelib/io/qresource.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 11d117c990..52b746d04a 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -951,11 +951,12 @@ Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree, if (resourceGlobalData.isDestroyed()) return false; QMutexLocker lock(resourceMutex()); + ResourceList *list = resourceList(); if (version >= 0x01 && version <= 0x3) { bool found = false; QResourceRoot res(version, tree, name, data); - for(int i = 0; i < resourceList()->size(); ++i) { - if(*resourceList()->at(i) == res) { + for (int i = 0; i < list->size(); ++i) { + if (*list->at(i) == res) { found = true; break; } @@ -963,7 +964,7 @@ Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree, if(!found) { QResourceRoot *root = new QResourceRoot(version, tree, name, data); root->ref.ref(); - resourceList()->append(root); + list->append(root); } return true; } @@ -979,9 +980,10 @@ Q_CORE_EXPORT bool qUnregisterResourceData(int version, const unsigned char *tre QMutexLocker lock(resourceMutex()); if (version >= 0x01 && version <= 0x3) { QResourceRoot res(version, tree, name, data); - for(int i = 0; i < resourceList()->size(); ) { - if(*resourceList()->at(i) == res) { - QResourceRoot *root = resourceList()->takeAt(i); + ResourceList *list = resourceList(); + for (int i = 0; i < list->size(); ) { + if (*list->at(i) == res) { + QResourceRoot *root = list->takeAt(i); if(!root->ref.deref()) delete root; } else { @@ -1227,7 +1229,7 @@ QResource::unregisterResource(const QString &rccFilename, const QString &resourc if(res->type() == QResourceRoot::Resource_File) { QDynamicFileResourceRoot *root = reinterpret_cast(res); if (root->mappingFile() == rccFilename && root->mappingRoot() == r) { - resourceList()->removeAt(i); + list->removeAt(i); if(!root->ref.deref()) { delete root; return true; @@ -1298,7 +1300,7 @@ QResource::unregisterResource(const uchar *rccData, const QString &resourceRoot) if(res->type() == QResourceRoot::Resource_Buffer) { QDynamicBufferResourceRoot *root = reinterpret_cast(res); if (root->mappingBuffer() == rccData && root->mappingRoot() == r) { - resourceList()->removeAt(i); + list->removeAt(i); if(!root->ref.deref()) { delete root; return true; From a2c18fd10ca046b52d701e1bfe6e456d6cabec50 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 31 Jul 2019 13:12:47 +0300 Subject: [PATCH 242/264] tst_QMenu: Eradicate Q_FOREACH loops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In two cases, we now detach. ¯\_(ツ)_/¯ This is test code. Change-Id: I244f5e20dd923281049f38b76366163c16b6498c Reviewed-by: Friedemann Kleint --- tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index 3bfbe754ef..4f5a2ce1a6 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -610,7 +610,7 @@ void tst_QMenu::widgetActionFocus() static QMenu *getTornOffMenu() { - foreach (QWidget *w, QApplication::allWidgets()) { + for (QWidget *w : QApplication::allWidgets()) { if (w->isVisible() && w->inherits("QTornOffMenu")) return static_cast(w); } @@ -948,8 +948,7 @@ void tst_QMenu::menuSizeHint() { QMenu menu; //this is a list of arbitrary strings so that we check the geometry - QStringList list = QStringList() << "trer" << "ezrfgtgvqd" << "sdgzgzerzerzer" << "eerzertz" << "er"; - foreach (QString str, list) + for (auto str : {"trer", "ezrfgtgvqd", "sdgzgzerzerzer", "eerzertz", "er"}) menu.addAction(str); int left, top, right, bottom; @@ -960,7 +959,7 @@ void tst_QMenu::menuSizeHint() int maxWidth =0; QRect result; - foreach (QAction *action, menu.actions()) { + for (QAction *action : menu.actions()) { maxWidth = qMax(maxWidth, menu.actionGeometry(action).width()); result |= menu.actionGeometry(action); QCOMPARE(result.x(), left + hmargin + panelWidth); From d914a5ba4e2f0c208473d5e76adb7d16e2e8e706 Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Tue, 30 Jul 2019 17:16:50 +0200 Subject: [PATCH 243/264] Remove the remaining usages of deprecated APIs of qtbase This change removes the leftovers form other cleanup commits. Task-number: QTBUG-76491 Change-Id: I61440f87c5a280f9666b78e19aac4d8ac603767e Reviewed-by: Volker Hilsheimer Reviewed-by: Alex Blasche --- examples/widgets/statemachine/trafficlight/main.cpp | 2 +- tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp | 4 ++++ tests/auto/corelib/tools/qline/tst_qline.cpp | 5 ++++- tests/auto/network/socket/qudpsocket/clientserver/main.cpp | 2 +- .../printsupport/kernel/qprinterinfo/tst_qprinterinfo.cpp | 4 ++++ 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/examples/widgets/statemachine/trafficlight/main.cpp b/examples/widgets/statemachine/trafficlight/main.cpp index 1a7050c28d..a12d2f10d1 100644 --- a/examples/widgets/statemachine/trafficlight/main.cpp +++ b/examples/widgets/statemachine/trafficlight/main.cpp @@ -105,7 +105,7 @@ public: m_green = new LightWidget(Qt::green); vbox->addWidget(m_green); QPalette pal = palette(); - pal.setColor(QPalette::Background, Qt::black); + pal.setColor(QPalette::Window, Qt::black); setPalette(pal); setAutoFillBackground(true); } diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index 112c36952c..60e8d8cba2 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -92,7 +92,9 @@ private slots: void priorityStart(); void waitForDone(); void clear(); +#if QT_DEPRECATED_SINCE(5, 9) void cancel(); +#endif void tryTake(); void waitForDoneTimeout(); void destroyingWaitsForTasksToFinish(); @@ -963,6 +965,7 @@ void tst_QThreadPool::clear() QCOMPARE(count.loadRelaxed(), threadPool.maxThreadCount()); } +#if QT_DEPRECATED_SINCE(5, 9) void tst_QThreadPool::cancel() { QSemaphore sem(0); @@ -1034,6 +1037,7 @@ void tst_QThreadPool::cancel() delete runnables[0]; //if the pool deletes them then we'll get double-free crash delete runnables[runs-1]; } +#endif void tst_QThreadPool::tryTake() { diff --git a/tests/auto/corelib/tools/qline/tst_qline.cpp b/tests/auto/corelib/tools/qline/tst_qline.cpp index 0418daf640..31aa5b4e0c 100644 --- a/tests/auto/corelib/tools/qline/tst_qline.cpp +++ b/tests/auto/corelib/tools/qline/tst_qline.cpp @@ -207,7 +207,10 @@ void tst_QLine::testIntersection() QPointF ip; - QLineF::IntersectionType itype = a.intersect(b, &ip); + QLineF::IntersectionType itype = a.intersects(b, &ip); +#if QT_DEPRECATED_SINCE(5, 14) + QCOMPARE(a.intersect(b, &ip), itype); +#endif QCOMPARE(int(itype), type); if (type != QLineF::NoIntersection) { diff --git a/tests/auto/network/socket/qudpsocket/clientserver/main.cpp b/tests/auto/network/socket/qudpsocket/clientserver/main.cpp index cc3e90671a..8172cd4f6f 100644 --- a/tests/auto/network/socket/qudpsocket/clientserver/main.cpp +++ b/tests/auto/network/socket/qudpsocket/clientserver/main.cpp @@ -54,7 +54,7 @@ public: printf("ok\n"); break; case UnconnectedClient: - peerAddress = host; + peerAddress = QHostAddress(host); peerPort = port; if (bind(QHostAddress::Any, port + 1, ShareAddress | ReuseAddressHint)) { startTimer(250); diff --git a/tests/auto/printsupport/kernel/qprinterinfo/tst_qprinterinfo.cpp b/tests/auto/printsupport/kernel/qprinterinfo/tst_qprinterinfo.cpp index d1b4ed8bcd..81b49a3a87 100644 --- a/tests/auto/printsupport/kernel/qprinterinfo/tst_qprinterinfo.cpp +++ b/tests/auto/printsupport/kernel/qprinterinfo/tst_qprinterinfo.cpp @@ -302,10 +302,12 @@ void tst_QPrinterInfo::testConstructors() QCOMPARE(copy1.minimumPhysicalPageSize(), printers.at(i).minimumPhysicalPageSize()); QCOMPARE(copy1.maximumPhysicalPageSize(), printers.at(i).maximumPhysicalPageSize()); QCOMPARE(copy1.supportedPageSizes(), printers.at(i).supportedPageSizes()); +#if QT_DEPRECATED_SINCE(5, 3) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED QCOMPARE(copy1.supportedSizesWithNames(), printers.at(i).supportedSizesWithNames()); QT_WARNING_POP +#endif QCOMPARE(copy1.supportedResolutions(), printers.at(i).supportedResolutions()); QCOMPARE(copy1.defaultDuplexMode(), printers.at(i).defaultDuplexMode()); QCOMPARE(copy1.supportedDuplexModes(), printers.at(i).supportedDuplexModes()); @@ -326,10 +328,12 @@ QT_WARNING_POP QCOMPARE(copy2.minimumPhysicalPageSize(), printers.at(i).minimumPhysicalPageSize()); QCOMPARE(copy2.maximumPhysicalPageSize(), printers.at(i).maximumPhysicalPageSize()); QCOMPARE(copy2.supportedPageSizes(), printers.at(i).supportedPageSizes()); +#if QT_DEPRECATED_SINCE(5, 3) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED QCOMPARE(copy2.supportedSizesWithNames(), printers.at(i).supportedSizesWithNames()); QT_WARNING_POP +#endif QCOMPARE(copy2.supportedResolutions(), printers.at(i).supportedResolutions()); QCOMPARE(copy2.defaultDuplexMode(), printers.at(i).defaultDuplexMode()); QCOMPARE(copy2.supportedDuplexModes(), printers.at(i).supportedDuplexModes()); From b80b2282401f6dc6b157daf9733457711dafaf82 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 30 Jul 2019 10:56:52 +0200 Subject: [PATCH 244/264] Fix QColorTransform memory leak Introduced recently when the smart-pointer was made manual. Change-Id: I29a041631e94a8e131dd29dae32975d68b386e00 Reviewed-by: Marc Mutz --- src/gui/painting/qcolorspace.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp index 4a1ed373f5..926f2f687a 100644 --- a/src/gui/painting/qcolorspace.cpp +++ b/src/gui/painting/qcolorspace.cpp @@ -364,6 +364,7 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace QColorTransform combined; auto ptr = new QColorTransformPrivate; combined.d = ptr; + combined.d->ref.ref(); ptr->colorSpaceIn = this; ptr->colorSpaceOut = out; ptr->colorMatrix = out->toXyz.inverted() * toXyz; From 10845315b714857c754c1de5360bba3b0386bdab Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Thu, 1 Aug 2019 12:24:06 +0200 Subject: [PATCH 245/264] Conditionally disable parts of the tests testing the deprecated APIs Somehow missed these during my first iteration. Change-Id: Iaef0ab84d9320a98f49ec071c93cd6f2907d92c3 Reviewed-by: Alex Blasche --- tests/auto/corelib/global/qlogging/tst_qlogging.cpp | 4 ++-- tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp index 7dd2a46807..17d0f86728 100644 --- a/tests/auto/corelib/global/qlogging/tst_qlogging.cpp +++ b/tests/auto/corelib/global/qlogging/tst_qlogging.cpp @@ -50,8 +50,8 @@ private slots: void installMessageHandler(); #if QT_DEPRECATED_SINCE(5, 0) void installMsgHandler(); -#endif void installBothHandler(); +#endif #ifdef QT_BUILD_INTERNAL void cleanupFuncinfo_data(); @@ -163,7 +163,6 @@ void tst_qmessagehandler::installMsgHandler() QtMsgHandler myHandler = qInstallMsgHandler(oldHandler); QCOMPARE((void*)myHandler, (void*)customMsgHandler); } -#endif void tst_qmessagehandler::installBothHandler() { @@ -178,6 +177,7 @@ void tst_qmessagehandler::installBothHandler() QCOMPARE(s_function, Q_FUNC_INFO); QCOMPARE(s_line, line); } +#endif # define ADD(x) QTest::newRow(x) << Q_FUNC_INFO << x; diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 5d06f6e8c8..074cb07092 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -379,11 +379,13 @@ void tst_QVariant::isNull() QString str1; QVariant var1( str1 ); QVERIFY( var1.isNull() ); +#if QT_DEPRECATED_SINCE(5, 9) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED QVariant var2( QString::null ); QT_WARNING_POP QVERIFY( var2.isNull() ); +#endif QVariant var3( QString( "blah" ) ); QVERIFY( !var3.isNull() ); From f23f9ba041a790566ca1553d4dc138af3c49db80 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 21 May 2019 13:51:50 +0200 Subject: [PATCH 246/264] QTestLib: Speed up QCOMPARE for QString Add overloads for qCompare() for QStringView making use of the fast formatting helper introduced by 94aa350621e8a5c4ad3b438c10fc1c0a9ed3bc8a for int. Speeds up the bug report example by a factor of 3..4. Task-number: QTBUG-38890 Change-Id: Icc706618b2f1d23b37d354a04d4e1d1cc4b5aee3 Reviewed-by: Edward Welbourne --- src/testlib/qtestcase.cpp | 51 +++++++++++++++++++++++++++++++++++++ src/testlib/qtestcase.h | 28 ++++++++++++++++++++ src/testlib/qtestresult.cpp | 26 +++++++++++++++++++ src/testlib/qtestresult_p.h | 15 +++++++++++ 4 files changed, 120 insertions(+) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 52eb04b109..990fc5679d 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -2587,6 +2587,57 @@ bool QTest::qCompare(unsigned t1, unsigned t2, const char *actual, const char *e t1, t2, actual, expected, file, line); } +/*! \fn bool QTest::qCompare(QStringView t1, QStringView t2, const char *actual, const char *expected, const char *file, int line) + \internal + \since 5.14 + */ +bool QTest::qCompare(QStringView t1, QStringView t2, const char *actual, const char *expected, + const char *file, int line) +{ + return QTestResult::compare(t1 == t2, + "Compared values are not the same", + t1, t2, actual, expected, file, line); +} + +/*! \fn bool QTest::qCompare(QStringView t1, const QLatin1String &t2, const char *actual, const char *expected, const char *file, int line) + \internal + \since 5.14 + */ +bool QTest::qCompare(QStringView t1, const QLatin1String &t2, const char *actual, const char *expected, + const char *file, int line) +{ + return QTestResult::compare(t1 == t2, + "Compared values are not the same", + t1, t2, actual, expected, file, line); +} + +/*! \fn bool QTest::qCompare(const QLatin1String &t1, QStringView t2, const char *actual, const char *expected, const char *file, int line) + \internal + \since 5.14 + */ +bool QTest::qCompare(const QLatin1String &t1, QStringView t2, const char *actual, const char *expected, + const char *file, int line) +{ + return QTestResult::compare(t1 == t2, + "Compared values are not the same", + t1, t2, actual, expected, file, line); +} + +/*! \fn bool QTest::qCompare(const QString &t1, const QString &t2, const char *actual, const char *expected, const char *file, int line) + \internal + \since 5.14 + */ + +/*! \fn bool QTest::qCompare(const QString &t1, const QLatin1String &t2, const char *actual, const char *expected, const char *file, int line) + \internal + \since 5.14 + */ + +/*! \fn bool QTest::qCompare(const QLatin1String &t1, const QString &t2, const char *actual, const char *expected, const char *file, int line) + \internal + \since 5.14 + */ + /*! \fn bool QTest::qCompare(const double &t1, const float &t2, const char *actual, const char *expected, const char *file, int line) \internal */ diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index 40afac37c5..e61e450e98 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -369,6 +369,34 @@ namespace QTest Q_TESTLIB_EXPORT bool qCompare(unsigned t1, unsigned t2, const char *actual, const char *expected, const char *file, int line); + Q_TESTLIB_EXPORT bool qCompare(QStringView t1, QStringView t2, + const char *actual, const char *expected, + const char *file, int line); + Q_TESTLIB_EXPORT bool qCompare(QStringView t1, const QLatin1String &t2, + const char *actual, const char *expected, + const char *file, int line); + Q_TESTLIB_EXPORT bool qCompare(const QLatin1String &t1, QStringView t2, + const char *actual, const char *expected, + const char *file, int line); + inline bool qCompare(const QString &t1, const QString &t2, + const char *actual, const char *expected, + const char *file, int line) + { + return qCompare(QStringView(t1), QStringView(t2), actual, expected, file, line); + } + inline bool qCompare(const QString &t1, const QLatin1String &t2, + const char *actual, const char *expected, + const char *file, int line) + { + return qCompare(QStringView(t1), t2, actual, expected, file, line); + } + inline bool qCompare(const QLatin1String &t1, const QString &t2, + const char *actual, const char *expected, + const char *file, int line) + { + return qCompare(t1, QStringView(t2), actual, expected, file, line); + } + inline bool compare_ptr_helper(const volatile void *t1, const volatile void *t2, const char *actual, const char *expected, const char *file, int line) { diff --git a/src/testlib/qtestresult.cpp b/src/testlib/qtestresult.cpp index eeae7ef0f4..88028aac6e 100644 --- a/src/testlib/qtestresult.cpp +++ b/src/testlib/qtestresult.cpp @@ -39,8 +39,10 @@ #include #include +#include #include +#include // toString() specializations for QStringView #include #include #include @@ -389,6 +391,30 @@ bool QTestResult::compare(bool success, const char *failureMsg, return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line); } +bool QTestResult::compare(bool success, const char *failureMsg, + QStringView val1, QStringView val2, + const char *actual, const char *expected, + const char *file, int line) +{ + return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line); +} + +bool QTestResult::compare(bool success, const char *failureMsg, + QStringView val1, const QLatin1String &val2, + const char *actual, const char *expected, + const char *file, int line) +{ + return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line); +} + +bool QTestResult::compare(bool success, const char *failureMsg, + const QLatin1String & val1, QStringView val2, + const char *actual, const char *expected, + const char *file, int line) +{ + return compareHelper(success, failureMsg, val1, val2, actual, expected, file, line); +} + void QTestResult::addFailure(const char *message, const char *file, int line) { clearExpectFail(); diff --git a/src/testlib/qtestresult_p.h b/src/testlib/qtestresult_p.h index 92f98bb047..38a3024a0f 100644 --- a/src/testlib/qtestresult_p.h +++ b/src/testlib/qtestresult_p.h @@ -55,6 +55,9 @@ QT_BEGIN_NAMESPACE +class QLatin1String; +class QStringView; + class QTestResultPrivate; class QTestData; @@ -95,6 +98,18 @@ public: unsigned val1, unsigned val2, const char *actual, const char *expected, const char *file, int line); + static bool compare(bool success, const char *failureMsg, + QStringView val1, QStringView val2, + const char *actual, const char *expected, + const char *file, int line); + static bool compare(bool success, const char *failureMsg, + const QLatin1String &val1, QStringView val2, + const char *actual, const char *expected, + const char *file, int line); + static bool compare(bool success, const char *failureMsg, + QStringView val1, const QLatin1String &val2, + const char *actual, const char *expected, + const char *file, int line); static void setCurrentGlobalTestData(QTestData *data); static void setCurrentTestData(QTestData *data); static void setCurrentTestFunction(const char *func); From 4726f47b41e507a967c8995609e11947dde4c250 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 31 Jul 2019 08:28:28 +0300 Subject: [PATCH 247/264] Port users of get{Contents,Text}Margins() missed first time around Done-with: Sona Kurazyan Change-Id: I5b584cbe468429c53c2d661a0d7957d74e7ad691 Reviewed-by: Edward Welbourne --- .../tst_qgraphicsproxywidget.cpp | 11 +++++------ .../qgraphicsview/tst_qgraphicsview.cpp | 10 ++++------ .../widgets/widgets/qlineedit/tst_qlineedit.cpp | 8 ++++++++ tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp | 14 ++++++-------- 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index 530c3bb464..39aa65a478 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -463,14 +463,13 @@ void tst_QGraphicsProxyWidget::setWidget() QCOMPARE(proxy->focusPolicy(), Qt::WheelFocus); QVERIFY(proxy->acceptDrops()); QCOMPARE(proxy->acceptHoverEvents(), true); // to get widget enter events - int left, top, right, bottom; - widget->getContentsMargins(&left, &top, &right, &bottom); + const QMarginsF margins = QMarginsF{widget->contentsMargins()}; qreal rleft, rtop, rright, rbottom; proxy->getContentsMargins(&rleft, &rtop, &rright, &rbottom); - QCOMPARE((qreal)left, rleft); - QCOMPARE((qreal)top, rtop); - QCOMPARE((qreal)right, rright); - QCOMPARE((qreal)bottom, rbottom); + QCOMPARE(margins.left(), rleft); + QCOMPARE(margins.top(), rtop); + QCOMPARE(margins.right(), rright); + QCOMPARE(margins.bottom(), rbottom); } else { // proxy shouldn't mess with the widget if it can't insert it. QCOMPARE(proxy->widget(), nullptr); diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index 7a385a230e..4709499cd6 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -2526,9 +2526,8 @@ void tst_QGraphicsView::viewportUpdateMode2() view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); view.setScene(&dummyScene); view.ensurePolished(); // make sure we get the right content margins - int left, top, right, bottom; - view.getContentsMargins(&left, &top, &right, &bottom); - view.resize(200 + left + right, 200 + top + bottom); + const QMargins margins = view.contentsMargins(); + view.resize(200 + margins.left() + margins.right(), 200 + margins.top() + margins.bottom()); toplevel.show(); qApp->setActiveWindow(&toplevel); QVERIFY(QTest::qWaitForWindowExposed(&toplevel)); @@ -4043,9 +4042,8 @@ void tst_QGraphicsView::update() CustomView view(0, &toplevel); view.setScene(&dummyScene); view.ensurePolished(); // must ensure polished to get content margins right - int left, top, right, bottom; - view.getContentsMargins(&left, &top, &right, &bottom); - view.resize(200 + left + right, 200 + top + bottom); + const QMargins margins = view.contentsMargins(); + view.resize(200 + margins.left() + margins.right(), 200 + margins.top() + margins.bottom()); toplevel.show(); QVERIFY(QTest::qWaitForWindowExposed(&toplevel)); diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index f1bc3e8dd4..1c68a5f752 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -3530,6 +3530,13 @@ void tst_QLineEdit::textMargin() centerOnScreen(&tlw); tlw.show(); + const QMargins margins = testWidget.textMargins(); + QCOMPARE(left, margins.left()); + QCOMPARE(top, margins.top()); + QCOMPARE(right, margins.right()); + QCOMPARE(bottom, margins.bottom()); + +#if QT_DEPRECATED_SINCE(5, 14) int l; int t; int r; @@ -3539,6 +3546,7 @@ void tst_QLineEdit::textMargin() QCOMPARE(top, t); QCOMPARE(right, r); QCOMPARE(bottom, b); +#endif QTest::mouseClick(&testWidget, Qt::LeftButton, 0, mousePressPos); QTRY_COMPARE(testWidget.cursorPosition(), cursorPosition); diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index 4f5a2ce1a6..9c40c0bd57 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -951,8 +951,7 @@ void tst_QMenu::menuSizeHint() for (auto str : {"trer", "ezrfgtgvqd", "sdgzgzerzerzer", "eerzertz", "er"}) menu.addAction(str); - int left, top, right, bottom; - menu.getContentsMargins(&left, &top, &right, &bottom); + const QMargins cm = menu.contentsMargins(); const int panelWidth = menu.style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, &menu); const int hmargin = menu.style()->pixelMetric(QStyle::PM_MenuHMargin, 0, &menu), vmargin = menu.style()->pixelMetric(QStyle::PM_MenuVMargin, 0, &menu); @@ -962,15 +961,15 @@ void tst_QMenu::menuSizeHint() for (QAction *action : menu.actions()) { maxWidth = qMax(maxWidth, menu.actionGeometry(action).width()); result |= menu.actionGeometry(action); - QCOMPARE(result.x(), left + hmargin + panelWidth); - QCOMPARE(result.y(), top + vmargin + panelWidth); + QCOMPARE(result.x(), cm.left() + hmargin + panelWidth); + QCOMPARE(result.y(), cm.top() + vmargin + panelWidth); } QStyleOption opt(0); opt.rect = menu.rect(); opt.state = QStyle::State_None; - QSize resSize = QSize(result.x(), result.y()) + result.size() + QSize(hmargin + right + panelWidth, vmargin + top + panelWidth); + QSize resSize = QSize(result.x(), result.y()) + result.size() + QSize(hmargin + cm.right() + panelWidth, vmargin + cm.top() + panelWidth); resSize = menu.style()->sizeFromContents(QStyle::CT_Menu, &opt, resSize.expandedTo(QApplication::globalStrut()), &menu); @@ -1571,8 +1570,7 @@ void tst_QMenu::menuSize_Scrolling() int hmargin = style()->pixelMetric(QStyle::PM_MenuHMargin, nullptr, this); int fw = style()->pixelMetric(QStyle::PM_MenuPanelWidth, nullptr, this); - int leftMargin, topMargin, rightMargin, bottomMargin; - getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin); + const QMargins cm = contentsMargins(); QRect lastItem = actionGeometry(actions().at(actions().length() - 1)); QSize s = size(); #ifdef Q_OS_WINRT @@ -1585,7 +1583,7 @@ void tst_QMenu::menuSize_Scrolling() return; } - QCOMPARE( s.width(), lastItem.right() + fw + hmargin + rightMargin + 1); + QCOMPARE( s.width(), lastItem.right() + fw + hmargin + cm.right() + 1); QMenu::showEvent(e); } From b6688a4d4939b15713ffd8702253433032879fcb Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Fri, 26 Jul 2019 17:08:01 +0200 Subject: [PATCH 248/264] Un-deprecate QSignalMapper From the comments on QTBUG-73407 and the last comments on 29bcbeab90210da80234529905d17280374f9684, it seems like there are still use-cases when QSignalMapper is useful. Change-Id: I8402286cb8a395a4601cda8a4cdda51f19aef073 Reviewed-by: Simon Hausmann Reviewed-by: Volker Hilsheimer --- src/corelib/kernel/qsignalmapper.cpp | 8 +++----- src/corelib/kernel/qsignalmapper.h | 6 +----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/corelib/kernel/qsignalmapper.cpp b/src/corelib/kernel/qsignalmapper.cpp index 34fea861cd..24b174972f 100644 --- a/src/corelib/kernel/qsignalmapper.cpp +++ b/src/corelib/kernel/qsignalmapper.cpp @@ -38,7 +38,6 @@ ****************************************************************************/ #include "qglobal.h" -#if QT_DEPRECATED_SINCE(5, 10) #include "qsignalmapper.h" #include "qhash.h" @@ -64,7 +63,6 @@ public: /*! \class QSignalMapper \inmodule QtCore - \obsolete The recommended solution is connecting the signal to a lambda. \brief The QSignalMapper class bundles signals from identifiable senders. \ingroup objectmodel @@ -72,7 +70,9 @@ public: This class collects a set of parameterless signals, and re-emits them with integer, string or widget parameters corresponding to - the object that sent the signal. + the object that sent the signal. Note that in most cases you can + use lambdas for passing custom parameters to slots. This is less + costly and will simplify the code. The class supports the mapping of particular strings or integers with particular objects using setMapping(). The objects' signals @@ -314,5 +314,3 @@ void QSignalMapper::map(QObject *sender) QT_END_NAMESPACE #include "moc_qsignalmapper.cpp" - -#endif diff --git a/src/corelib/kernel/qsignalmapper.h b/src/corelib/kernel/qsignalmapper.h index 6c4cfa9627..0da1e8f87d 100644 --- a/src/corelib/kernel/qsignalmapper.h +++ b/src/corelib/kernel/qsignalmapper.h @@ -42,8 +42,6 @@ #include -#if QT_DEPRECATED_SINCE(5, 10) - QT_BEGIN_NAMESPACE class QSignalMapperPrivate; @@ -53,7 +51,7 @@ class Q_CORE_EXPORT QSignalMapper : public QObject Q_OBJECT Q_DECLARE_PRIVATE(QSignalMapper) public: - QT_DEPRECATED explicit QSignalMapper(QObject *parent = nullptr); + explicit QSignalMapper(QObject *parent = nullptr); ~QSignalMapper(); void setMapping(QObject *sender, int id); @@ -84,6 +82,4 @@ private: QT_END_NAMESPACE -#endif - #endif // QSIGNALMAPPER_H From bd2c8353b44a1e63b84852ec9adeed78dbfab312 Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Fri, 26 Jul 2019 16:05:39 +0200 Subject: [PATCH 249/264] Improve the keypadnavigation manual test - No need to use QSignalMapper here, replace its uses with lambdas. - Replace index 'for' loop with iterator loop, to simplify the code. Change-Id: Ide3d2db99a074c0233eb5c2fd7a9b217d804973f Reviewed-by: Marc Mutz --- tests/manual/keypadnavigation/main.cpp | 37 +++++++++++--------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/tests/manual/keypadnavigation/main.cpp b/tests/manual/keypadnavigation/main.cpp index 67986a9cc9..dad4376514 100644 --- a/tests/manual/keypadnavigation/main.cpp +++ b/tests/manual/keypadnavigation/main.cpp @@ -33,7 +33,6 @@ #include #include #include -#include #include "ui_keypadnavigation.h" class KeypadNavigation : public QMainWindow @@ -48,7 +47,7 @@ public: ui->setupUi(this); const struct { - QObject *action; + QAction *action; QWidget *page; } layoutMappings[] = { {ui->m_actionLayoutVerticalSimple, ui->m_pageVerticalSimple}, @@ -58,15 +57,16 @@ public: {ui->m_actionLayoutChaos, ui->m_pageChaos}, {ui->m_actionLayoutDialogs, ui->m_pageDialogs} }; - for (int i = 0; i < int(sizeof layoutMappings / sizeof layoutMappings[0]); ++i) { - connect(layoutMappings[i].action, SIGNAL(triggered()), &m_layoutSignalMapper, SLOT(map())); - m_layoutSignalMapper.setMapping(layoutMappings[i].action, layoutMappings[i].page); + for (auto layoutMapping : layoutMappings) { + const auto page = layoutMapping.page; + connect(layoutMapping.action, &QAction::triggered, ui->m_stackWidget, + [this, page]() + { ui->m_stackWidget->setCurrentWidget(page); }); } - connect(&m_layoutSignalMapper, SIGNAL(mapped(QWidget*)), ui->m_stackWidget, SLOT(setCurrentWidget(QWidget*))); #ifdef QT_KEYPAD_NAVIGATION const struct { - QObject *action; + QAction *action; Qt::NavigationMode mode; } modeMappings[] = { {ui->m_actionModeNone, Qt::NavigationModeNone}, @@ -75,17 +75,17 @@ public: {ui->m_actionModeCursorAuto, Qt::NavigationModeCursorAuto}, {ui->m_actionModeCursorForceVisible, Qt::NavigationModeCursorForceVisible} }; - for (int i = 0; i < int(sizeof modeMappings / sizeof modeMappings[0]); ++i) { - connect(modeMappings[i].action, SIGNAL(triggered()), &m_modeSignalMapper, SLOT(map())); - m_modeSignalMapper.setMapping(modeMappings[i].action, int(modeMappings[i].mode)); + for (auto modeMapping : modeMappings) { + const auto mode = modeMapping.mode; + connect(modeMapping.action, &QAction::triggered, this, + [this, mode]() { setNavigationMode(mode); }); } - connect(&m_modeSignalMapper, SIGNAL(mapped(int)), SLOT(setNavigationMode(int))); #else // QT_KEYPAD_NAVIGATION ui->m_menuNavigation_mode->deleteLater(); #endif // QT_KEYPAD_NAVIGATION const struct { - QObject *button; + QPushButton *button; Dialog dialog; } openDialogMappings[] = { {ui->m_buttonGetOpenFileName, DialogGetOpenFileName}, @@ -97,11 +97,11 @@ public: {ui->m_buttonAboutQt, DialogAboutQt}, {ui->m_buttonGetItem, DialogGetItem} }; - for (int i = 0; i < int(sizeof openDialogMappings / sizeof openDialogMappings[0]); ++i) { - connect(openDialogMappings[i].button, SIGNAL(clicked()), &m_dialogSignalMapper, SLOT(map())); - m_dialogSignalMapper.setMapping(openDialogMappings[i].button, int(openDialogMappings[i].dialog)); + for (auto openDialogMapping : openDialogMappings) { + const auto dialog = openDialogMapping.dialog; + connect(openDialogMapping.button, &QPushButton::clicked, this, + [this, dialog]() { openDialog(dialog); }); } - connect(&m_dialogSignalMapper, SIGNAL(mapped(int)), SLOT(openDialog(int))); } ~KeypadNavigation() @@ -162,11 +162,6 @@ private: }; Ui_KeypadNavigation *ui; - QSignalMapper m_layoutSignalMapper; -#ifdef QT_KEYPAD_NAVIGATION - QSignalMapper m_modeSignalMapper; -#endif // QT_KEYPAD_NAVIGATION - QSignalMapper m_dialogSignalMapper; }; int main(int argc, char *argv[]) From 376715f1a57209cbb19502954a37939e2d6d88c6 Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Tue, 23 Jul 2019 15:26:19 +0200 Subject: [PATCH 250/264] Remove usages of deprecated APIs of qtbase/widgets - Replace the usages of deprecated APIs by corresponding alternatives in the library code and documentation. - Build docs for deprecated APIs conditionally, based on deprecation version. Remove the docs of methods deprecated since 5.0.0, these methods are not compiled anymore. - Modify the tests to make them build when deprecated APIs disabled: * Make the the parts of the tests testing the deprecated APIs to be compiled conditionally, only when the corresponding methods are enabled. * If the test-case tests only the deprecated API, but not the corresponding replacement, add tests for the replacement Task-number: QTBUG-76491 Task-number: QTBUG-76540 Task-number: QTBUG-76541 Change-Id: I6aaf0a1369c479fb880369a38f2b8e1e86b46934 Reviewed-by: Volker Hilsheimer --- .../dialogs/standarddialogs/dialog.cpp | 2 +- src/widgets/graphicsview/qgraphicsitem.cpp | 4 +- src/widgets/itemviews/qheaderview.cpp | 80 ++----------------- src/widgets/itemviews/qlistwidget.cpp | 6 ++ src/widgets/itemviews/qtablewidget.cpp | 4 + src/widgets/itemviews/qtreewidget.cpp | 4 + .../widgets/dialogs/qdialog/tst_qdialog.cpp | 43 +++++++++- .../dialogs/qfiledialog/tst_qfiledialog.cpp | 3 + .../dialogs/qfiledialog2/tst_qfiledialog2.cpp | 16 ++-- .../qgraphicsitem/tst_qgraphicsitem.cpp | 4 + .../kernel/qboxlayout/tst_qboxlayout.cpp | 4 +- .../kernel/qgridlayout/tst_qgridlayout.cpp | 12 +-- .../widgets/kernel/qlayout/tst_qlayout.cpp | 4 +- .../widgets/kernel/qwidget/tst_qwidget.cpp | 4 +- .../widgets/qcombobox/tst_qcombobox.cpp | 19 +++++ .../widgets/widgets/qlabel/tst_qlabel.cpp | 2 +- .../widgets/widgets/qmdiarea/tst_qmdiarea.cpp | 2 +- .../qmdisubwindow/tst_qmdisubwindow.cpp | 7 +- .../widgets/qsplitter/tst_qsplitter.cpp | 2 +- .../widgets/qtabwidget/tst_qtabwidget.cpp | 4 +- .../qgraphicsview/benchapps/chipTest/chip.cpp | 2 +- 21 files changed, 120 insertions(+), 108 deletions(-) diff --git a/examples/widgets/dialogs/standarddialogs/dialog.cpp b/examples/widgets/dialogs/standarddialogs/dialog.cpp index c91a594490..df77d03567 100644 --- a/examples/widgets/dialogs/standarddialogs/dialog.cpp +++ b/examples/widgets/dialogs/standarddialogs/dialog.cpp @@ -317,7 +317,7 @@ void Dialog::setInteger() { //! [0] bool ok; - int i = QInputDialog::getInt(this, tr("QInputDialog::getInteger()"), + int i = QInputDialog::getInt(this, tr("QInputDialog::getInt()"), tr("Percentage:"), 25, 0, 100, 1, &ok); if (ok) integerLabel->setText(tr("%1%").arg(i)); diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp index 65708fa1ca..ca30c72db5 100644 --- a/src/widgets/graphicsview/qgraphicsitem.cpp +++ b/src/widgets/graphicsview/qgraphicsitem.cpp @@ -449,8 +449,8 @@ \value ItemSendsGeometryChanges The item enables itemChange() notifications for ItemPositionChange, ItemPositionHasChanged, - ItemMatrixChange, ItemTransformChange, ItemTransformHasChanged, - ItemRotationChange, ItemRotationHasChanged, ItemScaleChange, ItemScaleHasChanged, + ItemTransformChange, ItemTransformHasChanged, ItemRotationChange, + ItemRotationHasChanged, ItemScaleChange, ItemScaleHasChanged, ItemTransformOriginPointChange, and ItemTransformOriginPointHasChanged. For performance reasons, these notifications are disabled by default. You must enable this flag to receive notifications for position and transform diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index be80843b07..c4766a74bd 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -189,7 +189,7 @@ static const int maxSizeSection = 1048575; // since section size is in a bitfiel The following values are obsolete: \value Custom Use Fixed instead. - \sa setResizeMode(), setSectionResizeMode(), stretchLastSection, minimumSectionSize + \sa setSectionResizeMode(), stretchLastSection, minimumSectionSize */ /*! @@ -880,7 +880,7 @@ void QHeaderView::swapSections(int first, int second) size equal to zero is however not recommended. In that situation hideSection should be used instead. - \sa sectionResized(), resizeMode(), sectionSize(), hideSection() + \sa sectionResized(), sectionSize(), hideSection() */ void QHeaderView::resizeSection(int logical, int size) @@ -960,7 +960,7 @@ void QHeaderView::resizeSection(int logical, int size) Resizes the sections according to the given \a mode, ignoring the current resize mode. - \sa resizeMode(), sectionResized() + \sa sectionResized() */ void QHeaderView::resizeSections(QHeaderView::ResizeMode mode) @@ -1139,16 +1139,6 @@ void QHeaderView::setSectionsMovable(bool movable) d->movableSections = movable; } -// ### Qt 6 - remove this obsolete function -/*! - \obsolete - \fn void QHeaderView::setMovable(bool movable) - - Use setSectionsMovable instead. - - \sa setSectionsMovable() -*/ - /*! \since 5.0 @@ -1167,16 +1157,6 @@ bool QHeaderView::sectionsMovable() const return d->movableSections; } -// ### Qt 6 - remove this obsolete function -/*! - \obsolete - \fn bool QHeaderView::isMovable() const - - Use sectionsMovable instead. - - \sa sectionsMovable() -*/ - /*! \property QHeaderView::firstSectionMovable \brief Whether the first column can be moved by the user @@ -1223,16 +1203,6 @@ void QHeaderView::setSectionsClickable(bool clickable) d->clickableSections = clickable; } -// ### Qt 6 - remove this obsolete function -/*! - \obsolete - \fn void QHeaderView::setClickable(bool clickable) - - Use setSectionsClickable instead. - - \sa setSectionsClickable() -*/ - /*! \since 5.0 @@ -1249,16 +1219,6 @@ bool QHeaderView::sectionsClickable() const return d->clickableSections; } -// ### Qt 6 - remove this obsolete function -/*! - \obsolete - \fn bool QHeaderView::isClickable() const - - Use sectionsClickable instead. - - \sa sectionsClickable() -*/ - void QHeaderView::setHighlightSections(bool highlight) { Q_D(QHeaderView); @@ -1277,7 +1237,7 @@ bool QHeaderView::highlightSections() const Sets the constraints on how the header can be resized to those described by the given \a mode. - \sa resizeMode(), length(), sectionResized() + \sa length(), sectionResized() */ void QHeaderView::setSectionResizeMode(ResizeMode mode) @@ -1327,26 +1287,6 @@ void QHeaderView::setSectionResizeMode(int logicalIndex, ResizeMode mode) d->doDelayedResizeSections(); // section sizes may change as a result of the new mode } -// ### Qt 6 - remove this obsolete function -/*! - \overload - \obsolete - \fn void QHeaderView::setResizeMode(int logicalIndex, ResizeMode mode) - - Use setSectionResizeMode instead. - - \sa setSectionResizeMode() -*/ - -/*! - \obsolete - \fn void QHeaderView::setResizeMode(ResizeMode mode) - - Use setSectionResizeMode instead. - - \sa setSectionResizeMode() -*/ - /*! \since 5.0 @@ -1407,16 +1347,6 @@ int QHeaderView::resizeContentsPrecision() const return d->resizeContentsPrecision; } -// ### Qt 6 - remove this obsolete function -/*! - \obsolete - \fn QHeaderView::ResizeMode QHeaderView::resizeMode(int logicalIndex) const - - Use sectionResizeMode instead. - - \sa sectionResizeMode() -*/ - /*! \since 4.1 @@ -1424,7 +1354,7 @@ int QHeaderView::resizeContentsPrecision() const views, this can be used to see if the headerview needs to resize the sections when the view's geometry changes. - \sa stretchLastSection, resizeMode() + \sa stretchLastSection */ int QHeaderView::stretchSectionCount() const diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp index 37bb370e73..e7dcfac403 100644 --- a/src/widgets/itemviews/qlistwidget.cpp +++ b/src/widgets/itemviews/qlistwidget.cpp @@ -930,12 +930,14 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item) \sa Qt::AlignmentFlag */ +#if QT_DEPRECATED_SINCE(5, 13) /*! \fn QColor QListWidgetItem::backgroundColor() const \obsolete This function is deprecated. Use background() instead. */ +#endif /*! \fn QBrush QListWidgetItem::background() const @@ -946,6 +948,7 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item) \sa setBackground(), foreground() */ +#if QT_DEPRECATED_SINCE(5, 13) /*! \fn QColor QListWidgetItem::textColor() const \obsolete @@ -954,6 +957,7 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item) This function is deprecated. Use foreground() instead. */ +#endif /*! \fn QBrush QListWidgetItem::foreground() const @@ -1119,12 +1123,14 @@ void QListWidgetItem::setFlags(Qt::ItemFlags aflags) \sa background(), setForeground() */ +#if QT_DEPRECATED_SINCE(5, 13) /*! \fn void QListWidgetItem::setTextColor(const QColor &color) \obsolete This function is deprecated. Use setForeground() instead. */ +#endif /*! \fn void QListWidgetItem::setForeground(const QBrush &brush) diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp index 0fb9e28385..a25a582881 100644 --- a/src/widgets/itemviews/qtablewidget.cpp +++ b/src/widgets/itemviews/qtablewidget.cpp @@ -1251,6 +1251,7 @@ void QTableWidgetItem::setFlags(Qt::ItemFlags aflags) \sa font(), setText(), setForeground() */ +#if QT_DEPRECATED_SINCE(5, 13) /*! \fn QColor QTableWidgetItem::backgroundColor() const \obsolete @@ -1264,6 +1265,7 @@ void QTableWidgetItem::setFlags(Qt::ItemFlags aflags) This function is deprecated. Use setBackground() instead. */ +#endif /*! \fn QBrush QTableWidgetItem::background() const @@ -1283,6 +1285,7 @@ void QTableWidgetItem::setFlags(Qt::ItemFlags aflags) \sa setForeground() */ +#if QT_DEPRECATED_SINCE(5, 13) /*! \fn QColor QTableWidgetItem::textColor() const \obsolete @@ -1296,6 +1299,7 @@ void QTableWidgetItem::setFlags(Qt::ItemFlags aflags) This function is deprecated. Use setForeground() instead. */ +#endif /*! \fn QBrush QTableWidgetItem::foreground() const diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp index d2dc91b18c..d285ad6d28 100644 --- a/src/widgets/itemviews/qtreewidget.cpp +++ b/src/widgets/itemviews/qtreewidget.cpp @@ -1251,6 +1251,7 @@ bool QTreeWidgetItem::isFirstColumnSpanned() const \sa font(), setText(), setForeground() */ +#if QT_DEPRECATED_SINCE(5, 13) /*! \fn QColor QTreeWidgetItem::backgroundColor(int column) const \obsolete @@ -1264,6 +1265,7 @@ bool QTreeWidgetItem::isFirstColumnSpanned() const This function is deprecated. Use setBackground() instead. */ +#endif /*! \fn QBrush QTreeWidgetItem::background(int column) const @@ -1284,6 +1286,7 @@ bool QTreeWidgetItem::isFirstColumnSpanned() const \sa setForeground() */ +#if QT_DEPRECATED_SINCE(5, 13) /*! \fn QColor QTreeWidgetItem::textColor(int column) const \obsolete @@ -1297,6 +1300,7 @@ bool QTreeWidgetItem::isFirstColumnSpanned() const This function is deprecated. Use setForeground() instead. */ +#endif /*! \fn QBrush QTreeWidgetItem::foreground(int column) const diff --git a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp index c840dabc1a..a494d7119a 100644 --- a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp +++ b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp @@ -52,7 +52,9 @@ class DummyDialog : public QDialog { public: DummyDialog(): QDialog() {} +#if QT_DEPRECATED_SINCE(5, 13) using QDialog::showExtension; +#endif }; class tst_QDialog : public QObject @@ -64,8 +66,10 @@ public: private slots: void cleanup(); void getSetCheck(); +#if QT_DEPRECATED_SINCE(5, 13) void showExtension_data(); void showExtension(); +#endif void defaultButtons(); void showMaximized(); void showMinimized(); @@ -76,6 +80,9 @@ private slots: void deleteInExec(); #if QT_CONFIG(sizegrip) void showSizeGrip(); +#if QT_DEPRECATED_SINCE(5, 13) + void showSizeGrip_deprecated(); +#endif #endif void setVisible(); void reject(); @@ -89,6 +96,7 @@ private slots: void tst_QDialog::getSetCheck() { QDialog obj1; +#if QT_DEPRECATED_SINCE(5, 13) // QWidget* QDialog::extension() // void QDialog::setExtension(QWidget*) QWidget *var1 = new QWidget; @@ -97,6 +105,7 @@ void tst_QDialog::getSetCheck() obj1.setExtension((QWidget *)0); QCOMPARE((QWidget *)0, obj1.extension()); // No delete var1, since setExtension takes ownership +#endif // int QDialog::result() // void QDialog::setResult(int) @@ -146,6 +155,7 @@ void tst_QDialog::cleanup() QVERIFY(QApplication::topLevelWidgets().isEmpty()); } +#if QT_DEPRECATED_SINCE(5, 13) void tst_QDialog::showExtension_data() { QTest::addColumn("dlgSize"); @@ -197,6 +207,7 @@ void tst_QDialog::showExtension() testWidget.setExtension( 0 ); } +#endif void tst_QDialog::defaultButtons() { @@ -422,8 +433,36 @@ void tst_QDialog::deleteInExec() } #if QT_CONFIG(sizegrip) + // From Task 124269 void tst_QDialog::showSizeGrip() +{ + QDialog dialog(nullptr); + dialog.show(); + QWidget *ext = new QWidget(&dialog); + QVERIFY(!dialog.isSizeGripEnabled()); + + dialog.setSizeGripEnabled(true); + QPointer sizeGrip = dialog.findChild(); + QVERIFY(sizeGrip); + QVERIFY(sizeGrip->isVisible()); + QVERIFY(dialog.isSizeGripEnabled()); + + dialog.setSizeGripEnabled(false); + QVERIFY(!dialog.isSizeGripEnabled()); + + dialog.setSizeGripEnabled(true); + sizeGrip = dialog.findChild(); + QVERIFY(sizeGrip); + QVERIFY(sizeGrip->isVisible()); + sizeGrip->hide(); + dialog.hide(); + dialog.show(); + QVERIFY(!sizeGrip->isVisible()); +} + +#if QT_DEPRECATED_SINCE(5, 13) +void tst_QDialog::showSizeGrip_deprecated() { QDialog dialog(0); dialog.show(); @@ -476,7 +515,9 @@ void tst_QDialog::showSizeGrip() dialog.show(); QVERIFY(!sizeGrip->isVisible()); } -#endif +#endif // QT_DEPRECATED_SINCE(5, 13) + +#endif // QT_CONFIG(sizegrip) void tst_QDialog::setVisible() { diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp index f7482bae45..2131e45f29 100644 --- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp @@ -800,7 +800,10 @@ void tst_QFiledialog::isReadOnly() QAction* renameAction = fd.findChild("qt_rename_action"); QAction* deleteAction = fd.findChild("qt_delete_action"); +#if QT_DEPRECATED_SINCE(5, 13) QCOMPARE(fd.isReadOnly(), false); +#endif + QCOMPARE(fd.testOption(QFileDialog::ReadOnly), false); // This is dependent upon the file/dir, find cross platform way to test //fd.setDirectory(QDir::home()); diff --git a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp index 869418371c..40eff1e4c3 100644 --- a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp +++ b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp @@ -378,24 +378,24 @@ void tst_QFileDialog2::task143519_deleteAndRenameActionBehavior() // defaults QVERIFY(openContextMenu(fd)); QCOMPARE(fd.selectedFiles(), QStringList(ctx.file.fileName())); - QCOMPARE(rm->isEnabled(), !fd.isReadOnly()); - QCOMPARE(mv->isEnabled(), !fd.isReadOnly()); + QCOMPARE(rm->isEnabled(), !fd.testOption(QFileDialog::ReadOnly)); + QCOMPARE(mv->isEnabled(), !fd.testOption(QFileDialog::ReadOnly)); // change to non-defaults: - fd.setReadOnly(!fd.isReadOnly()); + fd.setOption(QFileDialog::ReadOnly, !fd.testOption(QFileDialog::ReadOnly)); QVERIFY(openContextMenu(fd)); QCOMPARE(fd.selectedFiles().size(), 1); - QCOMPARE(rm->isEnabled(), !fd.isReadOnly()); - QCOMPARE(mv->isEnabled(), !fd.isReadOnly()); + QCOMPARE(rm->isEnabled(), !fd.testOption(QFileDialog::ReadOnly)); + QCOMPARE(mv->isEnabled(), !fd.testOption(QFileDialog::ReadOnly)); // and changed back to defaults: - fd.setReadOnly(!fd.isReadOnly()); + fd.setOption(QFileDialog::ReadOnly, !fd.testOption(QFileDialog::ReadOnly)); QVERIFY(openContextMenu(fd)); QCOMPARE(fd.selectedFiles().size(), 1); - QCOMPARE(rm->isEnabled(), !fd.isReadOnly()); - QCOMPARE(mv->isEnabled(), !fd.isReadOnly()); + QCOMPARE(rm->isEnabled(), !fd.testOption(QFileDialog::ReadOnly)); + QCOMPARE(mv->isEnabled(), !fd.testOption(QFileDialog::ReadOnly)); } #endif // !QT_NO_CONTEXTMENU && !QT_NO_MENU diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index 432d8d75b7..7b914512ab 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -4441,12 +4441,14 @@ protected: case QGraphicsItem::ItemPositionHasChanged: break; case QGraphicsItem::ItemMatrixChange: { +#if QT_DEPRECATED_SINCE(5, 13) QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED QVariant variant; variant.setValue(matrix()); oldValues << variant; QT_WARNING_POP +#endif } break; case QGraphicsItem::ItemTransformChange: { @@ -4566,6 +4568,7 @@ void tst_QGraphicsItem::itemChange() QCOMPARE(tester.oldValues.last(), QVariant(true)); QCOMPARE(tester.isEnabled(), true); } +#if QT_DEPRECATED_SINCE(5, 13) { QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED // QDesktopWidget::screen() @@ -4585,6 +4588,7 @@ QT_WARNING_DISABLE_DEPRECATED // QDesktopWidget::screen() QCOMPARE(tester.matrix(), QMatrix().rotate(90)); QT_WARNING_POP } +#endif { tester.resetTransform(); ++changeCount; diff --git a/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp b/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp index 8dd9d7c428..00bde3cb25 100644 --- a/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp +++ b/tests/auto/widgets/kernel/qboxlayout/tst_qboxlayout.cpp @@ -194,7 +194,7 @@ void tst_QBoxLayout::setGeometry() setFrameless(&toplevel); QWidget w(&toplevel); QVBoxLayout *lay = new QVBoxLayout; - lay->setMargin(0); + lay->setContentsMargins(0, 0, 0, 0); lay->setSpacing(0); QHBoxLayout *lay2 = new QHBoxLayout; QDial *dial = new QDial; @@ -271,7 +271,7 @@ void tst_QBoxLayout::widgetSurplus() QDialog window; QScopedPointer marginEater(new MarginEatingStyle); QVBoxLayout *vbox = new QVBoxLayout(&window); - vbox->setMargin(0); + vbox->setContentsMargins(0, 0, 0, 0); vbox->setSpacing(0); QLabel *hiddenLabel = new QLabel(tr("Invisible label")); diff --git a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp index 5e0327319b..1d63d140fb 100644 --- a/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp +++ b/tests/auto/widgets/kernel/qgridlayout/tst_qgridlayout.cpp @@ -219,9 +219,9 @@ void tst_QGridLayout::badDistributionBug() QDialog dialog; Ui::SortDialog ui; ui.setupUi(&dialog); - ui.gridLayout->setMargin(0); + ui.gridLayout->setContentsMargins(0, 0, 0, 0); ui.gridLayout->setSpacing(0); - ui.vboxLayout->setMargin(0); + ui.vboxLayout->setContentsMargins(0, 0, 0, 0); ui.vboxLayout->setSpacing(0); ui.okButton->setFixedHeight(20); ui.moreButton->setFixedHeight(20); @@ -237,7 +237,7 @@ void tst_QGridLayout::setMinAndMaxSize() QWidget widget; setFrameless(&widget); QGridLayout layout(&widget); - layout.setMargin(0); + layout.setContentsMargins(0, 0, 0, 0); layout.setSpacing(0); layout.setSizeConstraint(QLayout::SetMinAndMaxSize); widget.show(); @@ -396,7 +396,7 @@ void tst_QGridLayout::spacingAndSpacers() QWidget widget; setFrameless(&widget); QGridLayout layout(&widget); - layout.setMargin(0); + layout.setContentsMargins(0, 0, 0, 0); layout.setSpacing(0); widget.show(); @@ -1541,7 +1541,7 @@ void tst_QGridLayout::spacerWithSpacing() QWidget window; QGridLayout layout(&window); layout.setSpacing(1); - layout.setMargin(0); + layout.setContentsMargins(0, 0, 0, 0); populate(&layout, 0, i); populate(&layout, 1, j); populate(&layout, 2, k); @@ -1651,7 +1651,7 @@ void tst_QGridLayout::taskQTBUG_52357_spacingWhenItemIsHidden() QWidget widget; setFrameless(&widget); QGridLayout layout(&widget); - layout.setMargin(0); + layout.setContentsMargins(0, 0, 0, 0); layout.setSpacing(5); QPushButton button1; layout.addWidget(&button1, 0, 0); diff --git a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp index 936f581d89..140a367afe 100644 --- a/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp +++ b/tests/auto/widgets/kernel/qlayout/tst_qlayout.cpp @@ -308,7 +308,7 @@ void tst_QLayout::controlTypes2() { QWidget main; QVBoxLayout *const layout = new QVBoxLayout(&main); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); QComboBox *combo = new QComboBox(&main); layout->addWidget(combo); QCOMPARE(layout->controlTypes(), QSizePolicy::ComboBox); @@ -319,7 +319,7 @@ void tst_QLayout::adjustSizeShouldMakeSureLayoutIsActivated() QWidget main; QVBoxLayout *const layout = new QVBoxLayout(&main); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); SizeHinterFrame *frame = new SizeHinterFrame(QSize(200, 10), QSize(200, 8)); frame->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); layout->addWidget(frame); diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 5465bd5518..bfc2631842 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -8073,7 +8073,7 @@ public: sp.setHeightForWidth(hfwLayout); QVBoxLayout *vbox = new QVBoxLayout; - vbox->setMargin(0); + vbox->setContentsMargins(0, 0, 0, 0); vbox->addWidget(new ASWidget(sizeHint + QSize(30, 20), sp, false, false)); setLayout(vbox); } @@ -10120,7 +10120,7 @@ void tst_QWidget::grabMouse() w.setObjectName(QLatin1String("tst_qwidget_grabMouse")); w.setWindowTitle(w.objectName()); QLayout *layout = new QVBoxLayout(&w); - layout->setMargin(50); + layout->setContentsMargins(50, 50, 50, 50); GrabLoggerWidget *grabber = new GrabLoggerWidget(&log, &w); const QString grabberObjectName = QLatin1String("tst_qwidget_grabMouse_grabber"); grabber->setObjectName(grabberObjectName); diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index 8a46211714..4e16edaca8 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -254,12 +254,22 @@ void tst_QComboBox::getSetCheck() obj1.setMaxCount(INT_MAX); QCOMPARE(INT_MAX, obj1.maxCount()); + // QCompleter *QComboBox::completer() + // void QComboBox::setCompleter(QCompleter *) + obj1.setCompleter(nullptr); + QCOMPARE(nullptr, obj1.completer()); + QCompleter completer; + obj1.setCompleter(&completer); + QVERIFY(obj1.completer() == nullptr); // no QLineEdit is set + +#if QT_DEPRECATED_SINCE(5, 13) // bool QComboBox::autoCompletion() // void QComboBox::setAutoCompletion(bool) obj1.setAutoCompletion(false); QCOMPARE(false, obj1.autoCompletion()); obj1.setAutoCompletion(true); QCOMPARE(true, obj1.autoCompletion()); +#endif // bool QComboBox::duplicatesEnabled() // void QComboBox::setDuplicatesEnabled(bool) @@ -317,6 +327,9 @@ void tst_QComboBox::getSetCheck() QCOMPARE(var8, obj1.lineEdit()); // delete var8; // No delete, since QComboBox takes ownership + // After setting a line edit, completer() should not return nullptr anymore + QVERIFY(obj1.completer() != nullptr); + // const QValidator * QComboBox::validator() // void QComboBox::setValidator(const QValidator *) QIntValidator *var9 = new QIntValidator(0); @@ -777,7 +790,9 @@ void tst_QComboBox::virtualAutocompletion() QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); QComboBox *testWidget = topLevel.comboBox(); testWidget->clear(); +#if QT_DEPRECATED_SINCE(5, 13) testWidget->setAutoCompletion(true); +#endif testWidget->addItem("Foo"); testWidget->addItem("Bar"); testWidget->addItem("Boat"); @@ -837,7 +852,9 @@ void tst_QComboBox::autoCompletionCaseSensitivity() QCOMPARE(qApp->focusWidget(), (QWidget *)testWidget); testWidget->clear(); +#if QT_DEPRECATED_SINCE(5, 13) testWidget->setAutoCompletion(true); +#endif testWidget->addItem("Cow"); testWidget->addItem("irrelevant1"); testWidget->addItem("aww"); @@ -3054,7 +3071,9 @@ void tst_QComboBox::task_QTBUG_31146_popupCompletion() { QComboBox comboBox; comboBox.setEditable(true); +#if QT_DEPRECATED_SINCE(5, 13) comboBox.setAutoCompletion(true); +#endif comboBox.setInsertPolicy(QComboBox::NoInsert); comboBox.completer()->setCaseSensitivity(Qt::CaseInsensitive); comboBox.completer()->setCompletionMode(QCompleter::PopupCompletion); diff --git a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp index 34862f6810..f599ac73c6 100644 --- a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp +++ b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp @@ -461,7 +461,7 @@ void tst_QLabel::unicodeText() QVBoxLayout *layout = new QVBoxLayout(); QLabel *label = new QLabel(text, &frame); layout->addWidget(label); - layout->setMargin(8); + layout->setContentsMargins(8, 8, 8, 8); frame.setLayout(layout); frame.show(); QVERIFY(QTest::qWaitForWindowExposed(&frame)); diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index 046899ce05..b8abd78657 100644 --- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp @@ -880,7 +880,7 @@ void tst_QMdiArea::minimumSizeHint() { QMdiArea workspace; workspace.show(); - QSize expectedSize(workspace.style()->pixelMetric(QStyle::PM_MDIMinimizedWidth), + QSize expectedSize(workspace.style()->pixelMetric(QStyle::PM_MdiSubWindowMinimizedWidth), workspace.style()->pixelMetric(QStyle::PM_TitleBarHeight)); qApp->processEvents(); QAbstractScrollArea dummyScrollArea; diff --git a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp index 2b59a227b3..b8891fab95 100644 --- a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp +++ b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp @@ -613,7 +613,7 @@ void tst_QMdiSubWindow::showShaded() // Calculate mouse position for bottom right corner and simulate a // vertical resize with the mouse. - int offset = window->style()->pixelMetric(QStyle::PM_MDIFrameWidth) / 2; + int offset = window->style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth) / 2; QPoint mousePosition(window->width() - qMax(offset, 2), window->height() - qMax(offset, 2)); QWidget *mouseReceiver = nullptr; #ifdef Q_OS_MAC @@ -759,7 +759,7 @@ void tst_QMdiSubWindow::setOpaqueResizeAndMove() QTRY_COMPARE(priv->resizeTimerId, -1); // Enter resize mode. - int offset = window->style()->pixelMetric(QStyle::PM_MDIFrameWidth) / 2; + int offset = window->style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth) / 2; QPoint mousePosition(mouseReceiver->width() - qMax(offset, 2), mouseReceiver->height() - qMax(offset, 2)); sendMouseMove(mouseReceiver, mousePosition, Qt::NoButton); sendMousePress(mouseReceiver, mousePosition); @@ -1762,7 +1762,8 @@ void tst_QMdiSubWindow::fixedMinMaxSize() int minimizedHeight = subWindow->style()->pixelMetric(QStyle::PM_TitleBarHeight, &options); if (!subWindow->style()->styleHint(QStyle::SH_TitleBar_NoBorder, &options, subWindow)) minimizedHeight += 8; - int minimizedWidth = subWindow->style()->pixelMetric(QStyle::PM_MDIMinimizedWidth, &options); + int minimizedWidth = subWindow->style()->pixelMetric(QStyle::PM_MdiSubWindowMinimizedWidth, + &options); const QSize minimizedSize = QSize(minimizedWidth, minimizedHeight); // Even though the sub window has a minimum size set, it should be possible diff --git a/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp b/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp index 8b45ac20b7..cbeb77a25e 100644 --- a/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp +++ b/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp @@ -599,7 +599,7 @@ void tst_QSplitter::testShowHide() QWidget widget(&topLevel); widget.resize(400 + split->handleWidth(), 200); QVBoxLayout *lay=new QVBoxLayout(&widget); - lay->setMargin(0); + lay->setContentsMargins(0, 0, 0, 0); lay->setSpacing(0); split->addWidget(new QWidget); split->addWidget(new QWidget); diff --git a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp index cbf5196bb9..feade7d443 100644 --- a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp +++ b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp @@ -620,7 +620,7 @@ void tst_QTabWidget::heightForWidth() QWidget *window = new QWidget; QVBoxLayout *lay = new QVBoxLayout(window); - lay->setMargin(0); + lay->setContentsMargins(0, 0, 0, 0); lay->setSpacing(0); QTabWidget *tabWid = new QTabWidget(window); QWidget *w = new QWidget; @@ -637,7 +637,7 @@ void tst_QTabWidget::heightForWidth() ); label->setWordWrap(true); lay2->addWidget(label); - lay2->setMargin(0); + lay2->setContentsMargins(0, 0, 0, 0); lay->addWidget(tabWid); int h = window->heightForWidth(160); diff --git a/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/chip.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/chip.cpp index 57ab62b1c3..2277ae0f14 100644 --- a/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/chip.cpp +++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/benchapps/chipTest/chip.cpp @@ -38,7 +38,7 @@ Chip::Chip(const QColor &color, int x, int y) setZValue((x + y) % 2); setFlags(ItemIsSelectable | ItemIsMovable); - setAcceptsHoverEvents(true); + setAcceptHoverEvents(true); } QRectF Chip::boundingRect() const From 1932754e901792b68690863612648b76077edf57 Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Tue, 23 Jul 2019 13:35:05 +0200 Subject: [PATCH 251/264] Clean up documentation of deprecated APIs from QApplication Build docs for deprecated APIs conditionally, based on deprecation version. Remove the docs of methods deprecated since 5.0.0, these methods are not compiled anymore. Change-Id: If9302eecc8b3fff4a27c2e4a66ac102add7d66c5 Reviewed-by: Leena Miettinen Reviewed-by: Volker Hilsheimer --- src/widgets/kernel/qapplication.cpp | 43 ++--------------------------- 1 file changed, 2 insertions(+), 41 deletions(-) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 97175f2134..94b14ecb4f 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -236,9 +236,6 @@ void QApplicationPrivate::createEventDispatcher() encapsulated in a QStyle object. This can be changed at runtime with setStyle(). - \li It specifies how the application is to allocate colors. See - setColorSpec() for details. - \li It provides localization of strings that are visible to the user via translate(). @@ -298,11 +295,6 @@ void QApplicationPrivate::createEventDispatcher() \li style(), setStyle(). - \row - \li Color usage - \li colorSpec(), - setColorSpec(). - \row \li Text handling \li installTranslator(), @@ -337,6 +329,7 @@ void QApplicationPrivate::createEventDispatcher() \sa QCoreApplication, QAbstractEventDispatcher, QEventLoop, QSettings */ +#if QT_DEPRECATED_SINCE(5, 8) // ### fixme: Qt 6: Remove ColorSpec and accessors. /*! \enum QApplication::ColorSpec @@ -350,15 +343,7 @@ void QApplicationPrivate::createEventDispatcher() See setColorSpec() for full details. */ - -/*! - \fn QApplication::setGraphicsSystem(const QString &) - \obsolete - - This call has no effect. - - Use the QPA framework instead. -*/ +#endif /*! \fn QWidget *QApplication::topLevelAt(const QPoint &point) @@ -1956,13 +1941,6 @@ bool QApplication::event(QEvent *e) return QGuiApplication::event(e); } -/*! - \fn void QApplication::syncX() - Was used to synchronize with the X server in 4.x, here for source compatibility. - \internal - \obsolete -*/ - // ### FIXME: topLevelWindows does not contain QWidgets without a parent // until QWidgetPrivate::create is called. So we have to override the // QGuiApplication::notifyLayoutDirectionChange @@ -3989,15 +3967,6 @@ int QApplication::doubleClickInterval() return QGuiApplication::styleHints()->mouseDoubleClickInterval(); } -/*! - \fn QApplication::keyboardInputDirection() - \since 4.2 - \deprecated - - Returns the current keyboard input direction. Replaced with QInputMethod::inputDirection() - \sa QInputMethod::inputDirection() -*/ - /*! \property QApplication::keyboardInputInterval \brief the time limit in milliseconds that distinguishes a key press @@ -4135,14 +4104,6 @@ void QApplication::beep() \sa QCoreApplication::instance(), qGuiApp */ -/*! - \fn QLocale QApplication::keyboardInputLocale() - \since 4.2 - \obsolete - - Returns the current keyboard input locale. Replaced with QInputMethod::locale() -*/ - bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event) { return QGuiApplication::sendSpontaneousEvent(receiver, event); From 97d651711480be05a060b37baa6c86bf75c3df30 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 30 Jul 2019 13:16:26 +0200 Subject: [PATCH 252/264] Fix Makefile re-generation for debug_and_release builds Re-generation of the Makefile depends on a correctly set up QMAKE_INTERNAL_INCLUDED_FILES variable. In debug_and_release builds this variable is set up for Makefile.Debug and Makefile.Release, but not for the meta Makefile. However, that's where the Makefile re-generation target is located. We now collect the contents of QMAKE_INTERNAL_INCLUDED_FILES for Makefile.Debug/Release and use that for the meta Makefile. Fixes: QTBUG-13334 Change-Id: I6124a91447d5c54d51680e23570c4e97f44e6a73 Reviewed-by: Oliver Wolff Reviewed-by: Edward Welbourne --- qmake/generators/metamakefile.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp index 0fa3e29ad3..705ad7008a 100644 --- a/qmake/generators/metamakefile.cpp +++ b/qmake/generators/metamakefile.cpp @@ -57,6 +57,7 @@ private: QList makefiles; void clearBuilds(); MakefileGenerator *processBuild(const ProString &); + void accumulateVariableFromBuilds(const ProKey &name, Build *build) const; public: @@ -185,6 +186,7 @@ BuildsMetaMakefileGenerator::write() if(!build->makefile) { ret = false; } else if(build == glue) { + accumulateVariableFromBuilds("QMAKE_INTERNAL_INCLUDED_FILES", build); ret = build->makefile->writeProjectMakefile(); } else { ret = build->makefile->write(); @@ -227,6 +229,16 @@ MakefileGenerator return nullptr; } +void BuildsMetaMakefileGenerator::accumulateVariableFromBuilds(const ProKey &name, Build *dst) const +{ + ProStringList &values = dst->makefile->projectFile()->values(name); + for (auto build : makefiles) { + if (build != dst) + values += build->makefile->projectFile()->values(name); + } + values.removeDuplicates(); +} + class SubdirsMetaMakefileGenerator : public MetaMakefileGenerator { protected: From 76c097c4d7eb873052de031fbc2d21579aa3947a Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 12 Jul 2019 18:18:21 +0200 Subject: [PATCH 253/264] Improve our color space terminology Replace our use of 'gamut' with 'primaries'. One is the axes of the color space, the other the volume of representable values. For the currently supported color spaces those are mostly equivalent, but when we later add support for scRgb, this would be misleading as it has the same primaries as sRGB but a much wider gamut, and we would like to use the same primaries/"gamut" id for it. Also few people would know what "the sRGB gamut" is, but "the sRGB primaries" is easily googable. Change-Id: I3348ccaae27a071ec77a4356331b9bbbf92e0d19 Reviewed-by: Allan Sandfeld Jensen --- src/gui/image/qpnghandler.cpp | 2 +- src/gui/painting/qcolorspace.cpp | 116 +++++++++--------- src/gui/painting/qcolorspace.h | 10 +- src/gui/painting/qcolorspace_p.h | 6 +- src/gui/painting/qicc.cpp | 24 ++-- .../painting/qcolorspace/tst_qcolorspace.cpp | 46 +++---- 6 files changed, 104 insertions(+), 100 deletions(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 8cfcbdb2d2..3bf4e9db15 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -648,7 +648,7 @@ bool QPngHandlerPrivate::readPngHeader() colorSpace = QColorSpace(primaries.whitePoint, primaries.redPoint, primaries.greenPoint, primaries.bluePoint, QColorSpace::TransferFunction::Gamma, fileGamma); } else { - colorSpace = QColorSpace(QColorSpace::Gamut::SRgb, + colorSpace = QColorSpace(QColorSpace::Primaries::SRgb, QColorSpace::TransferFunction::Gamma, fileGamma); } colorSpaceState = GammaChrm; diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp index 926f2f687a..a14d630814 100644 --- a/src/gui/painting/qcolorspace.cpp +++ b/src/gui/painting/qcolorspace.cpp @@ -55,34 +55,34 @@ QT_BEGIN_NAMESPACE QBasicMutex QColorSpacePrivate::s_lutWriteLock; -QColorSpacePrimaries::QColorSpacePrimaries(QColorSpace::Gamut gamut) +QColorSpacePrimaries::QColorSpacePrimaries(QColorSpace::Primaries primaries) { - switch (gamut) { - case QColorSpace::Gamut::SRgb: + switch (primaries) { + case QColorSpace::Primaries::SRgb: redPoint = QPointF(0.640, 0.330); greenPoint = QPointF(0.300, 0.600); bluePoint = QPointF(0.150, 0.060); whitePoint = QColorVector::D65Chromaticity(); break; - case QColorSpace::Gamut::DciP3D65: + case QColorSpace::Primaries::DciP3D65: redPoint = QPointF(0.680, 0.320); greenPoint = QPointF(0.265, 0.690); bluePoint = QPointF(0.150, 0.060); whitePoint = QColorVector::D65Chromaticity(); break; - case QColorSpace::Gamut::Bt2020: + case QColorSpace::Primaries::Bt2020: redPoint = QPointF(0.708, 0.292); greenPoint = QPointF(0.190, 0.797); bluePoint = QPointF(0.131, 0.046); whitePoint = QColorVector::D65Chromaticity(); break; - case QColorSpace::Gamut::AdobeRgb: + case QColorSpace::Primaries::AdobeRgb: redPoint = QPointF(0.640, 0.330); greenPoint = QPointF(0.210, 0.710); bluePoint = QPointF(0.150, 0.060); whitePoint = QColorVector::D65Chromaticity(); break; - case QColorSpace::Gamut::ProPhotoRgb: + case QColorSpace::Primaries::ProPhotoRgb: redPoint = QPointF(0.7347, 0.2653); greenPoint = QPointF(0.1596, 0.8404); bluePoint = QPointF(0.0366, 0.0001); @@ -153,7 +153,7 @@ QColorMatrix QColorSpacePrimaries::toXyzMatrix() const QColorSpacePrivate::QColorSpacePrivate() : id(QColorSpace::Unknown) - , gamut(QColorSpace::Gamut::Custom) + , primaries(QColorSpace::Primaries::Custom) , transferFunction(QColorSpace::TransferFunction::Custom) , gamma(0.0f) , whitePoint(QColorVector::null()) @@ -166,43 +166,43 @@ QColorSpacePrivate::QColorSpacePrivate(QColorSpace::ColorSpaceId colorSpaceId) { switch (colorSpaceId) { case QColorSpace::Undefined: - gamut = QColorSpace::Gamut::Custom; + primaries = QColorSpace::Primaries::Custom; transferFunction = QColorSpace::TransferFunction::Custom; gamma = 0.0f; description = QStringLiteral("Undefined"); break; case QColorSpace::SRgb: - gamut = QColorSpace::Gamut::SRgb; + primaries = QColorSpace::Primaries::SRgb; transferFunction = QColorSpace::TransferFunction::SRgb; gamma = 2.31f; // ? description = QStringLiteral("sRGB"); break; case QColorSpace::SRgbLinear: - gamut = QColorSpace::Gamut::SRgb; + primaries = QColorSpace::Primaries::SRgb; transferFunction = QColorSpace::TransferFunction::Linear; gamma = 1.0f; description = QStringLiteral("Linear sRGB"); break; case QColorSpace::AdobeRgb: - gamut = QColorSpace::Gamut::AdobeRgb; + primaries = QColorSpace::Primaries::AdobeRgb; transferFunction = QColorSpace::TransferFunction::Gamma; gamma = 2.19921875f; // Not quite 2.2, see https://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf description = QStringLiteral("Adobe RGB"); break; case QColorSpace::DisplayP3: - gamut = QColorSpace::Gamut::DciP3D65; + primaries = QColorSpace::Primaries::DciP3D65; transferFunction = QColorSpace::TransferFunction::SRgb; gamma = 2.31f; // ? description = QStringLiteral("Display P3"); break; case QColorSpace::ProPhotoRgb: - gamut = QColorSpace::Gamut::ProPhotoRgb; + primaries = QColorSpace::Primaries::ProPhotoRgb; transferFunction = QColorSpace::TransferFunction::ProPhotoRgb; gamma = 1.8f; description = QStringLiteral("ProPhoto RGB"); break; case QColorSpace::Bt2020: - gamut = QColorSpace::Gamut::Bt2020; + primaries = QColorSpace::Primaries::Bt2020; transferFunction = QColorSpace::TransferFunction::Bt2020; gamma = 2.1f; // ? description = QStringLiteral("BT.2020"); @@ -216,8 +216,8 @@ QColorSpacePrivate::QColorSpacePrivate(QColorSpace::ColorSpaceId colorSpaceId) initialize(); } -QColorSpacePrivate::QColorSpacePrivate(QColorSpace::Gamut gamut, QColorSpace::TransferFunction fun, float gamma) - : gamut(gamut) +QColorSpacePrivate::QColorSpacePrivate(QColorSpace::Primaries primaries, QColorSpace::TransferFunction fun, float gamma) + : primaries(primaries) , transferFunction(fun) , gamma(gamma) { @@ -229,7 +229,7 @@ QColorSpacePrivate::QColorSpacePrivate(QColorSpace::Gamut gamut, QColorSpace::Tr QColorSpacePrivate::QColorSpacePrivate(const QColorSpacePrimaries &primaries, QColorSpace::TransferFunction fun, float gamma) - : gamut(QColorSpace::Gamut::Custom) + : primaries(QColorSpace::Primaries::Custom) , transferFunction(fun) , gamma(gamma) { @@ -243,8 +243,8 @@ QColorSpacePrivate::QColorSpacePrivate(const QColorSpacePrimaries &primaries, bool QColorSpacePrivate::identifyColorSpace() { - switch (gamut) { - case QColorSpace::Gamut::SRgb: + switch (primaries) { + case QColorSpace::Primaries::SRgb: if (transferFunction == QColorSpace::TransferFunction::SRgb) { id = QColorSpace::SRgb; if (description.isEmpty()) @@ -258,7 +258,7 @@ bool QColorSpacePrivate::identifyColorSpace() return true; } break; - case QColorSpace::Gamut::AdobeRgb: + case QColorSpace::Primaries::AdobeRgb: if (transferFunction == QColorSpace::TransferFunction::Gamma) { if (qAbs(gamma - 2.19921875f) < (1/1024.0f)) { id = QColorSpace::AdobeRgb; @@ -268,7 +268,7 @@ bool QColorSpacePrivate::identifyColorSpace() } } break; - case QColorSpace::Gamut::DciP3D65: + case QColorSpace::Primaries::DciP3D65: if (transferFunction == QColorSpace::TransferFunction::SRgb) { id = QColorSpace::DisplayP3; if (description.isEmpty()) @@ -276,7 +276,7 @@ bool QColorSpacePrivate::identifyColorSpace() return true; } break; - case QColorSpace::Gamut::ProPhotoRgb: + case QColorSpace::Primaries::ProPhotoRgb: if (transferFunction == QColorSpace::TransferFunction::ProPhotoRgb) { id = QColorSpace::ProPhotoRgb; if (description.isEmpty()) @@ -293,7 +293,7 @@ bool QColorSpacePrivate::identifyColorSpace() } } break; - case QColorSpace::Gamut::Bt2020: + case QColorSpace::Primaries::Bt2020: if (transferFunction == QColorSpace::TransferFunction::Bt2020) { id = QColorSpace::Bt2020; if (description.isEmpty()) @@ -315,14 +315,14 @@ void QColorSpacePrivate::initialize() void QColorSpacePrivate::setToXyzMatrix() { - if (gamut == QColorSpace::Gamut::Custom) { + if (primaries == QColorSpace::Primaries::Custom) { toXyz = QColorMatrix::null(); whitePoint = QColorVector::D50(); return; } - QColorSpacePrimaries primaries(gamut); - toXyz = primaries.toXyzMatrix(); - whitePoint = QColorVector(primaries.whitePoint); + QColorSpacePrimaries colorSpacePrimaries(primaries); + toXyz = colorSpacePrimaries.toXyzMatrix(); + whitePoint = QColorVector(colorSpacePrimaries.whitePoint); } void QColorSpacePrivate::setTransferFunction() @@ -390,12 +390,14 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace QColorSpace can also represent color spaces defined by ICC profiles or embedded in images, that do not otherwise fit the predefined color spaces. - A color space can generally speaking be conceived as a combination of a transfer - function and a gamut. The gamut defines which colors the color space can represent. - A color space that can represent a wider range of colors is also known as a - wide-gamut color space. The gamut is defined by three primary colors that represent - exactly how red, green, and blue look in this particular color space, and a white - color that represents where and how bright pure white is. + A color space can generally speaking be conceived as a combination of set of primary + colors and a transfer function. The primaries defines the axes of the color space, and + the transfer function how values are mapped on the axes. + The primaries are defined by three primary colors that represent exactly how red, green, + and blue look in this particular color space, and a white color that represents where + and how bright pure white is. The range of colors expressable by the primary colors is + called the gamut, and a color space that can represent a wider range of colors is also + known as a wide-gamut color space. The transfer function or gamma curve determines how each component in the color space is encoded. These are used because human perception does not operate @@ -427,16 +429,16 @@ QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpace */ /*! - \enum QColorSpace::Gamut + \enum QColorSpace::Primaries - Predefined gamuts, or sets of primary colors. + Predefined sets of primary colors. - \value Custom The gamut is undefined or does not match any predefined sets. - \value SRgb The sRGB gamut - \value AdobeRgb The Adobe RGB gamut - \value DciP3D65 The DCI-P3 gamut with the D65 whitepoint - \value ProPhotoRgb The ProPhoto RGB gamut with the D50 whitepoint - \value Bt2020 The BT.2020 gamut + \value Custom The primaries are undefined or does not match any predefined sets. + \value SRgb The sRGB primaries + \value AdobeRgb The Adobe RGB primaries + \value DciP3D65 The DCI-P3 primaries with the D65 whitepoint + \value ProPhotoRgb The ProPhoto RGB primaries with the D50 whitepoint + \value Bt2020 The BT.2020 primaries */ /*! @@ -472,25 +474,25 @@ QColorSpace::QColorSpace(QColorSpace::ColorSpaceId colorSpaceId) } /*! - Creates a custom color space with the gamut \a gamut, using the transfer function \a fun and + Creates a custom color space with the primaries \a primaries, using the transfer function \a fun and optionally \a gamma. */ -QColorSpace::QColorSpace(QColorSpace::Gamut gamut, QColorSpace::TransferFunction fun, float gamma) - : d_ptr(new QColorSpacePrivate(gamut, fun, gamma)) +QColorSpace::QColorSpace(QColorSpace::Primaries primaries, QColorSpace::TransferFunction fun, float gamma) + : d_ptr(new QColorSpacePrivate(primaries, fun, gamma)) { } /*! - Creates a custom color space with the gamut \a gamut, using a gamma transfer function of + Creates a custom color space with the primaries \a primaries, using a gamma transfer function of \a gamma. */ -QColorSpace::QColorSpace(QColorSpace::Gamut gamut, float gamma) - : d_ptr(new QColorSpacePrivate(gamut, TransferFunction::Gamma, gamma)) +QColorSpace::QColorSpace(QColorSpace::Primaries primaries, float gamma) + : d_ptr(new QColorSpacePrivate(primaries, TransferFunction::Gamma, gamma)) { } /*! - Creates a custom colorspace with a gamut based on the chromaticities of the primary colors \a whitePoint, + Creates a custom colorspace with a primaries based on the chromaticities of the primary colors \a whitePoint, \a redPoint, \a greenPoint and \a bluePoint, and using the transfer function \a fun and optionally \a gamma. */ QColorSpace::QColorSpace(const QPointF &whitePoint, const QPointF &redPoint, @@ -548,12 +550,14 @@ QColorSpace::ColorSpaceId QColorSpace::colorSpaceId() const noexcept } /*! - Returns the predefined gamut of the color space - or \c Gamut::Custom if it doesn't match any of them. + Returns the predefined primaries of the color space + or \c primaries::Custom if it doesn't match any of them. */ -QColorSpace::Gamut QColorSpace::gamut() const noexcept +QColorSpace::Primaries QColorSpace::primaries() const noexcept { - return d_ptr->gamut; + if (Q_UNLIKELY(!d_ptr)) + return QColorSpace::Primaries::Custom; + return d_ptr->primaries; } /*! @@ -646,8 +650,8 @@ bool operator==(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2) if (colorSpace1.colorSpaceId() != QColorSpace::Unknown && colorSpace2.colorSpaceId() != QColorSpace::Unknown) return colorSpace1.colorSpaceId() == colorSpace2.colorSpaceId(); - if (colorSpace1.gamut() != QColorSpace::Gamut::Custom && colorSpace2.gamut() != QColorSpace::Gamut::Custom) { - if (colorSpace1.gamut() != colorSpace2.gamut()) + if (colorSpace1.primaries() != QColorSpace::Primaries::Custom && colorSpace2.primaries() != QColorSpace::Primaries::Custom) { + if (colorSpace1.primaries() != colorSpace2.primaries()) return false; } else { if (colorSpace1.d_ptr->toXyz != colorSpace2.d_ptr->toXyz) @@ -735,7 +739,7 @@ QDebug operator<<(QDebug dbg, const QColorSpace &colorSpace) QDebugStateSaver saver(dbg); dbg.nospace(); dbg << "QColorSpace("; - dbg << colorSpace.colorSpaceId() << ", " << colorSpace.gamut() << ", " << colorSpace.transferFunction(); + dbg << colorSpace.colorSpaceId() << ", " << colorSpace.primaries() << ", " << colorSpace.transferFunction(); dbg << ", gamma=" << colorSpace.gamma(); dbg << ')'; return dbg; diff --git a/src/gui/painting/qcolorspace.h b/src/gui/painting/qcolorspace.h index 709ce38916..a9871fc277 100644 --- a/src/gui/painting/qcolorspace.h +++ b/src/gui/painting/qcolorspace.h @@ -63,7 +63,7 @@ public: Bt2020, }; Q_ENUM(ColorSpaceId) - enum class Gamut { + enum class Primaries { Custom = 0, SRgb, AdobeRgb, @@ -71,7 +71,7 @@ public: ProPhotoRgb, Bt2020, }; - Q_ENUM(Gamut) + Q_ENUM(Primaries) enum class TransferFunction { Custom = 0, Linear, @@ -83,8 +83,8 @@ public: Q_ENUM(TransferFunction) QColorSpace(ColorSpaceId colorSpaceId = Undefined); - QColorSpace(Gamut gamut, TransferFunction fun, float gamma = 0.0f); - QColorSpace(Gamut gamut, float gamma); + QColorSpace(Primaries primaries, TransferFunction fun, float gamma = 0.0f); + QColorSpace(Primaries primaries, float gamma); QColorSpace(const QPointF &whitePoint, const QPointF &redPoint, const QPointF &greenPoint, const QPointF &bluePoint, TransferFunction fun, float gamma = 0.0f); @@ -99,7 +99,7 @@ public: { qSwap(d_ptr, colorSpace.d_ptr); } ColorSpaceId colorSpaceId() const noexcept; - Gamut gamut() const noexcept; + Primaries primaries() const noexcept; TransferFunction transferFunction() const noexcept; float gamma() const noexcept; diff --git a/src/gui/painting/qcolorspace_p.h b/src/gui/painting/qcolorspace_p.h index 75b74f062f..2a40a0cfd8 100644 --- a/src/gui/painting/qcolorspace_p.h +++ b/src/gui/painting/qcolorspace_p.h @@ -66,7 +66,7 @@ class Q_GUI_EXPORT QColorSpacePrimaries { public: QColorSpacePrimaries() = default; - QColorSpacePrimaries(QColorSpace::Gamut gamut); + QColorSpacePrimaries(QColorSpace::Primaries primaries); QColorSpacePrimaries(QPointF whitePoint, QPointF redPoint, QPointF greenPoint, @@ -91,7 +91,7 @@ class QColorSpacePrivate : public QSharedData public: QColorSpacePrivate(); QColorSpacePrivate(QColorSpace::ColorSpaceId colorSpaceId); - QColorSpacePrivate(QColorSpace::Gamut gamut, QColorSpace::TransferFunction fun, float gamma); + QColorSpacePrivate(QColorSpace::Primaries primaries, QColorSpace::TransferFunction fun, float gamma); QColorSpacePrivate(const QColorSpacePrimaries &primaries, QColorSpace::TransferFunction fun, float gamma); QColorSpacePrivate(const QColorSpacePrivate &other) = default; @@ -113,7 +113,7 @@ public: QColorTransform transformationToColorSpace(const QColorSpacePrivate *out) const; QColorSpace::ColorSpaceId id; - QColorSpace::Gamut gamut; + QColorSpace::Primaries primaries; QColorSpace::TransferFunction transferFunction; float gamma; QColorVector whitePoint; diff --git a/src/gui/painting/qicc.cpp b/src/gui/painting/qicc.cpp index 1941981d30..6cb7b57493 100644 --- a/src/gui/painting/qicc.cpp +++ b/src/gui/painting/qicc.cpp @@ -677,26 +677,26 @@ bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace) if (!parseXyzData(data, tagIndex[Tag::wtpt], colorspaceDPtr->whitePoint)) return false; - colorspaceDPtr->gamut = QColorSpace::Gamut::Custom; + colorspaceDPtr->primaries = QColorSpace::Primaries::Custom; if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromSRgb()) { - qCDebug(lcIcc) << "fromIccProfile: sRGB gamut detected"; - colorspaceDPtr->gamut = QColorSpace::Gamut::SRgb; + qCDebug(lcIcc) << "fromIccProfile: sRGB primaries detected"; + colorspaceDPtr->primaries = QColorSpace::Primaries::SRgb; } else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromAdobeRgb()) { - qCDebug(lcIcc) << "fromIccProfile: Adobe RGB gamut detected"; - colorspaceDPtr->gamut = QColorSpace::Gamut::AdobeRgb; + qCDebug(lcIcc) << "fromIccProfile: Adobe RGB primaries detected"; + colorspaceDPtr->primaries = QColorSpace::Primaries::AdobeRgb; } else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromDciP3D65()) { - qCDebug(lcIcc) << "fromIccProfile: DCI-P3 D65 gamut detected"; - colorspaceDPtr->gamut = QColorSpace::Gamut::DciP3D65; + qCDebug(lcIcc) << "fromIccProfile: DCI-P3 D65 primaries detected"; + colorspaceDPtr->primaries = QColorSpace::Primaries::DciP3D65; } else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromBt2020()) { - qCDebug(lcIcc) << "fromIccProfile: BT.2020 gamut detected"; - colorspaceDPtr->gamut = QColorSpace::Gamut::Bt2020; + qCDebug(lcIcc) << "fromIccProfile: BT.2020 primaries detected"; + colorspaceDPtr->primaries = QColorSpace::Primaries::Bt2020; } if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromProPhotoRgb()) { - qCDebug(lcIcc) << "fromIccProfile: ProPhoto RGB gamut detected"; - colorspaceDPtr->gamut = QColorSpace::Gamut::ProPhotoRgb; + qCDebug(lcIcc) << "fromIccProfile: ProPhoto RGB primaries detected"; + colorspaceDPtr->primaries = QColorSpace::Primaries::ProPhotoRgb; } // Reset the matrix to our canonical values: - if (colorspaceDPtr->gamut != QColorSpace::Gamut::Custom) + if (colorspaceDPtr->primaries != QColorSpace::Primaries::Custom) colorspaceDPtr->setToXyzMatrix(); // Parse TRC tags diff --git a/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp b/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp index 291a25fede..c0f3559f57 100644 --- a/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp +++ b/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp @@ -36,7 +36,7 @@ #include Q_DECLARE_METATYPE(QColorSpace::ColorSpaceId) -Q_DECLARE_METATYPE(QColorSpace::Gamut) +Q_DECLARE_METATYPE(QColorSpace::Primaries) Q_DECLARE_METATYPE(QColorSpace::TransferFunction) class tst_QColorSpace : public QObject @@ -61,7 +61,7 @@ private slots: void loadImage(); - void gamut(); + void primaries(); void primariesXyz(); void primaries2_data(); void primaries2(); @@ -75,33 +75,33 @@ tst_QColorSpace::tst_QColorSpace() void tst_QColorSpace::namedColorSpaces_data() { QTest::addColumn("colorSpaceId"); - QTest::addColumn("gamutId"); + QTest::addColumn("primariesId"); QTest::addColumn("transferFunctionId"); QTest::newRow("sRGB") << QColorSpace::SRgb - << QColorSpace::Gamut::SRgb + << QColorSpace::Primaries::SRgb << QColorSpace::TransferFunction::SRgb; QTest::newRow("sRGB Linear") << QColorSpace::SRgbLinear - << QColorSpace::Gamut::SRgb + << QColorSpace::Primaries::SRgb << QColorSpace::TransferFunction::Linear; QTest::newRow("Adobe RGB") << QColorSpace::AdobeRgb - << QColorSpace::Gamut::AdobeRgb + << QColorSpace::Primaries::AdobeRgb << QColorSpace::TransferFunction::Gamma; QTest::newRow("Display-P3") << QColorSpace::DisplayP3 - << QColorSpace::Gamut::DciP3D65 + << QColorSpace::Primaries::DciP3D65 << QColorSpace::TransferFunction::SRgb; QTest::newRow("ProPhoto RGB") << QColorSpace::ProPhotoRgb - << QColorSpace::Gamut::ProPhotoRgb + << QColorSpace::Primaries::ProPhotoRgb << QColorSpace::TransferFunction::ProPhotoRgb; QTest::newRow("BT.2020") << QColorSpace::Bt2020 - << QColorSpace::Gamut::Bt2020 + << QColorSpace::Primaries::Bt2020 << QColorSpace::TransferFunction::Bt2020; } void tst_QColorSpace::namedColorSpaces() { QFETCH(QColorSpace::ColorSpaceId, colorSpaceId); - QFETCH(QColorSpace::Gamut, gamutId); + QFETCH(QColorSpace::Primaries, primariesId); QFETCH(QColorSpace::TransferFunction, transferFunctionId); QColorSpace colorSpace = colorSpaceId; @@ -109,7 +109,7 @@ void tst_QColorSpace::namedColorSpaces() QVERIFY(colorSpace.isValid()); QCOMPARE(colorSpace.colorSpaceId(), colorSpaceId); - QCOMPARE(colorSpace.gamut(), gamutId); + QCOMPARE(colorSpace.primaries(), primariesId); QCOMPARE(colorSpace.transferFunction(), transferFunctionId); } @@ -122,10 +122,10 @@ void tst_QColorSpace::toIccProfile_data() void tst_QColorSpace::toIccProfile() { QFETCH(QColorSpace::ColorSpaceId, colorSpaceId); - QFETCH(QColorSpace::Gamut, gamutId); + QFETCH(QColorSpace::Primaries, primariesId); QFETCH(QColorSpace::TransferFunction, transferFunctionId); - Q_UNUSED(gamutId); + Q_UNUSED(primariesId); Q_UNUSED(transferFunctionId); QColorSpace colorSpace = colorSpaceId; @@ -280,7 +280,7 @@ void tst_QColorSpace::loadImage() QVERIFY(maxBlue2 > maxBlue); } -void tst_QColorSpace::gamut() +void tst_QColorSpace::primaries() { QColor black = QColor::fromRgbF(0.0, 0.0, 0.0); QColor white = QColor::fromRgbF(1.0, 1.0, 1.0); @@ -331,21 +331,21 @@ void tst_QColorSpace::primariesXyz() void tst_QColorSpace::primaries2_data() { - QTest::addColumn("gamut"); + QTest::addColumn("primariesId"); - QTest::newRow("sRGB") << QColorSpace::Gamut::SRgb; - QTest::newRow("DCI-P3 (D65)") << QColorSpace::Gamut::DciP3D65; - QTest::newRow("Adobe RGB (1998)") << QColorSpace::Gamut::AdobeRgb; - QTest::newRow("ProPhoto RGB") << QColorSpace::Gamut::ProPhotoRgb; - QTest::newRow("BT.2020") << QColorSpace::Gamut::Bt2020; + QTest::newRow("sRGB") << QColorSpace::Primaries::SRgb; + QTest::newRow("DCI-P3 (D65)") << QColorSpace::Primaries::DciP3D65; + QTest::newRow("Adobe RGB (1998)") << QColorSpace::Primaries::AdobeRgb; + QTest::newRow("ProPhoto RGB") << QColorSpace::Primaries::ProPhotoRgb; + QTest::newRow("BT.2020") << QColorSpace::Primaries::Bt2020; } void tst_QColorSpace::primaries2() { - QFETCH(QColorSpace::Gamut, gamut); - QColorSpacePrimaries primaries(gamut); + QFETCH(QColorSpace::Primaries, primariesId); + QColorSpacePrimaries primaries(primariesId); - QColorSpace original(gamut, QColorSpace::TransferFunction::Linear); + QColorSpace original(primariesId, QColorSpace::TransferFunction::Linear); QColorSpace custom1(primaries.whitePoint, primaries.redPoint, primaries.greenPoint, primaries.bluePoint, QColorSpace::TransferFunction::Linear); QCOMPARE(original, custom1); From b4b2a066c0a25cc6d7402901d13d8b80c336ccc8 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 31 Jul 2019 12:04:17 +0200 Subject: [PATCH 254/264] rhi: Move info prints to categorized logging Following the Quick scenegraph (qt.scenegraph.*), we now have qt.rhi.general. Other categories may get added later. This does not change the printing of real errors, those will continue to use qWarning(). Change-Id: Id95416fc82ba8add9527212e431bcbd47d416f1a Reviewed-by: Andy Nichols --- src/gui/rhi/qrhi.cpp | 32 +++++++++++++++++++++++++++++++- src/gui/rhi/qrhi_p_p.h | 3 +++ src/gui/rhi/qrhid3d11.cpp | 4 ++-- src/gui/rhi/qrhigles2.cpp | 4 ++-- src/gui/rhi/qrhimetal.mm | 4 ++-- src/gui/rhi/qrhivulkan.cpp | 25 +++++++++++++------------ 6 files changed, 53 insertions(+), 19 deletions(-) diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index 3576b30349..7770cac870 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -36,6 +36,7 @@ #include "qrhi_p_p.h" #include +#include #include "qrhinull_p_p.h" #ifndef QT_NO_OPENGL @@ -54,6 +55,8 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general") + /*! \class QRhi \inmodule QtRhi @@ -389,6 +392,22 @@ QT_BEGIN_NAMESPACE texture object is "exported" via QRhi::nativeHandles() or QRhiTexture::nativeHandles(). Most importantly, passing pointers in structs and via setters does not transfer ownership. + + \section2 Troubleshooting + + Errors are printed to the output via qWarning(). Additional debug messages + can be enabled via the following logging categories. Messages from these + categories are not printed by default unless explicitly enabled via + QRhi::EnableProfiling or the facilities of QLoggingCategory (such as, the + \c QT_LOGGING_RULES environment variable). + + \list + \li \c{qt.rhi.general} + \endlist + + It is strongly advised to inspect the output with the logging categories + (\c{qt.rhi.*}) enabled whenever a QRhi-based application is not behaving as + expected. */ /*! @@ -409,7 +428,8 @@ QT_BEGIN_NAMESPACE \value EnableProfiling Enables gathering timing (CPU, GPU) and resource (QRhiBuffer, QRhiTexture, etc.) information and additional metadata. See QRhiProfiler. Avoid enabling in production builds as it may involve a - performance penalty. + performance penalty. Also enables debug messages from the \c{qt.rhi.*} + logging categories. \value EnableDebugMarkers Enables debug marker groups. Without this frame debugging features like making debug groups and custom resource name @@ -3873,11 +3893,21 @@ QRhi *QRhi::create(Implementation impl, QRhiInitParams *params, Flags flags, QRh if (r->d) { r->d->q = r.data(); + if (flags.testFlag(EnableProfiling)) { QRhiProfilerPrivate *profD = QRhiProfilerPrivate::get(&r->d->profiler); profD->rhiDWhenEnabled = r->d; + const_cast(QRHI_LOG_INFO()).setEnabled(QtDebugMsg, true); } + + // Play nice with QSG_INFO since that is still the most commonly used + // way to get graphics info printed from Qt Quick apps, and the Quick + // scenegraph is our primary user. + if (qEnvironmentVariableIsSet("QSG_INFO")) + const_cast(QRHI_LOG_INFO()).setEnabled(QtDebugMsg, true); + r->d->debugMarkers = flags.testFlag(EnableDebugMarkers); + if (r->d->create(flags)) { r->d->implType = impl; r->d->implThread = QThread::currentThread(); diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h index d87c4372ca..b592fe82f2 100644 --- a/src/gui/rhi/qrhi_p_p.h +++ b/src/gui/rhi/qrhi_p_p.h @@ -52,6 +52,7 @@ #include "qrhiprofiler_p_p.h" #include #include +#include QT_BEGIN_NAMESPACE @@ -60,6 +61,8 @@ QT_BEGIN_NAMESPACE #define QRHI_PROF QRhiProfilerPrivate *rhiP = m_rhi->profilerPrivateOrNull() #define QRHI_PROF_F(f) for (bool qrhip_enabled = rhiP != nullptr; qrhip_enabled; qrhip_enabled = false) rhiP->f +Q_DECLARE_LOGGING_CATEGORY(QRHI_LOG_INFO) + class QRhiImplementation { public: diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index a8a490eb5c..0c5df600a0 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -189,10 +189,10 @@ bool QRhiD3D11::create(QRhi::Flags flags) DXGI_ADAPTER_DESC1 desc; adapter->GetDesc1(&desc); const QString name = QString::fromUtf16((char16_t *) desc.Description); - qDebug("Adapter %d: '%s' (flags 0x%x)", adapterIndex, qPrintable(name), desc.Flags); + qCDebug(QRHI_LOG_INFO, "Adapter %d: '%s' (flags 0x%x)", adapterIndex, qPrintable(name), desc.Flags); if (!adapterToUse && (requestedAdapterIndex < 0 || requestedAdapterIndex == adapterIndex)) { adapterToUse = adapter; - qDebug(" using this adapter"); + qCDebug(QRHI_LOG_INFO, " using this adapter"); } else { adapter->Release(); } diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 3ef4bb3a07..929f3fe21d 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -385,7 +385,7 @@ bool QRhiGles2::create(QRhi::Flags flags) ctx = nullptr; return false; } - qDebug() << "Created OpenGL context" << ctx->format(); + qCDebug(QRHI_LOG_INFO) << "Created OpenGL context" << ctx->format(); } if (!ensureContext(maybeWindow ? maybeWindow : fallbackSurface)) // see 'window' discussion in QRhiGles2InitParams comments @@ -397,7 +397,7 @@ bool QRhiGles2::create(QRhi::Flags flags) const char *renderer = reinterpret_cast(f->glGetString(GL_RENDERER)); const char *version = reinterpret_cast(f->glGetString(GL_VERSION)); if (vendor && renderer && version) - qDebug("OpenGL VENDOR: %s RENDERER: %s VERSION: %s", vendor, renderer, version); + qCDebug(QRHI_LOG_INFO, "OpenGL VENDOR: %s RENDERER: %s VERSION: %s", vendor, renderer, version); const QSurfaceFormat actualFormat = ctx->format(); diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 98b2a9bcac..ffb2283ae7 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -353,7 +353,7 @@ bool QRhiMetal::create(QRhi::Flags flags) else d->dev = MTLCreateSystemDefaultDevice(); - qDebug("Metal device: %s", qPrintable(QString::fromNSString([d->dev name]))); + qCDebug(QRHI_LOG_INFO, "Metal device: %s", qPrintable(QString::fromNSString([d->dev name]))); if (importedCmdQueue) [d->cmdQueue retain]; @@ -3538,7 +3538,7 @@ bool QMetalSwapChain::buildOrResize() rtWrapper.d->colorAttCount = 1; rtWrapper.d->dsAttCount = ds ? 1 : 0; - qDebug("got CAMetalLayer, size %dx%d", pixelSize.width(), pixelSize.height()); + qCDebug(QRHI_LOG_INFO, "got CAMetalLayer, size %dx%d", pixelSize.width(), pixelSize.height()); if (samples > 1) { MTLTextureDescriptor *desc = [[MTLTextureDescriptor alloc] init]; diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index f48a8a3cfe..61a1595a50 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -360,14 +360,14 @@ bool QRhiVulkan::create(QRhi::Flags flags) requestedPhysDevIndex = qEnvironmentVariableIntValue("QT_VK_PHYSICAL_DEVICE_INDEX"); for (uint32_t i = 0; i < physDevCount; ++i) { f->vkGetPhysicalDeviceProperties(physDevs[i], &physDevProperties); - qDebug("Physical device %d: '%s' %d.%d.%d", i, - physDevProperties.deviceName, - VK_VERSION_MAJOR(physDevProperties.driverVersion), - VK_VERSION_MINOR(physDevProperties.driverVersion), - VK_VERSION_PATCH(physDevProperties.driverVersion)); + qCDebug(QRHI_LOG_INFO, "Physical device %d: '%s' %d.%d.%d", i, + physDevProperties.deviceName, + VK_VERSION_MAJOR(physDevProperties.driverVersion), + VK_VERSION_MINOR(physDevProperties.driverVersion), + VK_VERSION_PATCH(physDevProperties.driverVersion)); if (physDevIndex < 0 && (requestedPhysDevIndex < 0 || requestedPhysDevIndex == int(i))) { physDevIndex = i; - qDebug(" using this physical device"); + qCDebug(QRHI_LOG_INFO, " using this physical device"); } } if (physDevIndex < 0) { @@ -386,7 +386,8 @@ bool QRhiVulkan::create(QRhi::Flags flags) gfxQueueFamilyIdx = -1; int computelessGfxQueueCandidateIdx = -1; for (int i = 0; i < queueFamilyProps.count(); ++i) { - qDebug("queue family %d: flags=0x%x count=%d", i, queueFamilyProps[i].queueFlags, queueFamilyProps[i].queueCount); + qCDebug(QRHI_LOG_INFO, "queue family %d: flags=0x%x count=%d", + i, queueFamilyProps[i].queueFlags, queueFamilyProps[i].queueCount); if (gfxQueueFamilyIdx == -1 && (queueFamilyProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) && (!maybeWindow || inst->supportsPresent(physDev, i, maybeWindow))) @@ -422,7 +423,7 @@ bool QRhiVulkan::create(QRhi::Flags flags) f->vkEnumerateDeviceExtensionProperties(physDev, nullptr, &devExtCount, nullptr); QVector devExts(devExtCount); f->vkEnumerateDeviceExtensionProperties(physDev, nullptr, &devExtCount, devExts.data()); - qDebug("%d device extensions available", devExts.count()); + qCDebug(QRHI_LOG_INFO, "%d device extensions available", devExts.count()); QVector requestedDevExts; requestedDevExts.append("VK_KHR_swapchain"); @@ -1244,9 +1245,9 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain) // with VK_ERROR_NATIVE_WINDOW_IN_USE_KHR if the old swapchain is provided) const bool reuseExisting = swapChainD->sc && swapChainD->lastConnectedSurface == swapChainD->surface; - qDebug("Creating %s swapchain of %u buffers, size %dx%d, presentation mode %d", - reuseExisting ? "recycled" : "new", - reqBufferCount, swapChainD->pixelSize.width(), swapChainD->pixelSize.height(), presentMode); + qCDebug(QRHI_LOG_INFO, "Creating %s swapchain of %u buffers, size %dx%d, presentation mode %d", + reuseExisting ? "recycled" : "new", + reqBufferCount, swapChainD->pixelSize.width(), swapChainD->pixelSize.height(), presentMode); VkSwapchainCreateInfoKHR swapChainInfo; memset(&swapChainInfo, 0, sizeof(swapChainInfo)); @@ -1290,7 +1291,7 @@ bool QRhiVulkan::recreateSwapChain(QRhiSwapChain *swapChain) return false; } if (actualSwapChainBufferCount != reqBufferCount) - qDebug("Actual swapchain buffer count is %u", actualSwapChainBufferCount); + qCDebug(QRHI_LOG_INFO, "Actual swapchain buffer count is %u", actualSwapChainBufferCount); swapChainD->bufferCount = actualSwapChainBufferCount; VkImage swapChainImages[QVkSwapChain::MAX_BUFFER_COUNT]; From 804ddcfb17e532deb164459c25e20fbe0b286598 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 31 Jul 2019 15:08:11 +0200 Subject: [PATCH 255/264] rhi: gl: Add support for bool members in uniform blocks Note that SPIRV-Cross does not translate 'bool' to GLSL versions that do not have uint. So in practice we will still need to use 'int' instead in shaders that also target old GL versions. Change-Id: I070f5414fe761796ab92937034b7182cdfb73a14 Reviewed-by: Andy Nichols --- src/gui/rhi/qrhigles2.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 929f3fe21d..a4ab1cf2ec 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -2337,6 +2337,18 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC case QShaderDescription::Uint4: f->glUniform4uiv(uniform.glslLocation, 1, reinterpret_cast(src)); break; + case QShaderDescription::Bool: // a glsl bool is 4 bytes, like (u)int + f->glUniform1i(uniform.glslLocation, *reinterpret_cast(src)); + break; + case QShaderDescription::Bool2: + f->glUniform2iv(uniform.glslLocation, 1, reinterpret_cast(src)); + break; + case QShaderDescription::Bool3: + f->glUniform3iv(uniform.glslLocation, 1, reinterpret_cast(src)); + break; + case QShaderDescription::Bool4: + f->glUniform4iv(uniform.glslLocation, 1, reinterpret_cast(src)); + break; // ### more types default: break; From 092074f9df073c9af075810602d61ac54a115d89 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 1 Aug 2019 14:50:54 +0200 Subject: [PATCH 256/264] rhi: Add a note about size to newBuffer() Also make sure the gl backend is consistent with the other three. Change-Id: I2f6b783f5fa474c94ede460f5d7ac6fe8129a4f6 Reviewed-by: Andy Nichols --- src/gui/rhi/qrhi.cpp | 5 +++++ src/gui/rhi/qrhigles2.cpp | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index 7770cac870..7443c0a04f 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -4947,6 +4947,11 @@ QRhiShaderResourceBindings *QRhi::newShaderResourceBindings() backends. See \l{QRhiBuffer::UsageFlag}{UsageFlags} and \l{QRhi::NonDynamicUniformBuffers}{the feature flags}. + \note Backends may choose to allocate buffers bigger than \a size. This is + done transparently to applications, so there are no special restrictions on + the value of \a size. QRhiBuffer::size() will always report back the value + that was requested in \a size. + \sa QRhiResource::release() */ QRhiBuffer *QRhi::newBuffer(QRhiBuffer::Type type, diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index a4ab1cf2ec..379801efbd 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -2847,13 +2847,15 @@ bool QGles2Buffer::build() QRHI_RES_RHI(QRhiGles2); QRHI_PROF; + const int nonZeroSize = m_size <= 0 ? 256 : m_size; + if (m_usage.testFlag(QRhiBuffer::UniformBuffer)) { if (int(m_usage) != QRhiBuffer::UniformBuffer) { qWarning("Uniform buffer: multiple usages specified, this is not supported by the OpenGL backend"); return false; } - ubuf.resize(m_size); - QRHI_PROF_F(newBuffer(this, m_size, 0, 1)); + ubuf.resize(nonZeroSize); + QRHI_PROF_F(newBuffer(this, nonZeroSize, 0, 1)); return true; } @@ -2868,11 +2870,11 @@ bool QGles2Buffer::build() rhiD->f->glGenBuffers(1, &buffer); rhiD->f->glBindBuffer(targetForDataOps, buffer); - rhiD->f->glBufferData(targetForDataOps, m_size, nullptr, m_type == Dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); + rhiD->f->glBufferData(targetForDataOps, nonZeroSize, nullptr, m_type == Dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); usageState.access = AccessNone; - QRHI_PROF_F(newBuffer(this, m_size, 1, 0)); + QRHI_PROF_F(newBuffer(this, nonZeroSize, 1, 0)); rhiD->registerResource(this); return true; } From 05251bca1dc5aabdd1e4548a1bf1bf757f615791 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 26 Feb 2019 14:55:33 +0100 Subject: [PATCH 257/264] Add an easier way to change colorspaces Adds setters for transfer-functions and primaries. This allows us to remove use of private QColorSpace API from the PNG handler. Change-Id: Ieeff81c813c253649500acd1e53f35247b872325 Reviewed-by: Eirik Aavitsland --- src/gui/image/qpnghandler.cpp | 16 +-- src/gui/painting/qcolorspace.cpp | 106 ++++++++++++++++-- src/gui/painting/qcolorspace.h | 7 ++ .../painting/qcolorspace/tst_qcolorspace.cpp | 47 ++++++++ 4 files changed, 154 insertions(+), 22 deletions(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 3bf4e9db15..16d6c25b8b 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -53,7 +53,6 @@ #include #include -#include #include #include @@ -681,10 +680,7 @@ bool QPngHandlerPrivate::readPngImage(QImage *outImage) // This configuration forces gamma correction and // thus changes the output colorspace png_set_gamma(png_ptr, 1.0f / gamma, fileGamma); - QColorSpacePrivate *csPrivate = QColorSpacePrivate::getWritable(colorSpace); - csPrivate->transferFunction = QColorSpace::TransferFunction::Gamma; - csPrivate->gamma = 1.0f / gamma; - csPrivate->setTransferFunction(); + colorSpace = colorSpace.withTransferFunction(QColorSpace::TransferFunction::Gamma, 1.0f / gamma); colorSpaceState = GammaChrm; } @@ -984,14 +980,8 @@ bool QPNGImageWriter::writeImage(const QImage& image, volatile int compression_i if (image.colorSpace().isValid()) { QColorSpace cs = image.colorSpace(); // Support the old gamma making it override transferfunction. - if (gamma != 0.0 && !qFuzzyCompare(cs.gamma(), 1.0f / gamma)) { - QColorSpacePrivate *csPrivate = QColorSpacePrivate::getWritable(cs); - csPrivate->transferFunction = QColorSpace::TransferFunction::Gamma; - csPrivate->gamma = 1.0f / gamma; - csPrivate->setTransferFunction(); - csPrivate->iccProfile.clear(); - csPrivate->description.clear(); - } + if (gamma != 0.0 && !qFuzzyCompare(cs.gamma(), 1.0f / gamma)) + cs = cs.withTransferFunction(QColorSpace::TransferFunction::Gamma, 1.0f / gamma); QByteArray iccProfileName = QColorSpacePrivate::get(cs)->description.toLatin1(); if (iccProfileName.isEmpty()) iccProfileName = QByteArrayLiteral("Custom"); diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp index a14d630814..043a951521 100644 --- a/src/gui/painting/qcolorspace.cpp +++ b/src/gui/painting/qcolorspace.cpp @@ -163,24 +163,22 @@ QColorSpacePrivate::QColorSpacePrivate() QColorSpacePrivate::QColorSpacePrivate(QColorSpace::ColorSpaceId colorSpaceId) : id(colorSpaceId) + , gamma(0.0f) { switch (colorSpaceId) { case QColorSpace::Undefined: primaries = QColorSpace::Primaries::Custom; transferFunction = QColorSpace::TransferFunction::Custom; - gamma = 0.0f; description = QStringLiteral("Undefined"); break; case QColorSpace::SRgb: primaries = QColorSpace::Primaries::SRgb; transferFunction = QColorSpace::TransferFunction::SRgb; - gamma = 2.31f; // ? description = QStringLiteral("sRGB"); break; case QColorSpace::SRgbLinear: primaries = QColorSpace::Primaries::SRgb; transferFunction = QColorSpace::TransferFunction::Linear; - gamma = 1.0f; description = QStringLiteral("Linear sRGB"); break; case QColorSpace::AdobeRgb: @@ -192,19 +190,16 @@ QColorSpacePrivate::QColorSpacePrivate(QColorSpace::ColorSpaceId colorSpaceId) case QColorSpace::DisplayP3: primaries = QColorSpace::Primaries::DciP3D65; transferFunction = QColorSpace::TransferFunction::SRgb; - gamma = 2.31f; // ? description = QStringLiteral("Display P3"); break; case QColorSpace::ProPhotoRgb: primaries = QColorSpace::Primaries::ProPhotoRgb; transferFunction = QColorSpace::TransferFunction::ProPhotoRgb; - gamma = 1.8f; description = QStringLiteral("ProPhoto RGB"); break; case QColorSpace::Bt2020: primaries = QColorSpace::Primaries::Bt2020; transferFunction = QColorSpace::TransferFunction::Bt2020; - gamma = 2.1f; // ? description = QStringLiteral("BT.2020"); break; case QColorSpace::Unknown: @@ -236,8 +231,7 @@ QColorSpacePrivate::QColorSpacePrivate(const QColorSpacePrimaries &primaries, Q_ASSERT(primaries.areValid()); toXyz = primaries.toXyzMatrix(); whitePoint = QColorVector(primaries.whitePoint); - if (!identifyColorSpace()) - id = QColorSpace::Unknown; + identifyColorSpace(); setTransferFunction(); } @@ -304,6 +298,7 @@ bool QColorSpacePrivate::identifyColorSpace() default: break; } + id = QColorSpace::Unknown; return false; } @@ -331,6 +326,8 @@ void QColorSpacePrivate::setTransferFunction() case QColorSpace::TransferFunction::Linear: trc[0].m_type = QColorTrc::Type::Function; trc[0].m_fun = QColorTransferFunction(); + if (qFuzzyIsNull(gamma)) + gamma = 1.0f; break; case QColorSpace::TransferFunction::Gamma: trc[0].m_type = QColorTrc::Type::Function; @@ -339,14 +336,20 @@ void QColorSpacePrivate::setTransferFunction() case QColorSpace::TransferFunction::SRgb: trc[0].m_type = QColorTrc::Type::Function; trc[0].m_fun = QColorTransferFunction::fromSRgb(); + if (qFuzzyIsNull(gamma)) + gamma = 2.31f; break; case QColorSpace::TransferFunction::ProPhotoRgb: trc[0].m_type = QColorTrc::Type::Function; trc[0].m_fun = QColorTransferFunction::fromProPhotoRgb(); + if (qFuzzyIsNull(gamma)) + gamma = 1.8f; break; case QColorSpace::TransferFunction::Bt2020: trc[0].m_type = QColorTrc::Type::Function; trc[0].m_fun = QColorTransferFunction::fromBt2020(); + if (qFuzzyIsNull(gamma)) + gamma = 1.961f; break; case QColorSpace::TransferFunction::Custom: break; @@ -564,7 +567,7 @@ QColorSpace::Primaries QColorSpace::primaries() const noexcept Returns the predefined transfer function of the color space or \c TransferFunction::Custom if it doesn't match any of them. - \sa gamma() + \sa gamma(), setTransferFunction(), withTransferFunction() */ QColorSpace::TransferFunction QColorSpace::transferFunction() const noexcept { @@ -583,6 +586,91 @@ float QColorSpace::gamma() const noexcept return d_ptr->gamma; } +/*! + Sets the transfer function to \a transferFunction and \a gamma. + + \note This also changes colorSpaceId(). + + \sa transferFunction(), gamma(), withTransferFunction() +*/ +void QColorSpace::setTransferFunction(QColorSpace::TransferFunction transferFunction, float gamma) +{ + if (!isValid() || transferFunction == QColorSpace::TransferFunction::Custom) + return; + if (d_ptr->transferFunction == transferFunction && d_ptr->gamma == gamma) + return; + d_ptr.detach(); + d_ptr->description.clear(); + d_ptr->transferFunction = transferFunction; + d_ptr->gamma = gamma; + d_ptr->identifyColorSpace(); + d_ptr->setTransferFunction(); +} + +/*! + Returns a copy of this color space, except using the transfer function + \a transferFunction and \a gamma. + + \sa transferFunction(), gamma(), setTransferFunction() +*/ +QColorSpace QColorSpace::withTransferFunction(QColorSpace::TransferFunction transferFunction, float gamma) const +{ + if (!isValid() || transferFunction == QColorSpace::TransferFunction::Custom) + return *this; + if (d_ptr->transferFunction == transferFunction && d_ptr->gamma == gamma) + return *this; + QColorSpace out(*this); + out.setTransferFunction(transferFunction, gamma); + return out; +} + +/*! + Sets the primaries to those of the \a primariesId set. + + \note This also changes colorSpaceId(). + + \sa primaries() +*/ +void QColorSpace::setPrimaries(QColorSpace::Primaries primariesId) +{ + if (!isValid() || primariesId == QColorSpace::Primaries::Custom) + return; + if (d_ptr->primaries == primariesId) + return; + d_ptr.detach(); + d_ptr->description.clear(); + d_ptr->primaries = primariesId; + d_ptr->identifyColorSpace(); + d_ptr->setToXyzMatrix(); +} + +/*! + Set primaries to the chromaticities of \a whitePoint, \a redPoint, \a greenPoint + and \a bluePoint. + + \note This also changes colorSpaceId(). + + \sa primaries() +*/ +void QColorSpace::setPrimaries(const QPointF &whitePoint, const QPointF &redPoint, + const QPointF &greenPoint, const QPointF &bluePoint) +{ + if (!isValid()) + return; + QColorSpacePrimaries primaries(whitePoint, redPoint, greenPoint, bluePoint); + if (!primaries.areValid()) + return; + QColorMatrix toXyz = primaries.toXyzMatrix(); + if (QColorVector(primaries.whitePoint) == d_ptr->whitePoint && toXyz == d_ptr->toXyz) + return; + d_ptr.detach(); + d_ptr->description.clear(); + d_ptr->primaries = QColorSpace::Primaries::Custom; + d_ptr->toXyz = toXyz; + d_ptr->whitePoint = QColorVector(primaries.whitePoint); + d_ptr->identifyColorSpace(); +} + /*! Returns an ICC profile representing the color space. diff --git a/src/gui/painting/qcolorspace.h b/src/gui/painting/qcolorspace.h index a9871fc277..a7c1091911 100644 --- a/src/gui/painting/qcolorspace.h +++ b/src/gui/painting/qcolorspace.h @@ -103,6 +103,13 @@ public: TransferFunction transferFunction() const noexcept; float gamma() const noexcept; + void setTransferFunction(TransferFunction transferFunction, float gamma = 0.0f); + QColorSpace withTransferFunction(TransferFunction transferFunction, float gamma = 0.0f) const; + + void setPrimaries(Primaries primariesId); + void setPrimaries(const QPointF &whitePoint, const QPointF &redPoint, + const QPointF &greenPoint, const QPointF &bluePoint); + bool isValid() const noexcept; friend Q_GUI_EXPORT bool operator==(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2); diff --git a/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp b/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp index c0f3559f57..bc1a45013c 100644 --- a/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp +++ b/tests/auto/gui/painting/qcolorspace/tst_qcolorspace.cpp @@ -66,6 +66,9 @@ private slots: void primaries2_data(); void primaries2(); void invalidPrimaries(); + + void changeTransferFunction(); + void changePrimaries(); }; tst_QColorSpace::tst_QColorSpace() @@ -375,5 +378,49 @@ void tst_QColorSpace::invalidPrimaries() QCOMPARE(custom.colorSpaceId(), QColorSpace::Undefined); } +void tst_QColorSpace::changeTransferFunction() +{ + QColorSpace sRgb = QColorSpace::SRgb; + + QColorSpace sRgbLinear = sRgb.withTransferFunction(QColorSpace::TransferFunction::Linear); + QCOMPARE(sRgbLinear.transferFunction(), QColorSpace::TransferFunction::Linear); + QCOMPARE(sRgbLinear.gamma(), 1.0f); + QCOMPARE(sRgbLinear.primaries(), QColorSpace::Primaries::SRgb); + QCOMPARE(sRgbLinear.colorSpaceId(), QColorSpace::SRgbLinear); + QCOMPARE(sRgbLinear, QColorSpace(QColorSpace::SRgbLinear)); + QVERIFY(sRgbLinear != sRgb); + QCOMPARE(sRgbLinear.withTransferFunction(QColorSpace::TransferFunction::SRgb), sRgb); + + QColorSpace aRgb = QColorSpace::AdobeRgb; + aRgb.setTransferFunction(QColorSpace::TransferFunction::SRgb); + QCOMPARE(aRgb.transferFunction(), QColorSpace::TransferFunction::SRgb); + QCOMPARE(aRgb.primaries(), QColorSpace::Primaries::AdobeRgb); + QCOMPARE(aRgb.colorSpaceId(), QColorSpace::Unknown); + QVERIFY(aRgb != QColorSpace(QColorSpace::AdobeRgb)); + QVERIFY(aRgb != sRgb); + QCOMPARE(aRgb.withTransferFunction(QColorSpace::TransferFunction::Gamma, 2.2f), + QColorSpace(QColorSpace::AdobeRgb)); + QVERIFY(aRgb != QColorSpace(QColorSpace::AdobeRgb)); + aRgb.setTransferFunction(QColorSpace::TransferFunction::Gamma, 2.2f); + QVERIFY(aRgb == QColorSpace(QColorSpace::AdobeRgb)); + + QColorSpace undefined; + QCOMPARE(undefined.withTransferFunction(QColorSpace::TransferFunction::Linear), undefined); + undefined.setTransferFunction(QColorSpace::TransferFunction::SRgb); + QCOMPARE(undefined, QColorSpace()); +} + +void tst_QColorSpace::changePrimaries() +{ + QColorSpace cs = QColorSpace::SRgb; + cs.setPrimaries(QColorSpace::Primaries::DciP3D65); + QVERIFY(cs.isValid()); + QCOMPARE(cs, QColorSpace(QColorSpace::DisplayP3)); + cs.setTransferFunction(QColorSpace::TransferFunction::Linear); + cs.setPrimaries(QPointF(0.3127, 0.3290), QPointF(0.640, 0.330), + QPointF(0.3000, 0.6000), QPointF(0.150, 0.060)); + QCOMPARE(cs, QColorSpace(QColorSpace::SRgbLinear)); +} + QTEST_MAIN(tst_QColorSpace) #include "tst_qcolorspace.moc" From 2ab3af564c7c8424b558c5902614d1a410850acf Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 2 Aug 2019 22:27:45 +0300 Subject: [PATCH 258/264] Thou Shalt Not Specialize std Function Templates (or forward-declare std types) (with apologies to Mr Walter Brown) This applies the changes to our other smart pointers that a0c4b6f34546bdd22167a76a0540d37e9a37c0cf applied to QSharedPointer, with the same rationale: wg21.link/p0551. It also fixes a fwd declaration of std::function, including instead. Rationale: wg21.link/p684r0. Change-Id: If275af91f6eac15eb418b200ac7d08ba084a6130 Reviewed-by: Giuseppe D'Angelo --- src/corelib/kernel/qeventdispatcher_winrt_p.h | 2 +- src/corelib/tools/qarraydatapointer.h | 13 +------------ src/corelib/tools/qshareddata.h | 16 ++-------------- 3 files changed, 4 insertions(+), 27 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_winrt_p.h b/src/corelib/kernel/qeventdispatcher_winrt_p.h index 8b998a7958..2672f11123 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt_p.h +++ b/src/corelib/kernel/qeventdispatcher_winrt_p.h @@ -57,7 +57,7 @@ #include -namespace std { template class function; } +#include QT_BEGIN_NAMESPACE diff --git a/src/corelib/tools/qarraydatapointer.h b/src/corelib/tools/qarraydatapointer.h index 0322615f91..af5173c9ad 100644 --- a/src/corelib/tools/qarraydatapointer.h +++ b/src/corelib/tools/qarraydatapointer.h @@ -202,22 +202,11 @@ inline bool operator!=(const QArrayDataPointer &lhs, const QArrayDataPointer< } template -inline void qSwap(QArrayDataPointer &p1, QArrayDataPointer &p2) +inline void swap(QArrayDataPointer &p1, QArrayDataPointer &p2) { p1.swap(p2); } QT_END_NAMESPACE -namespace std -{ - template - inline void swap( - QT_PREPEND_NAMESPACE(QArrayDataPointer) &p1, - QT_PREPEND_NAMESPACE(QArrayDataPointer) &p2) - { - p1.swap(p2); - } -} - #endif // include guard diff --git a/src/corelib/tools/qshareddata.h b/src/corelib/tools/qshareddata.h index ab54c76720..f123f8e7b9 100644 --- a/src/corelib/tools/qshareddata.h +++ b/src/corelib/tools/qshareddata.h @@ -297,25 +297,13 @@ template inline bool operator==(const QExplicitlySharedDataPointer } template -Q_INLINE_TEMPLATE void qSwap(QSharedDataPointer &p1, QSharedDataPointer &p2) +Q_INLINE_TEMPLATE void swap(QSharedDataPointer &p1, QSharedDataPointer &p2) { p1.swap(p2); } template -Q_INLINE_TEMPLATE void qSwap(QExplicitlySharedDataPointer &p1, QExplicitlySharedDataPointer &p2) +Q_INLINE_TEMPLATE void swap(QExplicitlySharedDataPointer &p1, QExplicitlySharedDataPointer &p2) { p1.swap(p2); } -QT_END_NAMESPACE -namespace std { - template - Q_INLINE_TEMPLATE void swap(QT_PREPEND_NAMESPACE(QSharedDataPointer) &p1, QT_PREPEND_NAMESPACE(QSharedDataPointer) &p2) - { p1.swap(p2); } - - template - Q_INLINE_TEMPLATE void swap(QT_PREPEND_NAMESPACE(QExplicitlySharedDataPointer) &p1, QT_PREPEND_NAMESPACE(QExplicitlySharedDataPointer) &p2) - { p1.swap(p2); } -} -QT_BEGIN_NAMESPACE - template Q_INLINE_TEMPLATE uint qHash(const QSharedDataPointer &ptr, uint seed = 0) noexcept { From a3de48eccc135bfc550d36646bf2ab555151239e Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 30 Jul 2019 15:16:11 +0200 Subject: [PATCH 259/264] Remove QMake's -createstub option This undocumented option was introduced in 69c22301806b56d56cbe5f5076b889ba98e41a2b (old internal history, 2006) to prepare some unspecified change to configure that was never done. Change-Id: I60de731ac9bc6f6424c57574e59e9f6b4f6c5eb3 Reviewed-by: Kai Koehne --- qmake/generators/makefile.cpp | 15 --------------- qmake/generators/makefile.h | 1 - qmake/generators/unix/unixmake.h | 1 - qmake/generators/unix/unixmake2.cpp | 2 -- qmake/generators/win32/mingw_make.cpp | 12 ------------ qmake/generators/win32/msvc_nmake.cpp | 4 ---- qmake/option.cpp | 3 --- qmake/option.h | 1 - 8 files changed, 39 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 5ccd1aea83..6034a9c5dd 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2233,21 +2233,6 @@ MakefileGenerator::writeDummyMakefile(QTextStream &t) return true; } -bool -MakefileGenerator::writeStubMakefile(QTextStream &t) -{ - t << "QMAKE = " << var("QMAKE_QMAKE") << Qt::endl; - const ProStringList &qut = project->values("QMAKE_EXTRA_TARGETS"); - for (ProStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it) - t << *it << " "; - //const QString ofile = Option::fixPathToTargetOS(fileFixify(Option::output.fileName())); - t << "first all clean install distclean uninstall: qmake\n" - << "qmake_all:\n"; - writeMakeQmake(t); - t << "FORCE:\n\n"; - return true; -} - bool MakefileGenerator::writeMakefile(QTextStream &t) { diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index 4d1b998197..ac1d5abb11 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -90,7 +90,6 @@ protected: void writeExtraCompilerTargets(QTextStream &t); void writeExtraCompilerVariables(QTextStream &t); bool writeDummyMakefile(QTextStream &t); - virtual bool writeStubMakefile(QTextStream &t); virtual bool writeMakefile(QTextStream &t); virtual void writeDefaultVariables(QTextStream &t); diff --git a/qmake/generators/unix/unixmake.h b/qmake/generators/unix/unixmake.h index 901419d3cc..79b161f6da 100644 --- a/qmake/generators/unix/unixmake.h +++ b/qmake/generators/unix/unixmake.h @@ -42,7 +42,6 @@ class UnixMakefileGenerator : public MakefileGenerator protected: virtual bool doPrecompiledHeaders() const { return project->isActiveConfig("precompile_header"); } - bool doDepends() const override { return !Option::mkfile::do_stub_makefile && MakefileGenerator::doDepends(); } #ifdef Q_OS_WIN // MinGW x-compiling for QNX QString installRoot() const override; #endif diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index c8efd0680b..8d1bd08197 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -66,8 +66,6 @@ UnixMakefileGenerator::writeMakefile(QTextStream &t) if (project->first("TEMPLATE") == "app" || project->first("TEMPLATE") == "lib" || project->first("TEMPLATE") == "aux") { - if(Option::mkfile::do_stub_makefile && MakefileGenerator::writeStubMakefile(t)) - return true; writeMakeParts(t); return MakefileGenerator::writeMakefile(t); } else if (project->first("TEMPLATE") == "subdirs") { diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index 37bf5e8669..40114948c2 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -93,18 +93,6 @@ bool MingwMakefileGenerator::writeMakefile(QTextStream &t) project->first("TEMPLATE") == "aux") { if(project->isActiveConfig("create_pc") && project->first("TEMPLATE") == "lib") writePkgConfigFile(); - - if(Option::mkfile::do_stub_makefile) { - t << "QMAKE = " << var("QMAKE_QMAKE") << Qt::endl; - const ProStringList &qut = project->values("QMAKE_EXTRA_TARGETS"); - for (ProStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it) - t << escapeDependencyPath(*it) << ' '; - t << "first all clean install distclean uninstall: qmake\n" - << "qmake_all:\n"; - writeMakeQmake(t); - t << "FORCE:\n\n"; - return true; - } writeMingwParts(t); return MakefileGenerator::writeMakefile(t); } diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 1f6223f01d..67b478ae28 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -48,10 +48,6 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) if(project->first("TEMPLATE") == "app" || project->first("TEMPLATE") == "lib" || project->first("TEMPLATE") == "aux") { -#if 0 - if(Option::mkfile::do_stub_makefile) - return MakefileGenerator::writeStubMakefile(t); -#endif writeNmakeParts(t); return MakefileGenerator::writeMakefile(t); } diff --git a/qmake/option.cpp b/qmake/option.cpp index dcebeadcb8..1e31ecd6b7 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -93,7 +93,6 @@ bool Option::mkfile::do_deps = true; bool Option::mkfile::do_mocs = true; bool Option::mkfile::do_dep_heuristics = true; bool Option::mkfile::do_preprocess = false; -bool Option::mkfile::do_stub_makefile = false; QStringList Option::mkfile::project_files; static Option::QMAKE_MODE default_mode(QString progname) @@ -254,8 +253,6 @@ Option::parseCommandLine(QStringList &args, QMakeCmdLineParserState &state) Option::mkfile::do_deps = false; } else if (arg == "-nomoc") { Option::mkfile::do_mocs = false; - } else if (arg == "-createstub") { - Option::mkfile::do_stub_makefile = true; } else if (arg == "-nodependheuristics") { Option::mkfile::do_dep_heuristics = false; } else if (arg == "-E") { diff --git a/qmake/option.h b/qmake/option.h index 25b2d64aaa..d7f4e87c70 100644 --- a/qmake/option.h +++ b/qmake/option.h @@ -189,7 +189,6 @@ struct Option static bool do_mocs; static bool do_dep_heuristics; static bool do_preprocess; - static bool do_stub_makefile; static int cachefile_depth; static QStringList project_files; }; From 49a8aae6d3b254a0e1dcc3f997b6eb2dd1e6c7b7 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 3 Jul 2019 14:20:27 +0200 Subject: [PATCH 260/264] Remove special handling of DLLDESTDIR on Windows In MakefileGenerator::initOutPaths() we ensure that directory variables end with a directory separator, except for DLLDESTDIR. There doesn't seem to be a valid reason for this exception. Remove it for the sake of simplifying the code base. Change-Id: I60eb01b410161e6e1d147d76f044f5140a7573bd Reviewed-by: Edward Welbourne --- qmake/generators/makefile.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 6034a9c5dd..2082bd6dc3 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -167,14 +167,8 @@ MakefileGenerator::initOutPaths() ProString &pathRef = v[dkey].first(); pathRef = fileFixify(pathRef.toQString(), FileFixifyFromOutdir); -#ifdef Q_OS_WIN - // We don't want to add a separator for DLLDESTDIR on Windows (###why?) - if (dkey != "DLLDESTDIR") -#endif - { - if(!pathRef.endsWith(Option::dir_sep)) - pathRef += Option::dir_sep; - } + if (!pathRef.endsWith(Option::dir_sep)) + pathRef += Option::dir_sep; if (noIO() || (project->first("TEMPLATE") == "subdirs")) continue; From 19a9d3517b4ab22410c815b127d38ce4398a5828 Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Thu, 1 Aug 2019 10:27:15 +0200 Subject: [PATCH 261/264] Remove the unused includes for QSignalMapper Change-Id: I13f19fadc7ad3fed8eb0a6718244cc8880e91be9 Reviewed-by: Marc Mutz --- src/widgets/widgets/qtoolbar.cpp | 1 - tests/manual/lance/widgets.h | 1 - 2 files changed, 2 deletions(-) diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp index fcaafbc581..d1a0f5ea78 100644 --- a/src/widgets/widgets/qtoolbar.cpp +++ b/src/widgets/widgets/qtoolbar.cpp @@ -53,7 +53,6 @@ #if QT_CONFIG(rubberband) #include #endif -#include #include #include #include diff --git a/tests/manual/lance/widgets.h b/tests/manual/lance/widgets.h index 46c55f4c16..09b2c3e667 100644 --- a/tests/manual/lance/widgets.h +++ b/tests/manual/lance/widgets.h @@ -43,7 +43,6 @@ #include #include #include -#include #include #include From bbff70181fc3c2b56489ad4fc0b0dea18a75b70a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 1 Aug 2019 22:59:09 -0700 Subject: [PATCH 262/264] QTest: add toString(QBitArray) Change-Id: Ife213d861bb14c1787e1fffd15b70598cda8baf3 Reviewed-by: Edward Welbourne --- src/testlib/qtest.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/testlib/qtest.h b/src/testlib/qtest.h index bff8f292a5..cdf0800371 100644 --- a/src/testlib/qtest.h +++ b/src/testlib/qtest.h @@ -46,6 +46,7 @@ #include #include +#include #include #include #include @@ -91,6 +92,16 @@ template<> inline char *toString(const QByteArray &ba) return QTest::toPrettyCString(ba.constData(), ba.length()); } +template<> inline char *toString(const QBitArray &ba) +{ + qsizetype size = ba.size(); + char *str = static_cast(malloc(size + 1)); + for (qsizetype i = 0; i < size; ++i) + str[i] = "01"[ba.testBit(i)]; + str[size] = '\0'; + return str; +} + #if QT_CONFIG(datestring) template<> inline char *toString(const QTime &time) { From 3183e428a95c95e5047dd12fbf2b6388aa7698fb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 30 Jul 2019 08:50:27 -0700 Subject: [PATCH 263/264] Mark QDBusError::ErrorType a Q_ENUM Easier qDebugging. Fixes: QTBUG-77183 Change-Id: Ife213d861bb14c1787e1fffd15b63a1f8d64cc30 Reviewed-by: Marc Mutz Reviewed-by: Edward Welbourne --- src/dbus/qdbuserror.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dbus/qdbuserror.h b/src/dbus/qdbuserror.h index bcf68dbcdc..312bac71de 100644 --- a/src/dbus/qdbuserror.h +++ b/src/dbus/qdbuserror.h @@ -41,6 +41,7 @@ #define QDBUSERROR_H #include +#include #include #ifndef QT_NO_DBUS @@ -54,6 +55,7 @@ class QDBusMessage; class Q_DBUS_EXPORT QDBusError { + Q_GADGET public: enum ErrorType { NoError = 0, @@ -90,6 +92,7 @@ public: LastErrorType = InvalidMember #endif }; + Q_ENUM(ErrorType) QDBusError(); #ifndef QT_BOOTSTRAPPED From 6132260da394a9627947f0fe6a279c20863b6ad2 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Wed, 7 Aug 2019 14:37:21 +0200 Subject: [PATCH 264/264] Temporarily remove dependencies.yaml We'll re-add it after we get a working qt5.git wip/qt6 build. Change-Id: Ic6724070a03cd0b2e2535c3ad9d19215b1cdf891 Reviewed-by: Simon Hausmann --- dependencies.yaml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 dependencies.yaml diff --git a/dependencies.yaml b/dependencies.yaml deleted file mode 100644 index c093387ce0..0000000000 --- a/dependencies.yaml +++ /dev/null @@ -1 +0,0 @@ -dependencies: {}