macOS: Port from deprecated NSAppearance.currentAppearance
When the system appearance changes, it will be reflected through NSApp.effectiveAppearance, but NSAppearance.currentAppearance and NSAppearance.currentDrawingAppearance will remain as is for some reason (perhaps as a compatibility for apps that were not ready to handle dark mode). The original way to deal with this was to explicitly set the NSAppearance.currentAppearance to the new effective appearance, which would take effect for the thread from that point on. But this API has been deprecated, most likely because overriding it globally could mess up views or logic that was not prepared for dark mode). The replacement API, NSAppearance performAsCurrentDrawingAppearance is given a block, and will only override NSAppearance.currentAppearance during the block, which isolates it from other fragile components. We now use a helper from QtGui that takes care of wrapping our style drawing in performAsCurrentDrawingAppearance. Task-number: QTBUG-135789 Change-Id: I0eb5dfc05734cf75181e6a3ed8cf2d23185f425f Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
parent
6ae7a5a89e
commit
fa4568622c
|
@ -31,6 +31,9 @@
|
|||
#include <QtGui/private/qcoregraphics_p.h>
|
||||
#include <QtGui/private/qguiapplication_p.h>
|
||||
|
||||
using namespace QQC2;
|
||||
#include <QtGui/private/qmacstyle_p.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
QT_USE_NAMESPACE
|
||||
|
@ -265,42 +268,6 @@ static const int toolButtonArrowMargin = 2;
|
|||
|
||||
static const qreal focusRingWidth = 3.5;
|
||||
|
||||
// An application can force 'Aqua' theme while the system theme is one of
|
||||
// the 'Dark' variants. Since in Qt we sometimes use NSControls and even
|
||||
// NSCells directly without attaching them to any view hierarchy, we have
|
||||
// to set NSAppearance.currentAppearance to 'Aqua' manually, to make sure
|
||||
// the correct rendering path is triggered. Apple recommends us to un-set
|
||||
// the current appearance back after we finished with drawing. This is what
|
||||
// AppearanceSync is for.
|
||||
|
||||
class AppearanceSync {
|
||||
public:
|
||||
AppearanceSync()
|
||||
{
|
||||
#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14)
|
||||
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave
|
||||
&& !isDarkMode()) {
|
||||
auto requiredAppearanceName = NSApplication.sharedApplication.effectiveAppearance.name;
|
||||
if (![NSAppearance.currentAppearance.name isEqualToString:requiredAppearanceName]) {
|
||||
previous = NSAppearance.currentAppearance;
|
||||
NSAppearance.currentAppearance = [NSAppearance appearanceNamed:requiredAppearanceName];
|
||||
}
|
||||
}
|
||||
#endif // QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14)
|
||||
}
|
||||
|
||||
~AppearanceSync()
|
||||
{
|
||||
if (previous)
|
||||
NSAppearance.currentAppearance = previous;
|
||||
}
|
||||
|
||||
private:
|
||||
NSAppearance *previous = nil;
|
||||
|
||||
Q_DISABLE_COPY(AppearanceSync)
|
||||
};
|
||||
|
||||
static bool setupScroller(NSScroller *scroller, const QStyleOptionSlider *sb)
|
||||
{
|
||||
const qreal length = sb->maximum - sb->minimum + sb->pageStep;
|
||||
|
@ -1615,6 +1582,11 @@ void QMacStylePrivate::resolveCurrentNSView(QWindow *window) const
|
|||
backingStoreNSView = window ? (NSView *)window->winId() : nil;
|
||||
}
|
||||
|
||||
QMacStyle *QMacStyle::create()
|
||||
{
|
||||
return new QMacApperanceStyle<QMacStyle>;
|
||||
}
|
||||
|
||||
QMacStyle::QMacStyle()
|
||||
: QCommonStyle(*new QMacStylePrivate)
|
||||
{
|
||||
|
@ -2408,7 +2380,6 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
|
|||
{
|
||||
Q_D(const QMacStyle);
|
||||
|
||||
const AppearanceSync appSync;
|
||||
QMacCGContext cg(p);
|
||||
d->resolveCurrentNSView(opt->window);
|
||||
|
||||
|
@ -2903,7 +2874,6 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
|
|||
{
|
||||
Q_D(const QMacStyle);
|
||||
|
||||
const AppearanceSync sync;
|
||||
const QMacAutoReleasePool pool;
|
||||
|
||||
QMacCGContext cg(p);
|
||||
|
@ -4431,7 +4401,6 @@ void QMacStylePrivate::restoreNSGraphicsContext(CGContextRef cg) const
|
|||
void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p) const
|
||||
{
|
||||
Q_D(const QMacStyle);
|
||||
const AppearanceSync sync;
|
||||
|
||||
QMacCGContext cg(p);
|
||||
d->resolveCurrentNSView(opt->window);
|
||||
|
|
|
@ -32,10 +32,13 @@ class QMacStylePrivate;
|
|||
class QMacStyle : public QCommonStyle
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
protected:
|
||||
QMacStyle();
|
||||
public:
|
||||
~QMacStyle();
|
||||
|
||||
static QMacStyle *create();
|
||||
|
||||
void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p) const override;
|
||||
void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p) const override;
|
||||
void drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p) const override;
|
||||
|
|
|
@ -98,7 +98,7 @@ void QtQuickControls2NativeStylePlugin::initializeEngine(QQmlEngine *engine, con
|
|||
style = new QCommonStyle;
|
||||
#if defined(Q_OS_MACOS)
|
||||
else if (envStyle == QLatin1String("mac"))
|
||||
style = new QMacStyle;
|
||||
style = QMacStyle::create();
|
||||
#endif
|
||||
#if defined(Q_OS_WINDOWS)
|
||||
else if (envStyle == QLatin1String("windows"))
|
||||
|
@ -109,7 +109,7 @@ void QtQuickControls2NativeStylePlugin::initializeEngine(QQmlEngine *engine, con
|
|||
}
|
||||
if (!style) {
|
||||
#if defined(Q_OS_MACOS)
|
||||
style = new QMacStyle;
|
||||
style = QMacStyle::create();
|
||||
#elif defined(Q_OS_WINDOWS)
|
||||
style = new QWindowsXPStyle;
|
||||
if (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark)
|
||||
|
|
Loading…
Reference in New Issue