diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp | 13 | ||||
| -rw-r--r-- | src/corelib/global/qnamespace.h | 4 | ||||
| -rw-r--r-- | src/corelib/global/qnamespace.qdoc | 20 | ||||
| -rw-r--r-- | src/corelib/kernel/qabstracteventdispatcher_p.h | 4 | ||||
| -rw-r--r-- | src/corelib/kernel/qchronotimer.cpp | 26 | ||||
| -rw-r--r-- | src/corelib/kernel/qchronotimer.h | 2 | ||||
| -rw-r--r-- | src/corelib/kernel/qobject.cpp | 29 | ||||
| -rw-r--r-- | src/corelib/kernel/qobject.h | 1 | ||||
| -rw-r--r-- | src/corelib/kernel/qobject_p.h | 2 | ||||
| -rw-r--r-- | src/corelib/kernel/qsingleshottimer_p.h | 15 | ||||
| -rw-r--r-- | src/corelib/kernel/qtimer.cpp | 35 | ||||
| -rw-r--r-- | src/corelib/kernel/qtimer.h | 1 | ||||
| -rw-r--r-- | src/corelib/kernel/qtimer_p.h | 15 | 
13 files changed, 120 insertions, 47 deletions
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp index 3e9f78c0ff9..e3bbac7a3c6 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qobject.cpp @@ -469,3 +469,16 @@ const bool wasBlocked = someQObject->blockSignals(true);  // no signals here  someQObject->blockSignals(wasBlocked);  //! [54] + +{ +//! [invalid-timer-id] +    QObject *obj; +    ... +    int id = obj->startTimer(100ms); +    if (id > Qt::TimerId::Invalid) +        // The timer has been started successfully + +    if (id > 0) // Equivalent, albeit less readable +        // The timer has been started successfully +//! [invalid-timer-id] +} diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index a8069c0c3b0..33b2a69709b 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1675,6 +1675,10 @@ namespace Qt {          VeryCoarseTimer      }; +    enum class TimerId { +        Invalid = 0, +    }; +      enum ScrollPhase {          NoScrollPhase = 0,          ScrollBegin, diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 7e1536a5984..d90be59520f 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -3230,6 +3230,26 @@  */  /*! +    \enum class Qt::TimerId +    \since 6.8 +    \relates QObject +    \relates QTimer +    \relates QChronoTimer + +    This is used to represent timer IDs (for example, QTimer and QChronoTimer). +    The underlying type is \c int. You can use \l qToUnderlying() to convert +    Qt::TimerId to \c int. + +    \value Invalid Represents a no-op timer ID; it's usage depends on the +    context, for example, this is the value returned by QObject::startTimer() +    to indicate it failed to start a timer; whereas QChronoTimer::id() returns +    this value when the timer is inactive, that is, \c timer.isActive() +    returns \c false. + +    \sa QTimer::id(), QChronoTimer::id(), QObject::startTimer() +*/ + +/*!      \enum Qt::ScrollPhase      \since 5.2 diff --git a/src/corelib/kernel/qabstracteventdispatcher_p.h b/src/corelib/kernel/qabstracteventdispatcher_p.h index 7d57fd03604..87afe6a191f 100644 --- a/src/corelib/kernel/qabstracteventdispatcher_p.h +++ b/src/corelib/kernel/qabstracteventdispatcher_p.h @@ -16,7 +16,9 @@  //  #include "QtCore/qabstracteventdispatcher.h" +#include "QtCore/qnamespace.h"  #include "private/qobject_p.h" +#include "QtCore/qttypetraits.h"  QT_BEGIN_NAMESPACE @@ -33,6 +35,8 @@ public:      static int allocateTimerId();      static void releaseTimerId(int id); +    static void releaseTimerId(Qt::TimerId id) +    { releaseTimerId(qToUnderlying(id)); }  };  QT_END_NAMESPACE diff --git a/src/corelib/kernel/qchronotimer.cpp b/src/corelib/kernel/qchronotimer.cpp index 4cc8ff59fc4..ac799203d38 100644 --- a/src/corelib/kernel/qchronotimer.cpp +++ b/src/corelib/kernel/qchronotimer.cpp @@ -167,10 +167,12 @@ QBindable<bool> QChronoTimer::bindableActive()  }  /*! -    Returns the ID of the timer if the timer is running; otherwise returns -    -1. +    Returns a Qt::TimerId representing the timer ID if the timer is running; +    otherwise returns \c Qt::TimerId::Invalid. + +    \sa Qt::TimerId  */ -int QChronoTimer::id() const +Qt::TimerId QChronoTimer::id() const  {      return d_func()->id;  } @@ -189,8 +191,8 @@ void QChronoTimer::start()      auto *d = d_func();      if (d->isActive()) // stop running timer          stop(); -    const auto id = QObject::startTimer(d->intervalDuration, d->type); -    if (id > 0) { +    const auto id = Qt::TimerId{QObject::startTimer(d->intervalDuration, d->type)}; +    if (id > Qt::TimerId::Invalid) {          d->id = id;          d->isActiveData.notify();      } @@ -206,7 +208,7 @@ void QChronoTimer::stop()      auto *d = d_func();      if (d->isActive()) {          QObject::killTimer(d->id); -        d->id = QTimerPrivate::INV_TIMER; +        d->id = Qt::TimerId::Invalid;          d->isActiveData.notify();      }  } @@ -217,7 +219,7 @@ void QChronoTimer::stop()  void QChronoTimer::timerEvent(QTimerEvent *e)  {      auto *d = d_func(); -    if (e->timerId() == d->id) { +    if (Qt::TimerId{e->timerId()} == d->id) {          if (d->single)              stop();          Q_EMIT timeout(QPrivateSignal()); @@ -288,14 +290,14 @@ void QChronoTimer::setInterval(std::chrono::nanoseconds nsec)      d->intervalDuration.setValueBypassingBindings(nsec);      if (d->isActive()) { // Create new timer          QObject::killTimer(d->id); // Restart timer -        const auto id = QObject::startTimer(nsec, d->type); -        if (id > 0) { +        const auto newId = Qt::TimerId{QObject::startTimer(nsec, d->type)}; +        if (newId > Qt::TimerId::Invalid) {              // Restarted successfully. No need to update the active state. -            d->id = id; +            d->id = newId;          } else {              // Failed to start the timer.              // Need to notify about active state change. -            d->id = QTimerPrivate::INV_TIMER; +            d->id = Qt::TimerId::Invalid;              d->isActiveData.notify();          }      } @@ -328,7 +330,7 @@ QBindable<std::chrono::nanoseconds> QChronoTimer::bindableInterval()  std::chrono::nanoseconds QChronoTimer::remainingTime() const  {      if (isActive()) -        return QAbstractEventDispatcher::instance()->remainingTime(d_func()->id) * 1ms; +        return 1ms * QAbstractEventDispatcher::instance()->remainingTime(qToUnderlying(d_func()->id));      return std::chrono::nanoseconds::min();  } diff --git a/src/corelib/kernel/qchronotimer.h b/src/corelib/kernel/qchronotimer.h index 58735c46f24..79c475e93ce 100644 --- a/src/corelib/kernel/qchronotimer.h +++ b/src/corelib/kernel/qchronotimer.h @@ -38,7 +38,7 @@ public:      bool isActive() const;      QBindable<bool> bindableActive(); -    int id() const; +    Qt::TimerId id() const;      void setInterval(std::chrono::nanoseconds nsec);      std::chrono::nanoseconds interval() const; diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index cbdb95079b0..4fea4d0d3af 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -191,8 +191,8 @@ QObjectPrivate::~QObjectPrivate()                  thisThreadData->eventDispatcher.loadRelaxed()->unregisterTimers(q_ptr);              // release the timer ids back to the pool -            for (int i = 0; i < extraData->runningTimers.size(); ++i) -                QAbstractEventDispatcherPrivate::releaseTimerId(extraData->runningTimers.at(i)); +            for (auto id : std::as_const(extraData->runningTimers)) +                QAbstractEventDispatcherPrivate::releaseTimerId(id);          } else {              qWarning("QObject::~QObject: Timers cannot be stopped from another thread");          } @@ -1888,6 +1888,13 @@ int QObject::startTimer(int interval, Qt::TimerType timerType)      is \c std::chrono::nanoseconds, prior to that it was \c      std::chrono::milliseconds. This change is backwards compatible with      older releases of Qt. + +    \note In Qt 6.8, QObject was changed to use Qt::TimerId to represent timer +    IDs. This method converts the TimerId to int for backwards compatibility +    reasons, however you can use Qt::TimerId to check the value returned by +    this method, for example: +    \snippet code/src_corelib_kernel_qobject.cpp invalid-timer-id +  */  int QObject::startTimer(std::chrono::nanoseconds interval, Qt::TimerType timerType)  { @@ -1914,7 +1921,7 @@ int QObject::startTimer(std::chrono::nanoseconds interval, Qt::TimerType timerTy      const auto msecs = std::chrono::ceil<std::chrono::milliseconds>(interval);      int timerId = dispatcher->registerTimer(msecs.count(), timerType, this);      d->ensureExtraData(); -    d->extraData->runningTimers.append(timerId); +    d->extraData->runningTimers.append(Qt::TimerId{timerId});      return timerId;  } @@ -1929,17 +1936,26 @@ int QObject::startTimer(std::chrono::nanoseconds interval, Qt::TimerType timerTy  void QObject::killTimer(int id)  { +    killTimer(Qt::TimerId{id}); +} + +/*! +    \since 6.8 +    \overload +*/ +void QObject::killTimer(Qt::TimerId id) +{      Q_D(QObject);      if (Q_UNLIKELY(thread() != QThread::currentThread())) {          qWarning("QObject::killTimer: Timers cannot be stopped from another thread");          return;      } -    if (id) { +    if (id > Qt::TimerId::Invalid) {          int at = d->extraData ? d->extraData->runningTimers.indexOf(id) : -1;          if (at == -1) {              // timer isn't owned by this object              qWarning("QObject::killTimer(): Error: timer id %d is not valid for object %p (%s, %ls), timer has not been killed", -                     id, +                     qToUnderlying(id),                       this,                       metaObject()->className(),                       qUtf16Printable(objectName())); @@ -1948,14 +1964,13 @@ void QObject::killTimer(int id)          auto thisThreadData = d->threadData.loadRelaxed();          if (thisThreadData->hasEventDispatcher()) -            thisThreadData->eventDispatcher.loadRelaxed()->unregisterTimer(id); +            thisThreadData->eventDispatcher.loadRelaxed()->unregisterTimer(qToUnderlying(id));          d->extraData->runningTimers.remove(at);          QAbstractEventDispatcherPrivate::releaseTimerId(id);      }  } -  /*!      \fn QObject *QObject::parent() const diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 9d4f4bcbff6..51452580294 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -149,6 +149,7 @@ public:      int startTimer(std::chrono::nanoseconds time, Qt::TimerType timerType = Qt::CoarseTimer);      void killTimer(int id); +    void killTimer(Qt::TimerId id);      template<typename T>      T findChild(QAnyStringView aName, Qt::FindChildOptions options = Qt::FindChildrenRecursively) const diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 68ca9f53a26..54647313853 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -91,7 +91,7 @@ public:          QList<QByteArray> propertyNames;          QList<QVariant> propertyValues; -        QList<int> runningTimers; +        QList<Qt::TimerId> runningTimers;          QList<QPointer<QObject>> eventFilters;          Q_OBJECT_COMPAT_PROPERTY(QObjectPrivate::ExtraData, QString, objectName,                                   &QObjectPrivate::ExtraData::setObjectNameForwarder, diff --git a/src/corelib/kernel/qsingleshottimer_p.h b/src/corelib/kernel/qsingleshottimer_p.h index 06656ec79cb..3ae207fcd4b 100644 --- a/src/corelib/kernel/qsingleshottimer_p.h +++ b/src/corelib/kernel/qsingleshottimer_p.h @@ -27,7 +27,8 @@ QT_BEGIN_NAMESPACE  class QSingleShotTimer : public QObject  {      Q_OBJECT -    int timerId = -1; + +    Qt::TimerId timerId = Qt::TimerId::Invalid;  public:      inline ~QSingleShotTimer(); @@ -68,7 +69,7 @@ QSingleShotTimer::QSingleShotTimer(std::chrono::nanoseconds interval, Qt::TimerT  QSingleShotTimer::~QSingleShotTimer()  { -    if (timerId > 0) +    if (timerId > Qt::TimerId::Invalid)          killTimer(timerId);  } @@ -93,13 +94,12 @@ void QSingleShotTimer::startTimerForReceiver(std::chrono::nanoseconds interval,              if (deadline.hasExpired()) {                  Q_EMIT timeout();              } else { -                auto nsecs = deadline.remainingTimeAsDuration(); -                timerId = startTimer(nsecs, timerType); +                timerId = Qt::TimerId{startTimer(deadline.remainingTimeAsDuration(), timerType)};              }          };          QMetaObject::invokeMethod(this, invokable, Qt::QueuedConnection);      } else { -        timerId = startTimer(interval, timerType); +        timerId = Qt::TimerId{startTimer(interval, timerType)};      }  } @@ -107,9 +107,8 @@ void QSingleShotTimer::timerEvent(QTimerEvent *)  {      // need to kill the timer _before_ we emit timeout() in case the      // slot connected to timeout calls processEvents() -    if (timerId > 0) -        killTimer(timerId); -    timerId = -1; +    if (timerId > Qt::TimerId::Invalid) +        killTimer(std::exchange(timerId, Qt::TimerId::Invalid));      Q_EMIT timeout(); diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index e235e30a2d4..5784d023ffe 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -175,9 +175,21 @@ QBindable<bool> QTimer::bindableActive()  */  int QTimer::timerId() const  { -    return d_func()->id; +    auto v = qToUnderlying(id()); +    return v == 0 ? -1 : v;  } +/*! +    \since 6.8 +    Returns a Qt::TimerId representing the timer ID if the timer is running; +    otherwise returns \c Qt::TimerId::Invalid. + +    \sa Qt::TimerId +*/ +Qt::TimerId QTimer::id() const +{ +    return d_func()->id; +}  /*! \overload start() @@ -193,9 +205,10 @@ void QTimer::start()      Q_D(QTimer);      if (d->isActive()) // stop running timer          stop(); -    const int id = QObject::startTimer(std::chrono::milliseconds{d->inter}, d->type); -    if (id > 0) { -        d->id = id; + +    const auto newId = Qt::TimerId{QObject::startTimer(d->inter * 1ms, d->type)}; +    if (newId > Qt::TimerId::Invalid) { +        d->id = newId;          d->isActiveData.notify();      }  } @@ -249,7 +262,7 @@ void QTimer::stop()      Q_D(QTimer);      if (d->isActive()) {          QObject::killTimer(d->id); -        d->id = QTimerPrivate::INV_TIMER; +        d->id = Qt::TimerId::Invalid;          d->isActiveData.notify();      }  } @@ -261,7 +274,7 @@ void QTimer::stop()  void QTimer::timerEvent(QTimerEvent *e)  {      Q_D(QTimer); -    if (e->timerId() == d->id) { +    if (Qt::TimerId{e->timerId()} == d->id) {          if (d->single)              stop();          emit timeout(QPrivateSignal()); @@ -572,14 +585,14 @@ void QTimer::setInterval(std::chrono::milliseconds interval)      d->inter.setValueBypassingBindings(msec);      if (d->isActive()) { // create new timer          QObject::killTimer(d->id);                        // restart timer -        const int id = QObject::startTimer(std::chrono::milliseconds{msec}, d->type); -        if (id > 0) { +        const auto newId = Qt::TimerId{QObject::startTimer(msec * 1ms, d->type)}; +        if (newId > Qt::TimerId::Invalid) {              // Restarted successfully. No need to update the active state. -            d->id = id; +            d->id = newId;          } else {              // Failed to start the timer.              // Need to notify about active state change. -            d->id = QTimerPrivate::INV_TIMER; +            d->id = Qt::TimerId::Invalid;              d->isActiveData.notify();          }      } @@ -612,7 +625,7 @@ int QTimer::remainingTime() const  {      Q_D(const QTimer);      if (d->isActive()) { -        return QAbstractEventDispatcher::instance()->remainingTime(d->id); +        return QAbstractEventDispatcher::instance()->remainingTime(qToUnderlying(d->id));      }      return -1; diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h index 9b59895e60e..854d9072f20 100644 --- a/src/corelib/kernel/qtimer.h +++ b/src/corelib/kernel/qtimer.h @@ -31,6 +31,7 @@ public:      bool isActive() const;      QBindable<bool> bindableActive();      int timerId() const; +    Qt::TimerId id() const;      void setInterval(int msec);      int interval() const; diff --git a/src/corelib/kernel/qtimer_p.h b/src/corelib/kernel/qtimer_p.h index 6b99d342f1a..9347f6c241c 100644 --- a/src/corelib/kernel/qtimer_p.h +++ b/src/corelib/kernel/qtimer_p.h @@ -12,11 +12,13 @@  //  // We mean it.  // -#include "qobject_p.h" -#include "qproperty_p.h"  #include "qtimer.h"  #include "qchronotimer.h" +#include "qobject_p.h" +#include "qproperty_p.h" +#include "qttypetraits.h" +  QT_BEGIN_NAMESPACE  class QTimerPrivate : public QObjectPrivate @@ -39,7 +41,7 @@ public:      void setIntervalDuration(std::chrono::nanoseconds nsec)      {          if (isQTimer) { -            const auto msec = std::chrono::duration_cast<std::chrono::milliseconds>(nsec); +            const auto msec = std::chrono::ceil<std::chrono::milliseconds>(nsec);              static_cast<QTimer *>(q)->setInterval(msec);          } else {              static_cast<QChronoTimer *>(q)->setInterval(nsec); @@ -52,9 +54,9 @@ public:          static_cast<QTimer *>(q)->setInterval(msec);      } -    bool isActive() const { return id > 0; } +    bool isActive() const { return id > Qt::TimerId::Invalid; } -    int id = INV_TIMER; +    Qt::TimerId id = Qt::TimerId::Invalid;      Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QTimerPrivate, int, inter, &QTimerPrivate::setInterval, 0)      Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QTimerPrivate, std::chrono::nanoseconds, intervalDuration,                                         &QTimerPrivate::setIntervalDuration, @@ -64,8 +66,7 @@ public:      Q_OBJECT_COMPUTED_PROPERTY(QTimerPrivate, bool, isActiveData, &QTimerPrivate::isActive)      QObject *q; -    // true if q is a QTimer*, false otherwise -    const bool isQTimer = false; +    const bool isQTimer = false; // true if q is a QTimer*  };  QT_END_NAMESPACE  | 
