| 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 97eb5f57a8c69e4dc60dc633054ae5fa214548fe..a8499d1c31d7899bdb40c222f624d63d1dd27927 100644
|
| --- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
|
| +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm
|
| @@ -142,6 +142,11 @@ CGFloat FlipXInView(NSView* view, CGFloat width, CGFloat x) {
|
| return x;
|
| }
|
|
|
| +NSRect FlipRectInView(NSView* view, NSRect rect) {
|
| + rect.origin.x = FlipXInView(view, NSWidth(rect), NSMinX(rect));
|
| + return rect;
|
| +}
|
| +
|
| } // namespace
|
|
|
| @interface NSView (PrivateAPI)
|
| @@ -401,8 +406,8 @@ CGFloat FlipXInView(NSView* view, CGFloat width, CGFloat x) {
|
|
|
| @implementation TabStripController
|
|
|
| -@synthesize leftIndentForControls = leftIndentForControls_;
|
| -@synthesize rightIndentForControls = rightIndentForControls_;
|
| +@synthesize leadingIndentForControls = leadingIndentForControls_;
|
| +@synthesize trailingIndentForControls = trailingIndentForControls_;
|
|
|
| - (id)initWithView:(TabStripView*)view
|
| switchView:(NSView*)switchView
|
| @@ -432,8 +437,9 @@ CGFloat FlipXInView(NSView* view, CGFloat width, CGFloat x) {
|
| defaultFavicon_.reset(
|
| rb.GetNativeImageNamed(IDR_DEFAULT_FAVICON).CopyNSImage());
|
|
|
| - [self setLeftIndentForControls:[[self class] defaultLeftIndentForControls]];
|
| - [self setRightIndentForControls:0];
|
| + [self setLeadingIndentForControls:[[self class]
|
| + defaultLeadingIndentForControls]];
|
| + [self setTrailingIndentForControls:0];
|
|
|
| // Add this invisible view first so that it is ordered below other views.
|
| dragBlockingView_.reset(
|
| @@ -569,7 +575,7 @@ CGFloat FlipXInView(NSView* view, CGFloat width, CGFloat x) {
|
| return [TabController defaultTabHeight];
|
| }
|
|
|
| -+ (CGFloat)defaultLeftIndentForControls {
|
| ++ (CGFloat)defaultLeadingIndentForControls {
|
| // Default indentation leaves enough room so tabs don't overlap with the
|
| // window controls.
|
| return 70.0;
|
| @@ -823,14 +829,20 @@ CGFloat FlipXInView(NSView* view, CGFloat width, CGFloat x) {
|
| availableResizeWidth_ = kUseFullAvailableWidth;
|
| } else {
|
| NSView* penultimateTab = [self viewAtIndex:numberOfOpenTabs - 2];
|
| - availableResizeWidth_ = NSMaxX([penultimateTab frame]);
|
| + availableResizeWidth_ =
|
| + cocoa_l10n_util::ShouldDoExperimentalRTLLayout()
|
| + ? FlipXInView(tabStripView_, 0, NSMinX([penultimateTab frame]))
|
| + : NSMaxX([penultimateTab frame]);
|
| }
|
| } else {
|
| - // If the rightmost tab is closed, change the available width so that
|
| + // If the trailing tab is closed, change the available width so that
|
| // another tab's close button lands below the cursor (assuming the tabs
|
| // are currently below their maximum width and can grow).
|
| NSView* lastTab = [self viewAtIndex:numberOfOpenTabs - 1];
|
| - availableResizeWidth_ = NSMaxX([lastTab frame]);
|
| + availableResizeWidth_ =
|
| + cocoa_l10n_util::ShouldDoExperimentalRTLLayout()
|
| + ? FlipXInView(tabStripView_, 0, NSMinX([lastTab frame]))
|
| + : NSMaxX([lastTab frame]);
|
| }
|
| tabStripModel_->CloseWebContentsAt(
|
| index,
|
| @@ -886,12 +898,20 @@ CGFloat FlipXInView(NSView* view, CGFloat width, CGFloat x) {
|
|
|
| - (BOOL)isTabFullyVisible:(TabView*)tab {
|
| NSRect frame = [tab frame];
|
| - return NSMinX(frame) >= [self leftIndentForControls] &&
|
| - NSMaxX(frame) <= [self tabAreaRightEdge];
|
| + if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) {
|
| + return NSMinX(frame) >= [self trailingIndentForControls] &&
|
| + NSMaxX(frame) <= [self tabAreaRightEdge];
|
| + } else {
|
| + return NSMinX(frame) >= [self leadingIndentForControls] &&
|
| + NSMaxX(frame) <= [self tabAreaRightEdge];
|
| + }
|
| }
|
|
|
| - (CGFloat)tabAreaRightEdge {
|
| - return NSMaxX([tabStripView_ frame]) - [self rightIndentForControls];
|
| + CGFloat rightEdge = cocoa_l10n_util::ShouldDoExperimentalRTLLayout()
|
| + ? [self leadingIndentForControls]
|
| + : [self trailingIndentForControls];
|
| + return NSMaxX([tabStripView_ frame]) - rightEdge;
|
| }
|
|
|
| - (void)showNewTabButton:(BOOL)show {
|
| @@ -939,15 +959,15 @@ CGFloat FlipXInView(NSView* view, CGFloat width, CGFloat x) {
|
| // Account for the width of the new tab button.
|
| availableSpace -=
|
| NSWidth([newTabButton_ frame]) + kNewTabButtonOffset - kTabOverlap;
|
| - // Account for the right-side controls if not in rapid closure mode.
|
| + // Account for the trailing controls if not in rapid closure mode.
|
| // (In rapid closure mode, the available width is set based on the
|
| - // position of the rightmost tab, not based on the width of the tab strip,
|
| - // so the right controls have already been accounted for.)
|
| - availableSpace -= [self rightIndentForControls];
|
| + // position of the trailing tab, not based on the width of the tab strip,
|
| + // so the trailing controls have already been accounted for.)
|
| + availableSpace -= [self trailingIndentForControls];
|
| }
|
|
|
| - // Need to leave room for the left-side controls even in rapid closure mode.
|
| - availableSpace -= [self leftIndentForControls];
|
| + // Need to leave room for the leading controls even in rapid closure mode.
|
| + availableSpace -= [self leadingIndentForControls];
|
|
|
| // This may be negative, but that's okay (taken care of by |MAX()| when
|
| // calculating tab sizes). "pinned" tabs in horizontal mode just get a special
|
| @@ -1006,16 +1026,15 @@ CGFloat FlipXInView(NSView* view, CGFloat width, CGFloat x) {
|
|
|
| BOOL visible = [[tabStripView_ window] isVisible];
|
|
|
| - CGFloat offset =
|
| - cocoa_l10n_util::ShouldDoExperimentalRTLLayout()
|
| - ? [self rightIndentForControls]
|
| - : [self leftIndentForControls];
|
| + CGFloat offset = [self leadingIndentForControls];
|
| bool hasPlaceholderGap = false;
|
| // Whether or not the last tab processed by the loop was a pinned tab.
|
| BOOL isLastTabPinned = NO;
|
| CGFloat tabWidthAccumulatedFraction = 0;
|
| NSInteger laidOutNonPinnedTabs = 0;
|
|
|
| + // Lay everything out as if it was LTR and flip at the end
|
| + // for RTL, if necessary.
|
| for (TabController* tab in tabArray_.get()) {
|
| // Ignore a tab that is going through a close animation.
|
| if ([closingControllers_ containsObject:tab])
|
| @@ -1050,10 +1069,17 @@ CGFloat FlipXInView(NSView* view, CGFloat width, CGFloat x) {
|
| }
|
|
|
| if (placeholderTab_ && !hasPlaceholderGap) {
|
| - const CGFloat placeholderMin = NSMinX(placeholderFrame_);
|
| - // If the left edge is to the left of the placeholder's left, but the
|
| - // mid is to the right of it slide over to make space for it.
|
| - if (NSMidX(tabFrame) > placeholderMin) {
|
| + // If the back edge is behind the placeholder's back edge, but the
|
| + // mid is in front of it of it, slide over to make space for it.
|
| + bool shouldLeaveGap;
|
| + if (cocoa_l10n_util::ShouldDoExperimentalRTLLayout()) {
|
| + const CGFloat tabMidpoint =
|
| + NSMidX(FlipRectInView(tabStripView_, tabFrame));
|
| + shouldLeaveGap = tabMidpoint < NSMaxX(placeholderFrame_);
|
| + } else {
|
| + shouldLeaveGap = NSMidX(tabFrame) > NSMinX(placeholderFrame_);
|
| + }
|
| + if (shouldLeaveGap) {
|
| hasPlaceholderGap = true;
|
| offset += NSWidth(placeholderFrame_);
|
| offset -= kTabOverlap;
|
| @@ -2019,6 +2045,7 @@ CGFloat FlipXInView(NSView* view, CGFloat width, CGFloat x) {
|
|
|
| DCHECK(index && disposition);
|
| NSInteger i = 0;
|
| + BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout();
|
| for (TabController* tab in tabArray_.get()) {
|
| NSView* view = [tab view];
|
| DCHECK([view isKindOfClass:[TabView class]]);
|
| @@ -2034,16 +2061,18 @@ CGFloat FlipXInView(NSView* view, CGFloat width, CGFloat x) {
|
| if (frame.size.width < 1.0)
|
| frame.size.width = 1.0; // try to avoid complete failure
|
|
|
| - // Drop in a new tab to the left of tab |i|?
|
| - if (point.x < (frame.origin.x + kLRProportion * frame.size.width)) {
|
| + CGFloat rightEdge = NSMaxX(frame) - kLRProportion * frame.size.width;
|
| + CGFloat leftEdge = frame.origin.x + kLRProportion * frame.size.width;
|
| +
|
| + // Drop in a new tab before tab |i|?
|
| + if (isRTL ? point.x > rightEdge : point.x < leftEdge) {
|
| *index = i;
|
| *disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
|
| return;
|
| }
|
|
|
| // Drop on tab |i|?
|
| - if (point.x <= (frame.origin.x +
|
| - (1.0 - kLRProportion) * frame.size.width)) {
|
| + if (isRTL ? point.x >= leftEdge : point.x <= rightEdge) {
|
| *index = i;
|
| *disposition = WindowOpenDisposition::CURRENT_TAB;
|
| return;
|
| @@ -2220,20 +2249,26 @@ CGFloat FlipXInView(NSView* view, CGFloat width, CGFloat x) {
|
| }
|
|
|
| - (void)addCustomWindowControls {
|
| + BOOL isRTL = cocoa_l10n_util::ShouldDoExperimentalRTLLayout();
|
| if (!customWindowControls_) {
|
| // Make the container view.
|
| CGFloat height = NSHeight([tabStripView_ frame]);
|
| - NSRect frame = NSMakeRect(0, 0, [self leftIndentForControls], height);
|
| + CGFloat width = [self leadingIndentForControls];
|
| + CGFloat xOrigin = isRTL ? NSWidth([tabStripView_ frame]) - width : 0;
|
| + NSRect frame = NSMakeRect(xOrigin, 0, width, height);
|
| customWindowControls_.reset(
|
| [[CustomWindowControlsView alloc] initWithFrame:frame]);
|
| [customWindowControls_
|
| - setAutoresizingMask:NSViewMaxXMargin | NSViewHeightSizable];
|
| + setAutoresizingMask:isRTL ? NSViewMaxXMargin | NSViewHeightSizable
|
| + : NSViewMinXMargin | NSViewHeightSizable];
|
|
|
| // Add the traffic light buttons. The horizontal layout was determined by
|
| // manual inspection on Yosemite.
|
| CGFloat closeButtonX = 11;
|
| CGFloat pinnedButtonX = 31;
|
| CGFloat zoomButtonX = 51;
|
| + if (isRTL)
|
| + std::swap(closeButtonX, zoomButtonX);
|
|
|
| NSUInteger styleMask = [[tabStripView_ window] styleMask];
|
| NSButton* closeButton = [NSWindow standardWindowButton:NSWindowCloseButton
|
| @@ -2265,7 +2300,13 @@ CGFloat FlipXInView(NSView* view, CGFloat width, CGFloat x) {
|
| [customWindowControls_
|
| addTrackingArea:customWindowControlsTrackingArea_.get()];
|
| }
|
| -
|
| + if (isRTL &&
|
| + NSMaxX([customWindowControls_ frame]) != NSMaxX([tabStripView_ frame])) {
|
| + NSRect frame = [customWindowControls_ frame];
|
| + frame.origin.x =
|
| + NSMaxX([tabStripView_ frame]) - [self leadingIndentForControls];
|
| + [customWindowControls_ setFrame:frame];
|
| + }
|
| if (![permanentSubviews_ containsObject:customWindowControls_]) {
|
| [self addSubviewToPermanentList:customWindowControls_];
|
| [self regenerateSubviewList];
|
|
|