summaryrefslogtreecommitdiffstats
path: root/src/widgets/styles
diff options
context:
space:
mode:
authorGabriel de Dietrich <gabriel.dedietrich@digia.com>2014-08-25 19:07:11 +0200
committerGabriel de Dietrich <gabriel.dedietrich@digia.com>2014-08-27 12:13:01 +0200
commite94642a9b0806f2e5dfd9a2f8c76ce5b420c3424 (patch)
tree6e3ea47c1ceadb3f6b01d7a56848a2a6e008648f /src/widgets/styles
parent63f48d00aaa51bc892d6381b43d57a6bc55afced (diff)
QMacStyle: Fix push buttons focus ring on Yosemite
HITheme renders the focus ring in a way that diminishes contrast on the focused button edges. The same issue seems to affect combo boxes, check boxes, and radio buttons. We refactor the code that was used to draw CE_FocusFrame into qt_drawFocusRingOnPath(). We use it to render our own path for the push button contour. This should also allow us to implement the focus ring animation in the future. As a side note, notice how the square button part (kThemeBevelButton) is a complete joke. Not only we impose the wrong button kind and let HITheme do what it can with it, but we also prevent ourselves from using it by never adding padding for the focus ring. Hopefully, we can fix this whole button sizing and padding mess in 5.5 or 6.0, whatever breaks less apps around. Task-number: QTBUG-40833 Change-Id: Ib9e7829d99b38dc926c55b31c3d6d5d32b691867 Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
Diffstat (limited to 'src/widgets/styles')
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm58
1 files changed, 49 insertions, 9 deletions
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index 277ad47090..0845a5eb02 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -1098,6 +1098,19 @@ static QAquaWidgetSize qt_aqua_guess_size(const QWidget *widg, QSize large, QSiz
}
#endif
+static void qt_drawFocusRingOnPath(CGContextRef cg, NSBezierPath *focusRingPath)
+{
+ CGContextSaveGState(cg);
+ [NSGraphicsContext setCurrentContext:[NSGraphicsContext
+ graphicsContextWithGraphicsPort:(CGContextRef)cg flipped:NO]];
+ [NSGraphicsContext saveGraphicsState];
+ NSSetFocusRingStyle(NSFocusRingOnly);
+ [focusRingPath setClip]; // Clear clip path to avoid artifacts when rendering the cursor at zero pos
+ [focusRingPath fill];
+ [NSGraphicsContext restoreGraphicsState];
+ CGContextRestoreGState(cg);
+}
+
QAquaWidgetSize QMacStylePrivate::aquaSizeConstrain(const QStyleOption *option, const QWidget *widg,
QStyle::ContentsType ct, QSize szHint, QSize *insz) const
{
@@ -3573,6 +3586,10 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
d->initHIThemePushButton(btn, w, tds, &bdi);
if (yosemiteOrLater) {
+ // HITheme is not drawing a nice focus frame around buttons.
+ // We'll do it ourselves further down.
+ bdi.adornment &= ~kThemeAdornmentFocus;
+
// We can't rely on an animation existing to test for the default look. That means a bit
// more logic (notice that the logic is slightly different for the bevel and the label).
if (tds == kThemeStateActive
@@ -3625,6 +3642,37 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
else
HIThemeDrawButton(&newRect, &bdi, cg, kHIThemeOrientationNormal, 0);
+ if (yosemiteOrLater && btn->state & State_HasFocus) {
+ CGRect focusRect = newRect;
+ if (bdi.kind == kThemePushButton)
+ focusRect.size.height += 1; // Another thing HITheme and Cocoa seem to disagree about.
+ else if (bdi.kind == kThemePushButtonMini)
+ focusRect.size.height = 15; // Our QPushButton sizes are really weird
+
+ if (bdi.adornment & kThemeAdornmentDefault || bdi.state == kThemeStatePressed) {
+ if (bdi.kind == kThemePushButtonSmall) {
+ focusRect = CGRectInset(focusRect, -1, 0);
+ } else if (bdi.kind == kThemePushButtonMini) {
+ focusRect = CGRectInset(focusRect, 1, 0);
+ }
+ } else {
+ if (bdi.kind == kThemePushButton) {
+ focusRect = CGRectInset(focusRect, 1, 1);
+ } else if (bdi.kind == kThemePushButtonSmall) {
+ focusRect = CGRectInset(focusRect, 0, 2);
+ } else if (bdi.kind == kThemePushButtonMini) {
+ focusRect = CGRectInset(focusRect, 2, 1);
+ }
+ }
+
+ NSBezierPath *pushButtonFocusRingPath;
+ if (bdi.kind == kThemeBevelButton)
+ pushButtonFocusRingPath = [NSBezierPath bezierPathWithRect:focusRect];
+ else
+ pushButtonFocusRingPath = [NSBezierPath bezierPathWithRoundedRect:focusRect xRadius:4 yRadius:4];
+ qt_drawFocusRingOnPath(cg, pushButtonFocusRingPath);
+ }
+
if (hasMenu) {
int mbi = proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, btn, w);
QRect ir = btn->rect;
@@ -4089,16 +4137,8 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
int yOff = proxy()->pixelMetric(PM_FocusFrameVMargin, opt, w);
NSRect rect = NSMakeRect(xOff+opt->rect.x(), yOff+opt->rect.y(), opt->rect.width() - 2 * xOff,
opt->rect.height() - 2 * yOff);
- CGContextSaveGState(cg);
- [NSGraphicsContext setCurrentContext:[NSGraphicsContext
- graphicsContextWithGraphicsPort:(CGContextRef)cg flipped:NO]];
- [NSGraphicsContext saveGraphicsState];
- NSSetFocusRingStyle(NSFocusRingOnly);
NSBezierPath *focusFramePath = [NSBezierPath bezierPathWithRect:rect];
- [focusFramePath setClip]; // Clear clip path to avoid artifacts when rendering the cursor at zero pos
- [focusFramePath fill];
- [NSGraphicsContext restoreGraphicsState];
- CGContextRestoreGState(cg);
+ qt_drawFocusRingOnPath(cg, focusFramePath);
break; }
case CE_MenuItem:
case CE_MenuEmptyArea: