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
This commit is contained in:
commit
aedc59b1c3
@ -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" },
|
||||
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)))
|
||||
|
@ -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:
|
||||
|
3
src/dbus/doc/snippets/cmake/examples.cmake
Normal file
3
src/dbus/doc/snippets/cmake/examples.cmake
Normal file
@ -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]
|
224
src/dbus/doc/src/qtdbus-cmake.qdoc
Normal file
224
src/dbus/doc/src/qtdbus-cmake.qdoc
Normal file
@ -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
|
||||
*/
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
#endif // QSSLSOCKET_DEBUG
|
||||
#endif // !QT_CONFIG(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;
|
||||
}
|
||||
|
||||
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 ¤tError : lastErrors) {
|
||||
for (const auto ¤tError : 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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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))
|
||||
|
@ -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) {
|
||||
|
@ -515,6 +515,8 @@ public:
|
||||
bool tearoffHighlighted : 1;
|
||||
//menu fading/scrolling effects
|
||||
bool doChildEffects : 1;
|
||||
|
||||
int popupScreen = -1;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -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();
|
||||
|
@ -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()
|
||||
|
@ -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-----
|
||||
|
@ -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
|
||||
|
@ -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-----
|
||||
|
@ -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");
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user