summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ash/shelf/shelf_layout_manager.cc6
-rw-r--r--ash/shelf/shelf_layout_manager.h4
-rw-r--r--ash/wm/dock/docked_window_layout_manager.cc39
-rw-r--r--ash/wm/dock/docked_window_layout_manager.h7
-rw-r--r--ash/wm/dock/docked_window_layout_manager_observer.h12
-rw-r--r--ash/wm/dock/docked_window_resizer_unittest.cc41
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) {