/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*
  Note: The qdoc comments for QMacStyle are contained in
  .../doc/src/qstyles.qdoc.
*/

#include <AppKit/AppKit.h>

#include "qmacstyle_mac_p.h"
#include "qmacstyle_mac_p_p.h"

#define QMAC_QAQUASTYLE_SIZE_CONSTRAIN
//#define DEBUG_SIZE_CONSTRAINT

#include <QtCore/qoperatingsystemversion.h>
#include <QtCore/qvariant.h>
#include <QtCore/qvarlengtharray.h>

#include <QtCore/private/qcore_mac_p.h>

#include <QtGui/private/qcoregraphics_p.h>
#include <QtGui/qpa/qplatformfontdatabase.h>
#include <QtGui/qpa/qplatformtheme.h>

#include <QtWidgets/private/qstyleanimation_p.h>

#if QT_CONFIG(mdiarea)
#include <QtWidgets/qmdisubwindow.h>
#endif
#if QT_CONFIG(scrollbar)
#include <QtWidgets/qscrollbar.h>
#endif
#if QT_CONFIG(tabbar)
#include <QtWidgets/private/qtabbar_p.h>
#endif
#if QT_CONFIG(wizard)
#include <QtWidgets/qwizard.h>
#endif

#include <cmath>

QT_USE_NAMESPACE

static QWindow *qt_getWindow(const QWidget *widget)
{
    return widget ? widget->window()->windowHandle() : 0;
}

@interface QT_MANGLE_NAMESPACE(QIndeterminateProgressIndicator) : NSProgressIndicator

@property (readonly, nonatomic) NSInteger animators;

- (instancetype)init;

- (void)startAnimation;
- (void)stopAnimation;

- (void)drawWithFrame:(CGRect)rect inView:(NSView *)view;

@end

QT_NAMESPACE_ALIAS_OBJC_CLASS(QIndeterminateProgressIndicator);

@implementation QIndeterminateProgressIndicator

- (instancetype)init
{
    if ((self = [super init])) {
        _animators = 0;
        self.indeterminate = YES;
        self.usesThreadedAnimation = NO;
        self.alphaValue = 0.0;
    }

    return self;
}

- (void)startAnimation
{
    if (_animators == 0) {
        self.hidden = NO;
        [super startAnimation:self];
    }
    ++_animators;
}

- (void)stopAnimation
{
    --_animators;
    if (_animators == 0) {
        [super stopAnimation:self];
        self.hidden = YES;
        [self removeFromSuperviewWithoutNeedingDisplay];
    }
}

- (void)drawWithFrame:(CGRect)rect inView:(NSView *)view
{
    // The alphaValue change is not strictly necessary, but feels safer.
    self.alphaValue = 1.0;
    if (self.superview != view)
        [view addSubview:self];
    if (!CGRectEqualToRect(self.frame, rect))
        self.frame = rect;
    [self drawRect:rect];
    self.alphaValue = 0.0;
}

@end

@interface QT_MANGLE_NAMESPACE(QVerticalSplitView) : NSSplitView
- (BOOL)isVertical;
@end

QT_NAMESPACE_ALIAS_OBJC_CLASS(QVerticalSplitView);

@implementation QVerticalSplitView
- (BOOL)isVertical
{
    return YES;
}
@end

// See render code in drawPrimitive(PE_FrameTabWidget)
@interface QT_MANGLE_NAMESPACE(QDarkNSBox) : NSBox
@end

QT_NAMESPACE_ALIAS_OBJC_CLASS(QDarkNSBox);

@implementation QDarkNSBox
- (instancetype)init
{
    if ((self = [super init])) {
        self.title = @"";
        self.titlePosition = NSNoTitle;
        self.boxType = NSBoxCustom;
        self.cornerRadius = 3;
        self.borderColor = [NSColor.controlColor colorWithAlphaComponent:0.1];
        self.fillColor = [NSColor.darkGrayColor colorWithAlphaComponent:0.2];
    }

    return self;
}

- (void)drawRect:(NSRect)rect
{
    [super drawRect:rect];
}
@end

QT_BEGIN_NAMESPACE

// The following constants are used for adjusting the size
// of push buttons so that they are drawn inside their bounds.
const int QMacStylePrivate::PushButtonLeftOffset = 6;
const int QMacStylePrivate::PushButtonRightOffset = 12;
const int QMacStylePrivate::PushButtonContentPadding = 6;

QVector<QPointer<QObject> > QMacStylePrivate::scrollBars;

// Title bar gradient colors for Lion were determined by inspecting PSDs exported
// using CoreUI's CoreThemeDocument; there is no public API to retrieve them

static QLinearGradient titlebarGradientActive()
{
    static QLinearGradient darkGradient = [](){
        QLinearGradient gradient;
        // FIXME: colors are chosen somewhat arbitrarily and could be fine-tuned,
        // or ideally determined by calling a native API.
        gradient.setColorAt(0, QColor(47, 47, 47));
        return gradient;
    }();
    static QLinearGradient lightGradient = [](){
        QLinearGradient gradient;
        gradient.setColorAt(0, QColor(235, 235, 235));
        gradient.setColorAt(0.5, QColor(210, 210, 210));
        gradient.setColorAt(0.75, QColor(195, 195, 195));
        gradient.setColorAt(1, QColor(180, 180, 180));
        return gradient;
    }();
    return qt_mac_applicationIsInDarkMode() ? darkGradient : lightGradient;
}

static QLinearGradient titlebarGradientInactive()
{
    static QLinearGradient darkGradient = [](){
        QLinearGradient gradient;
        gradient.setColorAt(1, QColor(42, 42, 42));
        return gradient;
    }();
    static QLinearGradient lightGradient = [](){
        QLinearGradient gradient;
        gradient.setColorAt(0, QColor(250, 250, 250));
        gradient.setColorAt(1, QColor(225, 225, 225));
        return gradient;
    }();
    return qt_mac_applicationIsInDarkMode() ? darkGradient : lightGradient;
}

#if QT_CONFIG(tabwidget)
static void clipTabBarFrame(const QStyleOption *option, const QMacStyle *style, CGContextRef ctx)
{
    Q_ASSERT(option);
    Q_ASSERT(style);
    Q_ASSERT(ctx);

    if (qt_mac_applicationIsInDarkMode()) {
        QTabWidget *tabWidget = qobject_cast<QTabWidget *>(option->styleObject);
        Q_ASSERT(tabWidget);

        const QRect tabBarRect = style->subElementRect(QStyle::SE_TabWidgetTabBar, option, tabWidget).adjusted(2, 2, -3, -2);
        const QRegion clipPath = QRegion(option->rect) - tabBarRect;
        QVarLengthArray<CGRect, 3> cgRects;
        for (const QRect &qtRect : clipPath)
            cgRects.push_back(qtRect.toCGRect());
        if (cgRects.size())
            CGContextClipToRects(ctx, &cgRects[0], size_t(cgRects.size()));
    }
}
#endif

static const QColor titlebarSeparatorLineActive(111, 111, 111);
static const QColor titlebarSeparatorLineInactive(131, 131, 131);
static const QColor darkModeSeparatorLine(88, 88, 88);

// Gradient colors used for the dock widget title bar and
// non-unifed tool bar bacground.
static const QColor lightMainWindowGradientBegin(240, 240, 240);
static const QColor lightMainWindowGradientEnd(200, 200, 200);
static const QColor darkMainWindowGradientBegin(47, 47, 47);
static const QColor darkMainWindowGradientEnd(47, 47, 47);

static const int DisclosureOffset = 4;

static const qreal titleBarIconTitleSpacing = 5;
static const qreal titleBarTitleRightMargin = 12;
static const qreal titleBarButtonSpacing = 8;

// Tab bar colors
// active: window is active
// selected: tab is selected
// hovered: tab is hovered
bool isDarkMode() { return qt_mac_applicationIsInDarkMode(); }

#if QT_CONFIG(tabbar)
static const QColor lightTabBarTabBackgroundActive(190, 190, 190);
static const QColor darkTabBarTabBackgroundActive(38, 38, 38);
static const QColor tabBarTabBackgroundActive() { return isDarkMode() ? darkTabBarTabBackgroundActive : lightTabBarTabBackgroundActive; }

static const QColor lightTabBarTabBackgroundActiveHovered(178, 178, 178);
static const QColor darkTabBarTabBackgroundActiveHovered(32, 32, 32);
static const QColor tabBarTabBackgroundActiveHovered() { return isDarkMode() ? darkTabBarTabBackgroundActiveHovered : lightTabBarTabBackgroundActiveHovered; }

static const QColor lightTabBarTabBackgroundActiveSelected(211, 211, 211);
static const QColor darkTabBarTabBackgroundActiveSelected(52, 52, 52);
static const QColor tabBarTabBackgroundActiveSelected() { return isDarkMode() ? darkTabBarTabBackgroundActiveSelected : lightTabBarTabBackgroundActiveSelected; }

static const QColor lightTabBarTabBackground(227, 227, 227);
static const QColor darkTabBarTabBackground(38, 38, 38);
static const QColor tabBarTabBackground() { return isDarkMode() ? darkTabBarTabBackground : lightTabBarTabBackground; }

static const QColor lightTabBarTabBackgroundSelected(246, 246, 246);
static const QColor darkTabBarTabBackgroundSelected(52, 52, 52);
static const QColor tabBarTabBackgroundSelected() { return isDarkMode() ? darkTabBarTabBackgroundSelected : lightTabBarTabBackgroundSelected; }

static const QColor lightTabBarTabLineActive(160, 160, 160);
static const QColor darkTabBarTabLineActive(90, 90, 90);
static const QColor tabBarTabLineActive() { return isDarkMode() ? darkTabBarTabLineActive : lightTabBarTabLineActive; }

static const QColor lightTabBarTabLineActiveHovered(150, 150, 150);
static const QColor darkTabBarTabLineActiveHovered(90, 90, 90);
static const QColor tabBarTabLineActiveHovered() { return isDarkMode() ? darkTabBarTabLineActiveHovered : lightTabBarTabLineActiveHovered; }

static const QColor lightTabBarTabLine(210, 210, 210);
static const QColor darkTabBarTabLine(90, 90, 90);
static const QColor tabBarTabLine() { return isDarkMode() ? darkTabBarTabLine : lightTabBarTabLine; }

static const QColor lightTabBarTabLineSelected(189, 189, 189);
static const QColor darkTabBarTabLineSelected(90, 90, 90);
static const QColor tabBarTabLineSelected() { return isDarkMode() ? darkTabBarTabLineSelected : lightTabBarTabLineSelected; }

static const QColor tabBarCloseButtonBackgroundHovered(162, 162, 162);
static const QColor tabBarCloseButtonBackgroundPressed(153, 153, 153);
static const QColor tabBarCloseButtonBackgroundSelectedHovered(192, 192, 192);
static const QColor tabBarCloseButtonBackgroundSelectedPressed(181, 181, 181);
static const QColor tabBarCloseButtonCross(100, 100, 100);
static const QColor tabBarCloseButtonCrossSelected(115, 115, 115);

static const int closeButtonSize = 14;
static const qreal closeButtonCornerRadius = 2.0;
#endif // QT_CONFIG(tabbar)

#ifndef QT_NO_ACCESSIBILITY // This ifdef to avoid "unused function" warning.
QBrush brushForToolButton(bool isOnKeyWindow)
{
    // When a toolbutton in a toolbar is in the 'ON' state, we draw a
    // partially transparent background. The colors must be different
    // for 'Aqua' and 'DarkAqua' appearances though.
    if (isDarkMode())
        return isOnKeyWindow ? QColor(73, 73, 73, 100) : QColor(56, 56, 56, 100);

    return isOnKeyWindow ? QColor(0, 0, 0, 28) : QColor(0, 0, 0, 21);
}
#endif // QT_NO_ACCESSIBILITY


static const int headerSectionArrowHeight = 6;
static const int headerSectionSeparatorInset = 2;

// One for each of QStyleHelper::WidgetSizePolicy
static const QMarginsF comboBoxFocusRingMargins[3] = {
    { 0.5, 2, 3.5, 4 },
    { 0.5, 1, 2.5, 4 },
    { 0.5, 1.5, 2.5, 3.5 }
};

static const QMarginsF pullDownButtonShadowMargins[3] = {
    { 0.5, -1, 0.5, 2 },
    { 0.5, -1.5, 0.5, 2.5 },
    { 0.5, 0, 0.5, 1 }
};

static const QMarginsF pushButtonShadowMargins[3] = {
    { 1.5, -1.5, 1.5, 4.5 },
    { 1.5, -1, 1.5, 4 },
    { 1.5, 0.5, 1.5, 2.5 }
};

// These are frame heights as reported by Xcode 9's Interface Builder.
// Alignemnet rectangle's heights match for push and popup buttons
// with respective values 21, 18 and 15.

static const qreal comboBoxDefaultHeight[3] = {
    26, 22, 19
};

static const qreal pushButtonDefaultHeight[3] = {
    32, 28, 16
};

static const qreal popupButtonDefaultHeight[3] = {
    26, 22, 15
};

static const int toolButtonArrowSize = 7;
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
            && !qt_mac_applicationIsInDarkMode()) {
            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;
    if (qFuzzyIsNull(length))
        return false;
    const qreal proportion = sb->pageStep / length;
    const qreal range = qreal(sb->maximum - sb->minimum);
    qreal value = range ? qreal(sb->sliderValue - sb->minimum) / range : 0;
    if (sb->orientation == Qt::Horizontal && sb->direction == Qt::RightToLeft)
        value = 1.0 - value;

    scroller.frame = sb->rect.toCGRect();
    scroller.floatValue = value;
    scroller.knobProportion = proportion;
    return true;
}

static bool setupSlider(NSSlider *slider, const QStyleOptionSlider *sl)
{
    if (sl->minimum >= sl->maximum)
        return false;

    slider.frame = sl->rect.toCGRect();
    slider.minValue = sl->minimum;
    slider.maxValue = sl->maximum;
    slider.intValue = sl->sliderPosition;
    slider.enabled = sl->state & QStyle::State_Enabled;
    if (sl->tickPosition != QSlider::NoTicks) {
        // Set numberOfTickMarks, but TicksBothSides will be treated differently
        int interval = sl->tickInterval;
        if (interval == 0) {
            interval = sl->pageStep;
            if (interval == 0)
                interval = sl->singleStep;
            if (interval == 0)
                interval = 1; // return false?
        }
        slider.numberOfTickMarks = 1 + ((sl->maximum - sl->minimum) / interval);

        const bool ticksAbove = sl->tickPosition == QSlider::TicksAbove;
        if (sl->orientation == Qt::Horizontal)
            slider.tickMarkPosition = ticksAbove ? NSTickMarkPositionAbove : NSTickMarkPositionBelow;
        else
            slider.tickMarkPosition = ticksAbove ? NSTickMarkPositionLeading : NSTickMarkPositionTrailing;
    } else {
        slider.numberOfTickMarks = 0;
    }

    return true;
}

static void fixStaleGeometry(NSSlider *slider)
{
    // If it's later fixed in AppKit, this function is not needed.
    // On macOS Mojave we suddenly have NSSliderCell with a cached
    // (and stale) geometry, thus its -drawKnob, -drawBarInside:flipped:,
    // -drawTickMarks fail to render the slider properly. Setting the number
    // of tickmarks triggers an update in geometry.

    Q_ASSERT(slider);

    if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSMojave)
        return;

    NSSliderCell *cell = slider.cell;
    const NSRect barRect = [cell barRectFlipped:NO];
    const NSSize sliderSize = slider.frame.size;
    CGFloat difference = 0.;
    if (slider.vertical)
        difference = std::abs(sliderSize.height - barRect.size.height);
    else
        difference = std::abs(sliderSize.width - barRect.size.width);

    if (difference > 6.) {
        // Stale ...
        const auto nOfTicks = slider.numberOfTickMarks;
        // Non-zero, different from nOfTicks to force update
        slider.numberOfTickMarks = nOfTicks + 10;
        slider.numberOfTickMarks = nOfTicks;
    }
}

static bool isInMacUnifiedToolbarArea(QWindow *window, int windowY)
{
    QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
    QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
        nativeInterface->nativeResourceFunctionForIntegration("testContentBorderPosition");
    if (!function)
        return false; // Not Cocoa platform plugin.

    typedef bool (*TestContentBorderPositionFunction)(QWindow *, int);
    return (reinterpret_cast<TestContentBorderPositionFunction>(function))(window, windowY);
}


#if QT_CONFIG(tabbar)
static void drawTabCloseButton(QPainter *p, bool hover, bool selected, bool pressed, bool documentMode)
{
    p->setRenderHints(QPainter::Antialiasing);
    QRect rect(0, 0, closeButtonSize, closeButtonSize);
    const int width = rect.width();
    const int height = rect.height();

    if (hover) {
        // draw background circle
        QColor background;
        if (selected) {
            if (documentMode)
                background = pressed ? tabBarCloseButtonBackgroundSelectedPressed : tabBarCloseButtonBackgroundSelectedHovered;
            else
                background = QColor(255, 255, 255, pressed ? 150 : 100); // Translucent white
        } else {
            background = pressed ? tabBarCloseButtonBackgroundPressed : tabBarCloseButtonBackgroundHovered;
            if (!documentMode)
                background = background.lighter(pressed ? 135 : 140); // Lighter tab background, lighter color
        }

        p->setPen(Qt::transparent);
        p->setBrush(background);
        p->drawRoundedRect(rect, closeButtonCornerRadius, closeButtonCornerRadius);
    }

    // draw cross
    const int margin = 3;
    QPen crossPen;
    crossPen.setColor(selected ? (documentMode ? tabBarCloseButtonCrossSelected : Qt::white) : tabBarCloseButtonCross);
    crossPen.setWidthF(1.1);
    crossPen.setCapStyle(Qt::FlatCap);
    p->setPen(crossPen);
    p->drawLine(margin, margin, width - margin, height - margin);
    p->drawLine(margin, height - margin, width - margin, margin);
}

QRect rotateTabPainter(QPainter *p, QTabBar::Shape shape, QRect tabRect)
{
    const auto tabDirection = QMacStylePrivate::tabDirection(shape);
    if (QMacStylePrivate::verticalTabs(tabDirection)) {
        int newX, newY, newRot;
        if (tabDirection == QMacStylePrivate::East) {
            newX = tabRect.width();
            newY = tabRect.y();
            newRot = 90;
        } else {
            newX = 0;
            newY = tabRect.y() + tabRect.height();
            newRot = -90;
        }
        tabRect.setRect(0, 0, tabRect.height(), tabRect.width());
        QTransform transform;
        transform.translate(newX, newY);
        transform.rotate(newRot);
        p->setTransform(transform, true);
    }
    return tabRect;
}

void drawTabShape(QPainter *p, const QStyleOptionTab *tabOpt, bool isUnified, int tabOverlap)
{
    QRect rect = tabOpt->rect;
    if (QMacStylePrivate::verticalTabs(QMacStylePrivate::tabDirection(tabOpt->shape)))
        rect = rect.adjusted(-tabOverlap, 0, 0, 0);
    else
        rect = rect.adjusted(0, -tabOverlap, 0, 0);

    p->translate(rect.x(), rect.y());
    rect.moveLeft(0);
    rect.moveTop(0);
    const QRect tabRect = rotateTabPainter(p, tabOpt->shape, rect);

    const int width = tabRect.width();
    const int height = tabRect.height();
    const bool active = (tabOpt->state & QStyle::State_Active);
    const bool selected = (tabOpt->state & QStyle::State_Selected);

    const QRect bodyRect(1, 2, width - 2, height - 3);
    const QRect topLineRect(1, 0, width - 2, 1);
    const QRect bottomLineRect(1, height - 1, width - 2, 1);
    if (selected) {
        // fill body
        if (tabOpt->documentMode && isUnified) {
            p->save();
            p->setCompositionMode(QPainter::CompositionMode_Source);
            p->fillRect(tabRect, QColor(Qt::transparent));
            p->restore();
        } else if (active) {
            p->fillRect(bodyRect, tabBarTabBackgroundActiveSelected());
            // top line
            p->fillRect(topLineRect, tabBarTabLineSelected());
        } else {
            p->fillRect(bodyRect, tabBarTabBackgroundSelected());
        }
    } else {
        // when the mouse is over non selected tabs they get a new color
        const bool hover = (tabOpt->state & QStyle::State_MouseOver);
        if (hover) {
            // fill body
            p->fillRect(bodyRect, tabBarTabBackgroundActiveHovered());
            // bottom line
            p->fillRect(bottomLineRect, isDarkMode() ? QColor(Qt::black) : tabBarTabLineActiveHovered());
        }
    }

    // separator lines between tabs
    const QRect leftLineRect(0, 1, 1, height - 2);
    const QRect rightLineRect(width - 1, 1, 1, height - 2);
    const QColor separatorLineColor = active ? tabBarTabLineActive() : tabBarTabLine();
    p->fillRect(leftLineRect, separatorLineColor);
    p->fillRect(rightLineRect, separatorLineColor);
}

void drawTabBase(QPainter *p, const QStyleOptionTabBarBase *tbb, const QWidget *w)
{
    QRect r = tbb->rect;
    if (QMacStylePrivate::verticalTabs(QMacStylePrivate::tabDirection(tbb->shape)))
        r.setWidth(w->width());
    else
        r.setHeight(w->height());

    const QRect tabRect = rotateTabPainter(p, tbb->shape, r);
    const int width = tabRect.width();
    const int height = tabRect.height();
    const bool active = (tbb->state & QStyle::State_Active);

    // fill body
    const QRect bodyRect(0, 1, width, height - 1);
    const QColor bodyColor = active ? tabBarTabBackgroundActive() : tabBarTabBackground();
    p->fillRect(bodyRect, bodyColor);

    // top line
    const QRect topLineRect(0, 0, width, 1);
    const QColor topLineColor = active ? tabBarTabLineActive() : tabBarTabLine();
    p->fillRect(topLineRect, topLineColor);

    // bottom line
    const QRect bottomLineRect(0, height - 1, width, 1);
    bool isDocument = false;
    if (const QTabBar *tabBar = qobject_cast<const QTabBar*>(w))
        isDocument = tabBar->documentMode();
    const QColor bottomLineColor = isDocument && isDarkMode() ? QColor(Qt::black) : active ? tabBarTabLineActive() : tabBarTabLine();
    p->fillRect(bottomLineRect, bottomLineColor);
}
#endif

static QStyleHelper::WidgetSizePolicy getControlSize(const QStyleOption *option, const QWidget *widget)
{
    const auto wsp = QStyleHelper::widgetSizePolicy(widget, option);
    if (wsp == QStyleHelper::SizeDefault)
        return QStyleHelper::SizeLarge;

    return wsp;
}

#if QT_CONFIG(treeview)
static inline bool isTreeView(const QWidget *widget)
{
    return (widget && widget->parentWidget() &&
            qobject_cast<const QTreeView *>(widget->parentWidget()));
}
#endif

static QString qt_mac_removeMnemonics(const QString &original)
{
    QString returnText(original.size(), 0);
    int finalDest = 0;
    int currPos = 0;
    int l = original.length();
    while (l) {
        if (original.at(currPos) == QLatin1Char('&')) {
            ++currPos;
            --l;
            if (l == 0)
                break;
        } else if (original.at(currPos) == QLatin1Char('(') && l >= 4 &&
                   original.at(currPos + 1) == QLatin1Char('&') &&
                   original.at(currPos + 2) != QLatin1Char('&') &&
                   original.at(currPos + 3) == QLatin1Char(')')) {
            /* remove mnemonics its format is "\s*(&X)" */
            int n = 0;
            while (finalDest > n && returnText.at(finalDest - n - 1).isSpace())
                ++n;
            finalDest -= n;
            currPos += 4;
            l -= 4;
            continue;
        }
        returnText[finalDest] = original.at(currPos);
        ++currPos;
        ++finalDest;
        --l;
    }
    returnText.truncate(finalDest);
    return returnText;
}

static bool qt_macWindowMainWindow(const QWidget *window)
{
    if (QWindow *w = window->windowHandle()) {
        if (w->handle()) {
            if (NSWindow *nswindow = static_cast<NSWindow*>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow(QByteArrayLiteral("nswindow"), w))) {
                return [nswindow isMainWindow];
            }
        }
    }
    return false;
}

/*****************************************************************************
  QMacCGStyle globals
 *****************************************************************************/
const int macItemFrame         = 2;    // menu item frame width
const int macItemHMargin       = 3;    // menu item hor text margin
const int macRightBorder       = 12;   // right border on mac

/*****************************************************************************
  QMacCGStyle utility functions
 *****************************************************************************/

enum QAquaMetric {
    // Prepend kThemeMetric to get the HIToolBox constant.
    // Represents the values already used in QMacStyle.
    CheckBoxHeight = 0,
    CheckBoxWidth,
    EditTextFrameOutset,
    FocusRectOutset,
    HSliderHeight,
    HSliderTickHeight,
    LargeProgressBarThickness,
    ListHeaderHeight,
    MenuSeparatorHeight, // GetThemeMenuSeparatorHeight
    MiniCheckBoxHeight,
    MiniCheckBoxWidth,
    MiniHSliderHeight,
    MiniHSliderTickHeight,
    MiniPopupButtonHeight,
    MiniPushButtonHeight,
    MiniRadioButtonHeight,
    MiniRadioButtonWidth,
    MiniVSliderTickWidth,
    MiniVSliderWidth,
    NormalProgressBarThickness,
    PopupButtonHeight,
    ProgressBarShadowOutset,
    PushButtonHeight,
    RadioButtonHeight,
    RadioButtonWidth,
    SeparatorSize,
    SmallCheckBoxHeight,
    SmallCheckBoxWidth,
    SmallHSliderHeight,
    SmallHSliderTickHeight,
    SmallPopupButtonHeight,
    SmallProgressBarShadowOutset,
    SmallPushButtonHeight,
    SmallRadioButtonHeight,
    SmallRadioButtonWidth,
    SmallVSliderTickWidth,
    SmallVSliderWidth,
    VSliderTickWidth,
    VSliderWidth
};

static const int qt_mac_aqua_metrics[] = {
    // Values as of macOS 10.12.4 and Xcode 8.3.1
    18 /* CheckBoxHeight */,
    18 /* CheckBoxWidth */,
    1  /* EditTextFrameOutset */,
    4  /* FocusRectOutset */,
    22 /* HSliderHeight */,
    5  /* HSliderTickHeight */,
    16 /* LargeProgressBarThickness */,
    17 /* ListHeaderHeight */,
    12 /* MenuSeparatorHeight, aka GetThemeMenuSeparatorHeight */,
    11 /* MiniCheckBoxHeight */,
    10 /* MiniCheckBoxWidth */,
    12 /* MiniHSliderHeight */,
    4  /* MiniHSliderTickHeight */,
    15 /* MiniPopupButtonHeight */,
    16 /* MiniPushButtonHeight */,
    11 /* MiniRadioButtonHeight */,
    10 /* MiniRadioButtonWidth */,
    4  /* MiniVSliderTickWidth */,
    12 /* MiniVSliderWidth */,
    12 /* NormalProgressBarThickness */,
    20 /* PopupButtonHeight */,
    4  /* ProgressBarShadowOutset */,
    20 /* PushButtonHeight */,
    18 /* RadioButtonHeight */,
    18 /* RadioButtonWidth */,
    1  /* SeparatorSize */,
    16 /* SmallCheckBoxHeight */,
    14 /* SmallCheckBoxWidth */,
    15 /* SmallHSliderHeight */,
    4  /* SmallHSliderTickHeight */,
    17 /* SmallPopupButtonHeight */,
    2  /* SmallProgressBarShadowOutset */,
    17 /* SmallPushButtonHeight */,
    15 /* SmallRadioButtonHeight */,
    14 /* SmallRadioButtonWidth */,
    4  /* SmallVSliderTickWidth */,
    15 /* SmallVSliderWidth */,
    5  /* VSliderTickWidth */,
    22 /* VSliderWidth */
};

static inline int qt_mac_aqua_get_metric(QAquaMetric m)
{
    return qt_mac_aqua_metrics[m];
}

