summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authorstevenjb@chromium.org <stevenjb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-04 16:44:27 +0000
committerstevenjb@chromium.org <stevenjb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-04 16:44:27 +0000
commit6b85493985ec994cd82977ea088bb7a3de955a66 (patch)
tree6824605dce0d1118ae77600a4f18f5c37626aa9d /ash
parent83b583eee2d88a6a79f30073e83ed6a5e0ae3fc5 (diff)
downloadchromium_src-6b85493985ec994cd82977ea088bb7a3de955a66.zip
chromium_src-6b85493985ec994cd82977ea088bb7a3de955a66.tar.gz
chromium_src-6b85493985ec994cd82977ea088bb7a3de955a66.tar.bz2
Add PanelWindow and PanelLayoutManager to ash. (+ win fix)
This implements a sample implementation of a WidgetDelegateView (PanelWindow) and a LayoutManager to provide an initial out ash_shell must be run with --aura-panels to get the new behavior, since Chrome currently relies on existing behavior for wi BUG=98330 TEST=Run ash_shell --aura-panels to see a simple panel test implementation. Ensure panels work as expected in Chrome. Original Review URL: http://codereview.chromium.org/9104027 TBR=dslomov@chromium.org Review URL: http://codereview.chromium.org/9325051 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@120478 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r--ash/ash.gyp9
-rw-r--r--ash/ash_switches.cc3
-rw-r--r--ash/ash_switches.h1
-rw-r--r--ash/shell.cc8
-rw-r--r--ash/shell/panel_window.cc84
-rw-r--r--ash/shell/panel_window.h53
-rw-r--r--ash/shell/window_type_launcher.cc13
-rw-r--r--ash/shell/window_type_launcher.h1
-rw-r--r--ash/wm/panel_layout_manager.cc118
-rw-r--r--ash/wm/panel_layout_manager.h69
-rw-r--r--ash/wm/panel_layout_manager_unittest.cc91
11 files changed, 447 insertions, 3 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp
index a4dfdef..986795f 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -115,6 +115,8 @@
'wm/dialog_frame_view.h',
'wm/image_grid.cc',
'wm/image_grid.h',
+ 'wm/panel_layout_manager.cc',
+ 'wm/panel_layout_manager.h',
'wm/system_modal_container_layout_manager.cc',
'wm/system_modal_container_layout_manager.h',
'wm/system_modal_container_event_filter.cc',
@@ -227,19 +229,20 @@
'wm/base_layout_manager_unittest.cc',
'wm/compact_layout_manager_unittest.cc',
'wm/image_grid_unittest.cc',
- 'wm/system_modal_container_layout_manager_unittest.cc',
+ 'wm/panel_layout_manager_unittest.cc',
'wm/power_button_controller_unittest.cc',
'wm/root_window_event_filter_unittest.cc',
'wm/shadow_controller_unittest.cc',
'wm/shelf_layout_manager_unittest.cc',
+ 'wm/system_modal_container_layout_manager_unittest.cc',
'wm/toplevel_layout_manager_unittest.cc',
'wm/toplevel_window_event_filter_unittest.cc',
'wm/video_detector_unittest.cc',
'wm/visibility_controller_unittest.cc',
'wm/window_cycle_controller_unittest.cc',
'wm/window_modality_controller_unittest.cc',
- 'wm/workspace_controller_unittest.cc',
'wm/workspace/workspace_manager_unittest.cc',
+ 'wm/workspace_controller_unittest.cc',
'<(SHARED_INTERMEDIATE_DIR)/ui/gfx/gfx_resources.rc',
'<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources/ui_resources.rc',
@@ -293,6 +296,8 @@
'shell/bubble.cc',
'shell/example_factory.h',
'shell/lock_view.cc',
+ 'shell/panel_window.cc',
+ 'shell/panel_window.h',
'shell/shell_main.cc',
'shell/shell_main_parts.cc',
'shell/shell_main_parts.h',
diff --git a/ash/ash_switches.cc b/ash/ash_switches.cc
index 44e1737..69067eb 100644
--- a/ash/ash_switches.cc
+++ b/ash/ash_switches.cc
@@ -49,5 +49,8 @@ const char kAuraWindowModeManaged[] = "managed";
// Traditional window management with multiple draggable windows.
const char kAuraWindowModeOverlapping[] = "overlapping";
+// Use Aura to manage windows of type WINDOW_TYPE_PANEL.
+const char kAuraPanelManager[] = "aura-panels";
+
} // namespace switches
} // namespace ash
diff --git a/ash/ash_switches.h b/ash/ash_switches.h
index 3759607..5af50965 100644
--- a/ash/ash_switches.h
+++ b/ash/ash_switches.h
@@ -22,6 +22,7 @@ ASH_EXPORT extern const char kAuraWindowMode[];
ASH_EXPORT extern const char kAuraWindowModeCompact[];
ASH_EXPORT extern const char kAuraWindowModeManaged[];
ASH_EXPORT extern const char kAuraWindowModeOverlapping[];
+ASH_EXPORT extern const char kAuraPanelManager[];
} // namespace switches
} // namespace ash
diff --git a/ash/shell.cc b/ash/shell.cc
index 1b06566..b1203bc 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -22,6 +22,7 @@
#include "ash/wm/compact_layout_manager.h"
#include "ash/wm/compact_status_area_layout_manager.h"
#include "ash/wm/dialog_frame_view.h"
+#include "ash/wm/panel_layout_manager.h"
#include "ash/wm/power_button_controller.h"
#include "ash/wm/root_window_event_filter.h"
#include "ash/wm/root_window_layout_manager.h"
@@ -95,6 +96,13 @@ void CreateSpecialContainers(aura::Window::Windows* containers) {
aura::Window* panel_container = new aura::Window(NULL);
panel_container->set_id(internal::kShellWindowId_PanelContainer);
+ if (CommandLine::ForCurrentProcess()->
+ HasSwitch(switches::kAuraPanelManager)) {
+ panel_container->SetEventFilter(
+ new ToplevelWindowEventFilter(panel_container));
+ panel_container->SetLayoutManager(
+ new internal::PanelLayoutManager(panel_container));
+ }
containers->push_back(panel_container);
aura::Window* launcher_container = new aura::Window(NULL);
diff --git a/ash/shell/panel_window.cc b/ash/shell/panel_window.cc
new file mode 100644
index 0000000..5cfaffa
--- /dev/null
+++ b/ash/shell/panel_window.cc
@@ -0,0 +1,84 @@
+// 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 "ash/shell/panel_window.h"
+
+#include "ash/wm/toplevel_frame_view.h"
+#include "base/utf_string_conversions.h"
+#include "ui/aura/window.h"
+#include "ui/gfx/canvas.h"
+#include "ui/views/widget/widget.h"
+
+namespace {
+const int kMinWidth = 100;
+const int kMinHeight = 100;
+const int kDefaultWidth = 200;
+const int kDefaultHeight = 300;
+}
+
+namespace ash {
+
+// static
+views::Widget* PanelWindow::CreatePanelWindow(const gfx::Rect& rect) {
+ PanelWindow* panel_window = new PanelWindow("Example Panel Window");
+ panel_window->params().bounds = rect;
+ return panel_window->CreateWidget();
+}
+
+PanelWindow::PanelWindow(const std::string& name)
+ : name_(name),
+ params_(views::Widget::InitParams::TYPE_PANEL) {
+ params_.delegate = this;
+}
+
+PanelWindow::~PanelWindow() {
+}
+
+views::Widget* PanelWindow::CreateWidget() {
+ views::Widget* widget = new views::Widget;
+
+ if (params().bounds.width() == 0)
+ params().bounds.set_width(kDefaultWidth);
+ if (params().bounds.height() == 0)
+ params().bounds.set_height(kDefaultHeight);
+
+ widget->Init(params());
+ widget->GetNativeView()->SetName(name_);
+ widget->Show();
+
+ return widget;
+}
+
+gfx::Size PanelWindow::GetPreferredSize() {
+ return gfx::Size(kMinWidth, kMinHeight);
+}
+
+void PanelWindow::OnPaint(gfx::Canvas* canvas) {
+ canvas->FillRect(GetLocalBounds(), SK_ColorGREEN);
+}
+
+string16 PanelWindow::GetWindowTitle() const {
+ return ASCIIToUTF16(name_);
+}
+
+views::View* PanelWindow::GetContentsView() {
+ return this;
+}
+
+bool PanelWindow::CanResize() const {
+ return true;
+}
+
+bool PanelWindow::CanMaximize() const {
+ return false;
+}
+
+views::NonClientFrameView* PanelWindow::CreateNonClientFrameView() {
+ // TODO(stevenjb): Implement a custom frame view for panels.
+ // For now, use the default frame view (views::CustomFrameView)
+ // which implements close and resize for us.
+ return NULL;
+}
+
+} // namespace ash
diff --git a/ash/shell/panel_window.h b/ash/shell/panel_window.h
new file mode 100644
index 0000000..cc1afbd
--- /dev/null
+++ b/ash/shell/panel_window.h
@@ -0,0 +1,53 @@
+// 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.
+
+#ifndef ASH_SHELL_PANEL_WINDOW_H_
+#define ASH_SHELL_PANEL_WINDOW_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "ui/aura/aura_export.h"
+#include "ui/views/widget/widget.h"
+#include "ui/views/widget/widget_delegate.h"
+
+namespace ash {
+
+// Example Class for panel windows (Widget::InitParams::TYPE_PANEL).
+// Instances of PanelWindow will get added to the PanelContainer top level
+// window which manages the panel layout through PanelLayoutManager.
+class PanelWindow : public views::WidgetDelegateView {
+ public:
+ explicit PanelWindow(const std::string& name);
+ virtual ~PanelWindow();
+
+ // Creates the widget for the panel window using |params_|.
+ views::Widget* CreateWidget();
+
+ const std::string& name() { return name_; }
+ views::Widget::InitParams& params() { return params_; }
+
+ // Creates a panel window and returns the associated widget.
+ static views::Widget* CreatePanelWindow(const gfx::Rect& rect);
+
+ private:
+ // Overridden from views::View:
+ virtual gfx::Size GetPreferredSize() OVERRIDE;
+ virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE;
+
+ // Overridden from views::WidgetDelegate:
+ virtual string16 GetWindowTitle() const OVERRIDE;
+ virtual View* GetContentsView() OVERRIDE;
+ virtual bool CanResize() const OVERRIDE;
+ virtual bool CanMaximize() const OVERRIDE;
+ virtual views::NonClientFrameView* CreateNonClientFrameView() OVERRIDE;
+
+ std::string name_;
+ views::Widget::InitParams params_;
+
+ DISALLOW_COPY_AND_ASSIGN(PanelWindow);
+};
+
+} // namespace ash
+
+#endif // ASH_SHELL_PANEL_WINDOW_H_
diff --git a/ash/shell/window_type_launcher.cc b/ash/shell/window_type_launcher.cc
index 42f5db1..0153d1c 100644
--- a/ash/shell/window_type_launcher.cc
+++ b/ash/shell/window_type_launcher.cc
@@ -6,6 +6,7 @@
#include "ash/shell_window_ids.h"
#include "ash/shell/example_factory.h"
+#include "ash/shell/panel_window.h"
#include "ash/shell/toplevel_window.h"
#include "ash/wm/shadow_types.h"
#include "ash/wm/toplevel_frame_view.h"
@@ -177,6 +178,8 @@ void InitWindowTypeLauncher() {
WindowTypeLauncher::WindowTypeLauncher()
: ALLOW_THIS_IN_INITIALIZER_LIST(create_button_(
new views::NativeTextButton(this, ASCIIToUTF16("Create Window")))),
+ ALLOW_THIS_IN_INITIALIZER_LIST(panel_button_(
+ new views::NativeTextButton(this, ASCIIToUTF16("Create Panel")))),
ALLOW_THIS_IN_INITIALIZER_LIST(create_nonresizable_button_(
new views::NativeTextButton(
this, ASCIIToUTF16("Create Non-Resizable Window")))),
@@ -204,6 +207,7 @@ WindowTypeLauncher::WindowTypeLauncher()
new views::NativeTextButton(
this, ASCIIToUTF16("Show/Hide a Window")))) {
AddChildView(create_button_);
+ AddChildView(panel_button_);
AddChildView(create_nonresizable_button_);
AddChildView(bubble_button_);
AddChildView(lock_button_);
@@ -232,9 +236,14 @@ void WindowTypeLauncher::Layout() {
5, local_bounds.bottom() - create_button_ps.height() - 5,
create_button_ps.width(), create_button_ps.height());
+ gfx::Size panel_button_ps = panel_button_->GetPreferredSize();
+ panel_button_->SetBounds(
+ 5, create_button_->y() - panel_button_ps.height() - 5,
+ panel_button_ps.width(), panel_button_ps.height());
+
gfx::Size bubble_button_ps = bubble_button_->GetPreferredSize();
bubble_button_->SetBounds(
- 5, create_button_->y() - bubble_button_ps.height() - 5,
+ 5, panel_button_->y() - bubble_button_ps.height() - 5,
bubble_button_ps.width(), bubble_button_ps.height());
gfx::Size create_nr_button_ps =
@@ -307,6 +316,8 @@ void WindowTypeLauncher::ButtonPressed(views::Button* sender,
ToplevelWindow::CreateParams params;
params.can_resize = true;
ToplevelWindow::CreateToplevelWindow(params);
+ } else if (sender == panel_button_) {
+ PanelWindow::CreatePanelWindow(gfx::Rect());
} else if (sender == create_nonresizable_button_) {
ToplevelWindow::CreateToplevelWindow(ToplevelWindow::CreateParams());
} else if (sender == bubble_button_) {
diff --git a/ash/shell/window_type_launcher.h b/ash/shell/window_type_launcher.h
index 3dbe197..afaaf52 100644
--- a/ash/shell/window_type_launcher.h
+++ b/ash/shell/window_type_launcher.h
@@ -68,6 +68,7 @@ class WindowTypeLauncher : public views::WidgetDelegateView,
#endif // !defined(OS_MACOSX)
views::NativeTextButton* create_button_;
+ views::NativeTextButton* panel_button_;
views::NativeTextButton* create_nonresizable_button_;
views::NativeTextButton* bubble_button_;
views::NativeTextButton* lock_button_;
diff --git a/ash/wm/panel_layout_manager.cc b/ash/wm/panel_layout_manager.cc
new file mode 100644
index 0000000..3591726
--- /dev/null
+++ b/ash/wm/panel_layout_manager.cc
@@ -0,0 +1,118 @@
+// 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 "ash/wm/panel_layout_manager.h"
+
+#include <algorithm>
+
+#include "ash/launcher/launcher.h"
+#include "ash/shell.h"
+#include "base/auto_reset.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/window.h"
+#include "ui/gfx/rect.h"
+#include "ui/views/widget/widget.h"
+
+namespace {
+const int kPanelMarginEdge = 4;
+const int kPanelMarginMiddle = 8;
+const float kMaxHeightFactor = .80f;
+const float kMaxWidthFactor = .50f;
+}
+
+namespace ash {
+namespace internal {
+
+////////////////////////////////////////////////////////////////////////////////
+// PanelLayoutManager public implementation:
+
+PanelLayoutManager::PanelLayoutManager(aura::Window* panel_container)
+ : panel_container_(panel_container),
+ in_layout_(false) {
+ DCHECK(panel_container);
+}
+
+PanelLayoutManager::~PanelLayoutManager() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// PanelLayoutManager, aura::LayoutManager implementation:
+
+void PanelLayoutManager::OnWindowResized() {
+ Relayout();
+}
+
+void PanelLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
+ panel_windows_.push_back(child);
+ Relayout();
+}
+
+void PanelLayoutManager::OnWillRemoveWindowFromLayout(aura::Window* child) {
+ PanelList::iterator found =
+ std::find(panel_windows_.begin(), panel_windows_.end(), child);
+ if (found != panel_windows_.end())
+ panel_windows_.erase(found);
+ Relayout();
+}
+
+void PanelLayoutManager::OnChildWindowVisibilityChanged(aura::Window* child,
+ bool visible) {
+ Relayout();
+}
+
+void PanelLayoutManager::SetChildBounds(aura::Window* child,
+ const gfx::Rect& requested_bounds) {
+ gfx::Rect bounds(requested_bounds);
+ const gfx::Rect& max_bounds = panel_container_->GetRootWindow()->bounds();
+ const int max_width = max_bounds.width() * kMaxWidthFactor;
+ const int max_height = max_bounds.height() * kMaxHeightFactor;
+ if (bounds.width() > max_width)
+ bounds.set_width(max_width);
+ if (bounds.height() > max_height)
+ bounds.set_height(max_height);
+ SetChildBoundsDirect(child, bounds);
+ Relayout();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// PanelLayoutManager private implementation:
+
+// This is a rough outline of a simple panel layout manager.
+void PanelLayoutManager::Relayout() {
+ if (in_layout_)
+ return;
+ AutoReset<bool> auto_reset_in_layout(&in_layout_, true);
+
+ // Panels are currently laid out just above the launcher (if it exists),
+ // otherwise at the bottom of the root window.
+ int right, bottom;
+ ash::Shell* shell = ash::Shell::GetInstance();
+ if (shell->launcher() && shell->launcher()->widget()->IsVisible()) {
+ const gfx::Rect& bounds =
+ shell->launcher()->widget()->GetWindowScreenBounds();
+ right = bounds.width() - 1 - kPanelMarginEdge;
+ bottom = bounds.y() - 1;
+ } else {
+ const gfx::Rect& bounds = panel_container_->GetRootWindow()->bounds();
+ right = bounds.width() - 1 - kPanelMarginEdge;
+ bottom = bounds.bottom() - 1;
+ }
+
+ // Layout the panel windows right to left.
+ for (PanelList::iterator iter = panel_windows_.begin();
+ iter != panel_windows_.end(); ++iter) {
+ aura::Window* panel_win = *iter;
+ if (!panel_win->IsVisible())
+ continue;
+ int x = right - panel_win->bounds().width();
+ int y = bottom - panel_win->bounds().height();
+ gfx::Rect bounds(x, y,
+ panel_win->bounds().width(), panel_win->bounds().height());
+ SetChildBoundsDirect(panel_win, bounds);
+ right = x - kPanelMarginMiddle;
+ }
+}
+
+} // namespace internal
+} // namespace ash
diff --git a/ash/wm/panel_layout_manager.h b/ash/wm/panel_layout_manager.h
new file mode 100644
index 0000000..a4921d7
--- /dev/null
+++ b/ash/wm/panel_layout_manager.h
@@ -0,0 +1,69 @@
+// 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.
+
+#ifndef ASH_WM_PANEL_LAYOUT_MANAGER_H_
+#define ASH_WM_PANEL_LAYOUT_MANAGER_H_
+#pragma once
+
+#include <list>
+
+#include "ash/ash_export.h"
+#include "base/basictypes.h"
+#include "base/compiler_specific.h"
+#include "ui/aura/layout_manager.h"
+
+namespace aura {
+class Window;
+}
+
+namespace gfx {
+class Rect;
+}
+
+namespace ash {
+namespace internal {
+
+// PanelLayoutManager is responsible for organizing panels within the
+// workspace. It is associated with a specific container window (i.e.
+// kShellWindowId_PanelContainer) and controls the layout of any windows
+// added to that container.
+//
+// The constructor takes a |panel_container| argument which is expected to set
+// its layout manager to this instance, e.g.:
+// panel_container->SetLayoutManager(new PanelLayoutManager(panel_container));
+
+class ASH_EXPORT PanelLayoutManager : public aura::LayoutManager {
+ public:
+ explicit PanelLayoutManager(aura::Window* panel_container);
+ virtual ~PanelLayoutManager();
+
+ // Overridden from aura::LayoutManager:
+ virtual void OnWindowResized() OVERRIDE;
+ virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE;
+ virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE;
+ virtual void OnChildWindowVisibilityChanged(aura::Window* child,
+ bool visibile) OVERRIDE;
+ virtual void SetChildBounds(aura::Window* child,
+ const gfx::Rect& requested_bounds) OVERRIDE;
+
+ private:
+ typedef std::list<aura::Window*> PanelList;
+
+ // Called whenever the panel layout might change.
+ void Relayout();
+
+ // Parent window associated with this layout manager.
+ aura::Window* panel_container_;
+ // Protect against recursive calls to Relayout().
+ bool in_layout_;
+ // Ordered list of unowned pointers to panel windows.
+ PanelList panel_windows_;
+
+ DISALLOW_COPY_AND_ASSIGN(PanelLayoutManager);
+};
+
+} // namespace internal
+} // namespace ash
+
+#endif // ASH_WM_PANEL_LAYOUT_MANAGER_H_
diff --git a/ash/wm/panel_layout_manager_unittest.cc b/ash/wm/panel_layout_manager_unittest.cc
new file mode 100644
index 0000000..c30330f
--- /dev/null
+++ b/ash/wm/panel_layout_manager_unittest.cc
@@ -0,0 +1,91 @@
+// 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 "ash/wm/panel_layout_manager.h"
+
+#include "ash/ash_switches.h"
+#include "ash/shell.h"
+#include "ash/shell_window_ids.h"
+#include "ash/test/aura_shell_test_base.h"
+#include "base/basictypes.h"
+#include "base/command_line.h"
+#include "base/compiler_specific.h"
+#include "ui/aura/window.h"
+#include "ui/views/widget/widget.h"
+#include "ui/views/widget/widget_delegate.h"
+
+namespace ash {
+
+namespace {
+
+views::Widget* CreatePanelWindow(const gfx::Rect& rect) {
+ views::Widget::InitParams params(views::Widget::InitParams::TYPE_PANEL);
+ params.bounds = rect;
+ views::Widget* widget = new views::Widget();
+ widget->Init(params);
+ widget->Show();
+ return widget;
+}
+
+class PanelLayoutManagerTest : public ash::test::AuraShellTestBase {
+ public:
+ PanelLayoutManagerTest() {}
+ virtual ~PanelLayoutManagerTest() {}
+
+ aura::Window* GetPanelContainer() {
+ return Shell::GetInstance()->GetContainer(
+ ash::internal::kShellWindowId_PanelContainer);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PanelLayoutManagerTest);
+};
+
+} // namespace
+
+// Tests that a created panel window is successfully added to the panel
+// layout manager.
+TEST_F(PanelLayoutManagerTest, AddOnePanel) {
+ gfx::Rect bounds(1, 1, 200, 200);
+ views::Widget* w1 = CreatePanelWindow(bounds);
+ EXPECT_EQ(GetPanelContainer(), w1->GetNativeWindow()->parent());
+}
+
+// Tests that panels are ordered right-to-left.
+TEST_F(PanelLayoutManagerTest, PanelOrderRightToLeft) {
+ if (!CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kAuraPanelManager))
+ return;
+ gfx::Rect bounds(1, 1, 200, 200);
+ views::Widget* w1 = CreatePanelWindow(bounds);
+ views::Widget* w2 = CreatePanelWindow(bounds);
+ EXPECT_LT(w2->GetWindowScreenBounds().x(), w1->GetWindowScreenBounds().x());
+
+ views::Widget* w3 = CreatePanelWindow(bounds);
+ EXPECT_LT(w3->GetWindowScreenBounds().x(), w2->GetWindowScreenBounds().x());
+ EXPECT_LT(w2->GetWindowScreenBounds().x(), w1->GetWindowScreenBounds().x());
+}
+
+// Tests removing a panel.
+TEST_F(PanelLayoutManagerTest, RemovePanel) {
+ if (!CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kAuraPanelManager))
+ return;
+
+ gfx::Rect bounds(1, 1, 200, 200);
+ views::Widget* w1 = CreatePanelWindow(bounds);
+ views::Widget* w2 = CreatePanelWindow(bounds);
+ views::Widget* w3 = CreatePanelWindow(bounds);
+
+ gfx::Rect w3bounds = w3->GetWindowScreenBounds();
+
+ GetPanelContainer()->RemoveChild(w2->GetNativeWindow());
+
+ // Verify that w3 has moved.
+ EXPECT_NE(w3->GetWindowScreenBounds(), w3bounds);
+ // Verify that w3 is still left of w1.
+ EXPECT_LT(w3->GetWindowScreenBounds().x(), w1->GetWindowScreenBounds().x());
+}
+
+} // namespace ash