diff options
-rw-r--r-- | ash/shelf/shelf_layout_manager.cc | 6 | ||||
-rw-r--r-- | ash/shelf/shelf_layout_manager.h | 4 | ||||
-rw-r--r-- | ash/wm/dock/docked_window_layout_manager.cc | 39 | ||||
-rw-r--r-- | ash/wm/dock/docked_window_layout_manager.h | 7 | ||||
-rw-r--r-- | ash/wm/dock/docked_window_layout_manager_observer.h | 12 | ||||
-rw-r--r-- | ash/wm/dock/docked_window_resizer_unittest.cc | 41 |
6 files changed, 86 insertions, 23 deletions
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index 390ab22..d5441c4 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc @@ -1127,7 +1127,11 @@ void ShelfLayoutManager::OnKeyboardBoundsChanging( } void ShelfLayoutManager::OnDockBoundsChanging( - const gfx::Rect& dock_bounds) { + const gfx::Rect& dock_bounds, + DockedWindowLayoutManagerObserver::Reason reason) { + // Skip shelf layout in case docked notification originates from this class. + if (reason == DISPLAY_INSETS_CHANGED) + return; if (dock_bounds_ != dock_bounds) { dock_bounds_ = dock_bounds; OnWindowResized(); diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h index 4865964..d8b6e8f 100644 --- a/ash/shelf/shelf_layout_manager.h +++ b/ash/shelf/shelf_layout_manager.h @@ -332,7 +332,9 @@ class ASH_EXPORT ShelfLayoutManager : const gfx::Rect& keyboard_bounds) OVERRIDE; // Overridden from dock::DockObserver: - virtual void OnDockBoundsChanging(const gfx::Rect& dock_bounds) OVERRIDE; + virtual void OnDockBoundsChanging( + const gfx::Rect& dock_bounds, + DockedWindowLayoutManagerObserver::Reason reason) OVERRIDE; // Generates insets for inward edge based on the current shelf alignment. gfx::Insets GetInsetsForAlignment(int distance) const; diff --git a/ash/wm/dock/docked_window_layout_manager.cc b/ash/wm/dock/docked_window_layout_manager.cc index a75f219..e878608 100644 --- a/ash/wm/dock/docked_window_layout_manager.cc +++ b/ash/wm/dock/docked_window_layout_manager.cc @@ -69,6 +69,7 @@ class DockedBackgroundWidget : public views::Widget { params.accept_events = false; set_focus_on_creation(false); Init(params); + GetNativeWindow()->SetProperty(internal::kStayInSameRootWindowKey, true); DCHECK_EQ(GetNativeView()->GetRootWindow(), parent->GetRootWindow()); views::View* content_view = new views::View; content_view->set_background( @@ -236,7 +237,7 @@ void DockedWindowLayoutManager::UndockDraggedWindow() { DCHECK(!IsPopupOrTransient(dragged_window_)); OnWindowUndocked(); Relayout(); - UpdateDockBounds(); + UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); is_dragged_from_dock_ = false; } @@ -263,7 +264,7 @@ void DockedWindowLayoutManager::FinishDragging() { dragged_window_ = NULL; dragged_bounds_ = gfx::Rect(); Relayout(); - UpdateDockBounds(); + UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); } void DockedWindowLayoutManager::SetLauncher(ash::Launcher* launcher) { @@ -350,7 +351,7 @@ void DockedWindowLayoutManager::OnWindowResized() { Relayout(); // When screen resizes update the insets even when dock width or alignment // does not change. - UpdateDockBounds(); + UpdateDockBounds(DockedWindowLayoutManagerObserver::DISPLAY_RESIZED); } void DockedWindowLayoutManager::OnWindowAddedToLayout(aura::Window* child) { @@ -369,7 +370,7 @@ void DockedWindowLayoutManager::OnWindowAddedToLayout(aura::Window* child) { child->AddObserver(this); wm::GetWindowState(child)->AddObserver(this); Relayout(); - UpdateDockBounds(); + UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); } void DockedWindowLayoutManager::OnWindowRemovedFromLayout(aura::Window* child) { @@ -400,7 +401,7 @@ void DockedWindowLayoutManager::OnChildWindowVisibilityChanged( if (visible) wm::GetWindowState(child)->Restore(); Relayout(); - UpdateDockBounds(); + UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); } void DockedWindowLayoutManager::SetChildBounds( @@ -413,6 +414,11 @@ void DockedWindowLayoutManager::SetChildBounds( //////////////////////////////////////////////////////////////////////////////// // DockLayoutManager, ash::ShellObserver implementation: +void DockedWindowLayoutManager::OnDisplayWorkAreaInsetsChanged() { + Relayout(); + UpdateDockBounds(DockedWindowLayoutManagerObserver::DISPLAY_INSETS_CHANGED); +} + void DockedWindowLayoutManager::OnFullscreenStateChanged( bool is_fullscreen, aura::RootWindow* root_window) { if (dock_container_->GetRootWindow() != root_window) @@ -440,7 +446,7 @@ void DockedWindowLayoutManager::OnFullscreenStateChanged( } } Relayout(); - UpdateDockBounds(); + UpdateDockBounds(DockedWindowLayoutManagerObserver::CHILD_CHANGED); } void DockedWindowLayoutManager::OnShelfAlignmentChanged( @@ -465,7 +471,7 @@ void DockedWindowLayoutManager::OnShelfAlignmentChanged( alignment_ = DOCKED_ALIGNMENT_LEFT; } Relayout(); - UpdateDockBounds(); + UpdateDockBounds(DockedWindowLayoutManagerObserver::SHELF_ALIGNMENT_CHANGED); } ///////////////////////////////////////////////////////////////////////////// @@ -498,7 +504,6 @@ void DockedWindowLayoutManager::OnWindowShowTypeChanged( SetChildBoundsDirect(window, previous_bounds); window->Show(); } - UpdateDockBounds(); } else { RestoreDockedWindow(window_state); } @@ -801,28 +806,26 @@ void DockedWindowLayoutManager::Relayout() { UpdateStacking(active_window); } -void DockedWindowLayoutManager::UpdateDockBounds() { +void DockedWindowLayoutManager::UpdateDockBounds( + DockedWindowLayoutManagerObserver::Reason reason) { int dock_inset = docked_width_ + (docked_width_ > 0 ? kMinDockGap : 0); + const gfx::Rect work_area = + Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); gfx::Rect bounds = gfx::Rect( alignment_ == DOCKED_ALIGNMENT_RIGHT && dock_inset > 0 ? dock_container_->bounds().right() - dock_inset: dock_container_->bounds().x(), dock_container_->bounds().y(), dock_inset, - dock_container_->bounds().height()); + work_area.height()); docked_bounds_ = bounds + dock_container_->GetBoundsInScreen().OffsetFromOrigin(); FOR_EACH_OBSERVER( DockedWindowLayoutManagerObserver, observer_list_, - OnDockBoundsChanging(bounds)); - + OnDockBoundsChanging(bounds, reason)); // Show or hide background for docked area. - gfx::Rect background_bounds(docked_bounds_); - const gfx::Rect work_area = - Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); - background_bounds.set_height(work_area.height()); - background_widget_->SetBounds(background_bounds); + background_widget_->SetBounds(docked_bounds_); if (docked_width_ > 0) { background_widget_->Show(); background_widget_->GetNativeWindow()->layer()->SetOpacity( @@ -895,7 +898,7 @@ void DockedWindowLayoutManager::OnKeyboardBoundsChanging( // This bounds change will have caused a change to the Shelf which does not // propagate automatically to this class, so manually recalculate bounds. Relayout(); - UpdateDockBounds(); + UpdateDockBounds(DockedWindowLayoutManagerObserver::KEYBOARD_BOUNDS_CHANGING); } } // namespace internal diff --git a/ash/wm/dock/docked_window_layout_manager.h b/ash/wm/dock/docked_window_layout_manager.h index 6fc7aed..eab6910 100644 --- a/ash/wm/dock/docked_window_layout_manager.h +++ b/ash/wm/dock/docked_window_layout_manager.h @@ -9,6 +9,7 @@ #include "ash/shelf/shelf_layout_manager_observer.h" #include "ash/shell_observer.h" #include "ash/wm/dock/dock_types.h" +#include "ash/wm/dock/docked_window_layout_manager_observer.h" #include "ash/wm/window_state_observer.h" #include "ash/wm/workspace/snap_types.h" #include "base/basictypes.h" @@ -126,6 +127,7 @@ class ASH_EXPORT DockedWindowLayoutManager const gfx::Rect& requested_bounds) OVERRIDE; // ash::ShellObserver: + virtual void OnDisplayWorkAreaInsetsChanged() OVERRIDE; virtual void OnFullscreenStateChanged(bool is_fullscreen, aura::RootWindow* root_window) OVERRIDE; virtual void OnShelfAlignmentChanged(aura::RootWindow* root_window) OVERRIDE; @@ -202,8 +204,9 @@ class ASH_EXPORT DockedWindowLayoutManager void Relayout(); // Updates |docked_bounds_| and workspace insets when bounds of docked windows - // area change. - void UpdateDockBounds(); + // area change. Passing |reason| to observers allows selectively skipping + // notifications. + void UpdateDockBounds(DockedWindowLayoutManagerObserver::Reason reason); // Called whenever the window stacking order needs to be updated (e.g. focus // changes or a window is moved). diff --git a/ash/wm/dock/docked_window_layout_manager_observer.h b/ash/wm/dock/docked_window_layout_manager_observer.h index 20afca9..f529753 100644 --- a/ash/wm/dock/docked_window_layout_manager_observer.h +++ b/ash/wm/dock/docked_window_layout_manager_observer.h @@ -18,8 +18,18 @@ namespace internal { // events that occur with the docked windows, such as the bounds change. class ASH_EXPORT DockedWindowLayoutManagerObserver { public: + // Reason for notification. Allows selectively ignoring notifications to + // prevent a notification loop. + enum Reason { + CHILD_CHANGED, + DISPLAY_RESIZED, + DISPLAY_INSETS_CHANGED, + SHELF_ALIGNMENT_CHANGED, + KEYBOARD_BOUNDS_CHANGING + }; // Called after the dock bounds are changed. - virtual void OnDockBoundsChanging(const gfx::Rect& new_bounds) = 0; + virtual void OnDockBoundsChanging(const gfx::Rect& new_bounds, + Reason reason) = 0; protected: virtual ~DockedWindowLayoutManagerObserver() {} diff --git a/ash/wm/dock/docked_window_resizer_unittest.cc b/ash/wm/dock/docked_window_resizer_unittest.cc index da06e10..7b17e0b 100644 --- a/ash/wm/dock/docked_window_resizer_unittest.cc +++ b/ash/wm/dock/docked_window_resizer_unittest.cc @@ -492,6 +492,47 @@ TEST_P(DockedWindowResizerTest, AttachTwoWindows) { w2->parent()->id()); } +// Create two windows, dock one and change shelf to auto-hide. +TEST_P(DockedWindowResizerTest, AttachOneAutoHideShelf) { + if (!SupportsHostWindowResize()) + return; + + scoped_ptr<aura::Window> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201))); + DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT, w1.get(), 20); + + // w1 should be attached and snapped to the right edge. + EXPECT_EQ(w1->GetRootWindow()->bounds().right(), + w1->GetBoundsInScreen().right()); + EXPECT_EQ(internal::kShellWindowId_DockedContainer, w1->parent()->id()); + + scoped_ptr<aura::Window> w2(CreateTestWindowInShellWithDelegateAndType( + NULL, aura::client::WINDOW_TYPE_NORMAL, 0, gfx::Rect(20, 20, 150, 20))); + wm::GetWindowState(w2.get())->Maximize(); + EXPECT_EQ(internal::kShellWindowId_DefaultContainer, w2->parent()->id()); + EXPECT_TRUE(wm::GetWindowState(w2.get())->IsMaximized()); + + gfx::Rect work_area = + Shell::GetScreen()->GetDisplayNearestWindow(w1.get()).work_area(); + DockedWindowLayoutManager* manager = + static_cast<DockedWindowLayoutManager*>(w1->parent()->layout_manager()); + + // Docked window should be centered vertically in the work area. + EXPECT_EQ(work_area.CenterPoint().y(), w1->bounds().CenterPoint().y()); + // Docked background should extend to the bottom of work area. + EXPECT_EQ(work_area.bottom(), manager->docked_bounds().bottom()); + + // set launcher shelf to be aligned on the right + ash::Shell* shell = ash::Shell::GetInstance(); + shell->SetShelfAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS, + shell->GetPrimaryRootWindow()); + work_area = + Shell::GetScreen()->GetDisplayNearestWindow(w1.get()).work_area(); + // Docked window should be centered vertically in the work area. + EXPECT_EQ(work_area.CenterPoint().y(), w1->bounds().CenterPoint().y()); + // Docked background should extend to the bottom of work area. + EXPECT_EQ(work_area.bottom(), manager->docked_bounds().bottom()); +} + // Dock one window, try to dock another window on the opposite side (should not // dock). TEST_P(DockedWindowResizerTest, AttachOnTwoSides) { |