static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg, QSize szHint,
                                    QStyleHelper::WidgetSizePolicy sz)
{
    QSize ret(-1, -1);
    if (sz != QStyleHelper::SizeSmall && sz != QStyleHelper::SizeLarge && sz != QStyleHelper::SizeMini) {
        qDebug("Not sure how to return this...");
        return ret;
    }
    if ((widg && widg->testAttribute(Qt::WA_SetFont)) || !QApplication::desktopSettingsAware()) {
        // If you're using a custom font and it's bigger than the default font,
        // then no constraints for you. If you are smaller, we can try to help you out
        QFont font = qt_app_fonts_hash()->value(widg->metaObject()->className(), QFont());
        if (widg->font().pointSize() > font.pointSize())
            return ret;
    }

    if (ct == QStyle::CT_CustomBase && widg) {
#if QT_CONFIG(pushbutton)
        if (qobject_cast<const QPushButton *>(widg))
            ct = QStyle::CT_PushButton;
#endif
        else if (qobject_cast<const QRadioButton *>(widg))
            ct = QStyle::CT_RadioButton;
#if QT_CONFIG(checkbox)
        else if (qobject_cast<const QCheckBox *>(widg))
            ct = QStyle::CT_CheckBox;
#endif
#if QT_CONFIG(combobox)
        else if (qobject_cast<const QComboBox *>(widg))
            ct = QStyle::CT_ComboBox;
#endif
#if QT_CONFIG(toolbutton)
        else if (qobject_cast<const QToolButton *>(widg))
            ct = QStyle::CT_ToolButton;
#endif
        else if (qobject_cast<const QSlider *>(widg))
            ct = QStyle::CT_Slider;
#if QT_CONFIG(progressbar)
        else if (qobject_cast<const QProgressBar *>(widg))
            ct = QStyle::CT_ProgressBar;
#endif
#if QT_CONFIG(lineedit)
        else if (qobject_cast<const QLineEdit *>(widg))
            ct = QStyle::CT_LineEdit;
#endif
#if QT_CONFIG(itemviews)
        else if (qobject_cast<const QHeaderView *>(widg))
            ct = QStyle::CT_HeaderSection;
#endif
#if QT_CONFIG(menubar)
        else if (qobject_cast<const QMenuBar *>(widg))
            ct = QStyle::CT_MenuBar;
#endif
#if QT_CONFIG(sizegrip)
        else if (qobject_cast<const QSizeGrip *>(widg))
            ct = QStyle::CT_SizeGrip;
#endif
        else
            return ret;
    }

    switch (ct) {
#if QT_CONFIG(pushbutton)
    case QStyle::CT_PushButton: {
        const QPushButton *psh = qobject_cast<const QPushButton *>(widg);
        // If this comparison is false, then the widget was not a push button.
        // This is bad and there's very little we can do since we were requested to find a
        // sensible size for a widget that pretends to be a QPushButton but is not.
        if(psh) {
            QString buttonText = qt_mac_removeMnemonics(psh->text());
            if (buttonText.contains(QLatin1Char('\n')))
                ret = QSize(-1, -1);
            else if (sz == QStyleHelper::SizeLarge)
                ret = QSize(-1, qt_mac_aqua_get_metric(PushButtonHeight));
            else if (sz == QStyleHelper::SizeSmall)
                ret = QSize(-1, qt_mac_aqua_get_metric(SmallPushButtonHeight));
            else if (sz == QStyleHelper::SizeMini)
                ret = QSize(-1, qt_mac_aqua_get_metric(MiniPushButtonHeight));

            if (!psh->icon().isNull()){
                // If the button got an icon, and the icon is larger than the
                // button, we can't decide on a default size
                ret.setWidth(-1);
                if (ret.height() < psh->iconSize().height())
                    ret.setHeight(-1);
            }
            else if (buttonText == QLatin1String("OK") || buttonText == QLatin1String("Cancel")){
                // Aqua Style guidelines restrict the size of OK and Cancel buttons to 68 pixels.
                // However, this doesn't work for German, therefore only do it for English,
                // I suppose it would be better to do some sort of lookups for languages
                // that like to have really long words.
                // FIXME This is not exactly true. Out of context, OK buttons have their
                // implicit size calculated the same way as any other button. Inside a
                // QDialogButtonBox, their size should be calculated such that the action
                // or accept button (i.e., rightmost) and cancel button have the same width.
                ret.setWidth(69);
            }
        } else {
            // The only sensible thing to do is to return whatever the style suggests...
            if (sz == QStyleHelper::SizeLarge)
                ret = QSize(-1, qt_mac_aqua_get_metric(PushButtonHeight));
            else if (sz == QStyleHelper::SizeSmall)
                ret = QSize(-1, qt_mac_aqua_get_metric(SmallPushButtonHeight));
            else if (sz == QStyleHelper::SizeMini)
                ret = QSize(-1, qt_mac_aqua_get_metric(MiniPushButtonHeight));
            else
                // Since there's no default size we return the large size...
                ret = QSize(-1, qt_mac_aqua_get_metric(PushButtonHeight));
         }
#endif
#if 0 //Not sure we are applying the rules correctly for RadioButtons/CheckBoxes --Sam
    } else if (ct == QStyle::CT_RadioButton) {
        QRadioButton *rdo = static_cast<QRadioButton *>(widg);
        // Exception for case where multiline radio button text requires no size constrainment
        if (rdo->text().find('\n') != -1)
            return ret;
        if (sz == QStyleHelper::SizeLarge)
            ret = QSize(-1, qt_mac_aqua_get_metric(RadioButtonHeight));
        else if (sz == QStyleHelper::SizeSmall)
            ret = QSize(-1, qt_mac_aqua_get_metric(SmallRadioButtonHeight));
        else if (sz == QStyleHelper::SizeMini)
            ret = QSize(-1, qt_mac_aqua_get_metric(MiniRadioButtonHeight));
    } else if (ct == QStyle::CT_CheckBox) {
        if (sz == QStyleHelper::SizeLarge)
            ret = QSize(-1, qt_mac_aqua_get_metric(CheckBoxHeight));
        else if (sz == QStyleHelper::SizeSmall)
            ret = QSize(-1, qt_mac_aqua_get_metric(SmallCheckBoxHeight));
        else if (sz == QStyleHelper::SizeMini)
            ret = QSize(-1, qt_mac_aqua_get_metric(MiniCheckBoxHeight));
#endif
        break;
    }
    case QStyle::CT_SizeGrip:
        // Not HIG kosher: mimic what we were doing earlier until we support 4-edge resizing in MDI subwindows
        if (sz == QStyleHelper::SizeLarge || sz == QStyleHelper::SizeSmall) {
            int s = sz == QStyleHelper::SizeSmall ? 16 : 22; // large: pixel measured from HITheme, small: from my hat
            int width = 0;
#if QT_CONFIG(mdiarea)
            if (widg && qobject_cast<QMdiSubWindow *>(widg->parentWidget()))
                width = s;
#endif
            ret = QSize(width, s);
        }
        break;
    case QStyle::CT_ComboBox:
        switch (sz) {
        case QStyleHelper::SizeLarge:
            ret = QSize(-1, qt_mac_aqua_get_metric(PopupButtonHeight));
            break;
        case QStyleHelper::SizeSmall:
            ret = QSize(-1, qt_mac_aqua_get_metric(SmallPopupButtonHeight));
            break;
        case QStyleHelper::SizeMini:
            ret = QSize(-1, qt_mac_aqua_get_metric(MiniPopupButtonHeight));
            break;
        default:
            break;
        }
        break;
    case QStyle::CT_ToolButton:
        if (sz == QStyleHelper::SizeSmall) {
            int width = 0, height = 0;
            if (szHint == QSize(-1, -1)) { //just 'guess'..
#if QT_CONFIG(toolbutton)
                const QToolButton *bt = qobject_cast<const QToolButton *>(widg);
                // If this conversion fails then the widget was not what it claimed to be.
                if(bt) {
                    if (!bt->icon().isNull()) {
                        QSize iconSize = bt->iconSize();
                        QSize pmSize = bt->icon().actualSize(QSize(32, 32), QIcon::Normal);
                        width = qMax(width, qMax(iconSize.width(), pmSize.width()));
                        height = qMax(height, qMax(iconSize.height(), pmSize.height()));
                    }
                    if (!bt->text().isNull() && bt->toolButtonStyle() != Qt::ToolButtonIconOnly) {
                        int text_width = bt->fontMetrics().horizontalAdvance(bt->text()),
                           text_height = bt->fontMetrics().height();
                        if (bt->toolButtonStyle() == Qt::ToolButtonTextUnderIcon) {
                            width = qMax(width, text_width);
                            height += text_height;
                        } else {
                            width += text_width;
                            width = qMax(height, text_height);
                        }
                    }
                } else
#endif
                {
                    // Let's return the size hint...
                    width = szHint.width();
                    height = szHint.height();
                }
            } else {
                width = szHint.width();
                height = szHint.height();
            }
            width =  qMax(20, width +  5); //border
            height = qMax(20, height + 5); //border
            ret = QSize(width, height);
        }
        break;
    case QStyle::CT_Slider: {
        int w = -1;
        const QSlider *sld = qobject_cast<const QSlider *>(widg);
        // If this conversion fails then the widget was not what it claimed to be.
        if(sld) {
            if (sz == QStyleHelper::SizeLarge) {
                if (sld->orientation() == Qt::Horizontal) {
                    w = qt_mac_aqua_get_metric(HSliderHeight);
                    if (sld->tickPosition() != QSlider::NoTicks)
                        w += qt_mac_aqua_get_metric(HSliderTickHeight);
                } else {
                    w = qt_mac_aqua_get_metric(VSliderWidth);
                    if (sld->tickPosition() != QSlider::NoTicks)
                        w += qt_mac_aqua_get_metric(VSliderTickWidth);
                }
            } else if (sz == QStyleHelper::SizeSmall) {
                if (sld->orientation() == Qt::Horizontal) {
                    w = qt_mac_aqua_get_metric(SmallHSliderHeight);
                    if (sld->tickPosition() != QSlider::NoTicks)
                        w += qt_mac_aqua_get_metric(SmallHSliderTickHeight);
                } else {
                    w = qt_mac_aqua_get_metric(SmallVSliderWidth);
                    if (sld->tickPosition() != QSlider::NoTicks)
                        w += qt_mac_aqua_get_metric(SmallVSliderTickWidth);
                }
            } else if (sz == QStyleHelper::SizeMini) {
                if (sld->orientation() == Qt::Horizontal) {
                    w = qt_mac_aqua_get_metric(MiniHSliderHeight);
                    if (sld->tickPosition() != QSlider::NoTicks)
                        w += qt_mac_aqua_get_metric(MiniHSliderTickHeight);
                } else {
                    w = qt_mac_aqua_get_metric(MiniVSliderWidth);
                    if (sld->tickPosition() != QSlider::NoTicks)
                        w += qt_mac_aqua_get_metric(MiniVSliderTickWidth);
                }
            }
        } else {
            // This is tricky, we were requested to find a size for a slider which is not
            // a slider. We don't know if this is vertical or horizontal or if we need to
            // have tick marks or not.
            // For this case we will return an horizontal slider without tick marks.
            w = qt_mac_aqua_get_metric(HSliderHeight);
            w += qt_mac_aqua_get_metric(HSliderTickHeight);
        }
        if (sld->orientation() == Qt::Horizontal)
            ret.setHeight(w);
        else
            ret.setWidth(w);
        break;
    }
#if QT_CONFIG(progressbar)
    case QStyle::CT_ProgressBar: {
        int finalValue = -1;
        Qt::Orientation orient = Qt::Horizontal;
        if (const QProgressBar *pb = qobject_cast<const QProgressBar *>(widg))
            orient = pb->orientation();

        if (sz == QStyleHelper::SizeLarge)
            finalValue = qt_mac_aqua_get_metric(LargeProgressBarThickness)
                            + qt_mac_aqua_get_metric(ProgressBarShadowOutset);
        else
            finalValue = qt_mac_aqua_get_metric(NormalProgressBarThickness)
                            + qt_mac_aqua_get_metric(SmallProgressBarShadowOutset);
        if (orient == Qt::Horizontal)
            ret.setHeight(finalValue);
        else
            ret.setWidth(finalValue);
        break;
    }
#endif
#if QT_CONFIG(combobox)
    case QStyle::CT_LineEdit:
        if (!widg || !qobject_cast<QComboBox *>(widg->parentWidget())) {
            //should I take into account the font dimentions of the lineedit? -Sam
            if (sz == QStyleHelper::SizeLarge)
                ret = QSize(-1, 21);
            else
                ret = QSize(-1, 19);
        }
        break;
#endif
    case QStyle::CT_HeaderSection:
#if QT_CONFIG(treeview)
        if (isTreeView(widg))
           ret = QSize(-1, qt_mac_aqua_get_metric(ListHeaderHeight));
#endif
        break;
    case QStyle::CT_MenuBar:
        if (sz == QStyleHelper::SizeLarge) {
            ret = QSize(-1, [[NSApp mainMenu] menuBarHeight]);
            // In the qt_mac_set_native_menubar(false) case,
            // we come it here with a zero-height main menu,
            // preventing the in-window menu from displaying.
            // Use 22 pixels for the height, by observation.
            if (ret.height() <= 0)
                ret.setHeight(22);
        }
        break;
    default:
        break;
    }
    return ret;
}


#if defined(QMAC_QAQUASTYLE_SIZE_CONSTRAIN) || defined(DEBUG_SIZE_CONSTRAINT)
static QStyleHelper::WidgetSizePolicy qt_aqua_guess_size(const QWidget *widg, QSize large, QSize small, QSize mini)
{
    Q_UNUSED(widg);

    if (large == QSize(-1, -1)) {
        if (small != QSize(-1, -1))
            return QStyleHelper::SizeSmall;
        if (mini != QSize(-1, -1))
            return QStyleHelper::SizeMini;
        return QStyleHelper::SizeDefault;
    } else if (small == QSize(-1, -1)) {
        if (mini != QSize(-1, -1))
            return QStyleHelper::SizeMini;
        return QStyleHelper::SizeLarge;
    } else if (mini == QSize(-1, -1)) {
        return QStyleHelper::SizeLarge;
    }

    if (qEnvironmentVariableIsSet("QWIDGET_ALL_SMALL"))
        return QStyleHelper::SizeSmall;
    else if (qEnvironmentVariableIsSet("QWIDGET_ALL_MINI"))
        return QStyleHelper::SizeMini;

    return QStyleHelper::SizeLarge;
}
#endif

void QMacStylePrivate::drawFocusRing(QPainter *p, const QRectF &targetRect, int hMargin, int vMargin, const CocoaControl &cw) const
{
    QPainterPath focusRingPath;
    focusRingPath.setFillRule(Qt::OddEvenFill);

    qreal hOffset = 0.0;
    qreal vOffset = 0.0;
    switch (cw.type) {
    case Box:
    case Button_SquareButton:
    case SegmentedControl_Middle:
    case TextField: {
        auto innerRect = targetRect;
        if (cw.type == TextField)
            innerRect = innerRect.adjusted(hMargin, vMargin, -hMargin, -vMargin).adjusted(0.5, 0.5, -0.5, -0.5);
        const auto outerRect = innerRect.adjusted(-focusRingWidth, -focusRingWidth, focusRingWidth, focusRingWidth);
        const auto outerRadius = focusRingWidth;
        focusRingPath.addRect(innerRect);
        focusRingPath.addRoundedRect(outerRect, outerRadius, outerRadius);
        break;
    }
    case Button_CheckBox: {
        const auto cbInnerRadius = (cw.size == QStyleHelper::SizeMini ? 2.0 : 3.0);
        const auto cbSize = cw.size == QStyleHelper::SizeLarge ? 13 :
                            cw.size == QStyleHelper::SizeSmall ? 11 : 9; // As measured
        hOffset = hMargin + (cw.size == QStyleHelper::SizeLarge ? 2.5 :
                             cw.size == QStyleHelper::SizeSmall ? 2.0 : 1.0); // As measured
        vOffset = 0.5 * qreal(targetRect.height() - cbSize);
        const auto cbInnerRect = QRectF(0, 0, cbSize, cbSize);
        const auto cbOuterRadius = cbInnerRadius + focusRingWidth;
        const auto cbOuterRect = cbInnerRect.adjusted(-focusRingWidth, -focusRingWidth, focusRingWidth, focusRingWidth);
        focusRingPath.addRoundedRect(cbOuterRect, cbOuterRadius, cbOuterRadius);
        focusRingPath.addRoundedRect(cbInnerRect, cbInnerRadius, cbInnerRadius);
        break;
    }
    case Button_RadioButton: {
        const auto rbSize = cw.size == QStyleHelper::SizeLarge ? 15 :
                            cw.size == QStyleHelper::SizeSmall ? 13 : 9; // As measured
        hOffset = hMargin + (cw.size == QStyleHelper::SizeLarge ? 1.5 :
                             cw.size == QStyleHelper::SizeSmall ? 1.0 : 1.0); // As measured
        vOffset = 0.5 * qreal(targetRect.height() - rbSize);
        const auto rbInnerRect = QRectF(0, 0, rbSize, rbSize);
        const auto rbOuterRect = rbInnerRect.adjusted(-focusRingWidth, -focusRingWidth, focusRingWidth, focusRingWidth);
        focusRingPath.addEllipse(rbInnerRect);
        focusRingPath.addEllipse(rbOuterRect);
        break;
    }
    case Button_PopupButton:
    case Button_PullDown:
    case Button_PushButton:
    case SegmentedControl_Single: {
        const qreal innerRadius = cw.type == Button_PushButton ? 3 : 4;
        const qreal outerRadius = innerRadius + focusRingWidth;
        hOffset = targetRect.left();
        vOffset = targetRect.top();
        const auto innerRect = targetRect.translated(-targetRect.topLeft());
        const auto outerRect = innerRect.adjusted(-hMargin, -vMargin, hMargin, vMargin);
        focusRingPath.addRoundedRect(innerRect, innerRadius, innerRadius);
        focusRingPath.addRoundedRect(outerRect, outerRadius, outerRadius);
        break;
    }
    case ComboBox:
    case SegmentedControl_First:
    case SegmentedControl_Last: {
        hOffset = targetRect.left();
        vOffset = targetRect.top();
        const qreal innerRadius = 8;
        const qreal outerRadius = innerRadius + focusRingWidth;
        const auto innerRect = targetRect.translated(-targetRect.topLeft());
        const auto outerRect = innerRect.adjusted(-hMargin, -vMargin, hMargin, vMargin);

        const auto cbFocusFramePath = [](const QRectF &rect, qreal tRadius, qreal bRadius) {
            QPainterPath path;

            if (tRadius > 0) {
                const auto topLeftCorner = QRectF(rect.topLeft(), QSizeF(tRadius, tRadius));
                path.arcMoveTo(topLeftCorner, 180);
                path.arcTo(topLeftCorner, 180, -90);
            } else {
                path.moveTo(rect.topLeft());
            }
            const auto rightEdge = rect.right() - bRadius;
            path.arcTo(rightEdge, rect.top(), bRadius, bRadius, 90, -90);
            path.arcTo(rightEdge, rect.bottom() - bRadius, bRadius, bRadius, 0, -90);
            if (tRadius > 0)
                path.arcTo(rect.left(), rect.bottom() - tRadius, tRadius, tRadius, 270, -90);
            else
                path.lineTo(rect.bottomLeft());
            path.closeSubpath();

            return path;
        };

        const auto innerPath = cbFocusFramePath(innerRect, 0, innerRadius);
        focusRingPath.addPath(innerPath);
        const auto outerPath = cbFocusFramePath(outerRect, 2 * focusRingWidth, outerRadius);
        focusRingPath.addPath(outerPath);
        break;
    }
    default:
        Q_UNREACHABLE();
    }

    auto focusRingColor = qt_mac_toQColor(NSColor.keyboardFocusIndicatorColor.CGColor);
    if (!qt_mac_applicationIsInDarkMode()) {
        // This color already has alpha ~ 0.25, this value is too small - the ring is
        // very pale and nothing like the native one. 0.39 makes it better (not ideal
        // anyway). The color seems to be correct in dark more without any modification.
        focusRingColor.setAlphaF(0.39);
    }

    p->save();
    p->setRenderHint(QPainter::Antialiasing);

    if (cw.type == SegmentedControl_First) {
        // TODO Flip left-right
    }
    p->translate(hOffset, vOffset);
    p->fillPath(focusRingPath, focusRingColor);
    p->restore();
}

QPainterPath QMacStylePrivate::windowPanelPath(const QRectF &r) const
{
    static const qreal CornerPointOffset = 5.5;
    static const qreal CornerControlOffset = 2.1;

    QPainterPath path;
    // Top-left corner
    path.moveTo(r.left(), r.top() + CornerPointOffset);
    path.cubicTo(r.left(), r.top() + CornerControlOffset,
                 r.left() + CornerControlOffset, r.top(),
                 r.left() + CornerPointOffset, r.top());
    // Top-right corner
    path.lineTo(r.right() - CornerPointOffset, r.top());
    path.cubicTo(r.right() - CornerControlOffset, r.top(),
                 r.right(), r.top() + CornerControlOffset,
                 r.right(), r.top() + CornerPointOffset);
    // Bottom-right corner
    path.lineTo(r.right(), r.bottom() - CornerPointOffset);
    path.cubicTo(r.right(), r.bottom() - CornerControlOffset,
                 r.right() - CornerControlOffset, r.bottom(),
                 r.right() - CornerPointOffset, r.bottom());
    // Bottom-right corner
    path.lineTo(r.left() + CornerPointOffset, r.bottom());
    path.cubicTo(r.left() + CornerControlOffset, r.bottom(),
                 r.left(), r.bottom() - CornerControlOffset,
                 r.left(), r.bottom() - CornerPointOffset);
    path.lineTo(r.left(), r.top() + CornerPointOffset);

    return path;
}

QMacStylePrivate::CocoaControlType QMacStylePrivate::windowButtonCocoaControl(QStyle::SubControl sc) const
{
    struct WindowButtons {
        QStyle::SubControl sc;
        QMacStylePrivate::CocoaControlType ct;
    };

    static const WindowButtons buttons[] = {
        { QStyle::SC_TitleBarCloseButton, QMacStylePrivate::Button_WindowClose },
        { QStyle::SC_TitleBarMinButton,   QMacStylePrivate::Button_WindowMiniaturize },
        { QStyle::SC_TitleBarMaxButton,   QMacStylePrivate::Button_WindowZoom }
    };

    for (const auto &wb : buttons)
        if (wb.sc == sc)
            return wb.ct;

    return NoControl;
}


#if QT_CONFIG(tabbar)
void QMacStylePrivate::tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const
{
    Q_ASSERT(textRect);
    Q_ASSERT(iconRect);
    QRect tr = opt->rect;
    const bool verticalTabs = opt->shape == QTabBar::RoundedEast
                              || opt->shape == QTabBar::RoundedWest
                              || opt->shape == QTabBar::TriangularEast
                              || opt->shape == QTabBar::TriangularWest;
    if (verticalTabs)
        tr.setRect(0, 0, tr.height(), tr.width()); // 0, 0 as we will have a translate transform

    int verticalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftVertical, opt, widget);
    int horizontalShift = proxyStyle->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, opt, widget);
    const int hpadding = 4;
    const int vpadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabVSpace, opt, widget) / 2;
    if (opt->shape == QTabBar::RoundedSouth || opt->shape == QTabBar::TriangularSouth)
        verticalShift = -verticalShift;
    tr.adjust(hpadding, verticalShift - vpadding, horizontalShift - hpadding, vpadding);

    // left widget
    if (!opt->leftButtonSize.isEmpty()) {
        const int buttonSize = verticalTabs ? opt->leftButtonSize.height() : opt->leftButtonSize.width();
        tr.setLeft(tr.left() + 4 + buttonSize);
        // make text aligned to center
        if (opt->rightButtonSize.isEmpty())
            tr.setRight(tr.right() - 4 - buttonSize);
    }
    // right widget
    if (!opt->rightButtonSize.isEmpty()) {
        const int buttonSize = verticalTabs ? opt->rightButtonSize.height() : opt->rightButtonSize.width();
        tr.setRight(tr.right() - 4 - buttonSize);
        // make text aligned to center
        if (opt->leftButtonSize.isEmpty())
            tr.setLeft(tr.left() + 4 + buttonSize);
    }

    // icon
    if (!opt->icon.isNull()) {
        QSize iconSize = opt->iconSize;
        if (!iconSize.isValid()) {
            int iconExtent = proxyStyle->pixelMetric(QStyle::PM_SmallIconSize);
            iconSize = QSize(iconExtent, iconExtent);
        }
        QSize tabIconSize = opt->icon.actualSize(iconSize,
                        (opt->state & QStyle::State_Enabled) ? QIcon::Normal : QIcon::Disabled,
                        (opt->state & QStyle::State_Selected) ? QIcon::On : QIcon::Off);
        // High-dpi icons do not need adjustment; make sure tabIconSize is not larger than iconSize
        tabIconSize = QSize(qMin(tabIconSize.width(), iconSize.width()), qMin(tabIconSize.height(), iconSize.height()));

        *iconRect = QRect(tr.left(), tr.center().y() - tabIconSize.height() / 2,
                    tabIconSize.width(), tabIconSize.height());
        if (!verticalTabs)
            *iconRect = proxyStyle->visualRect(opt->direction, opt->rect, *iconRect);

        int stylePadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabHSpace, opt, widget) / 2;
        stylePadding -= hpadding;

        tr.setLeft(tr.left() + stylePadding + tabIconSize.width() + 4);
        tr.setRight(tr.right() - stylePadding - tabIconSize.width() - 4);
    }

    if (!verticalTabs)
        tr = proxyStyle->visualRect(opt->direction, opt->rect, tr);

    *textRect = tr;
}

QMacStylePrivate::Direction QMacStylePrivate::tabDirection(QTabBar::Shape shape)
{
    switch (shape) {
    case QTabBar::RoundedSouth:
    case QTabBar::TriangularSouth:
        return South;
    case QTabBar::RoundedNorth:
    case QTabBar::TriangularNorth:
        return North;
    case QTabBar::RoundedWest:
    case QTabBar::TriangularWest:
        return West;
    case QTabBar::RoundedEast:
    case QTabBar::TriangularEast:
        return East;
    }
}

bool QMacStylePrivate::verticalTabs(QMacStylePrivate::Direction direction)
{
    return (direction == QMacStylePrivate::East
         || direction == QMacStylePrivate::West);
}

#endif // QT_CONFIG(tabbar)

QStyleHelper::WidgetSizePolicy QMacStylePrivate::effectiveAquaSizeConstrain(const QStyleOption *option,
                                                            const QWidget *widg,
                                                            QStyle::ContentsType ct,
                                                            QSize szHint, QSize *insz) const
{
    QStyleHelper::WidgetSizePolicy sz = aquaSizeConstrain(option, widg, ct, szHint, insz);
    if (sz == QStyleHelper::SizeDefault)
        return QStyleHelper::SizeLarge;
    return sz;
}

QStyleHelper::WidgetSizePolicy QMacStylePrivate::aquaSizeConstrain(const QStyleOption *option, const QWidget *widg,
                                       QStyle::ContentsType ct, QSize szHint, QSize *insz) const
{
#if defined(QMAC_QAQUASTYLE_SIZE_CONSTRAIN) || defined(DEBUG_SIZE_CONSTRAINT)
    if (option) {
        if (option->state & QStyle::State_Small)
            return QStyleHelper::SizeSmall;
        if (option->state & QStyle::State_Mini)
            return QStyleHelper::SizeMini;
    }

    if (!widg) {
        if (insz)
            *insz = QSize();
        if (qEnvironmentVariableIsSet("QWIDGET_ALL_SMALL"))
            return QStyleHelper::SizeSmall;
        if (qEnvironmentVariableIsSet("QWIDGET_ALL_MINI"))
            return QStyleHelper::SizeMini;
        return QStyleHelper::SizeDefault;
    }

    QSize large = qt_aqua_get_known_size(ct, widg, szHint, QStyleHelper::SizeLarge),
          small = qt_aqua_get_known_size(ct, widg, szHint, QStyleHelper::SizeSmall),
          mini  = qt_aqua_get_known_size(ct, widg, szHint, QStyleHelper::SizeMini);
    bool guess_size = false;
    QStyleHelper::WidgetSizePolicy ret = QStyleHelper::SizeDefault;
    QStyleHelper::WidgetSizePolicy wsp = QStyleHelper::widgetSizePolicy(widg);
    if (wsp == QStyleHelper::SizeDefault)
        guess_size = true;
    else if (wsp == QStyleHelper::SizeMini)
        ret = QStyleHelper::SizeMini;
    else if (wsp == QStyleHelper::SizeSmall)
        ret = QStyleHelper::SizeSmall;
    else if (wsp == QStyleHelper::SizeLarge)
        ret = QStyleHelper::SizeLarge;
    if (guess_size)
        ret = qt_aqua_guess_size(widg, large, small, mini);

    QSize *sz = 0;
    if (ret == QStyleHelper::SizeSmall)
        sz = &small;
    else if (ret == QStyleHelper::SizeLarge)
        sz = &large;
    else if (ret == QStyleHelper::SizeMini)
        sz = &mini;
    if (insz)
        *insz = sz ? *sz : QSize(-1, -1);
#ifdef DEBUG_SIZE_CONSTRAINT
    if (sz) {
        const char *size_desc = "Unknown";
        if (sz == &small)
            size_desc = "Small";
        else if (sz == &large)
            size_desc = "Large";
        else if (sz == &mini)
            size_desc = "Mini";
        qDebug("%s - %s: %s taken (%d, %d) [%d, %d]",
               widg ? widg->objectName().toLatin1().constData() : "*Unknown*",
               widg ? widg->metaObject()->className() : "*Unknown*", size_desc, widg->width(), widg->height(),
               sz->width(), sz->height());
    }
#endif
    return ret;
#else
    if (insz)
        *insz = QSize();
    Q_UNUSED(widg);
    Q_UNUSED(ct);
    Q_UNUSED(szHint);
    return QStyleHelper::SizeDefault;
#endif
}

uint qHash(const QMacStylePrivate::CocoaControl &cw, uint seed = 0)
{
    return ((cw.type << 2) | cw.size) ^ seed;
}

QMacStylePrivate::CocoaControl::CocoaControl()
  : type(NoControl), size(QStyleHelper::SizeDefault)
{
}

QMacStylePrivate::CocoaControl::CocoaControl(CocoaControlType t, QStyleHelper::WidgetSizePolicy s)
    : type(t), size(s)
{
}

bool QMacStylePrivate::CocoaControl::operator==(const CocoaControl &other) const
{
    return other.type == type && other.size == size;
}

QSizeF QMacStylePrivate::CocoaControl::defaultFrameSize() const
{
    // We need this because things like NSView.alignmentRectInsets
    // or -[NSCell titleRectForBounds:] won't work unless the control
    // has a reasonable frame set. IOW, it's a chicken and egg problem.
    // These values are as observed in Xcode 9's Interface Builder.

    if (type == Button_PushButton)
        return QSizeF(-1, pushButtonDefaultHeight[size]);

    if (type == Button_PopupButton
            || type == Button_PullDown)
        return QSizeF(-1, popupButtonDefaultHeight[size]);

    if (type == ComboBox)
        return QSizeF(-1, comboBoxDefaultHeight[size]);

    return QSizeF();
}

QRectF QMacStylePrivate::CocoaControl::adjustedControlFrame(const QRectF &rect) const
{
    QRectF frameRect;
    const auto frameSize = defaultFrameSize();
    if (type == QMacStylePrivate::Button_SquareButton) {
        frameRect = rect.adjusted(3, 1, -3, -1)
                        .adjusted(focusRingWidth, focusRingWidth, -focusRingWidth, -focusRingWidth);
    } else if (type == QMacStylePrivate::Button_PushButton) {
        // Start from the style option's top-left corner.
        frameRect = QRectF(rect.topLeft(),
                           QSizeF(rect.width(), frameSize.height()));
        if (size == QStyleHelper::SizeSmall)
            frameRect = frameRect.translated(0, 1.5);
        else if (size == QStyleHelper::SizeMini)
            frameRect = frameRect.adjusted(0, 0, -8, 0).translated(4, 4);
    } else {
        // Center in the style option's rect.
        frameRect = QRectF(QPointF(0, (rect.height() - frameSize.height()) / 2.0),
                           QSizeF(rect.width(), frameSize.height()));
        frameRect = frameRect.translated(rect.topLeft());
        if (type == QMacStylePrivate::Button_PullDown || type == QMacStylePrivate::Button_PopupButton) {
            if (size == QStyleHelper::SizeLarge)
                frameRect = frameRect.adjusted(0, 0, -6, 0).translated(3, 0);
            else if (size == QStyleHelper::SizeSmall)
                frameRect = frameRect.adjusted(0, 0, -4, 0).translated(2, 1);
            else if (size == QStyleHelper::SizeMini)
                frameRect = frameRect.adjusted(0, 0, -9, 0).translated(5, 0);
        } else if (type == QMacStylePrivate::ComboBox) {
            frameRect = frameRect.adjusted(0, 0, -6, 0).translated(4, 0);
        }
    }

    return frameRect;
}

QMarginsF QMacStylePrivate::CocoaControl::titleMargins() const
{
    if (type == QMacStylePrivate::Button_PushButton) {
        if (size == QStyleHelper::SizeLarge)
            return QMarginsF(12, 5, 12, 9);
        if (size == QStyleHelper::SizeSmall)
            return QMarginsF(12, 4, 12, 9);
        if (size == QStyleHelper::SizeMini)
            return QMarginsF(10, 1, 10, 2);
    }

    if (type == QMacStylePrivate::Button_PullDown) {
        if (size == QStyleHelper::SizeLarge)
            return QMarginsF(7.5, 2.5, 22.5, 5.5);
        if (size == QStyleHelper::SizeSmall)
            return QMarginsF(7.5, 2, 20.5, 4);
        if (size == QStyleHelper::SizeMini)
            return QMarginsF(4.5, 0, 16.5, 2);
    }

    if (type == QMacStylePrivate::Button_SquareButton)
        return QMarginsF(6, 1, 6, 2);

    return QMarginsF();
}

bool QMacStylePrivate::CocoaControl::getCocoaButtonTypeAndBezelStyle(NSButtonType *buttonType, NSBezelStyle *bezelStyle) const
{
    switch (type) {
    case Button_CheckBox:
        *buttonType = NSSwitchButton;
        *bezelStyle = NSRegularSquareBezelStyle;
        break;
    case Button_Disclosure:
        *buttonType = NSOnOffButton;
        *bezelStyle = NSDisclosureBezelStyle;
        break;
    case Button_RadioButton:
        *buttonType = NSRadioButton;
        *bezelStyle = NSRegularSquareBezelStyle;
        break;
    case Button_SquareButton:
        *buttonType = NSPushOnPushOffButton;
        *bezelStyle = NSShadowlessSquareBezelStyle;
        break;
    case Button_PushButton:
        *buttonType = NSPushOnPushOffButton;
        *bezelStyle = NSRoundedBezelStyle;
        break;
    default:
        return false;
    }

    return true;
}

QMacStylePrivate::CocoaControlType cocoaControlType(const QStyleOption *opt, const QWidget *w)
{
    if (const auto *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
        const bool hasMenu = btn->features & QStyleOptionButton::HasMenu;
        // When the contents won't fit in a large sized button,
        // and WA_MacNormalSize is not set, make the button square.
        // Threshold used to be at 34, not 32.
        const auto maxNonSquareHeight = pushButtonDefaultHeight[QStyleHelper::SizeLarge];
        const bool isSquare = (btn->features & QStyleOptionButton::Flat)
                || (btn->rect.height() > maxNonSquareHeight
                    && !(w && w->testAttribute(Qt::WA_MacNormalSize)));
        return (isSquare? QMacStylePrivate::Button_SquareButton :
                hasMenu ? QMacStylePrivate::Button_PullDown :
                QMacStylePrivate::Button_PushButton);
    }

    if (const auto *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
        if (combo->editable)
            return QMacStylePrivate::ComboBox;
        // TODO Me may support square, non-editable combo boxes, but not more than that
        return QMacStylePrivate::Button_PopupButton;
    }

    return QMacStylePrivate::NoControl;
}

/**
    Carbon draws comboboxes (and other views) outside the rect given as argument. Use this function to obtain
    the corresponding inner rect for drawing the same combobox so that it stays inside the given outerBounds.
*/
CGRect QMacStylePrivate::comboboxInnerBounds(const CGRect &outerBounds, const CocoaControl &cocoaWidget)
{
    CGRect innerBounds = outerBounds;
    // Carbon draw parts of the view outside the rect.
    // So make the rect a bit smaller to compensate
    // (I wish HIThemeGetButtonBackgroundBounds worked)
    if (cocoaWidget.type == Button_PopupButton) {
        switch (cocoaWidget.size) {
        case QStyleHelper::SizeSmall:
            innerBounds.origin.x += 3;
            innerBounds.origin.y += 3;
            innerBounds.size.width -= 6;
            innerBounds.size.height -= 7;
            break;
        case QStyleHelper::SizeMini:
            innerBounds.origin.x += 2;
            innerBounds.origin.y += 2;
            innerBounds.size.width -= 5;
            innerBounds.size.height -= 6;
            break;
        case QStyleHelper::SizeLarge:
        case QStyleHelper::SizeDefault:
            innerBounds.origin.x += 2;
            innerBounds.origin.y += 2;
            innerBounds.size.width -= 5;
            innerBounds.size.height -= 6;
        }
    } else if (cocoaWidget.type == ComboBox) {
        switch (cocoaWidget.size) {
        case QStyleHelper::SizeSmall:
            innerBounds.origin.x += 3;
            innerBounds.origin.y += 3;
            innerBounds.size.width -= 7;
            innerBounds.size.height -= 8;
            break;
        case QStyleHelper::SizeMini:
            innerBounds.origin.x += 3;
            innerBounds.origin.y += 3;
            innerBounds.size.width -= 4;
            innerBounds.size.height -= 8;
            break;
        case QStyleHelper::SizeLarge:
        case QStyleHelper::SizeDefault:
            innerBounds.origin.x += 3;
            innerBounds.origin.y += 2;
            innerBounds.size.width -= 6;
            innerBounds.size.height -= 8;
        }
    }

    return innerBounds;
}

