Skip to content
This repository was archived by the owner on Apr 3, 2020. It is now read-only.

Commit 1f9f16b

Browse files
author
Andre Santoso
committed
Mac: Fix missing focus rings on toolbar, profile, and tab buttons
This is a reland of http://crrev.com/1160143010, with some additional tweaks. It was reverted because it tickled an AppKit crash (crbug.com/504808). The hope is that the crash won't reappear now that we link with 10.10 SDK. In 10.7, AppKit introduced new API for drawing focus rings. This automatic focus ring drawing is automatically enabled for applications linking with 10.8 sdk or later. After we link with 10.10 SDK the new style focus ring gets enabled but we get focus rings with double lines. This is because AppKit thinks the buttons are bordered (-isBordered is YES) and draws lines inside and outside the borders that are actually not there due to drawing overrides. 10.6 before: manually drawn, tab close and avatar buttons missing focus rings. 10.6 after: no change. 10.7 before: broken, no focus rings on toolbar, avatar, tab close, new tab buttons. 10.7 after: manually drawn, same as 10.6. 10.8+ before: broken, no focus rings on toolbar, avatar, tab close, new tab buttons. 10.8+ after: drawn by AppKit. Toolbar.xib changes: Change the toolbar buttons (back, forward, reload, home, wrench) Focus Ring from None to Default, to allow the new style focus ring to draw. BUG=459860, 520471 [email protected] Review URL: https://codereview.chromium.org/1310183005 Cr-Commit-Position: refs/heads/master@{#345989} (cherry picked from commit 9c75e37) Review URL: https://codereview.chromium.org/1327203003 . Cr-Commit-Position: refs/branch-heads/2490@{#218} Cr-Branched-From: 7790a35-refs/heads/master@{#344925}
1 parent 5659db2 commit 1f9f16b

File tree

9 files changed

+71
-33
lines changed

9 files changed

+71
-33
lines changed

chrome/app/nibs/Toolbar.xib

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,51 +24,51 @@
2424
<rect key="frame" x="0.0" y="0.0" width="604" height="35"/>
2525
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
2626
<subviews>
27-
<button toolTip="^IDS_APPMENU_TOOLTIP" focusRingType="none" id="38" customClass="MenuButton">
27+
<button toolTip="^IDS_APPMENU_TOOLTIP" id="38" customClass="MenuButton">
2828
<rect key="frame" x="572" y="4" width="29" height="29"/>
2929
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
30-
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" imagePosition="only" alignment="center" focusRingType="none" inset="2" id="39" customClass="WrenchToolbarButtonCell">
30+
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" imagePosition="only" alignment="center" inset="2" id="39" customClass="WrenchToolbarButtonCell">
3131
<behavior key="behavior" lightByContents="YES"/>
3232
<font key="font" metaFont="system"/>
3333
</buttonCell>
3434
</button>
35-
<button toolTip="^IDS_TOOLTIP_BACK" focusRingType="none" tag="33000" id="2" customClass="MenuButton">
35+
<button toolTip="^IDS_TOOLTIP_BACK" tag="33000" id="2" customClass="MenuButton">
3636
<rect key="frame" x="3" y="4" width="29" height="29"/>
3737
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
38-
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" imagePosition="only" alignment="center" state="on" focusRingType="none" inset="2" id="15" customClass="ClickHoldButtonCell">
38+
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" imagePosition="only" alignment="center" state="on" inset="2" id="15" customClass="ClickHoldButtonCell">
3939
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
4040
<font key="font" metaFont="system"/>
4141
</buttonCell>
4242
<connections>
4343
<action selector="commandDispatchUsingKeyModifiers:" target="-1" id="138"/>
4444
</connections>
4545
</button>
46-
<button toolTip="^IDS_TOOLTIP_FORWARD" focusRingType="none" tag="33001" id="7" customClass="MenuButton">
46+
<button toolTip="^IDS_TOOLTIP_FORWARD" tag="33001" id="7" customClass="MenuButton">
4747
<rect key="frame" x="31" y="4" width="29" height="29"/>
4848
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
49-
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" imagePosition="only" alignment="center" state="on" focusRingType="none" inset="2" id="10" customClass="ClickHoldButtonCell">
49+
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" imagePosition="only" alignment="center" state="on" inset="2" id="10" customClass="ClickHoldButtonCell">
5050
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
5151
<font key="font" metaFont="system"/>
5252
</buttonCell>
5353
<connections>
5454
<action selector="commandDispatchUsingKeyModifiers:" target="-1" id="139"/>
5555
</connections>
5656
</button>
57-
<button toolTip="^IDS_TOOLTIP_RELOAD" focusRingType="none" tag="33002" id="3" customClass="ReloadButton">
57+
<button toolTip="^IDS_TOOLTIP_RELOAD" tag="33002" id="3" customClass="ReloadButton">
5858
<rect key="frame" x="59" y="4" width="29" height="29"/>
5959
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
60-
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" imagePosition="only" alignment="center" focusRingType="none" inset="2" id="14" customClass="ClickHoldButtonCell">
60+
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" imagePosition="only" alignment="center" inset="2" id="14" customClass="ClickHoldButtonCell">
6161
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
6262
<font key="font" metaFont="system"/>
6363
</buttonCell>
6464
<connections>
6565
<action selector="commandDispatchUsingKeyModifiers:" target="-1" id="26"/>
6666
</connections>
6767
</button>
68-
<button toolTip="^IDS_TOOLTIP_HOME" focusRingType="none" tag="33003" id="8" customClass="ToolbarButton">
68+
<button toolTip="^IDS_TOOLTIP_HOME" tag="33003" id="8" customClass="ToolbarButton">
6969
<rect key="frame" x="87" y="4" width="29" height="29"/>
7070
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
71-
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" imagePosition="only" alignment="center" focusRingType="none" inset="2" id="9" customClass="ClickHoldButtonCell">
71+
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" imagePosition="only" alignment="center" inset="2" id="9" customClass="ClickHoldButtonCell">
7272
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
7373
<font key="font" metaFont="system"/>
7474
</buttonCell>

chrome/browser/ui/cocoa/autofill/down_arrow_popup_menu_cell.mm

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,7 @@ - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
4141
if ([title length])
4242
[self drawTitle:title withFrame:titleRect inView:controlView];
4343

44-
// Only draw custom focus ring if the 10.7 focus ring APIs are not available.
45-
// TODO(groby): Remove once we build against the 10.7 SDK.
46-
if (![self respondsToSelector:@selector(drawFocusRingMaskWithFrame:inView:)])
47-
[super drawFocusRingWithFrame:cellFrame inView:controlView];
44+
[self drawFocusRingWithFrame:cellFrame inView:controlView];
4845
}
4946

5047
@end

chrome/browser/ui/cocoa/extensions/browser_action_button.mm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,13 @@ - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
549549
hints:nil];
550550
}
551551

552+
- (void)drawFocusRingMaskWithFrame:(NSRect)cellFrame inView:(NSView*)view {
553+
// Match the hover image's bezel.
554+
[[NSBezierPath bezierPathWithRoundedRect:NSInsetRect(cellFrame, 2, 2)
555+
xRadius:2
556+
yRadius:2] fill];
557+
}
558+
552559
- (ui::ThemeProvider*)themeProviderForWindow:(NSWindow*)window {
553560
ui::ThemeProvider* themeProvider = [window themeProvider];
554561
if (!themeProvider)

chrome/browser/ui/cocoa/gradient_button_cell.mm

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <cmath>
88

99
#include "base/logging.h"
10+
#include "base/mac/mac_util.h"
1011
#import "base/mac/scoped_nsobject.h"
1112
#import "chrome/browser/themes/theme_properties.h"
1213
#import "chrome/browser/themes/theme_service.h"
@@ -528,14 +529,20 @@ - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
528529
ui::ThemeProvider* themeProvider = [window themeProvider];
529530
BOOL active = [window isKeyWindow] || [window isMainWindow];
530531

532+
// Draw custom focus ring only if AppKit won't draw one automatically.
533+
// The new focus ring APIs became available with 10.7, but did not get
534+
// applied to buttons (only editable text fields) until 10.8.
535+
BOOL shouldDrawFocusRing = base::mac::IsOSLionOrEarlier() &&
536+
[self showsFirstResponder];
537+
531538
// Stroke the borders and appropriate fill gradient. If we're borderless, the
532539
// only time we want to draw the inner gradient is if we're highlighted or if
533-
// we're the first responder (when "Full Keyboard Access" is turned on).
540+
// we're drawing the focus ring manually.
534541
if (([self isBordered] && ![self showsBorderOnlyWhileMouseInside]) ||
535542
pressed ||
536543
[self isMouseInside] ||
537544
[self isContinuousPulsing] ||
538-
[self showsFirstResponder]) {
545+
shouldDrawFocusRing) {
539546

540547
// When pulsing we want the bookmark to stand out a little more.
541548
BOOL showClickedGradient = pressed ||
@@ -569,8 +576,7 @@ - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
569576
}
570577
[self drawInteriorWithFrame:innerFrame inView:controlView];
571578

572-
// Draws the blue focus ring.
573-
if ([self showsFirstResponder]) {
579+
if (shouldDrawFocusRing) {
574580
gfx::ScopedNSGraphicsContextSaveGState scoped_state;
575581
const CGFloat lineWidth = [controlView cr_lineWidth];
576582
// insetX = 1.0 is used for the drawing of blue highlight so that this

chrome/browser/ui/cocoa/hover_close_button.mm

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,6 @@ - (void)drawRect:(NSRect)dirtyRect {
9696

9797
switch(self.hoverState) {
9898
case kHoverStateMouseOver:
99-
[image drawInRect:destRect
100-
fromRect:imageRect
101-
operation:NSCompositeSourceOver
102-
fraction:1.0
103-
respectFlipped:YES
104-
hints:nil];
105-
break;
106-
10799
case kHoverStateMouseDown:
108100
[image drawInRect:destRect
109101
fromRect:imageRect
@@ -140,6 +132,12 @@ - (void)drawRect:(NSRect)dirtyRect {
140132
}
141133
}
142134

135+
- (void)drawFocusRingMask {
136+
// Match the hover image's shape.
137+
NSRect circleRect = NSInsetRect([self bounds], 2, 2);
138+
[[NSBezierPath bezierPathWithOvalInRect:circleRect] fill];
139+
}
140+
143141
- (void)setFadeOutValue:(CGFloat)value {
144142
[self setNeedsDisplay];
145143
}

chrome/browser/ui/cocoa/image_button_cell.mm

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#import "chrome/browser/ui/cocoa/image_button_cell.h"
66

77
#include "base/logging.h"
8+
#include "base/mac/mac_util.h"
89
#import "chrome/browser/themes/theme_service.h"
910
#import "chrome/browser/ui/cocoa/rect_path_utils.h"
1011
#import "chrome/browser/ui/cocoa/themed_window.h"
@@ -100,10 +101,7 @@ - (void)drawImageWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
100101

101102
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
102103
[self drawImageWithFrame:cellFrame inView:controlView];
103-
// Only draw custom focus ring if the 10.7 focus ring APIs are not available.
104-
// TODO(groby): Remove once we build against the 10.7 SDK.
105-
if (![self respondsToSelector:@selector(drawFocusRingMaskWithFrame:inView:)])
106-
[self drawFocusRingWithFrame:cellFrame inView:controlView];
104+
[self drawFocusRingWithFrame:cellFrame inView:controlView];
107105
}
108106

109107
- (void)setImageID:(NSInteger)imageID
@@ -137,6 +135,12 @@ - (CGFloat)imageAlphaForWindowState:(NSWindow*)window {
137135
}
138136

139137
- (void)drawFocusRingWithFrame:(NSRect)cellFrame inView:(NSView*)controlView {
138+
// Draw custom focus ring only if AppKit won't draw one automatically.
139+
// The new focus ring APIs became available with 10.7, but did not get
140+
// applied to buttons (only editable text fields) until 10.8.
141+
if (base::mac::IsOSMountainLionOrLater())
142+
return;
143+
140144
if (![self showsFirstResponder])
141145
return;
142146
gfx::ScopedNSGraphicsContextSaveGState scoped_state;

chrome/browser/ui/cocoa/new_tab_button.mm

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@
88
#include "grit/theme_resources.h"
99
#include "ui/base/resource/resource_bundle.h"
1010

11+
namespace {
12+
13+
NSImage* GetMaskImage() {
14+
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
15+
return bundle.GetNativeImageNamed(IDR_NEWTAB_BUTTON_MASK).ToNSImage();
16+
}
17+
18+
}
19+
1120
// A simple override of the ImageButtonCell to disable handling of
1221
// -mouseEntered.
1322
@interface NewTabButtonCell : ImageButtonCell
@@ -22,6 +31,11 @@ - (void)mouseEntered:(NSEvent*)theEvent {
2231
// Ignore this since the NTB enter is handled by the TabStripController.
2332
}
2433

34+
- (void)drawFocusRingMaskWithFrame:(NSRect)cellFrame inView:(NSView*)view {
35+
// Match the button's shape.
36+
[self drawImage:GetMaskImage() withFrame:cellFrame inView:view];
37+
}
38+
2539
@end
2640

2741

@@ -34,9 +48,7 @@ + (Class)cellClass {
3448
- (BOOL)pointIsOverButton:(NSPoint)point {
3549
NSPoint localPoint = [self convertPoint:point fromView:[self superview]];
3650
NSRect pointRect = NSMakeRect(localPoint.x, localPoint.y, 1, 1);
37-
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
38-
NSImage* buttonMask =
39-
bundle.GetNativeImageNamed(IDR_NEWTAB_BUTTON_MASK).ToNSImage();
51+
NSImage* buttonMask = GetMaskImage();
4052
NSRect destinationRect = NSMakeRect(
4153
(NSWidth(self.bounds) - [buttonMask size].width) / 2,
4254
(NSHeight(self.bounds) - [buttonMask size].height) / 2,

chrome/browser/ui/cocoa/profiles/avatar_button_controller.mm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ - (void)drawBezelWithFrame:(NSRect)frame
114114
ui::DrawNinePartImage(frame, imageIds, NSCompositeSourceOver, 1.0, true);
115115
}
116116

117+
- (void)drawFocusRingMaskWithFrame:(NSRect)frame inView:(NSView*)view {
118+
// Match the bezel's shape.
119+
[[NSBezierPath bezierPathWithRoundedRect:NSInsetRect(frame, 2, 2)
120+
xRadius:2
121+
yRadius:2] fill];
122+
}
123+
117124
- (void)setIsThemedWindow:(BOOL)isThemedWindow {
118125
isThemedWindow_ = isThemedWindow;
119126
}

chrome/browser/ui/cocoa/toolbar/toolbar_button_cocoa.mm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,11 @@ - (BOOL)shouldHandleEvent:(NSEvent*)theEvent {
4848
return handleMiddleClick_ && [theEvent buttonNumber] == 2;
4949
}
5050

51+
- (void)drawFocusRingMask {
52+
// Match the hover image's bezel.
53+
[[NSBezierPath bezierPathWithRoundedRect:NSInsetRect([self bounds], 2, 2)
54+
xRadius:2
55+
yRadius:2] fill];
56+
}
57+
5158
@end

0 commit comments

Comments
 (0)