diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-10-30 01:00:32 +0100 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-10-30 01:00:33 +0100 |
commit | cd04181b2ba20e98a29a1782b3736539f70f6607 (patch) | |
tree | a5c82740a2145599d3d9a70598180f0cbe046ad9 /src | |
parent | 3ea6a13a01f513ab491f698109fdf189e6264203 (diff) | |
parent | b56e856d218976bf39d981468267337d8d6223f5 (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Change-Id: I7f11733bda960196a96c6452bdabeb7072a8430d
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/kernel/qobject_p.h | 1 | ||||
-rw-r--r-- | src/gui/rhi/qshader.cpp | 23 | ||||
-rw-r--r-- | src/gui/rhi/qshader_p_p.h | 6 | ||||
-rw-r--r-- | src/gui/rhi/qshaderdescription.cpp | 152 | ||||
-rw-r--r-- | src/gui/rhi/qshaderdescription_p.h | 40 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyhttpimpl.cpp | 36 | ||||
-rw-r--r-- | src/network/access/qnetworkreplyhttpimpl_p.h | 7 | ||||
-rw-r--r-- | src/network/access/qnetworkrequest.cpp | 50 | ||||
-rw-r--r-- | src/network/access/qnetworkrequest.h | 6 | ||||
-rw-r--r-- | src/network/kernel/qnetworkproxy_mac.cpp | 7 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm | 68 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoascreen.h | 8 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoascreen.mm | 51 |
13 files changed, 383 insertions, 72 deletions
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 11ebba7787..db62c03b7a 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -362,6 +362,7 @@ public: } public: ExtraData *extraData; // extra data set by the user + QThreadData *getThreadData() const { return threadData; } QThreadData *threadData; // id of the thread that owns the object using ConnectionDataPointer = QExplicitlySharedDataPointer<ConnectionData>; diff --git a/src/gui/rhi/qshader.cpp b/src/gui/rhi/qshader.cpp index c22b029dc8..14d780b4e4 100644 --- a/src/gui/rhi/qshader.cpp +++ b/src/gui/rhi/qshader.cpp @@ -214,9 +214,6 @@ QT_BEGIN_NAMESPACE QShader, it indicates no shader code was found for the requested key. */ -static const int QSB_VERSION = 2; -static const int QSB_VERSION_WITHOUT_BINDINGS = 1; - /*! Constructs a new, empty (and thus invalid) QShader instance. */ @@ -368,9 +365,9 @@ QByteArray QShader::serialized() const if (!buf.open(QIODevice::WriteOnly)) return QByteArray(); - ds << QSB_VERSION; + ds << QShaderPrivate::QSB_VERSION; ds << d->stage; - ds << d->desc.toBinaryJson(); + ds << d->desc.toCbor(); ds << d->shaders.count(); for (auto it = d->shaders.cbegin(), itEnd = d->shaders.cend(); it != itEnd; ++it) { const QShaderKey &k(it.key()); @@ -429,9 +426,12 @@ QShader QShader::fromSerialized(const QByteArray &data) Q_ASSERT(d->ref.loadRelaxed() == 1); // must be detached int intVal; ds >> intVal; - const int qsbVersion = intVal; - if (qsbVersion != QSB_VERSION && qsbVersion != QSB_VERSION_WITHOUT_BINDINGS) { - qWarning("Attempted to deserialize QShader with unknown version %d.", qsbVersion); + d->qsbVersion = intVal; + if (d->qsbVersion != QShaderPrivate::QSB_VERSION + && d->qsbVersion != QShaderPrivate::QSB_VERSION_WITH_BINARY_JSON + && d->qsbVersion != QShaderPrivate::QSB_VERSION_WITHOUT_BINDINGS) + { + qWarning("Attempted to deserialize QShader with unknown version %d.", d->qsbVersion); return QShader(); } @@ -439,7 +439,10 @@ QShader QShader::fromSerialized(const QByteArray &data) d->stage = Stage(intVal); QByteArray descBin; ds >> descBin; - d->desc = QShaderDescription::fromBinaryJson(descBin); + if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITH_BINARY_JSON) + d->desc = QShaderDescription::fromCbor(descBin); + else + d->desc = QShaderDescription::fromBinaryJson(descBin); int count; ds >> count; for (int i = 0; i < count; ++i) { @@ -454,7 +457,7 @@ QShader QShader::fromSerialized(const QByteArray &data) d->shaders[k] = shader; } - if (qsbVersion != QSB_VERSION_WITHOUT_BINDINGS) { + if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITHOUT_BINDINGS) { ds >> count; for (int i = 0; i < count; ++i) { QShaderKey k; diff --git a/src/gui/rhi/qshader_p_p.h b/src/gui/rhi/qshader_p_p.h index 4535e01491..8c89f2b45f 100644 --- a/src/gui/rhi/qshader_p_p.h +++ b/src/gui/rhi/qshader_p_p.h @@ -57,6 +57,10 @@ QT_BEGIN_NAMESPACE struct Q_GUI_EXPORT QShaderPrivate { + static const int QSB_VERSION = 3; + static const int QSB_VERSION_WITH_BINARY_JSON = 2; + static const int QSB_VERSION_WITHOUT_BINDINGS = 1; + QShaderPrivate() : ref(1) { @@ -64,6 +68,7 @@ struct Q_GUI_EXPORT QShaderPrivate QShaderPrivate(const QShaderPrivate *other) : ref(1), + qsbVersion(other->qsbVersion), stage(other->stage), desc(other->desc), shaders(other->shaders), @@ -75,6 +80,7 @@ struct Q_GUI_EXPORT QShaderPrivate static const QShaderPrivate *get(const QShader *s) { return s->d; } QAtomicInt ref; + int qsbVersion = QSB_VERSION; QShader::Stage stage = QShader::VertexStage; QShaderDescription desc; QHash<QShaderKey, QShaderCode> shaders; diff --git a/src/gui/rhi/qshaderdescription.cpp b/src/gui/rhi/qshaderdescription.cpp index 179d5f3a07..d0f73f6aa7 100644 --- a/src/gui/rhi/qshaderdescription.cpp +++ b/src/gui/rhi/qshaderdescription.cpp @@ -38,6 +38,9 @@ #include <QDebug> #include <QJsonObject> #include <QJsonArray> +#include <QCborValue> +#include <QCborMap> +#include <QCborArray> QT_BEGIN_NAMESPACE @@ -335,11 +338,27 @@ bool QShaderDescription::isValid() const /*! \return a serialized binary version of the data. - \sa toJson() + \sa toJson(), toCbor() */ QByteArray QShaderDescription::toBinaryJson() const { +#if QT_CONFIG(binaryjson) return d->makeDoc().toBinaryData(); +#else + qWarning("Cannot generate binary JSON from QShaderDescription due to disabled binaryjson feature"); + return QByteArray(); +#endif +} + +/*! + \return a serialized binary version of the data in CBOR (Concise Binary + Object Representation) format. + + \sa QCborValue, toBinaryJson(), toJson() + */ +QByteArray QShaderDescription::toCbor() const +{ + return QCborValue::fromJsonValue(d->makeDoc().object()).toCbor(); } /*! @@ -347,7 +366,7 @@ QByteArray QShaderDescription::toBinaryJson() const \note There is no deserialization method provided for JSON text. - \sa toBinaryJson() + \sa toBinaryJson(), toCbor() */ QByteArray QShaderDescription::toJson() const { @@ -357,11 +376,38 @@ QByteArray QShaderDescription::toJson() const /*! Deserializes the given binary JSON \a data and returns a new QShaderDescription. + + \sa fromCbor() */ QShaderDescription QShaderDescription::fromBinaryJson(const QByteArray &data) { QShaderDescription desc; +#if QT_CONFIG(binaryjson) QShaderDescriptionPrivate::get(&desc)->loadDoc(QJsonDocument::fromBinaryData(data)); +#else + Q_UNUSED(data); + qWarning("Cannot load QShaderDescription from binary JSON due to disabled binaryjson feature"); +#endif + return desc; +} + +/*! + Deserializes the given CBOR \a data and returns a new QShaderDescription. + + \sa fromBinaryJson() + */ +QShaderDescription QShaderDescription::fromCbor(const QByteArray &data) +{ + QShaderDescription desc; + const QCborValue cbor = QCborValue::fromCbor(data); + if (cbor.isMap()) { + const QJsonDocument doc(cbor.toMap().toJsonObject()); + QShaderDescriptionPrivate::get(&desc)->loadDoc(doc); + } + if (cbor.isArray()) { + const QJsonDocument doc(cbor.toArray().toJsonArray()); + QShaderDescriptionPrivate::get(&desc)->loadDoc(doc); + } return desc; } @@ -1119,4 +1165,106 @@ void QShaderDescriptionPrivate::loadDoc(const QJsonDocument &doc) } } +/*! + Returns \c true if the two QShaderDescription objects \a lhs and \a rhs are + equal. + + \relates QShaderDescription + */ +bool operator==(const QShaderDescription &lhs, const QShaderDescription &rhs) Q_DECL_NOTHROW +{ + if (lhs.d == rhs.d) + return true; + + return lhs.d->inVars == rhs.d->inVars + && lhs.d->outVars == rhs.d->outVars + && lhs.d->uniformBlocks == rhs.d->uniformBlocks + && lhs.d->pushConstantBlocks == rhs.d->pushConstantBlocks + && lhs.d->storageBlocks == rhs.d->storageBlocks + && lhs.d->combinedImageSamplers == rhs.d->combinedImageSamplers + && lhs.d->storageImages == rhs.d->storageImages + && lhs.d->localSize == rhs.d->localSize; +} + +/*! + Returns \c true if the two InOutVariable objects \a lhs and \a rhs are + equal. + + \relates QShaderDescription::InOutVariable + */ +bool operator==(const QShaderDescription::InOutVariable &lhs, const QShaderDescription::InOutVariable &rhs) Q_DECL_NOTHROW +{ + return lhs.name == rhs.name + && lhs.type == rhs.type + && lhs.location == rhs.location + && lhs.binding == rhs.binding + && lhs.descriptorSet == rhs.descriptorSet + && lhs.imageFormat == rhs.imageFormat + && lhs.imageFlags == rhs.imageFlags; +} + +/*! + Returns \c true if the two BlockVariable objects \a lhs and \a rhs are + equal. + + \relates QShaderDescription::BlockVariable + */ +bool operator==(const QShaderDescription::BlockVariable &lhs, const QShaderDescription::BlockVariable &rhs) Q_DECL_NOTHROW +{ + return lhs.name == rhs.name + && lhs.type == rhs.type + && lhs.offset == rhs.offset + && lhs.size == rhs.size + && lhs.arrayDims == rhs.arrayDims + && lhs.arrayStride == rhs.arrayStride + && lhs.matrixStride == rhs.matrixStride + && lhs.matrixIsRowMajor == rhs.matrixIsRowMajor + && lhs.structMembers == rhs.structMembers; +} + +/*! + Returns \c true if the two UniformBlock objects \a lhs and \a rhs are + equal. + + \relates QShaderDescription::UniformBlock + */ +bool operator==(const QShaderDescription::UniformBlock &lhs, const QShaderDescription::UniformBlock &rhs) Q_DECL_NOTHROW +{ + return lhs.blockName == rhs.blockName + && lhs.structName == rhs.structName + && lhs.size == rhs.size + && lhs.binding == rhs.binding + && lhs.descriptorSet == rhs.descriptorSet + && lhs.members == rhs.members; +} + +/*! + Returns \c true if the two PushConstantBlock objects \a lhs and \a rhs are + equal. + + \relates QShaderDescription::PushConstantBlock + */ +bool operator==(const QShaderDescription::PushConstantBlock &lhs, const QShaderDescription::PushConstantBlock &rhs) Q_DECL_NOTHROW +{ + return lhs.name == rhs.name + && lhs.size == rhs.size + && lhs.members == rhs.members; +} + +/*! + Returns \c true if the two StorageBlock objects \a lhs and \a rhs are + equal. + + \relates QShaderDescription::StorageBlock + */ +bool operator==(const QShaderDescription::StorageBlock &lhs, const QShaderDescription::StorageBlock &rhs) Q_DECL_NOTHROW +{ + return lhs.blockName == rhs.blockName + && lhs.instanceName == rhs.instanceName + && lhs.knownSize == rhs.knownSize + && lhs.binding == rhs.binding + && lhs.descriptorSet == rhs.descriptorSet + && lhs.members == rhs.members; +} + QT_END_NAMESPACE diff --git a/src/gui/rhi/qshaderdescription_p.h b/src/gui/rhi/qshaderdescription_p.h index 5a63b998cd..e02a53dcb5 100644 --- a/src/gui/rhi/qshaderdescription_p.h +++ b/src/gui/rhi/qshaderdescription_p.h @@ -69,9 +69,11 @@ public: bool isValid() const; QByteArray toBinaryJson() const; + QByteArray toCbor() const; QByteArray toJson() const; static QShaderDescription fromBinaryJson(const QByteArray &data); + static QShaderDescription fromCbor(const QByteArray &data); enum VariableType { Unknown = 0, @@ -263,6 +265,7 @@ private: #ifndef QT_NO_DEBUG_STREAM friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription &); #endif + friend Q_GUI_EXPORT bool operator==(const QShaderDescription &lhs, const QShaderDescription &rhs) Q_DECL_NOTHROW; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QShaderDescription::ImageFlags) @@ -276,6 +279,43 @@ Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription::PushConstantBlo Q_GUI_EXPORT QDebug operator<<(QDebug, const QShaderDescription::StorageBlock &); #endif +Q_GUI_EXPORT bool operator==(const QShaderDescription &lhs, const QShaderDescription &rhs) Q_DECL_NOTHROW; +Q_GUI_EXPORT bool operator==(const QShaderDescription::InOutVariable &lhs, const QShaderDescription::InOutVariable &rhs) Q_DECL_NOTHROW; +Q_GUI_EXPORT bool operator==(const QShaderDescription::BlockVariable &lhs, const QShaderDescription::BlockVariable &rhs) Q_DECL_NOTHROW; +Q_GUI_EXPORT bool operator==(const QShaderDescription::UniformBlock &lhs, const QShaderDescription::UniformBlock &rhs) Q_DECL_NOTHROW; +Q_GUI_EXPORT bool operator==(const QShaderDescription::PushConstantBlock &lhs, const QShaderDescription::PushConstantBlock &rhs) Q_DECL_NOTHROW; +Q_GUI_EXPORT bool operator==(const QShaderDescription::StorageBlock &lhs, const QShaderDescription::StorageBlock &rhs) Q_DECL_NOTHROW; + +inline bool operator!=(const QShaderDescription &lhs, const QShaderDescription &rhs) Q_DECL_NOTHROW +{ + return !(lhs == rhs); +} + +inline bool operator!=(const QShaderDescription::InOutVariable &lhs, const QShaderDescription::InOutVariable &rhs) Q_DECL_NOTHROW +{ + return !(lhs == rhs); +} + +inline bool operator!=(const QShaderDescription::BlockVariable &lhs, const QShaderDescription::BlockVariable &rhs) Q_DECL_NOTHROW +{ + return !(lhs == rhs); +} + +inline bool operator!=(const QShaderDescription::UniformBlock &lhs, const QShaderDescription::UniformBlock &rhs) Q_DECL_NOTHROW +{ + return !(lhs == rhs); +} + +inline bool operator!=(const QShaderDescription::PushConstantBlock &lhs, const QShaderDescription::PushConstantBlock &rhs) Q_DECL_NOTHROW +{ + return !(lhs == rhs); +} + +inline bool operator!=(const QShaderDescription::StorageBlock &lhs, const QShaderDescription::StorageBlock &rhs) Q_DECL_NOTHROW +{ + return !(lhs == rhs); +} + QT_END_NAMESPACE #endif diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index 0bd7825186..f4b8661fe7 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -461,6 +461,7 @@ QNetworkReplyHttpImplPrivate::QNetworkReplyHttpImplPrivate() , preMigrationDownloaded(-1) , bytesDownloaded(0) , bytesBuffered(0) + , transferTimeout(nullptr) , downloadBufferReadPosition(0) , downloadBufferCurrentSize(0) , downloadZerocopyBuffer(nullptr) @@ -1064,6 +1065,7 @@ void QNetworkReplyHttpImplPrivate::replyDownloadData(QByteArray d) if (!isHttpRedirectResponse()) { buffer.append(d); bytesDownloaded += d.size(); + setupTransferTimeout(); } bytesBuffered += d.size(); @@ -1389,6 +1391,7 @@ void QNetworkReplyHttpImplPrivate::replyDownloadProgressSlot(qint64 bytesReceive return; bytesDownloaded = bytesReceived; + setupTransferTimeout(); downloadBufferCurrentSize = bytesReceived; @@ -1845,7 +1848,6 @@ bool QNetworkReplyHttpImplPrivate::startWaitForSession(QSharedPointer<QNetworkSe void QNetworkReplyHttpImplPrivate::_q_startOperation() { Q_Q(QNetworkReplyHttpImpl); - if (state == Working) // ensure this function is only being called once return; @@ -1885,6 +1887,7 @@ void QNetworkReplyHttpImplPrivate::_q_startOperation() } #endif // QT_NO_BEARERMANAGEMENT + setupTransferTimeout(); if (synchronous) { state = Finished; q_func()->setFinished(true); @@ -2021,6 +2024,31 @@ void QNetworkReplyHttpImplPrivate::_q_bufferOutgoingData() } } +void QNetworkReplyHttpImplPrivate::_q_transferTimedOut() +{ + Q_Q(QNetworkReplyHttpImpl); + q->abort(); +} + +void QNetworkReplyHttpImplPrivate::setupTransferTimeout() +{ + Q_Q(QNetworkReplyHttpImpl); + if (!transferTimeout) { + transferTimeout = new QTimer(q); + QObject::connect(transferTimeout, SIGNAL(timeout()), + q, SLOT(_q_transferTimedOut()), + Qt::QueuedConnection); + } + transferTimeout->stop(); + if (request.transferTimeout()) { + transferTimeout->setSingleShot(true); + transferTimeout->setInterval(request.transferTimeout()); + QMetaObject::invokeMethod(transferTimeout, "start", + Qt::QueuedConnection); + + } +} + #ifndef QT_NO_BEARERMANAGEMENT void QNetworkReplyHttpImplPrivate::_q_networkSessionConnected() { @@ -2103,6 +2131,8 @@ void QNetworkReplyHttpImplPrivate::emitReplyUploadProgress(qint64 bytesSent, qin if (isFinished) return; + setupTransferTimeout(); + if (!emitAllUploadProgressSignals) { //choke signal emissions, except the first and last signals which are unconditional if (uploadProgressSignalChoke.isValid()) { @@ -2114,7 +2144,6 @@ void QNetworkReplyHttpImplPrivate::emitReplyUploadProgress(qint64 bytesSent, qin uploadProgressSignalChoke.start(); } } - emit q->uploadProgress(bytesSent, bytesTotal); } @@ -2147,7 +2176,8 @@ void QNetworkReplyHttpImplPrivate::_q_finished() void QNetworkReplyHttpImplPrivate::finished() { Q_Q(QNetworkReplyHttpImpl); - + if (transferTimeout) + transferTimeout->stop(); if (state == Finished || state == Aborted || state == WaitingForSession) return; diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h index ef69ce0653..dec0c4c589 100644 --- a/src/network/access/qnetworkreplyhttpimpl_p.h +++ b/src/network/access/qnetworkreplyhttpimpl_p.h @@ -59,6 +59,7 @@ #include "QtCore/qdatetime.h" #include "QtCore/qsharedpointer.h" #include "QtCore/qscopedpointer.h" +#include "QtCore/qtimer.h" #include "qatomic.h" #include <QtNetwork/QNetworkCacheMetaData> @@ -100,6 +101,7 @@ public: Q_PRIVATE_SLOT(d_func(), void _q_cacheLoadReadyRead()) Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingData()) Q_PRIVATE_SLOT(d_func(), void _q_bufferOutgoingDataFinished()) + Q_PRIVATE_SLOT(d_func(), void _q_transferTimedOut()) #ifndef QT_NO_BEARERMANAGEMENT Q_PRIVATE_SLOT(d_func(), void _q_networkSessionConnected()) Q_PRIVATE_SLOT(d_func(), void _q_networkSessionFailed()) @@ -181,6 +183,9 @@ public: void _q_cacheSaveDeviceAboutToClose(); + void _q_transferTimedOut(); + void setupTransferTimeout(); + #ifndef QT_NO_BEARERMANAGEMENT void _q_networkSessionConnected(); void _q_networkSessionFailed(); @@ -250,6 +255,8 @@ public: qint64 bytesDownloaded; qint64 bytesBuffered; + QTimer *transferTimeout; + // Only used when the "zero copy" style is used. // Please note that the whole "zero copy" download buffer API is private right now. Do not use it. qint64 downloadBufferReadPosition; diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 1deaa03f71..06ba3a96da 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -407,6 +407,18 @@ QT_BEGIN_NAMESPACE based on some app-specific configuration. */ +/*! + \enum QNetworkRequest::TransferTimeoutConstant + \since 5.15 + + A constant that can be used for enabling transfer + timeouts with a preset value. + + \value TransferTimeoutPreset The transfer timeout in milliseconds. + Used if setTimeout() is called + without an argument. + */ + class QNetworkRequestPrivate: public QSharedData, public QNetworkHeadersPrivate { public: @@ -417,6 +429,7 @@ public: , sslConfiguration(0) #endif , maxRedirectsAllowed(maxRedirectCount) + , transferTimeout(0) { qRegisterMetaType<QNetworkRequest>(); } ~QNetworkRequestPrivate() { @@ -441,6 +454,7 @@ public: #if QT_CONFIG(http) h2Configuration = other.h2Configuration; #endif + transferTimeout = other.transferTimeout; } inline bool operator==(const QNetworkRequestPrivate &other) const @@ -454,6 +468,7 @@ public: #if QT_CONFIG(http) && h2Configuration == other.h2Configuration #endif + && transferTimeout == other.transferTimeout ; // don't compare cookedHeaders } @@ -468,6 +483,7 @@ public: #if QT_CONFIG(http) QHttp2Configuration h2Configuration; #endif + int transferTimeout; }; /*! @@ -891,6 +907,40 @@ void QNetworkRequest::setHttp2Configuration(const QHttp2Configuration &configura { d->h2Configuration = configuration; } + +/*! + \since 5.15 + + Returns the timeout used for transfers, in milliseconds. + + This timeout is zero if setTransferTimeout hasn't been + called, which means that the timeout is not used. + + \sa setTransferTimeout +*/ +int QNetworkRequest::transferTimeout() +{ + return d->transferTimeout; +} + +/*! + \since 5.15 + + Sets \a timeout as the transfer timeout in milliseconds. + + Transfers are aborted if no bytes are transferred before + the timeout expires. Zero means no timer is set. If no + argument is provided, the timeout is + QNetworkRequest::TransferTimeoutPreset. If this function + is not called, the timeout is disabled and has the + value zero. + + \sa transferTimeout +*/ +void QNetworkRequest::setTransferTimeout(int timeout) +{ + d->transferTimeout = timeout; +} #endif // QT_CONFIG(http) || defined(Q_CLANG_QDOC) static QByteArray headerName(QNetworkRequest::KnownHeaders header) diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h index 95b5dc89b5..e9098accd9 100644 --- a/src/network/access/qnetworkrequest.h +++ b/src/network/access/qnetworkrequest.h @@ -126,6 +126,9 @@ public: UserVerifiedRedirectPolicy }; + enum TransferTimeoutConstant { + TransferTimeoutPreset = 30000 + }; QNetworkRequest(); explicit QNetworkRequest(const QUrl &url); @@ -177,6 +180,9 @@ public: #if QT_CONFIG(http) || defined(Q_CLANG_QDOC) QHttp2Configuration http2Configuration() const; void setHttp2Configuration(const QHttp2Configuration &configuration); + + int transferTimeout(); + void setTransferTimeout(int timeout = TransferTimeoutPreset); #endif // QT_CONFIG(http) || defined(Q_CLANG_QDOC) private: QSharedDataPointer<QNetworkRequestPrivate> d; diff --git a/src/network/kernel/qnetworkproxy_mac.cpp b/src/network/kernel/qnetworkproxy_mac.cpp index 92f91956b9..67fda24ea6 100644 --- a/src/network/kernel/qnetworkproxy_mac.cpp +++ b/src/network/kernel/qnetworkproxy_mac.cpp @@ -210,16 +210,14 @@ QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query) QList<QNetworkProxy> result; // obtain a dictionary to the proxy settings: - CFDictionaryRef dict = SCDynamicStoreCopyProxies(NULL); + const QCFType<CFDictionaryRef> dict = SCDynamicStoreCopyProxies(NULL); if (!dict) { qWarning("QNetworkProxyFactory::systemProxyForQuery: SCDynamicStoreCopyProxies returned NULL"); return result; // failed } - if (isHostExcluded(dict, query.peerHostName())) { - CFRelease(dict); + if (isHostExcluded(dict, query.peerHostName())) return result; // no proxy for this host - } // is there a PAC enabled? If so, use it first. CFNumberRef pacEnabled; @@ -329,7 +327,6 @@ QList<QNetworkProxy> macQueryInternal(const QNetworkProxyQuery &query) result << https; } - CFRelease(dict); return result; } diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm index e87fc39c42..b3ce9e45dc 100644 --- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm +++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm @@ -293,46 +293,42 @@ bool QCocoaEventDispatcher::hasPendingEvents() return qGlobalPostedEventsCount() || (qt_is_gui_used && !CFRunLoopIsWaiting(CFRunLoopGetMain())); } -static bool IsMouseOrKeyEvent( NSEvent* event ) +static bool isUserInputEvent(NSEvent* event) { - bool result = false; - - switch( [event type] ) - { - case NSEventTypeLeftMouseDown: - case NSEventTypeLeftMouseUp: - case NSEventTypeRightMouseDown: - case NSEventTypeRightMouseUp: - case NSEventTypeMouseMoved: // ?? - case NSEventTypeLeftMouseDragged: - case NSEventTypeRightMouseDragged: - case NSEventTypeMouseEntered: - case NSEventTypeMouseExited: - case NSEventTypeKeyDown: - case NSEventTypeKeyUp: - case NSEventTypeFlagsChanged: // key modifiers changed? - case NSEventTypeCursorUpdate: // ?? - case NSEventTypeScrollWheel: - case NSEventTypeTabletPoint: - case NSEventTypeTabletProximity: - case NSEventTypeOtherMouseDown: - case NSEventTypeOtherMouseUp: - case NSEventTypeOtherMouseDragged: + switch ([event type]) { + case NSEventTypeLeftMouseDown: + case NSEventTypeLeftMouseUp: + case NSEventTypeRightMouseDown: + case NSEventTypeRightMouseUp: + case NSEventTypeMouseMoved: // ?? + case NSEventTypeLeftMouseDragged: + case NSEventTypeRightMouseDragged: + case NSEventTypeMouseEntered: + case NSEventTypeMouseExited: + case NSEventTypeKeyDown: + case NSEventTypeKeyUp: + case NSEventTypeFlagsChanged: // key modifiers changed? + case NSEventTypeCursorUpdate: // ?? + case NSEventTypeScrollWheel: + case NSEventTypeTabletPoint: + case NSEventTypeTabletProximity: + case NSEventTypeOtherMouseDown: + case NSEventTypeOtherMouseUp: + case NSEventTypeOtherMouseDragged: #ifndef QT_NO_GESTURES - case NSEventTypeGesture: // touch events - case NSEventTypeMagnify: - case NSEventTypeSwipe: - case NSEventTypeRotate: - case NSEventTypeBeginGesture: - case NSEventTypeEndGesture: + case NSEventTypeGesture: // touch events + case NSEventTypeMagnify: + case NSEventTypeSwipe: + case NSEventTypeRotate: + case NSEventTypeBeginGesture: + case NSEventTypeEndGesture: #endif // QT_NO_GESTURES - result = true; + return true; break; - - default: + default: break; } - return result; + return false; } static inline void qt_mac_waitForMoreEvents(NSString *runLoopMode = NSDefaultRunLoopMode) @@ -465,7 +461,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) dequeue: YES]; if (event) { - if (IsMouseOrKeyEvent(event)) { + if (isUserInputEvent(event)) { [event retain]; d->queuedUserInputEvents.append(event); continue; @@ -485,7 +481,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) if (event) { if (flags & QEventLoop::ExcludeUserInputEvents) { - if (IsMouseOrKeyEvent(event)) { + if (isUserInputEvent(event)) { [event retain]; d->queuedUserInputEvents.append(event); continue; diff --git a/src/plugins/platforms/cocoa/qcocoascreen.h b/src/plugins/platforms/cocoa/qcocoascreen.h index 60243b79be..7ec9a2b5af 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.h +++ b/src/plugins/platforms/cocoa/qcocoascreen.h @@ -99,18 +99,18 @@ private: static void add(CGDirectDisplayID displayId); void remove(); - CGDirectDisplayID m_displayId = 0; + CGDirectDisplayID m_displayId = kCGNullDirectDisplay; QRect m_geometry; QRect m_availableGeometry; QDpi m_logicalDpi; - qreal m_refreshRate; - int m_depth; + qreal m_refreshRate = 0; + int m_depth = 0; QString m_name; QImage::Format m_format; QSizeF m_physicalSize; QCocoaCursor *m_cursor; - qreal m_devicePixelRatio; + qreal m_devicePixelRatio = 0; CVDisplayLinkRef m_displayLink = nullptr; dispatch_source_t m_displayLinkSource = nullptr; diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index 392099d083..40273bac84 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -54,6 +54,23 @@ QT_BEGIN_NAMESPACE +namespace CoreGraphics { + Q_NAMESPACE + enum DisplayChange { + Moved = kCGDisplayMovedFlag, + SetMain = kCGDisplaySetMainFlag, + SetMode = kCGDisplaySetModeFlag, + Added = kCGDisplayAddFlag, + Removed = kCGDisplayRemoveFlag, + Enabled = kCGDisplayEnabledFlag, + Disabled = kCGDisplayDisabledFlag, + Mirrored = kCGDisplayMirrorFlag, + UnMirrored = kCGDisplayUnMirrorFlag, + DesktopShapeChanged = kCGDisplayDesktopShapeChangedFlag + }; + Q_ENUM_NS(DisplayChange) +} + void QCocoaScreen::initializeScreens() { uint32_t displayCount = 0; @@ -73,6 +90,10 @@ void QCocoaScreen::initializeScreens() Q_UNUSED(userInfo); + qCDebug(lcQpaScreen).verbosity(0).nospace() << "Display reconfiguration" + << " (" << QFlags<CoreGraphics::DisplayChange>(flags) << ")" + << " for displayId=" << displayId; + QCocoaScreen *cocoaScreen = QCocoaScreen::get(displayId); if ((flags & kCGDisplayAddFlag) || !cocoaScreen) { @@ -93,22 +114,24 @@ void QCocoaScreen::initializeScreens() mainDisplay->updateProperties(); qCInfo(lcQpaScreen) << "Primary screen changed to" << mainDisplay; QWindowSystemInterface::handlePrimaryScreenChanged(mainDisplay); + if (cocoaScreen == mainDisplay) + return; // Already reconfigured } - if (cocoaScreen == mainDisplay) - return; // Already reconfigured - cocoaScreen->updateProperties(); - qCInfo(lcQpaScreen) << "Reconfigured" << cocoaScreen; + qCInfo(lcQpaScreen).nospace() << "Reconfigured " << + (primaryScreen() == cocoaScreen ? "primary " : "") + << cocoaScreen; } }, nullptr); } void QCocoaScreen::add(CGDirectDisplayID displayId) { + const bool isPrimary = CGDisplayIsMain(displayId); QCocoaScreen *cocoaScreen = new QCocoaScreen(displayId); - qCInfo(lcQpaScreen) << "Adding" << cocoaScreen; - QWindowSystemInterface::handleScreenAdded(cocoaScreen, CGDisplayIsMain(displayId)); + qCInfo(lcQpaScreen).nospace() << "Adding " << (isPrimary ? "new primary " : "") << cocoaScreen; + QWindowSystemInterface::handleScreenAdded(cocoaScreen, isPrimary); } QCocoaScreen::QCocoaScreen(CGDirectDisplayID displayId) @@ -127,7 +150,7 @@ void QCocoaScreen::cleanupScreens() void QCocoaScreen::remove() { - m_displayId = 0; // Prevent stale references during removal + m_displayId = kCGNullDirectDisplay; // Prevent stale references during removal // This may result in the application responding to QGuiApplication::screenRemoved // by moving the window to another screen, either by setGeometry, or by setScreen. @@ -140,6 +163,7 @@ void QCocoaScreen::remove() // QCocoaWindow::windowDidChangeScreen. At that point the window will appear to have // already changed its screen, but that's only true if comparing the Qt screens, // not when comparing the NSScreens. + qCInfo(lcQpaScreen).nospace() << "Removing " << (primaryScreen() == this ? "current primary " : "") << this; QWindowSystemInterface::handleScreenRemoved(this); } @@ -552,10 +576,10 @@ QPixmap QCocoaScreen::grabWindow(WId view, int x, int y, int width, int height) */ QCocoaScreen *QCocoaScreen::primaryScreen() { - auto screen = static_cast<QCocoaScreen *>(QGuiApplication::primaryScreen()->handle()); - Q_ASSERT_X(screen == get(CGMainDisplayID()), "QCocoaScreen", - "The application's primary screen should always be in sync with the main display"); - return screen; + // Note: The primary screen that Qt knows about may not match the current CGMainDisplayID() + // if macOS has not yet been able to inform us that the main display has changed, but we + // will update the primary screen accordingly once the reconfiguration callback comes in. + return static_cast<QCocoaScreen *>(QGuiApplication::primaryScreen()->handle()); } QList<QPlatformScreen*> QCocoaScreen::virtualSiblings() const @@ -597,7 +621,7 @@ NSScreen *QCocoaScreen::nativeScreen() const QCFType<CFUUIDRef> uuid = CGDisplayCreateUUIDFromDisplayID(m_displayId); for (NSScreen *screen in [NSScreen screens]) { - if (CGDisplayCreateUUIDFromDisplayID(screen.qt_displayId) == uuid) + if (QCFType<CFUUIDRef>(CGDisplayCreateUUIDFromDisplayID(screen.qt_displayId)) == uuid) return screen; } @@ -639,6 +663,7 @@ QDebug operator<<(QDebug debug, const QCocoaScreen *screen) debug << ", geometry=" << screen->geometry(); debug << ", dpr=" << screen->devicePixelRatio(); debug << ", name=" << screen->name(); + debug << ", displayId=" << screen->m_displayId; debug << ", native=" << screen->nativeScreen(); } debug << ')'; @@ -646,6 +671,8 @@ QDebug operator<<(QDebug debug, const QCocoaScreen *screen) } #endif // !QT_NO_DEBUG_STREAM +#include "qcocoascreen.moc" + QT_END_NAMESPACE @implementation NSScreen (QtExtras) |