/**
    Inside a combobox Qt places a line edit widget. The size of this widget should depend on the kind
    of combobox we choose to draw. This function calculates and returns this size.
*/
QRectF QMacStylePrivate::comboboxEditBounds(const QRectF &outerBounds, const CocoaControl &cw)
{
    QRectF ret = outerBounds;
    if (cw.type == ComboBox) {
        switch (cw.size) {
        case QStyleHelper::SizeLarge:
            ret = ret.adjusted(0, 0, -25, 0).translated(2, 4.5);
            ret.setHeight(16);
            break;
        case QStyleHelper::SizeSmall:
            ret = ret.adjusted(0, 0, -22, 0).translated(2, 3);
            ret.setHeight(14);
            break;
        case QStyleHelper::SizeMini:
            ret = ret.adjusted(0, 0, -19, 0).translated(2, 2.5);
            ret.setHeight(10.5);
            break;
        default:
            break;
        }
    } else if (cw.type == Button_PopupButton) {
        switch (cw.size) {
        case QStyleHelper::SizeLarge:
            ret.adjust(10, 1, -23, -4);
            break;
        case QStyleHelper::SizeSmall:
            ret.adjust(10, 4, -20, -3);
            break;
        case QStyleHelper::SizeMini:
            ret.adjust(9, 0, -19, 0);
            ret.setHeight(13);
            break;
        default:
            break;
        }
    }
    return ret;
}

QMacStylePrivate::QMacStylePrivate()
    : backingStoreNSView(nil)
{
    if (auto *ssf = QGuiApplicationPrivate::platformTheme()->font(QPlatformTheme::SmallFont))
        smallSystemFont = *ssf;
    if (auto *msf = QGuiApplicationPrivate::platformTheme()->font(QPlatformTheme::MiniFont))
        miniSystemFont = *msf;
}

QMacStylePrivate::~QMacStylePrivate()
{
    QMacAutoReleasePool pool;
    for (NSView *b : cocoaControls)
        [b release];
    for (NSCell *cell : cocoaCells)
        [cell release];
}

NSView *QMacStylePrivate::cocoaControl(CocoaControl widget) const
{
    if (widget.type == QMacStylePrivate::NoControl
        || widget.size == QStyleHelper::SizeDefault)
        return nil;

    if (widget.type == Box) {
        if (__builtin_available(macOS 10.14, *)) {
            if (qt_mac_applicationIsInDarkMode()) {
                // See render code in drawPrimitive(PE_FrameTabWidget)
                widget.type = Box_Dark;
            }
        }
    }

    NSView *bv = cocoaControls.value(widget, nil);
    if (!bv) {
        switch (widget.type) {
        case Box: {
            NSBox *box = [[NSBox alloc] init];
            bv = box;
            box.title = @"";
            box.titlePosition = NSNoTitle;
            break;
        }
        case Box_Dark:
            bv = [[QDarkNSBox alloc] init];
            break;
        case Button_CheckBox:
        case Button_Disclosure:
        case Button_PushButton:
        case Button_RadioButton:
        case Button_SquareButton: {
            NSButton *bc = [[NSButton alloc] init];
            bc.title = @"";
            // See below for style and bezel setting.
            bv = bc;
            break;
        }
        case Button_PopupButton:
        case Button_PullDown: {
            NSPopUpButton *bc = [[NSPopUpButton alloc] init];
            bc.title = @"";
            if (widget.type == Button_PullDown)
                bc.pullsDown = YES;
            bv = bc;
            break;
        }
        case Button_WindowClose:
        case Button_WindowMiniaturize:
        case Button_WindowZoom: {
            const NSWindowButton button = [=] {
                switch (widget.type) {
                case Button_WindowClose:
                    return NSWindowCloseButton;
                case Button_WindowMiniaturize:
                    return NSWindowMiniaturizeButton;
                case Button_WindowZoom:
                    return NSWindowZoomButton;
                default:
                    break;
                }
                Q_UNREACHABLE();
            } ();
            const auto styleMask = NSWindowStyleMaskTitled
                                 | NSWindowStyleMaskClosable
                                 | NSWindowStyleMaskMiniaturizable
                                 | NSWindowStyleMaskResizable;
            bv = [NSWindow standardWindowButton:button forStyleMask:styleMask];
            [bv retain];
            break;
        }
        case ComboBox:
            bv = [[NSComboBox alloc] init];
            break;
        case ProgressIndicator_Determinate:
            bv = [[NSProgressIndicator alloc] init];
            break;
        case ProgressIndicator_Indeterminate:
            bv = [[QIndeterminateProgressIndicator alloc] init];
            break;
        case Scroller_Horizontal:
            bv = [[NSScroller alloc] initWithFrame:NSMakeRect(0, 0, 200, 20)];
            break;
        case Scroller_Vertical:
            // Cocoa sets the orientation from the view's frame
            // at construction time, and it cannot be changed later.
            bv = [[NSScroller alloc] initWithFrame:NSMakeRect(0, 0, 20, 200)];
            break;
        case Slider_Horizontal:
            bv = [[NSSlider alloc] initWithFrame:NSMakeRect(0, 0, 200, 20)];
            break;
        case Slider_Vertical:
            // Cocoa sets the orientation from the view's frame
            // at construction time, and it cannot be changed later.
            bv = [[NSSlider alloc] initWithFrame:NSMakeRect(0, 0, 20, 200)];
            break;
        case SplitView_Horizontal:
            bv = [[NSSplitView alloc] init];
            break;
        case SplitView_Vertical:
            bv = [[QVerticalSplitView alloc] init];
            break;
        case TextField:
            bv = [[NSTextField alloc] init];
            break;
        default:
            break;
        }

        if ([bv isKindOfClass:[NSControl class]]) {
            auto *ctrl = static_cast<NSControl *>(bv);
            switch (widget.size) {
            case QStyleHelper::SizeSmall:
                ctrl.controlSize = NSControlSizeSmall;
                break;
            case QStyleHelper::SizeMini:
                ctrl.controlSize = NSControlSizeMini;
                break;
            default:
                break;
            }
        } else if (widget.type == ProgressIndicator_Determinate ||
                   widget.type == ProgressIndicator_Indeterminate) {
            auto *pi = static_cast<NSProgressIndicator *>(bv);
            pi.indeterminate = (widget.type == ProgressIndicator_Indeterminate);
            switch (widget.size) {
            case QStyleHelper::SizeSmall:
                pi.controlSize = NSControlSizeSmall;
                break;
            case QStyleHelper::SizeMini:
                pi.controlSize = NSControlSizeMini;
                break;
            default:
                break;
            }
        }

        cocoaControls.insert(widget, bv);
    }

    NSButtonType buttonType;
    NSBezelStyle bezelStyle;
    if (widget.getCocoaButtonTypeAndBezelStyle(&buttonType, &bezelStyle)) {
        // FIXME We need to reset the button's type and
        // bezel style properties, even when cached.
        auto *button = static_cast<NSButton *>(bv);
        button.buttonType = buttonType;
        button.bezelStyle = bezelStyle;
        if (widget.type == Button_CheckBox)
            button.allowsMixedState = YES;
    }

    return bv;
}

NSCell *QMacStylePrivate::cocoaCell(CocoaControl widget) const
{
    NSCell *cell = cocoaCells[widget];
    if (!cell) {
        switch (widget.type) {
        case Stepper:
            cell = [[NSStepperCell alloc] init];
            break;
        case Button_Disclosure: {
            NSButtonCell *bc = [[NSButtonCell alloc] init];
            bc.buttonType = NSOnOffButton;
            bc.bezelStyle = NSDisclosureBezelStyle;
            cell = bc;
            break;
        }
        default:
            break;
        }

        switch (widget.size) {
        case QStyleHelper::SizeSmall:
            cell.controlSize = NSControlSizeSmall;
            break;
        case QStyleHelper::SizeMini:
            cell.controlSize = NSControlSizeMini;
            break;
        default:
            break;
        }

        cocoaCells.insert(widget, cell);
    }

    return cell;
}

void QMacStylePrivate::drawNSViewInRect(NSView *view, const QRectF &rect, QPainter *p,
                                        __attribute__((noescape)) DrawRectBlock drawRectBlock) const
{
    QMacCGContext ctx(p);
    setupNSGraphicsContext(ctx, YES);

    // FIXME: The rect that we get in is relative to the widget that we're drawing
    // style on behalf of, and doesn't take into account the offset of that widget
    // to the widget that owns the backingstore, which we are placing the native
    // view into below. This means most of the views are placed in the upper left
    // corner of backingStoreNSView, which does not map to where the actual widget
    // is, and which may cause problems such as triggering a setNeedsDisplay of the
    // backingStoreNSView for the wrong rect. We work around this by making the view
    // layer-backed, which prevents triggering display of the backingStoreNSView, but
    // but there may be other issues lurking here due to the wrong position. QTBUG-68023
    view.wantsLayer = YES;

    // FIXME: We are also setting the frame of the incoming view a lot at the call
    // sites of this function, making it unclear who's actually responsible for
    // maintaining the size and position of the view. In theory the call sites
    // should ensure the _size_ of the view is correct, and then let this code
    // take care of _positioning_ the view at the right place inside backingStoreNSView.
    // For now we pass on the rect as is, to prevent any regressions until this
    // can be investigated properly.
    view.frame = rect.toCGRect();

    [backingStoreNSView addSubview:view];

    // FIXME: Based on the code below, this method isn't drawing an NSView into
    // a rect, it's drawing _part of the NSView_, defined by the incoming clip
    // or dirty rect, into the current graphics context. We're doing some manual
    // translations at the call sites that would indicate that this relationship
    // is a bit fuzzy.
    const CGRect dirtyRect = rect.toCGRect();

    if (drawRectBlock)
        drawRectBlock(ctx, dirtyRect);
    else
        [view drawRect:dirtyRect];

    [view removeFromSuperviewWithoutNeedingDisplay];

    restoreNSGraphicsContext(ctx);
}

void QMacStylePrivate::resolveCurrentNSView(QWindow *window) const
{
    backingStoreNSView = window ? (NSView *)window->winId() : nil;
}

QMacStyle::QMacStyle()
    : QCommonStyle(*new QMacStylePrivate)
{
    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);
    });

#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14)
    Q_D(QMacStyle);
    // FIXME: Tie this logic into theme change, or even polish/unpolish
    if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave) {
        d->appearanceObserver = QMacKeyValueObserver(NSApp, @"effectiveAppearance", [this] {
            Q_D(QMacStyle);
            for (NSView *b : d->cocoaControls)
                [b release];
            d->cocoaControls.clear();
        });
    }
#endif
}

QMacStyle::~QMacStyle()
{
}

void QMacStyle::polish(QPalette &)
{
}

void QMacStyle::polish(QApplication *)
{
}

void QMacStyle::unpolish(QApplication *)
{
}

void QMacStyle::polish(QWidget* w)
{
    if (false
#if QT_CONFIG(menu)
        || qobject_cast<QMenu*>(w)
#  if QT_CONFIG(combobox)
        || qobject_cast<QComboBoxPrivateContainer *>(w)
#  endif
#endif
#if QT_CONFIG(mdiarea)
        || qobject_cast<QMdiSubWindow *>(w)
#endif
        ) {
        w->setAttribute(Qt::WA_TranslucentBackground, true);
        w->setAutoFillBackground(false);
    }

#if QT_CONFIG(tabbar)
    if (QTabBar *tb = qobject_cast<QTabBar*>(w)) {
        if (tb->documentMode()) {
            w->setAttribute(Qt::WA_Hover);
            w->setFont(qt_app_fonts_hash()->value("QSmallFont", QFont()));
            QPalette p = w->palette();
            p.setColor(QPalette::WindowText, QColor(17, 17, 17));
            w->setPalette(p);
            w->setAttribute(Qt::WA_SetPalette, false);
            w->setAttribute(Qt::WA_SetFont, false);
        }
    }
#endif

    QCommonStyle::polish(w);

    if (QRubberBand *rubber = qobject_cast<QRubberBand*>(w)) {
        rubber->setWindowOpacity(0.25);
        rubber->setAttribute(Qt::WA_PaintOnScreen, false);
        rubber->setAttribute(Qt::WA_NoSystemBackground, false);
    }

    if (qobject_cast<QScrollBar*>(w)) {
        w->setAttribute(Qt::WA_OpaquePaintEvent, false);
        w->setAttribute(Qt::WA_Hover, true);
        w->setMouseTracking(true);
    }
}

void QMacStyle::unpolish(QWidget* w)
{
    if (
#if QT_CONFIG(menu)
        qobject_cast<QMenu*>(w) &&
#endif
        !w->testAttribute(Qt::WA_SetPalette))
    {
        w->setPalette(QPalette());
        w->setWindowOpacity(1.0);
    }

#if QT_CONFIG(combobox)
    if (QComboBox *combo = qobject_cast<QComboBox *>(w)) {
        if (!combo->isEditable()) {
            if (QWidget *widget = combo->findChild<QComboBoxPrivateContainer *>())
                widget->setWindowOpacity(1.0);
        }
    }
#endif

#if QT_CONFIG(tabbar)
    if (qobject_cast<QTabBar*>(w)) {
        if (!w->testAttribute(Qt::WA_SetFont))
            w->setFont(QFont());
        if (!w->testAttribute(Qt::WA_SetPalette))
            w->setPalette(QPalette());
    }
#endif

    if (QRubberBand *rubber = qobject_cast<QRubberBand*>(w)) {
        rubber->setWindowOpacity(1.0);
        rubber->setAttribute(Qt::WA_PaintOnScreen, true);
        rubber->setAttribute(Qt::WA_NoSystemBackground, true);
    }

    if (QFocusFrame *frame = qobject_cast<QFocusFrame *>(w))
        frame->setAttribute(Qt::WA_NoSystemBackground, true);

    QCommonStyle::unpolish(w);

    if (qobject_cast<QScrollBar*>(w)) {
        w->setAttribute(Qt::WA_OpaquePaintEvent, true);
        w->setAttribute(Qt::WA_Hover, false);
        w->setMouseTracking(false);
    }
}

int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QWidget *widget) const
{
    Q_D(const QMacStyle);
    const int controlSize = getControlSize(opt, widget);
    int ret = 0;

    switch (metric) {
#if QT_CONFIG(tabbar)
    case PM_TabCloseIndicatorWidth:
    case PM_TabCloseIndicatorHeight:
        ret = closeButtonSize;
        break;
#endif
    case PM_ToolBarIconSize:
        ret = proxy()->pixelMetric(PM_LargeIconSize);
        break;
    case PM_FocusFrameVMargin:
    case PM_FocusFrameHMargin:
        ret = qt_mac_aqua_get_metric(FocusRectOutset);
        break;
    case PM_DialogButtonsSeparator:
        ret = -5;
        break;
    case PM_DialogButtonsButtonHeight: {
        QSize sz;
        ret = d->aquaSizeConstrain(opt, 0, QStyle::CT_PushButton, QSize(-1, -1), &sz);
        if (sz == QSize(-1, -1))
            ret = 32;
        else
            ret = sz.height();
        break; }
    case PM_DialogButtonsButtonWidth: {
        QSize sz;
        ret = d->aquaSizeConstrain(opt, 0, QStyle::CT_PushButton, QSize(-1, -1), &sz);
        if (sz == QSize(-1, -1))
            ret = 70;
        else
            ret = sz.width();
        break; }

    case PM_MenuBarHMargin:
        ret = 8;
        break;

    case PM_MenuBarVMargin:
        ret = 0;
        break;

    case PM_MenuBarPanelWidth:
        ret = 0;
        break;

    case PM_MenuButtonIndicator:
        ret = toolButtonArrowSize;
        break;

    case QStyle::PM_MenuDesktopFrameWidth:
        ret = 5;
        break;

    case PM_CheckBoxLabelSpacing:
    case PM_RadioButtonLabelSpacing:
        ret = [=] {
            if (opt) {
                if (opt->state & State_Mini)
                    return 4;
                if (opt->state & State_Small)
                    return 3;
            }
            return 2;
        } ();
        break;
    case PM_MenuScrollerHeight:
        ret = 15; // I hate having magic numbers in here...
        break;
    case PM_DefaultFrameWidth:
#if QT_CONFIG(mainwindow)
        if (widget && (widget->isWindow() || !widget->parentWidget()
                || (qobject_cast<const QMainWindow*>(widget->parentWidget())
                   && static_cast<QMainWindow *>(widget->parentWidget())->centralWidget() == widget))
                && qobject_cast<const QAbstractScrollArea *>(widget))
            ret = 0;
        else
#endif
        // The combo box popup has no frame.
        if (qstyleoption_cast<const QStyleOptionComboBox *>(opt) != 0)
            ret = 0;
        else
            ret = 1;
        break;
    case PM_MaximumDragDistance:
        ret = -1;
        break;
    case PM_ScrollBarSliderMin:
        ret = 24;
        break;
    case PM_SpinBoxFrameWidth:
        ret = qt_mac_aqua_get_metric(EditTextFrameOutset);
        break;
    case PM_ButtonShiftHorizontal:
    case PM_ButtonShiftVertical:
        ret = 0;
        break;
    case PM_SliderLength:
        ret = 17;
        break;
        // Returns the number of pixels to use for the business part of the
        // slider (i.e., the non-tickmark portion). The remaining space is shared
        // equally between the tickmark regions.
    case PM_SliderControlThickness:
        if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
            int space = (sl->orientation == Qt::Horizontal) ? sl->rect.height() : sl->rect.width();
            int ticks = sl->tickPosition;
            int n = 0;
            if (ticks & QSlider::TicksAbove)
                ++n;
            if (ticks & QSlider::TicksBelow)
                ++n;
            if (!n) {
                ret = space;
                break;
            }

            int thick = 6;        // Magic constant to get 5 + 16 + 5
            if (ticks != QSlider::TicksBothSides && ticks != QSlider::NoTicks)
                thick += proxy()->pixelMetric(PM_SliderLength, sl, widget) / 4;

            space -= thick;
            if (space > 0)
                thick += (space * 2) / (n + 2);
            ret = thick;
        } else {
            ret = 0;
        }
        break;
    case PM_SmallIconSize:
        ret = int(QStyleHelper::dpiScaled(16., opt));
        break;

    case PM_LargeIconSize:
        ret = int(QStyleHelper::dpiScaled(32., opt));
        break;

    case PM_IconViewIconSize:
        ret = proxy()->pixelMetric(PM_LargeIconSize, opt, widget);
        break;

    case PM_ButtonDefaultIndicator:
        ret = 0;
        break;
    case PM_TitleBarHeight: {
        NSUInteger style = NSWindowStyleMaskTitled;
        if (widget && ((widget->windowFlags() & Qt::Tool) == Qt::Tool))
            style |= NSWindowStyleMaskUtilityWindow;
        ret = int([NSWindow frameRectForContentRect:NSZeroRect
                                          styleMask:style].size.height);
        break; }
    case QStyle::PM_TabBarTabHSpace:
        switch (d->aquaSizeConstrain(opt, widget)) {
        case QStyleHelper::SizeLarge:
            ret = QCommonStyle::pixelMetric(metric, opt, widget);
            break;
        case QStyleHelper::SizeSmall:
            ret = 20;
            break;
        case QStyleHelper::SizeMini:
            ret = 16;
            break;
        case QStyleHelper::SizeDefault:
#if QT_CONFIG(tabbar)
            const QStyleOptionTab *tb = qstyleoption_cast<const QStyleOptionTab *>(opt);
            if (tb && tb->documentMode)
                ret = 30;
            else
#endif
                ret = QCommonStyle::pixelMetric(metric, opt, widget);
            break;
        }
        break;
    case PM_TabBarTabVSpace:
        ret = 4;
        break;
    case PM_TabBarTabShiftHorizontal:
    case PM_TabBarTabShiftVertical:
        ret = 0;
        break;
    case PM_TabBarBaseHeight:
        ret = 0;
        break;
    case PM_TabBarTabOverlap:
        ret = 1;
        break;
    case PM_TabBarBaseOverlap:
        switch (d->aquaSizeConstrain(opt, widget)) {
        case QStyleHelper::SizeDefault:
        case QStyleHelper::SizeLarge:
            ret = 11;
            break;
        case QStyleHelper::SizeSmall:
            ret = 8;
            break;
        case QStyleHelper::SizeMini:
            ret = 7;
            break;
        }
        break;
    case PM_ScrollBarExtent: {
        const QStyleHelper::WidgetSizePolicy size = d->effectiveAquaSizeConstrain(opt, widget);
        ret = static_cast<int>([NSScroller
            scrollerWidthForControlSize:static_cast<NSControlSize>(size)
                          scrollerStyle:[NSScroller preferredScrollerStyle]]);
        break; }
    case PM_IndicatorHeight: {
        switch (d->aquaSizeConstrain(opt, widget)) {
        case QStyleHelper::SizeDefault:
        case QStyleHelper::SizeLarge:
            ret = qt_mac_aqua_get_metric(CheckBoxHeight);
            break;
        case QStyleHelper::SizeMini:
            ret = qt_mac_aqua_get_metric(MiniCheckBoxHeight);
            break;
        case QStyleHelper::SizeSmall:
            ret = qt_mac_aqua_get_metric(SmallCheckBoxHeight);
            break;
        }
        break; }
    case PM_IndicatorWidth: {
        switch (d->aquaSizeConstrain(opt, widget)) {
        case QStyleHelper::SizeDefault:
        case QStyleHelper::SizeLarge:
            ret = qt_mac_aqua_get_metric(CheckBoxWidth);
            break;
        case QStyleHelper::SizeMini:
            ret = qt_mac_aqua_get_metric(MiniCheckBoxWidth);
            break;
        case QStyleHelper::SizeSmall:
            ret = qt_mac_aqua_get_metric(SmallCheckBoxWidth);
            break;
        }
        ++ret;
        break; }
    case PM_ExclusiveIndicatorHeight: {
        switch (d->aquaSizeConstrain(opt, widget)) {
        case QStyleHelper::SizeDefault:
        case QStyleHelper::SizeLarge:
            ret = qt_mac_aqua_get_metric(RadioButtonHeight);
            break;
        case QStyleHelper::SizeMini:
            ret = qt_mac_aqua_get_metric(MiniRadioButtonHeight);
            break;
        case QStyleHelper::SizeSmall:
            ret = qt_mac_aqua_get_metric(SmallRadioButtonHeight);
            break;
        }
        break; }
    case PM_ExclusiveIndicatorWidth: {
        switch (d->aquaSizeConstrain(opt, widget)) {
        case QStyleHelper::SizeDefault:
        case QStyleHelper::SizeLarge:
            ret = qt_mac_aqua_get_metric(RadioButtonWidth);
            break;
        case QStyleHelper::SizeMini:
            ret = qt_mac_aqua_get_metric(MiniRadioButtonWidth);
            break;
        case QStyleHelper::SizeSmall:
            ret = qt_mac_aqua_get_metric(SmallRadioButtonWidth);
            break;
        }
        ++ret;
        break; }
    case PM_MenuVMargin:
        ret = 4;
        break;
    case PM_MenuPanelWidth:
        ret = 0;
        break;
    case PM_ToolTipLabelFrameWidth:
        ret = 0;
        break;
    case PM_SizeGripSize: {
        QStyleHelper::WidgetSizePolicy aSize;
        if (widget && widget->window()->windowType() == Qt::Tool)
            aSize = QStyleHelper::SizeSmall;
        else
            aSize = QStyleHelper::SizeLarge;
        const QSize size = qt_aqua_get_known_size(CT_SizeGrip, widget, QSize(), aSize);
        ret = size.width();
        break; }
    case PM_MdiSubWindowFrameWidth:
        ret = 1;
        break;
    case PM_DockWidgetFrameWidth:
        ret = 0;
        break;
    case PM_DockWidgetTitleMargin:
        ret = 0;
        break;
    case PM_DockWidgetSeparatorExtent:
        ret = 1;
        break;
    case PM_ToolBarHandleExtent:
        ret = 11;
        break;
    case PM_ToolBarItemMargin:
        ret = 0;
        break;
    case PM_ToolBarItemSpacing:
        ret = 4;
        break;
    case PM_SplitterWidth:
        ret = qMax(7, QApplication::globalStrut().width());
        break;
    case PM_LayoutLeftMargin:
    case PM_LayoutTopMargin:
    case PM_LayoutRightMargin:
    case PM_LayoutBottomMargin:
        {
            bool isWindow = false;
            if (opt) {
                isWindow = (opt->state & State_Window);
            } else if (widget) {
                isWindow = widget->isWindow();
            }

            if (isWindow) {
                /*
                    AHIG would have (20, 8, 10) here but that makes
                    no sense. It would also have 14 for the top margin
                    but this contradicts both Builder and most
                    applications.
                */
                return_SIZE(20, 10, 10);    // AHIG
            } else {
                // hack to detect QTabWidget
                if (widget && widget->parentWidget()
                        && widget->parentWidget()->sizePolicy().controlType() == QSizePolicy::TabWidget) {
                    if (metric == PM_LayoutTopMargin) {
                        /*
                            Builder would have 14 (= 20 - 6) instead of 12,
                            but that makes the tab look disproportionate.
                        */
                        return_SIZE(12, 6, 6);  // guess
                    } else {
                        return_SIZE(20 /* Builder */, 8 /* guess */, 8 /* guess */);
                    }
                } else {
                    /*
                        Child margins are highly inconsistent in AHIG and Builder.
                    */
                    return_SIZE(12, 8, 6);    // guess
                }
            }
        }
    case PM_LayoutHorizontalSpacing:
    case PM_LayoutVerticalSpacing:
        return -1;
    case PM_MenuHMargin:
        ret = 0;
        break;
    case PM_ToolBarExtensionExtent:
        ret = 21;
        break;
    case PM_ToolBarFrameWidth:
        ret = 1;
        break;
    case PM_ScrollView_ScrollBarOverlap:
        ret = [NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay ?
               pixelMetric(PM_ScrollBarExtent, opt, widget) : 0;
        break;
    default:
        ret = QCommonStyle::pixelMetric(metric, opt, widget);
        break;
    }
    return ret;
}

QPalette QMacStyle::standardPalette() const
{
    auto platformTheme = QGuiApplicationPrivate::platformTheme();
    auto styleNames = platformTheme->themeHint(QPlatformTheme::StyleNames);
    if (styleNames.toStringList().contains("macintosh"))
        return *platformTheme->palette();
    else
        return QStyle::standardPalette();
}

int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w,
                         QStyleHintReturn *hret) const
{
    QMacAutoReleasePool pool;

    int ret = 0;
    switch (sh) {
    case SH_Slider_SnapToValue:
    case SH_PrintDialog_RightAlignButtons:
    case SH_FontDialog_SelectAssociatedText:
    case SH_MenuBar_MouseTracking:
    case SH_Menu_MouseTracking:
    case SH_ComboBox_ListMouseTracking:
    case SH_MainWindow_SpaceBelowMenuBar:
    case SH_ItemView_ChangeHighlightOnFocus:
        ret = 1;
        break;
    case SH_ToolBox_SelectedPageTitleBold:
        ret = 0;
        break;
    case SH_DialogButtonBox_ButtonsHaveIcons:
        ret = 0;
        break;
    case SH_Menu_SelectionWrap:
        ret = false;
        break;
    case SH_Menu_KeyboardSearch:
        ret = true;
        break;
    case SH_Menu_SpaceActivatesItem:
        ret = true;
        break;
    case SH_Slider_AbsoluteSetButtons:
        ret = Qt::LeftButton|Qt::MidButton;
        break;
    case SH_Slider_PageSetButtons:
        ret = 0;
        break;
    case SH_ScrollBar_ContextMenu:
        ret = false;
        break;
    case SH_TitleBar_AutoRaise:
        ret = true;
        break;
    case SH_Menu_AllowActiveAndDisabled:
        ret = false;
        break;
    case SH_Menu_SubMenuPopupDelay:
        ret = 100;
        break;
    case SH_Menu_SubMenuUniDirection:
        ret = true;
        break;
    case SH_Menu_SubMenuSloppySelectOtherActions:
        ret = false;
        break;
    case SH_Menu_SubMenuResetWhenReenteringParent:
        ret = true;
        break;
    case SH_Menu_SubMenuDontStartSloppyOnLeave:
        ret = true;
        break;

    case SH_ScrollBar_LeftClickAbsolutePosition: {
        NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
        bool result = [defaults boolForKey:@"AppleScrollerPagingBehavior"];
        if(QApplication::keyboardModifiers() & Qt::AltModifier)
            ret = !result;
        else
            ret = result;
        break; }
    case SH_TabBar_PreferNoArrows:
        ret = true;
        break;
        /*
    case SH_DialogButtons_DefaultButton:
        ret = QDialogButtons::Reject;
        break;
        */
    case SH_GroupBox_TextLabelVerticalAlignment:
        ret = Qt::AlignTop;
        break;
    case SH_ScrollView_FrameOnlyAroundContents:
        ret = QCommonStyle::styleHint(sh, opt, w, hret);
        break;
    case SH_Menu_FillScreenWithScroll:
        ret = false;
        break;
    case SH_Menu_Scrollable:
        ret = true;
        break;
    case SH_RichText_FullWidthSelection:
        ret = true;
        break;
    case SH_BlinkCursorWhenTextSelected:
        ret = false;
        break;
    case SH_ScrollBar_StopMouseOverSlider:
        ret = true;
        break;
    case SH_ListViewExpand_SelectMouseType:
        ret = QEvent::MouseButtonRelease;
        break;
    case SH_TabBar_SelectMouseType:
#if QT_CONFIG(tabbar)
        if (const QStyleOptionTabBarBase *opt2 = qstyleoption_cast<const QStyleOptionTabBarBase *>(opt)) {
            ret = opt2->documentMode ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease;
        } else
#endif
        {
            ret = QEvent::MouseButtonRelease;
        }
        break;
    case SH_ComboBox_Popup:
        if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt))
            ret = !cmb->editable;
        else
            ret = 0;
        break;
    case SH_Workspace_FillSpaceOnMaximize:
        ret = true;
        break;
    case SH_Widget_ShareActivation:
        ret = true;
        break;
    case SH_Header_ArrowAlignment:
        ret = Qt::AlignRight;
        break;
    case SH_TabBar_Alignment: {
#if QT_CONFIG(tabwidget)
        if (const QTabWidget *tab = qobject_cast<const QTabWidget*>(w)) {
            if (tab->documentMode()) {
                ret = Qt::AlignLeft;
                break;
            }
        }
#endif
#if QT_CONFIG(tabbar)
        if (const QTabBar *tab = qobject_cast<const QTabBar*>(w)) {
            if (tab->documentMode()) {
                ret = Qt::AlignLeft;
                break;
            }
        }
#endif
        ret = Qt::AlignCenter;
        } break;
    case SH_UnderlineShortcut:
        ret = false;
        break;
    case SH_ToolTipLabel_Opacity:
        ret = 242; // About 95%
        break;
    case SH_Button_FocusPolicy:
        ret = Qt::TabFocus;
        break;
    case SH_EtchDisabledText:
        ret = false;
        break;
    case SH_FocusFrame_Mask: {
        ret = true;
        if(QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
            const uchar fillR = 192, fillG = 191, fillB = 190;
            QImage img;

            QSize pixmapSize = opt->rect.size();
            if (!pixmapSize.isEmpty()) {
                QPixmap pix(pixmapSize);
                pix.fill(QColor(fillR, fillG, fillB));
                QPainter pix_paint(&pix);
                proxy()->drawControl(CE_FocusFrame, opt, &pix_paint, w);
                pix_paint.end();
                img = pix.toImage();
            }

            const QRgb *sptr = (QRgb*)img.bits(), *srow;
            const int sbpl = img.bytesPerLine();
            const int w = sbpl/4, h = img.height();

            QImage img_mask(img.width(), img.height(), QImage::Format_ARGB32);
            QRgb *dptr = (QRgb*)img_mask.bits(), *drow;
            const int dbpl = img_mask.bytesPerLine();

            for (int y = 0; y < h; ++y) {
                srow = sptr+((y*sbpl)/4);
                drow = dptr+((y*dbpl)/4);
                for (int x = 0; x < w; ++x) {
                    const int redDiff = qRed(*srow) - fillR;
                    const int greenDiff = qGreen(*srow) - fillG;
                    const int blueDiff = qBlue(*srow) - fillB;
                    const int diff = (redDiff * redDiff) + (greenDiff * greenDiff) + (blueDiff * blueDiff);
                    (*drow++) = (diff < 10) ? 0xffffffff : 0xff000000;
                    ++srow;
                }
            }
            QBitmap qmask = QBitmap::fromImage(img_mask);
            mask->region = QRegion(qmask);
        }
        break; }
    case SH_TitleBar_NoBorder:
        ret = 1;
        break;
    case SH_RubberBand_Mask:
        ret = 0;
        break;
    case SH_ComboBox_LayoutDirection:
        ret = Qt::LeftToRight;
        break;
    case SH_ItemView_EllipsisLocation:
        ret = Qt::AlignHCenter;
        break;
    case SH_ItemView_ShowDecorationSelected:
        ret = true;
        break;
    case SH_TitleBar_ModifyNotification:
        ret = false;
        break;
    case SH_ScrollBar_RollBetweenButtons:
        ret = true;
        break;
    case SH_WindowFrame_Mask:
        ret = false;
        break;
    case SH_TabBar_ElideMode:
        ret = Qt::ElideRight;
        break;
