| Index: chrome/browser/ui/panels/docked_panel_collection.cc | 
| diff --git a/chrome/browser/ui/panels/docked_panel_collection.cc b/chrome/browser/ui/panels/docked_panel_collection.cc | 
| deleted file mode 100644 | 
| index 9ded24d408948104ee458633e5292aa2fdb481b2..0000000000000000000000000000000000000000 | 
| --- a/chrome/browser/ui/panels/docked_panel_collection.cc | 
| +++ /dev/null | 
| @@ -1,781 +0,0 @@ | 
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
| -// Use of this source code is governed by a BSD-style license that can be | 
| -// found in the LICENSE file. | 
| - | 
| -#include "chrome/browser/ui/panels/docked_panel_collection.h" | 
| - | 
| -#include <math.h> | 
| - | 
| -#include <algorithm> | 
| -#include <queue> | 
| -#include <vector> | 
| - | 
| -#include "base/auto_reset.h" | 
| -#include "base/bind.h" | 
| -#include "base/location.h" | 
| -#include "base/logging.h" | 
| -#include "base/single_thread_task_runner.h" | 
| -#include "base/threading/thread_task_runner_handle.h" | 
| -#include "chrome/browser/chrome_notification_types.h" | 
| -#include "chrome/browser/ui/panels/panel_drag_controller.h" | 
| -#include "chrome/browser/ui/panels/panel_manager.h" | 
| -#include "chrome/browser/ui/panels/panel_mouse_watcher.h" | 
| -#include "content/public/browser/notification_service.h" | 
| -#include "content/public/browser/notification_source.h" | 
| - | 
| -namespace { | 
| -// Width of spacing around panel collection and the left/right edges of the | 
| -// screen. | 
| -const int kPanelCollectionLeftMargin = 6; | 
| -const int kPanelCollectionRightMargin = 24; | 
| - | 
| -// Occasionally some system, like Windows, might not bring up or down the bottom | 
| -// bar when the mouse enters or leaves the bottom screen area. This is the | 
| -// maximum time we will wait for the bottom bar visibility change notification. | 
| -// After the time expires, we bring up/down the titlebars as planned. | 
| -const int kMaxDelayWaitForBottomBarVisibilityChangeMs = 1000; | 
| - | 
| -// After focus changed, one panel lost active status, another got it, | 
| -// we refresh layout with a delay. | 
| -const int kRefreshLayoutAfterActivePanelChangeDelayMs = 600;  // arbitrary | 
| - | 
| -// As we refresh panel positions, some or all panels may move. We make sure | 
| -// we do not animate too many panels at once as this tends to perform poorly. | 
| -const int kNumPanelsToAnimateSimultaneously = 3; | 
| - | 
| -}  // namespace | 
| - | 
| -DockedPanelCollection::DockedPanelCollection(PanelManager* panel_manager) | 
| -    : PanelCollection(PanelCollection::DOCKED), | 
| -      panel_manager_(panel_manager), | 
| -      minimized_panel_count_(0), | 
| -      are_titlebars_up_(false), | 
| -      minimizing_all_(false), | 
| -      delayed_titlebar_action_(NO_ACTION), | 
| -      titlebar_action_factory_(this), | 
| -      refresh_action_factory_(this) { | 
| -  panel_manager_->display_settings_provider()->AddDesktopBarObserver(this); | 
| -  OnDisplayChanged(); | 
| -} | 
| - | 
| -DockedPanelCollection::~DockedPanelCollection() { | 
| -  DCHECK(panels_.empty()); | 
| -  DCHECK_EQ(0, minimized_panel_count_); | 
| -  panel_manager_->display_settings_provider()->RemoveDesktopBarObserver(this); | 
| -} | 
| - | 
| -void DockedPanelCollection::OnDisplayChanged() { | 
| -  work_area_ = | 
| -      panel_manager_->display_settings_provider()->GetPrimaryWorkArea(); | 
| -  work_area_.set_x(work_area_.x() + kPanelCollectionLeftMargin); | 
| -  work_area_.set_width(work_area_.width() - | 
| -      kPanelCollectionLeftMargin - kPanelCollectionRightMargin); | 
| - | 
| -  if (panels_.empty()) | 
| -    return; | 
| - | 
| -  for (Panels::const_iterator iter = panels_.begin(); | 
| -       iter != panels_.end(); ++iter) { | 
| -    (*iter)->LimitSizeToWorkArea(work_area_); | 
| -  } | 
| - | 
| -  RefreshLayout(); | 
| -} | 
| - | 
| -void DockedPanelCollection::AddPanel(Panel* panel, | 
| -                                PositioningMask positioning_mask) { | 
| -  // This method does not handle minimized panels. | 
| -  DCHECK_EQ(Panel::EXPANDED, panel->expansion_state()); | 
| - | 
| -  DCHECK(panel->initialized()); | 
| -  DCHECK_NE(this, panel->collection()); | 
| -  panel->set_collection(this); | 
| - | 
| -  bool default_position = (positioning_mask & KNOWN_POSITION) == 0; | 
| -  bool update_bounds = (positioning_mask & DO_NOT_UPDATE_BOUNDS) == 0; | 
| - | 
| -  if (default_position) { | 
| -    gfx::Size full_size = panel->full_size(); | 
| -    gfx::Point pt = GetDefaultPositionForPanel(full_size); | 
| -    panel->SetPanelBounds(gfx::Rect(pt, full_size)); | 
| -    panels_.push_back(panel); | 
| -  } else { | 
| -    DCHECK(update_bounds); | 
| -    int x = panel->GetBounds().x(); | 
| -    Panels::iterator iter = panels_.begin(); | 
| -    for (; iter != panels_.end(); ++iter) | 
| -      if (x > (*iter)->GetBounds().x()) | 
| -        break; | 
| -    panels_.insert(iter, panel); | 
| -  } | 
| - | 
| -  if (update_bounds) { | 
| -    if ((positioning_mask & DELAY_LAYOUT_REFRESH) != 0) | 
| -      ScheduleLayoutRefresh(); | 
| -    else | 
| -      RefreshLayout(); | 
| -  } | 
| -} | 
| - | 
| -gfx::Point DockedPanelCollection::GetDefaultPositionForPanel( | 
| -    const gfx::Size& full_size) const { | 
| -  int x = 0; | 
| -  if (!panels_.empty() && | 
| -      panels_.back()->GetBounds().x() < work_area_.x()) { | 
| -    // Panels go off screen. Make sure the default position will place | 
| -    // the panel in view. | 
| -    Panels::const_reverse_iterator iter = panels_.rbegin(); | 
| -    for (; iter != panels_.rend(); ++iter) { | 
| -      if ((*iter)->GetBounds().x() >= work_area_.x()) { | 
| -        x = (*iter)->GetBounds().x(); | 
| -        break; | 
| -      } | 
| -    } | 
| -    // At least one panel should fit on the screen. | 
| -    DCHECK(x > work_area_.x()); | 
| -  } else { | 
| -    x = std::max(GetRightMostAvailablePosition() - full_size.width(), | 
| -                 work_area_.x()); | 
| -  } | 
| -  return gfx::Point(x, work_area_.bottom() - full_size.height()); | 
| -} | 
| - | 
| -int DockedPanelCollection::StartingRightPosition() const { | 
| -  return work_area_.right(); | 
| -} | 
| - | 
| -int DockedPanelCollection::GetRightMostAvailablePosition() const { | 
| -  return panels_.empty() ? StartingRightPosition() : | 
| -      (panels_.back()->GetBounds().x() - kPanelsHorizontalSpacing); | 
| -} | 
| - | 
| -void DockedPanelCollection::RemovePanel(Panel* panel, RemovalReason reason) { | 
| -  DCHECK_EQ(this, panel->collection()); | 
| -  panel->set_collection(NULL); | 
| - | 
| -  // Optimize for the common case of removing the last panel. | 
| -  DCHECK(!panels_.empty()); | 
| -  if (panels_.back() == panel) { | 
| -    panels_.pop_back(); | 
| - | 
| -    // Update the saved panel placement if needed. This is because | 
| -    // we might remove |saved_panel_placement_.left_panel|. | 
| -    if (saved_panel_placement_.panel && | 
| -        saved_panel_placement_.left_panel == panel) | 
| -      saved_panel_placement_.left_panel = NULL; | 
| - | 
| -  } else { | 
| -    Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); | 
| -    DCHECK(iter != panels_.end()); | 
| -    iter = panels_.erase(iter); | 
| - | 
| -    // Update the saved panel placement if needed. This is because | 
| -    // we might remove |saved_panel_placement_.left_panel|. | 
| -    if (saved_panel_placement_.panel && | 
| -        saved_panel_placement_.left_panel == panel) | 
| -      saved_panel_placement_.left_panel = *iter; | 
| -  } | 
| - | 
| -  if (panel->expansion_state() != Panel::EXPANDED) | 
| -    UpdateMinimizedPanelCount(); | 
| - | 
| -  RefreshLayout(); | 
| -} | 
| - | 
| -void DockedPanelCollection::SavePanelPlacement(Panel* panel) { | 
| -  DCHECK(!saved_panel_placement_.panel); | 
| - | 
| -  saved_panel_placement_.panel = panel; | 
| - | 
| -  // To recover panel to its original placement, we only need to track the panel | 
| -  // that is placed after it. | 
| -  Panels::iterator iter = find(panels_.begin(), panels_.end(), panel); | 
| -  DCHECK(iter != panels_.end()); | 
| -  ++iter; | 
| -  saved_panel_placement_.left_panel = (iter == panels_.end()) ? NULL : *iter; | 
| -} | 
| - | 
| -void DockedPanelCollection::RestorePanelToSavedPlacement() { | 
| -  DCHECK(saved_panel_placement_.panel); | 
| - | 
| -  Panel* panel = saved_panel_placement_.panel; | 
| - | 
| -  // Find next panel after this panel. | 
| -  Panels::iterator iter = std::find(panels_.begin(), panels_.end(), panel); | 
| -  DCHECK(iter != panels_.end()); | 
| -  Panels::iterator next_iter = iter; | 
| -  next_iter++; | 
| -  Panel* next_panel = (next_iter == panels_.end()) ? NULL : *iter; | 
| - | 
| -  // Restoring is only needed when this panel is not in the right position. | 
| -  if (next_panel != saved_panel_placement_.left_panel) { | 
| -    // Remove this panel from its current position. | 
| -    panels_.erase(iter); | 
| - | 
| -    // Insert this panel into its previous position. | 
| -    if (saved_panel_placement_.left_panel) { | 
| -      Panels::iterator iter_to_insert_before = std::find(panels_.begin(), | 
| -          panels_.end(), saved_panel_placement_.left_panel); | 
| -      DCHECK(iter_to_insert_before != panels_.end()); | 
| -      panels_.insert(iter_to_insert_before, panel); | 
| -    } else { | 
| -      panels_.push_back(panel); | 
| -    } | 
| -  } | 
| - | 
| -  RefreshLayout(); | 
| - | 
| -  DiscardSavedPanelPlacement(); | 
| -} | 
| - | 
| -void DockedPanelCollection::DiscardSavedPanelPlacement() { | 
| -  DCHECK(saved_panel_placement_.panel); | 
| -  saved_panel_placement_.panel = NULL; | 
| -  saved_panel_placement_.left_panel = NULL; | 
| -} | 
| - | 
| -panel::Resizability DockedPanelCollection::GetPanelResizability( | 
| -    const Panel* panel) const { | 
| -  return (panel->expansion_state() == Panel::EXPANDED) ? | 
| -      panel::RESIZABLE_EXCEPT_BOTTOM : panel::NOT_RESIZABLE; | 
| -} | 
| - | 
| -void DockedPanelCollection::OnPanelResizedByMouse(Panel* panel, | 
| -                                                  const gfx::Rect& new_bounds) { | 
| -  DCHECK_EQ(this, panel->collection()); | 
| -  panel->set_full_size(new_bounds.size()); | 
| -} | 
| - | 
| -void DockedPanelCollection::OnPanelExpansionStateChanged(Panel* panel) { | 
| -  gfx::Rect panel_bounds = panel->GetBounds(); | 
| -  AdjustPanelBoundsPerExpansionState(panel, &panel_bounds); | 
| -  panel->SetPanelBounds(panel_bounds); | 
| - | 
| -  UpdateMinimizedPanelCount(); | 
| - | 
| -  // Ensure minimized panel does not get the focus. If minimizing all, | 
| -  // the active panel will be deactivated once when all panels are minimized | 
| -  // rather than per minimized panel. | 
| -  if (panel->expansion_state() != Panel::EXPANDED && !minimizing_all_ && | 
| -      panel->IsActive()) { | 
| -    panel->Deactivate(); | 
| -    // The layout will refresh itself in response | 
| -    // to (de)activation notification. | 
| -  } | 
| -} | 
| - | 
| -void DockedPanelCollection::AdjustPanelBoundsPerExpansionState(Panel* panel, | 
| -                                                          gfx::Rect* bounds) { | 
| -  Panel::ExpansionState expansion_state = panel->expansion_state(); | 
| -  switch (expansion_state) { | 
| -    case Panel::EXPANDED: | 
| -      bounds->set_height(panel->full_size().height()); | 
| - | 
| -      break; | 
| -    case Panel::TITLE_ONLY: | 
| -      bounds->set_height(panel->TitleOnlyHeight()); | 
| - | 
| -      break; | 
| -    case Panel::MINIMIZED: | 
| -      bounds->set_height(panel::kMinimizedPanelHeight); | 
| - | 
| -      break; | 
| -    default: | 
| -      NOTREACHED(); | 
| -      break; | 
| -  } | 
| - | 
| -  int bottom = GetBottomPositionForExpansionState(expansion_state); | 
| -  bounds->set_y(bottom - bounds->height()); | 
| -} | 
| - | 
| -void DockedPanelCollection::OnPanelAttentionStateChanged(Panel* panel) { | 
| -  DCHECK_EQ(this, panel->collection()); | 
| -  Panel::ExpansionState state = panel->expansion_state(); | 
| -  if (panel->IsDrawingAttention()) { | 
| -    // Bring up the titlebar to get user's attention. | 
| -    if (state == Panel::MINIMIZED) | 
| -      panel->SetExpansionState(Panel::TITLE_ONLY); | 
| -    return; | 
| -  } | 
| - | 
| -  // Panel is no longer drawing attention, but leave the panel in | 
| -  // title-only mode if all titlebars are currently up. | 
| -  if (state != Panel::TITLE_ONLY || are_titlebars_up_) | 
| -    return; | 
| - | 
| -  // Leave titlebar up if panel is being dragged. | 
| -  if (panel_manager_->drag_controller()->dragging_panel() == panel) | 
| -    return; | 
| - | 
| -  // Leave titlebar up if mouse is in/below the panel. | 
| -  const gfx::Point mouse_position = | 
| -      panel_manager_->mouse_watcher()->GetMousePosition(); | 
| -  gfx::Rect bounds = panel->GetBounds(); | 
| -  if (bounds.x() <= mouse_position.x() && | 
| -      mouse_position.x() <= bounds.right() && | 
| -      mouse_position.y() >= bounds.y()) | 
| -    return; | 
| - | 
| -  // Bring down the titlebar now that panel is not drawing attention. | 
| -  panel->SetExpansionState(Panel::MINIMIZED); | 
| -} | 
| - | 
| -void DockedPanelCollection::OnPanelTitlebarClicked(Panel* panel, | 
| -                                              panel::ClickModifier modifier) { | 
| -  DCHECK_EQ(this, panel->collection()); | 
| -  if (!IsPanelMinimized(panel)) | 
| -    return; | 
| - | 
| -  if (modifier == panel::APPLY_TO_ALL) | 
| -    RestoreAll(); | 
| -  else | 
| -    RestorePanel(panel); | 
| -} | 
| - | 
| -void DockedPanelCollection::ActivatePanel(Panel* panel) { | 
| -  DCHECK_EQ(this, panel->collection()); | 
| - | 
| -  // Make sure the panel is expanded when activated so the user input | 
| -  // does not go into a collapsed window. | 
| -  panel->SetExpansionState(Panel::EXPANDED); | 
| - | 
| -  // If the layout needs to be refreshed, it will happen in response to | 
| -  // the activation notification (and with a slight delay to let things settle). | 
| -} | 
| - | 
| -void DockedPanelCollection::MinimizePanel(Panel* panel) { | 
| -  DCHECK_EQ(this, panel->collection()); | 
| - | 
| -  if (panel->expansion_state() != Panel::EXPANDED) | 
| -    return; | 
| - | 
| -  panel->SetExpansionState(panel->IsDrawingAttention() ? | 
| -      Panel::TITLE_ONLY : Panel::MINIMIZED); | 
| -} | 
| - | 
| -void DockedPanelCollection::RestorePanel(Panel* panel) { | 
| -  DCHECK_EQ(this, panel->collection()); | 
| -  panel->SetExpansionState(Panel::EXPANDED); | 
| -} | 
| - | 
| -void DockedPanelCollection::MinimizeAll() { | 
| -  // Set minimizing_all_ to prevent deactivation of each panel when it | 
| -  // is minimized. See comments in OnPanelExpansionStateChanged. | 
| -  base::AutoReset<bool> pin(&minimizing_all_, true); | 
| -  Panel* minimized_active_panel = NULL; | 
| -  for (Panels::const_iterator iter = panels_.begin(); | 
| -       iter != panels_.end(); ++iter) { | 
| -    if ((*iter)->IsActive()) | 
| -      minimized_active_panel = *iter; | 
| -    MinimizePanel(*iter); | 
| -  } | 
| - | 
| -  // When a single panel is minimized, it is deactivated to ensure that | 
| -  // a minimized panel does not have focus. However, when minimizing all, | 
| -  // the deactivation is only done once after all panels are minimized, | 
| -  // rather than per minimized panel, both for efficiency and to avoid | 
| -  // temporary activations of random not-yet-minimized panels. | 
| -  if (minimized_active_panel) { | 
| -    minimized_active_panel->Deactivate(); | 
| -    // Layout will be refreshed in response to (de)activation notification. | 
| -  } | 
| -} | 
| - | 
| -void DockedPanelCollection::RestoreAll() { | 
| -  for (Panels::const_iterator iter = panels_.begin(); | 
| -       iter != panels_.end(); ++iter) { | 
| -    RestorePanel(*iter); | 
| -  } | 
| -} | 
| - | 
| -void DockedPanelCollection::OnMinimizeButtonClicked( | 
| -    Panel* panel, panel::ClickModifier modifier) { | 
| -  if (modifier == panel::APPLY_TO_ALL) | 
| -    MinimizeAll(); | 
| -  else | 
| -    MinimizePanel(panel); | 
| -} | 
| - | 
| -void DockedPanelCollection::OnRestoreButtonClicked( | 
| -    Panel* panel, panel::ClickModifier modifier) { | 
| -  if (modifier == panel::APPLY_TO_ALL) | 
| -    RestoreAll(); | 
| -  else | 
| -    RestorePanel(panel); | 
| -} | 
| - | 
| -bool DockedPanelCollection::CanShowMinimizeButton(const Panel* panel) const { | 
| -  return !IsPanelMinimized(panel); | 
| -} | 
| - | 
| -bool DockedPanelCollection::CanShowRestoreButton(const Panel* panel) const { | 
| -  return IsPanelMinimized(panel); | 
| -} | 
| - | 
| -bool DockedPanelCollection::IsPanelMinimized(const Panel* panel) const { | 
| -  return panel->expansion_state() != Panel::EXPANDED; | 
| -} | 
| - | 
| -bool DockedPanelCollection::UsesAlwaysOnTopPanels() const { | 
| -  return true; | 
| -} | 
| - | 
| -void DockedPanelCollection::UpdateMinimizedPanelCount() { | 
| -  int prev_minimized_panel_count = minimized_panel_count_; | 
| -  minimized_panel_count_ = 0; | 
| -  for (Panels::const_iterator panel_iter = panels_.begin(); | 
| -        panel_iter != panels_.end(); ++panel_iter) { | 
| -    if ((*panel_iter)->expansion_state() != Panel::EXPANDED) | 
| -      minimized_panel_count_++; | 
| -  } | 
| - | 
| -  if (prev_minimized_panel_count == 0 && minimized_panel_count_ > 0) | 
| -    panel_manager_->mouse_watcher()->AddObserver(this); | 
| -  else if (prev_minimized_panel_count > 0 &&  minimized_panel_count_ == 0) | 
| -    panel_manager_->mouse_watcher()->RemoveObserver(this); | 
| - | 
| -  DCHECK_LE(minimized_panel_count_, num_panels()); | 
| -} | 
| - | 
| -void DockedPanelCollection::ResizePanelWindow( | 
| -    Panel* panel, | 
| -    const gfx::Size& preferred_window_size) { | 
| -  DCHECK_EQ(this, panel->collection()); | 
| -  // Make sure the new size does not violate panel's size restrictions. | 
| -  gfx::Size new_size(preferred_window_size.width(), | 
| -                     preferred_window_size.height()); | 
| -  new_size = panel->ClampSize(new_size); | 
| - | 
| -  if (new_size == panel->full_size()) | 
| -    return; | 
| - | 
| -  panel->set_full_size(new_size); | 
| - | 
| -  RefreshLayout(); | 
| -} | 
| - | 
| -bool DockedPanelCollection::ShouldBringUpTitlebars(int mouse_x, | 
| -                                                   int mouse_y) const { | 
| -  // We should always bring up the titlebar if the mouse is over the | 
| -  // visible auto-hiding bottom bar. | 
| -  DisplaySettingsProvider* provider = | 
| -      panel_manager_->display_settings_provider(); | 
| -  if (provider->IsAutoHidingDesktopBarEnabled( | 
| -          DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM) && | 
| -      provider->GetDesktopBarVisibility( | 
| -          DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM) == | 
| -              DisplaySettingsProvider::DESKTOP_BAR_VISIBLE) { | 
| -    int bottom_bar_bottom = work_area_.bottom(); | 
| -    int bottom_bar_y = bottom_bar_bottom - provider->GetDesktopBarThickness( | 
| -        DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM); | 
| -    if (bottom_bar_y <= mouse_y && mouse_y <= bottom_bar_bottom) | 
| -      return true; | 
| -  } | 
| - | 
| -  // Bring up titlebars if any panel needs the titlebar up. | 
| -  Panel* dragging_panel = panel_manager_->drag_controller()->dragging_panel(); | 
| -  if (dragging_panel && | 
| -      dragging_panel->collection()->type() != PanelCollection::DOCKED) | 
| -    dragging_panel = NULL; | 
| -  for (Panels::const_iterator iter = panels_.begin(); | 
| -       iter != panels_.end(); ++iter) { | 
| -    Panel* panel = *iter; | 
| -    Panel::ExpansionState state = panel->expansion_state(); | 
| -    // Skip the expanded panel. | 
| -    if (state == Panel::EXPANDED) | 
| -      continue; | 
| - | 
| -    // If the panel is showing titlebar only, we want to keep it up when it is | 
| -    // being dragged. | 
| -    if (state == Panel::TITLE_ONLY && panel == dragging_panel) | 
| -      return true; | 
| - | 
| -    // We do not want to bring up other minimized panels if the mouse is over | 
| -    // the panel that pops up the titlebar to attract attention. | 
| -    if (panel->IsDrawingAttention()) | 
| -      continue; | 
| - | 
| -    gfx::Rect bounds = panel->GetBounds(); | 
| -    if (bounds.x() <= mouse_x && mouse_x <= bounds.right() && | 
| -        mouse_y >= bounds.y()) | 
| -      return true; | 
| -  } | 
| -  return false; | 
| -} | 
| - | 
| -void DockedPanelCollection::BringUpOrDownTitlebars(bool bring_up) { | 
| -  if (are_titlebars_up_ == bring_up) | 
| -    return; | 
| - | 
| -  are_titlebars_up_ = bring_up; | 
| -  int task_delay_ms = 0; | 
| - | 
| -  // If the auto-hiding bottom bar exists, delay the action until the bottom | 
| -  // bar is fully visible or hidden. We do not want both bottom bar and panel | 
| -  // titlebar to move at the same time but with different speeds. | 
| -  DisplaySettingsProvider* provider = | 
| -      panel_manager_->display_settings_provider(); | 
| -  if (provider->IsAutoHidingDesktopBarEnabled( | 
| -          DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM)) { | 
| -    DisplaySettingsProvider::DesktopBarVisibility visibility = | 
| -        provider->GetDesktopBarVisibility( | 
| -            DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM); | 
| -    if (visibility != | 
| -        (bring_up ? DisplaySettingsProvider::DESKTOP_BAR_VISIBLE | 
| -                  : DisplaySettingsProvider::DESKTOP_BAR_HIDDEN)) { | 
| -      // Occasionally some system, like Windows, might not bring up or down the | 
| -      // bottom bar when the mouse enters or leaves the bottom screen area. | 
| -      // Thus, we schedule a delayed task to do the work if we do not receive | 
| -      // the bottom bar visibility change notification within a certain period | 
| -      // of time. | 
| -      task_delay_ms = kMaxDelayWaitForBottomBarVisibilityChangeMs; | 
| -    } | 
| -  } | 
| - | 
| -  // OnAutoHidingDesktopBarVisibilityChanged will handle this. | 
| -  delayed_titlebar_action_ = bring_up ? BRING_UP : BRING_DOWN; | 
| - | 
| -  // If user moves the mouse in and out of mouse tracking area, we might have | 
| -  // previously posted but not yet dispatched task in the queue. New action | 
| -  // should always 'reset' the delays so cancel any tasks that haven't run yet | 
| -  // and post a new one. | 
| -  titlebar_action_factory_.InvalidateWeakPtrs(); | 
| -  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 
| -      FROM_HERE, | 
| -      base::Bind(&DockedPanelCollection::DelayedBringUpOrDownTitlebarsCheck, | 
| -                 titlebar_action_factory_.GetWeakPtr()), | 
| -      base::TimeDelta::FromMilliseconds( | 
| -          PanelManager::AdjustTimeInterval(task_delay_ms))); | 
| -} | 
| - | 
| -void DockedPanelCollection::DelayedBringUpOrDownTitlebarsCheck() { | 
| -  // Task was already processed or cancelled - bail out. | 
| -  if (delayed_titlebar_action_ == NO_ACTION) | 
| -    return; | 
| - | 
| -  bool need_to_bring_up_titlebars = (delayed_titlebar_action_ == BRING_UP); | 
| - | 
| -  delayed_titlebar_action_ = NO_ACTION; | 
| - | 
| -  // Check if the action is still needed based on the latest mouse position. The | 
| -  // user could move the mouse into the tracking area and then quickly move it | 
| -  // out of the area. In case of this, cancel the action. | 
| -  if (are_titlebars_up_ != need_to_bring_up_titlebars) | 
| -    return; | 
| - | 
| -  DoBringUpOrDownTitlebars(need_to_bring_up_titlebars); | 
| -} | 
| - | 
| -void DockedPanelCollection::DoBringUpOrDownTitlebars(bool bring_up) { | 
| -  for (Panels::const_iterator iter = panels_.begin(); | 
| -       iter != panels_.end(); ++iter) { | 
| -    Panel* panel = *iter; | 
| - | 
| -    // Skip any panel that is drawing the attention. | 
| -    if (panel->IsDrawingAttention()) | 
| -      continue; | 
| - | 
| -    if (bring_up) { | 
| -      if (panel->expansion_state() == Panel::MINIMIZED) | 
| -        panel->SetExpansionState(Panel::TITLE_ONLY); | 
| -    } else { | 
| -      if (panel->expansion_state() == Panel::TITLE_ONLY) | 
| -        panel->SetExpansionState(Panel::MINIMIZED); | 
| -    } | 
| -  } | 
| -} | 
| - | 
| -int DockedPanelCollection::GetBottomPositionForExpansionState( | 
| -    Panel::ExpansionState expansion_state) const { | 
| -  int bottom = work_area_.bottom(); | 
| -  // If there is an auto-hiding desktop bar aligned to the bottom edge, we need | 
| -  // to move the title-only panel above the auto-hiding desktop bar. | 
| -  DisplaySettingsProvider* provider = | 
| -      panel_manager_->display_settings_provider(); | 
| -  if (expansion_state == Panel::TITLE_ONLY && | 
| -      provider->IsAutoHidingDesktopBarEnabled( | 
| -          DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM)) { | 
| -    bottom -= provider->GetDesktopBarThickness( | 
| -        DisplaySettingsProvider::DESKTOP_BAR_ALIGNED_BOTTOM); | 
| -  } | 
| - | 
| -  return bottom; | 
| -} | 
| - | 
| -void DockedPanelCollection::OnMouseMove(const gfx::Point& mouse_position) { | 
| -  bool bring_up_titlebars = ShouldBringUpTitlebars(mouse_position.x(), | 
| -                                                   mouse_position.y()); | 
| -  BringUpOrDownTitlebars(bring_up_titlebars); | 
| -} | 
| - | 
| -void DockedPanelCollection::OnAutoHidingDesktopBarVisibilityChanged( | 
| -    DisplaySettingsProvider::DesktopBarAlignment alignment, | 
| -    DisplaySettingsProvider::DesktopBarVisibility visibility) { | 
| -  if (delayed_titlebar_action_ == NO_ACTION) | 
| -    return; | 
| - | 
| -  DisplaySettingsProvider::DesktopBarVisibility expected_visibility = | 
| -      delayed_titlebar_action_ == BRING_UP | 
| -          ? DisplaySettingsProvider::DESKTOP_BAR_VISIBLE | 
| -          : DisplaySettingsProvider::DESKTOP_BAR_HIDDEN; | 
| -  if (visibility != expected_visibility) | 
| -    return; | 
| - | 
| -  DoBringUpOrDownTitlebars(delayed_titlebar_action_ == BRING_UP); | 
| -  delayed_titlebar_action_ = NO_ACTION; | 
| -} | 
| - | 
| -void DockedPanelCollection::OnAutoHidingDesktopBarThicknessChanged( | 
| -    DisplaySettingsProvider::DesktopBarAlignment alignment, int thickness) { | 
| -  RefreshLayout(); | 
| -} | 
| - | 
| -void DockedPanelCollection::RefreshLayout() { | 
| -  int total_active_width = 0; | 
| -  int total_inactive_width = 0; | 
| - | 
| -  for (Panels::const_iterator panel_iter = panels_.begin(); | 
| -       panel_iter != panels_.end(); ++panel_iter) { | 
| -    Panel* panel = *panel_iter; | 
| -    if (panel->IsActive()) | 
| -      total_active_width += panel->full_size().width(); | 
| -    else | 
| -      total_inactive_width += panel->full_size().width(); | 
| -  } | 
| - | 
| -  double display_width_for_inactive_panels = | 
| -      work_area_.width() - total_active_width - | 
| -          kPanelsHorizontalSpacing * panels_.size(); | 
| -  double overflow_squeeze_factor = (total_inactive_width > 0) ? | 
| -      std::min(display_width_for_inactive_panels / total_inactive_width, 1.0) : | 
| -      1.0; | 
| - | 
| -  // We want to calculate all bounds first, then apply them in a specific order. | 
| -  typedef std::pair<Panel*, gfx::Rect> PanelBoundsInfo; | 
| -  // The next pair of variables will hold panels that move, respectively, | 
| -  // to the right and to the left. We want to process them from the center | 
| -  // outwards, so one is a stack and another is a queue. | 
| -  std::vector<PanelBoundsInfo> moving_right; | 
| -  std::queue<PanelBoundsInfo> moving_left; | 
| - | 
| -  int rightmost_position = StartingRightPosition(); | 
| -  for (Panels::const_iterator panel_iter = panels_.begin(); | 
| -       panel_iter != panels_.end(); ++panel_iter) { | 
| -    Panel* panel = *panel_iter; | 
| -    gfx::Rect old_bounds = panel->GetBounds(); | 
| -    gfx::Rect new_bounds = old_bounds; | 
| -    AdjustPanelBoundsPerExpansionState(panel, &new_bounds); | 
| - | 
| -    new_bounds.set_width( | 
| -      WidthToDisplayPanelInCollection(panel->IsActive(), | 
| -                                      overflow_squeeze_factor, | 
| -                                      panel->full_size().width())); | 
| -    int x = rightmost_position - new_bounds.width(); | 
| -    new_bounds.set_x(x); | 
| - | 
| -    if (x < old_bounds.x() || | 
| -        (x == old_bounds.x() && new_bounds.width() <= old_bounds.width())) | 
| -      moving_left.push(std::make_pair(panel, new_bounds)); | 
| -    else | 
| -      moving_right.push_back(std::make_pair(panel, new_bounds)); | 
| - | 
| -    rightmost_position = x - kPanelsHorizontalSpacing; | 
| -  } | 
| - | 
| -  // Update panels going in both directions. | 
| -  // This is important on Mac where bounds changes are slow and you see a | 
| -  // "wave" instead of a smooth sliding effect. | 
| -  int num_animated = 0; | 
| -  bool going_right = true; | 
| -  while (!moving_right.empty() || !moving_left.empty()) { | 
| -    PanelBoundsInfo bounds_info; | 
| -    // Alternate between processing the panels that moving left and right, | 
| -    // starting from the center. | 
| -    going_right = !going_right; | 
| -    bool take_panel_on_right = | 
| -        (going_right && !moving_right.empty()) || | 
| -        moving_left.empty(); | 
| -    if (take_panel_on_right) { | 
| -      bounds_info = moving_right.back(); | 
| -      moving_right.pop_back(); | 
| -    } else { | 
| -      bounds_info = moving_left.front(); | 
| -      moving_left.pop(); | 
| -    } | 
| - | 
| -    // Don't update the docked panel that is in preview mode. | 
| -    Panel* panel = bounds_info.first; | 
| -    gfx::Rect bounds = bounds_info.second; | 
| -    if (!panel->in_preview_mode() && bounds != panel->GetBounds()) { | 
| -      // We animate a limited number of panels, starting with the | 
| -      // "most important" ones, that is, ones that are close to the center | 
| -      // of the action. Other panels are moved instantly to improve performance. | 
| -      if (num_animated < kNumPanelsToAnimateSimultaneously) { | 
| -        panel->SetPanelBounds(bounds);  // Animates. | 
| -        ++num_animated; | 
| -      } else { | 
| -        panel->SetPanelBoundsInstantly(bounds); | 
| -      } | 
| -    } | 
| -  } | 
| - | 
| -  content::NotificationService::current()->Notify( | 
| -      chrome::NOTIFICATION_PANEL_COLLECTION_UPDATED, | 
| -      content::Source<PanelCollection>(this), | 
| -      content::NotificationService::NoDetails()); | 
| -} | 
| - | 
| -int DockedPanelCollection::WidthToDisplayPanelInCollection( | 
| -    bool is_for_active_panel, double squeeze_factor, int full_width) const { | 
| -  return is_for_active_panel ? full_width : | 
| -      std::max(panel::kPanelMinWidth, | 
| -               static_cast<int>(floor(full_width * squeeze_factor))); | 
| -} | 
| - | 
| -void DockedPanelCollection::CloseAll() { | 
| -  // This should only be called at the end of tests to clean up. | 
| - | 
| -  // Make a copy of the iterator as closing panels can modify the vector. | 
| -  Panels panels_copy = panels_; | 
| - | 
| -  // Start from the bottom to avoid reshuffling. | 
| -  for (Panels::reverse_iterator iter = panels_copy.rbegin(); | 
| -       iter != panels_copy.rend(); ++iter) | 
| -    (*iter)->Close(); | 
| -} | 
| - | 
| -void DockedPanelCollection::UpdatePanelOnCollectionChange(Panel* panel) { | 
| -  panel->set_attention_mode(Panel::USE_PANEL_ATTENTION); | 
| -  panel->ShowShadow(true); | 
| -  panel->UpdateMinimizeRestoreButtonVisibility(); | 
| -  panel->SetWindowCornerStyle(panel::TOP_ROUNDED); | 
| -} | 
| - | 
| -void DockedPanelCollection::ScheduleLayoutRefresh() { | 
| -  refresh_action_factory_.InvalidateWeakPtrs(); | 
| -  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 
| -      FROM_HERE, base::Bind(&DockedPanelCollection::RefreshLayout, | 
| -                            refresh_action_factory_.GetWeakPtr()), | 
| -      base::TimeDelta::FromMilliseconds(PanelManager::AdjustTimeInterval( | 
| -          kRefreshLayoutAfterActivePanelChangeDelayMs))); | 
| -} | 
| - | 
| -void DockedPanelCollection::OnPanelActiveStateChanged(Panel* panel) { | 
| -  // Refresh layout, but wait till active states settle. | 
| -  // This lets us avoid refreshing too many times when one panel loses | 
| -  // focus and another gains it. | 
| -  ScheduleLayoutRefresh(); | 
| -} | 
| - | 
| -gfx::Rect DockedPanelCollection::GetInitialPanelBounds( | 
| -      const gfx::Rect& requested_bounds) const { | 
| -  gfx::Rect initial_bounds = requested_bounds; | 
| -  initial_bounds.set_origin( | 
| -      GetDefaultPositionForPanel(requested_bounds.size())); | 
| -  return initial_bounds; | 
| -} | 
| - | 
| -bool DockedPanelCollection::HasPanel(Panel* panel) const { | 
| -  return find(panels_.begin(), panels_.end(), panel) != panels_.end(); | 
| -} | 
|  |