diff options
-rw-r--r-- | chrome/browser/infobars/infobar_container.cc | 17 | ||||
-rw-r--r-- | chrome/browser/infobars/infobar_container.h | 30 | ||||
-rw-r--r-- | chrome/browser/ui/browser.cc | 22 | ||||
-rw-r--r-- | chrome/browser/ui/browser.h | 2 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/browser_view.h | 3 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/browser_view_layout.cc | 39 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/contents_container.cc | 1 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/contents_container.h | 13 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/instant_preview_controller_views.cc | 6 |
9 files changed, 104 insertions, 29 deletions
diff --git a/chrome/browser/infobars/infobar_container.cc b/chrome/browser/infobars/infobar_container.cc index a252025..51d3ac7 100644 --- a/chrome/browser/infobars/infobar_container.cc +++ b/chrome/browser/infobars/infobar_container.cc @@ -15,6 +15,7 @@ #include "chrome/browser/api/infobars/infobar_delegate.h" #include "chrome/browser/api/infobars/infobar_service.h" #include "chrome/browser/infobars/infobar.h" +#include "chrome/browser/instant/instant_model.h" #include "chrome/browser/ui/search/search_model.h" #include "chrome/common/chrome_notification_types.h" #include "content/public/browser/notification_details.h" @@ -164,6 +165,12 @@ 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 preview is ready is received via + // PreviewStateChanged(); this prevents jankiness caused by infobars hiding + // followed by suggestions appearing. + if (new_mode.is_origin_default()) + return; HideAllInfoBars(); OnInfoBarStateChanged(false); } else { @@ -172,6 +179,16 @@ void InfoBarContainer::ModeChanged(const chrome::search::Mode& old_mode, } } +void InfoBarContainer::PreviewStateChanged(const InstantModel& 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()) { + HideAllInfoBars(); + OnInfoBarStateChanged(false); + } +} + size_t InfoBarContainer::HideInfoBar(InfoBarDelegate* delegate, bool use_animation) { bool should_animate = use_animation && diff --git a/chrome/browser/infobars/infobar_container.h b/chrome/browser/infobars/infobar_container.h index 508bf76..c3f0330 100644 --- a/chrome/browser/infobars/infobar_container.h +++ b/chrome/browser/infobars/infobar_container.h @@ -9,6 +9,7 @@ #include "base/compiler_specific.h" #include "base/time.h" +#include "chrome/browser/instant/instant_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" @@ -33,16 +34,24 @@ class SearchModel; // Platforms need to subclass this to implement a few platform-specific // functions, which are pure virtual here. // -// This class also observes changes to the SearchModel mode. If the user changes -// into suggestions mode, it hides all the infobars temporarily. When the user -// changes back out of suggestions mode, it reshows any infobars, and starts a -// 50 ms window during which any attempts to re-hide any infobars are handled -// without animation. This prevents glitchy-looking behavior when the user -// navigates following a mode change, which otherwise would re-show the infobars -// only to instantly animate them closed. The window is canceled if a tab -// change occurs. +// This class also observes changes to the SearchModel modes. It hides infobars +// temporarily if the user changes into |SEARCH_SUGGESTIONS| mode (refer to +// chrome::search::Mode in chrome/common/search_types.h for all search modes) +// when on a : +// - |DEFAULT| page: when instant preview is ready; +// - |NTP| or |SEARCH_RESULTS| page: immediately; +// TODO(kuan): this scenario requires more complex synchronization with +// renderer SearchBoxAPI and will be implemented as the next step; +// for now, hiding is immediate. +// When the user changes back out of |SEARCH_SUGGESTIONS| mode, it reshows any +// infobars, and starts a 50 ms window during which any attempts to re-hide any +// infobars are handled without animation. This prevents glitchy-looking +// behavior when the user navigates following a mode change, which otherwise +// 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 chrome::search::SearchModelObserver, + public InstantModelObserver { public: class Delegate { public: @@ -101,6 +110,9 @@ class InfoBarContainer : public content::NotificationObserver, const Delegate* delegate() const { return delegate_; } + // InstantModelObserver: + virtual void PreviewStateChanged(const InstantModel& 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 diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 5343c29..071d8bd 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -1239,12 +1239,8 @@ void Browser::MaybeUpdateBookmarkBarStateForInstantPreview( // |InstantPreviewController| to update bookmark bar state according to // instant preview state. // ModeChanged() updates bookmark bar state for all mode transitions except - // when transitioning from |NTP| to |SEARCH_SUGGESTIONS|, because that needs - // to be done when the suggestions are ready. - // If |mode| is |SEARCH_SUGGESTIONS| and bookmark bar is still showing - // attached, the previous mode is definitely NTP; it won't be |DEFAULT| - // because ModeChanged() would have handled that transition by hiding the - // bookmark bar. + // 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); @@ -1910,12 +1906,16 @@ void Browser::Observe(int type, void Browser::ModeChanged(const chrome::search::Mode& old_mode, const chrome::search::Mode& new_mode) { - // If mode is transitioning from |NTP| to |SEARCH_SUGGESTIONS|, don't update - // bookmark bar state now; wait till the instant preview is ready to show - // suggestions before starting the animation to hide the bookmark bar (in - // MaybeUpdateBookmarkBarStateForInstantPreview()). + // If new mode is |SEARCH_SUGGESTIONS|, don't update bookmark bar state now; + // wait till the instant preview is ready to show suggestions before hiding + // the bookmark bar (in MaybeUpdateBookmarkBarStateForInstantPreview()). + // 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 (old_mode.is_ntp() && new_mode.is_search_suggestions() && + if (new_mode.is_search_suggestions() && + new_mode.is_origin_default() && bookmark_bar_state_ == BookmarkBar::SHOW) { return; } diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 1f54a73..8d0ce58 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h @@ -460,7 +460,7 @@ class Browser : public TabStripModelObserver, // If necessary, update the bookmark bar state according to the instant // preview state: when instant preview shows suggestions and bookmark bar is - // still showing attached, start the animation to hide it. + // still showing attached, hide it. void MaybeUpdateBookmarkBarStateForInstantPreview( const chrome::search::Mode& mode); diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 5569734..d6c3f20 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h @@ -161,6 +161,9 @@ class BrowserView : public BrowserWindow, // Accessor for the Toolbar. ToolbarView* toolbar() { return toolbar_; } + // Accessor for the InfobarContainer. + InfoBarContainerView* infobar_container() { return infobar_container_; } + // Returns true if various window components are visible. virtual bool IsTabStripVisible() const; diff --git a/chrome/browser/ui/views/frame/browser_view_layout.cc b/chrome/browser/ui/views/frame/browser_view_layout.cc index 00311c5..c21ca77 100644 --- a/chrome/browser/ui/views/frame/browser_view_layout.cc +++ b/chrome/browser/ui/views/frame/browser_view_layout.cc @@ -7,6 +7,7 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/find_bar/find_bar.h" #include "chrome/browser/ui/find_bar/find_bar_controller.h" +#include "chrome/browser/ui/search/search_model.h" #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" #include "chrome/browser/ui/views/download/download_shelf_view.h" @@ -22,6 +23,7 @@ #include "ui/gfx/scrollbar_size.h" #include "ui/gfx/size.h" #include "ui/views/controls/single_split_view.h" +#include "ui/views/controls/webview/webview.h" namespace { @@ -257,6 +259,24 @@ void BrowserViewLayout::ViewRemoved(views::View* host, views::View* view) { } void BrowserViewLayout::Layout(views::View* host) { + // Showing instant extended suggestions causes us to temporarily hide any + // visible bookmark bar and infobars. In turn, this hiding would normally + // cause the content below the suggestions to shift upwards, which looks + // surprising (since from the user's perspective, we're "covering" rather than + // "removing" the bookmark bar/infobars). To prevent this, we save off the + // content origin here, then once we finish laying things out, force the + // contents to continue to display from that origin. + const chrome::search::Mode& mode = browser()->search_model()->mode(); + views::WebView* contents = browser_view_->contents_container_; + int preview_height = contents_container_->preview_height(); + gfx::Point old_contents_origin; + if (preview_height > 0 && mode.is_search_suggestions() && + mode.is_origin_default()) { + old_contents_origin = contents->bounds().origin(); + views::View::ConvertPointToTarget(contents->parent(), browser_view_, + &old_contents_origin); + } + vertical_layout_rect_ = browser_view_->GetLocalBounds(); int top = LayoutTabStripRegion(); if (browser_view_->IsTabStripVisible()) { @@ -280,6 +300,23 @@ void BrowserViewLayout::Layout(views::View* host) { top -= active_top_margin; contents_container_->SetActiveTopMargin(active_top_margin); LayoutTabContents(top, bottom); + + // Now set the contents to display at their previous origin if we just hid the + // bookmark and/or infobars. + if (active_top_margin == 0 && !old_contents_origin.IsOrigin()) { + gfx::Point new_contents_origin(contents->bounds().origin()); + views::View::ConvertPointToTarget(contents->parent(), browser_view_, + &new_contents_origin); + active_top_margin = old_contents_origin.y() - new_contents_origin.y(); + // Special case: While normally the suggestions appear to "cover" any + // bookmark/infobars, if the suggestions are very short, they might not + // fully cover that gap, and leaving the contents at their original height + // would leave an odd-looking blank space. In this case, we allow the + // contents to go ahead and shift upward. + if (active_top_margin > 0 && active_top_margin < preview_height) + contents_container_->SetActiveTopMargin(active_top_margin); + } + // This must be done _after_ we lay out the WebContents since this // code calls back into us to find the bounding box the find bar // must be laid out within, and that code depends on the @@ -320,7 +357,7 @@ int BrowserViewLayout::LayoutTabStripRegion() { browser_view_->frame()->GetBoundsForTabStrip(tabstrip)); gfx::Point tabstrip_origin(tabstrip_bounds.origin()); views::View::ConvertPointToTarget(browser_view_->parent(), browser_view_, - &tabstrip_origin); + &tabstrip_origin); tabstrip_bounds.set_origin(tabstrip_origin); tabstrip->SetVisible(true); diff --git a/chrome/browser/ui/views/frame/contents_container.cc b/chrome/browser/ui/views/frame/contents_container.cc index 3af337b..9b4f5ba 100644 --- a/chrome/browser/ui/views/frame/contents_container.cc +++ b/chrome/browser/ui/views/frame/contents_container.cc @@ -8,7 +8,6 @@ #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" #include "ui/gfx/image/image_skia.h" -#include "ui/views/controls/webview/webview.h" // static const char ContentsContainer::kViewClassName[] = diff --git a/chrome/browser/ui/views/frame/contents_container.h b/chrome/browser/ui/views/frame/contents_container.h index 4a24d79..49f17df 100644 --- a/chrome/browser/ui/views/frame/contents_container.h +++ b/chrome/browser/ui/views/frame/contents_container.h @@ -11,6 +11,7 @@ #include "base/compiler_specific.h" #include "chrome/common/instant_types.h" #include "chrome/common/search_types.h" +#include "ui/views/controls/webview/webview.h" #include "ui/views/view.h" namespace content { @@ -21,10 +22,6 @@ namespace gfx { class Rect; } -namespace views { -class WebView; -} - // ContentsContainer is responsible for managing the WebContents views. // ContentsContainer has up to two children: one for the currently active // WebContents and one for Instant's WebContents. @@ -56,7 +53,13 @@ class ContentsContainer : public views::View { return preview_web_contents_; } - // Sets the active top margin. + int preview_height() const { + return preview_ ? preview_->bounds().height() : 0; + } + + // Sets the active top margin; the active WebView's y origin would be + // positioned at this |margin|, causing the active WebView to be pushed down + // vertically by |margin| pixels in the |ContentsContainer|. void SetActiveTopMargin(int margin); // Returns the bounds the preview would be shown at. diff --git a/chrome/browser/ui/views/frame/instant_preview_controller_views.cc b/chrome/browser/ui/views/frame/instant_preview_controller_views.cc index abf481a..742c4be 100644 --- a/chrome/browser/ui/views/frame/instant_preview_controller_views.cc +++ b/chrome/browser/ui/views/frame/instant_preview_controller_views.cc @@ -10,6 +10,7 @@ #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" +#include "chrome/browser/ui/views/infobars/infobar_container_view.h" #include "ui/views/controls/webview/webview.h" InstantPreviewControllerViews::InstantPreviewControllerViews( @@ -51,9 +52,12 @@ void InstantPreviewControllerViews::PreviewStateChanged( // If an instant preview is added during an immersive mode reveal, the reveal // view needs to stay on top. + // Notify infobar container of change in preview state. if (preview_) { BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser_); - if (browser_view) + if (browser_view) { browser_view->MaybeStackImmersiveRevealAtTop(); + browser_view->infobar_container()->PreviewStateChanged(model); + } } } |