| Index: chrome/browser/cocoa/tab_strip_controller.mm
|
| diff --git a/chrome/browser/cocoa/tab_strip_controller.mm b/chrome/browser/cocoa/tab_strip_controller.mm
|
| index fb39bd77f57631c4865311828062eea8afc5d0fb..c6a42f773de5d43ebc7143fba8d024320f5beb32 100644
|
| --- a/chrome/browser/cocoa/tab_strip_controller.mm
|
| +++ b/chrome/browser/cocoa/tab_strip_controller.mm
|
| @@ -37,17 +37,52 @@ NSString* const kTabStripNumberOfTabsChanged = @"kTabStripNumberOfTabsChanged";
|
| // view.
|
| static const float kUseFullAvailableWidth = -1.0;
|
|
|
| -// A simple view class that prevents the windowserver from dragging the
|
| -// area behind tabs. Sometimes core animation confuses it.
|
| -@interface TabStripControllerDragBlockingView : NSView
|
| +// A simple view class that prevents the Window Server from dragging the area
|
| +// behind tabs. Sometimes core animation confuses it. Unfortunately, it can also
|
| +// falsely pick up clicks during rapid tab closure, so we have to account for
|
| +// that.
|
| +@interface TabStripControllerDragBlockingView : NSView {
|
| + TabStripController* controller_; // weak; owns us
|
| +}
|
| +
|
| +- (id)initWithFrame:(NSRect)frameRect
|
| + controller:(TabStripController*)controller;
|
| @end
|
| @implementation TabStripControllerDragBlockingView
|
| - (BOOL)mouseDownCanMoveWindow {return NO;}
|
| - (void)drawRect:(NSRect)rect {}
|
| +
|
| +- (id)initWithFrame:(NSRect)frameRect
|
| + controller:(TabStripController*)controller {
|
| + if ((self = [super initWithFrame:frameRect]))
|
| + controller_ = controller;
|
| + return self;
|
| +}
|
| +
|
| +// In "rapid tab closure" mode (i.e., the user is clicking close tab buttons in
|
| +// rapid succession), the animations confuse Cocoa's hit testing (which appears
|
| +// to use cached results, among other tricks), so this view can somehow end up
|
| +// getting a mouse down event. Thus we do an explicit hit test during rapid tab
|
| +// closure, and if we find that we got a mouse down we shouldn't have, we send
|
| +// it off to the appropriate view.
|
| +- (void)mouseDown:(NSEvent*)event {
|
| + if ([controller_ inRapidClosureMode]) {
|
| + NSView* superview = [self superview];
|
| + NSPoint hitLocation =
|
| + [[superview superview] convertPoint:[event locationInWindow]
|
| + fromView:nil];
|
| + NSView* hitView = [superview hitTest:hitLocation];
|
| + if (hitView != self) {
|
| + [hitView mouseDown:event];
|
| + return;
|
| + }
|
| + }
|
| + [super mouseDown:event];
|
| +}
|
| @end
|
|
|
| @interface TabStripController(Private)
|
| -- (BOOL)useFullWidthForLayout;
|
| +- (void)installTrackingArea;
|
| - (void)addSubviewToPermanentList:(NSView*)aView;
|
| - (void)regenerateSubviewList;
|
| - (NSInteger)indexForContentsView:(NSView*)view;
|
| @@ -82,8 +117,9 @@ static const float kUseFullAvailableWidth = -1.0;
|
| [newTabButton_ setAction:@selector(commandDispatch:)];
|
| [newTabButton_ setTag:IDC_NEW_TAB];
|
| targetFrames_.reset([[NSMutableDictionary alloc] init]);
|
| - dragBlockingView_.reset([[TabStripControllerDragBlockingView alloc]
|
| - initWithFrame:NSZeroRect]);
|
| + dragBlockingView_.reset(
|
| + [[TabStripControllerDragBlockingView alloc] initWithFrame:NSZeroRect
|
| + controller:self]);
|
| [self addSubviewToPermanentList:dragBlockingView_];
|
| newTabTargetFrame_ = NSMakeRect(0, 0, 0, 0);
|
| availableResizeWidth_ = kUseFullAvailableWidth;
|
| @@ -321,11 +357,11 @@ static const float kUseFullAvailableWidth = -1.0;
|
| // may not be able to use the entire width if the user is quickly closing
|
| // tabs.
|
| float availableWidth = 0;
|
| - if ([self useFullWidthForLayout]) {
|
| + if ([self inRapidClosureMode]) {
|
| + availableWidth = availableResizeWidth_;
|
| + } else {
|
| availableWidth = NSWidth([tabView_ frame]);
|
| availableWidth -= NSWidth([newTabButton_ frame]) + kNewTabButtonOffset;
|
| - } else {
|
| - availableWidth = availableResizeWidth_;
|
| }
|
| availableWidth -= kIndentLeavingSpaceForControls;
|
|
|
| @@ -418,11 +454,11 @@ static const float kUseFullAvailableWidth = -1.0;
|
| [newTabButton_ setHidden:YES];
|
| } else {
|
| NSRect newTabNewFrame = [newTabButton_ frame];
|
| - if ([self useFullWidthForLayout])
|
| + if ([self inRapidClosureMode])
|
| + newTabNewFrame.origin = NSMakePoint(offset + kNewTabButtonOffset, 0);
|
| + else
|
| newTabNewFrame.origin =
|
| NSMakePoint(MIN(availableWidth, offset + kNewTabButtonOffset), 0);
|
| - else
|
| - newTabNewFrame.origin = NSMakePoint(offset + kNewTabButtonOffset, 0);
|
| newTabNewFrame.origin.x = MAX(newTabNewFrame.origin.x,
|
| NSMaxX(placeholderFrame_));
|
| if (i > 0 && [newTabButton_ isHidden]) {
|
| @@ -776,8 +812,8 @@ static const float kUseFullAvailableWidth = -1.0;
|
| [self layoutTabsWithAnimation:NO regenerateSubviews:NO];
|
| }
|
|
|
| -- (BOOL)useFullWidthForLayout {
|
| - return availableResizeWidth_ == kUseFullAvailableWidth;
|
| +- (BOOL)inRapidClosureMode {
|
| + return availableResizeWidth_ != kUseFullAvailableWidth;
|
| }
|
|
|
| - (void)mouseMoved:(NSEvent *)event {
|
|
|