summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorkuan@chromium.org <kuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-19 11:23:05 +0000
committerkuan@chromium.org <kuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-19 11:23:05 +0000
commit5ee671febc6bc846bc3127932e9d3e6c26cb9ed9 (patch)
tree9b3d5b5a34cec2e0db431596085a955c947011b1 /chrome/browser
parent02e44ae8d2d94044c1dd317d5dcab61923822cd4 (diff)
downloadchromium_src-5ee671febc6bc846bc3127932e9d3e6c26cb9ed9.zip
chromium_src-5ee671febc6bc846bc3127932e9d3e6c26cb9ed9.tar.gz
chromium_src-5ee671febc6bc846bc3127932e9d3e6c26cb9ed9.tar.bz2
alternate ntp: implement Show/HideBars SearchBox API to reduce jank when showing/hiding bars
this is the chrome side combining melevin@'s renderer parts with my browser parts; gws side is implemented by melevin@. - when suggestions show/hide, bookmark and info bars hide/show respectively; this causes contents to shift up/down respectively, resulting in jank. - to reduce jank, these APIs synchronize the showing/hiding of suggestions in gws with the showing/hiding of bookmark and info bars in browser. - gws sends HideBars() whenever suggestions show, and ShowBars() whenever they close. - browser only obliges when bookmark and/or info bars are enabled and only on NTP and SERP pages, but always fires onbarshidden event for every HideBars() call, so that gws can proceed to show suggestions. BUG=176146,178550,175776 TEST=verify as per bug rpts Review URL: https://chromiumcodereview.appspot.com/12631008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@188994 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/infobars/infobar_container.cc52
-rw-r--r--chrome/browser/infobars/infobar_container.h12
-rw-r--r--chrome/browser/ui/browser.cc53
-rw-r--r--chrome/browser/ui/browser.h11
-rw-r--r--chrome/browser/ui/browser_instant_controller.cc12
-rw-r--r--chrome/browser/ui/browser_instant_controller.h5
-rw-r--r--chrome/browser/ui/cocoa/browser_window_cocoa.h5
-rw-r--r--chrome/browser/ui/cocoa/browser_window_cocoa.mm6
-rw-r--r--chrome/browser/ui/cocoa/tab_contents/instant_overlay_controller_mac.mm25
-rw-r--r--chrome/browser/ui/search/search_delegate.cc7
-rw-r--r--chrome/browser/ui/search/search_delegate.h3
-rw-r--r--chrome/browser/ui/search/search_model.cc57
-rw-r--r--chrome/browser/ui/search/search_model.h39
-rw-r--r--chrome/browser/ui/search/search_model_observer.h9
-rw-r--r--chrome/browser/ui/search/search_tab_helper.cc36
-rw-r--r--chrome/browser/ui/search/search_tab_helper.h12
-rw-r--r--chrome/browser/ui/views/frame/instant_overlay_controller_views.cc26
17 files changed, 250 insertions, 120 deletions
diff --git a/chrome/browser/infobars/infobar_container.cc b/chrome/browser/infobars/infobar_container.cc
index 0dd6371..8ea298f 100644
--- a/chrome/browser/infobars/infobar_container.cc
+++ b/chrome/browser/infobars/infobar_container.cc
@@ -45,17 +45,23 @@ InfoBarContainer::~InfoBarContainer() {
}
void InfoBarContainer::ChangeInfoBarService(InfoBarService* infobar_service) {
- registrar_.RemoveAll();
+ // We have to call HideAllInfoBars() here and not after the early exit below,
+ // to handle the case we're switching from a tab with visible infobars to one
+ // where the SearchModel directs us to hide infobars.
+ HideAllInfoBars();
+
+ infobar_service_ = infobar_service;
+
+ if (search_model_ && !search_model_->top_bars_visible())
+ return;
// Note that HideAllInfoBars() sets |infobars_shown_| to false, because that's
// what the other, Instant-related callers want; but here we actually
// explicitly want to reset this variable to true. So do that after calling
// the function.
- HideAllInfoBars();
infobars_shown_ = true;
infobars_shown_time_ = base::TimeTicks();
- infobar_service_ = infobar_service;
if (infobar_service_) {
content::Source<InfoBarService> source(infobar_service_);
registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
@@ -138,12 +144,8 @@ void InfoBarContainer::RemoveAllInfoBarsForDestruction() {
void InfoBarContainer::Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
- // When infobars are supposed to be hidden, we shouldn't try to hide or show
- // anything in response to any notifications. Once infobars get un-hidden
- // via ChangeInfoBarService(), we'll get the updated set of visible infobars
- // from the InfoBarService.
- if (!infobars_shown_)
- return;
+ // When infobars are hidden, we shouldn't be listening for notifications.
+ DCHECK(infobars_shown_);
switch (type) {
case chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED:
@@ -174,29 +176,17 @@ void InfoBarContainer::Observe(int type,
}
}
-void InfoBarContainer::ModeChanged(const chrome::search::Mode& old_mode,
- const chrome::search::Mode& new_mode) {
- // Hide infobars when showing Instant Extended suggestions.
- if (new_mode.is_search_suggestions()) {
- // If suggestions are being shown on a |DEFAULT| page, delay the hiding
- // until notification that Instant overlay is ready is received via
- // OverlayStateChanged(); this prevents jankiness caused by infobars hiding
- // followed by suggestions appearing.
- if (new_mode.is_origin_default())
- return;
- HideAllInfoBars();
- OnInfoBarStateChanged(false);
- } else {
+void InfoBarContainer::ModelChanged(
+ const chrome::search::SearchModel::State& old_state,
+ const chrome::search::SearchModel::State& new_state) {
+ if (!chrome::search::SearchModel::ShouldChangeTopBarsVisibility(old_state,
+ new_state))
+ return;
+
+ if (new_state.top_bars_visible && !infobars_shown_) {
ChangeInfoBarService(infobar_service_);
infobars_shown_time_ = base::TimeTicks::Now();
- }
-}
-
-void InfoBarContainer::OverlayStateChanged(const InstantOverlayModel& model) {
- // If suggestions are being shown on a |DEFAULT| page, hide the infobars now.
- // See comments for ModeChanged() for explanation.
- if (model.mode().is_search_suggestions() &&
- model.mode().is_origin_default()) {
+ } else if (!new_state.top_bars_visible && infobars_shown_) {
HideAllInfoBars();
OnInfoBarStateChanged(false);
}
@@ -229,6 +219,8 @@ size_t InfoBarContainer::HideInfoBar(InfoBarDelegate* delegate,
}
void InfoBarContainer::HideAllInfoBars() {
+ registrar_.RemoveAll();
+
infobars_shown_ = false;
while (!infobars_.empty()) {
InfoBar* infobar = infobars_.front();
diff --git a/chrome/browser/infobars/infobar_container.h b/chrome/browser/infobars/infobar_container.h
index 896f112..da153a0ea 100644
--- a/chrome/browser/infobars/infobar_container.h
+++ b/chrome/browser/infobars/infobar_container.h
@@ -9,7 +9,6 @@
#include "base/compiler_specific.h"
#include "base/time.h"
-#include "chrome/browser/ui/search/instant_overlay_model_observer.h"
#include "chrome/browser/ui/search/search_model_observer.h"
#include "chrome/common/search_types.h"
#include "content/public/browser/notification_observer.h"
@@ -50,8 +49,7 @@ class SearchModel;
// would re-show the infobars only to instantly animate them closed. The window
// to re-hide infobars without animation is canceled if a tab change occurs.
class InfoBarContainer : public content::NotificationObserver,
- public chrome::search::SearchModelObserver,
- public InstantOverlayModelObserver {
+ public chrome::search::SearchModelObserver {
public:
class Delegate {
public:
@@ -110,9 +108,6 @@ class InfoBarContainer : public content::NotificationObserver,
const Delegate* delegate() const { return delegate_; }
- // InstantOverlayModelObserver:
- virtual void OverlayStateChanged(const InstantOverlayModel& model) OVERRIDE;
-
protected:
// Subclasses must call this during destruction, so that we can remove
// infobars (which will call the pure virtual functions below) while the
@@ -135,8 +130,9 @@ class InfoBarContainer : public content::NotificationObserver,
const content::NotificationDetails& details) OVERRIDE;
// chrome::search::SearchModelObserver:
- virtual void ModeChanged(const chrome::search::Mode& old_mode,
- const chrome::search::Mode& new_mode) OVERRIDE;
+ virtual void ModelChanged(
+ const chrome::search::SearchModel::State& old_state,
+ const chrome::search::SearchModel::State& new_state) OVERRIDE;
// Hides an InfoBar for the specified delegate, in response to a notification
// from the selected InfoBarService. The InfoBar's disappearance will be
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index c34edf9..d16ac65 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -1225,20 +1225,6 @@ void Browser::ShowFirstRunBubble() {
window()->GetLocationBar()->ShowFirstRunBubble();
}
-void Browser::MaybeUpdateBookmarkBarStateForInstantOverlay(
- const chrome::search::Mode& mode) {
- // This is invoked by a platform-specific implementation of
- // |InstantOverlayController| to update bookmark bar state according to
- // Instant overlay state.
- // ModeChanged() updates bookmark bar state for all mode transitions except
- // when new mode is |SEARCH_SUGGESTIONS|, because that needs to be done when
- // the suggestions are ready.
- if (mode.is_search_suggestions() &&
- bookmark_bar_state_ == BookmarkBar::SHOW) {
- UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
- }
-}
-
void Browser::ShowDownload(content::DownloadItem* download) {
if (!window())
return;
@@ -1814,22 +1800,13 @@ void Browser::Observe(int type,
}
}
-void Browser::ModeChanged(const chrome::search::Mode& old_mode,
- const chrome::search::Mode& new_mode) {
- // If new mode is |SEARCH_SUGGESTIONS|, don't update bookmark bar state now;
- // wait till the Instant overlay is ready to show suggestions before hiding
- // the bookmark bar (in MaybeUpdateBookmarkBarStateForInstantOverlay()).
- // TODO(kuan): but for now, only delay updating bookmark bar state if origin
- // is |DEFAULT|; other origins require more complex logic to be implemented
- // to prevent jankiness caused by hiding bookmark bar, so just hide the
- // bookmark bar immediately and tolerate the jankiness for a while.
- // For other mode transitions, update bookmark bar state accordingly.
- if (new_mode.is_search_suggestions() &&
- new_mode.is_origin_default() &&
- bookmark_bar_state_ == BookmarkBar::SHOW) {
- return;
+void Browser::ModelChanged(
+ const chrome::search::SearchModel::State& old_state,
+ const chrome::search::SearchModel::State& new_state) {
+ if (chrome::search::SearchModel::ShouldChangeTopBarsVisibility(old_state,
+ new_state)) {
+ UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
}
- UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE);
}
///////////////////////////////////////////////////////////////////////////////
@@ -2139,16 +2116,22 @@ void Browser::UpdateBookmarkBarState(BookmarkBarStateChangeReason reason) {
state = BookmarkBar::HIDDEN;
}
- // Don't allow the bookmark bar to be shown in suggestions mode.
+ // Bookmark bar may need to be hidden for |SEARCH_SUGGESTIONS| and
+ // |SEARCH_RESULTS| modes as per SearchBox API or Instant overlay or if it's
+ // detached.
+ // TODO(sail): remove conditional MACOSX flag when bookmark bar is actually
+ // hidden on mac; for now, mac keeps the bookmark bar shown but changes its
+ // z-order to stack it below contents.
#if !defined(OS_MACOSX)
- if (search_model_->mode().is_search_suggestions())
+ if (search_model_->mode().is_search() &&
+ (state == BookmarkBar::DETACHED || !search_model_->top_bars_visible())) {
state = BookmarkBar::HIDDEN;
-#endif
-
- // Don't allow detached bookmark bar to be shown in suggestions or results
- // modes.
+ }
+#else
+ // TODO(sail): remove this when the above block is enabled for mac.
if (state == BookmarkBar::DETACHED && search_model_->mode().is_search())
state = BookmarkBar::HIDDEN;
+#endif // !defined(OS_MACOSX)
if (state == bookmark_bar_state_)
return;
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index 35db7f3..280d58f 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -453,12 +453,6 @@ class Browser : public TabStripModelObserver,
// Show the first run search engine bubble on the location bar.
void ShowFirstRunBubble();
- // If necessary, update the bookmark bar state according to the Instant
- // overlay state: when Instant overlay shows suggestions and bookmark bar is
- // still showing attached, hide it.
- void MaybeUpdateBookmarkBarStateForInstantOverlay(
- const chrome::search::Mode& mode);
-
// Show a download on the download shelf.
void ShowDownload(content::DownloadItem* download);
@@ -680,8 +674,9 @@ class Browser : public TabStripModelObserver,
const content::NotificationDetails& details) OVERRIDE;
// Overridden from chrome::search::SearchModelObserver:
- virtual void ModeChanged(const chrome::search::Mode& old_mode,
- const chrome::search::Mode& new_mode) OVERRIDE;
+ virtual void ModelChanged(
+ const chrome::search::SearchModel::State& old_state,
+ const chrome::search::SearchModel::State& new_state) OVERRIDE;
// Command and state updating ///////////////////////////////////////////////
diff --git a/chrome/browser/ui/browser_instant_controller.cc b/chrome/browser/ui/browser_instant_controller.cc
index ca47c0f..068aa504 100644
--- a/chrome/browser/ui/browser_instant_controller.cc
+++ b/chrome/browser/ui/browser_instant_controller.cc
@@ -236,8 +236,14 @@ void BrowserInstantController::ResetInstant(const std::string& pref_name) {
////////////////////////////////////////////////////////////////////////////////
// BrowserInstantController, search::SearchModelObserver implementation:
-void BrowserInstantController::ModeChanged(const search::Mode& old_mode,
- const search::Mode& new_mode) {
+void BrowserInstantController::ModelChanged(
+ const search::SearchModel::State& old_state,
+ const search::SearchModel::State& new_state) {
+ if (old_state.mode == new_state.mode)
+ return;
+
+ const search::Mode& new_mode = new_state.mode;
+
if (search::IsInstantExtendedAPIEnabled()) {
// Record some actions corresponding to the mode change. Note that to get
// the full story, it's necessary to look at other UMA actions as well,
@@ -252,7 +258,7 @@ void BrowserInstantController::ModeChanged(const search::Mode& old_mode,
if (new_mode.is_ntp())
UpdateThemeInfo();
- instant_.SearchModeChanged(old_mode, new_mode);
+ instant_.SearchModeChanged(old_state.mode, new_mode);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/browser_instant_controller.h b/chrome/browser/ui/browser_instant_controller.h
index f6d2bde..3708669 100644
--- a/chrome/browser/ui/browser_instant_controller.h
+++ b/chrome/browser/ui/browser_instant_controller.h
@@ -111,8 +111,9 @@ class BrowserInstantController : public content::NotificationObserver,
void ResetInstant(const std::string& pref_name);
// Overridden from search::SearchModelObserver:
- virtual void ModeChanged(const search::Mode& old_mode,
- const search::Mode& new_mode) OVERRIDE;
+ virtual void ModelChanged(
+ const search::SearchModel::State& old_state,
+ const search::SearchModel::State& new_state) OVERRIDE;
// content::NotificationObserver implementation.
virtual void Observe(int type,
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.h b/chrome/browser/ui/cocoa/browser_window_cocoa.h
index 8ce489a0..1ddc053 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.h
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.h
@@ -149,8 +149,9 @@ class BrowserWindowCocoa :
GetActiveTabPermissionGranter() OVERRIDE;
// Overridden from chrome::search::SearchModelObserver:
- virtual void ModeChanged(const chrome::search::Mode& old_mode,
- const chrome::search::Mode& new_mode) OVERRIDE;
+ virtual void ModelChanged(
+ const chrome::search::SearchModel::State& old_state,
+ const chrome::search::SearchModel::State& new_state) OVERRIDE;
// Adds the given FindBar cocoa controller to this browser window.
void AddFindBar(FindBarCocoaController* find_bar_cocoa_controller);
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
index 6a0f839..2dd1dbc 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm
@@ -665,9 +665,9 @@ extensions::ActiveTabPermissionGranter*
return tab_helper ? tab_helper->active_tab_permission_granter() : NULL;
}
-void BrowserWindowCocoa::ModeChanged(
- const chrome::search::Mode& old_mode,
- const chrome::search::Mode& new_mode) {
+void BrowserWindowCocoa::ModelChanged(
+ const chrome::search::SearchModel::State& old_state,
+ const chrome::search::SearchModel::State& new_state) {
[controller_ updateBookmarkBarStateForInstantOverlay];
}
diff --git a/chrome/browser/ui/cocoa/tab_contents/instant_overlay_controller_mac.mm b/chrome/browser/ui/cocoa/tab_contents/instant_overlay_controller_mac.mm
index 13bad50..68006c7 100644
--- a/chrome/browser/ui/cocoa/tab_contents/instant_overlay_controller_mac.mm
+++ b/chrome/browser/ui/cocoa/tab_contents/instant_overlay_controller_mac.mm
@@ -2,11 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "chrome/browser/ui/cocoa/tab_contents/instant_overlay_controller_mac.h"
+
+#include "chrome/browser/search/search.h"
#include "chrome/browser/ui/browser.h"
#import "chrome/browser/ui/cocoa/browser_window_controller.h"
#include "chrome/browser/ui/cocoa/tab_contents/instant_overlay_controller_mac.h"
#import "chrome/browser/ui/cocoa/tab_contents/overlayable_contents_controller.h"
#include "chrome/browser/ui/search/instant_overlay_model.h"
+#include "chrome/browser/ui/search/search_model.h"
+#include "chrome/browser/ui/search/search_tab_helper.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
InstantOverlayControllerMac::InstantOverlayControllerMac(
Browser* browser,
@@ -22,6 +28,11 @@ InstantOverlayControllerMac::~InstantOverlayControllerMac() {
void InstantOverlayControllerMac::OverlayStateChanged(
const InstantOverlayModel& model) {
+ // TODO(sail): migrate from InstantOverlayControllerViews::OverlayStateChanged
+ // to only call SetTopBarsVisible if we did something with overlay; this
+ // prevents the top bars from flashing in this transition
+ // DEFAULT->SUGGESTIONS->SERP.
+ bool has_overlay = false;
if (model.mode().is_ntp() || model.mode().is_search_suggestions()) {
// Drop shadow is only needed if search mode is not |NTP| and overlay does
// not fill up the entire contents page.
@@ -32,12 +43,24 @@ void InstantOverlayControllerMac::OverlayStateChanged(
height:model.height()
heightUnits:model.height_units()
drawDropShadow:drawDropShadow];
+ has_overlay = true;
} else {
[overlay_ setOverlay:NULL
height:0
heightUnits:INSTANT_SIZE_PIXELS
drawDropShadow:NO];
}
- browser_->MaybeUpdateBookmarkBarStateForInstantOverlay(model.mode());
+
+ if (chrome::search::IsInstantExtendedAPIEnabled()) {
+ // Set top bars (bookmark and info bars) visibility for current tab via
+ // |SearchTabHelper| of current active web contents: top bars are hidden if
+ // there's overlay.
+ chrome::search::SearchTabHelper* search_tab_helper =
+ chrome::search::SearchTabHelper::FromWebContents(
+ browser_->tab_strip_model()->GetActiveWebContents());
+ if (search_tab_helper)
+ search_tab_helper->model()->SetTopBarsVisible(!has_overlay);
+ }
+
[window_ updateBookmarkBarStateForInstantOverlay];
}
diff --git a/chrome/browser/ui/search/search_delegate.cc b/chrome/browser/ui/search/search_delegate.cc
index 6e437c0..6c0ec71 100644
--- a/chrome/browser/ui/search/search_delegate.cc
+++ b/chrome/browser/ui/search/search_delegate.cc
@@ -20,8 +20,9 @@ SearchDelegate::~SearchDelegate() {
DCHECK(!tab_model_) << "All tabs should have been deactivated or closed.";
}
-void SearchDelegate::ModeChanged(const Mode& old_mode, const Mode& new_mode) {
- browser_model_->SetMode(new_mode);
+void SearchDelegate::ModelChanged(const SearchModel::State& old_state,
+ const SearchModel::State& new_state) {
+ browser_model_->SetState(new_state);
}
void SearchDelegate::OnTabActivated(content::WebContents* web_contents) {
@@ -29,7 +30,7 @@ void SearchDelegate::OnTabActivated(content::WebContents* web_contents) {
tab_model_->RemoveObserver(this);
tab_model_ =
chrome::search::SearchTabHelper::FromWebContents(web_contents)->model();
- browser_model_->SetMode(tab_model_->mode());
+ browser_model_->SetState(tab_model_->state());
tab_model_->AddObserver(this);
}
diff --git a/chrome/browser/ui/search/search_delegate.h b/chrome/browser/ui/search/search_delegate.h
index f88e291..11b105c 100644
--- a/chrome/browser/ui/search/search_delegate.h
+++ b/chrome/browser/ui/search/search_delegate.h
@@ -33,7 +33,8 @@ class SearchDelegate : public SearchModelObserver {
virtual ~SearchDelegate();
// Overrides for SearchModelObserver:
- virtual void ModeChanged(const Mode& old_mode, const Mode& new_mode) OVERRIDE;
+ virtual void ModelChanged(const SearchModel::State& old_state,
+ const SearchModel::State& new_state) OVERRIDE;
// When the active tab is changed, the model state of this new active tab is
// propagated to the browser.
diff --git a/chrome/browser/ui/search/search_model.cc b/chrome/browser/ui/search/search_model.cc
index b1830e6..6637b8f 100644
--- a/chrome/browser/ui/search/search_model.cc
+++ b/chrome/browser/ui/search/search_model.cc
@@ -16,19 +16,68 @@ SearchModel::SearchModel() {
SearchModel::~SearchModel() {
}
+// static.
+bool SearchModel::ShouldChangeTopBarsVisibility(const State& old_state,
+ const State& new_state) {
+ // If mode has changed, only change top bars visibility if new mode is not
+ // |SEARCH_SUGGESTIONS| or |SEARCH_RESULTS|. Top bars visibility for
+ // these 2 modes is determined when the mode stays the same, and:
+ // - for |NTP/SERP| pages: by SearchBox API, or
+ // - for |DEFAULT| pages: by platform-specific implementation of
+ // |InstantOverlayController| when it shows/hides the Instant overlay.
+ return old_state.mode != new_state.mode ?
+ !new_state.mode.is_search() : new_state.mode.is_search();
+}
+
+void SearchModel::SetState(const State& new_state) {
+ DCHECK(IsInstantExtendedAPIEnabled())
+ << "Please do not try to set the SearchModel mode without first "
+ << "checking if Search is enabled.";
+
+ if (state_ == new_state)
+ return;
+
+ const State old_state = state_;
+ state_ = new_state;
+
+ FOR_EACH_OBSERVER(SearchModelObserver, observers_,
+ ModelChanged(old_state, state_));
+}
+
void SearchModel::SetMode(const Mode& new_mode) {
DCHECK(IsInstantExtendedAPIEnabled())
<< "Please do not try to set the SearchModel mode without first "
<< "checking if Search is enabled.";
- if (mode_ == new_mode)
+ if (state_.mode == new_mode)
+ return;
+
+ const State old_state = state_;
+ state_.mode = new_mode;
+
+ // For |SEARCH_SUGGESTIONS| and |SEARCH_RESULTS| modes, SearchBox API will
+ // determine visibility of top bars via SetTopBarsVisible(); for other modes,
+ // top bars are always visible, if available.
+ if (!state_.mode.is_search())
+ state_.top_bars_visible = true;
+
+ FOR_EACH_OBSERVER(SearchModelObserver, observers_,
+ ModelChanged(old_state, state_));
+}
+
+void SearchModel::SetTopBarsVisible(bool visible) {
+ DCHECK(IsInstantExtendedAPIEnabled())
+ << "Please do not try to set the SearchModel mode without first "
+ << "checking if Search is enabled.";
+
+ if (state_.top_bars_visible == visible)
return;
- const Mode old_mode = mode_;
- mode_ = new_mode;
+ const State old_state = state_;
+ state_.top_bars_visible = visible;
FOR_EACH_OBSERVER(SearchModelObserver, observers_,
- ModeChanged(old_mode, mode_));
+ ModelChanged(old_state, state_));
}
void SearchModel::AddObserver(SearchModelObserver* observer) {
diff --git a/chrome/browser/ui/search/search_model.h b/chrome/browser/ui/search/search_model.h
index 6a7f1f1..44322a6 100644
--- a/chrome/browser/ui/search/search_model.h
+++ b/chrome/browser/ui/search/search_model.h
@@ -18,23 +18,52 @@ class SearchModelObserver;
// changes.
class SearchModel {
public:
+ struct State {
+ State() : top_bars_visible(true) {}
+
+ bool operator==(const State& rhs) const {
+ return mode == rhs.mode && top_bars_visible == rhs.top_bars_visible;
+ }
+
+ // The display mode of UI elements such as the toolbar, the tab strip, etc.
+ Mode mode;
+ // The visibility of top bars such as bookmark and info bars.
+ bool top_bars_visible;
+ };
+
SearchModel();
~SearchModel();
- // Change the mode. Change notifications are sent to observers. An animated
- // transition may be requested.
+ // Returns true if visibility in top bars should be changed based on
+ // |old_state| and |new_state|.
+ static bool ShouldChangeTopBarsVisibility(const State& old_state,
+ const State& new_state);
+
+ // Change the state. Change notifications are sent to observers.
+ void SetState(const State& state);
+
+ // Get the current state.
+ const State& state() const { return state_; }
+
+ // Change the mode. Change notifications are sent to observers.
void SetMode(const Mode& mode);
// Get the active mode.
- const Mode& mode() const { return mode_; }
+ const Mode& mode() const { return state_.mode; }
+
+ // Set visibility of top bars. Change notifications are sent to observers.
+ void SetTopBarsVisible(bool visible);
+
+ // Get the visibility of top bars.
+ bool top_bars_visible() const { return state_.top_bars_visible; }
// Add and remove observers.
void AddObserver(SearchModelObserver* observer);
void RemoveObserver(SearchModelObserver* observer);
private:
- // The display mode of UI elements such as the toolbar, the tab strip, etc.
- Mode mode_;
+ // Current state of model.
+ State state_;
// Observers.
ObserverList<SearchModelObserver> observers_;
diff --git a/chrome/browser/ui/search/search_model_observer.h b/chrome/browser/ui/search/search_model_observer.h
index 970bba8..200356b 100644
--- a/chrome/browser/ui/search/search_model_observer.h
+++ b/chrome/browser/ui/search/search_model_observer.h
@@ -5,16 +5,17 @@
#ifndef CHROME_BROWSER_UI_SEARCH_SEARCH_MODEL_OBSERVER_H_
#define CHROME_BROWSER_UI_SEARCH_SEARCH_MODEL_OBSERVER_H_
+#include "chrome/browser/ui/search/search_model.h"
+
namespace chrome {
namespace search {
-struct Mode;
-
// This class defines the observer interface for the |SearchModel|.
class SearchModelObserver {
public:
- // Informs the observer that the mode has changed.
- virtual void ModeChanged(const Mode& old_mode, const Mode& new_mode) = 0;
+ // Informs the observer that the model's state has changed.
+ virtual void ModelChanged(const SearchModel::State& old_state,
+ const SearchModel::State& new_state) = 0;
protected:
virtual ~SearchModelObserver() {}
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc
index cece414..d28404f 100644
--- a/chrome/browser/ui/search/search_tab_helper.cc
+++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/ui/search/search_tab_helper.h"
#include "chrome/browser/search/search.h"
+#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/notification_service.h"
@@ -35,7 +36,8 @@ namespace chrome {
namespace search {
SearchTabHelper::SearchTabHelper(content::WebContents* web_contents)
- : is_search_enabled_(chrome::search::IsInstantExtendedAPIEnabled()),
+ : WebContentsObserver(web_contents),
+ is_search_enabled_(chrome::search::IsInstantExtendedAPIEnabled()),
user_input_in_progress_(false),
web_contents_(web_contents) {
if (!is_search_enabled_)
@@ -60,14 +62,14 @@ void SearchTabHelper::OmniboxEditModelChanged(bool user_input_in_progress,
if (!user_input_in_progress && !cancelling)
return;
- UpdateModel();
+ UpdateMode();
}
void SearchTabHelper::NavigationEntryUpdated() {
if (!is_search_enabled_)
return;
- UpdateModel();
+ UpdateMode();
}
void SearchTabHelper::Observe(
@@ -75,10 +77,22 @@ void SearchTabHelper::Observe(
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK_EQ(content::NOTIFICATION_NAV_ENTRY_COMMITTED, type);
- UpdateModel();
+ UpdateMode();
}
-void SearchTabHelper::UpdateModel() {
+bool SearchTabHelper::OnMessageReceived(const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(SearchTabHelper, message)
+ IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SearchBoxShowBars,
+ OnSearchBoxShowBars)
+ IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SearchBoxHideBars,
+ OnSearchBoxHideBars)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void SearchTabHelper::UpdateMode() {
Mode::Type type = Mode::MODE_DEFAULT;
Mode::Origin origin = Mode::ORIGIN_DEFAULT;
if (IsNTP(web_contents_)) {
@@ -93,5 +107,17 @@ void SearchTabHelper::UpdateModel() {
model_.SetMode(Mode(type, origin));
}
+void SearchTabHelper::OnSearchBoxShowBars(int page_id) {
+ if (web_contents()->IsActiveEntry(page_id))
+ model_.SetTopBarsVisible(true);
+}
+
+void SearchTabHelper::OnSearchBoxHideBars(int page_id) {
+ if (web_contents()->IsActiveEntry(page_id)) {
+ model_.SetTopBarsVisible(false);
+ Send(new ChromeViewMsg_SearchBoxBarsHidden(routing_id()));
+ }
+}
+
} // namespace search
} // namespace chrome
diff --git a/chrome/browser/ui/search/search_tab_helper.h b/chrome/browser/ui/search/search_tab_helper.h
index 7034705..e575dc2 100644
--- a/chrome/browser/ui/search/search_tab_helper.h
+++ b/chrome/browser/ui/search/search_tab_helper.h
@@ -10,6 +10,7 @@
#include "chrome/browser/ui/search/search_model.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
+#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
namespace content {
@@ -22,6 +23,7 @@ namespace search {
// Per-tab search "helper". Acts as the owner and controller of the tab's
// search UI model.
class SearchTabHelper : public content::NotificationObserver,
+ public content::WebContentsObserver,
public content::WebContentsUserData<SearchTabHelper> {
public:
virtual ~SearchTabHelper();
@@ -50,8 +52,16 @@ class SearchTabHelper : public content::NotificationObserver,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
+ // Overridden from contents::WebContentsObserver:
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+
// Sets the mode of the model based on the current URL of web_contents().
- void UpdateModel();
+ void UpdateMode();
+
+ // Handlers for SearchBox API to show and hide top bars (bookmark and info
+ // bars).
+ void OnSearchBoxShowBars(int page_id);
+ void OnSearchBoxHideBars(int page_id);
const bool is_search_enabled_;
diff --git a/chrome/browser/ui/views/frame/instant_overlay_controller_views.cc b/chrome/browser/ui/views/frame/instant_overlay_controller_views.cc
index 097d415..0478599 100644
--- a/chrome/browser/ui/views/frame/instant_overlay_controller_views.cc
+++ b/chrome/browser/ui/views/frame/instant_overlay_controller_views.cc
@@ -5,8 +5,12 @@
#include "chrome/browser/ui/views/frame/instant_overlay_controller_views.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search/search.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/search/instant_overlay_model.h"
+#include "chrome/browser/ui/search/search_model.h"
+#include "chrome/browser/ui/search/search_tab_helper.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/view_ids.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/contents_container.h"
@@ -25,6 +29,10 @@ InstantOverlayControllerViews::~InstantOverlayControllerViews() {
void InstantOverlayControllerViews::OverlayStateChanged(
const InstantOverlayModel& model) {
+ // Set top bars (bookmark and info bars) visibility if Instant Extended API
+ // is enabled.
+ bool set_top_bars_visibility = chrome::search::IsInstantExtendedAPIEnabled();
+
if (model.mode().is_ntp() || model.mode().is_search_suggestions()) {
// Show the overlay.
if (!overlay_) {
@@ -44,18 +52,26 @@ void InstantOverlayControllerViews::OverlayStateChanged(
overlay_->SetWebContents(NULL);
contents_->SetOverlay(NULL, NULL, 100, INSTANT_SIZE_PERCENT, false);
overlay_.reset();
+ } else {
+ // Don't set top bars visiblility if nothing was done with overlay.
+ set_top_bars_visibility = false;
}
- browser_->MaybeUpdateBookmarkBarStateForInstantOverlay(model.mode());
+ if (set_top_bars_visibility) {
+ // Set top bars visibility for current tab via |SearchTabHelper| of current
+ // active web contents: top bars are hidden if there's overlay.
+ chrome::search::SearchTabHelper* search_tab_helper =
+ chrome::search::SearchTabHelper::FromWebContents(
+ browser_->tab_strip_model()->GetActiveWebContents());
+ if (search_tab_helper)
+ search_tab_helper->model()->SetTopBarsVisible(!overlay_);
+ }
// If an Instant overlay is added during an immersive mode reveal, the reveal
// view needs to stay on top.
- // Notify infobar container of change in overlay state.
if (overlay_) {
BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser_);
- if (browser_view) {
+ if (browser_view)
browser_view->MaybeStackImmersiveRevealAtTop();
- browser_view->infobar_container()->OverlayStateChanged(model);
- }
}
}