diff options
author | Liang Qi <liang.qi@qt.io> | 2019-07-01 10:21:37 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2019-07-01 19:20:20 +0200 |
commit | 57fccd6f2156e097fb902789a61731905487c543 (patch) | |
tree | d0114319e7016538d0ca4ffca2e77beb312b38e5 /src | |
parent | 8f4baa3a223ad6f12101d5c4c10756a98d340ae6 (diff) | |
parent | d25c3227299a6a281db37e68e45f0b02db3f5297 (diff) |
Merge "Merge remote-tracking branch 'origin/5.13' into dev"
Diffstat (limited to 'src')
24 files changed, 237 insertions, 80 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp index dcfd06484d..e8f13b388f 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp @@ -504,6 +504,10 @@ EGLint SwapChain11::resize(const gl::Context *context, ASSERT(SUCCEEDED(result)); if (SUCCEEDED(result)) { +#ifndef ANGLE_ENABLE_WINDOWS_STORE + if (mNativeWindow->getNativeWindow()) + InvalidateRect(mNativeWindow->getNativeWindow(), nullptr, FALSE); +#endif const auto &format = d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps()); mBackBufferTexture.set(backbufferTexture, format); diff --git a/src/android/templates/build.gradle b/src/android/templates/build.gradle index 5754c82708..8d4aa63153 100644 --- a/src/android/templates/build.gradle +++ b/src/android/templates/build.gradle @@ -36,7 +36,7 @@ android { compileSdkVersion androidCompileSdkVersion.toInteger() - buildToolsVersion androidBuildToolsVersion + buildToolsVersion '28.0.3' sourceSets { main { diff --git a/src/angle/patches/0015-ANGLE-Invalidate-client-window-area-when-resizing-sw.patch b/src/angle/patches/0015-ANGLE-Invalidate-client-window-area-when-resizing-sw.patch new file mode 100644 index 0000000000..9380437761 --- /dev/null +++ b/src/angle/patches/0015-ANGLE-Invalidate-client-window-area-when-resizing-sw.patch @@ -0,0 +1,37 @@ +From 7d300c6e7d05f4e31c966f1298d11da3eae9d679 Mon Sep 17 00:00:00 2001 +From: Val Doroshchuk <valentyn.doroshchuk@qt.io> +Date: Fri, 21 Jun 2019 11:24:06 +0200 +Subject: [PATCH] ANGLE: Invalidate client window area when resizing swap chain + +Inspired by: +https://codereview.appspot.com/6812076/ +Resizing a window larger results in the newly exposed region being invalidated +but the old region is treated as valid. +This can result in the old region no longer updating. +Was added to D3D9. + +Improving a fix from Filippo Cucchetto: +https://codereview.qt-project.org/c/qt/qtbase/+/195336 +and pushing to D3D11. + +ifndef protects against compilation error for WinRT. +Invalidate() should be used only for desktop apps. + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +index dcfd06484d..e8f13b388f 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp +@@ -504,6 +504,10 @@ EGLint SwapChain11::resize(const gl::Context *context, + ASSERT(SUCCEEDED(result)); + if (SUCCEEDED(result)) + { ++#ifndef ANGLE_ENABLE_WINDOWS_STORE ++ if (mNativeWindow->getNativeWindow()) ++ InvalidateRect(mNativeWindow->getNativeWindow(), nullptr, FALSE); ++#endif + const auto &format = + d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps()); + mBackBufferTexture.set(backbufferTexture, format); +-- +2.14.2.windows.1 + diff --git a/src/corelib/itemmodels/qtransposeproxymodel.cpp b/src/corelib/itemmodels/qtransposeproxymodel.cpp index d4f379bc64..4853f90632 100644 --- a/src/corelib/itemmodels/qtransposeproxymodel.cpp +++ b/src/corelib/itemmodels/qtransposeproxymodel.cpp @@ -445,3 +445,5 @@ void QTransposeProxyModel::sort(int column, Qt::SortOrder order) } QT_END_NAMESPACE + +#include "moc_qtransposeproxymodel.cpp" diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index dc0ab9f08a..637ef84d21 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -948,11 +948,8 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context, end: if (!tn) return QString(); - QString str = QString((const QChar *)tn, tn_length/2); - if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) { - QChar *data = str.data(); - qbswap<sizeof(QChar)>(data, str.length(), data); - } + QString str(tn_length / 2, Qt::Uninitialized); + qFromBigEndian<ushort>(tn, str.length(), str.data()); return str; } diff --git a/src/corelib/serialization/qcborstream.h b/src/corelib/serialization/qcborstream.h index 3b13a309ab..7a451e63ac 100644 --- a/src/corelib/serialization/qcborstream.h +++ b/src/corelib/serialization/qcborstream.h @@ -242,8 +242,8 @@ private: template <typename FP> FP _toFloatingPoint() const noexcept { - using UInt = typename QIntegerForSizeof<FP>::Unsigned; - UInt u = UInt(value64); + using UIntFP = typename QIntegerForSizeof<FP>::Unsigned; + UIntFP u = UIntFP(value64); FP f; memcpy(static_cast<void *>(&f), &u, sizeof(f)); return f; diff --git a/src/corelib/serialization/qjsonwriter.cpp b/src/corelib/serialization/qjsonwriter.cpp index 5b246837d2..012d3bea86 100644 --- a/src/corelib/serialization/qjsonwriter.cpp +++ b/src/corelib/serialization/qjsonwriter.cpp @@ -43,6 +43,7 @@ #include "qjsonwriter_p.h" #include "qjson_p.h" #include "private/qutfcodec_p.h" +#include <private/qnumeric_p.h> QT_BEGIN_NAMESPACE @@ -135,8 +136,9 @@ static void valueToJson(const QJsonPrivate::Base *b, const QJsonPrivate::Value & case QJsonValue::Double: { const double d = v.toDouble(b); if (qIsFinite(d)) { // +2 to format to ensure the expected precision - const double abs = std::abs(d); - json += QByteArray::number(d, abs == static_cast<quint64>(abs) ? 'f' : 'g', QLocale::FloatingPointShortest); + quint64 absInt; + json += QByteArray::number(d, convertDoubleTo(std::abs(d), &absInt) ? 'f' : 'g', + QLocale::FloatingPointShortest); } else { json += "null"; // +INF || -INF || NaN (see RFC4627#section2.4) } diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index c25d39461f..ecbb4743af 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -943,6 +943,23 @@ QByteArray qUncompress(const uchar* data, int nbytes) and QByteArray() compares equal to QByteArray(""). We recommend that you always use isEmpty() and avoid isNull(). + \section1 Maximum size and out-of-memory conditions + + The current version of QByteArray is limited to just under 2 GB (2^31 + bytes) in size. The exact value is architecture-dependent, since it depends + on the overhead required for managing the data block, but is no more than + 32 bytes. Raw data blocks are also limited by the use of \c int type in the + current version to 2 GB minus 1 byte. + + In case memory allocation fails, QByteArray will throw a \c std::bad_alloc + exception. Out of memory conditions in the Qt containers are the only case + where Qt will throw exceptions. + + Note that the operating system may impose further limits on applications + holding a lot of allocated memory, especially large, contiguous blocks. + Such considerations, the configuration of such behavior or any mitigation + are outside the scope of the QByteArray API. + \section1 Notes on Locale \section2 Number-String Conversions diff --git a/src/corelib/tools/qiterator.h b/src/corelib/tools/qiterator.h index 82212c3eb5..449d1049a0 100644 --- a/src/corelib/tools/qiterator.h +++ b/src/corelib/tools/qiterator.h @@ -115,11 +115,11 @@ template <class Key, class T> \ class Q##C##Iterator \ { \ typedef typename Q##C<Key,T>::const_iterator const_iterator; \ - typedef const_iterator Item; \ Q##C<Key,T> c; \ const_iterator i, n; \ inline bool item_exists() const { return n != c.constEnd(); } \ public: \ + typedef const_iterator Item; \ inline Q##C##Iterator(const Q##C<Key,T> &container) \ : c(container), i(c.constBegin()), n(c.constEnd()) {} \ inline Q##C##Iterator &operator=(const Q##C<Key,T> &container) \ @@ -148,11 +148,11 @@ class QMutable##C##Iterator \ { \ typedef typename Q##C<Key,T>::iterator iterator; \ typedef typename Q##C<Key,T>::const_iterator const_iterator; \ - typedef iterator Item; \ Q##C<Key,T> *c; \ iterator i, n; \ inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \ public: \ + typedef iterator Item; \ inline QMutable##C##Iterator(Q##C<Key,T> &container) \ : c(&container) \ { i = c->begin(); n = c->end(); } \ diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 319f82af53..47db97cdfc 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1739,6 +1739,24 @@ const QString::Null QString::null = { }; and the \c{'+'} will automatically be performed as the \c{QStringBuilder} \c{'%'} everywhere. + \section1 Maximum size and out-of-memory conditions + + The current version of QString is limited to just under 2 GB (2^31 bytes) + in size. The exact value is architecture-dependent, since it depends on the + overhead required for managing the data block, but is no more than 32 + bytes. Raw data blocks are also limited by the use of \c int type in the + current version to 2 GB minus 1 byte. Since QString uses two bytes per + character, that translates to just under 2^30 characters in one QString. + + In case memory allocation fails, QString will throw a \c std::bad_alloc + exception. Out of memory conditions in the Qt containers are the only case + where Qt will throw exceptions. + + Note that the operating system may impose further limits on applications + holding a lot of allocated memory, especially large, contiguous blocks. + Such considerations, the configuration of such behavior or any mitigation + are outside the scope of the Qt API. + \sa fromRawData(), QChar, QLatin1String, QByteArray, QStringRef */ diff --git a/src/corelib/tools/qvector.qdoc b/src/corelib/tools/qvector.qdoc index 4c442511ea..8765b7fbd6 100644 --- a/src/corelib/tools/qvector.qdoc +++ b/src/corelib/tools/qvector.qdoc @@ -173,6 +173,24 @@ For a detailed discussion comparing Qt containers with each other and with STL containers, see \l {Understand the Qt Containers}. + \section1 Maximum size and out-of-memory conditions + + The current version of QVector is limited to just under 2 GB (2^31 bytes) + in size. The exact value is architecture-dependent, since it depends on the + overhead required for managing the data block, but is no more than 32 + bytes. The number of elements that can be stored in a QVector is that size + divided by the size of each element. + + In case memory allocation fails, QVector will use the \l Q_CHECK_PTR macro, + which will throw a \c std::bad_alloc exception if the application is being + compiled with exception support. If exceptions are disabled, then running + out of memory is undefined behavior. + + Note that the operating system may impose further limits on applications + holding a lot of allocated memory, especially large, contiguous blocks. + Such considerations, the configuration of such behavior or any mitigation + are outside the scope of the Qt API. + \sa QVectorIterator, QMutableVectorIterator, QList, QLinkedList */ diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 39d0807606..864a944fcb 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -417,7 +417,7 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal } QSize outSize(width,height); if (!scaledSize.isEmpty() && quint32(scaledSize.width()) <= width && - quint32(scaledSize.height()) <= height && interlace_method == PNG_INTERLACE_NONE) { + quint32(scaledSize.height()) <= height && scaledSize != outSize && interlace_method == PNG_INTERLACE_NONE) { // Do inline downscaling outSize = scaledSize; if (doScaledRead) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 7799be77d2..b8bfad4f16 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -3260,9 +3260,12 @@ void QGuiApplication::setPalette(const QPalette &pal) QGuiApplicationPrivate::app_pal = new QPalette(pal); else *QGuiApplicationPrivate::app_pal = pal; + applicationResourceFlags |= ApplicationPaletteExplicitlySet; QCoreApplication::setAttribute(Qt::AA_SetPalette); - emit qGuiApp->paletteChanged(*QGuiApplicationPrivate::app_pal); + + if (qGuiApp) + emit qGuiApp->paletteChanged(*QGuiApplicationPrivate::app_pal); } void QGuiApplicationPrivate::applyWindowGeometrySpecificationTo(QWindow *window) diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp index 93fcb1a216..0fea416404 100644 --- a/src/gui/kernel/qhighdpiscaling.cpp +++ b/src/gui/kernel/qhighdpiscaling.cpp @@ -452,52 +452,30 @@ QDpi QHighDpiScaling::logicalDpi() return m_logicalDpi; } -qreal QHighDpiScaling::factor(const QScreen *screen) +QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QPlatformScreen *platformScreen, QPoint *nativePosition) { - // Fast path for when scaling in Qt is not used at all. if (!m_active) - return qreal(1.0); - - // The effective factor for a given screen is the product of the - // screen and global sub-factors - qreal factor = m_factor; - if (screen) - factor *= screenSubfactor(screen->handle()); - return factor; + return { qreal(1), QPoint() }; + const QPlatformScreen *actualScreen = nativePosition ? + platformScreen->screenForPosition(*nativePosition) : platformScreen; + return { m_factor * screenSubfactor(actualScreen), actualScreen->geometry().topLeft() }; } -qreal QHighDpiScaling::factor(const QPlatformScreen *platformScreen) +QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QScreen *screen, QPoint *nativePosition) { if (!m_active) - return qreal(1.0); - - return m_factor * screenSubfactor(platformScreen); + return { qreal(1), QPoint() }; + if (!screen) + return { m_factor, QPoint() }; // the global factor + return scaleAndOrigin(screen->handle(), nativePosition); } -qreal QHighDpiScaling::factor(const QWindow *window) +QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QWindow *window, QPoint *nativePosition) { if (!m_active) - return qreal(1.0); - - return factor(window ? window->screen() : QGuiApplication::primaryScreen()); -} - -QPoint QHighDpiScaling::origin(const QScreen *screen) -{ - return screen->geometry().topLeft(); -} - -QPoint QHighDpiScaling::origin(const QPlatformScreen *platformScreen) -{ - return platformScreen->geometry().topLeft(); -} - -QPoint QHighDpiScaling::origin(const QWindow *window) -{ - if (window && window->isTopLevel() && window->screen()) - return window->screen()->geometry().topLeft(); - - return QPoint(0, 0); + return { qreal(1), QPoint() }; + QScreen *screen = window ? window->screen() : QGuiApplication::primaryScreen(); + return scaleAndOrigin(screen, nativePosition); } #endif //QT_NO_HIGHDPISCALING diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h index 6e89f85746..50221926c6 100644 --- a/src/gui/kernel/qhighdpiscaling_p.h +++ b/src/gui/kernel/qhighdpiscaling_p.h @@ -78,14 +78,23 @@ public: static void setScreenFactor(QScreen *window, qreal factor); static bool isActive() { return m_active; } - static qreal factor(const QWindow *window); - static qreal factor(const QScreen *screen); - static qreal factor(const QPlatformScreen *platformScreen); - static QPoint origin(const QScreen *screen); - static QPoint origin(const QPlatformScreen *platformScreen); - static QPoint origin(const QWindow *window); - static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen); + + struct ScaleAndOrigin + { + qreal factor; + QPoint origin; + }; + static ScaleAndOrigin scaleAndOrigin(const QPlatformScreen *platformScreen, QPoint *nativePosition = nullptr); + static ScaleAndOrigin scaleAndOrigin(const QScreen *screen, QPoint *nativePosition = nullptr); + static ScaleAndOrigin scaleAndOrigin(const QWindow *platformScreen, QPoint *nativePosition = nullptr); + + template<typename C> + static qreal factor(C *context, QPoint *nativePosition = nullptr) { + return scaleAndOrigin(context, nativePosition).factor; + } + static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen); + static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen); static QPoint mapPositionToGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window); static QPoint mapPositionFromGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window); static QDpi logicalDpi(); @@ -166,16 +175,26 @@ inline QRegion scale(const QRegion ®ion, qreal scaleFactor, QPoint origin = Q return scaled; } +template <typename T> +inline QPoint position(T) { return QPoint(); } +inline QPoint position(QPoint point) { return point; } +inline QPoint position(QPointF point) { return point.toPoint(); } +inline QPoint position(QRect rect) { return rect.center(); } +inline QPoint position(QRectF rect) { return rect.center().toPoint(); } + template <typename T, typename C> T fromNativePixels(const T &value, const C *context) { - return scale(value, qreal(1) / QHighDpiScaling::factor(context), QHighDpiScaling::origin(context)); + QPoint nativePosition = position(value); + QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context, &nativePosition); + return scale(value, qreal(1) / so.factor, so.origin); } template <typename T, typename C> T toNativePixels(const T &value, const C *context) { - return scale(value, QHighDpiScaling::factor(context), QHighDpiScaling::origin(context)); + QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context); + return scale(value, so.factor, so.origin); } template <typename T, typename C> diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp index bba2a863a9..d3070a3d1a 100644 --- a/src/gui/kernel/qsimpledrag.cpp +++ b/src/gui/kernel/qsimpledrag.cpp @@ -309,11 +309,15 @@ void QBasicDrag::updateCursor(Qt::DropAction action) m_dndHasSetOverrideCursor = true; } else { QCursor *cursor = QGuiApplication::overrideCursor(); - if (!pixmap.isNull()) { - if (cursor->pixmap().cacheKey() != pixmap.cacheKey()) - QGuiApplication::changeOverrideCursor(QCursor(pixmap)); - } else if (cursorShape != cursor->shape()) { - QGuiApplication::changeOverrideCursor(QCursor(cursorShape)); + if (!cursor) { + QGuiApplication::changeOverrideCursor(pixmap.isNull() ? QCursor(cursorShape) : QCursor(pixmap)); + } else { + if (!pixmap.isNull()) { + if (cursor->pixmap().cacheKey() != pixmap.cacheKey()) + QGuiApplication::changeOverrideCursor(QCursor(pixmap)); + } else if (cursorShape != cursor->shape()) { + QGuiApplication::changeOverrideCursor(QCursor(cursorShape)); + } } } #endif diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 2e38ac2dcf..1f1de478ea 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -1579,19 +1579,21 @@ void QHttpNetworkConnectionPrivate::emitProxyAuthenticationRequired(const QHttpN // dialog is displaying pauseConnection(); QHttpNetworkReply *reply; -#ifndef QT_NO_SSL - if (connectionType == QHttpNetworkConnection::ConnectionTypeSPDY) { + if (connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2 + || connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2Direct +#if QT_CONFIG(ssl) + || connectionType == QHttpNetworkConnection::ConnectionTypeSPDY +#endif + ) { + // we choose the reply to emit the proxyAuth signal from somewhat arbitrarily, // but that does not matter because the signal will ultimately be emitted // by the QNetworkAccessManager. Q_ASSERT(chan->spdyRequestsToSend.count() > 0); reply = chan->spdyRequestsToSend.cbegin().value().second; } else { // HTTP -#endif // QT_NO_SSL reply = chan->reply; -#ifndef QT_NO_SSL } -#endif // QT_NO_SSL Q_ASSERT(reply); emit reply->proxyAuthenticationRequired(proxy, auth); diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 9309d718e4..3c9d53c5b5 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -209,6 +209,9 @@ void QHttpNetworkConnectionChannel::init() void QHttpNetworkConnectionChannel::close() { + if (state == QHttpNetworkConnectionChannel::ClosingState) + return; + if (!socket) state = QHttpNetworkConnectionChannel::IdleState; else if (socket->state() == QAbstractSocket::UnconnectedState) @@ -1125,11 +1128,13 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket void QHttpNetworkConnectionChannel::_q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator* auth) { if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2 + || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2Direct #ifndef QT_NO_SSL || connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY #endif ) { - connection->d_func()->emitProxyAuthenticationRequired(this, proxy, auth); + if (spdyRequestsToSend.count() > 0) + connection->d_func()->emitProxyAuthenticationRequired(this, proxy, auth); } else { // HTTP // Need to dequeue the request before we can emit the error. if (!reply) diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp index 47b500227f..c8a990aa01 100644 --- a/src/network/socket/qsocks5socketengine.cpp +++ b/src/network/socket/qsocks5socketengine.cpp @@ -1611,8 +1611,10 @@ qint64 QSocks5SocketEngine::readDatagram(char *data, qint64 maxlen, QIpPacketHea QSocks5RevivedDatagram datagram = d->udpData->pendingDatagrams.dequeue(); int copyLen = qMin<int>(maxlen, datagram.data.size()); memcpy(data, datagram.data.constData(), copyLen); - header->senderAddress = datagram.address; - header->senderPort = datagram.port; + if (header) { + header->senderAddress = datagram.address; + header->senderPort = datagram.port; + } return copyLen; #else Q_UNUSED(data) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index d6376b5716..d4bad1b1a5 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -1573,7 +1573,6 @@ bool QSslSocketBackendPrivate::checkOcspStatus() // verify the responder's chain (see their commit 4ba9a4265bd). // Working this around - is too much fuss for ancient versions we // are dropping quite soon anyway. - const unsigned long verificationFlags = 0; const int success = q_OCSP_basic_verify(basicResponse, peerChain, store, verificationFlags); if (success <= 0) diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index fa07af8c46..5614d3b04f 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -558,6 +558,7 @@ static inline int getBlockPosition(const QSharedPointer<QInputMethodQueryEvent> void QAndroidInputContext::reset() { + focusObjectStopComposing(); clear(); m_batchEditNestingLevel = 0; m_handleMode = Hidden; @@ -792,7 +793,25 @@ void QAndroidInputContext::touchDown(int x, int y) m_handleMode = ShowCursor; // The VK will appear in a moment, stop the timer m_hideCursorHandleTimer.stop(); - focusObjectStopComposing(); + + if (focusObjectIsComposing()) { + const double pixelDensity = + QGuiApplication::focusWindow() + ? QHighDpiScaling::factor(QGuiApplication::focusWindow()) + : QHighDpiScaling::factor(QtAndroid::androidPlatformIntegration()->screen()); + + const QPointF touchPointLocal = + QGuiApplication::inputMethod()->inputItemTransform().inverted().map( + QPointF(x / pixelDensity, y / pixelDensity)); + + const int curBlockPos = getBlockPosition( + focusObjectInputMethodQuery(Qt::ImCursorPosition | Qt::ImAbsolutePosition)); + const int touchPosition = curBlockPos + + QInputMethod::queryFocusObject(Qt::ImCursorPosition, touchPointLocal).toInt(); + if (touchPosition != m_composingCursor) + focusObjectStopComposing(); + } + updateSelectionHandles(); } } @@ -1200,13 +1219,18 @@ jint QAndroidInputContext::getCursorCapsMode(jint /*reqModes*/) const uint qtInputMethodHints = query->value(Qt::ImHints).toUInt(); const int localPos = query->value(Qt::ImCursorPosition).toInt(); - bool atWordBoundary = (localPos == 0); + bool atWordBoundary = + localPos == 0 + && (!focusObjectIsComposing() || m_composingCursor == m_composingTextStart); + if (!atWordBoundary) { QString surroundingText = query->value(Qt::ImSurroundingText).toString(); surroundingText.truncate(localPos); + if (focusObjectIsComposing()) + surroundingText += m_composingText.leftRef(m_composingCursor - m_composingTextStart); // Add a character to see if it is at the end of the sentence or not QTextBoundaryFinder finder(QTextBoundaryFinder::Sentence, surroundingText + QLatin1Char('A')); - finder.setPosition(localPos); + finder.setPosition(surroundingText.length()); if (finder.isAtBoundary()) atWordBoundary = finder.isAtBoundary(); } diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp index a78a62337f..7fc68c3d7c 100644 --- a/src/plugins/platforms/android/qandroidplatformtheme.cpp +++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp @@ -489,6 +489,8 @@ QVariant QAndroidPlatformTheme::themeHint(ThemeHint hint) const Q_FALLTHROUGH(); } + case DialogButtonBoxLayout: + return QVariant(QPlatformDialogHelper::AndroidLayout); default: return QPlatformTheme::themeHint(hint); } diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 300082d694..08e7447a75 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -215,6 +215,25 @@ QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList) connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &QCocoaIntegration::focusWindowChanged); + + static auto splashScreenHider = QMacKeyValueObserver(NSApp, @"modalWindow", []{ + const QWindowList allWindows = QGuiApplication::topLevelWindows(); + for (QWindow *window : allWindows) { + if ((window->flags() & Qt::SplashScreen) == Qt::SplashScreen) { + QCocoaWindow *platformWindow = static_cast<QCocoaWindow*>(window->handle()); + NSWindow *splashWindow = platformWindow->view().window; + if (!splashWindow) + continue; + if (NSApp.modalWindow) { + NSInteger originalLevel = splashWindow.level; + splashWindow.level = NSNormalWindowLevel; + window->setProperty("_q_levelBeforeModalSession", (qlonglong)originalLevel); + } else if (NSInteger originalLevel = window->property("_q_levelBeforeModalSession").toLongLong()) { + splashWindow.level = originalLevel; + } + } + } + }); } QCocoaIntegration::~QCocoaIntegration() diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp index c7b9f3ec7a..c418db14ff 100644 --- a/src/widgets/kernel/qshortcut.cpp +++ b/src/widgets/kernel/qshortcut.cpp @@ -189,10 +189,15 @@ static bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidge } #endif - /* if a floating tool window is active, keep shortcuts on the - * parent working */ - if (active_window != tlw && active_window && active_window->windowType() == Qt::Tool && active_window->parentWidget()) { - active_window = active_window->parentWidget()->window(); + if (active_window && active_window != tlw) { + /* if a floating tool window is active, keep shortcuts on the parent working. + * and if a popup window is active (f.ex a completer), keep shortcuts on the + * focus proxy working */ + if (active_window->windowType() == Qt::Tool && active_window->parentWidget()) { + active_window = active_window->parentWidget()->window(); + } else if (active_window->windowType() == Qt::Popup && active_window->focusProxy()) { + active_window = active_window->focusProxy()->window(); + } } if (active_window != tlw) { |