diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2015-06-30 18:15:53 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2015-07-08 03:20:29 +0000 |
commit | d01d08971a1ba4d66927a48577041abc5b7df8a2 (patch) | |
tree | 7274e52fa8ec9b374bc9b7b5a66746384e8f886d /src/corelib | |
parent | 1ac0c4a2f787607269c2b5511a0f9a410d2f5603 (diff) |
Fix the remainingTime() result after the first activation of a QTimer
On Windows, t->timeout was updated only once, at creation time, so the
timer would always show as "overdue" after the first activation.
The timer is updated to indicate the full remaining time during the slot
activation, which is the behavior of the Unix and Glib dispatchers.
Task-number: QTBUG-46940
Change-Id: I255870833a024a36adf6ffff13ecadb021c4358c
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_win.cpp | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index b55679f3d5..6da70cf0bd 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -561,6 +561,17 @@ static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatch return wnd; } +static void calculateNextTimeout(WinTimerInfo *t, quint64 currentTime) +{ + uint interval = t->interval; + if ((interval >= 20000u && t->timerType != Qt::PreciseTimer) || t->timerType == Qt::VeryCoarseTimer) { + // round the interval, VeryCoarseTimers only have full second accuracy + interval = ((interval + 500)) / 1000 * 1000; + } + t->interval = interval; + t->timeout = currentTime + interval; +} + void QEventDispatcherWin32Private::registerTimer(WinTimerInfo *t) { Q_ASSERT(internalHwnd); @@ -568,6 +579,7 @@ void QEventDispatcherWin32Private::registerTimer(WinTimerInfo *t) Q_Q(QEventDispatcherWin32); int ok = 0; + calculateNextTimeout(t, qt_msectime()); uint interval = t->interval; if (interval == 0u) { // optimization for single-shot-zero-timer @@ -576,17 +588,13 @@ void QEventDispatcherWin32Private::registerTimer(WinTimerInfo *t) } else if ((interval < 20u || t->timerType == Qt::PreciseTimer) && qtimeSetEvent) { ok = t->fastTimerId = qtimeSetEvent(interval, 1, qt_fast_timer_proc, (DWORD_PTR)t, TIME_CALLBACK_FUNCTION | TIME_PERIODIC | TIME_KILL_SYNCHRONOUS); - } else if (interval >= 20000u || t->timerType == Qt::VeryCoarseTimer) { - // round the interval, VeryCoarseTimers only have full second accuracy - interval = ((interval + 500)) / 1000 * 1000; } + if (ok == 0) { // user normal timers for (Very)CoarseTimers, or if no more multimedia timers available ok = SetTimer(internalHwnd, t->timerId, interval, 0); } - t->timeout = qt_msectime() + interval; - if (ok == 0) qErrnoWarning("QEventDispatcherWin32::registerTimer: Failed to create a timer"); } @@ -611,6 +619,9 @@ void QEventDispatcherWin32Private::sendTimerEvent(int timerId) // send event, but don't allow it to recurse t->inTimerEvent = true; + // recalculate next emission + calculateNextTimeout(t, qt_msectime()); + QTimerEvent e(t->timerId); QCoreApplication::sendEvent(t->obj, &e); |