Makes the linux bookmark bar use Browsers's bookmarkbarstate instead
of figuring it outself.

BUG=60166
TEST=make sure the bookmark bar on linux doesn't behave oddly when
showing/hiding, transitioning from ntp to other pages.

Review URL: http://codereview.chromium.org/7275011

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@91018 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 80c4a5c9..f136541 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -1223,56 +1223,9 @@
   browser::Navigate(&params);
 }
 
-void Browser::UpdateCommandsForFullscreenMode(bool is_fullscreen) {
-#if !defined(OS_MACOSX)
-  const bool show_main_ui = is_type_tabbed() && !is_fullscreen;
-#else
-  const bool show_main_ui = is_type_tabbed();
-#endif
-
-  bool main_not_fullscreen = show_main_ui && !is_fullscreen;
-
-  // Navigation commands
-  command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui);
-
-  // Window management commands
-  command_updater_.UpdateCommandEnabled(IDC_SHOW_AS_TAB,
-      type_ != TYPE_TABBED && !is_fullscreen);
-
-  // Focus various bits of UI
-  command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui);
-  command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_main_ui);
-  command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui);
-  command_updater_.UpdateCommandEnabled(
-      IDC_FOCUS_MENU_BAR, main_not_fullscreen);
-  command_updater_.UpdateCommandEnabled(
-      IDC_FOCUS_NEXT_PANE, main_not_fullscreen);
-  command_updater_.UpdateCommandEnabled(
-      IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen);
-  command_updater_.UpdateCommandEnabled(
-      IDC_FOCUS_BOOKMARKS, main_not_fullscreen);
-  command_updater_.UpdateCommandEnabled(
-      IDC_FOCUS_CHROMEOS_STATUS, main_not_fullscreen);
-
-  // Show various bits of UI
-  command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui);
-  command_updater_.UpdateCommandEnabled(IDC_FEEDBACK, show_main_ui);
-  command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR,
-      browser_defaults::bookmarks_enabled && show_main_ui);
-  command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, show_main_ui);
-  command_updater_.UpdateCommandEnabled(IDC_SYNC_BOOKMARKS,
-      show_main_ui && profile_->IsSyncAccessible());
-
-  command_updater_.UpdateCommandEnabled(IDC_OPTIONS, show_main_ui);
-  command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui);
-  command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui);
-  command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui);
-  command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui);
-  command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS, show_main_ui);
-  command_updater_.UpdateCommandEnabled(IDC_COMPACT_NAVBAR, show_main_ui);
-#if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC)
-  command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui);
-#endif
+void Browser::WindowFullscreenStateChanged() {
+  UpdateCommandsForFullscreenMode(window_->IsFullscreen());
+  UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TOGGLE_FULLSCREEN);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1611,10 +1564,16 @@
 
   UserMetrics::RecordAction(UserMetricsAction("ToggleFullscreen"));
   window_->SetFullscreen(!window_->IsFullscreen());
-  // On X11, setting fullscreen mode is an async call to the X server, which
-  // may or may not support fullscreen mode.
-#if !defined(USE_X11)
-  UpdateCommandsForFullscreenMode(window_->IsFullscreen());
+
+  // Once the window has become fullscreen it'll call back to
+  // WindowFullscreenStateChanged(). We don't do this immediately as
+  // BrowserWindow::SetFullscreen() asks for bookmark_bar_state_, so we let the
+  // BrowserWindow invoke WindowFullscreenStateChanged when appropriate.
+
+  // TODO: convert mac to invoke WindowFullscreenStateChanged once it updates
+  // the necessary state of the frame.
+#if defined(OS_MACOSX)
+  WindowFullscreenStateChanged();
 #endif
 }
 
@@ -3937,6 +3896,58 @@
   UpdateCommandsForBookmarkEditing();
 }
 
