macOS: Use QMacNotificationObserver over manual notification handling

This also fixes a bug where we were implicitly capturing this inside
the block, which meant that we would crash if the theme was recreated.
The capture is now tied to the lifetime of QCocoaTheme.

Change-Id: I37df8e6c0b33bf41e76d66be3cf29576041a7546
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Tor Arne Vestbø 2019-05-29 16:36:09 +02:00
parent 15d73a9f47
commit b53994de5f
3 changed files with 17 additions and 20 deletions

View File

@ -45,6 +45,8 @@
Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QCocoaThemeAppAppearanceObserver));
#include <QtCore/private/qcore_mac_p.h>
QT_BEGIN_NAMESPACE
class QPalette;
@ -82,6 +84,7 @@ public:
private:
mutable QPalette *m_systemPalette;
QMacNotificationObserver m_systemColorObserver;
mutable QHash<QPlatformTheme::Palette, QPalette*> m_palettes;
mutable QHash<QPlatformTheme::Font, QFont*> m_fonts;
QT_MANGLE_NAMESPACE(QCocoaThemeAppAppearanceObserver) *m_appearanceObserver;

View File

@ -133,10 +133,10 @@ QCocoaTheme::QCocoaTheme()
m_appearanceObserver = [[QCocoaThemeAppAppearanceObserver alloc] initWithTheme:this];
#endif
[[NSNotificationCenter defaultCenter] addObserverForName:NSSystemColorsDidChangeNotification
object:nil queue:nil usingBlock:^(NSNotification *) {
m_systemColorObserver = QMacNotificationObserver(nil,
NSSystemColorsDidChangeNotification, [this] {
handleSystemThemeChange();
}];
});
}
QCocoaTheme::~QCocoaTheme()

View File

@ -161,18 +161,6 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(NotificationReceiver);
return self;
}
- (void)scrollBarStyleDidChange:(NSNotification *)notification
{
Q_UNUSED(notification);
// purge destroyed scroll bars:
QMacStylePrivate::scrollBars.removeAll(QPointer<QObject>());
QEvent event(QEvent::StyleChange);
for (const auto &o : QMacStylePrivate::scrollBars)
QCoreApplication::sendEvent(o, &event);
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary<NSKeyValueChangeKey, id> *)change context:(void *)context
{
@ -2095,11 +2083,18 @@ QMacStyle::QMacStyle()
Q_D(QMacStyle);
QMacAutoReleasePool pool;
static QMacNotificationObserver scrollbarStyleObserver(nil,
NSPreferredScrollerStyleDidChangeNotification, []() {
// Purge destroyed scroll bars
QMacStylePrivate::scrollBars.removeAll(QPointer<QObject>());
QEvent event(QEvent::StyleChange);
for (const auto &o : QMacStylePrivate::scrollBars)
QCoreApplication::sendEvent(o, &event);
});
d->receiver = [[NotificationReceiver alloc] initWithPrivateStyle:d];
[[NSNotificationCenter defaultCenter] addObserver:d->receiver
selector:@selector(scrollBarStyleDidChange:)
name:NSPreferredScrollerStyleDidChangeNotification
object:nil];
#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14)
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave) {
[NSApplication.sharedApplication addObserver:d->receiver forKeyPath:@"effectiveAppearance"
@ -2113,7 +2108,6 @@ QMacStyle::~QMacStyle()
Q_D(QMacStyle);
QMacAutoReleasePool pool;
[[NSNotificationCenter defaultCenter] removeObserver:d->receiver];
#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14)
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave)
[NSApplication.sharedApplication removeObserver:d->receiver forKeyPath:@"effectiveAppearance"];