diff options
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 17 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreapplication_p.h | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreapplication_platform.h | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_wasm.cpp | 9 | ||||
-rw-r--r-- | src/corelib/kernel/qeventloop.cpp | 6 | ||||
-rw-r--r-- | src/corelib/kernel/qmetacontainer.cpp | 16 | ||||
-rw-r--r-- | src/corelib/kernel/qmetacontainer.h | 31 | ||||
-rw-r--r-- | src/corelib/kernel/qmetaobject.cpp | 9 | ||||
-rw-r--r-- | src/corelib/kernel/qmetaobject.h | 10 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.cpp | 11 | ||||
-rw-r--r-- | src/corelib/kernel/qmimedata.cpp | 5 | ||||
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qsingleshottimer_p.h | 15 | ||||
-rw-r--r-- | src/corelib/kernel/qsystemerror_p.h | 7 | ||||
-rw-r--r-- | src/corelib/kernel/qtimer.cpp | 8 |
15 files changed, 95 insertions, 54 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 939965cff7..bd00f69c1c 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -525,6 +525,7 @@ void QCoreApplicationPrivate::eventDispatcherReady() } Q_CONSTINIT QBasicAtomicPointer<QThread> QCoreApplicationPrivate::theMainThread = Q_BASIC_ATOMIC_INITIALIZER(nullptr); +Q_CONSTINIT QBasicAtomicPointer<void> QCoreApplicationPrivate::theMainThreadId = Q_BASIC_ATOMIC_INITIALIZER(nullptr); QThread *QCoreApplicationPrivate::mainThread() { Q_ASSERT(theMainThread.loadRelaxed() != nullptr); @@ -1090,6 +1091,14 @@ bool QCoreApplication::testAttribute(Qt::ApplicationAttribute attribute) \brief Whether the use of the QEventLoopLocker feature can cause the application to quit. + When this property is \c true the release of the last remaining + QEventLoopLocker operating on the application will attempt to + quit the application. + + Note that attempting a quit may not necessarily result in the + application quitting, for example if there still are open windows, + or the QEvent::Quit event is ignored. + The default is \c true. \sa QEventLoopLocker @@ -2093,7 +2102,13 @@ bool QCoreApplicationPrivate::canQuitAutomatically() if (!in_exec) return false; - if (quitLockEnabled && quitLockRef.loadRelaxed()) + // The automatic quit functionality is triggered by + // both QEventLoopLocker and maybeLastWindowClosed. + // In either case, we don't want to quit if there + // are active QEventLoopLockers, even if quitLockEnabled + // is not enabled, as the property signals whether to + // trigger the automatic quit, not whether to block it. + if (quitLockRef.loadRelaxed()) return false; return true; diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index 1c1577c9ff..bfd65d2c9a 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -108,6 +108,7 @@ public: virtual void quit(); static QBasicAtomicPointer<QThread> theMainThread; + static QBasicAtomicPointer<void> theMainThreadId; static QThread *mainThread(); static bool threadRequiresCoreApplication(); diff --git a/src/corelib/kernel/qcoreapplication_platform.h b/src/corelib/kernel/qcoreapplication_platform.h index e430f3495b..d5f266179e 100644 --- a/src/corelib/kernel/qcoreapplication_platform.h +++ b/src/corelib/kernel/qcoreapplication_platform.h @@ -43,7 +43,7 @@ struct Q_CORE_EXPORT QAndroidApplication { QT_DECLARE_NATIVE_INTERFACE(QAndroidApplication, 1, QCoreApplication) #ifdef Q_QDOC - static jobject context(); + static QJniObject context(); #else static QtJniTypes::Context context(); #endif diff --git a/src/corelib/kernel/qeventdispatcher_wasm.cpp b/src/corelib/kernel/qeventdispatcher_wasm.cpp index f4fcdbb8b2..4aa435b64b 100644 --- a/src/corelib/kernel/qeventdispatcher_wasm.cpp +++ b/src/corelib/kernel/qeventdispatcher_wasm.cpp @@ -938,10 +938,11 @@ void QEventDispatcherWasm::callOnLoadedIfRequired() void QEventDispatcherWasm::onLoaded() { - emscripten::val qt = emscripten::val::module_property("qt"); - if (qt.isUndefined()) - return; - qt.call<void>("onLoaded"); + // TODO: call qtloader.js onLoaded from here, in order to delay + // hiding the "Loading..." message until the app is ready to paint + // the first frame. Currently onLoaded must be called early before + // main() in order to ensure that the screen/container elements + // have valid geometry at startup. } namespace { diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp index d318069ca0..e314a17ff8 100644 --- a/src/corelib/kernel/qeventloop.cpp +++ b/src/corelib/kernel/qeventloop.cpp @@ -346,7 +346,11 @@ static_assert(alignof(QCoreApplication) >= 4); /*! Creates an event locker operating on the QCoreApplication. - The application will quit when there are no more QEventLoopLockers operating on it. + The application will attempt to quit when there are no more QEventLoopLockers + operating on it, as long as QCoreApplication::isQuitLockEnabled() is \c true. + + Note that attempting a quit may not necessarily result in the application quitting, + if there for example are open windows, or the QEvent::Quit event is ignored. \sa QCoreApplication::quit(), QCoreApplication::isQuitLockEnabled() */ diff --git a/src/corelib/kernel/qmetacontainer.cpp b/src/corelib/kernel/qmetacontainer.cpp index 200724c9f4..5f68f8fe74 100644 --- a/src/corelib/kernel/qmetacontainer.cpp +++ b/src/corelib/kernel/qmetacontainer.cpp @@ -14,6 +14,8 @@ QT_BEGIN_NAMESPACE \ingroup objectmodel + \compares equality + The class provides a number of primitive container operations, using void* as operands. This way, you can manipulate a generic container retrieved from a Variant without knowing its type. @@ -790,21 +792,19 @@ void QMetaSequence::valueAtConstIterator(const void *iterator, void *result) con } /*! - \fn bool operator==(QMetaSequence a, QMetaSequence b) + \fn bool QMetaSequence::operator==(const QMetaSequence &lhs, const QMetaSequence &rhs) \since 6.0 - \relates QMetaSequence - Returns \c true if the QMetaSequence \a a represents the same container type - as the QMetaSequence \a b, otherwise returns \c false. + Returns \c true if the QMetaSequence \a lhs represents the same container type + as the QMetaSequence \a rhs, otherwise returns \c false. */ /*! - \fn bool operator!=(QMetaSequence a, QMetaSequence b) + \fn bool QMetaSequence::operator!=(const QMetaSequence &lhs, const QMetaSequence &rhs) \since 6.0 - \relates QMetaSequence - Returns \c true if the QMetaSequence \a a represents a different container - type than the QMetaSequence \a b, otherwise returns \c false. + Returns \c true if the QMetaSequence \a lhs represents a different container + type than the QMetaSequence \a rhs, otherwise returns \c false. */ diff --git a/src/corelib/kernel/qmetacontainer.h b/src/corelib/kernel/qmetacontainer.h index 67c0ddcf36..1bed7f9f7b 100644 --- a/src/corelib/kernel/qmetacontainer.h +++ b/src/corelib/kernel/qmetacontainer.h @@ -5,6 +5,7 @@ #define QMETACONTAINER_H #include <QtCore/qcontainerinfo.h> +#include <QtCore/qcompare.h> #include <QtCore/qflags.h> #include <QtCore/qglobal.h> @@ -975,18 +976,15 @@ public: bool canGetValueAtConstIterator() const; void valueAtConstIterator(const void *iterator, void *result) const; - friend bool operator==(const QMetaSequence &a, const QMetaSequence &b) - { - return a.d() == b.d(); - } - friend bool operator!=(const QMetaSequence &a, const QMetaSequence &b) - { - return a.d() != b.d(); - } - const QtMetaContainerPrivate::QMetaSequenceInterface *iface() const { return d(); } private: + friend bool comparesEqual(const QMetaSequence &lhs, const QMetaSequence &rhs) noexcept + { + return lhs.d() == rhs.d(); + } + Q_DECLARE_EQUALITY_COMPARABLE(QMetaSequence) + template<typename T> struct MetaSequence { @@ -1171,18 +1169,15 @@ public: return nullptr; } - friend bool operator==(const QMetaAssociation &a, const QMetaAssociation &b) - { - return a.d() == b.d(); - } - friend bool operator!=(const QMetaAssociation &a, const QMetaAssociation &b) - { - return a.d() != b.d(); - } - const QtMetaContainerPrivate::QMetaAssociationInterface *iface() const { return d(); } private: + friend bool comparesEqual(const QMetaAssociation &lhs, const QMetaAssociation &rhs) noexcept + { + return lhs.d() == rhs.d(); + } + Q_DECLARE_EQUALITY_COMPARABLE(QMetaAssociation) + template<typename T> struct MetaAssociation { diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 8d304bd890..148983f126 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1798,6 +1798,7 @@ bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase * function. \ingroup objectmodel + \compares equality A QMetaMethod has a methodType(), a methodSignature(), a list of parameterTypes() and parameterNames(), a return typeName(), a @@ -1825,19 +1826,19 @@ bool QMetaObject::invokeMethodImpl(QObject *object, QtPrivate::QSlotObjectBase * invoked), otherwise returns \c false. */ -/*! \fn bool QMetaMethod::operator==(const QMetaMethod &m1, const QMetaMethod &m2) +/*! \fn bool QMetaMethod::operator==(const QMetaMethod &lhs, const QMetaMethod &rhs) \since 5.0 \overload - Returns \c true if method \a m1 is equal to method \a m2, + Returns \c true if method \a lhs is equal to method \a rhs, otherwise returns \c false. */ -/*! \fn bool QMetaMethod::operator!=(const QMetaMethod &m1, const QMetaMethod &m2) +/*! \fn bool QMetaMethod::operator!=(const QMetaMethod &lhs, const QMetaMethod &rhs) \since 5.0 \overload - Returns \c true if method \a m1 is not equal to method \a m2, + Returns \c true if method \a lhs is not equal to method \a rhs, otherwise returns \c false. */ diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h index 4e52e854d9..91f287a8d3 100644 --- a/src/corelib/kernel/qmetaobject.h +++ b/src/corelib/kernel/qmetaobject.h @@ -6,6 +6,7 @@ #define QMETAOBJECT_H #include <QtCore/qobjectdefs.h> +#include <QtCore/qcompare.h> #include <QtCore/qvariant.h> QT_BEGIN_NAMESPACE @@ -251,10 +252,11 @@ protected: friend struct QMetaObject; friend struct QMetaObjectPrivate; friend class QObject; - friend bool operator==(const QMetaMethod &m1, const QMetaMethod &m2) noexcept - { return m1.data == m2.data; } - friend bool operator!=(const QMetaMethod &m1, const QMetaMethod &m2) noexcept - { return !(m1 == m2); } + +private: + friend bool comparesEqual(const QMetaMethod &lhs, const QMetaMethod &rhs) noexcept + { return lhs.data == rhs.data; } + Q_DECLARE_EQUALITY_COMPARABLE(QMetaMethod) }; Q_DECLARE_TYPEINFO(QMetaMethod, Q_RELOCATABLE_TYPE); diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index f845eb3239..387c0f49ab 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -5,7 +5,6 @@ #include "qmetatype.h" #include "qmetatype_p.h" -#include "qobject.h" #include "qobjectdefs.h" #include "qdatetime.h" #include "qbytearray.h" @@ -43,6 +42,7 @@ # include "qmetaobject.h" # include "qsequentialiterable.h" # include "qassociativeiterable.h" +# include "qobject.h" #endif #if QT_CONFIG(itemmodel) @@ -56,7 +56,6 @@ # include "qline.h" #endif -#include <bitset> #include <new> #include <cstring> @@ -151,13 +150,7 @@ struct QMetaTypeCustomRegistry auto &ti = registry[idx]; // We must unregister all names. - auto it = aliases.begin(); - while (it != aliases.end()) { - if (it.value() == ti) - it = aliases.erase(it); - else - ++it; - } + aliases.removeIf([ti] (const auto &kv) { return kv.value() == ti; }); ti = nullptr; diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp index 1348c70b1a..2c0a89dbd7 100644 --- a/src/corelib/kernel/qmimedata.cpp +++ b/src/corelib/kernel/qmimedata.cpp @@ -90,6 +90,11 @@ static QList<QVariant> dataToUrls(QByteArrayView text) if (from >= text.size()) break; } + if (from != text.size()) { + const auto bav = QByteArrayView(begin + from, text.end()).trimmed(); + if (!bav.isEmpty()) + list.push_back(QUrl::fromEncoded(bav)); + } return list; } diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 708b10a75e..e1129c5d25 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1816,6 +1816,8 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData int QObject::startTimer(int interval, Qt::TimerType timerType) { + // no overflow can happen here: + // 2^31 ms * 1,000,000 always fits a 64-bit signed integer type return startTimer(std::chrono::milliseconds{interval}, timerType); } diff --git a/src/corelib/kernel/qsingleshottimer_p.h b/src/corelib/kernel/qsingleshottimer_p.h index d7e33c5221..dd1402f63a 100644 --- a/src/corelib/kernel/qsingleshottimer_p.h +++ b/src/corelib/kernel/qsingleshottimer_p.h @@ -19,6 +19,7 @@ #include "qabstracteventdispatcher.h" #include "qcoreapplication.h" #include "qmetaobject_p.h" +#include "private/qnumeric_p.h" #include <chrono> @@ -43,6 +44,20 @@ public: inline void startTimerForReceiver(Duration interval, Qt::TimerType timerType, const QObject *receiver); + static Duration fromMsecs(std::chrono::milliseconds ms) + { + using namespace std::chrono; + using ratio = std::ratio_divide<std::milli, Duration::period>; + static_assert(ratio::den == 1); + + Duration::rep r; + if (qMulOverflow<ratio::num>(ms.count(), &r)) { + qWarning("QTimer::singleShot(std::chrono::milliseconds, ...): " + "interval argument overflowed when converted to nanoseconds."); + return Duration::max(); + } + return Duration{r}; + } Q_SIGNALS: void timeout(); diff --git a/src/corelib/kernel/qsystemerror_p.h b/src/corelib/kernel/qsystemerror_p.h index 66c434cb13..72ced63dc5 100644 --- a/src/corelib/kernel/qsystemerror_p.h +++ b/src/corelib/kernel/qsystemerror_p.h @@ -40,12 +40,19 @@ public: constexpr ErrorScope scope() const { return errorScope; } constexpr int error() const { return errorCode; } + constexpr bool ok() const noexcept { return errorScope == NoError; } + static constexpr QSystemError stdError(int error) + { return QSystemError(error, StandardLibraryError); } + static Q_CORE_EXPORT QString string(ErrorScope errorScope, int errorCode); static Q_CORE_EXPORT QString stdString(int errorCode = -1); #ifdef Q_OS_WIN static Q_CORE_EXPORT QString windowsString(int errorCode = -1); using HRESULT = long; static Q_CORE_EXPORT QString windowsComString(HRESULT hr); + + static constexpr QSystemError nativeError(int error) + { return QSystemError(error, NativeError); } #endif // data members diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index cc46c1433b..294369c1b3 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -213,7 +213,7 @@ void QTimer::start() if (d->isActive()) // stop running timer stop(); - const auto newId = Qt::TimerId{QObject::startTimer(d->inter * 1ms, d->type)}; + Qt::TimerId newId{ QObject::startTimer(d->inter * 1ms, d->type) }; // overflow impossible if (newId > Qt::TimerId::Invalid) { d->id = newId; d->isActiveData.notify(); @@ -332,7 +332,7 @@ void QTimer::singleShotImpl(std::chrono::milliseconds msec, Qt::TimerType timerT return; } - new QSingleShotTimer(msec, timerType, receiver, slotObj); + new QSingleShotTimer(QSingleShotTimer::fromMsecs(msec), timerType, receiver, slotObj); } /*! @@ -396,7 +396,7 @@ void QTimer::singleShot(std::chrono::milliseconds msec, Qt::TimerType timerType, Qt::QueuedConnection); return; } - (void) new QSingleShotTimer(msec, timerType, receiver, member); + (void) new QSingleShotTimer(QSingleShotTimer::fromMsecs(msec), timerType, receiver, member); } } @@ -592,7 +592,7 @@ void QTimer::setInterval(std::chrono::milliseconds interval) d->inter.setValueBypassingBindings(msec); if (d->isActive()) { // create new timer QObject::killTimer(d->id); // restart timer - const auto newId = Qt::TimerId{QObject::startTimer(msec * 1ms, d->type)}; + Qt::TimerId newId{ QObject::startTimer(msec * 1ms, d->type) }; // overflow impossible if (newId > Qt::TimerId::Invalid) { // Restarted successfully. No need to update the active state. d->id = newId; |