summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2019-03-31 18:45:03 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2019-03-31 18:45:03 +0000
commite104c1972877c1732aa3c58f52bb766a0bfa29e7 (patch)
treede540871ce7657c4a8787066392b157bf82074cb
parentc19d556863d931f5fd04d9e27ee7a47aafeaca2a (diff)
parent29f01b32f58573b23bd35857376f6f92e15382a3 (diff)
Merge "Merge remote-tracking branch 'origin/5.13' into dev" into refs/staging/dev
-rw-r--r--configure.pri7
-rw-r--r--examples/corelib/serialization/convert/xmlconverter.cpp6
-rw-r--r--mkspecs/common/ghs-integrity-armv8.conf4
-rw-r--r--qmake/generators/win32/msvc_nmake.cpp2
-rw-r--r--src/corelib/configure.json23
-rw-r--r--src/corelib/global/minimum-linux_p.h6
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.cpp14
-rw-r--r--src/corelib/kernel/qsignalmapper.cpp2
-rw-r--r--src/corelib/mimetypes/mimetypes.pri2
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp2
-rw-r--r--src/corelib/platform/wasm/qstdweb.cpp2
-rw-r--r--src/corelib/tools/qtimezoneprivate_p.h1
-rw-r--r--src/corelib/tools/qtimezoneprivate_tz.cpp48
-rw-r--r--src/gui/image/qimage_neon.cpp66
-rw-r--r--src/gui/image/qpixmap.cpp15
-rw-r--r--src/gui/kernel/qplatformwindow.cpp7
-rw-r--r--src/gui/kernel/qwindow_p.h8
-rw-r--r--src/gui/painting/painting.pri6
-rw-r--r--src/gui/painting/qdrawhelper_neon.cpp13
-rw-r--r--src/gui/text/qtextengine.cpp2
-rw-r--r--src/network/access/qabstractnetworkcache.cpp4
-rw-r--r--src/network/access/qhttp2protocolhandler.cpp2
-rw-r--r--src/network/access/qnetworkaccesscachebackend.cpp17
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp14
-rw-r--r--src/network/access/qnetworkreplywasmimpl.cpp22
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm21
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsfontengine.cpp25
-rw-r--r--src/platformsupport/input/tslib/qtslib.cpp6
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemsettings.mm3
-rw-r--r--src/plugins/platforms/wasm/qwasmclipboard.cpp38
-rw-r--r--src/plugins/platforms/wasm/qwasmeventtranslator.cpp6
-rw-r--r--src/plugins/platforms/wasm/qwasmintegration.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp3
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp7
-rw-r--r--src/plugins/sqldrivers/configure.pri4
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm167
-rw-r--r--src/testlib/qappletestlogger.cpp130
-rw-r--r--src/testlib/qappletestlogger_p.h7
-rw-r--r--src/widgets/kernel/qwidget.cpp7
-rw-r--r--src/widgets/widgets/qspinbox.cpp4
-rw-r--r--tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp5
-rw-r--r--tests/auto/corelib/itemmodels/qitemmodel/tst_qitemmodel.cpp3
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp45
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h3
-rw-r--r--tests/auto/corelib/serialization/qdatastream_core_pixmap/qdatastream_core_pixmap.pro4
-rw-r--r--tests/auto/corelib/serialization/qdatastream_core_pixmap/tst_qdatastream_core_pixmap.cpp68
-rw-r--r--tests/auto/corelib/serialization/serialization.pro1
-rw-r--r--tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp4
-rw-r--r--tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp9
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp29
-rw-r--r--tests/auto/network/kernel/qhostinfo/BLACKLIST2
-rw-r--r--tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/BLACKLIST2
-rw-r--r--tests/auto/tools/qmake/testcompiler.cpp8
-rw-r--r--tests/auto/tools/qmake/testcompiler.h5
-rw-r--r--tests/auto/tools/qmake/testdata/simple_app/simple_app.pro5
-rw-r--r--tests/auto/tools/qmake/tst_qmake.cpp45
-rw-r--r--tests/auto/widgets/graphicsview/qgraphicsitem/BLACKLIST3
-rw-r--r--tests/auto/widgets/kernel/qwidget/BLACKLIST1
-rw-r--r--tests/auto/widgets/widgets/qdoublespinbox/tst_qdoublespinbox.cpp12
-rw-r--r--tests/auto/widgets/widgets/qmainwindow/tst_qmainwindow.cpp2
-rw-r--r--tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp12
62 files changed, 743 insertions, 259 deletions
diff --git a/configure.pri b/configure.pri
index d8ca93d839..d8d0260fa0 100644
--- a/configure.pri
+++ b/configure.pri
@@ -465,7 +465,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
@@ -474,7 +476,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.
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:
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/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");
}
diff --git a/src/corelib/configure.json b/src/corelib/configure.json
index 81768507f6..a6091d4825 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": [ "no", "qt", "system" ] },
"posix-ipc": { "type": "boolean", "name": "ipc_posix" },
"pps": { "type": "boolean", "name": "qqnx_pps" },
@@ -374,6 +375,16 @@
]
}
},
+ "glibc": {
+ "label": "GNU libc",
+ "type": "compile",
+ "test": {
+ "include": "stdlib.h",
+ "main": [
+ "return __GLIBC__;"
+ ]
+ }
+ },
"inotify": {
"label": "inotify",
"type": "compile",
@@ -593,6 +604,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.",
@@ -662,6 +679,11 @@
"condition": "features.textcodec",
"output": [ "publicFeature", "feature" ]
},
+ "mimetype-database": {
+ "label": "Built-in copy of the MIME database",
+ "condition": "features.mimetype",
+ "output": [ "privateFeature" ]
+ },
"pcre2": {
"label": "PCRE2",
"disable": "input.pcre == 'no' || input.pcre == 'system'",
@@ -1036,6 +1058,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/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
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index abd86f2b49..18f0f6f55f 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -2355,6 +2355,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);
@@ -2362,7 +2363,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);
@@ -2401,10 +2402,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/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
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 5e1447aaa9..7e2696b719 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
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/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<QTimeZonePrivate::Data> getPosixTransitions(qint64 msNear) const;
Data dataForTzTransition(QTzTransitionTime tran) const;
QVector<QTzTransitionTime> m_tranTimes;
diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp
index bed62a02bd..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<QTimeZonePrivate::Data> 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<QTimeZonePrivate::Data> posixTrans =
- calculatePosixTransitions(m_posixRule, year - 1, year + 1,
- m_tranTimes.last().atMSecsSinceEpoch);
+ QVector<QTimeZonePrivate::Data> 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<QTimeZonePrivate::Data> posixTrans =
- calculatePosixTransitions(m_posixRule, year - 1, year + 1,
- m_tranTimes.last().atMSecsSinceEpoch);
+ QVector<QTimeZonePrivate::Data> posixTrans = getPosixTransitions(afterMSecsSinceEpoch);
auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(),
[afterMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) {
return at.atMSecsSinceEpoch <= afterMSecsSinceEpoch;
@@ -1011,19 +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<QTimeZonePrivate::Data> posixTrans =
- calculatePosixTransitions(m_posixRule, year - 1, year + 1,
- m_tranTimes.last().atMSecsSinceEpoch);
+ QVector<QTimeZonePrivate::Data> posixTrans = getPosixTransitions(beforeMSecsSinceEpoch);
auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(),
[beforeMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) {
return at.atMSecsSinceEpoch < beforeMSecsSinceEpoch;
});
- Q_ASSERT(it > posixTrans.cbegin());
- return *--it;
+ if (it > posixTrans.cbegin())
+ return *--it;
+ // 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/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<quintptr>(dst) >> 2) & 0x1;
- for (int i = 0; i < offsetToAlignOn8Bytes; ++i) {
+ // align dst on 128 bits
+ const int offsetToAlignOn16Bytes = (reinterpret_cast<quintptr>(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<uint8_t*>(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/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 2ef1d09422..5b4d218603 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -1552,6 +1552,11 @@ QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
if (image.isNull())
return QPixmap();
+ if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
+ qWarning("QPixmap::fromImage: QPixmap cannot be created without a QGuiApplication");
+ return QPixmap();
+ }
+
QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
data->fromImage(image, flags);
return QPixmap(data.take());
@@ -1574,6 +1579,11 @@ QPixmap QPixmap::fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags)
if (image.isNull())
return QPixmap();
+ if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
+ qWarning("QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication");
+ return QPixmap();
+ }
+
QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
data->fromImageInPlace(image, flags);
return QPixmap(data.take());
@@ -1593,6 +1603,11 @@ QPixmap QPixmap::fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags)
*/
QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
{
+ if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
+ qWarning("QPixmap::fromImageReader: QPixmap cannot be created without a QGuiApplication");
+ return QPixmap();
+ }
+
QScopedPointer<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
data->fromImageReader(imageReader, flags);
return QPixmap(data.take());
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index d6f90c9254..562289a8c9 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<QWindow*>(w));
QRect rect(QHighDpi::fromNativePixels(initialGeometry, w));
- rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight));
- if (qt_window_private(const_cast<QWindow*>(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 1098321135..eb0b606598 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)
@@ -156,6 +157,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(); }
@@ -179,6 +182,11 @@ 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;
QRegion mask;
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 0e2dfed9ab..972cf387ff 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -143,9 +143,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 3fcbcfd053..8196a87b24 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, qsizetype 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);
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;
diff --git a/src/network/access/qabstractnetworkcache.cpp b/src/network/access/qabstractnetworkcache.cpp
index 0b94dff61e..4e217294c4 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/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
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 9ae94afc5a..f801ef0c88 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -524,6 +524,8 @@ bool QNetworkReplyHttpImplPrivate::loadFromCacheIfAllowed(QHttpNetworkRequest &h
QHash<QByteArray, QByteArray> cacheControl = parseHttpOptionHeader(it->second);
if (cacheControl.contains("must-revalidate"))
return false;
+ if (cacheControl.contains("no-cache"))
+ return false;
}
QDateTime currentDateTime = QDateTime::currentDateTimeUtc();
@@ -1731,18 +1733,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/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<void>("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<void>("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<void *>(this))));
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<ConvertPathInfo *>(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<CGPathRef> 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<const TTPOLYGONHEADER *>(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; i<curve->cpfx; ++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; i<curve->cpfx - 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; i<curve->cpfx; ) {
- 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
diff --git a/src/platformsupport/input/tslib/qtslib.cpp b/src/platformsupport/input/tslib/qtslib.cpp
index 20a9824969..f8fdc151ec 100644
--- a/src/platformsupport/input/tslib/qtslib.cpp
+++ b/src/platformsupport/input/tslib/qtslib.cpp
@@ -83,7 +83,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());
}
@@ -127,7 +127,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;
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];
}
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<QPlatformTheme::Palette, QPalette*> 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) {
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<val>("getClipboardData");
- val clipFormat = module.call<val>("getClipboardFormat");
+ val clipdata = module.call<val>("qtGetClipboardData");
+ val clipFormat = module.call<val>("qtGetClipboardFormat");
event["clipboardData"].call<void>("setData", clipFormat, clipdata);
event.call<void>("preventDefault");
}
@@ -91,8 +91,8 @@ static void qClipboardCopyTo(val event)
}
val module = val::global("Module");
- val clipdata = module.call<val>("getClipboardData");
- val clipFormat = module.call<val>("getClipboardFormat");
+ val clipdata = module.call<val>("qtGetClipboardData");
+ val clipFormat = module.call<val>("qtGetClipboardFormat");
event["clipboardData"].call<void>("setData", clipFormat, clipdata);
event.call<void>("preventDefault");
}
@@ -101,7 +101,7 @@ static void qClipboardPasteTo(val event)
{
bool hasClipboardApi = QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi;
val clipdata = hasClipboardApi ?
- val::global("Module").call<val>("getClipboardData") :
+ val::global("Module").call<val>("qtGetClipboardData") :
event["clipboardData"].call<val>("getData", std::string("text"));
const std::string data = clipdata.as<std::string>();
@@ -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<void>("addEventListener", std::string("cut"),
- val::module_property("qClipboardCutTo"));
+ val::module_property("qtClipboardCutTo"));
canvas.call<void>("addEventListener", std::string("copy"),
- val::module_property("qClipboardCopyTo"));
+ val::module_property("qtClipboardCopyTo"));
canvas.call<void>("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<val>("readText");
- val readTextResolve = val::global("Module")["qClipboardPromiseResolve"];
+ val readTextResolve = val::global("Module")["qtClipboardPromiseResolve"];
textPromise.call<val>("then", readTextResolve);
}
}
@@ -221,8 +221,8 @@ void QWasmClipboard::writeTextToClipboard()
{
if (QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) {
val module = val::global("Module");
- val txt = module.call<val>("getClipboardData");
- val format = module.call<val>("getClipboardFormat");
+ val txt = module.call<val>("qtGetClipboardData");
+ val format = module.call<val>("qtGetClipboardFormat");
val navigator = val::global("navigator");
navigator["clipboard"].call<void>("writeText", txt.as<std::string>());
}
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<void>("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()
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 07fd2916c2..338e594c7b 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<QWindow *>(w))->resizeAutomatic) {
frameX = geometry.x();
frameY = geometry.y();
const QMargins effectiveMargins = margins + customMargins;
diff --git a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp
index 3377eeaae9..8d958aae94 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<size_t>(img.sizeInBytes()));
+ }
+
set->setGlyph(glyphs[i], spp, glyph);
Q_ASSERT(glyph->data || glyph->width == 0 || glyph->height == 0);
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)
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index 9602340f9d..5c2a839781 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<const QTabBar*>(w))
+ isDocument = tabBar->documentMode();
+ const QColor bottomLineColor = isDocument && isDarkMode() ? QColor(Qt::black) : active ? tabBarTabLineActive() : tabBarTabLine();
p->fillRect(bottomLineRect, bottomLineColor);
}
#endif
@@ -1124,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;
@@ -1227,11 +1319,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
}
@@ -3203,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; }
@@ -3536,7 +3641,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);
@@ -3958,6 +4063,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;
@@ -4444,16 +4554,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();
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<QtMsgType, const char *> 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
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 90a23f7cd4..74b18d9991 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -1538,14 +1538,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);
}
}
diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp
index 40044223e2..97a3a12336 100644
--- a/src/widgets/widgets/qspinbox.cpp
+++ b/src/widgets/widgets/qspinbox.cpp
@@ -751,6 +751,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/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 <QStandardItemModel>
#include <QStringListModel>
#include <QTest>
+#include <QLoggingCategory>
#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 da13b9f33f..b9deb7b6a9 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<QAbstractItemModel::LayoutChangeHint>();
+ qRegisterMetaType<QList<QPersistentModelIndex>>();
}
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..ccce5a44e5 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 <qdebug.h>
+Q_LOGGING_CATEGORY(lcItemModels, "qt.corelib.tests.itemmodels")
+
// Testing get/set functions
void tst_QSortFilterProxyModel::getSetCheck()
{
@@ -2361,6 +2363,45 @@ void tst_QSortFilterProxyModel::match()
QCOMPARE(indexes.at(i).row(), expectedProxyItems.at(i));
}
+QList<QStandardItem *> createStandardItemList(const QString &prefix, int n)
+{
+ QList<QStandardItem *> 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;
@@ -4277,7 +4318,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 +4404,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..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();
@@ -186,4 +187,6 @@ private:
Q_DECLARE_METATYPE(QAbstractItemModel::LayoutChangeHint)
+Q_DECLARE_LOGGING_CATEGORY(lcItemModels)
+
#endif // TST_QSORTFILTERPROXYMODEL_H
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 <QtTest/QtTest>
+#include <QtGui/QBitmap>
+#include <QtGui/QPalette>
+#include <QtGui/QPixmap>
+#include <QtGui/QPicture>
+#include <QtGui/QTextLength>
+#include <QtGui/QPainter>
+#include <QtGui/QPen>
+
+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>(), 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
diff --git a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
index fc4cb717ec..e1bb3149c6 100644
--- a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
+++ b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp
@@ -538,6 +538,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 }
@@ -550,6 +552,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);
}
}
}
diff --git a/tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp b/tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp
index 92384e85bc..182e3e9547 100644
--- a/tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp
+++ b/tests/auto/network/access/qabstractnetworkcache/tst_qabstractnetworkcache.cpp
@@ -256,9 +256,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 0d6828797a..8627a37e12 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -3976,7 +3976,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";
@@ -4002,6 +4002,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
//
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
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
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 <QProcess>
#include <QDir>
-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";
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
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
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/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;
diff --git a/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp b/tests/auto/widgets/widgets/qspinbox/tst_qspinbox.cpp
index 7174c274f9..b9d6888263 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::textChangedHelper(const QString &text)