diff options
Diffstat (limited to 'src/corelib/kernel')
24 files changed, 625 insertions, 164 deletions
diff --git a/src/corelib/kernel/qbasictimer.cpp b/src/corelib/kernel/qbasictimer.cpp index 637c98cd40..b16833b34c 100644 --- a/src/corelib/kernel/qbasictimer.cpp +++ b/src/corelib/kernel/qbasictimer.cpp @@ -65,6 +65,10 @@ QT_BEGIN_NAMESPACE has not been stopped. The timer's ID can be retrieved using timerId(). + Objects of this class cannot be copied, but can be moved, so you + can maintain a list of basic timers by holding them in container + that supports move-only types, e.g. std::vector. + The \l{widgets/wiggly}{Wiggly} example uses QBasicTimer to repaint a widget at regular intervals. @@ -79,6 +83,49 @@ QT_BEGIN_NAMESPACE \sa start() */ + +/*! + \fn QBasicTimer::QBasicTimer(QBasicTimer &&other) + \since 5.14 + + Move-constructs a basic timer from \a other, which is left + \l{isActive()}{inactive}. + + \sa isActive(), swap() +*/ + +/*! + \fn QBasicTimer &QBasicTimer::operator=(QBasicTimer &&other) + \since 5.14 + + Move-assigns \a other to this basic timer. The timer + previously represented by this basic timer is stopped. + \a other is left as \l{isActive()}{inactive}. + + \sa stop(), isActive(), swap() +*/ + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +/*! + \internal +*/ +QBasicTimer::QBasicTimer(const QBasicTimer &other) + : id{other.id} +{ + qWarning("QBasicTimer can't be copied"); +} + +/*! + \internal +*/ +QBasicTimer &QBasicTimer::operator=(const QBasicTimer &other) +{ + id = other.id; + qWarning("QBasicTimer can't be assigned to"); + return *this; +} +#endif + /*! \fn QBasicTimer::~QBasicTimer() @@ -95,6 +142,15 @@ QT_BEGIN_NAMESPACE */ /*! + \fn QBasicTimer::swap(QBasicTimer &other) + \fn swap(QBasicTimer &lhs, QBasicTimer &rhs) + \since 5.14 + + Swaps string \a other with this string, or \a lhs with \a rhs. + This operation is very fast and never fails. +*/ + +/*! \fn int QBasicTimer::timerId() const Returns the timer's ID. @@ -115,24 +171,7 @@ QT_BEGIN_NAMESPACE */ void QBasicTimer::start(int msec, QObject *obj) { - QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(); - if (Q_UNLIKELY(!eventDispatcher)) { - qWarning("QBasicTimer::start: QBasicTimer can only be used with threads started with QThread"); - return; - } - if (Q_UNLIKELY(obj && obj->thread() != eventDispatcher->thread())) { - qWarning("QBasicTimer::start: Timers cannot be started from another thread"); - return; - } - if (id) { - if (Q_LIKELY(eventDispatcher->unregisterTimer(id))) - QAbstractEventDispatcherPrivate::releaseTimerId(id); - else - qWarning("QBasicTimer::start: Stopping previous timer failed. Possibly trying to stop from a different thread"); - } - id = 0; - if (obj) - id = eventDispatcher->registerTimer(msec, Qt::CoarseTimer, obj); + start(msec, Qt::CoarseTimer, obj); } /*! @@ -161,13 +200,7 @@ void QBasicTimer::start(int msec, Qt::TimerType timerType, QObject *obj) qWarning("QBasicTimer::start: Timers cannot be started from another thread"); return; } - if (id) { - if (Q_LIKELY(eventDispatcher->unregisterTimer(id))) - QAbstractEventDispatcherPrivate::releaseTimerId(id); - else - qWarning("QBasicTimer::start: Stopping previous timer failed. Possibly trying to stop from a different thread"); - } - id = 0; + stop(); if (obj) id = eventDispatcher->registerTimer(msec, timerType, obj); } diff --git a/src/corelib/kernel/qbasictimer.h b/src/corelib/kernel/qbasictimer.h index bfd6ffd125..769898f835 100644 --- a/src/corelib/kernel/qbasictimer.h +++ b/src/corelib/kernel/qbasictimer.h @@ -51,12 +51,35 @@ class QObject; class Q_CORE_EXPORT QBasicTimer { int id; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) + Q_DISABLE_COPY(QBasicTimer) +#elif QT_DEPRECATED_SINCE(5, 14) public: - inline QBasicTimer() : id(0) {} + // Just here to preserve BC, we can't remove them yet + QT_DEPRECATED_X("copy-construction is unsupported; use move-construction instead") + QBasicTimer(const QBasicTimer &); + QT_DEPRECATED_X("copy-assignment is unsupported; use move-assignment instead") + QBasicTimer &operator=(const QBasicTimer &); +#endif + +public: + constexpr QBasicTimer() noexcept : id{0} {} inline ~QBasicTimer() { if (id) stop(); } - inline bool isActive() const { return id != 0; } - inline int timerId() const { return id; } + QBasicTimer(QBasicTimer &&other) noexcept + : id{qExchange(other.id, 0)} + {} + + QBasicTimer& operator=(QBasicTimer &&other) noexcept + { + QBasicTimer{std::move(other)}.swap(*this); + return *this; + } + + void swap(QBasicTimer &other) noexcept { qSwap(id, other.id); } + + bool isActive() const noexcept { return id != 0; } + int timerId() const noexcept { return id; } void start(int msec, QObject *obj); void start(int msec, Qt::TimerType timerType, QObject *obj); @@ -64,6 +87,8 @@ public: }; Q_DECLARE_TYPEINFO(QBasicTimer, Q_MOVABLE_TYPE); +inline void swap(QBasicTimer &lhs, QBasicTimer &rhs) noexcept { lhs.swap(rhs); } + QT_END_NAMESPACE #endif // QBASICTIMER_H diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index d9fdb7f785..b70c61e351 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -46,6 +46,7 @@ #include "qcoreevent.h" #include "qeventloop.h" #endif +#include "qmetaobject.h" #include "qcorecmdlineargs_p.h" #include <qdatastream.h> #include <qdebug.h> @@ -690,7 +691,7 @@ void QCoreApplicationPrivate::initLocale() Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance. - If no instance has been allocated, \c null is returned. + If no instance has been allocated, \nullptr is returned. */ /*! @@ -952,6 +953,10 @@ bool QCoreApplication::isSetuidAllowed() Sets the attribute \a attribute if \a on is true; otherwise clears the attribute. + \note Some application attributes must be set \b before creating a + QCoreApplication instance. Refer to the Qt::ApplicationAttribute + documentation for more information. + \sa testAttribute() */ void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on) @@ -960,6 +965,27 @@ void QCoreApplication::setAttribute(Qt::ApplicationAttribute attribute, bool on) QCoreApplicationPrivate::attribs |= 1 << attribute; else QCoreApplicationPrivate::attribs &= ~(1 << attribute); + if (Q_UNLIKELY(qApp)) { + switch (attribute) { + case Qt::AA_EnableHighDpiScaling: + case Qt::AA_DisableHighDpiScaling: + case Qt::AA_PluginApplication: + case Qt::AA_UseDesktopOpenGL: + case Qt::AA_UseOpenGLES: + case Qt::AA_UseSoftwareOpenGL: + case Qt::AA_ShareOpenGLContexts: +#ifdef QT_BOOTSTRAPPED + qWarning("Attribute %d must be set before QCoreApplication is created.", + attribute); +#else + qWarning("Attribute Qt::%s must be set before QCoreApplication is created.", + QMetaEnum::fromType<Qt::ApplicationAttribute>().valueToKey(attribute)); +#endif + break; + default: + break; + } + } } /*! @@ -999,6 +1025,7 @@ void QCoreApplication::setQuitLockEnabled(bool enabled) quitLockRefEnabled = enabled; } +#if QT_DEPRECATED_SINCE(5, 6) /*! \internal \deprecated @@ -1010,6 +1037,7 @@ bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event) { return notifyInternal2(receiver, event); } +#endif /*! \internal @@ -1183,28 +1211,26 @@ bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event) { // Note: when adjusting the tracepoints in here // consider adjusting QApplicationPrivate::notify_helper too. - Q_TRACE_SCOPE(QCoreApplication_notify, receiver, event, event->type()); + Q_TRACE(QCoreApplication_notify_entry, receiver, event, event->type()); + bool consumed = false; + bool filtered = false; + Q_TRACE_EXIT(QCoreApplication_notify_exit, consumed, filtered); // send to all application event filters (only does anything in the main thread) if (QCoreApplication::self && receiver->d_func()->threadData->thread == mainThread() && QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) { - Q_TRACE(QCoreApplication_notify_event_filtered, receiver, event, event->type()); - return true; + filtered = true; + return filtered; } // send to all receiver event filters if (sendThroughObjectEventFilters(receiver, event)) { - Q_TRACE(QCoreApplication_notify_event_filtered, receiver, event, event->type()); - return true; + filtered = true; + return filtered; } - Q_TRACE(QCoreApplication_notify_before_delivery, receiver, event, event->type()); - // deliver the event - const bool consumed = receiver->event(event); - - Q_TRACE(QCoreApplication_notify_after_delivery, receiver, event, event->type(), consumed); - + consumed = receiver->event(event); return consumed; } diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index b373267fcb..65e1db3745 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -48,6 +48,7 @@ #include "qmutex.h" #include <private/qthread_p.h> #endif +#include "qtextstream.h" #include <ctype.h> #include <qt_windows.h> @@ -63,8 +64,6 @@ using namespace Microsoft::WRL::Wrappers; QT_BEGIN_NAMESPACE -int appCmdShow = 0; - Q_CORE_EXPORT QString qAppFileName() // get application file name { /* @@ -174,16 +173,12 @@ Q_CORE_EXPORT HINSTANCE qWinAppPrevInst() // get Windows prev app Q_CORE_EXPORT int qWinAppCmdShow() // get main window show command { -#if defined(Q_OS_WINCE) - return appCmdShow; -#else STARTUPINFO startupInfo; GetStartupInfo(&startupInfo); return (startupInfo.dwFlags & STARTF_USESHOWWINDOW) ? startupInfo.wShowWindow : SW_SHOWDEFAULT; -#endif } #endif @@ -480,6 +475,7 @@ static const char *findWMstr(uint msg) { 0x02DD, "WM_TABLET_FIRST + 29" }, { 0x02DE, "WM_TABLET_FIRST + 30" }, { 0x02DF, "WM_TABLET_LAST" }, + { 0x02E0, "WM_DPICHANGED" }, { 0x0300, "WM_CUT" }, { 0x0301, "WM_COPY" }, { 0x0302, "WM_PASTE" }, @@ -765,6 +761,13 @@ QString decodeMSG(const MSG& msg) case WM_DESTROY: parameters = QLatin1String("Destroy hwnd ") + hwndS; break; + case 0x02E0u: { // WM_DPICHANGED + auto rect = reinterpret_cast<const RECT *>(lParam); + QTextStream(¶meters) << "DPI: " << HIWORD(wParam) << ',' + << LOWORD(wParam) << ' ' << (rect->right - rect->left) << 'x' + << (rect->bottom - rect->top) << forcesign << rect->left << rect->top; + } + break; case WM_IME_NOTIFY: { parameters = QLatin1String("Command("); diff --git a/src/corelib/kernel/qdeadlinetimer.cpp b/src/corelib/kernel/qdeadlinetimer.cpp index e0d9d9de73..06b56bb09b 100644 --- a/src/corelib/kernel/qdeadlinetimer.cpp +++ b/src/corelib/kernel/qdeadlinetimer.cpp @@ -39,18 +39,294 @@ #include "qdeadlinetimer.h" #include "qdeadlinetimer_p.h" +#include "private/qnumeric_p.h" QT_BEGIN_NAMESPACE -Q_DECL_CONST_FUNCTION static inline QPair<qint64, qint64> toSecsAndNSecs(qint64 nsecs) +namespace { + class TimeReference + { + enum : unsigned { + umega = 1000 * 1000, + ugiga = umega * 1000 + }; + + enum : qint64 { + kilo = 1000, + mega = kilo * 1000, + giga = mega * 1000 + }; + + public: + enum RoundingStrategy { + RoundDown, + RoundUp, + RoundDefault = RoundDown + }; + + static constexpr qint64 Min = std::numeric_limits<qint64>::min(); + static constexpr qint64 Max = std::numeric_limits<qint64>::max(); + + inline TimeReference(qint64 = 0, unsigned = 0); + inline void updateTimer(qint64 &, unsigned &); + + inline bool addNanoseconds(qint64); + inline bool addMilliseconds(qint64); + bool addSecsAndNSecs(qint64, qint64); + + inline bool subtract(const qint64, const unsigned); + + inline bool toMilliseconds(qint64 *, RoundingStrategy = RoundDefault) const; + inline bool toNanoseconds(qint64 *) const; + + inline void saturate(bool toMax); + static bool sign(qint64, qint64); + + private: + bool adjust(const qint64, const unsigned, qint64 = 0); + + private: + qint64 secs; + unsigned nsecs; + }; +} + +inline TimeReference::TimeReference(qint64 t1, unsigned t2) + : secs(t1), nsecs(t2) +{ +} + +inline void TimeReference::updateTimer(qint64 &t1, unsigned &t2) +{ + t1 = secs; + t2 = nsecs; +} + +inline void TimeReference::saturate(bool toMax) +{ + secs = toMax ? Max : Min; +} + +/*! + * \internal + * + * Determines the sign of a (seconds, nanoseconds) pair + * for differentiating overflow from underflow. It doesn't + * deal with equality as it shouldn't ever be called in that case. + * + * Returns true if the pair represents a positive time offset + * false otherwise. + */ +bool TimeReference::sign(qint64 secs, qint64 nsecs) +{ + if (secs > 0) { + if (nsecs > 0) + return true; + } else { + if (nsecs < 0) + return false; + } + + // They are different in sign + secs += nsecs / giga; + if (secs > 0) + return true; + else if (secs < 0) + return false; + + // We should never get over|underflow out of + // the case: secs * giga == -nsecs + // So the sign of nsecs is the deciding factor + Q_ASSERT(nsecs % giga != 0); + return nsecs > 0; +} + +#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) +inline bool TimeReference::addNanoseconds(qint64 arg) +{ + return addSecsAndNSecs(arg / giga, arg % giga); +} + +inline bool TimeReference::addMilliseconds(qint64 arg) +{ + return addSecsAndNSecs(arg / kilo, (arg % kilo) * mega); +} + +/*! + * \internal + * + * Adds \a t1 addSecs seconds and \a addNSecs nanoseconds to the + * time reference. The arguments are normalized to seconds (qint64) + * and nanoseconds (unsigned) before the actual calculation is + * delegated to adjust(). If the nanoseconds are negative the + * owed second used for the normalization is passed on to adjust() + * as third argument. + * + * Returns true if operation was successful, false on over|underflow + */ +bool TimeReference::addSecsAndNSecs(qint64 addSecs, qint64 addNSecs) +{ + // Normalize the arguments + if (qAbs(addNSecs) >= giga) { + if (add_overflow<qint64>(addSecs, addNSecs / giga, &addSecs)) + return false; + + addNSecs %= giga; + } + + if (addNSecs < 0) + return adjust(addSecs, ugiga - unsigned(-addNSecs), -1); + + return adjust(addSecs, unsigned(addNSecs)); +} + +/*! + * \internal + * + * Adds \a t1 seconds and \a t2 nanoseconds to the internal members. + * Takes into account the additional \a carrySeconds we may owe or need to carry over. + * + * Returns true if operation was successful, false on over|underflow + */ +bool TimeReference::adjust(const qint64 t1, const unsigned t2, qint64 carrySeconds) +{ + Q_STATIC_ASSERT(QDeadlineTimerNanosecondsInT2); + nsecs += t2; + if (nsecs >= ugiga) { + nsecs -= ugiga; + carrySeconds++; + } + + // We don't worry about the order of addition, because the result returned by + // callers of this function is unchanged regardless of us over|underflowing. + // If we do, we do so by no more than a second, thus saturating the timer to + // Forever has the same effect as if we did the arithmetic exactly and salvaged + // the overflow. + return !add_overflow<qint64>(secs, t1, &secs) && !add_overflow<qint64>(secs, carrySeconds, &secs); +} + +/*! + * \internal + * + * Subtracts \a t1 seconds and \a t2 nanoseconds from the time reference. + * When normalizing the nanoseconds to a positive number the owed seconds is + * passed as third argument to adjust() as the seconds may over|underflow + * if we do the calculation directly. There is little sense to check the + * seconds for over|underflow here in case we are going to need to carry + * over a second _after_ we add the nanoseconds. + * + * Returns true if operation was successful, false on over|underflow + */ +inline bool TimeReference::subtract(const qint64 t1, const unsigned t2) +{ + Q_ASSERT(t2 < ugiga); + return adjust(-t1, ugiga - t2, -1); +} + +/*! + * \internal + * + * Converts the time reference to milliseconds. + * + * Checks are done without making use of mul_overflow because it may + * not be implemented on some 32bit platforms. + * + * Returns true if operation was successful, false on over|underflow + */ +inline bool TimeReference::toMilliseconds(qint64 *result, RoundingStrategy rounding) const +{ + static constexpr qint64 maxSeconds = Max / kilo; + static constexpr qint64 minSeconds = Min / kilo; + if (secs > maxSeconds || secs < minSeconds) + return false; + + unsigned ns = rounding == RoundDown ? nsecs : nsecs + umega - 1; + + return !add_overflow<qint64>(secs * kilo, ns / umega, result); +} + +/*! + * \internal + * + * Converts the time reference to nanoseconds. + * + * Checks are done without making use of mul_overflow because it may + * not be implemented on some 32bit platforms. + * + * Returns true if operation was successful, false on over|underflow + */ +inline bool TimeReference::toNanoseconds(qint64 *result) const +{ + static constexpr qint64 maxSeconds = Max / giga; + static constexpr qint64 minSeconds = Min / giga; + if (secs > maxSeconds || secs < minSeconds) + return false; + + return !add_overflow<qint64>(secs * giga, nsecs, result); +} +#else +inline bool TimeReference::addNanoseconds(qint64 arg) +{ + return adjust(arg, 0); +} + +inline bool TimeReference::addMilliseconds(qint64 arg) +{ + static constexpr qint64 maxMilliseconds = Max / mega; + if (qAbs(arg) > maxMilliseconds) + return false; + + return addNanoseconds(arg * mega); +} + +inline bool TimeReference::addSecsAndNSecs(qint64 addSecs, qint64 addNSecs) { - qint64 secs = nsecs / (1000*1000*1000); - if (nsecs < 0) - --secs; - nsecs -= secs * 1000*1000*1000; - return qMakePair(secs, nsecs); + static constexpr qint64 maxSeconds = Max / giga; + static constexpr qint64 minSeconds = Min / giga; + if (addSecs > maxSeconds || addSecs < minSeconds || add_overflow<qint64>(addSecs * giga, addNSecs, &addNSecs)) + return false; + + return addNanoseconds(addNSecs); } +inline bool TimeReference::adjust(const qint64 t1, const unsigned t2, qint64 carrySeconds) +{ + Q_STATIC_ASSERT(!QDeadlineTimerNanosecondsInT2); + Q_UNUSED(t2); + Q_UNUSED(carrySeconds); + + return !add_overflow<qint64>(secs, t1, &secs); +} + +inline bool TimeReference::subtract(const qint64 t1, const unsigned t2) +{ + Q_UNUSED(t2); + + return addNanoseconds(-t1); +} + +inline bool TimeReference::toMilliseconds(qint64 *result, RoundingStrategy rounding) const +{ + // Force QDeadlineTimer to treat the border cases as + // over|underflow and saturate the results returned to the user. + // We don't want to get valid milliseconds out of saturated timers. + if (secs == Max || secs == Min) + return false; + + *result = secs / mega; + if (rounding == RoundUp && secs > *result * mega) + (*result)++; + + return true; +} + +inline bool TimeReference::toNanoseconds(qint64 *result) const +{ + *result = secs; + return true; +} +#endif + /*! \class QDeadlineTimer \inmodule QtCore @@ -262,10 +538,17 @@ QDeadlineTimer::QDeadlineTimer(qint64 msecs, Qt::TimerType type) noexcept */ void QDeadlineTimer::setRemainingTime(qint64 msecs, Qt::TimerType timerType) noexcept { - if (msecs == -1) + if (msecs == -1) { *this = QDeadlineTimer(Forever, timerType); - else - setPreciseRemainingTime(0, msecs * 1000 * 1000, timerType); + return; + } + + *this = current(timerType); + + TimeReference ref(t1, t2); + if (!ref.addMilliseconds(msecs)) + ref.saturate(msecs > 0); + ref.updateTimer(t1, t2); } /*! @@ -287,16 +570,10 @@ void QDeadlineTimer::setPreciseRemainingTime(qint64 secs, qint64 nsecs, Qt::Time } *this = current(timerType); - if (QDeadlineTimerNanosecondsInT2) { - t1 += secs + toSecsAndNSecs(nsecs).first; - t2 += toSecsAndNSecs(nsecs).second; - if (t2 > 1000*1000*1000) { - t2 -= 1000*1000*1000; - ++t1; - } - } else { - t1 += secs * 1000 * 1000 * 1000 + nsecs; - } + TimeReference ref(t1, t2); + if (!ref.addSecsAndNSecs(secs, nsecs)) + ref.saturate(TimeReference::sign(secs, nsecs)); + ref.updateTimer(t1, t2); } /*! @@ -391,8 +668,22 @@ void QDeadlineTimer::setTimerType(Qt::TimerType timerType) */ qint64 QDeadlineTimer::remainingTime() const noexcept { - qint64 ns = remainingTimeNSecs(); - return ns <= 0 ? ns : (ns + 999999) / (1000 * 1000); + if (isForever()) + return -1; + + QDeadlineTimer now = current(timerType()); + TimeReference ref(t1, t2); + + qint64 msecs; + if (!ref.subtract(now.t1, now.t2)) + return 0; // We can only underflow here + + // If we fail the conversion, t1 < now.t1 means we underflowed, + // thus the deadline had long expired + if (!ref.toMilliseconds(&msecs, TimeReference::RoundUp)) + return t1 < now.t1 ? 0 : -1; + + return msecs < 0 ? 0 : msecs; } /*! @@ -414,14 +705,23 @@ qint64 QDeadlineTimer::remainingTimeNSecs() const noexcept /*! \internal Same as remainingTimeNSecs, but may return negative remaining times. Does - not deal with Forever. + not deal with Forever. In case of underflow the result is saturated to + the minimum possible value, on overflow - the maximum possible value. */ qint64 QDeadlineTimer::rawRemainingTimeNSecs() const noexcept { QDeadlineTimer now = current(timerType()); - if (QDeadlineTimerNanosecondsInT2) - return (t1 - now.t1) * (1000*1000*1000) + t2 - now.t2; - return t1 - now.t1; + TimeReference ref(t1, t2); + + qint64 nsecs; + if (!ref.subtract(now.t1, now.t2)) + return TimeReference::Min; // We can only underflow here + + // If we fail the conversion, t1 < now.t1 means we underflowed, + // thus the deadline had long expired + if (!ref.toNanoseconds(&nsecs)) + return t1 < now.t1 ? TimeReference::Min : TimeReference::Max; + return nsecs; } /*! @@ -447,8 +747,13 @@ qint64 QDeadlineTimer::rawRemainingTimeNSecs() const noexcept qint64 QDeadlineTimer::deadline() const noexcept { if (isForever()) - return t1; - return deadlineNSecs() / (1000 * 1000); + return TimeReference::Max; + + qint64 result; + if (!TimeReference(t1, t2).toMilliseconds(&result)) + return t1 < 0 ? TimeReference::Min : TimeReference::Max; + + return result; } /*! @@ -457,7 +762,8 @@ qint64 QDeadlineTimer::deadline() const noexcept same as QElapsedTimer::msecsSinceReference(). The value will be in the past if this QDeadlineTimer has expired. - If this QDeadlineTimer never expires, this function returns + If this QDeadlineTimer never expires or the number of nanoseconds until the + deadline can't be accommodated in the return type, this function returns \c{std::numeric_limits<qint64>::max()}. This function can be used to calculate the amount of time a timer is @@ -474,10 +780,13 @@ qint64 QDeadlineTimer::deadline() const noexcept qint64 QDeadlineTimer::deadlineNSecs() const noexcept { if (isForever()) - return t1; - if (QDeadlineTimerNanosecondsInT2) - return t1 * 1000 * 1000 * 1000 + t2; - return t1; + return TimeReference::Max; + + qint64 result; + if (!TimeReference(t1, t2).toNanoseconds(&result)) + return t1 < 0 ? TimeReference::Min : TimeReference::Max; + + return result; } /*! @@ -487,18 +796,25 @@ qint64 QDeadlineTimer::deadlineNSecs() const noexcept timerType. If the value is in the past, this QDeadlineTimer will be marked as expired. - If \a msecs is \c{std::numeric_limits<qint64>::max()}, this QDeadlineTimer - will be set to never expire. + If \a msecs is \c{std::numeric_limits<qint64>::max()} or the deadline is + beyond a representable point in the future, this QDeadlineTimer will be set + to never expire. \sa setPreciseDeadline(), deadline(), deadlineNSecs(), setRemainingTime() */ void QDeadlineTimer::setDeadline(qint64 msecs, Qt::TimerType timerType) noexcept { - if (msecs == (std::numeric_limits<qint64>::max)()) { - setPreciseDeadline(msecs, 0, timerType); // msecs == MAX implies Forever - } else { - setPreciseDeadline(msecs / 1000, msecs % 1000 * 1000 * 1000, timerType); + if (msecs == TimeReference::Max) { + *this = QDeadlineTimer(Forever, timerType); + return; } + + type = timerType; + + TimeReference ref; + if (!ref.addMilliseconds(msecs)) + ref.saturate(msecs > 0); + ref.updateTimer(t1, t2); } /*! @@ -516,14 +832,13 @@ void QDeadlineTimer::setDeadline(qint64 msecs, Qt::TimerType timerType) noexcept void QDeadlineTimer::setPreciseDeadline(qint64 secs, qint64 nsecs, Qt::TimerType timerType) noexcept { type = timerType; - if (secs == (std::numeric_limits<qint64>::max)() || nsecs == (std::numeric_limits<qint64>::max)()) { - *this = QDeadlineTimer(Forever, timerType); - } else if (QDeadlineTimerNanosecondsInT2) { - t1 = secs + toSecsAndNSecs(nsecs).first; - t2 = toSecsAndNSecs(nsecs).second; - } else { - t1 = secs * (1000*1000*1000) + nsecs; - } + + // We don't pass the seconds to the constructor, because we don't know + // at this point if t1 holds the seconds or nanoseconds; it's platform specific. + TimeReference ref; + if (!ref.addSecsAndNSecs(secs, nsecs)) + ref.saturate(TimeReference::sign(secs, nsecs)); + ref.updateTimer(t1, t2); } /*! @@ -536,18 +851,14 @@ void QDeadlineTimer::setPreciseDeadline(qint64 secs, qint64 nsecs, Qt::TimerType */ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) noexcept { - if (dt.isForever() || nsecs == (std::numeric_limits<qint64>::max)()) { - dt = QDeadlineTimer(Forever, dt.timerType()); - } else if (QDeadlineTimerNanosecondsInT2) { - dt.t1 += toSecsAndNSecs(nsecs).first; - dt.t2 += toSecsAndNSecs(nsecs).second; - if (dt.t2 > 1000*1000*1000) { - dt.t2 -= 1000*1000*1000; - ++dt.t1; - } - } else { - dt.t1 += nsecs; - } + if (dt.isForever()) + return dt; + + TimeReference ref(dt.t1, dt.t2); + if (!ref.addNanoseconds(nsecs)) + ref.saturate(nsecs > 0); + ref.updateTimer(dt.t1, dt.t2); + return dt; } @@ -656,6 +967,19 @@ QDeadlineTimer QDeadlineTimer::addNSecs(QDeadlineTimer dt, qint64 nsecs) noexcep To add times of precision greater than 1 millisecond, use addNSecs(). */ +QDeadlineTimer operator+(QDeadlineTimer dt, qint64 msecs) +{ + if (dt.isForever()) + return dt; + + TimeReference ref(dt.t1, dt.t2); + if (!ref.addMilliseconds(msecs)) + ref.saturate(msecs > 0); + ref.updateTimer(dt.t1, dt.t2); + + return dt; +} + /*! \fn QDeadlineTimer operator+(qint64 msecs, QDeadlineTimer dt) \relates QDeadlineTimer diff --git a/src/corelib/kernel/qdeadlinetimer.h b/src/corelib/kernel/qdeadlinetimer.h index 8032ee9018..9dd92481d2 100644 --- a/src/corelib/kernel/qdeadlinetimer.h +++ b/src/corelib/kernel/qdeadlinetimer.h @@ -108,8 +108,7 @@ public: friend bool operator>=(QDeadlineTimer d1, QDeadlineTimer d2) noexcept { return !(d1 < d2); } - friend QDeadlineTimer operator+(QDeadlineTimer dt, qint64 msecs) - { return QDeadlineTimer::addNSecs(dt, msecs * 1000 * 1000); } + friend Q_CORE_EXPORT QDeadlineTimer operator+(QDeadlineTimer dt, qint64 msecs); friend QDeadlineTimer operator+(qint64 msecs, QDeadlineTimer dt) { return dt + msecs; } friend QDeadlineTimer operator-(QDeadlineTimer dt, qint64 msecs) diff --git a/src/corelib/kernel/qeventdispatcher_cf.mm b/src/corelib/kernel/qeventdispatcher_cf.mm index b7b379e2c1..33c231987f 100644 --- a/src/corelib/kernel/qeventdispatcher_cf.mm +++ b/src/corelib/kernel/qeventdispatcher_cf.mm @@ -190,7 +190,7 @@ Q_ENUM_PRINTER(Result); QDebug operator<<(QDebug s, timespec tv) { - s << tv.tv_sec << "." << qSetFieldWidth(9) << qSetPadChar(QChar(48)) << tv.tv_nsec << reset; + s << tv.tv_sec << "." << qSetFieldWidth(9) << qSetPadChar(QChar(48)) << tv.tv_nsec << Qt::reset; return s; } diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 84378454ca..acc66ed107 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -610,7 +610,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) } } if (haveMessage) { - // WinCE doesn't support hooks at all, so we have to call this by hand :( + // The Direct2d integration unsets getMessageHook. See QTBUG-42428 if (!d->getMessageHook) (void) qt_GetMessageHook(0, PM_REMOVE, reinterpret_cast<LPARAM>(&msg)); diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp index 712e8bbcab..7d278c69f2 100644 --- a/src/corelib/kernel/qjnihelpers.cpp +++ b/src/corelib/kernel/qjnihelpers.cpp @@ -45,6 +45,7 @@ #include "qsharedpointer.h" #include "qvector.h" #include "qthread.h" +#include "qcoreapplication.h" #include <QtCore/qrunnable.h> #include <deque> @@ -474,6 +475,17 @@ void QtAndroidPrivate::runOnAndroidThread(const QtAndroidPrivate::Runnable &runn env->CallStaticVoidMethod(g_jNativeClass, g_runPendingCppRunnablesMethodID); } +static bool waitForSemaphore(int timeoutMs, QSharedPointer<QSemaphore> sem) +{ + while (timeoutMs > 0) { + if (sem->tryAcquire(1, 10)) + return true; + timeoutMs -= 10; + QCoreApplication::processEvents(); + } + return false; +} + void QtAndroidPrivate::runOnAndroidThreadSync(const QtAndroidPrivate::Runnable &runnable, JNIEnv *env, int timeoutMs) { QSharedPointer<QSemaphore> sem(new QSemaphore); @@ -481,7 +493,7 @@ void QtAndroidPrivate::runOnAndroidThreadSync(const QtAndroidPrivate::Runnable & runnable(); sem->release(); }, env); - sem->tryAcquire(1, timeoutMs); + waitForSemaphore(timeoutMs, sem); } void QtAndroidPrivate::requestPermissions(JNIEnv *env, const QStringList &permissions, const QtAndroidPrivate::PermissionsResultFunc &callbackFunc, bool directCall) @@ -524,7 +536,7 @@ QtAndroidPrivate::PermissionsHash QtAndroidPrivate::requestPermissionsSync(JNIEn *res = result; sem->release(); }, true); - if (sem->tryAcquire(1, timeoutMs)) + if (waitForSemaphore(timeoutMs, sem)) return std::move(*res); else // mustn't touch *res return QHash<QString, QtAndroidPrivate::PermissionsResult>(); diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h index 6c5f78d208..fcd92afd89 100644 --- a/src/corelib/kernel/qmetaobject.h +++ b/src/corelib/kernel/qmetaobject.h @@ -183,7 +183,7 @@ private: // signature() has been renamed to methodSignature() in Qt 5. // Warning, that function returns a QByteArray; check the life time if // you convert to char*. - char *signature(struct renamedInQt5_warning_checkTheLifeTime * = nullptr) Q_DECL_EQ_DELETE; + char *signature(struct renamedInQt5_warning_checkTheLifeTime * = nullptr) = delete; #endif static QMetaMethod fromSignalImpl(const QMetaObject *, void **); @@ -230,7 +230,8 @@ public: template<typename T> static QMetaEnum fromType() { Q_STATIC_ASSERT_X(QtPrivate::IsQEnumHelper<T>::Value, - "QMetaEnum::fromType only works with enums declared as Q_ENUM or Q_FLAG"); + "QMetaEnum::fromType only works with enums declared as " + "Q_ENUM, Q_ENUM_NS, Q_FLAG or Q_FLAG_NS"); const QMetaObject *metaObject = qt_getEnumMetaObject(T()); const char *name = qt_getEnumName(T()); return metaObject->enumerator(metaObject->indexOfEnumerator(name)); diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 19bda7e8d6..855d36794d 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -51,6 +51,7 @@ #include "quuid.h" #include "qvariant.h" #include "qdatastream.h" +#include "qregexp.h" #include "qmetatypeswitcher_p.h" #if QT_CONFIG(regularexpression) diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index a47fbfe28d..154ccf62bb 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -849,7 +849,7 @@ struct VariantData const uint flags; private: // copy constructor allowed to be implicit to silence level 4 warning from MSVC - VariantData &operator=(const VariantData &) Q_DECL_EQ_DELETE; + VariantData &operator=(const VariantData &) = delete; }; template<typename const_iterator> @@ -1720,7 +1720,7 @@ namespace QtPrivate { { QObject* operator()(const QWeakPointer<T> &p) const { - return p.data(); + return p.internalData(); } }; } diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index 94e9228778..0846193e66 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -87,7 +87,7 @@ template<> \ class QTypeModuleInfo<TYPE > \ { \ public: \ - enum Module { \ + enum Module : bool { \ IsCore = (((MODULE) == (QModulesPrivate::Core))), \ IsWidget = (((MODULE) == (QModulesPrivate::Widgets))), \ IsGui = (((MODULE) == (QModulesPrivate::Gui))), \ diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 73b655cb36..9c3e67c781 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -173,6 +173,12 @@ int (*QAbstractDeclarativeData::receivers)(QAbstractDeclarativeData *, const QO bool (*QAbstractDeclarativeData::isSignalConnected)(QAbstractDeclarativeData *, const QObject *, int) = 0; void (*QAbstractDeclarativeData::setWidgetParent)(QObject *, QObject *) = 0; +/*! + \fn QObjectData::QObjectData() + \internal + */ + + QObjectData::~QObjectData() {} QMetaObject *QObjectData::dynamicMetaObject() const @@ -836,7 +842,7 @@ static bool check_parent_thread(QObject *parent, The destructor of a parent object destroys all child objects. - Setting \a parent to 0 constructs an object with no parent. If the + Setting \a parent to \nullptr constructs an object with no parent. If the object is a widget, it will become a top-level window. \sa parent(), findChild(), findChildren() @@ -1457,8 +1463,9 @@ QThread *QObject::thread() const \snippet code/src_corelib_kernel_qobject.cpp 7 - If \a targetThread is zero, all event processing for this object - and its children stops. + If \a targetThread is \nullptr, all event processing for this object + and its children stops, as they are no longer associated with any + thread. Note that all active timers for the object will be reset. The timers are first stopped in the current thread and restarted (with @@ -1469,13 +1476,18 @@ QThread *QObject::thread() const A QEvent::ThreadChange event is sent to this object just before the thread affinity is changed. You can handle this event to perform any special processing. Note that any new events that are - posted to this object will be handled in the \a targetThread. + posted to this object will be handled in the \a targetThread, + provided it is non-null: when it is \nullptr, no event processing + for this object or its children can happen, as they are no longer + associated with any thread. \warning This function is \e not thread-safe; the current thread must be same as the current thread affinity. In other words, this function can only "push" an object from the current thread to another thread, it cannot "pull" an object from any arbitrary - thread to the current thread. + thread to the current thread. There is one exception to this rule + however: objects with no thread affinity can be "pulled" to the + current thread. \sa thread() */ @@ -3399,7 +3411,7 @@ bool QMetaObject::disconnectOne(const QObject *sender, int signal_index, /*! \internal - Helper function to remove the connection from the senders list and setting the receivers to 0 + Helper function to remove the connection from the senders list and set the receivers to \nullptr */ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::ConnectionData *connections, int signalIndex, const QObject *receiver, int method_index, void **slot, @@ -3653,12 +3665,13 @@ void doActivate(QObject *sender, int signal_index, void **argv) if (sp->blockSig) return; + Q_TRACE_SCOPE(QMetaObject_activate, sender, signal_index); + if (sp->isDeclarativeSignalConnected(signal_index) && QAbstractDeclarativeData::signalEmitted) { - Q_TRACE(QMetaObject_activate_begin_declarative_signal, sender, signal_index); + Q_TRACE_SCOPE(QMetaObject_activate_declarative_signal, sender, signal_index); QAbstractDeclarativeData::signalEmitted(sp->declarativeData, sender, signal_index, argv); - Q_TRACE(QMetaObject_activate_end_declarative_signal, sender, signal_index); } const QSignalSpyCallbackSet *signal_spy_set = callbacks_enabled ? qt_signal_spy_callback_set.load() : nullptr; @@ -3671,8 +3684,6 @@ void doActivate(QObject *sender, int signal_index, void **argv) // The possible declarative connection is done, and nothing else is connected if (callbacks_enabled && signal_spy_set->signal_begin_callback != nullptr) signal_spy_set->signal_begin_callback(sender, signal_index, argv); - Q_TRACE(QMetaObject_activate_begin_signal, sender, signal_index); - Q_TRACE(QMetaObject_activate_end_signal, sender, signal_index); if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr) signal_spy_set->signal_end_callback(sender, signal_index); return; @@ -3680,7 +3691,6 @@ void doActivate(QObject *sender, int signal_index, void **argv) if (callbacks_enabled && signal_spy_set->signal_begin_callback != nullptr) signal_spy_set->signal_begin_callback(sender, signal_index, argv); - Q_TRACE(QMetaObject_activate_begin_signal, sender, signal_index); bool senderDeleted = false; { @@ -3758,9 +3768,11 @@ void doActivate(QObject *sender, int signal_index, void **argv) if (c->isSlotObject) { c->slotObj->ref(); QScopedPointer<QtPrivate::QSlotObjectBase, QSlotObjectBaseDeleter> obj(c->slotObj); - Q_TRACE(QMetaObject_activate_begin_slot_functor, obj.data()); - obj->call(receiver, argv); - Q_TRACE(QMetaObject_activate_end_slot_functor, obj.data()); + + { + Q_TRACE_SCOPE(QMetaObject_activate_slot_functor, obj.data()); + obj->call(receiver, argv); + } } else if (c->callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) { //we compare the vtable to make sure we are not in the destructor of the object. const int method_relative = c->method_relative; @@ -3768,11 +3780,12 @@ void doActivate(QObject *sender, int signal_index, void **argv) const int methodIndex = (Q_HAS_TRACEPOINTS || callbacks_enabled) ? c->method() : 0; if (callbacks_enabled && signal_spy_set->slot_begin_callback != nullptr) signal_spy_set->slot_begin_callback(receiver, methodIndex, argv); - Q_TRACE(QMetaObject_activate_begin_slot, receiver, methodIndex); - callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv); + { + Q_TRACE_SCOPE(QMetaObject_activate_slot, receiver, methodIndex); + callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv); + } - Q_TRACE(QMetaObject_activate_end_slot, receiver, methodIndex); if (callbacks_enabled && signal_spy_set->slot_end_callback != nullptr) signal_spy_set->slot_end_callback(receiver, methodIndex); } else { @@ -3781,11 +3794,12 @@ void doActivate(QObject *sender, int signal_index, void **argv) if (callbacks_enabled && signal_spy_set->slot_begin_callback != nullptr) { signal_spy_set->slot_begin_callback(receiver, method, argv); } - Q_TRACE(QMetaObject_activate_begin_slot, receiver, method); - QMetaObject::metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv); + { + Q_TRACE_SCOPE(QMetaObject_activate_slot, receiver, method); + QMetaObject::metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv); + } - Q_TRACE(QMetaObject_activate_end_slot, receiver, method); if (callbacks_enabled && signal_spy_set->slot_end_callback != nullptr) signal_spy_set->slot_end_callback(receiver, method); } @@ -3803,8 +3817,6 @@ void doActivate(QObject *sender, int signal_index, void **argv) if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr) signal_spy_set->signal_end_callback(sender, signal_index); - Q_TRACE(QMetaObject_activate_end_signal, sender, signal_index); - } /*! @@ -4031,6 +4043,7 @@ static void dumpRecursive(int level, const QObject *object) } } +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) /*! \overload \obsolete @@ -4044,6 +4057,7 @@ void QObject::dumpObjectTree() { const_cast<const QObject *>(this)->dumpObjectTree(); } +#endif /*! Dumps a tree of children to the debug output. @@ -4058,6 +4072,7 @@ void QObject::dumpObjectTree() const dumpRecursive(0, this); } +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) /*! \overload \obsolete @@ -4072,6 +4087,7 @@ void QObject::dumpObjectInfo() { const_cast<const QObject *>(this)->dumpObjectInfo(); } +#endif /*! Dumps information about signal connections, etc. for this object @@ -4159,6 +4175,11 @@ uint QObject::registerUserData() } /*! + \fn QObjectUserData::QObjectUserData() + \internal + */ + +/*! \internal */ QObjectUserData::~QObjectUserData() diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 1d83731441..12512e74c5 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -93,7 +93,9 @@ Q_CORE_EXPORT void qt_qFindChildren_helper(const QObject *parent, const QRegular Q_CORE_EXPORT QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const QMetaObject &mo, Qt::FindChildOptions options); class Q_CORE_EXPORT QObjectData { + Q_DISABLE_COPY(QObjectData) public: + QObjectData() = default; virtual ~QObjectData() = 0; QObject *q_ptr; QObject *parent; @@ -472,7 +474,9 @@ inline const QMetaObject *qt_getQtMetaObject() noexcept #ifndef QT_NO_USERDATA class Q_CORE_EXPORT QObjectUserData { + Q_DISABLE_COPY(QObjectUserData) public: + QObjectUserData() = default; virtual ~QObjectUserData(); }; #endif diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 418b8cf1d2..0bceab6fb4 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -515,7 +515,7 @@ struct Q_CORE_EXPORT QMetaObject Qt::ConnectionType type = Qt::AutoConnection, decltype(function()) *ret = nullptr) { return invokeMethodImpl(context, - new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(function), + new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)), type, ret); } @@ -527,7 +527,7 @@ struct Q_CORE_EXPORT QMetaObject invokeMethod(QObject *context, Func function, typename std::result_of<Func()>::type *ret) { return invokeMethodImpl(context, - new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(function), + new QtPrivate::QFunctorSlotObjectWithNoArgs<Func, decltype(function())>(std::move(function)), Qt::AutoConnection, ret); } diff --git a/src/corelib/kernel/qpointer.cpp b/src/corelib/kernel/qpointer.cpp index c3dee7989e..068314633b 100644 --- a/src/corelib/kernel/qpointer.cpp +++ b/src/corelib/kernel/qpointer.cpp @@ -45,7 +45,7 @@ \ingroup objectmodel A guarded pointer, QPointer<T>, behaves like a normal C++ - pointer \c{T *}, except that it is automatically set to 0 when the + pointer \c{T *}, except that it is automatically cleared when the referenced object is destroyed (unlike normal C++ pointers, which become "dangling pointers" in such cases). \c T must be a subclass of QObject. @@ -79,7 +79,7 @@ \snippet pointer/pointer.cpp 2 If the QLabel is deleted in the meantime, the \c label variable - will hold 0 instead of an invalid address, and the last line will + will hold \nullptr instead of an invalid address, and the last line will never be executed. The functions and operators available with a QPointer are the @@ -93,7 +93,7 @@ For creating guarded pointers, you can construct or assign to them from a T* or from another guarded pointer of the same type. You can compare them with each other using operator==() and - operator!=(), or test for 0 with isNull(). You can dereference + operator!=(), or test for \nullptr with isNull(). You can dereference them using either the \c *x or the \c x->member notation. A guarded pointer will automatically cast to a \c T *, so you can @@ -113,7 +113,7 @@ /*! \fn template <class T> QPointer<T>::QPointer() - Constructs a 0 guarded pointer. + Constructs a guarded pointer with value \nullptr. \sa isNull() */ diff --git a/src/corelib/kernel/qpointer.h b/src/corelib/kernel/qpointer.h index b2b3cda4ab..80faef2990 100644 --- a/src/corelib/kernel/qpointer.h +++ b/src/corelib/kernel/qpointer.h @@ -77,13 +77,13 @@ public: ~QPointer(); #endif - inline void swap(QPointer &other) { wp.swap(other.wp); } + inline void swap(QPointer &other) noexcept { wp.swap(other.wp); } inline QPointer<T> &operator=(T* p) { wp.assign(static_cast<QObjectType*>(p)); return *this; } inline T* data() const - { return static_cast<T*>( wp.data()); } + { return static_cast<T*>(wp.internalData()); } inline T* operator->() const { return data(); } inline T& operator*() const @@ -143,9 +143,13 @@ template<typename T> QPointer<T> qPointerFromVariant(const QVariant &variant) { - return QPointer<T>(qobject_cast<T*>(QtSharedPointer::weakPointerFromVariant_internal(variant).data())); + return QPointer<T>(qobject_cast<T*>(QtSharedPointer::weakPointerFromVariant_internal(variant).internalData())); } +template <class T> +inline void swap(QPointer<T> &p1, QPointer<T> &p2) noexcept +{ p1.swap(p2); } + QT_END_NAMESPACE #endif // QT_NO_QOBJECT diff --git a/src/corelib/kernel/qsignalmapper.cpp b/src/corelib/kernel/qsignalmapper.cpp index 02a1281f92..34fea861cd 100644 --- a/src/corelib/kernel/qsignalmapper.cpp +++ b/src/corelib/kernel/qsignalmapper.cpp @@ -37,6 +37,9 @@ ** ****************************************************************************/ +#include "qglobal.h" +#if QT_DEPRECATED_SINCE(5, 10) + #include "qsignalmapper.h" #include "qhash.h" #include "qobject_p.h" @@ -312,3 +315,4 @@ QT_END_NAMESPACE #include "moc_qsignalmapper.cpp" +#endif diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index 188d529f04..178227e914 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -628,7 +628,7 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv */ /*! - \fn template <typename PointerToMemberFunction> QMetaObject::Connection QTimer::callOnTimeout(const QObject *receiver, PointerToMemberFunction slot, Qt::ConnectionType connectionType = Qt::AutoConnection) + \fn template <typename MemberFunction> QMetaObject::Connection QTimer::callOnTimeout(const QObject *receiver, MemberFunction *slot, Qt::ConnectionType connectionType = Qt::AutoConnection) \since 5.12 \overload callOnTimeout() diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h index ae5552f1c9..eb7185c12d 100644 --- a/src/corelib/kernel/qtimer.h +++ b/src/corelib/kernel/qtimer.h @@ -100,8 +100,8 @@ public: QMetaObject::Connection callOnTimeout(Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection); template <typename Functor> QMetaObject::Connection callOnTimeout(const QObject *context, Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection); - template <typename PointerToMemberFunction> - QMetaObject::Connection callOnTimeout(const QObject *receiver, PointerToMemberFunction slot, Qt::ConnectionType connectionType = Qt::AutoConnection); + template <typename MemberFunction> + QMetaObject::Connection callOnTimeout(const QObject *receiver, MemberFunction *slot, Qt::ConnectionType connectionType = Qt::AutoConnection); #else // singleShot to a QObject slot template <typename Duration, typename Func1> diff --git a/src/corelib/kernel/qtimerinfo_unix.cpp b/src/corelib/kernel/qtimerinfo_unix.cpp index c3b8c86063..39010c19cb 100644 --- a/src/corelib/kernel/qtimerinfo_unix.cpp +++ b/src/corelib/kernel/qtimerinfo_unix.cpp @@ -215,7 +215,7 @@ static timespec roundToMillisecond(timespec val) QDebug operator<<(QDebug s, timeval tv) { QDebugStateSaver saver(s); - s.nospace() << tv.tv_sec << "." << qSetFieldWidth(6) << qSetPadChar(QChar(48)) << tv.tv_usec << reset; + s.nospace() << tv.tv_sec << "." << qSetFieldWidth(6) << qSetPadChar(QChar(48)) << tv.tv_usec << Qt::reset; return s; } QDebug operator<<(QDebug s, Qt::TimerType t) @@ -373,7 +373,7 @@ static void calculateNextTimeout(QTimerInfo *t, timespec currentTime) #ifdef QTIMERINFO_DEBUG if (t->timerType != Qt::PreciseTimer) - qDebug() << "timer" << t->timerType << hex << t->id << dec << "interval" << t->interval + qDebug() << "timer" << t->timerType << Qt::hex << t->id << Qt::dec << "interval" << t->interval << "originally expected at" << t->expected << "will fire at" << t->timeout << "or" << (t->timeout - t->expected) << "s late"; #endif @@ -500,7 +500,7 @@ void QTimerInfoList::registerTimer(int timerId, int interval, Qt::TimerType time t->cumulativeError = 0; t->count = 0; if (t->timerType != Qt::PreciseTimer) - qDebug() << "timer" << t->timerType << hex <<t->id << dec << "interval" << t->interval << "expected at" + qDebug() << "timer" << t->timerType << Qt::hex <<t->id << Qt::dec << "interval" << t->interval << "expected at" << t->expected << "will fire first at" << t->timeout; #endif } @@ -620,7 +620,7 @@ int QTimerInfoList::activateTimers() currentTimerInfo->cumulativeError += diff; ++currentTimerInfo->count; if (currentTimerInfo->timerType != Qt::PreciseTimer) - qDebug() << "timer" << currentTimerInfo->timerType << hex << currentTimerInfo->id << dec << "interval" + qDebug() << "timer" << currentTimerInfo->timerType << Qt::hex << currentTimerInfo->id << Qt::dec << "interval" << currentTimerInfo->interval << "firing at" << currentTime << "(orig" << currentTimerInfo->expected << "scheduled at" << currentTimerInfo->timeout << ") off by" << diff << "activation" << currentTimerInfo->count diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index ec5c39d8c1..0ecd17df09 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -55,6 +55,7 @@ #include "qstringlist.h" #include "qurl.h" #include "qlocale.h" +#include "qregexp.h" #include "quuid.h" #if QT_CONFIG(itemmodel) #include "qabstractitemmodel.h" @@ -2410,7 +2411,7 @@ void QVariant::clear() Converts the int representation of the storage type, \a typeId, to its string representation. - Returns a null pointer if the type is QMetaType::UnknownType or doesn't exist. + Returns \nullptr if the type is QMetaType::UnknownType or doesn't exist. */ const char *QVariant::typeToName(int typeId) { @@ -4146,7 +4147,7 @@ void* QVariant::data() /*! Returns \c true if this is a null variant, false otherwise. A variant is considered null if it contains no initialized value, or the contained value - is a null pointer or is an instance of a built-in type that has an isNull + is \nullptr or is an instance of a built-in type that has an isNull method, in which case the result would be the same as calling isNull on the wrapped object. @@ -4226,7 +4227,7 @@ QDebug operator<<(QDebug dbg, const QVariant::Type p) If the QVariant contains a pointer to a type derived from QObject then \c{T} may be any QObject type. If the pointer stored in the QVariant can be - qobject_cast to T, then that result is returned. Otherwise a null pointer is + qobject_cast to T, then that result is returned. Otherwise \nullptr is returned. Note that this only works for QObject subclasses which use the Q_OBJECT macro. diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index 2247c7adc8..e094ebff52 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -393,10 +393,13 @@ class Q_CORE_EXPORT QVariant : type(variantType), is_shared(false), is_null(false) {} - inline Private(const Private &other) noexcept +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + Private(const Private &other) noexcept : data(other.data), type(other.type), is_shared(other.is_shared), is_null(other.is_null) {} + Private &operator=(const Private &other) noexcept = default; +#endif union Data { char c; @@ -483,27 +486,27 @@ public: private: // force compile error, prevent QVariant(bool) to be called - inline QVariant(void *) Q_DECL_EQ_DELETE; + inline QVariant(void *) = delete; // QVariant::Type is marked as \obsolete, but we don't want to // provide a constructor from its intended replacement, // QMetaType::Type, instead, because the idea behind these // constructors is flawed in the first place. But we also don't // want QVariant(QMetaType::String) to compile and falsely be an // int variant, so delete this constructor: - QVariant(QMetaType::Type) Q_DECL_EQ_DELETE; + QVariant(QMetaType::Type) = delete; // These constructors don't create QVariants of the type associcated // with the enum, as expected, but they would create a QVariant of // type int with the value of the enum value. // Use QVariant v = QColor(Qt::red) instead of QVariant v = Qt::red for // example. - QVariant(Qt::GlobalColor) Q_DECL_EQ_DELETE; - QVariant(Qt::BrushStyle) Q_DECL_EQ_DELETE; - QVariant(Qt::PenStyle) Q_DECL_EQ_DELETE; - QVariant(Qt::CursorShape) Q_DECL_EQ_DELETE; + QVariant(Qt::GlobalColor) = delete; + QVariant(Qt::BrushStyle) = delete; + QVariant(Qt::PenStyle) = delete; + QVariant(Qt::CursorShape) = delete; #ifdef QT_NO_CAST_FROM_ASCII // force compile error when implicit conversion is not wanted - inline QVariant(const char *) Q_DECL_EQ_DELETE; + inline QVariant(const char *) = delete; #endif public: typedef Private DataPtr; |