From 2dfe0f8f6854f518e8ffb23e17cc99400355cc3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 29 May 2019 17:00:40 +0200 Subject: macOS: Introduce QMacKeyValueObserver and use in theme and style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I2d21c883628933543ae5a66b694ff7503119bc4a Reviewed-by: Tor Arne Vestbø --- src/corelib/kernel/qcore_mac_objc.mm | 31 ++++++++++++++++++++ src/corelib/kernel/qcore_mac_p.h | 55 ++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index 4550891e2a..9139b372a8 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -514,5 +514,36 @@ Q_CONSTRUCTOR_FUNCTION(qt_apple_check_os_version); // ------------------------------------------------------------------------- +void QMacKeyValueObserver::addObserver() +{ + [object addObserver:observer forKeyPath:keyPath + options:NSKeyValueObservingOptionNew context:callback.get()]; +} + +void QMacKeyValueObserver::removeObserver() { + if (object) + [object removeObserver:observer forKeyPath:keyPath context:callback.get()]; + object = nil; +} + +KeyValueObserver *QMacKeyValueObserver::observer = [[KeyValueObserver alloc] init]; + +QT_END_NAMESPACE +@implementation KeyValueObserver +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object + change:(NSDictionary *)change context:(void *)context +{ + Q_UNUSED(keyPath); + Q_UNUSED(object); + Q_UNUSED(change); + + (*reinterpret_cast(context))(); +} +@end +QT_BEGIN_NAMESPACE + +// ------------------------------------------------------------------------- + + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index 2428faed15..8f4c96bbd6 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -67,6 +67,7 @@ #ifdef __OBJC__ #include +#include #endif #include "qstring.h" @@ -334,6 +335,60 @@ public: 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; + + 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; + + static KeyValueObserver *observer; +}; #endif // ------------------------------------------------------------------------- -- cgit v1.2.3