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: 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"); -- cgit v1.2.3 From 1a14f7e91b065ed287a4982d4bea0027121926f4 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Wed, 3 Jul 2019 13:41:13 +0200 Subject: 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; } -- cgit v1.2.3 From cc873ec23a98ac32d10ac5fa569792fde2f6b2c8 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Wed, 3 Jul 2019 18:20:17 +0200 Subject: 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); } -- cgit v1.2.3 From 11d9af5d957ac391a0c6cfdea4819df44b2b1560 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 4 Jul 2019 10:54:21 +0200 Subject: 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) -- cgit v1.2.3 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: 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: -- cgit v1.2.3 From 72ebc7458dabe61c5231456d72a81ec7234a5785 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 28 Jun 2019 10:44:12 +0200 Subject: 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": { -- cgit v1.2.3 From 78caba7ae637bf4b33631c3425eb92ec3946c99e Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 20 Jun 2019 14:52:19 +0200 Subject: 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 +++--- .../fontdatabases/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); -- cgit v1.2.3 From a4718f1274b62eb1a8e633a5d5cc0c6e22024c11 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Tue, 4 Jun 2019 18:30:17 +0200 Subject: 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 -- cgit v1.2.3 From 94570dc49aa6319c4811dcf37a29f179b6f64391 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 5 Jul 2019 12:41:58 +0200 Subject: 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; -- cgit v1.2.3 From f66c22ff5b7b9ec81d8c1621850649be8a1ac4d4 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 5 Jul 2019 09:55:46 +0200 Subject: 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())); -- cgit v1.2.3 From 85dc392135feb72eed449e6eaf47cdd023879394 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 5 Jul 2019 09:58:45 +0200 Subject: 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 -- cgit v1.2.3 From 90a29a73f84ffd6386beb37690c328b039423fab Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 4 Jul 2019 14:08:44 +0200 Subject: 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 -- cgit v1.2.3 From f5745609481dd4f660e196b8438e25615d3dfe0a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 6 Jul 2019 11:04:34 +0200 Subject: 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(); }); -- cgit v1.2.3 From 1e9355fdf2c03e119c7e546c8bac3947d6c6b0b8 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Thu, 4 Jul 2019 12:35:49 +0200 Subject: 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() */ -- cgit v1.2.3 From a41701904e880f58e19b352ade1931d6cd1a7112 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Sun, 7 Jul 2019 13:44:26 +0200 Subject: 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 -- cgit v1.2.3 From 307403f8b4f25f3fa711fb64102c755d50283c2b Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 5 Jul 2019 17:20:14 +0200 Subject: 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); } -- cgit v1.2.3 From d8688d44840dd3f2324769d10b927c442b42e2c0 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 5 Jul 2019 17:24:22 +0200 Subject: 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 ++-- .../widgets/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 /* -- cgit v1.2.3 From fc95af3621c8d135d613e1fff82c0613bf281c87 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 21 Jun 2019 18:35:22 +0200 Subject: 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(); } } -- cgit v1.2.3 From 1c6828b9d61a5988e91e67342cc0f616fa87949e Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 26 Jun 2019 07:24:18 +0200 Subject: 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 -- cgit v1.2.3 From 0a3107dd302c521c240b273229ba40a358cb0873 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 4 Jul 2019 15:24:13 +0200 Subject: 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; -- cgit v1.2.3 From 89984a8a61a7e33a4ff62db98083a0e3c0c7b4b1 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 5 Jul 2019 15:35:34 +0200 Subject: 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:")); -- cgit v1.2.3 From d9fb502b20129ef975cc6e20df306dcd84c64142 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 9 Jul 2019 14:59:00 +0200 Subject: 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.") -- cgit v1.2.3 From 59b29d03b2fff8a138382d45077c81fe0d4b8ea8 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 9 Jul 2019 15:18:46 +0200 Subject: 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 /* -- cgit v1.2.3 From b426cff1e0363b350f98bc64691b9b279bc6c757 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 3 Jul 2019 16:25:54 +0200 Subject: 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() -- cgit v1.2.3 From 89aa6e780a28b2c6dc9f57d14afd2c49b743f472 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 10 Jul 2019 10:21:42 +0200 Subject: 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.") -- cgit v1.2.3 From 2d597c0e1a32dda3f4d2f1c941b8a0d2a4be4735 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Mon, 17 Dec 2018 11:12:50 +0100 Subject: 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(); -- cgit v1.2.3 From cc32226e647854a02ecd0775787bb08b85e2a014 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 2 Jul 2019 14:28:58 +0200 Subject: 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 --- src/network/socket/qnativesocketengine_win.cpp | 115 ++++++++++----------- .../network/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() -- cgit v1.2.3 From de8bd9ec6b21e3b43b08c4c2588b5116a7ca8ece Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 9 Jul 2019 17:19:26 +0200 Subject: 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 -- cgit v1.2.3 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: 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 --- src/plugins/platforms/windows/qwindowspointerhandler.cpp | 11 +++++++---- src/plugins/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 -- cgit v1.2.3