diff options
Diffstat (limited to 'src/corelib/kernel/qcore_mac_p.h')
-rw-r--r-- | src/corelib/kernel/qcore_mac_p.h | 71 |
1 files changed, 63 insertions, 8 deletions
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index 920105ee9e..0e1a5fe345 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -67,6 +67,7 @@ #ifdef __OBJC__ #include <Foundation/Foundation.h> +#include <functional> #endif #include "qstring.h" @@ -295,13 +296,13 @@ QT_MAC_WEAK_IMPORT(_os_activity_current); // ------------------------------------------------------------------------- #if defined( __OBJC__) -class QMacScopedObserver +class QMacNotificationObserver { public: - QMacScopedObserver() {} + QMacNotificationObserver() {} template<typename Functor> - QMacScopedObserver(id object, NSNotificationName name, Functor callback) { + QMacNotificationObserver(id object, NSNotificationName name, Functor callback) { observer = [[NSNotificationCenter defaultCenter] addObserverForName:name object:object queue:nil usingBlock:^(NSNotification *) { callback(); @@ -309,13 +310,13 @@ public: ]; } - QMacScopedObserver(const QMacScopedObserver& other) = delete; - QMacScopedObserver(QMacScopedObserver&& other) : observer(other.observer) { + QMacNotificationObserver(const QMacNotificationObserver& other) = delete; + QMacNotificationObserver(QMacNotificationObserver&& other) : observer(other.observer) { other.observer = nil; } - QMacScopedObserver &operator=(const QMacScopedObserver& other) = delete; - QMacScopedObserver &operator=(QMacScopedObserver&& other) { + QMacNotificationObserver &operator=(const QMacNotificationObserver& other) = delete; + QMacNotificationObserver &operator=(QMacNotificationObserver&& other) { if (this != &other) { remove(); observer = other.observer; @@ -329,11 +330,65 @@ public: [[NSNotificationCenter defaultCenter] removeObserver:observer]; observer = nil; } - ~QMacScopedObserver() { remove(); } + ~QMacNotificationObserver() { remove(); } private: id observer = nil; }; + +QT_END_NAMESPACE +@interface QT_MANGLE_NAMESPACE(KeyValueObserver) : NSObject +@end +QT_NAMESPACE_ALIAS_OBJC_CLASS(KeyValueObserver); +QT_BEGIN_NAMESPACE + +class Q_CORE_EXPORT QMacKeyValueObserver +{ +public: + using Callback = std::function<void()>; + + QMacKeyValueObserver() {} + + // Note: QMacKeyValueObserver must not outlive the object observed! + QMacKeyValueObserver(id object, NSString *keyPath, Callback callback) + : object(object), keyPath(keyPath), callback(new Callback(callback)) { addObserver(); } + + QMacKeyValueObserver(const QMacKeyValueObserver &other) + : QMacKeyValueObserver(other.object, other.keyPath, *other.callback.get()) {} + + QMacKeyValueObserver(QMacKeyValueObserver &&other) { swap(other, *this); } + + ~QMacKeyValueObserver() { removeObserver(); } + + QMacKeyValueObserver &operator=(const QMacKeyValueObserver &other) { + QMacKeyValueObserver tmp(other); + swap(tmp, *this); + return *this; + } + + QMacKeyValueObserver &operator=(QMacKeyValueObserver &&other) { + QMacKeyValueObserver tmp(std::move(other)); + swap(tmp, *this); + return *this; + } + + void removeObserver(); + +private: + void swap(QMacKeyValueObserver &first, QMacKeyValueObserver &second) { + std::swap(first.object, second.object); + std::swap(first.keyPath, second.keyPath); + std::swap(first.callback, second.callback); + } + + void addObserver(); + + id object = nil; + NSString *keyPath = nullptr; + std::unique_ptr<Callback> callback; + + static KeyValueObserver *observer; +}; #endif // ------------------------------------------------------------------------- |