#if QT_CONFIG(dialogbuttonbox)
    case SH_DialogButtonLayout:
        ret = QDialogButtonBox::MacLayout;
        break;
#endif
    case SH_FormLayoutWrapPolicy:
        ret = QFormLayout::DontWrapRows;
        break;
    case SH_FormLayoutFieldGrowthPolicy:
        ret = QFormLayout::FieldsStayAtSizeHint;
        break;
    case SH_FormLayoutFormAlignment:
        ret = Qt::AlignHCenter | Qt::AlignTop;
        break;
    case SH_FormLayoutLabelAlignment:
        ret = Qt::AlignRight;
        break;
    case SH_ComboBox_PopupFrameStyle:
        ret = QFrame::NoFrame;
        break;
    case SH_MessageBox_TextInteractionFlags:
        ret = Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard;
        break;
    case SH_SpellCheckUnderlineStyle:
        ret = QTextCharFormat::DashUnderline;
        break;
    case SH_MessageBox_CenterButtons:
        ret = false;
        break;
    case SH_MenuBar_AltKeyNavigation:
        ret = false;
        break;
    case SH_ItemView_MovementWithoutUpdatingSelection:
        ret = false;
        break;
    case SH_FocusFrame_AboveWidget:
        ret = true;
        break;
#if QT_CONFIG(wizard)
    case SH_WizardStyle:
        ret = QWizard::MacStyle;
        break;
#endif
    case SH_ItemView_ArrowKeysNavigateIntoChildren:
        ret = false;
        break;
    case SH_Menu_FlashTriggeredItem:
        ret = true;
        break;
    case SH_Menu_FadeOutOnHide:
        ret = true;
        break;
    case SH_ItemView_PaintAlternatingRowColorsForEmptyArea:
        ret = true;
        break;
#if QT_CONFIG(tabbar)
    case SH_TabBar_CloseButtonPosition:
        ret = QTabBar::LeftSide;
        break;
#endif
    case SH_DockWidget_ButtonsHaveFrame:
        ret = false;
        break;
    case SH_ScrollBar_Transient:
        if ((qobject_cast<const QScrollBar *>(w) && w->parent() &&
                qobject_cast<QAbstractScrollArea*>(w->parent()->parent()))
#ifndef QT_NO_ACCESSIBILITY
                || (opt && QStyleHelper::hasAncestor(opt->styleObject, QAccessible::ScrollBar))
#endif
        ) {
            ret = [NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay;
        }
        break;
#if QT_CONFIG(itemviews)
    case SH_ItemView_ScrollMode:
        ret = QAbstractItemView::ScrollPerPixel;
        break;
#endif
    case SH_TitleBar_ShowToolTipsOnButtons:
        // min/max/close buttons on windows don't show tool tips
        ret = false;
        break;
    case SH_ComboBox_AllowWheelScrolling:
        ret = false;
        break;
    case SH_SpinBox_ButtonsInsideFrame:
        ret = false;
        break;
    case SH_Table_GridLineColor:
        ret = int(qt_mac_toQColor(NSColor.gridColor).rgb());
        break;
    default:
        ret = QCommonStyle::styleHint(sh, opt, w, hret);
        break;
    }
    return ret;
}

QPixmap QMacStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap,
                                       const QStyleOption *opt) const
{
    switch (iconMode) {
    case QIcon::Disabled: {
        QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
        int imgh = img.height();
        int imgw = img.width();
        QRgb pixel;
        for (int y = 0; y < imgh; ++y) {
            for (int x = 0; x < imgw; ++x) {
                pixel = img.pixel(x, y);
                img.setPixel(x, y, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel),
                                         qAlpha(pixel) / 2));
            }
        }
        return QPixmap::fromImage(img);
    }
    default:
        ;
    }
    return QCommonStyle::generatedIconPixmap(iconMode, pixmap, opt);
}


QPixmap QMacStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
                                  const QWidget *widget) const
{
    // The default implementation of QStyle::standardIconImplementation() is to call standardPixmap()
    // I don't want infinite recursion so if we do get in that situation, just return the Window's
    // standard pixmap instead (since there is no mac-specific icon then). This should be fine until
    // someone changes how Windows standard
    // pixmap works.
    static bool recursionGuard = false;

    if (recursionGuard)
        return QCommonStyle::standardPixmap(standardPixmap, opt, widget);

    recursionGuard = true;
    QIcon icon = proxy()->standardIcon(standardPixmap, opt, widget);
    recursionGuard = false;
    int size;
    switch (standardPixmap) {
        default:
            size = 32;
            break;
        case SP_MessageBoxCritical:
        case SP_MessageBoxQuestion:
        case SP_MessageBoxInformation:
        case SP_MessageBoxWarning:
            size = 64;
            break;
    }
    return icon.pixmap(qt_getWindow(widget), QSize(size, size));
}

void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p,
                              const QWidget *w) const
{
    Q_D(const QMacStyle);
    const AppearanceSync appSync;
    QMacCGContext cg(p);
    QWindow *window = w && w->window() ? w->window()->windowHandle() : nullptr;
    d->resolveCurrentNSView(window);
    switch (pe) {
    case PE_IndicatorArrowUp:
    case PE_IndicatorArrowDown:
    case PE_IndicatorArrowRight:
    case PE_IndicatorArrowLeft: {
        p->save();
        p->setRenderHint(QPainter::Antialiasing);
        const int xOffset = 1; // FIXME: opt->direction == Qt::LeftToRight ? 2 : -1;
        qreal halfSize = 0.5 * qMin(opt->rect.width(), opt->rect.height());
        const qreal penWidth = qMax(halfSize / 3.0, 1.25);
#if QT_CONFIG(toolbutton)
        if (const QToolButton *tb = qobject_cast<const QToolButton *>(w)) {
            // When stroking the arrow, make sure it fits in the tool button
            if (tb->arrowType() != Qt::NoArrow
                    || tb->popupMode() == QToolButton::MenuButtonPopup)
                halfSize -= penWidth;
        }
#endif

        QTransform transform;
        transform.translate(opt->rect.center().x() + xOffset, opt->rect.center().y() + 2);
        QPainterPath path;
        switch(pe) {
        default:
        case PE_IndicatorArrowDown:
            break;
        case PE_IndicatorArrowUp:
            transform.rotate(180);
            break;
        case PE_IndicatorArrowLeft:
            transform.rotate(90);
            break;
        case PE_IndicatorArrowRight:
            transform.rotate(-90);
            break;
        }
        p->setTransform(transform);

        path.moveTo(-halfSize, -halfSize * 0.5);
        path.lineTo(0.0, halfSize * 0.5);
        path.lineTo(halfSize, -halfSize * 0.5);

        const QPen arrowPen(opt->palette.text(), penWidth,
                            Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
        p->strokePath(path, arrowPen);
        p->restore();
        break; }
#if QT_CONFIG(tabbar)
    case PE_FrameTabBarBase:
        if (const QStyleOptionTabBarBase *tbb
                = qstyleoption_cast<const QStyleOptionTabBarBase *>(opt)) {
            if (tbb->documentMode) {
                p->save();
                drawTabBase(p, tbb, w);
                p->restore();
                return;
            }
#if QT_CONFIG(tabwidget)
            QRegion region(tbb->rect);
            region -= tbb->tabBarRect;
            p->save();
            p->setClipRegion(region);
            QStyleOptionTabWidgetFrame twf;
            twf.QStyleOption::operator=(*tbb);
            twf.shape  = tbb->shape;
            switch (QMacStylePrivate::tabDirection(twf.shape)) {
            case QMacStylePrivate::North:
                twf.rect = twf.rect.adjusted(0, 0, 0, 10);
                break;
            case QMacStylePrivate::South:
                twf.rect = twf.rect.adjusted(0, -10, 0, 0);
                break;
            case QMacStylePrivate::West:
                twf.rect = twf.rect.adjusted(0, 0, 10, 0);
                break;
            case QMacStylePrivate::East:
                twf.rect = twf.rect.adjusted(0, -10, 0, 0);
                break;
            }
            proxy()->drawPrimitive(PE_FrameTabWidget, &twf, p, w);
            p->restore();
#endif
        }
        break;
#endif
    case PE_PanelTipLabel:
        p->fillRect(opt->rect, opt->palette.brush(QPalette::ToolTipBase));
        break;
    case PE_FrameGroupBox:
        if (const auto *groupBox = qstyleoption_cast<const QStyleOptionFrame *>(opt))
            if (groupBox->features & QStyleOptionFrame::Flat) {
                QCommonStyle::drawPrimitive(pe, groupBox, p, w);
                break;
            }
#if QT_CONFIG(tabwidget)
        Q_FALLTHROUGH();
    case PE_FrameTabWidget:
#endif
    {
        const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Box, QStyleHelper::SizeLarge);
        auto *box = static_cast<NSBox *>(d->cocoaControl(cw));
        // FIXME Since macOS 10.14, simply calling drawRect: won't display anything anymore.
        // The AppKit team is aware of this and has proposed a couple of solutions.
        // The first solution was to call displayRectIgnoringOpacity:inContext: instead.
        // However, it doesn't seem to work on 10.13. More importantly, dark mode on 10.14
        // is extremely slow. Light mode works fine.
        // The second solution is to subclass NSBox and reimplement a trivial drawRect: which
        // would only call super. This works without any issue on 10.13, but a double border
        // shows on 10.14 in both light and dark modes.
        // The code below picks what works on each version and mode. On 10.13 and earlier, we
        // simply call drawRect: on a regular NSBox. On 10.14, we call displayRectIgnoringOpacity:
        // inContext:, but only in light mode. In dark mode, we use a custom NSBox subclass,
        // QDarkNSBox, of type NSBoxCustom. Its appearance is close enough to the real thing so
        // we can use this for now.
        auto adjustedRect = opt->rect;
        bool needTranslation = false;
        if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::MacOSMojave
            && !qt_mac_applicationIsInDarkMode()) {
            // Another surprise from AppKit (SDK 10.14) - -displayRectIgnoringOpacity:
            // is different from drawRect: for some Apple-known reason box is smaller
            // in height than we need, resulting in tab buttons sitting too high/not
            // centered. Attempts to play with insets etc did not work - the same wrong
            // height. Simple translation is not working (too much space "at bottom"),
            // so we make it bigger and translate (otherwise it's clipped at bottom btw).
            adjustedRect.adjust(0, 0, 0, 3);
            needTranslation = true;
        }
        d->drawNSViewInRect(box, adjustedRect, p, ^(CGContextRef ctx, const CGRect &rect) {
#if QT_CONFIG(tabwidget)
            if (QTabWidget *tabWidget = qobject_cast<QTabWidget *>(opt->styleObject))
                clipTabBarFrame(opt, this, ctx);
#endif
            CGContextTranslateCTM(ctx, 0, rect.origin.y + rect.size.height);
            CGContextScaleCTM(ctx, 1, -1);
            if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSMojave
                || [box isMemberOfClass:QDarkNSBox.class]) {
                [box drawRect:rect];
            } else {
                if (needTranslation)
                    CGContextTranslateCTM(ctx, 0.0, 4.0);
                [box displayRectIgnoringOpacity:box.bounds inContext:NSGraphicsContext.currentContext];
            }
        });
        break;
    }
    case PE_IndicatorToolBarSeparator: {
            QPainterPath path;
            if (opt->state & State_Horizontal) {
                int xpoint = opt->rect.center().x();
                path.moveTo(xpoint + 0.5, opt->rect.top() + 1);
                path.lineTo(xpoint + 0.5, opt->rect.bottom());
            } else {
                int ypoint = opt->rect.center().y();
                path.moveTo(opt->rect.left() + 2 , ypoint + 0.5);
                path.lineTo(opt->rect.right() + 1, ypoint + 0.5);
            }
            QPainterPathStroker theStroker;
            theStroker.setCapStyle(Qt::FlatCap);
            theStroker.setDashPattern(QVector<qreal>() << 1 << 2);
            path = theStroker.createStroke(path);
            const auto dark = qt_mac_applicationIsInDarkMode() ? opt->palette.dark().color().darker()
                                                               : QColor(0, 0, 0, 119);
            p->fillPath(path, dark);
        }
        break;
    case PE_FrameWindow:
        if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
            if (w && w->inherits("QMdiSubWindow")) {
                p->save();
                p->setPen(QPen(frame->palette.dark().color(), frame->lineWidth));
                p->setBrush(frame->palette.window());
                p->drawRect(frame->rect);
                p->restore();
            }
        }
        break;
    case PE_IndicatorDockWidgetResizeHandle: {
            // The docwidget resize handle is drawn as a one-pixel wide line.
            p->save();
            if (opt->state & State_Horizontal) {
                p->setPen(QColor(160, 160, 160));
                p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
            } else {
                p->setPen(QColor(145, 145, 145));
                p->drawLine(opt->rect.topRight(), opt->rect.bottomRight());
            }
            p->restore();
        } break;
    case PE_IndicatorToolBarHandle: {
            p->save();
            QPainterPath path;
            int x = opt->rect.x() + 6;
            int y = opt->rect.y() + 7;
            static const int RectHeight = 2;
            if (opt->state & State_Horizontal) {
                while (y < opt->rect.height() - RectHeight - 5) {
                    path.moveTo(x, y);
                    path.addEllipse(x, y, RectHeight, RectHeight);
                    y += 6;
                }
            } else {
                while (x < opt->rect.width() - RectHeight - 5) {
                    path.moveTo(x, y);
                    path.addEllipse(x, y, RectHeight, RectHeight);
                    x += 6;
                }
            }
            p->setPen(Qt::NoPen);
            QColor dark = opt->palette.dark().color().darker();
            dark.setAlphaF(0.50);
            p->fillPath(path, dark);
            p->restore();

            break;
        }
    case PE_IndicatorHeaderArrow:
        if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
            // In HITheme, up is down, down is up and hamburgers eat people.
            if (header->sortIndicator != QStyleOptionHeader::None)
                proxy()->drawPrimitive(
                    (header->sortIndicator == QStyleOptionHeader::SortDown) ?
                    PE_IndicatorArrowUp : PE_IndicatorArrowDown, header, p, w);
        }
        break;
    case PE_IndicatorMenuCheckMark: {
        QColor pc;
        if (opt->state & State_On)
            pc = opt->palette.highlightedText().color();
        else
            pc = opt->palette.text().color();

        QCFType<CGColorRef> checkmarkColor = CGColorCreateGenericRGB(static_cast<CGFloat>(pc.redF()),
                                                                     static_cast<CGFloat>(pc.greenF()),
                                                                     static_cast<CGFloat>(pc.blueF()),
                                                                     static_cast<CGFloat>(pc.alphaF()));
        // kCTFontUIFontSystem and others give the same result
        // as kCTFontUIFontMenuItemMark. However, the latter is
        // more reminiscent to HITheme's kThemeMenuItemMarkFont.
        // See also the font for small- and mini-sized widgets,
        // where we end up using the generic system font type.
        const CTFontUIFontType fontType = (opt->state & State_Mini) ? kCTFontUIFontMiniSystem :
                                          (opt->state & State_Small) ? kCTFontUIFontSmallSystem :
                                          kCTFontUIFontMenuItemMark;
        // Similarly for the font size, where there is a small difference
        // between regular combobox and item view items, and and menu items.
        // However, we ignore any difference for small- and mini-sized widgets.
        const CGFloat fontSize = fontType == kCTFontUIFontMenuItemMark ? opt->fontMetrics.height() : 0.0;
        QCFType<CTFontRef> checkmarkFont = CTFontCreateUIFontForLanguage(fontType, fontSize, NULL);

        CGContextSaveGState(cg);
        CGContextSetShouldSmoothFonts(cg, NO); // Same as HITheme and Cocoa menu checkmarks

        // Baseline alignment tweaks for QComboBox and QMenu
        const CGFloat vOffset = (opt->state & State_Mini) ? 0.0 :
                                (opt->state & State_Small) ? 1.0 :
                                0.75;

        CGContextTranslateCTM(cg, 0, opt->rect.bottom());
        CGContextScaleCTM(cg, 1, -1);
        // Translate back to the original position and add rect origin and offset
        CGContextTranslateCTM(cg, opt->rect.x(), vOffset);

        // CTFont has severe difficulties finding the checkmark character among its
        // glyphs. Fortunately, CTLine knows its ways inside the Cocoa labyrinth.
        static const CFStringRef keys[] = { kCTFontAttributeName, kCTForegroundColorAttributeName };
        static const int numValues = sizeof(keys) / sizeof(keys[0]);
        const CFTypeRef values[] = { (CFTypeRef)checkmarkFont,  (CFTypeRef)checkmarkColor };
        Q_STATIC_ASSERT((sizeof(values) / sizeof(values[0])) == numValues);
        QCFType<CFDictionaryRef> attributes = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values,
                                                                 numValues, NULL, NULL);
        // U+2713: CHECK MARK
        QCFType<CFAttributedStringRef> checkmarkString = CFAttributedStringCreate(kCFAllocatorDefault, (CFStringRef)@"\u2713", attributes);
        QCFType<CTLineRef> line = CTLineCreateWithAttributedString(checkmarkString);

        CTLineDraw((CTLineRef)line, cg);
        CGContextFlush(cg); // CTLineDraw's documentation says it doesn't flush

        CGContextRestoreGState(cg);
        break; }
    case PE_IndicatorViewItemCheck:
    case PE_IndicatorRadioButton:
    case PE_IndicatorCheckBox: {
        const bool isEnabled = opt->state & State_Enabled;
        const bool isPressed = opt->state & State_Sunken;
        const bool isRadioButton = (pe == PE_IndicatorRadioButton);
        const auto ct = isRadioButton ? QMacStylePrivate::Button_RadioButton : QMacStylePrivate::Button_CheckBox;
        const auto cs = d->effectiveAquaSizeConstrain(opt, w);
        const auto cw = QMacStylePrivate::CocoaControl(ct, cs);
        auto *tb = static_cast<NSButton *>(d->cocoaControl(cw));
        tb.enabled = isEnabled;
        tb.state = (opt->state & State_NoChange) ? NSMixedState :
                   (opt->state & State_On) ? NSOnState : NSOffState;
        [tb highlight:isPressed];
        const auto vOffset = [=] {
            // As measured
            if (cs == QStyleHelper::SizeMini)
                return ct == QMacStylePrivate::Button_CheckBox ? -0.5 : 0.5;

            return cs == QStyleHelper::SizeSmall ? 0.5 : 0.0;
        } ();
        d->drawNSViewInRect(tb, opt->rect, p, ^(CGContextRef ctx, const CGRect &rect) {
            CGContextTranslateCTM(ctx, 0, vOffset);
            [tb.cell drawInteriorWithFrame:rect inView:tb];
        });
        break; }
    case PE_FrameFocusRect:
        // Use the our own focus widget stuff.
        break;
    case PE_IndicatorBranch: {
        if (!(opt->state & State_Children))
            break;
        const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Button_Disclosure, QStyleHelper::SizeLarge);
        NSButtonCell *triangleCell = static_cast<NSButtonCell *>(d->cocoaCell(cw));
        [triangleCell setState:(opt->state & State_Open) ? NSOnState : NSOffState];
        bool viewHasFocus = (w && w->hasFocus()) || (opt->state & State_HasFocus);
        [triangleCell setBackgroundStyle:((opt->state & State_Selected) && viewHasFocus) ? NSBackgroundStyleDark : NSBackgroundStyleLight];

        d->setupNSGraphicsContext(cg, NO);

        QRect qtRect = opt->rect.adjusted(DisclosureOffset, 0, -DisclosureOffset, 0);
        CGRect rect = CGRectMake(qtRect.x() + 1, qtRect.y(), qtRect.width(), qtRect.height());
        CGContextTranslateCTM(cg, rect.origin.x, rect.origin.y + rect.size.height);
        CGContextScaleCTM(cg, 1, -1);
        CGContextTranslateCTM(cg, -rect.origin.x, -rect.origin.y);

        [triangleCell drawBezelWithFrame:NSRectFromCGRect(rect) inView:[triangleCell controlView]];

        d->restoreNSGraphicsContext(cg);
        break; }

    case PE_Frame: {
        QPen oldPen = p->pen();
        p->setPen(opt->palette.base().color().darker(140));
        p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
        p->setPen(opt->palette.base().color().darker(180));
        p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
        p->setPen(oldPen);
        break; }

    case PE_FrameLineEdit:
        if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
            if (frame->state & State_Sunken) {
                const bool isEnabled = opt->state & State_Enabled;
                const bool isReadOnly = opt->state & State_ReadOnly;
                const bool isRounded = frame->features & QStyleOptionFrame::Rounded;
                const auto cs = d->effectiveAquaSizeConstrain(opt, w, CT_LineEdit);
                const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::TextField, cs);
                auto *tf = static_cast<NSTextField *>(d->cocoaControl(cw));
                tf.enabled = isEnabled;
                tf.editable = !isReadOnly;
                tf.bezeled = YES;
                static_cast<NSTextFieldCell *>(tf.cell).bezelStyle = isRounded ? NSTextFieldRoundedBezel : NSTextFieldSquareBezel;
                tf.frame = opt->rect.toCGRect();
                d->drawNSViewInRect(tf, opt->rect, p, ^(CGContextRef, const CGRect &rect) {
                    if (!qt_mac_applicationIsInDarkMode()) {
                        // In 'Dark' mode controls are transparent, so we do not
                        // over-paint the (potentially custom) color in the background.
                        // In 'Light' mode we have to care about the correct
                        // background color. See the comments below for PE_PanelLineEdit.
                        CGContextRef cgContext = NSGraphicsContext.currentContext.CGContext;
                        // See QMacCGContext, here we expect bitmap context created with
                        // color space 'kCGColorSpaceSRGB', if it's something else - we
                        // give up.
                        if (cgContext ? bool(CGBitmapContextGetColorSpace(cgContext)) : false) {
                            tf.drawsBackground = YES;
                            const QColor bgColor = frame->palette.brush(QPalette::Base).color();
                            tf.backgroundColor = [NSColor colorWithSRGBRed:bgColor.redF()
                                                                     green:bgColor.greenF()
                                                                      blue:bgColor.blueF()
                                                                     alpha:bgColor.alphaF()];
                            if (bgColor.alpha() != 255) {
                                // No way we can have it bezeled and transparent ...
                                tf.bordered = YES;
                            }
                        }
                    }

                    [tf.cell drawWithFrame:rect inView:tf];
                });
            } else {
                QCommonStyle::drawPrimitive(pe, opt, p, w);
            }
        }
        break;
    case PE_PanelLineEdit:
        {
            const QStyleOptionFrame *panel = qstyleoption_cast<const QStyleOptionFrame *>(opt);
            if (qt_mac_applicationIsInDarkMode() || (panel && panel->lineWidth <= 0)) {
                // QCommonStyle::drawPrimitive(PE_PanelLineEdit) fill the background with
                // a proper color, defined in opt->palette and then, if lineWidth > 0, it
                // calls QMacStyle::drawPrimitive(PE_FrameLineEdit). We use NSTextFieldCell
                // to handle PE_FrameLineEdit, which will use system-default background.
                // In 'Dark' mode it's transparent and thus it's not over-painted.
                QCommonStyle::drawPrimitive(pe, opt, p, w);
            } else {
                // In 'Light' mode, if panel->lineWidth > 0, we have to use the correct
                // background color when drawing PE_FrameLineEdit, so let's call it
                // directly and set the proper color there.
                drawPrimitive(PE_FrameLineEdit, opt, p, w);
            }

            // Draw the focus frame for widgets other than QLineEdit (e.g. for line edits in Webkit).
            // Focus frame is drawn outside the rectangle passed in the option-rect.
            if (panel) {
#if QT_CONFIG(lineedit)
                if ((opt->state & State_HasFocus) && !qobject_cast<const QLineEdit*>(w)) {
                    int vmargin = pixelMetric(QStyle::PM_FocusFrameVMargin);
                    int hmargin = pixelMetric(QStyle::PM_FocusFrameHMargin);
                    QStyleOptionFrame focusFrame = *panel;
                    focusFrame.rect = panel->rect.adjusted(-hmargin, -vmargin, hmargin, vmargin);
                    drawControl(CE_FocusFrame, &focusFrame, p, w);
                }
#endif
            }
        }
        break;
    case PE_PanelScrollAreaCorner: {
        const QBrush brush(opt->palette.brush(QPalette::Base));
        p->fillRect(opt->rect, brush);
        p->setPen(QPen(QColor(217, 217, 217)));
        p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
        p->drawLine(opt->rect.topLeft(), opt->rect.bottomLeft());
        } break;
    case PE_FrameStatusBarItem:
        break;
#if QT_CONFIG(tabbar)
    case PE_IndicatorTabClose: {
        // Make close button visible only on the hovered tab.
        QTabBar *tabBar = qobject_cast<QTabBar*>(w->parentWidget());
        const QWidget *closeBtn = w;
        if (!tabBar) {
            // QStyleSheetStyle instead of CloseButton (which has
            // a QTabBar as a parent widget) uses the QTabBar itself:
            tabBar = qobject_cast<QTabBar *>(const_cast<QWidget*>(w));
            closeBtn = decltype(closeBtn)(property("_q_styleSheetRealCloseButton").value<void *>());
        }
        if (tabBar) {
            const bool documentMode = tabBar->documentMode();
            const QTabBarPrivate *tabBarPrivate = static_cast<QTabBarPrivate *>(QObjectPrivate::get(tabBar));
            const int hoveredTabIndex = tabBarPrivate->hoveredTabIndex();
            if (!documentMode ||
                (hoveredTabIndex != -1 && ((closeBtn == tabBar->tabButton(hoveredTabIndex, QTabBar::LeftSide)) ||
                                           (closeBtn == tabBar->tabButton(hoveredTabIndex, QTabBar::RightSide))))) {
                const bool hover = (opt->state & State_MouseOver);
                const bool selected = (opt->state & State_Selected);
                const bool pressed = (opt->state & State_Sunken);
                drawTabCloseButton(p, hover, selected, pressed, documentMode);
            }
        }
        } break;
#endif // QT_CONFIG(tabbar)
    case PE_PanelStatusBar: {
        // Fill the status bar with the titlebar gradient.
        QLinearGradient linearGrad;
        if (w ? qt_macWindowMainWindow(w->window()) : (opt->state & QStyle::State_Active)) {
            linearGrad = titlebarGradientActive();
        } else {
            linearGrad = titlebarGradientInactive();
        }

        linearGrad.setStart(0, opt->rect.top());
        linearGrad.setFinalStop(0, opt->rect.bottom());
        p->fillRect(opt->rect, linearGrad);

        // Draw the black separator line at the top of the status bar.
        if (w ? qt_macWindowMainWindow(w->window()) : (opt->state & QStyle::State_Active))
            p->setPen(titlebarSeparatorLineActive);
        else
            p->setPen(titlebarSeparatorLineInactive);
        p->drawLine(opt->rect.left(), opt->rect.top(), opt->rect.right(), opt->rect.top());

        break;
    }
    case PE_PanelMenu: {
        p->save();
        p->fillRect(opt->rect, Qt::transparent);
        p->setPen(Qt::transparent);
        p->setBrush(opt->palette.window());
        p->setRenderHint(QPainter::Antialiasing, true);
        const QPainterPath path = d->windowPanelPath(opt->rect);
        p->drawPath(path);
        p->restore();
        } break;

    default:
        QCommonStyle::drawPrimitive(pe, opt, p, w);
        break;
    }
}

static QPixmap darkenPixmap(const QPixmap &pixmap)
{
    QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
    int imgh = img.height();
    int imgw = img.width();
    int h, s, v, a;
    QRgb pixel;
    for (int y = 0; y < imgh; ++y) {
        for (int x = 0; x < imgw; ++x) {
            pixel = img.pixel(x, y);
            a = qAlpha(pixel);
            QColor hsvColor(pixel);
            hsvColor.getHsv(&h, &s, &v);
            s = qMin(100, s * 2);
            v = v / 2;
            hsvColor.setHsv(h, s, v);
            pixel = hsvColor.rgb();
            img.setPixel(x, y, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), a));
        }
    }
    return QPixmap::fromImage(img);
}

void QMacStylePrivate::setupVerticalInvertedXform(CGContextRef cg, bool reverse, bool vertical, const CGRect &rect) const
{
    if (vertical) {
        CGContextTranslateCTM(cg, rect.size.height, 0);
        CGContextRotateCTM(cg, M_PI_2);
    }
    if (vertical != reverse) {
        CGContextTranslateCTM(cg, rect.size.width, 0);
        CGContextScaleCTM(cg, -1, 1);
    }
}

