summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Yadrov <oleg.yadrov@qt.io>2017-10-02 10:27:10 -0400
committerGabriel de Dietrich <gabriel.dedietrich@qt.io>2017-10-05 17:04:07 +0000
commit5ff9d6a470dbcf424f2f43206ab6ab6eb91edcc1 (patch)
treeeb2424ff6dfb579aaa962f218e094b932fe41cec
parent08e083e682d92290e36e4fb09abaf0318575dd41 (diff)
QMacStyle: smooth QMenu corners for real
It's been for years that QMenu's rounded corners in qmacstyle_mac were done via QWidget::setMask(QRegion). Unfortunately, QRegion mask does not work well with retina displays and also does not support translucency. That's why in this change we explicitly make QMenu's background transparent and then draw a rectangle with rounded corners in QMacStyle::drawPrimitive(PE_PanelMenu). This not only gives much better result than the mask-based approach, but also de-HIThemes QMenu. As a consequence, QComboBoxPrivateContainer doesn't get any mask from QMacStyle anymore. Therefore, when the mask is empty, we need to paint PE_PanelMenu before invoking QFrame's paint event handler. Made-with: Gabriel de Dietrich <gabriel.dedietrich@qt.io> Change-Id: Ia9236176113f23b86e45507fa6ddf77236084ce3 Reviewed-by: Oleg Yadrov <oleg.yadrov@qt.io> Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@qt.io>
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemsettings.mm1
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm92
-rw-r--r--src/widgets/widgets/qcombobox.cpp14
-rw-r--r--src/widgets/widgets/qcombobox_p.h1
4 files changed, 56 insertions, 52 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
index 91fb6e973d..7c6f879b18 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
@@ -144,7 +144,6 @@ QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes()
}
if (mac_widget_colors[i].paletteRole == QPlatformTheme::MenuPalette
|| mac_widget_colors[i].paletteRole == QPlatformTheme::MenuBarPalette) {
- pal.setBrush(QPalette::Background, qt_mac_toQColor([NSColor windowBackgroundColor]));
pal.setBrush(QPalette::Highlight, qt_mac_toQColor([NSColor selectedMenuItemColor]));
qc = qt_mac_toQColor([NSColor labelColor]);
pal.setBrush(QPalette::ButtonText, qc);
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index d9e622c28a..b24ecee102 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -663,14 +663,6 @@ HIMutableShapeRef qt_mac_toHIMutableShape(const QRegion &region)
return shape;
}
-QRegion qt_mac_fromHIShapeRef(HIShapeRef shape)
-{
- QRegion returnRegion;
- //returnRegion.detach();
- HIShapeEnumerate(shape, kHIShapeParseFromTopLeft, qt_mac_shape2QRegionHelper, &returnRegion);
- return returnRegion;
-}
-
bool qt_macWindowIsTextured(const QWidget *window)
{
if (QWindow *w = window->windowHandle())
@@ -2291,24 +2283,7 @@ void QMacStyle::polish(QWidget* w)
|| qobject_cast<QComboBoxPrivateContainer *>(w)
#endif
) {
- w->setWindowOpacity(0.985);
- if (!w->testAttribute(Qt::WA_SetPalette)) {
- QPixmap px(64, 64);
- px.fill(Qt::white);
- HIThemeMenuDrawInfo mtinfo;
- mtinfo.version = qt_mac_hitheme_version;
- mtinfo.menuType = kThemeMenuTypePopUp;
- // HIRect rect = CGRectMake(0, 0, px.width(), px.height());
- // ###
- //HIThemeDrawMenuBackground(&rect, &mtinfo, QMacCGContext(&px)),
- // kHIThemeOrientationNormal);
- QPalette pal = w->palette();
- QBrush background(px);
- pal.setBrush(QPalette::All, QPalette::Window, background);
- pal.setBrush(QPalette::All, QPalette::Button, background);
- w->setPalette(pal);
- w->setAttribute(Qt::WA_SetPalette, false);
- }
+ w->setAttribute(Qt::WA_TranslucentBackground, true);
}
#endif
@@ -3023,7 +2998,7 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w
ret = Qt::AlignRight;
break;
case SH_ComboBox_PopupFrameStyle:
- ret = QFrame::NoFrame | QFrame::Plain;
+ ret = QFrame::NoFrame;
break;
case SH_MessageBox_TextInteractionFlags:
ret = Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard;
@@ -3057,27 +3032,6 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w
case SH_Menu_FadeOutOnHide:
ret = true;
break;
- case SH_Menu_Mask:
- if (opt) {
- if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
- ret = true;
- CGRect menuRect = CGRectMake(opt->rect.x(), opt->rect.y() + 4,
- opt->rect.width(), opt->rect.height() - 8);
- HIThemeMenuDrawInfo mdi;
- mdi.version = 0;
-#if QT_CONFIG(menu)
- if (w && qobject_cast<QMenu *>(w->parentWidget()))
- mdi.menuType = kThemeMenuTypeHierarchical;
- else
-#endif
- mdi.menuType = kThemeMenuTypePopUp;
- QCFType<HIShapeRef> shape;
- HIThemeGetMenuBackgroundShape(&menuRect, &mdi, &shape);
-
- mask->region = qt_mac_fromHIShapeRef(shape);
- }
- }
- break;
case SH_ItemView_PaintAlternatingRowColorsForEmptyArea:
ret = true;
break;
@@ -3587,6 +3541,40 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
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);
+ QPainterPath path;
+ static const qreal CornerPointOffset = 5.5;
+ static const qreal CornerControlOffset = 2.1;
+ QRectF r = opt->rect;
+ // 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);
+ p->drawPath(path);
+ p->restore();
+ } break;
default:
QCommonStyle::drawPrimitive(pe, opt, p, w);
@@ -4269,16 +4257,18 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
const int vMargin = proxy()->pixelMetric(QStyle::PM_FocusFrameVMargin, opt, w);
d->drawFocusRing(p, opt->rect, hMargin, vMargin);
break; }
+ case CE_MenuEmptyArea:
+ // Skip: PE_PanelMenu fills in everything
+ break;
case CE_MenuItem:
case CE_MenuHMargin:
case CE_MenuVMargin:
- case CE_MenuEmptyArea:
case CE_MenuTearoff:
case CE_MenuScroller:
if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
const bool active = mi->state & State_Selected;
- const QBrush bg = active ? mi->palette.highlight() : mi->palette.background();
- p->fillRect(mi->rect, bg);
+ if (active)
+ p->fillRect(mi->rect, mi->palette.highlight());
const QStyleHelper::WidgetSizePolicy widgetSize = d->aquaSizeConstrain(opt, w);
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index 1338a496e6..9afb4b3ae6 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -428,6 +428,20 @@ void QComboBoxPrivateContainer::resizeEvent(QResizeEvent *e)
QFrame::resizeEvent(e);
}
+void QComboBoxPrivateContainer::paintEvent(QPaintEvent *e)
+{
+ QStyleOptionComboBox cbOpt = comboStyleOption();
+ if (combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &cbOpt, combo)
+ && mask().isEmpty()) {
+ QStyleOption opt;
+ opt.initFrom(this);
+ QPainter p(this);
+ style()->drawPrimitive(QStyle::PE_PanelMenu, &opt, &p, this);
+ }
+
+ QFrame::paintEvent(e);
+}
+
void QComboBoxPrivateContainer::leaveEvent(QEvent *)
{
// On Mac using the Mac style we want to clear the selection
diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h
index 835bbf866e..3f75a357e4 100644
--- a/src/widgets/widgets/qcombobox_p.h
+++ b/src/widgets/widgets/qcombobox_p.h
@@ -248,6 +248,7 @@ protected:
void timerEvent(QTimerEvent *timerEvent) override;
void leaveEvent(QEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
+ void paintEvent(QPaintEvent *e) override;
QStyleOptionComboBox comboStyleOption() const;
Q_SIGNALS: