Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qeventdispatcher_cf.mm
Go to the documentation of this file.
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
5
6#include <QtCore/qdebug.h>
7#include <QtCore/qmetaobject.h>
8#include <QtCore/qthread.h>
9#include <QtCore/private/qcoreapplication_p.h>
10#include <QtCore/private/qcore_unix_p.h>
11#include <QtCore/private/qthread_p.h>
12
13#include <limits>
14
15#ifdef Q_OS_MACOS
16# include <AppKit/NSApplication.h>
17#elif defined(Q_OS_WATCHOS)
18# include <WatchKit/WatchKit.h>
19#else
20# include <UIKit/UIApplication.h>
21#endif
22
24namespace QtPrivate {
25Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher");
26Q_LOGGING_CATEGORY(lcEventDispatcherTimers, "qt.eventdispatcher.timers");
27}
28using namespace QtPrivate;
30
32
33/*
34 During scroll view panning, and possibly other gestures, UIKit will
35 request a switch to UITrackingRunLoopMode via GSEventPushRunLoopMode,
36 which records the new runloop mode and stops the current runloop.
37
38 Unfortunately the runloop mode is just stored on an internal stack, used
39 when UIKit itself is running the runloop, and is not available through e.g.
40 CFRunLoopCopyCurrentMode, which only knows about the current running
41 runloop mode, not the requested future runloop mode.
42
43 To ensure that we pick up this new runloop mode and use it when calling
44 CFRunLoopRunInMode from processEvents, we listen for the notification
45 emitted by [UIApplication pushRunLoopMode:requester:].
46
47 Without this workaround we end up always running in the default runloop
48 mode, resulting in missing momentum-phases in UIScrollViews such as the
49 emoji keyboard.
50*/
52@end
53
55
57 QStack<CFStringRef> m_runLoopModes;
58}
59
60- (instancetype)init
61{
62 if ((self = [super init])) {
63 m_runLoopModes.push(kCFRunLoopDefaultMode);
64
65#if !defined(Q_OS_WATCHOS)
67 [[NSNotificationCenter defaultCenter]
68 addObserver:self selector:@selector(receivedNotification:)
69 name:nil object:qt_apple_sharedApplication()];
70 }
71#endif
72 }
73
74 return self;
75}
76
77- (void)dealloc
78{
79 [NSNotificationCenter.defaultCenter removeObserver:self];
80
81 [super dealloc];
82}
83
84static CFStringRef runLoopMode(NSDictionary *dictionary)
85{
86 for (NSString *key in dictionary) {
87 if (CFStringHasSuffix((CFStringRef)key, CFSTR("RunLoopMode")))
88 return (CFStringRef)dictionary[key];
89 }
90
91 return nil;
92}
93
94- (void)receivedNotification:(NSNotification *)notification
95{
96 if (CFStringHasSuffix((CFStringRef)notification.name, CFSTR("RunLoopModePushNotification"))) {
97 if (CFStringRef mode = runLoopMode(notification.userInfo))
98 m_runLoopModes.push(mode);
99 else
100 qCWarning(lcEventDispatcher) << "Encountered run loop push notification without run loop mode!";
101
102 } else if (CFStringHasSuffix((CFStringRef)notification.name, CFSTR("RunLoopModePopNotification"))) {
103 CFStringRef mode = runLoopMode(notification.userInfo);
104 if (CFStringCompare(mode, self.currentMode, 0) == kCFCompareEqualTo)
105 m_runLoopModes.pop();
106 else
107 qCWarning(lcEventDispatcher) << "Tried to pop run loop mode"
108 << qPrintable(QString::fromCFString(mode)) << "that was never pushed!";
109
110 Q_ASSERT(m_runLoopModes.size() >= 1);
111 }
112}
113
114- (CFStringRef)currentMode
115{
116 return m_runLoopModes.top();
117}
118
119@end
120
122
124{
126
129
130public:
131
132 #define Q_MIRROR_ENUM(name) name = name
133
134 enum Activity {
135 Q_MIRROR_ENUM(kCFRunLoopEntry),
136 Q_MIRROR_ENUM(kCFRunLoopBeforeTimers),
137 Q_MIRROR_ENUM(kCFRunLoopBeforeSources),
138 Q_MIRROR_ENUM(kCFRunLoopBeforeWaiting),
139 Q_MIRROR_ENUM(kCFRunLoopAfterWaiting),
140 Q_MIRROR_ENUM(kCFRunLoopExit)
141 };
142
143 enum Result {
144 Q_MIRROR_ENUM(kCFRunLoopRunFinished),
145 Q_MIRROR_ENUM(kCFRunLoopRunStopped),
146 Q_MIRROR_ENUM(kCFRunLoopRunTimedOut),
147 Q_MIRROR_ENUM(kCFRunLoopRunHandledSource)
148 };
149};
150
151#define Q_ENUM_PRINTER(enumName) \
152 static const char* qPrintable##enumName(int value) \
153 { \
154 return RunLoopDebugger::staticMetaObject.enumerator(RunLoopDebugger::staticMetaObject.indexOfEnumerator(#enumName)).valueToKey(value); \
155 }
156
159
161{
162 s << tv.tv_sec << "." << qSetFieldWidth(9) << qSetPadChar(QChar(48)) << tv.tv_nsec << Qt::reset;
163 return s;
164}
165
166static const CFTimeInterval kCFTimeIntervalMinimum = 0;
167static const CFTimeInterval kCFTimeIntervalDistantFuture = std::numeric_limits<CFTimeInterval>::max();
168
169#pragma mark - Class definition
170
173 , m_processEvents(QEventLoop::EventLoopExec)
174 , m_postedEventsRunLoopSource(this, &QEventDispatcherCoreFoundation::processPostedEvents)
175 , m_runLoopActivityObserver(this, &QEventDispatcherCoreFoundation::handleRunLoopActivity, kCFRunLoopAllActivities)
176 , m_runLoopModeTracker([[RunLoopModeTracker alloc] init])
177 , m_runLoopTimer(0)
178 , m_blockedRunLoopTimer(0)
179 , m_overdueTimerScheduled(false)
180{
181}
182
184{
185 // The following code must run on the event dispatcher thread, so that
186 // CFRunLoopGetCurrent() returns the correct run loop.
188
189 m_runLoop = QCFType<CFRunLoopRef>::constructFromGet(CFRunLoopGetCurrent());
190 m_cfSocketNotifier.setHostEventDispatcher(this);
191 m_postedEventsRunLoopSource.addToMode(kCFRunLoopCommonModes);
192 m_runLoopActivityObserver.addToMode(kCFRunLoopCommonModes);
193}
194
196{
197 invalidateTimer();
198 m_timerInfoList.clearTimers();
199
200 m_cfSocketNotifier.removeSocketNotifiers();
201}
202
204{
205 QEventLoop *eventLoop = QThreadData::current()->eventLoops.top();
206 Q_ASSERT(eventLoop);
207 return eventLoop;
208}
209
228bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlags flags)
229{
230 QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "processEvents");
231
232 bool eventsProcessed = false;
233
235 qCWarning(lcEventDispatcher) << "processEvents() flags" << flags << "not supported on iOS";
236
237 qCDebug(lcEventDispatcher) << "Processing events with flags" << flags;
238
239 if (m_blockedRunLoopTimer) {
240 Q_ASSERT(m_blockedRunLoopTimer == m_runLoopTimer);
241
242 qCDebug(lcEventDispatcher) << "Recursing from blocked timer" << m_blockedRunLoopTimer;
243 m_runLoopTimer = 0; // Unset current timer to force creation of new timer
244 updateTimers();
245 }
246
248 // We may be processing events recursively as a result of processing a posted event,
249 // in which case we need to signal the run-loop source so that this iteration of
250 // processEvents will take care of the newly posted events.
251 m_postedEventsRunLoopSource.signal();
253
254 qCDebug(lcEventDispatcher) << "Processed deferred wake-up";
255 }
256
257 // The documentation states that this signal is emitted after the event
258 // loop returns from a function that could block, which is not the case
259 // here, but all the other event dispatchers emit awake at the start of
260 // processEvents, and the QEventLoop auto-test has an explicit check for
261 // this behavior, so we assume it's for a good reason and do it as well.
262 emit awake();
263
264 ProcessEventsState previousState = m_processEvents;
265 m_processEvents = ProcessEventsState(flags);
266
267 bool returnAfterSingleSourceHandled = !(m_processEvents.flags & QEventLoop::EventLoopExec);
268
269 Q_FOREVER {
270 CFStringRef mode = [m_runLoopModeTracker currentMode];
271
272 CFTimeInterval duration = (m_processEvents.flags & QEventLoop::WaitForMoreEvents) ?
274
275 qCDebug(lcEventDispatcher) << "Calling CFRunLoopRunInMode =" << qPrintable(QString::fromCFString(mode))
276 << "for" << duration << "ms, processing single source =" << returnAfterSingleSourceHandled;
277
278 SInt32 result = CFRunLoopRunInMode(mode, duration, returnAfterSingleSourceHandled);
279
280 qCDebug(lcEventDispatcher) << "result =" << qPrintableResult(result);
281
282 eventsProcessed |= (result == kCFRunLoopRunHandledSource
285
286 if (result == kCFRunLoopRunFinished) {
287 // This should only happen at application shutdown, as the main runloop
288 // will presumably always have sources registered.
289 break;
290 } else if (m_processEvents.wasInterrupted) {
291
293 Q_ASSERT(result == kCFRunLoopRunStopped);
294
295 // The runloop was potentially stopped (interrupted) by us, as a response to
296 // a Qt event loop being asked to exit. We check that the topmost eventloop
297 // is still supposed to keep going and return if not. Note that the runloop
298 // might get stopped as a result of a non-top eventloop being asked to exit,
299 // in which case we continue running the top event loop until that is asked
300 // to exit, and then unwind back to the previous event loop which will break
301 // immediately, since it has already been exited.
302
303 if (!currentEventLoop()->isRunning()) {
304 qCDebug(lcEventDispatcher) << "Top level event loop was exited";
305 break;
306 } else {
307 qCDebug(lcEventDispatcher) << "Top level event loop still running, making another pass";
308 }
309 } else {
310 // We were called manually, through processEvents(), and should stop processing
311 // events, even if we didn't finish processing all the queued events.
312 qCDebug(lcEventDispatcher) << "Top level processEvents was interrupted";
313 break;
314 }
315 }
316
318 // We were called from QEventLoop's exec(), which blocks until the event
319 // loop is asked to exit by calling processEvents repeatedly. Instead of
320 // re-entering this method again and again from QEventLoop, we can block
321 // here, one lever closer to CFRunLoopRunInMode, by running the native
322 // event loop again and again until we're interrupted by QEventLoop.
323 continue;
324 } else {
325 // We were called 'manually', through processEvents()
326
327 if (result == kCFRunLoopRunHandledSource) {
328 // We processed one or more sources, but there might still be other
329 // sources that did not get a chance to process events, so we need
330 // to do another pass.
331
332 // But we should only wait for more events the first time
334 continue;
335
336 } else if (m_overdueTimerScheduled && !m_processEvents.processedTimers) {
337 // CFRunLoopRunInMode does not guarantee that a scheduled timer with a fire
338 // date in the past (overdue) will fire on the next run loop pass. The Qt
339 // APIs on the other hand document eg. zero-interval timers to always be
340 // handled after processing all available window-system events.
341 qCDebug(lcEventDispatcher) << "Manually processing timers due to overdue timer";
342 processTimers(0);
343 eventsProcessed = true;
344 }
345 }
346
347 break;
348 }
349
350 if (m_blockedRunLoopTimer) {
351 invalidateTimer();
352 m_runLoopTimer = m_blockedRunLoopTimer;
353 }
354
356 updateTimers();
357
359 m_postedEventsRunLoopSource.signal();
360 qCDebug(lcEventDispatcher) << "Processed deferred wake-up";
361 }
362
363 bool wasInterrupted = m_processEvents.wasInterrupted;
364
365 // Restore state of previous processEvents() call
366 m_processEvents = previousState;
367
368 if (wasInterrupted) {
369 // The current processEvents run has been interrupted, but there may still be
370 // others below it (eg, in the case of nested event loops). We need to trigger
371 // another interrupt so that the parent processEvents call has a chance to check
372 // if it should continue.
373 qCDebug(lcEventDispatcher) << "Forwarding interrupt in case of nested processEvents";
374 interrupt();
375 }
376
377 qCDebug(lcEventDispatcher) << "Returning with eventsProcessed =" << eventsProcessed;
378
379 return eventsProcessed;
380}
381
383{
384 QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "processPostedEvents");
385
387 qCDebug(lcEventDispatcher) << "Already processed events this pass";
388 return false;
389 }
390
392
393 qCDebug(lcEventDispatcher) << "Sending posted events for"
394 << QEventLoop::ProcessEventsFlags(m_processEvents.flags.loadRelaxed());
396
397 return true;
398}
399
400void QEventDispatcherCoreFoundation::processTimers(CFRunLoopTimerRef timer)
401{
402 QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "processTimers");
403
405 qCDebug(lcEventDispatcher) << "Already processed timers this pass";
407 return;
408 }
409
410 qCDebug(lcEventDispatcher) << "CFRunLoopTimer" << timer << "fired, activating Qt timers";
411
412 // Activating Qt timers might recurse into processEvents() if a timer-callback
413 // brings up a new event-loop or tries to processes events manually. Although
414 // a CFRunLoop can recurse inside its callbacks, a single CFRunLoopTimer can
415 // not. So, for each recursion into processEvents() from a timer-callback we
416 // need to set up a new timer-source. Instead of doing it preemtivly each
417 // time we activate Qt timers, we set a flag here, and let processEvents()
418 // decide whether or not it needs to bring up a new timer source.
419
420 // We may have multiple recused timers, so keep track of the previous blocked timer
421 CFRunLoopTimerRef previouslyBlockedRunLoopTimer = m_blockedRunLoopTimer;
422
423 m_blockedRunLoopTimer = timer;
424 m_timerInfoList.activateTimers();
425 m_blockedRunLoopTimer = previouslyBlockedRunLoopTimer;
427
428 // Now that the timer source is unblocked we may need to schedule it again
429 updateTimers();
430}
431
432Q_LOGGING_CATEGORY(lcEventDispatcherActivity, "qt.eventdispatcher.activity")
433
434void QEventDispatcherCoreFoundation::handleRunLoopActivity(CFRunLoopActivity activity)
435{
436 qCDebug(lcEventDispatcherActivity) << "Runloop entered activity" << qPrintableActivity(activity);
437
438 switch (activity) {
439 case kCFRunLoopBeforeWaiting:
440 if (m_processEvents.processedTimers
441 && !(m_processEvents.flags & QEventLoop::EventLoopExec)
442 && m_processEvents.flags & QEventLoop::WaitForMoreEvents) {
443 // CoreFoundation does not treat a timer as a reason to exit CFRunLoopRunInMode
444 // when asked to only process a single source, so we risk waiting a long time for
445 // a 'proper' source to fire (typically a system source that we don't control).
446 // To fix this we do an explicit interrupt after processing our timer, so that
447 // processEvents() gets a chance to re-evaluate the state of things.
448 interrupt();
449 }
450 emit aboutToBlock();
451 break;
452 case kCFRunLoopAfterWaiting:
453 emit awake();
454 break;
455 case kCFRunLoopEntry:
456 case kCFRunLoopBeforeTimers:
457 case kCFRunLoopBeforeSources:
458 case kCFRunLoopExit:
459 break;
460 default:
461 Q_UNREACHABLE();
462 }
463}
464
466{
468 // A manual processEvents call should only result in processing the events posted
469 // up until then. Any newly posted events as result of processing existing posted
470 // events should be handled in the next call to processEvents(). Since we're using
471 // a run-loop source to process our posted events we need to prevent it from being
472 // signaled as a result of posting new events, otherwise we end up in an infinite
473 // loop. We do however need to signal the source at some point, so that the newly
474 // posted event gets processed on the next processEvents() call, so we flag the
475 // need to do a deferred wake-up.
477 qCDebug(lcEventDispatcher) << "Already processed posted events, deferring wakeUp";
478 return;
479 }
480
481 m_postedEventsRunLoopSource.signal();
482 if (m_runLoop)
483 CFRunLoopWakeUp(m_runLoop);
484
485 qCDebug(lcEventDispatcher) << "Signaled posted event run-loop source";
486}
487
489{
490 qCDebug(lcEventDispatcher) << "Marking current processEvent as interrupted";
492 CFRunLoopStop(m_runLoop);
493}
494
495#pragma mark - Socket notifiers
496
498{
499 m_cfSocketNotifier.registerSocketNotifier(notifier);
500}
501
503{
504 m_cfSocketNotifier.unregisterSocketNotifier(notifier);
505}
506
507#pragma mark - Timers
508
509void QEventDispatcherCoreFoundation::registerTimer(Qt::TimerId timerId, Duration interval,
510 Qt::TimerType timerType, QObject *object)
511{
512 qCDebug(lcEventDispatcherTimers) << "Registering timer with id =" << int(timerId) << "interval =" << interval
513 << "type =" << timerType << "object =" << object;
514
515 Q_ASSERT(qToUnderlying(timerId) > 0 && interval.count() >= 0 && object);
516 Q_ASSERT(object->thread() == thread() && thread() == QThread::currentThread());
517
518 m_timerInfoList.registerTimer(timerId, interval, timerType, object);
519 updateTimers();
520}
521
523{
524 Q_ASSERT(qToUnderlying(timerId) > 0);
526
527 bool returnValue = m_timerInfoList.unregisterTimer(timerId);
528
529 qCDebug(lcEventDispatcherTimers) << "Unegistered timer with id =" << qToUnderlying(timerId)
530 << "Timers left:" << m_timerInfoList.size();
531
532 updateTimers();
533 return returnValue;
534}
535
537{
538 Q_ASSERT(object && object->thread() == thread() && thread() == QThread::currentThread());
539
540 bool returnValue = m_timerInfoList.unregisterTimers(object);
541
542 qCDebug(lcEventDispatcherTimers) << "Unegistered timers for object =" << object << "Timers left:" << m_timerInfoList.size();
543
544 updateTimers();
545 return returnValue;
546}
547
548QList<QAbstractEventDispatcher::TimerInfoV2>
550{
551 Q_ASSERT(object);
552 return m_timerInfoList.registeredTimers(object);
553}
554
557{
558 Q_ASSERT(qToUnderlying(timerId) > 0);
559 return m_timerInfoList.remainingDuration(timerId);
560}
561
562void QEventDispatcherCoreFoundation::updateTimers()
563{
564 if (m_timerInfoList.size() > 0) {
565 // We have Qt timers registered, so create or reschedule CF timer to match
566
567 using namespace std::chrono_literals;
568 using DoubleSeconds = std::chrono::duration<double, std::ratio<1>>;
569
570 CFAbsoluteTime timeToFire;
571 auto opt = m_timerInfoList.timerWait();
572 DoubleSeconds secs{};
573 if (opt) {
574 // We have a timer ready to fire right now, or some time in the future
575 secs = DoubleSeconds{*opt};
576 timeToFire = CFAbsoluteTimeGetCurrent() + secs.count();
577 } else {
578 // We have timers, but they are all currently blocked by callbacks
579 timeToFire = kCFTimeIntervalDistantFuture;
580 }
581
582 if (!m_runLoopTimer) {
583 m_runLoopTimer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault,
584 timeToFire, kCFTimeIntervalDistantFuture, 0, 0, ^(CFRunLoopTimerRef timer) {
585 processTimers(timer);
586 });
587
588 CFRunLoopAddTimer(m_runLoop, m_runLoopTimer, kCFRunLoopCommonModes);
589 qCDebug(lcEventDispatcherTimers) << "Created new CFRunLoopTimer" << m_runLoopTimer;
590
591 } else {
592 CFRunLoopTimerSetNextFireDate(m_runLoopTimer, timeToFire);
593 qCDebug(lcEventDispatcherTimers) << "Re-scheduled CFRunLoopTimer" << m_runLoopTimer;
594 }
595
596 m_overdueTimerScheduled = secs > 0s;
597
598 qCDebug(lcEventDispatcherTimers) << "Next timeout in" << secs;
599
600 } else {
601 // No Qt timers are registered, so make sure we're not running any CF timers
602 invalidateTimer();
603
604 m_overdueTimerScheduled = false;
605 }
606}
607
608void QEventDispatcherCoreFoundation::invalidateTimer()
609{
610 if (!m_runLoopTimer || (m_runLoopTimer == m_blockedRunLoopTimer))
611 return;
612
613 CFRunLoopTimerInvalidate(m_runLoopTimer);
614 qCDebug(lcEventDispatcherTimers) << "Invalidated CFRunLoopTimer" << m_runLoopTimer;
615
616 CFRelease(m_runLoopTimer);
617 m_runLoopTimer = 0;
618}
619
621
622#include "qeventdispatcher_cf.moc"
623#include "moc_qeventdispatcher_cf_p.cpp"
DarwinBluetooth::LECBManagerNotifier * notifier
std::chrono::nanoseconds Duration
A {std::chrono::duration} type that is used in various API in this class.
void awake()
This signal is emitted after the event loop returns from a function that could block.
T loadRelaxed() const noexcept
void unregisterSocketNotifier(QSocketNotifier *notifier)
void registerSocketNotifier(QSocketNotifier *notifier)
void setHostEventDispatcher(QAbstractEventDispatcher *hostEventDispacher)
static QCFType constructFromGet(const T &t)
\inmodule QtCore
static void sendPostedEvents(QObject *receiver=nullptr, int event_type=0)
Immediately dispatches all events which have been previously queued with QCoreApplication::postEvent(...
\inmodule QtCore
void interrupt() override
Interrupts event dispatching.
virtual bool processPostedEvents()
void registerTimer(Qt::TimerId timerId, Duration interval, Qt::TimerType timerType, QObject *object) override final
void registerSocketNotifier(QSocketNotifier *notifier) override
Registers notifier with the event loop.
bool processEvents(QEventLoop::ProcessEventsFlags flags) override
Processes pending events that match flags until there are no more events to process.
void wakeUp() override
\threadsafe
QEventDispatcherCoreFoundation(QObject *parent=nullptr)
QList< TimerInfoV2 > timersForObject(QObject *object) const override final
bool unregisterTimer(Qt::TimerId timerId) override final
void unregisterSocketNotifier(QSocketNotifier *notifier) override
Unregisters notifier from the event dispatcher.
QEventLoop * currentEventLoop() const
Duration remainingTime(Qt::TimerId timerId) const override final
Returns the remaining time of the timer with the given timerId.
bool unregisterTimers(QObject *object) override final
Unregisters all the timers associated with the given object.
\inmodule QtCore
Definition qeventloop.h:16
@ ExcludeSocketNotifiers
Definition qeventloop.h:28
@ WaitForMoreEvents
Definition qeventloop.h:29
@ ExcludeUserInputEvents
Definition qeventloop.h:27
\inmodule QtCore
Definition qobject.h:103
QThread * thread() const
Returns the thread in which the object lives.
Definition qobject.cpp:1598
\inmodule QtCore
static Q_AUTOTEST_EXPORT QThreadData * current(bool createIfNecessary=true)
Definition qthread.cpp:1087
static QThread * currentThread()
Definition qthread.cpp:1039
bool unregisterTimer(Qt::TimerId timerId)
qsizetype size() const
Duration remainingDuration(Qt::TimerId timerId) const
bool unregisterTimers(QObject *object)
std::optional< Duration > timerWait()
void registerTimer(Qt::TimerId timerId, Duration interval, Qt::TimerType timerType, QObject *object)
QList< TimerInfo > registeredTimers(QObject *object) const
void addToMode(CFStringRef mode, CFRunLoopRef runLoop=0)
void addToMode(CFStringRef mode, CFRunLoopRef runLoop=0)
#define this
Definition dialogs.cpp:9
QStyleOptionButton opt
Combined button and popup list for selecting options.
\macro QT_NO_KEYWORDS >
TimerType
QTextStream & reset(QTextStream &stream)
Calls QTextStream::reset() on stream and returns stream.
QString self
Definition language.cpp:58
bool qt_apple_isApplicationExtension()
Definition qcore_mac.mm:424
#define QT_APPLE_SCOPED_LOG_ACTIVITY(...)
#define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__)
Definition qcore_mac_p.h:58
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
#define Q_ENUM_PRINTER(enumName)
static const CFTimeInterval kCFTimeIntervalMinimum
QStack< CFStringRef > m_runLoopModes
static const CFTimeInterval kCFTimeIntervalDistantFuture
QDebug operator<<(QDebug s, timespec tv)
#define Q_FOREVER
Definition qforeach.h:70
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
GLenum mode
GLuint64 key
GLenum GLenum GLsizei count
GLuint object
[3]
GLbitfield flags
GLdouble s
[6]
Definition qopenglext.h:235
GLuint in
GLuint64EXT * result
[6]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define qPrintable(string)
Definition qstring.h:1531
static bool isRunning()
Definition main.cpp:452
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
QTextStreamManipulator qSetPadChar(QChar ch)
QTextStreamManipulator qSetFieldWidth(int width)
#define Q_OBJECT
#define Q_ENUMS(x)
#define emit
QT_BEGIN_NAMESPACE constexpr std::underlying_type_t< Enum > qToUnderlying(Enum e) noexcept
QFuture< QSet< QString > > dictionary
QTimer * timer
[3]