summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2019-06-25 15:37:01 +0200
committerLiang Qi <liang.qi@qt.io>2019-06-25 15:47:42 +0200
commitaedc59b1c38528f96f0e0cc51bf6c9eeca9dca28 (patch)
tree80e38cea91c93736a7d4436642dd46c8b2dd6386
parente3b3dbbe93dbbac196543f62b444b2c044d14907 (diff)
parentf6db25962e820d7709c2f235f02893dd3edde4f4 (diff)
Merge remote-tracking branch 'origin/5.12' into 5.13
Conflicts: src/corelib/io/qstorageinfo_unix.cpp src/network/ssl/qsslsocket_openssl.cpp Change-Id: Ibc9ce799bef62d60d616beaa9fbde8ebeadfbc20
-rw-r--r--configure.json2
-rw-r--r--qmake/generators/win32/mingw_make.cpp2
-rw-r--r--qmake/library/proitems.cpp5
-rw-r--r--qmake/library/proitems.h3
-rw-r--r--src/corelib/animation/qabstractanimation.cpp2
-rw-r--r--src/corelib/io/qstorageinfo_unix.cpp3
-rw-r--r--src/corelib/kernel/qcoreapplication_win.cpp12
-rw-r--r--src/corelib/serialization/qjsoncbor.cpp10
-rw-r--r--src/dbus/doc/snippets/cmake/examples.cmake3
-rw-r--r--src/dbus/doc/src/qtdbus-cmake.qdoc224
-rw-r--r--src/gui/opengl/qopengltextureblitter.cpp3
-rw-r--r--src/gui/text/qdistancefield.cpp5
-rw-r--r--src/gui/text/qdistancefield_p.h1
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp109
-rw-r--r--src/network/ssl/qsslsocket_openssl11_symbols_p.h2
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp10
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h1
-rw-r--r--src/network/ssl/qsslsocket_opensslpre11_symbols_p.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm10
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm8
-rw-r--r--src/plugins/platforms/cocoa/qcocoansmenu.mm2
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp20
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h1
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm3
-rw-r--r--src/widgets/kernel/qapplication.cpp59
-rw-r--r--src/widgets/kernel/qwidget.cpp81
-rw-r--r--src/widgets/kernel/qwidget_p.h2
-rw-r--r--src/widgets/widgets/qmdisubwindow.cpp16
-rw-r--r--src/widgets/widgets/qmenu.cpp12
-rw-r--r--src/widgets/widgets/qmenu_p.h2
-rw-r--r--src/widgets/widgets/qmenubar.cpp15
-rw-r--r--tests/auto/corelib/animation/qabstractanimation/tst_qabstractanimation.cpp15
-rw-r--r--tests/auto/network/access/qnetworkreply/certs/qt-test-server-cacert.pem30
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp23
-rw-r--r--tests/auto/network/ssl/qsslsocket/certs/qt-test-server-cacert.pem30
-rw-r--r--tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp1
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp73
-rw-r--r--tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp1
39 files changed, 586 insertions, 221 deletions
diff --git a/configure.json b/configure.json
index 5ee4faf1a3..9c9515bb52 100644
--- a/configure.json
+++ b/configure.json
@@ -82,7 +82,7 @@
"force-pkg-config": { "type": "void", "name": "pkg-config" },
"framework": "boolean",
"gc-binaries": { "type": "boolean", "name": "gc_binaries" },
- "gdb-index": { "type": "boolean", "name": "gdb_index" },
+ "gdb-index": { "type": "boolean", "name": "enable_gdb_index" },
"gcc-sysroot": "boolean",
"gcov": "boolean",
"gnumake": { "type": "boolean", "name": "GNUmake" },
diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp
index de7363e51b..746f3e9008 100644
--- a/qmake/generators/win32/mingw_make.cpp
+++ b/qmake/generators/win32/mingw_make.cpp
@@ -254,7 +254,7 @@ void MingwMakefileGenerator::init()
}
if(project->isActiveConfig("dll")) {
- project->values("QMAKE_CLEAN").append(project->first("MINGW_IMPORT_LIB"));
+ project->values("QMAKE_DISTCLEAN").append(project->first("MINGW_IMPORT_LIB"));
}
}
diff --git a/qmake/library/proitems.cpp b/qmake/library/proitems.cpp
index 8bbde9f8c0..41bed69f00 100644
--- a/qmake/library/proitems.cpp
+++ b/qmake/library/proitems.cpp
@@ -517,4 +517,9 @@ ProKey ProFile::getHashStr(const ushort *&tPtr)
return ret;
}
+QDebug operator<<(QDebug debug, const ProString &str)
+{
+ return debug << str.toQString();
+}
+
QT_END_NAMESPACE
diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h
index 71e5e05367..0e0bebddc7 100644
--- a/qmake/library/proitems.h
+++ b/qmake/library/proitems.h
@@ -31,6 +31,7 @@
#include "qmake_global.h"
+#include <qdebug.h>
#include <qstring.h>
#include <qvector.h>
#include <qhash.h>
@@ -468,6 +469,8 @@ struct ProFunctionDefs {
QHash<ProKey, ProFunctionDef> replaceFunctions;
};
+QDebug operator<<(QDebug debug, const ProString &str);
+
QT_END_NAMESPACE
#endif // PROITEMS_H
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index 8a9d86b7c5..5da8419fe8 100644
--- a/src/corelib/animation/qabstractanimation.cpp
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -1063,7 +1063,7 @@ QAbstractAnimation::~QAbstractAnimation()
if (d->state != Stopped) {
QAbstractAnimation::State oldState = d->state;
d->state = Stopped;
- emit stateChanged(oldState, d->state);
+ emit stateChanged(d->state, oldState);
if (oldState == QAbstractAnimation::Running)
QAnimationTimer::unregisterAnimation(this);
}
diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp
index 6b821b0fe9..b23ee3ad8d 100644
--- a/src/corelib/io/qstorageinfo_unix.cpp
+++ b/src/corelib/io/qstorageinfo_unix.cpp
@@ -846,6 +846,9 @@ QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes()
const QString mountDir = it.rootPath();
QStorageInfo info(mountDir);
+ info.d->device = it.device();
+ info.d->fileSystemType = it.fileSystemType();
+ info.d->subvolume = it.subvolume();
if (info.bytesTotal() == 0 && info != root())
continue;
volumes.append(info);
diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp
index 75cc813298..4f4a29b41b 100644
--- a/src/corelib/kernel/qcoreapplication_win.cpp
+++ b/src/corelib/kernel/qcoreapplication_win.cpp
@@ -694,6 +694,12 @@ static const char *winPosInsertAfter(quintptr h)
static const char *sessionMgrLogOffOption(uint p)
{
+#ifndef ENDSESSION_CLOSEAPP
+#define ENDSESSION_CLOSEAPP 0x00000001
+#endif
+#ifndef ENDSESSION_CRITICAL
+#define ENDSESSION_CRITICAL 0x40000000
+#endif
static const QWinMessageMapping<uint> values[] = {
{ENDSESSION_CLOSEAPP, "Close application"},
{ENDSESSION_CRITICAL, "Force application end"},
@@ -887,12 +893,6 @@ QString decodeMSG(const MSG& msg)
parameters += QLatin1Char(')');
}
break;
-#ifndef ENDSESSION_CLOSEAPP
-#define ENDSESSION_CLOSEAPP 0x00000001
-#endif
-#ifndef ENDSESSION_CRITICAL
-#define ENDSESSION_CRITICAL 0x40000000
-#endif
case WM_QUERYENDSESSION:
parameters = QLatin1String("End session: ");
if (const char *logoffOption = sessionMgrLogOffOption(uint(wParam)))
diff --git a/src/corelib/serialization/qjsoncbor.cpp b/src/corelib/serialization/qjsoncbor.cpp
index dc5f384108..e0c390f610 100644
--- a/src/corelib/serialization/qjsoncbor.cpp
+++ b/src/corelib/serialization/qjsoncbor.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 Intel Corporation.
+** Copyright (C) 2019 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -598,10 +598,12 @@ QCborValue QCborValue::fromJsonValue(const QJsonValue &v)
switch (v.type()) {
case QJsonValue::Bool:
return v.b;
- case QJsonValue::Double:
- if (v.dbl == qint64(v.dbl))
- return qint64(v.dbl);
+ case QJsonValue::Double: {
+ qint64 i;
+ if (convertDoubleTo(v.dbl, &i))
+ return i;
return v.dbl;
+ }
case QJsonValue::String:
return v.toString();
case QJsonValue::Array:
diff --git a/src/dbus/doc/snippets/cmake/examples.cmake b/src/dbus/doc/snippets/cmake/examples.cmake
new file mode 100644
index 0000000000..cb4f86844f
--- /dev/null
+++ b/src/dbus/doc/snippets/cmake/examples.cmake
@@ -0,0 +1,3 @@
+#! [qt5_add_dbus_adaptor]
+qt5_add_dbus_adaptor(GENERATED_SOURCES org.example.chat.xml chat.h ChatMainWindow)
+#! [qt5_add_dbus_adaptor]
diff --git a/src/dbus/doc/src/qtdbus-cmake.qdoc b/src/dbus/doc/src/qtdbus-cmake.qdoc
new file mode 100644
index 0000000000..de127fa9f4
--- /dev/null
+++ b/src/dbus/doc/src/qtdbus-cmake.qdoc
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\page qtdbus-cmake-qt5-add-dbus-interface.html
+\ingroup cmake-commands-qtdbus
+
+\title qt5_add_dbus_interface
+
+\brief Generates C++ sources implementing an interface for a D-Bus interface
+description file.
+
+\section1 Synopsis
+
+\badcode
+qt5_add_dbus_interface(<VAR> dbus_spec basename)
+\endcode
+
+\section1 Description
+
+Generates C++ sources implementing an interface for a D-Bus interface description
+file defined in \c{dbus_spec}. The generated files are named after \c{basename}:
+\c{basename.h}, \c{basename.cpp}, \c{basename.moc}. The paths of the files
+are added to \c{<VAR>}.
+
+The function sets up a call to the \l{Qt D-Bus XML compiler (qdbusxml2cpp)}
+in interface (proxy) mode. By default, \c{qdbusxml2cpp} generates a C++
+class named after the interface name, with a namespaced alias:
+
+\table
+\header
+ \li D-Bus Interface Name
+ \li Class name
+ \li Namespaced name
+\row
+ \li \c{org.example.chat}
+ \li \c{OrgExampleChatInterface}
+ \li \c{org.example.chat}
+\endtable
+
+\section1 Options
+
+Options can be set using \c set_source_file_property on the \c dbus_spec:
+
+\table
+\header
+ \li Option
+ \li Value
+ \li Description
+\row
+ \li \c CLASSNAME
+ \li \c class_name
+ \li Override the default interface class name with \c{class_name}.
+\row
+ \li \c NO_NAMESPACE
+ \li boolean
+ \li Do not generate the namespaced name if set to \c{ON}.
+\row
+ \li \c INCLUDE
+ \li \c path
+ \li Add an \c{#include "path"} in the generated code.
+\endtable
+*/
+
+/*!
+\page qtdbus-cmake-qt5-add-dbus-interfaces.html
+\ingroup cmake-commands-qtdbus
+
+\title qt5_add_dbus_interfaces
+
+\brief Generates C++ sources implementing interfaces for D-Bus interface
+description files.
+
+\section1 Synopsis
+
+\badcode
+qt5_add_dbus_interfaces(<VAR> dbus_spec1 [dbus_spec2 ...])
+\endcode
+
+\section1 Description
+
+Generates C++ sources implementing D-Bus interfaces defined in \c{dbus_spec1},
+\c{dbus_spec2}, where each argument needs to be the path to a valid D-Bus
+interface description file. The paths of the generated files are added to
+\c{<VAR>}.
+
+For each argument, a call to the \l{Qt D-Bus XML compiler (qdbusxml2cpp)}
+in interface (proxy) mode is set up.
+
+The generated C++ source files are named after the XML file: For the file
+\c{org.example.chat.xml} the generated header will be named
+\c{orgexamplechatinterface.h}.
+
+\section1 Options
+
+Options can be set using \c set_source_file_property on each of the file
+arguments:
+
+\table
+\header
+ \li Option
+ \li Value
+ \li Description
+\row
+ \li \c CLASSNAME
+ \li \c class_name
+ \li Override the default interface class name with \c{class_name}.
+\row
+ \li \c NO_NAMESPACE
+ \li boolean
+ \li Do not generate the namespaced name if set to \c{ON}.
+\row
+ \li \c INCLUDE
+ \li \c path
+ \li Add an \c{#include "path"} in the generated code.
+\endtable
+*/
+
+/*!
+\page qtdbus-cmake-qt5-generate-dbus-interface.html
+\ingroup cmake-commands-qtdbus
+
+\title qt5_generate_dbus_interface
+
+\brief Generates a D-Bus interface from a header file.
+
+\section1 Synopsis
+
+\badcode
+qt5_generate_dbus_interface(header
+ [customName]
+ [OPTIONS options]
+)
+\endcode
+
+\section1 Description
+
+Parses the C++ source or header file containing a QObject-derived class
+declaration and generates a file containing the D-BUS Introspection XML.
+
+By default, the generated XML file is stored in the current binary directory,
+and has the same base name as the header. You can specify a different name or
+path by adding \c{customName} as an optional second argument.
+
+\section1 Options
+
+The function sets up a call to the \c{qdbuscpp2xml} command line tool. Further
+arguments to the tool can be set after \c{OPTIONS}.
+*/
+
+/*!
+\page qtdbus-cmake-qt5-add-dbus-adaptor.html
+\ingroup cmake-commands-qtdbus
+
+\title qt5_add_dbus_adaptor
+
+\brief Generates an adaptor class for a D-Bus interface.
+
+\section1 Synopsis
+
+\badcode
+qt5_add_dbus_adaptor(<VAR> dbus_spec header parent_class
+ [basename]
+ [classname])
+\endcode
+
+\section1 Description
+
+Generates a C++ header file implementing an adaptor for a D-Bus interface
+description file defined in \c{dbus_spec}. The path of the generated file is
+added to \c{<VAR>}. The generated adaptor class takes a pointer to
+\c{parent_class} as QObject parent. \c{parent_class} should be declared in
+\c{header}, which is included in the generated code as \c{#include "header"}.
+
+The function sets up a call to the \l{Qt D-Bus XML compiler (qdbusxml2cpp)}
+in adaptor mode. The default file and class name are generated from the last
+segment in the \c{dbus_spec} base name:
+
+\table
+\header
+ \li XML file
+ \li Header file
+ \li Class name
+\row
+ \li \c{org.example.chat}
+ \li \c{chatadaptor.h}
+ \li \c{ChatAdaptor}
+\endtable
+
+
+You can change the name of the header file to be generated by passing
+\c{basename} as the fifth argument. The \c{.h} suffix is always added.
+
+You can change the default class name by passing \c{classname} as the sixth
+argument.
+
+\section1 Examples
+
+\snippet cmake/examples.cmake qt5_add_dbus_adaptor
+*/
diff --git a/src/gui/opengl/qopengltextureblitter.cpp b/src/gui/opengl/qopengltextureblitter.cpp
index b65df9dc82..b709f2f639 100644
--- a/src/gui/opengl/qopengltextureblitter.cpp
+++ b/src/gui/opengl/qopengltextureblitter.cpp
@@ -349,6 +349,9 @@ bool QOpenGLTextureBlitterPrivate::buildProgram(ProgramIndex idx, const char *vs
p->glProgram->setUniformValue(p->swizzleUniformPos, false);
+ // minmize state left set after a create()
+ p->glProgram->release();
+
return true;
}
diff --git a/src/gui/text/qdistancefield.cpp b/src/gui/text/qdistancefield.cpp
index 82bb617733..75e2e4e745 100644
--- a/src/gui/text/qdistancefield.cpp
+++ b/src/gui/text/qdistancefield.cpp
@@ -899,11 +899,6 @@ QDistanceField::QDistanceField(int width, int height)
{
}
-QDistanceField::QDistanceField(const QDistanceField &other)
-{
- d = other.d;
-}
-
QDistanceField::QDistanceField(const QRawFont &font, glyph_t glyph, bool doubleResolution)
{
setGlyph(font, glyph, doubleResolution);
diff --git a/src/gui/text/qdistancefield_p.h b/src/gui/text/qdistancefield_p.h
index 31cdf7edd2..c0873cedab 100644
--- a/src/gui/text/qdistancefield_p.h
+++ b/src/gui/text/qdistancefield_p.h
@@ -94,7 +94,6 @@ public:
QDistanceField(const QRawFont &font, glyph_t glyph, bool doubleResolution = false);
QDistanceField(QFontEngine *fontEngine, glyph_t glyph, bool doubleResolution = false);
QDistanceField(const QPainterPath &path, glyph_t glyph, bool doubleResolution = false);
- QDistanceField(const QDistanceField &other);
bool isNull() const;
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 7c04feb5f8..4bd2f4c99a 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -71,6 +71,10 @@
#include "qwindowscarootfetcher_p.h"
#endif
+#if !QT_CONFIG(opensslv11)
+#include <openssl/x509_vfy.h>
+#endif
+
#include <QtCore/qdatetime.h>
#include <QtCore/qdebug.h>
#include <QtCore/qdir.h>
@@ -394,47 +398,41 @@ bool qt_OCSP_certificate_match(OCSP_SINGLERESP *singleResponse, X509 *peerCert,
#endif // ocsp
-// ### This list is shared between all threads, and protected by a
-// mutex. Investigate using thread local storage instead. Or better properly
-// use OpenSSL's ability to attach application data to an SSL/SSL_CTX
-// and extract it in a callback. See how it's done, for example, in PSK
-// callback or in DTLS verification callback.
-struct QSslErrorList
-{
- QMutex mutex;
- QVector<QSslErrorEntry> errors;
-};
-
-Q_GLOBAL_STATIC(QSslErrorList, _q_sslErrorList)
-
int q_X509Callback(int ok, X509_STORE_CTX *ctx)
{
if (!ok) {
// Store the error and at which depth the error was detected.
- _q_sslErrorList()->errors << QSslErrorEntry::fromStoreContext(ctx);
-#if !QT_CONFIG(opensslv11)
-#ifdef QSSLSOCKET_DEBUG
- qCDebug(lcSsl) << "verification error: dumping bad certificate";
- qCDebug(lcSsl) << QSslCertificatePrivate::QSslCertificate_from_X509(q_X509_STORE_CTX_get_current_cert(ctx)).toPem();
- qCDebug(lcSsl) << "dumping chain";
- const auto certs = QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates(q_X509_STORE_CTX_get_chain(ctx));
- for (const QSslCertificate &cert : certs) {
- qCDebug(lcSsl) << "Issuer:" << "O=" << cert.issuerInfo(QSslCertificate::Organization)
- << "CN=" << cert.issuerInfo(QSslCertificate::CommonName)
- << "L=" << cert.issuerInfo(QSslCertificate::LocalityName)
- << "OU=" << cert.issuerInfo(QSslCertificate::OrganizationalUnitName)
- << "C=" << cert.issuerInfo(QSslCertificate::CountryName)
- << "ST=" << cert.issuerInfo(QSslCertificate::StateOrProvinceName);
- qCDebug(lcSsl) << "Subject:" << "O=" << cert.subjectInfo(QSslCertificate::Organization)
- << "CN=" << cert.subjectInfo(QSslCertificate::CommonName)
- << "L=" << cert.subjectInfo(QSslCertificate::LocalityName)
- << "OU=" << cert.subjectInfo(QSslCertificate::OrganizationalUnitName)
- << "C=" << cert.subjectInfo(QSslCertificate::CountryName)
- << "ST=" << cert.subjectInfo(QSslCertificate::StateOrProvinceName);
- qCDebug(lcSsl) << "Valid:" << cert.effectiveDate() << '-' << cert.expiryDate();
+
+ using ErrorListPtr = QVector<QSslErrorEntry>*;
+ ErrorListPtr errors = nullptr;
+
+ // Error list is attached to either 'SSL' or 'X509_STORE'.
+ if (X509_STORE *store = q_X509_STORE_CTX_get0_store(ctx)) { // We try store first:
+#if QT_CONFIG(opensslv11)
+ errors = ErrorListPtr(q_X509_STORE_get_ex_data(store, 0));
+#else
+ errors = ErrorListPtr(q_CRYPTO_get_ex_data(&store->ex_data, 0));
+#endif // opensslv11
+ }
+
+ if (!errors) {
+ // Not found on store? Try SSL and its external data then. According to the OpenSSL's
+ // documentation:
+ //
+ // "Whenever a X509_STORE_CTX object is created for the verification of the peers certificate
+ // during a handshake, a pointer to the SSL object is stored into the X509_STORE_CTX object
+ // to identify the connection affected. To retrieve this pointer the X509_STORE_CTX_get_ex_data()
+ // function can be used with the correct index."
+ if (SSL *ssl = static_cast<SSL *>(q_X509_STORE_CTX_get_ex_data(ctx, q_SSL_get_ex_data_X509_STORE_CTX_idx())))
+ errors = ErrorListPtr(q_SSL_get_ex_data(ssl, QSslSocketBackendPrivate::s_indexForSSLExtraData + 1));
+ }
+
+ if (!errors) {
+ qCWarning(lcSsl, "Neither X509_STORE, nor SSL contains error list, handshake failure");
+ return 0;
}
-#endif // QSSLSOCKET_DEBUG
-#endif // !QT_CONFIG(opensslv11)
+
+ errors->append(QSslErrorEntry::fromStoreContext(ctx));
}
// Always return OK to allow verification to continue. We handle the
// errors gracefully after collecting all errors, after verification has
@@ -589,11 +587,7 @@ bool QSslSocketBackendPrivate::initSslContext()
else
q_SSL_set_accept_state(ssl);
-#if OPENSSL_VERSION_NUMBER >= 0x10001000L
- // Save a pointer to this object into the SSL structure.
- if (QSslSocket::sslLibraryVersionNumber() >= 0x10001000L)
- q_SSL_set_ex_data(ssl, s_indexForSSLExtraData, this);
-#endif
+ q_SSL_set_ex_data(ssl, s_indexForSSLExtraData, this);
#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_PSK)
// Set the client callback for PSK
@@ -1178,14 +1172,14 @@ bool QSslSocketBackendPrivate::startHandshake()
if (inSetAndEmitError)
return false;
- QMutexLocker locker(&_q_sslErrorList()->mutex);
- _q_sslErrorList()->errors.clear();
+ QVector<QSslErrorEntry> lastErrors;
+ q_SSL_set_ex_data(ssl, s_indexForSSLExtraData + 1, &lastErrors);
int result = (mode == QSslSocket::SslClientMode) ? q_SSL_connect(ssl) : q_SSL_accept(ssl);
+ q_SSL_set_ex_data(ssl, s_indexForSSLExtraData + 1, nullptr);
- const auto &lastErrors = _q_sslErrorList()->errors;
if (!lastErrors.isEmpty())
storePeerCertificates();
- for (const auto &currentError : lastErrors) {
+ for (const auto &currentError : qAsConst(lastErrors)) {
emit q->peerVerifyError(_q_OpenSSL_to_QSslError(currentError.code,
configuration.peerCertificateChain.value(currentError.depth)));
if (q->state() != QAbstractSocket::ConnectedState)
@@ -1193,7 +1187,6 @@ bool QSslSocketBackendPrivate::startHandshake()
}
errorList << lastErrors;
- locker.unlock();
// Connection aborted during handshake phase.
if (q->state() != QAbstractSocket::ConnectedState)
@@ -1795,7 +1788,20 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
}
}
- QMutexLocker sslErrorListMutexLocker(&_q_sslErrorList()->mutex);
+ QVector<QSslErrorEntry> lastErrors;
+#if QT_CONFIG(opensslv11)
+ if (!q_X509_STORE_set_ex_data(certStore, 0, &lastErrors)) {
+ qCWarning(lcSsl) << "Unable to attach external data (error list) to a store";
+ errors << QSslError(QSslError::UnspecifiedError);
+ return errors;
+ }
+#else
+ if (!q_CRYPTO_set_ex_data(&certStore->ex_data, 0, &lastErrors)) {
+ qCWarning(lcSsl) << "Unable to attach external data (error list) to a store";
+ errors << QSslError(QSslError::UnspecifiedError);
+ return errors;
+ }
+#endif // opensslv11
// Register a custom callback to get all verification errors.
q_X509_STORE_set_verify_cb(certStore, q_X509Callback);
@@ -1845,12 +1851,7 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
q_OPENSSL_sk_free((OPENSSL_STACK *)intermediates);
// Now process the errors
- const auto errorList = std::move(_q_sslErrorList()->errors);
- _q_sslErrorList()->errors.clear();
- sslErrorListMutexLocker.unlock();
-
- // Translate the errors
if (QSslCertificatePrivate::isBlacklisted(certificateChain[0])) {
QSslError error(QSslError::CertificateBlacklisted, certificateChain[0]);
errors << error;
@@ -1864,8 +1865,8 @@ QList<QSslError> QSslSocketBackendPrivate::verify(const QList<QSslCertificate> &
}
// Translate errors from the error list into QSslErrors.
- errors.reserve(errors.size() + errorList.size());
- for (const auto &error : qAsConst(errorList))
+ errors.reserve(errors.size() + lastErrors.size());
+ for (const auto &error : qAsConst(lastErrors))
errors << _q_OpenSSL_to_QSslError(error.code, certificateChain.value(error.depth));
q_X509_STORE_free(certStore);
diff --git a/src/network/ssl/qsslsocket_openssl11_symbols_p.h b/src/network/ssl/qsslsocket_openssl11_symbols_p.h
index d523a95750..150617e3d2 100644
--- a/src/network/ssl/qsslsocket_openssl11_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl11_symbols_p.h
@@ -106,6 +106,8 @@ Q_AUTOTEST_EXPORT void q_X509_up_ref(X509 *a);
long q_X509_get_version(X509 *a);
EVP_PKEY *q_X509_get_pubkey(X509 *a);
void q_X509_STORE_set_verify_cb(X509_STORE *ctx, X509_STORE_CTX_verify_cb verify_cb);
+int q_X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data);
+void *q_X509_STORE_get_ex_data(X509_STORE *r, int idx);
STACK_OF(X509) *q_X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx);
void q_DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
int q_DH_bits(DH *dh);
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 93b54aaa67..e4a6020f1a 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -179,6 +179,8 @@ DEFINEFUNC(ASN1_TIME *, X509_getm_notAfter, X509 *a, a, return nullptr, return)
DEFINEFUNC(long, X509_get_version, X509 *a, a, return -1, return)
DEFINEFUNC(EVP_PKEY *, X509_get_pubkey, X509 *a, a, return nullptr, return)
DEFINEFUNC2(void, X509_STORE_set_verify_cb, X509_STORE *a, a, X509_STORE_CTX_verify_cb verify_cb, verify_cb, return, DUMMYARG)
+DEFINEFUNC3(int, X509_STORE_set_ex_data, X509_STORE *a, a, int idx, idx, void *data, data, return 0, return)
+DEFINEFUNC2(void *, X509_STORE_get_ex_data, X509_STORE *r, r, int idx, idx, return nullptr, return)
DEFINEFUNC(STACK_OF(X509) *, X509_STORE_CTX_get0_chain, X509_STORE_CTX *a, a, return nullptr, return)
DEFINEFUNC3(void, CRYPTO_free, void *str, str, const char *file, file, int line, line, return, DUMMYARG)
DEFINEFUNC(long, OpenSSL_version_num, void, DUMMYARG, return 0, return)
@@ -253,6 +255,8 @@ DEFINEFUNC(int, CRYPTO_num_locks, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(void, CRYPTO_set_locking_callback, void (*a)(int, int, const char *, int), a, return, DUMMYARG)
DEFINEFUNC(void, CRYPTO_set_id_callback, unsigned long (*a)(), a, return, DUMMYARG)
DEFINEFUNC(void, CRYPTO_free, void *a, a, return, DUMMYARG)
+DEFINEFUNC3(int, CRYPTO_set_ex_data, CRYPTO_EX_DATA *ad, ad, int idx, idx, void *val, val, return 0, return)
+DEFINEFUNC2(void *, CRYPTO_get_ex_data, const CRYPTO_EX_DATA *ad, ad, int idx, idx, return nullptr, return)
DEFINEFUNC(unsigned long, ERR_peek_last_error, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(void, ERR_free_strings, void, DUMMYARG, return, DUMMYARG)
DEFINEFUNC(void, EVP_CIPHER_CTX_cleanup, EVP_CIPHER_CTX *a, a, return, DUMMYARG)
@@ -519,6 +523,7 @@ DEFINEFUNC2(int, X509_STORE_CTX_set_purpose, X509_STORE_CTX *a, a, int b, b, ret
DEFINEFUNC(int, X509_STORE_CTX_get_error, X509_STORE_CTX *a, a, return -1, return)
DEFINEFUNC(int, X509_STORE_CTX_get_error_depth, X509_STORE_CTX *a, a, return -1, return)
DEFINEFUNC(X509 *, X509_STORE_CTX_get_current_cert, X509_STORE_CTX *a, a, return nullptr, return)
+DEFINEFUNC(X509_STORE *, X509_STORE_CTX_get0_store, X509_STORE_CTX *ctx, ctx, return nullptr, return)
DEFINEFUNC(X509_STORE_CTX *, X509_STORE_CTX_new, DUMMYARG, DUMMYARG, return nullptr, return)
DEFINEFUNC2(void *, X509_STORE_CTX_get_ex_data, X509_STORE_CTX *ctx, ctx, int idx, idx, return nullptr, return)
DEFINEFUNC(int, SSL_get_ex_data_X509_STORE_CTX_idx, DUMMYARG, DUMMYARG, return -1, return)
@@ -986,6 +991,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(X509_get_version)
RESOLVEFUNC(X509_get_pubkey)
RESOLVEFUNC(X509_STORE_set_verify_cb)
+ RESOLVEFUNC(X509_STORE_set_ex_data)
+ RESOLVEFUNC(X509_STORE_get_ex_data)
RESOLVEFUNC(CRYPTO_free)
RESOLVEFUNC(OpenSSL_version_num)
RESOLVEFUNC(OpenSSL_version)
@@ -1057,6 +1064,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(CRYPTO_num_locks)
RESOLVEFUNC(CRYPTO_set_id_callback)
RESOLVEFUNC(CRYPTO_set_locking_callback)
+ RESOLVEFUNC(CRYPTO_set_ex_data)
+ RESOLVEFUNC(CRYPTO_get_ex_data)
RESOLVEFUNC(ERR_peek_last_error)
RESOLVEFUNC(ERR_free_strings)
RESOLVEFUNC(EVP_CIPHER_CTX_cleanup)
@@ -1312,6 +1321,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(X509_STORE_CTX_get_error)
RESOLVEFUNC(X509_STORE_CTX_get_error_depth)
RESOLVEFUNC(X509_STORE_CTX_get_current_cert)
+ RESOLVEFUNC(X509_STORE_CTX_get0_store)
RESOLVEFUNC(X509_cmp)
RESOLVEFUNC(X509_STORE_CTX_get_ex_data)
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index e09820b2f2..7b604b2ab8 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -458,6 +458,7 @@ int q_X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
int q_X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
int q_X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
X509 *q_X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
+X509_STORE *q_X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx);
// Diffie-Hellman support
DH *q_DH_new();
diff --git a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
index 46b6505346..f5626d5d16 100644
--- a/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
+++ b/src/network/ssl/qsslsocket_opensslpre11_symbols_p.h
@@ -84,6 +84,8 @@ int q_CRYPTO_num_locks();
void q_CRYPTO_set_locking_callback(void (*a)(int, int, const char *, int));
void q_CRYPTO_set_id_callback(unsigned long (*a)());
void q_CRYPTO_free(void *a);
+int q_CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val);
+void *q_CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx);
unsigned long q_ERR_peek_last_error();
void q_ERR_free_strings();
void q_EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h
index 34d8428188..a957710a88 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.h
+++ b/src/plugins/platforms/cocoa/qcocoamenu.h
@@ -92,6 +92,9 @@ public:
bool isOpen() const;
void setIsOpen(bool isOpen);
+ bool isAboutToShow() const;
+ void setIsAboutToShow(bool isAbout);
+
void timerEvent(QTimerEvent *e) override;
void syncMenuItem_helper(QPlatformMenuItem *menuItem, bool menubarUpdate);
@@ -111,6 +114,7 @@ private:
bool m_parentEnabled:1;
bool m_visible:1;
bool m_isOpen:1;
+ bool m_isAboutToShow:1;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index f34988721d..8c4fca0d29 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -178,6 +178,16 @@ void QCocoaMenu::setIsOpen(bool isOpen)
m_isOpen = isOpen;
}
+bool QCocoaMenu::isAboutToShow() const
+{
+ return m_isAboutToShow;
+}
+
+void QCocoaMenu::setIsAboutToShow(bool isAbout)
+{
+ m_isAboutToShow = isAbout;
+}
+
void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem)
{
QMacAutoReleasePool pool;
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index e54b6284e5..ef9b2659d2 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -140,6 +140,12 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
if (menu == m_menu)
return;
+ bool setAttached = false;
+ if ([m_native.menu isKindOfClass:[QCocoaNSMenu class]]) {
+ auto parentMenu = static_cast<QCocoaNSMenu *>(m_native.menu);
+ setAttached = parentMenu.platformMenu && parentMenu.platformMenu->isAboutToShow();
+ }
+
if (m_menu && m_menu->menuParent() == this) {
m_menu->setMenuParent(nullptr);
// Free the menu from its parent's influence
@@ -153,6 +159,8 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
if (m_menu) {
m_menu->setMenuParent(this);
m_menu->propagateEnabledState(isEnabled());
+ if (setAttached)
+ m_menu->setAttachedItem(m_native);
} else {
// we previously had a menu, but no longer
// clear out our item so the nexy sync() call builds a new one
diff --git a/src/plugins/platforms/cocoa/qcocoansmenu.mm b/src/plugins/platforms/cocoa/qcocoansmenu.mm
index 65b0832d9f..c51460282a 100644
--- a/src/plugins/platforms/cocoa/qcocoansmenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoansmenu.mm
@@ -195,7 +195,9 @@ static NSString *qt_mac_removePrivateUnicode(NSString *string)
return;
platformMenu->setIsOpen(true);
+ platformMenu->setIsAboutToShow(true);
emit platformMenu->aboutToShow();
+ platformMenu->setIsAboutToShow(false);
}
- (void)menuDidClose:(NSMenu *)menu
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 0fa0e8cd7b..a5a2aeb9aa 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -658,16 +658,24 @@ QImage::Format QXcbScreen::format() const
return format;
}
-QDpi QXcbScreen::logicalDpi() const
+int QXcbScreen::forcedDpi() const
{
static const int overrideDpi = qEnvironmentVariableIntValue("QT_FONT_DPI");
if (overrideDpi)
- return QDpi(overrideDpi, overrideDpi);
+ return overrideDpi;
const int forcedDpi = m_virtualDesktop->forcedDpi();
- if (forcedDpi > 0) {
+ if (forcedDpi > 0)
+ return forcedDpi;
+ return 0;
+}
+
+QDpi QXcbScreen::logicalDpi() const
+{
+ const int forcedDpi = this->forcedDpi();
+ if (forcedDpi > 0)
return QDpi(forcedDpi, forcedDpi);
- }
+
return m_virtualDesktop->dpi();
}
@@ -739,7 +747,9 @@ void QXcbScreen::updateGeometry(const QRect &geometry, uint8_t rotation)
if (m_sizeMillimeters.isEmpty())
m_sizeMillimeters = sizeInMillimeters(geometry.size(), m_virtualDesktop->dpi());
- qreal dpi = geometry.width() / physicalSize().width() * qreal(25.4);
+ qreal dpi = forcedDpi();
+ if (dpi <= 0)
+ dpi = geometry.width() / physicalSize().width() * qreal(25.4);
// Use 128 as a reference DPI on small screens. This favors "small UI" over "large UI".
qreal referenceDpi = physicalSize().width() <= 320 ? 128 : 96;
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index be6c45e415..ec3b07bfb7 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -208,6 +208,7 @@ public:
private:
void sendStartupMessage(const QByteArray &message) const;
+ int forcedDpi() const;
QByteArray getOutputProperty(xcb_atom_t atom) const;
QByteArray getEdid() const;
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index 3542606a00..35b2fa50ac 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -2061,7 +2061,8 @@ QMacStyle::QMacStyle()
Q_D(QMacStyle);
// FIXME: Tie this logic into theme change, or even polish/unpolish
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave) {
- d->appearanceObserver = QMacKeyValueObserver(NSApp, @"effectiveAppearance", [&d] {
+ d->appearanceObserver = QMacKeyValueObserver(NSApp, @"effectiveAppearance", [this] {
+ Q_D(QMacStyle);
for (NSView *b : d->cocoaControls)
[b release];
d->cocoaControls.clear();
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 8f339a23f6..5264bbc581 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -381,8 +381,6 @@ QWidget *QApplication::topLevelAt(const QPoint &pos)
0 if there is no such widget.
*/
-void qt_init(QApplicationPrivate *priv, int type
- );
void qt_init_tooltip_palette();
void qt_cleanup();
@@ -428,16 +426,10 @@ bool Q_WIDGETS_EXPORT qt_tab_all_widgets()
// ######## move to QApplicationPrivate
// Default application palettes and fonts (per widget type)
Q_GLOBAL_STATIC(PaletteHash, app_palettes)
-PaletteHash *qt_app_palettes_hash()
-{
- return app_palettes();
-}
-
Q_GLOBAL_STATIC(FontHash, app_fonts)
-FontHash *qt_app_fonts_hash()
-{
- return app_fonts();
-}
+// Exported accessors for use outside of this file
+PaletteHash *qt_app_palettes_hash() { return app_palettes(); }
+FontHash *qt_app_fonts_hash() { return app_fonts(); }
QWidgetList *QApplicationPrivate::popupWidgets = 0; // has keyboard input focus
@@ -571,7 +563,10 @@ void QApplicationPrivate::init()
process_cmdline();
// Must be called before initialize()
- qt_init(this, application_type);
+ QColormap::initialize();
+ qt_init_tooltip_palette();
+ QApplicationPrivate::initializeWidgetFontHash();
+
initialize();
eventDispatcher->startingUp();
@@ -586,18 +581,6 @@ void QApplicationPrivate::init()
}
-void qt_init(QApplicationPrivate *priv, int type)
-{
- Q_UNUSED(priv);
- Q_UNUSED(type);
-
- QColormap::initialize();
-
- qt_init_tooltip_palette();
-
- QApplicationPrivate::initializeWidgetFontHash();
-}
-
void qt_init_tooltip_palette()
{
#ifndef QT_NO_TOOLTIP
@@ -663,7 +646,7 @@ void QApplicationPrivate::initializeWidgetPaletteHash()
QPlatformTheme *platformTheme = QGuiApplicationPrivate::platformTheme();
if (!platformTheme)
return;
- qt_app_palettes_hash()->clear();
+ app_palettes()->clear();
setPossiblePalette(platformTheme->palette(QPlatformTheme::ToolButtonPalette), "QToolButton");
setPossiblePalette(platformTheme->palette(QPlatformTheme::ButtonPalette), "QAbstractButton");
@@ -687,7 +670,7 @@ void QApplicationPrivate::initializeWidgetFontHash()
const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
if (!theme)
return;
- FontHash *fontHash = qt_app_fonts_hash();
+ FontHash *fontHash = app_fonts();
fontHash->clear();
if (const QFont *font = theme->font(QPlatformTheme::MenuFont))
@@ -1166,9 +1149,7 @@ void QApplication::setStyle(QStyle *style)
} else if (QApplicationPrivate::sys_pal) {
clearSystemPalette();
initSystemPalette();
- QApplicationPrivate::initializeWidgetPaletteHash();
QApplicationPrivate::initializeWidgetFontHash();
- QApplicationPrivate::setPalette_helper(*QApplicationPrivate::sys_pal, /*className=*/0, /*clearWidgetPaletteHash=*/false);
} else if (!QApplicationPrivate::sys_pal) {
// Initialize the sys_pal if it hasn't happened yet...
QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette());
@@ -1466,28 +1447,10 @@ void QApplication::setPalette(const QPalette &palette, const char* className)
void QApplicationPrivate::setSystemPalette(const QPalette &pal)
{
- QPalette adjusted;
-
-#if 0
- // adjust the system palette to avoid dithering
- QColormap cmap = QColormap::instance();
- if (cmap.depths() > 4 && cmap.depths() < 24) {
- for (int g = 0; g < QPalette::NColorGroups; g++)
- for (int i = 0; i < QPalette::NColorRoles; i++) {
- QColor color = pal.color((QPalette::ColorGroup)g, (QPalette::ColorRole)i);
- color = cmap.colorAt(cmap.pixel(color));
- adjusted.setColor((QPalette::ColorGroup)g, (QPalette::ColorRole) i, color);
- }
- }
-#else
- adjusted = pal;
-#endif
-
if (!sys_pal)
- sys_pal = new QPalette(adjusted);
+ sys_pal = new QPalette(pal);
else
- *sys_pal = adjusted;
-
+ *sys_pal = pal;
if (!QApplicationPrivate::set_pal)
QApplication::setPalette(*sys_pal);
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 0682717f54..1ef097e6e5 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -1,4 +1,4 @@
-/****************************************************************************
+/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
@@ -2592,14 +2592,27 @@ bool QWidgetPrivate::setScreenForPoint(const QPoint &pos)
Q_Q(QWidget);
if (!q->isWindow())
return false;
- // Find the screen for pos and make the widget undertand it is on that screen.
+ // Find the screen for pos and make the widget understand it is on that screen.
+ return setScreen(QGuiApplication::screenAt(pos));
+}
+
+/*!
+\internal
+Ensures that the widget's QWindow is set to be on the given \a screen.
+Returns true if the screen was changed.
+*/
+
+bool QWidgetPrivate::setScreen(QScreen *screen)
+{
+ Q_Q(QWidget);
+ if (!screen || !q->isWindow())
+ return false;
const QScreen *currentScreen = windowHandle() ? windowHandle()->screen() : nullptr;
- QScreen *actualScreen = QGuiApplication::screenAt(pos);
- if (actualScreen && currentScreen != actualScreen) {
+ if (currentScreen != screen) {
if (!windowHandle()) // Try to create a window handle if not created.
createWinId();
if (windowHandle())
- windowHandle()->setScreen(actualScreen);
+ windowHandle()->setScreen(screen);
return true;
}
return false;
@@ -7006,37 +7019,41 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second)
lastFocusChild = focusNext;
}
};
+ auto setPrev = [](QWidget *w, QWidget *prev)
+ {
+ w->d_func()->focus_prev = prev;
+ };
+ auto setNext = [](QWidget *w, QWidget *next)
+ {
+ w->d_func()->focus_next = next;
+ };
- QWidget *lastFocusChildOfFirst, *lastFocusChildOfSecond;
- determineLastFocusChild(first, lastFocusChildOfFirst);
+ // remove the second widget from the chain
+ QWidget *lastFocusChildOfSecond;
determineLastFocusChild(second, lastFocusChildOfSecond);
-
- // If the tab order is already correct, exit early
- if (lastFocusChildOfFirst == second ||
- lastFocusChildOfFirst->d_func()->focus_next == second) {
- return;
+ {
+ QWidget *oldPrev = second->d_func()->focus_prev;
+ QWidget *prevWithFocus = oldPrev;
+ while (prevWithFocus->focusPolicy() == Qt::NoFocus)
+ prevWithFocus = prevWithFocus->d_func()->focus_prev;
+ // only widgets between first and second -> all is fine
+ if (prevWithFocus == first)
+ return;
+ QWidget *oldNext = lastFocusChildOfSecond->d_func()->focus_next;
+ setPrev(oldNext, oldPrev);
+ setNext(oldPrev, oldNext);
}
- // Note that we need to handle two different sections in the tab chain; The section
- // that 'first' belongs to (firstSection), where we are about to insert 'second', and
- // the section that 'second' used be a part of (secondSection). When we pull 'second'
- // out of the second section and insert it into the first, we also need to ensure
- // that we leave the second section in a connected state.
- QWidget *firstChainOldSecond = lastFocusChildOfFirst->d_func()->focus_next;
- QWidget *secondChainNewFirst = second->d_func()->focus_prev;
- QWidget *secondChainNewSecond = lastFocusChildOfSecond->d_func()->focus_next;
-
- // Insert 'second' after 'first'
- lastFocusChildOfFirst->d_func()->focus_next = second;
- second->d_func()->focus_prev = lastFocusChildOfFirst;
-
- // The widget that used to be 'second' in the first section, should now become 'third'
- lastFocusChildOfSecond->d_func()->focus_next = firstChainOldSecond;
- firstChainOldSecond->d_func()->focus_prev = lastFocusChildOfSecond;
-
- // Repair the second section after we pulled 'second' out of it
- secondChainNewFirst->d_func()->focus_next = secondChainNewSecond;
- secondChainNewSecond->d_func()->focus_prev = secondChainNewFirst;
+ // insert the second widget into the chain
+ QWidget *lastFocusChildOfFirst;
+ determineLastFocusChild(first, lastFocusChildOfFirst);
+ {
+ QWidget *oldNext = lastFocusChildOfFirst->d_func()->focus_next;
+ setPrev(second, lastFocusChildOfFirst);
+ setNext(lastFocusChildOfFirst, second);
+ setPrev(oldNext, lastFocusChildOfSecond);
+ setNext(lastFocusChildOfSecond, oldNext);
+ }
}
/*!\internal
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index af4ad31501..39a4117cfc 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -181,6 +181,7 @@ struct QTLWExtra {
QRect frameStrut;
QRect normalGeometry; // used by showMin/maximized/FullScreen
Qt::WindowFlags savedFlags; // Save widget flags while showing fullscreen
+ // ### TODO replace initialScreenIndex with QScreen *, in case the screens change at runtime
int initialScreenIndex; // Screen number when passing a QDesktop[Screen]Widget as parent.
QVector<QPlatformTextureList *> widgetTextures;
@@ -356,6 +357,7 @@ public:
void createWinId();
bool setScreenForPoint(const QPoint &pos);
+ bool setScreen(QScreen *screen);
void createTLExtra();
void createExtra();
diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp
index e25bc6de7a..685c5e159e 100644
--- a/src/widgets/widgets/qmdisubwindow.cpp
+++ b/src/widgets/widgets/qmdisubwindow.cpp
@@ -3141,8 +3141,6 @@ void QMdiSubWindow::paintEvent(QPaintEvent *paintEvent)
}
Q_D(QMdiSubWindow);
- if (isMaximized() && !d->drawTitleBarWhenMaximized())
- return;
if (d->resizeTimerId != -1) {
// Only update the style option rect and the window title.
@@ -3162,6 +3160,17 @@ void QMdiSubWindow::paintEvent(QPaintEvent *paintEvent)
}
QStylePainter painter(this);
+ QStyleOptionFrame frameOptions;
+ frameOptions.initFrom(this);
+ frameOptions.state.setFlag(QStyle::State_Active, d->isActive);
+ if (isMaximized() && !d->drawTitleBarWhenMaximized()) {
+ if (!autoFillBackground() && (!widget() || !qt_widget_private(widget())->isOpaque)) {
+ // make sure we paint all pixels of a maximized QMdiSubWindow if no-one else does
+ painter.drawPrimitive(QStyle::PE_FrameWindow, frameOptions);
+ }
+ return;
+ }
+
if (!d->windowTitle.isEmpty())
painter.setFont(d->font);
painter.drawComplexControl(QStyle::CC_TitleBar, d->cachedStyleOptions);
@@ -3169,10 +3178,7 @@ void QMdiSubWindow::paintEvent(QPaintEvent *paintEvent)
if (isMinimized() && !d->hasBorder(d->cachedStyleOptions))
return;
- QStyleOptionFrame frameOptions;
- frameOptions.initFrom(this);
frameOptions.lineWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, this);
- frameOptions.state.setFlag(QStyle::State_Active, d->isActive);
// ### Ensure that we do not require setting the cliprect for 4.4
if (!isMinimized() && !d->hasBorder(d->cachedStyleOptions))
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 287be3e272..7b6a1b6da8 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -2331,8 +2331,18 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
d->updateLayoutDirection();
// Ensure that we get correct sizeHints by placing this window on the correct screen.
- if (d->setScreenForPoint(p))
+ // However if the QMenu was constructed with a QDesktopScreenWidget as its parent,
+ // then initialScreenIndex was set, so we should respect that for the lifetime of this menu.
+ // Use d->popupScreen to remember, because initialScreenIndex will be reset after the first showing.
+ const int screenIndex = d->topData()->initialScreenIndex;
+ if (screenIndex >= 0)
+ d->popupScreen = screenIndex;
+ if (auto s = QGuiApplication::screens().value(d->popupScreen)) {
+ if (d->setScreen(s))
+ d->itemsDirty = true;
+ } else if (d->setScreenForPoint(p)) {
d->itemsDirty = true;
+ }
const bool contextMenu = d->isContextMenu();
if (d->lastContextMenu != contextMenu) {
diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h
index 1821181535..a72592824b 100644
--- a/src/widgets/widgets/qmenu_p.h
+++ b/src/widgets/widgets/qmenu_p.h
@@ -515,6 +515,8 @@ public:
bool tearoffHighlighted : 1;
//menu fading/scrolling effects
bool doChildEffects : 1;
+
+ int popupScreen = -1;
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index a53d7841f4..9a60f1477d 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -68,6 +68,7 @@
#include "qmenu_p.h"
#include "qmenubar_p.h"
+#include <private/qscreen_p.h>
#include "qdebug.h"
QT_BEGIN_NAMESPACE
@@ -322,11 +323,18 @@ void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst)
QRect adjustedActionRect = actionRect(action);
QPoint pos(q->mapToGlobal(QPoint(adjustedActionRect.left(), adjustedActionRect.bottom() + 1)));
QSize popup_size = activeMenu->sizeHint();
-
//we put the popup menu on the screen containing the bottom-center of the action rect
- QRect screenRect = QDesktopWidgetPrivate::screenGeometry(pos + QPoint(adjustedActionRect.width() / 2, 0));
+ QScreen *popupScreen = q->window()->windowHandle()->screen();
+ QPoint bottomMiddlePos = pos + QPoint(adjustedActionRect.width() / 2, 0);
+ const auto &siblings = popupScreen->virtualSiblings();
+ for (QScreen *sibling : siblings) {
+ if (sibling->geometry().contains(bottomMiddlePos)) {
+ popupScreen = sibling;
+ break;
+ }
+ }
+ QRect screenRect = popupScreen->geometry();
pos = QPoint(qMax(pos.x(), screenRect.x()), qMax(pos.y(), screenRect.y()));
-
const bool fitUp = (pos.y() - popup_size.height() >= screenRect.top());
const bool fitDown = (pos.y() + popup_size.height() <= screenRect.bottom());
const bool rtl = q->isRightToLeft();
@@ -352,6 +360,7 @@ void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst)
if(!defaultPopDown || (fitUp && !fitDown))
pos.setY(qMax(screenRect.y(), q->mapToGlobal(QPoint(0, adjustedActionRect.top()-popup_size.height())).y()));
+ QMenuPrivate::get(activeMenu)->topData()->initialScreenIndex = QGuiApplication::screens().indexOf(popupScreen);
activeMenu->popup(pos);
if(activateFirst)
activeMenu->d_func()->setFirstActionActive();
diff --git a/tests/auto/corelib/animation/qabstractanimation/tst_qabstractanimation.cpp b/tests/auto/corelib/animation/qabstractanimation/tst_qabstractanimation.cpp
index fc09d57692..66a752df5d 100644
--- a/tests/auto/corelib/animation/qabstractanimation/tst_qabstractanimation.cpp
+++ b/tests/auto/corelib/animation/qabstractanimation/tst_qabstractanimation.cpp
@@ -83,6 +83,21 @@ void tst_QAbstractAnimation::destruction()
{
TestableQAbstractAnimation *anim = new TestableQAbstractAnimation;
delete anim;
+
+ // Animations should stop when deleted
+ auto *stopWhenDeleted = new TestableQAbstractAnimation;
+ QAbstractAnimation::State lastOldState, lastNewState;
+ QObject::connect(stopWhenDeleted, &QAbstractAnimation::stateChanged,
+ [&](QAbstractAnimation::State newState, QAbstractAnimation::State oldState) {
+ lastNewState = newState;
+ lastOldState = oldState;
+ });
+ stopWhenDeleted->start();
+ QCOMPARE(lastOldState, QAbstractAnimation::Stopped);
+ QCOMPARE(lastNewState, QAbstractAnimation::Running);
+ delete stopWhenDeleted;
+ QCOMPARE(lastOldState, QAbstractAnimation::Running);
+ QCOMPARE(lastNewState, QAbstractAnimation::Stopped);
}
void tst_QAbstractAnimation::currentLoop()
diff --git a/tests/auto/network/access/qnetworkreply/certs/qt-test-server-cacert.pem b/tests/auto/network/access/qnetworkreply/certs/qt-test-server-cacert.pem
index 25bd4046e8..c5aea0d7c9 100644
--- a/tests/auto/network/access/qnetworkreply/certs/qt-test-server-cacert.pem
+++ b/tests/auto/network/access/qnetworkreply/certs/qt-test-server-cacert.pem
@@ -1,17 +1,17 @@
-----BEGIN CERTIFICATE-----
-MIICrTCCAhYCCQCdDn5rci6VDjANBgkqhkiG9w0BAQQFADCBmjEOMAwGA1UEChMF
-Tm9raWExFDASBgNVBAsTC1F0IFNvZnR3YXJlMSIwIAYJKoZIhvcNAQkBFhNub2Jv
-ZHlAbm9kb21haW4ub3JnMQ0wCwYDVQQHEwRPc2xvMQ0wCwYDVQQIEwRPc2xvMQsw
-CQYDVQQGEwJOTzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQw
-HhcNMDkwNzEwMDc0MTIzWhcNMTkwNzA4MDc0MTIzWjCBmjEOMAwGA1UEChMFTm9r
-aWExFDASBgNVBAsTC1F0IFNvZnR3YXJlMSIwIAYJKoZIhvcNAQkBFhNub2JvZHlA
-bm9kb21haW4ub3JnMQ0wCwYDVQQHEwRPc2xvMQ0wCwYDVQQIEwRPc2xvMQswCQYD
-VQQGEwJOTzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQwgZ8w
-DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM2q22/WNMmn8cC+5EEYGeICySLmp9W6
-Ay6eKHr0Xxp3X3epETuPfvAuxp7rOtkS18EMUegkUj8jw0IMEcbyHKFC/rTCaYOt
-93CxGBXMIChiMPAsFeYzGa/D6xzAkfcRaJRQ+Ek3CDLXPnXfo7xpABXezYcPXAJr
-gsgBfWrwHdxzAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAy7YOLCZABQy2Ygkchq1I
-+TUpvMn+gLwAyW8TNErM1V4lNY2+K78RawzKx3SqM97ymCy4TD45EA3A2gmi32NI
-xSKBNjFyzngUqsXBdcSasALiowlZCiJrGwlGX5qCkBlxXvJeUEbuJLPYVl5FBjXZ
-6o00K4cSPCqtqUez7WSmDZU=
+MIICpzCCAhACCQCzAF1hyRVzAjANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UEBhMC
+Tk8xDTALBgNVBAgTBE9zbG8xDTALBgNVBAcTBE9zbG8xDjAMBgNVBAoTBU5va2lh
+MTUwMwYDVQQLFCxRdCBTb2Z0d2FyZS9lbWFpbEFkZHJlc3M9bm9ib2R5QG5vZG9t
+YWluLm9yZzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQwHhcN
+MTkwNjI0MTI0OTIxWhcNMjIwNjIzMTI0OTIxWjCBlzELMAkGA1UEBhMCTk8xDTAL
+BgNVBAgTBE9zbG8xDTALBgNVBAcTBE9zbG8xDjAMBgNVBAoTBU5va2lhMTUwMwYD
+VQQLFCxRdCBTb2Z0d2FyZS9lbWFpbEFkZHJlc3M9bm9ib2R5QG5vZG9tYWluLm9y
+ZzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQwgZ8wDQYJKoZI
+hvcNAQEBBQADgY0AMIGJAoGBAM2q22/WNMmn8cC+5EEYGeICySLmp9W6Ay6eKHr0
+Xxp3X3epETuPfvAuxp7rOtkS18EMUegkUj8jw0IMEcbyHKFC/rTCaYOt93CxGBXM
+IChiMPAsFeYzGa/D6xzAkfcRaJRQ+Ek3CDLXPnXfo7xpABXezYcPXAJrgsgBfWrw
+HdxzAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEASCKbqEX5ysC549mq90ydk4jyDW3m
+PUyet01fKpcRqVs+OJxdExFBTra3gho6WzzpTSPsuX2ZKOLF5k6KkCvdCGvhC1Kv
+HHPIExurfzvdlSRzj6HbKyPuSfxyOloH0bBp7/Gg5RIuBPKlbmfbnTLtwEjhhbMU
+SoYI8HZd3HfY87c=
-----END CERTIFICATE-----
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index 9a2c62b955..8627a37e12 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -5031,9 +5031,6 @@ public:
// very similar to ioPostToHttpUploadProgress but for SSL
void tst_QNetworkReply::ioPostToHttpsUploadProgress()
{
-#ifdef Q_OS_WIN
- QSKIP("QTBUG-76157: get rid of locking in TLS handshake (QSslSocket)");
-#endif
//QFile sourceFile(testDataDir + "/bigfile");
//QVERIFY(sourceFile.open(QIODevice::ReadOnly));
qint64 wantedSize = 2*1024*1024; // 2 MB
@@ -6415,10 +6412,6 @@ void tst_QNetworkReply::encrypted()
void tst_QNetworkReply::abortOnEncrypted()
{
-#ifdef Q_OS_WIN
- QSKIP("QTBUG-76157: get rid of locking in TLS handshake (QSslSocket)");
-#endif
-
SslServer server;
server.listen();
if (!server.isListening())
@@ -8496,9 +8489,7 @@ void tst_QNetworkReply::ioHttpRedirectErrors_data()
QTest::newRow("too-many-redirects") << "http://localhost" << tempRedirectReply << QNetworkReply::TooManyRedirectsError;
#if QT_CONFIG(ssl)
-#ifndef Q_OS_WIN // QTBUG-76157
QTest::newRow("insecure-redirect") << "https://localhost" << tempRedirectReply << QNetworkReply::InsecureRedirectError;
-#endif // Q_OS_WIN
#endif
QTest::newRow("unknown-redirect") << "http://localhost"<< tempRedirectReply.replace("http", "bad_protocol") << QNetworkReply::ProtocolUnknownError;
}
@@ -8575,11 +8566,9 @@ void tst_QNetworkReply::ioHttpRedirectPolicy_data()
QTest::newRow("nolesssafe-nossl") << QNetworkRequest::NoLessSafeRedirectPolicy << false << 1 << 200;
QTest::newRow("same-origin-nossl") << QNetworkRequest::SameOriginRedirectPolicy << false << 1 << 200;
#if QT_CONFIG(ssl)
-#ifndef Q_OS_WIN // QTBUG-76157
QTest::newRow("manual-ssl") << QNetworkRequest::ManualRedirectPolicy << true << 0 << 307;
QTest::newRow("nolesssafe-ssl") << QNetworkRequest::NoLessSafeRedirectPolicy << true << 1 << 200;
QTest::newRow("same-origin-ssl") << QNetworkRequest::SameOriginRedirectPolicy << true << 1 << 200;
-#endif // Q_OS_WIN
#endif
}
@@ -8633,41 +8622,33 @@ void tst_QNetworkReply::ioHttpRedirectPolicyErrors_data()
QTest::newRow("nolesssafe-nossl-nossl-too-many") << QNetworkRequest::NoLessSafeRedirectPolicy
<< false << QString("http://localhost:%1") << 0 << QNetworkReply::TooManyRedirectsError;
#if QT_CONFIG(ssl)
-#ifndef Q_OS_WIN // QTBUG-76157
QTest::newRow("nolesssafe-ssl-ssl-too-many") << QNetworkRequest::NoLessSafeRedirectPolicy
<< true << QString("https:/localhost:%1") << 0 << QNetworkReply::TooManyRedirectsError;
QTest::newRow("nolesssafe-ssl-nossl-insecure-redirect") << QNetworkRequest::NoLessSafeRedirectPolicy
<< true << QString("http://localhost:%1") << 50 << QNetworkReply::InsecureRedirectError;
-#endif // Q_OS_WIN
#endif
// 2. SameOriginRedirectsPolicy
QTest::newRow("same-origin-nossl-nossl-too-many") << QNetworkRequest::SameOriginRedirectPolicy
<< false << QString("http://localhost:%1") << 0 << QNetworkReply::TooManyRedirectsError;
#if QT_CONFIG(ssl)
-#ifndef Q_OS_WIN // QTBUG-76157
QTest::newRow("same-origin-ssl-ssl-too-many") << QNetworkRequest::SameOriginRedirectPolicy
<< true << QString("https://localhost:%1") << 0 << QNetworkReply::TooManyRedirectsError;
QTest::newRow("same-origin-https-http-wrong-protocol") << QNetworkRequest::SameOriginRedirectPolicy
<< true << QString("http://localhost:%1") << 50 << QNetworkReply::InsecureRedirectError;
-#endif // Q_OS_WIN
#endif
QTest::newRow("same-origin-http-https-wrong-protocol") << QNetworkRequest::SameOriginRedirectPolicy
<< false << QString("https://localhost:%1") << 50 << QNetworkReply::InsecureRedirectError;
QTest::newRow("same-origin-http-http-wrong-host") << QNetworkRequest::SameOriginRedirectPolicy
<< false << QString("http://not-so-localhost:%1") << 50 << QNetworkReply::InsecureRedirectError;
#if QT_CONFIG(ssl)
-#ifndef Q_OS_WIN // QTBUG-76157
QTest::newRow("same-origin-https-https-wrong-host") << QNetworkRequest::SameOriginRedirectPolicy
<< true << QString("https://not-so-localhost:%1") << 50 << QNetworkReply::InsecureRedirectError;
-#endif // Q_OS_WIN
#endif
QTest::newRow("same-origin-http-http-wrong-port") << QNetworkRequest::SameOriginRedirectPolicy
<< false << QString("http://localhost/%1") << 50 << QNetworkReply::InsecureRedirectError;
#if QT_CONFIG(ssl)
-#ifndef Q_OS_WIN // QTBUG-76157
QTest::newRow("same-origin-https-https-wrong-port") << QNetworkRequest::SameOriginRedirectPolicy
<< true << QString("https://localhost/%1") << 50 << QNetworkReply::InsecureRedirectError;
-#endif // Q_OS_WIN
#endif
}
@@ -9142,10 +9123,6 @@ void tst_QNetworkReply::putWithServerClosingConnectionImmediately()
for (int s = 0; s <= 1; s++) {
withSsl = (s == 1);
-#ifdef Q_OS_WIN
- if (withSsl)
- QSKIP("QTBUG-76157: get rid of locking in TLS handshake (QSslSocket)");
-#endif // Q_OS_WIN
// Test also needs to run several times because of 9c2ecf89
for (int j = 0; j < 20; j++) {
// emulate a minimal https server
diff --git a/tests/auto/network/ssl/qsslsocket/certs/qt-test-server-cacert.pem b/tests/auto/network/ssl/qsslsocket/certs/qt-test-server-cacert.pem
index 25bd4046e8..c5aea0d7c9 100644
--- a/tests/auto/network/ssl/qsslsocket/certs/qt-test-server-cacert.pem
+++ b/tests/auto/network/ssl/qsslsocket/certs/qt-test-server-cacert.pem
@@ -1,17 +1,17 @@
-----BEGIN CERTIFICATE-----
-MIICrTCCAhYCCQCdDn5rci6VDjANBgkqhkiG9w0BAQQFADCBmjEOMAwGA1UEChMF
-Tm9raWExFDASBgNVBAsTC1F0IFNvZnR3YXJlMSIwIAYJKoZIhvcNAQkBFhNub2Jv
-ZHlAbm9kb21haW4ub3JnMQ0wCwYDVQQHEwRPc2xvMQ0wCwYDVQQIEwRPc2xvMQsw
-CQYDVQQGEwJOTzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQw
-HhcNMDkwNzEwMDc0MTIzWhcNMTkwNzA4MDc0MTIzWjCBmjEOMAwGA1UEChMFTm9r
-aWExFDASBgNVBAsTC1F0IFNvZnR3YXJlMSIwIAYJKoZIhvcNAQkBFhNub2JvZHlA
-bm9kb21haW4ub3JnMQ0wCwYDVQQHEwRPc2xvMQ0wCwYDVQQIEwRPc2xvMQswCQYD
-VQQGEwJOTzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQwgZ8w
-DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM2q22/WNMmn8cC+5EEYGeICySLmp9W6
-Ay6eKHr0Xxp3X3epETuPfvAuxp7rOtkS18EMUegkUj8jw0IMEcbyHKFC/rTCaYOt
-93CxGBXMIChiMPAsFeYzGa/D6xzAkfcRaJRQ+Ek3CDLXPnXfo7xpABXezYcPXAJr
-gsgBfWrwHdxzAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAy7YOLCZABQy2Ygkchq1I
-+TUpvMn+gLwAyW8TNErM1V4lNY2+K78RawzKx3SqM97ymCy4TD45EA3A2gmi32NI
-xSKBNjFyzngUqsXBdcSasALiowlZCiJrGwlGX5qCkBlxXvJeUEbuJLPYVl5FBjXZ
-6o00K4cSPCqtqUez7WSmDZU=
+MIICpzCCAhACCQCzAF1hyRVzAjANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UEBhMC
+Tk8xDTALBgNVBAgTBE9zbG8xDTALBgNVBAcTBE9zbG8xDjAMBgNVBAoTBU5va2lh
+MTUwMwYDVQQLFCxRdCBTb2Z0d2FyZS9lbWFpbEFkZHJlc3M9bm9ib2R5QG5vZG9t
+YWluLm9yZzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQwHhcN
+MTkwNjI0MTI0OTIxWhcNMjIwNjIzMTI0OTIxWjCBlzELMAkGA1UEBhMCTk8xDTAL
+BgNVBAgTBE9zbG8xDTALBgNVBAcTBE9zbG8xDjAMBgNVBAoTBU5va2lhMTUwMwYD
+VQQLFCxRdCBTb2Z0d2FyZS9lbWFpbEFkZHJlc3M9bm9ib2R5QG5vZG9tYWluLm9y
+ZzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQwgZ8wDQYJKoZI
+hvcNAQEBBQADgY0AMIGJAoGBAM2q22/WNMmn8cC+5EEYGeICySLmp9W6Ay6eKHr0
+Xxp3X3epETuPfvAuxp7rOtkS18EMUegkUj8jw0IMEcbyHKFC/rTCaYOt93CxGBXM
+IChiMPAsFeYzGa/D6xzAkfcRaJRQ+Ek3CDLXPnXfo7xpABXezYcPXAJrgsgBfWrw
+HdxzAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEASCKbqEX5ysC549mq90ydk4jyDW3m
+PUyet01fKpcRqVs+OJxdExFBTra3gho6WzzpTSPsuX2ZKOLF5k6KkCvdCGvhC1Kv
+HHPIExurfzvdlSRzj6HbKyPuSfxyOloH0bBp7/Gg5RIuBPKlbmfbnTLtwEjhhbMU
+SoYI8HZd3HfY87c=
-----END CERTIFICATE-----
diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
index 66475e55ad..1a9cab3e24 100644
--- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
+++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
@@ -2711,6 +2711,7 @@ void tst_QSslSocket::encryptWithoutConnecting()
void tst_QSslSocket::resume_data()
{
+ QSKIP("Temporary skip while updating certificates");
QTest::addColumn<bool>("ignoreErrorsAfterPause");
QTest::addColumn<QList<QSslError> >("errorsToIgnore");
QTest::addColumn<bool>("expectSuccess");
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 063a2b5b9d..da542ba67f 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -180,6 +180,7 @@ private slots:
void tabOrderWithProxy();
void tabOrderWithCompoundWidgets();
void tabOrderNoChange();
+ void tabOrderNoChange2();
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
void activation();
#endif
@@ -1942,6 +1943,24 @@ static QVector<QWidget*> getFocusChain(QWidget *start, bool bForward)
return ret;
}
+//#define DEBUG_FOCUS_CHAIN
+static void dumpFocusChain(QWidget *start, bool bForward, const char *desc = nullptr)
+{
+#ifdef DEBUG_FOCUS_CHAIN
+ qDebug() << "Dump focus chain, start:" << start << "isForward:" << bForward << desc;
+ QWidget *cur = start;
+ do {
+ qDebug() << cur;
+ auto widgetPrivate = static_cast<QWidgetPrivate *>(qt_widget_private(cur));
+ cur = bForward ? widgetPrivate->focus_next : widgetPrivate->focus_prev;
+ } while (cur != start);
+#else
+ Q_UNUSED(start)
+ Q_UNUSED(bForward)
+ Q_UNUSED(desc)
+#endif
+}
+
void tst_QWidget::tabOrderNoChange()
{
QWidget w;
@@ -1953,7 +1972,61 @@ void tst_QWidget::tabOrderNoChange()
const auto focusChainForward = getFocusChain(&w, true);
const auto focusChainBackward = getFocusChain(&w, false);
+ dumpFocusChain(&w, true);
QWidget::setTabOrder(tabWidget, tv);
+ dumpFocusChain(&w, true);
+ QCOMPARE(focusChainForward, getFocusChain(&w, true));
+ QCOMPARE(focusChainBackward, getFocusChain(&w, false));
+}
+
+void tst_QWidget::tabOrderNoChange2()
+{
+ QWidget w;
+ auto *verticalLayout = new QVBoxLayout(&w);
+ auto *tabWidget = new QTabWidget(&w);
+ tabWidget->setObjectName("tabWidget");
+ verticalLayout->addWidget(tabWidget);
+
+ auto *tab1 = new QWidget(tabWidget);
+ tab1->setObjectName("tab1");
+ auto *vLay1 = new QVBoxLayout(tab1);
+ auto *le1 = new QLineEdit(tab1);
+ le1->setObjectName("le1");
+ auto *le2 = new QLineEdit(tab1);
+ le2->setObjectName("le2");
+ vLay1->addWidget(le1);
+ vLay1->addWidget(le2);
+ tabWidget->addTab(tab1, QStringLiteral("Tab 1"));
+
+ auto *tab2 = new QWidget(tabWidget);
+ tab2->setObjectName("tab2");
+ auto *vLay2 = new QVBoxLayout(tab2);
+ auto *le3 = new QLineEdit(tab2);
+ le3->setObjectName("le3");
+ auto *le4 = new QLineEdit(tab2);
+ le4->setObjectName("le4");
+ vLay2->addWidget(le3);
+ vLay2->addWidget(le4);
+ tabWidget->addTab(tab2, QStringLiteral("Tab 2"));
+
+ const auto focusChainForward = getFocusChain(&w, true);
+ const auto focusChainBackward = getFocusChain(&w, false);
+ dumpFocusChain(&w, true);
+ dumpFocusChain(&w, false);
+ // this will screw up the focus chain order without visible changes,
+ // so don't call it here for the simplicity of the test
+ //QWidget::setTabOrder(tabWidget, le1);
+
+ QWidget::setTabOrder(le1, le2);
+ dumpFocusChain(&w, true, "QWidget::setTabOrder(le1, le2)");
+ QWidget::setTabOrder(le2, le3);
+ dumpFocusChain(&w, true, "QWidget::setTabOrder(le2, le3)");
+ QWidget::setTabOrder(le3, le4);
+ dumpFocusChain(&w, true, "QWidget::setTabOrder(le3, le4)");
+ QWidget::setTabOrder(le4, tabWidget);
+ dumpFocusChain(&w, true, "QWidget::setTabOrder(le4, tabWidget)");
+ dumpFocusChain(&w, false);
+
QCOMPARE(focusChainForward, getFocusChain(&w, true));
QCOMPARE(focusChainBackward, getFocusChain(&w, false));
}
diff --git a/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp b/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp
index d744cece9c..8b45ac20b7 100644
--- a/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp
+++ b/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp
@@ -735,6 +735,7 @@ void tst_QSplitter::replaceWidget()
// Configure splitter
QWidget *oldWidget = sp.widget(index);
+ QTest::qWait(100); // Make sure we record the right original size (after the window manager adds the frame)
const QRect oldGeom = oldWidget ? oldWidget->geometry() : QRect();
if (oldWidget) {
// Collapse first, then hide, if necessary