void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p,
                            const QWidget *w) const
{
    Q_D(const QMacStyle);
    const AppearanceSync sync;
    const QMacAutoReleasePool pool;
    QMacCGContext cg(p);
    QWindow *window = w && w->window() ? w->window()->windowHandle() : nullptr;
    d->resolveCurrentNSView(window);
    switch (ce) {
    case CE_HeaderSection:
        if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
            State flags = header->state;
            QRect ir = header->rect;


#if 0 // FIXME: What's this solving exactly?
            bool noVerticalHeader = true;
#if QT_CONFIG(tableview)
            if (w)
                if (const QTableView *table = qobject_cast<const QTableView *>(w->parentWidget()))
                    noVerticalHeader = !table->verticalHeader()->isVisible();
#endif

            const bool drawLeftBorder = header->orientation == Qt::Vertical
                    || header->position == QStyleOptionHeader::OnlyOneSection
                    || (header->position == QStyleOptionHeader::Beginning && noVerticalHeader);
#endif

            const bool pressed = (flags & State_Sunken) && !(flags & State_On);
            p->fillRect(ir, pressed ? header->palette.dark() : header->palette.button());
            p->setPen(QPen(header->palette.dark(), 1.0));
            if (header->orientation == Qt::Horizontal)
                p->drawLine(QLineF(ir.right() + 0.5, ir.top() + headerSectionSeparatorInset,
                                   ir.right() + 0.5, ir.bottom() - headerSectionSeparatorInset));
            else
                p->drawLine(QLineF(ir.left() + headerSectionSeparatorInset, ir.bottom(),
                                   ir.right() - headerSectionSeparatorInset, ir.bottom()));
        }

        break;
    case CE_HeaderLabel:
        if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
            p->save();
            QRect textr = header->rect;
            if (!header->icon.isNull()) {
                QIcon::Mode mode = QIcon::Disabled;
                if (opt->state & State_Enabled)
                    mode = QIcon::Normal;
                int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
                QPixmap pixmap = header->icon.pixmap(window, QSize(iconExtent, iconExtent), mode);

                QRect pixr = header->rect;
                pixr.setY(header->rect.center().y() - (pixmap.height() / pixmap.devicePixelRatio() - 1) / 2);
                proxy()->drawItemPixmap(p, pixr, Qt::AlignVCenter, pixmap);
                textr.translate(pixmap.width() / pixmap.devicePixelRatio() + 2, 0);
            }

            proxy()->drawItemText(p, textr, header->textAlignment | Qt::AlignVCenter, header->palette,
                                       header->state & State_Enabled, header->text, QPalette::ButtonText);
            p->restore();
        }
        break;
    case CE_ToolButtonLabel:
        if (const QStyleOptionToolButton *tb = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
            QStyleOptionToolButton myTb = *tb;
            myTb.state &= ~State_AutoRaise;
#ifndef QT_NO_ACCESSIBILITY
            if (QStyleHelper::hasAncestor(opt->styleObject, QAccessible::ToolBar)) {
                QRect cr = tb->rect;
                int shiftX = 0;
                int shiftY = 0;
                bool needText = false;
                int alignment = 0;
                bool down = tb->state & (State_Sunken | State_On);
                if (down) {
                    shiftX = proxy()->pixelMetric(PM_ButtonShiftHorizontal, tb, w);
                    shiftY = proxy()->pixelMetric(PM_ButtonShiftVertical, tb, w);
                }
                // The down state is special for QToolButtons in a toolbar on the Mac
                // The text is a bit bolder and gets a drop shadow and the icons are also darkened.
                // This doesn't really fit into any particular case in QIcon, so we
                // do the majority of the work ourselves.
                if (!(tb->features & QStyleOptionToolButton::Arrow)) {
                    Qt::ToolButtonStyle tbstyle = tb->toolButtonStyle;
                    if (tb->icon.isNull() && !tb->text.isEmpty())
                        tbstyle = Qt::ToolButtonTextOnly;

                    switch (tbstyle) {
                    case Qt::ToolButtonTextOnly: {
                        needText = true;
                        alignment = Qt::AlignCenter;
                        break; }
                    case Qt::ToolButtonIconOnly:
                    case Qt::ToolButtonTextBesideIcon:
                    case Qt::ToolButtonTextUnderIcon: {
                        QRect pr = cr;
                        QIcon::Mode iconMode = (tb->state & State_Enabled) ? QIcon::Normal
                                                                            : QIcon::Disabled;
                        QIcon::State iconState = (tb->state & State_On) ? QIcon::On
                                                                         : QIcon::Off;
                        QPixmap pixmap = tb->icon.pixmap(window,
                                                         tb->rect.size().boundedTo(tb->iconSize),
                                                         iconMode, iconState);

                        // Draw the text if it's needed.
                        if (tb->toolButtonStyle != Qt::ToolButtonIconOnly) {
                            needText = true;
                            if (tb->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
                                pr.setHeight(pixmap.size().height() / pixmap.devicePixelRatio() + 6);
                                cr.adjust(0, pr.bottom(), 0, -3);
                                alignment |= Qt::AlignCenter;
                            } else {
                                pr.setWidth(pixmap.width() / pixmap.devicePixelRatio() + 8);
                                cr.adjust(pr.right(), 0, 0, 0);
                                alignment |= Qt::AlignLeft | Qt::AlignVCenter;
                            }
                        }
                        if (opt->state & State_Sunken) {
                            pr.translate(shiftX, shiftY);
                            pixmap = darkenPixmap(pixmap);
                        }
                        proxy()->drawItemPixmap(p, pr, Qt::AlignCenter, pixmap);
                        break; }
                    default:
                        Q_ASSERT(false);
                        break;
                    }

                    if (needText) {
                        QPalette pal = tb->palette;
                        QPalette::ColorRole role = QPalette::NoRole;
                        if (!proxy()->styleHint(SH_UnderlineShortcut, tb, w))
                            alignment |= Qt::TextHideMnemonic;
                        if (down)
                            cr.translate(shiftX, shiftY);
                        if (tbstyle == Qt::ToolButtonTextOnly
                            || (tbstyle != Qt::ToolButtonTextOnly && !down)) {
                            QPen pen = p->pen();
                            QColor light = down || isDarkMode() ? Qt::black : Qt::white;
                            light.setAlphaF(0.375f);
                            p->setPen(light);
                            p->drawText(cr.adjusted(0, 1, 0, 1), alignment, tb->text);
                            p->setPen(pen);
                            if (down && tbstyle == Qt::ToolButtonTextOnly) {
                                pal = QApplication::palette("QMenu");
                                pal.setCurrentColorGroup(tb->palette.currentColorGroup());
                                role = QPalette::HighlightedText;
                            }
                        }
                        proxy()->drawItemText(p, cr, alignment, pal,
                                              tb->state & State_Enabled, tb->text, role);
                    }
                } else {
                    QCommonStyle::drawControl(ce, &myTb, p, w);
                }
            } else
#endif // QT_NO_ACCESSIBILITY
            {
                QCommonStyle::drawControl(ce, &myTb, p, w);
            }
        }
        break;
    case CE_ToolBoxTabShape:
        QCommonStyle::drawControl(ce, opt, p, w);
        break;
    case CE_PushButtonBevel:
        if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
            if (!(btn->state & (State_Raised | State_Sunken | State_On)))
                break;

            if (btn->features & QStyleOptionButton::CommandLinkButton) {
                QCommonStyle::drawControl(ce, opt, p, w);
                break;
            }

            const bool hasFocus = btn->state & State_HasFocus;
            const bool isActive = btn->state & State_Active;

            // a focused auto-default button within an active window
            // takes precedence over a normal default button
            if ((btn->features & QStyleOptionButton::AutoDefaultButton)
                && isActive && hasFocus)
                d->autoDefaultButton = btn->styleObject;
            else if (d->autoDefaultButton == btn->styleObject)
                d->autoDefaultButton = nullptr;

            const bool isEnabled = btn->state & State_Enabled;
            const bool isPressed = btn->state & State_Sunken;
            const bool isHighlighted = isActive &&
                    ((btn->state & State_On)
                     || (btn->features & QStyleOptionButton::DefaultButton)
                     || (btn->features & QStyleOptionButton::AutoDefaultButton
                         && d->autoDefaultButton == btn->styleObject));
            const bool hasMenu = btn->features & QStyleOptionButton::HasMenu;
            const auto ct = cocoaControlType(btn, w);
            const auto cs = d->effectiveAquaSizeConstrain(btn, w);
            const auto cw = QMacStylePrivate::CocoaControl(ct, cs);
            auto *pb = static_cast<NSButton *>(d->cocoaControl(cw));
            // Ensure same size and location as we used to have with HITheme.
            // This is more convoluted than we initialy thought. See for example
            // differences between plain and menu button frames.
            const QRectF frameRect = cw.adjustedControlFrame(btn->rect);
            pb.frame = frameRect.toCGRect();

            pb.enabled = isEnabled;
            [pb highlight:isPressed];
            pb.state = isHighlighted && !isPressed ? NSOnState : NSOffState;
            d->drawNSViewInRect(pb, frameRect, p, ^(CGContextRef, const CGRect &r) {
                [pb.cell drawBezelWithFrame:r inView:pb.superview];
            });
            [pb highlight:NO];

            if (hasMenu && cw.type == QMacStylePrivate::Button_SquareButton) {
                // Using -[NSPopuButtonCell drawWithFrame:inView:] above won't do
                // it right because we don't set the text in the native button.
                const int mbi = proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, btn, w);
                const auto ir = frameRect.toRect();
                int arrowYOffset = 0;
#if 0
                // FIXME What's this for again?
                if (!w) {
                    // adjustment for Qt Quick Controls
                    arrowYOffset -= ir.top();
                    if (cw.second == QStyleHelper::SizeSmall)
                        arrowYOffset += 1;
                }
#endif
                const auto ar = visualRect(btn->direction, ir, QRect(ir.right() - mbi - 6, ir.height() / 2 - arrowYOffset, mbi, mbi));

                QStyleOption arrowOpt = *opt;
                arrowOpt.rect = ar;
                proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, w);
            }


            if (btn->state & State_HasFocus) {
                // TODO Remove and use QFocusFrame instead.
                const int hMargin = proxy()->pixelMetric(QStyle::PM_FocusFrameHMargin, btn, w);
                const int vMargin = proxy()->pixelMetric(QStyle::PM_FocusFrameVMargin, btn, w);
                QRectF focusRect;
                if (cw.type == QMacStylePrivate::Button_SquareButton) {
                    focusRect = frameRect;
                } else {
                    focusRect = QRectF::fromCGRect([pb alignmentRectForFrame:pb.frame]);
                    if (cw.type == QMacStylePrivate::Button_PushButton)
                        focusRect -= pushButtonShadowMargins[cw.size];
                    else if (cw.type == QMacStylePrivate::Button_PullDown)
                        focusRect -= pullDownButtonShadowMargins[cw.size];
                }
                d->drawFocusRing(p, focusRect, hMargin, vMargin, cw);
            }
        }
        break;
    case CE_PushButtonLabel:
        if (const QStyleOptionButton *b = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
            QStyleOptionButton btn(*b);
            // We really don't want the label to be drawn the same as on
            // windows style if it has an icon and text, then it should be more like a
            // tab. So, cheat a little here. However, if it *is* only an icon
            // the windows style works great, so just use that implementation.
            const bool isEnabled = btn.state & State_Enabled;
            const bool hasMenu = btn.features & QStyleOptionButton::HasMenu;
            const bool hasIcon = !btn.icon.isNull();
            const bool hasText = !btn.text.isEmpty();
            const bool isActive = btn.state & State_Active;
            const bool isPressed = btn.state & State_Sunken;

            const auto ct = cocoaControlType(&btn, w);

            if (!hasMenu && ct != QMacStylePrivate::Button_SquareButton) {
                if (isPressed
                    || (isActive && isEnabled
                        && ((btn.state & State_On)
                            || ((btn.features & QStyleOptionButton::DefaultButton) && !d->autoDefaultButton)
                            || d->autoDefaultButton == btn.styleObject)))
                btn.palette.setColor(QPalette::ButtonText, Qt::white);
            }

            if ((!hasIcon && !hasMenu) || (hasIcon && !hasText)) {
                QCommonStyle::drawControl(ce, &btn, p, w);
            } else {
                QRect freeContentRect = btn.rect;
                QRect textRect = itemTextRect(
                            btn.fontMetrics, freeContentRect, Qt::AlignCenter, isEnabled, btn.text);
                if (hasMenu) {
                    textRect.moveTo(w ? 15 : 11, textRect.top()); // Supports Qt Quick Controls
                }
                // Draw the icon:
                if (hasIcon) {
                    int contentW = textRect.width();
                    if (hasMenu)
                        contentW += proxy()->pixelMetric(PM_MenuButtonIndicator) + 4;
                    QIcon::Mode mode = isEnabled ? QIcon::Normal : QIcon::Disabled;
                    if (mode == QIcon::Normal && btn.state & State_HasFocus)
                        mode = QIcon::Active;
                    // Decide if the icon is should be on or off:
                    QIcon::State state = QIcon::Off;
                    if (btn.state & State_On)
                        state = QIcon::On;
                    QPixmap pixmap = btn.icon.pixmap(window, btn.iconSize, mode, state);
                    int pixmapWidth = pixmap.width() / pixmap.devicePixelRatio();
                    int pixmapHeight = pixmap.height() / pixmap.devicePixelRatio();
                    contentW += pixmapWidth + QMacStylePrivate::PushButtonContentPadding;
                    int iconLeftOffset = freeContentRect.x() + (freeContentRect.width() - contentW) / 2;
                    int iconTopOffset = freeContentRect.y() + (freeContentRect.height() - pixmapHeight) / 2;
                    QRect iconDestRect(iconLeftOffset, iconTopOffset, pixmapWidth, pixmapHeight);
                    QRect visualIconDestRect = visualRect(btn.direction, freeContentRect, iconDestRect);
                    proxy()->drawItemPixmap(p, visualIconDestRect, Qt::AlignLeft | Qt::AlignVCenter, pixmap);
                    int newOffset = iconDestRect.x() + iconDestRect.width()
                            + QMacStylePrivate::PushButtonContentPadding - textRect.x();
                    textRect.adjust(newOffset, 0, newOffset, 0);
                }
                // Draw the text:
                if (hasText) {
                    textRect = visualRect(btn.direction, freeContentRect, textRect);
                    proxy()->drawItemText(p, textRect, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextShowMnemonic, btn.palette,
                                          isEnabled, btn.text, QPalette::ButtonText);
                }
            }
        }
        break;
#if QT_CONFIG(combobox)
    case CE_ComboBoxLabel:
        if (const auto *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
            auto comboCopy = *cb;
            comboCopy.direction = Qt::LeftToRight;
            // The rectangle will be adjusted to SC_ComboBoxEditField with comboboxEditBounds()
            QCommonStyle::drawControl(CE_ComboBoxLabel, &comboCopy, p, w);
        }
        break;
#endif // #if QT_CONFIG(combobox)
#if QT_CONFIG(tabbar)
    case CE_TabBarTabShape:
        if (const auto *tabOpt = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
            if (tabOpt->documentMode) {
                p->save();
                bool isUnified = false;
                if (w) {
                    QRect tabRect = tabOpt->rect;
                    QPoint windowTabStart = w->mapTo(w->window(), tabRect.topLeft());
                    isUnified = isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowTabStart.y());
                }

                const int tabOverlap = proxy()->pixelMetric(PM_TabBarTabOverlap, opt, w);
                drawTabShape(p, tabOpt, isUnified, tabOverlap);

                p->restore();
                return;
            }

            const bool isActive = tabOpt->state & State_Active;
            const bool isEnabled = tabOpt->state & State_Enabled;
            const bool isPressed = tabOpt->state & State_Sunken;
            const bool isSelected = tabOpt->state & State_Selected;
            const auto tabDirection = QMacStylePrivate::tabDirection(tabOpt->shape);
            const bool verticalTabs = tabDirection == QMacStylePrivate::East
                                   || tabDirection == QMacStylePrivate::West;

            QStyleOptionTab::TabPosition tp = tabOpt->position;
            QStyleOptionTab::SelectedPosition sp = tabOpt->selectedPosition;
            if (tabOpt->direction == Qt::RightToLeft && !verticalTabs) {
                if (tp == QStyleOptionTab::Beginning)
                    tp = QStyleOptionTab::End;
                else if (tp == QStyleOptionTab::End)
                    tp = QStyleOptionTab::Beginning;

                if (sp == QStyleOptionTab::NextIsSelected)
                    sp = QStyleOptionTab::PreviousIsSelected;
                else if (sp == QStyleOptionTab::PreviousIsSelected)
                    sp = QStyleOptionTab::NextIsSelected;
            }

            // Alas, NSSegmentedControl and NSSegmentedCell are letting us down.
            // We're not able to draw it at will, either calling -[drawSegment:
            // inFrame:withView:], -[drawRect:] or anything in between. Besides,
            // there's no public API do draw the pressed state, AFAICS. We'll use
            // a push NSButton instead and clip the CGContext.
            // NOTE/TODO: this is not true. On 10.13 NSSegmentedControl works with
            // some (black?) magic/magic dances, on 10.14 it simply works (was
            // it fixed in AppKit?). But, indeed, we cannot make a tab 'pressed'
            // with NSSegmentedControl (only selected), so we stay with buttons
            // (mixing buttons and NSSegmentedControl for such a simple thing
            // is too much work).

            const auto cs = d->effectiveAquaSizeConstrain(opt, w);
            // Extra hacks to get the proper pressed appreance when not selected or selected and inactive
            const bool needsInactiveHack = (!isActive && isSelected);
            const auto ct = !needsInactiveHack && (isSelected || tp == QStyleOptionTab::OnlyOneTab) ?
                    QMacStylePrivate::Button_PushButton :
                    QMacStylePrivate::Button_PopupButton;
            const bool isPopupButton = ct == QMacStylePrivate::Button_PopupButton;
            const auto cw = QMacStylePrivate::CocoaControl(ct, cs);
            auto *pb = static_cast<NSButton *>(d->cocoaControl(cw));

            auto vOffset = isPopupButton ? 1 : 2;
            if (tabDirection == QMacStylePrivate::East)
                vOffset -= 1;
            const auto outerAdjust = isPopupButton ? 1 : 4;
            const auto innerAdjust = isPopupButton ? 20 : 10;
            QRectF frameRect = tabOpt->rect;
            if (verticalTabs)
                frameRect = QRectF(frameRect.y(), frameRect.x(), frameRect.height(), frameRect.width());
            // Adjust before clipping
            frameRect = frameRect.translated(0, vOffset);
            switch (tp) {
            case QStyleOptionTab::Beginning:
                // Pressed state hack: tweak adjustments in preparation for flip below
                if (!isSelected && tabDirection == QMacStylePrivate::West)
                    frameRect = frameRect.adjusted(-innerAdjust, 0, outerAdjust, 0);
                else
                    frameRect = frameRect.adjusted(-outerAdjust, 0, innerAdjust, 0);
                break;
            case QStyleOptionTab::Middle:
                frameRect = frameRect.adjusted(-innerAdjust, 0, innerAdjust, 0);
                break;
            case QStyleOptionTab::End:
                // Pressed state hack: tweak adjustments in preparation for flip below
                if (isSelected || tabDirection == QMacStylePrivate::West)
                    frameRect = frameRect.adjusted(-innerAdjust, 0, outerAdjust, 0);
                else
                    frameRect = frameRect.adjusted(-outerAdjust, 0, innerAdjust, 0);
                break;
            case QStyleOptionTab::OnlyOneTab:
                frameRect = frameRect.adjusted(-outerAdjust, 0, outerAdjust, 0);
                break;
            }
            pb.frame = frameRect.toCGRect();

            pb.enabled = isEnabled;
            [pb highlight:isPressed];
            // Set off state when inactive. See needsInactiveHack for when it's selected
            pb.state = (isActive && isSelected && !isPressed) ? NSOnState : NSOffState;

            const auto drawBezelBlock = ^(CGContextRef ctx, const CGRect &r) {
                CGContextClipToRect(ctx, opt->rect.toCGRect());
                if (!isSelected || needsInactiveHack) {
                    // Final stage of the pressed state hack: flip NSPopupButton rendering
                    if (!verticalTabs && tp == QStyleOptionTab::End) {
                        CGContextTranslateCTM(ctx, opt->rect.right(), 0);
                        CGContextScaleCTM(ctx, -1, 1);
                        CGContextTranslateCTM(ctx, -frameRect.left(), 0);
                    } else if (tabDirection == QMacStylePrivate::West && tp == QStyleOptionTab::Beginning) {
                        CGContextTranslateCTM(ctx, 0, opt->rect.top());
                        CGContextScaleCTM(ctx, 1, -1);
                        CGContextTranslateCTM(ctx, 0, -frameRect.right());
                    } else if (tabDirection == QMacStylePrivate::East && tp == QStyleOptionTab::End) {
                        CGContextTranslateCTM(ctx, 0, opt->rect.bottom());
                        CGContextScaleCTM(ctx, 1, -1);
                        CGContextTranslateCTM(ctx, 0, -frameRect.left());
                    }
                }

                // Rotate and translate CTM when vertical
                // On macOS: positive angle is CW, negative is CCW
                if (tabDirection == QMacStylePrivate::West) {
                    CGContextTranslateCTM(ctx, 0, frameRect.right());
                    CGContextRotateCTM(ctx, -M_PI_2);
                    CGContextTranslateCTM(ctx, -frameRect.left(), 0);
                } else if (tabDirection == QMacStylePrivate::East) {
                    CGContextTranslateCTM(ctx, opt->rect.right(), 0);
                    CGContextRotateCTM(ctx, M_PI_2);
                }

                [pb.cell drawBezelWithFrame:r inView:pb.superview];
            };

            if (needsInactiveHack) {
                // First, render tab as non-selected tab on a pixamp
                const qreal pixelRatio = p->device()->devicePixelRatioF();
                QImage tabPixmap(opt->rect.size() * pixelRatio, QImage::Format_ARGB32_Premultiplied);
                tabPixmap.setDevicePixelRatio(pixelRatio);
                tabPixmap.fill(Qt::transparent);
                QPainter tabPainter(&tabPixmap);
                d->drawNSViewInRect(pb, frameRect, &tabPainter, ^(CGContextRef ctx, const CGRect &r) {
                    CGContextTranslateCTM(ctx, -opt->rect.left(), -opt->rect.top());
                    drawBezelBlock(ctx, r);
                });
                tabPainter.end();

                // Then, darken it with the proper shade of gray
                const qreal inactiveGray = 0.898; // As measured
                const int inactiveGray8 = qRound(inactiveGray * 255.0);
                const QRgb inactiveGrayRGB = qRgb(inactiveGray8, inactiveGray8, inactiveGray8);
                for (int l = 0; l < tabPixmap.height(); ++l) {
                    auto *line = reinterpret_cast<QRgb*>(tabPixmap.scanLine(l));
                    for (int i = 0; i < tabPixmap.width(); ++i) {
                        if (qAlpha(line[i]) == 255) {
                            line[i] = inactiveGrayRGB;
                        } else if (qAlpha(line[i]) > 128) {
                            const int g = qRound(inactiveGray * qRed(line[i]));
                            line[i] = qRgba(g, g, g, qAlpha(line[i]));
                        }
                    }
                }

                // Finally, draw the tab pixmap on the current painter
                p->drawImage(opt->rect, tabPixmap);
            } else {
                d->drawNSViewInRect(pb, frameRect, p, drawBezelBlock);
            }

            if (!isSelected && sp != QStyleOptionTab::NextIsSelected
                    && tp != QStyleOptionTab::End
                    && tp != QStyleOptionTab::OnlyOneTab) {
                static const QPen separatorPen(Qt::black, 1.0);
                p->save();
                p->setOpacity(isEnabled ? 0.105 : 0.06); // As measured
                p->setPen(separatorPen);
                if (tabDirection == QMacStylePrivate::West) {
                    p->drawLine(QLineF(opt->rect.left() + 1.5, opt->rect.bottom(),
                                       opt->rect.right() - 0.5, opt->rect.bottom()));
                } else if (tabDirection == QMacStylePrivate::East) {
                    p->drawLine(QLineF(opt->rect.left(), opt->rect.bottom(),
                                       opt->rect.right() - 0.5, opt->rect.bottom()));
                } else {
                    p->drawLine(QLineF(opt->rect.right(), opt->rect.top() + 1.0,
                                       opt->rect.right(), opt->rect.bottom() - 0.5));
                }
                p->restore();
            }

            // TODO Needs size adjustment to fit the focus ring
            if (tabOpt->state & State_HasFocus) {
                QMacStylePrivate::CocoaControlType focusRingType;
                switch (tp) {
                case QStyleOptionTab::Beginning:
                    focusRingType = verticalTabs ? QMacStylePrivate::SegmentedControl_Last
                                                 : QMacStylePrivate::SegmentedControl_First;
                    break;
                case QStyleOptionTab::Middle:
                    focusRingType = QMacStylePrivate::SegmentedControl_Middle;
                    break;
                case QStyleOptionTab::End:
                    focusRingType = verticalTabs ? QMacStylePrivate::SegmentedControl_First
                                                 : QMacStylePrivate::SegmentedControl_Last;
                    break;
                case QStyleOptionTab::OnlyOneTab:
                    focusRingType = QMacStylePrivate::SegmentedControl_Single;
                    break;
                }
            }
        }
        break;
    case CE_TabBarTabLabel:
        if (const auto *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
            QStyleOptionTab myTab = *tab;
            const auto tabDirection = QMacStylePrivate::tabDirection(tab->shape);
            const bool verticalTabs = tabDirection == QMacStylePrivate::East
                                   || tabDirection == QMacStylePrivate::West;

            // Check to see if we use have the same as the system font
            // (QComboMenuItem is internal and should never be seen by the
            // outside world, unless they read the source, in which case, it's
            // their own fault).
            const bool nonDefaultFont = p->font() != qt_app_fonts_hash()->value("QComboMenuItem");

            if (!myTab.documentMode && (myTab.state & State_Selected) && (myTab.state & State_Active))
                if (const auto *tabBar = qobject_cast<const QTabBar *>(w))
                    if (!tabBar->tabTextColor(tabBar->currentIndex()).isValid())
                        myTab.palette.setColor(QPalette::WindowText, Qt::white);

            if (myTab.documentMode && isDarkMode()) {
                bool active = (myTab.state & State_Selected) && (myTab.state & State_Active);
                myTab.palette.setColor(QPalette::WindowText, active ? Qt::white : Qt::gray);
            }

            int heightOffset = 0;
            if (verticalTabs) {
                heightOffset = -1;
            } else if (nonDefaultFont) {
                if (p->fontMetrics().height() == myTab.rect.height())
                    heightOffset = 2;
            }
            myTab.rect.setHeight(myTab.rect.height() + heightOffset);

            QCommonStyle::drawControl(ce, &myTab, p, w);
        }
        break;
#endif
#if QT_CONFIG(dockwidget)
    case CE_DockWidgetTitle:
        if (const auto *dwOpt = qstyleoption_cast<const QStyleOptionDockWidget *>(opt)) {
            const bool isVertical = dwOpt->verticalTitleBar;
            const auto effectiveRect = isVertical ? opt->rect.transposed() : opt->rect;
            p->save();
            if (isVertical) {
                p->translate(effectiveRect.left(), effectiveRect.top() + effectiveRect.width());
                p->rotate(-90);
                p->translate(-effectiveRect.left(), -effectiveRect.top());
            }

            // fill title bar background
            QLinearGradient linearGrad;
            linearGrad.setStart(QPointF(0, 0));
            linearGrad.setFinalStop(QPointF(0, 2 * effectiveRect.height()));
            linearGrad.setColorAt(0, opt->palette.button().color());
            linearGrad.setColorAt(1, opt->palette.dark().color());
            p->fillRect(effectiveRect, linearGrad);

            // draw horizontal line at bottom
            p->setPen(opt->palette.dark().color());
            p->drawLine(effectiveRect.bottomLeft(), effectiveRect.bottomRight());

            if (!dwOpt->title.isEmpty()) {
                auto titleRect = proxy()->subElementRect(SE_DockWidgetTitleBarText, opt, w);
                if (isVertical)
                    titleRect = QRect(effectiveRect.left() + opt->rect.bottom() - titleRect.bottom(),
                                      effectiveRect.top() + titleRect.left() - opt->rect.left(),
                                      titleRect.height(),
                                      titleRect.width());

                const auto text = p->fontMetrics().elidedText(dwOpt->title, Qt::ElideRight, titleRect.width());
                proxy()->drawItemText(p, titleRect, Qt::AlignCenter, dwOpt->palette,
                                      dwOpt->state & State_Enabled, text, QPalette::WindowText);
            }
            p->restore();
        }
        break;
#endif
    case CE_FocusFrame: {
        const auto *ff = qobject_cast<const QFocusFrame *>(w);
        const auto *ffw = ff ? ff->widget() : nullptr;
        const auto ct = [=] {
            if (ffw) {
                if (ffw->inherits("QCheckBox"))
                    return QMacStylePrivate::Button_CheckBox;
                if (ffw->inherits("QRadioButton"))
                    return QMacStylePrivate::Button_RadioButton;
                if (ffw->inherits("QLineEdit") || ffw->inherits("QTextEdit"))
                    return QMacStylePrivate::TextField;
            }

            return QMacStylePrivate::Box; // Not really, just make it the default
        } ();
        const auto cs = ffw ? (ffw->testAttribute(Qt::WA_MacMiniSize) ? QStyleHelper::SizeMini :
                               ffw->testAttribute(Qt::WA_MacSmallSize) ? QStyleHelper::SizeSmall :
                               QStyleHelper::SizeLarge) :
                        QStyleHelper::SizeLarge;
        const int hMargin = proxy()->pixelMetric(QStyle::PM_FocusFrameHMargin, opt, w);
        const int vMargin = proxy()->pixelMetric(QStyle::PM_FocusFrameVMargin, opt, w);
        d->drawFocusRing(p, opt->rect, hMargin, vMargin, QMacStylePrivate::CocoaControl(ct, cs));
        break; }
    case CE_MenuEmptyArea:
        // Skip: PE_PanelMenu fills in everything
        break;
    case CE_MenuItem:
    case CE_MenuHMargin:
    case CE_MenuVMargin:
    case CE_MenuTearoff:
    case CE_MenuScroller:
        if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
            const bool active = mi->state & State_Selected;
            if (active)
                p->fillRect(mi->rect, mi->palette.highlight());

            const QStyleHelper::WidgetSizePolicy widgetSize = d->aquaSizeConstrain(opt, w);

            if (ce == CE_MenuTearoff) {
                p->setPen(QPen(mi->palette.dark().color(), 1, Qt::DashLine));
                p->drawLine(mi->rect.x() + 2, mi->rect.y() + mi->rect.height() / 2 - 1,
                            mi->rect.x() + mi->rect.width() - 4,
                            mi->rect.y() + mi->rect.height() / 2 - 1);
                p->setPen(QPen(mi->palette.light().color(), 1, Qt::DashLine));
                p->drawLine(mi->rect.x() + 2, mi->rect.y() + mi->rect.height() / 2,
                            mi->rect.x() + mi->rect.width() - 4,
                            mi->rect.y() + mi->rect.height() / 2);
            } else if (ce == CE_MenuScroller) {
                const QSize scrollerSize = QSize(10, 8);
                const int scrollerVOffset = 5;
                const int left = mi->rect.x() + (mi->rect.width() - scrollerSize.width()) / 2;
                const int right = left + scrollerSize.width();
                int top;
                int bottom;
                if (opt->state & State_DownArrow) {
                    bottom = mi->rect.y() + scrollerVOffset;
                    top = bottom + scrollerSize.height();
                } else {
                    bottom = mi->rect.bottom() - scrollerVOffset;
                    top = bottom - scrollerSize.height();
                }
                p->save();
                p->setRenderHint(QPainter::Antialiasing);
                QPainterPath path;
                path.moveTo(left, bottom);
                path.lineTo(right, bottom);
                path.lineTo((left + right) / 2, top);
                p->fillPath(path, opt->palette.buttonText());
                p->restore();
            } else if (ce != CE_MenuItem) {
                break;
            }

            if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
                CGColorRef separatorColor = [NSColor quaternaryLabelColor].CGColor;
                const QRect separatorRect = QRect(mi->rect.left(), mi->rect.center().y(), mi->rect.width(), 2);
                p->fillRect(separatorRect, qt_mac_toQColor(separatorColor));
                break;
            }

            const int maxpmw = mi->maxIconWidth;
            const bool enabled = mi->state & State_Enabled;

            int xpos = mi->rect.x() + 18;
            int checkcol = maxpmw;
            if (!enabled)
                p->setPen(mi->palette.text().color());
            else if (active)
                p->setPen(mi->palette.highlightedText().color());
            else
                p->setPen(mi->palette.buttonText().color());

            if (mi->checked) {
                QStyleOption checkmarkOpt;
                checkmarkOpt.initFrom(w);

                const int mw = checkcol + macItemFrame;
                const int mh = mi->rect.height() + macItemFrame;
                const int xp = mi->rect.x() + macItemFrame;
                checkmarkOpt.rect = QRect(xp, mi->rect.y() - checkmarkOpt.fontMetrics.descent(), mw, mh);

                checkmarkOpt.state.setFlag(State_On, active);
                checkmarkOpt.state.setFlag(State_Enabled, enabled);
                if (widgetSize == QStyleHelper::SizeMini)
                    checkmarkOpt.state |= State_Mini;
                else if (widgetSize == QStyleHelper::SizeSmall)
                    checkmarkOpt.state |= State_Small;

                // We let drawPrimitive(PE_IndicatorMenuCheckMark) pick the right color
                checkmarkOpt.palette.setColor(QPalette::HighlightedText, p->pen().color());
                checkmarkOpt.palette.setColor(QPalette::Text, p->pen().color());

                proxy()->drawPrimitive(PE_IndicatorMenuCheckMark, &checkmarkOpt, p, w);
            }
            if (!mi->icon.isNull()) {
                QIcon::Mode mode = (mi->state & State_Enabled) ? QIcon::Normal
                                                               : QIcon::Disabled;
                // Always be normal or disabled to follow the Mac style.
                int smallIconSize = proxy()->pixelMetric(PM_SmallIconSize);
                QSize iconSize(smallIconSize, smallIconSize);
#if QT_CONFIG(combobox)
                if (const QComboBox *comboBox = qobject_cast<const QComboBox *>(w)) {
                    iconSize = comboBox->iconSize();
                }
#endif
                QPixmap pixmap = mi->icon.pixmap(window, iconSize, mode);
                int pixw = pixmap.width() / pixmap.devicePixelRatio();
                int pixh = pixmap.height() / pixmap.devicePixelRatio();
                QRect cr(xpos, mi->rect.y(), checkcol, mi->rect.height());
                QRect pmr(0, 0, pixw, pixh);
                pmr.moveCenter(cr.center());
                p->drawPixmap(pmr.topLeft(), pixmap);
                xpos += pixw + 6;
            }

            QString s = mi->text;
            const auto text_flags = Qt::AlignVCenter | Qt::TextHideMnemonic
                                  | Qt::TextSingleLine | Qt::AlignAbsolute;
            int yPos = mi->rect.y();
            if (widgetSize == QStyleHelper::SizeMini)
                yPos += 1;

            const bool isSubMenu = mi->menuItemType == QStyleOptionMenuItem::SubMenu;
            const int tabwidth = isSubMenu ? 9 : mi->tabWidth;

            QString rightMarginText;
            if (isSubMenu)
                rightMarginText = QStringLiteral("\u25b6\ufe0e"); // U+25B6 U+FE0E: BLACK RIGHT-POINTING TRIANGLE

            // If present, save and remove embedded shorcut from text
            const int tabIndex = s.indexOf(QLatin1Char('\t'));
            if (tabIndex >= 0) {
                if (!isSubMenu) // ... but ignore it if it's a submenu.
                    rightMarginText = s.mid(tabIndex + 1);
                s = s.left(tabIndex);
            }

            p->save();
            if (!rightMarginText.isEmpty()) {
                p->setFont(qt_app_fonts_hash()->value("QMenuItem", p->font()));
                int xp = mi->rect.right() - tabwidth - macRightBorder + 2;
                if (!isSubMenu)
                    xp -= macItemHMargin + macItemFrame + 3; // Adjust for shortcut
                p->drawText(xp, yPos, tabwidth, mi->rect.height(), text_flags | Qt::AlignRight, rightMarginText);
            }

            if (!s.isEmpty()) {
                const int xm = macItemFrame + maxpmw + macItemHMargin;
                QFont myFont = mi->font;
                // myFont may not have any "hard" flags set. We override
                // the point size so that when it is resolved against the device, this font will win.
                // This is mainly to handle cases where someone sets the font on the window
                // and then the combo inherits it and passes it onward. At that point the resolve mask
                // is very, very weak. This makes it stonger.
                myFont.setPointSizeF(QFontInfo(mi->font).pointSizeF());

                // QTBUG-65653: Our own text rendering doesn't look good enough, especially on non-retina
                // displays. Worked around here while waiting for a proper fix in QCoreTextFontEngine.
                // Only if we're not using QCoreTextFontEngine we do fallback to our own text rendering.
                const auto *fontEngine = QFontPrivate::get(myFont)->engineForScript(QChar::Script_Common);
                Q_ASSERT(fontEngine);
                if (fontEngine->type() == QFontEngine::Multi) {
                    fontEngine = static_cast<const QFontEngineMulti *>(fontEngine)->engine(0);
                    Q_ASSERT(fontEngine);
                }
                if (fontEngine->type() == QFontEngine::Mac) {
                    NSFont *f = (NSFont *)(CTFontRef)fontEngine->handle();

                    // Respect the menu item palette as set in the style option.
                    const auto pc = p->pen().color();
                    NSColor *c = [NSColor colorWithSRGBRed:pc.redF()
                                                     green:pc.greenF()
                                                      blue:pc.blueF()
                                                     alpha:pc.alphaF()];

                    s = qt_mac_removeMnemonics(s);

                    QMacCGContext cgCtx(p);
                    d->setupNSGraphicsContext(cgCtx, YES);

                    // Draw at point instead of in rect, as the rect we've computed for the menu item
                    // is based on the font metrics we got from HarfBuzz, so we may risk having CoreText
                    // line-break the string if it doesn't fit the given rect. It's better to draw outside
                    // the rect and possibly overlap something than to have part of the text disappear.
                    [s.toNSString() drawAtPoint:CGPointMake(xpos, yPos)
                                withAttributes:@{ NSFontAttributeName:f, NSForegroundColorAttributeName:c,
                                                  NSObliquenessAttributeName: [NSNumber numberWithDouble: myFont.italic() ? 0.3 : 0.0]}];

                    d->restoreNSGraphicsContext(cgCtx);
                } else {
                    p->setFont(myFont);
                    p->drawText(xpos, yPos, mi->rect.width() - xm - tabwidth + 1,
                                mi->rect.height(), text_flags, s);
                }
            }
            p->restore();
        }
        break;
    case CE_MenuBarItem:
    case CE_MenuBarEmptyArea:
        if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
            const bool selected = (opt->state & State_Selected) && (opt->state & State_Enabled) && (opt->state & State_Sunken);
            const QBrush bg = selected ? mi->palette.highlight() : mi->palette.window();
            p->fillRect(mi->rect, bg);

            if (ce != CE_MenuBarItem)
                break;

            if (!mi->icon.isNull()) {
                int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
                drawItemPixmap(p, mi->rect,
                                  Qt::AlignCenter | Qt::TextHideMnemonic | Qt::TextDontClip
                                  | Qt::TextSingleLine,
                                  mi->icon.pixmap(window, QSize(iconExtent, iconExtent),
                          (mi->state & State_Enabled) ? QIcon::Normal : QIcon::Disabled));
            } else {
                drawItemText(p, mi->rect,
                                Qt::AlignCenter | Qt::TextHideMnemonic | Qt::TextDontClip
                                | Qt::TextSingleLine,
                                mi->palette, mi->state & State_Enabled,
                                mi->text, selected ? QPalette::HighlightedText : QPalette::ButtonText);
            }
        }
        break;
    case CE_ProgressBarLabel:
    case CE_ProgressBarGroove:
        // Do nothing. All done in CE_ProgressBarContents. Only keep these for proxy style overrides.
        break;
    case CE_ProgressBarContents:
        if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
            const bool isIndeterminate = (pb->minimum == 0 && pb->maximum == 0);
            const bool vertical = pb->orientation == Qt::Vertical;
            const bool inverted = pb->invertedAppearance;
            bool reverse = (!vertical && (pb->direction == Qt::RightToLeft));
            if (inverted)
                reverse = !reverse;

            QRect rect = pb->rect;
            if (vertical)
                rect = rect.transposed();
            const CGRect cgRect = rect.toCGRect();

            const auto aquaSize = d->effectiveAquaSizeConstrain(opt, w);
            const QProgressStyleAnimation *animation = qobject_cast<QProgressStyleAnimation*>(d->animation(opt->styleObject));
            QIndeterminateProgressIndicator *ipi = nil;
            if (isIndeterminate || animation)
                ipi = static_cast<QIndeterminateProgressIndicator *>(d->cocoaControl({ QMacStylePrivate::ProgressIndicator_Indeterminate, aquaSize }));
            if (isIndeterminate) {
                // QIndeterminateProgressIndicator derives from NSProgressIndicator. We use a single
                // instance that we start animating as soon as one of the progress bars is indeterminate.
                // Since they will be in sync (as it's the case in Cocoa), we just need to draw it with
                // the right geometry when the animation triggers an update. However, we can't hide it
                // entirely between frames since that would stop the animation, so we just set its alpha
                // value to 0. Same if we remove it from its superview. See QIndeterminateProgressIndicator
                // implementation for details.
                if (!animation && opt->styleObject) {
                    auto *animation = new QProgressStyleAnimation(d->animateSpeed(QMacStylePrivate::AquaProgressBar), opt->styleObject);
                    // NSProgressIndicator is heavier to draw than the HITheme API, so we reduce the frame rate a couple notches.
                    animation->setFrameRate(QStyleAnimation::FifteenFps);
                    d->startAnimation(animation);
                    [ipi startAnimation];
                }

                d->setupNSGraphicsContext(cg, NO);
                d->setupVerticalInvertedXform(cg, reverse, vertical, cgRect);
                [ipi drawWithFrame:cgRect inView:d->backingStoreNSView];
                d->restoreNSGraphicsContext(cg);
            } else {
                if (animation) {
                    d->stopAnimation(opt->styleObject);
                    [ipi stopAnimation];
                }

                const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::ProgressIndicator_Determinate, aquaSize);
                auto *pi = static_cast<NSProgressIndicator *>(d->cocoaControl(cw));
                d->drawNSViewInRect(pi, rect, p, ^(CGContextRef ctx, const CGRect &rect) {
                    d->setupVerticalInvertedXform(ctx, reverse, vertical, rect);
                    pi.minValue = pb->minimum;
                    pi.maxValue = pb->maximum;
                    pi.doubleValue = pb->progress;
                    [pi drawRect:rect];
                });
            }
        }
        break;
    case CE_SizeGrip: {
        // This is not HIG kosher: Fall back to the old stuff until we decide what to do.
#ifndef QT_NO_MDIAREA
        if (!w || !qobject_cast<QMdiSubWindow *>(w->parentWidget()))
#endif
            break;

        if (w->testAttribute(Qt::WA_MacOpaqueSizeGrip))
            p->fillRect(opt->rect, opt->palette.window());

        QPen lineColor = QColor(82, 82, 82, 192);
        lineColor.setWidth(1);
        p->save();
        p->setRenderHint(QPainter::Antialiasing);
        p->setPen(lineColor);
        const Qt::LayoutDirection layoutDirection = w ? w->layoutDirection() : qApp->layoutDirection();
        const int NumLines = 3;
        for (int l = 0; l < NumLines; ++l) {
            const int offset = (l * 4 + 3);
            QPoint start, end;
            if (layoutDirection == Qt::LeftToRight) {
                start = QPoint(opt->rect.width() - offset, opt->rect.height() - 1);
                end = QPoint(opt->rect.width() - 1, opt->rect.height() - offset);
            } else {
                start = QPoint(offset, opt->rect.height() - 1);
                end = QPoint(1, opt->rect.height() - offset);
            }
            p->drawLine(start, end);
        }
        p->restore();
        break;
        }
    case CE_Splitter:
        if (opt->rect.width() > 1 && opt->rect.height() > 1) {
            const bool isVertical = !(opt->state & QStyle::State_Horizontal);
            // Qt refers to the layout orientation, while Cocoa refers to the divider's.
            const auto ct = isVertical ? QMacStylePrivate::SplitView_Horizontal : QMacStylePrivate::SplitView_Vertical;
            const auto cw = QMacStylePrivate::CocoaControl(ct, QStyleHelper::SizeLarge);
            auto *sv = static_cast<NSSplitView *>(d->cocoaControl(cw));
            sv.frame = opt->rect.toCGRect();
            d->drawNSViewInRect(sv, opt->rect, p, ^(CGContextRef, const CGRect &rect) {
                [sv drawDividerInRect:rect];
            });
        } else {
            QPen oldPen = p->pen();
            p->setPen(opt->palette.dark().color());
            if (opt->state & QStyle::State_Horizontal)
                p->drawLine(opt->rect.topLeft(), opt->rect.bottomLeft());
            else
                p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
            p->setPen(oldPen);
        }
        break;
    case CE_RubberBand:
        if (const QStyleOptionRubberBand *rubber = qstyleoption_cast<const QStyleOptionRubberBand *>(opt)) {
            QColor fillColor(opt->palette.color(QPalette::Disabled, QPalette::Highlight));
            if (!rubber->opaque) {
                QColor strokeColor;
                // I retrieved these colors from the Carbon-Dev mailing list
                strokeColor.setHsvF(0, 0, 0.86, 1.0);
                fillColor.setHsvF(0, 0, 0.53, 0.25);
                if (opt->rect.width() * opt->rect.height() <= 3) {
                    p->fillRect(opt->rect, strokeColor);
                } else {
                    QPen oldPen = p->pen();
                    QBrush oldBrush = p->brush();
                    QPen pen(strokeColor);
                    p->setPen(pen);
                    p->setBrush(fillColor);
                    QRect adjusted = opt->rect.adjusted(1, 1, -1, -1);
                    if (adjusted.isValid())
                        p->drawRect(adjusted);
                    p->setPen(oldPen);
                    p->setBrush(oldBrush);
                }
            } else {
                p->fillRect(opt->rect, fillColor);
            }
        }
        break;
