summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mkspecs/common/msvc-version.conf2
-rw-r--r--mkspecs/common/winrt_winphone/qmake.conf2
-rw-r--r--mkspecs/features/toolchain.prf4
-rw-r--r--qmake/doc/src/qmake-manual.qdoc4
-rw-r--r--src/corelib/configure.json8
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp2
-rw-r--r--src/corelib/global/qconfig-bootstrapped.h14
-rw-r--r--src/corelib/global/qglobal.h2
-rw-r--r--src/corelib/tools/qcryptographichash.cpp40
-rw-r--r--src/corelib/tools/qcryptographichash.h25
-rw-r--r--src/corelib/tools/qdatetime.cpp8
-rw-r--r--src/corelib/tools/qdatetimeparser.cpp4
-rw-r--r--src/corelib/tools/qdatetimeparser_p.h6
-rw-r--r--src/corelib/tools/qlocale.cpp8
-rw-r--r--src/corelib/tools/qmessageauthenticationcode.cpp8
-rw-r--r--src/corelib/tools/qset.h13
-rw-r--r--src/corelib/tools/qtimezoneprivate_tz.cpp4
-rw-r--r--src/corelib/tools/tools.pri7
-rw-r--r--src/gui/configure.json5
-rw-r--r--src/gui/image/qbmphandler.cpp55
-rw-r--r--src/network/access/qhttp2protocolhandler.cpp21
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp11
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp8
-rw-r--r--src/network/socket/qabstractsocket.cpp38
-rw-r--r--src/network/socket/qabstractsocket.h1
-rw-r--r--src/network/socket/qabstractsocket_p.h2
-rw-r--r--src/platformsupport/glxconvenience/qglxconvenience.cpp5
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp2
-rw-r--r--src/platformsupport/kmsconvenience/qkmsdevice.cpp2
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm4
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h6
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp7
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp1
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp15
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h1
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp38
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h5
-rw-r--r--src/plugins/platforms/xcb/xcb_qpa_lib.pro1
-rw-r--r--src/plugins/sqldrivers/mysql/qsql_mysql.cpp18
-rw-r--r--src/plugins/sqldrivers/oci/qsql_oci.cpp9
-rw-r--r--src/tools/moc/generator.cpp16
-rw-r--r--src/widgets/configure.json2
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp18
-rw-r--r--src/widgets/kernel/qgesturemanager.cpp37
-rw-r--r--src/widgets/kernel/qwidget.cpp2
-rw-r--r--src/widgets/kernel/qwindowcontainer.cpp6
-rw-r--r--src/widgets/util/qcompleter_p.h3
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp13
-rw-r--r--src/widgets/widgets/qcombobox.cpp38
-rw-r--r--src/widgets/widgets/qmenubar.cpp3
-rw-r--r--src/widgets/widgets/qtabwidget.cpp83
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp17
-rw-r--r--tests/auto/gui/kernel/qwindow/BLACKLIST2
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp28
-rw-r--r--tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp4
-rw-r--r--tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp64
-rw-r--r--tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp106
-rw-r--r--tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST4
-rw-r--r--tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp26
-rw-r--r--tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp105
-rw-r--r--tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp48
-rw-r--r--tests/benchmarks/corelib/tools/qcryptographichash/main.cpp8
62 files changed, 779 insertions, 270 deletions
diff --git a/mkspecs/common/msvc-version.conf b/mkspecs/common/msvc-version.conf
index c2e22f455a..395c0535a9 100644
--- a/mkspecs/common/msvc-version.conf
+++ b/mkspecs/common/msvc-version.conf
@@ -37,7 +37,7 @@ greaterThan(QMAKE_MSC_VER, 1699) {
# Visual Studio 2012 (11.0) / Visual C++ 17.0 and up
MSVC_VER = 11.0
COMPAT_MKSPEC = win32-msvc2012
- QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -D_HAS_EXCEPTIONS=0
+ QMAKE_CXXFLAGS_EXCEPTIONS_OFF = /wd4530 /wd4577
QT_CONFIG += c++11
CONFIG += c++11
}
diff --git a/mkspecs/common/winrt_winphone/qmake.conf b/mkspecs/common/winrt_winphone/qmake.conf
index 3c68b91bd8..8c1a767dfa 100644
--- a/mkspecs/common/winrt_winphone/qmake.conf
+++ b/mkspecs/common/winrt_winphone/qmake.conf
@@ -52,7 +52,7 @@ QMAKE_CXXFLAGS_STL_OFF =
QMAKE_CXXFLAGS_RTTI_ON = -GR
QMAKE_CXXFLAGS_RTTI_OFF =
QMAKE_CXXFLAGS_EXCEPTIONS_ON = -EHsc
-QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -D_HAS_EXCEPTIONS=0
+QMAKE_CXXFLAGS_EXCEPTIONS_OFF = /wd4530 /wd4577
QMAKE_INCDIR =
diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf
index 35175f1744..7b6f48de72 100644
--- a/mkspecs/features/toolchain.prf
+++ b/mkspecs/features/toolchain.prf
@@ -120,7 +120,7 @@ isEmpty($${target_prefix}.INCDIRS) {
}
}
}
- !darwin:clang {
+ if(!darwin:clang)|intel_icc {
# Clang on a non-Apple system (that is, a system without ld64 -- say, with GNU ld
# or gold under Linux) will not print any library search path. Need to use another
# invocation with different options (which in turn doesn't print include search
@@ -205,7 +205,7 @@ isEmpty($${target_prefix}.COMPILER_MACROS) {
vars = $$qtVariablesFromGCC($$QMAKE_CXX)
}
for (v, vars) {
- isEmpty(v)|contains(v, $${LITERAL_HASH}.*): next()
+ contains(v, $${LITERAL_HASH}.*)|contains(v, " *"): next()
# Set both <varname> for the outer scope ...
eval($$v)
v ~= s/ .*//
diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc
index 8133f8771e..a4e28b4d0c 100644
--- a/qmake/doc/src/qmake-manual.qdoc
+++ b/qmake/doc/src/qmake-manual.qdoc
@@ -3800,8 +3800,8 @@
compiled (see QLibraryInfo::DataPath).
\endlist
- \note The \c QMAKESPEC path will automatically be added to the
- \l{INCLUDEPATH} system variable.
+ \note The \c QMAKESPEC path will be automatically added to the generated
+ Makefile after the contents of the \l{INCLUDEPATH} system variable.
\target cache
\section1 Cache File
diff --git a/src/corelib/configure.json b/src/corelib/configure.json
index 8b503233a0..3feda2fffc 100644
--- a/src/corelib/configure.json
+++ b/src/corelib/configure.json
@@ -815,10 +815,16 @@
},
"timezone": {
"label": "QTimeZone",
- "purpose": "Provides support for timezone handling.",
+ "purpose": "Provides support for time-zone handling.",
"section": "Utilities",
"output": [ "publicFeature" ]
},
+ "datetimeparser": {
+ "label": "QDateTimeParser",
+ "purpose": "Provides support for parsing date-time texts.",
+ "section": "Utilities",
+ "output": [ "privateFeature" ]
+ },
"commandlineparser": {
"label": "QCommandlineParser",
"purpose": "Provides support for command line parsing.",
diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
index 1169ad5536..8d4bd36beb 100644
--- a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
@@ -617,7 +617,7 @@ template<> class QTypeInfo<A> : public QTypeInfoMerger<A, B, C, D> {};
void overloadedFunction(int, QString);
void overloadedFunction(int, QString) const;
};
- ... qConstOverload<>(&Foo::overloadedFunction)
+ ... qConstOverload<int, QString>(&Foo::overloadedFunction)
... qNonConstOverload<int, QString>(&Foo::overloadedFunction)
//! [54]
diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h
index 95095f4b76..2164d7f21f 100644
--- a/src/corelib/global/qconfig-bootstrapped.h
+++ b/src/corelib/global/qconfig-bootstrapped.h
@@ -66,8 +66,7 @@
#define QT_NO_USING_NAMESPACE
#define QT_NO_DEPRECATED
-#define QT_CRYPTOGRAPHICHASH_ONLY_SHA1
-#define QT_NO_DATASTREAM
+// Keep feature-test macros in alphabetic order by feature name:
#define QT_FEATURE_alloca 1
#define QT_FEATURE_alloca_h -1
#ifdef _WIN32
@@ -75,9 +74,13 @@
#else
# define QT_FEATURE_alloca_malloc_h -1
#endif
+#define QT_CRYPTOGRAPHICHASH_ONLY_SHA1
#define QT_FEATURE_cxx11_random (QT_HAS_INCLUDE(<random>) ? 1 : -1)
+#define QT_NO_DATASTREAM
+#define QT_FEATURE_datetimeparser -1
#define QT_FEATURE_getauxval (QT_HAS_INCLUDE(<sys/auxv.h>) ? 1 : -1)
#define QT_FEATURE_getentropy -1
+#define QT_NO_GEOM_VARIANT
#define QT_FEATURE_iconv -1
#define QT_FEATURE_icu -1
#define QT_FEATURE_journald -1
@@ -86,20 +89,19 @@
#define QT_FEATURE_library -1
#define QT_NO_QOBJECT
#define QT_FEATURE_process -1
-#define QT_NO_SYSTEMLOCALE
#define QT_FEATURE_renameat2 -1
+#define QT_FEATURE_sharedmemory -1
#define QT_FEATURE_slog2 -1
#define QT_FEATURE_statx -1
#define QT_FEATURE_syslog -1
+#define QT_NO_SYSTEMLOCALE
+#define QT_FEATURE_systemsemaphore -1
#define QT_FEATURE_temporaryfile 1
#define QT_NO_THREAD
#define QT_FEATURE_timezone -1
#define QT_FEATURE_topleveldomain -1
#define QT_NO_TRANSLATION
#define QT_FEATURE_translation -1
-#define QT_NO_GEOM_VARIANT
-#define QT_FEATURE_sharedmemory -1
-#define QT_FEATURE_systemsemaphore -1
#ifdef QT_BUILD_QMAKE
#define QT_FEATURE_commandlineparser -1
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index ff388770f5..7b691ca59e 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -357,7 +357,7 @@ typedef double qreal;
#if !defined(QT_NAMESPACE) && defined(__cplusplus) && !defined(Q_QDOC)
extern "C"
#endif
-Q_CORE_EXPORT Q_DECL_CONST_FUNCTION const char *qVersion() Q_DECL_NOTHROW;
+Q_CORE_EXPORT Q_DECL_CONST_FUNCTION const char *qVersion(void) Q_DECL_NOTHROW;
#if defined(__cplusplus)
diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp
index ffad2df053..a1b121f1ee 100644
--- a/src/corelib/tools/qcryptographichash.cpp
+++ b/src/corelib/tools/qcryptographichash.cpp
@@ -254,7 +254,9 @@ void QCryptographicHashPrivate::sha3Finish(int bitCount, Sha3Variant sha3Variant
\note In Qt versions before 5.9, when asked to generate a SHA3 hash sum,
QCryptographicHash actually calculated Keccak. If you need compatibility with
- SHA-3 hashes produced by those versions of Qt, use the \c{Keccak_} enumerators.
+ SHA-3 hashes produced by those versions of Qt, use the \c{Keccak_}
+ enumerators. Alternatively, if source compatibility is required, define the
+ macro \c QT_SHA3_KECCAK_COMPAT.
\value Md4 Generate an MD4 hash sum
\value Md5 Generate an MD5 hash sum
@@ -267,10 +269,14 @@ void QCryptographicHashPrivate::sha3Finish(int bitCount, Sha3Variant sha3Variant
\value Sha3_256 Generate an SHA3-256 hash sum. Introduced in Qt 5.1
\value Sha3_384 Generate an SHA3-384 hash sum. Introduced in Qt 5.1
\value Sha3_512 Generate an SHA3-512 hash sum. Introduced in Qt 5.1
- \value Keccak_224 \deprecated Generate a Keccak-224 hash sum. Introduced in Qt 5.10
- \value Keccak_256 \deprecated Generate a Keccak-256 hash sum. Introduced in Qt 5.10
- \value Keccak_384 \deprecated Generate a Keccak-384 hash sum. Introduced in Qt 5.10
- \value Keccak_512 \deprecated Generate a Keccak-512 hash sum. Introduced in Qt 5.10
+ \value Keccak_224 Generate a Keccak-224 hash sum. Introduced in Qt 5.9.2
+ \value Keccak_256 Generate a Keccak-256 hash sum. Introduced in Qt 5.9.2
+ \value Keccak_384 Generate a Keccak-384 hash sum. Introduced in Qt 5.9.2
+ \value Keccak_512 Generate a Keccak-512 hash sum. Introduced in Qt 5.9.2
+ \omitvalue RealSha3_224
+ \omitvalue RealSha3_256
+ \omitvalue RealSha3_384
+ \omitvalue RealSha3_512
*/
/*!
@@ -324,19 +330,19 @@ void QCryptographicHash::reset()
case Sha512:
SHA512Reset(&d->sha512Context);
break;
- case Sha3_224:
+ case RealSha3_224:
case Keccak_224:
sha3Init(&d->sha3Context, 224);
break;
- case Sha3_256:
+ case RealSha3_256:
case Keccak_256:
sha3Init(&d->sha3Context, 256);
break;
- case Sha3_384:
+ case RealSha3_384:
case Keccak_384:
sha3Init(&d->sha3Context, 384);
break;
- case Sha3_512:
+ case RealSha3_512:
case Keccak_512:
sha3Init(&d->sha3Context, 512);
break;
@@ -379,19 +385,19 @@ void QCryptographicHash::addData(const char *data, int length)
case Sha512:
SHA512Input(&d->sha512Context, reinterpret_cast<const unsigned char *>(data), length);
break;
- case Sha3_224:
+ case RealSha3_224:
case Keccak_224:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8);
break;
- case Sha3_256:
+ case RealSha3_256:
case Keccak_256:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8);
break;
- case Sha3_384:
+ case RealSha3_384:
case Keccak_384:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8);
break;
- case Sha3_512:
+ case RealSha3_512:
case Keccak_512:
sha3Update(&d->sha3Context, reinterpret_cast<const BitSequence *>(data), length*8);
break;
@@ -491,19 +497,19 @@ QByteArray QCryptographicHash::result() const
SHA512Result(&copy, reinterpret_cast<unsigned char *>(d->result.data()));
break;
}
- case Sha3_224: {
+ case RealSha3_224: {
d->sha3Finish(224, QCryptographicHashPrivate::Sha3Variant::Sha3);
break;
}
- case Sha3_256: {
+ case RealSha3_256: {
d->sha3Finish(256, QCryptographicHashPrivate::Sha3Variant::Sha3);
break;
}
- case Sha3_384: {
+ case RealSha3_384: {
d->sha3Finish(384, QCryptographicHashPrivate::Sha3Variant::Sha3);
break;
}
- case Sha3_512: {
+ case RealSha3_512: {
d->sha3Finish(512, QCryptographicHashPrivate::Sha3Variant::Sha3);
break;
}
diff --git a/src/corelib/tools/qcryptographichash.h b/src/corelib/tools/qcryptographichash.h
index 20afab8b87..2f74d42405 100644
--- a/src/corelib/tools/qcryptographichash.h
+++ b/src/corelib/tools/qcryptographichash.h
@@ -65,15 +65,26 @@ public:
Sha256,
Sha384,
Sha512,
- Sha3_224,
- Sha3_256,
- Sha3_384,
- Sha3_512,
- // ### Qt 6: remove the Keccak enumerators
- Keccak_224,
+
+ Keccak_224 = 7,
Keccak_256,
Keccak_384,
- Keccak_512
+ Keccak_512,
+ RealSha3_224 = 11,
+ RealSha3_256,
+ RealSha3_384,
+ RealSha3_512,
+# ifndef QT_SHA3_KECCAK_COMPAT
+ Sha3_224 = RealSha3_224,
+ Sha3_256 = RealSha3_256,
+ Sha3_384 = RealSha3_384,
+ Sha3_512 = RealSha3_512
+# else
+ Sha3_224 = Keccak_224,
+ Sha3_256 = Keccak_256,
+ Sha3_384 = Keccak_384,
+ Sha3_512 = Keccak_512
+# endif
#endif
};
Q_ENUM(Algorithm)
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index 056dff5442..f6fc672486 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -40,7 +40,9 @@
#include "qplatformdefs.h"
#include "private/qdatetime_p.h"
+#if QT_CONFIG(datetimeparser)
#include "private/qdatetimeparser_p.h"
+#endif
#include "qdatastream.h"
#include "qset.h"
@@ -1337,7 +1339,7 @@ QDate QDate::fromString(const QString& string, Qt::DateFormat format)
QDate QDate::fromString(const QString &string, const QString &format)
{
QDate date;
-#if QT_CONFIG(timezone)
+#if QT_CONFIG(datetimeparser)
QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString);
// dt.setDefaultLocale(QLocale::c()); ### Qt 6
if (dt.parseFormat(format))
@@ -2055,7 +2057,7 @@ QTime QTime::fromString(const QString& string, Qt::DateFormat format)
QTime QTime::fromString(const QString &string, const QString &format)
{
QTime time;
-#if QT_CONFIG(timezone)
+#if QT_CONFIG(datetimeparser)
QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString);
// dt.setDefaultLocale(QLocale::c()); ### Qt 6
if (dt.parseFormat(format))
@@ -5055,7 +5057,7 @@ QDateTime QDateTime::fromString(const QString& string, Qt::DateFormat format)
QDateTime QDateTime::fromString(const QString &string, const QString &format)
{
-#if QT_CONFIG(timezone)
+#if QT_CONFIG(datetimeparser)
QTime time;
QDate date;
diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp
index 3908e6710e..978b663444 100644
--- a/src/corelib/tools/qdatetimeparser.cpp
+++ b/src/corelib/tools/qdatetimeparser.cpp
@@ -59,8 +59,6 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_BOOTSTRAPPED
-
QDateTimeParser::~QDateTimeParser()
{
}
@@ -1996,6 +1994,4 @@ bool operator==(const QDateTimeParser::SectionNode &s1, const QDateTimeParser::S
return (s1.type == s2.type) && (s1.pos == s2.pos) && (s1.count == s2.count);
}
-#endif // QT_BOOTSTRAPPED
-
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qdatetimeparser_p.h b/src/corelib/tools/qdatetimeparser_p.h
index f6f9ed5e24..75497f5c5a 100644
--- a/src/corelib/tools/qdatetimeparser_p.h
+++ b/src/corelib/tools/qdatetimeparser_p.h
@@ -63,6 +63,8 @@
#include "QtCore/qvector.h"
#include "QtCore/qcoreapplication.h"
+QT_REQUIRE_CONFIG(datetimeparser);
+
#define QDATETIMEEDIT_TIME_MIN QTime(0, 0, 0, 0)
#define QDATETIMEEDIT_TIME_MAX QTime(23, 59, 59, 999)
#define QDATETIMEEDIT_DATE_MIN QDate(100, 1, 1)
@@ -75,8 +77,6 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_BOOTSTRAPPED
-
class Q_CORE_EXPORT QDateTimeParser
{
Q_DECLARE_TR_FUNCTIONS(QDateTimeParser)
@@ -305,8 +305,6 @@ Q_CORE_EXPORT bool operator==(const QDateTimeParser::SectionNode &s1, const QDat
Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimeParser::Sections)
Q_DECLARE_OPERATORS_FOR_FLAGS(QDateTimeParser::FieldInfo)
-#endif // QT_BOOTSTRAPPED
-
QT_END_NAMESPACE
#endif // QDATETIME_P_H
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 9a46018ede..723e63114d 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -54,7 +54,9 @@
#include "qlocale.h"
#include "qlocale_p.h"
#include "qlocale_tools_p.h"
+#if QT_CONFIG(datetimeparser)
#include "qdatetimeparser_p.h"
+#endif
#include "qnamespace.h"
#include "qdatetime.h"
#include "qstringlist.h"
@@ -2084,7 +2086,7 @@ QDateTime QLocale::toDateTime(const QString &string, FormatType format) const
QTime QLocale::toTime(const QString &string, const QString &format) const
{
QTime time;
-#ifndef QT_BOOTSTRAPPED
+#if QT_CONFIG(datetimeparser)
QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString);
dt.setDefaultLocale(*this);
if (dt.parseFormat(format))
@@ -2115,7 +2117,7 @@ QTime QLocale::toTime(const QString &string, const QString &format) const
QDate QLocale::toDate(const QString &string, const QString &format) const
{
QDate date;
-#ifndef QT_BOOTSTRAPPED
+#if QT_CONFIG(datetimeparser)
QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString);
dt.setDefaultLocale(*this);
if (dt.parseFormat(format))
@@ -2145,7 +2147,7 @@ QDate QLocale::toDate(const QString &string, const QString &format) const
#ifndef QT_NO_DATESTRING
QDateTime QLocale::toDateTime(const QString &string, const QString &format) const
{
-#ifndef QT_BOOTSTRAPPED
+#if QT_CONFIG(datetimeparser)
QTime time;
QDate date;
diff --git a/src/corelib/tools/qmessageauthenticationcode.cpp b/src/corelib/tools/qmessageauthenticationcode.cpp
index 5dd9591bc6..40a1193622 100644
--- a/src/corelib/tools/qmessageauthenticationcode.cpp
+++ b/src/corelib/tools/qmessageauthenticationcode.cpp
@@ -99,16 +99,16 @@ static int qt_hash_block_size(QCryptographicHash::Algorithm method)
return SHA384_Message_Block_Size;
case QCryptographicHash::Sha512:
return SHA512_Message_Block_Size;
- case QCryptographicHash::Sha3_224:
+ case QCryptographicHash::RealSha3_224:
case QCryptographicHash::Keccak_224:
return 144;
- case QCryptographicHash::Sha3_256:
+ case QCryptographicHash::RealSha3_256:
case QCryptographicHash::Keccak_256:
return 136;
- case QCryptographicHash::Sha3_384:
+ case QCryptographicHash::RealSha3_384:
case QCryptographicHash::Keccak_384:
return 104;
- case QCryptographicHash::Sha3_512:
+ case QCryptographicHash::RealSha3_512:
case QCryptographicHash::Keccak_512:
return 72;
}
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index 08b38a08c2..7ded120ab7 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -340,13 +340,14 @@ Q_INLINE_TEMPLATE bool QSet<T>::intersects(const QSet<T> &other) const
template <class T>
Q_INLINE_TEMPLATE QSet<T> &QSet<T>::subtract(const QSet<T> &other)
{
- QSet<T> copy1(*this);
- QSet<T> copy2(other);
- typename QSet<T>::const_iterator i = copy1.constEnd();
- while (i != copy1.constBegin()) {
- --i;
- if (copy2.contains(*i))
+ if (&other == this) {
+ clear();
+ } else {
+ auto i = other.constEnd();
+ while (i != other.constBegin()) {
+ --i;
remove(*i);
+ }
}
return *this;
}
diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp
index 521475c2dd..bcc1285472 100644
--- a/src/corelib/tools/qtimezoneprivate_tz.cpp
+++ b/src/corelib/tools/qtimezoneprivate_tz.cpp
@@ -272,8 +272,9 @@ static void parseTzLeapSeconds(QDataStream &ds, int tzh_leapcnt, bool longTran)
{
// Parse tzh_leapcnt x pairs of leap seconds
// We don't use leap seconds, so only read and don't store
- qint64 val;
+ qint32 val;
if (longTran) {
+ // v2 file format, each entry is 12 bytes long
qint64 time;
for (int i = 0; i < tzh_leapcnt && ds.status() == QDataStream::Ok; ++i) {
// Parse Leap Occurrence Time, 8 bytes
@@ -283,6 +284,7 @@ static void parseTzLeapSeconds(QDataStream &ds, int tzh_leapcnt, bool longTran)
ds >> val;
}
} else {
+ // v0 file format, each entry is 8 bytes long
for (int i = 0; i < tzh_leapcnt && ds.status() == QDataStream::Ok; ++i) {
// Parse Leap Occurrence Time, 4 bytes
ds >> val;
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index aa545497a2..2c609098ea 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -21,7 +21,6 @@ HEADERS += \
tools/qcryptographichash.h \
tools/qdatetime.h \
tools/qdatetime_p.h \
- tools/qdatetimeparser_p.h \
tools/qdoublescanprint_p.h \
tools/qeasingcurve.h \
tools/qfreelist_p.h \
@@ -84,7 +83,6 @@ SOURCES += \
tools/qcollator.cpp \
tools/qcryptographichash.cpp \
tools/qdatetime.cpp \
- tools/qdatetimeparser.cpp \
tools/qeasingcurve.cpp \
tools/qfreelist.cpp \
tools/qhash.cpp \
@@ -173,6 +171,11 @@ qtConfig(timezone) {
SOURCES += tools/qtimezoneprivate_icu.cpp
}
+qtConfig(datetimeparser) {
+ HEADERS += tools/qdatetimeparser_p.h
+ SOURCES += tools/qdatetimeparser.cpp
+}
+
qtConfig(regularexpression) {
QMAKE_USE_PRIVATE += pcre2
diff --git a/src/gui/configure.json b/src/gui/configure.json
index 17b4c3df2c..0a591e110c 100644
--- a/src/gui/configure.json
+++ b/src/gui/configure.json
@@ -443,6 +443,7 @@
"xcb/xfixes.h",
"xcb/xcb_image.h",
"xcb/xcb_keysyms.h",
+ "xcb/xinerama.h",
"xcb/sync.h",
"xcb/randr.h",
"xcb/shm.h"
@@ -460,8 +461,8 @@
},
"sources": [
{ "type": "pkgConfig",
- "args": "xcb xcb-shm xcb-sync xcb-xfixes xcb-randr xcb-image xcb-keysyms xcb-icccm xcb-shape" },
- "-lxcb -lxcb-shm -lxcb-sync -lxcb-xfixes -lxcb-randr -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-shape"
+ "args": "xcb xcb-shm xcb-sync xcb-xfixes xcb-xinerama xcb-randr xcb-image xcb-keysyms xcb-icccm xcb-shape" },
+ "-lxcb -lxcb-shm -lxcb-sync -lxcb-xfixes -lxcb-xinerama -lxcb-randr -lxcb-image -lxcb-keysyms -lxcb-icccm -lxcb-shape"
]
},
"xcb_xlib": {
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp
index c232a84e4f..1ec45a7491 100644
--- a/src/gui/image/qbmphandler.cpp
+++ b/src/gui/image/qbmphandler.cpp
@@ -562,27 +562,12 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
}
// this is also used in qmime_win.cpp
-bool qt_write_dib(QDataStream &s, QImage image)
+bool qt_write_dib(QDataStream &s, const QImage &image, int bpl, int bpl_bmp, int nbits)
{
- int nbits;
- int bpl_bmp;
- int bpl = image.bytesPerLine();
-
QIODevice* d = s.device();
if (!d->isWritable())
return false;
- if (image.depth() == 8 && image.colorCount() <= 16) {
- bpl_bmp = (((bpl+1)/2+3)/4)*4;
- nbits = 4;
- } else if (image.depth() == 32) {
- bpl_bmp = ((image.width()*24+31)/32)*4;
- nbits = 24;
- } else {
- bpl_bmp = bpl;
- nbits = image.depth();
- }
-
BMP_INFOHDR bi;
bi.biSize = BMP_WIN; // build info header
bi.biWidth = image.width();
@@ -617,9 +602,6 @@ bool qt_write_dib(QDataStream &s, QImage image)
delete [] color_table;
}
- if (image.format() == QImage::Format_MonoLSB)
- image = image.convertToFormat(QImage::Format_Mono);
-
int y;
if (nbits == 1 || nbits == 8) { // direct output
@@ -769,21 +751,17 @@ bool QBmpHandler::read(QImage *image)
bool QBmpHandler::write(const QImage &img)
{
- if (m_format == DibFormat) {
- QDataStream dibStream(device());
- dibStream.setByteOrder(QDataStream::LittleEndian); // Intel byte order
- return qt_write_dib(dibStream, img);
- }
-
QImage image;
switch (img.format()) {
case QImage::Format_Mono:
- case QImage::Format_MonoLSB:
case QImage::Format_Indexed8:
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
image = img;
break;
+ case QImage::Format_MonoLSB:
+ image = img.convertToFormat(QImage::Format_Mono);
+ break;
case QImage::Format_Alpha8:
case QImage::Format_Grayscale8:
image = img.convertToFormat(QImage::Format_Indexed8);
@@ -796,21 +774,32 @@ bool QBmpHandler::write(const QImage &img)
break;
}
- QIODevice *d = device();
- QDataStream s(d);
- BMP_FILEHDR bf;
+ int nbits;
int bpl_bmp;
- int bpl = image.bytesPerLine();
+ // Calculate a minimum bytes-per-line instead of using whatever value this QImage is using internally.
+ int bpl = ((image.width() * image.depth() + 31) >> 5) << 2;
- // Code partially repeated in qt_write_dib
if (image.depth() == 8 && image.colorCount() <= 16) {
bpl_bmp = (((bpl+1)/2+3)/4)*4;
- } else if (image.depth() == 32) {
+ nbits = 4;
+ } else if (image.depth() == 32) {
bpl_bmp = ((image.width()*24+31)/32)*4;
+ nbits = 24;
} else {
bpl_bmp = bpl;
+ nbits = image.depth();
}
+ if (m_format == DibFormat) {
+ QDataStream dibStream(device());
+ dibStream.setByteOrder(QDataStream::LittleEndian); // Intel byte order
+ return qt_write_dib(dibStream, img, bpl, bpl_bmp, nbits);
+ }
+
+ QIODevice *d = device();
+ QDataStream s(d);
+ BMP_FILEHDR bf;
+
// Intel byte order
s.setByteOrder(QDataStream::LittleEndian);
@@ -825,7 +814,7 @@ bool QBmpHandler::write(const QImage &img)
s << bf;
// write image
- return qt_write_dib(s, image);
+ return qt_write_dib(s, image, bpl, bpl_bmp, nbits);
}
bool QBmpHandler::supportsOption(ImageOption option) const
diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp
index 5032f6017f..a651fc4092 100644
--- a/src/network/access/qhttp2protocolhandler.cpp
+++ b/src/network/access/qhttp2protocolhandler.cpp
@@ -1042,12 +1042,26 @@ void QHttp2ProtocolHandler::updateStream(Stream &stream, const HPack::HttpHeader
}
const auto httpReplyPrivate = httpReply->d_func();
+
+ // For HTTP/1 'location' is handled (and redirect URL set) when a protocol
+ // handler emits channel->allDone(). Http/2 protocol handler never emits
+ // allDone, since we have many requests multiplexed in one channel at any
+ // moment and we are probably not done yet. So we extract url and set it
+ // here, if needed.
+ int statusCode = 0;
+ QUrl redirectUrl;
+
for (const auto &pair : headers) {
const auto &name = pair.name;
auto value = pair.value;
+ // TODO: part of this code copies what SPDY protocol handler does when
+ // processing headers. Binary nature of HTTP/2 and SPDY saves us a lot
+ // of parsing and related errors/bugs, but it would be nice to have
+ // more detailed validation of headers.
if (name == ":status") {
- httpReply->setStatusCode(value.left(3).toInt());
+ statusCode = value.left(3).toInt();
+ httpReply->setStatusCode(statusCode);
httpReplyPrivate->reasonPhrase = QString::fromLatin1(value.mid(4));
} else if (name == ":version") {
httpReplyPrivate->majorVersion = value.at(5) - '0';
@@ -1058,6 +1072,8 @@ void QHttp2ProtocolHandler::updateStream(Stream &stream, const HPack::HttpHeader
if (ok)
httpReply->setContentLength(length);
} else {
+ if (name == "location")
+ redirectUrl = QUrl::fromEncoded(value);
QByteArray binder(", ");
if (name == "set-cookie")
binder = "\n";
@@ -1065,6 +1081,9 @@ void QHttp2ProtocolHandler::updateStream(Stream &stream, const HPack::HttpHeader
}
}
+ if (QHttpNetworkReply::isHttpRedirect(statusCode) && redirectUrl.isValid())
+ httpReply->setRedirectUrl(redirectUrl);
+
if (connectionType == Qt::DirectConnection)
emit httpReply->headerChanged();
else
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 8bbef0a0d8..edf9dee78e 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -75,6 +75,12 @@
#include <QHostInfo>
+#if defined(Q_OS_MACOS)
+#include <CoreServices/CoreServices.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <Security/SecKeychain.h>
+#endif
+
QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QNetworkAccessFileBackendFactory, fileBackend)
@@ -87,11 +93,6 @@ Q_GLOBAL_STATIC(QNetworkAccessDebugPipeBackendFactory, debugpipeBackend)
#endif
#if defined(Q_OS_MACX)
-
-#include <CoreServices/CoreServices.h>
-#include <SystemConfiguration/SystemConfiguration.h>
-#include <Security/SecKeychain.h>
-
bool getProxyAuth(const QString& proxyHostname, const QString &scheme, QString& username, QString& password)
{
OSStatus err;
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 84b1ddf5ac..48255d175a 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -1169,6 +1169,14 @@ void QNetworkReplyHttpImplPrivate::onRedirected(const QUrl &redirectUrl, int htt
redirectRequest = createRedirectRequest(originalRequest, url, maxRedirectsRemaining);
operation = getRedirectOperation(operation, httpStatus);
+ if (const QNetworkCookieJar *const cookieJar = (manager ? manager->cookieJar() : nullptr)) {
+ auto cookies = cookieJar->cookiesForUrl(url);
+ if (!cookies.empty()) {
+ redirectRequest.setHeader(QNetworkRequest::KnownHeaders::CookieHeader,
+ QVariant::fromValue(cookies));
+ }
+ }
+
if (httpRequest.redirectPolicy() != QNetworkRequest::UserVerifiedRedirectPolicy)
followRedirect();
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index 9cb6c4be57..7284b124c5 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -565,7 +565,6 @@ QAbstractSocketPrivate::QAbstractSocketPrivate()
isBuffered(false),
hasPendingData(false),
connectTimer(0),
- disconnectTimer(0),
hostLookupId(-1),
socketType(QAbstractSocket::UnknownSocketType),
state(QAbstractSocket::UnconnectedState),
@@ -604,8 +603,6 @@ void QAbstractSocketPrivate::resetSocketLayer()
}
if (connectTimer)
connectTimer->stop();
- if (disconnectTimer)
- disconnectTimer->stop();
}
/*! \internal
@@ -967,13 +964,17 @@ void QAbstractSocketPrivate::startConnectingByName(const QString &host)
emit q->stateChanged(state);
if (cachedSocketDescriptor != -1 || initSocketLayer(QAbstractSocket::UnknownNetworkLayerProtocol)) {
- if (socketEngine->connectToHostByName(host, port) ||
- socketEngine->state() == QAbstractSocket::ConnectingState) {
- cachedSocketDescriptor = socketEngine->socketDescriptor();
-
+ // Try to connect to the host. If it succeeds immediately
+ // (e.g. QSocks5SocketEngine in UDPASSOCIATE mode), emit
+ // connected() and return.
+ if (socketEngine->connectToHostByName(host, port)) {
+ fetchConnectionParameters();
return;
}
+ if (socketEngine->state() == QAbstractSocket::ConnectingState)
+ return;
+
// failed to connect
setError(socketEngine->error(), socketEngine->errorString());
}
@@ -1220,15 +1221,6 @@ void QAbstractSocketPrivate::_q_abortConnectionAttempt()
}
}
-void QAbstractSocketPrivate::_q_forceDisconnect()
-{
- Q_Q(QAbstractSocket);
- if (socketEngine && socketEngine->isValid() && state == QAbstractSocket::ClosingState) {
- socketEngine->close();
- q->disconnectFromHost();
- }
-}
-
/*! \internal
Reads data from the socket layer into the read buffer. Returns
@@ -2756,20 +2748,6 @@ void QAbstractSocket::disconnectFromHost()
// Wait for pending data to be written.
if (d->socketEngine && d->socketEngine->isValid() && (!d->allWriteBuffersEmpty()
|| d->socketEngine->bytesToWrite() > 0)) {
- // hack: when we are waiting for the socket engine to write bytes (only
- // possible when using Socks5 or HTTP socket engine), then close
- // anyway after 2 seconds. This is to prevent a timeout on Mac, where we
- // sometimes just did not get the write notifier from the underlying
- // CFSocket and no progress was made.
- if (d->allWriteBuffersEmpty() && d->socketEngine->bytesToWrite() > 0) {
- if (!d->disconnectTimer) {
- d->disconnectTimer = new QTimer(this);
- connect(d->disconnectTimer, SIGNAL(timeout()), this,
- SLOT(_q_forceDisconnect()), Qt::DirectConnection);
- }
- if (!d->disconnectTimer->isActive())
- d->disconnectTimer->start(2000);
- }
d->socketEngine->setWriteNotificationEnabled(true);
#if defined(QABSTRACTSOCKET_DEBUG)
diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h
index 73a8f11537..875609aa28 100644
--- a/src/network/socket/qabstractsocket.h
+++ b/src/network/socket/qabstractsocket.h
@@ -231,7 +231,6 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_startConnecting(const QHostInfo &))
Q_PRIVATE_SLOT(d_func(), void _q_abortConnectionAttempt())
Q_PRIVATE_SLOT(d_func(), void _q_testConnection())
- Q_PRIVATE_SLOT(d_func(), void _q_forceDisconnect())
};
diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h
index 8a96cb9d48..5411133ea9 100644
--- a/src/network/socket/qabstractsocket_p.h
+++ b/src/network/socket/qabstractsocket_p.h
@@ -95,7 +95,6 @@ public:
void _q_startConnecting(const QHostInfo &hostInfo);
void _q_testConnection();
void _q_abortConnectionAttempt();
- void _q_forceDisconnect();
bool emittedReadyRead;
bool emittedBytesWritten;
@@ -148,7 +147,6 @@ public:
bool hasPendingData;
QTimer *connectTimer;
- QTimer *disconnectTimer;
int hostLookupId;
diff --git a/src/platformsupport/glxconvenience/qglxconvenience.cpp b/src/platformsupport/glxconvenience/qglxconvenience.cpp
index 0c2b757920..8d2e58b57b 100644
--- a/src/platformsupport/glxconvenience/qglxconvenience.cpp
+++ b/src/platformsupport/glxconvenience/qglxconvenience.cpp
@@ -172,7 +172,8 @@ bool QXcbSoftwareOpenGLEnforcer::forceSoftwareOpenGL = false;
template <class T>
struct QXlibScopedPointerDeleter {
static inline void cleanup(T *pointer) {
- XFree(pointer);
+ if (pointer)
+ XFree(pointer);
}
};
@@ -217,6 +218,8 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format
}
QXlibPointer<XVisualInfo> visual(glXGetVisualFromFBConfig(display, candidate));
+ if (visual.isNull())
+ continue;
const int actualRed = qPopulationCount(visual->red_mask);
const int actualGreen = qPopulationCount(visual->green_mask);
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
index df2c079f24..c7595cf2b3 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
+++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
@@ -55,6 +55,8 @@
#include <linux/input.h>
#endif
+#include <math.h>
+
#if QT_CONFIG(mtdev)
extern "C" {
#include <mtdev.h>
diff --git a/src/platformsupport/kmsconvenience/qkmsdevice.cpp b/src/platformsupport/kmsconvenience/qkmsdevice.cpp
index 71b7633e6c..a25a1e582f 100644
--- a/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+++ b/src/platformsupport/kmsconvenience/qkmsdevice.cpp
@@ -508,7 +508,7 @@ void QKmsDevice::createScreens()
} else {
virtualPos = orderedScreen.vinfo.virtualPos;
}
- qCDebug(qLcKmsDebug) << "Adding QPlatformScren" << s << "(" << s->name() << ")"
+ qCDebug(qLcKmsDebug) << "Adding QPlatformScreen" << s << "(" << s->name() << ")"
<< "to QPA with geometry" << s->geometry()
<< "and isPrimary=" << orderedScreen.vinfo.isPrimary;
// The order in qguiapp's screens list will match the order set by
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 643d3b3a30..054dca122f 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -1374,6 +1374,10 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
if (m_composingText.isEmpty()) {
m_sendKeyEvent = !QWindowSystemInterface::handleShortcutEvent(window, timestamp, keyCode,
modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, [nsevent isARepeat], 1);
+
+ // Handling a shortcut may result in closing the window
+ if (!m_platformWindow)
+ return true;
}
QObject *fo = m_platformWindow->window()->focusObject();
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index d9c342be27..c8bdc1c93e 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -101,6 +101,8 @@ enum WindowsEventType // Simplify event types
FocusOutEvent = WindowEventFlag + 18,
WhatsThisEvent = WindowEventFlag + 19,
DpiChangedEvent = WindowEventFlag + 21,
+ EnterSizeMoveEvent = WindowEventFlag + 22,
+ ExitSizeMoveEvent = WindowEventFlag + 23,
MouseEvent = MouseEventFlag + 1,
MouseWheelEvent = MouseEventFlag + 2,
CursorEvent = MouseEventFlag + 3,
@@ -282,6 +284,10 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
return HIWORD(wParamIn) ? QtWindows::AcceleratorCommandEvent : QtWindows::MenuCommandEvent;
case WM_DPICHANGED:
return QtWindows::DpiChangedEvent;
+ case WM_ENTERSIZEMOVE:
+ return QtWindows::EnterSizeMoveEvent;
+ case WM_EXITSIZEMOVE:
+ return QtWindows::ExitSizeMoveEvent;
default:
break;
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 7683f0da4d..289a61336f 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -1081,6 +1081,13 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
if (platformWindow->frameStrutEventsEnabled())
return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result);
break;
+ case QtWindows::EnterSizeMoveEvent:
+ platformWindow->setFlag(QWindowsWindow::ResizeMoveActive);
+ return true;
+ case QtWindows::ExitSizeMoveEvent:
+ platformWindow->clearFlag(QWindowsWindow::ResizeMoveActive);
+ platformWindow->checkForScreenChanged();
+ return true;
case QtWindows::ScrollEvent:
return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateScrollEvent(platformWindow->window(), hwnd, msg, result);
case QtWindows::MouseWheelEvent:
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index af4304cb19..2b14edc804 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -233,6 +233,7 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
// Check for events synthesized from touch. Lower 7 bits are touch/pen index, bit 8 indicates touch.
// However, when tablet support is active, extraInfo is a packet serial number. This is not a problem
// since we do not want to ignore mouse events coming from a tablet.
+ // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms703320.aspx
const quint64 extraInfo = quint64(GetMessageExtraInfo());
if ((extraInfo & signatureMask) == miWpSignature) {
if (extraInfo & 0x80) { // Bit 7 indicates touch event, else tablet pen.
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 3a4793efcd..cfddb3cc71 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -566,4 +566,19 @@ const QWindowsScreen *QWindowsScreenManager::screenAtDp(const QPoint &p) const
return Q_NULLPTR;
}
+const QWindowsScreen *QWindowsScreenManager::screenForHwnd(HWND hwnd) const
+{
+ HMONITOR hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
+ if (hMonitor == NULL)
+ return nullptr;
+ const auto it =
+ std::find_if(m_screens.cbegin(), m_screens.cend(),
+ [hMonitor](const QWindowsScreen *s)
+ {
+ return s->data().hMonitor == hMonitor
+ && (s->data().flags & QWindowsScreenData::VirtualDesktop) != 0;
+ });
+ return it != m_screens.cend() ? *it : nullptr;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index 9a8997326b..7cf73f03af 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -134,6 +134,7 @@ public:
const WindowsScreenList &screens() const { return m_screens; }
const QWindowsScreen *screenAtDp(const QPoint &p) const;
+ const QWindowsScreen *screenForHwnd(HWND hwnd) const;
private:
void removeScreen(int index);
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 3f417fde27..312ff9065f 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -896,7 +896,9 @@ void QWindowsBaseWindow::hide_sys() // Normal hide, do not activate other window
void QWindowsBaseWindow::raise_sys()
{
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
- if (window()->type() == Qt::Popup
+ const Qt::WindowType type = window()->type();
+ if (type == Qt::Popup
+ || type == Qt::SubWindow // Special case for QTBUG-63121: MDI subwindows with WindowStaysOnTopHint
|| (window()->flags() & (Qt::WindowStaysOnTopHint | Qt::WindowStaysOnBottomHint)) == 0) {
SetWindowPos(handle(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
@@ -1629,6 +1631,26 @@ void QWindowsWindow::handleResized(int wParam)
}
}
+void QWindowsWindow::checkForScreenChanged()
+{
+ if (parent())
+ return;
+
+ QPlatformScreen *currentScreen = screen();
+ const auto &screenManager = QWindowsContext::instance()->screenManager();
+ // QTBUG-62971: When dragging a window by its border, detect by mouse position
+ // to prevent it from oscillating between screens when it resizes
+ const QWindowsScreen *newScreen = testFlag(ResizeMoveActive)
+ ? screenManager.screenAtDp(QWindowsCursor::mousePosition())
+ : screenManager.screenForHwnd(m_data.hwnd);
+ if (newScreen != nullptr && newScreen != currentScreen) {
+ qCDebug(lcQpaWindows).noquote().nospace() << __FUNCTION__
+ << ' ' << window() << " \"" << currentScreen->name()
+ << "\"->\"" << newScreen->name() << '"';
+ QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
+ }
+}
+
void QWindowsWindow::handleGeometryChange()
{
const QRect previousGeometry = m_data.geometry;
@@ -1642,17 +1664,9 @@ void QWindowsWindow::handleGeometryChange()
&& !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) {
fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true);
}
- if (!parent() && previousGeometry.topLeft() != m_data.geometry.topLeft()) {
- HMONITOR hMonitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONULL);
- QPlatformScreen *currentScreen = screen();
- const auto screens = QWindowsContext::instance()->screenManager().screens();
- auto newScreenIt = std::find_if(screens.begin(), screens.end(), [&](QWindowsScreen *s) {
- return s->data().hMonitor == hMonitor
- && s->data().flags & QWindowsScreenData::VirtualDesktop;
- });
- if (newScreenIt != screens.end() && *newScreenIt != currentScreen)
- QWindowSystemInterface::handleWindowScreenChanged(window(), (*newScreenIt)->screen());
- }
+
+ checkForScreenChanged();
+
if (testFlag(SynchronousGeometryChangeEvent))
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index f0789e5167..414d4a92f8 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -217,7 +217,8 @@ public:
Compositing = 0x200000,
HasBorderInFullScreen = 0x400000,
WithinDpiChanged = 0x800000,
- VulkanSurface = 0x1000000
+ VulkanSurface = 0x1000000,
+ ResizeMoveActive = 0x2000000
};
QWindowsWindow(QWindow *window, const QWindowsWindowData &data);
@@ -328,6 +329,8 @@ public:
void alertWindow(int durationMs = 0);
void stopAlertWindow();
+ void checkForScreenChanged();
+
static void setTouchWindowTouchTypeStatic(QWindow *window, QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes);
void registerTouchWindow(QWindowsWindowFunctions::TouchWindowTouchTypes touchTypes = QWindowsWindowFunctions::NormalTouch);
static void setHasBorderInFullScreenStatic(QWindow *window, bool border);
diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
index 6956d04083..a98a7892dd 100644
--- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro
+++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
@@ -83,7 +83,6 @@ qtConfig(vulkan) {
!qtConfig(system-xcb) {
QMAKE_USE += xcb-static xcb
} else {
- LIBS += -lxcb-xinerama ### there is no configure test for this!
qtConfig(xkb): QMAKE_USE += xcb_xkb
qtConfig(xcb-render): QMAKE_USE += xcb_render
QMAKE_USE += xcb_syslibs
diff --git a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
index 3dc0e73af5..d9aebff700 100644
--- a/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
+++ b/src/plugins/sqldrivers/mysql/qsql_mysql.cpp
@@ -1159,16 +1159,22 @@ static void qLibraryInit()
}
# endif // MYSQL_VERSION_ID
#endif // Q_NO_MYSQL_EMBEDDED
+
+#ifdef MARIADB_BASE_VERSION
+ qAddPostRoutine(mysql_server_end);
+#endif
}
static void qLibraryEnd()
{
-#ifndef Q_NO_MYSQL_EMBEDDED
-# if MYSQL_VERSION_ID > 40000
-# if (MYSQL_VERSION_ID >= 40110 && MYSQL_VERSION_ID < 50000) || MYSQL_VERSION_ID >= 50003
- mysql_library_end();
-# else
- mysql_server_end();
+#if !defined(MARIADB_BASE_VERSION)
+# if !defined(Q_NO_MYSQL_EMBEDDED)
+# if MYSQL_VERSION_ID > 40000
+# if (MYSQL_VERSION_ID >= 40110 && MYSQL_VERSION_ID < 50000) || MYSQL_VERSION_ID >= 50003
+ mysql_library_end();
+# else
+ mysql_server_end();
+# endif
# endif
# endif
#endif
diff --git a/src/plugins/sqldrivers/oci/qsql_oci.cpp b/src/plugins/sqldrivers/oci/qsql_oci.cpp
index 32d3681a17..a4793351de 100644
--- a/src/plugins/sqldrivers/oci/qsql_oci.cpp
+++ b/src/plugins/sqldrivers/oci/qsql_oci.cpp
@@ -206,6 +206,7 @@ protected:
QVariant lastInsertId() const Q_DECL_OVERRIDE;
bool execBatch(bool arrayBind = false) Q_DECL_OVERRIDE;
void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
+ bool fetchNext() override;
};
class QOCIResultPrivate: public QSqlCachedResultPrivate
@@ -2097,6 +2098,14 @@ void QOCIResult::virtual_hook(int id, void *data)
QSqlCachedResult::virtual_hook(id, data);
}
+bool QOCIResult::fetchNext()
+{
+ Q_D(QOCIResult);
+ if (isForwardOnly())
+ d->cache.clear();
+ return QSqlCachedResult::fetchNext();
+}
+
////////////////////////////////////////////////////////////////////////////
diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp
index 0b45776b88..139f7328af 100644
--- a/src/tools/moc/generator.cpp
+++ b/src/tools/moc/generator.cpp
@@ -562,14 +562,14 @@ void Generator::generateCode()
fprintf(out, "\nvoid *%s::qt_metacast(const char *_clname)\n{\n", cdef->qualified.constData());
fprintf(out, " if (!_clname) return nullptr;\n");
fprintf(out, " if (!strcmp(_clname, qt_meta_stringdata_%s.stringdata0))\n"
- " return static_cast<void*>(const_cast< %s*>(this));\n",
- qualifiedClassNameIdentifier.constData(), cdef->classname.constData());
+ " return static_cast<void*>(this);\n",
+ qualifiedClassNameIdentifier.constData());
for (int i = 1; i < cdef->superclassList.size(); ++i) { // for all superclasses but the first one
if (cdef->superclassList.at(i).second == FunctionDef::Private)
continue;
const char *cname = cdef->superclassList.at(i).first.constData();
- fprintf(out, " if (!strcmp(_clname, \"%s\"))\n return static_cast< %s*>(const_cast< %s*>(this));\n",
- cname, cname, cdef->classname.constData());
+ fprintf(out, " if (!strcmp(_clname, \"%s\"))\n return static_cast< %s*>(this);\n",
+ cname, cname);
}
for (int i = 0; i < cdef->interfaceList.size(); ++i) {
const QVector<ClassDef::Interface> &iface = cdef->interfaceList.at(i);
@@ -577,8 +577,7 @@ void Generator::generateCode()
fprintf(out, " if (!strcmp(_clname, %s))\n return ", iface.at(j).interfaceId.constData());
for (int k = j; k >= 0; --k)
fprintf(out, "static_cast< %s*>(", iface.at(k).className.constData());
- fprintf(out, "const_cast< %s*>(this)%s;\n",
- cdef->classname.constData(), QByteArray(j+1, ')').constData());
+ fprintf(out, "this%s;\n", QByteArray(j + 1, ')').constData());
}
}
if (!purestSuperClass.isEmpty() && !isQObject) {
@@ -1263,7 +1262,6 @@ void Generator::generateStaticMetacall()
Q_ASSERT(needElse); // if there is signal, there was method.
fprintf(out, " else if (_c == QMetaObject::IndexOfMethod) {\n");
fprintf(out, " int *result = reinterpret_cast<int *>(_a[0]);\n");
- fprintf(out, " void **func = reinterpret_cast<void **>(_a[1]);\n");
bool anythingUsed = false;
for (int methodindex = 0; methodindex < cdef->signalList.size(); ++methodindex) {
const FunctionDef &f = cdef->signalList.at(methodindex);
@@ -1289,14 +1287,14 @@ void Generator::generateStaticMetacall()
fprintf(out, ") const;\n");
else
fprintf(out, ");\n");
- fprintf(out, " if (*reinterpret_cast<_t *>(func) == static_cast<_t>(&%s::%s)) {\n",
+ fprintf(out, " if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&%s::%s)) {\n",
cdef->classname.constData(), f.name.constData());
fprintf(out, " *result = %d;\n", methodindex);
fprintf(out, " return;\n");
fprintf(out, " }\n }\n");
}
if (!anythingUsed)
- fprintf(out, " Q_UNUSED(result);\n Q_UNUSED(func);\n");
+ fprintf(out, " Q_UNUSED(result);\n");
fprintf(out, " }");
needElse = true;
}
diff --git a/src/widgets/configure.json b/src/widgets/configure.json
index 4c596c09a5..b3a5227d26 100644
--- a/src/widgets/configure.json
+++ b/src/widgets/configure.json
@@ -129,7 +129,7 @@
"label": "QDateTimeEdit",
"purpose": "Supports editing dates and times.",
"section": "Widgets",
- "condition": "features.calendarwidget && features.datestring && features.textdate",
+ "condition": "features.calendarwidget && features.datestring && features.textdate && features.datetimeparser",
"output": [ "publicFeature", "feature" ]
},
"stackedwidget": {
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index fe27be8522..15e6b0eb99 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -2230,7 +2230,7 @@ void QAbstractItemView::focusInEvent(QFocusEvent *event)
QAbstractScrollArea::focusInEvent(event);
const QItemSelectionModel* model = selectionModel();
- const bool currentIndexValid = currentIndex().isValid();
+ bool currentIndexValid = currentIndex().isValid();
if (model
&& !d->currentIndexSet
@@ -2238,19 +2238,16 @@ void QAbstractItemView::focusInEvent(QFocusEvent *event)
bool autoScroll = d->autoScroll;
d->autoScroll = false;
QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); // first visible index
- if (index.isValid() && d->isIndexEnabled(index) && event->reason() != Qt::MouseFocusReason)
+ if (index.isValid() && d->isIndexEnabled(index) && event->reason() != Qt::MouseFocusReason) {
selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
+ currentIndexValid = true;
+ }
d->autoScroll = autoScroll;
}
- if (model && currentIndexValid) {
- if (currentIndex().flags() != Qt::ItemIsEditable)
- setAttribute(Qt::WA_InputMethodEnabled, false);
- else
- setAttribute(Qt::WA_InputMethodEnabled);
- }
-
- if (!currentIndexValid)
+ if (model && currentIndexValid)
+ setAttribute(Qt::WA_InputMethodEnabled, (currentIndex().flags() & Qt::ItemIsEditable));
+ else if (!currentIndexValid)
setAttribute(Qt::WA_InputMethodEnabled, false);
d->viewport->update();
@@ -3665,6 +3662,7 @@ void QAbstractItemView::currentChanged(const QModelIndex &current, const QModelI
d->shouldScrollToCurrentOnShow = d->autoScroll;
}
}
+ setAttribute(Qt::WA_InputMethodEnabled, (current.isValid() && (current.flags() & Qt::ItemIsEditable)));
}
#ifndef QT_NO_DRAGANDDROP
diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp
index fca36c7472..5bf66d68e3 100644
--- a/src/widgets/kernel/qgesturemanager.cpp
+++ b/src/widgets/kernel/qgesturemanager.cpp
@@ -244,6 +244,36 @@ QGesture *QGestureManager::getState(QObject *object, QGestureRecognizer *recogni
return state;
}
+static bool logIgnoredEvent(QEvent::Type t)
+{
+ bool result = false;
+ switch (t) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchCancel:
+ case QEvent::TouchEnd:
+ case QEvent::TabletEnterProximity:
+ case QEvent::TabletLeaveProximity:
+ case QEvent::TabletMove:
+ case QEvent::TabletPress:
+ case QEvent::TabletRelease:
+ case QEvent::GraphicsSceneMouseDoubleClick:
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseRelease:
+ case QEvent::GraphicsSceneMouseMove:
+ result = true;
+ break;
+ default:
+ break;
+
+ }
+ return result;
+}
+
bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *,
Qt::GestureType> &contexts,
QEvent *event)
@@ -289,10 +319,13 @@ bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *,
qCDebug(lcGestureManager) << "QGestureManager:Recognizer: not gesture: " << state << event;
notGestures << state;
} else if (recognizerState == QGestureRecognizer::Ignore) {
- qCDebug(lcGestureManager) << "QGestureManager:Recognizer: ignored the event: " << state << event;
+ if (logIgnoredEvent(event->type()))
+ qCDebug(lcGestureManager) << "QGestureManager:Recognizer: ignored the event: " << state << event;
} else {
- qCDebug(lcGestureManager) << "QGestureManager:Recognizer: hm, lets assume the recognizer"
+ if (logIgnoredEvent(event->type())) {
+ qCDebug(lcGestureManager) << "QGestureManager:Recognizer: hm, lets assume the recognizer"
<< "ignored the event: " << state << event;
+ }
}
if (resultHint & QGestureRecognizer::ConsumeEventHint) {
qCDebug(lcGestureManager) << "QGestureManager: we were asked to consume the event: "
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 8e6b44c370..a5e09795a7 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -5912,7 +5912,7 @@ QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *
pixmapOffset -= effectRect.topLeft();
- const qreal dpr = context->painter->device()->devicePixelRatio();
+ const qreal dpr = context->painter->device()->devicePixelRatioF();
QPixmap pixmap(effectRect.size() * dpr);
pixmap.setDevicePixelRatio(dpr);
diff --git a/src/widgets/kernel/qwindowcontainer.cpp b/src/widgets/kernel/qwindowcontainer.cpp
index d2ad7a466e..d388327687 100644
--- a/src/widgets/kernel/qwindowcontainer.cpp
+++ b/src/widgets/kernel/qwindowcontainer.cpp
@@ -89,7 +89,7 @@ public:
void updateUsesNativeWidgets()
{
- if (usesNativeWidgets || window->parent() == 0)
+ if (window->parent() == 0)
return;
Q_Q(QWindowContainer);
if (q->internalWinId()) {
@@ -97,6 +97,7 @@ public:
usesNativeWidgets = true;
return;
}
+ bool nativeWidgetSet = false;
QWidget *p = q->parentWidget();
while (p) {
if (false
@@ -108,11 +109,12 @@ public:
#endif
) {
q->winId();
- usesNativeWidgets = true;
+ nativeWidgetSet = true;
break;
}
p = p->parentWidget();
}
+ usesNativeWidgets = nativeWidgetSet;
}
void markParentChain() {
diff --git a/src/widgets/util/qcompleter_p.h b/src/widgets/util/qcompleter_p.h
index 179e116d51..e76dcdc8bc 100644
--- a/src/widgets/util/qcompleter_p.h
+++ b/src/widgets/util/qcompleter_p.h
@@ -101,6 +101,9 @@ public:
void _q_autoResizePopup();
void _q_fileSystemModelDirectoryLoaded(const QString &path);
void setCurrentIndex(QModelIndex, bool = true);
+
+ static QCompleterPrivate *get(QCompleter *o) { return o->d_func(); }
+ static const QCompleterPrivate *get(const QCompleter *o) { return o->d_func(); }
};
class QIndexMapper
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index c72c060f9a..3427579d1f 100644
--- a/src/widgets/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
@@ -39,7 +39,9 @@
#include <qplatformdefs.h>
#include <private/qabstractspinbox_p.h>
+#if QT_CONFIG(datetimeparser)
#include <private/qdatetimeparser_p.h>
+#endif
#include <private/qlineedit_p.h>
#include <qabstractspinbox.h>
@@ -47,9 +49,6 @@
#include <qstylehints.h>
#include <qclipboard.h>
#include <qdatetime.h>
-#if QT_CONFIG(datetimeedit)
-#include <qdatetimeedit.h>
-#endif
#include <qevent.h>
#if QT_CONFIG(menu)
#include <qmenu.h>
@@ -1962,12 +1961,15 @@ QVariant operator+(const QVariant &arg1, const QVariant &arg2)
break;
}
case QVariant::Double: ret = QVariant(arg1.toDouble() + arg2.toDouble()); break;
+#if QT_CONFIG(datetimeparser)
case QVariant::DateTime: {
QDateTime a2 = arg2.toDateTime();
QDateTime a1 = arg1.toDateTime().addDays(QDATETIMEEDIT_DATETIME_MIN.daysTo(a2));
a1.setTime(a1.time().addMSecs(QTime().msecsTo(a2.time())));
ret = QVariant(a1);
+ break;
}
+#endif // datetimeparser
default: break;
}
return ret;
@@ -2022,6 +2024,7 @@ QVariant operator*(const QVariant &arg1, double multiplier)
ret = static_cast<int>(qBound<double>(INT_MIN, arg1.toInt() * multiplier, INT_MAX));
break;
case QVariant::Double: ret = QVariant(arg1.toDouble() * multiplier); break;
+#if QT_CONFIG(datetimeparser)
case QVariant::DateTime: {
double days = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDateTime().date()) * multiplier;
int daysInt = (int)days;
@@ -2031,6 +2034,7 @@ QVariant operator*(const QVariant &arg1, double multiplier)
ret = QDateTime(QDate().addDays(int(days)), QTime().addMSecs(msecs));
break;
}
+#endif // datetimeparser
default: ret = arg1; break;
}
@@ -2053,11 +2057,14 @@ double operator/(const QVariant &arg1, const QVariant &arg2)
a1 = arg1.toDouble();
a2 = arg2.toDouble();
break;
+#if QT_CONFIG(datetimeparser)
case QVariant::DateTime:
a1 = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDate());
a2 = QDATETIMEEDIT_DATE_MIN.daysTo(arg2.toDate());
a1 += (double)QDATETIMEEDIT_TIME_MIN.msecsTo(arg1.toDateTime().time()) / (long)(3600 * 24 * 1000);
a2 += (double)QDATETIMEEDIT_TIME_MIN.msecsTo(arg2.toDateTime().time()) / (long)(3600 * 24 * 1000);
+ break;
+#endif // datetimeparser
default: break;
}
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index cd2e20694e..1338a496e6 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -72,6 +72,7 @@
#include <private/qabstractitemmodel_p.h>
#include <private/qabstractscrollarea_p.h>
#include <private/qlineedit_p.h>
+#include <private/qcompleter_p.h>
#include <qdebug.h>
#if QT_CONFIG(effects)
# include <private/qeffects_p.h>
@@ -1227,8 +1228,27 @@ Qt::MatchFlags QComboBoxPrivate::matchFlags() const
void QComboBoxPrivate::_q_editingFinished()
{
Q_Q(QComboBox);
- if (lineEdit && !lineEdit->text().isEmpty() && itemText(currentIndex) != lineEdit->text()) {
- const int index = q_func()->findText(lineEdit->text(), matchFlags());
+ if (!lineEdit)
+ return;
+ const auto leText = lineEdit->text();
+ if (!leText.isEmpty() && itemText(currentIndex) != leText) {
+#if QT_CONFIG(completer)
+ const auto *leCompleter = lineEdit->completer();
+ const auto *popup = leCompleter ? QCompleterPrivate::get(leCompleter)->popup : nullptr;
+ if (popup && popup->isVisible()) {
+ // QLineEdit::editingFinished() will be emitted before the code flow returns
+ // to QCompleter::eventFilter(), where QCompleter::activated() may be emitted.
+ // We know that the completer popup will still be visible at this point, and
+ // that any selection should be valid.
+ const QItemSelectionModel *selModel = popup->selectionModel();
+ const QModelIndex curIndex = popup->currentIndex();
+ const bool completerIsActive = selModel && selModel->selectedIndexes().contains(curIndex);
+
+ if (completerIsActive)
+ return;
+ }
+#endif
+ const int index = q_func()->findText(leText, matchFlags());
if (index != -1) {
q->setCurrentIndex(index);
emitActivated(currentIndex);
@@ -3163,13 +3183,13 @@ void QComboBox::keyPressEvent(QKeyEvent *e)
Q_D(QComboBox);
#if QT_CONFIG(completer)
- if (d->lineEdit
- && d->lineEdit->completer()
- && d->lineEdit->completer()->popup()
- && d->lineEdit->completer()->popup()->isVisible()) {
- // provide same autocompletion support as line edit
- d->lineEdit->event(e);
- return;
+ if (const auto *cmpltr = completer()) {
+ const auto *popup = QCompleterPrivate::get(cmpltr)->popup;
+ if (popup && popup->isVisible()) {
+ // provide same autocompletion support as line edit
+ d->lineEdit->event(e);
+ return;
+ }
}
#endif
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index aa8e6a1c6a..cc6f39c439 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -289,7 +289,7 @@ void QMenuBarPrivate::setKeyboardMode(bool b)
keyboardState = b;
if(b) {
QWidget *fw = QApplication::focusWidget();
- if (fw != q)
+ if (fw && fw != q && fw->window() != QApplication::activePopupWidget())
keyboardFocusWidget = fw;
focusFirstAction();
q->setFocus(Qt::MenuBarFocusReason);
@@ -1707,6 +1707,7 @@ void QMenuBarPrivate::_q_internalShortcutActivated(int id)
}
}
+ keyboardFocusWidget = QApplication::focusWidget();
setCurrentAction(act, true, true);
if (act && !act->menu()) {
activateAction(act, QAction::Trigger);
diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp
index fd783da49a..60a924510a 100644
--- a/src/widgets/widgets/qtabwidget.cpp
+++ b/src/widgets/widgets/qtabwidget.cpp
@@ -196,6 +196,8 @@ public:
void _q_tabMoved(int from, int to);
void init();
+ void initBasicStyleOption(QStyleOptionTabWidgetFrame *option) const;
+
QTabBar *tabs;
QStackedWidget *stack;
QRect panelRect;
@@ -258,6 +260,43 @@ bool QTabWidget::hasHeightForWidth() const
return has;
}
+/*!
+ \internal
+
+ Initialize only time inexpensive parts of the style option
+ for QTabWidget::setUpLayout()'s non-visible code path.
+*/
+void QTabWidgetPrivate::initBasicStyleOption(QStyleOptionTabWidgetFrame *option) const
+{
+ Q_Q(const QTabWidget);
+ option->initFrom(q);
+
+ if (q->documentMode())
+ option->lineWidth = 0;
+ else
+ option->lineWidth = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, q);
+
+ switch (pos) {
+ case QTabWidget::North:
+ option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedNorth
+ : QTabBar::TriangularNorth;
+ break;
+ case QTabWidget::South:
+ option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedSouth
+ : QTabBar::TriangularSouth;
+ break;
+ case QTabWidget::West:
+ option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedWest
+ : QTabBar::TriangularWest;
+ break;
+ case QTabWidget::East:
+ option->shape = shape == QTabWidget::Rounded ? QTabBar::RoundedEast
+ : QTabBar::TriangularEast;
+ break;
+ }
+
+ option->tabBarRect = q->tabBar()->geometry();
+}
/*!
Initialize \a option with the values from this QTabWidget. This method is useful
@@ -272,12 +311,7 @@ void QTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const
return;
Q_D(const QTabWidget);
- option->initFrom(this);
-
- if (documentMode())
- option->lineWidth = 0;
- else
- option->lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0, this);
+ d->initBasicStyleOption(option);
int exth = style()->pixelMetric(QStyle::PM_TabBarBaseHeight, 0, this);
QSize t(0, d->stack->frameWidth());
@@ -308,31 +342,10 @@ void QTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const
option->leftCornerWidgetSize = QSize(0, 0);
}
- switch (d->pos) {
- case QTabWidget::North:
- option->shape = d->shape == QTabWidget::Rounded ? QTabBar::RoundedNorth
- : QTabBar::TriangularNorth;
- break;
- case QTabWidget::South:
- option->shape = d->shape == QTabWidget::Rounded ? QTabBar::RoundedSouth
- : QTabBar::TriangularSouth;
- break;
- case QTabWidget::West:
- option->shape = d->shape == QTabWidget::Rounded ? QTabBar::RoundedWest
- : QTabBar::TriangularWest;
- break;
- case QTabWidget::East:
- option->shape = d->shape == QTabWidget::Rounded ? QTabBar::RoundedEast
- : QTabBar::TriangularEast;
- break;
- }
-
option->tabBarSize = t;
- QRect tbRect = tabBar()->geometry();
QRect selectedTabRect = tabBar()->tabRect(tabBar()->currentIndex());
- option->tabBarRect = tbRect;
- selectedTabRect.moveTopLeft(selectedTabRect.topLeft() + tbRect.topLeft());
+ selectedTabRect.moveTopLeft(selectedTabRect.topLeft() + option->tabBarRect.topLeft());
option->selectedTabRect = selectedTabRect;
}
@@ -764,17 +777,19 @@ void QTabWidget::setUpLayout(bool onlyCheck)
if (onlyCheck && !d->dirty)
return; // nothing to do
- QStyleOptionTabWidgetFrame option;
- initStyleOption(&option);
-
- // this must be done immediately, because QWidgetItem relies on it (even if !isVisible())
- d->setLayoutItemMargins(QStyle::SE_TabWidgetLayoutItem, &option);
-
if (!isVisible()) {
+ // this must be done immediately, because QWidgetItem relies on it (even if !isVisible())
+ QStyleOptionTabWidgetFrame basicOption;
+ d->initBasicStyleOption(&basicOption);
+ d->setLayoutItemMargins(QStyle::SE_TabWidgetLayoutItem, &basicOption);
d->dirty = true;
return; // we'll do it later
}
+ QStyleOptionTabWidgetFrame option;
+ initStyleOption(&option);
+ d->setLayoutItemMargins(QStyle::SE_TabWidgetLayoutItem, &option);
+
QRect tabRect = style()->subElementRect(QStyle::SE_TabWidgetTabBar, &option, this);
d->panelRect = style()->subElementRect(QStyle::SE_TabWidgetTabPane, &option, this);
QRect contentsRect = style()->subElementRect(QStyle::SE_TabWidgetTabContents, &option, this);
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index 1b7a41d547..4f4a6f70b5 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -44,6 +44,7 @@
#endif
#include "qclipboard.h"
#include <private/qguiapplication_p.h>
+#include <private/qcompleter_p.h>
#include <qpa/qplatformtheme.h>
#include <qstylehints.h>
#ifndef QT_NO_ACCESSIBILITY
@@ -1484,7 +1485,8 @@ void QWidgetLineControl::complete(int key)
} else {
#ifndef QT_KEYPAD_NAVIGATION
if (text.isEmpty()) {
- m_completer->popup()->hide();
+ if (auto *popup = QCompleterPrivate::get(m_completer)->popup)
+ popup->hide();
return;
}
#endif
@@ -1630,25 +1632,16 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
#if QT_CONFIG(completer)
if (m_completer) {
QCompleter::CompletionMode completionMode = m_completer->completionMode();
+ auto *popup = QCompleterPrivate::get(m_completer)->popup;
if ((completionMode == QCompleter::PopupCompletion
|| completionMode == QCompleter::UnfilteredPopupCompletion)
- && m_completer->popup()
- && m_completer->popup()->isVisible()) {
+ && popup && popup->isVisible()) {
// The following keys are forwarded by the completer to the widget
// Ignoring the events lets the completer provide suitable default behavior
switch (event->key()) {
case Qt::Key_Escape:
event->ignore();
return;
- case Qt::Key_Enter:
- case Qt::Key_Return:
- case Qt::Key_F4:
-#ifdef QT_KEYPAD_NAVIGATION
- case Qt::Key_Select:
- if (!QApplication::keypadNavigationEnabled())
- break;
-#endif
- m_completer->popup()->hide(); // just hide. will end up propagating to parent
default:
break; // normal key processing
}
diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST
index 9ffcf73d64..3e03d9e236 100644
--- a/tests/auto/gui/kernel/qwindow/BLACKLIST
+++ b/tests/auto/gui/kernel/qwindow/BLACKLIST
@@ -23,3 +23,5 @@ osx
osx-10.11 ci
osx-10.12 ci
+[testInputEvents]
+rhel-7.4
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index e995b69f60..542246ff2d 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -487,6 +487,7 @@ private Q_SLOTS:
void ioHttpRedirectPolicyErrors();
void ioHttpUserVerifiedRedirect_data();
void ioHttpUserVerifiedRedirect();
+ void ioHttpCookiesDuringRedirect();
#ifndef QT_NO_SSL
void putWithServerClosingConnectionImmediately();
#endif
@@ -8410,6 +8411,33 @@ void tst_QNetworkReply::ioHttpUserVerifiedRedirect()
QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), statusCode);
}
+void tst_QNetworkReply::ioHttpCookiesDuringRedirect()
+{
+ MiniHttpServer target(httpEmpty200Response, false);
+
+ const QString cookieHeader = QStringLiteral("Set-Cookie: hello=world; Path=/;\r\n");
+ QString redirect = tempRedirectReplyStr();
+ // Insert 'cookieHeader' before the final \r\n
+ redirect.insert(redirect.length() - 2, cookieHeader);
+
+ QUrl url("http://localhost/");
+ url.setPort(target.serverPort());
+ redirect = redirect.arg(url.toString());
+ MiniHttpServer redirectServer(redirect.toLatin1(), false);
+
+ url = QUrl("http://localhost/");
+ url.setPort(redirectServer.serverPort());
+ QNetworkRequest request(url);
+ auto oldRedirectPolicy = manager.redirectPolicy();
+ manager.setRedirectPolicy(QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy);
+ QNetworkReplyPtr reply(manager.get(request));
+ // Set policy back to whatever it was
+ manager.setRedirectPolicy(oldRedirectPolicy);
+
+ QVERIFY(waitForFinish(reply) == Success);
+ QVERIFY(target.receivedData.contains("\r\nCookie: hello=world\r\n"));
+}
+
#ifndef QT_NO_SSL
class PutWithServerClosingConnectionImmediatelyHandler: public QObject
diff --git a/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp b/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp
index f3a1ac84ff..90da0b64e2 100644
--- a/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp
+++ b/tests/auto/network/kernel/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp
@@ -256,8 +256,8 @@ void tst_QNetworkProxyFactory::genericSystemProxy()
QFETCH(QString, hostName);
QFETCH(int, port);
-// The generic system proxy is only available on the following platforms
-#if (!defined Q_OS_WIN) && (!defined Q_OS_OSX) && !QT_CONFIG(libproxy)
+// We can only use the generic system proxy where available:
+#if !defined(Q_OS_WIN) && !defined(Q_OS_MACOS) && !QT_CONFIG(libproxy)
qputenv(envVar, url);
const QList<QNetworkProxy> systemProxy = QNetworkProxyFactory::systemProxyForQuery();
QCOMPARE(systemProxy.size(), 1);
diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp
index b5bfde3cab..25c2701f69 100644
--- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp
+++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp
@@ -168,29 +168,59 @@ void tst_QSslSocket_onDemandCertificates_member::proxyAuthenticationRequired(con
#ifndef QT_NO_OPENSSL
+static bool waitForEncrypted(QSslSocket *socket)
+{
+ Q_ASSERT(socket);
+
+ QEventLoop eventLoop;
+
+ QTimer connectionTimeoutWatcher;
+ connectionTimeoutWatcher.setSingleShot(true);
+ connectionTimeoutWatcher.connect(&connectionTimeoutWatcher, &QTimer::timeout,
+ [&eventLoop]() {
+ eventLoop.exit();
+ });
+
+ bool encrypted = false;
+ socket->connect(socket, &QSslSocket::encrypted, [&eventLoop, &encrypted](){
+ eventLoop.exit();
+ encrypted = true;
+ });
+
+ socket->connect(socket, QOverload<const QList<QSslError>&>::of(&QSslSocket::sslErrors),
+ [&eventLoop](){
+ eventLoop.exit();
+ });
+
+ // Wait for 30 s. maximum - the default timeout in our QSslSocket::waitForEncrypted ...
+ connectionTimeoutWatcher.start(30000);
+ eventLoop.exec();
+ return encrypted;
+}
+
void tst_QSslSocket_onDemandCertificates_member::onDemandRootCertLoadingMemberMethods()
{
- QString host("www.qt.io");
+ const QString host("www.qt.io");
// not using any root certs -> should not work
QSslSocketPtr socket2 = newSocket();
this->socket = socket2.data();
socket2->setCaCertificates(QList<QSslCertificate>());
socket2->connectToHostEncrypted(host, 443);
- QVERIFY(!socket2->waitForEncrypted());
+ QVERIFY(!waitForEncrypted(socket2.data()));
// default: using on demand loading -> should work
QSslSocketPtr socket = newSocket();
this->socket = socket.data();
socket->connectToHostEncrypted(host, 443);
- QVERIFY2(socket->waitForEncrypted(), qPrintable(socket->errorString()));
+ QVERIFY2(waitForEncrypted(socket.data()), qPrintable(socket->errorString()));
// not using any root certs again -> should not work
QSslSocketPtr socket3 = newSocket();
this->socket = socket3.data();
socket3->setCaCertificates(QList<QSslCertificate>());
socket3->connectToHostEncrypted(host, 443);
- QVERIFY(!socket3->waitForEncrypted());
+ QVERIFY(!waitForEncrypted(socket3.data()));
// setting empty SSL configuration explicitly -> depends on on-demand loading
QSslSocketPtr socket4 = newSocket();
@@ -199,24 +229,16 @@ void tst_QSslSocket_onDemandCertificates_member::onDemandRootCertLoadingMemberMe
socket4->setSslConfiguration(conf);
socket4->connectToHostEncrypted(host, 443);
#ifdef QT_BUILD_INTERNAL
- bool rootCertLoadingAllowed = QSslSocketPrivate::rootCertOnDemandLoadingSupported();
-#if defined(Q_OS_LINUX)
- QCOMPARE(rootCertLoadingAllowed, true);
+ const bool works = QSslSocketPrivate::rootCertOnDemandLoadingSupported();
+#if defined(Q_OS_LINUX) || defined(Q_OS_WIN)
+ QCOMPARE(works, true);
#elif defined(Q_OS_MAC)
- QCOMPARE(rootCertLoadingAllowed, false);
-#endif // other platforms: undecided (Windows: depends on the version)
- // when we allow on demand loading, it is enabled by default,
- // so on Unix it will work without setting any certificates. Otherwise,
- // the configuration contains an empty set of certificates
- // and will fail.
- bool works;
-#if defined (Q_OS_WIN)
- works = false; // on Windows, this won't work even though we use on demand loading
- Q_UNUSED(rootCertLoadingAllowed)
-#else
- works = rootCertLoadingAllowed;
-#endif
- QCOMPARE(socket4->waitForEncrypted(), works);
+ QCOMPARE(works, false);
+#endif // other platforms: undecided.
+ // When we *allow* on-demand loading, we enable it by default; so, on Unix,
+ // it will work without setting any certificates. Otherwise, the configuration
+ // contains an empty set of certificates, so on-demand loading shall fail.
+ QCOMPARE(waitForEncrypted(socket4.data()), works);
#endif // QT_BUILD_INTERNAL
}
diff --git a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
index a63ca49cbb..7acdf98ec3 100644
--- a/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
+++ b/tests/auto/widgets/itemviews/qabstractitemview/tst_qabstractitemview.cpp
@@ -55,6 +55,8 @@
#include <qproxystyle.h>
#include <qdialog.h>
+Q_DECLARE_METATYPE(Qt::ItemFlags);
+
static inline void setFrameless(QWidget *w)
{
Qt::WindowFlags flags = w->windowFlags();
@@ -154,6 +156,8 @@ private slots:
void testDialogAsEditor();
void QTBUG46785_mouseout_hover_state();
void testClearModelInClickedSignal();
+ void inputMethodEnabled_data();
+ void inputMethodEnabled();
};
class MyAbstractItemDelegate : public QAbstractItemDelegate
@@ -2295,5 +2299,107 @@ void tst_QAbstractItemView::testClearModelInClickedSignal()
QCOMPARE(view.model(), nullptr);
}
+void tst_QAbstractItemView::inputMethodEnabled_data()
+{
+ QTest::addColumn<QByteArray>("viewType");
+ QTest::addColumn<Qt::ItemFlags>("itemFlags");
+ QTest::addColumn<bool>("result");
+
+ QList<QByteArray> widgets;
+ widgets << "QListView" << "QTreeView" << "QTableView";
+
+ for (const QByteArray &widget : qAsConst(widgets)) {
+ QTest::newRow(widget + ": no flags") << widget << Qt::ItemFlags(Qt::NoItemFlags) << false;
+ QTest::newRow(widget + ": checkable") << widget << Qt::ItemFlags(Qt::ItemIsUserCheckable) << false;
+ QTest::newRow(widget + ": selectable") << widget << Qt::ItemFlags(Qt::ItemIsSelectable) << false;
+ QTest::newRow(widget + ": enabled") << widget << Qt::ItemFlags(Qt::ItemIsEnabled) << false;
+ QTest::newRow(widget + ": selectable|enabled")
+ << widget << Qt::ItemFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled) << false;
+ QTest::newRow(widget + ": editable|enabled")
+ << widget << Qt::ItemFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled) << true;
+ QTest::newRow(widget + ": editable|enabled|selectable")
+ << widget << Qt::ItemFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable) << true;
+ }
+}
+
+void tst_QAbstractItemView::inputMethodEnabled()
+{
+ QFETCH(QByteArray, viewType);
+ QFETCH(Qt::ItemFlags, itemFlags);
+ QFETCH(bool, result);
+
+ QScopedPointer<QAbstractItemView> view;
+ if (viewType == "QListView")
+ view.reset(new QListView());
+ else if (viewType == "QTableView")
+ view.reset(new QTableView());
+ else if (viewType == "QTreeView")
+ view.reset(new QTreeView());
+ else
+ QVERIFY(0);
+
+ centerOnScreen(view.data());
+ view->show();
+ QVERIFY(QTest::qWaitForWindowExposed(view.data()));
+
+ QStandardItemModel *model = new QStandardItemModel(view.data());
+ QStandardItem *item = new QStandardItem("first item");
+ item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+ model->appendRow(item);
+
+ QStandardItem *secondItem = new QStandardItem("test item");
+ secondItem->setFlags(Qt::ItemFlags(itemFlags));
+ model->appendRow(secondItem);
+
+ view->setModel(model);
+
+ // Check current changed
+ view->setCurrentIndex(model->index(0, 0));
+ QVERIFY(!view->testAttribute(Qt::WA_InputMethodEnabled));
+ view->setCurrentIndex(model->index(1, 0));
+ QCOMPARE(view->testAttribute(Qt::WA_InputMethodEnabled), result);
+ view->setCurrentIndex(model->index(0, 0));
+ QVERIFY(!view->testAttribute(Qt::WA_InputMethodEnabled));
+
+ // Check focus by switching the activation of the window to force a focus in
+ view->setCurrentIndex(model->index(1, 0));
+ QApplication::setActiveWindow(0);
+ QApplication::setActiveWindow(view.data());
+ QVERIFY(QTest::qWaitForWindowActive(view.data()));
+ QCOMPARE(view->testAttribute(Qt::WA_InputMethodEnabled), result);
+
+ view->setCurrentIndex(QModelIndex());
+ QVERIFY(!view->testAttribute(Qt::WA_InputMethodEnabled));
+ QApplication::setActiveWindow(0);
+ QApplication::setActiveWindow(view.data());
+ QVERIFY(QTest::qWaitForWindowActive(view.data()));
+ QModelIndex index = model->index(1, 0);
+ QPoint p = view->visualRect(index).center();
+ QTest::mouseClick(view->viewport(), Qt::LeftButton, Qt::NoModifier, p);
+ if (itemFlags & Qt::ItemIsEnabled)
+ QCOMPARE(view->currentIndex(), index);
+ QCOMPARE(view->testAttribute(Qt::WA_InputMethodEnabled), result);
+
+ index = model->index(0, 0);
+ QApplication::setActiveWindow(0);
+ QApplication::setActiveWindow(view.data());
+ QVERIFY(QTest::qWaitForWindowActive(view.data()));
+ p = view->visualRect(index).center();
+ QTest::mouseClick(view->viewport(), Qt::LeftButton, Qt::NoModifier, p);
+ QCOMPARE(view->currentIndex(), index);
+ QVERIFY(!view->testAttribute(Qt::WA_InputMethodEnabled));
+
+ // There is a case when it goes to the first visible item so we
+ // make the flags of the first item match the ones we are testing
+ // to check the attribute correctly
+ QApplication::setActiveWindow(0);
+ view->setCurrentIndex(QModelIndex());
+ view->reset();
+ item->setFlags(Qt::ItemFlags(itemFlags));
+ QApplication::setActiveWindow(view.data());
+ QVERIFY(QTest::qWaitForWindowActive(view.data()));
+ QCOMPARE(view->testAttribute(Qt::WA_InputMethodEnabled), result);
+}
+
QTEST_MAIN(tst_QAbstractItemView)
#include "tst_qabstractitemview.moc"
diff --git a/tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST b/tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST
index a16fd19b99..fea108f3fd 100644
--- a/tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST
+++ b/tests/auto/widgets/itemviews/qitemdelegate/BLACKLIST
@@ -1,2 +1,4 @@
[enterKey]
-opensuse-42.3
+opensuse-42.3 ci
+[testLineEditValidation]
+opensuse-42.3 ci
diff --git a/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp b/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp
index 6ec1b754d0..a3e549aa50 100644
--- a/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp
+++ b/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp
@@ -74,6 +74,7 @@ private slots:
void testOwnership();
void testBehindTheScenesDeletion();
void testUnparenting();
+ void testUnparentReparent();
void testActivation();
void testAncestorChange();
void testDockWidget();
@@ -241,6 +242,31 @@ void tst_QWindowContainer::testUnparenting()
QVERIFY(!window->isVisible());
}
+void tst_QWindowContainer::testUnparentReparent()
+{
+ QWidget root;
+
+ QWindow *window = new QWindow();
+ QScopedPointer<QWidget> container(QWidget::createWindowContainer(window, &root));
+ container->setWindowTitle(QTest::currentTestFunction());
+ container->setGeometry(m_availableGeometry.x() + 100, m_availableGeometry.y() + 100, 200, 100);
+
+ root.show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(&root));
+
+ QTRY_VERIFY(window->isVisible());
+
+ container->setParent(nullptr);
+ QTRY_VERIFY(!window->isVisible());
+
+ container->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+ QTRY_VERIFY(window->isVisible());
+
+ container->setParent(&root); // This should not crash (QTBUG-63168)
+}
+
void tst_QWindowContainer::testAncestorChange()
{
QWidget root;
diff --git a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp
index f8095badb8..3818b83584 100644
--- a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp
+++ b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp
@@ -143,6 +143,8 @@ private slots:
void task253125_lineEditCompletion();
void task247560_keyboardNavigation();
void QTBUG_14292_filesystem();
+ void QTBUG_52028_tabAutoCompletes();
+ void QTBUG_51889_activatedSentTwice();
private:
void filter(bool assync = false);
@@ -1742,5 +1744,108 @@ void tst_QCompleter::QTBUG_14292_filesystem()
QVERIFY(!comp.popup()->isVisible());
}
+void tst_QCompleter::QTBUG_52028_tabAutoCompletes()
+{
+ QStringList words;
+ words << "foobar1" << "foobar2" << "hux";
+
+ QWidget w;
+ w.setLayout(new QVBoxLayout);
+
+ QComboBox cbox;
+ cbox.setEditable(true);
+ cbox.setInsertPolicy(QComboBox::NoInsert);
+ cbox.addItems(words);
+
+ cbox.completer()->setCaseSensitivity(Qt::CaseInsensitive);
+ cbox.completer()->setCompletionMode(QCompleter::PopupCompletion);
+
+ w.layout()->addWidget(&cbox);
+
+ // Adding a line edit is a good reason for tab to do something unrelated
+ QLineEdit le;
+ w.layout()->addWidget(&le);
+
+ const auto pos = QApplication::desktop()->availableGeometry(&w).topLeft() + QPoint(200,200);
+ w.move(pos);
+ w.show();
+ QApplication::setActiveWindow(&w);
+ QVERIFY(QTest::qWaitForWindowActive(&w));
+
+ QSignalSpy activatedSpy(&cbox, QOverload<int>::of(&QComboBox::activated));
+
+ // Tab key will complete but not activate
+ cbox.lineEdit()->clear();
+ QTest::keyClick(&cbox, Qt::Key_H);
+ QVERIFY(cbox.completer()->popup());
+ QTRY_VERIFY(cbox.completer()->popup()->isVisible());
+ QTest::keyClick(cbox.completer()->popup(), Qt::Key_Tab);
+ QCOMPARE(cbox.completer()->currentCompletion(), QLatin1String("hux"));
+ QCOMPARE(activatedSpy.count(), 0);
+ QEXPECT_FAIL("", "QTBUG-52028 will not be fixed today.", Abort);
+ QCOMPARE(cbox.currentText(), QLatin1String("hux"));
+ QCOMPARE(activatedSpy.count(), 0);
+ QVERIFY(!le.hasFocus());
+}
+
+void tst_QCompleter::QTBUG_51889_activatedSentTwice()
+{
+ QStringList words;
+ words << "foobar1" << "foobar2" << "bar" <<"hux";
+
+ QWidget w;
+ w.setLayout(new QVBoxLayout);
+
+ QComboBox cbox;
+ setFrameless(&cbox);
+ cbox.setEditable(true);
+ cbox.setInsertPolicy(QComboBox::NoInsert);
+ cbox.addItems(words);
+
+ cbox.completer()->setCaseSensitivity(Qt::CaseInsensitive);
+ cbox.completer()->setCompletionMode(QCompleter::PopupCompletion);
+
+ w.layout()->addWidget(&cbox);
+
+ QLineEdit le;
+ w.layout()->addWidget(&le);
+
+ const auto pos = QApplication::desktop()->availableGeometry(&w).topLeft() + QPoint(200,200);
+ w.move(pos);
+ w.show();
+ QApplication::setActiveWindow(&w);
+ QVERIFY(QTest::qWaitForWindowActive(&w));
+
+ QSignalSpy activatedSpy(&cbox, QOverload<int>::of(&QComboBox::activated));
+
+ // Navigate + enter activates only once (first item)
+ cbox.lineEdit()->clear();
+ QTest::keyClick(&cbox, Qt::Key_F);
+ QVERIFY(cbox.completer()->popup());
+ QTRY_VERIFY(cbox.completer()->popup()->isVisible());
+ QTest::keyClick(cbox.completer()->popup(), Qt::Key_Down);
+ QTest::keyClick(cbox.completer()->popup(), Qt::Key_Return);
+ QTRY_COMPARE(activatedSpy.count(), 1);
+
+ // Navigate + enter activates only once (non-first item)
+ cbox.lineEdit()->clear();
+ activatedSpy.clear();
+ QTest::keyClick(&cbox, Qt::Key_H);
+ QVERIFY(cbox.completer()->popup());
+ QTRY_VERIFY(cbox.completer()->popup()->isVisible());
+ QTest::keyClick(cbox.completer()->popup(), Qt::Key_Down);
+ QTest::keyClick(cbox.completer()->popup(), Qt::Key_Return);
+ QTRY_COMPARE(activatedSpy.count(), 1);
+
+ // Full text + enter activates only once
+ cbox.lineEdit()->clear();
+ activatedSpy.clear();
+ QTest::keyClicks(&cbox, "foobar1");
+ QVERIFY(cbox.completer()->popup());
+ QTRY_VERIFY(cbox.completer()->popup()->isVisible());
+ QTest::keyClick(&cbox, Qt::Key_Return);
+ QTRY_COMPARE(activatedSpy.count(), 1);
+}
+
QTEST_MAIN(tst_QCompleter)
#include "tst_qcompleter.moc"
diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
index 9a0ca0565e..251a351cc1 100644
--- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
+++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
@@ -39,6 +39,7 @@
#include <qstyleoption.h>
#include <QVBoxLayout>
#include <QLabel>
+#include <QPlainTextEdit>
#include <qscreen.h>
#include <qobject.h>
@@ -106,6 +107,7 @@ private slots:
void allowActiveAndDisabled();
#endif
+ void taskQTBUG56860_focus();
void check_endKey();
void check_homeKey();
@@ -710,6 +712,52 @@ void tst_QMenuBar::check_cursorKeys3()
}
#endif
+void tst_QMenuBar::taskQTBUG56860_focus()
+{
+#if defined(Q_OS_DARWIN)
+ QSKIP("Native key events are needed to test menu action activation on macOS.");
+#endif
+ QMainWindow w;
+ QMenuBar *mb = w.menuBar();
+
+ if (mb->platformMenuBar())
+ QSKIP("This test requires the Qt menubar.");
+
+ QMenu *em = mb->addMenu("&Edit");
+ em->setObjectName("EditMenu");
+ em->addAction("&Cut");
+ em->addAction("C&opy");
+ QPlainTextEdit *e = new QPlainTextEdit;
+ e->setObjectName("edit");
+
+ w.setCentralWidget(e);
+ w.show();
+ QApplication::setActiveWindow(&w);
+ QVERIFY(QTest::qWaitForWindowActive(&w));
+
+ QTRY_COMPARE(QApplication::focusWidget(), e);
+
+ // Open menu
+ QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_E, Qt::AltModifier );
+ QTRY_COMPARE(QApplication::activePopupWidget(), em);
+ // key down to trigger focus
+ QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Down );
+ // and press ENTER to close
+ QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Enter );
+ QTRY_COMPARE(QApplication::activePopupWidget(), nullptr);
+ // focus should have returned to the editor by now
+ QTRY_COMPARE(QApplication::focusWidget(), e);
+
+ // Now do it all over again...
+ QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_E, Qt::AltModifier );
+ QTRY_COMPARE(QApplication::activePopupWidget(), em);
+ QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Down );
+ QTest::keyClick(static_cast<QWidget *>(0), Qt::Key_Enter );
+ QTRY_COMPARE(QApplication::activePopupWidget(), nullptr);
+ QTRY_COMPARE(QApplication::focusWidget(), e);
+
+}
+
/*!
If a popupmenu is active you can use home to go quickly to the first item in the menu.
*/
diff --git a/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp b/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp
index 5799b32b1c..507e2af708 100644
--- a/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp
+++ b/tests/benchmarks/corelib/tools/qcryptographichash/main.cpp
@@ -79,6 +79,14 @@ const char *algoname(int i)
return "sha3_384-";
case QCryptographicHash::Sha3_512:
return "sha3_512-";
+ case QCryptographicHash::Keccak_224:
+ return "keccak_224-";
+ case QCryptographicHash::Keccak_256:
+ return "keccak_256-";
+ case QCryptographicHash::Keccak_384:
+ return "keccak_384-";
+ case QCryptographicHash::Keccak_512:
+ return "keccak_512-";
}
Q_UNREACHABLE();
return 0;