diff options
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoatheme.mm')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoatheme.mm | 89 |
1 files changed, 61 insertions, 28 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index 93f0400916..a2229159b5 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -42,6 +42,7 @@ #include "qcocoatheme.h" #include "messages.h" +#include <QtCore/QOperatingSystemVersion> #include <QtCore/QVariant> #include "qcocoasystemsettings.h" @@ -75,30 +76,50 @@ #endif #endif -#include <Carbon/Carbon.h> +#include <CoreServices/CoreServices.h> -@interface QT_MANGLE_NAMESPACE(QCocoaThemeNotificationReceiver) : NSObject { -QCocoaTheme *mPrivate; -} -- (id)initWithPrivate:(QCocoaTheme *)priv; -- (void)systemColorsDidChange:(NSNotification *)notification; +#if !QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) +@interface NSApplication (MojaveForwardDeclarations) +@property (readonly, strong) NSAppearance *effectiveAppearance NS_AVAILABLE_MAC(10_14); @end +#endif -QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaThemeNotificationReceiver); +@interface QT_MANGLE_NAMESPACE(QCocoaThemeAppAppearanceObserver) : NSObject +@property (readonly, nonatomic) QCocoaTheme *theme; +- (instancetype)initWithTheme:(QCocoaTheme *)theme; +@end -@implementation QCocoaThemeNotificationReceiver -- (id)initWithPrivate:(QCocoaTheme *)priv +QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaThemeAppAppearanceObserver); + +@implementation QCocoaThemeAppAppearanceObserver +- (instancetype)initWithTheme:(QCocoaTheme *)theme { - self = [super init]; - mPrivate = priv; + if ((self = [super init])) { + _theme = theme; + [NSApp addObserver:self forKeyPath:@"effectiveAppearance" options:NSKeyValueObservingOptionNew context:nullptr]; + } return self; } -- (void)systemColorsDidChange:(NSNotification *)notification +- (void)dealloc { - Q_UNUSED(notification); - mPrivate->reset(); - QWindowSystemInterface::handleThemeChange(nullptr); + [NSApp removeObserver:self forKeyPath:@"effectiveAppearance"]; + [super dealloc]; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object + change:(NSDictionary<NSKeyValueChangeKey, id> *)change context:(void *)context +{ + Q_UNUSED(change); + Q_UNUSED(context); + + Q_ASSERT(object == NSApp); + Q_ASSERT([keyPath isEqualToString:@"effectiveAppearance"]); + + if (__builtin_available(macOS 10.14, *)) + NSAppearance.currentAppearance = NSApp.effectiveAppearance; + + self.theme->handleSystemThemeChange(); } @end @@ -107,19 +128,22 @@ QT_BEGIN_NAMESPACE const char *QCocoaTheme::name = "cocoa"; QCocoaTheme::QCocoaTheme() - :m_systemPalette(0) + : m_systemPalette(nullptr), m_appearanceObserver(nil) { - m_notificationReceiver = [[QT_MANGLE_NAMESPACE(QCocoaThemeNotificationReceiver) alloc] initWithPrivate:this]; - [[NSNotificationCenter defaultCenter] addObserver:m_notificationReceiver - selector:@selector(systemColorsDidChange:) - name:NSSystemColorsDidChangeNotification - object:nil]; + if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave) + m_appearanceObserver = [[QCocoaThemeAppAppearanceObserver alloc] initWithTheme:this]; + + [[NSNotificationCenter defaultCenter] addObserverForName:NSSystemColorsDidChangeNotification + object:nil queue:nil usingBlock:^(NSNotification *) { + handleSystemThemeChange(); + }]; } QCocoaTheme::~QCocoaTheme() { - [[NSNotificationCenter defaultCenter] removeObserver:m_notificationReceiver]; - [m_notificationReceiver release]; + if (m_appearanceObserver) + [m_appearanceObserver release]; + reset(); qDeleteAll(m_fonts); } @@ -132,6 +156,15 @@ void QCocoaTheme::reset() m_palettes.clear(); } +void QCocoaTheme::handleSystemThemeChange() +{ + reset(); + m_systemPalette = qt_mac_createSystemPalette(); + m_palettes = qt_mac_createRolePalettes(); + + QWindowSystemInterface::handleThemeChange(nullptr); +} + bool QCocoaTheme::usePlatformNativeDialog(DialogType dialogType) const { if (dialogType == QPlatformTheme::FileDialog) @@ -147,7 +180,7 @@ bool QCocoaTheme::usePlatformNativeDialog(DialogType dialogType) const return false; } -QPlatformDialogHelper * QCocoaTheme::createPlatformDialogHelper(DialogType dialogType) const +QPlatformDialogHelper *QCocoaTheme::createPlatformDialogHelper(DialogType dialogType) const { switch (dialogType) { #if defined(QT_WIDGETS_LIB) && QT_CONFIG(filedialog) @@ -163,7 +196,7 @@ QPlatformDialogHelper * QCocoaTheme::createPlatformDialogHelper(DialogType dialo return new QCocoaFontDialogHelper(); #endif default: - return 0; + return nullptr; } } @@ -183,9 +216,9 @@ const QPalette *QCocoaTheme::palette(Palette type) const } else { if (m_palettes.isEmpty()) m_palettes = qt_mac_createRolePalettes(); - return m_palettes.value(type, 0); + return m_palettes.value(type, nullptr); } - return 0; + return nullptr; } QHash<QPlatformTheme::Font, QFont *> qt_mac_createRoleFonts() @@ -199,7 +232,7 @@ const QFont *QCocoaTheme::font(Font type) const if (m_fonts.isEmpty()) { m_fonts = qt_mac_createRoleFonts(); } - return m_fonts.value(type, 0); + return m_fonts.value(type, nullptr); } //! \internal |