diff options
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qcore_mac_objc.mm | 15 | ||||
-rw-r--r-- | src/corelib/kernel/qcore_mac_p.h | 130 | ||||
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qdeadlinetimer.cpp | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qdeadlinetimer.h | 5 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_cf.mm | 35 | ||||
-rw-r--r-- | src/corelib/kernel/qmetatype.cpp | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qtimer.cpp | 42 | ||||
-rw-r--r-- | src/corelib/kernel/qtimer.h | 13 | ||||
-rw-r--r-- | src/corelib/kernel/qvariant.h | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qwineventnotifier.cpp | 7 |
11 files changed, 224 insertions, 30 deletions
diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 24d73fa8be..b91b5e76be 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -87,19 +87,20 @@ QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(QT_DECLARE_WEAK_QDEBUG_OPERATOR_FOR_CF_TY QT_END_NAMESPACE QT_USE_NAMESPACE @interface QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker) : NSObject -{ +@end + +@implementation QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker) { NSAutoreleasePool **m_pool; } --(id)initWithPool:(NSAutoreleasePool**)pool; -@end -@implementation QT_MANGLE_NAMESPACE(QMacAutoReleasePoolTracker) --(id)initWithPool:(NSAutoreleasePool**)pool + +- (instancetype)initWithPool:(NSAutoreleasePool **)pool { - if (self = [super init]) + if ((self = [self init])) m_pool = pool; return self; } --(void)dealloc + +- (void)dealloc { if (*m_pool) { // The pool is still valid, which means we're not being drained from diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index 9c6cef68b2..e8aa24b944 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -51,18 +51,50 @@ // We mean it. // +#include "private/qglobal_p.h" + #ifndef __IMAGECAPTURE__ # define __IMAGECAPTURE__ #endif +// -------------------------------------------------------------------------- + +#if !defined(QT_BOOTSTRAPPED) && (QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_12) || !defined(Q_OS_MACOS)) +#define QT_USE_APPLE_ACTIVITIES + +#if defined(OS_ACTIVITY_OBJECT_API) +#error The file <os/activity.h> has already been included +#endif + +// We runtime-check all use of the activity APIs, so we can safely build +// with them included, even if the deployment target is macOS 10.11 +#if QT_MACOS_DEPLOYMENT_TARGET_BELOW(__MAC_10_12) +#undef __MAC_OS_X_VERSION_MIN_REQUIRED +#define __MAC_OS_X_VERSION_MIN_REQUIRED __MAC_10_12 +#define DID_OVERRIDE_DEPLOYMENT_TARGET +#endif + +#include <os/activity.h> +#if !OS_ACTIVITY_OBJECT_API +#error "Expected activity API to be available" +#endif + +#if defined(DID_OVERRIDE_DEPLOYMENT_TARGET) +#undef __MAC_OS_X_VERSION_MIN_REQUIRED +#define __MAC_OS_X_VERSION_MIN_REQUIRED __MAC_10_11 +#undef DID_OVERRIDE_DEPLOYMENT_TARGET +#endif + +#endif + +// -------------------------------------------------------------------------- + #if defined(QT_BOOTSTRAPPED) #include <ApplicationServices/ApplicationServices.h> #else #include <CoreFoundation/CoreFoundation.h> #endif -#include "private/qglobal_p.h" - #ifdef __OBJC__ #include <Foundation/Foundation.h> #endif @@ -190,6 +222,100 @@ private: // -------------------------------------------------------------------------- +#if defined(QT_USE_APPLE_ACTIVITIES) + +QT_END_NAMESPACE +#include <os/availability.h> +#define OS_ACTIVITY_AVAILABILITY API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) +#define OS_ACTIVITY_AVAILABILITY_CHECK __builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *) +QT_BEGIN_NAMESPACE + +template <typename T> using QAppleOsType = QAppleRefCounted<T, void *, os_retain, os_release>; + +class Q_CORE_EXPORT QAppleLogActivity +{ +public: + QAppleLogActivity() : activity(nullptr) {} + QAppleLogActivity(os_activity_t activity) OS_ACTIVITY_AVAILABILITY : activity(activity) {} + ~QAppleLogActivity() { if (activity) leave(); } + + QAppleLogActivity(const QAppleLogActivity &) = delete; + QAppleLogActivity& operator=(const QAppleLogActivity &) = delete; + + QAppleLogActivity(QAppleLogActivity&& other) + : activity(other.activity), state(other.state) { other.activity = nullptr; } + + QAppleLogActivity& operator=(QAppleLogActivity &&other) + { + if (this != &other) { + activity = other.activity; + state = other.state; + other.activity = nullptr; + } + return *this; + } + + QAppleLogActivity&& enter() + { + if (activity) { + if (OS_ACTIVITY_AVAILABILITY_CHECK) + os_activity_scope_enter(static_cast<os_activity_t>(*this), &state); + } + return std::move(*this); + } + + void leave() { + if (activity) { + if (OS_ACTIVITY_AVAILABILITY_CHECK) + os_activity_scope_leave(&state); + } + } + + operator os_activity_t() OS_ACTIVITY_AVAILABILITY + { + return reinterpret_cast<os_activity_t>(static_cast<void *>(activity)); + } + +private: + // Work around API_AVAILABLE not working for templates by using void* + QAppleOsType<void *> activity; + os_activity_scope_state_s state; +}; + +#define QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, parent) []() { \ + if (!(condition)) \ + return QAppleLogActivity(); \ + if (OS_ACTIVITY_AVAILABILITY_CHECK) \ + return QAppleLogActivity(os_activity_create(description, parent, OS_ACTIVITY_FLAG_DEFAULT)); \ + return QAppleLogActivity(); \ + }() + +#define QT_VA_ARGS_CHOOSE(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N +#define QT_VA_ARGS_COUNT(...) QT_VA_ARGS_CHOOSE(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1) + +#define QT_OVERLOADED_MACRO(MACRO, ...) _QT_OVERLOADED_MACRO(MACRO, QT_VA_ARGS_COUNT(__VA_ARGS__))(__VA_ARGS__) +#define _QT_OVERLOADED_MACRO(MACRO, ARGC) _QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC) +#define _QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC) MACRO##ARGC + +#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT3(condition, description, parent) QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, parent) +#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT2(description, parent) QT_APPLE_LOG_ACTIVITY_WITH_PARENT3(true, description, parent) +#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY_WITH_PARENT, __VA_ARGS__) + +#define QT_APPLE_LOG_ACTIVITY2(condition, description) QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, OS_ACTIVITY_CURRENT) +#define QT_APPLE_LOG_ACTIVITY1(description) QT_APPLE_LOG_ACTIVITY2(true, description) +#define QT_APPLE_LOG_ACTIVITY(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY, __VA_ARGS__) + +#define QT_APPLE_SCOPED_LOG_ACTIVITY(...) QAppleLogActivity scopedLogActivity = QT_APPLE_LOG_ACTIVITY(__VA_ARGS__).enter(); + +#else +// No-ops for macOS 10.11. We don't need to provide QT_APPLE_SCOPED_LOG_ACTIVITY, +// as all the call sites for that are in code that's only built on 10.12 and above. +#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT(...) +#define QT_APPLE_LOG_ACTIVITY(...) +#endif // QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE + +// ------------------------------------------------------------------------- + QT_END_NAMESPACE #endif // QCORE_MAC_P_H diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 4e32f90964..e0ae350f32 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1889,7 +1889,7 @@ bool QCoreApplication::event(QEvent *e) \value UnicodeUTF8 UTF-8. \omitvalue Latin1 - \omitvalue DefaultCodec UTF-8. + \omitvalue DefaultCodec \omit UTF-8. \endomit \omitvalue CodecForTr \sa QObject::tr(), QString::fromUtf8() diff --git a/src/corelib/kernel/qdeadlinetimer.cpp b/src/corelib/kernel/qdeadlinetimer.cpp index d8a670310b..97b98a1376 100644 --- a/src/corelib/kernel/qdeadlinetimer.cpp +++ b/src/corelib/kernel/qdeadlinetimer.cpp @@ -39,7 +39,6 @@ #include "qdeadlinetimer.h" #include "qdeadlinetimer_p.h" -#include <qpair.h> QT_BEGIN_NAMESPACE diff --git a/src/corelib/kernel/qdeadlinetimer.h b/src/corelib/kernel/qdeadlinetimer.h index 6c10e1025e..1a4ee04a96 100644 --- a/src/corelib/kernel/qdeadlinetimer.h +++ b/src/corelib/kernel/qdeadlinetimer.h @@ -43,6 +43,7 @@ #include <QtCore/qelapsedtimer.h> #include <QtCore/qmetatype.h> #include <QtCore/qnamespace.h> +#include <QtCore/qpair.h> #ifdef max // un-pollute the namespace. We need std::numeric_limits::max() and std::chrono::duration::max() @@ -186,6 +187,10 @@ private: unsigned type; qint64 rawRemainingTimeNSecs() const Q_DECL_NOTHROW; + +public: + // This is not a public function, it's here only for Qt's internal convenience... + QPair<qint64, unsigned> _q_data() const { return qMakePair(t1, t2); } }; Q_DECLARE_SHARED(QDeadlineTimer) diff --git a/src/corelib/kernel/qeventdispatcher_cf.mm b/src/corelib/kernel/qeventdispatcher_cf.mm index 8499b3fd57..d670e297c0 100644 --- a/src/corelib/kernel/qeventdispatcher_cf.mm +++ b/src/corelib/kernel/qeventdispatcher_cf.mm @@ -58,18 +58,18 @@ QT_USE_NAMESPACE -@interface QT_MANGLE_NAMESPACE(RunLoopModeTracker) : NSObject { - QStack<CFStringRef> m_runLoopModes; -} +@interface QT_MANGLE_NAMESPACE(RunLoopModeTracker) : NSObject @end QT_NAMESPACE_ALIAS_OBJC_CLASS(RunLoopModeTracker); -@implementation RunLoopModeTracker +@implementation RunLoopModeTracker { + QStack<CFStringRef> m_runLoopModes; +} -- (id) init +- (instancetype)init { - if (self = [super init]) { + if ((self = [super init])) { m_runLoopModes.push(kCFRunLoopDefaultMode); [[NSNotificationCenter defaultCenter] @@ -77,21 +77,21 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(RunLoopModeTracker); selector:@selector(receivedNotification:) name:nil #ifdef Q_OS_OSX - object:[NSApplication sharedApplication]]; + object:NSApplication.sharedApplication]; #elif defined(Q_OS_WATCHOS) - object:[WKExtension sharedExtension]]; + object:WKExtension.sharedExtension]; #else // Use performSelector so this can work in an App Extension - object:[[UIApplication class] performSelector:@selector(sharedApplication)]]; + object:[UIApplication.class performSelector:@selector(sharedApplication)]]; #endif } return self; } -- (void) dealloc +- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [NSNotificationCenter.defaultCenter removeObserver:self]; [super dealloc]; } @@ -100,13 +100,13 @@ static CFStringRef runLoopMode(NSDictionary *dictionary) { for (NSString *key in dictionary) { if (CFStringHasSuffix((CFStringRef)key, CFSTR("RunLoopMode"))) - return (CFStringRef)[dictionary objectForKey: key]; + return (CFStringRef)dictionary[key]; } return nil; } -- (void) receivedNotification:(NSNotification *) notification +- (void)receivedNotification:(NSNotification *)notification { if (CFStringHasSuffix((CFStringRef)notification.name, CFSTR("RunLoopModePushNotification"))) { if (CFStringRef mode = runLoopMode(notification.userInfo)) @@ -116,7 +116,7 @@ static CFStringRef runLoopMode(NSDictionary *dictionary) } else if (CFStringHasSuffix((CFStringRef)notification.name, CFSTR("RunLoopModePopNotification"))) { CFStringRef mode = runLoopMode(notification.userInfo); - if (CFStringCompare(mode, [self currentMode], 0) == kCFCompareEqualTo) + if (CFStringCompare(mode, self.currentMode, 0) == kCFCompareEqualTo) m_runLoopModes.pop(); else qCWarning(lcEventDispatcher) << "Tried to pop run loop mode" @@ -126,7 +126,7 @@ static CFStringRef runLoopMode(NSDictionary *dictionary) } } -- (CFStringRef) currentMode +- (CFStringRef)currentMode { return m_runLoopModes.top(); } @@ -238,6 +238,7 @@ QEventLoop *QEventDispatcherCoreFoundation::currentEventLoop() const */ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlags flags) { + QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "processEvents"); bool eventsProcessed = false; if (flags & (QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers)) @@ -390,6 +391,8 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag bool QEventDispatcherCoreFoundation::processPostedEvents() { + QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "processPostedEvents"); + if (m_processEvents.processedPostedEvents && !(m_processEvents.flags & QEventLoop::EventLoopExec)) { qCDebug(lcEventDispatcher) << "Already processed events this pass"; return false; @@ -405,6 +408,8 @@ bool QEventDispatcherCoreFoundation::processPostedEvents() void QEventDispatcherCoreFoundation::processTimers(CFRunLoopTimerRef timer) { + QT_APPLE_SCOPED_LOG_ACTIVITY(lcEventDispatcher().isDebugEnabled(), "processTimers"); + if (m_processEvents.processedTimers && !(m_processEvents.flags & QEventLoop::EventLoopExec)) { qCDebug(lcEventDispatcher) << "Already processed timers this pass"; m_processEvents.deferredUpdateTimers = true; diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index fc40668c9a..0e57cb8cba 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -316,7 +316,7 @@ struct DefinedTypesFilter { \omitvalue WeakPointerToQObject \omitvalue TrackingPointerToQObject \omitvalue WasDeclaredAsMetaType - \omitvalue IsGadget This type is a Q_GADGET and it's corresponding QMetaObject can be accessed with QMetaType::metaObject Since 5.5. + \omitvalue IsGadget \omit This type is a Q_GADGET and it's corresponding QMetaObject can be accessed with QMetaType::metaObject Since 5.5. \endomit \omitvalue PointerToGadget */ diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index c3504943c4..802c8d72f6 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -571,6 +571,48 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv */ /*! + \fn template<typename Functor> QMetaObject::Connection connectTo(Functor functor, Qt::ConnectionType connectionType = Qt::AutoConnection) + \since 5.12 + \overload + + Creates a connection from the timeout() signal to \a functor, and returns a + handle to the connection. + + This method is provided for convenience. + It's equivalent to calling \c {QObject::connect(timer, &QTimer::timeout, timer, functor, connectionType)}. + + \sa QObject::connect(), timeout() +*/ + +/*! + \fn template<typename Functor> QMetaObject::Connection connectTo(QObject *context, Functor functor, Qt::ConnectionType connectionType = Qt::AutoConnection) + \since 5.12 + \overload connectTo() + + Creates a connection from the timeout() signal to \a functor to be placed in a specific + event loop of \a context, and returns a handle to the connection. + + This method is provided for convenience. It's equivalent to calling + \c {QObject::connect(timer, &QTimer::timeout, context, functor, connectionType)}. + + \sa QObject::connect(), timeout() +*/ + +/*! + \fn template<typename PointerToMemberFunction> QMetaObject::Connection connectTo(QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType connectionType = Qt::AutoConnection) + \since 5.12 + \overload connectTo() + + Creates a connection from the timeout() signal to the \a method in the \a receiver object. Returns + a handle to the connection. + + This method is provided for convenience. It's equivalent to calling + \c {QObject::connect(timer, &QTimer::timeout, receiver, method, connectionType)}. + + \sa QObject::connect(), timeout() +*/ + +/*! \fn void QTimer::start(std::chrono::milliseconds msec) \since 5.8 \overload diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h index e6db586aa0..7825bb0798 100644 --- a/src/corelib/kernel/qtimer.h +++ b/src/corelib/kernel/qtimer.h @@ -96,6 +96,12 @@ public: static void singleShot(int msec, const QObject *context, Functor functor); template<typename Functor, int> static void singleShot(int msec, Qt::TimerType timerType, const QObject *context, Functor functor); + template <typename Functor> + QMetaObject::Connection connectTo(Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection); + template <typename Functor> + QMetaObject::Connection connectTo(const QObject *context, Functor slot, Qt::ConnectionType connectionType = Qt::AutoConnection); + template <typename PointerToMemberFunction> + QMetaObject::Connection connectTo(const QObject *receiver, PointerToMemberFunction slot, Qt::ConnectionType connectionType = Qt::AutoConnection); #else // singleShot to a QObject slot template <typename Duration, typename Func1> @@ -152,6 +158,13 @@ public: new QtPrivate::QFunctorSlotObject<Func1, 0, typename QtPrivate::List_Left<void, 0>::Value, void>(std::move(slot))); } + + template <typename ... Args> + QMetaObject::Connection connectTo(Args && ...args) + { + return QObject::connect(this, &QTimer::timeout, std::forward<Args>(args)... ); + } + #endif public Q_SLOTS: diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index 9a5fc63d03..ff73c27b6e 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -633,6 +633,7 @@ public: const_iterator &operator-=(int j); const_iterator operator+(int j) const; const_iterator operator-(int j) const; + friend inline const_iterator operator+(int j, const_iterator k) { return k + j; } }; friend struct const_iterator; @@ -690,6 +691,7 @@ public: const_iterator &operator-=(int j); const_iterator operator+(int j) const; const_iterator operator-(int j) const; + friend inline const_iterator operator+(int j, const_iterator k) { return k + j; } }; friend struct const_iterator; diff --git a/src/corelib/kernel/qwineventnotifier.cpp b/src/corelib/kernel/qwineventnotifier.cpp index 24de491326..85d4ad4fa9 100644 --- a/src/corelib/kernel/qwineventnotifier.cpp +++ b/src/corelib/kernel/qwineventnotifier.cpp @@ -157,7 +157,6 @@ void QWinEventNotifier::setHandle(HANDLE hEvent) Q_D(QWinEventNotifier); setEnabled(false); d->handleToEvent = hEvent; - d->signaledCount = 0; } /*! @@ -209,10 +208,12 @@ void QWinEventNotifier::setEnabled(bool enable) return; } - if (enable) + if (enable) { + d->signaledCount = 0; eventDispatcher->registerEventNotifier(this); - else + } else { eventDispatcher->unregisterEventNotifier(this); + } } /*! |