1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qabstracteventdispatcher.h"
5#include "qabstracteventdispatcher_p.h"
6#include "qabstractnativeeventfilter.h"
7
8#include "qthread.h"
9#include <private/qthread_p.h>
10#include <private/qcoreapplication_p.h>
11#include <private/qfreelist_p.h>
12
13#include <QtCore/q26numeric.h>
14
15QT_BEGIN_NAMESPACE
16
17using namespace std::chrono_literals;
18
19// we allow for 2^24 = 8^8 = 16777216 simultaneously running timers
20struct QtTimerIdFreeListConstants : public QFreeListDefaultConstants
21{
22 enum
23 {
24 InitialNextValue = 1,
25 BlockCount = 6
26 };
27
28 static const int Sizes[BlockCount];
29};
30
31enum {
32 Offset0 = 0x00000000,
33 Offset1 = 0x00000040,
34 Offset2 = 0x00000100,
35 Offset3 = 0x00001000,
36 Offset4 = 0x00010000,
37 Offset5 = 0x00100000,
38
39 Size0 = Offset1 - Offset0,
40 Size1 = Offset2 - Offset1,
41 Size2 = Offset3 - Offset2,
42 Size3 = Offset4 - Offset3,
43 Size4 = Offset5 - Offset4,
44 Size5 = QtTimerIdFreeListConstants::MaxIndex - Offset5
45};
46
47Q_CONSTINIT const int QtTimerIdFreeListConstants::Sizes[QtTimerIdFreeListConstants::BlockCount] = {
48 Size0,
49 Size1,
50 Size2,
51 Size3,
52 Size4,
53 Size5
54};
55
56typedef QFreeList<void, QtTimerIdFreeListConstants> QtTimerIdFreeList;
57Q_GLOBAL_STATIC(QtTimerIdFreeList, timerIdFreeList)
58
59template <typename T> static T fromDuration(std::chrono::nanoseconds interval)
60{
61 using namespace std::chrono;
62 qint64 value = ceil<milliseconds>(d: interval).count();
63 return q26::saturate_cast<T>(value);
64}
65
66#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
67static inline QAbstractEventDispatcherV2 *v2(QAbstractEventDispatcher *self)
68{
69 if (QAbstractEventDispatcherPrivate::get(o: self)->isV2)
70 return static_cast<QAbstractEventDispatcherV2 *>(self);
71 return nullptr;
72}
73
74static inline const QAbstractEventDispatcherV2 *v2(const QAbstractEventDispatcher *self)
75{
76 if (QAbstractEventDispatcherPrivate::get(o: self)->isV2)
77 return static_cast<const QAbstractEventDispatcherV2 *>(self);
78 return nullptr;
79}
80#endif // Qt 7
81
82QAbstractEventDispatcherPrivate::QAbstractEventDispatcherPrivate()
83{
84 // Create the timer ID free list here to make sure that it is destroyed
85 // after any global static thread that may be using it.
86 // See also QTBUG-58732.
87 if (!timerIdFreeList.isDestroyed())
88 (void)timerIdFreeList();
89}
90
91QAbstractEventDispatcherPrivate::~QAbstractEventDispatcherPrivate()
92 = default;
93
94int QAbstractEventDispatcherPrivate::allocateTimerId()
95{
96 // This function may be called after timerIdFreeList() has been destructed
97 // for example in case when application exits without waiting for
98 // running threads to exit and running thread finished() has been connected
99 // to a slot which triggers a sequence that registers new timer.
100 // See https://bugreports.qt-project.org/browse/QTBUG-38957.
101 if (QtTimerIdFreeList *fl = timerIdFreeList())
102 return fl->next();
103 return 0; // Note! returning 0 generates a warning
104}
105
106void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId)
107{
108 // this function may be called by a global destructor after
109 // timerIdFreeList() has been destructed
110 if (QtTimerIdFreeList *fl = timerIdFreeList())
111 fl->release(id: timerId);
112}
113
114/*!
115 \class QAbstractEventDispatcher
116 \inmodule QtCore
117 \brief The QAbstractEventDispatcher class provides an interface to manage Qt's event queue.
118
119 \ingroup events
120
121 An event dispatcher receives events from the window system and other
122 sources. It then sends them to the QCoreApplication or QApplication
123 instance for processing and delivery. QAbstractEventDispatcher provides
124 fine-grained control over event delivery.
125
126 For simple control of event processing use
127 QCoreApplication::processEvents().
128
129 For finer control of the application's event loop, call
130 instance() and call functions on the QAbstractEventDispatcher
131 object that is returned. If you want to use your own instance of
132 QAbstractEventDispatcher or of a QAbstractEventDispatcher
133 subclass, you must install it with QCoreApplication::setEventDispatcher()
134 or QThread::setEventDispatcher() \e before a default event dispatcher has
135 been installed.
136
137 The main event loop is started by calling
138 QCoreApplication::exec(), and stopped by calling
139 QCoreApplication::exit(). Local event loops can be created using
140 QEventLoop.
141
142 Programs that perform long operations can call processEvents()
143 with a bitwise OR combination of various QEventLoop::ProcessEventsFlag
144 values to control which events should be delivered.
145
146 QAbstractEventDispatcher also allows the integration of an
147 external event loop with the Qt event loop.
148
149 \sa QEventLoop, QCoreApplication, QThread
150*/
151/*!
152 \typedef QAbstractEventDispatcher::Duration
153
154 A \c{std::chrono::duration} type that is used in various API in this class.
155 This type exists to facilitate a possible transition to a higher or lower
156 granularity.
157
158 In all current platforms, it is \c nanoseconds.
159*/
160
161/*!
162 Constructs a new event dispatcher with the given \a parent.
163*/
164QAbstractEventDispatcher::QAbstractEventDispatcher(QObject *parent)
165 : QObject(*new QAbstractEventDispatcherPrivate, parent) {}
166
167/*!
168 \internal
169*/
170QAbstractEventDispatcher::QAbstractEventDispatcher(QAbstractEventDispatcherPrivate &dd,
171 QObject *parent)
172 : QObject(dd, parent) {}
173
174/*!
175 Destroys the event dispatcher.
176*/
177QAbstractEventDispatcher::~QAbstractEventDispatcher()
178{ }
179
180/*!
181 Returns a pointer to the event dispatcher object for the specified
182 \a thread. If \a thread is \nullptr, the current thread is used. If no
183 event dispatcher exists for the specified thread, this function
184 returns \nullptr.
185
186 \b{Note:} If Qt is built without thread support, the \a thread
187 argument is ignored.
188 */
189QAbstractEventDispatcher *QAbstractEventDispatcher::instance(QThread *thread)
190{
191 QThreadData *data = thread ? QThreadData::get2(thread) : QThreadData::current();
192 return data->eventDispatcher.loadRelaxed();
193}
194
195/*!
196 \fn bool QAbstractEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
197
198 Processes pending events that match \a flags until there are no
199 more events to process. Returns \c true if an event was processed;
200 otherwise returns \c false.
201
202 This function is especially useful if you have a long running
203 operation, and want to show its progress without allowing user
204 input by using the QEventLoop::ExcludeUserInputEvents flag.
205
206 If the QEventLoop::WaitForMoreEvents flag is set in \a flags, the
207 behavior of this function is as follows:
208
209 \list
210
211 \li If events are available, this function returns after processing
212 them.
213
214 \li If no events are available, this function will wait until more
215 are available and return after processing newly available events.
216
217 \endlist
218
219 If the QEventLoop::WaitForMoreEvents flag is not set in \a flags,
220 and no events are available, this function will return
221 immediately.
222
223 \b{Note:} This function does not process events continuously; it
224 returns after all available events are processed.
225*/
226
227/*!
228 \internal
229
230 \note processEvents() only processes events queued before the function
231 is called. Events that are posted while the function runs will be queued
232 until a later round of event processing. This only applies to posted Qt
233 events. For timers and system level events, the situation is unknown.
234*/
235
236/*!
237 \fn void QAbstractEventDispatcher::registerSocketNotifier(QSocketNotifier *notifier)
238
239 Registers \a notifier with the event loop. Subclasses must
240 implement this method to tie a socket notifier into another
241 event loop.
242*/
243
244/*! \fn void QAbstractEventDispatcher::unregisterSocketNotifier(QSocketNotifier *notifier)
245
246 Unregisters \a notifier from the event dispatcher. Subclasses must
247 reimplement this method to tie a socket notifier into another
248 event loop. Reimplementations must call the base
249 implementation.
250*/
251
252/*!
253 \obsolete [6.8] This function will be removed in Qt 7. Use the overload taking \l Duration.
254
255 Registers a timer with the specified \a interval and \a timerType for the
256 given \a object and returns the timer id.
257*/
258int QAbstractEventDispatcher::registerTimer(qint64 interval, Qt::TimerType timerType, QObject *object)
259{
260 return int(registerTimer(interval: interval * 1ms, timerType, object));
261}
262
263/*!
264 \since 6.8
265 \overload
266
267 Registers a timer with the specified \a interval and \a timerType for the
268 given \a object and returns the timer id.
269*/
270Qt::TimerId QAbstractEventDispatcher::registerTimer(Duration interval, Qt::TimerType timerType,
271 QObject *object)
272{
273 auto id = Qt::TimerId(QAbstractEventDispatcherPrivate::allocateTimerId());
274#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
275 if (QAbstractEventDispatcherV2 *self = v2(self: this))
276 self->registerTimer(timerId: id, interval, timerType, object);
277 else
278 registerTimer(timerId: qToUnderlying(e: id), interval: fromDuration<qint64>(interval), timerType, object);
279#else
280 registerTimer(id, interval, timerType, object);
281#endif
282 return id;
283}
284
285#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
286/*!
287 \fn void QAbstractEventDispatcher::registerTimer(int timerId, qint64 interval, Qt::TimerType timerType, QObject *object)
288
289 Register a timer with the specified \a timerId, \a interval, and \a
290 timerType for the given \a object.
291*/
292
293/*!
294 \fn bool QAbstractEventDispatcher::unregisterTimer(int timerId)
295
296 Unregisters the timer with the given \a timerId.
297 Returns \c true if successful; otherwise returns \c false.
298
299 \sa registerTimer(), unregisterTimers()
300*/
301
302/*!
303 \fn QList<TimerInfo> QAbstractEventDispatcher::registeredTimers(QObject *object) const
304
305 Returns a list of registered timers for \a object. The TimerInfo struct has
306 \c timerId, \c interval, and \c timerType members.
307
308 \sa Qt::TimerType
309*/
310
311/*!
312 \fn int QAbstractEventDispatcher::remainingTime(int timerId)
313
314 Returns the remaining time in milliseconds with the given \a timerId.
315 If the timer is inactive, the returned value will be -1. If the timer is
316 overdue, the returned value will be 0.
317
318 \sa Qt::TimerType
319*/
320#else // Qt 7
321/*!
322 \fn void QAbstractEventDispatcher::registerTimer(Qt::TimerId timerId, Duration interval, Qt::TimerType timerType, QObject *object)
323 \since 6.8
324
325 Register a timer with the specified \a timerId, \a interval, and \a
326 timerType for the given \a object.
327
328 \sa unregisterTimer(), timersForObject()
329*/
330
331/*!
332 \fn bool QAbstractEventDispatcher::unregisterTimer(Qt::TimerId timerId)
333 \since 6.8
334
335 Unregisters the timer with the given \a timerId.
336 Returns \c true if successful; otherwise returns \c false.
337
338 \sa registerTimer(), unregisterTimers()
339*/
340
341/*!
342 \fn QList<TimerInfoV2> QAbstractEventDispatcher::timersForObject(QObject *object) const
343 \since 6.8
344
345 Returns a list of registered timers for \a object. The TimerInfoV2 struct has
346 \c timerId, \c interval, and \c timerType members.
347
348 \sa Qt::TimerType, registerTimer(), unregisterTimer()
349*/
350
351/*!
352 \fn QAbstractEventDispatcher::remainingTime(Qt::TimerId timerId) const
353
354 Returns the remaining time of the timer with the given \a timerId.
355 If the timer is inactive, the returned value will be negative. If the timer
356 is overdue, the returned value will be 0.
357
358 \sa Qt::TimerType, registerTimer(), unregisterTimer()
359*/
360#endif
361
362/*!
363 \fn bool QAbstractEventDispatcher::unregisterTimers(QObject *object)
364
365 Unregisters all the timers associated with the given \a object. Returns \c
366 true if all timers were successfully removed; otherwise returns \c false.
367
368 \sa unregisterTimer(), registeredTimers()
369*/
370
371
372/*! \fn void QAbstractEventDispatcher::wakeUp()
373 \threadsafe
374
375 Wakes up the event loop.
376
377 \omit
378 ### FIXME - QTBUG-70229
379 On Unix and Glib event dispatchers, if the dispatcher is already awake when
380 this function is called, it is ensured that the current iteration won't block
381 waiting for more events, but will instead do another event loop iteration.
382
383 ### TODO - does other event dispatchers behave the same?
384 \endomit
385
386 \sa awake()
387*/
388
389/*!
390 \fn void QAbstractEventDispatcher::interrupt()
391
392 Interrupts event dispatching. The event dispatcher will
393 return from processEvents() as soon as possible.
394*/
395
396// ### DOC: Are these called when the _application_ starts/stops or just
397// when the current _event loop_ starts/stops?
398/*!
399 \internal
400*/
401void QAbstractEventDispatcher::startingUp()
402{ }
403
404/*!
405 \internal
406*/
407void QAbstractEventDispatcher::closingDown()
408{ }
409
410/*!
411 \class QAbstractEventDispatcher::TimerInfo
412 \deprecated [6.8] Use TimerInfoV2
413 \inmodule QtCore
414
415 This struct represents information about a timer:
416 \l{QAbstractEventDispatcher::TimerInfo::timerId}{timerId},
417 \l{QAbstractEventDispatcher::TimerInfo::interval}{interval}, and
418 \l{QAbstractEventDispatcher::TimerInfo::timerType}{timerType}.
419
420 \sa registeredTimers(), QAbstractEventDispatcher::TimerInfoV2, timersForObject()
421*/
422/*! \fn QAbstractEventDispatcher::TimerInfo::TimerInfo(int timerId, int interval, Qt::TimerType timerType)
423
424 Constructs a TimerInfo struct with the given \a timerId, \a interval, and
425 \a timerType.
426*/
427/*!
428 \variable QAbstractEventDispatcher::TimerInfo::timerId
429
430 The timer's unique id.
431*/
432/*!
433 \variable QAbstractEventDispatcher::TimerInfo::interval
434
435 The timer's interval.
436*/
437/*!
438 \variable QAbstractEventDispatcher::TimerInfo::timerType
439
440 The timer's type
441
442 \sa Qt::TimerType
443*/
444
445/*!
446 \class QAbstractEventDispatcher::TimerInfoV2
447 \inmodule QtCore
448
449 This struct represents information about a timer:
450 \l{QAbstractEventDispatcher::TimerInfoV2::timerId}{timerId},
451 \l{QAbstractEventDispatcher::TimerInfoV2::interval}{interval}, and
452 \l{QAbstractEventDispatcher::TimerInfoV2::timerType}{timerType}.
453
454 \sa timersForObject()
455*/
456/*!
457 \variable QAbstractEventDispatcher::TimerInfoV2::timerId
458
459 The timer's unique id. This is created by registerTimer() upon creation and
460 uniquely identifies a timer while it is active. It is also used by
461 QTimer::id() and returned by QObject::startTimer().
462*/
463/*!
464 \variable QAbstractEventDispatcher::TimerInfoV2::interval
465
466 The timer's interval.
467*/
468/*!
469 \variable QAbstractEventDispatcher::TimerInfoV2::timerType
470
471 The timer's type
472
473 \sa Qt::TimerType
474*/
475
476/*!
477 Installs an event filter \a filterObj for all native events received by the application.
478
479 The event filter \a filterObj receives events via its \l {QAbstractNativeEventFilter::}{nativeEventFilter()}
480 function, which is called for all events received by all threads.
481
482 The \l {QAbstractNativeEventFilter::}{nativeEventFilter()} function should return true
483 if the event should be filtered, (in this case, stopped). It should return false to allow
484 normal Qt processing to continue: the native event can then be translated
485 into a QEvent and handled by the standard Qt \l{QEvent} {event} filtering,
486 e.g. QObject::installEventFilter().
487
488 If multiple event filters are installed, the filter that was installed last
489 is activated first.
490
491 \note The filter function set here receives native messages,
492 that is, MSG or XEvent structs.
493
494 For maximum portability, you should always try to use QEvent objects
495 and QObject::installEventFilter() whenever possible.
496
497 \sa QObject::installEventFilter()
498
499 \since 5.0
500*/
501void QAbstractEventDispatcher::installNativeEventFilter(QAbstractNativeEventFilter *filterObj)
502{
503 Q_D(QAbstractEventDispatcher);
504
505 // clean up unused items in the list
506 d->eventFilters.removeAll(t: nullptr);
507 d->eventFilters.removeAll(t: filterObj);
508 d->eventFilters.prepend(t: filterObj);
509}
510
511/*!
512 Removes the event filter \a filter from this object. The
513 request is ignored if such an event filter has not been installed.
514
515 All event filters for this object are automatically removed when
516 this object is destroyed.
517
518 It is always safe to remove an event filter, even during event filter
519 filter activation (that is, even from within the \l {QAbstractNativeEventFilter::}{nativeEventFilter()} function).
520
521 \sa installNativeEventFilter(), QAbstractNativeEventFilter
522 \since 5.0
523*/
524void QAbstractEventDispatcher::removeNativeEventFilter(QAbstractNativeEventFilter *filter)
525{
526 Q_D(QAbstractEventDispatcher);
527 for (int i = 0; i < d->eventFilters.size(); ++i) {
528 if (d->eventFilters.at(i) == filter) {
529 d->eventFilters[i] = nullptr;
530 break;
531 }
532 }
533}
534
535/*!
536 Sends \a message through the event filters that were set by
537 installNativeEventFilter(). This function returns \c true as soon as an
538 event filter returns \c true, and false otherwise to indicate that
539 the processing of the event should continue.
540
541 Subclasses of QAbstractEventDispatcher \e must call this function
542 for \e all messages received from the system to ensure
543 compatibility with any extensions that may be used in the
544 application. The type of event \a eventType is specific to the platform
545 plugin chosen at run-time, and can be used to cast message to the right type.
546 The \a result pointer is only used on Windows, and corresponds to the LRESULT pointer.
547
548 Note that the type of \a message is platform dependent. See
549 QAbstractNativeEventFilter for details.
550
551 \sa installNativeEventFilter(), QAbstractNativeEventFilter::nativeEventFilter()
552 \since 5.0
553*/
554bool QAbstractEventDispatcher::filterNativeEvent(const QByteArray &eventType, void *message, qintptr *result)
555{
556 Q_D(QAbstractEventDispatcher);
557 if (!d->eventFilters.isEmpty()) {
558 // Raise the loopLevel so that deleteLater() calls in or triggered
559 // by event_filter() will be processed from the main event loop.
560 QScopedScopeLevelCounter scopeLevelCounter(d->threadData.loadAcquire());
561 for (int i = 0; i < d->eventFilters.size(); ++i) {
562 QAbstractNativeEventFilter *filter = d->eventFilters.at(i);
563 if (!filter)
564 continue;
565 if (filter->nativeEventFilter(eventType, message, result))
566 return true;
567 }
568 }
569 return false;
570}
571
572/*! \fn void QAbstractEventDispatcher::awake()
573
574 This signal is emitted after the event loop returns from a
575 function that could block.
576
577 \sa wakeUp(), aboutToBlock()
578*/
579
580/*! \fn void QAbstractEventDispatcher::aboutToBlock()
581
582 This signal is emitted before the event loop calls a function that
583 could block.
584
585 \sa awake()
586*/
587
588#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
589void QAbstractEventDispatcher::registerTimer(Qt::TimerId timerId, Duration interval,
590 Qt::TimerType timerType, QObject *object)
591{
592 if (QAbstractEventDispatcherV2 *self = v2(self: this))
593 self->registerTimer(timerId, interval, timerType, object);
594 else
595 registerTimer(timerId: int(timerId), interval: fromDuration<qint64>(interval), timerType, object);
596}
597
598bool QAbstractEventDispatcher::unregisterTimer(Qt::TimerId timerId)
599{
600 if (QAbstractEventDispatcherV2 *self = v2(self: this))
601 return self->unregisterTimer(timerId);
602 return unregisterTimer(timerId: int(timerId));
603}
604
605QList<QAbstractEventDispatcher::TimerInfoV2>
606QAbstractEventDispatcher::timersForObject(QObject *object) const
607{
608 if (const QAbstractEventDispatcherV2 *self = v2(self: this))
609 return self->timersForObject(object);
610 QList<TimerInfo> timers = registeredTimers(object);
611 QList<TimerInfoV2> result;
612 result.reserve(asize: timers.size());
613 for (const TimerInfo &t : timers)
614 result.emplaceBack(args: TimerInfoV2{ .interval: t.interval * 1ms, .timerId: Qt::TimerId(t.timerId), .timerType: t.timerType });
615 return result;
616}
617
618QAbstractEventDispatcher::Duration
619QAbstractEventDispatcher::remainingTime(Qt::TimerId timerId) const
620{
621 if (const QAbstractEventDispatcherV2 *self = v2(self: this))
622 return self->remainingTime(timerId);
623 return const_cast<QAbstractEventDispatcher *>(this)->remainingTime(timerId: int(timerId)) * 1ms;
624}
625
626/*!
627 \class QAbstractEventDispatcherV2
628 \inmodule QtCore
629
630 This class is a temporary hack to enable transition to an API based on
631 \c{std::chrono} for the Qt event dispatcher. In Qt 7, it will be merged
632 with QAbstractEventDispatcher, replacing the pure virtuals there with the
633 ones defined here.
634
635 It is recommended applications and libraries port to the new API before
636 that future release to simplify work when the time comes.
637*/
638
639/*!
640 Constructs a new event dispatcher with the given \a parent.
641*/
642QAbstractEventDispatcherV2::QAbstractEventDispatcherV2(QObject *parent)
643 : QAbstractEventDispatcherV2(*new QAbstractEventDispatcherPrivate, parent)
644{
645}
646
647/*!
648 \internal
649*/
650QAbstractEventDispatcherV2::QAbstractEventDispatcherV2(QAbstractEventDispatcherPrivate &dd,
651 QObject *parent)
652 : QAbstractEventDispatcher((dd.isV2 = true, dd), parent)
653{
654}
655
656/*!
657 Destroys the event dispatcher.
658*/
659QAbstractEventDispatcherV2::~QAbstractEventDispatcherV2() = default;
660
661/*!
662 \internal
663 Temporary compatibility override.
664*/
665void QAbstractEventDispatcherV2::registerTimer(int timerId, qint64 interval,
666 Qt::TimerType timerType, QObject *object)
667{
668 auto self = static_cast<QAbstractEventDispatcherV2 *>(this);
669 self->registerTimer(timerId: Qt::TimerId(timerId), interval: interval * 1ms, timerType, object);
670}
671
672/*!
673 \internal
674 Temporary compatibility override.
675*/
676bool QAbstractEventDispatcherV2::unregisterTimer(int timerId)
677{
678 auto self = static_cast<QAbstractEventDispatcherV2 *>(this);
679 return self->unregisterTimer(timerId: Qt::TimerId(timerId));
680}
681
682/*!
683 \internal
684 Temporary compatibility override.
685*/
686auto QAbstractEventDispatcherV2::registeredTimers(QObject *object) const -> QList<TimerInfo>
687{
688 auto self = static_cast<const QAbstractEventDispatcherV2 *>(this);
689 QList<TimerInfoV2> timers = self->timersForObject(object);
690 QList<TimerInfo> result;
691 result.reserve(asize: timers.size());
692 for (const TimerInfoV2 &t : timers)
693 result.emplaceBack(args: qToUnderlying(e: t.timerId), args: fromDuration<int>(interval: t.interval), args: t.timerType);
694 return result;
695}
696
697/*!
698 \internal
699 Temporary compatibility override.
700*/
701int QAbstractEventDispatcherV2::remainingTime(int timerId)
702{
703 auto self = static_cast<QAbstractEventDispatcherV2 *>(this);
704 return fromDuration<int>(interval: self->remainingTime(timerId: Qt::TimerId(timerId)));
705}
706
707/*!
708 \internal
709 Temporary compatibility override.
710*/
711bool QAbstractEventDispatcherV2::processEventsWithDeadline(QEventLoop::ProcessEventsFlags flags, QDeadlineTimer deadline)
712{
713 Q_UNUSED(deadline);
714 return processEvents(flags);
715}
716#endif // ! Qt 7
717
718QT_END_NAMESPACE
719
720#include "moc_qabstracteventdispatcher.cpp"
721

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtbase/src/corelib/kernel/qabstracteventdispatcher.cpp