diff options
67 files changed, 678 insertions, 238 deletions
diff --git a/configure.json b/configure.json index 6ccb1acdd9..ee931ced06 100644 --- a/configure.json +++ b/configure.json @@ -56,7 +56,6 @@ "android-sdk": "string", "android-toolchain-version": "string", - "accessibility": "boolean", "android-style-assets": "boolean", "appstore-compliant": "boolean", "avx": "boolean", @@ -941,10 +940,6 @@ "condition": "config.qnx && tests.stack_protector", "output": [ "publicQtConfig" ] }, - "accessibility": { - "label": "Accessibility", - "output": [ "publicFeature", "feature" ] - }, "system-zlib": { "label": "Using system zlib", "condition": "libs.zlib", @@ -1107,11 +1102,6 @@ or compile needed modules into the library." Configure with '-qreal float' to create a build that is binary-compatible with 5.1." }, { - "type": "warning", - "condition": "!features.accessibility", - "message": "Accessibility disabled. This configuration of Qt is unsupported." - }, - { "type": "error", "condition": "!features.stl", "message": "Qt requires a compliant STL library." @@ -1217,7 +1207,6 @@ Configure with '-qreal float' to create a build that is binary-compatible with 5 }, { "section": "Support enabled for", "entries": [ - "accessibility", "pkg-config", "qml-debug", "libudev", diff --git a/src/3rdparty/sqlite.pri b/src/3rdparty/sqlite.pri index 8f50454064..79179daaf4 100644 --- a/src/3rdparty/sqlite.pri +++ b/src/3rdparty/sqlite.pri @@ -1,5 +1,5 @@ CONFIG(release, debug|release):DEFINES *= NDEBUG -DEFINES += SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_RTREE +DEFINES += SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_FTS5 SQLITE_ENABLE_RTREE !contains(CONFIG, largefile):DEFINES += SQLITE_DISABLE_LFS qtConfig(posix_fallocate): DEFINES += HAVE_POSIX_FALLOCATE=1 winrt: DEFINES += SQLITE_OS_WINRT diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h index d197c8d384..4f79c48c51 100644 --- a/src/corelib/global/qtypeinfo.h +++ b/src/corelib/global/qtypeinfo.h @@ -58,9 +58,10 @@ class QTypeInfo { public: enum { + isSpecialized = std::is_enum<T>::value, // don't require every enum to be marked manually isPointer = false, isIntegral = std::is_integral<T>::value, - isComplex = true, + isComplex = !isIntegral && !std::is_enum<T>::value, isStatic = true, isRelocatable = std::is_enum<T>::value, isLarge = (sizeof(T)>sizeof(void*)), @@ -74,6 +75,7 @@ class QTypeInfo<void> { public: enum { + isSpecialized = true, isPointer = false, isIntegral = false, isComplex = false, @@ -90,6 +92,7 @@ class QTypeInfo<T*> { public: enum { + isSpecialized = true, isPointer = true, isIntegral = false, isComplex = false, @@ -152,6 +155,7 @@ class QTypeInfoMerger { public: enum { + isSpecialized = true, isComplex = QTypeInfoQuery<T1>::isComplex || QTypeInfoQuery<T2>::isComplex || QTypeInfoQuery<T3>::isComplex || QTypeInfoQuery<T4>::isComplex, isStatic = QTypeInfoQuery<T1>::isStatic || QTypeInfoQuery<T2>::isStatic @@ -173,6 +177,7 @@ class QTypeInfo< CONTAINER<T> > \ { \ public: \ enum { \ + isSpecialized = true, \ isPointer = false, \ isIntegral = false, \ isComplex = true, \ @@ -201,6 +206,7 @@ class QTypeInfo< CONTAINER<K, V> > \ { \ public: \ enum { \ + isSpecialized = true, \ isPointer = false, \ isIntegral = false, \ isComplex = true, \ @@ -241,6 +247,7 @@ class QTypeInfo<TYPE > \ { \ public: \ enum { \ + isSpecialized = true, \ isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0), \ isStatic = (((FLAGS) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), \ isRelocatable = !isStatic || ((FLAGS) & Q_RELOCATABLE_TYPE), \ diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h index 1c540f64c7..e247c48703 100644 --- a/src/corelib/kernel/qmetaobject_p.h +++ b/src/corelib/kernel/qmetaobject_p.h @@ -143,21 +143,17 @@ public: } bool operator==(const QArgumentType &other) const { - if (_type) + if (_type && other._type) return _type == other._type; - else if (other._type) - return false; else - return _name == other._name; + return name() == other.name(); } bool operator!=(const QArgumentType &other) const { - if (_type) + if (_type && other._type) return _type != other._type; - else if (other._type) - return true; else - return _name != other._name; + return name() != other.name(); } private: diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp index 2ecf8f729a..e45aaec103 100644 --- a/src/corelib/thread/qthreadpool.cpp +++ b/src/corelib/thread/qthreadpool.cpp @@ -316,22 +316,39 @@ void QThreadPoolPrivate::clear() } /*! - \internal - Searches for \a runnable in the queue, removes it from the queue and - returns \c true if it was found in the queue + \since 5.9 + + Attempts to remove the specified \a runnable from the queue if it is not yet started. + If the runnable had not been started, returns \c true, and ownership of \a runnable + is transferred to the caller (even when \c{runnable->autoDelete() == true}). + Otherwise returns \c false. + + \note If \c{runnable->autoDelete() == true}, this function may remove the wrong + runnable. This is known as the \l{https://en.wikipedia.org/wiki/ABA_problem}{ABA problem}: + the original \a runnable may already have executed and has since been deleted. + The memory is re-used for another runnable, which then gets removed instead of + the intended one. For this reason, we recommend calling this function only for + runnables that are not auto-deleting. + + \sa start(), QRunnable::autoDelete() */ -bool QThreadPoolPrivate::stealRunnable(QRunnable *runnable) +bool QThreadPool::tryTake(QRunnable *runnable) { + Q_D(QThreadPool); + if (runnable == 0) return false; { - QMutexLocker locker(&mutex); - QVector<QPair<QRunnable *, int> >::iterator it = queue.begin(); - QVector<QPair<QRunnable *, int> >::iterator end = queue.end(); + QMutexLocker locker(&d->mutex); + + auto it = d->queue.begin(); + auto end = d->queue.end(); while (it != end) { if (it->first == runnable) { - queue.erase(it); + d->queue.erase(it); + if (runnable->autoDelete()) + --runnable->ref; // undo ++ref in start() return true; } ++it; @@ -349,10 +366,10 @@ bool QThreadPoolPrivate::stealRunnable(QRunnable *runnable) */ void QThreadPoolPrivate::stealAndRunRunnable(QRunnable *runnable) { - if (!stealRunnable(runnable)) + Q_Q(QThreadPool); + if (!q->tryTake(runnable)) return; - const bool autoDelete = runnable->autoDelete(); - bool del = autoDelete && !--runnable->ref; + const bool del = runnable->autoDelete() && !runnable->ref; // tryTake already deref'ed runnable->run(); @@ -642,24 +659,23 @@ void QThreadPool::clear() d->clear(); } +#if QT_DEPRECATED_SINCE(5, 9) /*! \since 5.5 + \obsolete use tryTake() instead, but note the different deletion rules. Removes the specified \a runnable from the queue if it is not yet started. The runnables for which \l{QRunnable::autoDelete()}{runnable->autoDelete()} returns \c true are deleted. - \sa start() + \sa start(), tryTake() */ void QThreadPool::cancel(QRunnable *runnable) { - Q_D(QThreadPool); - if (!d->stealRunnable(runnable)) - return; - if (runnable->autoDelete() && !--runnable->ref) { + if (tryTake(runnable) && runnable->autoDelete() && !runnable->ref) // tryTake already deref'ed delete runnable; - } } +#endif QT_END_NAMESPACE diff --git a/src/corelib/thread/qthreadpool.h b/src/corelib/thread/qthreadpool.h index 0ad63c5ac3..74a8c28fc8 100644 --- a/src/corelib/thread/qthreadpool.h +++ b/src/corelib/thread/qthreadpool.h @@ -83,7 +83,12 @@ public: bool waitForDone(int msecs = -1); void clear(); + +#if QT_DEPRECATED_SINCE(5, 9) + QT_DEPRECATED_X("use tryTake(), but note the different deletion rules") void cancel(QRunnable *runnable); +#endif + bool tryTake(QRunnable *runnable) Q_REQUIRED_RESULT; }; QT_END_NAMESPACE diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h index ea8127efef..4a9f9e5cfa 100644 --- a/src/corelib/thread/qthreadpool_p.h +++ b/src/corelib/thread/qthreadpool_p.h @@ -82,7 +82,6 @@ public: void reset(); bool waitForDone(int msecs); void clear(); - bool stealRunnable(QRunnable *runnable); void stealAndRunRunnable(QRunnable *runnable); mutable QMutex mutex; diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h index 47a19dd75d..ae83e6986e 100644 --- a/src/corelib/tools/qarraydataops.h +++ b/src/corelib/tools/qarraydataops.h @@ -145,7 +145,7 @@ struct QGenericArrayOps T *const begin = this->begin(); do { - new (begin + this->size) T(); + new (begin + this->size) T; } while (uint(++this->size) != newSize); } @@ -412,7 +412,7 @@ struct QArrayOpsSelector template <class T> struct QArrayOpsSelector<T, typename std::enable_if< - !QTypeInfo<T>::isComplex && !QTypeInfo<T>::isStatic + !QTypeInfoQuery<T>::isComplex && QTypeInfoQuery<T>::isRelocatable >::type> { typedef QPodArrayOps<T> Type; @@ -421,7 +421,7 @@ struct QArrayOpsSelector<T, template <class T> struct QArrayOpsSelector<T, typename std::enable_if< - QTypeInfo<T>::isComplex && !QTypeInfo<T>::isStatic + QTypeInfoQuery<T>::isComplex && QTypeInfoQuery<T>::isRelocatable >::type> { typedef QMovableArrayOps<T> Type; diff --git a/src/corelib/tools/qbytearraymatcher.h b/src/corelib/tools/qbytearraymatcher.h index 51e08ba4bf..476bc3c049 100644 --- a/src/corelib/tools/qbytearraymatcher.h +++ b/src/corelib/tools/qbytearraymatcher.h @@ -132,6 +132,9 @@ private: } }; +QT_WARNING_PUSH +QT_WARNING_DISABLE_MSVC(4351) // MSVC 2013: "new behavior: elements of array ... will be default initialized" + // remove once we drop MSVC 2013 support template <uint N> class QStaticByteArrayMatcher : QStaticByteArrayMatcherBase { @@ -153,6 +156,8 @@ public: QByteArray pattern() const { return QByteArray(m_pattern, int(N - 1)); } }; +QT_WARNING_POP + template <uint N> Q_DECL_RELAXED_CONSTEXPR QStaticByteArrayMatcher<N> qMakeStaticByteArrayMatcher(const char (&pattern)[N]) Q_DECL_NOTHROW { return QStaticByteArrayMatcher<N>(pattern); } diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index c0a92aaa10..f861c1e71c 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -126,6 +126,7 @@ class QList public: struct MemoryLayout : std::conditional< + // must stay isStatic until ### Qt 6 for BC reasons (don't use !isRelocatable)! QTypeInfo<T>::isStatic || QTypeInfo<T>::isLarge, QListData::IndirectLayout, typename std::conditional< diff --git a/src/corelib/tools/qtimezoneprivate.cpp b/src/corelib/tools/qtimezoneprivate.cpp index ea8f6d1438..7b780ecf7d 100644 --- a/src/corelib/tools/qtimezoneprivate.cpp +++ b/src/corelib/tools/qtimezoneprivate.cpp @@ -136,7 +136,7 @@ QTimeZonePrivate::~QTimeZonePrivate() { } -QTimeZonePrivate *QTimeZonePrivate::clone() +QTimeZonePrivate *QTimeZonePrivate::clone() const { return new QTimeZonePrivate(*this); } @@ -784,7 +784,7 @@ QUtcTimeZonePrivate::~QUtcTimeZonePrivate() { } -QTimeZonePrivate *QUtcTimeZonePrivate::clone() +QUtcTimeZonePrivate *QUtcTimeZonePrivate::clone() const { return new QUtcTimeZonePrivate(*this); } diff --git a/src/corelib/tools/qtimezoneprivate_android.cpp b/src/corelib/tools/qtimezoneprivate_android.cpp index e079fa0d63..c3f8c3e0d9 100644 --- a/src/corelib/tools/qtimezoneprivate_android.cpp +++ b/src/corelib/tools/qtimezoneprivate_android.cpp @@ -88,7 +88,7 @@ void QAndroidTimeZonePrivate::init(const QByteArray &ianaId) m_id = ianaId; } -QTimeZonePrivate *QAndroidTimeZonePrivate::clone() +QAndroidTimeZonePrivate *QAndroidTimeZonePrivate::clone() const { return new QAndroidTimeZonePrivate(*this); } diff --git a/src/corelib/tools/qtimezoneprivate_icu.cpp b/src/corelib/tools/qtimezoneprivate_icu.cpp index c088fe7694..887486f567 100644 --- a/src/corelib/tools/qtimezoneprivate_icu.cpp +++ b/src/corelib/tools/qtimezoneprivate_icu.cpp @@ -305,7 +305,7 @@ QIcuTimeZonePrivate::~QIcuTimeZonePrivate() ucal_close(m_ucal); } -QTimeZonePrivate *QIcuTimeZonePrivate::clone() +QIcuTimeZonePrivate *QIcuTimeZonePrivate::clone() const { return new QIcuTimeZonePrivate(*this); } diff --git a/src/corelib/tools/qtimezoneprivate_mac.mm b/src/corelib/tools/qtimezoneprivate_mac.mm index 0c2dbe6fef..4e9a432fbf 100644 --- a/src/corelib/tools/qtimezoneprivate_mac.mm +++ b/src/corelib/tools/qtimezoneprivate_mac.mm @@ -82,7 +82,7 @@ QMacTimeZonePrivate::~QMacTimeZonePrivate() [m_nstz release]; } -QTimeZonePrivate *QMacTimeZonePrivate::clone() +QMacTimeZonePrivate *QMacTimeZonePrivate::clone() const { return new QMacTimeZonePrivate(*this); } diff --git a/src/corelib/tools/qtimezoneprivate_p.h b/src/corelib/tools/qtimezoneprivate_p.h index 682edd3996..9985d0672c 100644 --- a/src/corelib/tools/qtimezoneprivate_p.h +++ b/src/corelib/tools/qtimezoneprivate_p.h @@ -92,7 +92,7 @@ public: QTimeZonePrivate(const QTimeZonePrivate &other); virtual ~QTimeZonePrivate(); - virtual QTimeZonePrivate *clone(); + virtual QTimeZonePrivate *clone() const; bool operator==(const QTimeZonePrivate &other) const; bool operator!=(const QTimeZonePrivate &other) const; @@ -187,7 +187,7 @@ public: QUtcTimeZonePrivate(const QUtcTimeZonePrivate &other); virtual ~QUtcTimeZonePrivate(); - QTimeZonePrivate *clone() Q_DECL_OVERRIDE; + QUtcTimeZonePrivate *clone() const override; Data data(qint64 forMSecsSinceEpoch) const Q_DECL_OVERRIDE; @@ -234,7 +234,7 @@ public: QIcuTimeZonePrivate(const QIcuTimeZonePrivate &other); ~QIcuTimeZonePrivate(); - QTimeZonePrivate *clone() Q_DECL_OVERRIDE; + QIcuTimeZonePrivate *clone() const override; QString displayName(QTimeZone::TimeType timeType, QTimeZone::NameType nameType, const QLocale &locale) const Q_DECL_OVERRIDE; @@ -287,15 +287,15 @@ Q_DECL_CONSTEXPR inline bool operator!=(const QTzTransitionRule &lhs, const QTzT class Q_AUTOTEST_EXPORT QTzTimeZonePrivate Q_DECL_FINAL : public QTimeZonePrivate { + QTzTimeZonePrivate(const QTzTimeZonePrivate &) = default; public: // Create default time zone QTzTimeZonePrivate(); // Create named time zone QTzTimeZonePrivate(const QByteArray &ianaId); - QTzTimeZonePrivate(const QTzTimeZonePrivate &other); ~QTzTimeZonePrivate(); - QTimeZonePrivate *clone() Q_DECL_OVERRIDE; + QTzTimeZonePrivate *clone() const override; QLocale::Country country() const Q_DECL_OVERRIDE; QString comment() const Q_DECL_OVERRIDE; @@ -351,7 +351,7 @@ public: QMacTimeZonePrivate(const QMacTimeZonePrivate &other); ~QMacTimeZonePrivate(); - QTimeZonePrivate *clone() Q_DECL_OVERRIDE; + QMacTimeZonePrivate *clone() const override; QString comment() const Q_DECL_OVERRIDE; @@ -404,7 +404,7 @@ public: QWinTimeZonePrivate(const QWinTimeZonePrivate &other); ~QWinTimeZonePrivate(); - QTimeZonePrivate *clone() Q_DECL_OVERRIDE; + QWinTimeZonePrivate *clone() const override; QString comment() const Q_DECL_OVERRIDE; @@ -454,7 +454,7 @@ public: QAndroidTimeZonePrivate(const QAndroidTimeZonePrivate &other); ~QAndroidTimeZonePrivate(); - QTimeZonePrivate *clone() Q_DECL_OVERRIDE; + QAndroidTimeZonePrivate *clone() const override; QString displayName(QTimeZone::TimeType timeType, QTimeZone::NameType nameType, const QLocale &locale) const Q_DECL_OVERRIDE; diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp index 38dff88919..1714c9802f 100644 --- a/src/corelib/tools/qtimezoneprivate_tz.cpp +++ b/src/corelib/tools/qtimezoneprivate_tz.cpp @@ -452,13 +452,31 @@ static inline bool asciiIsLetter(char ch) return ch >= 'a' && ch <= 'z'; } +namespace { + +struct PosixZone +{ + enum { + InvalidOffset = INT_MIN, + }; + + QString name; + int offset; + + static PosixZone invalid() { return {QString(), InvalidOffset}; } + static PosixZone parse(const char *&pos, const char *end); + + bool hasValidOffset() const Q_DECL_NOTHROW { return offset != InvalidOffset; } +}; + +} // unnamed namespace + // Returns the zone name, the offset (in seconds) and advances \a begin to // where the parsing ended. Returns a zone of INT_MIN in case an offset // couldn't be read. -static QPair<QString, int> parsePosixZoneNameAndOffset(const char *&pos, const char *end) +PosixZone PosixZone::parse(const char *&pos, const char *end) { static const char offsetChars[] = "0123456789:"; - QPair<QString, int> result = qMakePair(QString(), INT_MIN); const char *nameBegin = pos; const char *nameEnd; @@ -480,7 +498,7 @@ static QPair<QString, int> parsePosixZoneNameAndOffset(const char *&pos, const c pos = nameEnd; } if (nameEnd - nameBegin < 3) - return result; // name must be at least 3 characters long + return invalid(); // name must be at least 3 characters long // zone offset, form [+-]hh:mm:ss const char *zoneBegin = pos; @@ -493,11 +511,10 @@ static QPair<QString, int> parsePosixZoneNameAndOffset(const char *&pos, const c ++zoneEnd; } - result.first = QString::fromUtf8(nameBegin, nameEnd - nameBegin); - if (zoneEnd > zoneBegin) - result.second = parsePosixOffset(zoneBegin, zoneEnd); + QString name = QString::fromUtf8(nameBegin, nameEnd - nameBegin); + const int offset = zoneEnd > zoneBegin ? parsePosixOffset(zoneBegin, zoneEnd) : InvalidOffset; pos = zoneEnd; - return result; + return {std::move(name), offset}; } static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray &posixRule, @@ -517,19 +534,19 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra // See the section about TZ at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html QList<QByteArray> parts = posixRule.split(','); - QPair<QString, int> stdZone, dstZone; + PosixZone stdZone, dstZone; { const QByteArray &zoneinfo = parts.at(0); const char *begin = zoneinfo.constBegin(); - stdZone = parsePosixZoneNameAndOffset(begin, zoneinfo.constEnd()); - if (stdZone.second == INT_MIN) { - stdZone.second = 0; // reset to UTC if we failed to parse + stdZone = PosixZone::parse(begin, zoneinfo.constEnd()); + if (!stdZone.hasValidOffset()) { + stdZone.offset = 0; // reset to UTC if we failed to parse } else if (begin < zoneinfo.constEnd()) { - dstZone = parsePosixZoneNameAndOffset(begin, zoneinfo.constEnd()); - if (dstZone.second == INT_MIN) { + dstZone = PosixZone::parse(begin, zoneinfo.constEnd()); + if (!dstZone.hasValidOffset()) { // if the dst offset isn't provided, it is 1 hour ahead of the standard offset - dstZone.second = stdZone.second + (60 * 60); + dstZone.offset = stdZone.offset + (60 * 60); } } } @@ -538,10 +555,10 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra if (parts.count() == 1) { QTimeZonePrivate::Data data; data.atMSecsSinceEpoch = lastTranMSecs; - data.offsetFromUtc = stdZone.second; - data.standardTimeOffset = stdZone.second; + data.offsetFromUtc = stdZone.offset; + data.standardTimeOffset = stdZone.offset; data.daylightTimeOffset = 0; - data.abbreviation = stdZone.first; + data.abbreviation = stdZone.name; result << data; return result; } @@ -568,18 +585,18 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra for (int year = startYear; year <= endYear; ++year) { QTimeZonePrivate::Data dstData; QDateTime dst(calculatePosixDate(dstDateRule, year), dstTime, Qt::UTC); - dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - (stdZone.second * 1000); - dstData.offsetFromUtc = dstZone.second; - dstData.standardTimeOffset = stdZone.second; - dstData.daylightTimeOffset = dstZone.second - stdZone.second; - dstData.abbreviation = dstZone.first; + dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - (stdZone.offset * 1000); + dstData.offsetFromUtc = dstZone.offset; + dstData.standardTimeOffset = stdZone.offset; + dstData.daylightTimeOffset = dstZone.offset - stdZone.offset; + dstData.abbreviation = dstZone.name; QTimeZonePrivate::Data stdData; QDateTime std(calculatePosixDate(stdDateRule, year), stdTime, Qt::UTC); - stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - (dstZone.second * 1000); - stdData.offsetFromUtc = stdZone.second; - stdData.standardTimeOffset = stdZone.second; + stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - (dstZone.offset * 1000); + stdData.offsetFromUtc = stdZone.offset; + stdData.standardTimeOffset = stdZone.offset; stdData.daylightTimeOffset = 0; - stdData.abbreviation = stdZone.first; + stdData.abbreviation = stdZone.name; // Part of the high year will overflow if (year == 292278994 && (dstData.atMSecsSinceEpoch < 0 || stdData.atMSecsSinceEpoch < 0)) { if (dstData.atMSecsSinceEpoch > 0) { @@ -598,37 +615,21 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra // Create the system default time zone QTzTimeZonePrivate::QTzTimeZonePrivate() -#if QT_CONFIG(icu) - : m_icu(0) -#endif { init(systemTimeZoneId()); } // Create a named time zone QTzTimeZonePrivate::QTzTimeZonePrivate(const QByteArray &ianaId) -#if QT_CONFIG(icu) - : m_icu(0) -#endif { init(ianaId); } -QTzTimeZonePrivate::QTzTimeZonePrivate(const QTzTimeZonePrivate &other) - : QTimeZonePrivate(other), m_tranTimes(other.m_tranTimes), - m_tranRules(other.m_tranRules), m_abbreviations(other.m_abbreviations), -#if QT_CONFIG(icu) - m_icu(other.m_icu), -#endif - m_posixRule(other.m_posixRule) -{ -} - QTzTimeZonePrivate::~QTzTimeZonePrivate() { } -QTimeZonePrivate *QTzTimeZonePrivate::clone() +QTzTimeZonePrivate *QTzTimeZonePrivate::clone() const { return new QTzTimeZonePrivate(*this); } diff --git a/src/corelib/tools/qtimezoneprivate_win.cpp b/src/corelib/tools/qtimezoneprivate_win.cpp index 4febeda537..16dfaefb74 100644 --- a/src/corelib/tools/qtimezoneprivate_win.cpp +++ b/src/corelib/tools/qtimezoneprivate_win.cpp @@ -415,7 +415,7 @@ QWinTimeZonePrivate::~QWinTimeZonePrivate() { } -QTimeZonePrivate *QWinTimeZonePrivate::clone() +QWinTimeZonePrivate *QWinTimeZonePrivate::clone() const { return new QWinTimeZonePrivate(*this); } diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index bb5ae78d2b..25f5176c22 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -352,7 +352,7 @@ Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::realloc(int asize, int a a = Prealloc; } s = 0; - if (QTypeInfo<T>::isStatic) { + if (!QTypeInfoQuery<T>::isRelocatable) { QT_TRY { // copy all the old elements while (s < copySize) { @@ -445,7 +445,7 @@ Q_OUTOFLINE_TEMPLATE typename QVarLengthArray<T, Prealloc>::iterator QVarLengthA if (n != 0) { resize(s + n); const T copy(t); - if (QTypeInfo<T>::isStatic) { + if (!QTypeInfoQuery<T>::isRelocatable) { T *b = ptr + offset; T *j = ptr + s; T *i = j - n; diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 5225b68d40..c69d27bbf9 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -553,7 +553,7 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo T *srcEnd = asize > d->size ? d->end() : d->begin() + asize; T *dst = x->begin(); - if (QTypeInfo<T>::isStatic || (isShared && QTypeInfo<T>::isComplex)) { + if (!QTypeInfoQuery<T>::isRelocatable || (isShared && QTypeInfo<T>::isComplex)) { // we can not move the data, we need to copy construct it while (srcBegin != srcEnd) { new (dst++) T(*srcBegin++); @@ -598,7 +598,7 @@ void QVector<T>::reallocData(const int asize, const int aalloc, QArrayData::Allo } if (d != x) { if (!d->ref.deref()) { - if (QTypeInfo<T>::isStatic || !aalloc || (isShared && QTypeInfo<T>::isComplex)) { + if (!QTypeInfoQuery<T>::isRelocatable || !aalloc || (isShared && QTypeInfo<T>::isComplex)) { // data was copy constructed, we need to call destructors // or if !alloc we did nothing to the old 'd'. freeData(d); @@ -697,7 +697,7 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, c const T copy(t); if (!isDetached() || d->size + n > int(d->alloc)) reallocData(d->size, d->size + n, QArrayData::Grow); - if (QTypeInfo<T>::isStatic) { + if (!QTypeInfoQuery<T>::isRelocatable) { T *b = d->end(); T *i = d->end() + n; while (i != b) @@ -746,7 +746,7 @@ typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend) detach(); abegin = d->begin() + itemsUntouched; aend = abegin + itemsToErase; - if (QTypeInfo<T>::isStatic) { + if (!QTypeInfoQuery<T>::isRelocatable) { iterator moveBegin = abegin + itemsToErase; iterator moveEnd = d->end(); while (moveBegin != moveEnd) { diff --git a/src/gui/configure.json b/src/gui/configure.json index 08e50db906..52ccb60024 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -7,6 +7,7 @@ "commandline": { "options": { + "accessibility": "boolean", "angle": "boolean", "direct2d": "boolean", "directfb": "boolean", @@ -1042,6 +1043,11 @@ Specify -opengl desktop to use regular OpenGL." "message": "The OpenGL functionality tests failed! You might need to modify the include and library search paths by editing QMAKE_INCDIR_OPENGL[_ES2], QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your platform." + }, + { + "type": "warning", + "condition": "!features.accessibility", + "message": "Accessibility disabled. This configuration of Qt is unsupported." } ], @@ -1049,6 +1055,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla { "section": "Qt Gui", "entries": [ + "accessibility", "freetype", "system-freetype", "harfbuzz", diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 5f8cbe2cbe..511cfd1d22 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -3,7 +3,7 @@ QT = core-private qtConfig(opengl.*): MODULE_CONFIG = opengl -DEFINES += QT_NO_USING_NAMESPACE +DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH QMAKE_DOCS = $$PWD/doc/qtgui.qdocconf diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index d55a26b2a4..1d19c165fc 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -745,7 +745,7 @@ static void set_text(const QImage &image, png_structp png_ptr, png_infop info_pt #ifdef PNG_iTXt_SUPPORTED bool needsItxt = false; - foreach(const QChar c, it.value()) { + for (const QChar c : it.value()) { uchar ch = c.cell(); if (c.row() || (ch < 0x20 && ch != '\n') || (ch > 0x7e && ch < 0xa0)) { needsItxt = true; diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 7c596d5ae5..c057fccade 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1124,7 +1124,7 @@ static void init_platform(const QString &pluginArgument, const QString &platform = QStringLiteral("This application failed to start because it could not find or load the Qt platform plugin \"%1\"\nin \"%2\".\n\n").arg(name, QDir::toNativeSeparators(platformPluginPath)); if (!keys.isEmpty()) { fatalMessage += QStringLiteral("Available platform plugins are: %1.\n\n").arg( - keys.join(QStringLiteral(", "))); + keys.join(QLatin1String(", "))); } fatalMessage += QStringLiteral("Reinstalling the application may fix this problem."); #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h index 29f7b9b3a6..54904ef60d 100644 --- a/src/gui/kernel/qplatformintegration.h +++ b/src/gui/kernel/qplatformintegration.h @@ -109,6 +109,7 @@ public: virtual QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; virtual QPlatformWindow *createPlatformWindow(QWindow *window) const = 0; + virtual QPlatformWindow *createForeignWindow(QWindow *, WId) const { return 0; } virtual QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const = 0; #ifndef QT_NO_OPENGL virtual QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const; diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 9d41a72072..8e98958949 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -424,7 +424,7 @@ void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate) } } -void QWindowPrivate::create(bool recursive) +void QWindowPrivate::create(bool recursive, WId nativeHandle) { Q_Q(QWindow); if (platformWindow) @@ -433,8 +433,10 @@ void QWindowPrivate::create(bool recursive) if (q->parent()) q->parent()->create(); - platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q); - Q_ASSERT(platformWindow || q->type() == Qt::ForeignWindow); + QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration(); + platformWindow = nativeHandle ? platformIntegration->createForeignWindow(q, nativeHandle) + : platformIntegration->createPlatformWindow(q); + Q_ASSERT(platformWindow); if (!platformWindow) { qWarning() << "Failed to create platform window for" << q << "with flags" << q->flags(); @@ -629,9 +631,6 @@ WId QWindow::winId() const { Q_D(const QWindow); - if (type() == Qt::ForeignWindow) - return WId(property("_q_foreignWinId").value<WId>()); - if(!d->platformWindow) const_cast<QWindow *>(this)->create(); @@ -865,7 +864,12 @@ void QWindow::setFlags(Qt::WindowFlags flags) Qt::WindowFlags QWindow::flags() const { Q_D(const QWindow); - return d->windowFlags; + Qt::WindowFlags flags = d->windowFlags; + + if (d->platformWindow && d->platformWindow->isForeignWindow()) + flags |= Qt::ForeignWindow; + + return flags; } /*! @@ -2584,13 +2588,13 @@ QWindow *QWindow::fromWinId(WId id) } QWindow *window = new QWindow; - window->setFlags(Qt::ForeignWindow); - window->setProperty("_q_foreignWinId", QVariant::fromValue(id)); - window->create(); + qt_window_private(window)->create(false, id); + if (!window->handle()) { delete window; return nullptr; } + return window; } diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index 272401453a..59016e4551 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -136,7 +136,7 @@ public: void updateSiblingPosition(SiblingPosition); bool windowRecreationRequired(QScreen *newScreen) const; - void create(bool recursive); + void create(bool recursive, WId nativeHandle = 0); void destroy(); void setTopLevelScreen(QScreen *newScreen, bool recreate); void connectToScreen(QScreen *topLevelScreen); diff --git a/src/gui/painting/qcoregraphics.mm b/src/gui/painting/qcoregraphics.mm index a64a184e25..768d3e7148 100644 --- a/src/gui/painting/qcoregraphics.mm +++ b/src/gui/painting/qcoregraphics.mm @@ -133,7 +133,7 @@ NSImage *qt_mac_create_nsimage(const QIcon &icon, int defaultSize) QList<QSize> availableSizes = icon.availableSizes(); if (availableSizes.isEmpty() && defaultSize > 0) availableSizes << QSize(defaultSize, defaultSize); - foreach (QSize size, availableSizes) { + for (QSize size : qAsConst(availableSizes)) { QPixmap pm = icon.pixmap(size); if (pm.isNull()) continue; diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 654be5690b..9233bff68c 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6549,8 +6549,8 @@ static void qInitDrawhelperFunctions() destFetchProc[QImage::Format_RGB16] = qt_destFetchRGB16_neon; destStoreProc[QImage::Format_RGB16] = qt_destStoreRGB16_neon; - qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon; - qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon; + qMemRotateFunctions[QPixelLayout::BPP16][0] = qt_memrotate90_16_neon; + qMemRotateFunctions[QPixelLayout::BPP16][2] = qt_memrotate270_16_neon; #endif #endif // defined(__ARM_NEON__) diff --git a/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp b/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp index 8c1f0ea8d2..1c920c0af9 100644 --- a/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp @@ -45,12 +45,11 @@ QT_BEGIN_NAMESPACE -QAndroidPlatformForeignWindow::QAndroidPlatformForeignWindow(QWindow *window) +QAndroidPlatformForeignWindow::QAndroidPlatformForeignWindow(QWindow *window, WId nativeHandle) : QAndroidPlatformWindow(window), m_surfaceId(-1) { - const WId wId = window->property("_q_foreignWinId").value<WId>(); - m_view = reinterpret_cast<jobject>(wId); + m_view = reinterpret_cast<jobject>(nativeHandle); if (m_view.isValid()) QtAndroid::setViewVisibility(m_view.object(), false); } diff --git a/src/plugins/platforms/android/qandroidplatformforeignwindow.h b/src/plugins/platforms/android/qandroidplatformforeignwindow.h index d42c36dcee..af1eee5499 100644 --- a/src/plugins/platforms/android/qandroidplatformforeignwindow.h +++ b/src/plugins/platforms/android/qandroidplatformforeignwindow.h @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE class QAndroidPlatformForeignWindow : public QAndroidPlatformWindow { public: - explicit QAndroidPlatformForeignWindow(QWindow *window); + explicit QAndroidPlatformForeignWindow(QWindow *window, WId nativeHandle); ~QAndroidPlatformForeignWindow(); void lower() override; void raise() override; @@ -57,6 +57,7 @@ public: void setVisible(bool visible) override; void applicationStateChanged(Qt::ApplicationState state) override; void setParent(const QPlatformWindow *window) override; + bool isForeignWindow() const override { return true; } private: int m_surfaceId; diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp index 184a836e13..13f9dc5a68 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp @@ -285,10 +285,13 @@ QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *wind { if (!QtAndroid::activity()) return nullptr; - if (window->type() == Qt::ForeignWindow) - return new QAndroidPlatformForeignWindow(window); - else - return new QAndroidPlatformOpenGLWindow(window, m_eglDisplay); + + return new QAndroidPlatformOpenGLWindow(window, m_eglDisplay); +} + +QPlatformWindow *QAndroidPlatformIntegration::createForeignWindow(QWindow *window, WId nativeHandle) const +{ + return new QAndroidPlatformForeignWindow(window, nativeHandle); } QAbstractEventDispatcher *QAndroidPlatformIntegration::createEventDispatcher() const diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h index 2337801250..be10c3d161 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.h +++ b/src/plugins/platforms/android/qandroidplatformintegration.h @@ -78,6 +78,7 @@ public: bool hasCapability(QPlatformIntegration::Capability cap) const override; QPlatformWindow *createPlatformWindow(QWindow *window) const override; + QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const override; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override; QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; QAbstractEventDispatcher *createEventDispatcher() const override; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index a3c375881d..ecdd20c4dc 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -126,6 +126,7 @@ public: bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE; + QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const Q_DECL_OVERRIDE; #ifndef QT_NO_OPENGL QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE; #endif diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 291d39ea9d..91f408e5c2 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -524,6 +524,11 @@ QPlatformWindow *QCocoaIntegration::createPlatformWindow(QWindow *window) const return new QCocoaWindow(window); } +QPlatformWindow *QCocoaIntegration::createForeignWindow(QWindow *window, WId nativeHandle) const +{ + return new QCocoaWindow(window, nativeHandle); +} + #ifndef QT_NO_OPENGL QPlatformOpenGLContext *QCocoaIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h index f60597fe42..567eb7438b 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.h +++ b/src/plugins/platforms/cocoa/qcocoawindow.h @@ -156,7 +156,7 @@ class QCocoaWindow : public QObject, public QPlatformWindow { Q_OBJECT public: - QCocoaWindow(QWindow *tlw); + QCocoaWindow(QWindow *tlw, WId nativeHandle = 0); ~QCocoaWindow(); void setGeometry(const QRect &rect) Q_DECL_OVERRIDE; @@ -186,6 +186,8 @@ public: QMargins frameMargins() const Q_DECL_OVERRIDE; QSurfaceFormat format() const Q_DECL_OVERRIDE; + bool isForeignWindow() const Q_DECL_OVERRIDE; + void requestActivateWindow() Q_DECL_OVERRIDE; WId winId() const Q_DECL_OVERRIDE; @@ -206,7 +208,9 @@ public: Q_NOTIFICATION_HANDLER(NSWindowDidResignKeyNotification) void windowDidResignKey(); Q_NOTIFICATION_HANDLER(NSWindowDidMiniaturizeNotification) void windowDidMiniaturize(); Q_NOTIFICATION_HANDLER(NSWindowDidDeminiaturizeNotification) void windowDidDeminiaturize(); + Q_NOTIFICATION_HANDLER(NSWindowWillEnterFullScreenNotification) void windowWillEnterFullScreen(); Q_NOTIFICATION_HANDLER(NSWindowDidEnterFullScreenNotification) void windowDidEnterFullScreen(); + Q_NOTIFICATION_HANDLER(NSWindowWillExitFullScreenNotification) void windowWillExitFullScreen(); Q_NOTIFICATION_HANDLER(NSWindowDidExitFullScreenNotification) void windowDidExitFullScreen(); Q_NOTIFICATION_HANDLER(NSWindowDidOrderOffScreenNotification) void windowDidOrderOffScreen(); Q_NOTIFICATION_HANDLER(NSWindowDidOrderOnScreenAndFinishAnimatingNotification) void windowDidOrderOnScreen(); diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index 918f376446..75c13d6bbc 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -433,7 +433,7 @@ Q_CONSTRUCTOR_FUNCTION(qRegisterNotificationCallbacks) const int QCocoaWindow::NoAlertRequest = -1; -QCocoaWindow::QCocoaWindow(QWindow *tlw) +QCocoaWindow::QCocoaWindow(QWindow *tlw, WId nativeHandle) : QPlatformWindow(tlw) , m_view(nil) , m_nsWindow(0) @@ -470,8 +470,9 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw) QMacAutoReleasePool pool; - if (tlw->type() == Qt::ForeignWindow) { - m_view = (NSView *)WId(tlw->property("_q_foreignWinId").value<WId>()); + if (nativeHandle) { + m_view = reinterpret_cast<NSView *>(nativeHandle); + [m_view retain]; } else { m_view = [[QNSView alloc] initWithCocoaWindow:this]; // Enable high-dpi OpenGL for retina displays. Enabling has the side @@ -562,6 +563,11 @@ void QCocoaWindow::setGeometry(const QRect &rectIn) setCocoaGeometry(rect); } +bool QCocoaWindow::isForeignWindow() const +{ + return ![m_view isKindOfClass:[QNSView class]]; +} + QRect QCocoaWindow::geometry() const { // QWindows that are embedded in a NSView hiearchy may be considered @@ -941,6 +947,10 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) if (m_drawContentBorderGradient) styleMask |= NSTexturedBackgroundWindowMask; + // Don't wipe fullscreen state + if (m_nsWindow.styleMask & NSFullScreenWindowMask) + styleMask |= NSFullScreenWindowMask; + return styleMask; } @@ -1363,19 +1373,40 @@ void QCocoaWindow::windowDidDeminiaturize() reportCurrentWindowState(); } +void QCocoaWindow::windowWillEnterFullScreen() +{ + // 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. The styleMask will be reset below. + m_nsWindow.styleMask |= NSResizableWindowMask; +} + void QCocoaWindow::windowDidEnterFullScreen() { Q_ASSERT_X(m_nsWindow.qt_fullScreen, "QCocoaWindow", "FullScreen category processes window notifications first"); + // Reset to original styleMask + setWindowFlags(m_windowFlags); + reportCurrentWindowState(); } +void QCocoaWindow::windowWillExitFullScreen() +{ + // The NSWindow needs to be resizable, otherwise we'll end up with + // a weird zoom animation. The styleMask will be reset below. + m_nsWindow.styleMask |= NSResizableWindowMask; +} + void QCocoaWindow::windowDidExitFullScreen() { Q_ASSERT_X(!m_nsWindow.qt_fullScreen, "QCocoaWindow", "FullScreen category processes window notifications first"); + // Reset to original styleMask + setWindowFlags(m_windowFlags); + Qt::WindowState requestedState = window()->windowState(); // Deliver update of QWindow state @@ -1869,24 +1900,13 @@ void QCocoaWindow::toggleMaximized() 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; + // The window needs to have the correct collection behavior for the + // toggleFullScreen call to have an effect. The collection behavior + // will be reset in windowDidEnterFullScreen/windowDidLeaveFullScreen. 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 diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp index 7e5477e4bf..a27c89faab 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp @@ -41,6 +41,7 @@ #include "qeglfskmsegldevice.h" #include <QGuiApplication> #include <QLoggingCategory> +#include <errno.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp index 11cd1756e6..01191a7dc1 100644 --- a/src/plugins/platforms/windows/qwindowsclipboard.cpp +++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp @@ -81,7 +81,7 @@ static QDebug operator<<(QDebug d, const QMimeData *mimeData) d << "QMimeData("; if (mimeData) { const QStringList formats = mimeData->formats(); - d << "formats=" << formats.join(QStringLiteral(", ")); + d << "formats=" << formats.join(QLatin1String(", ")); if (mimeData->hasText()) d << ", text=" << mimeData->text(); if (mimeData->hasHtml()) @@ -321,7 +321,7 @@ void QWindowsClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode) const HRESULT src = OleSetClipboard(m_data); if (src != S_OK) { QString mimeDataFormats = mimeData ? - mimeData->formats().join(QStringLiteral(", ")) : QString(QStringLiteral("NULL")); + mimeData->formats().join(QLatin1String(", ")) : QString(QStringLiteral("NULL")); qErrnoWarning("OleSetClipboard: Failed to set mime data (%s) on clipboard: %s", qPrintable(mimeDataFormats), QWindowsContext::comErrorString(src).constData()); diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 896bdd3610..59e2aacee9 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -1167,7 +1167,7 @@ void QWindowsNativeFileDialogBase::selectNameFilter(const QString &filter) if (index < 0) { qWarning("%s: Invalid parameter '%s' not found in '%s'.", __FUNCTION__, qPrintable(filter), - qPrintable(m_nameFilters.join(QStringLiteral(", ")))); + qPrintable(m_nameFilters.join(QLatin1String(", ")))); return; } m_fileDialog->SetFileTypeIndex(index + 1); // one-based. diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 5a3020387a..316f93e3ac 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -304,24 +304,6 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons return result; } - if (window->type() == Qt::ForeignWindow) { - const HWND hwnd = reinterpret_cast<HWND>(window->winId()); - if (!IsWindow(hwnd)) { - qWarning("Windows QPA: Invalid foreign window ID %p.", hwnd); - return nullptr; - } - QWindowsForeignWindow *result = new QWindowsForeignWindow(window, hwnd); - const QRect obtainedGeometry = result->geometry(); - QScreen *screen = Q_NULLPTR; - if (const QPlatformScreen *pScreen = result->screenForGeometry(obtainedGeometry)) - screen = pScreen->screen(); - if (screen && screen != window->screen()) - window->setScreen(screen); - qCDebug(lcQpaWindows) << "Foreign window:" << window << showbase << hex - << result->winId() << noshowbase << dec << obtainedGeometry << screen; - return result; - } - QWindowsWindowData requested; requested.flags = window->flags(); requested.geometry = QHighDpi::toNativePixels(window->geometry(), window); @@ -365,6 +347,25 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons return result; } +QPlatformWindow *QWindowsIntegration::createForeignWindow(QWindow *window, WId nativeHandle) const +{ + const HWND hwnd = reinterpret_cast<HWND>(nativeHandle); + if (!IsWindow(hwnd)) { + qWarning("Windows QPA: Invalid foreign window ID %p.", hwnd); + return nullptr; + } + QWindowsForeignWindow *result = new QWindowsForeignWindow(window, hwnd); + const QRect obtainedGeometry = result->geometry(); + QScreen *screen = Q_NULLPTR; + if (const QPlatformScreen *pScreen = result->screenForGeometry(obtainedGeometry)) + screen = pScreen->screen(); + if (screen && screen != window->screen()) + window->setScreen(screen); + qCDebug(lcQpaWindows) << "Foreign window:" << window << showbase << hex + << result->winId() << noshowbase << dec << obtainedGeometry << screen; + return result; +} + // Overridden to return a QWindowsDirect2DWindow in Direct2D plugin. QWindowsWindow *QWindowsIntegration::createPlatformWindowHelper(QWindow *window, const QWindowsWindowData &data) const { diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h index 7647b0f4a6..607203829f 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.h +++ b/src/plugins/platforms/windows/qwindowsintegration.h @@ -73,6 +73,7 @@ public: bool hasCapability(QPlatformIntegration::Capability cap) const override; QPlatformWindow *createPlatformWindow(QWindow *window) const override; + QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const override; #ifndef QT_NO_OPENGL QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; QOpenGLContext::OpenGLModuleType openGLModuleType() override; diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 227b79a207..5664539058 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -171,6 +171,7 @@ public: void raise() override { raise_sys(); } void lower() override { lower_sys(); } void setWindowTitle(const QString &title) override { setWindowTitle_sys(title); } + bool isForeignWindow() const override { return true; } protected: HWND handle() const override { return m_hwnd; } diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index 47c85fce18..40858b39e0 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -214,6 +214,27 @@ QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const return xcbWindow; } +class QXcbForeignWindow : public QXcbWindow +{ +public: + QXcbForeignWindow(QWindow *window, WId nativeHandle) + : QXcbWindow(window) { m_window = nativeHandle; } + ~QXcbForeignWindow() {} + bool isForeignWindow() const override { return true; } + +protected: + // No-ops + void create() override {} + void destroy() override {} +}; + +QPlatformWindow *QXcbIntegration::createForeignWindow(QWindow *window, WId nativeHandle) const +{ + QXcbWindow *xcbWindow = new QXcbForeignWindow(window, nativeHandle); + xcbWindow->create(); + return xcbWindow; +} + #ifndef QT_NO_OPENGL QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h index f8034f436f..baa5c9d835 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.h +++ b/src/plugins/platforms/xcb/qxcbintegration.h @@ -61,6 +61,7 @@ public: ~QXcbIntegration(); QPlatformWindow *createPlatformWindow(QWindow *window) const override; + QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const override; #ifndef QT_NO_OPENGL QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; #endif diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 46b3f2ab5a..abd41bb942 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -341,11 +341,6 @@ enum { void QXcbWindow::create() { - if (window()->type() == Qt::ForeignWindow) { - m_window = window()->winId(); - return; - } - destroy(); m_windowState = Qt::WindowNoState; @@ -590,9 +585,10 @@ QXcbWindow::~QXcbWindow() if (m_currentBitmapCursor != XCB_CURSOR_NONE) { xcb_free_cursor(xcb_connection(), m_currentBitmapCursor); } - if (window()->type() != Qt::ForeignWindow) - destroy(); - else { + + destroy(); + + if (isForeignWindow()) { if (connection()->mouseGrabber() == this) connection()->setMouseGrabber(Q_NULLPTR); if (connection()->mousePressWindow() == this) diff --git a/src/testlib/qtestaccessible.h b/src/testlib/qtestaccessible.h index c4c79b7deb..464f87fb5c 100644 --- a/src/testlib/qtestaccessible.h +++ b/src/testlib/qtestaccessible.h @@ -47,8 +47,6 @@ #include <QtCore/qglobal.h> -#ifndef QT_NO_ACCESSIBILITY - #define QVERIFY_EVENT(event) \ QVERIFY(QTestAccessibility::verifyEvent(event)) @@ -59,6 +57,8 @@ #include <QtTest/qtest_global.h> #include <QtTest/qtestsystem.h> +#if QT_CONFIG(accessibility) + QT_BEGIN_NAMESPACE @@ -294,5 +294,5 @@ private: QT_END_NAMESPACE -#endif // QT_NO_ACCESSIBILITY +#endif // QT_CONFIG(accessibility) #endif // QTESTACCESSIBLE_H diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp index 6128d5490b..b30de66258 100644 --- a/src/tools/moc/main.cpp +++ b/src/tools/moc/main.cpp @@ -305,7 +305,7 @@ int runMoc(int argc, char **argv) const QStringList files = parser.positionalArguments(); if (files.count() > 1) { - error(qPrintable(QStringLiteral("Too many input files specified: '") + files.join(QStringLiteral("' '")) + QLatin1Char('\''))); + error(qPrintable(QLatin1String("Too many input files specified: '") + files.join(QLatin1String("' '")) + QLatin1Char('\''))); parser.showHelp(1); } else if (!files.isEmpty()) { filename = files.first(); diff --git a/src/widgets/dialogs/qerrormessage.cpp b/src/widgets/dialogs/qerrormessage.cpp index 5fcbe3fe9d..8200135abe 100644 --- a/src/widgets/dialogs/qerrormessage.cpp +++ b/src/widgets/dialogs/qerrormessage.cpp @@ -62,6 +62,13 @@ QT_BEGIN_NAMESPACE +namespace { +struct Message { + QString content; + QString type; +}; +} + class QErrorMessagePrivate : public QDialogPrivate { Q_DECLARE_PUBLIC(QErrorMessage) @@ -70,7 +77,7 @@ public: QCheckBox * again; QTextEdit * errors; QLabel * icon; - std::queue<QPair<QString, QString> > pending; + std::queue<Message> pending; QSet<QString> doNotShow; QSet<QString> doNotShowType; QString currentMessage; @@ -163,14 +170,20 @@ static void jump(QtMsgType t, const QMessageLogContext & /*context*/, const QStr switch (t) { case QtDebugMsg: - default: rich = QErrorMessage::tr("Debug Message:"); break; case QtWarningMsg: rich = QErrorMessage::tr("Warning:"); break; + case QtCriticalMsg: + rich = QErrorMessage::tr("Critical Error:"); + break; case QtFatalMsg: rich = QErrorMessage::tr("Fatal Error:"); + break; + case QtInfoMsg: + rich = QErrorMessage::tr("Information:"); + break; } rich = QString::fromLatin1("<p><b>%1</b></p>").arg(rich); rich += Qt::convertFromPlainText(m, Qt::WhiteSpaceNormal); @@ -297,9 +310,8 @@ bool QErrorMessagePrivate::isMessageToBeShown(const QString &message, const QStr bool QErrorMessagePrivate::nextPending() { while (!pending.empty()) { - QPair<QString,QString> &pendingMessage = pending.front(); - QString message = qMove(pendingMessage.first); - QString type = qMove(pendingMessage.second); + QString message = std::move(pending.front().content); + QString type = std::move(pending.front().type); pending.pop(); if (isMessageToBeShown(message, type)) { #ifndef QT_NO_TEXTHTMLPARSER @@ -349,7 +361,7 @@ void QErrorMessage::showMessage(const QString &message, const QString &type) Q_D(QErrorMessage); if (!d->isMessageToBeShown(message, type)) return; - d->pending.push(qMakePair(message, type)); + d->pending.push({message, type}); if (!isVisible() && d->nextPending()) show(); } diff --git a/src/widgets/kernel/qsizepolicy.cpp b/src/widgets/kernel/qsizepolicy.cpp index a03523d2af..b08a9abb1e 100644 --- a/src/widgets/kernel/qsizepolicy.cpp +++ b/src/widgets/kernel/qsizepolicy.cpp @@ -255,6 +255,11 @@ QSizePolicy::ControlType QSizePolicy::controlType() const */ void QSizePolicy::setControlType(ControlType type) { + bits.ctype = toControlTypeFieldValue(type); +} + +quint32 QSizePolicy::toControlTypeFieldValue(ControlType type) Q_DECL_NOTHROW +{ /* The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10, etc. In memory, we pack it onto the available bits (CTSize) in @@ -271,10 +276,8 @@ void QSizePolicy::setControlType(ControlType type) int i = 0; while (true) { - if (type & (0x1 << i)) { - bits.ctype = i; - return; - } + if (type & (0x1 << i)) + return i; ++i; } } diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h index 3ab672a8e8..83ce5853ab 100644 --- a/src/widgets/kernel/qsizepolicy.h +++ b/src/widgets/kernel/qsizepolicy.h @@ -119,18 +119,25 @@ public: QT_SIZEPOLICY_CONSTEXPR QSizePolicy() : data(0) { } +#ifdef Q_COMPILER_UNIFORM_INIT + QT_SIZEPOLICY_CONSTEXPR QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) + : bits{0, 0, quint32(horizontal), quint32(vertical), + type == DefaultType ? 0 : toControlTypeFieldValue(type), 0, 0, 0} + {} +#else QSizePolicy(Policy horizontal, Policy vertical, ControlType type = DefaultType) : data(0) { bits.horPolicy = horizontal; bits.verPolicy = vertical; setControlType(type); } +#endif // uniform-init QT_SIZEPOLICY_CONSTEXPR Policy horizontalPolicy() const { return static_cast<Policy>(bits.horPolicy); } QT_SIZEPOLICY_CONSTEXPR Policy verticalPolicy() const { return static_cast<Policy>(bits.verPolicy); } ControlType controlType() const; - void setHorizontalPolicy(Policy d) { bits.horPolicy = d; } - void setVerticalPolicy(Policy d) { bits.verPolicy = d; } + Q_DECL_RELAXED_CONSTEXPR void setHorizontalPolicy(Policy d) { bits.horPolicy = d; } + Q_DECL_RELAXED_CONSTEXPR void setVerticalPolicy(Policy d) { bits.verPolicy = d; } void setControlType(ControlType type); QT_SIZEPOLICY_CONSTEXPR Qt::Orientations expandingDirections() const { @@ -138,9 +145,9 @@ public: | ( (horizontalPolicy() & ExpandFlag) ? Qt::Horizontal : Qt::Orientations() ) ; } - void setHeightForWidth(bool b) { bits.hfw = b; } + Q_DECL_RELAXED_CONSTEXPR void setHeightForWidth(bool b) { bits.hfw = b; } QT_SIZEPOLICY_CONSTEXPR bool hasHeightForWidth() const { return bits.hfw; } - void setWidthForHeight(bool b) { bits.wfh = b; } + Q_DECL_RELAXED_CONSTEXPR void setWidthForHeight(bool b) { bits.wfh = b; } QT_SIZEPOLICY_CONSTEXPR bool hasWidthForHeight() const { return bits.wfh; } QT_SIZEPOLICY_CONSTEXPR bool operator==(const QSizePolicy& s) const { return data == s.data; } @@ -152,13 +159,13 @@ public: QT_SIZEPOLICY_CONSTEXPR int horizontalStretch() const { return static_cast<int>(bits.horStretch); } QT_SIZEPOLICY_CONSTEXPR int verticalStretch() const { return static_cast<int>(bits.verStretch); } - void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); } - void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); } + Q_DECL_RELAXED_CONSTEXPR void setHorizontalStretch(int stretchFactor) { bits.horStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); } + Q_DECL_RELAXED_CONSTEXPR void setVerticalStretch(int stretchFactor) { bits.verStretch = static_cast<quint32>(qBound(0, stretchFactor, 255)); } QT_SIZEPOLICY_CONSTEXPR bool retainSizeWhenHidden() const { return bits.retainSizeWhenHidden; } - void setRetainSizeWhenHidden(bool retainSize) { bits.retainSizeWhenHidden = retainSize; } + Q_DECL_RELAXED_CONSTEXPR void setRetainSizeWhenHidden(bool retainSize) { bits.retainSizeWhenHidden = retainSize; } - void transpose() { *this = transposed(); } + Q_DECL_RELAXED_CONSTEXPR void transpose() { *this = transposed(); } #ifndef Q_QDOC QT_SIZEPOLICY_CONSTEXPR_AND_UNIFORM_INIT #endif @@ -176,6 +183,8 @@ private: struct Bits; QT_SIZEPOLICY_CONSTEXPR explicit QSizePolicy(Bits b) Q_DECL_NOTHROW : bits(b) { } + static quint32 toControlTypeFieldValue(ControlType type) Q_DECL_NOTHROW; + struct Bits { quint32 horStretch : 8; quint32 verStretch : 8; diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 2ced12fb7d..cf9fbe2572 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -9190,6 +9190,7 @@ bool QWidget::event(QEvent *event) const QWindow *win = te->window; d->setWinId((win && win->handle()) ? win->handle()->winId() : 0); } + d->updateFont(d->data.fnt); #ifndef QT_NO_OPENGL d->renderToTextureReallyDirty = 1; #endif diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index 6bcdc372ef..7ee53587e6 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -694,6 +694,10 @@ void QAbstractSpinBox::setLineEdit(QLineEdit *lineEdit) this, SLOT(_q_editorTextChanged(QString))); connect(d->edit, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(_q_editorCursorPositionChanged(int,int))); + connect(d->edit, SIGNAL(cursorPositionChanged(int,int)), + this, SLOT(updateMicroFocus())); + connect(d->edit->d_func()->control, SIGNAL(updateMicroFocus()), + this, SLOT(updateMicroFocus())); } d->updateEditFieldGeometry(); d->edit->setContextMenuPolicy(Qt::NoContextMenu); diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 4519265fb8..f4e08dc670 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -65,6 +65,7 @@ #include <private/qcombobox_p.h> #include <private/qabstractitemmodel_p.h> #include <private/qabstractscrollarea_p.h> +#include <private/qlineedit_p.h> #include <qdebug.h> #if 0 /* Used to be included in Qt4 for Q_WS_MAC */ && !defined(QT_NO_EFFECTS) && QT_CONFIG(style_mac) #include <private/qcore_mac_p.h> @@ -1790,6 +1791,7 @@ void QComboBox::setLineEdit(QLineEdit *edit) connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(currentTextChanged(QString))); connect(d->lineEdit, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(updateMicroFocus())); connect(d->lineEdit, SIGNAL(selectionChanged()), this, SLOT(updateMicroFocus())); + connect(d->lineEdit->d_func()->control, SIGNAL(updateMicroFocus()), this, SLOT(updateMicroFocus())); d->lineEdit->setFrame(false); d->lineEdit->setContextMenuPolicy(Qt::NoContextMenu); d->updateFocusPolicy(); diff --git a/src/widgets/widgets/qlineedit.h b/src/widgets/widgets/qlineedit.h index 1bdcfaf848..96dd64164f 100644 --- a/src/widgets/widgets/qlineedit.h +++ b/src/widgets/widgets/qlineedit.h @@ -239,6 +239,7 @@ public: private: friend class QAbstractSpinBox; friend class QAccessibleLineEdit; + friend class QComboBox; #ifdef QT_KEYPAD_NAVIGATION friend class QDateTimeEdit; #endif diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index 9947d63279..13f18f66d2 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -196,6 +196,9 @@ void QLineEditPrivate::init(const QString& txt) QObject::connect(control, SIGNAL(textChanged(QString)), q, SLOT(updateMicroFocus())); + QObject::connect(control, SIGNAL(updateMicroFocus()), + q, SLOT(updateMicroFocus())); + // for now, going completely overboard with updates. QObject::connect(control, SIGNAL(selectionChanged()), q, SLOT(update())); diff --git a/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm b/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm index 8e565ecfe0..610df2125b 100644 --- a/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm +++ b/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm @@ -44,6 +44,7 @@ #include <QtGui/QWindow> #include <qpa/qplatformnativeinterface.h> #include <private/qwidget_p.h> +#include <private/qwindow_p.h> /*! \class QMacCocoaViewContainer @@ -117,7 +118,9 @@ QMacCocoaViewContainerPrivate::~QMacCocoaViewContainerPrivate() QMacCocoaViewContainer::QMacCocoaViewContainer(NSView *view, QWidget *parent) : QWidget(*new QMacCocoaViewContainerPrivate, parent, 0) { + // Ensures that we have a QWindow, even if we're not a top level widget setAttribute(Qt::WA_NativeWindow); + setCocoaView(view); } @@ -149,23 +152,19 @@ void QMacCocoaViewContainer::setCocoaView(NSView *view) [view retain]; d->nsview = view; - QWindow *window = windowHandle(); + // Get rid of QWindow completely, and re-create a new vanilla one, which + // we will then re-configure to be a foreign window. + destroy(); + create(); - // Note that we only set the flag on the QWindow, and not the QWidget. - // These two are not in sync, so from a QWidget standpoint the widget - // is not a Window, and hence will be shown when the parent widget is - // shown, like all QWidget children. - window->setFlags(Qt::ForeignWindow); - window->setProperty("_q_foreignWinId", view ? WId(view) : QVariant()); - - // Destroying the platform window implies hiding the window, and we - // also lose the geometry information that the platform window kept, - // and fall back to the stale QWindow geometry, so we update the two - // based on the widget visibility and geometry, which is up to date. + // Can't use QWindow::fromWinId() here due to QWidget controlling its + // QWindow, and can't use QWidget::createWindowContainer() due to the + // QMacCocoaViewContainer class being public API instead of a factory + // function. + QWindow *window = windowHandle(); window->destroy(); - window->setVisible(isVisible()); - window->setGeometry(geometry()); - window->create(); + qt_window_private(window)->create(false, WId(view)); + Q_ASSERT(window->handle()); [oldView release]; } diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 450bd1cf3f..d57c4629cc 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -734,7 +734,7 @@ QT_FOR_EACH_STATIC_CORE_POINTER(ADD_METATYPE_TEST_ROW) QTest::newRow("QPair<P,C>") << ::qMetaTypeId<QPair<P,C> >() << false << true << false << false; QTest::newRow("QPair<P,M>") << ::qMetaTypeId<QPair<P,M> >() << true << true << false << false; QTest::newRow("QPair<P,P>") << ::qMetaTypeId<QPair<P,P> >() << true << false << false << false; - QTest::newRow("FlagsDataEnum") << ::qMetaTypeId<FlagsDataEnum>() << true << true << false << true; + QTest::newRow("FlagsDataEnum") << ::qMetaTypeId<FlagsDataEnum>() << true << false << false << true; // invalid ids. QTest::newRow("-1") << -1 << false << false << false << false; diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index 5b7242fddb..fdc4ecb5c8 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -89,6 +89,7 @@ private slots: void waitForDone(); void clear(); void cancel(); + void tryTake(); void waitForDoneTimeout(); void destroyingWaitsForTasksToFinish(); void stressTest(); @@ -1042,6 +1043,97 @@ void tst_QThreadPool::cancel() delete runnables[runs-1]; } +void tst_QThreadPool::tryTake() +{ + QSemaphore sem(0); + QSemaphore startedThreads(0); + + class SemaphoreReleaser + { + QSemaphore &sem; + int n; + Q_DISABLE_COPY(SemaphoreReleaser) + public: + explicit SemaphoreReleaser(QSemaphore &sem, int n) + : sem(sem), n(n) {} + + ~SemaphoreReleaser() + { + sem.release(n); + } + }; + + class BlockingRunnable : public QRunnable + { + public: + QSemaphore &sem; + QSemaphore &startedThreads; + QAtomicInt &dtorCounter; + QAtomicInt &runCounter; + int dummy; + + explicit BlockingRunnable(QSemaphore &s, QSemaphore &started, QAtomicInt &c, QAtomicInt &r) + : sem(s), startedThreads(started), dtorCounter(c), runCounter(r) {} + + ~BlockingRunnable() + { + dtorCounter.fetchAndAddRelaxed(1); + } + + void run() override + { + startedThreads.release(); + runCounter.fetchAndAddRelaxed(1); + sem.acquire(); + count.ref(); + } + }; + + enum { + MaxThreadCount = 3, + OverProvisioning = 2, + Runs = MaxThreadCount * OverProvisioning + }; + + QThreadPool threadPool; + threadPool.setMaxThreadCount(MaxThreadCount); + BlockingRunnable *runnables[Runs]; + + // ensure that the QThreadPool doesn't deadlock if any of the checks fail + // and cause an early return: + const SemaphoreReleaser semReleaser(sem, Runs); + + count.store(0); + QAtomicInt dtorCounter = 0; + QAtomicInt runCounter = 0; + for (int i = 0; i < Runs; i++) { + runnables[i] = new BlockingRunnable(sem, startedThreads, dtorCounter, runCounter); + runnables[i]->setAutoDelete(i != 0 && i != Runs - 1); // one which will run and one which will not + QVERIFY(!threadPool.tryTake(runnables[i])); // verify NOOP for jobs not in the queue + threadPool.start(runnables[i]); + } + // wait for all worker threads to have started up: + QVERIFY(startedThreads.tryAcquire(MaxThreadCount, 60*1000 /* 1min */)); + + for (int i = 0; i < MaxThreadCount; ++i) { + // check taking runnables doesn't work once they were started: + QVERIFY(!threadPool.tryTake(runnables[i])); + } + for (int i = MaxThreadCount; i < Runs ; ++i) { + QVERIFY(threadPool.tryTake(runnables[i])); + delete runnables[i]; + } + + runnables[0]->dummy = 0; // valgrind will catch this if tryTake() is crazy enough to delete currently running jobs + QCOMPARE(dtorCounter.load(), int(Runs - MaxThreadCount)); + sem.release(MaxThreadCount); + threadPool.waitForDone(); + QCOMPARE(runCounter.load(), int(MaxThreadCount)); + QCOMPARE(count.load(), int(MaxThreadCount)); + QCOMPARE(dtorCounter.load(), int(Runs - 1)); + delete runnables[0]; // if the pool deletes them then we'll get double-free crash +} + void tst_QThreadPool::destroyingWaitsForTasksToFinish() { QTime total, pass; diff --git a/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp b/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp index 98b765a6c6..4ae1f02ce2 100644 --- a/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp +++ b/tests/auto/widgets/kernel/qsizepolicy/tst_qsizepolicy.cpp @@ -113,6 +113,8 @@ void tst_QSizePolicy::constExpr() // check that certain ctors are constexpr (compile-only): { Q_CONSTEXPR QSizePolicy sp; Q_UNUSED(sp); } { Q_CONSTEXPR QSizePolicy sp = QSizePolicy(); Q_UNUSED(sp); } + { Q_CONSTEXPR QSizePolicy sp = QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); Q_UNUSED(sp); } + { Q_CONSTEXPR QSizePolicy sp = QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding, QSizePolicy::DefaultType); Q_UNUSED(sp); } #else QSKIP("QSizePolicy cannot be constexpr with this version of the compiler."); #endif diff --git a/tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro b/tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro index f9b601228e..be758a8bdd 100644 --- a/tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro +++ b/tests/auto/widgets/widgets/qabstractspinbox/qabstractspinbox.pro @@ -4,7 +4,7 @@ CONFIG += testcase TARGET = tst_qabstractspinbox -QT += widgets testlib +QT += widgets gui-private core-private testlib SOURCES += tst_qabstractspinbox.cpp diff --git a/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp b/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp index 36f5df4649..3fb4863b0e 100644 --- a/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp +++ b/tests/auto/widgets/widgets/qabstractspinbox/tst_qabstractspinbox.cpp @@ -35,6 +35,20 @@ #include <qlineedit.h> #include <qspinbox.h> +#include "../../../shared/platforminputcontext.h" +#include <private/qinputmethod_p.h> + +static inline void centerOnScreen(QWidget *w, const QSize &size) +{ + const QPoint offset = QPoint(size.width() / 2, size.height() / 2); + w->move(QGuiApplication::primaryScreen()->availableGeometry().center() - offset); +} + +static inline void centerOnScreen(QWidget *w) +{ + centerOnScreen(w, w->geometry().size()); +} + class tst_QAbstractSpinBox : public QObject { Q_OBJECT @@ -44,11 +58,19 @@ public: virtual ~tst_QAbstractSpinBox(); private slots: + void initTestCase(); + void cleanupTestCase(); + void getSetCheck(); // task-specific tests below me: void task183108_clear(); void task228728_cssselector(); + + void inputMethodUpdate(); + +private: + PlatformInputContext m_platformInputContext; }; tst_QAbstractSpinBox::tst_QAbstractSpinBox() @@ -67,6 +89,18 @@ public: void setLineEdit(QLineEdit *le) { QAbstractSpinBox::setLineEdit(le); } }; +void tst_QAbstractSpinBox::initTestCase() +{ + QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod()); + inputMethodPrivate->testContext = &m_platformInputContext; +} + +void tst_QAbstractSpinBox::cleanupTestCase() +{ + QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod()); + inputMethodPrivate->testContext = 0; +} + // Testing get/set functions void tst_QAbstractSpinBox::getSetCheck() { @@ -141,6 +175,60 @@ void tst_QAbstractSpinBox::task228728_cssselector() QSpinBox box; } +void tst_QAbstractSpinBox::inputMethodUpdate() +{ + QSpinBox box; + + QSpinBox *testWidget = &box; + testWidget->setRange(0, 1); + + centerOnScreen(testWidget); + testWidget->clear(); + testWidget->show(); + QVERIFY(QTest::qWaitForWindowExposed(testWidget)); + + testWidget->activateWindow(); + testWidget->setFocus(); + QTRY_VERIFY(testWidget->hasFocus()); + QTRY_COMPARE(qApp->focusObject(), testWidget); + + m_platformInputContext.m_updateCallCount = 0; + { + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent event("1", attributes); + QApplication::sendEvent(testWidget, &event); + } + QVERIFY(m_platformInputContext.m_updateCallCount >= 1); + + m_platformInputContext.m_updateCallCount = 0; + { + QList<QInputMethodEvent::Attribute> attributes; + attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 1, QVariant()); + QInputMethodEvent event("1", attributes); + QApplication::sendEvent(testWidget, &event); + } + QVERIFY(m_platformInputContext.m_updateCallCount >= 1); + + m_platformInputContext.m_updateCallCount = 0; + { + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent event("", attributes); + event.setCommitString("1"); + QApplication::sendEvent(testWidget, &event); + } + QVERIFY(m_platformInputContext.m_updateCallCount >= 1); + QCOMPARE(testWidget->value(), 1); + + m_platformInputContext.m_updateCallCount = 0; + { + QList<QInputMethodEvent::Attribute> attributes; + attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 0, 0, QVariant()); + QInputMethodEvent event("", attributes); + QApplication::sendEvent(testWidget, &event); + } + QVERIFY(m_platformInputContext.m_updateCallCount >= 1); +} + QTEST_MAIN(tst_QAbstractSpinBox) #include "tst_qabstractspinbox.moc" diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index 3afdc0a12a..b882055888 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -64,6 +64,9 @@ #include <qproxystyle.h> #include <qfont.h> +#include "../../../shared/platforminputcontext.h" +#include <private/qinputmethod_p.h> + static inline void setFrameless(QWidget *w) { Qt::WindowFlags flags = w->windowFlags(); @@ -80,6 +83,8 @@ public: tst_QComboBox() {} private slots: + void initTestCase(); + void cleanupTestCase(); void getSetCheck(); void ensureReturnIsIgnored(); void setEditable(); @@ -162,6 +167,10 @@ private slots: void task_QTBUG_39088_inputMethodHints(); void task_QTBUG_49831_scrollerNotActivated(); void task_QTBUG_56693_itemFontFromModel(); + void inputMethodUpdate(); + +private: + PlatformInputContext m_platformInputContext; }; class MyAbstractItemDelegate : public QAbstractItemDelegate @@ -207,6 +216,18 @@ protected: QRegion visualRegionForSelection(const QItemSelection &) const { return QRegion(); } }; +void tst_QComboBox::initTestCase() +{ + QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod()); + inputMethodPrivate->testContext = &m_platformInputContext; +} + +void tst_QComboBox::cleanupTestCase() +{ + QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod()); + inputMethodPrivate->testContext = 0; +} + // Testing get/set functions void tst_QComboBox::getSetCheck() { @@ -3324,5 +3345,59 @@ void tst_QComboBox::task_QTBUG_56693_itemFontFromModel() box.hidePopup(); } +void tst_QComboBox::inputMethodUpdate() +{ + TestWidget topLevel; + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + QComboBox *testWidget = topLevel.comboBox(); + // make sure we have no lineedit + QVERIFY(!testWidget->lineEdit()); + // test setEditable(true) + testWidget->setEditable(true); + QVERIFY(testWidget->lineEdit()); + + testWidget->activateWindow(); + testWidget->setFocus(); + QTRY_VERIFY(testWidget->hasFocus()); + QTRY_COMPARE(qApp->focusObject(), testWidget); + + m_platformInputContext.m_updateCallCount = 0; + { + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent event("preedit text", attributes); + QApplication::sendEvent(testWidget, &event); + } + QVERIFY(m_platformInputContext.m_updateCallCount >= 1); + + m_platformInputContext.m_updateCallCount = 0; + { + QList<QInputMethodEvent::Attribute> attributes; + attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 1, QVariant()); + QInputMethodEvent event("preedit text", attributes); + QApplication::sendEvent(testWidget, &event); + } + QVERIFY(m_platformInputContext.m_updateCallCount >= 1); + + m_platformInputContext.m_updateCallCount = 0; + { + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent event("", attributes); + event.setCommitString("preedit text"); + QApplication::sendEvent(testWidget, &event); + } + QVERIFY(m_platformInputContext.m_updateCallCount >= 1); + QCOMPARE(testWidget->lineEdit()->text(), QString("preedit text")); + + m_platformInputContext.m_updateCallCount = 0; + { + QList<QInputMethodEvent::Attribute> attributes; + attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 0, 0, QVariant()); + QInputMethodEvent event("", attributes); + QApplication::sendEvent(testWidget, &event); + } + QVERIFY(m_platformInputContext.m_updateCallCount >= 1); +} + QTEST_MAIN(tst_QComboBox) #include "tst_qcombobox.moc" diff --git a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp index a4614d0a9d..4c0ffdc77c 100644 --- a/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/widgets/widgets/qlineedit/tst_qlineedit.cpp @@ -294,6 +294,8 @@ private slots: void inputMethodQueryImHints_data(); void inputMethodQueryImHints(); + void inputMethodUpdate(); + void undoRedoAndEchoModes_data(); void undoRedoAndEchoModes(); @@ -4184,6 +4186,57 @@ void tst_QLineEdit::inputMethodQueryImHints() QCOMPARE(static_cast<Qt::InputMethodHints>(value.toInt()), hints); } +void tst_QLineEdit::inputMethodUpdate() +{ + QLineEdit *testWidget = ensureTestWidget(); + + centerOnScreen(testWidget); + testWidget->show(); + QVERIFY(QTest::qWaitForWindowExposed(testWidget)); + + testWidget->setText(""); + testWidget->activateWindow(); + testWidget->setFocus(); + QTRY_VERIFY(testWidget->hasFocus()); + QTRY_COMPARE(qApp->focusObject(), testWidget); + + m_platformInputContext.m_updateCallCount = 0; + { + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent event("preedit text", attributes); + QApplication::sendEvent(testWidget, &event); + } + QVERIFY(m_platformInputContext.m_updateCallCount >= 1); + + m_platformInputContext.m_updateCallCount = 0; + { + QList<QInputMethodEvent::Attribute> attributes; + attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 1, QVariant()); + QInputMethodEvent event("preedit text", attributes); + QApplication::sendEvent(testWidget, &event); + } + QVERIFY(m_platformInputContext.m_updateCallCount >= 1); + + m_platformInputContext.m_updateCallCount = 0; + { + QList<QInputMethodEvent::Attribute> attributes; + QInputMethodEvent event("", attributes); + event.setCommitString("preedit text"); + QApplication::sendEvent(testWidget, &event); + } + QVERIFY(m_platformInputContext.m_updateCallCount >= 1); + QCOMPARE(testWidget->text(), QString("preedit text")); + + m_platformInputContext.m_updateCallCount = 0; + { + QList<QInputMethodEvent::Attribute> attributes; + attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 0, 0, QVariant()); + QInputMethodEvent event("", attributes); + QApplication::sendEvent(testWidget, &event); + } + QVERIFY(m_platformInputContext.m_updateCallCount >= 1); +} + void tst_QLineEdit::undoRedoAndEchoModes_data() { QTest::addColumn<int>("echoMode"); diff --git a/tests/auto/widgets/widgets/widgets.pro b/tests/auto/widgets/widgets/widgets.pro index a8e8f6d865..c098108edc 100644 --- a/tests/auto/widgets/widgets/widgets.pro +++ b/tests/auto/widgets/widgets/widgets.pro @@ -49,6 +49,7 @@ SUBDIRS=\ # The following tests depend on private API: !qtConfig(private_tests): SUBDIRS -= \ + qabstractspinbox \ qcombobox \ qmainwindow \ qtextedit \ diff --git a/tests/manual/windowflags/controllerwindow.cpp b/tests/manual/windowflags/controllerwindow.cpp index 3654bfbad0..9a12c8b2c9 100644 --- a/tests/manual/windowflags/controllerwindow.cpp +++ b/tests/manual/windowflags/controllerwindow.cpp @@ -191,12 +191,12 @@ static bool isTopLevel(const QObject *o) return false; } -static Qt::WindowState windowState(const QObject *o) +static Qt::WindowStates windowState(const QObject *o) { if (o->isWidgetType()) { Qt::WindowStates states = static_cast<const QWidget *>(o)->windowState(); states &= ~Qt::WindowActive; - return static_cast<Qt::WindowState>(int(states)); + return states; } #if QT_VERSION >= 0x050000 if (o->isWindowType()) diff --git a/tests/manual/windowflags/previewwindow.cpp b/tests/manual/windowflags/previewwindow.cpp index 54084fd1bc..65a287f788 100644 --- a/tests/manual/windowflags/previewwindow.cpp +++ b/tests/manual/windowflags/previewwindow.cpp @@ -202,16 +202,21 @@ PreviewWindow::PreviewWindow(QWidget *parent) setWindowTitle(tr("Preview <QWidget> Qt %1").arg(QLatin1String(QT_VERSION_STR))); } -void PreviewWindow::resizeEvent(QResizeEvent *e) +bool PreviewWindow::event(QEvent *event) { - QWidget::resizeEvent(e); - updateInfo(); -} + const bool ret = QWidget::event(event); -void PreviewWindow::moveEvent(QMoveEvent *e) -{ - QWidget::moveEvent(e); - updateInfo(); + switch (event->type()) { + case QEvent::Move: + case QEvent::Resize: + case QEvent::WindowStateChange: + updateInfo(); + break; + default: + break; + } + + return ret; } void PreviewWindow::setWindowFlags(Qt::WindowFlags flags) @@ -234,16 +239,21 @@ PreviewDialog::PreviewDialog(QWidget *parent) setWindowTitle(tr("Preview <QDialog> Qt %1").arg(QLatin1String(QT_VERSION_STR))); } -void PreviewDialog::resizeEvent(QResizeEvent *e) +bool PreviewDialog::event(QEvent *event) { - QDialog::resizeEvent(e); - updateInfo(); -} + const bool ret = QDialog::event(event); -void PreviewDialog::moveEvent(QMoveEvent *e) -{ - QDialog::moveEvent(e); - updateInfo(); + switch (event->type()) { + case QEvent::Move: + case QEvent::Resize: + case QEvent::WindowStateChange: + updateInfo(); + break; + default: + break; + } + + return ret; } void PreviewDialog::setWindowFlags(Qt::WindowFlags flags) diff --git a/tests/manual/windowflags/previewwindow.h b/tests/manual/windowflags/previewwindow.h index acd79735ad..9730e7a3f9 100644 --- a/tests/manual/windowflags/previewwindow.h +++ b/tests/manual/windowflags/previewwindow.h @@ -48,8 +48,7 @@ public slots: void updateInfo(); protected: - void resizeEvent(QResizeEvent *); - void moveEvent(QMoveEvent *); + bool event(QEvent *) override; private: QPlainTextEdit *textEdit; @@ -68,8 +67,7 @@ public slots: void updateInfo(); protected: - void resizeEvent(QResizeEvent *); - void moveEvent(QMoveEvent *); + bool event(QEvent *) override; private: QPlainTextEdit *textEdit; |