Disable TabDragController tests that fail with a real compositor.
[chromium-blink-merge.git] / ash / wm / panels / panel_window_resizer_unittest.cc
blob3fdddf11108a57169dbd7544545df286cef11c54
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ash/wm/panels/panel_window_resizer.h"
7 #include "ash/root_window_controller.h"
8 #include "ash/shelf/shelf.h"
9 #include "ash/shelf/shelf_layout_manager.h"
10 #include "ash/shelf/shelf_model.h"
11 #include "ash/shelf/shelf_types.h"
12 #include "ash/shelf/shelf_util.h"
13 #include "ash/shelf/shelf_widget.h"
14 #include "ash/shell.h"
15 #include "ash/shell_window_ids.h"
16 #include "ash/test/ash_test_base.h"
17 #include "ash/test/cursor_manager_test_api.h"
18 #include "ash/test/shell_test_api.h"
19 #include "ash/test/test_shelf_delegate.h"
20 #include "ash/wm/drag_window_resizer.h"
21 #include "ash/wm/panels/panel_layout_manager.h"
22 #include "ash/wm/window_state.h"
23 #include "base/win/windows_version.h"
24 #include "ui/aura/client/aura_constants.h"
25 #include "ui/aura/root_window.h"
26 #include "ui/base/hit_test.h"
27 #include "ui/base/l10n/l10n_util.h"
28 #include "ui/base/ui_base_types.h"
29 #include "ui/views/corewm/window_util.h"
30 #include "ui/views/widget/widget.h"
32 namespace ash {
33 namespace internal {
35 class PanelWindowResizerTest : public test::AshTestBase {
36 public:
37 PanelWindowResizerTest() {}
38 virtual ~PanelWindowResizerTest() {}
40 virtual void SetUp() OVERRIDE {
41 AshTestBase::SetUp();
42 UpdateDisplay("600x400");
43 test::ShellTestApi test_api(Shell::GetInstance());
44 model_ = test_api.shelf_model();
45 shelf_delegate_ = test::TestShelfDelegate::instance();
48 virtual void TearDown() OVERRIDE {
49 AshTestBase::TearDown();
52 protected:
53 gfx::Point CalculateDragPoint(const WindowResizer& resizer,
54 int delta_x,
55 int delta_y) const {
56 gfx::Point location = resizer.GetInitialLocation();
57 location.set_x(location.x() + delta_x);
58 location.set_y(location.y() + delta_y);
59 return location;
62 aura::Window* CreatePanelWindow(const gfx::Point& origin) {
63 gfx::Rect bounds(origin, gfx::Size(101, 101));
64 aura::Window* window = CreateTestWindowInShellWithDelegateAndType(
65 NULL, ui::wm::WINDOW_TYPE_PANEL, 0, bounds);
66 shelf_delegate_->AddLauncherItem(window);
67 PanelLayoutManager* manager =
68 static_cast<PanelLayoutManager*>(
69 Shell::GetContainer(window->GetRootWindow(),
70 internal::kShellWindowId_PanelContainer)->
71 layout_manager());
72 manager->Relayout();
73 return window;
76 void DragStart(aura::Window* window) {
77 resizer_.reset(CreateWindowResizer(
78 window,
79 window->bounds().origin(),
80 HTCAPTION,
81 aura::client::WINDOW_MOVE_SOURCE_MOUSE).release());
82 ASSERT_TRUE(resizer_.get());
85 void DragMove(int dx, int dy) {
86 resizer_->Drag(CalculateDragPoint(*resizer_, dx, dy), 0);
89 void DragEnd() {
90 resizer_->CompleteDrag();
91 resizer_.reset();
94 void DragRevert() {
95 resizer_->RevertDrag();
96 resizer_.reset();
99 // Test dragging the panel slightly, then detaching, and then reattaching
100 // dragging out by the vector (dx, dy).
101 void DetachReattachTest(aura::Window* window, int dx, int dy) {
102 wm::WindowState* window_state = wm::GetWindowState(window);
103 EXPECT_TRUE(window_state->panel_attached());
104 aura::Window* root_window = window->GetRootWindow();
105 EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id());
106 DragStart(window);
107 gfx::Rect initial_bounds = window->GetBoundsInScreen();
109 // Drag the panel slightly. The window should still be snapped to the
110 // launcher.
111 DragMove(dx * 5, dy * 5);
112 EXPECT_EQ(initial_bounds.x(), window->GetBoundsInScreen().x());
113 EXPECT_EQ(initial_bounds.y(), window->GetBoundsInScreen().y());
115 // Drag further out and the window should now move to the cursor.
116 DragMove(dx * 100, dy * 100);
117 EXPECT_EQ(initial_bounds.x() + dx * 100, window->GetBoundsInScreen().x());
118 EXPECT_EQ(initial_bounds.y() + dy * 100, window->GetBoundsInScreen().y());
120 // The panel should be detached when the drag completes.
121 DragEnd();
123 EXPECT_FALSE(window_state->panel_attached());
124 EXPECT_EQ(internal::kShellWindowId_DefaultContainer,
125 window->parent()->id());
126 EXPECT_EQ(root_window, window->GetRootWindow());
128 DragStart(window);
129 // Drag the panel down.
130 DragMove(dx * -95, dy * -95);
131 // Release the mouse and the panel should be reattached.
132 DragEnd();
134 // The panel should be reattached and have snapped to the launcher.
135 EXPECT_TRUE(window_state->panel_attached());
136 EXPECT_EQ(initial_bounds.x(), window->GetBoundsInScreen().x());
137 EXPECT_EQ(initial_bounds.y(), window->GetBoundsInScreen().y());
138 EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id());
141 void TestWindowOrder(const std::vector<aura::Window*>& window_order) {
142 int panel_index = model_->FirstPanelIndex();
143 EXPECT_EQ((int)(panel_index + window_order.size()), model_->item_count());
144 for (std::vector<aura::Window*>::const_iterator iter =
145 window_order.begin(); iter != window_order.end();
146 ++iter, ++panel_index) {
147 LauncherID id = GetLauncherIDForWindow(*iter);
148 EXPECT_EQ(id, model_->items()[panel_index].id);
152 // Test dragging panel window along the shelf and verify that panel icons
153 // are reordered appropriately.
154 void DragAlongShelfReorder(int dx, int dy) {
155 gfx::Point origin(0, 0);
156 scoped_ptr<aura::Window> w1(CreatePanelWindow(origin));
157 scoped_ptr<aura::Window> w2(CreatePanelWindow(origin));
158 std::vector<aura::Window*> window_order_original;
159 std::vector<aura::Window*> window_order_swapped;
160 window_order_original.push_back(w1.get());
161 window_order_original.push_back(w2.get());
162 window_order_swapped.push_back(w2.get());
163 window_order_swapped.push_back(w1.get());
164 TestWindowOrder(window_order_original);
166 // Drag window #2 to the beginning of the shelf.
167 DragStart(w2.get());
168 DragMove(400 * dx, 400 * dy);
169 TestWindowOrder(window_order_swapped);
170 DragEnd();
172 // Expect swapped window order.
173 TestWindowOrder(window_order_swapped);
175 // Drag window #2 back to the end.
176 DragStart(w2.get());
177 DragMove(-400 * dx, -400 * dy);
178 TestWindowOrder(window_order_original);
179 DragEnd();
181 // Expect original order.
182 TestWindowOrder(window_order_original);
185 private:
186 scoped_ptr<WindowResizer> resizer_;
187 internal::PanelLayoutManager* panel_layout_manager_;
188 ShelfModel* model_;
189 test::TestShelfDelegate* shelf_delegate_;
191 DISALLOW_COPY_AND_ASSIGN(PanelWindowResizerTest);
194 class PanelWindowResizerTextDirectionTest
195 : public PanelWindowResizerTest,
196 public testing::WithParamInterface<bool> {
197 public:
198 PanelWindowResizerTextDirectionTest() : is_rtl_(GetParam()) {}
199 virtual ~PanelWindowResizerTextDirectionTest() {}
201 virtual void SetUp() OVERRIDE {
202 original_locale = l10n_util::GetApplicationLocale(std::string());
203 if (is_rtl_)
204 base::i18n::SetICUDefaultLocale("he");
205 PanelWindowResizerTest::SetUp();
206 ASSERT_EQ(is_rtl_, base::i18n::IsRTL());
209 virtual void TearDown() OVERRIDE {
210 if (is_rtl_)
211 base::i18n::SetICUDefaultLocale(original_locale);
212 PanelWindowResizerTest::TearDown();
215 private:
216 bool is_rtl_;
217 std::string original_locale;
219 DISALLOW_COPY_AND_ASSIGN(PanelWindowResizerTextDirectionTest);
222 // PanelLayoutManager and PanelWindowResizer should work if panels have
223 // transient children of supported types.
224 class PanelWindowResizerTransientTest
225 : public PanelWindowResizerTest,
226 public testing::WithParamInterface<ui::wm::WindowType> {
227 public:
228 PanelWindowResizerTransientTest() : transient_window_type_(GetParam()) {}
229 virtual ~PanelWindowResizerTransientTest() {}
231 protected:
232 ui::wm::WindowType transient_window_type_;
234 private:
235 DISALLOW_COPY_AND_ASSIGN(PanelWindowResizerTransientTest);
238 // Verifies a window can be dragged from the panel and detached and then
239 // reattached.
240 TEST_F(PanelWindowResizerTest, PanelDetachReattachBottom) {
241 if (!SupportsHostWindowResize())
242 return;
244 scoped_ptr<aura::Window> window(
245 CreatePanelWindow(gfx::Point(0, 0)));
246 DetachReattachTest(window.get(), 0, -1);
249 TEST_F(PanelWindowResizerTest, PanelDetachReattachLeft) {
250 if (!SupportsHostWindowResize())
251 return;
253 ash::Shell* shell = ash::Shell::GetInstance();
254 shell->SetShelfAlignment(SHELF_ALIGNMENT_LEFT, shell->GetPrimaryRootWindow());
255 scoped_ptr<aura::Window> window(
256 CreatePanelWindow(gfx::Point(0, 0)));
257 DetachReattachTest(window.get(), 1, 0);
260 TEST_F(PanelWindowResizerTest, PanelDetachReattachRight) {
261 if (!SupportsHostWindowResize())
262 return;
264 ash::Shell* shell = ash::Shell::GetInstance();
265 shell->SetShelfAlignment(SHELF_ALIGNMENT_RIGHT,
266 shell->GetPrimaryRootWindow());
267 scoped_ptr<aura::Window> window(
268 CreatePanelWindow(gfx::Point(0, 0)));
269 DetachReattachTest(window.get(), -1, 0);
272 TEST_F(PanelWindowResizerTest, PanelDetachReattachTop) {
273 if (!SupportsHostWindowResize())
274 return;
276 ash::Shell* shell = ash::Shell::GetInstance();
277 shell->SetShelfAlignment(SHELF_ALIGNMENT_TOP, shell->GetPrimaryRootWindow());
278 scoped_ptr<aura::Window> window(
279 CreatePanelWindow(gfx::Point(0, 0)));
280 DetachReattachTest(window.get(), 0, 1);
283 TEST_F(PanelWindowResizerTest, PanelDetachReattachMultipleDisplays) {
284 if (!SupportsMultipleDisplays())
285 return;
287 UpdateDisplay("600x400,600x400");
288 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
289 scoped_ptr<aura::Window> window(
290 CreatePanelWindow(gfx::Point(600, 0)));
291 EXPECT_EQ(root_windows[1], window->GetRootWindow());
292 DetachReattachTest(window.get(), 0, -1);
295 TEST_F(PanelWindowResizerTest, DetachThenDragAcrossDisplays) {
296 if (!SupportsMultipleDisplays())
297 return;
299 UpdateDisplay("600x400,600x400");
300 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
301 scoped_ptr<aura::Window> window(
302 CreatePanelWindow(gfx::Point(0, 0)));
303 gfx::Rect initial_bounds = window->GetBoundsInScreen();
304 EXPECT_EQ(root_windows[0], window->GetRootWindow());
305 DragStart(window.get());
306 DragMove(0, -100);
307 DragEnd();
308 EXPECT_EQ(root_windows[0], window->GetRootWindow());
309 EXPECT_EQ(initial_bounds.x(), window->GetBoundsInScreen().x());
310 EXPECT_EQ(initial_bounds.y() - 100, window->GetBoundsInScreen().y());
311 EXPECT_FALSE(wm::GetWindowState(window.get())->panel_attached());
312 EXPECT_EQ(internal::kShellWindowId_DefaultContainer, window->parent()->id());
314 DragStart(window.get());
315 DragMove(500, 0);
316 DragEnd();
317 EXPECT_EQ(root_windows[1], window->GetRootWindow());
318 EXPECT_EQ(initial_bounds.x() + 500, window->GetBoundsInScreen().x());
319 EXPECT_EQ(initial_bounds.y() - 100, window->GetBoundsInScreen().y());
320 EXPECT_FALSE(wm::GetWindowState(window.get())->panel_attached());
321 EXPECT_EQ(internal::kShellWindowId_DefaultContainer, window->parent()->id());
324 TEST_F(PanelWindowResizerTest, DetachAcrossDisplays) {
325 if (!SupportsMultipleDisplays())
326 return;
328 UpdateDisplay("600x400,600x400");
329 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
330 scoped_ptr<aura::Window> window(
331 CreatePanelWindow(gfx::Point(0, 0)));
332 gfx::Rect initial_bounds = window->GetBoundsInScreen();
333 EXPECT_EQ(root_windows[0], window->GetRootWindow());
334 DragStart(window.get());
335 DragMove(500, -100);
336 DragEnd();
337 EXPECT_EQ(root_windows[1], window->GetRootWindow());
338 EXPECT_EQ(initial_bounds.x() + 500, window->GetBoundsInScreen().x());
339 EXPECT_EQ(initial_bounds.y() - 100, window->GetBoundsInScreen().y());
340 EXPECT_FALSE(wm::GetWindowState(window.get())->panel_attached());
341 EXPECT_EQ(internal::kShellWindowId_DefaultContainer, window->parent()->id());
344 TEST_F(PanelWindowResizerTest, DetachThenAttachToSecondDisplay) {
345 if (!SupportsMultipleDisplays())
346 return;
348 UpdateDisplay("600x400,600x600");
349 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
350 scoped_ptr<aura::Window> window(
351 CreatePanelWindow(gfx::Point(0, 0)));
352 gfx::Rect initial_bounds = window->GetBoundsInScreen();
353 EXPECT_EQ(root_windows[0], window->GetRootWindow());
355 // Detach the window.
356 DragStart(window.get());
357 DragMove(0, -100);
358 DragEnd();
359 EXPECT_EQ(root_windows[0], window->GetRootWindow());
360 EXPECT_FALSE(wm::GetWindowState(window.get())->panel_attached());
362 // Drag the window just above the other display's launcher.
363 DragStart(window.get());
364 DragMove(500, 295);
365 EXPECT_EQ(initial_bounds.x() + 500, window->GetBoundsInScreen().x());
367 // Should stick to other launcher.
368 EXPECT_EQ(initial_bounds.y() + 200, window->GetBoundsInScreen().y());
369 DragEnd();
371 // When dropped should move to second display's panel container.
372 EXPECT_EQ(root_windows[1], window->GetRootWindow());
373 EXPECT_TRUE(wm::GetWindowState(window.get())->panel_attached());
374 EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id());
377 TEST_F(PanelWindowResizerTest, AttachToSecondDisplay) {
378 if (!SupportsMultipleDisplays())
379 return;
381 UpdateDisplay("600x400,600x600");
382 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
383 scoped_ptr<aura::Window> window(
384 CreatePanelWindow(gfx::Point(0, 0)));
385 gfx::Rect initial_bounds = window->GetBoundsInScreen();
386 EXPECT_EQ(root_windows[0], window->GetRootWindow());
388 // Drag the window just above the other display's launcher.
389 DragStart(window.get());
390 DragMove(500, 195);
391 EXPECT_EQ(initial_bounds.x() + 500, window->GetBoundsInScreen().x());
393 // Should stick to other launcher.
394 EXPECT_EQ(initial_bounds.y() + 200, window->GetBoundsInScreen().y());
395 DragEnd();
397 // When dropped should move to second display's panel container.
398 EXPECT_EQ(root_windows[1], window->GetRootWindow());
399 EXPECT_TRUE(wm::GetWindowState(window.get())->panel_attached());
400 EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id());
403 TEST_F(PanelWindowResizerTest, RevertDragRestoresAttachment) {
404 scoped_ptr<aura::Window> window(
405 CreatePanelWindow(gfx::Point(0, 0)));
406 EXPECT_TRUE(wm::GetWindowState(window.get())->panel_attached());
407 EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id());
408 DragStart(window.get());
409 DragMove(0, -100);
410 DragRevert();
411 EXPECT_TRUE(wm::GetWindowState(window.get())->panel_attached());
412 EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id());
414 // Detach panel.
415 DragStart(window.get());
416 DragMove(0, -100);
417 DragEnd();
418 EXPECT_FALSE(wm::GetWindowState(window.get())->panel_attached());
419 EXPECT_EQ(internal::kShellWindowId_DefaultContainer, window->parent()->id());
421 // Drag back to launcher.
422 DragStart(window.get());
423 DragMove(0, 100);
425 // When the drag is reverted it should remain detached.
426 DragRevert();
427 EXPECT_FALSE(wm::GetWindowState(window.get())->panel_attached());
428 EXPECT_EQ(internal::kShellWindowId_DefaultContainer, window->parent()->id());
431 TEST_F(PanelWindowResizerTest, DragMovesToPanelLayer) {
432 scoped_ptr<aura::Window> window(CreatePanelWindow(gfx::Point(0, 0)));
433 DragStart(window.get());
434 DragMove(0, -100);
435 DragEnd();
436 EXPECT_EQ(internal::kShellWindowId_DefaultContainer, window->parent()->id());
438 // While moving the panel window should be moved to the panel container.
439 DragStart(window.get());
440 DragMove(20, 0);
441 EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id());
442 DragEnd();
444 // When dropped it should return to the default container.
445 EXPECT_EQ(internal::kShellWindowId_DefaultContainer,
446 window->parent()->id());
449 TEST_P(PanelWindowResizerTextDirectionTest, DragReordersPanelsHorizontal) {
450 if (!SupportsHostWindowResize())
451 return;
453 DragAlongShelfReorder(base::i18n::IsRTL() ? 1 : -1, 0);
456 TEST_F(PanelWindowResizerTest, DragReordersPanelsVertical) {
457 if (!SupportsHostWindowResize())
458 return;
460 ash::Shell* shell = ash::Shell::GetInstance();
461 shell->SetShelfAlignment(SHELF_ALIGNMENT_LEFT, shell->GetPrimaryRootWindow());
462 DragAlongShelfReorder(0, -1);
465 // Tests that panels can have transient children of different types.
466 // The transient children should be reparented in sync with the panel.
467 TEST_P(PanelWindowResizerTransientTest, PanelWithTransientChild) {
468 if (!SupportsHostWindowResize())
469 return;
471 scoped_ptr<aura::Window> window(CreatePanelWindow(gfx::Point(0, 0)));
472 scoped_ptr<aura::Window> child(CreateTestWindowInShellWithDelegateAndType(
473 NULL, transient_window_type_, 0, gfx::Rect(20, 20, 150, 40)));
474 views::corewm::AddTransientChild(window.get(), child.get());
475 if (window->parent() != child->parent())
476 window->parent()->AddChild(child.get());
477 EXPECT_EQ(window.get(), views::corewm::GetTransientParent(child.get()));
479 // Drag the child to the shelf. Its new position should not be overridden.
480 const gfx::Rect attached_bounds(window->GetBoundsInScreen());
481 const int dy = window->GetBoundsInScreen().bottom() -
482 child->GetBoundsInScreen().bottom();
483 DragStart(child.get());
484 DragMove(50, dy);
485 // While moving the transient child window should be in the panel container.
486 EXPECT_EQ(internal::kShellWindowId_PanelContainer, child->parent()->id());
487 DragEnd();
488 // Child should move, |window| should not.
489 EXPECT_EQ(gfx::Point(20 + 50, 20 + dy).ToString(),
490 child->GetBoundsInScreen().origin().ToString());
491 EXPECT_EQ(attached_bounds.ToString(), window->GetBoundsInScreen().ToString());
493 // Drag the child along the the shelf past the |window|.
494 // Its new position should not be overridden.
495 DragStart(child.get());
496 DragMove(350, 0);
497 // While moving the transient child window should be in the panel container.
498 EXPECT_EQ(internal::kShellWindowId_PanelContainer, child->parent()->id());
499 DragEnd();
500 // |child| should move, |window| should not.
501 EXPECT_EQ(gfx::Point(20 + 50 + 350, 20 + dy).ToString(),
502 child->GetBoundsInScreen().origin().ToString());
503 EXPECT_EQ(attached_bounds.ToString(), window->GetBoundsInScreen().ToString());
505 DragStart(window.get());
506 DragMove(0, -100);
507 // While moving the windows should be in the panel container.
508 EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id());
509 EXPECT_EQ(internal::kShellWindowId_PanelContainer, child->parent()->id());
510 DragEnd();
511 // When dropped they should return to the default container.
512 EXPECT_EQ(internal::kShellWindowId_DefaultContainer, window->parent()->id());
513 EXPECT_EQ(internal::kShellWindowId_DefaultContainer, child->parent()->id());
515 // While moving the window and child should be moved to the panel container.
516 DragStart(window.get());
517 DragMove(20, 0);
518 EXPECT_EQ(internal::kShellWindowId_PanelContainer, window->parent()->id());
519 EXPECT_EQ(internal::kShellWindowId_PanelContainer, child->parent()->id());
520 DragEnd();
522 // When dropped they should return to the default container.
523 EXPECT_EQ(internal::kShellWindowId_DefaultContainer, window->parent()->id());
524 EXPECT_EQ(internal::kShellWindowId_DefaultContainer, child->parent()->id());
527 INSTANTIATE_TEST_CASE_P(LtrRtl, PanelWindowResizerTextDirectionTest,
528 testing::Bool());
529 INSTANTIATE_TEST_CASE_P(NormalPanelPopup,
530 PanelWindowResizerTransientTest,
531 testing::Values(ui::wm::WINDOW_TYPE_NORMAL,
532 ui::wm::WINDOW_TYPE_PANEL,
533 ui::wm::WINDOW_TYPE_POPUP));
535 } // namespace internal
536 } // namespace ash