#ifndef QT_NO_TOOLBAR
    case CE_ToolBar: {
        const QStyleOptionToolBar *toolBar = qstyleoption_cast<const QStyleOptionToolBar *>(opt);
        const bool isDarkMode = qt_mac_applicationIsInDarkMode();

        // Unified title and toolbar drawing. In this mode the cocoa platform plugin will
        // fill the top toolbar area part with a background gradient that "unifies" with
        // the title bar. The following code fills the toolBar area with transparent pixels
        // to make that gradient visible.
        if (w) {
#if QT_CONFIG(mainwindow)
            if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(w->window())) {
                if (toolBar && toolBar->toolBarArea == Qt::TopToolBarArea && mainWindow->unifiedTitleAndToolBarOnMac()) {
                    // fill with transparent pixels.
                    p->save();
                    p->setCompositionMode(QPainter::CompositionMode_Source);
                    p->fillRect(opt->rect, Qt::transparent);
                    p->restore();

                    // Draw a horizontal separator line at the toolBar bottom if the "unified" area ends here.
                    // There might be additional toolbars or other widgets such as tab bars in document
                    // mode below. Determine this by making a unified toolbar area test for the row below
                    // this toolbar.
                    const QPoint windowToolbarEnd = w->mapTo(w->window(), opt->rect.bottomLeft());
                    const bool isEndOfUnifiedArea = !isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowToolbarEnd.y() + 1);
                    if (isEndOfUnifiedArea) {
                        const int margin = qt_mac_aqua_get_metric(SeparatorSize);
                        const auto separatorRect = QRect(opt->rect.left(), opt->rect.bottom(), opt->rect.width(), margin);
                        p->fillRect(separatorRect, isDarkMode ? darkModeSeparatorLine : opt->palette.dark().color());
                    }
                    break;
                }
            }
#endif
        }

        // draw background gradient
        QLinearGradient linearGrad;
        if (opt->state & State_Horizontal)
            linearGrad = QLinearGradient(0, opt->rect.top(), 0, opt->rect.bottom());
        else
            linearGrad = QLinearGradient(opt->rect.left(), 0,  opt->rect.right(), 0);

        QColor mainWindowGradientBegin = isDarkMode ? darkMainWindowGradientBegin : lightMainWindowGradientBegin;
        QColor mainWindowGradientEnd = isDarkMode ? darkMainWindowGradientEnd : lightMainWindowGradientEnd;

        linearGrad.setColorAt(0, mainWindowGradientBegin);
        linearGrad.setColorAt(1, mainWindowGradientEnd);
        p->fillRect(opt->rect, linearGrad);

        p->save();
        QRect toolbarRect = isDarkMode ? opt->rect.adjusted(0, 0, 0, 1) : opt->rect;
        if (opt->state & State_Horizontal) {
            p->setPen(isDarkMode ? darkModeSeparatorLine : mainWindowGradientBegin.lighter(114));
            p->drawLine(toolbarRect.topLeft(), toolbarRect.topRight());
            p->setPen(isDarkMode ? darkModeSeparatorLine :mainWindowGradientEnd.darker(114));
            p->drawLine(toolbarRect.bottomLeft(), toolbarRect.bottomRight());
        } else {
            p->setPen(isDarkMode ? darkModeSeparatorLine : mainWindowGradientBegin.lighter(114));
            p->drawLine(toolbarRect.topLeft(), toolbarRect.bottomLeft());
            p->setPen(isDarkMode ? darkModeSeparatorLine : mainWindowGradientEnd.darker(114));
            p->drawLine(toolbarRect.topRight(), toolbarRect.bottomRight());
        }
        p->restore();


        } break;
#endif
    default:
        QCommonStyle::drawControl(ce, opt, p, w);
        break;
    }
}

static void setLayoutItemMargins(int left, int top, int right, int bottom, QRect *rect, Qt::LayoutDirection dir)
{
    if (dir == Qt::RightToLeft) {
        rect->adjust(-right, top, -left, bottom);
    } else {
        rect->adjust(left, top, right, bottom);
    }
}

QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt,
                                const QWidget *widget) const
{
    Q_D(const QMacStyle);
    QRect rect;
    const int controlSize = getControlSize(opt, widget);

    switch (sr) {
#if QT_CONFIG(itemviews)
    case SE_ItemViewItemText:
        if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
            int fw = proxy()->pixelMetric(PM_FocusFrameHMargin, opt, widget);
            // We add the focusframeargin between icon and text in commonstyle
            rect = QCommonStyle::subElementRect(sr, opt, widget);
            if (vopt->features & QStyleOptionViewItem::HasDecoration)
                rect.adjust(-fw, 0, 0, 0);
        }
        break;
#endif
    case SE_ToolBoxTabContents:
        rect = QCommonStyle::subElementRect(sr, opt, widget);
        break;
    case SE_PushButtonContents:
        if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
            // Comment from the old HITheme days:
            //   "Unlike Carbon, we want the button to always be drawn inside its bounds.
            //    Therefore, the button is a bit smaller, so that even if it got focus,
            //    the focus 'shadow' will be inside. Adjust the content rect likewise."
            // In the future, we should consider using -[NSCell titleRectForBounds:].
            // Since it requires configuring the NSButton fully, i.e. frame, image,
            // title and font, we keep things more manual until we are more familiar
            // with side effects when changing NSButton state.
            const auto ct = cocoaControlType(btn, widget);
            const auto cs = d->effectiveAquaSizeConstrain(btn, widget);
            const auto cw = QMacStylePrivate::CocoaControl(ct, cs);
            const auto frameRect = cw.adjustedControlFrame(btn->rect);
            const auto titleMargins = cw.titleMargins();
            rect = (frameRect - titleMargins).toRect();
        }
        break;
    case SE_HeaderLabel: {
        int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt, widget);
        rect.setRect(opt->rect.x() + margin, opt->rect.y(),
                  opt->rect.width() - margin * 2, opt->rect.height() - 2);
        if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
            // Subtract width needed for arrow, if there is one
            if (header->sortIndicator != QStyleOptionHeader::None) {
                if (opt->state & State_Horizontal)
                    rect.setWidth(rect.width() - (headerSectionArrowHeight) - (margin * 2));
                else
                    rect.setHeight(rect.height() - (headerSectionArrowHeight) - (margin * 2));
            }
        }
        rect = visualRect(opt->direction, opt->rect, rect);
        break;
    }
    case SE_HeaderArrow: {
        int h = opt->rect.height();
        int w = opt->rect.width();
        int x = opt->rect.x();
        int y = opt->rect.y();
        int margin = proxy()->pixelMetric(QStyle::PM_HeaderMargin, opt, widget);

        if (opt->state & State_Horizontal) {
            rect.setRect(x + w - margin * 2 - headerSectionArrowHeight, y + 5,
                      headerSectionArrowHeight, h - margin * 2 - 5);
        } else {
            rect.setRect(x + 5, y + h - margin * 2 - headerSectionArrowHeight,
                      w - margin * 2 - 5, headerSectionArrowHeight);
        }
        rect = visualRect(opt->direction, opt->rect, rect);
        break;
    }
    case SE_ProgressBarGroove:
        // Wrong in the secondary dimension, but accurate enough in the main dimension.
        rect  = opt->rect;
        break;
    case SE_ProgressBarLabel:
        break;
    case SE_ProgressBarContents:
        rect = opt->rect;
        break;
    case SE_TreeViewDisclosureItem: {
        rect = opt->rect;
        // As previously returned by HIThemeGetButtonContentBounds
        rect.setLeft(rect.left() + 2 + DisclosureOffset);
        break;
    }
#if QT_CONFIG(tabwidget)
    case SE_TabWidgetLeftCorner:
        if (const QStyleOptionTabWidgetFrame *twf
                = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
            switch (twf->shape) {
            case QTabBar::RoundedNorth:
            case QTabBar::TriangularNorth:
                rect = QRect(QPoint(0, 0), twf->leftCornerWidgetSize);
                break;
            case QTabBar::RoundedSouth:
            case QTabBar::TriangularSouth:
                rect = QRect(QPoint(0, twf->rect.height() - twf->leftCornerWidgetSize.height()),
                          twf->leftCornerWidgetSize);
                break;
            default:
                break;
            }
            rect = visualRect(twf->direction, twf->rect, rect);
        }
        break;
    case SE_TabWidgetRightCorner:
        if (const QStyleOptionTabWidgetFrame *twf
                = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
            switch (twf->shape) {
            case QTabBar::RoundedNorth:
            case QTabBar::TriangularNorth:
                rect = QRect(QPoint(twf->rect.width() - twf->rightCornerWidgetSize.width(), 0),
                          twf->rightCornerWidgetSize);
                break;
            case QTabBar::RoundedSouth:
            case QTabBar::TriangularSouth:
                rect = QRect(QPoint(twf->rect.width() - twf->rightCornerWidgetSize.width(),
                                 twf->rect.height() - twf->rightCornerWidgetSize.height()),
                          twf->rightCornerWidgetSize);
                break;
            default:
                break;
            }
            rect = visualRect(twf->direction, twf->rect, rect);
        }
        break;
    case SE_TabWidgetTabContents:
        rect = QCommonStyle::subElementRect(sr, opt, widget);
        if (const auto *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
            if (twf->lineWidth != 0) {
                switch (QMacStylePrivate::tabDirection(twf->shape)) {
                case QMacStylePrivate::North:
                    rect.adjust(+1, +14, -1, -1);
                    break;
                case QMacStylePrivate::South:
                    rect.adjust(+1, +1, -1, -14);
                    break;
                case QMacStylePrivate::West:
                    rect.adjust(+14, +1, -1, -1);
                    break;
                case QMacStylePrivate::East:
                    rect.adjust(+1, +1, -14, -1);
                }
            }
        }
        break;
    case SE_TabBarTabText:
        if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
            QRect dummyIconRect;
            d->tabLayout(tab, widget, &rect, &dummyIconRect);
        }
        break;
    case SE_TabBarTabLeftButton:
    case SE_TabBarTabRightButton:
        if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
            bool selected = tab->state & State_Selected;
            int verticalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget);
            int horizontalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget);
            int hpadding = 5;

            bool verticalTabs = tab->shape == QTabBar::RoundedEast
                    || tab->shape == QTabBar::RoundedWest
                    || tab->shape == QTabBar::TriangularEast
                    || tab->shape == QTabBar::TriangularWest;

            QRect tr = tab->rect;
            if (tab->shape == QTabBar::RoundedSouth || tab->shape == QTabBar::TriangularSouth)
                verticalShift = -verticalShift;
            if (verticalTabs) {
                qSwap(horizontalShift, verticalShift);
                horizontalShift *= -1;
                verticalShift *= -1;
            }
            if (tab->shape == QTabBar::RoundedWest || tab->shape == QTabBar::TriangularWest)
                horizontalShift = -horizontalShift;

            tr.adjust(0, 0, horizontalShift, verticalShift);
            if (selected)
            {
                tr.setBottom(tr.bottom() - verticalShift);
                tr.setRight(tr.right() - horizontalShift);
            }

            QSize size = (sr == SE_TabBarTabLeftButton) ? tab->leftButtonSize : tab->rightButtonSize;
            int w = size.width();
            int h = size.height();
            int midHeight = static_cast<int>(qCeil(float(tr.height() - h) / 2));
            int midWidth = ((tr.width() - w) / 2);

            bool atTheTop = true;
            switch (tab->shape) {
            case QTabBar::RoundedWest:
            case QTabBar::TriangularWest:
                atTheTop = (sr == SE_TabBarTabLeftButton);
                break;
            case QTabBar::RoundedEast:
            case QTabBar::TriangularEast:
                atTheTop = (sr == SE_TabBarTabRightButton);
                break;
            default:
                if (sr == SE_TabBarTabLeftButton)
                    rect = QRect(tab->rect.x() + hpadding, midHeight, w, h);
                else
                    rect = QRect(tab->rect.right() - w - hpadding, midHeight, w, h);
                rect = visualRect(tab->direction, tab->rect, rect);
            }
            if (verticalTabs) {
                if (atTheTop)
                    rect = QRect(midWidth, tr.y() + tab->rect.height() - hpadding - h, w, h);
                else
                    rect = QRect(midWidth, tr.y() + hpadding, w, h);
            }
        }
        break;
#endif
    case SE_LineEditContents:
        rect = QCommonStyle::subElementRect(sr, opt, widget);
#if QT_CONFIG(combobox)
        if (widget && qobject_cast<const QComboBox*>(widget->parentWidget()))
            rect.adjust(-1, -2, 0, 0);
        else
#endif
            rect.adjust(-1, -1, 0, +1);
        break;
    case SE_CheckBoxLayoutItem:
        rect = opt->rect;
        if (controlSize == QStyleHelper::SizeLarge) {
            setLayoutItemMargins(+2, +3, -9, -4, &rect, opt->direction);
        } else if (controlSize == QStyleHelper::SizeSmall) {
            setLayoutItemMargins(+1, +5, 0 /* fix */, -6, &rect, opt->direction);
        } else {
            setLayoutItemMargins(0, +7, 0 /* fix */, -6, &rect, opt->direction);
        }
        break;
    case SE_ComboBoxLayoutItem:
#ifndef QT_NO_TOOLBAR
        if (widget && qobject_cast<QToolBar *>(widget->parentWidget())) {
            // Do nothing, because QToolbar needs the entire widget rect.
            // Otherwise it will be clipped. Equivalent to
            // widget->setAttribute(Qt::WA_LayoutUsesWidgetRect), but without
            // all the hassle.
        } else
#endif
        {
            rect = opt->rect;
            if (controlSize == QStyleHelper::SizeLarge) {
                rect.adjust(+3, +2, -3, -4);
            } else if (controlSize == QStyleHelper::SizeSmall) {
                setLayoutItemMargins(+2, +1, -3, -4, &rect, opt->direction);
            } else {
                setLayoutItemMargins(+1, 0, -2, 0, &rect, opt->direction);
            }
        }
        break;
    case SE_LabelLayoutItem:
        rect = opt->rect;
        setLayoutItemMargins(+1, 0 /* SHOULD be -1, done for alignment */, 0, 0 /* SHOULD be -1, done for alignment */, &rect, opt->direction);
        break;
    case SE_ProgressBarLayoutItem: {
        rect = opt->rect;
        int bottom = SIZE(3, 8, 8);
        if (opt->state & State_Horizontal) {
            rect.adjust(0, +1, 0, -bottom);
        } else {
            setLayoutItemMargins(+1, 0, -bottom, 0, &rect, opt->direction);
        }
        break;
    }
    case SE_PushButtonLayoutItem:
        if (const QStyleOptionButton *buttonOpt
                = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
            if ((buttonOpt->features & QStyleOptionButton::Flat))
                break;  // leave rect alone
        }
        rect = opt->rect;
        if (controlSize == QStyleHelper::SizeLarge) {
            rect.adjust(+6, +4, -6, -8);
        } else if (controlSize == QStyleHelper::SizeSmall) {
            rect.adjust(+5, +4, -5, -6);
        } else {
            rect.adjust(+1, 0, -1, -2);
        }
        break;
    case SE_RadioButtonLayoutItem:
        rect = opt->rect;
        if (controlSize == QStyleHelper::SizeLarge) {
            setLayoutItemMargins(+2, +2 /* SHOULD BE +3, done for alignment */,
                                 0, -4 /* SHOULD BE -3, done for alignment */, &rect, opt->direction);
        } else if (controlSize == QStyleHelper::SizeSmall) {
            rect.adjust(0, +6, 0 /* fix */, -5);
        } else {
            rect.adjust(0, +6, 0 /* fix */, -7);
        }
        break;
    case SE_SliderLayoutItem:
        if (const QStyleOptionSlider *sliderOpt
                = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
            rect = opt->rect;
            if (sliderOpt->tickPosition == QSlider::NoTicks) {
                int above = SIZE(3, 0, 2);
                int below = SIZE(4, 3, 0);
                if (sliderOpt->orientation == Qt::Horizontal) {
                    rect.adjust(0, +above, 0, -below);
                } else {
                    rect.adjust(+above, 0, -below, 0);  //### Seems that QSlider flip the position of the ticks in reverse mode.
                }
            } else if (sliderOpt->tickPosition == QSlider::TicksAbove) {
                int below = SIZE(3, 2, 0);
                if (sliderOpt->orientation == Qt::Horizontal) {
                    rect.setHeight(rect.height() - below);
                } else {
                    rect.setWidth(rect.width() - below);
                }
            } else if (sliderOpt->tickPosition == QSlider::TicksBelow) {
                int above = SIZE(3, 2, 0);
                if (sliderOpt->orientation == Qt::Horizontal) {
                    rect.setTop(rect.top() + above);
                } else {
                    rect.setLeft(rect.left() + above);
                }
            }
        }
        break;
    case SE_FrameLayoutItem:
        // hack because QStyleOptionFrame doesn't have a frameStyle member
        if (const QFrame *frame = qobject_cast<const QFrame *>(widget)) {
            rect = opt->rect;
            switch (frame->frameStyle() & QFrame::Shape_Mask) {
            case QFrame::HLine:
                rect.adjust(0, +1, 0, -1);
                break;
            case QFrame::VLine:
                rect.adjust(+1, 0, -1, 0);
                break;
            default:
                ;
            }
        }
        break;
    case SE_GroupBoxLayoutItem:
        rect = opt->rect;
        if (const QStyleOptionGroupBox *groupBoxOpt =
                qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
            /*
                AHIG is very inconsistent when it comes to group boxes.
                Basically, we make sure that (non-checkable) group boxes
                and tab widgets look good when laid out side by side.
            */
            if (groupBoxOpt->subControls & (QStyle::SC_GroupBoxCheckBox
                                            | QStyle::SC_GroupBoxLabel)) {
                int delta;
                if (groupBoxOpt->subControls & QStyle::SC_GroupBoxCheckBox) {
                    delta = SIZE(8, 4, 4);       // guess
                } else {
                    delta = SIZE(15, 12, 12);    // guess
                }
                rect.setTop(rect.top() + delta);
            }
        }
        rect.setBottom(rect.bottom() - 1);
        break;
#if QT_CONFIG(tabwidget)
    case SE_TabWidgetLayoutItem:
        if (const QStyleOptionTabWidgetFrame *tabWidgetOpt =
                qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
            /*
                AHIG specifies "12 or 14" as the distance from the window
                edge. We choose 14 and since the default top margin is 20,
                the overlap is 6.
            */
            rect = tabWidgetOpt->rect;
            if (tabWidgetOpt->shape == QTabBar::RoundedNorth)
                rect.setTop(rect.top() + SIZE(6 /* AHIG */, 3 /* guess */, 2 /* AHIG */));
        }
        break;
#endif
#if QT_CONFIG(dockwidget)
        case SE_DockWidgetCloseButton:
        case SE_DockWidgetFloatButton:
        case SE_DockWidgetTitleBarText:
        case SE_DockWidgetIcon: {
            int iconSize = proxy()->pixelMetric(PM_SmallIconSize, opt, widget);
            int buttonMargin = proxy()->pixelMetric(PM_DockWidgetTitleBarButtonMargin, opt, widget);
            QRect srect = opt->rect;

            const QStyleOptionDockWidget *dwOpt
                = qstyleoption_cast<const QStyleOptionDockWidget*>(opt);
            bool canClose = dwOpt == 0 ? true : dwOpt->closable;
            bool canFloat = dwOpt == 0 ? false : dwOpt->floatable;

            const bool verticalTitleBar = dwOpt->verticalTitleBar;

            // If this is a vertical titlebar, we transpose and work as if it was
            // horizontal, then transpose again.
            if (verticalTitleBar)
                srect = srect.transposed();

            do {
                int right = srect.right();
                int left = srect.left();

                QRect closeRect;
                if (canClose) {
                    QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarCloseButton,
                                            opt, widget).actualSize(QSize(iconSize, iconSize));
                    sz += QSize(buttonMargin, buttonMargin);
                    if (verticalTitleBar)
                        sz = sz.transposed();
                    closeRect = QRect(left,
                                      srect.center().y() - sz.height()/2,
                                      sz.width(), sz.height());
                    left = closeRect.right() + 1;
                }
                if (sr == SE_DockWidgetCloseButton) {
                    rect = closeRect;
                    break;
                }

                QRect floatRect;
                if (canFloat) {
                    QSize sz = proxy()->standardIcon(QStyle::SP_TitleBarNormalButton,
                                            opt, widget).actualSize(QSize(iconSize, iconSize));
                    sz += QSize(buttonMargin, buttonMargin);
                    if (verticalTitleBar)
                        sz = sz.transposed();
                    floatRect = QRect(left,
                                      srect.center().y() - sz.height()/2,
                                      sz.width(), sz.height());
                    left = floatRect.right() + 1;
                }
                if (sr == SE_DockWidgetFloatButton) {
                    rect = floatRect;
                    break;
                }

                QRect iconRect;
                if (const QDockWidget *dw = qobject_cast<const QDockWidget*>(widget)) {
                    QIcon icon;
                    if (dw->isFloating())
                        icon = dw->windowIcon();
                    if (!icon.isNull()
                        && icon.cacheKey() != QApplication::windowIcon().cacheKey()) {
                        QSize sz = icon.actualSize(QSize(rect.height(), rect.height()));
                        if (verticalTitleBar)
                            sz = sz.transposed();
                        iconRect = QRect(right - sz.width(), srect.center().y() - sz.height()/2,
                                         sz.width(), sz.height());
                        right = iconRect.left() - 1;
                    }
                }
                if (sr == SE_DockWidgetIcon) {
                    rect = iconRect;
                    break;
                }

                QRect textRect = QRect(left, srect.top(),
                                       right - left, srect.height());
                if (sr == SE_DockWidgetTitleBarText) {
                    rect = textRect;
                    break;
                }
            } while (false);

            if (verticalTitleBar) {
                rect = QRect(srect.left() + rect.top() - srect.top(),
                          srect.top() + srect.right() - rect.right(),
                          rect.height(), rect.width());
            } else {
                rect = visualRect(opt->direction, srect, rect);
            }
            break;
        }
#endif
    default:
        rect = QCommonStyle::subElementRect(sr, opt, widget);
        break;
    }
    return rect;
}

void QMacStylePrivate::drawToolbarButtonArrow(const QStyleOption *opt, QPainter *p) const
{
    Q_Q(const QMacStyle);
    QStyleOption arrowOpt = *opt;
    arrowOpt.rect = QRect(opt->rect.right() - (toolButtonArrowSize + toolButtonArrowMargin),
                          opt->rect.bottom() - (toolButtonArrowSize + toolButtonArrowMargin),
                          toolButtonArrowSize,
                          toolButtonArrowSize);
    q->proxy()->drawPrimitive(QStyle::PE_IndicatorArrowDown, &arrowOpt, p);
}

void QMacStylePrivate::setupNSGraphicsContext(CGContextRef cg, bool flipped) const
{
    CGContextSaveGState(cg);
    [NSGraphicsContext saveGraphicsState];

    [NSGraphicsContext setCurrentContext:
        [NSGraphicsContext graphicsContextWithCGContext:cg flipped:flipped]];
}

void QMacStylePrivate::restoreNSGraphicsContext(CGContextRef cg) const
{
    [NSGraphicsContext restoreGraphicsState];
    CGContextRestoreGState(cg);
}

