diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-02 21:20:54 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-02 21:20:54 +0000 |
commit | 1a242c311da93e0458808816d5212805e7b93464 (patch) | |
tree | 6cecde28259a1ae051436f44f1f23e9a69be276d /chrome/browser | |
parent | 12d1d395df66090ce37a8719040bf9c096636330 (diff) | |
download | chromium_src-1a242c311da93e0458808816d5212805e7b93464.zip chromium_src-1a242c311da93e0458808816d5212805e7b93464.tar.gz chromium_src-1a242c311da93e0458808816d5212805e7b93464.tar.bz2 |
Adjusts tab strip model to deal with app tabs. There were a couple of
places where I left them using the variable with pinned when it should
be app because those places need to be radically whacked. I'll do that
next.
BUG=32845
TEST=none yet
Review URL: http://codereview.chromium.org/555173
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37880 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
27 files changed, 243 insertions, 742 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index bc7b764..e683ca8 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -679,7 +679,7 @@ TabContents* Browser::AddRestoredTab( from_last_session); bool really_pin = - (pin && tab_index == tabstrip_model()->IndexOfFirstNonPinnedTab()); + (pin && tab_index == tabstrip_model()->IndexOfFirstNonAppTab()); tabstrip_model_.InsertTabContentsAt(tab_index, new_tab, select, false); if (really_pin) tabstrip_model_.SetTabPinned(tab_index, true); @@ -1909,8 +1909,7 @@ void Browser::TabSelectedAt(TabContents* old_contents, void Browser::TabMoved(TabContents* contents, int from_index, - int to_index, - bool pinned_state_changed) { + int to_index) { DCHECK(from_index >= 0 && to_index >= 0); // Notify the history service. SyncHistoryWithTabs(std::min(from_index, to_index)); diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index 4b35a1b..885ff0a 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -553,8 +553,7 @@ class Browser : public TabStripModelDelegate, bool user_gesture); virtual void TabMoved(TabContents* contents, int from_index, - int to_index, - bool pinned_state_changed); + int to_index); virtual void TabReplacedAt(TabContents* old_contents, TabContents* new_contents, int index); diff --git a/chrome/browser/browser_browsertest.cc b/chrome/browser/browser_browsertest.cc index bcf431e..89f9359 100644 --- a/chrome/browser/browser_browsertest.cc +++ b/chrome/browser/browser_browsertest.cc @@ -71,6 +71,7 @@ class BrowserTest : public InProcessBrowserTest { TabStripModel* model = browser()->tabstrip_model(); ui_test_utils::NavigateToURL(browser(), url); + model->GetTabContentsAt(0)->set_app(true); model->SetTabPinned(0, true); browser()->AddTabWithURL(GURL("about:blank"), GURL(), PageTransition::TYPED, @@ -323,17 +324,13 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, FaviconOfOnloadRedirectToAnchorPage) { EXPECT_EQ(expected_favicon_url.spec(), entry->favicon().url().spec()); } +// TODO(sky): get these to run a Mac. +#if !defined(OS_MACOSX) IN_PROC_BROWSER_TEST_F(BrowserTest, PhantomTab) { - if (!browser_defaults::kPinnedTabsActLikeApps) - return; - PhantomTabTest(); } IN_PROC_BROWSER_TEST_F(BrowserTest, RevivePhantomTab) { - if (!browser_defaults::kPinnedTabsActLikeApps) - return; - PhantomTabTest(); if (HasFatalFailure()) @@ -349,6 +346,7 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, RevivePhantomTab) { // The first tab should no longer be a phantom. EXPECT_FALSE(model->IsPhantomTab(0)); } +#endif // Tests that the CLD (Compact Language Detection) works properly. IN_PROC_BROWSER_TEST_F(BrowserTest, PageLanguageDetection) { diff --git a/chrome/browser/chromeos/compact_location_bar_host.cc b/chrome/browser/chromeos/compact_location_bar_host.cc index fafa967..0fee4a1 100644 --- a/chrome/browser/chromeos/compact_location_bar_host.cc +++ b/chrome/browser/chromeos/compact_location_bar_host.cc @@ -122,8 +122,7 @@ void CompactLocationBarHost::TabSelectedAt(TabContents* old_contents, void CompactLocationBarHost::TabMoved(TabContents* contents, int from_index, - int to_index, - bool pinned_state_changed) { + int to_index) { Update(to_index, false); } diff --git a/chrome/browser/chromeos/compact_location_bar_host.h b/chrome/browser/chromeos/compact_location_bar_host.h index 1d7b683..9243e78 100644 --- a/chrome/browser/chromeos/compact_location_bar_host.h +++ b/chrome/browser/chromeos/compact_location_bar_host.h @@ -77,8 +77,7 @@ class CompactLocationBarHost : public DropdownBarHost, bool user_gesture); virtual void TabMoved(TabContents* contents, int from_index, - int to_index, - bool pinned_state_changed); + int to_index); virtual void TabChangedAt(TabContents* contents, int index, TabChangeType change_type); diff --git a/chrome/browser/chromeos/compact_navigation_bar.cc b/chrome/browser/chromeos/compact_navigation_bar.cc index d6b137cc..3144041 100644 --- a/chrome/browser/chromeos/compact_navigation_bar.cc +++ b/chrome/browser/chromeos/compact_navigation_bar.cc @@ -285,7 +285,7 @@ void CompactNavigationBar::AddTabWithURL(const GURL& url, switch (StatusAreaView::GetOpenTabsMode()) { case StatusAreaView::OPEN_TABS_ON_LEFT: { // Add the new tab at the first non-pinned location. - int index = browser->tabstrip_model()->IndexOfFirstNonPinnedTab(); + int index = browser->tabstrip_model()->IndexOfFirstNonAppTab(); browser->AddTabWithURL(url, GURL(), transition, true, index, true, NULL); break; diff --git a/chrome/browser/cocoa/tab_strip_controller.mm b/chrome/browser/cocoa/tab_strip_controller.mm index 2ee7d55..876f56a 100644 --- a/chrome/browser/cocoa/tab_strip_controller.mm +++ b/chrome/browser/cocoa/tab_strip_controller.mm @@ -465,7 +465,8 @@ private: // Ask the model for the number of pinned tabs. Note that tabs which are in // the process of closing (i.e., whose controllers are in // |closingControllers_|) have already been removed from the model. - return static_cast<NSInteger>(tabStripModel_->IndexOfFirstNonPinnedTab()); + // TODO: convert to apps. + return 0; } // (Private) Returns the number of open, unpinned tabs. diff --git a/chrome/browser/cocoa/tab_strip_model_observer_bridge.h b/chrome/browser/cocoa/tab_strip_model_observer_bridge.h index a052344..fc608fc 100644 --- a/chrome/browser/cocoa/tab_strip_model_observer_bridge.h +++ b/chrome/browser/cocoa/tab_strip_model_observer_bridge.h @@ -33,8 +33,7 @@ class TabStripModelObserverBridge : public TabStripModelObserver { bool user_gesture); virtual void TabMoved(TabContents* contents, int from_index, - int to_index, - bool pinned_state_changed); + int to_index); virtual void TabChangedAt(TabContents* contents, int index, TabChangeType change_type); virtual void TabPinnedStateChanged(TabContents* contents, int index); diff --git a/chrome/browser/cocoa/tab_strip_model_observer_bridge.mm b/chrome/browser/cocoa/tab_strip_model_observer_bridge.mm index e3f2c02..87051c0 100644 --- a/chrome/browser/cocoa/tab_strip_model_observer_bridge.mm +++ b/chrome/browser/cocoa/tab_strip_model_observer_bridge.mm @@ -61,14 +61,14 @@ void TabStripModelObserverBridge::TabSelectedAt(TabContents* old_contents, void TabStripModelObserverBridge::TabMoved(TabContents* contents, int from_index, - int to_index, - bool pinned_state_changed) { + int to_index) { if ([controller_ respondsToSelector: @selector(tabMovedWithContents:fromIndex:toIndex:pinnedStateChanged:)]) { + // TODO: clean this up, need to remove pinnedStateChanged param. [controller_ tabMovedWithContents:contents fromIndex:from_index toIndex:to_index - pinnedStateChanged:(pinned_state_changed ? YES : NO)]; + pinnedStateChanged:NO]; } } diff --git a/chrome/browser/defaults.cc b/chrome/browser/defaults.cc index 080ec265..a901949 100644 --- a/chrome/browser/defaults.cc +++ b/chrome/browser/defaults.cc @@ -6,12 +6,6 @@ namespace browser_defaults { -#if defined(TOOLKIT_VIEWS) -const bool kPinnedTabsActLikeApps = true; -#else -const bool kPinnedTabsActLikeApps = false; -#endif - #if defined(OS_CHROMEOS) const double kAutocompleteEditFontPixelSize = 12.0; diff --git a/chrome/browser/defaults.h b/chrome/browser/defaults.h index 78c7be4..595bb70 100644 --- a/chrome/browser/defaults.h +++ b/chrome/browser/defaults.h @@ -60,9 +60,6 @@ extern const bool kDownloadPageHasShowInFolder; // Should the tab strip be sized to the top of the tab strip? extern const bool kSizeTabButtonToTopOfTabStrip; -// Should pinned tabs be treated as though they are apps as well? -extern const bool kPinnedTabsActLikeApps; - // Whether we should bootstrap the sync authentication using cookies instead of // asking the user for credentials. extern const bool kBootstrapSyncAuthentication; diff --git a/chrome/browser/extensions/extension_browser_event_router.cc b/chrome/browser/extensions/extension_browser_event_router.cc index 990a0a1..388863a 100644 --- a/chrome/browser/extensions/extension_browser_event_router.cc +++ b/chrome/browser/extensions/extension_browser_event_router.cc @@ -314,8 +314,7 @@ void ExtensionBrowserEventRouter::TabSelectedAt(TabContents* old_contents, void ExtensionBrowserEventRouter::TabMoved(TabContents* contents, int from_index, - int to_index, - bool pinned_state_changed) { + int to_index) { ListValue args; args.Append(Value::CreateIntegerValue(ExtensionTabUtil::GetTabId(contents))); diff --git a/chrome/browser/extensions/extension_browser_event_router.h b/chrome/browser/extensions/extension_browser_event_router.h index 0b56c45..13c8ead 100644 --- a/chrome/browser/extensions/extension_browser_event_router.h +++ b/chrome/browser/extensions/extension_browser_event_router.h @@ -47,8 +47,7 @@ class ExtensionBrowserEventRouter : public TabStripModelObserver, TabContents* new_contents, int index, bool user_gesture); - virtual void TabMoved(TabContents* contents, int from_index, int to_index, - bool pinned_state_changed); + virtual void TabMoved(TabContents* contents, int from_index, int to_index); virtual void TabChangedAt(TabContents* contents, int index, TabChangeType change_type); virtual void TabReplacedAt(TabContents* old_contents, diff --git a/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc b/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc index 415710c..0a602d1 100644 --- a/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc +++ b/chrome/browser/gtk/tabs/dragged_tab_controller_gtk.cc @@ -302,8 +302,7 @@ void DraggedTabControllerGtk::MoveTab(const gfx::Point& screen_point) { if (!dragged_tab_->is_pinned()) { // If the dragged tab isn't pinned, don't allow the drag to a pinned // tab. - to_index = - std::max(to_index, attached_model->IndexOfFirstNonPinnedTab()); + to_index = std::max(to_index, attached_model->IndexOfFirstNonAppTab()); } if (from_index != to_index) { last_move_screen_x_ = screen_point.x(); @@ -346,7 +345,7 @@ void DraggedTabControllerGtk::StartPinTimerIfNecessary( return; TabStripModel* attached_model = attached_tabstrip_->model(); - int pinned_count = attached_model->IndexOfFirstNonPinnedTab(); + int pinned_count = attached_model->IndexOfFirstNonAppTab(); if (pinned_count > 0) return; @@ -369,7 +368,7 @@ void DraggedTabControllerGtk::AdjustDragPointForPinnedTabs( int* from_index, gfx::Point* dragged_tab_point) { TabStripModel* attached_model = attached_tabstrip_->model(); - int pinned_count = attached_model->IndexOfFirstNonPinnedTab(); + int pinned_count = attached_model->IndexOfFirstNonAppTab(); if (pinned_count == 0) return; @@ -580,7 +579,7 @@ gfx::Point DraggedTabControllerGtk::ConvertScreenPointToTabStripPoint( } int DraggedTabControllerGtk::GetPinnedThreshold() { - int pinned_count = attached_tabstrip_->model()->IndexOfFirstNonPinnedTab(); + int pinned_count = attached_tabstrip_->model()->IndexOfFirstNonAppTab(); if (pinned_count == 0) return 0; if (!dragged_tab_->is_pinned()) { diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/gtk/tabs/tab_strip_gtk.cc index e27cdd7..decf8cf 100644 --- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc +++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc @@ -33,7 +33,6 @@ const int kDefaultAnimationDurationMs = 100; const int kResizeLayoutAnimationDurationMs = 166; const int kReorderAnimationDurationMs = 166; const int kAnimateToBoundsDurationMs = 150; -const int kPinnedTabAnimationDurationMs = 166; const int kNewTabButtonHOffset = -5; const int kNewTabButtonVOffset = 5; @@ -109,8 +108,6 @@ class TabStripGtk::TabAnimation : public AnimationDelegate { REMOVE, MOVE, RESIZE, - PIN, - PIN_MOVE }; TabAnimation(TabStripGtk* tabstrip, Type type) @@ -517,164 +514,6 @@ class ResizeLayoutAnimation : public TabStripGtk::TabAnimation { }; //////////////////////////////////////////////////////////////////////////////// - -// Handles a tabs pinned state changing while the tab does not change position -// in the model. -class PinnedTabAnimation : public TabStripGtk::TabAnimation { - public: - explicit PinnedTabAnimation(TabStripGtk* tabstrip, int index) - : TabAnimation(tabstrip, PIN), - index_(index) { - int tab_count = tabstrip->GetTabCount(); - int start_pinned_count = tabstrip->GetPinnedTabCount(); - int end_pinned_count = start_pinned_count; - if (tabstrip->GetTabAt(index)->is_pinned()) - start_pinned_count--; - else - start_pinned_count++; - tabstrip_->GetTabAt(index)->set_animating_pinned_change(true); - GenerateStartAndEndWidths(tab_count, tab_count, start_pinned_count, - end_pinned_count); - } - - protected: - // Overridden from TabStripGtk::TabAnimation: - virtual int GetDuration() const { - return kPinnedTabAnimationDurationMs; - } - - virtual double GetWidthForTab(int index) const { - TabGtk* tab = tabstrip_->GetTabAt(index); - - if (index == index_) { - if (tab->is_pinned()) { - return AnimationPosition( - start_selected_width_, - static_cast<double>(TabGtk::GetPinnedWidth())); - } else { - return AnimationPosition(static_cast<double>(TabGtk::GetPinnedWidth()), - end_selected_width_); - } - } else if (tab->is_pinned()) { - return TabGtk::GetPinnedWidth(); - } - - if (tab->IsSelected()) - return AnimationPosition(start_selected_width_, end_selected_width_); - - return AnimationPosition(start_unselected_width_, end_unselected_width_); - } - - private: - // Index of the tab whose pinned state changed. - int index_; - - DISALLOW_COPY_AND_ASSIGN(PinnedTabAnimation); -}; - -//////////////////////////////////////////////////////////////////////////////// - -// Handles the animation when a tabs pinned state changes and the tab moves as a -// result. -class PinAndMoveAnimation : public TabStripGtk::TabAnimation { - public: - explicit PinAndMoveAnimation(TabStripGtk* tabstrip, - int from_index, - int to_index, - const gfx::Rect& start_bounds) - : TabAnimation(tabstrip, PIN_MOVE), - tab_(tabstrip->GetTabAt(to_index)), - start_bounds_(start_bounds), - from_index_(from_index), - to_index_(to_index) { - int tab_count = tabstrip->GetTabCount(); - int start_pinned_count = tabstrip->GetPinnedTabCount(); - int end_pinned_count = start_pinned_count; - if (tabstrip->GetTabAt(to_index)->is_pinned()) - start_pinned_count--; - else - start_pinned_count++; - GenerateStartAndEndWidths(tab_count, tab_count, start_pinned_count, - end_pinned_count); - target_bounds_ = tabstrip->GetIdealBounds(to_index); - tab_->set_animating_pinned_change(true); - } - - // Overridden from AnimationDelegate: - virtual void AnimationProgressed(const Animation* animation) { - // Do the normal layout. - TabAnimation::AnimationProgressed(animation); - - // Then special case the position of the tab being moved. - int x = AnimationPosition(start_bounds_.x(), target_bounds_.x()); - int width = AnimationPosition(start_bounds_.width(), - target_bounds_.width()); - gfx::Rect tab_bounds(x, start_bounds_.y(), width, - start_bounds_.height()); - tabstrip_->SetTabBounds(tab_, tab_bounds); - } - - virtual void AnimationEnded(const Animation* animation) { - tabstrip_->needs_resize_layout_ = false; - TabStripGtk::TabAnimation::AnimationEnded(animation); - } - - virtual double GetGapWidth(int index) { - if (to_index_ < from_index_) { - // The tab was pinned. - if (index == to_index_) { - double current_size = AnimationPosition(0, target_bounds_.width()); - if (current_size < -kTabHOffset) - return -(current_size + kTabHOffset); - } else if (index == from_index_ + 1) { - return AnimationPosition(start_bounds_.width(), 0); - } - } else { - // The tab was unpinned. - if (index == from_index_) { - return AnimationPosition(TabGtk::GetPinnedWidth() + kTabHOffset, 0); - } - } - return 0; - } - - protected: - // Overridden from TabStripGtk::TabAnimation: - virtual int GetDuration() const { return kReorderAnimationDurationMs; } - - virtual double GetWidthForTab(int index) const { - TabGtk* tab = tabstrip_->GetTabAt(index); - - if (index == to_index_) - return AnimationPosition(0, target_bounds_.width()); - - if (tab->is_pinned()) - return TabGtk::GetPinnedWidth(); - - if (tab->IsSelected()) - return AnimationPosition(start_selected_width_, end_selected_width_); - - return AnimationPosition(start_unselected_width_, end_unselected_width_); - } - - private: - // The tab being moved. - TabGtk* tab_; - - // Initial bounds of tab_. - gfx::Rect start_bounds_; - - // Target bounds. - gfx::Rect target_bounds_; - - // Start and end indices of the tab. - int from_index_; - int to_index_; - - DISALLOW_COPY_AND_ASSIGN(PinAndMoveAnimation); -}; - -//////////////////////////////////////////////////////////////////////////////// // TabStripGtk, public: // static @@ -1003,8 +842,7 @@ void TabStripGtk::TabSelectedAt(TabContents* old_contents, void TabStripGtk::TabMoved(TabContents* contents, int from_index, - int to_index, - bool pinned_state_changed) { + int to_index) { gfx::Rect start_bounds = GetIdealBounds(from_index); TabGtk* tab = GetTabAt(from_index); tab_data_.erase(tab_data_.begin() + from_index); @@ -1012,12 +850,8 @@ void TabStripGtk::TabMoved(TabContents* contents, tab->set_pinned(model_->IsTabPinned(to_index)); tab->SetBlocked(model_->IsTabBlocked(to_index)); tab_data_.insert(tab_data_.begin() + to_index, data); - if (pinned_state_changed) { - StartPinAndMoveTabAnimation(from_index, to_index, start_bounds); - } else { - GenerateIdealBounds(); - StartMoveTabAnimation(from_index, to_index); - } + GenerateIdealBounds(); + StartMoveTabAnimation(from_index, to_index); } void TabStripGtk::TabChangedAt(TabContents* contents, int index, @@ -1037,14 +871,12 @@ void TabStripGtk::TabChangedAt(TabContents* contents, int index, void TabStripGtk::TabPinnedStateChanged(TabContents* contents, int index) { GetTabAt(index)->set_pinned(model_->IsTabPinned(index)); - StartPinnedTabAnimation(index); } void TabStripGtk::TabBlockedStateChanged(TabContents* contents, int index) { GetTabAt(index)->SetBlocked(model_->IsTabBlocked(index)); } - //////////////////////////////////////////////////////////////////////////////// // TabStripGtk, TabGtk::TabDelegate implementation: @@ -1773,21 +1605,6 @@ void TabStripGtk::StartResizeLayoutAnimation() { active_animation_->Start(); } -void TabStripGtk::StartPinnedTabAnimation(int index) { - StopAnimation(); - active_animation_.reset(new PinnedTabAnimation(this, index)); - active_animation_->Start(); -} - -void TabStripGtk::StartPinAndMoveTabAnimation(int from_index, - int to_index, - const gfx::Rect& start_bounds) { - StopAnimation(); - active_animation_.reset( - new PinAndMoveAnimation(this, from_index, to_index, start_bounds)); - active_animation_->Start(); -} - void TabStripGtk::FinishAnimation(TabStripGtk::TabAnimation* animation, bool layout) { active_animation_.reset(NULL); diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.h b/chrome/browser/gtk/tabs/tab_strip_gtk.h index 4533e7a..048f661 100644 --- a/chrome/browser/gtk/tabs/tab_strip_gtk.h +++ b/chrome/browser/gtk/tabs/tab_strip_gtk.h @@ -102,8 +102,7 @@ class TabStripGtk : public TabStripModelObserver, bool user_gesture); virtual void TabMoved(TabContents* contents, int from_index, - int to_index, - bool pinned_state_changed); + int to_index); virtual void TabChangedAt(TabContents* contents, int index, TabChangeType change_type); virtual void TabPinnedStateChanged(TabContents* contents, int index); @@ -148,8 +147,6 @@ class TabStripGtk : public TabStripModelObserver, friend class InsertTabAnimation; friend class RemoveTabAnimation; friend class MoveTabAnimation; - friend class PinAndMoveAnimation; - friend class PinnedTabAnimation; friend class ResizeLayoutAnimation; friend class TabAnimation; @@ -382,9 +379,6 @@ class TabStripGtk : public TabStripModelObserver, void StartRemoveTabAnimation(int index, TabContents* contents); void StartMoveTabAnimation(int from_index, int to_index); void StartResizeLayoutAnimation(); - void StartPinnedTabAnimation(int index); - void StartPinAndMoveTabAnimation(int from_index, int to_index, - const gfx::Rect& start_bounds); // Notifies the TabStrip that the specified TabAnimation has completed. // Optionally a full Layout will be performed, specified by |layout|. diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 81215e9..186e155 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -266,7 +266,8 @@ TabContents::TabContents(Profile* profile, suppress_javascript_messages_(false), is_showing_before_unload_dialog_(false), renderer_preferences_(), - opener_dom_ui_type_(DOMUIFactory::kNoDOMUI) { + opener_dom_ui_type_(DOMUIFactory::kNoDOMUI), + app_(false) { renderer_preferences_util::UpdateFromSystemSettings( &renderer_preferences_, profile); @@ -1216,7 +1217,7 @@ void TabContents::OnCloseStarted() { } TabContents* TabContents::CloneAndMakePhantom() { - // TODO: the initial URL, title and what not should come from the app. + // TODO(sky): the initial URL, title and what not should come from the app. NavigationEntry* entry = controller().GetActiveEntry(); TabNavigation tab_nav; @@ -1228,8 +1229,9 @@ TabContents* TabContents::CloneAndMakePhantom() { TabContents* new_contents = new TabContents(profile(), NULL, MSG_ROUTING_NONE, NULL); new_contents->controller().RestoreFromState(navigations, 0, false); + new_contents->app_ = app_; if (entry) { - // TODO: this should come from the app. + // TODO(sky): this should come from the app. new_contents->controller().GetActiveEntry()->favicon() = entry->favicon(); } diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index 4222e77..6615959 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -120,6 +120,7 @@ class TabContents : public PageNavigator, // |base_tab_contents| is used if we want to size the new tab contents view // based on an existing tab contents view. This can be NULL if not needed. + // TODO(sky): make constructor take Extension. TabContents(Profile* profile, SiteInstance* site_instance, int routing_id, @@ -183,6 +184,11 @@ class TabContents : public PageNavigator, return fav_icon_helper_; } + // TODO(sky): whether a tab is an app should be determined by the constructor, + // not a setter, and should likely take the extension. + void set_app(bool app) { app_ = app; } + bool app() const { return app_; } + #ifdef UNIT_TEST // Expose the render manager for testing. RenderViewHostManager* render_manager() { return &render_manager_; } @@ -1171,6 +1177,10 @@ class TabContents : public PageNavigator, // profile scoped_refptr<URLRequestContextGetter> request_context_; + // This is temporary until wired to extensions. + // TODO(sky): fix this. + bool app_; + // --------------------------------------------------------------------------- DISALLOW_COPY_AND_ASSIGN(TabContents); diff --git a/chrome/browser/tabs/tab_strip_model.cc b/chrome/browser/tabs/tab_strip_model.cc index 409815a..4e3708c 100644 --- a/chrome/browser/tabs/tab_strip_model.cc +++ b/chrome/browser/tabs/tab_strip_model.cc @@ -102,6 +102,13 @@ void TabStripModel::InsertTabContentsAt(int index, TabContents* contents, bool foreground, bool inherit_group) { + // Make sure the index maintains that all app tab occurs before non-app tabs. + int first_non_app = IndexOfFirstNonAppTab(); + if (contents->app()) + index = std::min(first_non_app, index); + else + index = std::max(first_non_app, index); + // In tab dragging situations, if the last tab in the window was detached // then the user aborted the drag, we will have the |closing_all_| member // set (see DetachTabContentsAt) which will mess with our mojo here. We need @@ -113,7 +120,6 @@ void TabStripModel::InsertTabContentsAt(int index, // since the old contents and the new contents will be the same... TabContents* selected_contents = GetSelectedTabContents(); TabContentsData* data = new TabContentsData(contents); - data->pinned = (index != count() && index < IndexOfFirstNonPinnedTab()); if (inherit_group && selected_contents) { if (foreground) { // Forget any existing relationships, we don't want to make things too @@ -190,7 +196,33 @@ void TabStripModel::SelectTabContentsAt(int index, bool user_gesture) { void TabStripModel::MoveTabContentsAt(int index, int to_position, bool select_after_move) { - MoveTabContentsAtImpl(index, to_position, select_after_move, true); + DCHECK(ContainsIndex(index)); + if (index == to_position) + return; + + int first_non_app_tab = IndexOfFirstNonAppTab(); + if ((index < first_non_app_tab && to_position >= first_non_app_tab) || + (to_position < first_non_app_tab && index >= first_non_app_tab)) { + // This would result in app tabs mixed with non-app tabs. We don't allow + // that. + return; + } + + TabContentsData* moved_data = contents_data_.at(index); + contents_data_.erase(contents_data_.begin() + index); + contents_data_.insert(contents_data_.begin() + to_position, moved_data); + + // if !select_after_move, keep the same tab selected as was selected before. + if (select_after_move || index == selected_index_) { + selected_index_ = to_position; + } else if (index < selected_index_ && to_position >= selected_index_) { + selected_index_--; + } else if (index > selected_index_ && to_position <= selected_index_) { + selected_index_++; + } + + FOR_EACH_OBSERVER(TabStripModelObserver, observers_, + TabMoved(moved_data->contents, index, to_position)); } TabContents* TabStripModel::GetSelectedTabContents() const { @@ -366,29 +398,19 @@ void TabStripModel::SetTabBlocked(int index, bool blocked) { void TabStripModel::SetTabPinned(int index, bool pinned) { DCHECK(ContainsIndex(index)); + int first_non_app_tab = IndexOfFirstNonAppTab(); + if (index >= first_non_app_tab) + return; // Only allow pinning of app tabs. + if (contents_data_[index]->pinned == pinned) return; - int first_non_pinned_tab = IndexOfFirstNonPinnedTab(); - contents_data_[index]->pinned = pinned; - if (pinned && index > first_non_pinned_tab) { - // The tab is being pinned but beyond the pinned tabs. Move it to the end - // of the pinned tabs. - MoveTabContentsAtImpl(index, first_non_pinned_tab, - selected_index() == index, false); - } else if (!pinned && index < first_non_pinned_tab - 1) { - // The tab is being unpinned, but is within the pinned tabs, move it to - // be after the set of pinned tabs. - MoveTabContentsAtImpl(index, first_non_pinned_tab - 1, - selected_index() == index, false); - } else { - // Tab didn't move, but it's pinned state changed. Notify observers. - FOR_EACH_OBSERVER(TabStripModelObserver, observers_, + // Notify observers of new state. + FOR_EACH_OBSERVER(TabStripModelObserver, observers_, TabPinnedStateChanged(contents_data_[index]->contents, index)); - } } bool TabStripModel::IsTabPinned(int index) const { @@ -396,12 +418,11 @@ bool TabStripModel::IsTabPinned(int index) const { } bool TabStripModel::IsAppTab(int index) const { - // TODO (sky): this is temporary and should be integrated with real apps. - return browser_defaults::kPinnedTabsActLikeApps && IsTabPinned(index); + return GetTabContentsAt(index)->app(); } bool TabStripModel::IsPhantomTab(int index) const { - return IsTabPinned(index) && IsAppTab(index) && + return IsTabPinned(index) && GetTabContentsAt(index)->controller().needs_reload(); } @@ -409,12 +430,12 @@ bool TabStripModel::IsTabBlocked(int index) const { return contents_data_[index]->blocked; } -int TabStripModel::IndexOfFirstNonPinnedTab() const { +int TabStripModel::IndexOfFirstNonAppTab() const { for (size_t i = 0; i < contents_data_.size(); ++i) { - if (!contents_data_[i]->pinned) + if (!contents_data_[i]->contents->app()) return static_cast<int>(i); } - // No pinned tabs. + // No app tabs. return count(); } @@ -519,7 +540,8 @@ bool TabStripModel::IsContextMenuCommandEnabled( switch (command_id) { case CommandNewTab: case CommandCloseTab: - return true; + // Phantom tabs can't be closed. + return !IsPhantomTab(context_index); case CommandReload: if (TabContents* contents = GetTabContentsAt(context_index)) { return contents->delegate()->CanReloadContents(contents); @@ -527,20 +549,24 @@ bool TabStripModel::IsContextMenuCommandEnabled( return false; } case CommandCloseOtherTabs: - return count() > 1; + // Close other doesn't effect app tabs. + return count() > IndexOfFirstNonAppTab(); case CommandCloseTabsToRight: - return context_index < (count() - 1); + // Close doesn't effect app tabs. + return count() != IndexOfFirstNonAppTab() && + context_index < (count() - 1); case CommandCloseTabsOpenedBy: { int next_index = GetIndexOfNextTabContentsOpenedBy( &GetTabContentsAt(context_index)->controller(), context_index, true); - return next_index != kNoTab; + return next_index != kNoTab && !IsAppTab(next_index); } case CommandDuplicate: return delegate_->CanDuplicateContentsAt(context_index); case CommandRestoreTab: return delegate_->CanRestoreTab(); case CommandTogglePinned: - return true; + // Only app tabs can be pinned. + return IsAppTab(context_index); case CommandBookmarkAllTabs: { return delegate_->CanBookmarkAllTabs(); } @@ -575,7 +601,7 @@ void TabStripModel::ExecuteContextMenuCommand( TabContents* contents = GetTabContentsAt(context_index); std::vector<int> closing_tabs; for (int i = count() - 1; i >= 0; --i) { - if (GetTabContentsAt(i) != contents && !IsTabPinned(i)) + if (GetTabContentsAt(i) != contents && !IsAppTab(i)) closing_tabs.push_back(i); } InternalCloseTabs(closing_tabs, true); @@ -585,7 +611,7 @@ void TabStripModel::ExecuteContextMenuCommand( UserMetrics::RecordAction("TabContextMenu_CloseTabsToRight", profile_); std::vector<int> closing_tabs; for (int i = count() - 1; i > context_index; --i) { - if (!IsTabPinned(i)) + if (!IsAppTab(i)) closing_tabs.push_back(i); } InternalCloseTabs(closing_tabs, true); @@ -596,7 +622,7 @@ void TabStripModel::ExecuteContextMenuCommand( std::vector<int> closing_tabs = GetIndexesOpenedBy(context_index); for (std::vector<int>::iterator i = closing_tabs.begin(); i != closing_tabs.end();) { - if (IsTabPinned(*i)) + if (IsAppTab(*i)) i = closing_tabs.erase(i); else ++i; @@ -736,43 +762,6 @@ bool TabStripModel::InternalCloseTabs(std::vector<int> indices, return retval; } -void TabStripModel::MoveTabContentsAtImpl(int index, int to_position, - bool select_after_move, - bool update_pinned_state) { - DCHECK(ContainsIndex(index)); - if (index == to_position) - return; - - bool pinned_state_changed = !update_pinned_state; - - if (update_pinned_state) { - bool is_pinned = IsTabPinned(index); - if (is_pinned && to_position >= IndexOfFirstNonPinnedTab()) { - contents_data_[index]->pinned = false; - } else if (!is_pinned && to_position < IndexOfFirstNonPinnedTab()) { - contents_data_[index]->pinned = true; - } - pinned_state_changed = is_pinned != contents_data_[index]->pinned; - } - - TabContentsData* moved_data = contents_data_.at(index); - contents_data_.erase(contents_data_.begin() + index); - contents_data_.insert(contents_data_.begin() + to_position, moved_data); - - // if !select_after_move, keep the same tab selected as was selected before. - if (select_after_move || index == selected_index_) { - selected_index_ = to_position; - } else if (index < selected_index_ && to_position >= selected_index_) { - selected_index_--; - } else if (index > selected_index_ && to_position <= selected_index_) { - selected_index_++; - } - - FOR_EACH_OBSERVER(TabStripModelObserver, observers_, - TabMoved(moved_data->contents, index, to_position, - pinned_state_changed)); -} - TabContents* TabStripModel::GetContentsAt(int index) const { CHECK(ContainsIndex(index)) << "Failed to find: " << index << " in: " << count() << " entries."; @@ -815,8 +804,7 @@ void TabStripModel::SelectRelativeTab(bool next) { int delta = next ? 1 : -1; do { index = (index + count() + delta) % count(); - } while (index != selected_index_ && IsTabPinned(index) && IsAppTab(index) && - IsPhantomTab(index)); + } while (index != selected_index_ && IsPhantomTab(index)); SelectTabContentsAt(index, true); } diff --git a/chrome/browser/tabs/tab_strip_model.h b/chrome/browser/tabs/tab_strip_model.h index 788aaa3..24eb20e 100644 --- a/chrome/browser/tabs/tab_strip_model.h +++ b/chrome/browser/tabs/tab_strip_model.h @@ -59,21 +59,21 @@ class TabStripModelObserver { // (selected). virtual void TabInsertedAt(TabContents* contents, int index, - bool foreground) { } + bool foreground) {} // The specified TabContents at |index| is being closed (and eventually // destroyed). - virtual void TabClosingAt(TabContents* contents, int index) { } + virtual void TabClosingAt(TabContents* contents, int index) {} // The specified TabContents at |index| is being detached, perhaps to be // inserted in another TabStripModel. The implementer should take whatever // action is necessary to deal with the TabContents no longer being present. - virtual void TabDetachedAt(TabContents* contents, int index) { } + virtual void TabDetachedAt(TabContents* contents, int index) {} // The selected TabContents is about to change from |old_contents| at |index|. // This gives observers a chance to prepare for an impending switch before it // happens. - virtual void TabDeselectedAt(TabContents* contents, int index) { } + virtual void TabDeselectedAt(TabContents* contents, int index) {} // The selected TabContents changed from |old_contents| to |new_contents| at // |index|. |user_gesture| specifies whether or not this was done by a user @@ -82,14 +82,12 @@ class TabStripModelObserver { virtual void TabSelectedAt(TabContents* old_contents, TabContents* new_contents, int index, - bool user_gesture) { } + bool user_gesture) {} - // The specified TabContents at |from_index| was moved to |to_index|. If - // the pinned state of the tab is changing |pinned_state_changed| is true. + // The specified TabContents at |from_index| was moved to |to_index|. virtual void TabMoved(TabContents* contents, int from_index, - int to_index, - bool pinned_state_changed) { } + int to_index) {} // The specified TabContents at |index| changed in some way. |contents| may // be an entirely different object and the old value is no longer available @@ -106,15 +104,12 @@ class TabStripModelObserver { TabContents* new_contents, int index) {} // Invoked when the pinned state of a tab changes. - // NOTE: this is only invoked if the tab doesn't move as a result of its - // pinned state changing. If the tab moves as a result, the observer is - // notified by way of the TabMoved method with |pinned_state_changed| true. - virtual void TabPinnedStateChanged(TabContents* contents, int index) { } + virtual void TabPinnedStateChanged(TabContents* contents, int index) {} // Invoked when the blocked state of a tab changes. // NOTE: This is invoked when a tab becomes blocked/unblocked by a tab modal // window. - virtual void TabBlockedStateChanged(TabContents* contents, int index) { } + virtual void TabBlockedStateChanged(TabContents* contents, int index) {} // The TabStripModel now no longer has any phantom tabs. The implementer may // use this as a trigger to try and close the window containing the @@ -234,22 +229,20 @@ class TabStripModelDelegate { // tasks like adding new Tabs from just a URL, etc. // // Each tab may be any one of the following states: -// . Pinned. The view typically renders pinned tabs differently. The model makes -// sure all pinned tabs are organized at the beginning of the tabstrip. -// Inserting a tab between pinned tabs implicitly makes the inserted tab -// pinned. Similarly moving a tab may pin or unpin the tab, again enforcing -// that all pinned tabs occur at the beginning of the tabstrip. Lastly, -// changing the pinned state of a tab moves the tab to be grouped with the -// pinned or unpinned tabs. For example, if the first two tabs are pinned, and -// the tenth tab is pinned, it is moved to become the third tab. -// . App. An app tab corresponds to an app extension. -// . Phantom. Only pinned app tabs may be made phantom (or if -// browser_defaults::kPinnedTabsActLikeApps is true then any pinned tab may be -// made phantom). When a tab that can be made phantom is closed the renderer -// is shutdown, a new TabContents/NavigationController is created that has -// not yet loaded the renderer and observers are notified via the -// TabReplacedAt method. When a phantom tab is selected the renderer is -// loaded and the tab is no longer phantom. +// . App. Corresponds to an extension that wants an app tab. App tabs are +// rendered differently than non-app tabs. The model makes sure all app tabs +// are at the beginning of the tab strip. Requests to insert a non-app tab +// before app tabs or an app tab after the app tabs is ignored (the UI +// disallows this). Similarly requests to move an app tab to be with non-app +// tabs is ignored. +// . Pinned. Only app tabs can be pinned. A pinned tab is made phantom when +/// closed. +// . Phantom. Only app pinned tabs may be made phantom. When a tab that can be +// made phantom is closed the renderer is shutdown, a new +// TabContents/NavigationController is created that has not yet loaded the +// renderer and observers are notified via the TabReplacedAt method. When a +// phantom tab is selected the renderer is loaded and the tab is no longer +// phantom. // Phantom tabs do not prevent the tabstrip from closing, for example if the // tabstrip has one phantom and one non-phantom tab and the non-phantom tab is // closed, then the tabstrip/browser are closed. @@ -326,8 +319,8 @@ class TabStripModel : public NotificationObserver { // Adds the specified TabContents in the specified location. If // |inherit_group| is true, the new contents is linked to the current tab's - // group. If there are pinned tabs at or before |index|, then the newly - // inserted tab is pinned. + // group. This adjusts the index such that all app tabs occur before non-app + // tabs. void InsertTabContentsAt(int index, TabContents* contents, bool foreground, @@ -369,7 +362,8 @@ class TabStripModel : public NotificationObserver { // If |select_after_move| is false, whatever tab was selected before the move // will still be selected, but it's index may have incremented or decremented // one slot. - // See class description for how pinning is effected by this. + // NOTE: this does nothing if the move would result in app tabs and non-app + // tabs mixing. void MoveTabContentsAt(int index, int to_position, bool select_after_move); // Returns the currently selected TabContents, or NULL if there is none. @@ -456,25 +450,24 @@ class TabStripModel : public NotificationObserver { void SetTabPinned(int index, bool pinned); // Returns true if the tab at |index| is pinned. + // See description above class for details on pinned tabs. bool IsTabPinned(int index) const; // Is the tab at |index| an app? - // See description above class for details on this. - // This is currently only true if browser_defaults::kPinnedTabsActLikeApps is - // true and the tab is pinned. + // See description above class for details on app tabs. bool IsAppTab(int index) const; // Returns true if the tab is a phantom tab. A phantom tab is one where the // renderer has not been loaded. - // See description above class for details on this. + // See description above class for details on phantom tabs. bool IsPhantomTab(int index) const; // Returns true if the tab at |index| is blocked by a tab modal dialog. bool IsTabBlocked(int index) const; - // Returns the index of the first tab that is not pinned. This returns - // |count()| if all of the tabs are pinned, and 0 if no tabs are pinned. - int IndexOfFirstNonPinnedTab() const; + // Returns the index of the first tab that is not an app. This returns + // |count()| if all of the tabs are apps, and 0 if none of the tabs are apps. + int IndexOfFirstNonAppTab() const; // Command level API ///////////////////////////////////////////////////////// @@ -575,10 +568,6 @@ class TabStripModel : public NotificationObserver { bool InternalCloseTabs(std::vector<int> indices, bool create_historical_tabs); - void MoveTabContentsAtImpl(int index, int to_position, - bool select_after_move, - bool update_pinned_state); - TabContents* GetContentsAt(int index) const; // The actual implementation of SelectTabContentsAt. Takes the previously @@ -669,6 +658,7 @@ class TabStripModel : public NotificationObserver { bool reset_group_on_select; // Is the tab pinned? + // TODO(sky): decide if we really want this, or call it phantomable. bool pinned; // Is the tab interaction blocked by a modal dialog? diff --git a/chrome/browser/tabs/tab_strip_model_order_controller.cc b/chrome/browser/tabs/tab_strip_model_order_controller.cc index de0ab23..36db14a7 100644 --- a/chrome/browser/tabs/tab_strip_model_order_controller.cc +++ b/chrome/browser/tabs/tab_strip_model_order_controller.cc @@ -24,17 +24,17 @@ int TabStripModelOrderController::DetermineInsertionIndex( PageTransition::Type transition, bool foreground) { int tab_count = tabstrip_->count(); - int first_non_pinned_tab = tabstrip_->IndexOfFirstNonPinnedTab(); if (!tab_count) return 0; + int first_non_app_tab = tabstrip_->IndexOfFirstNonAppTab(); if (transition == PageTransition::LINK && tabstrip_->selected_index() != -1) { if (foreground) { // If the page was opened in the foreground by a link click in another // tab, insert it adjacent to the tab that opened that link. // TODO(beng): (http://b/1085481) may want to open right of all locked // tabs? - return std::max(first_non_pinned_tab, + return std::max(first_non_app_tab, tabstrip_->selected_index() + 1); } NavigationController* opener = @@ -46,7 +46,7 @@ int TabStripModelOrderController::DetermineInsertionIndex( if (index != TabStripModel::kNoTab) return index + 1; // Otherwise insert adjacent to opener... - return std::max(first_non_pinned_tab, tabstrip_->selected_index() + 1); + return std::max(first_non_app_tab, tabstrip_->selected_index() + 1); } // In other cases, such as Ctrl+T, open at the end of the strip. return tab_count; diff --git a/chrome/browser/tabs/tab_strip_model_unittest.cc b/chrome/browser/tabs/tab_strip_model_unittest.cc index 00afd03..7330a41 100644 --- a/chrome/browser/tabs/tab_strip_model_unittest.cc +++ b/chrome/browser/tabs/tab_strip_model_unittest.cc @@ -137,6 +137,9 @@ class TabStripModelTest : public RenderViewHostTestHarness { actual += IntToString(GetID(model.GetTabContentsAt(i))); + if (model.IsAppTab(i)) + actual += "a"; + if (model.IsTabPinned(i)) actual += "p"; } @@ -248,11 +251,9 @@ class MockTabStripModelObserver : public TabStripModelObserver { states_.push_back(s); } virtual void TabMoved( - TabContents* contents, int from_index, int to_index, - bool pinned_state_changed) { + TabContents* contents, int from_index, int to_index) { State* s = new State(contents, to_index, MOVE); s->src_index = from_index; - s->pinned_state_changed = pinned_state_changed; states_.push_back(s); } @@ -1278,8 +1279,65 @@ TEST_F(TabStripModelTest, NavigationForgettingDoesntAffectNewTab) { strip.CloseAllTabs(); } -// Tests various permutations of pinning tabs. -TEST_F(TabStripModelTest, Pinning) { +// Tests that fast shutdown is attempted appropriately. +TEST_F(TabStripModelTest, FastShutdown) { + TabStripDummyDelegate delegate(NULL); + TabStripModel tabstrip(&delegate, profile()); + MockTabStripModelObserver observer; + tabstrip.AddObserver(&observer); + + EXPECT_TRUE(tabstrip.empty()); + + // Make sure fast shutdown is attempted when tabs that share a RPH are shut + // down. + { + TabContents* contents1 = CreateTabContents(); + TabContents* contents2 = CreateTabContentsWithSharedRPH(contents1); + + SetID(contents1, 1); + SetID(contents2, 2); + + tabstrip.AppendTabContents(contents1, true); + tabstrip.AppendTabContents(contents2, true); + + // Turn on the fake unload listener so the tabs don't actually get shut + // down when we call CloseAllTabs()---we need to be able to check that + // fast shutdown was attempted. + delegate.set_run_unload_listener(true); + tabstrip.CloseAllTabs(); + // On a mock RPH this checks whether we *attempted* fast shutdown. + // A real RPH would reject our attempt since there is an unload handler. + EXPECT_TRUE(contents1->process()->fast_shutdown_started()); + EXPECT_EQ(2, tabstrip.count()); + + delegate.set_run_unload_listener(false); + tabstrip.CloseAllTabs(); + EXPECT_TRUE(tabstrip.empty()); + } + + // Make sure fast shutdown is not attempted when only some tabs that share a + // RPH are shut down. + { + TabContents* contents1 = CreateTabContents(); + TabContents* contents2 = CreateTabContentsWithSharedRPH(contents1); + + SetID(contents1, 1); + SetID(contents2, 2); + + tabstrip.AppendTabContents(contents1, true); + tabstrip.AppendTabContents(contents2, true); + + tabstrip.CloseTabContentsAt(1); + EXPECT_FALSE(contents1->process()->fast_shutdown_started()); + EXPECT_EQ(1, tabstrip.count()); + + tabstrip.CloseAllTabs(); + EXPECT_TRUE(tabstrip.empty()); + } +} + +// Tests various permutations of apps. +TEST_F(TabStripModelTest, Apps) { TabStripDummyDelegate delegate(NULL); TabStripModel tabstrip(&delegate, profile()); MockTabStripModelObserver observer; @@ -1290,7 +1348,9 @@ TEST_F(TabStripModelTest, Pinning) { typedef MockTabStripModelObserver::State State; TabContents* contents1 = CreateTabContents(); + contents1->set_app(true); TabContents* contents2 = CreateTabContents(); + contents2->set_app(true); TabContents* contents3 = CreateTabContents(); SetID(contents1, 1); @@ -1301,242 +1361,95 @@ TEST_F(TabStripModelTest, Pinning) { // builds on the state established in the previous. This is important if you // ever insert tests rather than append. - // Initial state, three tabs, first selected. - tabstrip.AppendTabContents(contents1, true); - tabstrip.AppendTabContents(contents2, false); - tabstrip.AppendTabContents(contents3, false); + // Initial state, tab3 only and selected. + tabstrip.AppendTabContents(contents3, true); observer.ClearStates(); - // Pin the first tab, this shouldn't visually reorder anything. - { - tabstrip.SetTabPinned(0, true); - - // As the order didn't change, we should get a pinned notification. - ASSERT_EQ(1, observer.GetStateCount()); - State state(contents1, 0, MockTabStripModelObserver::PINNED); - EXPECT_TRUE(observer.StateEquals(0, state)); - - // And verify the state. - EXPECT_EQ("1p 2 3", GetPinnedState(tabstrip)); - - observer.ClearStates(); - } - - // Unpin the first tab. - { - tabstrip.SetTabPinned(0, false); - - // As the order didn't change, we should get a pinned notification. - ASSERT_EQ(1, observer.GetStateCount()); - State state(contents1, 0, MockTabStripModelObserver::PINNED); - EXPECT_TRUE(observer.StateEquals(0, state)); - - // And verify the state. - EXPECT_EQ("1 2 3", GetPinnedState(tabstrip)); - - observer.ClearStates(); - } - - // Pin the 3rd tab, which should move it to the front. + // Attempt to insert tab1 (an app tab) at position 1. This isn't a legal + // position and tab1 should end up at position 0. { - tabstrip.SetTabPinned(2, true); + tabstrip.InsertTabContentsAt(1, contents1, false, false); - // The pinning should have resulted in a move. ASSERT_EQ(1, observer.GetStateCount()); - State state(contents3, 0, MockTabStripModelObserver::MOVE); - state.src_index = 2; - state.pinned_state_changed = true; + State state(contents1, 0, MockTabStripModelObserver::INSERT); EXPECT_TRUE(observer.StateEquals(0, state)); // And verify the state. - EXPECT_EQ("3p 1 2", GetPinnedState(tabstrip)); + EXPECT_EQ("1a 3", GetPinnedState(tabstrip)); observer.ClearStates(); } - // Pin the tab "1", which shouldn't move anything. + // Insert tab 2 at position 1. { - tabstrip.SetTabPinned(1, true); + tabstrip.InsertTabContentsAt(1, contents2, false, false); - // As the order didn't change, we should get a pinned notification. ASSERT_EQ(1, observer.GetStateCount()); - State state(contents1, 1, MockTabStripModelObserver::PINNED); + State state(contents2, 1, MockTabStripModelObserver::INSERT); EXPECT_TRUE(observer.StateEquals(0, state)); // And verify the state. - EXPECT_EQ("3p 1p 2", GetPinnedState(tabstrip)); + EXPECT_EQ("1a 2a 3", GetPinnedState(tabstrip)); observer.ClearStates(); } - // Move tab "2" to the front, which should pin it. + // Try to move tab 3 to position 0. This isn't legal and should be ignored. { tabstrip.MoveTabContentsAt(2, 0, false); - // As the order didn't change, we should get a pinned notification. - ASSERT_EQ(1, observer.GetStateCount()); - State state(contents2, 0, MockTabStripModelObserver::MOVE); - state.src_index = 2; - state.pinned_state_changed = true; - EXPECT_TRUE(observer.StateEquals(0, state)); + ASSERT_EQ(0, observer.GetStateCount()); - // And verify the state. - EXPECT_EQ("2p 3p 1p", GetPinnedState(tabstrip)); + // And verify the state didn't change. + EXPECT_EQ("1a 2a 3", GetPinnedState(tabstrip)); observer.ClearStates(); } - // Unpin tab "2", which implicitly moves it to the end. + // Try to move tab 0 to position 3. This isn't legal and should be ignored. { - tabstrip.SetTabPinned(0, false); + tabstrip.MoveTabContentsAt(0, 2, false); - ASSERT_EQ(1, observer.GetStateCount()); - State state(contents2, 2, MockTabStripModelObserver::MOVE); - state.src_index = 0; - state.pinned_state_changed = true; - EXPECT_TRUE(observer.StateEquals(0, state)); + ASSERT_EQ(0, observer.GetStateCount()); - // And verify the state. - EXPECT_EQ("3p 1p 2", GetPinnedState(tabstrip)); + // And verify the state didn't change. + EXPECT_EQ("1a 2a 3", GetPinnedState(tabstrip)); observer.ClearStates(); } - // Drag tab "3" to after "1', which should not change the pinned state. + // Try to move tab 0 to position 1. This is a legal move. { tabstrip.MoveTabContentsAt(0, 1, false); ASSERT_EQ(1, observer.GetStateCount()); - State state(contents3, 1, MockTabStripModelObserver::MOVE); + State state(contents1, 1, MockTabStripModelObserver::MOVE); state.src_index = 0; EXPECT_TRUE(observer.StateEquals(0, state)); - // And verify the state. - EXPECT_EQ("1p 3p 2", GetPinnedState(tabstrip)); + // And verify the state didn't change. + EXPECT_EQ("2a 1a 3", GetPinnedState(tabstrip)); observer.ClearStates(); } - // Unpin tab "1". + // Remove tab3 and insert at position 0. It should be forced to position 2. { - tabstrip.SetTabPinned(0, false); - - ASSERT_EQ(1, observer.GetStateCount()); - State state(contents1, 1, MockTabStripModelObserver::MOVE); - state.src_index = 0; - state.pinned_state_changed = true; - EXPECT_TRUE(observer.StateEquals(0, state)); - - // And verify the state. - EXPECT_EQ("3p 1 2", GetPinnedState(tabstrip)); - + tabstrip.DetachTabContentsAt(2); observer.ClearStates(); - } - // Unpin tab "3". - { - tabstrip.SetTabPinned(0, false); + tabstrip.InsertTabContentsAt(0, contents3, false, false); ASSERT_EQ(1, observer.GetStateCount()); - State state(contents3, 0, MockTabStripModelObserver::PINNED); + State state(contents3, 2, MockTabStripModelObserver::INSERT); EXPECT_TRUE(observer.StateEquals(0, state)); - EXPECT_EQ("3 1 2", GetPinnedState(tabstrip)); - - observer.ClearStates(); - } - - // Unpin tab "3" again, as it's unpinned nothing should change. - { - tabstrip.SetTabPinned(0, false); - - ASSERT_EQ(0, observer.GetStateCount()); - - EXPECT_EQ("3 1 2", GetPinnedState(tabstrip)); - } - - // Pin "3" and "1". - { - tabstrip.SetTabPinned(0, true); - tabstrip.SetTabPinned(1, true); - - EXPECT_EQ("3p 1p 2", GetPinnedState(tabstrip)); + // And verify the state didn't change. + EXPECT_EQ("2a 1a 3", GetPinnedState(tabstrip)); observer.ClearStates(); } - TabContents* contents4 = CreateTabContents(); - SetID(contents4, 4); - - // Insert "4" between "3" and "1". As "3" and "1" are pinned, "4" should - // be pinned too. - { - tabstrip.InsertTabContentsAt(1, contents4, false, false); - - ASSERT_EQ(1, observer.GetStateCount()); - State state(contents4, 1, MockTabStripModelObserver::INSERT); - EXPECT_TRUE(observer.StateEquals(0, state)); - - EXPECT_EQ("3p 4p 1p 2", GetPinnedState(tabstrip)); - } - tabstrip.CloseAllTabs(); } - -// Tests that fast shutdown is attempted appropriately. -TEST_F(TabStripModelTest, FastShutdown) { - TabStripDummyDelegate delegate(NULL); - TabStripModel tabstrip(&delegate, profile()); - MockTabStripModelObserver observer; - tabstrip.AddObserver(&observer); - - EXPECT_TRUE(tabstrip.empty()); - - // Make sure fast shutdown is attempted when tabs that share a RPH are shut - // down. - { - TabContents* contents1 = CreateTabContents(); - TabContents* contents2 = CreateTabContentsWithSharedRPH(contents1); - - SetID(contents1, 1); - SetID(contents2, 2); - - tabstrip.AppendTabContents(contents1, true); - tabstrip.AppendTabContents(contents2, true); - - // Turn on the fake unload listener so the tabs don't actually get shut - // down when we call CloseAllTabs()---we need to be able to check that - // fast shutdown was attempted. - delegate.set_run_unload_listener(true); - tabstrip.CloseAllTabs(); - // On a mock RPH this checks whether we *attempted* fast shutdown. - // A real RPH would reject our attempt since there is an unload handler. - EXPECT_TRUE(contents1->process()->fast_shutdown_started()); - EXPECT_EQ(2, tabstrip.count()); - - delegate.set_run_unload_listener(false); - tabstrip.CloseAllTabs(); - EXPECT_TRUE(tabstrip.empty()); - } - - // Make sure fast shutdown is not attempted when only some tabs that share a - // RPH are shut down. - { - TabContents* contents1 = CreateTabContents(); - TabContents* contents2 = CreateTabContentsWithSharedRPH(contents1); - - SetID(contents1, 1); - SetID(contents2, 2); - - tabstrip.AppendTabContents(contents1, true); - tabstrip.AppendTabContents(contents2, true); - - tabstrip.CloseTabContentsAt(1); - EXPECT_FALSE(contents1->process()->fast_shutdown_started()); - EXPECT_EQ(1, tabstrip.count()); - - tabstrip.CloseAllTabs(); - EXPECT_TRUE(tabstrip.empty()); - } -} diff --git a/chrome/browser/views/tabs/dragged_tab_controller.cc b/chrome/browser/views/tabs/dragged_tab_controller.cc index e354e56..04c0a1b 100644 --- a/chrome/browser/views/tabs/dragged_tab_controller.cc +++ b/chrome/browser/views/tabs/dragged_tab_controller.cc @@ -681,8 +681,7 @@ void DraggedTabController::MoveTab(const gfx::Point& screen_point) { if (!view_->pinned()) { // If the dragged tab isn't pinned, don't allow the drag to a pinned // tab. - to_index = - std::max(to_index, attached_model->IndexOfFirstNonPinnedTab()); + to_index = std::max(to_index, attached_model->IndexOfFirstNonAppTab()); } if (from_index != to_index) { last_move_screen_x_ = screen_point.x(); @@ -745,8 +744,8 @@ void DraggedTabController::StartPinTimerIfNecessary( return; TabStripModel* attached_model = attached_tabstrip_->model(); - int pinned_count = attached_model->IndexOfFirstNonPinnedTab(); - if (pinned_count > 0) + int app_count = attached_model->IndexOfFirstNonAppTab(); + if (app_count > 0) return; int index = attached_model->GetIndexOfTabContents(dragged_contents_); @@ -768,7 +767,7 @@ void DraggedTabController::AdjustDragPointForPinnedTabs( int* from_index, gfx::Point* dragged_tab_point) { TabStripModel* attached_model = attached_tabstrip_->model(); - int pinned_count = attached_model->IndexOfFirstNonPinnedTab(); + int pinned_count = attached_model->IndexOfFirstNonAppTab(); if (pinned_count == 0) return; @@ -982,7 +981,7 @@ void DraggedTabController::Detach() { } int DraggedTabController::GetPinnedThreshold() { - int pinned_count = attached_tabstrip_->model()->IndexOfFirstNonPinnedTab(); + int pinned_count = attached_tabstrip_->model()->IndexOfFirstNonAppTab(); if (pinned_count == 0) return 0; if (!view_->pinned()) { diff --git a/chrome/browser/views/tabs/tab_overview_controller.cc b/chrome/browser/views/tabs/tab_overview_controller.cc index 3e791d6..4422d85 100644 --- a/chrome/browser/views/tabs/tab_overview_controller.cc +++ b/chrome/browser/views/tabs/tab_overview_controller.cc @@ -253,8 +253,7 @@ void TabOverviewController::TabDetachedAt(TabContents* contents, int index) { void TabOverviewController::TabMoved(TabContents* contents, int from_index, - int to_index, - bool pinned_state_changed) { + int to_index) { if (!grid_->modifying_model()) grid_->CancelDrag(); diff --git a/chrome/browser/views/tabs/tab_overview_controller.h b/chrome/browser/views/tabs/tab_overview_controller.h index 4fc2cf8..3110f7d 100644 --- a/chrome/browser/views/tabs/tab_overview_controller.h +++ b/chrome/browser/views/tabs/tab_overview_controller.h @@ -90,8 +90,7 @@ class TabOverviewController : public TabStripModelObserver { virtual void TabDetachedAt(TabContents* contents, int index); virtual void TabMoved(TabContents* contents, int from_index, - int to_index, - bool pinned_state_changed); + int to_index); virtual void TabChangedAt(TabContents* contents, int index, TabChangeType change_type); virtual void TabStripEmpty(); diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc index 5dc8a49..69af0895 100644 --- a/chrome/browser/views/tabs/tab_strip.cc +++ b/chrome/browser/views/tabs/tab_strip.cc @@ -52,7 +52,6 @@ using views::DropTargetEvent; static const int kDefaultAnimationDurationMs = 200; static const int kResizeLayoutAnimationDurationMs = 200; static const int kReorderAnimationDurationMs = 200; -static const int kPinnedTabAnimationDurationMs = 200; static const int kNewTabButtonHOffset = -5; static const int kNewTabButtonVOffset = 5; @@ -129,8 +128,6 @@ class TabStrip::TabAnimation : public AnimationDelegate { REMOVE, MOVE, RESIZE, - PIN, - PIN_MOVE }; TabAnimation(TabStrip* tabstrip, Type type) @@ -558,164 +555,6 @@ class TabStrip::ResizeLayoutAnimation : public TabStrip::TabAnimation { DISALLOW_COPY_AND_ASSIGN(ResizeLayoutAnimation); }; -//////////////////////////////////////////////////////////////////////////////// - -// Handles a tabs pinned state changing while the tab does not change position -// in the model. -class TabStrip::PinnedTabAnimation : public TabStrip::TabAnimation { - public: - explicit PinnedTabAnimation(TabStrip* tabstrip, int index) - : TabAnimation(tabstrip, PIN), - index_(index) { - int tab_count = tabstrip->GetTabCount(); - int start_pinned_count = tabstrip->GetPinnedTabCount(); - int end_pinned_count = start_pinned_count; - if (tabstrip->GetTabAt(index)->pinned()) - start_pinned_count--; - else - start_pinned_count++; - tabstrip_->GetTabAt(index)->set_animating_pinned_change(true); - GenerateStartAndEndWidths(tab_count, tab_count, start_pinned_count, - end_pinned_count); - } - - protected: - // Overridden from TabStrip::TabAnimation: - virtual int GetDuration() const { - return kPinnedTabAnimationDurationMs; - } - - virtual double GetWidthForTab(int index) const { - Tab* tab = tabstrip_->GetTabAt(index); - - if (index == index_) { - if (tab->pinned()) { - return AnimationPosition( - start_selected_width_, - static_cast<double>(Tab::GetPinnedWidth())); - } else { - return AnimationPosition(static_cast<double>(Tab::GetPinnedWidth()), - end_selected_width_); - } - } else if (tab->pinned()) { - return Tab::GetPinnedWidth(); - } - - if (tab->IsSelected()) - return AnimationPosition(start_selected_width_, end_selected_width_); - - return AnimationPosition(start_unselected_width_, end_unselected_width_); - } - - private: - // Index of the tab whose pinned state changed. - int index_; - - DISALLOW_COPY_AND_ASSIGN(PinnedTabAnimation); -}; - -//////////////////////////////////////////////////////////////////////////////// - -// Handles the animation when a tabs pinned state changes and the tab moves as a -// result. -class TabStrip::PinAndMoveAnimation : public TabStrip::TabAnimation { - public: - explicit PinAndMoveAnimation(TabStrip* tabstrip, - int from_index, - int to_index, - const gfx::Rect& start_bounds) - : TabAnimation(tabstrip, PIN_MOVE), - tab_(tabstrip->GetTabAt(to_index)), - start_bounds_(start_bounds), - from_index_(from_index), - to_index_(to_index) { - int tab_count = tabstrip->GetTabCount(); - int start_pinned_count = tabstrip->GetPinnedTabCount(); - int end_pinned_count = start_pinned_count; - if (tabstrip->GetTabAt(to_index)->pinned()) - start_pinned_count--; - else - start_pinned_count++; - GenerateStartAndEndWidths(tab_count, tab_count, start_pinned_count, - end_pinned_count); - target_bounds_ = tabstrip->GetIdealBounds(to_index); - tab_->set_animating_pinned_change(true); - } - - // Overridden from AnimationDelegate: - virtual void AnimationProgressed(const Animation* animation) { - // Do the normal layout. - TabAnimation::AnimationProgressed(animation); - - // Then special case the position of the tab being moved. - int x = AnimationPosition(start_bounds_.x(), target_bounds_.x()); - int width = AnimationPosition(start_bounds_.width(), - target_bounds_.width()); - gfx::Rect tab_bounds(x, start_bounds_.y(), width, - start_bounds_.height()); - tab_->SetBounds(tab_bounds); - } - - virtual void AnimationEnded(const Animation* animation) { - tabstrip_->needs_resize_layout_ = false; - TabStrip::TabAnimation::AnimationEnded(animation); - } - - virtual double GetGapWidth(int index) { - if (to_index_ < from_index_) { - // The tab was pinned. - if (index == to_index_) { - double current_size = AnimationPosition(0, target_bounds_.width()); - if (current_size < -kTabHOffset) - return -(current_size + kTabHOffset); - } else if (index == from_index_ + 1) { - return AnimationPosition(start_bounds_.width(), 0); - } - } else { - // The tab was unpinned. - if (index == from_index_) { - return AnimationPosition(Tab::GetPinnedWidth() + kTabHOffset, 0); - } - } - return 0; - } - - protected: - // Overridden from TabStrip::TabAnimation: - virtual int GetDuration() const { return kReorderAnimationDurationMs; } - - virtual double GetWidthForTab(int index) const { - Tab* tab = tabstrip_->GetTabAt(index); - - if (index == to_index_) - return AnimationPosition(0, target_bounds_.width()); - - if (tab->pinned()) - return Tab::GetPinnedWidth(); - - if (tab->IsSelected()) - return AnimationPosition(start_selected_width_, end_selected_width_); - - return AnimationPosition(start_unselected_width_, end_unselected_width_); - } - - private: - // The tab being moved. - Tab* tab_; - - // Initial bounds of tab_. - gfx::Rect start_bounds_; - - // Target bounds. - gfx::Rect target_bounds_; - - // Start and end indices of the tab. - int from_index_; - int to_index_; - - DISALLOW_COPY_AND_ASSIGN(PinAndMoveAnimation); -}; - /////////////////////////////////////////////////////////////////////////////// // TabStrip, public: @@ -1158,8 +997,7 @@ void TabStrip::TabSelectedAt(TabContents* old_contents, GetTabAt(old_index)->StopPinnedTabTitleAnimation(); } -void TabStrip::TabMoved(TabContents* contents, int from_index, int to_index, - bool pinned_state_changed) { +void TabStrip::TabMoved(TabContents* contents, int from_index, int to_index) { gfx::Rect start_bounds = GetIdealBounds(from_index); Tab* tab = GetTabAt(from_index); tab_data_.erase(tab_data_.begin() + from_index); @@ -1169,12 +1007,8 @@ void TabStrip::TabMoved(TabContents* contents, int from_index, int to_index, tab_data_.insert(tab_data_.begin() + to_index, data); if (tab->phantom() != model_->IsPhantomTab(to_index)) tab->set_phantom(!tab->phantom()); - if (pinned_state_changed) { - StartPinAndMoveTabAnimation(from_index, to_index, start_bounds); - } else { - GenerateIdealBounds(); - StartMoveTabAnimation(from_index, to_index); - } + GenerateIdealBounds(); + StartMoveTabAnimation(from_index, to_index); } void TabStrip::TabChangedAt(TabContents* contents, int index, @@ -1201,7 +1035,6 @@ void TabStrip::TabReplacedAt(TabContents* old_contents, void TabStrip::TabPinnedStateChanged(TabContents* contents, int index) { GetTabAt(index)->set_pinned(model_->IsTabPinned(index)); - StartPinnedTabAnimation(index); } void TabStrip::TabBlockedStateChanged(TabContents* contents, int index) { @@ -1894,23 +1727,6 @@ void TabStrip::StartMoveTabAnimation(int from_index, int to_index) { active_animation_->Start(); } -void TabStrip::StartPinnedTabAnimation(int index) { - if (active_animation_.get()) - active_animation_->Stop(); - active_animation_.reset(new PinnedTabAnimation(this, index)); - active_animation_->Start(); -} - -void TabStrip::StartPinAndMoveTabAnimation(int from_index, - int to_index, - const gfx::Rect& start_bounds) { - if (active_animation_.get()) - active_animation_->Stop(); - active_animation_.reset( - new PinAndMoveAnimation(this, from_index, to_index, start_bounds)); - active_animation_->Start(); -} - void TabStrip::FinishAnimation(TabStrip::TabAnimation* animation, bool layout) { active_animation_.reset(NULL); diff --git a/chrome/browser/views/tabs/tab_strip.h b/chrome/browser/views/tabs/tab_strip.h index 309a9f3..e24cc43 100644 --- a/chrome/browser/views/tabs/tab_strip.h +++ b/chrome/browser/views/tabs/tab_strip.h @@ -135,8 +135,7 @@ class TabStrip : public views::View, TabContents* contents, int index, bool user_gesture); - virtual void TabMoved(TabContents* contents, int from_index, int to_index, - bool pinned_state_changed); + virtual void TabMoved(TabContents* contents, int from_index, int to_index); virtual void TabChangedAt(TabContents* contents, int index, TabChangeType change_type); virtual void TabReplacedAt(TabContents* old_contents, @@ -181,8 +180,6 @@ class TabStrip : public views::View, private: class InsertTabAnimation; class MoveTabAnimation; - class PinAndMoveAnimation; - class PinnedTabAnimation; class RemoveTabAnimation; class ResizeLayoutAnimation; class TabAnimation; @@ -190,8 +187,6 @@ class TabStrip : public views::View, friend class DraggedTabController; friend class InsertTabAnimation; friend class MoveTabAnimation; - friend class PinAndMoveAnimation; - friend class PinnedTabAnimation; friend class RemoveTabAnimation; friend class ResizeLayoutAnimation; friend class TabAnimation; @@ -295,9 +290,6 @@ class TabStrip : public views::View, void StartInsertTabAnimation(int index); void StartRemoveTabAnimation(int index, TabContents* contents); void StartMoveTabAnimation(int from_index, int to_index); - void StartPinnedTabAnimation(int index); - void StartPinAndMoveTabAnimation(int from_index, int to_index, - const gfx::Rect& start_bounds); // Notifies the TabStrip that the specified TabAnimation has completed. // Optionally a full Layout will be performed, specified by |layout|. |