diff options
author | toyoshim@chromium.org <toyoshim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-24 02:49:17 +0000 |
---|---|---|
committer | toyoshim@chromium.org <toyoshim@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-24 02:49:17 +0000 |
commit | 7f4c84ffe959733ebe3fe1e6c5ea2c65a2dc218f (patch) | |
tree | 1d273f5e372cad599d860b22be4ea3ec2bc7486e /chrome/browser/ui | |
parent | ee2408b9230399f65a42107f230dde7a70f934e4 (diff) | |
download | chromium_src-7f4c84ffe959733ebe3fe1e6c5ea2c65a2dc218f.zip chromium_src-7f4c84ffe959733ebe3fe1e6c5ea2c65a2dc218f.tar.gz chromium_src-7f4c84ffe959733ebe3fe1e6c5ea2c65a2dc218f.tar.bz2 |
[Mac] Middle clicking on home button does not work. It should open home in new
tab. backward button, forward button and reload button have the same problem.
XIB Changes:
* Add ToolbarButton for buttons which should handle middle clicking.
* Switch the home button to be ToolbarButton instead of NSButton.
* Back/forward and reload buttons inherit from ToolbarButton instead of
NSButton.
BUG=45795
TEST=Middle click on the home button create new tab with home page, or on the
reload button create new tab with current page. Middle click on the
back/forward buttons also work with new tab. unit_tests include
TestbarButtonTest.* suites for testint that.
R=pinkerton@chromium.org,avi@chromium.org,viettrungluu@chromium.org,mark@chromium.org,shess@chromium.org,rohitrao@chromium.org
Review URL: http://codereview.chromium.org/6703004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79245 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/ui')
-rw-r--r-- | chrome/browser/ui/cocoa/menu_button.h | 3 | ||||
-rw-r--r-- | chrome/browser/ui/cocoa/toolbar/reload_button.h | 7 | ||||
-rw-r--r-- | chrome/browser/ui/cocoa/toolbar/toolbar_button.h | 33 | ||||
-rw-r--r-- | chrome/browser/ui/cocoa/toolbar/toolbar_button.mm | 72 | ||||
-rw-r--r-- | chrome/browser/ui/cocoa/toolbar/toolbar_button_unittest.mm | 302 | ||||
-rw-r--r-- | chrome/browser/ui/cocoa/toolbar/toolbar_controller.h | 3 | ||||
-rw-r--r-- | chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm | 6 |
7 files changed, 421 insertions, 5 deletions
diff --git a/chrome/browser/ui/cocoa/menu_button.h b/chrome/browser/ui/cocoa/menu_button.h index 0b463db..b116b1f9 100644 --- a/chrome/browser/ui/cocoa/menu_button.h +++ b/chrome/browser/ui/cocoa/menu_button.h @@ -9,6 +9,7 @@ #import <Cocoa/Cocoa.h> #include "base/scoped_nsobject.h" +#import "chrome/browser/ui/cocoa/toolbar/toolbar_button.h" // This a button which displays a user-provided menu "attached" below it upon // being clicked or dragged (or clicked and held). It expects a @@ -22,7 +23,7 @@ // held. This is used for the toolbar back/forward buttons, which have a // primary action and the menu as a secondary click-hold action. The default // value is NO so that custom actions can be hooked up in Interface Builder. -@interface MenuButton : NSButton { +@interface MenuButton : ToolbarButton { @private scoped_nsobject<NSMenu> attachedMenu_; BOOL attachedMenuEnabled_; diff --git a/chrome/browser/ui/cocoa/toolbar/reload_button.h b/chrome/browser/ui/cocoa/toolbar/reload_button.h index e42e58c..3986b70 100644 --- a/chrome/browser/ui/cocoa/toolbar/reload_button.h +++ b/chrome/browser/ui/cocoa/toolbar/reload_button.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -9,11 +9,12 @@ #import <Cocoa/Cocoa.h> #import "base/scoped_nsobject.h" +#import "chrome/browser/ui/cocoa/toolbar/toolbar_button.h" -// NSButton subclass which defers certain state changes when the mouse +// ToolbarButton subclass which defers certain state changes when the mouse // is hovering over it. -@interface ReloadButton : NSButton { +@interface ReloadButton : ToolbarButton { @private // Tracks whether the mouse is hovering for purposes of not making // unexpected state changes. diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_button.h b/chrome/browser/ui/cocoa/toolbar/toolbar_button.h new file mode 100644 index 0000000..c35d1e5 --- /dev/null +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_button.h @@ -0,0 +1,33 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_BUTTON_H_ +#define CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_BUTTON_H_ +#pragma once + +#import <Cocoa/Cocoa.h> + +// NSButton subclass which handles middle mouse clicking. + +@interface ToolbarButton : NSButton { + @protected + // YES when middle mouse clicks should be handled. + BOOL handleMiddleClick_; + + // YES when a middle mouse click is being handled. This is set to YES by an + // NSOtherMouseDown event, and NO by an NSOtherMouseUp event. While this is + // YES, other mouse button events should be ignored. + BOOL handlingMiddleClick_; +} + +// Whether or not to handle the mouse middle click events. +@property(assign, nonatomic) BOOL handleMiddleClick; + +@end + +@interface ToolbarButton (ExposedForTesting) +- (BOOL)shouldHandleEvent:(NSEvent*)theEvent; +@end + +#endif // CHROME_BROWSER_UI_COCOA_TOOLBAR_TOOLBAR_BUTTON_H_ diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_button.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_button.mm new file mode 100644 index 0000000..517e6e5 --- /dev/null +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_button.mm @@ -0,0 +1,72 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "chrome/browser/ui/cocoa/toolbar/toolbar_button.h" + +@interface ToolbarButton (Private) +- (BOOL)updateStatus:(NSEvent*)theEvent; +@end + +@implementation ToolbarButton + +@synthesize handleMiddleClick = handleMiddleClick_; + +- (void)mouseDown:(NSEvent*)theEvent { + if (!handlingMiddleClick_) + [super mouseDown:theEvent]; +} + +- (void)mouseDragged:(NSEvent*)theEvent { + if (!handlingMiddleClick_) + [super mouseDragged:theEvent]; +} + +- (void)mouseUp:(NSEvent*)theEvent { + if (!handlingMiddleClick_) + [super mouseUp:theEvent]; +} + +- (void)otherMouseDown:(NSEvent*)theEvent { + if (![self shouldHandleEvent:theEvent]) + [super otherMouseDown:theEvent]; + else + handlingMiddleClick_ = [self updateStatus:theEvent]; +} + +- (void)otherMouseDragged:(NSEvent*)theEvent { + if (!handlingMiddleClick_ || ![self shouldHandleEvent:theEvent]) + [super otherMouseDragged:theEvent]; + else + [self updateStatus:theEvent]; +} + +- (void)otherMouseUp:(NSEvent*)theEvent { + if (!handlingMiddleClick_ || ![self shouldHandleEvent:theEvent]) { + [super otherMouseUp:theEvent]; + } else { + if ([self state] == NSOnState) + [self sendAction:[self action] to:[self target]]; + + [self setState:NSOffState]; + [self highlight:NO]; + handlingMiddleClick_ = NO; + } +} + +- (BOOL)updateStatus:(NSEvent*)theEvent { + NSPoint mouseLoc = [self convertPoint:[theEvent locationInWindow] + fromView:nil]; + BOOL isInside = [self mouse:mouseLoc inRect:[self bounds]]; + [self setState:isInside ? NSOnState : NSOffState]; + [self highlight:isInside]; + return isInside; +} + +- (BOOL)shouldHandleEvent:(NSEvent*)theEvent { + // |buttonNumber| is the mouse button whose action triggered theEvent. + // 2 corresponds to the middle mouse button. + return handleMiddleClick_ && [theEvent buttonNumber] == 2; +} + +@end diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_button_unittest.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_button_unittest.mm new file mode 100644 index 0000000..5b1a329 --- /dev/null +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_button_unittest.mm @@ -0,0 +1,302 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import <Cocoa/Cocoa.h> + +#import "base/scoped_nsobject.h" +#include "chrome/app/chrome_command_ids.h" +#import "chrome/browser/ui/cocoa/cocoa_test_helper.h" +#import "chrome/browser/ui/cocoa/test_event_utils.h" +#import "chrome/browser/ui/cocoa/toolbar/toolbar_button.h" +#import "testing/gtest_mac.h" + +@interface TestableToolbarButton : ToolbarButton { + @private + NSInteger numOfClick_; + NSInteger lastCommand_; +} + +@property(assign, nonatomic) NSInteger numOfClick; +@property(assign, nonatomic) NSInteger lastCommand; + +- (id)initWithFrame:(NSRect)frame; +- (void)doAction:(id)sender; +@end + +@implementation TestableToolbarButton + +@synthesize numOfClick = numOfClick_; +@synthesize lastCommand = lastCommand_; + +- (id)initWithFrame:(NSRect)frame { + if ((self = [super initWithFrame:frame])) { + lastCommand_ = IDC_STOP; + } + return self; +} + +- (void)doAction:(id)sender { + lastCommand_ = [sender tag]; + if (lastCommand_ == [self tag]) + ++numOfClick_; +} + +- (BOOL)shouldHandleEvent:(NSEvent*)theEvent { + return handleMiddleClick_; +} + +@end + +namespace { + +class ToolbarButtonTest : public CocoaTest { + public: + ToolbarButtonTest() { + NSRect frame = NSMakeRect(0, 0, 20, 20); + scoped_nsobject<TestableToolbarButton> button( + [[TestableToolbarButton alloc] initWithFrame:frame]); + button_ = button.get(); + + [button_ setTag:IDC_HOME]; + [button_ setTarget:button_]; + [button_ setAction:@selector(doAction:)]; + [[test_window() contentView] addSubview:button_]; + + NSRect bounds = [button_ bounds]; + NSPoint mid_point = NSMakePoint(NSMidX(bounds), NSMidY(bounds)); + NSPoint out_point = NSMakePoint(bounds.origin.x - 10, + bounds.origin.y - 10); + left_down_in_view = + test_event_utils::MouseEventAtPoint(mid_point, NSLeftMouseDown, 0); + left_up_in_view = + test_event_utils::MouseEventAtPoint(mid_point, NSLeftMouseUp, 0); + right_down_in_view = + test_event_utils::MouseEventAtPoint(mid_point, NSRightMouseDown, 0); + right_up_in_view = + test_event_utils::MouseEventAtPoint(mid_point, NSRightMouseUp, 0); + other_down_in_view = + test_event_utils::MouseEventAtPoint(mid_point, NSOtherMouseDown, 0); + other_dragged_in_view = + test_event_utils::MouseEventAtPoint(mid_point, NSOtherMouseDragged, 0); + other_up_in_view = + test_event_utils::MouseEventAtPoint(mid_point, NSOtherMouseUp, 0); + other_down_out_view = + test_event_utils::MouseEventAtPoint(out_point, NSOtherMouseDown, 0); + other_dragged_out_view = + test_event_utils::MouseEventAtPoint(out_point, NSOtherMouseDragged, 0); + other_up_out_view = + test_event_utils::MouseEventAtPoint(out_point, NSOtherMouseUp, 0); + } + + TestableToolbarButton* button_; + NSEvent* left_down_in_view; + NSEvent* left_up_in_view; + NSEvent* right_down_in_view; + NSEvent* right_up_in_view; + NSEvent* other_down_in_view; + NSEvent* other_dragged_in_view; + NSEvent* other_up_in_view; + NSEvent* other_down_out_view; + NSEvent* other_dragged_out_view; + NSEvent* other_up_out_view; +}; + +TEST_VIEW(ToolbarButtonTest, button_) + +TEST_F(ToolbarButtonTest, DoesNotSwallowClicksOnNO) { + // Middle button being down doesn't swallow right button clicks. But + // ToolbarButton doesn't handle right button events. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ rightMouseDown:right_down_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ rightMouseUp:right_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + + // Middle button being down doesn't swallows left button clicks. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [NSApp postEvent:left_up_in_view atStart:YES]; + [button_ mouseDown:left_down_in_view]; + EXPECT_EQ(1, [button_ numOfClick]); + EXPECT_EQ(IDC_HOME, [button_ lastCommand]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(1, [button_ numOfClick]); + EXPECT_EQ(IDC_HOME, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, WithoutMouseDownOnNO) { + // Middle button mouse up without leading mouse down in the view. + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + + // Middle button mouse dragged in the view and up without leading mouse down. + [button_ otherMouseDragged:other_dragged_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, MouseClickOnNO) { + // Middle button clicking in the view. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + + // Middle button clicking outside of the view. + [button_ otherMouseDown:other_down_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseUp:other_up_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, MouseDraggingOnNO) { + // Middle button being down in the view and up outside of the view. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseDragged:other_dragged_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseUp:other_up_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + + // Middle button being down on the button, move to outside and move on it + // again, then up on the button. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseDragged:other_dragged_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, WithoutMouseDownOnYES) { + // Enable middle button handling. + [button_ setHandleMiddleClick:YES]; + + // Middle button mouse up without leading mouse down in the view. + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + + // Middle button mouse dragged in the view and up without leading mouse down. + [button_ otherMouseDragged:other_dragged_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, MouseClickInsideOnYES) { + // Enable middle button handling. + [button_ setHandleMiddleClick:YES]; + + // Middle button clicking in the view. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOnState, [button_ state]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(1, [button_ numOfClick]); + EXPECT_EQ(IDC_HOME, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, MouseClickOutsideOnYES) { + // Enable middle button handling. + [button_ setHandleMiddleClick:YES]; + + // Middle button clicking outside of the view. + [button_ otherMouseDown:other_down_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseUp:other_up_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, MouseDraggingOnYES) { + // Enable middle button handling. + [button_ setHandleMiddleClick:YES]; + + // Middle button being down in the view and up outside of the view. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOnState, [button_ state]); + [button_ otherMouseDragged:other_dragged_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseUp:other_up_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + + // Middle button being down on the button, move to outside and move on it + // again, then up on the button. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOnState, [button_ state]); + [button_ otherMouseDragged:other_dragged_out_view]; + EXPECT_EQ(NSOffState, [button_ state]); + [button_ otherMouseDragged:other_dragged_in_view]; + EXPECT_EQ(NSOnState, [button_ state]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(1, [button_ numOfClick]); + EXPECT_EQ(IDC_HOME, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, DoesNotSwallowRightClickOnYES) { + // Enable middle button handling. + [button_ setHandleMiddleClick:YES]; + + // Middle button being down should swallow right button clicks, but + // ToolbarButton doesn't swallow it because it doesn't handle right button + // events. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOnState, [button_ state]); + [button_ rightMouseDown:right_down_in_view]; + EXPECT_EQ(NSOnState, [button_ state]); + [button_ rightMouseUp:right_up_in_view]; + EXPECT_EQ(NSOnState, [button_ state]); + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(NSOffState, [button_ state]); + EXPECT_EQ(1, [button_ numOfClick]); + EXPECT_EQ(IDC_HOME, [button_ lastCommand]); +} + +TEST_F(ToolbarButtonTest, DoesSwallowLeftClickOnYES) { + // Enable middle button handling. + [button_ setHandleMiddleClick:YES]; + + // Middle button being down swallows left button clicks. + [button_ otherMouseDown:other_down_in_view]; + EXPECT_EQ(NSOnState, [button_ state]); + [NSApp postEvent:left_up_in_view atStart:YES]; + [button_ mouseDown:left_down_in_view]; + EXPECT_EQ(0, [button_ numOfClick]); + EXPECT_EQ(IDC_STOP, [button_ lastCommand]); + [button_ otherMouseUp:other_up_in_view]; + EXPECT_EQ(1, [button_ numOfClick]); + EXPECT_EQ(IDC_HOME, [button_ lastCommand]); +} + +} // namespace diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h index 2240737..ef4ec76 100644 --- a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.h @@ -26,6 +26,7 @@ class CommandUpdater; class LocationBar; class LocationBarViewMac; @class MenuButton; +@class ToolbarButton; namespace ToolbarControllerInternal { class NotificationBridge; class WrenchAcceleratorDelegate; @@ -51,7 +52,7 @@ class WrenchMenuModel; IBOutlet MenuButton* backButton_; IBOutlet MenuButton* forwardButton_; IBOutlet ReloadButton* reloadButton_; - IBOutlet NSButton* homeButton_; + IBOutlet ToolbarButton* homeButton_; IBOutlet MenuButton* wrenchButton_; IBOutlet AutocompleteTextField* locationBar_; IBOutlet BrowserActionsContainerView* browserActionsContainerView_; diff --git a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm index a7141a9..3646a51 100644 --- a/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm +++ b/chrome/browser/ui/cocoa/toolbar/toolbar_controller.mm @@ -35,6 +35,7 @@ #import "chrome/browser/ui/cocoa/menu_controller.h" #import "chrome/browser/ui/cocoa/toolbar/back_forward_menu_controller.h" #import "chrome/browser/ui/cocoa/toolbar/reload_button.h" +#import "chrome/browser/ui/cocoa/toolbar/toolbar_button.h" #import "chrome/browser/ui/cocoa/toolbar/toolbar_view.h" #import "chrome/browser/ui/cocoa/view_id_util.h" #import "chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller.h" @@ -249,6 +250,11 @@ class NotificationBridge : public NotificationObserver { [homeButton_ setShowsBorderOnlyWhileMouseInside:YES]; [wrenchButton_ setShowsBorderOnlyWhileMouseInside:YES]; + [backButton_ setHandleMiddleClick:YES]; + [forwardButton_ setHandleMiddleClick:YES]; + [reloadButton_ setHandleMiddleClick:YES]; + [homeButton_ setHandleMiddleClick:YES]; + [self initCommandStatus:commands_]; locationBarView_.reset(new LocationBarViewMac(locationBar_, commands_, toolbarModel_, |