From e8a990c67467d60d4b95a94c1b763284e331adcf Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Mon, 11 Mar 2019 11:22:02 +0100 Subject: Fix aliased font rendering in native xcb mode Freetype creates 1bpp bitmaps in msb order, while XRender expects lsb order. Change-Id: If8dd8e07c424df2d135f56f1ce105ef94963f536 Reviewed-by: Lars Knoll Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp index d43b273f4d..6ddcec0256 100644 --- a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp +++ b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp @@ -2645,6 +2645,13 @@ bool QXRenderGlyphCache::addGlyphs(const QTextItemInt &ti, if (glyph == 0 || glyph->format != glyphFormat()) return false; + if (glyph->format == QFontEngine::Format_Mono) { + // Must convert bitmap from msb to lsb bit order + QImage img(glyph->data, glyph->width, glyph->height, QImage::Format_Mono); + img = img.convertToFormat(QImage::Format_MonoLSB); + memcpy(glyph->data, img.constBits(), static_cast(img.sizeInBytes())); + } + set->setGlyph(glyphs[i], spp, glyph); Q_ASSERT(glyph->data || glyph->width == 0 || glyph->height == 0); -- cgit v1.2.3 From c45f2eab8553a40d7185ed95b4ab3e45e95c8d70 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 20 Mar 2019 15:35:10 +0100 Subject: Silence the item model tests Introduce a logging category for the qDebug()-output. Add a meta type registration for QList, fixing numerous warnings like: WARN : tst_QItemModel::remove(QStandardItemModel:invalid start, valid count 5) QSignalSpy: Unable to handle parameter 'parents' of type 'QList' of method 'layoutChanged', use qRegisterMetaType to register it. Fix a Clang warning about potential misuse of operator , Task-number: QTBUG-73864 Change-Id: I60998403a44f5df8767926951ee13d1ed1e93c37 Reviewed-by: David Faure --- .../itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp | 5 ++++- tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp | 3 ++- .../qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp | 6 ++++-- .../qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h | 2 ++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp index 262c6dd9c8..c76052a38b 100644 --- a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp @@ -32,10 +32,13 @@ #include #include #include +#include #include "dynamictreemodel.h" #include "qidentityproxymodel.h" +Q_LOGGING_CATEGORY(lcItemModels, "qt.corelib.tests.itemmodels") + class DataChangedModel : public QAbstractListModel { public: @@ -390,7 +393,7 @@ void dump(QAbstractItemModel* model, QString const& indent = " - ", QModelIndex for (auto row = 0; row < model->rowCount(parent); ++row) { auto idx = model->index(row, 0, parent); - qDebug() << (indent + idx.data().toString()); + qCDebug(lcItemModels) << (indent + idx.data().toString()); dump(model, indent + "- ", idx); } } diff --git a/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp b/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp index 7cd220e684..af52852b99 100644 --- a/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp +++ b/tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp @@ -125,6 +125,7 @@ private: tst_QItemModel::tst_QItemModel() { qRegisterMetaType(); + qRegisterMetaType>(); } void tst_QItemModel::init() @@ -181,7 +182,7 @@ void tst_QItemModel::nonDestructiveBasicTest() currentModel->hasChildren(QModelIndex()); currentModel->hasIndex(0, 0); currentModel->headerData(0, Qt::Horizontal); - currentModel->index(0,0), QModelIndex(); + currentModel->index(0,0); currentModel->itemData(QModelIndex()); QVariant cache; currentModel->match(QModelIndex(), -1, cache); diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp index 82cd26971b..50e87f21ac 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp @@ -38,6 +38,8 @@ #include +Q_LOGGING_CATEGORY(lcItemModels, "qt.corelib.tests.itemmodels") + // Testing get/set functions void tst_QSortFilterProxyModel::getSetCheck() { @@ -4277,7 +4279,7 @@ public: QModelIndex index(int, int, const QModelIndex& parent = QModelIndex()) const override { // QTBUG-44962: Would we always expect the parent to belong to the model - qDebug() << parent.model() << this; + qCDebug(lcItemModels) << parent.model() << this; Q_ASSERT(!parent.isValid() || parent.model() == this); quintptr parentId = (parent.isValid()) ? parent.internalId() : 0; @@ -4363,7 +4365,7 @@ void tst_QSortFilterProxyModel::sourceLayoutChangeLeavesValidPersistentIndexes() // The use of qDebug here makes sufficient use of the heap to // cause corruption at runtime with normal use on linux (before // the fix). valgrind confirms the fix. - qDebug() << persistentIndex.parent(); + qCDebug(lcItemModels) << persistentIndex.parent(); QVERIFY(persistentIndex.parent().isValid()); } diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h index 82d4b7344e..d598a60932 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h @@ -186,4 +186,6 @@ private: Q_DECLARE_METATYPE(QAbstractItemModel::LayoutChangeHint) +Q_DECLARE_LOGGING_CATEGORY(lcItemModels) + #endif // TST_QSORTFILTERPROXYMODEL_H -- cgit v1.2.3 From a1c37462eebddf4ad7bc3192f1f3e9a3f7292b19 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 13 Mar 2019 11:24:48 +0100 Subject: Windows: Fix tooltip flicker on GL surfaces QPlatformWindow::initialGeometry() would assign a default height to the initial geometry of the QRollEffectClassWindow since it has height of 0. This causes the obtained geometry to not match and subsequently a geometry change being sent synchronously. Introduce a new flag QWindowPrivate::resizeAutomatic similar to the existing QWindowPrivate::positionAutomatic to prevent assigning a default size and pass through the geometry as is where required. Fixes: QTBUG-74176 Change-Id: I70c66490838a2c4dfe200ec86094d28bd984dd03 Reviewed-by: Kati Kankaanpaa Reviewed-by: Richard Moe Gustavsen --- src/gui/kernel/qplatformwindow.cpp | 7 ++++--- src/gui/kernel/qwindow_p.h | 4 ++++ src/plugins/platforms/windows/qwindowswindow.cpp | 3 ++- src/widgets/kernel/qwidget.cpp | 7 ++++++- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index 50f05721f7..24cfd32ace 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -708,10 +708,11 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w, const QScreen *screen = effectiveScreen(w); if (!screen) return initialGeometry; + const auto *wp = qt_window_private(const_cast(w)); QRect rect(QHighDpi::fromNativePixels(initialGeometry, w)); - rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight)); - if (qt_window_private(const_cast(w))->positionAutomatic - && w->type() != Qt::Popup) { + if (wp->resizeAutomatic) + rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight)); + if (wp->positionAutomatic && w->type() != Qt::Popup) { const QRect availableGeometry = screen->availableGeometry(); // Center unless the geometry ( + unknown window frame) is too large for the screen). if (rect.height() < (availableGeometry.height() * 8) / 9 diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index bf5e645114..af1233a9e2 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -90,6 +90,7 @@ public: , receivedExpose(false) , positionPolicy(WindowFrameExclusive) , positionAutomatic(true) + , resizeAutomatic(true) , contentOrientation(Qt::PrimaryOrientation) , opacity(qreal(1.0)) , minimumSize(0, 0) @@ -155,6 +156,8 @@ public: virtual void processSafeAreaMarginsChanged() {}; bool isPopup() const { return (windowFlags & Qt::WindowType_Mask) == Qt::Popup; } + void setAutomaticPositionAndResizeEnabled(bool a) + { positionAutomatic = resizeAutomatic = a; } static QWindowPrivate *get(QWindow *window) { return window->d_func(); } @@ -178,6 +181,7 @@ public: bool receivedExpose; PositionPolicy positionPolicy; bool positionAutomatic; + bool resizeAutomatic; Qt::ScreenOrientation contentOrientation; qreal opacity; QRegion mask; diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 2abd1eef8b..0376e363f3 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1132,7 +1132,8 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w, // TODO: No concept of WA_wasMoved yet that would indicate a // CW_USEDEFAULT unless set. For now, assume that 0,0 means 'default' // for toplevels. - if (geometry.isValid()) { + if (geometry.isValid() + || !qt_window_private(const_cast(w))->resizeAutomatic) { frameX = geometry.x(); frameY = geometry.y(); const QMargins effectiveMargins = margins + customMargins; diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 332eee9c03..2c84ff7161 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1543,14 +1543,19 @@ void QWidgetPrivate::createTLSysExtra() extra->topextra->window->setMaximumSize(QSize(extra->maxw, extra->maxh)); if (extra->topextra->opacity != 255 && q->isWindow()) extra->topextra->window->setOpacity(qreal(extra->topextra->opacity) / qreal(255)); + + const bool isTipLabel = q->inherits("QTipLabel"); + const bool isAlphaWidget = !isTipLabel && q->inherits("QAlphaWidget"); #ifdef Q_OS_WIN // Pass on native parent handle for Widget embedded into Active X. const QVariant activeXNativeParentHandle = q->property(activeXNativeParentHandleProperty); if (activeXNativeParentHandle.isValid()) extra->topextra->window->setProperty(activeXNativeParentHandleProperty, activeXNativeParentHandle); - if (q->inherits("QTipLabel") || q->inherits("QAlphaWidget")) + if (isTipLabel || isAlphaWidget) extra->topextra->window->setProperty("_q_windowsDropShadow", QVariant(true)); #endif + if (isTipLabel || isAlphaWidget || q->inherits("QRollEffect")) + qt_window_private(extra->topextra->window)->setAutomaticPositionAndResizeEnabled(false); } } -- cgit v1.2.3 From 4daf5204babc62a7ae58b6de5c09c527f81ea27c Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 20 Mar 2019 15:45:02 +0100 Subject: Cocoa: Clear the shortcut used when hiding a native menu entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The shortcut needs to be cleared if the native menu entry is being hidden due to the fact it was changed. Otherwise it will not show the shortcut anymore as it sees it as in-use. Change-Id: Ifb10db855766e4de71db06ea006f6d63497f3193 Fixes: QTBUG-74113 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoamenu.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 7b96fca3f9..f34988721d 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -250,6 +250,9 @@ void QCocoaMenu::syncMenuItem_helper(QPlatformMenuItem *menuItem, bool menubarUp if (wasMerged) { oldItem.enabled = NO; oldItem.hidden = YES; + oldItem.keyEquivalent = @""; + oldItem.keyEquivalentModifierMask = NSEventModifierFlagCommand; + } else { [m_nativeMenu removeItem:oldItem]; } -- cgit v1.2.3 From 7148dfc67ff20c1c625d203aa47b574b3aaa5db1 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 18 Mar 2019 07:46:15 -0700 Subject: Accept that glibc's statx() falls back for us So we don't need to have a high kernel requirement on its account. I needed to introduce a configure-time check because we need to include a header to get the __GLIBC__ macro, but we can't include any header in assembler until we know it's glibc (we need to know that the header is assembler-safe). glibc, uClibc and MUSL do provide an assembler-safe features.h, but Bionic does not. And we need to know that it's glibc's implementation, since the fallback was not required. The other three libraries may not implement such a thing when they get around to adding the system call. Fixes: QTBUG-74526 Change-Id: I1004b4b819774c4c9296fffd158d14da98bf571c Reviewed-by: Fabian Vogt Reviewed-by: Simon Hausmann --- src/corelib/configure.json | 16 ++++++++++++++++ src/corelib/global/minimum-linux_p.h | 6 +++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/corelib/configure.json b/src/corelib/configure.json index a22a7459bd..5f5a00a64f 100644 --- a/src/corelib/configure.json +++ b/src/corelib/configure.json @@ -374,6 +374,16 @@ ] } }, + "glibc": { + "label": "GNU libc", + "type": "compile", + "test": { + "include": "stdlib.h", + "main": [ + "return __GLIBC__;" + ] + } + }, "inotify": { "label": "inotify", "type": "compile", @@ -593,6 +603,12 @@ "condition": "libs.glib", "output": [ "privateFeature", "feature" ] }, + "glibc": { + "label": "GNU libc", + "autoDetect": "config.linux", + "condition": "tests.glibc", + "output": [ "privateFeature" ] + }, "iconv": { "label": "iconv", "purpose": "Provides internationalization on Unix.", diff --git a/src/corelib/global/minimum-linux_p.h b/src/corelib/global/minimum-linux_p.h index 9c074e13ba..5112015663 100644 --- a/src/corelib/global/minimum-linux_p.h +++ b/src/corelib/global/minimum-linux_p.h @@ -78,7 +78,11 @@ QT_BEGIN_NAMESPACE * - statx 4.11 QT_CONFIG(statx) */ -#if QT_CONFIG(statx) +#if QT_CONFIG(statx) && !QT_CONFIG(glibc) +// if using glibc, the statx() function in sysdeps/unix/sysv/linux/statx.c +// falls back to stat() for us. +// (Using QT_CONFIG(glibc) instead of __GLIBC__ because the macros aren't +// defined in assembler mode) # define MINLINUX_MAJOR 4 # define MINLINUX_MINOR 11 # define MINLINUX_PATCH 0 -- cgit v1.2.3 From 66fc17eb5c40568032ece0621c1ba0ffbf230b78 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 14 Mar 2019 20:21:20 -0700 Subject: Examples: properly parse more than one element in maps and lists Change-Id: I46363e5b8944459e8c48fffd158c03bca4b7394e Reviewed-by: Edward Welbourne Reviewed-by: Ulf Hermann --- examples/corelib/serialization/convert/xmlconverter.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/corelib/serialization/convert/xmlconverter.cpp b/examples/corelib/serialization/convert/xmlconverter.cpp index 62908273ce..e62801bf76 100644 --- a/examples/corelib/serialization/convert/xmlconverter.cpp +++ b/examples/corelib/serialization/convert/xmlconverter.cpp @@ -70,7 +70,7 @@ static QVariant variantFromXml(QXmlStreamReader &xml, Converter::Options options static QVariantList listFromXml(QXmlStreamReader &xml, Converter::Options options) { QVariantList list; - while (!xml.atEnd() && !xml.isEndElement()) { + while (!xml.atEnd() && !(xml.isEndElement() && xml.name() == QLatin1String("list"))) { xml.readNext(); switch (xml.tokenType()) { case QXmlStreamReader::StartElement: @@ -107,7 +107,7 @@ static QVariantList listFromXml(QXmlStreamReader &xml, Converter::Options option static VariantOrderedMap::value_type mapEntryFromXml(QXmlStreamReader &xml, Converter::Options options) { QVariant key, value; - while (!xml.atEnd() && !xml.isEndElement()) { + while (!xml.atEnd() && !(xml.isEndElement() && xml.name() == QLatin1String("entry"))) { xml.readNext(); switch (xml.tokenType()) { case QXmlStreamReader::StartElement: @@ -150,7 +150,7 @@ static QVariant mapFromXml(QXmlStreamReader &xml, Converter::Options options) QVariantMap map1; VariantOrderedMap map2; - while (!xml.atEnd() && !xml.isEndElement()) { + while (!xml.atEnd() && !(xml.isEndElement() && xml.name() == QLatin1String("map"))) { xml.readNext(); switch (xml.tokenType()) { case QXmlStreamReader::StartElement: -- cgit v1.2.3 From 4d77c37522b51861037f0ec3ee9d4d13951672ff Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 18 Mar 2019 16:21:26 +0100 Subject: QMacStyle - make focus ring less transparent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit But only for the 'Light' theme. For "Dark" the system color fits well (without our rather strange and random 0.5 we set for some reason). Change-Id: Ic5c8372913515611a567090f82852ffc7ca14eb7 Fixes: QTBUG-74095 Reviewed-by: Tor Arne Vestbø --- src/plugins/styles/mac/qmacstyle_mac.mm | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 13ef98b840..979f70ece5 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -1227,11 +1227,17 @@ void QMacStylePrivate::drawFocusRing(QPainter *p, const QRectF &targetRect, int Q_UNREACHABLE(); } - const auto focusRingColor = qt_mac_toQColor(NSColor.keyboardFocusIndicatorColor.CGColor); + auto focusRingColor = qt_mac_toQColor(NSColor.keyboardFocusIndicatorColor.CGColor); + if (!qt_mac_applicationIsInDarkMode()) { + // This color already has alpha ~ 0.25, this value is too small - the ring is + // very pale and nothing like the native one. 0.39 makes it better (not ideal + // anyway). The color seems to be correct in dark more without any modification. + focusRingColor.setAlphaF(0.39); + } p->save(); p->setRenderHint(QPainter::Antialiasing); - p->setOpacity(0.5); + if (cw.type == SegmentedControl_First) { // TODO Flip left-right } -- cgit v1.2.3 From 7c14233ec6539828cb0545188e47f726d0056094 Mon Sep 17 00:00:00 2001 From: Kari Oikarinen Date: Thu, 21 Mar 2019 09:07:57 +0200 Subject: Bump version Change-Id: I26f71350c0dee57bc6c765ece411700144100f42 Reviewed-by: Jani Heikkinen --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 6c2b67442a..124e265eb4 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -4,4 +4,4 @@ CONFIG += warning_clean QT_SOURCE_TREE = $$PWD QT_BUILD_TREE = $$shadowed($$PWD) -MODULE_VERSION = 5.12.2 +MODULE_VERSION = 5.12.3 -- cgit v1.2.3 From 0211774c6803b6d530ab2b804ab310f733567dfe Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 21 Mar 2019 11:49:55 +0100 Subject: Silence QMainWindow test Set object names on the widgets in restoreState(), fixing: QWARN : tst_QMainWindow::restoreState() QMainWindow::saveState(): 'objectName' not set for QDockWidget 0x7ffcb45e5e00 '; QWARN : tst_QMainWindow::restoreState() QMainWindow::saveState(): 'objectName' not set for QToolBar 0x7ffcb45e5dd0 '' QWARN : tst_QMainWindow::restoreState() QMainWindow::saveState(): 'objectName' not set for QDockWidget 0x7ffcb45e5e00 '; QWARN : tst_QMainWindow::restoreState() QMainWindow::saveState(): 'objectName' not set for QToolBar 0x7ffcb45e5dd0 '' Task-number: QTBUG-74242 Change-Id: I19f19e93de9df00d001b820a31836ce0b3cd2877 Reviewed-by: Richard Moe Gustavsen --- tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp index 1acf07301c..ea96322654 100644 --- a/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp +++ b/tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp @@ -1343,8 +1343,10 @@ void tst_QMainWindow::restoreState() { QMainWindow mw; QToolBar tb(&mw); + tb.setObjectName(QLatin1String("toolBar")); mw.addToolBar(Qt::TopToolBarArea, &tb); QDockWidget dw(&mw); + dw.setObjectName(QLatin1String("dock")); mw.addDockWidget(Qt::LeftDockWidgetArea, &dw); QByteArray state; -- cgit v1.2.3 From 1119cd4ece6555be82212b273d05d581bffb79d1 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 21 Mar 2019 16:10:09 +0100 Subject: Correct a misguided assertion in QTzTimeZonePrivate Without ICU, the TZ-DB backend for time-zones tripped over an assertion when running tst_QTimeZone::stressTest(), which happened to probe a zone between its last transition and the first transition of a POSIX rule that followed it. The code assumed there was no interval between these two; apparently, there can be. Change-Id: I3d0ad41fec0a255db2f9bfac54d33aa9b83938e8 Reviewed-by: Thiago Macieira --- src/corelib/tools/qtimezoneprivate_tz.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp index bed62a02bd..fa4ec031fa 100644 --- a/src/corelib/tools/qtimezoneprivate_tz.cpp +++ b/src/corelib/tools/qtimezoneprivate_tz.cpp @@ -1022,8 +1022,10 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecs [beforeMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) { return at.atMSecsSinceEpoch < beforeMSecsSinceEpoch; }); - Q_ASSERT(it > posixTrans.cbegin()); - return *--it; + if (it > posixTrans.cbegin()) + return *--it; + // else: it fell between the last transition and the first of the POSIX rule. + return dataForTzTransition(m_tranTimes.last()); } // Otherwise if we can find a valid tran then use its rule -- cgit v1.2.3 From 03fadc26e7617aece89949bc7d0acf50f6f050a9 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 21 Mar 2019 15:07:48 +0100 Subject: Fix broken data for time-zones with no transitions While an invalid time-zone shall have no transitions, so may various constant zones, like UTC. The TZ data may include only the POSIX rule for such a zone, in which case we should use it, even if there are no transitions. Broke out a piece of repeated code as a common method, in the process, since I was complicating it further. Added test for the case that revealed this; and made sure we see a warning if any of the checkOffset() tests gets skipped because its zone is unsupported. Fixes: QTBUG-74614 Change-Id: Ic8e039a2a9b3f4e0f567585682a94f4b494b558d Reviewed-by: Thiago Macieira --- src/corelib/tools/qtimezoneprivate_p.h | 1 + src/corelib/tools/qtimezoneprivate_tz.cpp | 46 +++++++++++----------- .../auto/corelib/tools/qtimezone/tst_qtimezone.cpp | 4 ++ 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/corelib/tools/qtimezoneprivate_p.h b/src/corelib/tools/qtimezoneprivate_p.h index c9a5726216..24a9a00f11 100644 --- a/src/corelib/tools/qtimezoneprivate_p.h +++ b/src/corelib/tools/qtimezoneprivate_p.h @@ -331,6 +331,7 @@ public: private: void init(const QByteArray &ianaId); + QVector getPosixTransitions(qint64 msNear) const; Data dataForTzTransition(QTzTransitionTime tran) const; QVector m_tranTimes; diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp index fa4ec031fa..f75a61977d 100644 --- a/src/corelib/tools/qtimezoneprivate_tz.cpp +++ b/src/corelib/tools/qtimezoneprivate_tz.cpp @@ -943,19 +943,21 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::dataForTzTransition(QTzTransitionTime return data; } -QTimeZonePrivate::Data QTzTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const +QVector QTzTimeZonePrivate::getPosixTransitions(qint64 msNear) const { - // If we have no rules (so probably an invalid tz), return invalid data: - if (!m_tranTimes.size()) - return invalidData(); + const int year = QDateTime::fromMSecsSinceEpoch(msNear, Qt::UTC).date().year(); + // The Data::atMSecsSinceEpoch of the single entry if zone is constant: + qint64 atTime = m_tranTimes.isEmpty() ? msNear : m_tranTimes.last().atMSecsSinceEpoch; + return calculatePosixTransitions(m_posixRule, year - 1, year + 1, atTime); +} - // If the required time is after the last transition and we have a POSIX rule then use it - if (m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch +QTimeZonePrivate::Data QTzTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const +{ + // If the required time is after the last transition (or there were none) + // and we have a POSIX rule then use it: + if ((m_tranTimes.isEmpty() || m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch) && !m_posixRule.isEmpty() && forMSecsSinceEpoch >= 0) { - const int year = QDateTime::fromMSecsSinceEpoch(forMSecsSinceEpoch, Qt::UTC).date().year(); - QVector posixTrans = - calculatePosixTransitions(m_posixRule, year - 1, year + 1, - m_tranTimes.last().atMSecsSinceEpoch); + QVector posixTrans = getPosixTransitions(forMSecsSinceEpoch); auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(), [forMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) { return at.atMSecsSinceEpoch <= forMSecsSinceEpoch; @@ -986,13 +988,11 @@ bool QTzTimeZonePrivate::hasTransitions() const QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch) const { - // If the required time is after the last transition and we have a POSIX rule then use it - if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < afterMSecsSinceEpoch + // If the required time is after the last transition (or there were none) + // and we have a POSIX rule then use it: + if ((m_tranTimes.isEmpty() || m_tranTimes.last().atMSecsSinceEpoch < afterMSecsSinceEpoch) && !m_posixRule.isEmpty() && afterMSecsSinceEpoch >= 0) { - const int year = QDateTime::fromMSecsSinceEpoch(afterMSecsSinceEpoch, Qt::UTC).date().year(); - QVector posixTrans = - calculatePosixTransitions(m_posixRule, year - 1, year + 1, - m_tranTimes.last().atMSecsSinceEpoch); + QVector posixTrans = getPosixTransitions(afterMSecsSinceEpoch); auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(), [afterMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) { return at.atMSecsSinceEpoch <= afterMSecsSinceEpoch; @@ -1011,21 +1011,19 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSince QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const { - // If the required time is after the last transition and we have a POSIX rule then use it - if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < beforeMSecsSinceEpoch + // If the required time is after the last transition (or there were none) + // and we have a POSIX rule then use it: + if ((m_tranTimes.isEmpty() || m_tranTimes.last().atMSecsSinceEpoch < beforeMSecsSinceEpoch) && !m_posixRule.isEmpty() && beforeMSecsSinceEpoch > 0) { - const int year = QDateTime::fromMSecsSinceEpoch(beforeMSecsSinceEpoch, Qt::UTC).date().year(); - QVector posixTrans = - calculatePosixTransitions(m_posixRule, year - 1, year + 1, - m_tranTimes.last().atMSecsSinceEpoch); + QVector posixTrans = getPosixTransitions(beforeMSecsSinceEpoch); auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(), [beforeMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) { return at.atMSecsSinceEpoch < beforeMSecsSinceEpoch; }); if (it > posixTrans.cbegin()) return *--it; - // else: it fell between the last transition and the first of the POSIX rule. - return dataForTzTransition(m_tranTimes.last()); + // It fell between the last transition (if any) and the first of the POSIX rule: + return m_tranTimes.isEmpty() ? invalidData() : dataForTzTransition(m_tranTimes.last()); } // Otherwise if we can find a valid tran then use its rule diff --git a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp index a25fd39693..eff9835776 100644 --- a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp +++ b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp @@ -539,6 +539,8 @@ void tst_QTimeZone::checkOffset_data() int year, month, day, hour, min, sec; int std, dst; } table[] = { + // Zone with no transitions (QTBUG-74614, when TZ backend uses minimalist data) + { "Etc/UTC", "epoch", 1970, 1, 1, 0, 0, 0, 0, 0 }, // Kiev: regression test for QTBUG-64122 (on MS): { "Europe/Kiev", "summer", 2017, 10, 27, 12, 0, 0, 2 * 3600, 3600 }, { "Europe/Kiev", "winter", 2017, 10, 29, 12, 0, 0, 2 * 3600, 0 } @@ -551,6 +553,8 @@ void tst_QTimeZone::checkOffset_data() << QDateTime(QDate(entry.year, entry.month, entry.day), QTime(entry.hour, entry.min, entry.sec), zone) << entry.dst + entry.std << entry.std << entry.dst; + } else { + qWarning("Skipping %s@%s test as zone is invalid", entry.zone, entry.nick); } } } -- cgit v1.2.3 From b01248ebbd42dd05d45fa655852169978beec40e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 20 Mar 2019 11:32:53 +0100 Subject: Fix tree recursion in QAbstractItemModel::match() Recurse down the sibling at column 0 of the index instead down the index. Change-Id: Ie78d8b28eab7438ca3f83ee0df177115ca82806e Fixes: QTBUG-73864 Reviewed-by: David Faure --- src/corelib/itemmodels/qabstractitemmodel.cpp | 14 +++++--- .../tst_qsortfilterproxymodel.cpp | 39 ++++++++++++++++++++++ .../tst_qsortfilterproxymodel.h | 1 + 3 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index e816add91d..83dcf68314 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -2360,6 +2360,7 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role, bool wrap = flags & Qt::MatchWrap; bool allHits = (hits == -1); QString text; // only convert to a string if it is needed + const int column = start.column(); QModelIndex p = parent(start); int from = start.row(); int to = rowCount(p); @@ -2367,7 +2368,7 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role, // iterates twice if wrapping for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) { for (int r = from; (r < to) && (allHits || result.count() < hits); ++r) { - QModelIndex idx = index(r, start.column(), p); + QModelIndex idx = index(r, column, p); if (!idx.isValid()) continue; QVariant v = data(idx, role); @@ -2406,10 +2407,13 @@ QModelIndexList QAbstractItemModel::match(const QModelIndex &start, int role, result.append(idx); } } - if (recurse && hasChildren(idx)) { // search the hierarchy - result += match(index(0, idx.column(), idx), role, - (text.isEmpty() ? value : text), - (allHits ? -1 : hits - result.count()), flags); + if (recurse) { + const auto parent = column != 0 ? idx.sibling(idx.row(), 0) : idx; + if (hasChildren(parent)) { // search the hierarchy + result += match(index(0, column, parent), role, + (text.isEmpty() ? value : text), + (allHits ? -1 : hits - result.count()), flags); + } } } // prepare for the next iteration diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp index 50e87f21ac..ccce5a44e5 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp @@ -2363,6 +2363,45 @@ void tst_QSortFilterProxyModel::match() QCOMPARE(indexes.at(i).row(), expectedProxyItems.at(i)); } +QList createStandardItemList(const QString &prefix, int n) +{ + QList result; + for (int i = 0; i < n; ++i) + result.append(new QStandardItem(prefix + QString::number(i))); + return result; +} + +// QTBUG-73864, recursive search in a tree model. + +void tst_QSortFilterProxyModel::matchTree() +{ + QStandardItemModel model(0, 2); + // Header00 Header01 + // Header10 Header11 + // Item00 Item01 + // Item10 Item11 + model.appendRow(createStandardItemList(QLatin1String("Header0"), 2)); + auto headerRow = createStandardItemList(QLatin1String("Header1"), 2); + model.appendRow(headerRow); + headerRow.first()->appendRow(createStandardItemList(QLatin1String("Item0"), 2)); + headerRow.first()->appendRow(createStandardItemList(QLatin1String("Item1"), 2)); + + auto item11 = model.match(model.index(1, 1), Qt::DisplayRole, QLatin1String("Item11"), 20, + Qt::MatchRecursive).value(0); + QVERIFY(item11.isValid()); + QCOMPARE(item11.data().toString(), QLatin1String("Item11")); + + // Repeat in proxy model + QSortFilterProxyModel proxy; + proxy.setSourceModel(&model); + auto proxyItem11 = proxy.match(proxy.index(1, 1), Qt::DisplayRole, QLatin1String("Item11"), 20, + Qt::MatchRecursive).value(0); + QVERIFY(proxyItem11.isValid()); + QCOMPARE(proxyItem11.data().toString(), QLatin1String("Item11")); + + QCOMPARE(proxy.mapToSource(proxyItem11).internalId(), item11.internalId()); +} + void tst_QSortFilterProxyModel::insertIntoChildrenlessItem() { QStandardItemModel model; diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h index d598a60932..8ae97165b8 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h @@ -109,6 +109,7 @@ private slots: void selectionFilteredOut(); void match_data(); void match(); + void matchTree(); void insertIntoChildrenlessItem(); void invalidateMappedChildren(); void insertRowIntoFilteredParent(); -- cgit v1.2.3 From 85a9009f258e130a7bd4aaaa252724ea5fb58e79 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Fri, 15 Mar 2019 11:01:31 +0100 Subject: QPixmap: More safe failing if qApp is not a QGuiApplication It can happen that QDataStream is fed a QVariant that contains a QPixmap representation, that will make the application crash when trying to restore it This is specially important for cases in which applications expose dbus interfaces with QVariantMaps Change-Id: Ife4feaef30f30e7e27d88464bd6b2a247f743123 Reported-by: Fabian Vogt Reviewed-by: Fabian Vogt Reviewed-by: Mitch Curtis Reviewed-by: Thiago Macieira --- src/gui/image/qpixmap.cpp | 15 +++++ .../qdatastream_core_pixmap.pro | 4 ++ .../tst_qdatastream_core_pixmap.cpp | 68 ++++++++++++++++++++++ tests/auto/corelib/serialization/serialization.pro | 1 + 4 files changed, 88 insertions(+) create mode 100644 tests/auto/corelib/serialization/qdatastream_core_pixmap/qdatastream_core_pixmap.pro create mode 100644 tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index ea6697cc39..7e862e9826 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1543,6 +1543,11 @@ QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags) if (image.isNull()) return QPixmap(); + if (Q_UNLIKELY(!qobject_cast(QCoreApplication::instance()))) { + qWarning("QPixmap::fromImage: QPixmap cannot be created without a QGuiApplication"); + return QPixmap(); + } + QScopedPointer data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType)); data->fromImage(image, flags); return QPixmap(data.take()); @@ -1565,6 +1570,11 @@ QPixmap QPixmap::fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags) if (image.isNull()) return QPixmap(); + if (Q_UNLIKELY(!qobject_cast(QCoreApplication::instance()))) { + qWarning("QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication"); + return QPixmap(); + } + QScopedPointer data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType)); data->fromImageInPlace(image, flags); return QPixmap(data.take()); @@ -1584,6 +1594,11 @@ QPixmap QPixmap::fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags) */ QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags) { + if (Q_UNLIKELY(!qobject_cast(QCoreApplication::instance()))) { + qWarning("QPixmap::fromImageReader: QPixmap cannot be created without a QGuiApplication"); + return QPixmap(); + } + QScopedPointer data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType)); data->fromImageReader(imageReader, flags); return QPixmap(data.take()); diff --git a/tests/auto/corelib/serialization/qdatastream_core_pixmap/qdatastream_core_pixmap.pro b/tests/auto/corelib/serialization/qdatastream_core_pixmap/qdatastream_core_pixmap.pro new file mode 100644 index 0000000000..7e003304af --- /dev/null +++ b/tests/auto/corelib/serialization/qdatastream_core_pixmap/qdatastream_core_pixmap.pro @@ -0,0 +1,4 @@ +CONFIG += testcase +TARGET = tst_qdatastream_core_pixmap +QT += testlib +SOURCES = tst_qdatastream_core_pixmap.cpp diff --git a/tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp b/tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp new file mode 100644 index 0000000000..c931016a61 --- /dev/null +++ b/tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** 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 +#include +#include +#include + +class tst_QDataStream : public QObject +{ +Q_OBJECT + +private slots: + void stream_with_pixmap(); + +}; + +void tst_QDataStream::stream_with_pixmap() +{ + // This is a QVariantMap with a 3x3 red QPixmap and two strings inside + const QByteArray ba = QByteArray::fromBase64("AAAAAwAAAAIAegAAAAoAAAAACgB0AGgAZQByAGUAAAACAHAAAABBAAAAAAGJUE5HDQoaCgAAAA1JSERSAAAAAwAAAAMIAgAAANlKIugAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAQSURBVAiZY/zPAAVMDJgsAB1bAQXZn5ieAAAAAElFTkSuQmCCAAAAAgBhAAAACgAAAAAKAGgAZQBsAGwAbw=="); + QImage dummy; // Needed to make sure qtGui is loaded + + QTest::ignoreMessage(QtWarningMsg, "QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication"); + + QVariantMap map; + QDataStream d(ba); + d.setVersion(QDataStream::Qt_5_12); + d >> map; + + QCOMPARE(map["a"].toString(), QString("hello")); + QCOMPARE(map["p"].value(), QPixmap()); // the pixmap is null because this is not a QGuiApplication + QCOMPARE(map["z"].toString(), QString("there")); +} + +QTEST_GUILESS_MAIN(tst_QDataStream) + +#include "tst_qdatastream_core_pixmap.moc" + diff --git a/tests/auto/corelib/serialization/serialization.pro b/tests/auto/corelib/serialization/serialization.pro index 9187de1bc5..9638178cdc 100644 --- a/tests/auto/corelib/serialization/serialization.pro +++ b/tests/auto/corelib/serialization/serialization.pro @@ -6,6 +6,7 @@ SUBDIRS = \ qcborvalue \ qcborvalue_json \ qdatastream \ + qdatastream_core_pixmap \ qtextstream \ qxmlstream -- cgit v1.2.3 From 9e61cec7915ca177e88bd685a3229f153ee7ab7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Tue, 19 Mar 2019 15:49:55 +0100 Subject: Network cache: Stop treating no-cache like no-store In the QNetworkAccessManager machinery we would treat "no-cache" as if it meant "don't cache" while in reality it means "don't return these cached elements without making sure they're up-to-date" At the same time as this change is made let's add test data for "no-store", which replaces the "no-cache" test data. Fixes: QTBUG-71896 Change-Id: Ieda98f3982884ccc839cac2420c777968c786f6e Reviewed-by: Timur Pocheptsov Reviewed-by: Mikhail Svetkin --- src/network/access/qabstractnetworkcache.cpp | 4 +-- src/network/access/qnetworkaccesscachebackend.cpp | 17 +++++++------ src/network/access/qnetworkreplyhttpimpl.cpp | 14 +++-------- .../tst_qabstractnetworkcache.cpp | 9 +++++-- .../access/qnetworkreply/tst_qnetworkreply.cpp | 29 +++++++++++++++++++++- 5 files changed, 49 insertions(+), 24 deletions(-) diff --git a/src/network/access/qabstractnetworkcache.cpp b/src/network/access/qabstractnetworkcache.cpp index 2b670b2cce..9afb99f23f 100644 --- a/src/network/access/qabstractnetworkcache.cpp +++ b/src/network/access/qabstractnetworkcache.cpp @@ -191,8 +191,8 @@ bool QNetworkCacheMetaData::isValid() const Some cache implementations can keep these cache items in memory for performance reasons, but for security reasons they should not be written to disk. - Specifically with http, documents marked with Pragma: no-cache, or have a Cache-control set to - no-store or no-cache or any https document that doesn't have "Cache-control: public" set will + Specifically with http, documents with Cache-control set to no-store or any + https document that doesn't have "Cache-control: public" set will set the saveToDisk to false. \sa setSaveToDisk() diff --git a/src/network/access/qnetworkaccesscachebackend.cpp b/src/network/access/qnetworkaccesscachebackend.cpp index 0c9a88596d..22fdc5bb0b 100644 --- a/src/network/access/qnetworkaccesscachebackend.cpp +++ b/src/network/access/qnetworkaccesscachebackend.cpp @@ -87,15 +87,16 @@ bool QNetworkAccessCacheBackend::sendCacheContents() setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, attributes.value(QNetworkRequest::HttpReasonPhraseAttribute)); // set the raw headers - QNetworkCacheMetaData::RawHeaderList rawHeaders = item.rawHeaders(); - QNetworkCacheMetaData::RawHeaderList::ConstIterator it = rawHeaders.constBegin(), - end = rawHeaders.constEnd(); - for ( ; it != end; ++it) { - if (it->first.toLower() == "cache-control" && - it->second.toLower().contains("must-revalidate")) { - return false; + const QNetworkCacheMetaData::RawHeaderList rawHeaders = item.rawHeaders(); + for (const auto &header : rawHeaders) { + if (header.first.toLower() == "cache-control") { + const QByteArray cacheControlValue = header.second.toLower(); + if (cacheControlValue.contains("must-revalidate") + || cacheControlValue.contains("no-cache")) { + return false; + } } - setRawHeader(it->first, it->second); + setRawHeader(header.first, header.second); } // handle a possible redirect diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index d4d3a21a7a..2d7649fa61 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -524,6 +524,8 @@ bool QNetworkReplyHttpImplPrivate::loadFromCacheIfAllowed(QHttpNetworkRequest &h QHash cacheControl = parseHttpOptionHeader(it->second); if (cacheControl.contains("must-revalidate")) return false; + if (cacheControl.contains("no-cache")) + return false; } QDateTime currentDateTime = QDateTime::currentDateTimeUtc(); @@ -1730,18 +1732,8 @@ QNetworkCacheMetaData QNetworkReplyHttpImplPrivate::fetchCacheMetaData(const QNe if (httpRequest.operation() == QHttpNetworkRequest::Get) { canDiskCache = true; - // 14.32 - // HTTP/1.1 caches SHOULD treat "Pragma: no-cache" as if the client - // had sent "Cache-Control: no-cache". - it = cacheHeaders.findRawHeader("pragma"); - if (it != cacheHeaders.rawHeaders.constEnd() - && it->second == "no-cache") - canDiskCache = false; - // HTTP/1.1. Check the Cache-Control header - if (cacheControl.contains("no-cache")) - canDiskCache = false; - else if (cacheControl.contains("no-store")) + if (cacheControl.contains("no-store")) canDiskCache = false; // responses to POST might be cacheable diff --git a/tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp b/tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp index 0da42b8b87..b8d9adf7a1 100644 --- a/tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp +++ b/tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp @@ -251,9 +251,14 @@ void tst_QAbstractNetworkCache::cacheControl_data() QTest::newRow("200-1") << QNetworkRequest::PreferNetwork << "httpcachetest_cachecontrol-expire.cgi" << false; QTest::newRow("200-2") << QNetworkRequest::AlwaysNetwork << "httpcachetest_cachecontrol.cgi?no-cache" << AlwaysFalse; - QTest::newRow("200-3") << QNetworkRequest::PreferNetwork << "httpcachetest_cachecontrol.cgi?no-cache" << false; + QTest::newRow("200-3") << QNetworkRequest::PreferNetwork << "httpcachetest_cachecontrol.cgi?no-cache" << true; QTest::newRow("200-4") << QNetworkRequest::AlwaysCache << "httpcachetest_cachecontrol.cgi?no-cache" << false; - QTest::newRow("200-5") << QNetworkRequest::PreferCache << "httpcachetest_cachecontrol.cgi?no-cache" << false; + QTest::newRow("200-5") << QNetworkRequest::PreferCache << "httpcachetest_cachecontrol.cgi?no-cache" << true; + + QTest::newRow("200-6") << QNetworkRequest::AlwaysNetwork << "httpcachetest_cachecontrol.cgi?no-store" << AlwaysFalse; + QTest::newRow("200-7") << QNetworkRequest::PreferNetwork << "httpcachetest_cachecontrol.cgi?no-store" << false; + QTest::newRow("200-8") << QNetworkRequest::AlwaysCache << "httpcachetest_cachecontrol.cgi?no-store" << false; + QTest::newRow("200-9") << QNetworkRequest::PreferCache << "httpcachetest_cachecontrol.cgi?no-store" << false; QTest::newRow("304-0") << QNetworkRequest::PreferNetwork << "httpcachetest_cachecontrol.cgi?max-age=1000" << true; diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 30b41da515..3876621983 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -3959,7 +3959,7 @@ void tst_QNetworkReply::ioGetFromHttpWithCache_data() "HTTP/1.0 200\r\n" "Connection: keep-alive\r\n" "Content-Type: text/plain\r\n" - "Cache-control: no-cache\r\n" + "Cache-control: no-store\r\n" "Content-length: 8\r\n" "\r\n" "Reloaded"; @@ -3985,6 +3985,33 @@ void tst_QNetworkReply::ioGetFromHttpWithCache_data() content.second = "Not-reloaded"; content.first.setLastModified(past); + // "no-cache" + rawHeaders.clear(); + rawHeaders << QNetworkCacheMetaData::RawHeader("Date", QLocale::c().toString(past, dateFormat).toLatin1()) + << QNetworkCacheMetaData::RawHeader("Cache-control", "no-cache"); + content.first.setRawHeaders(rawHeaders); + content.first.setLastModified(past); + content.first.setExpirationDate(future); + + // "no-cache" does not mean "no cache", just that we must consult remote first + QTest::newRow("no-cache,200,always-network") + << reply200 << "Reloaded" << content << int(QNetworkRequest::AlwaysNetwork) << QStringList() << false << true; + QTest::newRow("no-cache,200,prefer-network") + << reply200 << "Reloaded" << content << int(QNetworkRequest::PreferNetwork) << QStringList() << false << true; + QTest::newRow("no-cache,200,prefer-cache") + << reply200 << "Reloaded" << content << int(QNetworkRequest::PreferCache) << QStringList() << false << true; + // We're not allowed by the spec to deliver cached data without checking if it is still + // up-to-date. + QTest::newRow("no-cache,200,always-cache") + << reply200 << QString() << content << int(QNetworkRequest::AlwaysCache) << QStringList() << false << false; + + QTest::newRow("no-cache,304,prefer-network") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferNetwork) << QStringList() << true << true; + QTest::newRow("no-cache,304,prefer-cache") + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << QStringList() << true << true; + QTest::newRow("no-cache,304,always-cache") + << reply304 << QString() << content << int(QNetworkRequest::AlwaysCache) << QStringList() << false << false; + // // Set to expired // -- cgit v1.2.3 From 2f97a050bc43a7cdbee3219b7cfc4d703ef0a37e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 22 Mar 2019 14:31:07 +0100 Subject: Add explanatory comment to QWindowPrivate::resizeAutomatic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Amends a1c37462eebddf4ad7bc3192f1f3e9a3f7292b19. Task-number: QTBUG-74176 Change-Id: I24fa3e5d88e53e7efb8923fb4c55615a4f90abea Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qwindow_p.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index af1233a9e2..5103d97c6d 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -181,6 +181,10 @@ public: bool receivedExpose; PositionPolicy positionPolicy; bool positionAutomatic; + // resizeAutomatic suppresses resizing by QPlatformWindow::initialGeometry(). + // It also indicates that width/height=0 is acceptable (for example, for + // the QRollEffect widget) and is thus not cleared in setGeometry(). + // An alternative approach might be using -1,-1 as a default size. bool resizeAutomatic; Qt::ScreenOrientation contentOrientation; qreal opacity; -- cgit v1.2.3 From d8323376670fdc65e4a4a654def8b78b650bdbe7 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 13 Mar 2019 10:34:46 +0100 Subject: Fix detection of QMAKE_DEFAULT{INC|LIB}DIRS for gcc cross-builds The --sysroot flag is added to QMAKE_CXXFLAGS by the gcc-sysroot feature. However, when the makespec is reloaded, it can overwrite QMAKE_CXXFLAGS. Save QMAKE_CXXFLAGS before re-loading the mkspec and add it to the value from the makespec, like we do for CONFIG. Fixes: QTBUG-74326 Change-Id: Ie1fb713e2ffc9641d6db8c682bc5175581cd5b5f Reviewed-by: Oswald Buddenhagen Reviewed-by: Kai Koehne --- configure.pri | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/configure.pri b/configure.pri index 629ca78ff1..131aa868c2 100644 --- a/configure.pri +++ b/configure.pri @@ -448,7 +448,9 @@ defineTest(reloadSpec) { $$[QT_HOST_DATA/src]/mkspecs/features/mac/toolchain.prf \ $$[QT_HOST_DATA/src]/mkspecs/features/toolchain.prf - _SAVED_CONFIG = $$CONFIG + saved_variables = CONFIG QMAKE_CXXFLAGS + for (name, saved_variables): \ + _SAVED_$$name = $$eval($$name) load(spec_pre) # qdevice.pri gets written too late (and we can't write it early # enough, as it's populated in stages, with later ones depending @@ -457,7 +459,8 @@ defineTest(reloadSpec) { eval($$l) include($$QMAKESPEC/qmake.conf) load(spec_post) - CONFIG += $$_SAVED_CONFIG + for (name, saved_variables): \ + $$name += $$eval(_SAVED_$$name) load(default_pre) # ensure pristine environment for configuration. again. -- cgit v1.2.3 From be6c70ed7f9a5fed98d44f9993492ab9d2fc16df Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 19 Mar 2019 13:34:52 +0100 Subject: macOS: Don't scale advances to 0 when stretch is AnyStretch If the stretch is set to AnyStretch, then this is taken to mean we should accept the font as it is. But on mac, there is a special code path to scale the advances since the shaper doesn't do it for us, and this neglected to check the stretch, thus it would scale the advances by 0%. This happened when loading a file directly in QRawFont and using this in a QTextLayout, since no part of the code path will attempt to calculate the stretch in that case. Reproducible in q3dsviewer in Qt 3D Runtime 2.3. Task-number: QT3DS-3132 Change-Id: I8f934f3fac41bf7a93c01cca0416d44003119907 Reviewed-by: Lars Knoll Reviewed-by: Konstantin Ritt Reviewed-by: Allan Sandfeld Jensen --- src/gui/text/qtextengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index a83ef95c79..22c93d7ec2 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1754,7 +1754,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, #ifdef Q_OS_DARWIN if (actualFontEngine->type() == QFontEngine::Mac) { - if (actualFontEngine->fontDef.stretch != 100) { + if (actualFontEngine->fontDef.stretch != 100 && actualFontEngine->fontDef.stretch != QFont::AnyStretch) { QFixed stretch = QFixed(int(actualFontEngine->fontDef.stretch)) / QFixed(100); for (uint i = 0; i < num_glyphs; ++i) g.advances[i] *= stretch; -- cgit v1.2.3 From aec284dfc9179088e34fcb7e4bc9cbce71cb68db Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Mon, 25 Mar 2019 10:17:21 +0100 Subject: Doc: mention what is the suggested replacement for QSignalMapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I0f230c8b59eae4b2b63a73b8223ed99545be44ec Reviewed-by: Jędrzej Nowacki --- src/corelib/kernel/qsignalmapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qsignalmapper.cpp b/src/corelib/kernel/qsignalmapper.cpp index d56965281e..02a1281f92 100644 --- a/src/corelib/kernel/qsignalmapper.cpp +++ b/src/corelib/kernel/qsignalmapper.cpp @@ -61,7 +61,7 @@ public: /*! \class QSignalMapper \inmodule QtCore - \obsolete + \obsolete The recommended solution is connecting the signal to a lambda. \brief The QSignalMapper class bundles signals from identifiable senders. \ingroup objectmodel -- cgit v1.2.3 From efb74002c5da514eac31e0c11cefcdc02518db66 Mon Sep 17 00:00:00 2001 From: Yan Shapochnik Date: Thu, 21 Mar 2019 15:17:44 -0400 Subject: macOS: Use the correct text color for QPalette::ButtonText color role MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the text color displayed in the QToolBar on macOS Mojave dark mode Change-Id: Ic4415295e314a8fc1c4fbb58964386e0563b8d44 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoasystemsettings.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm index aef2c6cf48..9b6dc94d33 100644 --- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm +++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm @@ -158,10 +158,13 @@ QHash qt_mac_createRolePalettes() pal.setColor(QPalette::Inactive, QPalette::WindowText, qc); pal.setColor(QPalette::Active, QPalette::HighlightedText, qc); pal.setColor(QPalette::Inactive, QPalette::HighlightedText, qc); + pal.setColor(QPalette::Active, QPalette::ButtonText, qc); + pal.setColor(QPalette::Inactive, QPalette::ButtonText, qc); qc = qt_mac_toQColor(mac_widget_colors[i].inactive); pal.setColor(QPalette::Disabled, QPalette::Text, qc); pal.setColor(QPalette::Disabled, QPalette::WindowText, qc); pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc); + pal.setColor(QPalette::Disabled, QPalette::ButtonText, qc); } if (mac_widget_colors[i].paletteRole == QPlatformTheme::MenuPalette || mac_widget_colors[i].paletteRole == QPlatformTheme::MenuBarPalette) { -- cgit v1.2.3 From 2fedce8ed8451fd9b14bc214dc26e79b0d5ab7bd Mon Sep 17 00:00:00 2001 From: Yan Shapochnik Date: Thu, 21 Mar 2019 15:33:20 -0400 Subject: QMacStyle: Fix QTabWidget document mode on macOS Mojave dark mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix styling and positioning of QTabWidget tabs on macOS Mojave while using dark mode Change-Id: Ibe0c90b7625c4f4ff895083fefaade74305ba0ea Reviewed-by: Morten Johan Sørvig --- src/plugins/styles/mac/qmacstyle_mac.mm | 86 ++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 24 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 979f70ece5..5cb945a46c 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -356,15 +356,44 @@ static const qreal titleBarButtonSpacing = 8; // active: window is active // selected: tab is selected // hovered: tab is hovered -static const QColor tabBarTabBackgroundActive(190, 190, 190); -static const QColor tabBarTabBackgroundActiveHovered(178, 178, 178); -static const QColor tabBarTabBackgroundActiveSelected(211, 211, 211); -static const QColor tabBarTabBackground(227, 227, 227); -static const QColor tabBarTabBackgroundSelected(246, 246, 246); -static const QColor tabBarTabLineActive(160, 160, 160); -static const QColor tabBarTabLineActiveHovered(150, 150, 150); -static const QColor tabBarTabLine(210, 210, 210); -static const QColor tabBarTabLineSelected(189, 189, 189); +bool isDarkMode() { return qt_mac_applicationIsInDarkMode(); } + +static const QColor lightTabBarTabBackgroundActive(190, 190, 190); +static const QColor darkTabBarTabBackgroundActive(38, 38, 38); +static const QColor tabBarTabBackgroundActive() { return isDarkMode() ? darkTabBarTabBackgroundActive : lightTabBarTabBackgroundActive; } + +static const QColor lightTabBarTabBackgroundActiveHovered(178, 178, 178); +static const QColor darkTabBarTabBackgroundActiveHovered(32, 32, 32); +static const QColor tabBarTabBackgroundActiveHovered() { return isDarkMode() ? darkTabBarTabBackgroundActiveHovered : lightTabBarTabBackgroundActiveHovered; } + +static const QColor lightTabBarTabBackgroundActiveSelected(211, 211, 211); +static const QColor darkTabBarTabBackgroundActiveSelected(52, 52, 52); +static const QColor tabBarTabBackgroundActiveSelected() { return isDarkMode() ? darkTabBarTabBackgroundActiveSelected : lightTabBarTabBackgroundActiveSelected; } + +static const QColor lightTabBarTabBackground(227, 227, 227); +static const QColor darkTabBarTabBackground(38, 38, 38); +static const QColor tabBarTabBackground() { return isDarkMode() ? darkTabBarTabBackground : lightTabBarTabBackground; } + +static const QColor lightTabBarTabBackgroundSelected(246, 246, 246); +static const QColor darkTabBarTabBackgroundSelected(52, 52, 52); +static const QColor tabBarTabBackgroundSelected() { return isDarkMode() ? darkTabBarTabBackgroundSelected : lightTabBarTabBackgroundSelected; } + +static const QColor lightTabBarTabLineActive(160, 160, 160); +static const QColor darkTabBarTabLineActive(90, 90, 90); +static const QColor tabBarTabLineActive() { return isDarkMode() ? darkTabBarTabLineActive : lightTabBarTabLineActive; } + +static const QColor lightTabBarTabLineActiveHovered(150, 150, 150); +static const QColor darkTabBarTabLineActiveHovered(90, 90, 90); +static const QColor tabBarTabLineActiveHovered() { return isDarkMode() ? darkTabBarTabLineActiveHovered : lightTabBarTabLineActiveHovered; } + +static const QColor lightTabBarTabLine(210, 210, 210); +static const QColor darkTabBarTabLine(90, 90, 90); +static const QColor tabBarTabLine() { return isDarkMode() ? darkTabBarTabLine : lightTabBarTabLine; } + +static const QColor lightTabBarTabLineSelected(189, 189, 189); +static const QColor darkTabBarTabLineSelected(90, 90, 90); +static const QColor tabBarTabLineSelected() { return isDarkMode() ? darkTabBarTabLineSelected : lightTabBarTabLineSelected; } + static const QColor tabBarCloseButtonBackgroundHovered(162, 162, 162); static const QColor tabBarCloseButtonBackgroundPressed(153, 153, 153); static const QColor tabBarCloseButtonBackgroundSelectedHovered(192, 192, 192); @@ -561,7 +590,7 @@ void drawTabShape(QPainter *p, const QStyleOptionTab *tabOpt, bool isUnified, in const bool active = (tabOpt->state & QStyle::State_Active); const bool selected = (tabOpt->state & QStyle::State_Selected); - const QRect bodyRect(1, 1, width - 2, height - 2); + const QRect bodyRect(1, 2, width - 2, height - 3); const QRect topLineRect(1, 0, width - 2, 1); const QRect bottomLineRect(1, height - 1, width - 2, 1); if (selected) { @@ -572,27 +601,27 @@ void drawTabShape(QPainter *p, const QStyleOptionTab *tabOpt, bool isUnified, in p->fillRect(tabRect, QColor(Qt::transparent)); p->restore(); } else if (active) { - p->fillRect(bodyRect, tabBarTabBackgroundActiveSelected); + p->fillRect(bodyRect, tabBarTabBackgroundActiveSelected()); // top line - p->fillRect(topLineRect, tabBarTabLineSelected); + p->fillRect(topLineRect, tabBarTabLineSelected()); } else { - p->fillRect(bodyRect, tabBarTabBackgroundSelected); + p->fillRect(bodyRect, tabBarTabBackgroundSelected()); } } else { // when the mouse is over non selected tabs they get a new color const bool hover = (tabOpt->state & QStyle::State_MouseOver); if (hover) { // fill body - p->fillRect(bodyRect, tabBarTabBackgroundActiveHovered); + p->fillRect(bodyRect, tabBarTabBackgroundActiveHovered()); // bottom line - p->fillRect(bottomLineRect, tabBarTabLineActiveHovered); + p->fillRect(bottomLineRect, isDarkMode() ? QColor(Qt::black) : tabBarTabLineActiveHovered()); } } // separator lines between tabs const QRect leftLineRect(0, 1, 1, height - 2); const QRect rightLineRect(width - 1, 1, 1, height - 2); - const QColor separatorLineColor = active ? tabBarTabLineActive : tabBarTabLine; + const QColor separatorLineColor = active ? tabBarTabLineActive() : tabBarTabLine(); p->fillRect(leftLineRect, separatorLineColor); p->fillRect(rightLineRect, separatorLineColor); } @@ -612,17 +641,20 @@ void drawTabBase(QPainter *p, const QStyleOptionTabBarBase *tbb, const QWidget * // fill body const QRect bodyRect(0, 1, width, height - 1); - const QColor bodyColor = active ? tabBarTabBackgroundActive : tabBarTabBackground; + const QColor bodyColor = active ? tabBarTabBackgroundActive() : tabBarTabBackground(); p->fillRect(bodyRect, bodyColor); // top line const QRect topLineRect(0, 0, width, 1); - const QColor topLineColor = active ? tabBarTabLineActive : tabBarTabLine; + const QColor topLineColor = active ? tabBarTabLineActive() : tabBarTabLine(); p->fillRect(topLineRect, topLineColor); // bottom line const QRect bottomLineRect(0, height - 1, width, 1); - const QColor bottomLineColor = active ? tabBarTabLineActive : tabBarTabLine; + bool isDocument = false; + if (const QTabBar *tabBar = qobject_cast(w)) + isDocument = tabBar->documentMode(); + const QColor bottomLineColor = isDocument && isDarkMode() ? QColor(Qt::black) : active ? tabBarTabLineActive() : tabBarTabLine(); p->fillRect(bottomLineRect, bottomLineColor); } #endif @@ -3542,7 +3574,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter if (tbstyle == Qt::ToolButtonTextOnly || (tbstyle != Qt::ToolButtonTextOnly && !down)) { QPen pen = p->pen(); - QColor light = down ? Qt::black : Qt::white; + QColor light = down || isDarkMode() ? Qt::black : Qt::white; light.setAlphaF(0.375f); p->setPen(light); p->drawText(cr.adjusted(0, 1, 0, 1), alignment, tb->text); @@ -3964,6 +3996,11 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter if (!tabBar->tabTextColor(tabBar->currentIndex()).isValid()) myTab.palette.setColor(QPalette::WindowText, Qt::white); + if (myTab.documentMode && isDarkMode()) { + bool active = (myTab.state & State_Selected) && (myTab.state & State_Active); + myTab.palette.setColor(QPalette::WindowText, active ? Qt::white : Qt::gray); + } + int heightOffset = 0; if (verticalTabs) { heightOffset = -1; @@ -4450,16 +4487,17 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter p->fillRect(opt->rect, linearGrad); p->save(); + QRect toolbarRect = isDarkMode ? opt->rect.adjusted(0, 0, 0, 1) : opt->rect; if (opt->state & State_Horizontal) { p->setPen(isDarkMode ? darkModeSeparatorLine : mainWindowGradientBegin.lighter(114)); - p->drawLine(opt->rect.topLeft(), opt->rect.topRight()); + p->drawLine(toolbarRect.topLeft(), toolbarRect.topRight()); p->setPen(isDarkMode ? darkModeSeparatorLine :mainWindowGradientEnd.darker(114)); - p->drawLine(opt->rect.bottomLeft(), opt->rect.bottomRight()); + p->drawLine(toolbarRect.bottomLeft(), toolbarRect.bottomRight()); } else { p->setPen(isDarkMode ? darkModeSeparatorLine : mainWindowGradientBegin.lighter(114)); - p->drawLine(opt->rect.topLeft(), opt->rect.bottomLeft()); + p->drawLine(toolbarRect.topLeft(), toolbarRect.bottomLeft()); p->setPen(isDarkMode ? darkModeSeparatorLine : mainWindowGradientEnd.darker(114)); - p->drawLine(opt->rect.topRight(), opt->rect.bottomRight()); + p->drawLine(toolbarRect.topRight(), toolbarRect.bottomRight()); } p->restore(); -- cgit v1.2.3 From 63156e20629a087a761cbe34b110681267d58a93 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 12 Mar 2019 10:53:35 +0100 Subject: tst_qmake: Add XFAILing test Task-number: QTBUG-74265 Change-Id: I916eaf7b64a8777bf2523ddf9da65226d7d06417 Reviewed-by: Oliver Wolff --- tests/auto/tools/qmake/testcompiler.cpp | 8 ++-- tests/auto/tools/qmake/testcompiler.h | 5 ++- .../tools/qmake/testdata/simple_app/simple_app.pro | 5 +++ tests/auto/tools/qmake/tst_qmake.cpp | 45 +++++++++++++++++++++- 4 files changed, 58 insertions(+), 5 deletions(-) diff --git a/tests/auto/tools/qmake/testcompiler.cpp b/tests/auto/tools/qmake/testcompiler.cpp index 3276d97354..0a7ba3b40b 100644 --- a/tests/auto/tools/qmake/testcompiler.cpp +++ b/tests/auto/tools/qmake/testcompiler.cpp @@ -31,7 +31,7 @@ #include #include -static QString targetName( BuildType buildMode, const QString& target, const QString& version ) +QString TestCompiler::targetName(BuildType buildMode, const QString& target, const QString& version) { Q_UNUSED(version); QString targetName = target; @@ -257,7 +257,8 @@ bool TestCompiler::qmakeProject( const QString &workDir, const QString &proName return runCommand(qmakeCmd_, QStringList() << "-project" << "-o" << projectFile << "DESTDIR=./"); } -bool TestCompiler::qmake( const QString &workDir, const QString &proName, const QString &buildDir ) +bool TestCompiler::qmake(const QString &workDir, const QString &proName, const QString &buildDir, + const QStringList &additionalArguments) { QDir D; D.setCurrent( workDir ); @@ -274,7 +275,8 @@ bool TestCompiler::qmake( const QString &workDir, const QString &proName, const makeFile += "Makefile"; // Now start qmake and generate the makefile - return runCommand(qmakeCmd_, QStringList(qmakeArgs_) << projectFile << "-o" << makeFile); + return runCommand(qmakeCmd_, QStringList(qmakeArgs_) << projectFile << "-o" << makeFile + << additionalArguments); } bool TestCompiler::make( const QString &workPath, const QString &target, bool expectFail ) diff --git a/tests/auto/tools/qmake/testcompiler.h b/tests/auto/tools/qmake/testcompiler.h index d3fe6d88f8..50232669c0 100644 --- a/tests/auto/tools/qmake/testcompiler.h +++ b/tests/auto/tools/qmake/testcompiler.h @@ -49,6 +49,8 @@ public: void resetEnvironment(); void addToEnvironment( QString varAssignment ); + static QString targetName(BuildType buildMode, const QString& target, const QString& version); + // executes a make clean in the specified workPath bool makeClean( const QString &workPath ); // executes a make dist clean in the specified workPath @@ -56,7 +58,8 @@ public: // executes a qmake -project on the specified workDir bool qmakeProject( const QString &workDir, const QString &proName ); // executes a qmake on proName in the specified workDir, output goes to buildDir or workDir if it's null - bool qmake( const QString &workDir, const QString &proName, const QString &buildDir = QString() ); + bool qmake(const QString &workDir, const QString &proName, const QString &buildDir = QString(), + const QStringList &additionalArguments = QStringList()); // executes a make in the specified workPath, with an optional target (eg. install) bool make( const QString &workPath, const QString &target = QString(), bool expectFail = false ); // checks if the executable exists in destDir diff --git a/tests/auto/tools/qmake/testdata/simple_app/simple_app.pro b/tests/auto/tools/qmake/testdata/simple_app/simple_app.pro index 0e78a91f46..f089ac14fc 100644 --- a/tests/auto/tools/qmake/testdata/simple_app/simple_app.pro +++ b/tests/auto/tools/qmake/testdata/simple_app/simple_app.pro @@ -5,3 +5,8 @@ SOURCES = test_file.cpp \ RESOURCES = test.qrc TARGET = "simple app" DESTDIR = "dest dir" + +target.path = $$OUT_PWD/dist +INSTALLS += target + +!build_pass:msvc:CONFIG(debug, debug|release):message("check for pdb, please") diff --git a/tests/auto/tools/qmake/tst_qmake.cpp b/tests/auto/tools/qmake/tst_qmake.cpp index 2b822e682f..1eaf66311c 100644 --- a/tests/auto/tools/qmake/tst_qmake.cpp +++ b/tests/auto/tools/qmake/tst_qmake.cpp @@ -58,6 +58,7 @@ private slots: void simple_app(); void simple_app_shadowbuild(); void simple_app_shadowbuild2(); + void simple_app_versioned(); void simple_lib(); void simple_dll(); void subdirs(); @@ -173,10 +174,15 @@ void tst_qmake::simple_app() { QString workDir = base_path + "/testdata/simple_app"; QString destDir = workDir + "/dest dir"; + QString installDir = workDir + "/dist"; - QVERIFY( test_compiler.qmake( workDir, "simple_app" )); + QVERIFY( test_compiler.qmake( workDir, "simple_app", QString() )); QVERIFY( test_compiler.make( workDir )); QVERIFY( test_compiler.exists( destDir, "simple app", Exe, "1.0.0" )); + + QVERIFY(test_compiler.make(workDir, "install")); + QVERIFY(test_compiler.exists(installDir, "simple app", Exe, "1.0.0")); + QVERIFY( test_compiler.makeClean( workDir )); QVERIFY( test_compiler.exists( destDir, "simple app", Exe, "1.0.0" )); // Should still exist after a make clean QVERIFY( test_compiler.makeDistClean( workDir )); @@ -216,6 +222,43 @@ void tst_qmake::simple_app_shadowbuild2() QVERIFY( test_compiler.removeMakefile( buildDir ) ); } +void tst_qmake::simple_app_versioned() +{ + QString workDir = base_path + "/testdata/simple_app"; + QString buildDir = base_path + "/testdata/simple_app_versioned_build"; + QString destDir = buildDir + "/dest dir"; + QString installDir = buildDir + "/dist"; + + QString version = "4.5.6"; + QVERIFY(test_compiler.qmake(workDir, "simple_app", buildDir, QStringList{ "VERSION=" + version })); + QString qmakeOutput = test_compiler.commandOutput(); + QVERIFY(test_compiler.make(buildDir)); + QVERIFY(test_compiler.exists(destDir, "simple app", Exe, version)); + + QString pdbFilePath; + bool checkPdb = qmakeOutput.contains("Project MESSAGE: check for pdb, please"); + if (checkPdb) { + QString targetBase = QFileInfo(TestCompiler::targetName(Exe, "simple app", version)) + .completeBaseName(); + pdbFilePath = destDir + '/' + targetBase + ".pdb"; + QVERIFY2(QFile::exists(pdbFilePath), qPrintable(pdbFilePath)); + QVERIFY(test_compiler.make(buildDir, "install")); + QString installedPdbFilePath = installDir + '/' + targetBase + ".pdb"; + QEXPECT_FAIL("", "QTBUG-74265", Continue); + QVERIFY2(QFile::exists(installedPdbFilePath), qPrintable(installedPdbFilePath)); + } + + QVERIFY(test_compiler.makeClean(buildDir)); + QVERIFY(test_compiler.exists(destDir, "simple app", Exe, version)); + QVERIFY(test_compiler.makeDistClean(buildDir)); + QVERIFY(!test_compiler.exists(destDir, "simple app", Exe, version)); + if (checkPdb) { + QEXPECT_FAIL("", "QTBUG-74265", Continue); + QVERIFY(!QFile::exists(pdbFilePath)); + } + QVERIFY(test_compiler.removeMakefile(buildDir)); +} + void tst_qmake::simple_dll() { QString workDir = base_path + "/testdata/simple_dll"; -- cgit v1.2.3 From f4ac50a8389597827fd7fb952617b78aa4b113c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 15 Mar 2019 15:04:59 +0100 Subject: =?UTF-8?q?wasm:=20Use=20common=20=E2=80=9Cqt=E2=80=9D=20prefix=20?= =?UTF-8?q?for=20exported=20functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevent namespace collisions and make sure Qt functions are grouped together. Change-Id: I217188ee93e4300e273d10a79d6014179fc5a1ef Reviewed-by: Lorn Potter --- src/corelib/platform/wasm/qstdweb.cpp | 2 +- src/network/access/qnetworkreplywasmimpl.cpp | 22 ++++++------- src/plugins/platforms/wasm/qwasmclipboard.cpp | 38 +++++++++++----------- .../platforms/wasm/qwasmeventtranslator.cpp | 6 ++-- src/plugins/platforms/wasm/qwasmintegration.cpp | 8 ++--- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/corelib/platform/wasm/qstdweb.cpp b/src/corelib/platform/wasm/qstdweb.cpp index 1afd91d860..198ce897ca 100644 --- a/src/corelib/platform/wasm/qstdweb.cpp +++ b/src/corelib/platform/wasm/qstdweb.cpp @@ -227,7 +227,7 @@ std::string EventCallback::contextPropertyName(const std::string &eventName) return std::string("data-qtEventCallbackContext") + eventName; } -EMSCRIPTEN_BINDINGS(QtStdwebCalback) { +EMSCRIPTEN_BINDINGS(qtStdwebCalback) { emscripten::function("qtStdWebEventCallbackActivate", &EventCallback::activate); } diff --git a/src/network/access/qnetworkreplywasmimpl.cpp b/src/network/access/qnetworkreplywasmimpl.cpp index f347cc0479..bb6ef07741 100644 --- a/src/network/access/qnetworkreplywasmimpl.cpp +++ b/src/network/access/qnetworkreplywasmimpl.cpp @@ -117,7 +117,7 @@ static void q_loadCallback(val event) val blob = xhr["response"]; val reader = val::global("FileReader").new_(); - reader.set("onload", val::module_property("QNetworkReplyWasmImplPrivate_readBinary")); + reader.set("onload", val::module_property("qt_QNetworkReplyWasmImplPrivate_readBinary")); reader.set("data-handler", xhr["data-handler"]); reader.call("readAsArrayBuffer", blob); @@ -174,12 +174,12 @@ static void q_readBinary(val event) QCoreApplication::processEvents(); } -EMSCRIPTEN_BINDINGS(network_module) { - function("QNetworkReplyWasmImplPrivate_requestErrorCallback", q_requestErrorCallback); - function("QNetworkReplyWasmImplPrivate_progressCallback", q_progressCallback); - function("QNetworkReplyWasmImplPrivate_loadCallback", q_loadCallback); - function("QNetworkReplyWasmImplPrivate_responseHeadersCallback", q_responseHeadersCallback); - function("QNetworkReplyWasmImplPrivate_readBinary", q_readBinary); +EMSCRIPTEN_BINDINGS(qtNetworkModule) { + function("qt_QNetworkReplyWasmImplPrivate_requestErrorCallback", q_requestErrorCallback); + function("qt_QNetworkReplyWasmImplPrivate_progressCallback", q_progressCallback); + function("qt_QNetworkReplyWasmImplPrivate_loadCallback", q_loadCallback); + function("qt_QNetworkReplyWasmImplPrivate_responseHeadersCallback", q_responseHeadersCallback); + function("qt_QNetworkReplyWasmImplPrivate_readBinary", q_readBinary); } QNetworkReplyWasmImplPrivate::QNetworkReplyWasmImplPrivate() @@ -332,10 +332,10 @@ void QNetworkReplyWasmImplPrivate::doSendRequest() m_xhr.call("open", verb, request.url().toString().toStdString()); - m_xhr.set("onerror", val::module_property("QNetworkReplyWasmImplPrivate_requestErrorCallback")); - m_xhr.set("onload", val::module_property("QNetworkReplyWasmImplPrivate_loadCallback")); - m_xhr.set("onprogress", val::module_property("QNetworkReplyWasmImplPrivate_progressCallback")); - m_xhr.set("onreadystatechange", val::module_property("QNetworkReplyWasmImplPrivate_responseHeadersCallback")); + m_xhr.set("onerror", val::module_property("qt_QNetworkReplyWasmImplPrivate_requestErrorCallback")); + m_xhr.set("onload", val::module_property("qt_QNetworkReplyWasmImplPrivate_loadCallback")); + m_xhr.set("onprogress", val::module_property("qt_QNetworkReplyWasmImplPrivate_progressCallback")); + m_xhr.set("onreadystatechange", val::module_property("qt_QNetworkReplyWasmImplPrivate_responseHeadersCallback")); m_xhr.set("data-handler", val(quintptr(reinterpret_cast(this)))); diff --git a/src/plugins/platforms/wasm/qwasmclipboard.cpp b/src/plugins/platforms/wasm/qwasmclipboard.cpp index 7a7b253b19..d4a1e4dd50 100644 --- a/src/plugins/platforms/wasm/qwasmclipboard.cpp +++ b/src/plugins/platforms/wasm/qwasmclipboard.cpp @@ -76,8 +76,8 @@ static void qClipboardCutTo(val event) } val module = val::global("Module"); - val clipdata = module.call("getClipboardData"); - val clipFormat = module.call("getClipboardFormat"); + val clipdata = module.call("qtGetClipboardData"); + val clipFormat = module.call("qtGetClipboardFormat"); event["clipboardData"].call("setData", clipFormat, clipdata); event.call("preventDefault"); } @@ -91,8 +91,8 @@ static void qClipboardCopyTo(val event) } val module = val::global("Module"); - val clipdata = module.call("getClipboardData"); - val clipFormat = module.call("getClipboardFormat"); + val clipdata = module.call("qtGetClipboardData"); + val clipFormat = module.call("qtGetClipboardFormat"); event["clipboardData"].call("setData", clipFormat, clipdata); event.call("preventDefault"); } @@ -101,7 +101,7 @@ static void qClipboardPasteTo(val event) { bool hasClipboardApi = QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi; val clipdata = hasClipboardApi ? - val::global("Module").call("getClipboardData") : + val::global("Module").call("qtGetClipboardData") : event["clipboardData"].call("getData", std::string("text")); const std::string data = clipdata.as(); @@ -113,14 +113,14 @@ static void qClipboardPasteTo(val event) } } -EMSCRIPTEN_BINDINGS(clipboard_module) { - function("getClipboardData", &getClipboardData); - function("getClipboardFormat", &getClipboardFormat); - function("pasteClipboardData", &pasteClipboardData); - function("qClipboardPromiseResolve", &qClipboardPromiseResolve); - function("qClipboardCutTo", &qClipboardCutTo); - function("qClipboardCopyTo", &qClipboardCopyTo); - function("qClipboardPasteTo", &qClipboardPasteTo); +EMSCRIPTEN_BINDINGS(qtClipboardModule) { + function("qtGetClipboardData", &getClipboardData); + function("qtGetClipboardFormat", &getClipboardFormat); + function("qtPasteClipboardData", &pasteClipboardData); + function("qtClipboardPromiseResolve", &qClipboardPromiseResolve); + function("qtClipboardCutTo", &qClipboardCutTo); + function("qtClipboardCopyTo", &qClipboardCopyTo); + function("qtClipboardPasteTo", &qClipboardPasteTo); } QWasmClipboard::QWasmClipboard() @@ -200,11 +200,11 @@ void QWasmClipboard::installEventHandlers(const QString &canvasId) // Fallback path for browsers which do not support direct clipboard access val canvas = val::global(canvasId.toUtf8().constData()); canvas.call("addEventListener", std::string("cut"), - val::module_property("qClipboardCutTo")); + val::module_property("qtClipboardCutTo")); canvas.call("addEventListener", std::string("copy"), - val::module_property("qClipboardCopyTo")); + val::module_property("qtClipboardCopyTo")); canvas.call("addEventListener", std::string("paste"), - val::module_property("qClipboardPasteTo")); + val::module_property("qtClipboardPasteTo")); } void QWasmClipboard::readTextFromClipboard() @@ -212,7 +212,7 @@ void QWasmClipboard::readTextFromClipboard() if (QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) { val navigator = val::global("navigator"); val textPromise = navigator["clipboard"].call("readText"); - val readTextResolve = val::global("Module")["qClipboardPromiseResolve"]; + val readTextResolve = val::global("Module")["qtClipboardPromiseResolve"]; textPromise.call("then", readTextResolve); } } @@ -221,8 +221,8 @@ void QWasmClipboard::writeTextToClipboard() { if (QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) { val module = val::global("Module"); - val txt = module.call("getClipboardData"); - val format = module.call("getClipboardFormat"); + val txt = module.call("qtGetClipboardData"); + val format = module.call("qtGetClipboardFormat"); val navigator = val::global("navigator"); navigator["clipboard"].call("writeText", txt.as()); } diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index 63a764e741..1c4c8cb7e8 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -316,8 +316,8 @@ static void mouseWheelEvent(emscripten::val event) { } } -EMSCRIPTEN_BINDINGS(mouse_module) { - function("mouseWheelEvent", &mouseWheelEvent); +EMSCRIPTEN_BINDINGS(qtMouseModule) { + function("qtMouseWheelEvent", &mouseWheelEvent); } QWasmEventTranslator::QWasmEventTranslator(QWasmScreen *screen) @@ -358,7 +358,7 @@ void QWasmEventTranslator::initEventHandlers() emscripten::val::global(canvasId).call("addEventListener", std::string("wheel"), - val::module_property("mouseWheelEvent")); + val::module_property("qtMouseWheelEvent")); } } diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp index 486f4cb2b3..3b4800a787 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.cpp +++ b/src/plugins/platforms/wasm/qwasmintegration.cpp @@ -56,14 +56,14 @@ using namespace emscripten; QT_BEGIN_NAMESPACE -void browserBeforeUnload(emscripten::val) +static void browserBeforeUnload(emscripten::val) { QWasmIntegration::QWasmBrowserExit(); } -EMSCRIPTEN_BINDINGS(my_module) +EMSCRIPTEN_BINDINGS(qtQWasmIntegraton) { - function("browserBeforeUnload", &browserBeforeUnload); + function("qtBrowserBeforeUnload", &browserBeforeUnload); } QWasmIntegration *QWasmIntegration::s_instance; @@ -92,7 +92,7 @@ QWasmIntegration::QWasmIntegration() addScreen(canvasId); } - emscripten::val::global("window").set("onbeforeunload", val::module_property("browserBeforeUnload")); + emscripten::val::global("window").set("onbeforeunload", val::module_property("qtBrowserBeforeUnload")); } QWasmIntegration::~QWasmIntegration() -- cgit v1.2.3 From 998740c61961c0dc3e1296f0349c23846327aea0 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 22 Mar 2019 21:45:31 +0100 Subject: QDoubleSpinBox: reset size hint when prefix is set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QDoubleSpinBox did not resize when setPrefix() was called because the cached size hint was not reset. Fix it by resetting the cached size hints and update the geometry the same way it's done for QSpinBox::setPrefix(). Fixes: QTBUG-74520 Change-Id: I6f42a24ab0a4ce987ecbe1505a634d929474436b Reviewed-by: André Hartmann Reviewed-by: Friedemann Kleint Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qspinbox.cpp | 4 ++++ .../widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp | 12 ++++++++++++ tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp | 12 ++++++++++++ 3 files changed, 28 insertions(+) diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp index 7624b1ed3c..7d454c6359 100644 --- a/src/widgets/widgets/qspinbox.cpp +++ b/src/widgets/widgets/qspinbox.cpp @@ -728,6 +728,10 @@ void QDoubleSpinBox::setPrefix(const QString &prefix) d->prefix = prefix; d->updateEdit(); + + d->cachedSizeHint = QSize(); + d->cachedMinimumSizeHint = QSize(); // minimumSizeHint cares about the prefix + updateGeometry(); } /*! diff --git a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp index b1610c297d..b101f47bcd 100644 --- a/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp +++ b/tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp @@ -326,14 +326,26 @@ void tst_QDoubleSpinBox::setPrefixSuffix() QDoubleSpinBox spin(0); spin.setDecimals(decimals); + const QSize size1 = spin.sizeHint(); spin.setPrefix(prefix); + const QSize size2 = spin.sizeHint(); spin.setSuffix(suffix); + const QSize size3 = spin.sizeHint(); spin.setValue(value); if (show) spin.show(); QCOMPARE(spin.text(), expectedText); QCOMPARE(spin.cleanText(), expectedCleanText); + + if (!prefix.isEmpty() && !suffix.isEmpty()) { + QVERIFY(size1.width() < size2.width()); + QVERIFY(size2.width() < size3.width()); + spin.setSuffix(QString()); + QCOMPARE(spin.sizeHint(), size2); + spin.setPrefix(QString()); + QCOMPARE(spin.sizeHint(), size1); + } } void tst_QDoubleSpinBox::valueChangedHelper(const QString &text) diff --git a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp index 1d106f94f3..803b72f36e 100644 --- a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp +++ b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp @@ -462,8 +462,11 @@ void tst_QSpinBox::setPrefixSuffix() QFETCH(bool, show); QSpinBox spin(0); + const QSize size1 = spin.sizeHint(); spin.setPrefix(prefix); + const QSize size2 = spin.sizeHint(); spin.setSuffix(suffix); + const QSize size3 = spin.sizeHint(); spin.setValue(value); if (show) spin.show(); @@ -472,6 +475,15 @@ void tst_QSpinBox::setPrefixSuffix() QCOMPARE(spin.suffix(), suffix); QCOMPARE(spin.text(), expectedText); QCOMPARE(spin.cleanText(), expectedCleanText); + + if (!prefix.isEmpty() && !suffix.isEmpty()) { + QVERIFY(size1.width() < size2.width()); + QVERIFY(size2.width() < size3.width()); + spin.setSuffix(QString()); + QCOMPARE(spin.sizeHint(), size2); + spin.setPrefix(QString()); + QCOMPARE(spin.sizeHint(), size1); + } } void tst_QSpinBox::valueChangedHelper(const QString &text) -- cgit v1.2.3 From 3449042f5b6a112c9984ff49ee8e5fbdea597bae Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 22 Mar 2019 15:53:34 -0700 Subject: QMimeDatabase: allow building without our internal copy Saves 234kB of read-only data (when compressed with zstd) in QtCore, plus one load-time execution. With Zlib, the size was 315 kB. [ChangeLog][QtCore][QMimeDatabase] Added configure option -no-mimetype-database that tells Qt not to bundle its own copy of the XDG MIME database. If this option is passed, QMimeDatabase will only work if there's a system copy in $XDG_DATA_DIRS/mime. This option is useful for Linux distributions that ensure the data is always present. Change-Id: I1004b4b819774c4c9296fffd158e69c490e88fb6 Reviewed-by: David Faure --- src/corelib/configure.json | 7 +++++++ src/corelib/mimetypes/mimetypes.pri | 2 +- src/corelib/mimetypes/qmimeprovider.cpp | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/corelib/configure.json b/src/corelib/configure.json index ed31299603..b7eefb58c8 100644 --- a/src/corelib/configure.json +++ b/src/corelib/configure.json @@ -11,6 +11,7 @@ "icu": "boolean", "inotify": "boolean", "journald": "boolean", + "mimetype-database": "boolean", "pcre": { "type": "enum", "values": [ "qt", "system" ] }, "posix-ipc": { "type": "boolean", "name": "ipc_posix" }, "pps": { "type": "boolean", "name": "qqnx_pps" }, @@ -678,6 +679,11 @@ "condition": "features.textcodec", "output": [ "publicFeature", "feature" ] }, + "mimetype-database": { + "label": "Built-in copy of the MIME database", + "condition": "features.mimetype", + "output": [ "privateFeature" ] + }, "system-pcre2": { "label": "Using system PCRE2", "disable": "input.pcre == 'qt'", @@ -1048,6 +1054,7 @@ Please apply the patch corresponding to your Standard Library vendor, found in "glib", "iconv", "icu", + "mimetype-database", { "message": "Tracing backend", "type": "firstAvailableFeature", diff --git a/src/corelib/mimetypes/mimetypes.pri b/src/corelib/mimetypes/mimetypes.pri index 870b6c65a5..62bbe348e4 100644 --- a/src/corelib/mimetypes/mimetypes.pri +++ b/src/corelib/mimetypes/mimetypes.pri @@ -21,5 +21,5 @@ qtConfig(mimetype) { mimetypes/qmimeglobpattern.cpp \ mimetypes/qmimeprovider.cpp - RESOURCES += mimetypes/mimetypes.qrc + qtConfig(mimetype-database): RESOURCES += mimetypes/mimetypes.qrc } diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp index d5b8825972..37c8e3b157 100644 --- a/src/corelib/mimetypes/qmimeprovider.cpp +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -54,7 +54,9 @@ static void initResources() { +#if QT_CONFIG(mimetype_database) Q_INIT_RESOURCE(mimetypes); +#endif } QT_BEGIN_NAMESPACE -- cgit v1.2.3 From 1a8aa8186693d8549d0bca774fdb6ceb0b9ad850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 19 Mar 2019 11:58:39 +0100 Subject: Apple test logger: Handle test log messages without a context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We may get calls to the MessageTypes-overload of addMessage via e.g. qSkip, or other functions in QTestLog, so we have to implement the function. Change-Id: I9d58c73e93ca918c42448c246c37cc9ae6aa04de Reviewed-by: Joerg Bornemann Reviewed-by: Edward Welbourne Reviewed-by: Tor Arne Vestbø --- src/testlib/qappletestlogger.cpp | 130 ++++++++++++++++++++++++++++----------- src/testlib/qappletestlogger_p.h | 7 ++- 2 files changed, 98 insertions(+), 39 deletions(-) diff --git a/src/testlib/qappletestlogger.cpp b/src/testlib/qappletestlogger.cpp index 959ff6cf64..dfeadebdef 100644 --- a/src/testlib/qappletestlogger.cpp +++ b/src/testlib/qappletestlogger.cpp @@ -83,56 +83,56 @@ void QAppleTestLogger::leaveTestFunction() testFunctionActivity.leave(); } -typedef QPair IncidentClassification; -static IncidentClassification incidentTypeToClassification(QAbstractTestLogger::IncidentTypes type) +struct MessageData { - switch (type) { - case QAbstractTestLogger::Pass: - return IncidentClassification(QtInfoMsg, "pass"); - case QAbstractTestLogger::XFail: - return IncidentClassification(QtInfoMsg, "xfail"); - case QAbstractTestLogger::Fail: - return IncidentClassification(QtCriticalMsg, "fail"); - case QAbstractTestLogger::XPass: - return IncidentClassification(QtInfoMsg, "xpass"); - case QAbstractTestLogger::BlacklistedPass: - return IncidentClassification(QtWarningMsg, "bpass"); - case QAbstractTestLogger::BlacklistedFail: - return IncidentClassification(QtInfoMsg, "bfail"); - case QAbstractTestLogger::BlacklistedXPass: - return IncidentClassification(QtWarningMsg, "bxpass"); - case QAbstractTestLogger::BlacklistedXFail: - return IncidentClassification(QtInfoMsg, "bxfail"); + QtMsgType messageType = QtFatalMsg; + const char *categorySuffix = nullptr; + + void generateCategory(QTestCharBuffer *category) + { + if (categorySuffix) + QTest::qt_asprintf(category, "qt.test.%s", categorySuffix); + else + QTest::qt_asprintf(category, "qt.test"); } - return IncidentClassification(QtFatalMsg, nullptr); -} +}; + void QAppleTestLogger::addIncident(IncidentTypes type, const char *description, const char *file, int line) { - - IncidentClassification incidentClassification = incidentTypeToClassification(type); + MessageData messageData = [=]() { + switch (type) { + case QAbstractTestLogger::Pass: + return MessageData{QtInfoMsg, "pass"}; + case QAbstractTestLogger::XFail: + return MessageData{QtInfoMsg, "xfail"}; + case QAbstractTestLogger::Fail: + return MessageData{QtCriticalMsg, "fail"}; + case QAbstractTestLogger::XPass: + return MessageData{QtInfoMsg, "xpass"}; + case QAbstractTestLogger::BlacklistedPass: + return MessageData{QtWarningMsg, "bpass"}; + case QAbstractTestLogger::BlacklistedFail: + return MessageData{QtInfoMsg, "bfail"}; + case QAbstractTestLogger::BlacklistedXPass: + return MessageData{QtWarningMsg, "bxpass"}; + case QAbstractTestLogger::BlacklistedXFail: + return MessageData{QtInfoMsg, "bxfail"}; + } + Q_UNREACHABLE(); + }(); QTestCharBuffer category; - QTest::qt_asprintf(&category, "qt.test.%s", incidentClassification.second); - QMessageLogContext context(file, line, /* function = */ nullptr, category.data()); + messageData.generateCategory(&category); - QTestCharBuffer subsystemBuffer; - // It would be nice to have the data tag as part of the subsystem too, but that - // will for some tests results in hundreds of thousands of log objects being - // created, so we limit the subsystem to test functions, which we can hope - // are reasonably limited. - generateTestIdentifier(&subsystemBuffer, TestObject | TestFunction); - QString subsystem = QString::fromLatin1(subsystemBuffer.data()); + QMessageLogContext context(file, line, /* function = */ nullptr, category.data()); - // We still want the full identifier as part of the message though - QTestCharBuffer testIdentifier; - generateTestIdentifier(&testIdentifier); - QString message = QString::fromLatin1(testIdentifier.data()); + QString message = testIdentifier(); if (qstrlen(description)) message += QLatin1Char('\n') % QString::fromLatin1(description); - AppleUnifiedLogger::messageHandler(incidentClassification.first, context, message, subsystem); + AppleUnifiedLogger::messageHandler(messageData.messageType, context, message, subsystem()); } void QAppleTestLogger::addMessage(QtMsgType type, const QMessageLogContext &context, const QString &message) @@ -140,6 +140,62 @@ void QAppleTestLogger::addMessage(QtMsgType type, const QMessageLogContext &cont AppleUnifiedLogger::messageHandler(type, context, message); } +void QAppleTestLogger::addMessage(MessageTypes type, const QString &message, const char *file, int line) +{ + MessageData messageData = [=]() { + switch (type) { + case QAbstractTestLogger::Warn: + case QAbstractTestLogger::QWarning: + return MessageData{QtWarningMsg, nullptr}; + case QAbstractTestLogger::QDebug: + return MessageData{QtDebugMsg, nullptr}; + case QAbstractTestLogger::QSystem: + return MessageData{QtWarningMsg, "system"}; + case QAbstractTestLogger::QFatal: + return MessageData{QtFatalMsg, nullptr}; + case QAbstractTestLogger::Skip: + return MessageData{QtInfoMsg, "skip"}; + case QAbstractTestLogger::Info: + case QAbstractTestLogger::QInfo: + return MessageData{QtInfoMsg, nullptr}; + } + Q_UNREACHABLE(); + }(); + + QTestCharBuffer category; + messageData.generateCategory(&category); + + QMessageLogContext context(file, line, /* function = */ nullptr, category.data()); + QString msg = message; + + if (type == Skip) { + if (!message.isNull()) + msg.prepend(testIdentifier() + QLatin1Char('\n')); + else + msg = testIdentifier(); + } + + AppleUnifiedLogger::messageHandler(messageData.messageType, context, msg, subsystem()); +} + +QString QAppleTestLogger::subsystem() const +{ + QTestCharBuffer buffer; + // It would be nice to have the data tag as part of the subsystem too, but that + // will for some tests result in hundreds of thousands of log objects being + // created, so we limit the subsystem to test functions, which we can hope + // are reasonably limited. + generateTestIdentifier(&buffer, TestObject | TestFunction); + return QString::fromLatin1(buffer.data()); +} + +QString QAppleTestLogger::testIdentifier() const +{ + QTestCharBuffer buffer; + generateTestIdentifier(&buffer); + return QString::fromLatin1(buffer.data()); +} + #endif // QT_USE_APPLE_UNIFIED_LOGGING QT_END_NAMESPACE diff --git a/src/testlib/qappletestlogger_p.h b/src/testlib/qappletestlogger_p.h index 4217f4e6a2..62c6d95c5a 100644 --- a/src/testlib/qappletestlogger_p.h +++ b/src/testlib/qappletestlogger_p.h @@ -73,11 +73,14 @@ public: void addMessage(QtMsgType, const QMessageLogContext &, const QString &) override; void addMessage(MessageTypes type, const QString &message, - const char *file = 0, int line = 0) override - { Q_UNUSED(type); Q_UNUSED(message); Q_UNUSED(file); Q_UNUSED(line); Q_UNREACHABLE(); } + const char *file = 0, int line = 0) override; void addBenchmarkResult(const QBenchmarkResult &result) override { Q_UNUSED(result); } + +private: + QString subsystem() const; + QString testIdentifier() const; }; #endif -- cgit v1.2.3 From a868942b11a586861e167aaafaa9c65fde23e88d Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 20 Mar 2019 15:59:18 +0100 Subject: QMacStyle - workaround NSButtonCell (disclose button type) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Under the 'Dark' theme as a system one, in an application forcing 'Aqua' (and thus 'Light') appearance, disclose button (drawn as a triangle) can suddenly become transparent (apparently selecting a 'Dark' codepath internally). Different ways to fix this (attaching NSButton to a view, setting appearance on this button manually, etc.) - all seems to have no effect. We resort to manually drawing this button on macOS > 10.14 if 'effectiveAppearance' is 'Aqua'. Change-Id: I6f54c0c4cf8fdd1ba53263ba9535e3055be46d42 Fixes: QTBUG-74515 Reviewed-by: Morten Johan Sørvig --- src/plugins/styles/mac/qmacstyle_mac.mm | 71 ++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index 5cb945a46c..9a11c4d818 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -1156,6 +1156,66 @@ static QStyleHelper::WidgetSizePolicy qt_aqua_guess_size(const QWidget *widg, QS } #endif +static NSColor *qt_convertColorForContext(CGContextRef context, NSColor *color) +{ + Q_ASSERT(color); + Q_ASSERT(context); + + CGColorSpaceRef targetCGColorSpace = CGBitmapContextGetColorSpace(context); + NSColorSpace *targetNSColorSpace = [[NSColorSpace alloc] initWithCGColorSpace:targetCGColorSpace]; + NSColor *adjusted = [color colorUsingColorSpace:targetNSColorSpace]; + [targetNSColorSpace release]; + + return adjusted; +} + +static NSColor *qt_colorForContext(CGContextRef context, const CGFloat (&rgba)[4]) +{ + Q_ASSERT(context); + + auto colorSpace = CGBitmapContextGetColorSpace(context); + if (!colorSpace) + return nil; + + return qt_convertColorForContext(context, [NSColor colorWithSRGBRed:rgba[0] green:rgba[1] blue:rgba[2] alpha:rgba[3]]); +} + +static void qt_drawDisclosureButton(CGContextRef context, NSInteger state, bool selected, CGRect rect) +{ + Q_ASSERT(context); + + static const CGFloat gray[] = {0.55, 0.55, 0.55, 0.97}; + static const CGFloat white[] = {1.0, 1.0, 1.0, 0.9}; + + NSColor *fillColor = qt_colorForContext(context, selected ? white : gray); + [fillColor setFill]; + + if (state == NSOffState) { + static NSBezierPath *triangle = [[NSBezierPath alloc] init]; + [triangle removeAllPoints]; + // In off state, a disclosure button is an equilateral triangle + // ('pointing' to the right) with a bound rect that can be described + // as NSMakeRect(0, 0, 8, 9). Inside the 'rect' it's translated by + // (2, 4). + [triangle moveToPoint:NSMakePoint(rect.origin.x + 2, rect.origin.y + 4)]; + [triangle lineToPoint:NSMakePoint(rect.origin.x + 2, rect.origin.y + 4 + 9)]; + [triangle lineToPoint:NSMakePoint(rect.origin.x + 2 + 8, rect.origin.y + 4 + 4.5)]; + [triangle closePath]; + [triangle fill]; + } else { + static NSBezierPath *openTriangle = [[NSBezierPath alloc] init]; + [openTriangle removeAllPoints]; + // In 'on' state, the button is an equilateral triangle (looking down) + // with the bounding rect NSMakeRect(0, 0, 9, 8). Inside the 'rect' + // it's translated by (1, 4). + [openTriangle moveToPoint:NSMakePoint(rect.origin.x + 1, rect.origin.y + 4 + 8)]; + [openTriangle lineToPoint:NSMakePoint(rect.origin.x + 1 + 9, rect.origin.y + 4 + 8)]; + [openTriangle lineToPoint:NSMakePoint(rect.origin.x + 1 + 4.5, rect.origin.y + 4)]; + [openTriangle closePath]; + [openTriangle fill]; + } +} + void QMacStylePrivate::drawFocusRing(QPainter *p, const QRectF &targetRect, int hMargin, int vMargin, const CocoaControl &cw) const { QPainterPath focusRingPath; @@ -3241,8 +3301,15 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai CGContextScaleCTM(cg, 1, -1); CGContextTranslateCTM(cg, -rect.origin.x, -rect.origin.y); - [triangleCell drawBezelWithFrame:NSRectFromCGRect(rect) inView:[triangleCell controlView]]; - + if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave && !qt_mac_applicationIsInDarkMode()) { + // When the real system theme is one of the 'Dark' themes, and an application forces the 'Aqua' theme, + // under some conditions (see QTBUG-74515 for more details) NSButtonCell seems to select the 'Dark' + // code path and is becoming transparent, thus 'invisible' on the white background. To workaround this, + // we draw the disclose triangle manually: + qt_drawDisclosureButton(cg, triangleCell.state, (opt->state & State_Selected) && viewHasFocus, rect); + } else { + [triangleCell drawBezelWithFrame:NSRectFromCGRect(rect) inView:[triangleCell controlView]]; + } d->restoreNSGraphicsContext(cg); break; } -- cgit v1.2.3 From 0ba8ed2c5faaebd0236a8e0dcf8964341ee56ce4 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 12 Mar 2019 11:58:28 +0100 Subject: Add .lib and .exp files to clean targets only for libraries There is no point in adding those to applications. Change-Id: Ic8d3009b5099c266f56b5bdaa831d0816510bc3b Reviewed-by: Oliver Wolff --- qmake/generators/win32/msvc_nmake.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index a6e850a036..650c0888c7 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -254,7 +254,7 @@ void NmakeMakefileGenerator::init() ProString tgt = project->first("DESTDIR") + project->first("TARGET") + project->first("TARGET_VERSION_EXT"); - if(project->isActiveConfig("shared")) { + if (project->first("TEMPLATE") == "lib" && project->isActiveConfig("shared")) { project->values("QMAKE_CLEAN").append(tgt + ".exp"); project->values("QMAKE_DISTCLEAN").append(tgt + ".lib"); } -- cgit v1.2.3 From e20f4d966e1b7e26feadbc1a5410f71a9271ed99 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Thu, 21 Mar 2019 14:20:17 +0100 Subject: Fix stretched fonts with large pixel size The Windows and Cocoa font engines ignored the stretch factor when the pixel size is so large that QPainterPath rendering is used instead of native. Fixes: QTBUG-14315 Change-Id: I93390528ac264452b7d6af7d39f49f4b0dd56279 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../fontdatabases/mac/qfontengine_coretext.mm | 21 ++++++++++-------- .../fontdatabases/windows/qwindowsfontengine.cpp | 25 ++++++++++++---------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 7957cd130a..25e7c6df72 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -491,9 +491,11 @@ void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextIt struct ConvertPathInfo { - ConvertPathInfo(QPainterPath *newPath, const QPointF &newPos) : path(newPath), pos(newPos) {} + ConvertPathInfo(QPainterPath *newPath, const QPointF &newPos, qreal newStretch = 1.0) : + path(newPath), pos(newPos), stretch(newStretch) {} QPainterPath *path; QPointF pos; + qreal stretch; }; static void convertCGPathToQPainterPath(void *info, const CGPathElement *element) @@ -501,25 +503,25 @@ static void convertCGPathToQPainterPath(void *info, const CGPathElement *element ConvertPathInfo *myInfo = static_cast(info); switch(element->type) { case kCGPathElementMoveToPoint: - myInfo->path->moveTo(element->points[0].x + myInfo->pos.x(), + myInfo->path->moveTo((element->points[0].x * myInfo->stretch) + myInfo->pos.x(), element->points[0].y + myInfo->pos.y()); break; case kCGPathElementAddLineToPoint: - myInfo->path->lineTo(element->points[0].x + myInfo->pos.x(), + myInfo->path->lineTo((element->points[0].x * myInfo->stretch) + myInfo->pos.x(), element->points[0].y + myInfo->pos.y()); break; case kCGPathElementAddQuadCurveToPoint: - myInfo->path->quadTo(element->points[0].x + myInfo->pos.x(), + myInfo->path->quadTo((element->points[0].x * myInfo->stretch) + myInfo->pos.x(), element->points[0].y + myInfo->pos.y(), - element->points[1].x + myInfo->pos.x(), + (element->points[1].x * myInfo->stretch) + myInfo->pos.x(), element->points[1].y + myInfo->pos.y()); break; case kCGPathElementAddCurveToPoint: - myInfo->path->cubicTo(element->points[0].x + myInfo->pos.x(), + myInfo->path->cubicTo((element->points[0].x * myInfo->stretch) + myInfo->pos.x(), element->points[0].y + myInfo->pos.y(), - element->points[1].x + myInfo->pos.x(), + (element->points[1].x * myInfo->stretch) + myInfo->pos.x(), element->points[1].y + myInfo->pos.y(), - element->points[2].x + myInfo->pos.x(), + (element->points[2].x * myInfo->stretch) + myInfo->pos.x(), element->points[2].y + myInfo->pos.y()); break; case kCGPathElementCloseSubpath: @@ -543,9 +545,10 @@ void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *position if (synthesisFlags & QFontEngine::SynthesizedItalic) cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -SYNTHETIC_ITALIC_SKEW, 1, 0, 0)); + qreal stretch = fontDef.stretch ? qreal(fontDef.stretch) / 100 : 1.0; for (int i = 0; i < nGlyphs; ++i) { QCFType cgpath = CTFontCreatePathForGlyph(ctfont, glyphs[i], &cgMatrix); - ConvertPathInfo info(path, positions[i].toPointF()); + ConvertPathInfo info(path, positions[i].toPointF(), stretch); CGPathApply(cgpath, &info, convertCGPathToQPainterPath); } } diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp index d1d11883c1..2ae378c558 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp @@ -702,8 +702,8 @@ static inline double qt_fixed_to_double(const FIXED &p) { return ((p.value << 16) + p.fract) / 65536.0; } -static inline QPointF qt_to_qpointf(const POINTFX &pt, qreal scale) { - return QPointF(qt_fixed_to_double(pt.x) * scale, -qt_fixed_to_double(pt.y) * scale); +static inline QPointF qt_to_qpointf(const POINTFX &pt, qreal scale, qreal stretch) { + return QPointF(qt_fixed_to_double(pt.x) * scale * stretch, -qt_fixed_to_double(pt.y) * scale); } #ifndef GGO_UNHINTED @@ -711,7 +711,8 @@ static inline QPointF qt_to_qpointf(const POINTFX &pt, qreal scale) { #endif static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, - QPainterPath *path, bool ttf, glyph_metrics_t *metric = 0, qreal scale = 1) + QPainterPath *path, bool ttf, glyph_metrics_t *metric = 0, + qreal scale = 1.0, qreal stretch = 1.0) { MAT2 mat; mat.eM11.value = mat.eM22.value = 1; @@ -761,7 +762,7 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, while (headerOffset < bufferSize) { const TTPOLYGONHEADER *ttph = reinterpret_cast(dataBuffer + headerOffset); - QPointF lastPoint(qt_to_qpointf(ttph->pfxStart, scale)); + QPointF lastPoint(qt_to_qpointf(ttph->pfxStart, scale, stretch)); path->moveTo(lastPoint + oset); offset += sizeof(TTPOLYGONHEADER); while (offset < headerOffset + ttph->cb) { @@ -769,7 +770,7 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, switch (curve->wType) { case TT_PRIM_LINE: { for (int i=0; icpfx; ++i) { - QPointF p = qt_to_qpointf(curve->apfx[i], scale) + oset; + QPointF p = qt_to_qpointf(curve->apfx[i], scale, stretch) + oset; path->lineTo(p); } break; @@ -779,8 +780,8 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, QPointF prev(elm.x, elm.y); QPointF endPoint; for (int i=0; icpfx - 1; ++i) { - QPointF p1 = qt_to_qpointf(curve->apfx[i], scale) + oset; - QPointF p2 = qt_to_qpointf(curve->apfx[i+1], scale) + oset; + QPointF p1 = qt_to_qpointf(curve->apfx[i], scale, stretch) + oset; + QPointF p2 = qt_to_qpointf(curve->apfx[i+1], scale, stretch) + oset; if (i < curve->cpfx - 2) { endPoint = QPointF((p1.x() + p2.x()) / 2, (p1.y() + p2.y()) / 2); } else { @@ -795,9 +796,9 @@ static bool addGlyphToPath(glyph_t glyph, const QFixedPoint &position, HDC hdc, } case TT_PRIM_CSPLINE: { for (int i=0; icpfx; ) { - QPointF p2 = qt_to_qpointf(curve->apfx[i++], scale) + oset; - QPointF p3 = qt_to_qpointf(curve->apfx[i++], scale) + oset; - QPointF p4 = qt_to_qpointf(curve->apfx[i++], scale) + oset; + QPointF p2 = qt_to_qpointf(curve->apfx[i++], scale, stretch) + oset; + QPointF p3 = qt_to_qpointf(curve->apfx[i++], scale, stretch) + oset; + QPointF p4 = qt_to_qpointf(curve->apfx[i++], scale, stretch) + oset; path->cubicTo(p2, p3, p4); } break; @@ -829,9 +830,11 @@ void QWindowsFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions HDC hdc = m_fontEngineData->hdc; HGDIOBJ oldfont = SelectObject(hdc, hf); + qreal scale = qreal(fontDef.pixelSize) / unitsPerEm; + qreal stretch = fontDef.stretch ? qreal(fontDef.stretch) / 100 : 1.0; for(int i = 0; i < nglyphs; ++i) { if (!addGlyphToPath(glyphs[i], positions[i], hdc, path, ttf, /*metric*/0, - qreal(fontDef.pixelSize) / unitsPerEm)) { + scale, stretch)) { // Some windows fonts, like "Modern", are vector stroke // fonts, which are reported as TMPF_VECTOR but do not // support GetGlyphOutline, and thus we set this bit so -- cgit v1.2.3 From 93466daf13c7845cd3bf5e388c6a0967449dce21 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Mon, 25 Mar 2019 13:43:19 +0100 Subject: tslib: avoid deprecated overload Change-Id: Iab0c25c38d62303986a1f5739cc48de15b35dea2 Reviewed-by: Laszlo Agocs --- src/platformsupport/input/tslib/qtslib.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/platformsupport/input/tslib/qtslib.cpp b/src/platformsupport/input/tslib/qtslib.cpp index 75ac3c50e0..48f41b9eeb 100644 --- a/src/platformsupport/input/tslib/qtslib.cpp +++ b/src/platformsupport/input/tslib/qtslib.cpp @@ -129,7 +129,9 @@ void QTsLibMouseHandler::readMouseData() } QPoint pos(x, y); - QWindowSystemInterface::handleMouseEvent(0, pos, pos, pressed ? Qt::LeftButton : Qt::NoButton); + QWindowSystemInterface::handleMouseEvent(nullptr, pos, pos, + pressed ? Qt::LeftButton : Qt::NoButton, + Qt::NoButton, QEvent::None); m_x = x; m_y = y; -- cgit v1.2.3 From 958fa04327f4f3c29eb0e16cc448ef20c62e11a3 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Mon, 25 Mar 2019 13:10:04 +0100 Subject: tslib: use new connect syntax Change-Id: I06bbd681fbb4bf809814de454c266f08976e0916 Reviewed-by: Laszlo Agocs --- src/platformsupport/input/tslib/qtslib.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platformsupport/input/tslib/qtslib.cpp b/src/platformsupport/input/tslib/qtslib.cpp index 48f41b9eeb..84a468f60c 100644 --- a/src/platformsupport/input/tslib/qtslib.cpp +++ b/src/platformsupport/input/tslib/qtslib.cpp @@ -85,7 +85,7 @@ QTsLibMouseHandler::QTsLibMouseHandler(const QString &key, if (fd >= 0) { qCDebug(qLcTsLib) << "tslib device is" << device; m_notify = new QSocketNotifier(fd, QSocketNotifier::Read, this); - connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData())); + connect(m_notify, &QSocketNotifier::activated, this, &QTsLibMouseHandler::readMouseData); } else { qErrnoWarning(errno, "tslib: Cannot open input device %s", device.constData()); } -- cgit v1.2.3 From a0446b13982b8cd1c7d75df71c800c9343e8ab1e Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 26 Mar 2019 15:00:53 +0100 Subject: Remove blacklisting of tst_qsslsocket_onDemandCertificates_member It is constantly passing according to grafana. Change-Id: I4953cd54e27adde8dad79e9a0f025960802e6c7a Reviewed-by: Friedemann Kleint Reviewed-by: Timur Pocheptsov --- tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/BLACKLIST | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/BLACKLIST diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/BLACKLIST b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/BLACKLIST deleted file mode 100644 index c9b628d79b..0000000000 --- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/BLACKLIST +++ /dev/null @@ -1,2 +0,0 @@ -[onDemandRootCertLoadingMemberMethods] -linux -- cgit v1.2.3 From 54efa7e592420b8d952e18e956b33368b8b9f8e3 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 28 Mar 2019 09:18:55 +0100 Subject: Blacklist qgraphicsitem::sorting test on opensuse-42.3 Task-number: QTBUG-74760 Change-Id: I79bd58e6be61c59e0f1fa48dba0dee72e0a7e78c Reviewed-by: Mitch Curtis --- tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST b/tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST new file mode 100644 index 0000000000..e760042def --- /dev/null +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST @@ -0,0 +1,3 @@ +# QTBUG-74760 +[sorting] +opensuse-42.3 -- cgit v1.2.3 From 1a707be8b4a8e3cb2878cb18ce76c54f9fad9b28 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 22 Mar 2019 13:25:57 +0100 Subject: Do not look for pg_config, mysql_config in PATH when cross-compiling Otherwise it can happen that we pick up the tool for the host system, which will break compilation. Users can still pass -psql_config /path/to/pg_config or -mysql_config /path/to/mysql_config manually. [ChangeLog][QtSql] When cross-compiling pg_config, mysql_config are not looked up in PATH anymore. Pass -psql_config path/to/pg_config or -mysql_config path/to/mysql_config to explicitly enable PSQL or MySQL in this setup. Fixes: QTBUG-73565 Change-Id: I35ff32322bac69f1575ce6c846a56ac2ae3b8d55 Reviewed-by: Joerg Bornemann --- src/plugins/sqldrivers/configure.pri | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/sqldrivers/configure.pri b/src/plugins/sqldrivers/configure.pri index 84c8114c7b..be6a930e52 100644 --- a/src/plugins/sqldrivers/configure.pri +++ b/src/plugins/sqldrivers/configure.pri @@ -2,7 +2,7 @@ defineTest(qtConfLibrary_psqlConfig) { pg_config = $$config.input.psql_config - isEmpty(pg_config): \ + isEmpty(pg_config):!cross_compile: \ pg_config = $$qtConfFindInPath("pg_config") !win32:!isEmpty(pg_config) { qtRunLoggedCommand("$$pg_config --libdir", libdir)|return(false) @@ -33,7 +33,7 @@ defineTest(qtConfLibrary_psqlEnv) { defineTest(qtConfLibrary_mysqlConfig) { mysql_config = $$config.input.mysql_config - isEmpty(mysql_config): \ + isEmpty(mysql_config):!cross_compile: \ mysql_config = $$qtConfFindInPath("mysql_config") !isEmpty(mysql_config) { qtRunLoggedCommand("$$mysql_config --version", version)|return(false) -- cgit v1.2.3 From ff8d9ad5bcae7c29a49ed895dbfcf49061aaed39 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 24 Jan 2019 14:59:51 +0100 Subject: Speculative fix for building on INTEGRITY with ARM NEON Avoid using inline assembler Task-number: QTBUG-72716 Change-Id: I696efb5a787416eb4fc5ba3a250461aaa9a4afc2 Reviewed-by: Janne Koskinen --- mkspecs/common/ghs-integrity-armv8.conf | 4 +- src/gui/image/qimage_neon.cpp | 66 +++++++++++---------------------- src/gui/painting/painting.pri | 6 ++- src/gui/painting/qdrawhelper_neon.cpp | 41 ++++++++++++-------- 4 files changed, 53 insertions(+), 64 deletions(-) diff --git a/mkspecs/common/ghs-integrity-armv8.conf b/mkspecs/common/ghs-integrity-armv8.conf index ee4ce458de..e454cfd245 100644 --- a/mkspecs/common/ghs-integrity-armv8.conf +++ b/mkspecs/common/ghs-integrity-armv8.conf @@ -17,8 +17,8 @@ os_directory = $$(INTEGRITY_DIR) isEmpty(os_directory): \ error("This qmakespec requires $INTEGRITY_DIR to be set") -QMAKE_CC = cxintarm64 -U__ARM_NEON__ -U__ARM_NEON -bsp $$bsp_name -os_dir $$os_directory -non_shared -QMAKE_CXX = cxintarm64 -U__ARM_NEON__ -U__ARM_NEON -bsp $$bsp_name -os_dir $$os_directory -non_shared +QMAKE_CC = cxintarm64 -bsp $$bsp_name -os_dir $$os_directory -non_shared +QMAKE_CXX = cxintarm64 -bsp $$bsp_name -os_dir $$os_directory -non_shared QMAKE_LINK = $$QMAKE_CXX QMAKE_AR = $$QMAKE_CXX -archive -o diff --git a/src/gui/image/qimage_neon.cpp b/src/gui/image/qimage_neon.cpp index 57a24edeca..9dbcb11db5 100644 --- a/src/gui/image/qimage_neon.cpp +++ b/src/gui/image/qimage_neon.cpp @@ -52,65 +52,41 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, cons const quint32 *const end = dst + len; - // align dst on 64 bits - const int offsetToAlignOn8Bytes = (reinterpret_cast(dst) >> 2) & 0x1; - for (int i = 0; i < offsetToAlignOn8Bytes; ++i) { + // align dst on 128 bits + const int offsetToAlignOn16Bytes = (reinterpret_cast(dst) >> 2) & 0x3; + for (int i = 0; i < offsetToAlignOn16Bytes; ++i) { *dst++ = qRgb(src[0], src[1], src[2]); src += 3; } - if ((len - offsetToAlignOn8Bytes) >= 8) { - const quint32 *const simdEnd = end - 7; -#if !defined(Q_PROCESSOR_ARM_64) - register uint8x8_t fullVector asm ("d3") = vdup_n_u8(0xff); - do { + if ((len - offsetToAlignOn16Bytes) >= 16) { + const quint32 *const simdEnd = end - 15; + uint8x16x4_t dstVector; #if Q_BYTE_ORDER == Q_BIG_ENDIAN - asm volatile ( - "vld3.8 { d4, d5, d6 }, [%[SRC]] !\n\t" - "vst4.8 { d3, d4, d5, d6 }, [%[DST],:64] !\n\t" - : [DST]"+r" (dst), [SRC]"+r" (src) - : "w"(fullVector) - : "memory", "d4", "d5", "d6" - ); + dstVector.val[0] = vdupq_n_u8(0xff); #else - asm volatile ( - "vld3.8 { d0, d1, d2 }, [%[SRC]] !\n\t" - "vswp d0, d2\n\t" - "vst4.8 { d0, d1, d2, d3 }, [%[DST],:64] !\n\t" - : [DST]"+r" (dst), [SRC]"+r" (src) - : "w"(fullVector) - : "memory", "d0", "d1", "d2" - ); + dstVector.val[3] = vdupq_n_u8(0xff); #endif - } while (dst < simdEnd); -#else - register uint8x8_t fullVector asm ("v3") = vdup_n_u8(0xff); do { + uint8x16x3_t srcVector = vld3q_u8(src); + src += 3 * 16; #if Q_BYTE_ORDER == Q_BIG_ENDIAN - asm volatile ( - "ld3 { v4.8b, v5.8b, v6.8b }, [%[SRC]], #24 \n\t" - "st4 { v3.8b, v4.8b, v5.8b, v6.8b }, [%[DST]], #32 \n\t" - : [DST]"+r" (dst), [SRC]"+r" (src) - : "w"(fullVector) - : "memory", "v4", "v5", "v6" - ); + dstVector.val[1] = srcVector.val[0]; + dstVector.val[2] = srcVector.val[1]; + dstVector.val[3] = srcVector.val[2]; #else - asm volatile ( - "ld3 { v0.8b, v1.8b, v2.8b }, [%[SRC]], #24 \n\t" - "mov v4.8b, v2.8b\n\t" - "mov v2.8b, v0.8b\n\t" - "mov v0.8b, v4.8b\n\t" - "st4 { v0.8b, v1.8b, v2.8b, v3.8b }, [%[DST]], #32 \n\t" - : [DST]"+r" (dst), [SRC]"+r" (src) - : "w"(fullVector) - : "memory", "v0", "v1", "v2", "v4" - ); + dstVector.val[0] = srcVector.val[2]; + dstVector.val[1] = srcVector.val[1]; + dstVector.val[2] = srcVector.val[0]; #endif + vst4q_u8(reinterpret_cast(dst), dstVector); + dst += 16; } while (dst < simdEnd); -#endif } - while (dst != end) { + int i = 0; + int length = end - dst; + SIMD_EPILOGUE(i, length, 15) { *dst++ = qRgb(src[0], src[1], src[2]); src += 3; } diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index c3585a4647..a90abed4c0 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -131,9 +131,11 @@ ARCH_HASWELL_SOURCES += painting/qdrawhelper_avx2.cpp NEON_SOURCES += painting/qdrawhelper_neon.cpp painting/qimagescale_neon.cpp NEON_HEADERS += painting/qdrawhelper_neon_p.h -NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S !uikit:!win32:contains(QT_ARCH, "arm"): CONFIG += no_clang_integrated_as -!uikit:!win32:!contains(QT_ARCH, "arm64"): DEFINES += ENABLE_PIXMAN_DRAWHELPERS +!uikit:!win32:!integrity:!contains(QT_ARCH, "arm64") { + NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S + DEFINES += ENABLE_PIXMAN_DRAWHELPERS +} MIPS_DSP_SOURCES += painting/qdrawhelper_mips_dsp.cpp MIPS_DSP_HEADERS += painting/qdrawhelper_mips_dsp_p.h painting/qt_mips_asm_dsp_p.h diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index 629dfe2358..3fbd651f96 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -50,7 +50,18 @@ QT_BEGIN_NAMESPACE void qt_memfill32(quint32 *dest, quint32 value, int count) { const int epilogueSize = count % 16; -#if !defined(Q_PROCESSOR_ARM_64) +#if defined(Q_CC_GHS) || defined(Q_CC_MSVC) + // inline assembler free version: + if (count >= 16) { + quint32 *const neonEnd = dest + count - epilogueSize; + const uint32x4_t valueVector1 = vdupq_n_u32(value); + const uint32x4x4_t valueVector4 = { valueVector1, valueVector1, valueVector1, valueVector1 }; + do { + vst4q_u32(dest, valueVector4); + dest += 16; + } while (dest != neonEnd); + } +#elif !defined(Q_PROCESSOR_ARM_64) if (count >= 16) { quint32 *const neonEnd = dest + count - epilogueSize; register uint32x4_t valueVector1 asm ("q0") = vdupq_n_u32(value); @@ -84,20 +95,20 @@ void qt_memfill32(quint32 *dest, quint32 value, int count) switch (epilogueSize) { - case 15: *dest++ = value; - case 14: *dest++ = value; - case 13: *dest++ = value; - case 12: *dest++ = value; - case 11: *dest++ = value; - case 10: *dest++ = value; - case 9: *dest++ = value; - case 8: *dest++ = value; - case 7: *dest++ = value; - case 6: *dest++ = value; - case 5: *dest++ = value; - case 4: *dest++ = value; - case 3: *dest++ = value; - case 2: *dest++ = value; + case 15: *dest++ = value; Q_FALLTHROUGH(); + case 14: *dest++ = value; Q_FALLTHROUGH(); + case 13: *dest++ = value; Q_FALLTHROUGH(); + case 12: *dest++ = value; Q_FALLTHROUGH(); + case 11: *dest++ = value; Q_FALLTHROUGH(); + case 10: *dest++ = value; Q_FALLTHROUGH(); + case 9: *dest++ = value; Q_FALLTHROUGH(); + case 8: *dest++ = value; Q_FALLTHROUGH(); + case 7: *dest++ = value; Q_FALLTHROUGH(); + case 6: *dest++ = value; Q_FALLTHROUGH(); + case 5: *dest++ = value; Q_FALLTHROUGH(); + case 4: *dest++ = value; Q_FALLTHROUGH(); + case 3: *dest++ = value; Q_FALLTHROUGH(); + case 2: *dest++ = value; Q_FALLTHROUGH(); case 1: *dest++ = value; } } -- cgit v1.2.3 From 743e883c12edcc1d5e22a50eea4f7f28fc7b8188 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Thu, 28 Mar 2019 10:43:30 +0100 Subject: Blacklist the reverse lookup of 8.8.8.8 to unblock integrations The DNS entry for the host has changed, dig answers with dns.google, not with google-public-dns-a.google.com. While developing a proper fix to the test, blacklisting this particular lookup allows integrations to pass in the meantime. Change-Id: Id37da6b24554803bf4e2c84be5b949ded40566e8 Reviewed-by: Kari Oikarinen Reviewed-by: Timur Pocheptsov --- tests/auto/network/kernel/qhostinfo/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/network/kernel/qhostinfo/BLACKLIST b/tests/auto/network/kernel/qhostinfo/BLACKLIST index 87c5fe991f..cd4d4eb03c 100644 --- a/tests/auto/network/kernel/qhostinfo/BLACKLIST +++ b/tests/auto/network/kernel/qhostinfo/BLACKLIST @@ -4,3 +4,5 @@ windows ci [blockingLookup:a-plus-aaaa] windows ci +[reverseLookup:google-public-dns-a.google.com] +ci -- cgit v1.2.3 From 20b7e18146e28e73cba52a63a3415c6828f1f6f5 Mon Sep 17 00:00:00 2001 From: Alexey Edelev Date: Thu, 28 Mar 2019 11:58:04 +0100 Subject: Fix a crash in QHttp2ProtocolHandler in h2c-direct mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After 'h2c' mode was implemented with the proper protocol upgrade, the previously working 'direct connection' mode was lost for clear text connections due to the erroneous logic in the constructor: having !channel->ssl does not necessary mean we started with HTTP/1.1 request, including protocol upgrade header; it can also mean we connected a plain socket and immediately sending h2 frames, without any H2 negotiation at all. Fixes: QTBUG-74765 Change-Id: Ice466d6bffb40048b7ab46fb064f2d3d795a12aa Reviewed-by: Timur Pocheptsov Reviewed-by: Mårten Nordheim --- src/network/access/qhttp2protocolhandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp index d5221a4934..35aee6e3e1 100644 --- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -198,7 +198,7 @@ QHttp2ProtocolHandler::QHttp2ProtocolHandler(QHttpNetworkConnectionChannel *chan } } - if (!channel->ssl) { + if (!channel->ssl && m_connection->connectionType() != QHttpNetworkConnection::ConnectionTypeHTTP2Direct) { // We upgraded from HTTP/1.1 to HTTP/2. channel->request was already sent // as HTTP/1.1 request. The response with status code 101 triggered // protocol switch and now we are waiting for the real response, sent -- cgit v1.2.3 From 8d154810f56b9d831f78f454fb2b05e98c246313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tony=20Saraj=C3=A4rvi?= Date: Thu, 28 Mar 2019 15:24:18 +0200 Subject: Extend blacklistnig of tst_qwidgets to cover RHEL 7.6 Task-number: QTBUG-46116 Change-Id: I7d74dca7030a9c21b3654e3b5cde94015497208e Reviewed-by: Heikki Halmet --- tests/auto/widgets/kernel/qwidget/BLACKLIST | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index 1f68308bbe..3287d67875 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -10,6 +10,7 @@ osx ubuntu-16.04 ubuntu-18.04 rhel-7.4 +rhel-7.6 osx [focusProxyAndInputMethods] linux -- cgit v1.2.3