diff options
author | Gabriel de Dietrich <gabriel.dedietrich@qt.io> | 2017-01-05 16:42:10 -0800 |
---|---|---|
committer | Gabriel de Dietrich <gabriel.dedietrich@qt.io> | 2017-01-17 20:12:37 +0000 |
commit | 04a74c362f786e6300deb912c0ad40996f8b3bc3 (patch) | |
tree | 9c4fcd03962d7b71178796f7987a81e83f192962 /src | |
parent | 80fd1f81882024d13b6ce9688797239892092dfa (diff) |
QMacStyle: fix focus ring thickness on retina displays
NSSetFocusRingStyle() doesn't take the device pixel ratio
into account for offscreen graphics contexts. As a result,
the focus ring would appear too thin on retina displays.
Therefore, we need to render the focus ring in a more manual
way. The only added dependency is the focus ring's opacity
value and thickness.
This patch fixes CE_FocusFrame and the focus ring around
regular QPushButtons. More work needs to be done for other
widgets that currently rely on HITheme or NSControl–NSCell
to draw their focus ring.
Task-number: QTBUG-57843
Change-Id: I2c6f273698fdfd5ad7344a9688e96aef6da906f0
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/widgets/styles/qmacstyle_mac.mm | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index ee257c7310..cc895e2c33 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -1017,7 +1017,7 @@ static QAquaWidgetSize qt_aqua_guess_size(const QWidget *widg, QSize large, QSiz void QMacStylePrivate::drawFocusRing(QPainter *p, const QRect &targetRect, int hMargin, int vMargin, qreal radius) const { - qreal pixelRatio = p->device()->devicePixelRatioF(); + const qreal pixelRatio = p->device()->devicePixelRatioF(); static const QString keyFormat = QLatin1String("$qt_focusring%1-%2-%3-%4"); const QString &key = keyFormat.arg(hMargin).arg(vMargin).arg(radius).arg(pixelRatio); QPixmap focusRingPixmap; @@ -1028,20 +1028,38 @@ void QMacStylePrivate::drawFocusRing(QPainter *p, const QRect &targetRect, int h focusRingPixmap.fill(Qt::transparent); focusRingPixmap.setDevicePixelRatio(pixelRatio); { + const CGFloat focusRingWidth = radius > 0 ? 3.5 : 6; QMacAutoReleasePool pool; + QMacCGContext ctx(&focusRingPixmap); + CGContextBeginTransparencyLayer(ctx, NULL); + CGContextSetAlpha(ctx, 0.5); // As applied to the stroke color below + + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithCGContext:ctx + flipped:NO]]; + CGRect focusRingRect = CGRectMake(hMargin, vMargin, size, size); NSBezierPath *focusRingPath; - if (radius > 0) - focusRingPath = [NSBezierPath bezierPathWithRoundedRect:NSMakeRect(hMargin, vMargin, size, size) + if (radius > 0) { + const CGFloat roundedRectInset = -1.5; + focusRingPath = [NSBezierPath bezierPathWithRoundedRect:CGRectInset(focusRingRect, roundedRectInset, roundedRectInset) xRadius:radius yRadius:radius]; - else - focusRingPath = [NSBezierPath bezierPathWithRect:NSMakeRect(hMargin, vMargin, size, size)]; - [NSGraphicsContext saveGraphicsState]; - QMacCGContext gc(&focusRingPixmap); - [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:(CGContextRef)gc - flipped:NO]]; - NSSetFocusRingStyle(NSFocusRingOnly); - [focusRingPath fill]; + } else { + const CGFloat outerClipInset = -focusRingWidth / 2; + NSBezierPath *focusRingClipPath = [NSBezierPath bezierPathWithRect:CGRectInset(focusRingRect, outerClipInset, outerClipInset)]; + const CGFloat innerClipInset = 1; + NSBezierPath *focusRingInnerClipPath = [NSBezierPath bezierPathWithRect:CGRectInset(focusRingRect, innerClipInset, innerClipInset)]; + [focusRingClipPath appendBezierPath:focusRingInnerClipPath.bezierPathByReversingPath]; + [focusRingClipPath setClip]; + focusRingPath = [NSBezierPath bezierPathWithRect:focusRingRect]; + focusRingPath.lineJoinStyle = NSRoundLineJoinStyle; + } + + focusRingPath.lineWidth = focusRingWidth; + [[NSColor keyboardFocusIndicatorColor] setStroke]; + [focusRingPath stroke]; + + CGContextEndTransparencyLayer(ctx); [NSGraphicsContext restoreGraphicsState]; } QPixmapCache::insert(key, focusRingPixmap); |