diff options
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoatheme.mm')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoatheme.mm | 170 |
1 files changed, 91 insertions, 79 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm index fecb2b8c58..1623b12be6 100644 --- a/src/plugins/platforms/cocoa/qcocoatheme.mm +++ b/src/plugins/platforms/cocoa/qcocoatheme.mm @@ -5,7 +5,6 @@ #include "qcocoatheme.h" -#include <QtCore/QOperatingSystemVersion> #include <QtCore/QVariant> #include "qcocoasystemtrayicon.h" @@ -15,12 +14,14 @@ #include "qcocoahelpers.h" #include <QtCore/qfileinfo.h> +#include <QtCore/private/qcore_mac_p.h> #include <QtGui/private/qfont_p.h> #include <QtGui/private/qguiapplication_p.h> #include <QtGui/private/qcoregraphics_p.h> #include <QtGui/qpainter.h> #include <QtGui/qtextformat.h> #include <QtGui/private/qcoretextfontdatabase_p.h> +#include <QtGui/private/qappleiconengine_p.h> #include <QtGui/private/qfontengine_coretext_p.h> #include <QtGui/private/qabstractfileiconengine_p.h> #include <qpa/qplatformdialoghelper.h> @@ -30,21 +31,10 @@ #include "qcocoacolordialoghelper.h" #include "qcocoafiledialoghelper.h" #include "qcocoafontdialoghelper.h" +#include "qcocoamessagedialog.h" #include <CoreServices/CoreServices.h> -#if !QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) -@interface NSColor (MojaveForwardDeclarations) -@property (class, strong, readonly) NSColor *selectedContentBackgroundColor NS_AVAILABLE_MAC(10_14); -@property (class, strong, readonly) NSColor *unemphasizedSelectedTextBackgroundColor NS_AVAILABLE_MAC(10_14); -@property (class, strong, readonly) NSColor *unemphasizedSelectedTextColor NS_AVAILABLE_MAC(10_14); -@property (class, strong, readonly) NSColor *unemphasizedSelectedContentBackgroundColor NS_AVAILABLE_MAC(10_14); -@property (class, strong, readonly) NSArray<NSColor *> *alternatingContentBackgroundColors NS_AVAILABLE_MAC(10_14); -// Missing from non-Mojave SDKs, even if introduced in 10.10 -@property (class, strong, readonly) NSColor *linkColor NS_AVAILABLE_MAC(10_10); -@end -#endif - QT_BEGIN_NAMESPACE static QPalette *qt_mac_createSystemPalette() @@ -74,14 +64,9 @@ static QPalette *qt_mac_createSystemPalette() // System palette initialization: QBrush br = qt_mac_toQBrush([NSColor selectedControlColor]); palette->setBrush(QPalette::Active, QPalette::Highlight, br); - if (__builtin_available(macOS 10.14, *)) { - const auto inactiveHighlight = qt_mac_toQBrush([NSColor unemphasizedSelectedContentBackgroundColor]); - palette->setBrush(QPalette::Inactive, QPalette::Highlight, inactiveHighlight); - palette->setBrush(QPalette::Disabled, QPalette::Highlight, inactiveHighlight); - } else { - palette->setBrush(QPalette::Inactive, QPalette::Highlight, br); - palette->setBrush(QPalette::Disabled, QPalette::Highlight, br); - } + const auto inactiveHighlight = qt_mac_toQBrush([NSColor unemphasizedSelectedContentBackgroundColor]); + palette->setBrush(QPalette::Inactive, QPalette::Highlight, inactiveHighlight); + palette->setBrush(QPalette::Disabled, QPalette::Highlight, inactiveHighlight); palette->setBrush(QPalette::Shadow, qt_mac_toQColor([NSColor shadowColor])); @@ -109,6 +94,9 @@ static QPalette *qt_mac_createSystemPalette() palette->setColor(QPalette::Inactive, QPalette::PlaceholderText, qc); palette->setColor(QPalette::Disabled, QPalette::PlaceholderText, qc); + qc = qt_mac_toQColor([NSColor controlAccentColor]); + palette->setColor(QPalette::Accent, qc); + return palette; } @@ -166,17 +154,8 @@ static QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes() } if (mac_widget_colors[i].paletteRole == QPlatformTheme::MenuPalette || mac_widget_colors[i].paletteRole == QPlatformTheme::MenuBarPalette) { - NSColor *selectedMenuItemColor = nil; - if (__builtin_available(macOS 10.14, *)) { - // Cheap approximation for NSVisualEffectView (see deprecation note for selectedMenuItemTextColor) - selectedMenuItemColor = [[NSColor controlAccentColor] highlightWithLevel:0.3]; - } else { - // selectedMenuItemColor would presumably be the correct color to use as the background - // for selected menu items. But that color is always blue, and doesn't follow the - // appearance color in system preferences. So we therefore deliberately choose to use - // keyboardFocusIndicatorColor instead, which appears to have the same color value. - selectedMenuItemColor = [NSColor keyboardFocusIndicatorColor]; - } + // Cheap approximation for NSVisualEffectView (see deprecation note for selectedMenuItemTextColor) + auto selectedMenuItemColor = [[NSColor controlAccentColor] highlightWithLevel:0.3]; pal.setBrush(QPalette::Highlight, qt_mac_toQColor(selectedMenuItemColor)); qc = qt_mac_toQColor([NSColor labelColor]); pal.setBrush(QPalette::ButtonText, qc); @@ -197,17 +176,10 @@ static QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes() } else if (mac_widget_colors[i].paletteRole == QPlatformTheme::ItemViewPalette) { NSArray<NSColor *> *baseColors = nil; NSColor *activeHighlightColor = nil; - if (__builtin_available(macOS 10.14, *)) { - baseColors = [NSColor alternatingContentBackgroundColors]; - activeHighlightColor = [NSColor selectedContentBackgroundColor]; - pal.setBrush(QPalette::Inactive, QPalette::HighlightedText, - qt_mac_toQBrush([NSColor unemphasizedSelectedTextColor])); - } else { - baseColors = [NSColor controlAlternatingRowBackgroundColors]; - activeHighlightColor = [NSColor alternateSelectedControlColor]; - pal.setBrush(QPalette::Inactive, QPalette::HighlightedText, - pal.brush(QPalette::Active, QPalette::Text)); - } + baseColors = [NSColor alternatingContentBackgroundColors]; + activeHighlightColor = [NSColor selectedContentBackgroundColor]; + pal.setBrush(QPalette::Inactive, QPalette::HighlightedText, + qt_mac_toQBrush([NSColor unemphasizedSelectedTextColor])); pal.setBrush(QPalette::Base, qt_mac_toQBrush(baseColors[0])); pal.setBrush(QPalette::AlternateBase, qt_mac_toQBrush(baseColors[1])); pal.setBrush(QPalette::Active, QPalette::Highlight, @@ -241,21 +213,17 @@ const char *QCocoaTheme::name = "cocoa"; QCocoaTheme::QCocoaTheme() : m_systemPalette(nullptr) { -#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) - if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave) { - m_appearanceObserver = QMacKeyValueObserver(NSApp, @"effectiveAppearance", [this] { - if (__builtin_available(macOS 10.14, *)) - NSAppearance.currentAppearance = NSApp.effectiveAppearance; - - handleSystemThemeChange(); - }); - } -#endif + m_appearanceObserver = QMacKeyValueObserver(NSApp, @"effectiveAppearance", [this] { + NSAppearance.currentAppearance = NSApp.effectiveAppearance; + handleSystemThemeChange(); + }); m_systemColorObserver = QMacNotificationObserver(nil, NSSystemColorsDidChangeNotification, [this] { handleSystemThemeChange(); }); + + updateColorScheme(); } QCocoaTheme::~QCocoaTheme() @@ -274,6 +242,9 @@ void QCocoaTheme::reset() void QCocoaTheme::handleSystemThemeChange() { reset(); + + updateColorScheme(); + m_systemPalette = qt_mac_createSystemPalette(); m_palettes = qt_mac_createRolePalettes(); @@ -287,13 +258,15 @@ void QCocoaTheme::handleSystemThemeChange() bool QCocoaTheme::usePlatformNativeDialog(DialogType dialogType) const { - if (dialogType == QPlatformTheme::FileDialog) - return true; - if (dialogType == QPlatformTheme::ColorDialog) - return true; - if (dialogType == QPlatformTheme::FontDialog) + switch (dialogType) { + case QPlatformTheme::FileDialog: + case QPlatformTheme::ColorDialog: + case QPlatformTheme::FontDialog: + case QPlatformTheme::MessageDialog: return true; - return false; + default: + return false; + } } QPlatformDialogHelper *QCocoaTheme::createPlatformDialogHelper(DialogType dialogType) const @@ -305,6 +278,8 @@ QPlatformDialogHelper *QCocoaTheme::createPlatformDialogHelper(DialogType dialog return new QCocoaColorDialogHelper(); case QPlatformTheme::FontDialog: return new QCocoaFontDialogHelper(); + case QPlatformTheme::MessageDialog: + return new QCocoaMessageDialog; default: return nullptr; } @@ -412,11 +387,11 @@ QPixmap QCocoaTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const if (iconType != 0) { QPixmap pixmap; IconRef icon = nullptr; - GetIconRef(kOnSystemDisk, kSystemIconsCreator, iconType, &icon); + QT_IGNORE_DEPRECATIONS(GetIconRef(kOnSystemDisk, kSystemIconsCreator, iconType, &icon)); if (icon) { pixmap = qt_mac_convert_iconref(icon, size.width(), size.height()); - ReleaseIconRef(icon); + QT_IGNORE_DEPRECATIONS(ReleaseIconRef(icon)); } return pixmap; @@ -432,19 +407,8 @@ public: QPlatformTheme::IconOptions opts) : QAbstractFileIconEngine(info, opts) {} - static QList<QSize> availableIconSizes() - { - const qreal devicePixelRatio = qGuiApp->devicePixelRatio(); - const int sizes[] = { - qRound(16 * devicePixelRatio), qRound(32 * devicePixelRatio), - qRound(64 * devicePixelRatio), qRound(128 * devicePixelRatio), - qRound(256 * devicePixelRatio) - }; - return QAbstractFileIconEngine::toSizeList(sizes, sizes + sizeof(sizes) / sizeof(sizes[0])); - } - QList<QSize> availableSizes(QIcon::Mode = QIcon::Normal, QIcon::State = QIcon::Off) override - { return QCocoaFileIconEngine::availableIconSizes(); } + { return QAppleIconEngine::availableIconSizes(); } protected: QPixmap filePixmap(const QSize &size, QIcon::Mode, QIcon::State) override @@ -463,6 +427,11 @@ QIcon QCocoaTheme::fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptio return QIcon(new QCocoaFileIconEngine(fileInfo, iconOptions)); } +QIconEngine *QCocoaTheme::createIconEngine(const QString &iconName) const +{ + return new QAppleIconEngine(iconName); +} + QVariant QCocoaTheme::themeHint(ThemeHint hint) const { switch (hint) { @@ -476,7 +445,7 @@ QVariant QCocoaTheme::themeHint(ThemeHint hint) const return QVariant([[NSApplication sharedApplication] isFullKeyboardAccessEnabled] ? int(Qt::TabFocusAllControls) : int(Qt::TabFocusTextControls | Qt::TabFocusListControls)); case IconPixmapSizes: - return QVariant::fromValue(QCocoaFileIconEngine::availableIconSizes()); + return QVariant::fromValue(QAppleIconEngine::availableIconSizes()); case QPlatformTheme::PasswordMaskCharacter: return QVariant(QChar(0x2022)); case QPlatformTheme::UiEffects: @@ -489,15 +458,52 @@ QVariant QCocoaTheme::themeHint(ThemeHint hint) const return !NSScreen.screensHaveSeparateSpaces; case QPlatformTheme::ShowDirectoriesFirst: return false; + case QPlatformTheme::MouseDoubleClickInterval: + return NSEvent.doubleClickInterval * 1000; + case QPlatformTheme::KeyboardInputInterval: + return NSEvent.keyRepeatDelay * 1000; + case QPlatformTheme::KeyboardAutoRepeatRate: + return 1.0 / NSEvent.keyRepeatInterval; + case QPlatformTheme::ShowIconsInMenus: + return false; default: break; } return QPlatformTheme::themeHint(hint); } -QPlatformTheme::Appearance QCocoaTheme::appearance() const +Qt::ColorScheme QCocoaTheme::colorScheme() const +{ + return m_colorScheme; +} + +void QCocoaTheme::requestColorScheme(Qt::ColorScheme scheme) +{ + NSAppearance *appearance = nil; + switch (scheme) { + case Qt::ColorScheme::Dark: + appearance = [NSAppearance appearanceNamed:NSAppearanceNameDarkAqua]; + break; + case Qt::ColorScheme::Light: + appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua]; + break; + case Qt::ColorScheme::Unknown: + break; + } + if (appearance != NSApp.effectiveAppearance) + NSApplication.sharedApplication.appearance = appearance; +} + +/* + Update the theme's color scheme based on the current appearance. + + We can only reference the appearance on the main thread, but the + CoreText font engine needs to know the color scheme, and might be + used from secondary threads, so we cache the color scheme. +*/ +void QCocoaTheme::updateColorScheme() { - return qt_mac_applicationIsInDarkMode() ? Appearance::Dark : Appearance::Light; + m_colorScheme = qt_mac_applicationIsInDarkMode() ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light; } QString QCocoaTheme::standardButtonText(int button) const @@ -515,12 +521,16 @@ QKeySequence QCocoaTheme::standardButtonShortcut(int button) const QPlatformMenuItem *QCocoaTheme::createPlatformMenuItem() const { - return new QCocoaMenuItem(); + auto *menuItem = new QCocoaMenuItem(); + qCDebug(lcQpaMenus) << "Created" << menuItem; + return menuItem; } QPlatformMenu *QCocoaTheme::createPlatformMenu() const { - return new QCocoaMenu(); + auto *menu = new QCocoaMenu(); + qCDebug(lcQpaMenus) << "Created" << menu; + return menu; } QPlatformMenuBar *QCocoaTheme::createPlatformMenuBar() const @@ -533,7 +543,9 @@ QPlatformMenuBar *QCocoaTheme::createPlatformMenuBar() const SLOT(onAppFocusWindowChanged(QWindow*))); } - return new QCocoaMenuBar(); + auto *menuBar = new QCocoaMenuBar(); + qCDebug(lcQpaMenus) << "Created" << menuBar; + return menuBar; } #ifndef QT_NO_SHORTCUT |