Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(742)

Unified Diff: chrome/browser/cocoa/tab_strip_controller.mm

Issue 160116: Implement feature where tabs don't resize when using the close box until the ... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/cocoa/tab_strip_controller.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/cocoa/tab_strip_controller.mm
===================================================================
--- chrome/browser/cocoa/tab_strip_controller.mm (revision 21532)
+++ chrome/browser/cocoa/tab_strip_controller.mm (working copy)
@@ -29,6 +29,10 @@
NSString* const kTabStripNumberOfTabsChanged = @"kTabStripNumberOfTabsChanged";
+// A value to indicate tab layout should use the full available width of the
+// 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
@@ -38,6 +42,11 @@
- (void)drawRect:(NSRect)rect {}
@end
+@interface TabStripController(Private)
+- (void)installTrackingArea;
+- (BOOL)useFullWidthForLayout;
+@end
+
@implementation TabStripController
- (id)initWithView:(TabStripView*)view
@@ -66,6 +75,7 @@
initWithFrame:NSZeroRect]);
[view addSubview:dragBlockingView_];
newTabTargetFrame_ = NSMakeRect(0, 0, 0, 0);
+ availableResizeWidth_ = kUseFullAvailableWidth;
// Watch for notifications that the tab strip view has changed size so
// we can tell it to layout for the new size.
@@ -79,6 +89,7 @@
}
- (void)dealloc {
+ [tabView_ removeTrackingArea:closeTabTrackingArea_.get()];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
@@ -157,19 +168,27 @@
// Called when the user clicks a tab. Tell the model the selection has changed,
// which feeds back into us via a notification.
- (void)selectTab:(id)sender {
+ DCHECK([sender isKindOfClass:[NSView class]]);
int index = [self indexForTabView:sender];
if (index >= 0 && tabModel_->ContainsIndex(index))
tabModel_->SelectTabContentsAt(index, true);
}
-// Called when the user closes a tab. Asks the model to close the tab.
+// Called when the user closes a tab. Asks the model to close the tab. |sender|
+// is the TabView that is potentially going away.
- (void)closeTab:(id)sender {
+ DCHECK([sender isKindOfClass:[NSView class]]);
int index = [self indexForTabView:sender];
if (tabModel_->ContainsIndex(index)) {
TabContents* contents = tabModel_->GetTabContentsAt(index);
if (contents)
UserMetrics::RecordAction(L"CloseTab_Mouse", contents->profile());
if ([self numberOfTabViews] > 1) {
+ // Limit the width available for laying out tabs so that tabs are not
+ // resized until a later time (when the mouse leaves the tab strip).
+ NSView* penultimateTab = [self viewAtIndex:[tabArray_ count] - 2];
rohitrao (ping after 24h) 2009/07/24 20:35:57 Will we have to revisit this once we implement rea
+ availableResizeWidth_ = NSMaxX([penultimateTab frame]);
+ [self installTrackingArea];
tabModel_->CloseTabContentsAt(index);
} else {
// Use the standard window close if this is the last tab
@@ -225,12 +244,20 @@
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0.2];
- // Compute the base width of tabs given how much size we have available.
- float availableWidth =
- NSWidth([tabView_ frame]) - NSWidth([newTabButton_ frame]) -
- kNewTabButtonOffset - kIndentLeavingSpaceForControls;
+ // Compute the base width of tabs given how much room we're allowed. We
+ // may not be able to use the entire width if the user is quickly closing
+ // tabs.
+ float availableWidth = 0;
+ if ([self useFullWidthForLayout]) {
+ availableWidth = NSWidth([tabView_ frame]);
+ availableWidth -= NSWidth([newTabButton_ frame]) + kNewTabButtonOffset;
+ } else {
+ availableWidth = availableResizeWidth_;
+ }
+ availableWidth -= kIndentLeavingSpaceForControls;
+
// Add back in the amount we "get back" from the tabs overlapping.
- availableWidth += [tabContentsArray_ count] * kTabOverlap;
+ availableWidth += ([tabContentsArray_ count] - 1) * kTabOverlap;
const float baseTabWidth =
MAX(MIN(availableWidth / [tabContentsArray_ count],
kMaxTabWidth),
@@ -308,16 +335,20 @@
enclosingRect = NSUnionRect(tabFrame, enclosingRect);
}
+#if 0
// Ensure the current tab is "below" the tab before it in z-order so that
// all the tab overlaps are consistent. The selected tab is always the
// frontmost, but it's already been made frontmost when the tab was selected
// so we don't need to do anything about it here. It will get put back into
// place when another tab is selected.
+ // TODO(pinkerton): this doesn't seem to work in the case where a tab
+ // is opened between existing tabs. Disabling.
if (![tab selected]) {
[tabView_ addSubview:[tab view]
positioned:NSWindowBelow
relativeTo:previousTab];
}
+#endif
previousTab = [tab view];
offset += NSWidth(tabFrame);
@@ -326,8 +357,11 @@
}
NSRect newTabNewFrame = [newTabButton_ frame];
- newTabNewFrame.origin =
- NSMakePoint(MIN(availableWidth, offset + kNewTabButtonOffset), 0);
+ if ([self useFullWidthForLayout])
+ 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]) {
@@ -401,6 +435,10 @@
[self setTabTitle:newController withContents:contents];
+ // If a tab is being inserted, we can again use the entire tab strip width
+ // for layout.
+ availableResizeWidth_ = kUseFullAvailableWidth;
+
// We don't need to call |-layoutTabs| if the tab will be in the foreground
// because it will get called when the new tab is selected by the tab model.
if (!inForeground) {
@@ -654,4 +692,39 @@
[self layoutTabsWithAnimation:NO];
}
+- (BOOL)useFullWidthForLayout {
+ return availableResizeWidth_ == kUseFullAvailableWidth;
+}
+
+// Call to install a tracking area that reports mouseEnter/Exit messages so
+// we can track when the mouse leaves the tab view after closing a tab with
+// the mouse. Don't install another tracking rect if one is already there.
+- (void)installTrackingArea {
+ if (closeTabTrackingArea_.get())
+ return;
+ // Note that we pass |NSTrackingInVisibleRect| so the rect is actually
+ // ignored.
+ closeTabTrackingArea_.reset([[NSTrackingArea alloc]
+ initWithRect:[tabView_ bounds]
+ options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways |
+ NSTrackingInVisibleRect
+ owner:self
+ userInfo:nil]);
+ [tabView_ addTrackingArea:closeTabTrackingArea_.get()];
+}
+
+- (void)mouseEntered:(NSEvent*)event {
+ // Do nothing.
+}
+
+// Called when the tracking area is in effect which means we're tracking to
+// see if the user leaves the tab strip with their mouse. When they do,
+// reset layout to use all available width.
+- (void)mouseExited:(NSEvent*)event {
+ [tabView_ removeTrackingArea:closeTabTrackingArea_.get()];
+ closeTabTrackingArea_.reset(nil);
+ availableResizeWidth_ = kUseFullAvailableWidth;
+ [self layoutTabs];
+}
+
@end
« no previous file with comments | « chrome/browser/cocoa/tab_strip_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698