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

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

Issue 476313003: Mac: Improve tab strip layout in case of overflow (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase again Created 6 years, 3 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
Index: chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
index ea07a5e0bf38819193c6cea259f3c90244ef8861..20e3aca3501a5b2fb6f010726b8c3cc0c843adb5 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
@@ -945,7 +945,7 @@ NSImage* Overlay(NSImage* ground, NSImage* overlay, CGFloat alpha) {
const CGFloat kMaxTabWidth = [TabController maxTabWidth];
const CGFloat kMinTabWidth = [TabController minTabWidth];
- const CGFloat kMinSelectedTabWidth = [TabController minSelectedTabWidth];
+ const CGFloat kMinActiveTabWidth = [TabController minActiveTabWidth];
const CGFloat kMiniTabWidth = [TabController miniTabWidth];
const CGFloat kAppTabWidth = [TabController appTabWidth];
@@ -968,7 +968,8 @@ NSImage* Overlay(NSImage* ground, NSImage* overlay, CGFloat alpha) {
availableSpace = NSWidth([tabStripView_ frame]);
// Account for the width of the new tab button.
- availableSpace -= NSWidth([newTabButton_ frame]) + kNewTabButtonOffset;
+ availableSpace -=
+ NSWidth([newTabButton_ frame]) + kNewTabButtonOffset - kTabOverlap;
// Account for the right-side controls if not in rapid closure mode.
// (In rapid closure mode, the available width is set based on the
@@ -980,34 +981,56 @@ NSImage* Overlay(NSImage* ground, NSImage* overlay, CGFloat alpha) {
// Need to leave room for the left-side controls even in rapid closure mode.
availableSpace -= [self leftIndentForControls];
- // If there are any mini tabs, account for the extra spacing between the last
- // mini tab and the first regular tab.
- if ([self numberOfOpenMiniTabs])
- availableSpace -= kLastMiniTabSpacing;
-
// This may be negative, but that's okay (taken care of by |MAX()| when
// calculating tab sizes). "mini" tabs in horizontal mode just get a special
// section, they don't change size.
CGFloat availableSpaceForNonMini = availableSpace;
- availableSpaceForNonMini -=
- [self numberOfOpenMiniTabs] * (kMiniTabWidth - kTabOverlap);
+ if ([self numberOfOpenMiniTabs]) {
+ availableSpaceForNonMini -=
+ [self numberOfOpenMiniTabs] * (kMiniTabWidth - kTabOverlap);
+ availableSpaceForNonMini -= kLastMiniTabSpacing;
+ }
// Initialize |nonMiniTabWidth| in case there aren't any non-mini-tabs; this
// value shouldn't actually be used.
CGFloat nonMiniTabWidth = kMaxTabWidth;
CGFloat nonMiniTabWidthFraction = 0;
- const NSInteger numberOfOpenNonMiniTabs = [self numberOfOpenNonMiniTabs];
- if (numberOfOpenNonMiniTabs) {
+ NSInteger numberOfNonMiniTabs = MIN(
+ [self numberOfOpenNonMiniTabs],
+ (availableSpaceForNonMini - kTabOverlap) / (kMinTabWidth - kTabOverlap));
+
+ if (numberOfNonMiniTabs) {
// Find the width of a non-mini-tab. This only applies to horizontal
// mode. Add in the amount we "get back" from the tabs overlapping.
- availableSpaceForNonMini += (numberOfOpenNonMiniTabs - 1) * kTabOverlap;
-
- // Divide up the space between the non-mini-tabs.
- nonMiniTabWidth = availableSpaceForNonMini / numberOfOpenNonMiniTabs;
+ nonMiniTabWidth =
+ ((availableSpaceForNonMini - kTabOverlap) / numberOfNonMiniTabs) +
+ kTabOverlap;
// Clamp the width between the max and min.
nonMiniTabWidth = MAX(MIN(nonMiniTabWidth, kMaxTabWidth), kMinTabWidth);
+ // When there are multiple tabs, we'll have one active and some inactive
+ // tabs. If the desired width was between the minimum sizes of these types,
+ // try to shrink the tabs with the smaller minimum. For example, if we have
+ // a strip of width 10 with 4 tabs, the desired width per tab will be 2.5.
+ // If selected tabs have a minimum width of 4 and unselected tabs have
+ // minimum width of 1, the above code would set *unselected_width = 2.5,
+ // *selected_width = 4, which results in a total width of 11.5. Instead, we
+ // want to set *unselected_width = 2, *selected_width = 4, for a total width
+ // of 10.
+ if (numberOfNonMiniTabs > 1 && nonMiniTabWidth < kMinActiveTabWidth) {
+ nonMiniTabWidth = (availableSpaceForNonMini - kMinActiveTabWidth) /
+ (numberOfNonMiniTabs - 1) +
+ kTabOverlap;
+ if (nonMiniTabWidth < kMinTabWidth) {
+ // The above adjustment caused the tabs to not fit, show 1 less tab.
+ --numberOfNonMiniTabs;
+ nonMiniTabWidth =
+ ((availableSpaceForNonMini - kTabOverlap) / numberOfNonMiniTabs) +
+ kTabOverlap;
+ }
+ }
+
// Separate integral and fractional parts.
CGFloat integralPart = std::floor(nonMiniTabWidth);
nonMiniTabWidthFraction = nonMiniTabWidth - integralPart;
@@ -1092,7 +1115,7 @@ NSImage* Overlay(NSImage* ground, NSImage* overlay, CGFloat alpha) {
}
// In case of rounding error, give any left over pixels to the last tab.
- if (laidOutNonMiniTabs == numberOfOpenNonMiniTabs - 1 &&
+ if (laidOutNonMiniTabs == numberOfNonMiniTabs - 1 &&
tabWidthAccumulatedFraction > 0.5) {
++tabFrame.size.width;
}
@@ -1100,8 +1123,8 @@ NSImage* Overlay(NSImage* ground, NSImage* overlay, CGFloat alpha) {
++laidOutNonMiniTabs;
}
- if ([tab selected])
- tabFrame.size.width = MAX(tabFrame.size.width, kMinSelectedTabWidth);
+ if ([tab active])
+ tabFrame.size.width = MAX(tabFrame.size.width, kMinActiveTabWidth);
// If this is the first non-mini tab, then add a bit of spacing between this
// and the last mini tab.
@@ -1111,6 +1134,13 @@ NSImage* Overlay(NSImage* ground, NSImage* overlay, CGFloat alpha) {
}
isLastTabMini = isMini;
+ if (laidOutNonMiniTabs > numberOfNonMiniTabs) {
+ // There is not enough space to fit this tab.
+ tabFrame.size.width = 0;
+ [self setFrame:tabFrame ofTabView:[tab view]];
+ continue;
+ }
+
// Animate a new tab in by putting it below the horizon unless told to put
// it in a specific location (i.e., from a drop).
if (newTab && visible && animate) {

Powered by Google App Engine
This is Rietveld 408576698