void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p,
                                   const QWidget *widget) const
{
    Q_D(const QMacStyle);
    const AppearanceSync sync;
    QMacCGContext cg(p);
    QWindow *window = widget && widget->window() ? widget->window()->windowHandle() : nullptr;
    d->resolveCurrentNSView(window);
    switch (cc) {
    case CC_ScrollBar:
        if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {

            const bool drawTrack = sb->subControls & SC_ScrollBarGroove;
            const bool drawKnob = sb->subControls & SC_ScrollBarSlider;
            if (!drawTrack && !drawKnob)
                break;

            const bool isHorizontal = sb->orientation == Qt::Horizontal;

            if (opt && opt->styleObject && !QMacStylePrivate::scrollBars.contains(opt->styleObject))
                QMacStylePrivate::scrollBars.append(QPointer<QObject>(opt->styleObject));

            static const CGFloat knobWidths[] = { 7.0, 5.0, 5.0 };
            static const CGFloat expandedKnobWidths[] = { 11.0, 9.0, 9.0 };
            const auto cocoaSize = d->effectiveAquaSizeConstrain(opt, widget);
            const CGFloat maxExpandScale = expandedKnobWidths[cocoaSize] / knobWidths[cocoaSize];

            const bool isTransient = proxy()->styleHint(SH_ScrollBar_Transient, opt, widget);
            if (!isTransient)
                d->stopAnimation(opt->styleObject);
            bool wasActive = false;
            CGFloat opacity = 0.0;
            CGFloat expandScale = 1.0;
            CGFloat expandOffset = 0.0;
            bool shouldExpand = false;

            if (QObject *styleObject = opt->styleObject) {
                const int oldPos = styleObject->property("_q_stylepos").toInt();
                const int oldMin = styleObject->property("_q_stylemin").toInt();
                const int oldMax = styleObject->property("_q_stylemax").toInt();
                const QRect oldRect = styleObject->property("_q_stylerect").toRect();
                const QStyle::State oldState = static_cast<QStyle::State>(styleObject->property("_q_stylestate").value<QStyle::State::Int>());
                const uint oldActiveControls = styleObject->property("_q_stylecontrols").toUInt();

                // a scrollbar is transient when the scrollbar itself and
                // its sibling are both inactive (ie. not pressed/hovered/moved)
                const bool transient = isTransient && !opt->activeSubControls && !(sb->state & State_On);

                if (!transient ||
                        oldPos != sb->sliderPosition ||
                        oldMin != sb->minimum ||
                        oldMax != sb->maximum ||
                        oldRect != sb->rect ||
                        oldState != sb->state ||
                        oldActiveControls != sb->activeSubControls) {

                    // if the scrollbar is transient or its attributes, geometry or
                    // state has changed, the opacity is reset back to 100% opaque
                    opacity = 1.0;

                    styleObject->setProperty("_q_stylepos", sb->sliderPosition);
                    styleObject->setProperty("_q_stylemin", sb->minimum);
                    styleObject->setProperty("_q_stylemax", sb->maximum);
                    styleObject->setProperty("_q_stylerect", sb->rect);
                    styleObject->setProperty("_q_stylestate", static_cast<QStyle::State::Int>(sb->state));
                    styleObject->setProperty("_q_stylecontrols", static_cast<uint>(sb->activeSubControls));

                    QScrollbarStyleAnimation *anim  = qobject_cast<QScrollbarStyleAnimation *>(d->animation(styleObject));
                    if (transient) {
                        if (!anim) {
                            anim = new QScrollbarStyleAnimation(QScrollbarStyleAnimation::Deactivating, styleObject);
                            d->startAnimation(anim);
                        } else if (anim->mode() == QScrollbarStyleAnimation::Deactivating) {
                            // the scrollbar was already fading out while the
                            // state changed -> restart the fade out animation
                            anim->setCurrentTime(0);
                        }
                    } else if (anim && anim->mode() == QScrollbarStyleAnimation::Deactivating) {
                        d->stopAnimation(styleObject);
                    }
                }

                QScrollbarStyleAnimation *anim = qobject_cast<QScrollbarStyleAnimation *>(d->animation(styleObject));
                if (anim && anim->mode() == QScrollbarStyleAnimation::Deactivating) {
                    // once a scrollbar was active (hovered/pressed), it retains
                    // the active look even if it's no longer active while fading out
                    if (oldActiveControls)
                        anim->setActive(true);

                    wasActive = anim->wasActive();
                    opacity = anim->currentValue();
                }

                shouldExpand = isTransient && (opt->activeSubControls || wasActive);
                if (shouldExpand) {
                    if (!anim && !oldActiveControls) {
                        // Start expand animation only once and when entering
                        anim = new QScrollbarStyleAnimation(QScrollbarStyleAnimation::Activating, styleObject);
                        d->startAnimation(anim);
                    }
                    if (anim && anim->mode() == QScrollbarStyleAnimation::Activating) {
                        expandScale = 1.0 + (maxExpandScale - 1.0) * anim->currentValue();
                        expandOffset = 5.5 * (1.0 - anim->currentValue());
                    } else {
                        // Keep expanded state after the animation ends, and when fading out
                        expandScale = maxExpandScale;
                        expandOffset = 0.0;
                    }
                }
            }

            d->setupNSGraphicsContext(cg, NO /* flipped */);

            const auto controlType = isHorizontal ? QMacStylePrivate::Scroller_Horizontal : QMacStylePrivate::Scroller_Vertical;
            const auto cw = QMacStylePrivate::CocoaControl(controlType, cocoaSize);
            NSScroller *scroller = static_cast<NSScroller *>(d->cocoaControl(cw));

            const QColor bgColor = QStyleHelper::backgroundColor(opt->palette, widget);
            const bool hasDarkBg = bgColor.red() < 128 && bgColor.green() < 128 && bgColor.blue() < 128;
            if (isTransient) {
                // macOS behavior: as soon as one color channel is >= 128,
                // the background is considered bright, scroller is dark.
                scroller.knobStyle = hasDarkBg? NSScrollerKnobStyleLight : NSScrollerKnobStyleDark;
            } else {
                scroller.knobStyle = NSScrollerKnobStyleDefault;
            }

            scroller.scrollerStyle = isTransient ? NSScrollerStyleOverlay : NSScrollerStyleLegacy;

            if (!setupScroller(scroller, sb))
                break;

            if (isTransient) {
                CGContextBeginTransparencyLayerWithRect(cg, scroller.frame, nullptr);
                CGContextSetAlpha(cg, opacity);
            }

            if (drawTrack) {
                // Draw the track when hovering. Expand by shifting the track rect.
                if (!isTransient || opt->activeSubControls || wasActive) {
                    CGRect trackRect = scroller.bounds;
                    if (isHorizontal)
                        trackRect.origin.y += expandOffset;
                    else
                        trackRect.origin.x += expandOffset;
                    [scroller drawKnobSlotInRect:trackRect highlight:NO];
                }
            }

            if (drawKnob) {
                if (shouldExpand) {
                    // -[NSScroller drawKnob] is not useful here because any scaling applied
                    // will only be used to draw the hi-DPI artwork. And even if did scale,
                    // the stretched knob would look wrong, actually. So we need to draw the
                    // scroller manually when it's being hovered.
                    const CGFloat scrollerWidth = [NSScroller scrollerWidthForControlSize:scroller.controlSize scrollerStyle:scroller.scrollerStyle];
                    const CGFloat knobWidth = knobWidths[cocoaSize] * expandScale;
                    // Cocoa can help get the exact knob length in the current orientation
                    const CGRect scrollerKnobRect = CGRectInset([scroller rectForPart:NSScrollerKnob], 1, 1);
                    const CGFloat knobLength = isHorizontal ? scrollerKnobRect.size.width : scrollerKnobRect.size.height;
                    const CGFloat knobPos = isHorizontal ? scrollerKnobRect.origin.x : scrollerKnobRect.origin.y;
                    const CGFloat knobOffset = qRound((scrollerWidth + expandOffset - knobWidth) / 2.0);
                    const CGFloat knobRadius = knobWidth / 2.0;
                    CGRect knobRect;
                    if (isHorizontal)
                        knobRect = CGRectMake(knobPos, knobOffset, knobLength, knobWidth);
                    else
                        knobRect = CGRectMake(knobOffset, knobPos, knobWidth, knobLength);
                    QCFType<CGPathRef> knobPath = CGPathCreateWithRoundedRect(knobRect, knobRadius, knobRadius, nullptr);
                    CGContextAddPath(cg, knobPath);
                    CGContextSetAlpha(cg, 0.5);
                    CGColorRef knobColor = hasDarkBg ? NSColor.whiteColor.CGColor : NSColor.blackColor.CGColor;
                    CGContextSetFillColorWithColor(cg, knobColor);
                    CGContextFillPath(cg);
                } else {
                    [scroller drawKnob];

                    if (!isTransient && opt->activeSubControls) {
                        // The knob should appear darker (going from 0.76 down to 0.49).
                        // But no blending mode can help darken enough in a single pass,
                        // so we resort to drawing the knob twice with a small help from
                        // blending. This brings the gray level to a close enough 0.53.
                        CGContextSetBlendMode(cg, kCGBlendModePlusDarker);
                        [scroller drawKnob];
                    }
                }
            }

            if (isTransient)
                CGContextEndTransparencyLayer(cg);

            d->restoreNSGraphicsContext(cg);
        }
        break;
    case CC_Slider:
        if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
            const bool isHorizontal = sl->orientation == Qt::Horizontal;
            const auto ct = isHorizontal ? QMacStylePrivate::Slider_Horizontal : QMacStylePrivate::Slider_Vertical;
            const auto cs = d->effectiveAquaSizeConstrain(opt, widget);
            const auto cw = QMacStylePrivate::CocoaControl(ct, cs);
            auto *slider = static_cast<NSSlider *>(d->cocoaControl(cw));
            if (!setupSlider(slider, sl))
                break;

            const bool hasTicks = sl->tickPosition != QSlider::NoTicks;
            const bool hasDoubleTicks = sl->tickPosition == QSlider::TicksBothSides;
            const bool drawKnob = sl->subControls & SC_SliderHandle;
            const bool drawBar = sl->subControls & SC_SliderGroove;
            const bool drawTicks = sl->subControls & SC_SliderTickmarks;
            const bool isPressed = sl->state & State_Sunken;

            CGPoint pressPoint;
            if (isPressed) {
                const CGRect knobRect = [slider.cell knobRectFlipped:NO];
                pressPoint.x = CGRectGetMidX(knobRect);
                pressPoint.y = CGRectGetMidY(knobRect);
                [slider.cell startTrackingAt:pressPoint inView:slider];
            }

            d->drawNSViewInRect(slider, opt->rect, p, ^(CGContextRef ctx, const CGRect &rect) {

                // Since the GC is flipped, upsideDown means *not* inverted when vertical.
                const bool verticalFlip = !isHorizontal && !sl->upsideDown; // FIXME: && !isSierraOrLater

                if (isHorizontal) {
                    if (sl->upsideDown) {
                        CGContextTranslateCTM(ctx, rect.size.width, rect.origin.y);
                        CGContextScaleCTM(ctx, -1, 1);
                    } else {
                        CGContextTranslateCTM(ctx, 0, rect.origin.y);
                    }
                } else if (verticalFlip) {
                    CGContextTranslateCTM(ctx, rect.origin.x, rect.size.height);
                    CGContextScaleCTM(ctx, 1, -1);
                }

                if (hasDoubleTicks) {
                    // This ain't HIG kosher: eye-proved constants
                    if (isHorizontal)
                        CGContextTranslateCTM(ctx, 0, 4);
                    else
                        CGContextTranslateCTM(ctx, 1, 0);
                }

#if 0
                // FIXME: Sadly, this part doesn't work. It seems to somehow polute the
                // NSSlider's internal state and, when we need to use the "else" part,
                // the slider's frame is not in sync with its cell dimensions.
                const bool drawAllParts = drawKnob && drawBar && (!hasTicks || drawTicks);
                if (drawAllParts && !hasDoubleTicks && (!verticalFlip || drawTicks)) {
                    // Draw eveything at once if we're going to, except for inverted vertical
                    // sliders which need to be drawn part by part because of the shadow below
                    // the knob. Same for two-sided tickmarks.
                    if (verticalFlip && drawTicks) {
                        // Since tickmarks are always rendered symmetrically, a vertically
                        // flipped slider with tickmarks only needs to get its value flipped.
                        slider.intValue = slider.maxValue - slider.intValue + slider.minValue;
                    }
                    [slider drawRect:CGRectZero];
                } else
#endif
                {
                    [slider calcSize];
                    if (!hasDoubleTicks)
                        fixStaleGeometry(slider);
                    NSSliderCell *cell = slider.cell;

                    const int numberOfTickMarks = slider.numberOfTickMarks;
                    // This ain't HIG kosher: force tick-less bar position.
                    if (hasDoubleTicks)
                        slider.numberOfTickMarks = 0;

                    const CGRect barRect = [cell barRectFlipped:hasTicks];
                    if (drawBar) {
                        [cell drawBarInside:barRect flipped:!verticalFlip];
                        // This ain't HIG kosher: force unfilled bar look.
                        if (hasDoubleTicks)
                            slider.numberOfTickMarks = numberOfTickMarks;
                    }

                    if (hasTicks && drawTicks) {
                        if (!drawBar && hasDoubleTicks)
                            slider.numberOfTickMarks = numberOfTickMarks;

                        [cell drawTickMarks];

                        if (hasDoubleTicks) {
                            // This ain't HIG kosher: just slap a set of tickmarks on each side, like we used to.
                            CGAffineTransform tickMarksFlip;
                            const CGRect tickMarkRect = [cell rectOfTickMarkAtIndex:0];
                            if (isHorizontal) {
                                tickMarksFlip = CGAffineTransformMakeTranslation(0, rect.size.height - tickMarkRect.size.height - 3);
                                tickMarksFlip = CGAffineTransformScale(tickMarksFlip, 1, -1);
                            } else {
                                tickMarksFlip = CGAffineTransformMakeTranslation(rect.size.width - tickMarkRect.size.width / 2, 0);
                                tickMarksFlip = CGAffineTransformScale(tickMarksFlip, -1, 1);
                            }
                            CGContextConcatCTM(ctx, tickMarksFlip);
                            [cell drawTickMarks];
                            CGContextConcatCTM(ctx, CGAffineTransformInvert(tickMarksFlip));
                        }
                    }

                    if (drawKnob) {
                        // This ain't HIG kosher: force round knob look.
                        if (hasDoubleTicks)
                            slider.numberOfTickMarks = 0;
                        [cell drawKnob];
                    }
                }
            });

            if (isPressed)
                [slider.cell stopTracking:pressPoint at:pressPoint inView:slider mouseIsUp:NO];
        }
        break;
#if QT_CONFIG(spinbox)
    case CC_SpinBox:
        if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
            if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
                const auto lineEditRect = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxEditField, widget);
                QStyleOptionFrame frame;
                static_cast<QStyleOption &>(frame) = *opt;
                frame.rect = lineEditRect;
                frame.state |= State_Sunken;
                frame.lineWidth = 1;
                frame.midLineWidth = 0;
                frame.features = QStyleOptionFrame::None;
                frame.frameShape = QFrame::Box;
                drawPrimitive(PE_FrameLineEdit, &frame, p, widget);
            }
            if (sb->subControls & (SC_SpinBoxUp | SC_SpinBoxDown)) {
                const QRect updown = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget)
                                   | proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget);

                d->setupNSGraphicsContext(cg, NO);

                const auto aquaSize = d->effectiveAquaSizeConstrain(opt, widget);
                const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Stepper, aquaSize);
                NSStepperCell *cell = static_cast<NSStepperCell *>(d->cocoaCell(cw));
                cell.enabled = (sb->state & State_Enabled);

                const CGRect newRect = [cell drawingRectForBounds:updown.toCGRect()];

                const bool upPressed = sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken);
                const bool downPressed = sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken);
                const CGFloat x = CGRectGetMidX(newRect);
                const CGFloat y = upPressed ? -3 : 3; // Weird coordinate shift going on. Verified with Hopper
                const CGPoint pressPoint = CGPointMake(x, y);
                // Pretend we're pressing the mouse on the right button. Unfortunately, NSStepperCell has no
                // API to highlight a specific button. The highlighted property works only on the down button.
                if (upPressed || downPressed)
                    [cell startTrackingAt:pressPoint inView:d->backingStoreNSView];

                [cell drawWithFrame:newRect inView:d->backingStoreNSView];

                if (upPressed || downPressed)
                    [cell stopTracking:pressPoint at:pressPoint inView:d->backingStoreNSView mouseIsUp:NO];

                d->restoreNSGraphicsContext(cg);
            }
        }
        break;
#endif
#if QT_CONFIG(combobox)
    case CC_ComboBox:
        if (const auto *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
            const bool isEnabled = combo->state & State_Enabled;
            const bool isPressed = combo->state & State_Sunken;

            const auto ct = cocoaControlType(combo, widget);
            const auto cs = d->effectiveAquaSizeConstrain(combo, widget);
            const auto cw = QMacStylePrivate::CocoaControl(ct, cs);
            auto *cc = static_cast<NSControl *>(d->cocoaControl(cw));
            cc.enabled = isEnabled;
            QRectF frameRect = cw.adjustedControlFrame(combo->rect);;
            if (cw.type == QMacStylePrivate::Button_PopupButton) {
                // Non-editable QComboBox
                auto *pb = static_cast<NSPopUpButton *>(cc);
                // FIXME Old offsets. Try to move to adjustedControlFrame()
                if (cw.size == QStyleHelper::SizeSmall) {
                    frameRect = frameRect.translated(0, 1);
                } else if (cw.size == QStyleHelper::SizeMini) {
                    // Same 0.5 pt misalignment as AppKit and fit the focus ring
                    frameRect = frameRect.translated(2, -0.5);
                }
                pb.frame = frameRect.toCGRect();
                [pb highlight:isPressed];
                d->drawNSViewInRect(pb, frameRect, p, ^(CGContextRef, const CGRect &r) {
                    [pb.cell drawBezelWithFrame:r inView:pb.superview];
                });
            } else if (cw.type == QMacStylePrivate::ComboBox) {
                // Editable QComboBox
                auto *cb = static_cast<NSComboBox *>(cc);
                const auto frameRect = cw.adjustedControlFrame(combo->rect);
                cb.frame = frameRect.toCGRect();

                // This API was requested to Apple in rdar #36197888. We know it's safe to use up to macOS 10.13.3
                if (NSButtonCell *cell = static_cast<NSButtonCell *>([cc.cell qt_valueForPrivateKey:@"_buttonCell"])) {
                    cell.highlighted = isPressed;
                } else {
                    // TODO Render to pixmap and darken the button manually
                }

                d->drawNSViewInRect(cb, frameRect, p, ^(CGContextRef, const CGRect &r) {
                    // FIXME This is usually drawn in the control's superview, but we wouldn't get inactive look in this case
                    [cb.cell drawWithFrame:r inView:cb];
                });
            }

            if (combo->state & State_HasFocus) {
                // TODO Remove and use QFocusFrame instead.
                const int hMargin = proxy()->pixelMetric(QStyle::PM_FocusFrameHMargin, combo, widget);
                const int vMargin = proxy()->pixelMetric(QStyle::PM_FocusFrameVMargin, combo, widget);
                QRectF focusRect;
                if (cw.type == QMacStylePrivate::Button_PopupButton) {
                    focusRect = QRectF::fromCGRect([cc alignmentRectForFrame:cc.frame]);
                    focusRect -= pullDownButtonShadowMargins[cw.size];
                    if (cw.size == QStyleHelper::SizeSmall)
                        focusRect = focusRect.translated(0, 1);
                    else if (cw.size == QStyleHelper::SizeMini)
                        focusRect = focusRect.translated(2, -1);
                } else if (cw.type == QMacStylePrivate::ComboBox) {
                    focusRect = frameRect - comboBoxFocusRingMargins[cw.size];
                }
                d->drawFocusRing(p, focusRect, hMargin, vMargin, cw);
            }
        }
        break;
#endif // QT_CONFIG(combobox)
    case CC_TitleBar:
        if (const auto *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
            const bool isActive = (titlebar->state & State_Active)
                               && (titlebar->titleBarState & State_Active);

            p->fillRect(opt->rect, Qt::transparent);
            p->setRenderHint(QPainter::Antialiasing);
            p->setClipRect(opt->rect, Qt::IntersectClip);

            // FIXME A single drawPath() with 0-sized pen
            // doesn't look as good as this double fillPath().
            const auto outerFrameRect = QRectF(opt->rect.adjusted(0, 0, 0, opt->rect.height()));
            QPainterPath outerFramePath = d->windowPanelPath(outerFrameRect);
            p->fillPath(outerFramePath, opt->palette.dark());

            const auto frameAdjust = 1.0 / p->device()->devicePixelRatioF();
            const auto innerFrameRect = outerFrameRect.adjusted(frameAdjust, frameAdjust, -frameAdjust, 0);
            QPainterPath innerFramePath = d->windowPanelPath(innerFrameRect);
            if (isActive) {
                QLinearGradient g;
                g.setStart(QPointF(0, 0));
                g.setFinalStop(QPointF(0, 2 * opt->rect.height()));
                g.setColorAt(0, opt->palette.button().color());
                g.setColorAt(1, opt->palette.dark().color());
                p->fillPath(innerFramePath, g);
            } else {
                p->fillPath(innerFramePath, opt->palette.button());
            }

            if (titlebar->subControls & (SC_TitleBarCloseButton
                                         | SC_TitleBarMaxButton
                                         | SC_TitleBarMinButton
                                         | SC_TitleBarNormalButton)) {
                const bool isHovered = (titlebar->state & State_MouseOver);
                static const SubControl buttons[] = {
                    SC_TitleBarCloseButton, SC_TitleBarMinButton, SC_TitleBarMaxButton
                };
                for (const auto sc : buttons) {
                    const auto ct = d->windowButtonCocoaControl(sc);
                    const auto cw = QMacStylePrivate::CocoaControl(ct, QStyleHelper::SizeLarge);
                    auto *wb = static_cast<NSButton *>(d->cocoaControl(cw));
                    wb.enabled = (sc & titlebar->subControls) && isActive;
                    [wb highlight:(titlebar->state & State_Sunken) && (sc & titlebar->activeSubControls)];
                    Q_UNUSED(isHovered); // FIXME No public API for this

                    const auto buttonRect = proxy()->subControlRect(CC_TitleBar, titlebar, sc, widget);
                    d->drawNSViewInRect(wb, buttonRect, p, ^(CGContextRef, const CGRect &rect) {
                        auto *wbCell = static_cast<NSButtonCell *>(wb.cell);
                        [wbCell drawWithFrame:rect inView:wb];
                    });
                }
            }

            if (titlebar->subControls & SC_TitleBarLabel) {
                const auto tr = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarLabel, widget);
                if (!titlebar->icon.isNull()) {
                    const auto iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
                    const auto iconSize = QSize(iconExtent, iconExtent);
                    const auto iconPos = tr.x() - titlebar->icon.actualSize(iconSize).width() - qRound(titleBarIconTitleSpacing);
                    // Only render the icon if it'll be fully visible
                    if (iconPos < tr.right() - titleBarIconTitleSpacing)
                        p->drawPixmap(iconPos, tr.y(), titlebar->icon.pixmap(window, iconSize, QIcon::Normal));
                }

                if (!titlebar->text.isEmpty())
                    drawItemText(p, tr, Qt::AlignCenter, opt->palette, isActive, titlebar->text, QPalette::Text);
            }
        }
        break;
    case CC_GroupBox:
        if (const QStyleOptionGroupBox *gb
                = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {

            QStyleOptionGroupBox groupBox(*gb);
            const bool flat = groupBox.features & QStyleOptionFrame::Flat;
            if (!flat)
                groupBox.state |= QStyle::State_Mini; // Force mini-sized checkbox to go with small-sized label
            else
                groupBox.subControls = groupBox.subControls & ~SC_GroupBoxFrame; // We don't like frames and ugly lines

            const bool didSetFont = widget && widget->testAttribute(Qt::WA_SetFont);
            const bool didModifySubControls = !didSetFont && QApplication::desktopSettingsAware();
            if (didModifySubControls)
                groupBox.subControls = groupBox.subControls & ~SC_GroupBoxLabel;
            QCommonStyle::drawComplexControl(cc, &groupBox, p, widget);
            if (didModifySubControls) {
                const QRect rect = proxy()->subControlRect(CC_GroupBox, &groupBox, SC_GroupBoxLabel, widget);
                const bool rtl = groupBox.direction == Qt::RightToLeft;
                const int alignment = Qt::TextHideMnemonic | (rtl ? Qt::AlignRight : Qt::AlignLeft);
                const QFont savedFont = p->font();
                if (!flat)
                    p->setFont(d->smallSystemFont);
                proxy()->drawItemText(p, rect, alignment, groupBox.palette, groupBox.state & State_Enabled, groupBox.text, QPalette::WindowText);
                if (!flat)
                    p->setFont(savedFont);
            }
        }
        break;
    case CC_ToolButton:
        if (const QStyleOptionToolButton *tb
                = qstyleoption_cast<const QStyleOptionToolButton *>(opt)) {
#ifndef QT_NO_ACCESSIBILITY
            if (QStyleHelper::hasAncestor(opt->styleObject, QAccessible::ToolBar)) {
                if (tb->subControls & SC_ToolButtonMenu) {
                    QStyleOption arrowOpt = *tb;
                    arrowOpt.rect = proxy()->subControlRect(cc, tb, SC_ToolButtonMenu, widget);
                    arrowOpt.rect.setY(arrowOpt.rect.y() + arrowOpt.rect.height() / 2);
                    arrowOpt.rect.setHeight(arrowOpt.rect.height() / 2);
                    proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, widget);
                } else if ((tb->features & QStyleOptionToolButton::HasMenu)
                            && (tb->toolButtonStyle != Qt::ToolButtonTextOnly && !tb->icon.isNull())) {
                    d->drawToolbarButtonArrow(tb, p);
                }
                if (tb->state & State_On) {
                    NSView *view = window ? (NSView *)window->winId() : nil;
                    bool isKey = false;
                    if (view)
                        isKey = [view.window isKeyWindow];

                    QBrush brush(brushForToolButton(isKey));
                    QPainterPath path;
                    path.addRoundedRect(QRectF(tb->rect.x(), tb->rect.y(), tb->rect.width(), tb->rect.height() + 4), 4, 4);
                    p->setRenderHint(QPainter::Antialiasing);
                    p->fillPath(path, brush);
                }
                proxy()->drawControl(CE_ToolButtonLabel, opt, p, widget);
            } else
#endif // QT_NO_ACCESSIBILITY
            {
                auto bflags = tb->state;
                if (tb->subControls & SC_ToolButton)
                    bflags |= State_Sunken;
                auto mflags = tb->state;
                if (tb->subControls & SC_ToolButtonMenu)
                    mflags |= State_Sunken;

                if (tb->subControls & SC_ToolButton) {
                    if (bflags & (State_Sunken | State_On | State_Raised)) {
                        const bool isEnabled = tb->state & State_Enabled;
                        const bool isPressed = tb->state & State_Sunken;
                        const bool isHighlighted = (tb->state & State_Active) && (tb->state & State_On);
                        const auto ct = QMacStylePrivate::Button_PushButton;
                        const auto cs = d->effectiveAquaSizeConstrain(opt, widget);
                        const auto cw = QMacStylePrivate::CocoaControl(ct, cs);
                        auto *pb = static_cast<NSButton *>(d->cocoaControl(cw));
                        pb.bezelStyle = NSShadowlessSquareBezelStyle; // TODO Use NSTexturedRoundedBezelStyle in the future.
                        pb.frame = opt->rect.toCGRect();
                        pb.buttonType = NSPushOnPushOffButton;
                        pb.enabled = isEnabled;
                        [pb highlight:isPressed];
                        pb.state = isHighlighted && !isPressed ? NSOnState : NSOffState;
                        const auto buttonRect = proxy()->subControlRect(cc, tb, SC_ToolButton, widget);
                        d->drawNSViewInRect(pb, buttonRect, p, ^(CGContextRef, const CGRect &rect) {
                            [pb.cell drawBezelWithFrame:rect inView:pb];
                        });
                    }
                }

                if (tb->subControls & SC_ToolButtonMenu) {
                    const auto menuRect = proxy()->subControlRect(cc, tb, SC_ToolButtonMenu, widget);
                    QStyleOption arrowOpt = *tb;
                    arrowOpt.rect = QRect(menuRect.x() + ((menuRect.width() - toolButtonArrowSize) / 2),
                                          menuRect.height() - (toolButtonArrowSize + toolButtonArrowMargin),
                                          toolButtonArrowSize,
                                          toolButtonArrowSize);
                    proxy()->drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, p, widget);
                } else if (tb->features & QStyleOptionToolButton::HasMenu) {
                    d->drawToolbarButtonArrow(tb, p);
                }
                QRect buttonRect = proxy()->subControlRect(CC_ToolButton, tb, SC_ToolButton, widget);
                int fw = proxy()->pixelMetric(PM_DefaultFrameWidth, opt, widget);
                QStyleOptionToolButton label = *tb;
                label.rect = buttonRect.adjusted(fw, fw, -fw, -fw);
                proxy()->drawControl(CE_ToolButtonLabel, &label, p, widget);
            }
        }
        break;
#if QT_CONFIG(dial)
    case CC_Dial:
        if (const QStyleOptionSlider *dial = qstyleoption_cast<const QStyleOptionSlider *>(opt))
            QStyleHelper::drawDial(dial, p);
        break;
#endif
    default:
        QCommonStyle::drawComplexControl(cc, opt, p, widget);
        break;
    }
}

QStyle::SubControl QMacStyle::hitTestComplexControl(ComplexControl cc,
                                                    const QStyleOptionComplex *opt,
                                                    const QPoint &pt, const QWidget *widget) const
{
    Q_D(const QMacStyle);
    SubControl sc = QStyle::SC_None;
    switch (cc) {
    case CC_ComboBox:
        if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
            sc = QCommonStyle::hitTestComplexControl(cc, cmb, pt, widget);
            if (!cmb->editable && sc != QStyle::SC_None)
                sc = SC_ComboBoxArrow;  // A bit of a lie, but what we want
        }
        break;
    case CC_Slider:
        if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
            if (!sl->rect.contains(pt))
                break;

            const bool hasTicks = sl->tickPosition != QSlider::NoTicks;
            const bool isHorizontal = sl->orientation == Qt::Horizontal;
            const auto ct = isHorizontal ? QMacStylePrivate::Slider_Horizontal : QMacStylePrivate::Slider_Vertical;
            const auto cs = d->effectiveAquaSizeConstrain(opt, widget);
            const auto cw = QMacStylePrivate::CocoaControl(ct, cs);
            auto *slider = static_cast<NSSlider *>(d->cocoaControl(cw));
            if (!setupSlider(slider, sl))
                break;

            [slider calcSize];
            NSSliderCell *cell = slider.cell;
            const auto barRect = QRectF::fromCGRect([cell barRectFlipped:hasTicks]);
            const auto knobRect = QRectF::fromCGRect([cell knobRectFlipped:NO]);
            if (knobRect.contains(pt)) {
                sc = SC_SliderHandle;
            } else if (barRect.contains(pt)) {
                sc = SC_SliderGroove;
            } else if (hasTicks) {
                sc = SC_SliderTickmarks;
            }
        }
        break;
    case CC_ScrollBar:
        if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
            if (!sb->rect.contains(pt)) {
                sc = SC_None;
                break;
            }

            const bool isHorizontal = sb->orientation == Qt::Horizontal;
            const auto ct = isHorizontal ? QMacStylePrivate::Scroller_Horizontal : QMacStylePrivate::Scroller_Vertical;
            const auto cs = d->effectiveAquaSizeConstrain(opt, widget);
            const auto cw = QMacStylePrivate::CocoaControl(ct, cs);
            auto *scroller = static_cast<NSScroller *>(d->cocoaControl(cw));
            if (!setupScroller(scroller, sb)) {
                sc = SC_None;
                break;
            }

            // Since -[NSScroller testPart:] doesn't want to cooperate, we do it the
            // straightforward way. In any case, macOS doesn't return line-sized changes
            // with NSScroller since 10.7, according to the aforementioned method's doc.
            const auto knobRect = QRectF::fromCGRect([scroller rectForPart:NSScrollerKnob]);
            if (isHorizontal) {
                const bool isReverse = sb->direction == Qt::RightToLeft;
                if (pt.x() < knobRect.left())
                    sc = isReverse ? SC_ScrollBarAddPage : SC_ScrollBarSubPage;
                else if (pt.x() > knobRect.right())
                    sc = isReverse ? SC_ScrollBarSubPage : SC_ScrollBarAddPage;
                else
                    sc = SC_ScrollBarSlider;
            } else {
                if (pt.y() < knobRect.top())
                    sc = SC_ScrollBarSubPage;
                else if (pt.y() > knobRect.bottom())
                    sc = SC_ScrollBarAddPage;
                else
                    sc = SC_ScrollBarSlider;
            }
        }
        break;
    default:
        sc = QCommonStyle::hitTestComplexControl(cc, opt, pt, widget);
        break;
    }
    return sc;
}

QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, SubControl sc,
                                const QWidget *widget) const
{
    Q_D(const QMacStyle);
    QRect ret;
    switch (cc) {
    case CC_ScrollBar:
        if (const QStyleOptionSlider *sb = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
            const bool isHorizontal = sb->orientation == Qt::Horizontal;
            const bool isReverseHorizontal = isHorizontal && (sb->direction == Qt::RightToLeft);

            NSScrollerPart part = NSScrollerNoPart;
            if (sc == SC_ScrollBarSlider) {
                part = NSScrollerKnob;
            } else if (sc == SC_ScrollBarGroove) {
                part = NSScrollerKnobSlot;
            } else if (sc == SC_ScrollBarSubPage || sc == SC_ScrollBarAddPage) {
                if ((!isReverseHorizontal && sc == SC_ScrollBarSubPage)
                        || (isReverseHorizontal && sc == SC_ScrollBarAddPage))
                    part = NSScrollerDecrementPage;
                else
                    part = NSScrollerIncrementPage;
            }
            // And nothing else since 10.7

            if (part != NSScrollerNoPart) {
                const auto ct = isHorizontal ? QMacStylePrivate::Scroller_Horizontal : QMacStylePrivate::Scroller_Vertical;
                const auto cs = d->effectiveAquaSizeConstrain(opt, widget);
                const auto cw = QMacStylePrivate::CocoaControl(ct, cs);
                auto *scroller = static_cast<NSScroller *>(d->cocoaControl(cw));
                if (setupScroller(scroller, sb))
                    ret = QRectF::fromCGRect([scroller rectForPart:part]).toRect();
            }
        }
        break;
    case CC_Slider:
        if (const QStyleOptionSlider *sl = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
            const bool hasTicks = sl->tickPosition != QSlider::NoTicks;
            const bool isHorizontal = sl->orientation == Qt::Horizontal;
            const auto ct = isHorizontal ? QMacStylePrivate::Slider_Horizontal : QMacStylePrivate::Slider_Vertical;
            const auto cs = d->effectiveAquaSizeConstrain(opt, widget);
            const auto cw = QMacStylePrivate::CocoaControl(ct, cs);
            auto *slider = static_cast<NSSlider *>(d->cocoaControl(cw));
            if (!setupSlider(slider, sl))
                break;

            [slider calcSize];
            NSSliderCell *cell = slider.cell;
            if (sc == SC_SliderHandle) {
                ret = QRectF::fromCGRect([cell knobRectFlipped:NO]).toRect();
                if (isHorizontal) {
                    ret.setTop(sl->rect.top());
                    ret.setBottom(sl->rect.bottom());
                } else {
                    ret.setLeft(sl->rect.left());
                    ret.setRight(sl->rect.right());
                }
            } else if (sc == SC_SliderGroove) {
                ret = QRectF::fromCGRect([cell barRectFlipped:hasTicks]).toRect();
            } else if (hasTicks && sc == SC_SliderTickmarks) {
                const auto tickMarkRect = QRectF::fromCGRect([cell rectOfTickMarkAtIndex:0]);
                if (isHorizontal)
                    ret = QRect(sl->rect.left(), tickMarkRect.top(), sl->rect.width(), tickMarkRect.height());
                else
                    ret = QRect(tickMarkRect.left(), sl->rect.top(), tickMarkRect.width(), sl->rect.height());
            }

            // Invert if needed and extend to the actual bounds of the slider
            if (isHorizontal) {
                if (sl->upsideDown) {
                    ret = QRect(sl->rect.right() - ret.right(), sl->rect.top(), ret.width(), sl->rect.height());
                } else {
                    ret.setTop(sl->rect.top());
                    ret.setBottom(sl->rect.bottom());
                }
            } else {
                if (!sl->upsideDown) {
                    ret = QRect(sl->rect.left(), sl->rect.bottom() - ret.bottom(), sl->rect.width(), ret.height());
                } else {
                    ret.setLeft(sl->rect.left());
                    ret.setRight(sl->rect.right());
                }
            }
        }
        break;
    case CC_TitleBar:
        if (const auto *titlebar = qstyleoption_cast<const QStyleOptionTitleBar *>(opt)) {
            // The title bar layout is as follows: close, min, zoom, icon, title
            //              [ x _ +    @ Window Title    ]
            // Center the icon and title until it starts to overlap with the buttons.
            // The icon doesn't count towards SC_TitleBarLabel, but it's still rendered
            // next to the title text. See drawComplexControl().
            if (sc == SC_TitleBarLabel) {
                qreal labelWidth = titlebar->fontMetrics.horizontalAdvance(titlebar->text) + 1; // FIXME Rounding error?
                qreal labelHeight = titlebar->fontMetrics.height();

                const auto lastButtonRect = proxy()->subControlRect(CC_TitleBar, titlebar, SC_TitleBarMaxButton, widget);
                qreal controlsSpacing = lastButtonRect.right() + titleBarButtonSpacing;
                if (!titlebar->icon.isNull()) {
                    const auto iconSize = proxy()->pixelMetric(PM_SmallIconSize);
                    const auto actualIconSize = titlebar->icon.actualSize(QSize(iconSize, iconSize)).width();;
                    controlsSpacing += actualIconSize + titleBarIconTitleSpacing;
                }

                const qreal labelPos = qMax(controlsSpacing, (opt->rect.width() - labelWidth) / 2.0);
                labelWidth = qMin(labelWidth, opt->rect.width() - (labelPos + titleBarTitleRightMargin));
                ret = QRect(labelPos, (opt->rect.height() - labelHeight) / 2,
                            labelWidth, labelHeight);
            } else {
                const auto currentButton = d->windowButtonCocoaControl(sc);
                if (currentButton == QMacStylePrivate::NoControl)
                    break;

                QPointF buttonPos = titlebar->rect.topLeft() + QPointF(titleBarButtonSpacing, 0);
                QSizeF buttonSize;
                for (int ct = QMacStylePrivate::Button_WindowClose; ct <= currentButton; ct++) {
                    const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::CocoaControlType(ct),
                                                                   QStyleHelper::SizeLarge);
                    auto *wb = static_cast<NSButton *>(d->cocoaControl(cw));
                    if (ct == currentButton)
                        buttonSize = QSizeF::fromCGSize(wb.frame.size);
                    else
                        buttonPos.rx() += wb.frame.size.width + titleBarButtonSpacing;
                }

                const auto vOffset = (opt->rect.height() - buttonSize.height()) / 2.0;
                ret = QRectF(buttonPos, buttonSize).translated(0, vOffset).toRect();
            }
        }
        break;
    case CC_ComboBox:
        if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
            const auto ct = cocoaControlType(combo, widget);
            const auto cs = d->effectiveAquaSizeConstrain(combo, widget);
            const auto cw = QMacStylePrivate::CocoaControl(ct, cs);
            const auto editRect = QMacStylePrivate::comboboxEditBounds(cw.adjustedControlFrame(combo->rect), cw);

            switch (sc) {
            case SC_ComboBoxEditField:{
                ret = editRect.toAlignedRect();
                break; }
            case SC_ComboBoxArrow:{
                ret = editRect.toAlignedRect();
                ret.setX(ret.x() + ret.width());
                ret.setWidth(combo->rect.right() - ret.right());
                break; }
            case SC_ComboBoxListBoxPopup:{
                if (combo->editable) {
                    const CGRect inner = QMacStylePrivate::comboboxInnerBounds(combo->rect.toCGRect(), cw);
                    const int comboTop = combo->rect.top();
                    ret = QRect(qRound(inner.origin.x),
                                comboTop,
                                qRound(inner.origin.x - combo->rect.left() + inner.size.width),
                                editRect.bottom() - comboTop + 2);
                } else {
                    ret = QRect(combo->rect.x() + 4 - 11,
                                combo->rect.y() + 1,
                                editRect.width() + 10 + 11,
                                1);
                 }
                break; }
            default:
                break;
            }
        }
        break;
    case CC_GroupBox:
        if (const QStyleOptionGroupBox *groupBox = qstyleoption_cast<const QStyleOptionGroupBox *>(opt)) {
            bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
            const bool flat = groupBox->features & QStyleOptionFrame::Flat;
            bool hasNoText = !checkable && groupBox->text.isEmpty();
            switch (sc) {
            case SC_GroupBoxLabel:
            case SC_GroupBoxCheckBox: {
                // Cheat and use the smaller font if we need to
                const bool checkable = groupBox->subControls & SC_GroupBoxCheckBox;
                const bool fontIsSet = (widget && widget->testAttribute(Qt::WA_SetFont))
                                       || !QApplication::desktopSettingsAware();
                const int margin =  flat || hasNoText ? 0 : 9;
                ret = groupBox->rect.adjusted(margin, 0, -margin, 0);

                const QFontMetricsF fm = flat || fontIsSet ? QFontMetricsF(groupBox->fontMetrics) : QFontMetricsF(d->smallSystemFont);
                const QSizeF s = fm.size(Qt::AlignHCenter | Qt::AlignVCenter, qt_mac_removeMnemonics(groupBox->text), 0, nullptr);
                const int tw = qCeil(s.width());
                const int h = qCeil(fm.height());
                ret.setHeight(h);

                QRect labelRect = alignedRect(groupBox->direction, groupBox->textAlignment,
                                              QSize(tw, h), ret);
                if (flat && checkable)
                    labelRect.moveLeft(labelRect.left() + 4);
                int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, opt, widget);
                bool rtl = groupBox->direction == Qt::RightToLeft;
                if (sc == SC_GroupBoxLabel) {
                    if (checkable) {
                        int newSum = indicatorWidth + 1;
                        int newLeft = labelRect.left() + (rtl ? -newSum : newSum);
                        labelRect.moveLeft(newLeft);
                        if (flat)
                            labelRect.moveTop(labelRect.top() + 3);
                        else
                            labelRect.moveTop(labelRect.top() + 4);
                    } else if (flat) {
                        int newLeft = labelRect.left() - (rtl ? 3 : -3);
                        labelRect.moveLeft(newLeft);
                        labelRect.moveTop(labelRect.top() + 3);
                    } else {
                        int newLeft = labelRect.left() - (rtl ? 3 : 2);
                        labelRect.moveLeft(newLeft);
                        labelRect.moveTop(labelRect.top() + 4);
                    }
                    ret = labelRect;
                }

                if (sc == SC_GroupBoxCheckBox) {
                    int left = rtl ? labelRect.right() - indicatorWidth : labelRect.left() - 1;
                    int top = flat ? ret.top() + 1 : ret.top() + 5;
                    ret.setRect(left, top,
                                indicatorWidth, proxy()->pixelMetric(PM_IndicatorHeight, opt, widget));
                }
                break;
            }
            case SC_GroupBoxContents:
            case SC_GroupBoxFrame: {
                QFontMetrics fm = groupBox->fontMetrics;
                int yOffset = 3;
                if (!flat) {
                    if (widget && !widget->testAttribute(Qt::WA_SetFont)
                            && QApplication::desktopSettingsAware())
                        fm = QFontMetrics(qt_app_fonts_hash()->value("QSmallFont", QFont()));
                    yOffset = 5;
                }

                if (hasNoText)
                    yOffset = -qCeil(QFontMetricsF(fm).height());
                ret = opt->rect.adjusted(0, qCeil(QFontMetricsF(fm).height()) + yOffset, 0, 0);
                if (sc == SC_GroupBoxContents) {
                    if (flat)
                        ret.adjust(3, -5, -3, -4);   // guess too
                    else
                        ret.adjust(3, 3, -3, -4);    // guess
                }
            }
                break;
            default:
                ret = QCommonStyle::subControlRect(cc, groupBox, sc, widget);
                break;
            }
        }
        break;
#if QT_CONFIG(spinbox)
    case CC_SpinBox:
        if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
            QStyleHelper::WidgetSizePolicy aquaSize = d->effectiveAquaSizeConstrain(spin, widget);
            const auto fw = proxy()->pixelMetric(PM_SpinBoxFrameWidth, spin, widget);
            int spinner_w;
            int spinBoxSep;
            switch (aquaSize) {
            case QStyleHelper::SizeLarge:
                spinner_w = 14;
                spinBoxSep = 2;
                break;
            case QStyleHelper::SizeSmall:
                spinner_w = 12;
                spinBoxSep = 2;
                break;
            case QStyleHelper::SizeMini:
                spinner_w = 10;
                spinBoxSep = 1;
                break;
            default:
                Q_UNREACHABLE();
            }

            switch (sc) {
            case SC_SpinBoxUp:
            case SC_SpinBoxDown: {
                if (spin->buttonSymbols == QAbstractSpinBox::NoButtons)
                    break;

                const int y = fw;
                const int x = spin->rect.width() - spinner_w;
                ret.setRect(x + spin->rect.x(), y + spin->rect.y(), spinner_w, spin->rect.height() - y * 2);
                int hackTranslateX;
                switch (aquaSize) {
                case QStyleHelper::SizeLarge:
                    hackTranslateX = 0;
                    break;
                case QStyleHelper::SizeSmall:
                    hackTranslateX = -2;
                    break;
                case QStyleHelper::SizeMini:
                    hackTranslateX = -1;
                    break;
                default:
                    Q_UNREACHABLE();
                }

                const auto cw = QMacStylePrivate::CocoaControl(QMacStylePrivate::Stepper, aquaSize);
                NSStepperCell *cell = static_cast<NSStepperCell *>(d->cocoaCell(cw));
                const CGRect outRect = [cell drawingRectForBounds:ret.toCGRect()];
                ret = QRectF::fromCGRect(outRect).toRect();

                switch (sc) {
                case SC_SpinBoxUp:
                    ret.setHeight(ret.height() / 2);
                    break;
                case SC_SpinBoxDown:
                    ret.setY(ret.y() + ret.height() / 2);
                    break;
                default:
                    Q_ASSERT(0);
                    break;
                }
                ret.translate(hackTranslateX, 0); // hack: position the buttons correctly (weird that we need this)
                ret = visualRect(spin->direction, spin->rect, ret);
                break;
            }
            case SC_SpinBoxEditField:
                ret = spin->rect.adjusted(fw, fw, -fw, -fw);
                if (spin->buttonSymbols != QAbstractSpinBox::NoButtons) {
                    ret.setWidth(spin->rect.width() - spinBoxSep - spinner_w);
                    ret = visualRect(spin->direction, spin->rect, ret);
                }
                break;
            default:
                ret = QCommonStyle::subControlRect(cc, spin, sc, widget);
                break;
            }
        }
        break;
#endif
    case CC_ToolButton:
        ret = QCommonStyle::subControlRect(cc, opt, sc, widget);
        if (sc == SC_ToolButtonMenu) {
#ifndef QT_NO_ACCESSIBILITY
            if (QStyleHelper::hasAncestor(opt->styleObject, QAccessible::ToolBar))
                ret.adjust(-toolButtonArrowMargin, 0, 0, 0);
#endif
            ret.adjust(-1, 0, 0, 0);
        }
        break;
    default:
        ret = QCommonStyle::subControlRect(cc, opt, sc, widget);
        break;
    }
    return ret;
}

QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt,
                                  const QSize &csz, const QWidget *widget) const
{
    Q_D(const QMacStyle);
    QSize sz(csz);
    bool useAquaGuideline = true;

    switch (ct) {
#if QT_CONFIG(spinbox)
    case CT_SpinBox:
        if (const QStyleOptionSpinBox *vopt = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
            const bool hasButtons = (vopt->buttonSymbols != QAbstractSpinBox::NoButtons);
            const int buttonWidth = hasButtons ? proxy()->subControlRect(CC_SpinBox, vopt, SC_SpinBoxUp, widget).width() : 0;
            sz += QSize(buttonWidth, 0);
        }
        break;
#endif
    case QStyle::CT_TabWidget:
        // the size between the pane and the "contentsRect" (+4,+4)
        // (the "contentsRect" is on the inside of the pane)
        sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
        /**
            This is supposed to show the relationship between the tabBar and
            the stack widget of a QTabWidget.
            Unfortunately ascii is not a good way of representing graphics.....
            PS: The '=' line is the painted frame.

               top    ---+
                         |
                         |
                         |
                         |                vvv just outside the painted frame is the "pane"
                      - -|- - - - - - - - - - <-+
            TAB BAR      +=====^============    | +2 pixels
                    - - -|- - -|- - - - - - - <-+
                         |     |      ^   ^^^ just inside the painted frame is the "contentsRect"
                         |     |      |
                         |   overlap  |
                         |     |      |
            bottom ------+   <-+     +14 pixels
                                      |
                                      v
                ------------------------------  <- top of stack widget


        To summarize:
             * 2 is the distance between the pane and the contentsRect
             * The 14 and the 1's are the distance from the contentsRect to the stack widget.
               (same value as used in SE_TabWidgetTabContents)
             * overlap is how much the pane should overlap the tab bar
        */
        // then add the size between the stackwidget and the "contentsRect"
#if QT_CONFIG(tabwidget)
        if (const QStyleOptionTabWidgetFrame *twf
                = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(opt)) {
            QSize extra(0,0);
            const int overlap = pixelMetric(PM_TabBarBaseOverlap, opt, widget);
            const int gapBetweenTabbarAndStackWidget = 2 + 14 - overlap;

            const auto tabDirection = QMacStylePrivate::tabDirection(twf->shape);
            if (tabDirection == QMacStylePrivate::North
                    || tabDirection == QMacStylePrivate::South) {
                extra = QSize(2, gapBetweenTabbarAndStackWidget + 1);
            } else {
                extra = QSize(gapBetweenTabbarAndStackWidget + 1, 2);
            }
            sz+= extra;
        }
#endif
        break;
#if QT_CONFIG(tabbar)
    case QStyle::CT_TabBarTab:
        if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
            const bool differentFont = (widget && widget->testAttribute(Qt::WA_SetFont))
                                       || !QApplication::desktopSettingsAware();
            const auto tabDirection = QMacStylePrivate::tabDirection(tab->shape);
            const bool verticalTabs = tabDirection == QMacStylePrivate::East
                                   || tabDirection == QMacStylePrivate::West;
            if (verticalTabs)
                sz = sz.transposed();

            int defaultTabHeight;
            const auto cs = d->effectiveAquaSizeConstrain(opt, widget);
            switch (cs) {
            case QStyleHelper::SizeLarge:
                if (tab->documentMode)
                    defaultTabHeight = 24;
                else
                    defaultTabHeight = 21;
                break;
            case QStyleHelper::SizeSmall:
                defaultTabHeight = 18;
                break;
            case QStyleHelper::SizeMini:
                defaultTabHeight = 16;
                break;
            default:
                break;
            }

            const bool widthSet = !differentFont && tab->icon.isNull();
            if (widthSet) {
                const auto textSize = opt->fontMetrics.size(Qt::TextShowMnemonic, tab->text);
                sz.rwidth() = textSize.width();
                sz.rheight() = qMax(defaultTabHeight, textSize.height());
            } else {
                sz.rheight() = qMax(defaultTabHeight, sz.height());
            }
            sz.rwidth() += proxy()->pixelMetric(PM_TabBarTabHSpace, tab, widget);

            if (verticalTabs)
                sz = sz.transposed();

            int maxWidgetHeight = qMax(tab->leftButtonSize.height(), tab->rightButtonSize.height());
            int maxWidgetWidth = qMax(tab->leftButtonSize.width(), tab->rightButtonSize.width());

            int widgetWidth = 0;
            int widgetHeight = 0;
            int padding = 0;
            if (tab->leftButtonSize.isValid()) {
                padding += 8;
                widgetWidth += tab->leftButtonSize.width();
                widgetHeight += tab->leftButtonSize.height();
            }
            if (tab->rightButtonSize.isValid()) {
                padding += 8;
                widgetWidth += tab->rightButtonSize.width();
                widgetHeight += tab->rightButtonSize.height();
            }

            if (verticalTabs) {
                sz.setWidth(qMax(sz.width(), maxWidgetWidth));
                sz.setHeight(sz.height() + widgetHeight + padding);
            } else {
                if (widthSet)
                    sz.setWidth(sz.width() + widgetWidth + padding);
                sz.setHeight(qMax(sz.height(), maxWidgetHeight));
            }
        }
        break;
#endif
    case QStyle::CT_PushButton: {
        if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt))
            if (btn->features & QStyleOptionButton::CommandLinkButton)
                return QCommonStyle::sizeFromContents(ct, opt, sz, widget);

        // By default, we fit the contents inside a normal rounded push button.
        // Do this by add enough space around the contents so that rounded
        // borders (including highlighting when active) will show.
        // TODO Use QFocusFrame and get rid of these horrors.
        QSize macsz;
        const auto controlSize = d->effectiveAquaSizeConstrain(opt, widget, CT_PushButton, sz, &macsz);
        // FIXME See comment in CT_PushButton case in qt_aqua_get_known_size().
        if (macsz.width() != -1)
            sz.setWidth(macsz.width());
        else
            sz.rwidth() += QMacStylePrivate::PushButtonLeftOffset + QMacStylePrivate::PushButtonRightOffset + 12;
        // All values as measured from HIThemeGetButtonBackgroundBounds()
        if (controlSize != QStyleHelper::SizeMini)
            sz.rwidth() += 12; // We like 12 over here.
        if (controlSize == QStyleHelper::SizeLarge && sz.height() > 16)
            sz.rheight() += pushButtonDefaultHeight[QStyleHelper::SizeLarge] - 16;
        else if (controlSize == QStyleHelper::SizeMini)
            sz.setHeight(24); // FIXME Our previous HITheme-based logic returned this.
        else
            sz.setHeight(pushButtonDefaultHeight[controlSize]);
        break;
    }
    case QStyle::CT_MenuItem:
        if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
            int maxpmw = mi->maxIconWidth;
#if QT_CONFIG(combobox)
            const QComboBox *comboBox = qobject_cast<const QComboBox *>(widget);
#endif
            int w = sz.width(),
                h = sz.height();
            if (mi->menuItemType == QStyleOptionMenuItem::Separator) {
                w = 10;
                h = qt_mac_aqua_get_metric(MenuSeparatorHeight);
            } else {
                h = mi->fontMetrics.height() + 2;
                if (!mi->icon.isNull()) {
#if QT_CONFIG(combobox)
                    if (comboBox) {
                        const QSize &iconSize = comboBox->iconSize();
                        h = qMax(h, iconSize.height() + 4);
                        maxpmw = qMax(maxpmw, iconSize.width());
                    } else
#endif
                    {
                        int iconExtent = proxy()->pixelMetric(PM_SmallIconSize);
                        h = qMax(h, mi->icon.actualSize(QSize(iconExtent, iconExtent)).height() + 4);
                    }
                }
            }
            if (mi->text.contains(QLatin1Char('\t')))
                w += 12;
            else if (mi->menuItemType == QStyleOptionMenuItem::SubMenu)
                w += 35; // Not quite exactly as it seems to depend on other factors
            if (maxpmw)
                w += maxpmw + 6;
            // add space for a check. All items have place for a check too.
            w += 20;
#if QT_CONFIG(combobox)
            if (comboBox && comboBox->isVisible()) {
                QStyleOptionComboBox cmb;
                cmb.initFrom(comboBox);
                cmb.editable = false;
                cmb.subControls = QStyle::SC_ComboBoxEditField;
                cmb.activeSubControls = QStyle::SC_None;
                w = qMax(w, subControlRect(QStyle::CC_ComboBox, &cmb,
                                                   QStyle::SC_ComboBoxEditField,
                                                   comboBox).width());
            } else
#endif
            {
                w += 12;
            }
            sz = QSize(w, h);
        }
        break;
    case CT_MenuBarItem:
        if (!sz.isEmpty())
            sz += QSize(12, 4); // Constants from QWindowsStyle
        break;
    case CT_ToolButton:
        sz.rwidth() += 10;
        sz.rheight() += 10;
        if (const auto *tb = qstyleoption_cast<const QStyleOptionToolButton *>(opt))
            if (tb->features & QStyleOptionToolButton::Menu)
                sz.rwidth() += toolButtonArrowMargin;
        return sz;
    case CT_ComboBox:
        if (const auto *cb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) {
            const auto controlSize = d->effectiveAquaSizeConstrain(opt, widget);
            if (!cb->editable) {
                // Same as CT_PushButton, because we have to fit the focus
                // ring and a non-editable combo box is a NSPopUpButton.
                sz.rwidth() += QMacStylePrivate::PushButtonLeftOffset + QMacStylePrivate::PushButtonRightOffset + 12;
                // All values as measured from HIThemeGetButtonBackgroundBounds()
                if (controlSize != QStyleHelper::SizeMini)
                    sz.rwidth() += 12; // We like 12 over here.
#if 0
                // TODO Maybe support square combo boxes
                if (controlSize == QStyleHelper::SizeLarge && sz.height() > 16)
                    sz.rheight() += popupButtonDefaultHeight[QStyleHelper::SizeLarge] - 16;
                else
#endif
            } else {
                sz.rwidth() += 50; // FIXME Double check this
            }

            // This should be enough to fit the focus ring
            if (controlSize == QStyleHelper::SizeMini)
                sz.setHeight(24); // FIXME Our previous HITheme-based logic returned this for CT_PushButton.
            else
                sz.setHeight(pushButtonDefaultHeight[controlSize]);

            return sz;
        }
        break;
    case CT_Menu: {
        if (proxy() == this) {
            sz = csz;
        } else {
            QStyleHintReturnMask menuMask;
            QStyleOption myOption = *opt;
            myOption.rect.setSize(sz);
            if (proxy()->styleHint(SH_Menu_Mask, &myOption, widget, &menuMask))
                sz = menuMask.region.boundingRect().size();
        }
        break; }
    case CT_HeaderSection:{
        const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt);
        sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
        if (header->text.contains(QLatin1Char('\n')))
            useAquaGuideline = false;
        break; }
    case CT_ScrollBar :
        // Make sure that the scroll bar is large enough to display the thumb indicator.
        if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
            const int minimumSize = 24; // Smallest knob size, but Cocoa doesn't seem to care
            if (slider->orientation == Qt::Horizontal)
                sz = sz.expandedTo(QSize(minimumSize, sz.height()));
            else
                sz = sz.expandedTo(QSize(sz.width(), minimumSize));
        }
        break;
#if QT_CONFIG(itemviews)
    case CT_ItemViewItem:
        if (const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)) {
            sz = QCommonStyle::sizeFromContents(ct, vopt, csz, widget);
            sz.setHeight(sz.height() + 2);
        }
        break;
#endif

    default:
        sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
    }

    if (useAquaGuideline && ct != CT_PushButton) {
        // TODO Probably going away at some point
        QSize macsz;
        if (d->aquaSizeConstrain(opt, widget, ct, sz, &macsz) != QStyleHelper::SizeDefault) {
            if (macsz.width() != -1)
                sz.setWidth(macsz.width());
            if (macsz.height() != -1)
                sz.setHeight(macsz.height());
        }
    }

    // The sizes that Carbon and the guidelines gives us excludes the focus frame.
    // We compensate for this by adding some extra space here to make room for the frame when drawing:
    if (const QStyleOptionComboBox *combo = qstyleoption_cast<const QStyleOptionComboBox *>(opt)){
        if (combo->editable) {
            const auto widgetSize = d->aquaSizeConstrain(opt, widget);
            QMacStylePrivate::CocoaControl cw;
            cw.type = combo->editable ? QMacStylePrivate::ComboBox : QMacStylePrivate::Button_PopupButton;
            cw.size = widgetSize;
            const CGRect diffRect = QMacStylePrivate::comboboxInnerBounds(CGRectZero, cw);
            sz.rwidth() -= qRound(diffRect.size.width);
            sz.rheight() -= qRound(diffRect.size.height);
        }
    }
    return sz;
}

void QMacStyle::drawItemText(QPainter *p, const QRect &r, int flags, const QPalette &pal,
                             bool enabled, const QString &text, QPalette::ColorRole textRole) const
{
    if(flags & Qt::TextShowMnemonic)
        flags |= Qt::TextHideMnemonic;
    QCommonStyle::drawItemText(p, r, flags, pal, enabled, text, textRole);
}

bool QMacStyle::event(QEvent *e)
{
    Q_D(QMacStyle);
    if(e->type() == QEvent::FocusIn) {
        QWidget *f = 0;
        QWidget *focusWidget = QApplication::focusWidget();
#if QT_CONFIG(graphicsview)
        if (QGraphicsView *graphicsView = qobject_cast<QGraphicsView *>(focusWidget)) {
            QGraphicsItem *focusItem = graphicsView->scene() ? graphicsView->scene()->focusItem() : 0;
            if (focusItem && focusItem->type() == QGraphicsProxyWidget::Type) {
                QGraphicsProxyWidget *proxy = static_cast<QGraphicsProxyWidget *>(focusItem);
                if (proxy->widget())
                    focusWidget = proxy->widget()->focusWidget();
            }
        }
#endif

        if (focusWidget && focusWidget->testAttribute(Qt::WA_MacShowFocusRect)) {
#if QT_CONFIG(spinbox)
            if (const auto sb = qobject_cast<QAbstractSpinBox *>(focusWidget))
                f = sb->property("_q_spinbox_lineedit").value<QWidget *>();
            else
#endif
                f = focusWidget;
        }
        if (f) {
            if(!d->focusWidget)
                d->focusWidget = new QFocusFrame(f);
            d->focusWidget->setWidget(f);
        } else if(d->focusWidget) {
            d->focusWidget->setWidget(0);
        }
    } else if(e->type() == QEvent::FocusOut) {
        if(d->focusWidget)
            d->focusWidget->setWidget(0);
    }
    return false;
}

QIcon QMacStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *opt,
                              const QWidget *widget) const
{
    switch (standardIcon) {
    default:
        return QCommonStyle::standardIcon(standardIcon, opt, widget);
    case SP_ToolBarHorizontalExtensionButton:
    case SP_ToolBarVerticalExtensionButton: {
        QPixmap pixmap(QLatin1String(":/qt-project.org/styles/macstyle/images/toolbar-ext.png"));
        if (standardIcon == SP_ToolBarVerticalExtensionButton) {
            QPixmap pix2(pixmap.height(), pixmap.width());
            pix2.setDevicePixelRatio(pixmap.devicePixelRatio());
            pix2.fill(Qt::transparent);
            QPainter p(&pix2);
            p.translate(pix2.width(), 0);
            p.rotate(90);
            p.drawPixmap(0, 0, pixmap);
            return pix2;
        }
        return pixmap;
    }
    }
}

int QMacStyle::layoutSpacing(QSizePolicy::ControlType control1,
                             QSizePolicy::ControlType control2,
                             Qt::Orientation orientation,
                             const QStyleOption *option,
                             const QWidget *widget) const
{
    const int ButtonMask = QSizePolicy::ButtonBox | QSizePolicy::PushButton;
    const int controlSize = getControlSize(option, widget);

    if (control2 == QSizePolicy::ButtonBox) {
        /*
            AHIG seems to prefer a 12-pixel margin between group
            boxes and the row of buttons. The 20 pixel comes from
            Builder.
        */
        if (control1 & (QSizePolicy::Frame         // guess
                        | QSizePolicy::GroupBox    // (AHIG, guess, guess)
                        | QSizePolicy::TabWidget   // guess
                        | ButtonMask))    {        // AHIG
            return_SIZE(14, 8, 8);
        } else if (control1 == QSizePolicy::LineEdit) {
            return_SIZE(8, 8, 8); // Interface Builder
        } else {
            return_SIZE(20, 7, 7); // Interface Builder
        }
    }

    if ((control1 | control2) & ButtonMask) {
        if (control1 == QSizePolicy::LineEdit)
            return_SIZE(8, 8, 8); // Interface Builder
        else if (control2 == QSizePolicy::LineEdit) {
            if (orientation == Qt::Vertical)
                return_SIZE(20, 7, 7); // Interface Builder
            else
                return_SIZE(20, 8, 8);
        }
        return_SIZE(14, 8, 8);     // Interface Builder
    }

    switch (CT2(control1, control2)) {
    case CT1(QSizePolicy::Label):                             // guess
    case CT2(QSizePolicy::Label, QSizePolicy::DefaultType):   // guess
    case CT2(QSizePolicy::Label, QSizePolicy::CheckBox):      // AHIG
    case CT2(QSizePolicy::Label, QSizePolicy::ComboBox):      // AHIG
    case CT2(QSizePolicy::Label, QSizePolicy::LineEdit):      // guess
    case CT2(QSizePolicy::Label, QSizePolicy::RadioButton):   // AHIG
    case CT2(QSizePolicy::Label, QSizePolicy::Slider):        // guess
    case CT2(QSizePolicy::Label, QSizePolicy::SpinBox):       // guess
    case CT2(QSizePolicy::Label, QSizePolicy::ToolButton):    // guess
        return_SIZE(8, 6, 5);
    case CT1(QSizePolicy::ToolButton):
        return 8;   // AHIG
    case CT1(QSizePolicy::CheckBox):
    case CT2(QSizePolicy::CheckBox, QSizePolicy::RadioButton):
    case CT2(QSizePolicy::RadioButton, QSizePolicy::CheckBox):
        if (orientation == Qt::Vertical)
            return_SIZE(8, 8, 7);        // AHIG and Builder
        break;
    case CT1(QSizePolicy::RadioButton):
        if (orientation == Qt::Vertical)
            return 5;                   // (Builder, guess, AHIG)
    }

    if (orientation == Qt::Horizontal
            && (control2 & (QSizePolicy::CheckBox | QSizePolicy::RadioButton)))
        return_SIZE(12, 10, 8);        // guess

    if ((control1 | control2) & (QSizePolicy::Frame
                                 | QSizePolicy::GroupBox
                                 | QSizePolicy::TabWidget)) {
        /*
            These values were chosen so that nested container widgets
            look good side by side. Builder uses 8, which looks way
            too small, and AHIG doesn't say anything.
        */
        return_SIZE(16, 10, 10);    // guess
    }

    if ((control1 | control2) & (QSizePolicy::Line | QSizePolicy::Slider))
        return_SIZE(12, 10, 8);     // AHIG

    if ((control1 | control2) & QSizePolicy::LineEdit)
        return_SIZE(10, 8, 8);      // AHIG

    /*
        AHIG and Builder differ by up to 4 pixels for stacked editable
        comboboxes. We use some values that work fairly well in all
        cases.
    */
    if ((control1 | control2) & QSizePolicy::ComboBox)
        return_SIZE(10, 8, 7);      // guess

    /*
        Builder defaults to 8, 6, 5 in lots of cases, but most of the time the
        result looks too cramped.
    */
    return_SIZE(10, 8, 6);  // guess
}

QT_END_NAMESPACE
