Port QEventDispatcherWin32 to QAbstractEventDispatcherV2
The new APIs use Qt::TimerId to identify timers, and also use nanosecond resolution for the timer interval. However, as the underlying Windows APIs do not support nanosecond resolution, and always use uint millisecods and int timer id, this patch does not touch the internal WinTimerInfo struct definition, but only adjusts to changes in the public QAbstractEventDispatcherV2 API. Fixes: QTBUG-129170 Change-Id: Icc8d7b99affcf34e5677cd22502717f63a1d576c Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
242e293323
commit
0d0b346322
@ -428,7 +428,7 @@ QEventDispatcherWin32::QEventDispatcherWin32(QObject *parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QEventDispatcherWin32::QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent)
|
QEventDispatcherWin32::QEventDispatcherWin32(QEventDispatcherWin32Private &dd, QObject *parent)
|
||||||
: QAbstractEventDispatcher(dd, parent)
|
: QAbstractEventDispatcherV2(dd, parent)
|
||||||
{
|
{
|
||||||
Q_D(QEventDispatcherWin32);
|
Q_D(QEventDispatcherWin32);
|
||||||
|
|
||||||
@ -670,10 +670,11 @@ void QEventDispatcherWin32::doUnregisterSocketNotifier(QSocketNotifier *notifier
|
|||||||
delete sn;
|
delete sn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QEventDispatcherWin32::registerTimer(int timerId, qint64 interval, Qt::TimerType timerType, QObject *object)
|
void QEventDispatcherWin32::registerTimer(Qt::TimerId timerId, Duration interval,
|
||||||
|
Qt::TimerType timerType, QObject *object)
|
||||||
{
|
{
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
if (timerId < 1 || interval < 0 || !object) {
|
if (qToUnderlying(timerId) < 1 || interval.count() < 0 || !object) {
|
||||||
qWarning("QEventDispatcherWin32::registerTimer: invalid arguments");
|
qWarning("QEventDispatcherWin32::registerTimer: invalid arguments");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -690,10 +691,13 @@ void QEventDispatcherWin32::registerTimer(int timerId, qint64 interval, Qt::Time
|
|||||||
if (d->closingDown)
|
if (d->closingDown)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
using namespace std::chrono;
|
||||||
|
|
||||||
WinTimerInfo *t = new WinTimerInfo;
|
WinTimerInfo *t = new WinTimerInfo;
|
||||||
t->dispatcher = this;
|
t->dispatcher = this;
|
||||||
t->timerId = timerId;
|
t->timerId = qToUnderlying(timerId);
|
||||||
t->interval = interval;
|
// Windows does not have a ns-resolution timer
|
||||||
|
t->interval = ceil<milliseconds>(interval).count();
|
||||||
t->timerType = timerType;
|
t->timerType = timerType;
|
||||||
t->obj = object;
|
t->obj = object;
|
||||||
t->inTimerEvent = false;
|
t->inTimerEvent = false;
|
||||||
@ -704,10 +708,10 @@ void QEventDispatcherWin32::registerTimer(int timerId, qint64 interval, Qt::Time
|
|||||||
d->timerDict.insert(t->timerId, t); // store timers in dict
|
d->timerDict.insert(t->timerId, t); // store timers in dict
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QEventDispatcherWin32::unregisterTimer(int timerId)
|
bool QEventDispatcherWin32::unregisterTimer(Qt::TimerId timerId)
|
||||||
{
|
{
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
if (timerId < 1) {
|
if (qToUnderlying(timerId) < 1) {
|
||||||
qWarning("QEventDispatcherWin32::unregisterTimer: invalid argument");
|
qWarning("QEventDispatcherWin32::unregisterTimer: invalid argument");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -719,7 +723,7 @@ bool QEventDispatcherWin32::unregisterTimer(int timerId)
|
|||||||
|
|
||||||
Q_D(QEventDispatcherWin32);
|
Q_D(QEventDispatcherWin32);
|
||||||
|
|
||||||
WinTimerInfo *t = d->timerDict.take(timerId);
|
WinTimerInfo *t = d->timerDict.take(qToUnderlying(timerId));
|
||||||
if (!t)
|
if (!t)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -758,50 +762,55 @@ bool QEventDispatcherWin32::unregisterTimers(QObject *object)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QEventDispatcherWin32::TimerInfo>
|
QList<QEventDispatcherWin32::TimerInfoV2>
|
||||||
QEventDispatcherWin32::registeredTimers(QObject *object) const
|
QEventDispatcherWin32::timersForObject(QObject *object) const
|
||||||
{
|
{
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
if (!object) {
|
if (!object) {
|
||||||
qWarning("QEventDispatcherWin32:registeredTimers: invalid argument");
|
qWarning("QEventDispatcherWin32:registeredTimers: invalid argument");
|
||||||
return QList<TimerInfo>();
|
return QList<TimerInfoV2>();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Q_D(const QEventDispatcherWin32);
|
Q_D(const QEventDispatcherWin32);
|
||||||
QList<TimerInfo> list;
|
QList<TimerInfoV2> list;
|
||||||
for (WinTimerInfo *t : std::as_const(d->timerDict)) {
|
for (WinTimerInfo *t : std::as_const(d->timerDict)) {
|
||||||
Q_ASSERT(t);
|
Q_ASSERT(t);
|
||||||
if (t->obj == object)
|
if (t->obj == object) {
|
||||||
list << TimerInfo(t->timerId, t->interval, t->timerType);
|
list << TimerInfoV2{std::chrono::milliseconds{t->interval},
|
||||||
|
Qt::TimerId{t->timerId},
|
||||||
|
t->timerType};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QEventDispatcherWin32::remainingTime(int timerId)
|
QEventDispatcherWin32::Duration QEventDispatcherWin32::remainingTime(Qt::TimerId timerId) const
|
||||||
{
|
{
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
if (timerId < 1) {
|
if (qToUnderlying(timerId) < 1) {
|
||||||
qWarning("QEventDispatcherWin32::remainingTime: invalid argument");
|
qWarning("QEventDispatcherWin32::remainingTime: invalid argument");
|
||||||
return -1;
|
return Duration::min();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Q_D(QEventDispatcherWin32);
|
Q_D(const QEventDispatcherWin32);
|
||||||
|
|
||||||
quint64 currentTime = qt_msectime();
|
WinTimerInfo *t = d->timerDict.value(qToUnderlying(timerId));
|
||||||
|
|
||||||
WinTimerInfo *t = d->timerDict.value(timerId);
|
|
||||||
if (t) {
|
if (t) {
|
||||||
// timer found, return time to wait
|
// timer found, return time to wait
|
||||||
return t->timeout > currentTime ? t->timeout - currentTime : 0;
|
using namespace std::chrono;
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
const Duration currentTimeNs = steady_clock::now().time_since_epoch();
|
||||||
|
const Duration timeoutNs = Duration{t->timeout * 1ms};
|
||||||
|
return timeoutNs > currentTimeNs ? timeoutNs - currentTimeNs : 0ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
qWarning("QEventDispatcherWin32::remainingTime: timer id %d not found", timerId);
|
qWarning("QEventDispatcherWin32::remainingTime: timer id %d not found", qToUnderlying(timerId));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return -1;
|
return Duration::min();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QEventDispatcherWin32::wakeUp()
|
void QEventDispatcherWin32::wakeUp()
|
||||||
|
@ -29,7 +29,7 @@ class QEventDispatcherWin32Private;
|
|||||||
// forward declaration
|
// forward declaration
|
||||||
LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
|
LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp);
|
||||||
|
|
||||||
class Q_CORE_EXPORT QEventDispatcherWin32 : public QAbstractEventDispatcher
|
class Q_CORE_EXPORT QEventDispatcherWin32 : public QAbstractEventDispatcherV2
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_DECLARE_PRIVATE(QEventDispatcherWin32)
|
Q_DECLARE_PRIVATE(QEventDispatcherWin32)
|
||||||
@ -43,12 +43,12 @@ public:
|
|||||||
void registerSocketNotifier(QSocketNotifier *notifier) override;
|
void registerSocketNotifier(QSocketNotifier *notifier) override;
|
||||||
void unregisterSocketNotifier(QSocketNotifier *notifier) override;
|
void unregisterSocketNotifier(QSocketNotifier *notifier) override;
|
||||||
|
|
||||||
void registerTimer(int timerId, qint64 interval, Qt::TimerType timerType, QObject *object) override;
|
void registerTimer(Qt::TimerId timerId, Duration interval, Qt::TimerType timerType,
|
||||||
bool unregisterTimer(int timerId) override;
|
QObject *object) final;
|
||||||
bool unregisterTimers(QObject *object) override;
|
bool unregisterTimer(Qt::TimerId timerId) final;
|
||||||
QList<TimerInfo> registeredTimers(QObject *object) const override;
|
bool unregisterTimers(QObject *object) final;
|
||||||
|
QList<TimerInfoV2> timersForObject(QObject *object) const final;
|
||||||
int remainingTime(int timerId) override;
|
Duration remainingTime(Qt::TimerId timerId) const final;
|
||||||
|
|
||||||
void wakeUp() override;
|
void wakeUp() override;
|
||||||
void interrupt() override;
|
void interrupt() override;
|
||||||
@ -85,7 +85,7 @@ struct QSockFd {
|
|||||||
typedef QHash<qintptr, QSockFd> QSFDict;
|
typedef QHash<qintptr, QSockFd> QSFDict;
|
||||||
|
|
||||||
struct WinTimerInfo { // internal timer info
|
struct WinTimerInfo { // internal timer info
|
||||||
qint64 interval;
|
qint64 interval; // - in milliseconds
|
||||||
quint64 timeout; // - when to actually fire
|
quint64 timeout; // - when to actually fire
|
||||||
QObject *dispatcher;
|
QObject *dispatcher;
|
||||||
QObject *obj; // - object to receive events
|
QObject *obj; // - object to receive events
|
||||||
|
@ -194,9 +194,9 @@ private:
|
|||||||
// For precise timers, we expect the fudge factor to be present
|
// For precise timers, we expect the fudge factor to be present
|
||||||
QAbstractEventDispatcher::Duration interval =
|
QAbstractEventDispatcher::Duration interval =
|
||||||
fudgeInterval(PreciseTimerInterval, Qt::PreciseTimer);
|
fudgeInterval(PreciseTimerInterval, Qt::PreciseTimer);
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
|
#ifdef Q_OS_WIN
|
||||||
if (!qobject_cast<QAbstractEventDispatcherV2 *>(m_eventDispatcher))
|
// Windows does not have a nanosecond-resolution timer
|
||||||
interval = PreciseTimerInterval;
|
interval = PreciseTimerInterval;
|
||||||
#endif
|
#endif
|
||||||
QCOMPARE(timerInfo.interval, interval);
|
QCOMPARE(timerInfo.interval, interval);
|
||||||
QCOMPARE(timerInfo.timerType, Qt::PreciseTimer);
|
QCOMPARE(timerInfo.timerType, Qt::PreciseTimer);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user