+void Browser::UpdateCommandsForFullscreenMode(bool is_fullscreen) {
+#if !defined(OS_MACOSX)
+  const bool show_main_ui = is_type_tabbed() && !is_fullscreen;
+#else
+  const bool show_main_ui = is_type_tabbed();
+#endif
+
+  bool main_not_fullscreen = show_main_ui && !is_fullscreen;
+
+  // Navigation commands
+  command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui);
+
+  // Window management commands
+  command_updater_.UpdateCommandEnabled(IDC_SHOW_AS_TAB,
+      type_ != TYPE_TABBED && !is_fullscreen);
+
+  // Focus various bits of UI
+  command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui);
+  command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_main_ui);
+  command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui);
+  command_updater_.UpdateCommandEnabled(
+      IDC_FOCUS_MENU_BAR, main_not_fullscreen);
+  command_updater_.UpdateCommandEnabled(
+      IDC_FOCUS_NEXT_PANE, main_not_fullscreen);
+  command_updater_.UpdateCommandEnabled(
+      IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen);
+  command_updater_.UpdateCommandEnabled(
+      IDC_FOCUS_BOOKMARKS, main_not_fullscreen);
+  command_updater_.UpdateCommandEnabled(
+      IDC_FOCUS_CHROMEOS_STATUS, main_not_fullscreen);
+
+  // Show various bits of UI
+  command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui);
+  command_updater_.UpdateCommandEnabled(IDC_FEEDBACK, show_main_ui);
+  command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR,
+      browser_defaults::bookmarks_enabled && show_main_ui);
+  command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, show_main_ui);
+  command_updater_.UpdateCommandEnabled(IDC_SYNC_BOOKMARKS,
+      show_main_ui && profile_->IsSyncAccessible());
+
+  command_updater_.UpdateCommandEnabled(IDC_OPTIONS, show_main_ui);
+  command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui);
+  command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui);
+  command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui);
+  command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui);
+  command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS, show_main_ui);
+  command_updater_.UpdateCommandEnabled(IDC_COMPACT_NAVBAR, show_main_ui);
+#if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC)
+  command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui);
+#endif
+}
+
 void Browser::UpdateCommandsForTabState() {
   TabContents* current_tab = GetSelectedTabContents();
   TabContentsWrapper* current_tab_wrapper = GetSelectedTabContentsWrapper();
@@ -4684,8 +4695,10 @@
 
 void Browser::UpdateBookmarkBarState(BookmarkBarStateChangeReason reason) {
   BookmarkBar::State state;
-  if (profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) &&
-      profile_->GetPrefs()->GetBoolean(prefs::kEnableBookmarkBar)) {
+  // The bookmark bar is hidden in fullscreen mode, unless on the new tab page.
+  if ((profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) &&
+       profile_->GetPrefs()->GetBoolean(prefs::kEnableBookmarkBar)) &&
+      (!window_ || !window_->IsFullscreen())) {
     state = BookmarkBar::SHOW;
   } else {
     TabContentsWrapper* tab = GetSelectedTabContentsWrapper();
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index 850e5ca..e6c5a78 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -460,11 +460,10 @@
   // is created.
   void ShowSingletonTab(const GURL& url);
 
-  // Update commands whose state depends on whether the window is in fullscreen
-  // mode. This is a public function because on Linux, fullscreen mode is an
-  // async call to X. Once we get the fullscreen callback, the browser window
-  // will call this method.
-  void UpdateCommandsForFullscreenMode(bool is_fullscreen);
+  // Invoked when the fullscreen state of the window changes.
+  // BrowserWindow::SetFullscreen invokes this after the window has become
+  // fullscreen.
+  void WindowFullscreenStateChanged();
 
   // Assorted browser commands ////////////////////////////////////////////////
 
@@ -803,6 +802,9 @@
 
     // Change is the result of a state change in the active tab.
     BOOKMARK_BAR_STATE_CHANGE_TAB_STATE,
+
+    // Change is the result of window toggling in/out of fullscreen mode.
+    BOOKMARK_BAR_STATE_CHANGE_TOGGLE_FULLSCREEN,
   };
 
   // Overridden from TabContentsDelegate:
@@ -939,6 +941,10 @@
   // Updates commands for bookmark editing.
   void UpdateCommandsForBookmarkEditing();
 
+  // Update commands whose state depends on whether the window is in fullscreen
+  // mode.
+  void UpdateCommandsForFullscreenMode(bool is_fullscreen);
+
   // Updates the printing command state.
   void UpdatePrintingState(int content_restrictions);
 
diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.cc b/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.cc
index 1ec64b3..db428cf 100644
--- a/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.cc
+++ b/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.cc
@@ -17,7 +17,6 @@
 #include "chrome/browser/prefs/pref_service.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/sync_ui_util.h"
-#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/gtk/bookmarks/bookmark_menu_controller_gtk.h"
 #include "chrome/browser/ui/gtk/bookmarks/bookmark_tree_model.h"
@@ -34,8 +33,6 @@
 #include "chrome/browser/ui/gtk/tabs/tab_strip_gtk.h"
 #include "chrome/browser/ui/gtk/tabstrip_origin_provider.h"
 #include "chrome/browser/ui/gtk/view_id_util.h"
-#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
-#include "chrome/common/chrome_switches.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/common/pref_names.h"
 #include "content/browser/tab_contents/tab_contents.h"
@@ -56,15 +53,15 @@
 // The showing height of the bar.
 const int kBookmarkBarHeight = 29;
 
-// Padding for when the bookmark bar is floating.
+// Padding for when the bookmark bar is detached.
 const int kTopBottomNTPPadding = 12;
 const int kLeftRightNTPPadding = 8;
 
-// Padding around the bar's content area when the bookmark bar is floating.
+// Padding around the bar's content area when the bookmark bar is detached.
 const int kNTPPadding = 2;
 
 // The number of pixels of rounding on the corners of the bookmark bar content
-// area when in floating mode.
+// area when in detached mode.
 const int kNTPRoundedness = 3;
 
 // The height of the bar when it is "hidden". It is usually not completely
@@ -141,10 +138,10 @@
       show_instructions_(true),
       menu_bar_helper_(this),
       slide_animation_(this),
-      floating_(false),
       last_allocation_width_(-1),
       throbbing_widget_(NULL),
-      method_factory_(this) {
+      method_factory_(this),
+      bookmark_bar_state_(BookmarkBar::DETACHED) {
   if (profile->GetProfileSyncService()) {
     // Obtain a pointer to the profile sync service and add our instance as an
     // observer.
@@ -155,8 +152,9 @@
   Init(profile);
   SetProfile(profile);
   // Force an update by simulating being in the wrong state.
-  floating_ = !ShouldBeFloating();
-  UpdateFloatingState();
+  // BrowserWindowGtk sets our true state after we're created.
+  SetBookmarkBarState(BookmarkBar::SHOW,
+                      BookmarkBar::DONT_ANIMATE_STATE_CHANGE);
 
   registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
                  Source<ThemeService>(theme_service_));
@@ -303,13 +301,28 @@
   gtk_widget_hide(widget());
 }
 
-void BookmarkBarGtk::Show(bool animate) {
+void BookmarkBarGtk::SetBookmarkBarState(
+    BookmarkBar::State state,
+    BookmarkBar::AnimateChangeType animate_type) {
+  if (animate_type == BookmarkBar::ANIMATE_STATE_CHANGE &&
+      (state == BookmarkBar::DETACHED ||
+       bookmark_bar_state_ == BookmarkBar::DETACHED)) {
+    // TODO(estade): animate the transition between detached and non.
+    animate_type = BookmarkBar::DONT_ANIMATE_STATE_CHANGE;
+  }
+  BookmarkBar::State old_state = bookmark_bar_state_;
+  bookmark_bar_state_ = state;
+  if (state == BookmarkBar::SHOW || state == BookmarkBar::DETACHED)
+    Show(old_state, animate_type);
+  else
+    Hide(old_state, animate_type);
+}
+
+void BookmarkBarGtk::Show(BookmarkBar::State old_state,
+                          BookmarkBar::AnimateChangeType animate_type) {
   gtk_widget_show_all(widget());
-  bool old_floating = floating_;
-  UpdateFloatingState();
-  // TODO(estade): animate the transition between floating and non.
-  animate = animate && (old_floating == floating_);
-  if (animate) {
+  UpdateDetachedState(old_state);
+  if (animate_type == BookmarkBar::ANIMATE_STATE_CHANGE) {
     slide_animation_.Show();
   } else {
     slide_animation_.Reset(1);
@@ -318,7 +331,7 @@
 
   // Hide out behind the findbar. This is rather fragile code, it could
   // probably be improved.
-  if (floating_) {
+  if (bookmark_bar_state_ == BookmarkBar::DETACHED) {
     if (theme_service_->UsingNativeTheme()) {
       if (GTK_WIDGET_REALIZED(event_box_->parent))
         gdk_window_lower(event_box_->parent->window);
@@ -355,15 +368,17 @@
   SetChevronState();
 }
 
-void BookmarkBarGtk::Hide(bool animate) {
-  UpdateFloatingState();
+void BookmarkBarGtk::Hide(BookmarkBar::State old_state,
+                          BookmarkBar::AnimateChangeType animate_type) {
+  UpdateDetachedState(old_state);
 
   // After coming out of fullscreen, the browser window sets the bookmark bar
   // to the "hidden" state, which means we need to show our minimum height.
   gtk_widget_show(widget());
   // Sometimes we get called without a matching call to open. If that happens
   // then force hide.
-  if (slide_animation_.IsShowing() && animate) {
+  if (slide_animation_.IsShowing() &&
+      animate_type == BookmarkBar::ANIMATE_STATE_CHANGE) {
     slide_animation_.Hide();
   } else {
     gtk_widget_hide(bookmark_hbox_);
@@ -384,13 +399,6 @@
   browser_->OpenImportSettingsDialog();
 }
 
-void BookmarkBarGtk::EnterFullscreen() {
-  if (ShouldBeFloating())
-    Show(false);
-  else
-    gtk_widget_hide(widget());
-}
-
 int BookmarkBarGtk::GetHeight() {
   return event_box_->allocation.height - kBookmarkBarMinimumHeight;
 }
@@ -399,12 +407,6 @@
   return slide_animation_.is_animating();
 }
 
-bool BookmarkBarGtk::OnNewTabPage() {
-  return (browser_ && browser_->GetSelectedTabContentsWrapper() &&
-          browser_->GetSelectedTabContentsWrapper()->bookmark_tab_helper()->
-          ShouldShowBookmarkBar());
-}
-
 void BookmarkBarGtk::Loaded(BookmarkModel* model) {
   // If |instructions_| has been nulled, we are in the middle of browser
   // shutdown. Do nothing.
@@ -628,27 +630,14 @@
   return rv;
 }
 
-bool BookmarkBarGtk::ShouldBeFloating() {
-  // NTP4 never floats the bookmark bar.
-  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kNewTabPage4))
-    return false;
-
-  return (!IsAlwaysShown() || (window_ && window_->IsFullscreen())) &&
-      window_ && window_->GetDisplayedTab() &&
-      window_->GetDisplayedTab()->bookmark_tab_helper()->
-      ShouldShowBookmarkBar();
-}
-
-void BookmarkBarGtk::UpdateFloatingState() {
-  bool old_floating = floating_;
-  floating_ = ShouldBeFloating();
-  if (floating_ == old_floating)
+void BookmarkBarGtk::UpdateDetachedState(BookmarkBar::State old_state) {
+  bool old_detached = old_state == BookmarkBar::DETACHED;
+  bool detached = bookmark_bar_state_ == BookmarkBar::DETACHED;
+  if (detached == old_detached)
     return;
 
-  if (floating_) {
-#if !defined(OS_CHROMEOS)
+  if (detached) {
     gtk_event_box_set_visible_window(GTK_EVENT_BOX(paint_box_), TRUE);
-#endif
     GdkColor stroke_color = theme_service_->UsingNativeTheme() ?
         theme_service_->GetBorderColor() :
         theme_service_->GetGdkColor(ThemeService::COLOR_NTP_HEADER);
@@ -661,42 +650,34 @@
     gtk_container_set_border_width(GTK_CONTAINER(bookmark_hbox_), kNTPPadding);
   } else {
     gtk_util::StopActingAsRoundedWindow(paint_box_);
-#if !defined(OS_CHROMEOS)
     gtk_event_box_set_visible_window(GTK_EVENT_BOX(paint_box_), FALSE);
-#endif
     gtk_alignment_set_padding(GTK_ALIGNMENT(ntp_padding_box_), 0, 0, 0, 0);
     gtk_container_set_border_width(GTK_CONTAINER(bookmark_hbox_), 0);
   }
 
   UpdateEventBoxPaintability();
   // |window_| can be NULL during testing.
-  if (window_) {
-    window_->BookmarkBarIsFloating(floating_);
-
-    // Listen for parent size allocations.
-    if (floating_ && widget()->parent) {
-      // Only connect once.
-      if (g_signal_handler_find(widget()->parent, G_SIGNAL_MATCH_FUNC,
+  // Listen for parent size allocations. Only connect once.
+  if (window_ && detached && widget()->parent &&
+      g_signal_handler_find(widget()->parent, G_SIGNAL_MATCH_FUNC,
           0, 0, NULL, reinterpret_cast<gpointer>(OnParentSizeAllocateThunk),
           NULL) == 0) {
-        g_signal_connect(widget()->parent, "size-allocate",
-                         G_CALLBACK(OnParentSizeAllocateThunk), this);
-      }
-    }
+    g_signal_connect(widget()->parent, "size-allocate",
+                     G_CALLBACK(OnParentSizeAllocateThunk), this);
   }
 }
 
 void BookmarkBarGtk::UpdateEventBoxPaintability() {
   gtk_widget_set_app_paintable(
-      event_box_.get(), !theme_service_->UsingNativeTheme() || floating_);
+      event_box_.get(),
+      (!theme_service_->UsingNativeTheme() ||
+       bookmark_bar_state_ == BookmarkBar::DETACHED));
   // When using the GTK+ theme, we need to have the event box be visible so
   // buttons don't get a halo color from the background.  When using Chromium
   // themes, we want to let the background show through the toolbar.
 
-#if !defined(OS_CHROMEOS)
   gtk_event_box_set_visible_window(GTK_EVENT_BOX(event_box_.get()),
                                    theme_service_->UsingNativeTheme());
-#endif
 }
 
 void BookmarkBarGtk::PaintEventBox() {
@@ -803,15 +784,10 @@
       item, "size-allocate", G_CALLBACK(OnItemAllocateThunk), this);
 }
 
-bool BookmarkBarGtk::IsAlwaysShown() {
-  return (profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar) &&
-          profile_->GetPrefs()->GetBoolean(prefs::kEnableBookmarkBar));
-}
-
 void BookmarkBarGtk::AnimationProgressed(const ui::Animation* animation) {
   DCHECK_EQ(animation, &slide_animation_);
 
-  int max_height = ShouldBeFloating() ?
+  int max_height = (bookmark_bar_state_ == BookmarkBar::DETACHED) ?
                    kBookmarkBarNTPHeight : kBookmarkBarHeight;
   gint height =
       static_cast<gint>(animation->GetCurrentValue() *
@@ -854,7 +830,7 @@
         theme_service_->GetGdkColor(ThemeService::COLOR_TOOLBAR);
     gtk_widget_modify_bg(paint_box_, GTK_STATE_NORMAL, &paint_box_color);
 
-    if (floating_) {
+    if (bookmark_bar_state_ == BookmarkBar::DETACHED) {
       GdkColor stroke_color = theme_service_->UsingNativeTheme() ?
           theme_service_->GetBorderColor() :
           theme_service_->GetGdkColor(ThemeService::COLOR_NTP_HEADER);
@@ -1354,10 +1330,11 @@
 
   // We don't need to render the toolbar image in GTK mode, except when
   // detached.
-  if (theme_provider->UsingNativeTheme() && !floating_)
+  if (theme_provider->UsingNativeTheme() &&
+      bookmark_bar_state_ != BookmarkBar::DETACHED)
     return FALSE;
 
-  if (!floating_) {
+  if (bookmark_bar_state_ != BookmarkBar::DETACHED) {
     cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
     gdk_cairo_rectangle(cr, &event->area);
     cairo_clip(cr);
@@ -1395,12 +1372,12 @@
 
 void BookmarkBarGtk::OnParentSizeAllocate(GtkWidget* widget,
                                           GtkAllocation* allocation) {
-  // In floating mode, our layout depends on the size of the tab contents.
+  // In detached mode, our layout depends on the size of the tab contents.
   // We get the size-allocate signal before the tab contents does, hence we
   // need to post a delayed task so we will paint correctly. Note that
   // gtk_widget_queue_draw by itself does not work, despite that it claims to
   // be asynchronous.
-  if (floating_) {
+  if (bookmark_bar_state_ == BookmarkBar::DETACHED) {
     MessageLoop::current()->PostTask(FROM_HERE,
         method_factory_.NewRunnableMethod(
             &BookmarkBarGtk::PaintEventBox));
diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.h b/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.h
index 4be3e55b..e337993a 100644
--- a/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.h
+++ b/chrome/browser/ui/gtk/bookmarks/bookmark_bar_gtk.h
@@ -16,6 +16,7 @@
 #include "chrome/browser/bookmarks/bookmark_model_observer.h"
 #include "chrome/browser/prefs/pref_member.h"
 #include "chrome/browser/sync/profile_sync_service.h"
+#include "chrome/browser/ui/bookmarks/bookmark_bar.h"
 #include "chrome/browser/ui/gtk/bookmarks/bookmark_bar_instructions_gtk.h"
 #include "chrome/browser/ui/gtk/menu_bar_helper.h"
 #include "chrome/browser/ui/gtk/owned_widget_gtk.h"
@@ -73,21 +74,9 @@
   // Create the contents of the bookmark bar.
   void Init(Profile* profile);
 
-  // Whether the current page is the New Tag Page (which requires different
-  // rendering).
-  bool OnNewTabPage();
-
-  // Change the visibility of the bookmarks bar. (Starts out hidden, per GTK's
-  // default behaviour). There are three visiblity states:
-  //
-  //   Showing    - bookmark bar is fully visible.
-  //   Hidden     - bookmark bar is hidden except for a few pixels that give
-  //                extra padding to the bottom of the toolbar. Buttons are not
-  //                clickable.
-  //   Fullscreen - bookmark bar is fully hidden.
-  void Show(bool animate);
-  void Hide(bool animate);
-  void EnterFullscreen();
+  // Changes the state of the bookmark bar.
+  void SetBookmarkBarState(BookmarkBar::State state,
+                           BookmarkBar::AnimateChangeType animate_type);
 
   // Get the current height of the bookmark bar.
   int GetHeight();
@@ -95,9 +84,6 @@
   // Returns true if the bookmark bar is showing an animation.
   bool IsAnimating();
 
-  // Returns true if the bookmarks bar preference is set to 'always show'.
-  bool IsAlwaysShown();
-
   // ui::AnimationDelegate implementation --------------------------------------
   virtual void AnimationProgressed(const ui::Animation* animation);
   virtual void AnimationEnded(const ui::Animation* animation);
@@ -121,6 +107,19 @@
                            HidesHelpMessageWithBookmark);
   FRIEND_TEST_ALL_PREFIXES(BookmarkBarGtkUnittest, BuildsButtons);
 
+  // Change the visibility of the bookmarks bar. (Starts out hidden, per GTK's
+  // default behaviour). There are three visiblity states:
+  //
+  //   Showing    - bookmark bar is fully visible.
+  //   Hidden     - bookmark bar is hidden except for a few pixels that give
+  //                extra padding to the bottom of the toolbar. Buttons are not
+  //                clickable.
+  //   Fullscreen - bookmark bar is fully hidden.
+  void Show(BookmarkBar::State old_state,
+            BookmarkBar::AnimateChangeType animate_type);
+  void Hide(BookmarkBar::State old_state,
+            BookmarkBar::AnimateChangeType animate_type);
+
   // Helper function which generates GtkToolItems for |bookmark_toolbar_|.
   void CreateAllBookmarkButtons();
 
@@ -153,11 +152,8 @@
   int GetFirstHiddenBookmark(int extra_space,
                              std::vector<GtkWidget*>* showing_folders);
 
-  // Returns true if the bookmark bar should be floating on the page (for
-  // NTP).
-  bool ShouldBeFloating();
-  // Update the floating state (either enable or disable it, or do nothing).
-  void UpdateFloatingState();
+  // Update the detached state (either enable or disable it, or do nothing).
+  void UpdateDetachedState(BookmarkBar::State old_state);
 
   // Turns on or off the app_paintable flag on |event_box_|, depending on our
   // state.
@@ -321,10 +317,10 @@
   // background color from the toplevel application window's GDK window.
   OwnedWidgetGtk event_box_;
 
-  // Used to float the bookmark bar when on the NTP.
+  // Used to detached the bookmark bar when on the NTP.
   GtkWidget* ntp_padding_box_;
 
-  // Used to paint the background of the bookmark bar when in floating mode.
+  // Used to paint the background of the bookmark bar when in detached mode.
   GtkWidget* paint_box_;
 
   // Used to position all children.
@@ -385,11 +381,6 @@
 
   ui::SlideAnimation slide_animation_;
 
-  // Whether we are currently configured as floating (detached from the
-  // toolbar). This reflects our actual state, and can be out of sync with
-  // what ShouldShowFloating() returns.
-  bool floating_;
-
   // Used to optimize out |bookmark_toolbar_| size-allocate events we don't
   // need to respond to.
   int last_allocation_width_;
@@ -412,6 +403,10 @@
   BooleanPrefMember edit_bookmarks_enabled_;
 
   ScopedRunnableMethodFactory<BookmarkBarGtk> method_factory_;
+
+  BookmarkBar::State bookmark_bar_state_;
+
+  DISALLOW_COPY_AND_ASSIGN(BookmarkBarGtk);
 };
 
 #endif  // CHROME_BROWSER_UI_GTK_BOOKMARKS_BOOKMARK_BAR_GTK_H_
diff --git a/chrome/browser/ui/gtk/browser_window_gtk.cc b/chrome/browser/ui/gtk/browser_window_gtk.cc
index 85fa82cb..96a9670 100644
--- a/chrome/browser/ui/gtk/browser_window_gtk.cc
+++ b/chrome/browser/ui/gtk/browser_window_gtk.cc
@@ -303,7 +303,6 @@
 BrowserWindowGtk::BrowserWindowGtk(Browser* browser)
     :  browser_(browser),
        state_(GDK_WINDOW_STATE_WITHDRAWN),
-       bookmark_bar_is_floating_(false),
        frame_cursor_(NULL),
        is_active_(!ui::ActiveWindowWatcherX::WMSupportsActivation()),
        last_click_time_(0),
@@ -756,7 +755,6 @@
 
 void BrowserWindowGtk::BookmarkBarStateChanged(
     BookmarkBar::AnimateChangeType change_type) {
-  // TODO(sky): fix other sites like on views.
   MaybeShowBookmarkBar(change_type == BookmarkBar::ANIMATE_STATE_CHANGE);
 }
 
@@ -1284,28 +1282,22 @@
     return;
 
   TabContentsWrapper* tab = GetDisplayedTab();
-  bool show_bar = false;
 
   if (tab) {
     bookmark_bar_->SetProfile(tab->profile());
     bookmark_bar_->SetPageNavigator(tab->tab_contents());
-    show_bar = true;
   }
 
-  if (show_bar && tab && !tab->bookmark_tab_helper()->ShouldShowBookmarkBar()) {
-    PrefService* prefs = tab->profile()->GetPrefs();
-    show_bar = prefs->GetBoolean(prefs::kShowBookmarkBar) &&
-               prefs->GetBoolean(prefs::kEnableBookmarkBar) &&
-               !IsFullscreen();
-  }
+  BookmarkBar::State state = browser_->bookmark_bar_state();
+  if (contents_container_->HasPreview() && state == BookmarkBar::DETACHED)
+    state = BookmarkBar::HIDDEN;
 
-  if (show_bar) {
-    bookmark_bar_->Show(animate);
-  } else if (IsFullscreen()) {
-    bookmark_bar_->EnterFullscreen();
-  } else {
-    bookmark_bar_->Hide(animate);
-  }
+  bookmark_bar_->SetBookmarkBarState(
+      state,
+      animate ? BookmarkBar::ANIMATE_STATE_CHANGE :
+                BookmarkBar::DONT_ANIMATE_STATE_CHANGE);
+  toolbar_->UpdateForBookmarkBarVisibility(state == BookmarkBar::DETACHED);
+  PlaceBookmarkBar(state == BookmarkBar::DETACHED);
 }
 
 void BrowserWindowGtk::UpdateDevToolsForContents(TabContents* contents) {
@@ -1422,14 +1414,11 @@
   state_ = event->new_window_state;
 
   if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
-    bool is_fullscreen = state_ & GDK_WINDOW_STATE_FULLSCREEN;
-    browser_->UpdateCommandsForFullscreenMode(is_fullscreen);
-    if (is_fullscreen) {
+    browser_->WindowFullscreenStateChanged();
+    if (state_ & GDK_WINDOW_STATE_FULLSCREEN) {
       UpdateCustomFrame();
       toolbar_->Hide();
       tabstrip_->Hide();
-      if (IsBookmarkBarSupported())
-        bookmark_bar_->EnterFullscreen();
       bool is_kiosk =
           CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode);
       if (!is_kiosk) {
@@ -1573,15 +1562,6 @@
                              PrefService::SYNCABLE_PREF);
 }
 
-void BrowserWindowGtk::BookmarkBarIsFloating(bool is_floating) {
-  bookmark_bar_is_floating_ = is_floating;
-  toolbar_->UpdateForBookmarkBarVisibility(is_floating);
-
-  // This can be NULL during initialization of the bookmark bar.
-  if (bookmark_bar_.get())
-    PlaceBookmarkBar(is_floating);
-}
-
 TabContentsWrapper* BrowserWindowGtk::GetDisplayedTab() {
   return contents_container_->GetVisibleTab();
 }
@@ -1920,8 +1900,10 @@
 void BrowserWindowGtk::InvalidateInfoBarBits() {
   gtk_widget_queue_draw(toolbar_border_);
   gtk_widget_queue_draw(toolbar_->widget());
-  if (bookmark_bar_.get() && !bookmark_bar_is_floating_)
+  if (bookmark_bar_.get() &&
+      browser_->bookmark_bar_state() != BookmarkBar::DETACHED) {
     gtk_widget_queue_draw(bookmark_bar_->widget());
+  }
 }
 
 int BrowserWindowGtk::GetXPositionOfLocationIcon(GtkWidget* relative_to) {
@@ -1955,7 +1937,7 @@
 
 gboolean BrowserWindowGtk::OnBookmarkBarExpose(GtkWidget* sender,
                                                GdkEventExpose* expose) {
-  if (bookmark_bar_is_floating_)
+  if (browser_->bookmark_bar_state() == BookmarkBar::DETACHED)
     return FALSE;
 
   return OnExposeDrawInfobarBits(sender, expose);
@@ -1970,7 +1952,7 @@
 
   // Pass the new size to our infobar container.
   int arrow_size = InfoBar::kDefaultArrowTargetHeight;
-  if (!bookmark_bar_is_floating_)
+  if (browser_->bookmark_bar_state() != BookmarkBar::DETACHED)
     arrow_size += allocation->height;
   infobar_container_->SetMaxTopArrowHeight(arrow_size);
 }
diff --git a/chrome/browser/ui/gtk/browser_window_gtk.h b/chrome/browser/ui/gtk/browser_window_gtk.h
index 43b2f9b..a686695 100644
--- a/chrome/browser/ui/gtk/browser_window_gtk.h
+++ b/chrome/browser/ui/gtk/browser_window_gtk.h
@@ -200,10 +200,6 @@
 
   gfx::Rect bounds() const { return bounds_; }
 
-  // Make changes necessary when the floating state of the bookmark bar changes.
-  // This should only be called by the bookmark bar itself.
-  void BookmarkBarIsFloating(bool is_floating);
-
   // Returns the tab we're currently displaying in the tab contents container.
   TabContentsWrapper* GetDisplayedTab();
 
@@ -443,9 +439,6 @@
   // bookmark bar is not supported.
   scoped_ptr<BookmarkBarGtk> bookmark_bar_;
 
-  // Caches the hover state of the bookmark bar.
-  bool bookmark_bar_is_floating_;
-
   // The status bubble manager.  Always non-NULL.
   scoped_ptr<StatusBubbleGtk> status_bubble_;
 
diff --git a/chrome/browser/ui/gtk/tab_contents_container_gtk.h b/chrome/browser/ui/gtk/tab_contents_container_gtk.h
index 0bcc19a..f3e48c2 100644
--- a/chrome/browser/ui/gtk/tab_contents_container_gtk.h
+++ b/chrome/browser/ui/gtk/tab_contents_container_gtk.h
@@ -37,6 +37,8 @@
   // Returns the TabContentsWrapper currently displayed.
   TabContentsWrapper* GetVisibleTab();
 
+  bool HasPreview() const { return preview_ != NULL; }
+
   void SetPreview(TabContentsWrapper* preview);
   void PopPreview();
 
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
index 25a0c4fd..0f2974d 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -457,13 +457,6 @@
   bookmark_bar_state_ = state;
 }
 
-void BookmarkBarView::OnFullscreenToggled(bool fullscreen) {
-  if (!fullscreen)
-    size_animation_->Reset(bookmark_bar_state_ == BookmarkBar::SHOW ? 1 : 0);
-  else if (bookmark_bar_state_ == BookmarkBar::SHOW)
-    size_animation_->Reset(0);
-}
-
 int BookmarkBarView::GetToolbarOverlap(bool return_max) const {
   // When not detached, always overlap by the full amount.
   if (return_max || bookmark_bar_state_ != BookmarkBar::DETACHED)
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
index 763f7b70..1126736 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.h
@@ -94,9 +94,6 @@
   void SetBookmarkBarState(BookmarkBar::State state,
                            BookmarkBar::AnimateChangeType animate_type);
 
-  // Called when fullscreen mode toggles on or off; this affects our layout.
-  void OnFullscreenToggled(bool fullscreen);
-
   // How much we want the bookmark bar to overlap the toolbar.  If |return_max|
   // is true, we return the maximum overlap rather than the current overlap.
   int GetToolbarOverlap(bool return_max) const;
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index dd401d3..ce61c33 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -2279,23 +2279,13 @@
       PushForceHidden();
 #endif
 
-  // Notify bookmark bar, so it can set itself to the appropriate drawing state.
-  if (bookmark_bar_view_.get())
-    bookmark_bar_view_->OnFullscreenToggled(fullscreen);
-
   // Toggle fullscreen mode.
 #if defined(OS_WIN)
   frame_->SetFullscreen(fullscreen);
 #endif  // No need to invoke SetFullscreen for linux as this code is executed
         // once we're already fullscreen on linux.
 
-#if defined(TOOLKIT_USES_GTK)
-  // Updating of commands for fullscreen mode is called from SetFullScreen on
-  // Wndows (see just above), but for ChromeOS, this method (ProcessFullScreen)
-  // is called after full screen has happened successfully (via GTK's
-  // window-state-change event), so we have to update commands here.
-  browser_->UpdateCommandsForFullscreenMode(fullscreen);
-#endif
+  browser_->WindowFullscreenStateChanged();
 
   if (fullscreen) {
     bool is_kiosk =