diff options
author | Liang Qi <liang.qi@qt.io> | 2017-02-17 20:10:34 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-02-17 20:10:34 +0100 |
commit | bc4cd465dd5df82e13f3c7709166ee11289d219f (patch) | |
tree | d6323aaed6383e589fbefb6057648c22bb187c76 /src | |
parent | 43daefb0962794b2df256cae1098e889b9b36f12 (diff) | |
parent | 07745d7bfbf6c8d83e0243150d8ce934675dea87 (diff) |
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts:
qmake/Makefile.unix
Change-Id: Ia18e391198222eef34ffa2df6f683e052058d032
Diffstat (limited to 'src')
112 files changed, 1316 insertions, 726 deletions
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index a4341a5a48..b6dbd82597 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -243,13 +243,24 @@ public class QtNative } } - private static void runPendingCppRunnablesOnUiThread() + private static void runPendingCppRunnablesOnAndroidThread() { synchronized (m_mainActivityMutex) { - if (!m_activityPaused && m_activity != null) - m_activity.runOnUiThread(runPendingCppRunnablesRunnable); - else - runAction(runPendingCppRunnablesRunnable); + if (m_activity != null) { + if (!m_activityPaused) + m_activity.runOnUiThread(runPendingCppRunnablesRunnable); + else + runAction(runPendingCppRunnablesRunnable); + } else { + final Looper mainLooper = Looper.getMainLooper(); + final Thread looperThread = mainLooper.getThread(); + if (looperThread.equals(Thread.currentThread())) { + runPendingCppRunnablesRunnable.run(); + } else { + final Handler handler = new Handler(mainLooper); + handler.post(runPendingCppRunnablesRunnable); + } + } } } diff --git a/src/corelib/configure.json b/src/corelib/configure.json index 60248e9cd2..4fbc51a09c 100644 --- a/src/corelib/configure.json +++ b/src/corelib/configure.json @@ -211,8 +211,7 @@ }, "dlopen": { "label": "dlopen()", - "condition": "tests.dlopen || libs.libdl", - "output": [ { "type": "define", "negative": true, "name": "QT_NO_DYNAMIC_LIBRARY" } ] + "condition": "tests.dlopen || libs.libdl" }, "libdl": { "label": "dlopen() in libdl", @@ -443,7 +442,7 @@ "label": "QProcess", "purpose": "Supports external process invocation.", "section": "File I/O", - "condition": "!config.winrt && !config.uikit && !config.integrity && !config.vxworks", + "condition": "features.processenvironment && !config.winrt && !config.uikit && !config.integrity && !config.vxworks", "output": [ "publicFeature", "feature" ] }, "processenvironment": { @@ -463,6 +462,7 @@ "label": "QLibrary", "purpose": "Provides a wrapper for dynamically loaded libraries.", "section": "File I/O", + "condition": "config.win32 || config.hpux || (!config.nacl && features.dlopen)", "output": [ "publicFeature", "feature" ] }, "settings": { diff --git a/src/corelib/doc/snippets/events/events.cpp b/src/corelib/doc/snippets/events/events.cpp index b029296bc2..9606b0c2ee 100644 --- a/src/corelib/doc/snippets/events/events.cpp +++ b/src/corelib/doc/snippets/events/events.cpp @@ -87,15 +87,15 @@ public: bool MyWidget::event(QEvent *event) { if (event->type() == QEvent::KeyPress) { - QKeyEvent *ke = static_cast<QKeyEvent *>(event); - if (ke->key() == Qt::Key_Tab) { - // special tab handling here - return true; - } + QKeyEvent *ke = static_cast<QKeyEvent *>(event); + if (ke->key() == Qt::Key_Tab) { + // special tab handling here + return true; + } } else if (event->type() == MyCustomEventType) { - MyCustomEvent *myEvent = static_cast<MyCustomEvent *>(event); - // custom event handling here - return true; + MyCustomEvent *myEvent = static_cast<MyCustomEvent *>(event); + // custom event handling here + return true; } return QWidget::event(event); diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h index d7849d4699..1c806e0774 100644 --- a/src/corelib/global/qconfig-bootstrapped.h +++ b/src/corelib/global/qconfig-bootstrapped.h @@ -77,6 +77,7 @@ #define QT_NO_SYSTEMLOCALE #define QT_FEATURE_slog2 -1 #define QT_FEATURE_syslog -1 +#define QT_FEATURE_temporaryfile 1 #define QT_NO_THREAD #define QT_FEATURE_timezone -1 #define QT_FEATURE_topleveldomain -1 diff --git a/src/corelib/global/qfloat16.cpp b/src/corelib/global/qfloat16.cpp index 5264b56104..1de1ae65fb 100644 --- a/src/corelib/global/qfloat16.cpp +++ b/src/corelib/global/qfloat16.cpp @@ -61,8 +61,21 @@ QT_BEGIN_NAMESPACE Q_STATIC_ASSERT_X(sizeof(float) == sizeof(quint32), "qfloat16 assumes that floats are 32 bits wide"); + +// There are a few corner cases regarding denormals where GHS compiler is relying +// hardware behavior that is not IEC 559 compliant. Therefore the compiler +// reports std::numeric_limits<float>::is_iec559 as false. This is all right +// according to our needs. + +#if !defined(Q_CC_GHS) Q_STATIC_ASSERT_X(std::numeric_limits<float>::is_iec559, "Only works with IEEE 754 floating point"); +#endif + +Q_STATIC_ASSERT_X(std::numeric_limits<float>::has_infinity && + std::numeric_limits<float>::has_quiet_NaN && + std::numeric_limits<float>::has_signaling_NaN, + "Only works with IEEE 754 floating point"); /*! Returns true if the \c qfloat16 \a {f} is equivalent to infinity. diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h index 67c062d349..8fd2f212af 100644 --- a/src/corelib/global/qfloat16.h +++ b/src/corelib/global/qfloat16.h @@ -44,6 +44,10 @@ #include <QtCore/qmetatype.h> #include <string.h> +#if defined __F16C__ +#include <immintrin.h> +#endif + QT_BEGIN_NAMESPACE #if 0 @@ -111,19 +115,34 @@ inline int qIntCast(qfloat16 f) Q_DECL_NOTHROW inline qfloat16::qfloat16(float f) Q_DECL_NOTHROW { +#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__) + b16 = _cvtss_sh(f, 0); +#elif defined (__ARM_FP16_FORMAT_IEEE) + __fp16 f16 = f; + memcpy(&b16, &f16, sizeof(quint16)); +#else quint32 u; memcpy(&u, &f, sizeof(quint32)); b16 = basetable[(u >> 23) & 0x1ff] + ((u & 0x007fffff) >> shifttable[(u >> 23) & 0x1ff]); +#endif } inline qfloat16::operator float() const Q_DECL_NOTHROW { +#if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__F16C__) + return _cvtsh_ss(b16); +#elif defined (__ARM_FP16_FORMAT_IEEE) + __fp16 f16; + memcpy(&f16, &b16, sizeof(quint16)); + return f16; +#else quint32 u = mantissatable[offsettable[b16 >> 10] + (b16 & 0x3ff)] + exponenttable[b16 >> 10]; float f; memcpy(&f, &u, sizeof(quint32)); return f; +#endif } inline qfloat16::operator double() const Q_DECL_NOTHROW diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 153d7466ed..f8c58c6b3e 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -3974,7 +3974,10 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters) { Q_ASSERT_X(cb >= 0, "QInternal::activateCallback()", "Callback id must be a valid id"); - QInternal_CallBackTable *cbt = global_callback_table(); + if (!global_callback_table.exists()) + return false; + + QInternal_CallBackTable *cbt = &(*global_callback_table); if (cbt && cb < cbt->callbacks.size()) { QList<qInternalCallback> callbacks = cbt->callbacks[cb]; bool ret = false; diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 6b90a47388..6573e0a53e 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1445,12 +1445,14 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con now.start(); uint ms = now.msecsSinceReference(); message.append(QString::asprintf("%6d.%03d", uint(ms / 1000), uint(ms % 1000))); +#if QT_CONFIG(datestring) } else if (timeFormat.isEmpty()) { message.append(QDateTime::currentDateTime().toString(Qt::ISODate)); } else { message.append(QDateTime::currentDateTime().toString(timeFormat)); +#endif // QT_CONFIG(datestring) } -#endif +#endif // !QT_BOOTSTRAPPED } else if (token == ifCategoryTokenC) { if (!context.category || (strcmp(context.category, "default") == 0)) skip = true; diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index af485a1832..8da06f71f7 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2105,7 +2105,7 @@ On \macos, tool windows correspond to the \l{http://developer.apple.com/documentation/Carbon/Conceptual/HandlingWindowsControls/hitb-wind_cont_concept/chapter_2_section_2.html}{Floating} class of windows. This means that the window lives on a - level above normal windows; it impossible to put a normal + level above normal windows making it impossible to put a normal window on top of it. By default, tool windows will disappear when the application is inactive. This can be controlled by the Qt::WA_MacAlwaysShowToolWindow attribute. diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index 52a78ad1c4..41a4d7a1ba 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -1007,10 +1007,9 @@ qint64 QIODevice::read(char *data, qint64 maxSize) #endif const bool sequential = d->isSequential(); - const bool keepDataInBuffer = sequential && d->transactionStarted; - // Short circuit for getChar() - if (maxSize == 1 && !keepDataInBuffer) { + // Short-cut for getChar(), unless we need to keep the data in the buffer. + if (maxSize == 1 && !(sequential && d->transactionStarted)) { int chint; while ((chint = d->buffer.getChar()) != -1) { if (!sequential) @@ -1031,43 +1030,67 @@ qint64 QIODevice::read(char *data, qint64 maxSize) } CHECK_MAXLEN(read, qint64(-1)); + CHECK_READABLE(read, qint64(-1)); + + const qint64 readBytes = d->read(data, maxSize); + +#if defined QIODEVICE_DEBUG + printf("%p \treturning %lld, d->pos == %lld, d->buffer.size() == %lld\n", this, + readBytes, d->pos, d->buffer.size()); + if (readBytes > 0) + debugBinaryString(data - readBytes, readBytes); +#endif + + return readBytes; +} + +/*! + \internal +*/ +qint64 QIODevicePrivate::read(char *data, qint64 maxSize, bool peeking) +{ + Q_Q(QIODevice); + + const bool buffered = (openMode & QIODevice::Unbuffered) == 0; + const bool sequential = isSequential(); + const bool keepDataInBuffer = sequential + ? peeking || transactionStarted + : peeking && buffered; + const qint64 savedPos = pos; qint64 readSoFar = 0; bool madeBufferReadsOnly = true; bool deviceAtEof = false; char *readPtr = data; + qint64 bufferPos = (sequential && transactionStarted) ? transactionPos : Q_INT64_C(0); forever { // Try reading from the buffer. qint64 bufferReadChunkSize = keepDataInBuffer - ? d->buffer.peek(data, maxSize, d->transactionPos) - : d->buffer.read(data, maxSize); + ? buffer.peek(data, maxSize, bufferPos) + : buffer.read(data, maxSize); if (bufferReadChunkSize > 0) { - if (keepDataInBuffer) - d->transactionPos += bufferReadChunkSize; - else if (!sequential) - d->pos += bufferReadChunkSize; + bufferPos += bufferReadChunkSize; + if (!sequential) + pos += bufferReadChunkSize; +#if defined QIODEVICE_DEBUG + printf("%p \treading %lld bytes from buffer into position %lld\n", q, + bufferReadChunkSize, readSoFar); +#endif readSoFar += bufferReadChunkSize; data += bufferReadChunkSize; maxSize -= bufferReadChunkSize; -#if defined QIODEVICE_DEBUG - printf("%p \treading %lld bytes from buffer into position %lld\n", this, - bufferReadChunkSize, readSoFar - bufferReadChunkSize); -#endif - } else { - CHECK_READABLE(read, qint64(-1)); } if (maxSize > 0 && !deviceAtEof) { qint64 readFromDevice = 0; // Make sure the device is positioned correctly. - if (sequential || d->pos == d->devicePos || seek(d->pos)) { + if (sequential || pos == devicePos || q->seek(pos)) { madeBufferReadsOnly = false; // fix readData attempt - if ((maxSize >= d->readBufferChunkSize || (d->openMode & Unbuffered)) - && !keepDataInBuffer) { + if ((!buffered || maxSize >= readBufferChunkSize) && !keepDataInBuffer) { // Read big chunk directly to output buffer - readFromDevice = readData(data, maxSize); + readFromDevice = q->readData(data, maxSize); deviceAtEof = (readFromDevice != maxSize); #if defined QIODEVICE_DEBUG - printf("%p \treading %lld bytes from device (total %lld)\n", this, + printf("%p \treading %lld bytes from device (total %lld)\n", q, readFromDevice, readSoFar); #endif if (readFromDevice > 0) { @@ -1075,24 +1098,24 @@ qint64 QIODevice::read(char *data, qint64 maxSize) data += readFromDevice; maxSize -= readFromDevice; if (!sequential) { - d->pos += readFromDevice; - d->devicePos += readFromDevice; + pos += readFromDevice; + devicePos += readFromDevice; } } } else { // Do not read more than maxSize on unbuffered devices - const qint64 bytesToBuffer = (d->openMode & Unbuffered) - ? qMin(maxSize, qint64(d->readBufferChunkSize)) - : qint64(d->readBufferChunkSize); + const qint64 bytesToBuffer = (buffered || readBufferChunkSize < maxSize) + ? qint64(readBufferChunkSize) + : maxSize; // Try to fill QIODevice buffer by single read - readFromDevice = readData(d->buffer.reserve(bytesToBuffer), bytesToBuffer); + readFromDevice = q->readData(buffer.reserve(bytesToBuffer), bytesToBuffer); deviceAtEof = (readFromDevice != bytesToBuffer); - d->buffer.chop(bytesToBuffer - qMax(Q_INT64_C(0), readFromDevice)); + buffer.chop(bytesToBuffer - qMax(Q_INT64_C(0), readFromDevice)); if (readFromDevice > 0) { if (!sequential) - d->devicePos += readFromDevice; + devicePos += readFromDevice; #if defined QIODEVICE_DEBUG - printf("%p \treading %lld from device into buffer\n", this, + printf("%p \treading %lld from device into buffer\n", q, readFromDevice); #endif continue; @@ -1108,7 +1131,7 @@ qint64 QIODevice::read(char *data, qint64 maxSize) } } - if ((d->openMode & Text) && readPtr < data) { + if ((openMode & QIODevice::Text) && readPtr < data) { const char *endPtr = data; // optimization to avoid initial self-assignment @@ -1140,14 +1163,18 @@ qint64 QIODevice::read(char *data, qint64 maxSize) break; } -#if defined QIODEVICE_DEBUG - printf("%p \treturning %lld, d->pos == %lld, d->buffer.size() == %lld\n", this, - readSoFar, d->pos, d->buffer.size()); - debugBinaryString(data - readSoFar, readSoFar); -#endif + // Restore positions after reading + if (keepDataInBuffer) { + if (peeking) + pos = savedPos; // does nothing on sequential devices + else + transactionPos = bufferPos; + } else if (peeking) { + seekBuffer(savedPos); // unbuffered random-access device + } - if (madeBufferReadsOnly && d->isBufferEmpty()) - readData(data, 0); + if (madeBufferReadsOnly && isBufferEmpty()) + q->readData(data, 0); return readSoFar; } @@ -1759,27 +1786,7 @@ bool QIODevicePrivate::putCharHelper(char c) */ qint64 QIODevicePrivate::peek(char *data, qint64 maxSize) { - Q_Q(QIODevice); - - if (transactionStarted) { - const qint64 savedTransactionPos = transactionPos; - const qint64 savedPos = pos; - - qint64 readBytes = q->read(data, maxSize); - - // Restore initial position - if (isSequential()) - transactionPos = savedTransactionPos; - else - seekBuffer(savedPos); - return readBytes; - } - - q->startTransaction(); - qint64 readBytes = q->read(data, maxSize); - q->rollbackTransaction(); - - return readBytes; + return read(data, maxSize, true); } /*! @@ -1787,26 +1794,17 @@ qint64 QIODevicePrivate::peek(char *data, qint64 maxSize) */ QByteArray QIODevicePrivate::peek(qint64 maxSize) { - Q_Q(QIODevice); - - if (transactionStarted) { - const qint64 savedTransactionPos = transactionPos; - const qint64 savedPos = pos; + QByteArray result(maxSize, Qt::Uninitialized); - QByteArray result = q->read(maxSize); + const qint64 readBytes = read(result.data(), maxSize, true); - // Restore initial position - if (isSequential()) - transactionPos = savedTransactionPos; + if (readBytes < maxSize) { + if (readBytes <= 0) + result.clear(); else - seekBuffer(savedPos); - return result; + result.resize(readBytes); } - q->startTransaction(); - QByteArray result = q->read(maxSize); - q->rollbackTransaction(); - return result; } @@ -1844,7 +1842,12 @@ bool QIODevice::getChar(char *c) */ qint64 QIODevice::peek(char *data, qint64 maxSize) { - return d_func()->peek(data, maxSize); + Q_D(QIODevice); + + CHECK_MAXLEN(peek, qint64(-1)); + CHECK_READABLE(peek, qint64(-1)); + + return d->peek(data, maxSize); } /*! @@ -1866,7 +1869,13 @@ qint64 QIODevice::peek(char *data, qint64 maxSize) */ QByteArray QIODevice::peek(qint64 maxSize) { - return d_func()->peek(maxSize); + Q_D(QIODevice); + + CHECK_MAXLEN(peek, QByteArray()); + CHECK_MAXBYTEARRAYSIZE(peek); + CHECK_READABLE(peek, QByteArray()); + + return d->peek(maxSize); } /*! diff --git a/src/corelib/io/qiodevice_p.h b/src/corelib/io/qiodevice_p.h index 76bec89ef2..71a326dd53 100644 --- a/src/corelib/io/qiodevice_p.h +++ b/src/corelib/io/qiodevice_p.h @@ -171,6 +171,7 @@ public: void setReadChannelCount(int count); void setWriteChannelCount(int count); + qint64 read(char *data, qint64 maxSize, bool peeking = false); virtual qint64 peek(char *data, qint64 maxSize); virtual QByteArray peek(qint64 maxSize); diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index febf22639c..32639759e4 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -149,12 +149,23 @@ static QString cleanPath(const QString &_path) Q_DECLARE_TYPEINFO(QResourceRoot, Q_MOVABLE_TYPE); -Q_GLOBAL_STATIC_WITH_ARGS(QMutex, resourceMutex, (QMutex::Recursive)) - typedef QList<QResourceRoot*> ResourceList; -Q_GLOBAL_STATIC(ResourceList, resourceList) +struct QResourceGlobalData +{ + QMutex resourceMutex{QMutex::Recursive}; + ResourceList resourceList; + QStringList resourceSearchPaths; +}; +Q_GLOBAL_STATIC(QResourceGlobalData, resourceGlobalData) + +static inline QMutex *resourceMutex() +{ return &resourceGlobalData->resourceMutex; } -Q_GLOBAL_STATIC(QStringList, resourceSearchPaths) +static inline ResourceList *resourceList() +{ return &resourceGlobalData->resourceList; } + +static inline QStringList *resourceSearchPaths() +{ return &resourceGlobalData->resourceSearchPaths; } /*! \class QResource @@ -870,6 +881,9 @@ Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree, Q_CORE_EXPORT bool qUnregisterResourceData(int version, const unsigned char *tree, const unsigned char *name, const unsigned char *data) { + if (resourceGlobalData.isDestroyed()) + return false; + QMutexLocker lock(resourceMutex()); if ((version == 0x01 || version == 0x02) && resourceList()) { QResourceRoot res(version, tree, name, data); diff --git a/src/corelib/io/qstorageinfo.cpp b/src/corelib/io/qstorageinfo.cpp index 9885da1af9..27f0552a31 100644 --- a/src/corelib/io/qstorageinfo.cpp +++ b/src/corelib/io/qstorageinfo.cpp @@ -268,7 +268,7 @@ QByteArray QStorageInfo::device() const } /*! - \since 5.8 + \since 5.9 Returns the subvolume name for this volume. Some filesystem types allow multiple subvolumes inside one device, which diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index a936457bce..0ac49c5019 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -305,12 +305,13 @@ void qRemovePostRoutine(QtCleanUpFunction p) static void qt_call_pre_routines() { - QStartUpFuncList *list = preRList(); - if (!list) + if (!preRList.exists()) return; + #ifndef QT_NO_THREAD QMutexLocker locker(&globalPreRoutinesMutex); #endif + QVFuncList *list = &(*preRList); // Unlike qt_call_post_routines, we don't empty the list, because // Q_COREAPP_STARTUP_FUNCTION is a macro, so the user expects // the function to be executed every time QCoreApplication is created. @@ -320,16 +321,10 @@ static void qt_call_pre_routines() void Q_CORE_EXPORT qt_call_post_routines() { - QVFuncList *list = 0; - QT_TRY { - list = postRList(); - } QT_CATCH(const std::bad_alloc &) { - // ignore - if we can't allocate a post routine list, - // there's a high probability that there's no post - // routine to be executed :) - } - if (!list) + if (!postRList.exists()) return; + + QVFuncList *list = &(*postRList); while (!list->isEmpty()) (list->takeFirst())(); } diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp index 6a46f7dd11..93bc477e7d 100644 --- a/src/corelib/kernel/qjnihelpers.cpp +++ b/src/corelib/kernel/qjnihelpers.cpp @@ -52,6 +52,18 @@ QT_BEGIN_NAMESPACE +namespace QtAndroidPrivate { + // *Listener virtual function implementations. + // Defined out-of-line to pin the vtable/type_info. + ActivityResultListener::~ActivityResultListener() {} + NewIntentListener::~NewIntentListener() {} + ResumePauseListener::~ResumePauseListener() {} + void ResumePauseListener::handlePause() {} + void ResumePauseListener::handleResume() {} + GenericMotionEventListener::~GenericMotionEventListener() {} + KeyEventListener::~KeyEventListener() {} +} + static JavaVM *g_javaVM = Q_NULLPTR; static jobject g_jActivity = Q_NULLPTR; static jobject g_jService = Q_NULLPTR; @@ -61,7 +73,7 @@ static jclass g_jNativeClass = Q_NULLPTR; static jmethodID g_runPendingCppRunnablesMethodID = Q_NULLPTR; static jmethodID g_hideSplashScreenMethodID = Q_NULLPTR; Q_GLOBAL_STATIC(std::deque<QtAndroidPrivate::Runnable>, g_pendingRunnables); -Q_GLOBAL_STATIC(QMutex, g_pendingRunnablesMutex); +static QBasicMutex g_pendingRunnablesMutex; class PermissionsResultClass : public QObject { @@ -76,21 +88,24 @@ private: typedef QHash<int, QSharedPointer<PermissionsResultClass>> PendingPermissionRequestsHash; Q_GLOBAL_STATIC(PendingPermissionRequestsHash, g_pendingPermissionRequests); -Q_GLOBAL_STATIC(QMutex, g_pendingPermissionRequestsMutex); -Q_GLOBAL_STATIC(QAtomicInt, g_requestPermissionsRequestCode); +static QBasicMutex g_pendingPermissionRequestsMutex; +static int nextRequestCode() +{ + static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(0); + return counter.fetchAndAddRelaxed(1); +} // function called from Java from Android UI thread static void runPendingCppRunnables(JNIEnv */*env*/, jobject /*obj*/) { for (;;) { // run all posted runnables - g_pendingRunnablesMutex->lock(); + QMutexLocker locker(&g_pendingRunnablesMutex); if (g_pendingRunnables->empty()) { - g_pendingRunnablesMutex->unlock(); break; } QtAndroidPrivate::Runnable runnable(std::move(g_pendingRunnables->front())); g_pendingRunnables->pop_front(); - g_pendingRunnablesMutex->unlock(); + locker.unlock(); runnable(); // run it outside the sync block! } } @@ -110,16 +125,17 @@ Q_GLOBAL_STATIC(GenericMotionEventListeners, g_genericMotionEventListeners) static void sendRequestPermissionsResult(JNIEnv *env, jobject /*obj*/, jint requestCode, jobjectArray permissions, jintArray grantResults) { - g_pendingPermissionRequestsMutex->lock(); + QMutexLocker locker(&g_pendingPermissionRequestsMutex); auto it = g_pendingPermissionRequests->find(requestCode); if (it == g_pendingPermissionRequests->end()) { - g_pendingPermissionRequestsMutex->unlock(); // show an error or something ? return; } - g_pendingPermissionRequestsMutex->unlock(); + auto request = std::move(*it); + g_pendingPermissionRequests->erase(it); + locker.unlock(); - Qt::ConnectionType connection = QThread::currentThread() == it.value()->thread() ? Qt::DirectConnection : Qt::BlockingQueuedConnection; + Qt::ConnectionType connection = QThread::currentThread() == request->thread() ? Qt::DirectConnection : Qt::BlockingQueuedConnection; QtAndroidPrivate::PermissionsHash hash; const int size = env->GetArrayLength(permissions); std::unique_ptr<jint[]> results(new jint[size]); @@ -131,10 +147,7 @@ static void sendRequestPermissionsResult(JNIEnv *env, jobject /*obj*/, jint requ QtAndroidPrivate::PermissionsResult::Denied; hash[permission] = value; } - QMetaObject::invokeMethod(it.value().data(), "sendResult", connection, Q_ARG(QtAndroidPrivate::PermissionsHash, hash)); - g_pendingPermissionRequestsMutex->lock(); - g_pendingPermissionRequests->erase(it); - g_pendingPermissionRequestsMutex->unlock(); + QMetaObject::invokeMethod(request.data(), "sendResult", connection, Q_ARG(QtAndroidPrivate::PermissionsHash, hash)); } static jboolean dispatchGenericMotionEvent(JNIEnv *, jclass, jobject event) @@ -391,7 +404,7 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env) return JNI_ERR; g_runPendingCppRunnablesMethodID = env->GetStaticMethodID(jQtNative, - "runPendingCppRunnablesOnUiThread", + "runPendingCppRunnablesOnAndroidThread", "()V"); g_hideSplashScreenMethodID = env->GetStaticMethodID(jQtNative, "hideSplashScreen", "()V"); g_jNativeClass = static_cast<jclass>(env->NewGlobalRef(jQtNative)); @@ -447,10 +460,10 @@ void QtAndroidPrivate::runOnUiThread(QRunnable *runnable, JNIEnv *env) void QtAndroidPrivate::runOnAndroidThread(const QtAndroidPrivate::Runnable &runnable, JNIEnv *env) { - g_pendingRunnablesMutex->lock(); + QMutexLocker locker(&g_pendingRunnablesMutex); const bool triggerRun = g_pendingRunnables->empty(); g_pendingRunnables->push_back(runnable); - g_pendingRunnablesMutex->unlock(); + locker.unlock(); if (triggerRun) env->CallStaticVoidMethod(g_jNativeClass, g_runPendingCppRunnablesMethodID); } @@ -475,18 +488,16 @@ void QtAndroidPrivate::requestPermissions(JNIEnv *env, const QStringList &permis return; } // Check API 23+ permissions - const int requestCode = (*g_requestPermissionsRequestCode)++; + const int requestCode = nextRequestCode(); if (!directCall) { - g_pendingPermissionRequestsMutex->lock(); + QMutexLocker locker(&g_pendingPermissionRequestsMutex); (*g_pendingPermissionRequests)[requestCode] = QSharedPointer<PermissionsResultClass>::create(callbackFunc); - g_pendingPermissionRequestsMutex->unlock(); } runOnAndroidThread([permissions, callbackFunc, requestCode, directCall] { if (directCall) { - g_pendingPermissionRequestsMutex->lock(); + QMutexLocker locker(&g_pendingPermissionRequestsMutex); (*g_pendingPermissionRequests)[requestCode] = QSharedPointer<PermissionsResultClass>::create(callbackFunc); - g_pendingPermissionRequestsMutex->unlock(); } QJNIEnvironmentPrivate env; @@ -507,8 +518,10 @@ QHash<QString, QtAndroidPrivate::PermissionsResult> QtAndroidPrivate::requestPer *res = result; sem->release(); }, true); - sem->tryAcquire(1, timeoutMs); - return *res; + if (sem->tryAcquire(1, timeoutMs)) + return std::move(*res); + else // mustn't touch *res + return QHash<QString, QtAndroidPrivate::PermissionsResult>(); } QtAndroidPrivate::PermissionsResult QtAndroidPrivate::checkPermission(const QString &permission) diff --git a/src/corelib/kernel/qjnihelpers_p.h b/src/corelib/kernel/qjnihelpers_p.h index 478f62a5c7..62f9358513 100644 --- a/src/corelib/kernel/qjnihelpers_p.h +++ b/src/corelib/kernel/qjnihelpers_p.h @@ -65,36 +65,36 @@ namespace QtAndroidPrivate class Q_CORE_EXPORT ActivityResultListener { public: - virtual ~ActivityResultListener() {} + virtual ~ActivityResultListener(); virtual bool handleActivityResult(jint requestCode, jint resultCode, jobject data) = 0; }; class Q_CORE_EXPORT NewIntentListener { public: - virtual ~NewIntentListener() {} + virtual ~NewIntentListener(); virtual bool handleNewIntent(JNIEnv *env, jobject intent) = 0; }; class Q_CORE_EXPORT ResumePauseListener { public: - virtual ~ResumePauseListener() {} - virtual void handlePause() {}; - virtual void handleResume() {}; + virtual ~ResumePauseListener(); + virtual void handlePause(); + virtual void handleResume(); }; class Q_CORE_EXPORT GenericMotionEventListener { public: - virtual ~GenericMotionEventListener() {} + virtual ~GenericMotionEventListener(); virtual bool handleGenericMotionEvent(jobject event) = 0; }; class Q_CORE_EXPORT KeyEventListener { public: - virtual ~KeyEventListener() {} + virtual ~KeyEventListener(); virtual bool handleKeyEvent(jobject event) = 0; }; diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 5623b085b8..1764c8116e 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -834,38 +834,27 @@ void QMetaType::registerStreamOperators(int idx, SaveOperator saveOp, const char *QMetaType::typeName(int typeId) { const uint type = typeId; - // In theory it can be filled during compilation time, but for some reason template code - // that is able to do it causes GCC 4.6 to generate additional 3K of executable code. Probably - // it is not worth of it. - static const char *namesCache[QMetaType::HighestInternalId + 1]; - - const char *result; - if (type <= QMetaType::HighestInternalId && ((result = namesCache[type]))) - return result; - #define QT_METATYPE_TYPEID_TYPENAME_CONVERTER(MetaTypeName, TypeId, RealName) \ - case QMetaType::MetaTypeName: result = #RealName; break; + case QMetaType::MetaTypeName: return #RealName; break; switch (QMetaType::Type(type)) { QT_FOR_EACH_STATIC_TYPE(QT_METATYPE_TYPEID_TYPENAME_CONVERTER) - - default: { - if (Q_UNLIKELY(type < QMetaType::User)) { - return 0; // It can happen when someone cast int to QVariant::Type, we should not crash... - } else { - const QVector<QCustomTypeInfo> * const ct = customTypes(); - QReadLocker locker(customTypesLock()); - return ct && uint(ct->count()) > type - QMetaType::User && !ct->at(type - QMetaType::User).typeName.isEmpty() - ? ct->at(type - QMetaType::User).typeName.constData() - : 0; - } + case QMetaType::UnknownType: + case QMetaType::User: + break; } + + if (Q_UNLIKELY(type < QMetaType::User)) { + return nullptr; // It can happen when someone cast int to QVariant::Type, we should not crash... } -#undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER - Q_ASSERT(type <= QMetaType::HighestInternalId); - namesCache[type] = result; - return result; + const QVector<QCustomTypeInfo> * const ct = customTypes(); + QReadLocker locker(customTypesLock()); + return ct && uint(ct->count()) > type - QMetaType::User && !ct->at(type - QMetaType::User).typeName.isEmpty() + ? ct->at(type - QMetaType::User).typeName.constData() + : nullptr; + +#undef QT_METATYPE_TYPEID_TYPENAME_CONVERTER } /* diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 8088b18ef4..8e906b278d 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3708,7 +3708,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i continue; QObject * const receiver = c->receiver; - const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId; + const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId.load(); // determine if this connection should be sent immediately or // put into the event queue diff --git a/src/corelib/plugin/qelfparser_p.cpp b/src/corelib/plugin/qelfparser_p.cpp index 2c3a5f1d02..0a219d1251 100644 --- a/src/corelib/plugin/qelfparser_p.cpp +++ b/src/corelib/plugin/qelfparser_p.cpp @@ -142,10 +142,12 @@ int QElfParser::parse(const char *dataStart, ulong fdlen, const QString &library data += sizeof(qelfhalf_t); // e_shtrndx if ((quint32)(e_shnum * e_shentsize) > fdlen) { - if (lib) - lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)") - .arg(library, QLibrary::tr("announced %1 section(s), each %2 byte(s), exceed file size") - .arg(e_shnum).arg(e_shentsize)); + if (lib) { + const QString message = + QLibrary::tr("announced %n section(s), each %1 byte(s), exceed file size", + nullptr, int(e_shnum)).arg(e_shentsize); + lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library, message); + } return Corrupt; } diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index aff2991ed1..96cf5371f9 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -617,40 +617,34 @@ bool QLibrary::isLibrary(const QString &fileName) { #if defined(Q_OS_WIN) return fileName.endsWith(QLatin1String(".dll"), Qt::CaseInsensitive); -#else +#else // Generic Unix QString completeSuffix = QFileInfo(fileName).completeSuffix(); if (completeSuffix.isEmpty()) return false; const QVector<QStringRef> suffixes = completeSuffix.splitRef(QLatin1Char('.')); -# if defined(Q_OS_DARWIN) - - // On Mac, libs look like libmylib.1.0.0.dylib - const QStringRef &lastSuffix = suffixes.at(suffixes.count() - 1); - const QStringRef &firstSuffix = suffixes.at(0); - - bool valid = (lastSuffix == QLatin1String("dylib") - || firstSuffix == QLatin1String("so") - || firstSuffix == QLatin1String("bundle")); - - return valid; -# else // Generic Unix QStringList validSuffixList; -# if defined(Q_OS_HPUX) +# if defined(Q_OS_HPUX) /* See "HP-UX Linker and Libraries User's Guide", section "Link-time Differences between PA-RISC and IPF": "In PA-RISC (PA-32 and PA-64) shared libraries are suffixed with .sl. In IPF (32-bit and 64-bit), the shared libraries are suffixed with .so. For compatibility, the IPF linker also supports the .sl suffix." */ validSuffixList << QLatin1String("sl"); -# if defined __ia64 +# if defined __ia64 validSuffixList << QLatin1String("so"); -# endif -# elif defined(Q_OS_AIX) +# endif +# elif defined(Q_OS_AIX) validSuffixList << QLatin1String("a") << QLatin1String("so"); -# elif defined(Q_OS_UNIX) +# elif defined(Q_OS_DARWIN) + // On Apple platforms, dylib look like libmylib.1.0.0.dylib + if (suffixes.last() == QLatin1String("dylib")) + return true; + + validSuffixList << QLatin1String("so") << QLatin1String("bundle"); +# elif defined(Q_OS_UNIX) validSuffixList << QLatin1String("so"); -# endif +# endif // Examples of valid library names: // libfoo.so @@ -669,9 +663,7 @@ bool QLibrary::isLibrary(const QString &fileName) if (i != suffixPos) suffixes.at(i).toInt(&valid); return valid; -# endif #endif - } typedef const char * (*QtPluginQueryVerificationDataFunction)(); diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp index bb7874071e..3553763bcd 100644 --- a/src/corelib/plugin/qlibrary_unix.cpp +++ b/src/corelib/plugin/qlibrary_unix.cpp @@ -50,13 +50,9 @@ # include <private/qcore_mac_p.h> #endif -#if (defined(Q_OS_VXWORKS) && !defined(VXWORKS_RTP)) || defined (Q_OS_NACL) -#define QT_NO_DYNAMIC_LIBRARY -#endif - QT_BEGIN_NAMESPACE -#if !defined(QT_HPUX_LD) && !defined(QT_NO_DYNAMIC_LIBRARY) +#if !defined(QT_HPUX_LD) QT_BEGIN_INCLUDE_NAMESPACE #include <dlfcn.h> QT_END_INCLUDE_NAMESPACE @@ -64,9 +60,7 @@ QT_END_INCLUDE_NAMESPACE static QString qdlerror() { -#if defined(QT_NO_DYNAMIC_LIBRARY) - const char *err = "This platform does not support dynamic libraries."; -#elif !defined(QT_HPUX_LD) +#if !defined(QT_HPUX_LD) const char *err = dlerror(); #else const char *err = strerror(errno); @@ -131,7 +125,6 @@ QStringList QLibraryPrivate::prefixes_sys() bool QLibraryPrivate::load_sys() { QString attempt; -#if !defined(QT_NO_DYNAMIC_LIBRARY) QFileSystemEntry fsEntry(fileName); QString path = fsEntry.path(); @@ -250,7 +243,6 @@ bool QLibraryPrivate::load_sys() } } #endif -#endif // QT_NO_DYNAMIC_LIBRARY if (!pHnd) { errorString = QLibrary::tr("Cannot load library %1: %2").arg(fileName, qdlerror()); } @@ -263,29 +255,27 @@ bool QLibraryPrivate::load_sys() bool QLibraryPrivate::unload_sys() { -#if !defined(QT_NO_DYNAMIC_LIBRARY) -# if defined(QT_HPUX_LD) +#if defined(QT_HPUX_LD) if (shl_unload((shl_t)pHnd)) { -# else +#else if (dlclose(pHnd)) { -# endif -# if defined (Q_OS_QNX) // Workaround until fixed in QNX; fixes crash in +#endif +#if defined (Q_OS_QNX) // Workaround until fixed in QNX; fixes crash in char *error = dlerror(); // QtDeclarative auto test "qqmlenginecleanup" for instance if (!qstrcmp(error, "Shared objects still referenced")) // On QNX that's only "informative" return true; errorString = QLibrary::tr("Cannot unload library %1: %2").arg(fileName, QLatin1String(error)); -# else +#else errorString = QLibrary::tr("Cannot unload library %1: %2").arg(fileName, qdlerror()); -# endif +#endif return false; } -#endif errorString.clear(); return true; } -#if defined(Q_OS_LINUX) && !defined(QT_NO_DYNAMIC_LIBRARY) +#if defined(Q_OS_LINUX) Q_CORE_EXPORT QFunctionPointer qt_linux_find_symbol_sys(const char *symbol) { return QFunctionPointer(dlsym(RTLD_DEFAULT, symbol)); @@ -305,8 +295,6 @@ QFunctionPointer QLibraryPrivate::resolve_sys(const char* symbol) QFunctionPointer address = 0; if (shl_findsym((shl_t*)&pHnd, symbol, TYPE_UNDEFINED, &address) < 0) address = 0; -#elif defined (QT_NO_DYNAMIC_LIBRARY) - QFunctionPointer address = 0; #else QFunctionPointer address = QFunctionPointer(dlsym(pHnd, symbol)); #endif diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index f11ac6548b..0afce7fcf0 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -968,10 +968,10 @@ QUuid QUuid::createUuid() if (!uuidseed.hasLocalData()) { int *pseed = new int; - static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(2); + static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(0); qsrand(*pseed = QDateTime::currentSecsSinceEpoch() + quintptr(&pseed) - + serial.fetchAndAddRelaxed(1)); + + 2 + serial.fetchAndAddRelaxed(1)); uuidseed.setLocalData(pseed); } #else diff --git a/src/corelib/thread/qmutex_linux.cpp b/src/corelib/thread/qmutex_linux.cpp index 17072f44d4..5f6e74ac6f 100644 --- a/src/corelib/thread/qmutex_linux.cpp +++ b/src/corelib/thread/qmutex_linux.cpp @@ -107,8 +107,6 @@ QT_BEGIN_NAMESPACE * waiting in the past. We then set the mutex to 0x0 and perform a FUTEX_WAKE. */ -static QBasicAtomicInt futexFlagSupport = Q_BASIC_ATOMIC_INITIALIZER(-1); - static inline int _q_futex(void *addr, int op, int val, const struct timespec *timeout) Q_DECL_NOTHROW { volatile int *int_addr = reinterpret_cast<volatile int *>(addr); diff --git a/src/corelib/thread/qreadwritelock_p.h b/src/corelib/thread/qreadwritelock_p.h index bb58dfab56..04dd45a2e1 100644 --- a/src/corelib/thread/qreadwritelock_p.h +++ b/src/corelib/thread/qreadwritelock_p.h @@ -74,7 +74,7 @@ public: int writerCount; int waitingReaders; int waitingWriters; - bool recursive; + const bool recursive; //Called with the mutex locked bool lockForWrite(int timeout); diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index c8777cac82..0828400733 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE */ QThreadData::QThreadData(int initialRefCount) - : _ref(initialRefCount), loopLevel(0), scopeLevel(0), thread(0), threadId(0), + : _ref(initialRefCount), loopLevel(0), scopeLevel(0), eventDispatcher(0), quitNow(false), canWait(true), isAdopted(false), requiresCoreApplication(true) { diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index 37eca9c612..885b4c0c1e 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -284,7 +284,7 @@ public: QStack<QEventLoop *> eventLoops; QPostEventList postEventList; QAtomicPointer<QThread> thread; - Qt::HANDLE threadId; + QAtomicPointer<void> threadId; QAtomicPointer<QAbstractEventDispatcher> eventDispatcher; QVector<void *> tls; FlaggedDebugSignatures flaggedSignatures; diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index c60742631b..f359d25a73 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -255,7 +255,7 @@ QThreadData *QThreadData::current(bool createIfNecessary) } data->deref(); data->isAdopted = true; - data->threadId = to_HANDLE(pthread_self()); + data->threadId.store(to_HANDLE(pthread_self())); if (!QCoreApplicationPrivate::theMainThread) QCoreApplicationPrivate::theMainThread = data->thread.load(); } @@ -335,7 +335,7 @@ void *QThreadPrivate::start(void *arg) thr->d_func()->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag)); } - data->threadId = to_HANDLE(pthread_self()); + data->threadId.store(to_HANDLE(pthread_self())); set_thread_data(data); data->ref(); @@ -352,7 +352,7 @@ void *QThreadPrivate::start(void *arg) // sets the name of the current thread. QString objectName = thr->objectName(); - pthread_t thread_id = from_HANDLE<pthread_t>(data->threadId); + pthread_t thread_id = from_HANDLE<pthread_t>(data->threadId.load()); if (Q_LIKELY(objectName.isEmpty())) setCurrentThreadName(thread_id, thr->metaObject()->className()); else @@ -651,7 +651,7 @@ void QThread::start(Priority priority) #endif code = pthread_create(&threadId, &attr, QThreadPrivate::start, this); } - d->data->threadId = to_HANDLE(threadId); + d->data->threadId.store(to_HANDLE(threadId)); pthread_attr_destroy(&attr); @@ -660,7 +660,7 @@ void QThread::start(Priority priority) d->running = false; d->finished = false; - d->data->threadId = 0; + d->data->threadId.store(nullptr); } } @@ -670,10 +670,10 @@ void QThread::terminate() Q_D(QThread); QMutexLocker locker(&d->mutex); - if (!d->data->threadId) + if (!d->data->threadId.load()) return; - int code = pthread_cancel(from_HANDLE<pthread_t>(d->data->threadId)); + int code = pthread_cancel(from_HANDLE<pthread_t>(d->data->threadId.load())); if (code) { qWarning("QThread::start: Thread termination error: %s", qPrintable(qt_error_string((code)))); @@ -686,7 +686,7 @@ bool QThread::wait(unsigned long time) Q_D(QThread); QMutexLocker locker(&d->mutex); - if (from_HANDLE<pthread_t>(d->data->threadId) == pthread_self()) { + if (from_HANDLE<pthread_t>(d->data->threadId.load()) == pthread_self()) { qWarning("QThread::wait: Thread tried to wait on itself"); return false; } @@ -728,7 +728,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority) int sched_policy; sched_param param; - if (pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId), &sched_policy, ¶m) != 0) { + if (pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId.load()), &sched_policy, ¶m) != 0) { // failed to get the scheduling policy, don't bother setting // the priority qWarning("QThread::setPriority: Cannot get scheduler parameters"); @@ -744,15 +744,15 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority) } param.sched_priority = prio; - int status = pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId), sched_policy, ¶m); + int status = pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId.load()), sched_policy, ¶m); # ifdef SCHED_IDLE // were we trying to set to idle priority and failed? if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) { // reset to lowest priority possible - pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId), &sched_policy, ¶m); + pthread_getschedparam(from_HANDLE<pthread_t>(data->threadId.load()), &sched_policy, ¶m); param.sched_priority = sched_get_priority_min(sched_policy); - pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId), sched_policy, ¶m); + pthread_setschedparam(from_HANDLE<pthread_t>(data->threadId.load()), sched_policy, ¶m); } # else Q_UNUSED(status); diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index a14c193bad..ef7bfc511d 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -96,7 +96,7 @@ void qt_create_tls() { if (qt_current_thread_data_tls_index != TLS_OUT_OF_INDEXES) return; - static QMutex mutex; + static QBasicMutex mutex; QMutexLocker locker(&mutex); qt_current_thread_data_tls_index = TlsAlloc(); } @@ -137,7 +137,7 @@ QThreadData *QThreadData::current(bool createIfNecessary) } threadData->deref(); threadData->isAdopted = true; - threadData->threadId = reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())); + threadData->threadId.store(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId()))); if (!QCoreApplicationPrivate::theMainThread) { QCoreApplicationPrivate::theMainThread = threadData->thread.load(); @@ -166,7 +166,7 @@ void QAdoptedThread::init() static QVector<HANDLE> qt_adopted_thread_handles; static QVector<QThread *> qt_adopted_qthreads; -static QMutex qt_adopted_thread_watcher_mutex; +static QBasicMutex qt_adopted_thread_watcher_mutex; static DWORD qt_adopted_thread_watcher_id = 0; static HANDLE qt_adopted_thread_wakeup = 0; @@ -351,7 +351,7 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi qt_create_tls(); TlsSetValue(qt_current_thread_data_tls_index, data); - data->threadId = reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId())); + data->threadId.store(reinterpret_cast<Qt::HANDLE>(quintptr(GetCurrentThreadId()))); QThread::setTerminationEnabled(false); diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp index 7ce757064f..2ecf8f729a 100644 --- a/src/corelib/thread/qthreadpool.cpp +++ b/src/corelib/thread/qthreadpool.cpp @@ -245,7 +245,8 @@ void QThreadPoolPrivate::startThread(QRunnable *runnable) { QScopedPointer <QThreadPoolThread> thread(new QThreadPoolThread(this)); thread->setObjectName(QLatin1String("Thread (pooled)")); - allThreads.insert(thread.data()); + Q_ASSERT(!allThreads.contains(thread.data())); // if this assert hits, we have an ABA problem (deleted threads don't get removed here) + allThreads.append(thread.data()); ++activeThreads; if (runnable->autoDelete()) @@ -265,7 +266,7 @@ void QThreadPoolPrivate::reset() while (!allThreads.empty()) { // move the contents of the set out so that we can iterate without the lock - QSet<QThreadPoolThread *> allThreadsCopy; + QList<QThreadPoolThread *> allThreadsCopy; allThreadsCopy.swap(allThreads); locker.unlock(); diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h index 5694bc8b10..ea8127efef 100644 --- a/src/corelib/thread/qthreadpool_p.h +++ b/src/corelib/thread/qthreadpool_p.h @@ -86,7 +86,7 @@ public: void stealAndRunRunnable(QRunnable *runnable); mutable QMutex mutex; - QSet<QThreadPoolThread *> allThreads; + QList<QThreadPoolThread *> allThreads; QQueue<QThreadPoolThread *> waitingThreads; QQueue<QThreadPoolThread *> expiredThreads; QVector<QPair<QRunnable *, int> > queue; diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp index c820892307..5d5ea4c8a1 100644 --- a/src/corelib/tools/qchar.cpp +++ b/src/corelib/tools/qchar.cpp @@ -101,7 +101,7 @@ QT_BEGIN_NAMESPACE In Qt, Unicode characters are 16-bit entities without any markup or structure. This class represents such an entity. It is lightweight, so it can be used everywhere. Most compilers treat - it like a \c{unsigned short}. + it like an \c{unsigned short}. QChar provides a full complement of testing/classification functions, converting to and from other formats, converting from diff --git a/src/corelib/tools/qcollator_icu.cpp b/src/corelib/tools/qcollator_icu.cpp index 26e2121092..ad98a187c5 100644 --- a/src/corelib/tools/qcollator_icu.cpp +++ b/src/corelib/tools/qcollator_icu.cpp @@ -145,7 +145,7 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const string.size(), (uint8_t *)result.data(), result.size()); } result.truncate(size); - return QCollatorSortKey(new QCollatorSortKeyPrivate(result)); + return QCollatorSortKey(new QCollatorSortKeyPrivate(std::move(result))); } return QCollatorSortKey(new QCollatorSortKeyPrivate(QByteArray())); diff --git a/src/corelib/tools/qcollator_macx.cpp b/src/corelib/tools/qcollator_macx.cpp index c4eb8e6978..d468272430 100644 --- a/src/corelib/tools/qcollator_macx.cpp +++ b/src/corelib/tools/qcollator_macx.cpp @@ -131,7 +131,7 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const ret.size(), &actualSize, ret.data()); } ret[actualSize] = 0; - return QCollatorSortKey(new QCollatorSortKeyPrivate(ret)); + return QCollatorSortKey(new QCollatorSortKeyPrivate(std::move(ret))); } int QCollatorSortKey::compare(const QCollatorSortKey &key) const diff --git a/src/corelib/tools/qcollator_p.h b/src/corelib/tools/qcollator_p.h index 6ac79e820d..c03a3431db 100644 --- a/src/corelib/tools/qcollator_p.h +++ b/src/corelib/tools/qcollator_p.h @@ -131,9 +131,10 @@ class QCollatorSortKeyPrivate : public QSharedData { friend class QCollator; public: - QCollatorSortKeyPrivate(const CollatorKeyType &key) + template <typename...T> + explicit QCollatorSortKeyPrivate(T &&...args) : QSharedData() - , m_key(key) + , m_key(std::forward<T>(args)...) { } diff --git a/src/corelib/tools/qcollator_posix.cpp b/src/corelib/tools/qcollator_posix.cpp index da424970e6..42413a4a82 100644 --- a/src/corelib/tools/qcollator_posix.cpp +++ b/src/corelib/tools/qcollator_posix.cpp @@ -110,7 +110,7 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const } result.resize(size+1); result[size] = 0; - return QCollatorSortKey(new QCollatorSortKeyPrivate(result)); + return QCollatorSortKey(new QCollatorSortKeyPrivate(std::move(result))); } int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const diff --git a/src/corelib/tools/qcollator_win.cpp b/src/corelib/tools/qcollator_win.cpp index 44beaeaf75..bce896278e 100644 --- a/src/corelib/tools/qcollator_win.cpp +++ b/src/corelib/tools/qcollator_win.cpp @@ -147,7 +147,7 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const if (finalSize == 0) { qWarning() << "there were problems when generating the ::sortKey by LCMapStringW with error:" << GetLastError(); } - return QCollatorSortKey(new QCollatorSortKeyPrivate(ret)); + return QCollatorSortKey(new QCollatorSortKeyPrivate(std::move(ret))); } int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index be53c51c48..f6164e2297 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -230,12 +230,39 @@ // SSE4.2 intrinsics #if defined(__SSE4_2__) || (defined(QT_COMPILER_SUPPORTS_SSE4_2) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)) #include <nmmintrin.h> + +# if defined(__SSE4_2__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) +// POPCNT instructions: +// All processors that support SSE4.2 support POPCNT +// (but neither MSVC nor the Intel compiler define this macro) +# define __POPCNT__ 1 +# endif #endif // AVX intrinsics #if defined(__AVX__) || (defined(QT_COMPILER_SUPPORTS_AVX) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)) // immintrin.h is the ultimate header, we don't need anything else after this #include <immintrin.h> + +# if defined(__AVX__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) +// AES, PCLMULQDQ instructions: +// All processors that support AVX support AES, PCLMULQDQ +// (but neither MSVC nor the Intel compiler define these macros) +# define __AES__ 1 +# define __PCLMUL__ 1 +# endif + +# if defined(__AVX2__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) +// F16C & RDRAND instructions: +// All processors that support AVX2 support F16C & RDRAND: +// (but neither MSVC nor the Intel compiler define these macros) +# define __F16C__ 1 +# define __RDRND__ 1 +# endif +#endif + +#if defined(__AES__) || defined(__PCLMUL__) +# include <wmmintrin.h> #endif #define QT_FUNCTION_TARGET_STRING_SSE2 "sse2" @@ -255,7 +282,10 @@ #define QT_FUNCTION_TARGET_STRING_AVX512IFMA "avx512ifma" #define QT_FUNCTION_TARGET_STRING_AVX512VBMI "avx512vbmi" -#define QT_FUNCTION_TARGET_STRING_F16C "f16c" +#define QT_FUNCTION_TARGET_STRING_AES "aes,sse4.2" +#define QT_FUNCTION_TARGET_STRING_PCLMUL "pclmul,sse4.2" +#define QT_FUNCTION_TARGET_STRING_POPCNT "popcnt" +#define QT_FUNCTION_TARGET_STRING_F16C "f16c,avx" #define QT_FUNCTION_TARGET_STRING_RDRAND "rdrnd" #define QT_FUNCTION_TARGET_STRING_BMI "bmi" #define QT_FUNCTION_TARGET_STRING_BMI2 "bmi2" diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 5da45181d9..8e7f0e50d3 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -4635,6 +4635,8 @@ QByteArray QString::toLatin1_helper_inplace(QString &s) QByteArray QString::toLocal8Bit_helper(const QChar *data, int size) { + if (!data) + return QByteArray(); #ifndef QT_NO_TEXTCODEC QTextCodec *localeCodec = QTextCodec::codecForLocale(); if (localeCodec) @@ -10394,6 +10396,8 @@ static inline bool qt_ends_with(const QChar *haystack, int haystackLen, */ QByteArray QStringRef::toLatin1() const { + if (isNull()) + return QByteArray(); return QString::toLatin1_helper(unicode(), length()); } @@ -10432,9 +10436,11 @@ QByteArray QStringRef::toLatin1() const QByteArray QStringRef::toLocal8Bit() const { #ifndef QT_NO_TEXTCODEC - QTextCodec *localeCodec = QTextCodec::codecForLocale(); - if (localeCodec) - return localeCodec->fromUnicode(unicode(), length()); + if (!isNull()) { + QTextCodec *localeCodec = QTextCodec::codecForLocale(); + if (localeCodec) + return localeCodec->fromUnicode(unicode(), length()); + } #endif // QT_NO_TEXTCODEC return toLatin1(); } diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 87d9c07a8b..36edcc7242 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -147,15 +147,10 @@ typedef QLatin1String QLatin1Literal; typedef QTypedArrayData<ushort> QStringData; -#if defined(Q_COMPILER_UNICODE_STRINGS) - -#define QT_UNICODE_LITERAL_II(str) u"" str -typedef char16_t qunicodechar; - -#elif defined(Q_OS_WIN) \ - || (defined(__SIZEOF_WCHAR_T__) && __SIZEOF_WCHAR_T__ == 2) \ - || (!defined(__SIZEOF_WCHAR_T__) && defined(WCHAR_MAX) && (WCHAR_MAX - 0 < 65536)) -// wchar_t is 2 bytes +#if defined(Q_OS_WIN) && !defined(Q_COMPILER_UNICODE_STRINGS) +// fall back to wchar_t if the a Windows compiler does not +// support Unicode string literals, assuming wchar_t is 2 bytes +// on that platform (sanity-checked by static_assert further below) #if defined(Q_CC_MSVC) # define QT_UNICODE_LITERAL_II(str) L##str @@ -165,21 +160,22 @@ typedef char16_t qunicodechar; typedef wchar_t qunicodechar; #else +// all our supported compilers support Unicode string literals, +// even if their Q_COMPILER_UNICODE_STRING has been revoked due +// to lacking stdlib support. But QStringLiteral only needs the +// core language feature, so just use u"" here unconditionally: -#define QT_NO_UNICODE_LITERAL -typedef ushort qunicodechar; +#define QT_UNICODE_LITERAL_II(str) u"" str +typedef char16_t qunicodechar; #endif Q_STATIC_ASSERT_X(sizeof(qunicodechar) == 2, "qunicodechar must typedef an integral type of size 2"); -#ifndef QT_NO_UNICODE_LITERAL -# define QT_UNICODE_LITERAL(str) QT_UNICODE_LITERAL_II(str) -# if defined(Q_COMPILER_LAMBDA) - -# define QStringLiteral(str) \ - ([]() -> QString { \ +#define QT_UNICODE_LITERAL(str) QT_UNICODE_LITERAL_II(str) +#define QStringLiteral(str) \ + ([]() Q_DECL_NOEXCEPT -> QString { \ enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \ static const QStaticStringData<Size> qstring_literal = { \ Q_STATIC_STRING_DATA_HEADER_INITIALIZER(Size), \ @@ -190,17 +186,6 @@ Q_STATIC_ASSERT_X(sizeof(qunicodechar) == 2, }()) \ /**/ -# endif -#endif // QT_NO_UNICODE_LITERAL - -#ifndef QStringLiteral -// no lambdas, not GCC, or GCC in C++98 mode with 4-byte wchar_t -// fallback, return a temporary QString -// source code is assumed to be encoded in UTF-8 - -# define QStringLiteral(str) QString::fromUtf8("" str "", sizeof(str) - 1) -#endif - #define Q_STATIC_STRING_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset) \ { Q_REFCOUNT_INITIALIZE_STATIC, size, 0, 0, offset } \ /**/ @@ -535,9 +520,9 @@ public: QByteArray toUtf8() && Q_REQUIRED_RESULT { return toUtf8_helper(*this); } QByteArray toLocal8Bit() const & Q_REQUIRED_RESULT - { return toLocal8Bit_helper(constData(), size()); } + { return toLocal8Bit_helper(isNull() ? nullptr : constData(), size()); } QByteArray toLocal8Bit() && Q_REQUIRED_RESULT - { return toLocal8Bit_helper(constData(), size()); } + { return toLocal8Bit_helper(isNull() ? nullptr : constData(), size()); } #else QByteArray toLatin1() const Q_REQUIRED_RESULT; QByteArray toUtf8() const Q_REQUIRED_RESULT; diff --git a/src/corelib/tools/qstring_compat.cpp b/src/corelib/tools/qstring_compat.cpp index 300f8467b1..45bb816e4b 100644 --- a/src/corelib/tools/qstring_compat.cpp +++ b/src/corelib/tools/qstring_compat.cpp @@ -80,7 +80,7 @@ QByteArray QString::toLatin1() const QByteArray QString::toLocal8Bit() const { - return toLocal8Bit_helper(constData(), size()); + return toLocal8Bit_helper(isNull() ? nullptr : constData(), size()); } QByteArray QString::toUtf8() const diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.qdoc index 0ea47b1a1a..0ea47b1a1a 100644 --- a/src/corelib/tools/qvector.cpp +++ b/src/corelib/tools/qvector.qdoc diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index 4c215474fa..b93ec824ed 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -110,7 +110,6 @@ SOURCES += \ tools/qtextboundaryfinder.cpp \ tools/qtimeline.cpp \ tools/qunicodetools.cpp \ - tools/qvector.cpp \ tools/qvsnprintf.cpp \ tools/qversionnumber.cpp diff --git a/src/gui/configure.json b/src/gui/configure.json index 6d0848c9f0..08e50db906 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -520,7 +520,7 @@ }, "libinput-axis-api": { "label": "axis API in libinput", - "condition": "tests.libinput_axis_api", + "condition": "features.libinput && tests.libinput_axis_api", "output": [ "privateFeature" ] }, "lgmon": { @@ -614,8 +614,7 @@ "eglfs": { "label": "EGLFS", "section": "Platform plugins", - "autoDetect": "!config.android && !config.win32", - "condition": "features.egl", + "condition": "!config.android && !config.darwin && !config.win32 && features.egl", "output": [ "privateFeature" ] }, "eglfs_brcm": { diff --git a/src/gui/doc/snippets/code/src_gui_text_qsyntaxhighlighter.cpp b/src/gui/doc/snippets/code/src_gui_text_qsyntaxhighlighter.cpp index da960088b7..bb27eb9612 100644 --- a/src/gui/doc/snippets/code/src_gui_text_qsyntaxhighlighter.cpp +++ b/src/gui/doc/snippets/code/src_gui_text_qsyntaxhighlighter.cpp @@ -60,14 +60,13 @@ void MyHighlighter::highlightBlock(const QString &text) QTextCharFormat myClassFormat; myClassFormat.setFontWeight(QFont::Bold); myClassFormat.setForeground(Qt::darkMagenta); - QString pattern = "\\bMy[A-Za-z]+\\b"; - QRegExp expression(pattern); - int index = text.indexOf(expression); - while (index >= 0) { - int length = expression.matchedLength(); - setFormat(index, length, myClassFormat); - index = text.indexOf(expression, index + length); + QRegularExpression expression("\\bMy[A-Za-z]+\\b"); + QRegularExpressionMatchIterator i = expression.globalMatch(text); + while (i.hasNext()) + { + QRegularExpressionMatch match = i.next(); + setFormat(match.capturedStart(), match.capturedLength(), myClassFormat); } } //! [1] @@ -77,8 +76,8 @@ void MyHighlighter::highlightBlock(const QString &text) QTextCharFormat multiLineCommentFormat; multiLineCommentFormat.setForeground(Qt::red); -QRegExp startExpression("/\\*"); -QRegExp endExpression("\\*/"); +QRegularExpression startExpression("/\\*"); +QRegularExpression endExpression("\\*/"); setCurrentBlockState(0); @@ -87,14 +86,15 @@ if (previousBlockState() != 1) startIndex = text.indexOf(startExpression); while (startIndex >= 0) { - int endIndex = text.indexOf(endExpression, startIndex); + QRegularExpressionMatch endMatch; + int endIndex = text.indexOf(endExpression, startIndex, &endMatch); int commentLength; if (endIndex == -1) { setCurrentBlockState(1); commentLength = text.length() - startIndex; } else { commentLength = endIndex - startIndex - + endExpression.matchedLength(); + + endMatch.capturedLength(); } setFormat(startIndex, commentLength, multiLineCommentFormat); startIndex = text.indexOf(startExpression, @@ -104,25 +104,6 @@ while (startIndex >= 0) { //! [3] -void MyHighlighter::highlightBlock(const QString &text) -{ - QTextCharFormat myClassFormat; - myClassFormat.setFontWeight(QFont::Bold); - myClassFormat.setForeground(Qt::darkMagenta); - QString pattern = "\\bMy[A-Za-z]+\\b"; - - QRegExp expression(pattern); - int index = text.indexOf(expression); - while (index >= 0) { - int length = expression.matchedLength(); - setFormat(index, length, myClassFormat); - index = text.indexOf(expression, index + length); - } - } -//! [3] - - -//! [4] struct ParenthesisInfo { QChar char; @@ -133,4 +114,4 @@ struct BlockData : public QTextBlockUserData { QVector<ParenthesisInfo> parentheses; }; -//! [4] +//! [3] diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 17734f05f3..7d6cd50bac 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -97,7 +97,11 @@ QT_BEGIN_NAMESPACE \value On Display the pixmap when the widget is in an "on" state */ -static QBasicAtomicInt serialNumCounter = Q_BASIC_ATOMIC_INITIALIZER(1); +static int nextSerialNumCounter() +{ + static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(0); + return 1 + serial.fetchAndAddRelaxed(1); +} static void qt_cleanup_icon_cache(); namespace { @@ -139,7 +143,7 @@ static qreal qt_effective_device_pixel_ratio(QWindow *window = 0) QIconPrivate::QIconPrivate(QIconEngine *e) : engine(e), ref(1), - serialNum(serialNumCounter.fetchAndAddRelaxed(1)), + serialNum(nextSerialNumCounter()), detach_no(0), is_mask(false) { diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 9870e19cec..c1ea053204 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -89,12 +89,16 @@ static QImage rotated90(const QImage &src); static QImage rotated180(const QImage &src); static QImage rotated270(const QImage &src); -QBasicAtomicInt qimage_serial_number = Q_BASIC_ATOMIC_INITIALIZER(1); +static int next_qimage_serial_number() +{ + static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(0); + return 1 + serial.fetchAndAddRelaxed(1); +} QImageData::QImageData() : ref(0), width(0), height(0), depth(0), nbytes(0), devicePixelRatio(1.0), data(0), format(QImage::Format_ARGB32), bytes_per_line(0), - ser_no(qimage_serial_number.fetchAndAddRelaxed(1)), + ser_no(next_qimage_serial_number()), detach_no(0), dpmx(qt_defaultDpiX() * 100 / qreal(2.54)), dpmy(qt_defaultDpiY() * 100 / qreal(2.54)), diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 2a0bdeb7c1..50fad1566c 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -46,6 +46,22 @@ QT_BEGIN_NAMESPACE +struct QDefaultColorTables +{ + QDefaultColorTables() + : gray(256), alpha(256) + { + for (int i = 0; i < 256; ++i) { + gray[i] = qRgb(i, i, i); + alpha[i] = qRgba(0, 0, 0, i); + } + } + + QVector<QRgb> gray, alpha; +}; + +Q_GLOBAL_STATIC(QDefaultColorTables, defaultColorTables); + // table to flip bits static const uchar bitflip[256] = { /* @@ -1952,11 +1968,7 @@ static void convert_Alpha8_to_Indexed8(QImageData *dest, const QImageData *src, memcpy(dest->data, src->data, src->bytes_per_line * src->height); - QVector<QRgb> colors(256); - for (int i=0; i<256; ++i) - colors[i] = qRgba(0, 0, 0, i); - - dest->colortable = colors; + dest->colortable = defaultColorTables->alpha; } static void convert_Grayscale8_to_Indexed8(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) @@ -1966,22 +1978,15 @@ static void convert_Grayscale8_to_Indexed8(QImageData *dest, const QImageData *s memcpy(dest->data, src->data, src->bytes_per_line * src->height); - QVector<QRgb> colors(256); - for (int i=0; i<256; ++i) - colors[i] = qRgb(i, i, i); - dest->colortable = colors; + dest->colortable = defaultColorTables->gray; } static bool convert_Alpha8_to_Indexed8_inplace(QImageData *data, Qt::ImageConversionFlags) { Q_ASSERT(data->format == QImage::Format_Alpha8); - QVector<QRgb> colors(256); - for (int i=0; i<256; ++i) - colors[i] = qRgba(0, 0, 0, i); - - data->colortable = colors; + data->colortable = defaultColorTables->alpha; data->format = QImage::Format_Indexed8; return true; @@ -1991,11 +1996,7 @@ static bool convert_Grayscale8_to_Indexed8_inplace(QImageData *data, Qt::ImageCo { Q_ASSERT(data->format == QImage::Format_Grayscale8); - QVector<QRgb> colors(256); - for (int i=0; i<256; ++i) - colors[i] = qRgb(i, i, i); - - data->colortable = colors; + data->colortable = defaultColorTables->gray; data->format = QImage::Format_Indexed8; return true; diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index e4eabc815e..7c596d5ae5 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -2162,7 +2162,7 @@ void QGuiApplicationPrivate::processActivatedEvent(QWindowSystemInterfacePrivate void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfacePrivate::WindowStateChangedEvent *wse) { if (QWindow *window = wse->window.data()) { - QWindowStateChangeEvent e(window->windowState()); + QWindowStateChangeEvent e(wse->oldState); window->d_func()->windowState = wse->newState; QGuiApplication::sendSpontaneousEvent(window, &e); } diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index bfb2deff50..5062bd1e77 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -561,7 +561,8 @@ bool QPlatformWindow::isAlertState() const // Return the effective screen for the initial geometry of a window. In a // multimonitor-setup, try to find the right screen by checking the transient // parent or the mouse cursor for parentless windows (cf QTBUG-34204, -// QDialog::adjustPosition()). +// QDialog::adjustPosition()), unless a non-primary screen has been set, +// in which case we try to respect that. static inline const QScreen *effectiveScreen(const QWindow *window) { if (!window) @@ -569,6 +570,8 @@ static inline const QScreen *effectiveScreen(const QWindow *window) const QScreen *screen = window->screen(); if (!screen) return QGuiApplication::primaryScreen(); + if (screen != QGuiApplication::primaryScreen()) + return screen; #ifndef QT_NO_CURSOR const QList<QScreen *> siblings = screen->virtualSiblings(); if (siblings.size() > 1) { diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 47277abea3..9d41a72072 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -155,8 +155,17 @@ QWindow::QWindow(QScreen *targetScreen) , QSurface(QSurface::Window) { Q_D(QWindow); - d->connectToScreen(targetScreen ? targetScreen : QGuiApplication::primaryScreen()); - d->init(); + d->init(targetScreen); +} + +static QWindow *nonDesktopParent(QWindow *parent) +{ + if (parent && parent->type() == Qt::Desktop) { + qWarning("QWindows can not be reparented into desktop windows"); + return nullptr; + } + + return parent; } /*! @@ -170,14 +179,8 @@ QWindow::QWindow(QScreen *targetScreen) \sa setParent() */ QWindow::QWindow(QWindow *parent) - : QObject(*new QWindowPrivate(), parent) - , QSurface(QSurface::Window) + : QWindow(*new QWindowPrivate(), parent) { - Q_D(QWindow); - d->parentWindow = parent; - if (!parent) - d->connectToScreen(QGuiApplication::primaryScreen()); - d->init(); } /*! @@ -193,13 +196,10 @@ QWindow::QWindow(QWindow *parent) \sa setParent() */ QWindow::QWindow(QWindowPrivate &dd, QWindow *parent) - : QObject(dd, parent) + : QObject(dd, nonDesktopParent(parent)) , QSurface(QSurface::Window) { Q_D(QWindow); - d->parentWindow = parent; - if (!parent) - d->connectToScreen(QGuiApplication::primaryScreen()); d->init(); } @@ -215,10 +215,15 @@ QWindow::~QWindow() QGuiApplicationPrivate::instance()->modalWindowList.removeOne(this); } -void QWindowPrivate::init() +void QWindowPrivate::init(QScreen *targetScreen) { Q_Q(QWindow); + parentWindow = static_cast<QWindow *>(q->QObject::parent()); + + if (!parentWindow) + connectToScreen(targetScreen ? targetScreen : QGuiApplication::primaryScreen()); + // If your application aborts here, you are probably creating a QWindow // before the screen list is populated. if (Q_UNLIKELY(!parentWindow && !topLevelScreen)) { @@ -532,7 +537,9 @@ void QWindow::setVisible(bool visible) // can defer creation until the parent is created or we're re-parented. if (parent() && !parent()->handle()) return; - else + + // We only need to create the window if it's being shown + if (visible) create(); } @@ -574,7 +581,8 @@ void QWindow::setVisible(bool visible) d->applyCursor(); #endif - d->platformWindow->setVisible(visible); + if (d->platformWindow) + d->platformWindow->setVisible(visible); if (!visible) { QHideEvent hideEvent; @@ -668,6 +676,8 @@ QWindow *QWindow::parent() const */ void QWindow::setParent(QWindow *parent) { + parent = nonDesktopParent(parent); + Q_D(QWindow); if (d->parentWindow == parent) return; diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index d1727a1c57..272401453a 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -113,7 +113,7 @@ public: { } - void init(); + void init(QScreen *targetScreen = nullptr); void maybeQuitOnLastWindowClosed(); #ifndef QT_NO_CURSOR diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index b273682b97..7ad4f57198 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -241,11 +241,15 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowActivated, QWindow *window, Qt::Fo QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e); } -void QWindowSystemInterface::handleWindowStateChanged(QWindow *window, Qt::WindowState newState) +QT_DEFINE_QPA_EVENT_HANDLER(void, handleWindowStateChanged, QWindow *window, Qt::WindowState newState, int oldState) { + Q_ASSERT(window); + if (oldState < Qt::WindowNoState) + oldState = window->windowState(); + QWindowSystemInterfacePrivate::WindowStateChangedEvent *e = - new QWindowSystemInterfacePrivate::WindowStateChangedEvent(window, newState); - QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); + new QWindowSystemInterfacePrivate::WindowStateChangedEvent(window, newState, Qt::WindowState(oldState)); + QWindowSystemInterfacePrivate::handleWindowSystemEvent<Delivery>(e); } void QWindowSystemInterface::handleWindowScreenChanged(QWindow *window, QScreen *screen) diff --git a/src/gui/kernel/qwindowsysteminterface.h b/src/gui/kernel/qwindowsysteminterface.h index 11864e7adc..253584314c 100644 --- a/src/gui/kernel/qwindowsysteminterface.h +++ b/src/gui/kernel/qwindowsysteminterface.h @@ -175,7 +175,8 @@ public: template<typename Delivery = QWindowSystemInterface::DefaultDelivery> static void handleWindowActivated(QWindow *window, Qt::FocusReason r = Qt::OtherFocusReason); - static void handleWindowStateChanged(QWindow *window, Qt::WindowState newState); + template<typename Delivery = QWindowSystemInterface::DefaultDelivery> + static void handleWindowStateChanged(QWindow *window, Qt::WindowState newState, int oldState = -1); static void handleWindowScreenChanged(QWindow *window, QScreen *newScreen); static void handleApplicationStateChanged(Qt::ApplicationState newState, bool forcePropagate = false); diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h index 1db60e8cb8..1bcc79552d 100644 --- a/src/gui/kernel/qwindowsysteminterface_p.h +++ b/src/gui/kernel/qwindowsysteminterface_p.h @@ -168,12 +168,13 @@ public: class WindowStateChangedEvent : public WindowSystemEvent { public: - WindowStateChangedEvent(QWindow *_window, Qt::WindowState _newState) - : WindowSystemEvent(WindowStateChanged), window(_window), newState(_newState) + WindowStateChangedEvent(QWindow *_window, Qt::WindowState _newState, Qt::WindowState _oldState) + : WindowSystemEvent(WindowStateChanged), window(_window), newState(_newState), oldState(_oldState) { } QPointer<QWindow> window; Qt::WindowState newState; + Qt::WindowState oldState; }; class WindowScreenChangedEvent : public WindowSystemEvent { diff --git a/src/gui/opengl/qopengl.h b/src/gui/opengl/qopengl.h index cd44ddfe4d..a76da20910 100644 --- a/src/gui/opengl/qopengl.h +++ b/src/gui/opengl/qopengl.h @@ -83,17 +83,16 @@ typedef void* GLeglImageOES; # else // "uncontrolled" ES2 platforms -// In "es2" builds (QT_OPENGL_ES_2) additional defines indicate if ES -// 3.0 or higher is available. In this case include the corresponding -// header. These are backwards compatible and it should be safe to -// include headers on top of each other, meaning that applications can -// include gl2.h even if gl31.h gets included here. - -// NB! This file contains the only usages of the ES_3 and ES_3_1 -// macros. They are useless for pretty much anything else. The fact -// that Qt was built against an SDK with f.ex. ES 2 only does not mean -// applications cannot target ES 3. Therefore QOpenGLFunctions and -// friends do everything dynamically and never rely on these macros. +// In "es2" builds (QT_OPENGL_ES_2) additional defines indicate GLES 3.0 or +// higher is available *at build time*. In this case include the corresponding +// header. These are backwards compatible and it should be safe to include +// headers on top of each other, meaning that applications can include gl2.h +// even if gl31.h gets included here. + +// NB! The fact that Qt was built against an SDK with GLES 2 only does not mean +// applications cannot be deployed on a GLES 3 system. Therefore +// QOpenGLFunctions and friends must do everything dynamically and must not rely +// on these macros, except in special cases for controlled build/run environments. // Some Khronos headers use the ext proto guard in the standard headers as well, // which is bad. Work it around, but avoid spilling over to the ext header. diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp index c9552fd321..cc8af16bfe 100644 --- a/src/gui/opengl/qopenglshaderprogram.cpp +++ b/src/gui/opengl/qopenglshaderprogram.cpp @@ -215,10 +215,12 @@ Q_LOGGING_CATEGORY(DBG_SHADER_CACHE, "qt.opengl.diskcache") #define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE #endif +#ifndef QT_OPENGL_ES_2 static inline bool isFormatGLES(const QSurfaceFormat &f) { return (f.renderableType() == QSurfaceFormat::OpenGLES); } +#endif static inline bool supportsGeometry(const QSurfaceFormat &f) { diff --git a/src/gui/opengl/qopengltextureglyphcache.cpp b/src/gui/opengl/qopengltextureglyphcache.cpp index 62b069a1d0..556d52ef99 100644 --- a/src/gui/opengl/qopengltextureglyphcache.cpp +++ b/src/gui/opengl/qopengltextureglyphcache.cpp @@ -47,7 +47,11 @@ QT_BEGIN_NAMESPACE -QBasicAtomicInt qopengltextureglyphcache_serial_number = Q_BASIC_ATOMIC_INITIALIZER(1); +static int next_qopengltextureglyphcache_serial_number() +{ + static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(0); + return 1 + serial.fetchAndAddRelaxed(1); +} QOpenGLTextureGlyphCache::QOpenGLTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix) : QImageTextureGlyphCache(format, matrix) @@ -55,7 +59,7 @@ QOpenGLTextureGlyphCache::QOpenGLTextureGlyphCache(QFontEngine::GlyphFormat form , pex(0) , m_blitProgram(0) , m_filterMode(Nearest) - , m_serialNumber(qopengltextureglyphcache_serial_number.fetchAndAddRelaxed(1)) + , m_serialNumber(next_qopengltextureglyphcache_serial_number()) , m_buffer(QOpenGLBuffer::VertexBuffer) { #ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 4671c5cecf..654be5690b 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1144,6 +1144,11 @@ static QRgba64 *QT_FASTCALL destFetch64uint32(QRgba64 *buffer, QRasterBuffer *ra return const_cast<QRgba64 *>(layout->convertToARGB64PM(buffer, src, length, 0, 0)); } +static QRgba64 * QT_FASTCALL destFetch64Undefined(QRgba64 *buffer, QRasterBuffer *, int, int, int) +{ + return buffer; +} + static DestFetchProc destFetchProc[QImage::NImageFormats] = { 0, // Format_Invalid @@ -1176,8 +1181,8 @@ static DestFetchProc destFetchProc[QImage::NImageFormats] = static DestFetchProc64 destFetchProc64[QImage::NImageFormats] = { 0, // Format_Invalid - destFetch64, // Format_Mono, - destFetch64, // Format_MonoLSB + 0, // Format_Mono, + 0, // Format_MonoLSB 0, // Format_Indexed8 destFetch64uint32, // Format_RGB32 destFetch64uint32, // Format_ARGB32, @@ -3737,27 +3742,23 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in op.destFetch = destFetchProc[data->rasterBuffer->format]; op.destFetch64 = destFetchProc64[data->rasterBuffer->format]; - if (op.mode == QPainter::CompositionMode_Source) { - switch (data->rasterBuffer->format) { - case QImage::Format_RGB32: - case QImage::Format_ARGB32_Premultiplied: - // don't clear destFetch as it sets up the pointer correctly to save one copy - break; - default: { - if (data->type == QSpanData::Texture && data->texture.const_alpha != 256) + if (op.mode == QPainter::CompositionMode_Source && + (data->type != QSpanData::Texture || data->texture.const_alpha == 256)) { + const QSpan *lastSpan = spans + spanCount; + bool alphaSpans = false; + while (spans < lastSpan) { + if (spans->coverage != 255) { + alphaSpans = true; break; - const QSpan *lastSpan = spans + spanCount; - bool alphaSpans = false; - while (spans < lastSpan) { - if (spans->coverage != 255) { - alphaSpans = true; - break; - } - ++spans; } - if (!alphaSpans) - op.destFetch = 0; + ++spans; } + if (!alphaSpans) { + // If all spans are opaque we do not need to fetch dest. + // But don't clear passthrough destFetch as they are just as fast and save destStore. + if (op.destFetch != destFetchARGB32P) + op.destFetch = 0; + op.destFetch64 = destFetch64Undefined; } } diff --git a/src/gui/painting/qrgba64_p.h b/src/gui/painting/qrgba64_p.h index 2a17d8a624..7776a5b08a 100644 --- a/src/gui/painting/qrgba64_p.h +++ b/src/gui/painting/qrgba64_p.h @@ -256,11 +256,12 @@ Q_ALWAYS_INLINE uint16x4_t addWithSaturation(uint16x4_t a, uint16x4_t b) inline QRgba64 rgbBlend(QRgba64 d, QRgba64 s, uint rgbAlpha) { QRgba64 blend; -#ifdef __SSE2__ +#if defined(__SSE2__) __m128i vd = _mm_loadl_epi64((const __m128i *)&d); __m128i vs = _mm_loadl_epi64((const __m128i *)&s); __m128i va = _mm_cvtsi32_si128(rgbAlpha); va = _mm_unpacklo_epi8(va, va); + va = _mm_shufflelo_epi16(va, _MM_SHUFFLE(3, 0, 1, 2)); __m128i vb = _mm_xor_si128(_mm_set1_epi16(-1), va); vs = _mm_unpacklo_epi16(_mm_mullo_epi16(vs, va), _mm_mulhi_epu16(vs, va)); @@ -275,7 +276,7 @@ inline QRgba64 rgbBlend(QRgba64 d, QRgba64 s, uint rgbAlpha) #elif defined(__ARM_NEON__) uint16x4_t vd = vreinterpret_u16_u64(vmov_n_u64(d)); uint16x4_t vs = vreinterpret_u16_u64(vmov_n_u64(s)); - uint8x8_t va8 = vreinterpret_u8_u32(vmov_n_u32(rgbAlpha)); + uint8x8_t va8 = vreinterpret_u8_u32(vmov_n_u32(ARGB2RGBA(rgbAlpha))); uint16x4_t va = vreinterpret_u16_u8(vzip_u8(va8, va8).val[0]); uint16x4_t vb = vdup_n_u16(0xffff); vb = vsub_u16(vb, va); diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h index 9f79e9934e..c1594531ea 100644 --- a/src/gui/text/qcssparser_p.h +++ b/src/gui/text/qcssparser_p.h @@ -75,6 +75,10 @@ QT_END_NAMESPACE #if defined(Q_OS_INTEGRITY) # undef Value #endif +// Hurd has #define TILDE 0x00080000 from <sys/ioctl.h> +#if defined(TILDE) +# undef TILDE +#endif #define QT_CSS_DECLARE_TYPEINFO(Class, Type) \ } /* namespace QCss */ \ diff --git a/src/gui/text/qsyntaxhighlighter.cpp b/src/gui/text/qsyntaxhighlighter.cpp index d5541b0df1..8834afc80e 100644 --- a/src/gui/text/qsyntaxhighlighter.cpp +++ b/src/gui/text/qsyntaxhighlighter.cpp @@ -243,6 +243,8 @@ void QSyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block) \snippet code/src_gui_text_qsyntaxhighlighter.cpp 1 + \target QSyntaxHighlighter multiblock + Some syntaxes can have constructs that span several text blocks. For example, a C++ syntax highlighter should be able to cope with \c{/}\c{*...*}\c{/} multiline comments. To deal with @@ -267,12 +269,12 @@ void QSyntaxHighlighterPrivate::reformatBlock(const QTextBlock &block) \snippet code/src_gui_text_qsyntaxhighlighter.cpp 2 In the example above, we first set the current block state to - 0. Then, if the previous block ended within a comment, we higlight + 0. Then, if the previous block ended within a comment, we highlight from the beginning of the current block (\c {startIndex = 0}). Otherwise, we search for the given start expression. If the specified end expression cannot be found in the text block, we change the current block state by calling setCurrentBlockState(), - and make sure that the rest of the block is higlighted. + and make sure that the rest of the block is highlighted. In addition you can query the current formatting and user data using the format() and currentBlockUserData() functions @@ -411,33 +413,12 @@ void QSyntaxHighlighter::rehighlightBlock(const QTextBlock &block) setFormat() as often as necessary to apply any font and color changes that you require. For example: - \snippet code/src_gui_text_qsyntaxhighlighter.cpp 3 - - Some syntaxes can have constructs that span several text - blocks. For example, a C++ syntax highlighter should be able to - cope with \c{/}\c{*...*}\c{/} multiline comments. To deal with - these cases it is necessary to know the end state of the previous - text block (e.g. "in comment"). - - Inside your highlightBlock() implementation you can query the end - state of the previous text block using the previousBlockState() - function. After parsing the block you can save the last state - using setCurrentBlockState(). - - The currentBlockState() and previousBlockState() functions return - an int value. If no state is set, the returned value is -1. You - can designate any other value to identify any given state using - the setCurrentBlockState() function. Once the state is set the - QTextBlock keeps that value until it is set set again or until the - corresponding paragraph of text gets deleted. + \snippet code/src_gui_text_qsyntaxhighlighter.cpp 1 - For example, if you're writing a simple C++ syntax highlighter, - you might designate 1 to signify "in comment". For a text block - that ended in the middle of a comment you'd set 1 using - setCurrentBlockState, and for other paragraphs you'd set 0. - In your parsing code if the return value of previousBlockState() - is 1, you would highlight the text as a C++ comment until you - reached the closing \c{*}\c{/}. + See the \l{QSyntaxHighlighter multiblock}{Detailed Description} for + examples of using setCurrentBlockState(), currentBlockState() + and previousBlockState() to handle syntaxes with constructs that + span several text blocks \sa previousBlockState(), setFormat(), setCurrentBlockState() */ @@ -581,7 +562,7 @@ void QSyntaxHighlighter::setCurrentBlockState(int newState) and store their relative position and the actual QChar in a simple class derived from QTextBlockUserData: - \snippet code/src_gui_text_qsyntaxhighlighter.cpp 4 + \snippet code/src_gui_text_qsyntaxhighlighter.cpp 3 During cursor navigation in the associated editor, you can ask the current QTextBlock (retrieved using the QTextCursor::block() diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp index 52b9dd9169..e9cb3aa498 100644 --- a/src/network/access/qftp.cpp +++ b/src/network/access/qftp.cpp @@ -246,22 +246,25 @@ public: } data; bool is_ba; - static QBasicAtomicInt idCounter; }; -QBasicAtomicInt QFtpCommand::idCounter = Q_BASIC_ATOMIC_INITIALIZER(1); +static int nextId() +{ + static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(0); + return 1 + counter.fetchAndAddRelaxed(1); +} QFtpCommand::QFtpCommand(QFtp::Command cmd, const QStringList &raw, const QByteArray &ba) : command(cmd), rawCmds(raw), is_ba(true) { - id = idCounter.fetchAndAddRelaxed(1); + id = nextId(); data.ba = new QByteArray(ba); } QFtpCommand::QFtpCommand(QFtp::Command cmd, const QStringList &raw, QIODevice *dev) : command(cmd), rawCmds(raw), is_ba(false) { - id = idCounter.fetchAndAddRelaxed(1); + id = nextId(); data.dev = dev; } diff --git a/src/network/bearer/qnetworksession.cpp b/src/network/bearer/qnetworksession.cpp index 2ad46918b2..bbcd191041 100644 --- a/src/network/bearer/qnetworksession.cpp +++ b/src/network/bearer/qnetworksession.cpp @@ -252,6 +252,10 @@ QT_BEGIN_NAMESPACE QNetworkSession::QNetworkSession(const QNetworkConfiguration &connectionConfig, QObject *parent) : QObject(parent), d(0) { + qRegisterMetaType<QNetworkSession::State>(); + qRegisterMetaType<QNetworkSession::SessionError>(); + qRegisterMetaType<QNetworkSession::UsagePolicies>(); + // invalid configuration if (!connectionConfig.identifier().isEmpty()) { const auto engines = qNetworkConfigurationManagerPrivate()->engines(); @@ -277,10 +281,6 @@ QNetworkSession::QNetworkSession(const QNetworkConfiguration &connectionConfig, } } } - - qRegisterMetaType<QNetworkSession::State>(); - qRegisterMetaType<QNetworkSession::SessionError>(); - qRegisterMetaType<QNetworkSession::UsagePolicies>(); } /*! diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index 193c990d8c..46123eb8a7 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -183,7 +183,11 @@ void emit_results_ready(const QHostInfo &hostInfo, const QObject *receiver, \sa QAbstractSocket, {http://www.rfc-editor.org/rfc/rfc3492.txt}{RFC 3492} */ -static QBasicAtomicInt theIdCounter = Q_BASIC_ATOMIC_INITIALIZER(1); +static int nextId() +{ + static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(0); + return 1 + counter.fetchAndAddRelaxed(1); +} /*! Looks up the IP address(es) associated with host name \a name, and @@ -229,7 +233,7 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver, qRegisterMetaType<QHostInfo>(); - int id = theIdCounter.fetchAndAddRelaxed(1); // generate unique ID + int id = nextId(); // generate unique ID if (name.isEmpty()) { if (!receiver) @@ -596,7 +600,7 @@ int QHostInfo::lookupHostImpl(const QString &name, qRegisterMetaType<QHostInfo>(); - int id = theIdCounter.fetchAndAddRelaxed(1); // generate unique ID + int id = nextId(); // generate unique ID if (Q_UNLIKELY(name.isEmpty())) { QHostInfo hostInfo(id); diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp index 95a0d0563a..2847b910f3 100644 --- a/src/network/socket/qsocks5socketengine.cpp +++ b/src/network/socket/qsocks5socketengine.cpp @@ -1002,13 +1002,17 @@ QSocks5SocketEngine::~QSocks5SocketEngine() delete d->bindData; } -static QBasicAtomicInt descriptorCounter = Q_BASIC_ATOMIC_INITIALIZER(1); +static int nextDescriptor() +{ + static QBasicAtomicInt counter; + return 1 + counter.fetchAndAddRelaxed(1); +} bool QSocks5SocketEngine::initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol) { Q_D(QSocks5SocketEngine); - d->socketDescriptor = descriptorCounter.fetchAndAddRelaxed(1); + d->socketDescriptor = nextDescriptor(); d->socketType = type; d->socketProtocol = protocol; diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 047b681bcb..d5ce4efd1a 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -45,7 +45,11 @@ QT_BEGIN_NAMESPACE -QBasicAtomicInt qgltextureglyphcache_serial_number = Q_BASIC_ATOMIC_INITIALIZER(1); +static int next_qgltextureglyphcache_serial_number() +{ + static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(0); + return 1 + serial.fetchAndAddRelaxed(1); +} QGLTextureGlyphCache::QGLTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix) : QImageTextureGlyphCache(format, matrix) @@ -53,7 +57,7 @@ QGLTextureGlyphCache::QGLTextureGlyphCache(QFontEngine::GlyphFormat format, cons , pex(0) , m_blitProgram(0) , m_filterMode(Nearest) - , m_serialNumber(qgltextureglyphcache_serial_number.fetchAndAddRelaxed(1)) + , m_serialNumber(next_qgltextureglyphcache_serial_number()) { #ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG qDebug(" -> QGLTextureGlyphCache() %p for context %p.", this, QOpenGLContext::currentContext()); diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp index 2d3d91b4fa..674ab29012 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp @@ -457,7 +457,352 @@ QFunctionPointer QEGLPlatformContext::getProcAddress(const char *procName) #if !defined(Q_OS_WIN) && !defined(Q_OS_INTEGRITY) if (!proc) proc = (QFunctionPointer) dlsym(RTLD_DEFAULT, procName); +#elif !defined(QT_OPENGL_DYNAMIC) + // On systems without KHR_get_all_proc_addresses and without + // dynamic linking there still has to be a way to access the + // standard GLES functions. QOpenGL(Extra)Functions never makes + // direct GL API calls since Qt 5.7, so all such workarounds are + // expected to be handled in the platform plugin. + if (!proc) { + static struct StdFunc { + const char *name; + QFunctionPointer func; + } standardFuncs[] = { +#ifdef QT_OPENGL_ES_2 + { "glBindTexture", (QFunctionPointer) ::glBindTexture }, + { "glBlendFunc", (QFunctionPointer) ::glBlendFunc }, + { "glClear", (QFunctionPointer) ::glClear }, + { "glClearColor", (QFunctionPointer) ::glClearColor }, + { "glClearStencil", (QFunctionPointer) ::glClearStencil }, + { "glColorMask", (QFunctionPointer) ::glColorMask }, + { "glCopyTexImage2D", (QFunctionPointer) ::glCopyTexImage2D }, + { "glCopyTexSubImage2D", (QFunctionPointer) ::glCopyTexSubImage2D }, + { "glCullFace", (QFunctionPointer) ::glCullFace }, + { "glDeleteTextures", (QFunctionPointer) ::glDeleteTextures }, + { "glDepthFunc", (QFunctionPointer) ::glDepthFunc }, + { "glDepthMask", (QFunctionPointer) ::glDepthMask }, + { "glDisable", (QFunctionPointer) ::glDisable }, + { "glDrawArrays", (QFunctionPointer) ::glDrawArrays }, + { "glDrawElements", (QFunctionPointer) ::glDrawElements }, + { "glEnable", (QFunctionPointer) ::glEnable }, + { "glFinish", (QFunctionPointer) ::glFinish }, + { "glFlush", (QFunctionPointer) ::glFlush }, + { "glFrontFace", (QFunctionPointer) ::glFrontFace }, + { "glGenTextures", (QFunctionPointer) ::glGenTextures }, + { "glGetBooleanv", (QFunctionPointer) ::glGetBooleanv }, + { "glGetError", (QFunctionPointer) ::glGetError }, + { "glGetFloatv", (QFunctionPointer) ::glGetFloatv }, + { "glGetIntegerv", (QFunctionPointer) ::glGetIntegerv }, + { "glGetString", (QFunctionPointer) ::glGetString }, + { "glGetTexParameterfv", (QFunctionPointer) ::glGetTexParameterfv }, + { "glGetTexParameteriv", (QFunctionPointer) ::glGetTexParameteriv }, + { "glHint", (QFunctionPointer) ::glHint }, + { "glIsEnabled", (QFunctionPointer) ::glIsEnabled }, + { "glIsTexture", (QFunctionPointer) ::glIsTexture }, + { "glLineWidth", (QFunctionPointer) ::glLineWidth }, + { "glPixelStorei", (QFunctionPointer) ::glPixelStorei }, + { "glPolygonOffset", (QFunctionPointer) ::glPolygonOffset }, + { "glReadPixels", (QFunctionPointer) ::glReadPixels }, + { "glScissor", (QFunctionPointer) ::glScissor }, + { "glStencilFunc", (QFunctionPointer) ::glStencilFunc }, + { "glStencilMask", (QFunctionPointer) ::glStencilMask }, + { "glStencilOp", (QFunctionPointer) ::glStencilOp }, + { "glTexImage2D", (QFunctionPointer) ::glTexImage2D }, + { "glTexParameterf", (QFunctionPointer) ::glTexParameterf }, + { "glTexParameterfv", (QFunctionPointer) ::glTexParameterfv }, + { "glTexParameteri", (QFunctionPointer) ::glTexParameteri }, + { "glTexParameteriv", (QFunctionPointer) ::glTexParameteriv }, + { "glTexSubImage2D", (QFunctionPointer) ::glTexSubImage2D }, + { "glViewport", (QFunctionPointer) ::glViewport }, + + { "glActiveTexture", (QFunctionPointer) ::glActiveTexture }, + { "glAttachShader", (QFunctionPointer) ::glAttachShader }, + { "glBindAttribLocation", (QFunctionPointer) ::glBindAttribLocation }, + { "glBindBuffer", (QFunctionPointer) ::glBindBuffer }, + { "glBindFramebuffer", (QFunctionPointer) ::glBindFramebuffer }, + { "glBindRenderbuffer", (QFunctionPointer) ::glBindRenderbuffer }, + { "glBlendColor", (QFunctionPointer) ::glBlendColor }, + { "glBlendEquation", (QFunctionPointer) ::glBlendEquation }, + { "glBlendEquationSeparate", (QFunctionPointer) ::glBlendEquationSeparate }, + { "glBlendFuncSeparate", (QFunctionPointer) ::glBlendFuncSeparate }, + { "glBufferData", (QFunctionPointer) ::glBufferData }, + { "glBufferSubData", (QFunctionPointer) ::glBufferSubData }, + { "glCheckFramebufferStatus", (QFunctionPointer) ::glCheckFramebufferStatus }, + { "glCompileShader", (QFunctionPointer) ::glCompileShader }, + { "glCompressedTexImage2D", (QFunctionPointer) ::glCompressedTexImage2D }, + { "glCompressedTexSubImage2D", (QFunctionPointer) ::glCompressedTexSubImage2D }, + { "glCreateProgram", (QFunctionPointer) ::glCreateProgram }, + { "glCreateShader", (QFunctionPointer) ::glCreateShader }, + { "glDeleteBuffers", (QFunctionPointer) ::glDeleteBuffers }, + { "glDeleteFramebuffers", (QFunctionPointer) ::glDeleteFramebuffers }, + { "glDeleteProgram", (QFunctionPointer) ::glDeleteProgram }, + { "glDeleteRenderbuffers", (QFunctionPointer) ::glDeleteRenderbuffers }, + { "glDeleteShader", (QFunctionPointer) ::glDeleteShader }, + { "glDetachShader", (QFunctionPointer) ::glDetachShader }, + { "glDisableVertexAttribArray", (QFunctionPointer) ::glDisableVertexAttribArray }, + { "glEnableVertexAttribArray", (QFunctionPointer) ::glEnableVertexAttribArray }, + { "glFramebufferRenderbuffer", (QFunctionPointer) ::glFramebufferRenderbuffer }, + { "glFramebufferTexture2D", (QFunctionPointer) ::glFramebufferTexture2D }, + { "glGenBuffers", (QFunctionPointer) ::glGenBuffers }, + { "glGenerateMipmap", (QFunctionPointer) ::glGenerateMipmap }, + { "glGenFramebuffers", (QFunctionPointer) ::glGenFramebuffers }, + { "glGenRenderbuffers", (QFunctionPointer) ::glGenRenderbuffers }, + { "glGetActiveAttrib", (QFunctionPointer) ::glGetActiveAttrib }, + { "glGetActiveUniform", (QFunctionPointer) ::glGetActiveUniform }, + { "glGetAttachedShaders", (QFunctionPointer) ::glGetAttachedShaders }, + { "glGetAttribLocation", (QFunctionPointer) ::glGetAttribLocation }, + { "glGetBufferParameteriv", (QFunctionPointer) ::glGetBufferParameteriv }, + { "glGetFramebufferAttachmentParameteriv", (QFunctionPointer) ::glGetFramebufferAttachmentParameteriv }, + { "glGetProgramiv", (QFunctionPointer) ::glGetProgramiv }, + { "glGetProgramInfoLog", (QFunctionPointer) ::glGetProgramInfoLog }, + { "glGetRenderbufferParameteriv", (QFunctionPointer) ::glGetRenderbufferParameteriv }, + { "glGetShaderiv", (QFunctionPointer) ::glGetShaderiv }, + { "glGetShaderInfoLog", (QFunctionPointer) ::glGetShaderInfoLog }, + { "glGetShaderPrecisionFormat", (QFunctionPointer) ::glGetShaderPrecisionFormat }, + { "glGetShaderSource", (QFunctionPointer) ::glGetShaderSource }, + { "glGetUniformfv", (QFunctionPointer) ::glGetUniformfv }, + { "glGetUniformiv", (QFunctionPointer) ::glGetUniformiv }, + { "glGetUniformLocation", (QFunctionPointer) ::glGetUniformLocation }, + { "glGetVertexAttribfv", (QFunctionPointer) ::glGetVertexAttribfv }, + { "glGetVertexAttribiv", (QFunctionPointer) ::glGetVertexAttribiv }, + { "glGetVertexAttribPointerv", (QFunctionPointer) ::glGetVertexAttribPointerv }, + { "glIsBuffer", (QFunctionPointer) ::glIsBuffer }, + { "glIsFramebuffer", (QFunctionPointer) ::glIsFramebuffer }, + { "glIsProgram", (QFunctionPointer) ::glIsProgram }, + { "glIsRenderbuffer", (QFunctionPointer) ::glIsRenderbuffer }, + { "glIsShader", (QFunctionPointer) ::glIsShader }, + { "glLinkProgram", (QFunctionPointer) ::glLinkProgram }, + { "glReleaseShaderCompiler", (QFunctionPointer) ::glReleaseShaderCompiler }, + { "glRenderbufferStorage", (QFunctionPointer) ::glRenderbufferStorage }, + { "glSampleCoverage", (QFunctionPointer) ::glSampleCoverage }, + { "glShaderBinary", (QFunctionPointer) ::glShaderBinary }, + { "glShaderSource", (QFunctionPointer) ::glShaderSource }, + { "glStencilFuncSeparate", (QFunctionPointer) ::glStencilFuncSeparate }, + { "glStencilMaskSeparate", (QFunctionPointer) ::glStencilMaskSeparate }, + { "glStencilOpSeparate", (QFunctionPointer) ::glStencilOpSeparate }, + { "glUniform1f", (QFunctionPointer) ::glUniform1f }, + { "glUniform1fv", (QFunctionPointer) ::glUniform1fv }, + { "glUniform1i", (QFunctionPointer) ::glUniform1i }, + { "glUniform1iv", (QFunctionPointer) ::glUniform1iv }, + { "glUniform2f", (QFunctionPointer) ::glUniform2f }, + { "glUniform2fv", (QFunctionPointer) ::glUniform2fv }, + { "glUniform2i", (QFunctionPointer) ::glUniform2i }, + { "glUniform2iv", (QFunctionPointer) ::glUniform2iv }, + { "glUniform3f", (QFunctionPointer) ::glUniform3f }, + { "glUniform3fv", (QFunctionPointer) ::glUniform3fv }, + { "glUniform3i", (QFunctionPointer) ::glUniform3i }, + { "glUniform3iv", (QFunctionPointer) ::glUniform3iv }, + { "glUniform4f", (QFunctionPointer) ::glUniform4f }, + { "glUniform4fv", (QFunctionPointer) ::glUniform4fv }, + { "glUniform4i", (QFunctionPointer) ::glUniform4i }, + { "glUniform4iv", (QFunctionPointer) ::glUniform4iv }, + { "glUniformMatrix2fv", (QFunctionPointer) ::glUniformMatrix2fv }, + { "glUniformMatrix3fv", (QFunctionPointer) ::glUniformMatrix3fv }, + { "glUniformMatrix4fv", (QFunctionPointer) ::glUniformMatrix4fv }, + { "glUseProgram", (QFunctionPointer) ::glUseProgram }, + { "glValidateProgram", (QFunctionPointer) ::glValidateProgram }, + { "glVertexAttrib1f", (QFunctionPointer) ::glVertexAttrib1f }, + { "glVertexAttrib1fv", (QFunctionPointer) ::glVertexAttrib1fv }, + { "glVertexAttrib2f", (QFunctionPointer) ::glVertexAttrib2f }, + { "glVertexAttrib2fv", (QFunctionPointer) ::glVertexAttrib2fv }, + { "glVertexAttrib3f", (QFunctionPointer) ::glVertexAttrib3f }, + { "glVertexAttrib3fv", (QFunctionPointer) ::glVertexAttrib3fv }, + { "glVertexAttrib4f", (QFunctionPointer) ::glVertexAttrib4f }, + { "glVertexAttrib4fv", (QFunctionPointer) ::glVertexAttrib4fv }, + { "glVertexAttribPointer", (QFunctionPointer) ::glVertexAttribPointer }, + + { "glClearDepthf", (QFunctionPointer) ::glClearDepthf }, + { "glDepthRangef", (QFunctionPointer) ::glDepthRangef }, +#endif // QT_OPENGL_ES_2 + +#ifdef QT_OPENGL_ES_3 + { "glBeginQuery", (QFunctionPointer) ::glBeginQuery }, + { "glBeginTransformFeedback", (QFunctionPointer) ::glBeginTransformFeedback }, + { "glBindBufferBase", (QFunctionPointer) ::glBindBufferBase }, + { "glBindBufferRange", (QFunctionPointer) ::glBindBufferRange }, + { "glBindSampler", (QFunctionPointer) ::glBindSampler }, + { "glBindTransformFeedback", (QFunctionPointer) ::glBindTransformFeedback }, + { "glBindVertexArray", (QFunctionPointer) ::glBindVertexArray }, + { "glBlitFramebuffer", (QFunctionPointer) ::glBlitFramebuffer }, + { "glClearBufferfi", (QFunctionPointer) ::glClearBufferfi }, + { "glClearBufferfv", (QFunctionPointer) ::glClearBufferfv }, + { "glClearBufferiv", (QFunctionPointer) ::glClearBufferiv }, + { "glClearBufferuiv", (QFunctionPointer) ::glClearBufferuiv }, + { "glClientWaitSync", (QFunctionPointer) ::glClientWaitSync }, + { "glCompressedTexImage3D", (QFunctionPointer) ::glCompressedTexImage3D }, + { "glCompressedTexSubImage3D", (QFunctionPointer) ::glCompressedTexSubImage3D }, + { "glCopyBufferSubData", (QFunctionPointer) ::glCopyBufferSubData }, + { "glCopyTexSubImage3D", (QFunctionPointer) ::glCopyTexSubImage3D }, + { "glDeleteQueries", (QFunctionPointer) ::glDeleteQueries }, + { "glDeleteSamplers", (QFunctionPointer) ::glDeleteSamplers }, + { "glDeleteSync", (QFunctionPointer) ::glDeleteSync }, + { "glDeleteTransformFeedbacks", (QFunctionPointer) ::glDeleteTransformFeedbacks }, + { "glDeleteVertexArrays", (QFunctionPointer) ::glDeleteVertexArrays }, + { "glDrawArraysInstanced", (QFunctionPointer) ::glDrawArraysInstanced }, + { "glDrawBuffers", (QFunctionPointer) ::glDrawBuffers }, + { "glDrawElementsInstanced", (QFunctionPointer) ::glDrawElementsInstanced }, + { "glDrawRangeElements", (QFunctionPointer) ::glDrawRangeElements }, + { "glEndQuery", (QFunctionPointer) ::glEndQuery }, + { "glEndTransformFeedback", (QFunctionPointer) ::glEndTransformFeedback }, + { "glFenceSync", (QFunctionPointer) ::glFenceSync }, + { "glFlushMappedBufferRange", (QFunctionPointer) ::glFlushMappedBufferRange }, + { "glFramebufferTextureLayer", (QFunctionPointer) ::glFramebufferTextureLayer }, + { "glGenQueries", (QFunctionPointer) ::glGenQueries }, + { "glGenSamplers", (QFunctionPointer) ::glGenSamplers }, + { "glGenTransformFeedbacks", (QFunctionPointer) ::glGenTransformFeedbacks }, + { "glGenVertexArrays", (QFunctionPointer) ::glGenVertexArrays }, + { "glGetActiveUniformBlockName", (QFunctionPointer) ::glGetActiveUniformBlockName }, + { "glGetActiveUniformBlockiv", (QFunctionPointer) ::glGetActiveUniformBlockiv }, + { "glGetActiveUniformsiv", (QFunctionPointer) ::glGetActiveUniformsiv }, + { "glGetBufferParameteri64v", (QFunctionPointer) ::glGetBufferParameteri64v }, + { "glGetBufferPointerv", (QFunctionPointer) ::glGetBufferPointerv }, + { "glGetFragDataLocation", (QFunctionPointer) ::glGetFragDataLocation }, + { "glGetInteger64i_v", (QFunctionPointer) ::glGetInteger64i_v }, + { "glGetInteger64v", (QFunctionPointer) ::glGetInteger64v }, + { "glGetIntegeri_v", (QFunctionPointer) ::glGetIntegeri_v }, + { "glGetInternalformativ", (QFunctionPointer) ::glGetInternalformativ }, + { "glGetProgramBinary", (QFunctionPointer) ::glGetProgramBinary }, + { "glGetQueryObjectuiv", (QFunctionPointer) ::glGetQueryObjectuiv }, + { "glGetQueryiv", (QFunctionPointer) ::glGetQueryiv }, + { "glGetSamplerParameterfv", (QFunctionPointer) ::glGetSamplerParameterfv }, + { "glGetSamplerParameteriv", (QFunctionPointer) ::glGetSamplerParameteriv }, + { "glGetStringi", (QFunctionPointer) ::glGetStringi }, + { "glGetSynciv", (QFunctionPointer) ::glGetSynciv }, + { "glGetTransformFeedbackVarying", (QFunctionPointer) ::glGetTransformFeedbackVarying }, + { "glGetUniformBlockIndex", (QFunctionPointer) ::glGetUniformBlockIndex }, + { "glGetUniformIndices", (QFunctionPointer) ::glGetUniformIndices }, + { "glGetUniformuiv", (QFunctionPointer) ::glGetUniformuiv }, + { "glGetVertexAttribIiv", (QFunctionPointer) ::glGetVertexAttribIiv }, + { "glGetVertexAttribIuiv", (QFunctionPointer) ::glGetVertexAttribIuiv }, + { "glInvalidateFramebuffer", (QFunctionPointer) ::glInvalidateFramebuffer }, + { "glInvalidateSubFramebuffer", (QFunctionPointer) ::glInvalidateSubFramebuffer }, + { "glIsQuery", (QFunctionPointer) ::glIsQuery }, + { "glIsSampler", (QFunctionPointer) ::glIsSampler }, + { "glIsSync", (QFunctionPointer) ::glIsSync }, + { "glIsTransformFeedback", (QFunctionPointer) ::glIsTransformFeedback }, + { "glIsVertexArray", (QFunctionPointer) ::glIsVertexArray }, + { "glMapBufferRange", (QFunctionPointer) ::glMapBufferRange }, + { "glPauseTransformFeedback", (QFunctionPointer) ::glPauseTransformFeedback }, + { "glProgramBinary", (QFunctionPointer) ::glProgramBinary }, + { "glProgramParameteri", (QFunctionPointer) ::glProgramParameteri }, + { "glReadBuffer", (QFunctionPointer) ::glReadBuffer }, + { "glRenderbufferStorageMultisample", (QFunctionPointer) ::glRenderbufferStorageMultisample }, + { "glResumeTransformFeedback", (QFunctionPointer) ::glResumeTransformFeedback }, + { "glSamplerParameterf", (QFunctionPointer) ::glSamplerParameterf }, + { "glSamplerParameterfv", (QFunctionPointer) ::glSamplerParameterfv }, + { "glSamplerParameteri", (QFunctionPointer) ::glSamplerParameteri }, + { "glSamplerParameteriv", (QFunctionPointer) ::glSamplerParameteriv }, + { "glTexImage3D", (QFunctionPointer) ::glTexImage3D }, + { "glTexStorage2D", (QFunctionPointer) ::glTexStorage2D }, + { "glTexStorage3D", (QFunctionPointer) ::glTexStorage3D }, + { "glTexSubImage3D", (QFunctionPointer) ::glTexSubImage3D }, + { "glTransformFeedbackVaryings", (QFunctionPointer) ::glTransformFeedbackVaryings }, + { "glUniform1ui", (QFunctionPointer) ::glUniform1ui }, + { "glUniform1uiv", (QFunctionPointer) ::glUniform1uiv }, + { "glUniform2ui", (QFunctionPointer) ::glUniform2ui }, + { "glUniform2uiv", (QFunctionPointer) ::glUniform2uiv }, + { "glUniform3ui", (QFunctionPointer) ::glUniform3ui }, + { "glUniform3uiv", (QFunctionPointer) ::glUniform3uiv }, + { "glUniform4ui", (QFunctionPointer) ::glUniform4ui }, + { "glUniform4uiv", (QFunctionPointer) ::glUniform4uiv }, + { "glUniformBlockBinding", (QFunctionPointer) ::glUniformBlockBinding }, + { "glUniformMatrix2x3fv", (QFunctionPointer) ::glUniformMatrix2x3fv }, + { "glUniformMatrix2x4fv", (QFunctionPointer) ::glUniformMatrix2x4fv }, + { "glUniformMatrix3x2fv", (QFunctionPointer) ::glUniformMatrix3x2fv }, + { "glUniformMatrix3x4fv", (QFunctionPointer) ::glUniformMatrix3x4fv }, + { "glUniformMatrix4x2fv", (QFunctionPointer) ::glUniformMatrix4x2fv }, + { "glUniformMatrix4x3fv", (QFunctionPointer) ::glUniformMatrix4x3fv }, + { "glUnmapBuffer", (QFunctionPointer) ::glUnmapBuffer }, + { "glVertexAttribDivisor", (QFunctionPointer) ::glVertexAttribDivisor }, + { "glVertexAttribI4i", (QFunctionPointer) ::glVertexAttribI4i }, + { "glVertexAttribI4iv", (QFunctionPointer) ::glVertexAttribI4iv }, + { "glVertexAttribI4ui", (QFunctionPointer) ::glVertexAttribI4ui }, + { "glVertexAttribI4uiv", (QFunctionPointer) ::glVertexAttribI4uiv }, + { "glVertexAttribIPointer", (QFunctionPointer) ::glVertexAttribIPointer }, + { "glWaitSync", (QFunctionPointer) ::glWaitSync }, +#endif // QT_OPENGL_ES_3 + +#ifdef QT_OPENGL_ES_3_1 + { "glActiveShaderProgram", (QFunctionPointer) ::glActiveShaderProgram }, + { "glBindImageTexture", (QFunctionPointer) ::glBindImageTexture }, + { "glBindProgramPipeline", (QFunctionPointer) ::glBindProgramPipeline }, + { "glBindVertexBuffer", (QFunctionPointer) ::glBindVertexBuffer }, + { "glCreateShaderProgramv", (QFunctionPointer) ::glCreateShaderProgramv }, + { "glDeleteProgramPipelines", (QFunctionPointer) ::glDeleteProgramPipelines }, + { "glDispatchCompute", (QFunctionPointer) ::glDispatchCompute }, + { "glDispatchComputeIndirect", (QFunctionPointer) ::glDispatchComputeIndirect }, + { "glDrawArraysIndirect", (QFunctionPointer) ::glDrawArraysIndirect }, + { "glDrawElementsIndirect", (QFunctionPointer) ::glDrawElementsIndirect }, + { "glFramebufferParameteri", (QFunctionPointer) ::glFramebufferParameteri }, + { "glGenProgramPipelines", (QFunctionPointer) ::glGenProgramPipelines }, + { "glGetBooleani_v", (QFunctionPointer) ::glGetBooleani_v }, + { "glGetFramebufferParameteriv", (QFunctionPointer) ::glGetFramebufferParameteriv }, + { "glGetMultisamplefv", (QFunctionPointer) ::glGetMultisamplefv }, + { "glGetProgramInterfaceiv", (QFunctionPointer) ::glGetProgramInterfaceiv }, + { "glGetProgramPipelineInfoLog", (QFunctionPointer) ::glGetProgramPipelineInfoLog }, + { "glGetProgramPipelineiv", (QFunctionPointer) ::glGetProgramPipelineiv }, + { "glGetProgramResourceIndex", (QFunctionPointer) ::glGetProgramResourceIndex }, + { "glGetProgramResourceLocation", (QFunctionPointer) ::glGetProgramResourceLocation }, + { "glGetProgramResourceName", (QFunctionPointer) ::glGetProgramResourceName }, + { "glGetProgramResourceiv", (QFunctionPointer) ::glGetProgramResourceiv }, + { "glGetTexLevelParameterfv", (QFunctionPointer) ::glGetTexLevelParameterfv }, + { "glGetTexLevelParameteriv", (QFunctionPointer) ::glGetTexLevelParameteriv }, + { "glIsProgramPipeline", (QFunctionPointer) ::glIsProgramPipeline }, + { "glMemoryBarrier", (QFunctionPointer) ::glMemoryBarrier }, + { "glMemoryBarrierByRegion", (QFunctionPointer) ::glMemoryBarrierByRegion }, + { "glProgramUniform1f", (QFunctionPointer) ::glProgramUniform1f }, + { "glProgramUniform1fv", (QFunctionPointer) ::glProgramUniform1fv }, + { "glProgramUniform1i", (QFunctionPointer) ::glProgramUniform1i }, + { "glProgramUniform1iv", (QFunctionPointer) ::glProgramUniform1iv }, + { "glProgramUniform1ui", (QFunctionPointer) ::glProgramUniform1ui }, + { "glProgramUniform1uiv", (QFunctionPointer) ::glProgramUniform1uiv }, + { "glProgramUniform2f", (QFunctionPointer) ::glProgramUniform2f }, + { "glProgramUniform2fv", (QFunctionPointer) ::glProgramUniform2fv }, + { "glProgramUniform2i", (QFunctionPointer) ::glProgramUniform2i }, + { "glProgramUniform2iv", (QFunctionPointer) ::glProgramUniform2iv }, + { "glProgramUniform2ui", (QFunctionPointer) ::glProgramUniform2ui }, + { "glProgramUniform2uiv", (QFunctionPointer) ::glProgramUniform2uiv }, + { "glProgramUniform3f", (QFunctionPointer) ::glProgramUniform3f }, + { "glProgramUniform3fv", (QFunctionPointer) ::glProgramUniform3fv }, + { "glProgramUniform3i", (QFunctionPointer) ::glProgramUniform3i }, + { "glProgramUniform3iv", (QFunctionPointer) ::glProgramUniform3iv }, + { "glProgramUniform3ui", (QFunctionPointer) ::glProgramUniform3ui }, + { "glProgramUniform3uiv", (QFunctionPointer) ::glProgramUniform3uiv }, + { "glProgramUniform4f", (QFunctionPointer) ::glProgramUniform4f }, + { "glProgramUniform4fv", (QFunctionPointer) ::glProgramUniform4fv }, + { "glProgramUniform4i", (QFunctionPointer) ::glProgramUniform4i }, + { "glProgramUniform4iv", (QFunctionPointer) ::glProgramUniform4iv }, + { "glProgramUniform4ui", (QFunctionPointer) ::glProgramUniform4ui }, + { "glProgramUniform4uiv", (QFunctionPointer) ::glProgramUniform4uiv }, + { "glProgramUniformMatrix2fv", (QFunctionPointer) ::glProgramUniformMatrix2fv }, + { "glProgramUniformMatrix2x3fv", (QFunctionPointer) ::glProgramUniformMatrix2x3fv }, + { "glProgramUniformMatrix2x4fv", (QFunctionPointer) ::glProgramUniformMatrix2x4fv }, + { "glProgramUniformMatrix3fv", (QFunctionPointer) ::glProgramUniformMatrix3fv }, + { "glProgramUniformMatrix3x2fv", (QFunctionPointer) ::glProgramUniformMatrix3x2fv }, + { "glProgramUniformMatrix3x4fv", (QFunctionPointer) ::glProgramUniformMatrix3x4fv }, + { "glProgramUniformMatrix4fv", (QFunctionPointer) ::glProgramUniformMatrix4fv }, + { "glProgramUniformMatrix4x2fv", (QFunctionPointer) ::glProgramUniformMatrix4x2fv }, + { "glProgramUniformMatrix4x3fv", (QFunctionPointer) ::glProgramUniformMatrix4x3fv }, + { "glSampleMaski", (QFunctionPointer) ::glSampleMaski }, + { "glTexStorage2DMultisample", (QFunctionPointer) ::glTexStorage2DMultisample }, + { "glUseProgramStages", (QFunctionPointer) ::glUseProgramStages }, + { "glValidateProgramPipeline", (QFunctionPointer) ::glValidateProgramPipeline }, + { "glVertexAttribBinding", (QFunctionPointer) ::glVertexAttribBinding }, + { "glVertexAttribFormat", (QFunctionPointer) ::glVertexAttribFormat }, + { "glVertexAttribIFormat", (QFunctionPointer) ::glVertexAttribIFormat }, + { "glVertexBindingDivisor", (QFunctionPointer) ::glVertexBindingDivisor }, +#endif // QT_OPENGL_ES_3_1 + }; + + for (size_t i = 0; i < sizeof(standardFuncs) / sizeof(StdFunc); ++i) { + if (!qstrcmp(procName, standardFuncs[i].name)) { + proc = standardFuncs[i].func; + break; + } + } + } #endif + return proc; } diff --git a/src/platformsupport/eglconvenience/qeglstreamconvenience.cpp b/src/platformsupport/eglconvenience/qeglstreamconvenience.cpp index 1e90f849f5..5c336f0553 100644 --- a/src/platformsupport/eglconvenience/qeglstreamconvenience.cpp +++ b/src/platformsupport/eglconvenience/qeglstreamconvenience.cpp @@ -103,6 +103,11 @@ void QEGLStreamConvenience::initialize(EGLDisplay dpy) stream_consumer_gltexture = reinterpret_cast<PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC>(eglGetProcAddress("eglStreamConsumerGLTextureExternalKHR")); stream_consumer_acquire = reinterpret_cast<PFNEGLSTREAMCONSUMERACQUIREKHRPROC>(eglGetProcAddress("eglStreamConsumerAcquireKHR")); stream_consumer_release = reinterpret_cast<PFNEGLSTREAMCONSUMERRELEASEKHRPROC>(eglGetProcAddress("eglStreamConsumerReleaseKHR")); + create_stream_attrib_nv = reinterpret_cast<PFNEGLCREATESTREAMATTRIBNVPROC>(eglGetProcAddress("eglCreateStreamAttribNV")); + set_stream_attrib_nv = reinterpret_cast<PFNEGLSETSTREAMATTRIBNVPROC>(eglGetProcAddress("eglSetStreamAttribNV")); + query_stream_attrib_nv = reinterpret_cast<PFNEGLQUERYSTREAMATTRIBNVPROC>(eglGetProcAddress("eglQueryStreamAttribNV")); + acquire_stream_attrib_nv = reinterpret_cast<PFNEGLSTREAMCONSUMERACQUIREATTRIBNVPROC>(eglGetProcAddress("eglStreamConsumerAcquireAttribNV")); + release_stream_attrib_nv = reinterpret_cast<PFNEGLSTREAMCONSUMERRELEASEATTRIBNVPROC>(eglGetProcAddress("eglStreamConsumerReleaseAttribNV")); has_egl_stream = strstr(extensions, "EGL_KHR_stream"); has_egl_stream_producer_eglsurface = strstr(extensions, "EGL_KHR_stream_producer_eglsurface"); diff --git a/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h index 8c802a0ca1..c3d3070210 100644 --- a/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h +++ b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h @@ -148,6 +148,14 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay #define EGL_PLATFORM_X11_KHR 0x31D5 #endif +#ifndef EGL_NV_stream_attrib +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMATTRIBNVPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMATTRIBNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMATTRIBNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREATTRIBNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEATTRIBNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#endif + QT_BEGIN_NAMESPACE class QEGLStreamConvenience @@ -160,6 +168,11 @@ public: PFNEGLQUERYDEVICESEXTPROC query_devices; PFNEGLQUERYDEVICESTRINGEXTPROC query_device_string; PFNEGLCREATESTREAMKHRPROC create_stream; + PFNEGLCREATESTREAMATTRIBNVPROC create_stream_attrib_nv; + PFNEGLSETSTREAMATTRIBNVPROC set_stream_attrib_nv; + PFNEGLQUERYSTREAMATTRIBNVPROC query_stream_attrib_nv; + PFNEGLSTREAMCONSUMERACQUIREATTRIBNVPROC acquire_stream_attrib_nv; + PFNEGLSTREAMCONSUMERRELEASEATTRIBNVPROC release_stream_attrib_nv; PFNEGLDESTROYSTREAMKHRPROC destroy_stream; PFNEGLSTREAMATTRIBKHRPROC stream_attrib; PFNEGLQUERYSTREAMKHRPROC query_stream; diff --git a/src/platformsupport/fontdatabases/basic/basic.pri b/src/platformsupport/fontdatabases/basic/basic.pri index c50dba3ce2..0617bf74d7 100644 --- a/src/platformsupport/fontdatabases/basic/basic.pri +++ b/src/platformsupport/fontdatabases/basic/basic.pri @@ -1,9 +1,9 @@ HEADERS += \ $$PWD/qbasicfontdatabase_p.h \ - $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft_p.h + $$PWD/qfontengine_ft_p.h SOURCES += \ $$PWD/qbasicfontdatabase.cpp \ - $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft.cpp + $$PWD/qfontengine_ft.cpp -QMAKE_USE += freetype +QMAKE_USE_PRIVATE += freetype diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp index 60ddc9fa23..0826b0f2fb 100644 --- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp @@ -49,8 +49,7 @@ #include <QtCore/QtEndian> #undef QT_NO_FREETYPE -#include <QtGui/private/qfontengine_ft_p.h> -#include <QtGui/private/qfontengine_p.h> +#include <QtFontDatabaseSupport/private/qfontengine_ft_p.h> #include <ft2build.h> #include FT_TRUETYPE_TABLES_H diff --git a/src/gui/text/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/basic/qfontengine_ft.cpp index 03e72546eb..03e72546eb 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/platformsupport/fontdatabases/basic/qfontengine_ft.cpp diff --git a/src/gui/text/qfontengine_ft_p.h b/src/platformsupport/fontdatabases/basic/qfontengine_ft_p.h index 47f13eb274..3b751eae3e 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/platformsupport/fontdatabases/basic/qfontengine_ft_p.h @@ -126,13 +126,7 @@ private: QFontEngine::Holder hbFace; }; -// If this is exported this breaks compilation of the windows -// plugin as qfontengine_ft_p.h/.cpp are also compiled there -#ifndef Q_OS_WIN -class Q_GUI_EXPORT QFontEngineFT : public QFontEngine -#else class QFontEngineFT : public QFontEngine -#endif { public: diff --git a/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri b/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri index 6458464870..671d6be237 100644 --- a/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri +++ b/src/platformsupport/fontdatabases/fontconfig/fontconfig.pri @@ -3,4 +3,4 @@ HEADERS += $$PWD/qfontconfigdatabase_p.h \ SOURCES += $$PWD/qfontconfigdatabase.cpp \ $$PWD/qfontenginemultifontconfig.cpp -QMAKE_USE += fontconfig +QMAKE_USE_PRIVATE += fontconfig diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index 65bc494e91..2c5ce3e87d 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -40,6 +40,8 @@ #include "qfontconfigdatabase_p.h" #include "qfontenginemultifontconfig_p.h" +#include <QtFontDatabaseSupport/private/qfontengine_ft_p.h> + #include <QtCore/QList> #include <QtCore/QElapsedTimer> #include <QtCore/QFile> @@ -49,7 +51,6 @@ #include <qpa/qplatformintegration.h> #include <qpa/qplatformservices.h> -#include <QtGui/private/qfontengine_ft_p.h> #include <QtGui/private/qguiapplication_p.h> #include <QtGui/private/qhighdpiscaling_p.h> diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp index 7574f9f9e6..2fbcb6216e 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp @@ -39,7 +39,7 @@ #include "qfontenginemultifontconfig_p.h" -#include <QtGui/private/qfontengine_ft_p.h> +#include <QtFontDatabaseSupport/private/qfontengine_ft_p.h> QT_BEGIN_NAMESPACE diff --git a/src/platformsupport/fontdatabases/mac/coretext.pri b/src/platformsupport/fontdatabases/mac/coretext.pri index 06f1971696..f73e22eb1a 100644 --- a/src/platformsupport/fontdatabases/mac/coretext.pri +++ b/src/platformsupport/fontdatabases/mac/coretext.pri @@ -2,9 +2,9 @@ HEADERS += $$PWD/qcoretextfontdatabase_p.h $$PWD/qfontengine_coretext_p.h OBJECTIVE_SOURCES += $$PWD/qfontengine_coretext.mm $$PWD/qcoretextfontdatabase.mm qtConfig(freetype) { - QMAKE_USE += freetype - HEADERS += $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft_p.h - SOURCES += $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft.cpp + QMAKE_USE_PRIVATE += freetype + HEADERS += basic/qfontengine_ft_p.h + SOURCES += basic/qfontengine_ft.cpp } uikit: \ diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 6466db59ce..2b9e928266 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -53,7 +53,7 @@ #include <QtCore/QSettings> #include <QtCore/QtEndian> #ifndef QT_NO_FREETYPE -#include <QtGui/private/qfontengine_ft_p.h> +#include <QtFontDatabaseSupport/private/qfontengine_ft_p.h> #endif QT_BEGIN_NAMESPACE diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp index 7cfebf0436..65947ab7da 100644 --- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp +++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase_ft.cpp @@ -40,6 +40,8 @@ #include "qwindowsfontdatabase_ft_p.h" #include "qwindowsfontdatabase_p.h" +#include <QtFontDatabaseSupport/private/qfontengine_ft_p.h> + #include <ft2build.h> #include FT_TRUETYPE_TABLES_H @@ -47,7 +49,6 @@ #include <QtCore/QDirIterator> #include <QtCore/QSettings> #include <QtCore/QRegularExpression> -#include <QtGui/private/qfontengine_ft_p.h> #include <QtGui/QGuiApplication> #include <QtGui/QFontDatabase> diff --git a/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase.cpp b/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase.cpp index 9f4b182ece..eb5a38855e 100644 --- a/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase.cpp +++ b/src/platformsupport/fontdatabases/winrt/qwinrtfontdatabase.cpp @@ -39,11 +39,12 @@ #include "qwinrtfontdatabase_p.h" +#include <QtFontDatabaseSupport/private/qfontengine_ft_p.h> + #include <QtCore/QCoreApplication> #include <QtCore/QFile> #include <QtCore/QUuid> -#include <QtGui/private/qfontengine_ft_p.h> #include <dwrite_1.h> #include <wrl.h> using namespace Microsoft::WRL; diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchfilter_p.h b/src/platformsupport/input/evdevtouch/qevdevtouchfilter_p.h index ebb793b3db..b596269e0c 100644 --- a/src/platformsupport/input/evdevtouch/qevdevtouchfilter_p.h +++ b/src/platformsupport/input/evdevtouch/qevdevtouchfilter_p.h @@ -33,6 +33,17 @@ #include <qglobal.h> +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + QT_BEGIN_NAMESPACE struct QEvdevTouchFilter diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index a7cc19b3bf..9e688f4d1b 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -255,7 +255,8 @@ void QCocoaGLContext::setActiveWindow(QWindow *window) QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle()); cocoaWindow->setCurrentContext(this); - [(QNSView *) cocoaWindow->view() setQCocoaGLContext:this]; + Q_ASSERT(!cocoaWindow->isForeignWindow()); + [qnsview_cast(cocoaWindow->view()) setQCocoaGLContext:this]; } void QCocoaGLContext::updateSurfaceFormat() diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index e177a24e73..8e47974d12 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -581,8 +581,8 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, // The calls above block, and also swallow any mouse release event, // so we need to clear any mouse button that triggered the menu popup. - if ([view isKindOfClass:[QNSView class]]) - [(QNSView *)view resetMouseButtons]; + if (!cocoaWindow->isForeignWindow()) + [qnsview_cast(view) resetMouseButtons]; } void QCocoaMenu::dismiss() diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index bb015c2419..f60597fe42 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -217,7 +217,7 @@ public: bool windowShouldClose(); bool windowIsPopupType(Qt::WindowType type = Qt::Widget) const; - void setSynchedWindowStateFromWindow(); + void reportCurrentWindowState(bool unconditionally = false); NSInteger windowLevel(Qt::WindowFlags flags); NSUInteger windowStyleMask(Qt::WindowFlags flags); @@ -284,10 +284,15 @@ protected: QCocoaNSWindow *createNSWindow(bool shouldBeChildNSWindow, bool shouldBePanel); QRect nativeWindowGeometry() const; - void syncWindowState(Qt::WindowState newState); void reinsertChildWindow(QCocoaWindow *child); void removeChildWindow(QCocoaWindow *child); + Qt::WindowState windowState() const; + void applyWindowState(Qt::WindowState newState); + void toggleMaximized(); + void toggleFullScreen(); + bool isTransitioningToFullScreen() const; + // private: public: // for QNSView friend class QCocoaBackingStore; @@ -304,8 +309,7 @@ public: // for QNSView bool m_viewIsToBeEmbedded; // true if the m_view is intended to be embedded in a "foreign" NSView hiearchy Qt::WindowFlags m_windowFlags; - bool m_effectivelyMaximized; - Qt::WindowState m_synchedWindowState; + Qt::WindowState m_lastReportedWindowState; Qt::WindowModality m_windowModality; QPointer<QWindow> m_enterLeaveTargetWindow; bool m_windowUnderMouse; @@ -339,11 +343,6 @@ public: // for QNSView int m_topContentBorderThickness; int m_bottomContentBorderThickness; - // used by showFullScreen in fake mode - QRect m_normalGeometry; - Qt::WindowFlags m_oldWindowFlags; - NSApplicationPresentationOptions m_presentationOptions; - struct BorderRange { BorderRange(quintptr i, int u, int l) : identifier(i), upper(u), lower(l) { } quintptr identifier; diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 114efc3e92..918f376446 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -87,6 +87,36 @@ static void qt_closePopups() } } +@interface NSWindow (FullScreenProperty) +@property(readonly) BOOL qt_fullScreen; +@end + +@implementation NSWindow (FullScreenProperty) + ++ (void)load +{ + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center addObserverForName:NSWindowDidEnterFullScreenNotification object:nil queue:nil + usingBlock:^(NSNotification *notification) { + objc_setAssociatedObject(notification.object, @selector(qt_fullScreen), + [NSNumber numberWithBool:YES], OBJC_ASSOCIATION_RETAIN); + } + ]; + [center addObserverForName:NSWindowDidExitFullScreenNotification object:nil queue:nil + usingBlock:^(NSNotification *notification) { + objc_setAssociatedObject(notification.object, @selector(qt_fullScreen), + nil, OBJC_ASSOCIATION_RETAIN); + } + ]; +} + +- (BOOL)qt_fullScreen +{ + NSNumber *number = objc_getAssociatedObject(self, @selector(qt_fullScreen)); + return [number boolValue]; +} +@end + @implementation QNSWindowHelper @synthesize window = _window; @@ -409,8 +439,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_nsWindow(0) , m_viewIsEmbedded(false) , m_viewIsToBeEmbedded(false) - , m_effectivelyMaximized(false) - , m_synchedWindowState(Qt::WindowActive) + , m_lastReportedWindowState(Qt::WindowNoState) , m_windowModality(Qt::NonModal) , m_windowUnderMouse(false) , m_inConstructor(true) @@ -435,7 +464,6 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) , m_drawContentBorderGradient(false) , m_topContentBorderThickness(0) , m_bottomContentBorderThickness(0) - , m_normalGeometry(QRect(0,0,-1,-1)) , m_hasWindowFilePath(false) { qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::QCocoaWindow" << window(); @@ -728,7 +756,7 @@ void QCocoaWindow::setVisible(bool visible) // setWindowState might have been called while the window was hidden and // will not change the NSWindow state in that case. Sync up here: - syncWindowState(window()->windowState()); + applyWindowState(window()->windowState()); if (window()->windowState() != Qt::WindowMinimized) { if ((window()->modality() == Qt::WindowModal @@ -930,7 +958,8 @@ void QCocoaWindow::setWindowZoomButton(Qt::WindowFlags flags) // in line with the platform style guidelines. bool fixedSizeNoZoom = (windowMinimumSize().isValid() && windowMaximumSize().isValid() && windowMinimumSize() == windowMaximumSize()); - bool customizeNoZoom = ((flags & Qt::CustomizeWindowHint) && !(flags & Qt::WindowMaximizeButtonHint)); + bool customizeNoZoom = ((flags & Qt::CustomizeWindowHint) + && !(flags & (Qt::WindowMaximizeButtonHint | Qt::WindowFullscreenButtonHint))); [[m_nsWindow standardWindowButton:NSWindowZoomButton] setEnabled:!(fixedSizeNoZoom || customizeNoZoom)]; } @@ -965,13 +994,16 @@ void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags) setWindowZoomButton(flags); } + if (m_nsWindow) + m_nsWindow.ignoresMouseEvents = flags & Qt::WindowTransparentForInput; + m_windowFlags = flags; } void QCocoaWindow::setWindowState(Qt::WindowState state) { if (window()->isVisible()) - syncWindowState(state); // Window state set for hidden windows take effect when show() is called. + applyWindowState(state); // Window state set for hidden windows take effect when show() is called } void QCocoaWindow::setWindowTitle(const QString &title) @@ -1247,6 +1279,9 @@ void QCocoaWindow::windowDidMove() return; [qnsview_cast(m_view) updateGeometry]; + + // Moving a window might bring it out of maximized state + reportCurrentWindowState(); } void QCocoaWindow::windowDidResize() @@ -1259,6 +1294,9 @@ void QCocoaWindow::windowDidResize() clipChildWindows(); [qnsview_cast(m_view) updateGeometry]; + + if (!m_view.inLiveResize) + reportCurrentWindowState(); } void QCocoaWindow::viewDidChangeFrame() @@ -1280,10 +1318,7 @@ void QCocoaWindow::viewDidChangeGlobalFrame() void QCocoaWindow::windowDidEndLiveResize() { - if (m_synchedWindowState == Qt::WindowMaximized && ![m_nsWindow isZoomed]) { - m_effectivelyMaximized = false; - [qnsview_cast(m_view) notifyWindowStateChanged:Qt::WindowNoState]; - } + reportCurrentWindowState(); } void QCocoaWindow::windowDidBecomeKey() @@ -1320,22 +1355,37 @@ void QCocoaWindow::windowDidResignKey() void QCocoaWindow::windowDidMiniaturize() { - [qnsview_cast(m_view) notifyWindowStateChanged:Qt::WindowMinimized]; + reportCurrentWindowState(); } void QCocoaWindow::windowDidDeminiaturize() { - [qnsview_cast(m_view) notifyWindowStateChanged:Qt::WindowNoState]; + reportCurrentWindowState(); } void QCocoaWindow::windowDidEnterFullScreen() { - [qnsview_cast(m_view) notifyWindowStateChanged:Qt::WindowFullScreen]; + Q_ASSERT_X(m_nsWindow.qt_fullScreen, "QCocoaWindow", + "FullScreen category processes window notifications first"); + + reportCurrentWindowState(); } void QCocoaWindow::windowDidExitFullScreen() { - [qnsview_cast(m_view) notifyWindowStateChanged:Qt::WindowNoState]; + Q_ASSERT_X(!m_nsWindow.qt_fullScreen, "QCocoaWindow", + "FullScreen category processes window notifications first"); + + Qt::WindowState requestedState = window()->windowState(); + + // Deliver update of QWindow state + reportCurrentWindowState(); + + if (requestedState != windowState() && requestedState != Qt::WindowFullScreen) { + // We were only going out of full screen as an intermediate step before + // progressing into the final step, so re-sync the desired state. + applyWindowState(requestedState); + } } void QCocoaWindow::windowDidOrderOffScreen() @@ -1399,12 +1449,6 @@ bool QCocoaWindow::windowShouldClose() // -------------------------------------------------------------------------- -void QCocoaWindow::setSynchedWindowStateFromWindow() -{ - if (QWindow *w = window()) - m_synchedWindowState = w->windowState(); -} - bool QCocoaWindow::windowIsPopupType(Qt::WindowType type) const { if (type == Qt::Widget) @@ -1579,15 +1623,8 @@ void QCocoaWindow::recreateWindowIfNeeded() } // Set properties after the window has been made a child NSWindow - m_nsWindow.styleMask = NSBorderlessWindowMask; - m_nsWindow.hasShadow = NO; - m_nsWindow.level = NSNormalWindowLevel; - NSWindowCollectionBehavior collectionBehavior = - NSWindowCollectionBehaviorManaged | NSWindowCollectionBehaviorIgnoresCycle - | NSWindowCollectionBehaviorFullScreenAuxiliary; - m_nsWindow.animationBehavior = NSWindowAnimationBehaviorNone; - m_nsWindow.collectionBehavior = collectionBehavior; setCocoaGeometry(windowGeometry()); + setWindowFlags(window()->flags()); } else { // Child windows have no NSWindow, link the NSViews instead. if ([m_view superview]) @@ -1604,9 +1641,6 @@ void QCocoaWindow::recreateWindowIfNeeded() [m_view setHidden:!window()->isVisible()]; } - m_nsWindow.ignoresMouseEvents = - (window()->flags() & Qt::WindowTransparentForInput) == Qt::WindowTransparentForInput; - const qreal opacity = qt_window_private(window())->opacity; if (!qFuzzyCompare(opacity, qreal(1.0))) setOpacity(opacity); @@ -1674,62 +1708,49 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBeChildNSWindow, bool sh Qt::WindowType type = window()->type(); Qt::WindowFlags flags = window()->flags(); - NSUInteger styleMask; - if (shouldBeChildNSWindow) { - styleMask = NSBorderlessWindowMask; - } else { - styleMask = windowStyleMask(flags); - } - QCocoaNSWindow *createdWindow = 0; - - // Use NSPanel for popup-type windows. (Popup, Tool, ToolTip, SplashScreen) - // and dialogs - if (shouldBePanel) { - QNSPanel *panel = [[QNSPanel alloc] initWithContentRect:frame screen:cocoaScreen->nativeScreen() - styleMask: styleMask qPlatformWindow:this]; - - if ((type & Qt::Popup) == Qt::Popup) - [panel setHasShadow:YES]; - - // Qt::Tool windows hide on app deactivation, unless Qt::WA_MacAlwaysShowToolWindow is set. - QVariant showWithoutActivating = QPlatformWindow::window()->property("_q_macAlwaysShowToolWindow"); - bool shouldHideOnDeactivate = ((type & Qt::Tool) == Qt::Tool) && - !(showWithoutActivating.isValid() && showWithoutActivating.toBool()); - [panel setHidesOnDeactivate: shouldHideOnDeactivate]; + // Create NSWindow + Class windowClass = shouldBePanel ? [QNSPanel class] : [QNSWindow class]; + NSUInteger styleMask = shouldBeChildNSWindow ? NSBorderlessWindowMask : windowStyleMask(flags); + QCocoaNSWindow *window = [[windowClass alloc] initWithContentRect:frame + screen:cocoaScreen->nativeScreen() styleMask:styleMask qPlatformWindow:this]; - // Make popup windows show on the same desktop as the parent full-screen window. - [panel setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary]; - if ((type & Qt::Popup) == Qt::Popup) - [panel setAnimationBehavior:NSWindowAnimationBehaviorUtilityWindow]; + window.restorable = NO; + window.level = shouldBeChildNSWindow ? NSNormalWindowLevel : windowLevel(flags); - createdWindow = panel; - } else { - createdWindow = [[QNSWindow alloc] initWithContentRect:frame screen:cocoaScreen->nativeScreen() - styleMask: styleMask qPlatformWindow:this]; + if (!isOpaque()) { + window.backgroundColor = [NSColor clearColor]; + window.opaque = NO; } - if ([createdWindow respondsToSelector:@selector(setRestorable:)]) - [createdWindow setRestorable: NO]; + Q_ASSERT(!(shouldBePanel && shouldBeChildNSWindow)); - NSInteger level = windowLevel(flags); - [createdWindow setLevel:level]; + if (shouldBePanel) { + // Qt::Tool windows hide on app deactivation, unless Qt::WA_MacAlwaysShowToolWindow is set + window.hidesOnDeactivate = ((type & Qt::Tool) == Qt::Tool) && + !qt_mac_resolveOption(false, QPlatformWindow::window(), "_q_macAlwaysShowToolWindow", ""); - // OpenGL surfaces can be ordered either above(default) or below the NSWindow. - // When ordering below the window must be tranclucent and have a clear background color. - static GLint openglSourfaceOrder = qt_mac_resolveOption(1, "QT_MAC_OPENGL_SURFACE_ORDER"); + // Make popup windows show on the same desktop as the parent full-screen window + window.collectionBehavior = NSWindowCollectionBehaviorFullScreenAuxiliary; - bool isTranslucent = window()->format().alphaBufferSize() > 0 - || (surface()->supportsOpenGL() && openglSourfaceOrder == -1); - if (isTranslucent) { - [createdWindow setBackgroundColor:[NSColor clearColor]]; - [createdWindow setOpaque:NO]; + if ((type & Qt::Popup) == Qt::Popup) { + window.hasShadow = YES; + window.animationBehavior = NSWindowAnimationBehaviorUtilityWindow; + } + } else if (shouldBeChildNSWindow) { + window.collectionBehavior = + NSWindowCollectionBehaviorManaged + | NSWindowCollectionBehaviorIgnoresCycle + | NSWindowCollectionBehaviorFullScreenAuxiliary; + window.hasShadow = NO; + window.animationBehavior = NSWindowAnimationBehaviorNone; } - m_windowModality = window()->modality(); + // Persist modality so we can detect changes later on + m_windowModality = QPlatformWindow::window()->modality(); - applyContentBorderThickness(createdWindow); + applyContentBorderThickness(window); - return createdWindow; + return window; } void QCocoaWindow::removeMonitor() @@ -1753,85 +1774,155 @@ QRect QCocoaWindow::nativeWindowGeometry() const return qRect; } -// Syncs the NSWindow minimize/maximize/fullscreen state with the current QWindow state -void QCocoaWindow::syncWindowState(Qt::WindowState newState) +/*! + Applies the given state to the NSWindow, going in/out of minimize/zoomed/fullscreen + + When this is called from QWindow::setWindowState(), the QWindow state has not been + updated yet, so window()->windowState() will reflect the previous state that was + reported to QtGui. +*/ +void QCocoaWindow::applyWindowState(Qt::WindowState newState) { + const Qt::WindowState currentState = windowState(); + if (newState == currentState) + return; + if (!m_nsWindow) return; - // if content view width or height is 0 then the window animations will crash so - // do nothing except set the new state - NSRect contentRect = m_view.frame; - if (contentRect.size.width <= 0 || contentRect.size.height <= 0) { + + const NSSize contentSize = m_view.frame.size; + if (contentSize.width <= 0 || contentSize.height <= 0) { + // If content view width or height is 0 then the window animations will crash so + // do nothing. We report the current state back to reflect the failed operation. qWarning("invalid window content view size, check your window geometry"); - m_synchedWindowState = newState; + reportCurrentWindowState(true); return; } - Qt::WindowState predictedState = newState; - if ((m_synchedWindowState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized)) { - const int styleMask = [m_nsWindow styleMask]; - const bool usePerform = styleMask & NSResizableWindowMask; - [m_nsWindow setStyleMask:styleMask | NSResizableWindowMask]; - if (usePerform) - [m_nsWindow performZoom : m_nsWindow]; // toggles - else - [m_nsWindow zoom : m_nsWindow]; // toggles - [m_nsWindow setStyleMask:styleMask]; + if (m_nsWindow.styleMask & NSUtilityWindowMask) { + // Utility panels cannot be fullscreen + qWarning() << window()->type() << "windows can not be made full screen"; + reportCurrentWindowState(true); + return; } - if ((m_synchedWindowState & Qt::WindowMinimized) != (newState & Qt::WindowMinimized)) { - if (newState & Qt::WindowMinimized) { - if ([m_nsWindow styleMask] & NSMiniaturizableWindowMask) - [m_nsWindow performMiniaturize : m_nsWindow]; - else - [m_nsWindow miniaturize : m_nsWindow]; - } else { - [m_nsWindow deminiaturize : m_nsWindow]; - } + const id sender = m_nsWindow; + + // First we need to exit states that can't transition directly to other states + switch (currentState) { + case Qt::WindowMinimized: + [m_nsWindow deminiaturize:sender]; + Q_ASSERT_X(windowState() != Qt::WindowMinimized, "QCocoaWindow", + "[NSWindow deminiaturize:] is synchronous"); + break; + case Qt::WindowFullScreen: { + toggleFullScreen(); + // Exiting fullscreen is not synchronous, so we need to wait for the + // NSWindowDidExitFullScreenNotification before continuing to apply + // the new state. + return; } - - const bool effMax = m_effectivelyMaximized; - if ((m_synchedWindowState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized) || (m_effectivelyMaximized && newState == Qt::WindowNoState)) { - if ((m_synchedWindowState & Qt::WindowFullScreen) == (newState & Qt::WindowFullScreen)) { - [m_nsWindow zoom : m_nsWindow]; // toggles - m_effectivelyMaximized = !effMax; - } else if (!(newState & Qt::WindowMaximized)) { - // it would be nice to change the target geometry that toggleFullScreen will animate toward - // but there is no known way, so the maximized state is not possible at this time - predictedState = static_cast<Qt::WindowState>(static_cast<int>(newState) | Qt::WindowMaximized); - m_effectivelyMaximized = true; - } + default: + Q_FALLTHROUGH(); } - if ((m_synchedWindowState & Qt::WindowFullScreen) != (newState & Qt::WindowFullScreen)) { - if (window()->flags() & Qt::WindowFullscreenButtonHint) { - if (m_effectivelyMaximized && m_synchedWindowState == Qt::WindowFullScreen) - predictedState = Qt::WindowMaximized; - [m_nsWindow toggleFullScreen : m_nsWindow]; - } else { - if (newState & Qt::WindowFullScreen) { - QScreen *screen = window()->screen(); - if (screen) { - if (m_normalGeometry.width() < 0) { - m_oldWindowFlags = m_windowFlags; - window()->setFlags(window()->flags() | Qt::FramelessWindowHint); - m_normalGeometry = nativeWindowGeometry(); - setGeometry(screen->geometry()); - m_presentationOptions = [NSApp presentationOptions]; - [NSApp setPresentationOptions : m_presentationOptions | NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationAutoHideDock]; - } - } - } else { - window()->setFlags(m_oldWindowFlags); - setGeometry(m_normalGeometry); - m_normalGeometry.setRect(0, 0, -1, -1); - [NSApp setPresentationOptions : m_presentationOptions]; - } + // Then we apply the new state if needed + if (newState == windowState()) + return; + + switch (newState) { + case Qt::WindowFullScreen: + toggleFullScreen(); + break; + case Qt::WindowMaximized: + toggleMaximized(); + break; + case Qt::WindowMinimized: + [m_nsWindow miniaturize:sender]; + break; + case Qt::WindowNoState: + switch (windowState()) { + case Qt::WindowMaximized: + toggleMaximized(); + default: + Q_FALLTHROUGH(); } + break; + default: + Q_UNREACHABLE(); } +} + +void QCocoaWindow::toggleMaximized() +{ + // The NSWindow needs to be resizable, otherwise the window will + // not be possible to zoom back to non-zoomed state. + const bool wasResizable = m_nsWindow.styleMask & NSResizableWindowMask; + m_nsWindow.styleMask |= NSResizableWindowMask; + + const id sender = m_nsWindow; + [m_nsWindow zoom:sender]; + + if (!wasResizable) + m_nsWindow.styleMask &= ~NSResizableWindowMask; +} + +void QCocoaWindow::toggleFullScreen() +{ + // The NSWindow needs to be resizable, otherwise we'll end up with + // the normal window geometry, centered in the middle of the screen + // on a black background. + const bool wasResizable = m_nsWindow.styleMask & NSResizableWindowMask; + m_nsWindow.styleMask |= NSResizableWindowMask; + + // It also needs to have the correct collection behavior for the + // toggleFullScreen call to have an effect. + const bool wasFullScreenEnabled = m_nsWindow.collectionBehavior & NSWindowCollectionBehaviorFullScreenPrimary; + m_nsWindow.collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary; + + const id sender = m_nsWindow; + [m_nsWindow toggleFullScreen:sender]; + + if (!wasResizable) + m_nsWindow.styleMask &= ~NSResizableWindowMask; + if (!wasFullScreenEnabled) + m_nsWindow.collectionBehavior &= ~NSWindowCollectionBehaviorFullScreenPrimary; +} + +bool QCocoaWindow::isTransitioningToFullScreen() const +{ + NSWindow *window = m_view.window; + return window.styleMask & NSFullScreenWindowMask && !window.qt_fullScreen; +} + +Qt::WindowState QCocoaWindow::windowState() const +{ + // FIXME: Support compound states (Qt::WindowStates) + + NSWindow *window = m_view.window; + if (window.miniaturized) + return Qt::WindowMinimized; + if (window.qt_fullScreen) + return Qt::WindowFullScreen; + if ((window.zoomed && !isTransitioningToFullScreen()) + || (m_lastReportedWindowState == Qt::WindowMaximized && isTransitioningToFullScreen())) + return Qt::WindowMaximized; + + // Note: We do not report Qt::WindowActive, even if isActive() + // is true, as QtGui does not expect this window state to be set. + + return Qt::WindowNoState; +} + +void QCocoaWindow::reportCurrentWindowState(bool unconditionally) +{ + Qt::WindowState currentState = windowState(); + if (!unconditionally && currentState == m_lastReportedWindowState) + return; - // New state is now the current synched state - m_synchedWindowState = predictedState; + QWindowSystemInterface::handleWindowStateChanged<QWindowSystemInterface::SynchronousDelivery>( + window(), currentState, m_lastReportedWindowState); + m_lastReportedWindowState = currentState; } bool QCocoaWindow::setWindowModified(bool modified) diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 84be7eb797..75a508370f 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -100,8 +100,6 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); - (void)drawRect:(NSRect)dirtyRect; - (void)drawBackingStoreUsingCoreGraphics:(NSRect)dirtyRect; - (void)updateGeometry; -- (void)notifyWindowStateChanged:(Qt::WindowState)newState; -- (void)notifyWindowWillZoom:(BOOL)willZoom; - (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification; - (void)viewDidHide; - (void)viewDidUnhide; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 7ce407f7d0..fbf4f99f2e 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -339,21 +339,6 @@ static bool _q_dontOverrideCtrlLMB = false; } } -- (void)notifyWindowStateChanged:(Qt::WindowState)newState -{ - // If the window was maximized, then fullscreen, then tried to go directly to "normal" state, - // this notification will say that it is "normal", but it will still look maximized, and - // if you called performZoom it would actually take it back to "normal". - // So we should say that it is maximized because it actually is. - if (newState == Qt::WindowNoState && m_platformWindow->m_effectivelyMaximized) - newState = Qt::WindowMaximized; - QWindowSystemInterface::handleWindowStateChanged(m_platformWindow->window(), newState); - // We want to read the window state back from the window, - // but the event we just sent may be asynchronous. - QWindowSystemInterface::flushWindowSystemEvents(); - m_platformWindow->setSynchedWindowStateFromWindow(); -} - - (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification { Q_UNUSED(textInputContextKeyboardSelectionDidChangeNotification) @@ -363,14 +348,6 @@ static bool _q_dontOverrideCtrlLMB = false; } } -- (void)notifyWindowWillZoom:(BOOL)willZoom -{ - Qt::WindowState newState = willZoom ? Qt::WindowMaximized : Qt::WindowNoState; - if (!willZoom) - m_platformWindow->m_effectivelyMaximized = false; - [self notifyWindowStateChanged:newState]; -} - - (void)viewDidHide { m_platformWindow->obscureWindow(); diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h index a465b249c5..d2078b5786 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.h +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h @@ -52,7 +52,6 @@ - (id)initWithQCocoaWindow:(QCocoaWindow *)cocoaWindow; - (BOOL)windowShouldClose:(NSNotification *)notification; -- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame; - (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu; - (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard; diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm index 2d5afa9375..ce74aa9973 100644 --- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm +++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm @@ -41,6 +41,7 @@ #include "qcocoahelpers.h" #include <QDebug> +#include <qpa/qplatformscreen.h> #include <qpa/qwindowsysteminterface.h> @implementation QNSWindowDelegate @@ -62,13 +63,19 @@ return YES; } - -- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame +/*! + Overridden to ensure that the zoomed state always results in a maximized + window, which would otherwise not be the case for borderless windows. +*/ +- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)newFrame { Q_UNUSED(newFrame); - if (m_cocoaWindow && !m_cocoaWindow->isForeignWindow()) - [qnsview_cast(m_cocoaWindow->view()) notifyWindowWillZoom:![window isZoomed]]; - return YES; + + // We explicitly go through the QScreen API here instead of just using + // window.screen.visibleFrame directly, as that ensures we have the same + // behavior for both use-cases/APIs. + Q_ASSERT(window == m_cocoaWindow->nativeWindow()); + return m_cocoaWindow->screen()->availableGeometry().toCGRect(); } - (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorintegration.cpp index 8a059ba973..1abc430da6 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorintegration.cpp @@ -122,13 +122,13 @@ EGLNativeWindowType QEglFSEmulatorIntegration::createNativeWindow(QPlatformWindo { Q_UNUSED(size); Q_UNUSED(format); - static QAtomicInt uniqueWindowId(1); QEglFSEmulatorScreen *screen = static_cast<QEglFSEmulatorScreen *>(platformWindow->screen()); if (screen && setDisplay) { // Let the emulator know which screen the window surface is attached to setDisplay(screen->id()); } - return EGLNativeWindowType(qintptr(uniqueWindowId.fetchAndAddRelaxed(1))); + static QBasicAtomicInt uniqueWindowId = Q_BASIC_ATOMIC_INITIALIZER(0); + return EGLNativeWindowType(qintptr(1 + uniqueWindowId.fetchAndAddRelaxed(1))); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h index 27632de688..a5c05bf1a3 100644 --- a/src/plugins/platforms/windows/qtwindowsglobal.h +++ b/src/plugins/platforms/windows/qtwindowsglobal.h @@ -56,6 +56,10 @@ # define WM_GESTURE 0x0119 #endif +#ifndef WM_DPICHANGED +# define WM_DPICHANGED 0x02E0 +#endif + QT_BEGIN_NAMESPACE namespace QtWindows @@ -96,6 +100,7 @@ enum WindowsEventType // Simplify event types FocusInEvent = WindowEventFlag + 17, FocusOutEvent = WindowEventFlag + 18, WhatsThisEvent = WindowEventFlag + 19, + DpiChangedEvent = WindowEventFlag + 21, MouseEvent = MouseEventFlag + 1, MouseWheelEvent = MouseEventFlag + 2, CursorEvent = MouseEventFlag + 3, @@ -266,6 +271,8 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI #endif case WM_GESTURE: return QtWindows::GestureEvent; + case WM_DPICHANGED: + return QtWindows::DpiChangedEvent; default: break; } diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index fefc848d01..5745fc6d19 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -1088,6 +1088,15 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, return true; #endif } break; + case QtWindows::DpiChangedEvent: { + platformWindow->setFlag(QWindowsWindow::WithinDpiChanged); + const RECT *prcNewWindow = reinterpret_cast<RECT *>(lParam); + SetWindowPos(hwnd, NULL, prcNewWindow->left, prcNewWindow->top, + prcNewWindow->right - prcNewWindow->left, + prcNewWindow->bottom - prcNewWindow->top, SWP_NOZORDER | SWP_NOACTIVATE); + platformWindow->clearFlag(QWindowsWindow::WithinDpiChanged); + return true; + } #if !defined(QT_NO_SESSIONMANAGER) case QtWindows::QueryEndSessionApplicationEvent: { QWindowsSessionManager *sessionManager = platformSessionManager(); diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h index 23d2fd0d09..dfaa428520 100644 --- a/src/plugins/platforms/windows/qwindowsglcontext.h +++ b/src/plugins/platforms/windows/qwindowsglcontext.h @@ -48,6 +48,7 @@ #include <vector> QT_BEGIN_NAMESPACE +#ifndef QT_NO_OPENGL class QDebug; @@ -227,7 +228,7 @@ private: GLenum (APIENTRY * m_getGraphicsResetStatus)(); bool m_lost; }; - +#endif QT_END_NAMESPACE #endif // QWINDOWSGLCONTEXT_H diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index bd598630ba..24fb12d27a 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -82,6 +82,7 @@ static bool monitorData(HMONITOR hMonitor, QWindowsScreenData *data) if (GetMonitorInfo(hMonitor, &info) == FALSE) return false; + data->hMonitor = hMonitor; data->geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1)); data->availableGeometry = QRect(QPoint(info.rcWork.left, info.rcWork.top), QPoint(info.rcWork.right - 1, info.rcWork.bottom - 1)); data->name = QString::fromWCharArray(info.szDevice); diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h index 00722e2fa4..9a8997326b 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.h +++ b/src/plugins/platforms/windows/qwindowsscreen.h @@ -69,6 +69,7 @@ struct QWindowsScreenData QString name; Qt::ScreenOrientation orientation = Qt::LandscapeOrientation; qreal refreshRateHz = 60; + HMONITOR hMonitor = nullptr; }; class QWindowsScreen : public QPlatformScreen diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 0b6318ce9f..121fdaeabd 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -43,7 +43,11 @@ #include "qwindowsscreen.h" #include "qwindowsintegration.h" #include "qwindowsnativeinterface.h" -#include "qwindowsglcontext.h" +#if QT_CONFIG(dynamicgl) +# include "qwindowsglcontext.h" +#else +# include "qwindowsopenglcontext.h" +#endif #ifdef QT_NO_CURSOR # include "qwindowscursor.h" #endif @@ -1546,10 +1550,16 @@ void QWindowsWindow::handleGeometryChange() && !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) { fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true); } - if (previousGeometry.topLeft() != m_data.geometry.topLeft()) { - QPlatformScreen *newScreen = screenForGeometry(m_data.geometry); - if (newScreen != screen()) - QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); + if (!parent() && previousGeometry.topLeft() != m_data.geometry.topLeft()) { + HMONITOR hMonitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONULL); + QPlatformScreen *currentScreen = screen(); + const auto screens = QWindowsContext::instance()->screenManager().screens(); + auto newScreenIt = std::find_if(screens.begin(), screens.end(), [&](QWindowsScreen *s) { + return s->data().hMonitor == hMonitor + && s->data().flags & QWindowsScreenData::VirtualDesktop; + }); + if (newScreenIt != screens.end() && *newScreenIt != currentScreen) + QWindowSystemInterface::handleWindowScreenChanged(window(), (*newScreenIt)->screen()); } if (testFlag(SynchronousGeometryChangeEvent)) QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); @@ -1629,7 +1639,8 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message, if (message == WM_ERASEBKGND) // Backing store - ignored. return true; // Ignore invalid update bounding rectangles - if (!GetUpdateRect(m_data.hwnd, 0, FALSE)) + RECT updateRect; + if (!GetUpdateRect(m_data.hwnd, &updateRect, FALSE)) return false; PAINTSTRUCT ps; @@ -1653,7 +1664,7 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message, // we still need to send isExposed=true, for compatibility. // Our tests depend on it. fireExpose(QRegion(qrectFromRECT(ps.rcPaint)), true); - if (!QWindowsContext::instance()->asyncExpose()) + if (qSizeOfRect(updateRect) == m_data.geometry.size() && !QWindowsContext::instance()->asyncExpose()) QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); EndPaint(hwnd, &ps); @@ -2121,8 +2132,12 @@ void QWindowsWindow::setFrameStrutEventsEnabled(bool enabled) void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const { - const QWindowsGeometryHint hint(window(), m_data.customMargins); - hint.applyToMinMaxInfo(m_data.hwnd, mmi); + // We don't apply the min/max size hint as we change the dpi, because we did not adjust the + // QScreen of the window yet so we don't have the min/max with the right ratio + if (!testFlag(QWindowsWindow::WithinDpiChanged)) { + const QWindowsGeometryHint hint(window(), m_data.customMargins); + hint.applyToMinMaxInfo(m_data.hwnd, mmi); + } if ((testFlag(WithinMaximize) || (window()->windowState() == Qt::WindowMinimized)) && (m_data.flags & Qt::FramelessWindowHint)) { diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index bc4f6216ba..227b79a207 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -205,7 +205,8 @@ public: MaximizeToFullScreen = 0x80000, InputMethodDisabled = 0x100000, Compositing = 0x200000, - HasBorderInFullScreen = 0x400000 + HasBorderInFullScreen = 0x400000, + WithinDpiChanged = 0x800000, }; QWindowsWindow(QWindow *window, const QWindowsWindowData &data); diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 3444b21654..8c5f8cae08 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -605,7 +605,8 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra initializeXRender(); #if defined(XCB_USE_XINPUT2) - initializeXInput2(); + if (!qEnvironmentVariableIsSet("QT_XCB_NO_XI2")) + initializeXInput2(); #endif initializeXShape(); initializeXKB(); diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index acdcc996b7..f70c7138b3 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -226,6 +226,9 @@ void QXcbConnection::xi2SetupDevices() isTablet = true; tabletData.pointerType = QTabletEvent::Pen; dbgType = QLatin1String("pen"); + } else if (name.contains("uc-logic") && isTablet) { + tabletData.pointerType = QTabletEvent::Pen; + dbgType = QLatin1String("pen"); } else { isTablet = false; } diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp index d91e502b96..0416215870 100644 --- a/src/sql/kernel/qsqldatabase.cpp +++ b/src/sql/kernel/qsqldatabase.cpp @@ -313,7 +313,7 @@ void QSqlDatabasePrivate::disable() /*! \class QSqlDatabase - \brief The QSqlDatabase class represents a connection to + \brief The QSqlDatabase class handles a connection to a database. \ingroup database @@ -332,18 +332,17 @@ void QSqlDatabasePrivate::disable() Create a connection (i.e., an instance of QSqlDatabase) by calling one of the static addDatabase() functions, where you specify \l{SQL Database Drivers#Supported Databases} {the driver or type - of driver} to use (i.e., what kind of database will you access?) + of driver} to use (depending on the type of database) and a connection name. A connection is known by its own name, \e{not} by the name of the database it connects to. You can have multiple connections to one database. QSqlDatabase also supports the concept of a \e{default} connection, which is the unnamed connection. To create the default connection, don't pass the connection name argument when you call addDatabase(). - Subsequently, when you call any static member function that takes - the connection name argument, if you don't pass the connection - name argument, the default connection is assumed. The following - snippet shows how to create and open a default connection to a - PostgreSQL database: + Subsequently, the default connection will be assumed if you call + any static member function without specifying the connection name. + The following snippet shows how to create and open a default connection + to a PostgreSQL database: \snippet sqldatabase/sqldatabase.cpp 0 @@ -374,27 +373,50 @@ void QSqlDatabasePrivate::disable() referenced by other QSqlDatabase objects. Use contains() to see if a given connection name is in the list of connections. - Once a connection is established, you can call tables() to get the - list of tables in the database, call primaryIndex() to get a - table's primary index, and call record() to get meta-information - about a table's fields (e.g., field names). + \table + \header + \li {2,1}Some utility methods: + \row + \li tables() + \li returns the list of tables + \row + \li primaryIndex() + \li returns a table's primary index + \row + \li record() + \li returns meta-information about a table's fields + \row + \li transaction() + \li starts a transaction + \row + \li commit() + \li saves and completes a transaction + \row + \li rollback() + \li cancels a transaction + \row + \li hasFeature() + \li checks if a driver supports transactions + \row + \li lastError() + \li returns information about the last error + \row + \li drivers() + \li returns the names of the available SQL drivers + \row + \li isDriverAvailable() + \li checks if a particular driver is available + \row + \li registerSqlDriver() + \li registers a custom-made driver + \endtable \note QSqlDatabase::exec() is deprecated. Use QSqlQuery::exec() instead. - If the driver supports transactions, use transaction() to start a - transaction, and commit() or rollback() to complete it. Use - \l{QSqlDriver::} {hasFeature()} to ask if the driver supports - transactions. \note When using transactions, you must start the + \note When using transactions, you must start the transaction before you create your query. - If an error occurs, lastError() will return information about it. - - Get the names of the available SQL drivers with drivers(). Check - for the presence of a particular driver with isDriverAvailable(). - If you have created your own custom driver, you must register it - with registerSqlDriver(). - \sa QSqlDriver, QSqlQuery, {Qt SQL}, {Threads and the SQL Module} */ @@ -963,9 +985,9 @@ QString QSqlDatabase::userName() const } /*! - Returns the connection's password. If the password was not set - with setPassword(), and if the password was given in the open() - call, or if no password was used, an empty string is returned. + Returns the connection's password. An empty string will be returned + if the password was not set with setPassword(), and if the password + was given in the open() call, or if no password was used. */ QString QSqlDatabase::password() const { @@ -1045,7 +1067,7 @@ QStringList QSqlDatabase::tables(QSql::TableType type) const /*! Returns the primary index for table \a tablename. If no primary - index exists an empty QSqlIndex is returned. + index exists, an empty QSqlIndex is returned. \sa tables(), record() */ @@ -1071,8 +1093,9 @@ QSqlRecord QSqlDatabase::record(const QString& tablename) const /*! Sets database-specific \a options. This must be done before the - connection is opened or it has no effect (or you can close() the - connection, call this function and open() the connection again). + connection is opened, otherwise it has no effect. Another possibility + is to close the connection, call QSqlDatabase::setConnectOptions(), + and open() the connection again. The format of the \a options string is a semicolon separated list of option names or option=value pairs. The options depend on the diff --git a/src/testlib/qtestsystem.h b/src/testlib/qtestsystem.h index b39fa17a34..4c611aab6b 100644 --- a/src/testlib/qtestsystem.h +++ b/src/testlib/qtestsystem.h @@ -58,7 +58,7 @@ namespace QTest { Q_ASSERT(QCoreApplication::instance()); - QDeadlineTimer timer(ms); + QDeadlineTimer timer(ms, Qt::PreciseTimer); int remaining = ms; do { QCoreApplication::processEvents(QEventLoop::AllEvents, remaining); @@ -74,7 +74,7 @@ namespace QTest #ifdef QT_GUI_LIB inline static bool qWaitForWindowActive(QWindow *window, int timeout = 5000) { - QDeadlineTimer timer(timeout); + QDeadlineTimer timer(timeout, Qt::PreciseTimer); int remaining = timeout; while (!window->isActive() && remaining > 0) { QCoreApplication::processEvents(QEventLoop::AllEvents, remaining); @@ -101,7 +101,7 @@ namespace QTest inline static bool qWaitForWindowExposed(QWindow *window, int timeout = 5000) { - QDeadlineTimer timer(timeout); + QDeadlineTimer timer(timeout, Qt::PreciseTimer); int remaining = timeout; while (!window->isExposed() && remaining > 0) { QCoreApplication::processEvents(QEventLoop::AllEvents, remaining); diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro index 0e0fe7932e..507b5260cd 100644 --- a/src/tools/bootstrap/bootstrap.pro +++ b/src/tools/bootstrap/bootstrap.pro @@ -80,7 +80,6 @@ SOURCES += \ ../../corelib/tools/qstringbuilder.cpp \ ../../corelib/tools/qstring_compat.cpp \ ../../corelib/tools/qstringlist.cpp \ - ../../corelib/tools/qvector.cpp \ ../../corelib/tools/qvsnprintf.cpp \ ../../corelib/xml/qxmlutils.cpp \ ../../corelib/xml/qxmlstream.cpp \ diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index 03f022da69..e2987f1be4 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -1294,7 +1294,12 @@ void Moc::parsePluginData(ClassDef *def) return; } QFile file(fi.canonicalFilePath()); - file.open(QFile::ReadOnly); + if (!file.open(QFile::ReadOnly)) { + QByteArray msg = "Plugin Metadata file " + lexem() + " could not be opened: " + + file.errorString().toUtf8(); + error(msg.constData()); + return; + } metaData = file.readAll(); } } diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index 65d6367d1d..2b0d70eac6 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -1153,6 +1153,7 @@ void WriteInitialization::writeProperties(const QString &varName, DomPropertyMap properties = propertyMap(lst); if (properties.contains(QLatin1String("control"))) { DomProperty *p = properties.value(QLatin1String("control")); + Q_ASSERT( p ); m_output << m_indent << varName << "->setControl(" << writeString(toString(p->elementString()), m_dindent) << ");\n"; } diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 5bfb7553a5..a552746385 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -656,7 +656,7 @@ void QFileDialogPrivate::retranslateStrings() /* WIDGETS */ if (options->useDefaultNameFilters()) q->setNameFilter(QFileDialogOptions::defaultNameFilterString()); - if (nativeDialogInUse) + if (!usingWidgets()) return; QList<QAction*> actions = qFileDialogUi->treeView->header()->actions(); @@ -2246,7 +2246,7 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent, } /*! - This is a convenience static function that will return or or more existing + This is a convenience static function that will return one or more existing files selected by the user. If the user presses Cancel, it returns an empty list. diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp index 4f6ef49a7f..4ab01aca66 100644 --- a/src/widgets/dialogs/qwizard_win.cpp +++ b/src/widgets/dialogs/qwizard_win.cpp @@ -215,8 +215,7 @@ void QVistaHelper::disconnectBackButton() QColor QVistaHelper::basicWindowFrameColor() { DWORD rgb; - HWND handle = QApplicationPrivate::getHWNDForWidget(QApplication::desktop()); - const HANDLE hTheme = OpenThemeData(handle, L"WINDOW"); + const HANDLE hTheme = OpenThemeData(GetDesktopWindow(), L"WINDOW"); GetThemeColor(hTheme, WP_CAPTION, CS_ACTIVE, wizard->isActiveWindow() ? TMT_FILLCOLORHINT : TMT_BORDERCOLORHINT, &rgb); BYTE r = GetRValue(rgb); @@ -258,8 +257,7 @@ static LOGFONT getCaptionLogFont(HANDLE hTheme) static bool getCaptionQFont(int dpi, QFont *result) { - const HANDLE hTheme = - OpenThemeData(QApplicationPrivate::getHWNDForWidget(QApplication::desktop()), L"WINDOW"); + const HANDLE hTheme = OpenThemeData(GetDesktopWindow(), L"WINDOW"); if (!hTheme) return false; // Call into QWindowsNativeInterface to convert the LOGFONT into a QFont. @@ -590,8 +588,7 @@ bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const Q if (vistaState() == VistaAero) { const QRect rectDp = QRect(rect.topLeft() * QVistaHelper::m_devicePixelRatio, rect.size() * QVistaHelper::m_devicePixelRatio); - HWND handle = QApplicationPrivate::getHWNDForWidget(QApplication::desktop()); - const HANDLE hTheme = OpenThemeData(handle, L"WINDOW"); + const HANDLE hTheme = OpenThemeData(GetDesktopWindow(), L"WINDOW"); if (!hTheme) return false; // Set up a memory DC and bitmap that we'll draw into HDC dcMem; diff --git a/src/widgets/kernel/qaction.cpp b/src/widgets/kernel/qaction.cpp index e0700d877e..4582a55394 100644 --- a/src/widgets/kernel/qaction.cpp +++ b/src/widgets/kernel/qaction.cpp @@ -625,7 +625,7 @@ QActionGroup *QAction::actionGroup() const it is displayed to the left of the menu text. There is no default icon. - If a null icon (QIcon::isNull() is passed into this function, + If a null icon (QIcon::isNull()) is passed into this function, the icon of the action is cleared. */ void QAction::setIcon(const QIcon &icon) diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp index a06d01be67..c66a6d5673 100644 --- a/src/widgets/kernel/qformlayout.cpp +++ b/src/widgets/kernel/qformlayout.cpp @@ -1551,24 +1551,19 @@ QFormLayout::TakeRowResult QFormLayout::takeRow(int row) { Q_D(QFormLayout); - const int storageIndex = storageIndexFromLayoutItem(d->m_matrix, d->m_things.value(row)); - if (Q_UNLIKELY(storageIndex == -1)) { + if (Q_UNLIKELY(!(uint(row) < uint(d->m_matrix.rowCount())))) { qWarning("QFormLayout::takeRow: Invalid row %d", row); return TakeRowResult(); } - int storageRow, dummy; - QFormLayoutPrivate::ItemMatrix::storageIndexToPosition(storageIndex, &storageRow, &dummy); - Q_ASSERT(d->m_matrix(storageRow, dummy)); - - QFormLayoutItem *label = d->m_matrix(storageRow, 0); - QFormLayoutItem *field = d->m_matrix(storageRow, 1); + QFormLayoutItem *label = d->m_matrix(row, 0); + QFormLayoutItem *field = d->m_matrix(row, 1); Q_ASSERT(field); d->m_things.removeOne(label); d->m_things.removeOne(field); - d->m_matrix.removeRow(storageRow); + d->m_matrix.removeRow(row); invalidate(); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index d35ad87c8d..dc55c2d5d9 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1477,10 +1477,12 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO qt_window_private(win)->positionPolicy = topData()->posIncludesFrame ? QWindowPrivate::WindowFrameInclusive : QWindowPrivate::WindowFrameExclusive; - win->create(); - // Enable nonclient-area events for QDockWidget and other NonClientArea-mouse event processing. - if ((flags & Qt::Desktop) == Qt::Window) + + if (q->windowType() != Qt::Desktop || q->testAttribute(Qt::WA_NativeWindow)) { + win->create(); + // Enable nonclient-area events for QDockWidget and other NonClientArea-mouse event processing. win->handle()->setFrameStrutEventsEnabled(true); + } data.window_flags = win->flags(); if (!win->isTopLevel()) // In a Widget world foreign windows can only be top level @@ -1501,10 +1503,13 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO } setWindowModified_helper(); - WId id = win->winId(); - // See the QPlatformWindow::winId() documentation - Q_ASSERT(id != WId(0)); - setWinId(id); + + if (win->handle()) { + WId id = win->winId(); + // See the QPlatformWindow::winId() documentation + Q_ASSERT(id != WId(0)); + setWinId(id); + } // Check children and create windows for them if necessary q_createNativeChildrenAndSetParent(q); diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index 972deef150..1bdd8bf0c8 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -600,6 +600,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt XPThemeData theme(widget, painter, QWindowsXPStylePrivate::EditTheme, EP_EDITBORDER_NOSCROLL, stateId, option->rect); + theme.noContent = true; painter->save(); QRegion clipRegion = option->rect; clipRegion -= option->rect.adjusted(2, 2, -2, -2); diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp index f999d823e0..f50c143a4a 100644 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ b/src/widgets/styles/qwindowsxpstyle.cpp @@ -397,13 +397,7 @@ HWND QWindowsXPStylePrivate::winId(const QWidget *widget) return topLevelHwnd; } - if (QDesktopWidget *desktop = qApp->desktop()) - if (const HWND desktopHwnd = QApplicationPrivate::getHWNDForWidget(desktop)) - return desktopHwnd; - - Q_ASSERT(false); - - return 0; + return GetDesktopWindow(); } /*! \internal diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index 53cb21186f..aa5d809431 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -930,7 +930,9 @@ bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event) } if (state->dragging && !state->nca) { - QPoint pos = event->globalPos() - state->pressPos; + QMargins windowMargins = q->window()->windowHandle()->frameMargins(); + QPoint windowMarginOffset = QPoint(windowMargins.left(), windowMargins.top()); + QPoint pos = event->globalPos() - state->pressPos - windowMarginOffset; QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent); if (floatingTab && !q->isFloating()) |