Qt 6.x
The Qt SDK
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
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 qDeleteAll(m_timerInfoList);
199
200 m_cfSocketNotifier.removeSocketNotifiers();
201}
202
204{
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(int timerId, qint64 interval, Qt::TimerType timerType, QObject *object)
510{
511 qCDebug(lcEventDispatcherTimers) << "Registering timer with id =" << timerId << "interval =" << interval
512 << "type =" << timerType << "object =" << object;
513
514 Q_ASSERT(timerId > 0 && interval >= 0 && object);
515 Q_ASSERT(object->thread() == thread() && thread() == QThread::currentThread());
516
517 m_timerInfoList.registerTimer(timerId, interval, timerType, object);
518 updateTimers();
519}
520
522{
523 Q_ASSERT(timerId > 0);
525
526 bool returnValue = m_timerInfoList.unregisterTimer(timerId);
527
528 qCDebug(lcEventDispatcherTimers) << "Unegistered timer with id =" << timerId << "Timers left:" << m_timerInfoList.size();
529
530 updateTimers();
531 return returnValue;
532}
533
535{
536 Q_ASSERT(object && object->thread() == thread() && thread() == QThread::currentThread());
537
538 bool returnValue = m_timerInfoList.unregisterTimers(object);
539
540 qCDebug(lcEventDispatcherTimers) << "Unegistered timers for object =" << object << "Timers left:" << m_timerInfoList.size();
541
542 updateTimers();
543 return returnValue;
544}
545
547{
548 Q_ASSERT(object);
549 return m_timerInfoList.registeredTimers(object);
550}
551
553{
554 Q_ASSERT(timerId > 0);
555 return m_timerInfoList.timerRemainingTime(timerId);
556}
557
558static double timespecToSeconds(const timespec &spec)
559{
560 static double nanosecondsPerSecond = 1.0 * 1000 * 1000 * 1000;
561 return spec.tv_sec + (spec.tv_nsec / nanosecondsPerSecond);
562}
563
564void QEventDispatcherCoreFoundation::updateTimers()
565{
566 if (m_timerInfoList.size() > 0) {
567 // We have Qt timers registered, so create or reschedule CF timer to match
568
569 timespec tv = { -1, -1 };
570 CFAbsoluteTime timeToFire = m_timerInfoList.timerWait(tv) ?
571 // We have a timer ready to fire right now, or some time in the future
572 CFAbsoluteTimeGetCurrent() + timespecToSeconds(tv)
573 // We have timers, but they are all currently blocked by callbacks
574 : kCFTimeIntervalDistantFuture;
575
576 if (!m_runLoopTimer) {
577 m_runLoopTimer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault,
578 timeToFire, kCFTimeIntervalDistantFuture, 0, 0, ^(CFRunLoopTimerRef timer) {
579 processTimers(timer);
580 });
581
582 CFRunLoopAddTimer(m_runLoop, m_runLoopTimer, kCFRunLoopCommonModes);
583 qCDebug(lcEventDispatcherTimers) << "Created new CFRunLoopTimer" << m_runLoopTimer;
584
585 } else {
586 CFRunLoopTimerSetNextFireDate(m_runLoopTimer, timeToFire);
587 qCDebug(lcEventDispatcherTimers) << "Re-scheduled CFRunLoopTimer" << m_runLoopTimer;
588 }
589
590 m_overdueTimerScheduled = !timespecToSeconds(tv);
591
592 qCDebug(lcEventDispatcherTimers) << "Next timeout in" << tv << "seconds";
593
594 } else {
595 // No Qt timers are registered, so make sure we're not running any CF timers
596 invalidateTimer();
597
598 m_overdueTimerScheduled = false;
599 }
600}
601
602void QEventDispatcherCoreFoundation::invalidateTimer()
603{
604 if (!m_runLoopTimer || (m_runLoopTimer == m_blockedRunLoopTimer))
605 return;
606
607 CFRunLoopTimerInvalidate(m_runLoopTimer);
608 qCDebug(lcEventDispatcherTimers) << "Invalidated CFRunLoopTimer" << m_runLoopTimer;
609
610 CFRelease(m_runLoopTimer);
611 m_runLoopTimer = 0;
612}
613
615
616#include "qeventdispatcher_cf.moc"
617#include "moc_qeventdispatcher_cf_p.cpp"
DarwinBluetooth::LECBManagerNotifier * notifier
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
Definition qchar.h:48
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()
QList< QAbstractEventDispatcher::TimerInfo > registeredTimers(QObject *object) const override
Returns a list of registered timers for object.
void registerTimer(int timerId, qint64 interval, Qt::TimerType timerType, QObject *object) override
Register a timer with the specified timerId, interval, and timerType for the given object.
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
bool unregisterTimers(QObject *object) override
Unregisters all the timers associated with the given object.
QEventDispatcherCoreFoundation(QObject *parent=nullptr)
void unregisterSocketNotifier(QSocketNotifier *notifier) override
Unregisters notifier from the event dispatcher.
bool unregisterTimer(int timerId) override
Unregisters the timer with the given timerId.
QEventLoop * currentEventLoop() const
int remainingTime(int timerId) override
Returns the remaining time in milliseconds with the given timerId.
\inmodule QtCore
Definition qeventloop.h:16
@ ExcludeSocketNotifiers
Definition qeventloop.h:28
@ WaitForMoreEvents
Definition qeventloop.h:29
@ ExcludeUserInputEvents
Definition qeventloop.h:27
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
\inmodule QtCore
Definition qobject.h:90
QThread * thread() const
Returns the thread in which the object lives.
Definition qobject.cpp:1561
\inmodule QtCore
\inmodule QtCore
Definition qstack.h:13
T & top()
Returns a reference to the stack's top item.
Definition qstack.h:19
static Q_AUTOTEST_EXPORT QThreadData * current(bool createIfNecessary=true)
Definition qthread.cpp:1005
QStack< QEventLoop * > eventLoops
Definition qthread_p.h:320
static QThread * currentThread()
Definition qthread.cpp:966
bool timerWait(timespec &)
qint64 timerRemainingTime(int timerId)
bool unregisterTimers(QObject *object)
void registerTimer(int timerId, qint64 interval, Qt::TimerType timerType, QObject *object)
QList< QAbstractEventDispatcher::TimerInfo > registeredTimers(QObject *object) const
bool unregisterTimer(int timerId)
void addToMode(CFStringRef mode, CFRunLoopRef runLoop=0)
void addToMode(CFStringRef mode, CFRunLoopRef runLoop=0)
#define this
Definition dialogs.cpp:9
qDeleteAll(list.begin(), list.end())
Combined button and popup list for selecting options.
\macro QT_NAMESPACE
TimerType
QTextStream & reset(QTextStream &stream)
Calls QTextStream::reset() on stream and returns stream.
QString self
Definition language.cpp:57
bool qt_apple_isApplicationExtension()
Definition qcore_mac.mm:423
#define QT_APPLE_SCOPED_LOG_ACTIVITY(...)
#define QT_NAMESPACE_ALIAS_OBJC_CLASS(__KLASS__)
Definition qcore_mac_p.h:57
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
GLuint object
[3]
GLbitfield flags
GLuint in
GLuint64EXT * result
[6]
GLdouble s
[6]
Definition qopenglext.h:235
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define qPrintable(string)
Definition qstring.h:1391
static bool isRunning()
Definition main.cpp:358
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
long long qint64
Definition qtypes.h:55
QFuture< QSet< QString > > dictionary
QTimer * timer
[3]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent