Commit df4f7e43 authored by liaoyuke's avatar liaoyuke Committed by Commit bot

Autoscroll new background tabs on iPad

On iPads, when many tabs are open, additional tabs opened in the background
(through the context menu) will collapse together and remain hidden. Users will
have to manually scroll through to see newly opened ones.

This CL fixes the issue by enabling the scenario that every time a new tab is
inserted, we auto scroll the tab strip view to make it immediately visible.

BUG=228419

Review-Url: https://codereview.chromium.org/2611003002
Cr-Commit-Position: refs/heads/master@{#442106}
parent d890f99c
...@@ -98,6 +98,11 @@ void AppendSwitchesFromExperimentalSettings(base::CommandLine* command_line) { ...@@ -98,6 +98,11 @@ void AppendSwitchesFromExperimentalSettings(base::CommandLine* command_line) {
BUILDFLAG(GOOGLE_TEST_OAUTH_CLIENT_SECRET)); BUILDFLAG(GOOGLE_TEST_OAUTH_CLIENT_SECRET));
} }
// Populate command line flag for the tab strip auto scroll new tabs
// experiment from the configuration plist.
if ([defaults boolForKey:@"TabStripAutoScrollNewTabsDisabled"])
command_line->AppendSwitch(switches::kDisableTabStripAutoScrollNewTabs);
// Populate command line flag for the Tab Switcher experiment from the // Populate command line flag for the Tab Switcher experiment from the
// configuration plist. // configuration plist.
NSString* enableTabSwitcher = [defaults stringForKey:@"EnableTabSwitcher"]; NSString* enableTabSwitcher = [defaults stringForKey:@"EnableTabSwitcher"];
......
...@@ -49,6 +49,10 @@ const char kDisableQRScanner[] = "disable-qr-scanner"; ...@@ -49,6 +49,10 @@ const char kDisableQRScanner[] = "disable-qr-scanner";
// Disables the Spotlight actions. // Disables the Spotlight actions.
const char kDisableSpotlightActions[] = "disable-spotlight-actions"; const char kDisableSpotlightActions[] = "disable-spotlight-actions";
// Disables the tab strip auto scroll new tabs.
const char kDisableTabStripAutoScrollNewTabs[] =
"disable-tab-strip-autoscroll-new-tabs";
// Disables the tab switcher. // Disables the tab switcher.
const char kDisableTabSwitcher[] = "disable-tab-switcher"; const char kDisableTabSwitcher[] = "disable-tab-switcher";
......
...@@ -21,6 +21,7 @@ extern const char kDisableOfflineAutoReload[]; ...@@ -21,6 +21,7 @@ extern const char kDisableOfflineAutoReload[];
extern const char kDisablePaymentRequest[]; extern const char kDisablePaymentRequest[];
extern const char kDisableQRScanner[]; extern const char kDisableQRScanner[];
extern const char kDisableSpotlightActions[]; extern const char kDisableSpotlightActions[];
extern const char kDisableTabStripAutoScrollNewTabs[];
extern const char kDisableTabSwitcher[]; extern const char kDisableTabSwitcher[];
extern const char kDisableIOSPhysicalWeb[]; extern const char kDisableIOSPhysicalWeb[];
extern const char kDisableDownloadImageRenaming[]; extern const char kDisableDownloadImageRenaming[];
......
...@@ -106,6 +106,9 @@ bool IsSpotlightActionsEnabled(); ...@@ -106,6 +106,9 @@ bool IsSpotlightActionsEnabled();
// Whether startup crash is enabled. // Whether startup crash is enabled.
bool IsStartupCrashEnabled(); bool IsStartupCrashEnabled();
// Whether or not the tab strip scrolls new tabs to be visible.
bool IsTabStripAutoScrollNewTabsEnabled();
// Whether the Tab Switcher is enabled for iPad or not. // Whether the Tab Switcher is enabled for iPad or not.
bool IsTabSwitcherEnabled(); bool IsTabSwitcherEnabled();
......
...@@ -273,6 +273,11 @@ bool IsStartupCrashEnabled() { ...@@ -273,6 +273,11 @@ bool IsStartupCrashEnabled() {
return [[NSUserDefaults standardUserDefaults] boolForKey:kEnableStartupCrash]; return [[NSUserDefaults standardUserDefaults] boolForKey:kEnableStartupCrash];
} }
bool IsTabStripAutoScrollNewTabsEnabled() {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
return !command_line->HasSwitch(switches::kDisableTabStripAutoScrollNewTabs);
}
bool IsTabSwitcherEnabled() { bool IsTabSwitcherEnabled() {
// Check if the experimental flag is forced off. // Check if the experimental flag is forced off.
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
......
...@@ -36,6 +36,22 @@ ...@@ -36,6 +36,22 @@
<string>Disabled</string> <string>Disabled</string>
</array> </array>
</dict> </dict>
<dict>
<key>Type</key>
<string>PSGroupSpecifier</string>
<key>Title</key>
<string>iPad Tab Strip</string>
</dict>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>Disable Tab Strip Auto Scroll New Tabs</string>
<key>Key</key>
<string>TabStripAutoScrollNewTabsDisabled</string>
<key>DefaultValue</key>
<false/>
</dict>
<dict> <dict>
<key>Type</key> <key>Type</key>
<string>PSGroupSpecifier</string> <string>PSGroupSpecifier</string>
......
...@@ -315,9 +315,11 @@ const CGFloat kNewTabButtonBottomOffsetHighRes = 2.0; ...@@ -315,9 +315,11 @@ const CGFloat kNewTabButtonBottomOffsetHighRes = 2.0;
// Updates the content offset of the tab strip view in order to keep the // Updates the content offset of the tab strip view in order to keep the
// selected tab view visible. // selected tab view visible.
// Content offset adjustement is only needed/performed in compact mode. // Content offset adjustement is only needed/performed in compact mode or
// regular mode for newly opened tabs.
// This method must be called with a valid |tabIndex|. // This method must be called with a valid |tabIndex|.
- (void)updateContentOffsetForTabIndex:(NSUInteger)tabIndex; - (void)updateContentOffsetForTabIndex:(NSUInteger)tabIndex
isNewTab:(BOOL)isNewTab;
// Update the frame of the tab strip view (scrollview) frame, content inset and // Update the frame of the tab strip view (scrollview) frame, content inset and
// toggle buttons states depending on the current layout mode. // toggle buttons states depending on the current layout mode.
...@@ -639,7 +641,7 @@ const CGFloat kNewTabButtonBottomOffsetHighRes = 2.0; ...@@ -639,7 +641,7 @@ const CGFloat kNewTabButtonBottomOffsetHighRes = 2.0;
[currentTab updateSnapshotWithOverlay:YES visibleFrameOnly:YES]; [currentTab updateSnapshotWithOverlay:YES visibleFrameOnly:YES];
} }
[_tabModel setCurrentTab:tappedTab]; [_tabModel setCurrentTab:tappedTab];
[self updateContentOffsetForTabIndex:index]; [self updateContentOffsetForTabIndex:index isNewTab:NO];
} }
- (void)closeTab:(id)sender { - (void)closeTab:(id)sender {
...@@ -943,7 +945,7 @@ const CGFloat kNewTabButtonBottomOffsetHighRes = 2.0; ...@@ -943,7 +945,7 @@ const CGFloat kNewTabButtonBottomOffsetHighRes = 2.0;
[self updateContentSizeAndRepositionViews]; [self updateContentSizeAndRepositionViews];
[self setNeedsLayoutWithAnimation]; [self setNeedsLayoutWithAnimation];
[self updateContentOffsetForTabIndex:modelIndex]; [self updateContentOffsetForTabIndex:modelIndex isNewTab:YES];
} }
// Observer method. // Observer method.
...@@ -1250,9 +1252,39 @@ const CGFloat kNewTabButtonBottomOffsetHighRes = 2.0; ...@@ -1250,9 +1252,39 @@ const CGFloat kNewTabButtonBottomOffsetHighRes = 2.0;
return IsCompactTablet() ? kMinTabWidthForCompactLayout : kMinTabWidth; return IsCompactTablet() ? kMinTabWidthForCompactLayout : kMinTabWidth;
} }
- (void)updateContentOffsetForTabIndex:(NSUInteger)tabIndex { - (void)updateContentOffsetForTabIndex:(NSUInteger)tabIndex
isNewTab:(BOOL)isNewTab {
DCHECK_NE(NSNotFound, static_cast<NSInteger>(tabIndex)); DCHECK_NE(NSNotFound, static_cast<NSInteger>(tabIndex));
if (experimental_flags::IsTabStripAutoScrollNewTabsEnabled() && isNewTab) {
// The following code calculates the amount of scroll needed to make
// |tabIndex| visible in the "virtual" coordinate system, where root is x=0
// and it contains all the tabs laid out as if the tabstrip was infinitely
// long. The amount of scroll is calculated as a desired length that it is
// just large enough to contain all the tabs to the left of |tabIndex|, with
// the standard overlap.
NSUInteger numNonClosingTabsToLeft = 0;
NSUInteger i = 0;
for (TabView* tab in _tabArray.get()) {
if ([_closingTabs containsObject:tab])
++i;
if (i == tabIndex)
break;
++numNonClosingTabsToLeft;
++i;
}
const CGFloat tabHeight = CGRectGetHeight([_tabStripView bounds]);
CGRect scrollRect =
CGRectMake(_currentTabWidth * numNonClosingTabsToLeft -
([self tabOverlap] * (numNonClosingTabsToLeft - 1)),
0, _currentTabWidth, tabHeight);
[_tabStripView scrollRectToVisible:scrollRect animated:YES];
return;
}
if (IsCompactTablet()) { if (IsCompactTablet()) {
if (tabIndex == [_tabArray count] - 1) { if (tabIndex == [_tabArray count] - 1) {
const CGFloat tabStripAvailableSpace = const CGFloat tabStripAvailableSpace =
...@@ -1603,7 +1635,7 @@ const CGFloat kNewTabButtonBottomOffsetHighRes = 2.0; ...@@ -1603,7 +1635,7 @@ const CGFloat kNewTabButtonBottomOffsetHighRes = 2.0;
[self updateContentSizeAndRepositionViews]; [self updateContentSizeAndRepositionViews];
NSUInteger selectedModelIndex = [_tabModel indexOfTab:[_tabModel currentTab]]; NSUInteger selectedModelIndex = [_tabModel indexOfTab:[_tabModel currentTab]];
if (selectedModelIndex != NSNotFound) { if (selectedModelIndex != NSNotFound) {
[self updateContentOffsetForTabIndex:selectedModelIndex]; [self updateContentOffsetForTabIndex:selectedModelIndex isNewTab:NO];
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment