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/dock/docked_window_resizer.h"
7 #include "ash/ash_switches.h"
8 #include "ash/root_window_controller.h"
9 #include "ash/screen_util.h"
10 #include "ash/shelf/shelf.h"
11 #include "ash/shelf/shelf_layout_manager.h"
12 #include "ash/shelf/shelf_model.h"
13 #include "ash/shelf/shelf_types.h"
14 #include "ash/shelf/shelf_widget.h"
15 #include "ash/shell.h"
16 #include "ash/shell_window_ids.h"
17 #include "ash/test/ash_test_base.h"
18 #include "ash/test/cursor_manager_test_api.h"
19 #include "ash/test/shell_test_api.h"
20 #include "ash/test/test_shelf_delegate.h"
21 #include "ash/wm/dock/docked_window_layout_manager.h"
22 #include "ash/wm/drag_window_resizer.h"
23 #include "ash/wm/panels/panel_layout_manager.h"
24 #include "ash/wm/window_state.h"
25 #include "ash/wm/window_util.h"
26 #include "ash/wm/wm_event.h"
27 #include "base/command_line.h"
28 #include "ui/aura/client/aura_constants.h"
29 #include "ui/aura/client/window_tree_client.h"
30 #include "ui/aura/test/test_window_delegate.h"
31 #include "ui/aura/window_event_dispatcher.h"
32 #include "ui/base/hit_test.h"
33 #include "ui/base/ui_base_types.h"
34 #include "ui/events/test/event_generator.h"
35 #include "ui/views/widget/widget.h"
36 #include "ui/wm/core/coordinate_conversion.h"
37 #include "ui/wm/core/window_util.h"
41 class DockedWindowResizerTest
42 : public test::AshTestBase
,
43 public testing::WithParamInterface
<ui::wm::WindowType
> {
45 DockedWindowResizerTest() : model_(NULL
), window_type_(GetParam()) {}
46 virtual ~DockedWindowResizerTest() {}
48 void SetUp() override
{
50 UpdateDisplay("600x400");
51 test::ShellTestApi
test_api(Shell::GetInstance());
52 model_
= test_api
.shelf_model();
55 void TearDown() override
{ AshTestBase::TearDown(); }
64 int ideal_width() const { return DockedWindowLayoutManager::kIdealWidth
; }
65 int min_dock_gap() const { return DockedWindowLayoutManager::kMinDockGap
; }
66 int max_width() const { return DockedWindowLayoutManager::kMaxDockWidth
; }
67 int docked_width(const DockedWindowLayoutManager
* layout_manager
) const {
68 return layout_manager
->docked_width_
;
70 int docked_alignment(const DockedWindowLayoutManager
* layout_manager
) const {
71 return layout_manager
->alignment_
;
73 aura::Window
* CreateTestWindow(const gfx::Rect
& bounds
) {
74 aura::Window
* window
= CreateTestWindowInShellWithDelegateAndType(
79 if (window_type_
== ui::wm::WINDOW_TYPE_PANEL
) {
80 test::TestShelfDelegate
* shelf_delegate
=
81 test::TestShelfDelegate::instance();
82 shelf_delegate
->AddShelfItem(window
);
83 PanelLayoutManager
* manager
= static_cast<PanelLayoutManager
*>(
84 Shell::GetContainer(window
->GetRootWindow(),
85 kShellWindowId_PanelContainer
)->layout_manager());
91 aura::Window
* CreateModalWindow(const gfx::Rect
& bounds
) {
92 aura::Window
* window
= new aura::Window(&delegate_
);
93 window
->SetProperty(aura::client::kModalKey
, ui::MODAL_TYPE_SYSTEM
);
94 window
->SetType(ui::wm::WINDOW_TYPE_NORMAL
);
95 window
->Init(aura::WINDOW_LAYER_TEXTURED
);
98 if (bounds
.IsEmpty()) {
99 ParentWindowInPrimaryRootWindow(window
);
101 gfx::Display display
=
102 Shell::GetScreen()->GetDisplayMatching(bounds
);
103 aura::Window
* root
= ash::Shell::GetInstance()->display_controller()->
104 GetRootWindowForDisplayId(display
.id());
105 gfx::Point origin
= bounds
.origin();
106 ::wm::ConvertPointFromScreen(root
, &origin
);
107 window
->SetBounds(gfx::Rect(origin
, bounds
.size()));
108 aura::client::ParentWindowWithContext(window
, root
, bounds
);
113 static WindowResizer
* CreateSomeWindowResizer(
114 aura::Window
* window
,
115 const gfx::Point
& point_in_parent
,
116 int window_component
) {
117 return CreateWindowResizer(
121 aura::client::WINDOW_MOVE_SOURCE_MOUSE
).release();
124 void DragStart(aura::Window
* window
) {
125 DragStartAtOffsetFromWindowOrigin(window
, 0, 0);
128 void DragStartAtOffsetFromWindowOrigin(aura::Window
* window
,
130 initial_location_in_parent_
=
131 window
->bounds().origin() + gfx::Vector2d(dx
, dy
);
132 resizer_
.reset(CreateSomeWindowResizer(window
,
133 initial_location_in_parent_
,
135 ASSERT_TRUE(resizer_
.get());
138 void ResizeStartAtOffsetFromWindowOrigin(aura::Window
* window
,
140 int window_component
) {
141 initial_location_in_parent_
=
142 window
->bounds().origin() + gfx::Vector2d(dx
, dy
);
143 resizer_
.reset(CreateSomeWindowResizer(window
,
144 initial_location_in_parent_
,
146 ASSERT_TRUE(resizer_
.get());
149 void DragMove(int dx
, int dy
) {
150 resizer_
->Drag(initial_location_in_parent_
+ gfx::Vector2d(dx
, dy
), 0);
154 resizer_
->CompleteDrag();
159 resizer_
->RevertDrag();
163 // Panels are parented by panel container during drags.
164 // All other windows that are tested here are parented by dock container
166 int CorrectContainerIdDuringDrag() {
167 if (window_type_
== ui::wm::WINDOW_TYPE_PANEL
)
168 return kShellWindowId_PanelContainer
;
169 return kShellWindowId_DockedContainer
;
172 // Test dragging the window vertically (to detach if it is a panel) and then
173 // horizontally to the edge with an added offset from the edge of |dx|.
174 void DragRelativeToEdge(DockedEdge edge
,
175 aura::Window
* window
,
177 DragVerticallyAndRelativeToEdge(
181 window_type_
== ui::wm::WINDOW_TYPE_PANEL
? -100 : 20,
186 void DragToVerticalPositionAndToEdge(DockedEdge edge
,
187 aura::Window
* window
,
189 DragToVerticalPositionRelativeToEdge(edge
, window
, 0, y
);
192 void DragToVerticalPositionRelativeToEdge(DockedEdge edge
,
193 aura::Window
* window
,
196 gfx::Rect initial_bounds
= window
->GetBoundsInScreen();
197 DragVerticallyAndRelativeToEdge(edge
,
199 dx
, y
- initial_bounds
.y(),
203 // Detach if our window is a panel, then drag it vertically by |dy| and
204 // horizontally to the edge with an added offset from the edge of |dx|.
205 void DragVerticallyAndRelativeToEdge(DockedEdge edge
,
206 aura::Window
* window
,
208 int grab_x
, int grab_y
) {
209 gfx::Rect initial_bounds
= window
->GetBoundsInScreen();
210 // avoid snap by clicking away from the border
211 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromWindowOrigin(window
,
214 gfx::Rect work_area
=
215 Shell::GetScreen()->GetDisplayNearestWindow(window
).work_area();
216 gfx::Point initial_location_in_screen
= initial_location_in_parent_
;
217 ::wm::ConvertPointToScreen(window
->parent(), &initial_location_in_screen
);
218 // Drag the window left or right to the edge (or almost to it).
219 if (edge
== DOCKED_EDGE_LEFT
)
220 dx
+= work_area
.x() - initial_location_in_screen
.x();
221 else if (edge
== DOCKED_EDGE_RIGHT
)
222 dx
+= work_area
.right() - 1 - initial_location_in_screen
.x();
224 EXPECT_EQ(CorrectContainerIdDuringDrag(), window
->parent()->id());
225 // Release the mouse and the panel should be attached to the dock.
228 // x-coordinate can get adjusted by snapping or sticking.
229 // y-coordinate could be changed by possible automatic layout if docked.
230 if (window
->parent()->id() != kShellWindowId_DockedContainer
&&
231 !wm::GetWindowState(window
)->HasRestoreBounds()) {
232 EXPECT_EQ(initial_bounds
.y() + dy
, window
->GetBoundsInScreen().y());
236 bool test_panels() const { return window_type_
== ui::wm::WINDOW_TYPE_PANEL
; }
238 aura::test::TestWindowDelegate
* delegate() {
242 const gfx::Point
& initial_location_in_parent() const {
243 return initial_location_in_parent_
;
247 scoped_ptr
<WindowResizer
> resizer_
;
249 ui::wm::WindowType window_type_
;
250 aura::test::TestWindowDelegate delegate_
;
252 // Location at start of the drag in |window->parent()|'s coordinates.
253 gfx::Point initial_location_in_parent_
;
255 DISALLOW_COPY_AND_ASSIGN(DockedWindowResizerTest
);
258 // Verifies a window can be dragged and attached to the dock.
259 TEST_P(DockedWindowResizerTest
, AttachRightPrecise
) {
260 if (!SupportsHostWindowResize())
263 scoped_ptr
<aura::Window
> window(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
264 DragRelativeToEdge(DOCKED_EDGE_RIGHT
, window
.get(), 0);
266 // The window should be docked at the right edge.
267 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right(),
268 window
->GetBoundsInScreen().right());
269 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
272 // Verifies a window can be dragged and attached to the dock
273 // even if pointer overshoots the screen edge by a few pixels (sticky edge)
274 TEST_P(DockedWindowResizerTest
, AttachRightOvershoot
) {
275 if (!SupportsHostWindowResize())
278 scoped_ptr
<aura::Window
> window(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
279 DragRelativeToEdge(DOCKED_EDGE_RIGHT
, window
.get(), +4);
281 // The window should be docked at the right edge.
282 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right(),
283 window
->GetBoundsInScreen().right());
284 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
287 // Verifies a window can be dragged and then if a pointer is not quite reaching
288 // the screen edge the window does not get docked and stays in the desktop.
289 TEST_P(DockedWindowResizerTest
, AttachRightUndershoot
) {
290 if (!SupportsHostWindowResize())
293 scoped_ptr
<aura::Window
> window(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
294 // Grabbing at 70px ensures that at least 30% of the window is in screen,
295 // otherwise the window would be adjusted in
296 // WorkspaceLayoutManager::AdjustWindowBoundsWhenAdded.
297 const int kGrabOffsetX
= 70;
298 const int kUndershootBy
= 1;
299 DragVerticallyAndRelativeToEdge(DOCKED_EDGE_RIGHT
,
301 -kUndershootBy
, test_panels() ? -100 : 20,
304 // The window right should be past the screen edge but not docked.
305 // Initial touch point is 70px to the right which helps to find where the edge
307 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right() +
308 window
->bounds().width() - kGrabOffsetX
- kUndershootBy
- 1,
309 window
->GetBoundsInScreen().right());
310 EXPECT_EQ(kShellWindowId_DefaultContainer
, window
->parent()->id());
313 // Verifies a window can be dragged and attached to the dock.
314 TEST_P(DockedWindowResizerTest
, AttachLeftPrecise
) {
315 if (!SupportsHostWindowResize())
318 scoped_ptr
<aura::Window
> window(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
319 DragRelativeToEdge(DOCKED_EDGE_LEFT
, window
.get(), 0);
321 // The window should be docked at the left edge.
322 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().x(),
323 window
->GetBoundsInScreen().x());
324 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
327 // Verifies a window can be dragged and attached to the dock
328 // even if pointer overshoots the screen edge by a few pixels (sticky edge)
329 TEST_P(DockedWindowResizerTest
, AttachLeftOvershoot
) {
330 if (!SupportsHostWindowResize())
333 scoped_ptr
<aura::Window
> window(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
334 DragRelativeToEdge(DOCKED_EDGE_LEFT
, window
.get(), -4);
336 // The window should be docked at the left edge.
337 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().x(),
338 window
->GetBoundsInScreen().x());
339 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
342 // Verifies a window can be dragged and then if a pointer is not quite reaching
343 // the screen edge the window does not get docked and stays in the desktop.
344 TEST_P(DockedWindowResizerTest
, AttachLeftUndershoot
) {
345 if (!SupportsHostWindowResize())
348 scoped_ptr
<aura::Window
> window(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
349 gfx::Rect
initial_bounds(window
->bounds());
350 DragRelativeToEdge(DOCKED_EDGE_LEFT
, window
.get(), 1);
352 // The window should be crossing the screen edge but not docked.
353 int expected_x
= initial_bounds
.x() - initial_location_in_parent().x() + 1;
354 EXPECT_EQ(expected_x
, window
->GetBoundsInScreen().x());
355 EXPECT_EQ(kShellWindowId_DefaultContainer
, window
->parent()->id());
358 // Dock on the right side, change shelf alignment, check that windows move to
359 // the opposite side.
360 TEST_P(DockedWindowResizerTest
, AttachRightChangeShelf
) {
361 if (!SupportsHostWindowResize())
364 scoped_ptr
<aura::Window
> window(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
365 DragRelativeToEdge(DOCKED_EDGE_RIGHT
, window
.get(), 0);
367 // The window should be docked at the right edge.
368 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right(),
369 window
->GetBoundsInScreen().right());
370 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
372 // set launcher shelf to be aligned on the right
373 ash::Shell
* shell
= ash::Shell::GetInstance();
374 shell
->SetShelfAlignment(SHELF_ALIGNMENT_RIGHT
,
375 shell
->GetPrimaryRootWindow());
376 // The window should have moved and get attached to the left dock.
377 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().x(),
378 window
->GetBoundsInScreen().x());
379 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
381 // set launcher shelf to be aligned on the left
382 shell
->SetShelfAlignment(SHELF_ALIGNMENT_LEFT
,
383 shell
->GetPrimaryRootWindow());
384 // The window should have moved and get attached to the right edge.
385 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right(),
386 window
->GetBoundsInScreen().right());
387 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
389 // set launcher shelf to be aligned at the bottom
390 shell
->SetShelfAlignment(SHELF_ALIGNMENT_BOTTOM
,
391 shell
->GetPrimaryRootWindow());
392 // The window should stay in the right edge.
393 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right(),
394 window
->GetBoundsInScreen().right());
395 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
398 // Dock on the right side, try to undock, then drag more to really undock
399 TEST_P(DockedWindowResizerTest
, AttachTryDetach
) {
400 if (!SupportsHostWindowResize())
403 scoped_ptr
<aura::Window
> window(CreateTestWindow(
404 gfx::Rect(0, 0, ideal_width() + 10, 201)));
405 DragRelativeToEdge(DOCKED_EDGE_RIGHT
, window
.get(), 0);
407 // The window should be docked at the right edge.
408 // Its width should shrink to ideal width.
409 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right(),
410 window
->GetBoundsInScreen().right());
411 EXPECT_EQ(ideal_width(), window
->GetBoundsInScreen().width());
412 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
414 // Try to detach by dragging left less than kSnapToDockDistance.
415 // The window should stay docked.
416 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromWindowOrigin(
417 window
.get(), 10, 0));
419 // Release the mouse and the window should be still attached to the dock.
422 // The window should be still attached to the right edge.
423 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right(),
424 window
->GetBoundsInScreen().right());
425 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
427 // Try to detach by dragging left by kSnapToDockDistance or more.
428 // The window should get undocked.
429 const int left_edge
= window
->bounds().x();
430 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromWindowOrigin(
431 window
.get(), 10, 0));
433 // Release the mouse and the window should be no longer attached to the dock.
436 // The window should be floating on the desktop again and moved to the left.
437 EXPECT_EQ(left_edge
- 32, window
->GetBoundsInScreen().x());
438 EXPECT_EQ(kShellWindowId_DefaultContainer
, window
->parent()->id());
441 // Dock on the right side, and undock by dragging the right edge of the window
442 // header. This test is useful because both the position of the dragged window
443 // and the position of the mouse are used in determining whether a window should
445 TEST_P(DockedWindowResizerTest
, AttachTryDetachDragRightEdgeOfHeader
) {
446 if (!SupportsHostWindowResize())
449 scoped_ptr
<aura::Window
> window(CreateTestWindow(
450 gfx::Rect(0, 0, ideal_width() + 10, 201)));
451 DragRelativeToEdge(DOCKED_EDGE_RIGHT
, window
.get(), 0);
453 // The window should be docked at the right edge.
454 // Its width should shrink to ideal width.
455 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right(),
456 window
->GetBoundsInScreen().right());
457 EXPECT_EQ(ideal_width(), window
->GetBoundsInScreen().width());
458 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
460 // Try to detach by dragging left less than kSnapToDockDistance.
461 // The window should stay docked.
462 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromWindowOrigin(
463 window
.get(), ideal_width() - 10, 0));
465 // Release the mouse and the window should be still attached to the dock.
468 // The window should be still attached to the right edge.
469 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right(),
470 window
->GetBoundsInScreen().right());
471 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
473 // Try to detach by dragging left by kSnapToDockDistance or more.
474 // The window should get undocked.
475 const int left_edge
= window
->bounds().x();
476 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromWindowOrigin(
477 window
.get(), ideal_width() - 10, 0));
479 // Release the mouse and the window should be no longer attached to the dock.
482 // The window should be floating on the desktop again and moved to the left.
483 EXPECT_EQ(left_edge
- 32, window
->GetBoundsInScreen().x());
484 EXPECT_EQ(kShellWindowId_DefaultContainer
, window
->parent()->id());
487 // Minimize a docked window, then restore it and check that it is still docked.
488 TEST_P(DockedWindowResizerTest
, AttachMinimizeRestore
) {
489 if (!SupportsHostWindowResize())
492 scoped_ptr
<aura::Window
> window(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
493 DragRelativeToEdge(DOCKED_EDGE_RIGHT
, window
.get(), 0);
495 // The window should be docked at the right edge.
496 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right(),
497 window
->GetBoundsInScreen().right());
498 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
500 wm::WindowState
* window_state
= wm::GetWindowState(window
.get());
501 // Minimize the window, it should be hidden.
502 window_state
->Minimize();
503 RunAllPendingInMessageLoop();
504 EXPECT_FALSE(window
->IsVisible());
505 EXPECT_TRUE(window_state
->IsMinimized());
506 // Restore the window; window should be visible.
507 window_state
->Restore();
508 RunAllPendingInMessageLoop();
509 EXPECT_TRUE(window
->IsVisible());
510 EXPECT_TRUE(window_state
->IsDocked());
513 // Maximize a docked window and check that it is maximized and no longer docked.
514 TEST_P(DockedWindowResizerTest
, AttachMaximize
) {
515 if (!SupportsHostWindowResize())
518 scoped_ptr
<aura::Window
> window(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
519 DragRelativeToEdge(DOCKED_EDGE_RIGHT
, window
.get(), 0);
521 // The window should be docked at the right edge.
522 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right(),
523 window
->GetBoundsInScreen().right());
524 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
526 wm::WindowState
* window_state
= wm::GetWindowState(window
.get());
527 // Maximize the window, it should get undocked and maximized in a desktop.
528 window_state
->Maximize();
529 RunAllPendingInMessageLoop();
530 EXPECT_TRUE(window
->IsVisible());
531 EXPECT_TRUE(window_state
->IsMaximized());
532 EXPECT_EQ(kShellWindowId_DefaultContainer
, window
->parent()->id());
535 // Dock two windows, undock one, check that the other one is still docked.
536 TEST_P(DockedWindowResizerTest
, AttachTwoWindows
) {
537 if (!SupportsHostWindowResize())
539 UpdateDisplay("600x600");
541 scoped_ptr
<aura::Window
> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
542 scoped_ptr
<aura::Window
> w2(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
543 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
544 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w2
.get(), 50);
546 // Docking second window should not minimize the first.
547 wm::WindowState
* window_state1
= wm::GetWindowState(w1
.get());
548 EXPECT_FALSE(window_state1
->IsMinimized());
550 // Both windows should be docked at the right edge.
551 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
552 w1
->GetBoundsInScreen().right());
553 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
555 EXPECT_EQ(w2
->GetRootWindow()->GetBoundsInScreen().right(),
556 w2
->GetBoundsInScreen().right());
557 EXPECT_EQ(kShellWindowId_DockedContainer
, w2
->parent()->id());
559 // Detach by dragging left (should get undocked).
560 const int left_edge
= w2
->bounds().x();
561 ASSERT_NO_FATAL_FAILURE(DragStart(w2
.get()));
562 // Drag up as well to avoid attaching panels to launcher shelf.
564 // Release the mouse and the window should be no longer attached to the edge.
567 // The first window should be still docked.
568 EXPECT_FALSE(window_state1
->IsMinimized());
569 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
570 w1
->GetBoundsInScreen().right());
571 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
573 // The window should be floating on the desktop again and moved to the left.
574 EXPECT_EQ(left_edge
- 32, w2
->GetBoundsInScreen().x());
575 EXPECT_EQ(kShellWindowId_DefaultContainer
, w2
->parent()->id());
578 // Create two windows, dock one and change shelf to auto-hide.
579 TEST_P(DockedWindowResizerTest
, AttachOneAutoHideShelf
) {
580 if (!SupportsHostWindowResize())
583 scoped_ptr
<aura::Window
> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
584 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
586 // w1 should be docked at the right edge.
587 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
588 w1
->GetBoundsInScreen().right());
589 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
591 scoped_ptr
<aura::Window
> w2(CreateTestWindowInShellWithDelegateAndType(
592 NULL
, ui::wm::WINDOW_TYPE_NORMAL
, 0, gfx::Rect(20, 20, 150, 20)));
593 wm::GetWindowState(w2
.get())->Maximize();
594 EXPECT_EQ(kShellWindowId_DefaultContainer
, w2
->parent()->id());
595 EXPECT_TRUE(wm::GetWindowState(w2
.get())->IsMaximized());
597 gfx::Rect work_area
=
598 Shell::GetScreen()->GetDisplayNearestWindow(w1
.get()).work_area();
599 DockedWindowLayoutManager
* manager
=
600 static_cast<DockedWindowLayoutManager
*>(w1
->parent()->layout_manager());
602 // Docked window should be centered vertically in the work area.
603 EXPECT_EQ(work_area
.CenterPoint().y(), w1
->bounds().CenterPoint().y());
604 // Docked background should extend to the bottom of work area.
605 EXPECT_EQ(work_area
.bottom(), manager
->docked_bounds().bottom());
607 // set launcher shelf to be aligned on the right
608 ash::Shell
* shell
= ash::Shell::GetInstance();
609 shell
->SetShelfAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
,
610 shell
->GetPrimaryRootWindow());
612 Shell::GetScreen()->GetDisplayNearestWindow(w1
.get()).work_area();
613 // Docked window should be centered vertically in the work area.
614 EXPECT_EQ(work_area
.CenterPoint().y(), w1
->bounds().CenterPoint().y());
615 // Docked background should extend to the bottom of work area.
616 EXPECT_EQ(work_area
.bottom(), manager
->docked_bounds().bottom());
619 // Dock one window, try to dock another window on the opposite side (should not
621 TEST_P(DockedWindowResizerTest
, AttachOnTwoSides
) {
622 if (!SupportsHostWindowResize())
625 scoped_ptr
<aura::Window
> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
626 scoped_ptr
<aura::Window
> w2(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
627 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
628 gfx::Rect
initial_bounds(w2
->bounds());
629 DragToVerticalPositionAndToEdge(DOCKED_EDGE_LEFT
, w2
.get(), 50);
631 // The first window should be docked at the right edge.
632 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
633 w1
->GetBoundsInScreen().right());
634 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
636 // The second window should be near the left edge but not snapped.
637 // Normal window will get side-maximized while panels will not.
638 int expected_x
= test_panels() ?
639 (initial_bounds
.x() - initial_location_in_parent().x()) : 0;
640 EXPECT_EQ(expected_x
, w2
->GetBoundsInScreen().x());
641 EXPECT_EQ(kShellWindowId_DefaultContainer
, w2
->parent()->id());
644 // Tests that reverting a drag restores docked state if a window was docked.
645 TEST_P(DockedWindowResizerTest
, RevertDragRestoresAttachment
) {
646 if (!SupportsHostWindowResize())
649 scoped_ptr
<aura::Window
> window(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
650 DragRelativeToEdge(DOCKED_EDGE_RIGHT
, window
.get(), 0);
652 // The window should be docked at the right edge.
653 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right(),
654 window
->GetBoundsInScreen().right());
655 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
657 // Drag the window out but revert the drag
658 ASSERT_NO_FATAL_FAILURE(DragStart(window
.get()));
661 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
664 ASSERT_NO_FATAL_FAILURE(DragStart(window
.get()));
667 EXPECT_EQ(kShellWindowId_DefaultContainer
, window
->parent()->id());
670 // Tests that reverting drag restores undocked state if a window was not docked.
671 TEST_P(DockedWindowResizerTest
, RevertDockedDragRevertsAttachment
) {
672 if (!SupportsHostWindowResize())
674 scoped_ptr
<aura::Window
> window(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
675 aura::Window
* dock_container
= Shell::GetContainer(
676 window
->GetRootWindow(),
677 kShellWindowId_DockedContainer
);
678 DockedWindowLayoutManager
* manager
=
679 static_cast<DockedWindowLayoutManager
*>(dock_container
->layout_manager());
680 int previous_container_id
= window
->parent()->id();
681 // Drag the window out but revert the drag
682 ASSERT_NO_FATAL_FAILURE(DragStart(window
.get()));
683 DragMove(-50 - window
->bounds().x(), 50 - window
->bounds().y());
684 EXPECT_EQ(CorrectContainerIdDuringDrag(), window
->parent()->id());
686 EXPECT_EQ(previous_container_id
, window
->parent()->id());
687 EXPECT_EQ(DOCKED_ALIGNMENT_NONE
, docked_alignment(manager
));
689 // Drag a window to the left so that it overlaps the screen edge.
690 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromWindowOrigin(
692 window
->bounds().width()/2 + 10,
694 DragMove(-50 - window
->bounds().x(), 50 - window
->bounds().y());
696 // The window now overlaps the left screen edge but is not docked.
697 EXPECT_EQ(kShellWindowId_DefaultContainer
, window
->parent()->id());
698 EXPECT_EQ(DOCKED_ALIGNMENT_NONE
, docked_alignment(manager
));
699 EXPECT_LT(window
->bounds().x(), 0);
700 EXPECT_GT(window
->bounds().right(), 0);
702 // Drag the window further left and revert the drag.
703 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromWindowOrigin(
705 window
->bounds().width()/2 + 10,
709 // The window should be in default container and not docked.
710 EXPECT_EQ(kShellWindowId_DefaultContainer
, window
->parent()->id());
711 // Docked area alignment should be cleared.
712 EXPECT_EQ(DOCKED_ALIGNMENT_NONE
, docked_alignment(manager
));
715 // Move a docked window to the second display
716 TEST_P(DockedWindowResizerTest
, DragAcrossDisplays
) {
717 if (!SupportsMultipleDisplays())
720 UpdateDisplay("800x800,800x800");
721 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
722 EXPECT_EQ(2, static_cast<int>(root_windows
.size()));
723 scoped_ptr
<aura::Window
> window(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
724 gfx::Rect initial_bounds
= window
->GetBoundsInScreen();
725 EXPECT_EQ(root_windows
[0], window
->GetRootWindow());
727 DragRelativeToEdge(DOCKED_EDGE_RIGHT
, window
.get(), 0);
728 // The window should be docked at the right edge.
729 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right(),
730 window
->GetBoundsInScreen().right());
731 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
733 // Try dragging to the right - enough to get it peeking at the other screen
734 // but not enough to land in the other screen.
735 // The window should stay on the left screen.
736 ASSERT_NO_FATAL_FAILURE(DragStart(window
.get()));
738 EXPECT_EQ(CorrectContainerIdDuringDrag(), window
->parent()->id());
740 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right(),
741 window
->GetBoundsInScreen().right());
742 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
743 EXPECT_EQ(root_windows
[0], window
->GetRootWindow());
745 // Undock and move to the right - enough to get the mouse pointer past the
746 // edge of the screen and into the second screen. The window should now be
747 // in the second screen and not docked.
748 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromWindowOrigin(
750 window
->bounds().width()/2 + 10,
752 DragMove(window
->bounds().width()/2 - 5, 0);
753 EXPECT_EQ(CorrectContainerIdDuringDrag(), window
->parent()->id());
755 EXPECT_NE(window
->GetRootWindow()->GetBoundsInScreen().right(),
756 window
->GetBoundsInScreen().right());
757 EXPECT_EQ(kShellWindowId_DefaultContainer
, window
->parent()->id());
758 EXPECT_EQ(root_windows
[1], window
->GetRootWindow());
760 // Keep dragging it to the right until its left edge touches the screen edge.
761 // The window should now be in the second screen and not docked.
762 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromWindowOrigin(
764 window
->bounds().width()/2 + 10,
766 DragMove(window
->GetRootWindow()->GetBoundsInScreen().x() -
767 window
->GetBoundsInScreen().x(),
769 EXPECT_EQ(CorrectContainerIdDuringDrag(), window
->parent()->id());
771 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().x(),
772 window
->GetBoundsInScreen().x());
773 EXPECT_EQ(kShellWindowId_DefaultContainer
, window
->parent()->id());
774 EXPECT_EQ(root_windows
[1], window
->GetRootWindow());
777 // Dock two windows, undock one.
778 // Test the docked windows area size and default container resizing.
779 TEST_P(DockedWindowResizerTest
, AttachTwoWindowsDetachOne
) {
780 if (!SupportsHostWindowResize())
782 UpdateDisplay("600x600");
784 scoped_ptr
<aura::Window
> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
785 scoped_ptr
<aura::Window
> w2(CreateTestWindow(gfx::Rect(0, 0, 210, 201)));
786 // Work area should cover the whole screen.
787 EXPECT_EQ(ScreenUtil::GetDisplayBoundsInParent(w2
.get()).width(),
788 ScreenUtil::GetDisplayWorkAreaBoundsInParent(w2
.get()).width());
790 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
791 // A window should be docked at the right edge.
792 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
793 w1
->GetBoundsInScreen().right());
794 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
795 DockedWindowLayoutManager
* manager
=
796 static_cast<DockedWindowLayoutManager
*>(w1
->parent()->layout_manager());
797 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
798 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
800 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w2
.get(), 100);
801 // Both windows should now be docked at the right edge.
802 EXPECT_EQ(w2
->GetRootWindow()->GetBoundsInScreen().right(),
803 w2
->GetBoundsInScreen().right());
804 EXPECT_EQ(kShellWindowId_DockedContainer
, w2
->parent()->id());
805 // Dock width should be set to a wider window.
806 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
807 EXPECT_EQ(std::max(w1
->bounds().width(), w2
->bounds().width()),
808 docked_width(manager
));
810 // Try to detach by dragging left a bit (should not get undocked).
811 // This would normally detach a single docked window but since we have another
812 // window and the mouse pointer does not leave the dock area the window
813 // should stay docked.
814 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromWindowOrigin(w2
.get(), 60, 0));
815 // Drag up as well as left to avoid attaching panels to launcher shelf.
817 // Release the mouse and the window should be still attached to the edge.
820 // The first window should be still docked.
821 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
822 w1
->GetBoundsInScreen().right());
823 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
825 // The second window should be still docked.
826 EXPECT_EQ(w2
->GetRootWindow()->GetBoundsInScreen().right(),
827 w2
->GetBoundsInScreen().right());
828 EXPECT_EQ(kShellWindowId_DockedContainer
, w2
->parent()->id());
830 // Detach by dragging left more (should get undocked).
831 const int left_edge
= w2
->bounds().x();
832 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromWindowOrigin(
834 w2
->bounds().width()/2 + 10,
836 // Drag up as well to avoid attaching panels to launcher shelf.
837 const int drag_x
= -(w2
->bounds().width()/2 + 20);
838 DragMove(drag_x
, -100);
839 // Release the mouse and the window should be no longer attached to the edge.
842 // The second window should be floating on the desktop again.
843 EXPECT_EQ(left_edge
+ drag_x
, w2
->bounds().x());
844 EXPECT_EQ(kShellWindowId_DefaultContainer
, w2
->parent()->id());
845 // Dock width should be set to remaining single docked window.
846 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
847 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
848 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
851 // Dock one of the windows. Maximize other testing desktop resizing.
852 TEST_P(DockedWindowResizerTest
, AttachWindowMaximizeOther
) {
853 if (!SupportsHostWindowResize())
856 scoped_ptr
<aura::Window
> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
857 scoped_ptr
<aura::Window
> w2(CreateTestWindow(gfx::Rect(0, 0, 210, 201)));
858 // Work area should cover the whole screen.
859 EXPECT_EQ(ScreenUtil::GetDisplayBoundsInParent(w2
.get()).width(),
860 ScreenUtil::GetDisplayWorkAreaBoundsInParent(w2
.get()).width());
862 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
863 // A window should be docked at the right edge.
864 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
865 w1
->GetBoundsInScreen().right());
866 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
867 DockedWindowLayoutManager
* manager
=
868 static_cast<DockedWindowLayoutManager
*>(w1
->parent()->layout_manager());
869 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
870 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
872 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromWindowOrigin(w2
.get(), 25, 5));
873 DragMove(w2
->GetRootWindow()->bounds().width()
874 -w2
->bounds().width()
875 -(w2
->bounds().width()/2 + 20)
877 50 - w2
->bounds().y());
879 // The first window should be still docked.
880 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
881 w1
->GetBoundsInScreen().right());
882 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
884 // The second window should be floating on the desktop.
885 EXPECT_EQ(w2
->GetRootWindow()->GetBoundsInScreen().right() -
886 (w2
->bounds().width()/2 + 20),
887 w2
->GetBoundsInScreen().right());
888 EXPECT_EQ(kShellWindowId_DefaultContainer
, w2
->parent()->id());
889 // Dock width should be set to remaining single docked window.
890 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
891 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
892 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
893 // Desktop work area should now shrink.
894 EXPECT_EQ(ScreenUtil::GetDisplayBoundsInParent(w2
.get()).width() -
895 docked_width(manager
) - min_dock_gap(),
896 ScreenUtil::GetDisplayWorkAreaBoundsInParent(w2
.get()).width());
898 // Maximize the second window - Maximized area should be shrunk.
899 const gfx::Rect restored_bounds
= w2
->bounds();
900 wm::WindowState
* w2_state
= wm::GetWindowState(w2
.get());
901 w2_state
->Maximize();
902 EXPECT_EQ(ScreenUtil::GetDisplayBoundsInParent(w2
.get()).width() -
903 docked_width(manager
) - min_dock_gap(),
904 w2
->bounds().width());
906 // Detach the first window (this should require very little drag).
907 ASSERT_NO_FATAL_FAILURE(DragStart(w1
.get()));
908 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
910 // Alignment is set to "NONE" when drag starts.
911 EXPECT_EQ(DOCKED_ALIGNMENT_NONE
, docked_alignment(manager
));
912 // Release the mouse and the window should be no longer attached to the edge.
914 EXPECT_EQ(DOCKED_ALIGNMENT_NONE
, docked_alignment(manager
));
915 // Dock should get shrunk and desktop should get expanded.
916 EXPECT_EQ(kShellWindowId_DefaultContainer
, w1
->parent()->id());
917 EXPECT_EQ(kShellWindowId_DefaultContainer
, w2
->parent()->id());
918 EXPECT_EQ(DOCKED_ALIGNMENT_NONE
, docked_alignment(manager
));
919 EXPECT_EQ(0, docked_width(manager
));
920 // The second window should now get resized and take up the whole screen.
921 EXPECT_EQ(ScreenUtil::GetDisplayBoundsInParent(w2
.get()).width(),
922 w2
->bounds().width());
924 // Dock the first window to the left edge.
925 // Click at an offset from origin to prevent snapping.
926 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromWindowOrigin(w1
.get(), 10, 0));
927 // Drag left to get pointer touching the screen edge.
928 DragMove(-w1
->bounds().x() - 10, 0);
929 // Alignment set to "NONE" during the drag of the window when none are docked.
930 EXPECT_EQ(DOCKED_ALIGNMENT_NONE
, docked_alignment(manager
));
931 // Release the mouse and the window should be now attached to the edge.
933 // Dock should get expanded and desktop should get shrunk.
934 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
935 EXPECT_EQ(DOCKED_ALIGNMENT_LEFT
, docked_alignment(manager
));
936 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
937 // Second window should still be in the desktop.
938 EXPECT_EQ(kShellWindowId_DefaultContainer
, w2
->parent()->id());
939 // Maximized window should be shrunk.
940 EXPECT_EQ(ScreenUtil::GetDisplayBoundsInParent(w2
.get()).width() -
941 docked_width(manager
) - min_dock_gap(),
942 w2
->bounds().width());
944 // Unmaximize the second window.
946 // Its bounds should get restored.
947 EXPECT_EQ(restored_bounds
, w2
->bounds());
950 // Dock one window. Test the sticky behavior near screen or desktop edge.
951 TEST_P(DockedWindowResizerTest
, AttachOneTestSticky
) {
952 if (!SupportsHostWindowResize())
955 scoped_ptr
<aura::Window
> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
956 scoped_ptr
<aura::Window
> w2(CreateTestWindow(gfx::Rect(0, 0, 210, 201)));
957 // Work area should cover the whole screen.
958 EXPECT_EQ(ScreenUtil::GetDisplayBoundsInParent(w2
.get()).width(),
959 ScreenUtil::GetDisplayWorkAreaBoundsInParent(w2
.get()).width());
961 DragToVerticalPositionAndToEdge(DOCKED_EDGE_LEFT
, w1
.get(), 20);
962 // A window should be docked at the left edge.
963 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().x(),
964 w1
->GetBoundsInScreen().x());
965 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
966 DockedWindowLayoutManager
* manager
=
967 static_cast<DockedWindowLayoutManager
*>(w1
->parent()->layout_manager());
968 // The first window should be docked.
969 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().x(),
970 w1
->GetBoundsInScreen().x());
971 // Dock width should be set to that of a single docked window.
972 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
973 EXPECT_EQ(DOCKED_ALIGNMENT_LEFT
, docked_alignment(manager
));
974 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
976 // Position second window in the desktop 20px to the right of the docked w1.
977 DragToVerticalPositionRelativeToEdge(DOCKED_EDGE_LEFT
,
982 // The second window should be floating on the desktop.
983 EXPECT_EQ(w2
->GetRootWindow()->GetBoundsInScreen().x() +
984 (w1
->bounds().right() + 20),
985 w2
->GetBoundsInScreen().x());
986 EXPECT_EQ(kShellWindowId_DefaultContainer
, w2
->parent()->id());
987 // Dock width should be set to that of a single docked window.
988 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
989 EXPECT_EQ(DOCKED_ALIGNMENT_LEFT
, docked_alignment(manager
));
990 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
992 // Drag w2 almost to the dock, the mouse pointer not quite reaching the dock.
993 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromWindowOrigin(w2
.get(), 10, 0));
994 DragMove(1 + docked_width(manager
) - w2
->bounds().x(), 0);
995 // Alignment set to "LEFT" during the drag because dock has a window in it.
996 EXPECT_EQ(DOCKED_ALIGNMENT_LEFT
, docked_alignment(manager
));
997 // Release the mouse and the window should not be attached to the edge.
999 // Dock should still have only one window in it.
1000 EXPECT_EQ(DOCKED_ALIGNMENT_LEFT
, docked_alignment(manager
));
1001 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1002 // The second window should still be in the desktop.
1003 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1004 EXPECT_EQ(kShellWindowId_DefaultContainer
, w2
->parent()->id());
1006 // Drag w2 by a bit more - it should resist the drag (stuck edges)
1007 int start_x
= w2
->bounds().x();
1008 ASSERT_NO_FATAL_FAILURE(DragStartAtOffsetFromWindowOrigin(w2
.get(), 100, 5));
1010 // Window should not actually move.
1011 EXPECT_EQ(start_x
, w2
->bounds().x());
1012 // Alignment set to "LEFT" during the drag because dock has a window in it.
1013 EXPECT_EQ(DOCKED_ALIGNMENT_LEFT
, docked_alignment(manager
));
1014 // Release the mouse and the window should not be attached to the edge.
1016 // Window should be still where it was before the last drag started.
1017 EXPECT_EQ(start_x
, w2
->bounds().x());
1018 // Dock should still have only one window in it
1019 EXPECT_EQ(DOCKED_ALIGNMENT_LEFT
, docked_alignment(manager
));
1020 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1021 // The second window should still be in the desktop
1022 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1023 EXPECT_EQ(kShellWindowId_DefaultContainer
, w2
->parent()->id());
1025 // Drag w2 by more than the stuck threshold and drop it into the dock.
1026 ASSERT_NO_FATAL_FAILURE(DragStart(w2
.get()));
1028 // Window should actually move.
1029 EXPECT_NE(start_x
, w2
->bounds().x());
1030 // Alignment set to "LEFT" during the drag because dock has a window in it.
1031 EXPECT_EQ(DOCKED_ALIGNMENT_LEFT
, docked_alignment(manager
));
1032 // Release the mouse and the window should be attached to the edge.
1034 // Both windows are docked now.
1035 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1036 EXPECT_EQ(kShellWindowId_DockedContainer
, w2
->parent()->id());
1037 // Dock should get expanded and desktop should get shrunk.
1038 EXPECT_EQ(DOCKED_ALIGNMENT_LEFT
, docked_alignment(manager
));
1039 EXPECT_EQ(std::max(w1
->bounds().width(), w2
->bounds().width()),
1040 docked_width(manager
));
1041 // Desktop work area should now shrink by dock width.
1042 EXPECT_EQ(ScreenUtil::GetDisplayBoundsInParent(w2
.get()).width() -
1043 docked_width(manager
) - min_dock_gap(),
1044 ScreenUtil::GetDisplayWorkAreaBoundsInParent(w2
.get()).width());
1047 // Dock two windows, resize one.
1048 // Test the docked windows area size and remaining desktop resizing.
1049 TEST_P(DockedWindowResizerTest
, ResizeOneOfTwoWindows
) {
1050 if (!SupportsHostWindowResize())
1053 // Wider display to start since panels are limited to half the display width.
1054 UpdateDisplay("1000x600");
1055 scoped_ptr
<aura::Window
> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
1056 scoped_ptr
<aura::Window
> w2(CreateTestWindow(gfx::Rect(0, 0, 210, 201)));
1057 // Work area should cover the whole screen.
1058 EXPECT_EQ(ScreenUtil::GetDisplayBoundsInParent(w2
.get()).width(),
1059 ScreenUtil::GetDisplayWorkAreaBoundsInParent(w2
.get()).width());
1061 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
1062 // A window should be docked at the right edge.
1063 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
1064 w1
->GetBoundsInScreen().right());
1065 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1066 DockedWindowLayoutManager
* manager
=
1067 static_cast<DockedWindowLayoutManager
*>(w1
->parent()->layout_manager());
1068 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1069 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1071 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w2
.get(), 100);
1072 // Both windows should now be docked at the right edge.
1073 EXPECT_EQ(w2
->GetRootWindow()->GetBoundsInScreen().right(),
1074 w2
->GetBoundsInScreen().right());
1075 EXPECT_EQ(kShellWindowId_DockedContainer
, w2
->parent()->id());
1076 // Dock width should be set to a wider window.
1077 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1078 EXPECT_EQ(std::max(w1
->bounds().width(), w2
->bounds().width()),
1079 docked_width(manager
));
1081 // Resize the first window left by a bit and test that the dock expands.
1082 int previous_width
= w1
->bounds().width();
1083 const int kResizeSpan1
= 30;
1084 ASSERT_NO_FATAL_FAILURE(ResizeStartAtOffsetFromWindowOrigin(w1
.get(),
1087 DragMove(-kResizeSpan1
, 0);
1088 // Alignment set to "RIGHT" during the drag because dock has a window in it.
1089 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1090 // Release the mouse and the window should be attached to the edge.
1092 // Dock should still have both windows in it.
1093 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1094 EXPECT_EQ(kShellWindowId_DockedContainer
, w2
->parent()->id());
1095 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1096 // w1 is now wider than before. The dock should expand and be as wide as w1.
1097 EXPECT_EQ(previous_width
+ kResizeSpan1
, w1
->bounds().width());
1098 // Both windows should get resized since they both don't have min/max size.
1099 EXPECT_EQ(w1
->bounds().width(), w2
->bounds().width());
1100 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1101 // Desktop work area should shrink.
1102 EXPECT_EQ(ScreenUtil::GetDisplayBoundsInParent(w2
.get()).width() -
1103 docked_width(manager
) - min_dock_gap(),
1104 ScreenUtil::GetDisplayWorkAreaBoundsInParent(w2
.get()).width());
1106 // Resize the first window left by more than the dock maximum width.
1107 // This should cause the window width to be restricted by maximum dock width.
1108 previous_width
= w1
->bounds().width();
1109 const int kResizeSpan2
= 250;
1110 ASSERT_NO_FATAL_FAILURE(ResizeStartAtOffsetFromWindowOrigin(w1
.get(),
1113 DragMove(-kResizeSpan2
, 0);
1114 // Alignment set to "RIGHT" during the drag because dock has a window in it.
1115 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1116 // Release the mouse and the window should be attached to the edge.
1118 // Dock should still have both windows in it.
1119 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1120 EXPECT_EQ(kShellWindowId_DockedContainer
, w2
->parent()->id());
1121 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1122 // w1 is now as wide as the maximum dock width and the dock should get
1123 // resized to the maximum width.
1124 EXPECT_EQ(max_width(), w1
->bounds().width());
1125 // Both windows should get resized since they both don't have min/max size.
1126 EXPECT_EQ(w1
->bounds().width(), w2
->bounds().width());
1127 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1128 // Desktop work area should shrink.
1129 EXPECT_EQ(ScreenUtil::GetDisplayBoundsInParent(w2
.get()).width() -
1130 docked_width(manager
) - min_dock_gap(),
1131 ScreenUtil::GetDisplayWorkAreaBoundsInParent(w2
.get()).width());
1133 // Resize the first window right to get it completely inside the docked area.
1134 previous_width
= w1
->bounds().width();
1135 const int kResizeSpan3
= 100;
1136 ASSERT_NO_FATAL_FAILURE(ResizeStartAtOffsetFromWindowOrigin(w1
.get(),
1139 DragMove(kResizeSpan3
, 0);
1140 // Alignment set to "RIGHT" during the drag because dock has a window in it.
1141 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1142 // Release the mouse and the window should be docked.
1144 // Dock should still have both windows in it.
1145 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1146 EXPECT_EQ(kShellWindowId_DockedContainer
, w2
->parent()->id());
1147 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1148 // w1 should be narrower than before by the length of the drag.
1149 EXPECT_EQ(previous_width
- kResizeSpan3
, w1
->bounds().width());
1150 // Both windows should get resized since they both don't have min/max size.
1151 EXPECT_EQ(w1
->bounds().width(), w2
->bounds().width());
1152 // The dock should be as wide as w1 or w2.
1153 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1154 // Desktop work area should shrink.
1155 EXPECT_EQ(ScreenUtil::GetDisplayBoundsInParent(w2
.get()).width() -
1156 docked_width(manager
) - min_dock_gap(),
1157 ScreenUtil::GetDisplayWorkAreaBoundsInParent(w2
.get()).width());
1159 // Resize the first window left to be overhang again.
1160 previous_width
= w1
->bounds().width();
1161 ASSERT_NO_FATAL_FAILURE(ResizeStartAtOffsetFromWindowOrigin(w1
.get(),
1164 DragMove(-kResizeSpan3
, 0);
1166 EXPECT_EQ(previous_width
+ kResizeSpan3
, w1
->bounds().width());
1167 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1168 // Docked area should be as wide as possible (maximum) and same as w1.
1169 EXPECT_EQ(max_width(), docked_width(manager
));
1170 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1172 // Undock the first window. Docked area should shrink to its ideal size.
1173 ASSERT_NO_FATAL_FAILURE(DragStart(w1
.get()));
1174 // Drag up as well to avoid attaching panels to launcher shelf.
1175 DragMove(-(400 - 210), -100);
1176 // Alignment set to "RIGHT" since we have another window docked.
1177 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1178 // Release the mouse and the window should be no longer attached to the edge.
1180 EXPECT_EQ(kShellWindowId_DefaultContainer
, w1
->parent()->id());
1181 // Dock should be as wide as w2 (and same as ideal width).
1182 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1183 EXPECT_EQ(ideal_width(), docked_width(manager
));
1184 EXPECT_EQ(w2
->bounds().width(), docked_width(manager
));
1185 // The second window should be still docked.
1186 EXPECT_EQ(kShellWindowId_DockedContainer
, w2
->parent()->id());
1187 // Desktop work area should be inset.
1188 EXPECT_EQ(ScreenUtil::GetDisplayBoundsInParent(w1
.get()).width() -
1189 docked_width(manager
) - min_dock_gap(),
1190 ScreenUtil::GetDisplayWorkAreaBoundsInParent(w1
.get()).width());
1193 // Dock a window, resize it and test that undocking it preserves the width.
1194 TEST_P(DockedWindowResizerTest
, ResizingKeepsWidth
) {
1195 if (!SupportsHostWindowResize())
1198 // Wider display to start since panels are limited to half the display width.
1199 UpdateDisplay("1000x600");
1200 scoped_ptr
<aura::Window
> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
1202 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
1203 // Window should be docked at the right edge.
1204 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
1205 w1
->GetBoundsInScreen().right());
1206 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1207 DockedWindowLayoutManager
* manager
=
1208 static_cast<DockedWindowLayoutManager
*>(w1
->parent()->layout_manager());
1209 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1210 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1212 // Resize the window left by a bit and test that the dock expands.
1213 int previous_width
= w1
->bounds().width();
1214 const int kResizeSpan1
= 30;
1215 ASSERT_NO_FATAL_FAILURE(ResizeStartAtOffsetFromWindowOrigin(w1
.get(),
1218 DragMove(-kResizeSpan1
, 0);
1219 // Alignment stays "RIGHT" during the drag because the only docked window
1220 // is being resized.
1221 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1222 // Release the mouse and the window should be attached to the edge.
1224 // The window should get docked.
1225 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1226 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1227 // w1 is now wider and the dock should expand to be as wide as w1.
1228 EXPECT_EQ(previous_width
+ kResizeSpan1
, w1
->bounds().width());
1229 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1231 // Undock by dragging almost to the left edge.
1232 DragToVerticalPositionRelativeToEdge(DOCKED_EDGE_LEFT
, w1
.get(), 100, 20);
1233 // Width should be preserved.
1234 EXPECT_EQ(previous_width
+ kResizeSpan1
, w1
->bounds().width());
1235 // Height should be restored to what it was originally.
1236 EXPECT_EQ(201, w1
->bounds().height());
1239 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
1240 // Width should be reset to initial ideal width (25px).
1241 EXPECT_EQ(ideal_width(), w1
->bounds().width());
1243 // Undock again by dragging left.
1244 DragToVerticalPositionRelativeToEdge(DOCKED_EDGE_LEFT
, w1
.get(), 100, 20);
1245 // Width should be reset to what it was last time the window was not docked.
1246 EXPECT_EQ(previous_width
+ kResizeSpan1
, w1
->bounds().width());
1247 // Height should be restored to what it was originally.
1248 EXPECT_EQ(201, w1
->bounds().height());
1251 // Dock a window, resize it and test that it stays docked.
1252 TEST_P(DockedWindowResizerTest
, ResizingKeepsDockedState
) {
1253 if (!SupportsHostWindowResize())
1256 // Wider display to start since panels are limited to half the display width.
1257 UpdateDisplay("1000x600");
1258 scoped_ptr
<aura::Window
> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
1260 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
1261 // Window should be docked at the right edge.
1262 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
1263 w1
->GetBoundsInScreen().right());
1264 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1265 DockedWindowLayoutManager
* manager
=
1266 static_cast<DockedWindowLayoutManager
*>(w1
->parent()->layout_manager());
1267 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1268 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1270 // Resize the window left by a bit and test that the dock expands.
1271 int previous_width
= w1
->bounds().width();
1272 const int kResizeSpan1
= 30;
1273 ASSERT_NO_FATAL_FAILURE(ResizeStartAtOffsetFromWindowOrigin(
1274 w1
.get(), 0, 20, HTLEFT
));
1275 DragMove(-kResizeSpan1
, 0);
1276 // Normally alignment would be reset to "NONE" during the drag when there is
1277 // only a single window docked and it is being dragged. However because that
1278 // window is being resized rather than moved the alignment is not changed.
1279 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1280 // Release the mouse and the window should be attached to the edge.
1282 // The window should stay docked.
1283 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1284 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1285 // w1 is now wider and the dock should expand to be as wide as w1.
1286 EXPECT_EQ(previous_width
+ kResizeSpan1
, w1
->bounds().width());
1287 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1289 // Resize the window by dragging its right edge left a bit and test that the
1290 // window stays docked.
1291 previous_width
= w1
->bounds().width();
1292 const int kResizeSpan2
= 15;
1293 ASSERT_NO_FATAL_FAILURE(ResizeStartAtOffsetFromWindowOrigin(
1294 w1
.get(), w1
->bounds().width(), 20, HTRIGHT
));
1295 DragMove(-kResizeSpan2
, 0);
1296 // Alignment stays "RIGHT" during the drag because the window is being
1297 // resized rather than dragged.
1298 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1299 // Release the mouse and the window should be attached to the edge.
1301 // The window should stay docked.
1302 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1303 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1304 // The dock should stay as wide as w1 is now (a bit less than before).
1305 EXPECT_EQ(previous_width
- kResizeSpan2
, w1
->bounds().width());
1306 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1309 // Dock two windows, resize one. Test the docked windows area size.
1310 TEST_P(DockedWindowResizerTest
, ResizeTwoWindows
) {
1311 if (!SupportsHostWindowResize())
1314 // Wider display to start since panels are limited to half the display width.
1315 UpdateDisplay("1000x600");
1316 scoped_ptr
<aura::Window
> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
1317 scoped_ptr
<aura::Window
> w2(CreateTestWindow(gfx::Rect(0, 0, 210, 201)));
1319 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
1320 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w2
.get(), 100);
1321 // Both windows should now be docked at the right edge.
1322 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1323 EXPECT_EQ(kShellWindowId_DockedContainer
, w2
->parent()->id());
1324 // Dock width should be set to ideal width.
1325 DockedWindowLayoutManager
* manager
=
1326 static_cast<DockedWindowLayoutManager
*>(w1
->parent()->layout_manager());
1327 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1328 EXPECT_EQ(ideal_width(), docked_width(manager
));
1330 // Resize the first window left by a bit and test that the dock expands.
1331 int previous_width
= w1
->bounds().width();
1332 const int kResizeSpan1
= 30;
1333 ASSERT_NO_FATAL_FAILURE(ResizeStartAtOffsetFromWindowOrigin(w1
.get(),
1336 DragMove(-kResizeSpan1
, 0);
1338 // w1 is now wider than before.
1339 EXPECT_EQ(previous_width
+ kResizeSpan1
, w1
->bounds().width());
1340 // Both windows should get resized since they both don't have min/max size.
1341 EXPECT_EQ(w1
->bounds().width(), w2
->bounds().width());
1342 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1344 // Resize the second window left by a bit more and test that the dock expands.
1345 previous_width
= w2
->bounds().width();
1346 ASSERT_NO_FATAL_FAILURE(ResizeStartAtOffsetFromWindowOrigin(w2
.get(),
1349 DragMove(-kResizeSpan1
, 0);
1351 // w2 should get wider since it was resized by a user.
1352 EXPECT_EQ(previous_width
+ kResizeSpan1
, w2
->bounds().width());
1353 // w1 should stay as wide as w2 since both were flush with the dock edge.
1354 EXPECT_EQ(w2
->bounds().width(), w1
->bounds().width());
1355 EXPECT_EQ(w2
->bounds().width(), docked_width(manager
));
1357 // Undock w2 and then dock it back.
1358 DragToVerticalPositionRelativeToEdge(DOCKED_EDGE_RIGHT
, w2
.get(), -400, 100);
1359 EXPECT_EQ(kShellWindowId_DefaultContainer
, w2
->parent()->id());
1360 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w2
.get(), 100);
1361 EXPECT_EQ(kShellWindowId_DockedContainer
, w2
->parent()->id());
1362 // w2 should become same width as w1.
1363 EXPECT_EQ(w1
->bounds().width(), w2
->bounds().width());
1364 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1366 // Make w1 even wider.
1367 ASSERT_NO_FATAL_FAILURE(ResizeStartAtOffsetFromWindowOrigin(w1
.get(),
1370 DragMove(-kResizeSpan1
, 0);
1372 // Making w1 wider should make both windows wider since w2 no longer remembers
1374 EXPECT_EQ(w1
->bounds().width(), w2
->bounds().width());
1375 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1378 // Tests that dragging a window down to shelf attaches a panel but does not
1379 // attach a regular window.
1380 TEST_P(DockedWindowResizerTest
, DragToShelf
) {
1381 if (!SupportsHostWindowResize())
1384 scoped_ptr
<aura::Window
> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
1385 // Work area should cover the whole screen.
1386 EXPECT_EQ(ScreenUtil::GetDisplayBoundsInParent(w1
.get()).width(),
1387 ScreenUtil::GetDisplayWorkAreaBoundsInParent(w1
.get()).width());
1389 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
1390 // A window should be docked at the right edge.
1391 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
1392 w1
->GetBoundsInScreen().right());
1393 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1394 DockedWindowLayoutManager
* manager
=
1395 static_cast<DockedWindowLayoutManager
*>(w1
->parent()->layout_manager());
1396 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1397 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1399 // Detach and drag down to shelf.
1400 ASSERT_NO_FATAL_FAILURE(DragStart(w1
.get()));
1402 // Alignment is set to "NONE" when drag starts.
1403 EXPECT_EQ(DOCKED_ALIGNMENT_NONE
, docked_alignment(manager
));
1404 // Release the mouse and the window should be no longer attached to the edge.
1406 EXPECT_EQ(DOCKED_ALIGNMENT_NONE
, docked_alignment(manager
));
1408 // Drag down almost to shelf. A panel will snap, a regular window won't.
1409 ShelfWidget
* shelf
= Shelf::ForPrimaryDisplay()->shelf_widget();
1410 const int shelf_y
= shelf
->GetWindowBoundsInScreen().y();
1411 const int kDistanceFromShelf
= 10;
1412 ASSERT_NO_FATAL_FAILURE(DragStart(w1
.get()));
1413 DragMove(0, -kDistanceFromShelf
+ shelf_y
- w1
->bounds().bottom());
1415 if (test_panels()) {
1416 // The panel should be touching the shelf and attached.
1417 EXPECT_EQ(shelf_y
, w1
->bounds().bottom());
1418 EXPECT_TRUE(wm::GetWindowState(w1
.get())->panel_attached());
1420 // The window should not be touching the shelf.
1421 EXPECT_EQ(shelf_y
- kDistanceFromShelf
, w1
->bounds().bottom());
1425 // Tests that docking and undocking a |window| with a transient child properly
1426 // maintains the parent of that transient child to be the same as the |window|.
1427 TEST_P(DockedWindowResizerTest
, DragWindowWithTransientChild
) {
1428 if (!SupportsHostWindowResize())
1431 // Create a window with a transient child.
1432 scoped_ptr
<aura::Window
> window(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
1433 scoped_ptr
<aura::Window
> child(CreateTestWindowInShellWithDelegateAndType(
1434 NULL
, ui::wm::WINDOW_TYPE_NORMAL
, 0, gfx::Rect(20, 20, 150, 20)));
1435 ::wm::AddTransientChild(window
.get(), child
.get());
1436 if (window
->parent() != child
->parent())
1437 window
->parent()->AddChild(child
.get());
1438 EXPECT_EQ(window
.get(), ::wm::GetTransientParent(child
.get()));
1440 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, window
.get(), 20);
1442 // A window should be docked at the right edge.
1443 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
1444 EXPECT_EQ(kShellWindowId_DockedContainer
, child
->parent()->id());
1446 // Drag the child - it should move freely and stay where it is dragged.
1447 ASSERT_NO_FATAL_FAILURE(DragStart(child
.get()));
1450 EXPECT_EQ(gfx::Point(20 + 500, 20 + 20).ToString(),
1451 child
->GetBoundsInScreen().origin().ToString());
1453 // Undock the window by dragging left.
1454 ASSERT_NO_FATAL_FAILURE(DragStart(window
.get()));
1458 // The window should be undocked and the transient child should be reparented.
1459 EXPECT_EQ(kShellWindowId_DefaultContainer
, window
->parent()->id());
1460 EXPECT_EQ(kShellWindowId_DefaultContainer
, child
->parent()->id());
1461 // The child should not have moved.
1462 EXPECT_EQ(gfx::Point(20 + 500, 20 + 20).ToString(),
1463 child
->GetBoundsInScreen().origin().ToString());
1466 // Tests that reparenting windows during the drag does not affect system modal
1467 // windows that are transient children of the dragged windows.
1468 TEST_P(DockedWindowResizerTest
, DragWindowWithModalTransientChild
) {
1469 if (!SupportsHostWindowResize())
1473 scoped_ptr
<aura::Window
> window(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
1474 gfx::Rect
bounds(window
->bounds());
1476 // Start dragging the window.
1477 ASSERT_NO_FATAL_FAILURE(DragStart(window
.get()));
1478 gfx::Vector2d
move_vector(40, test_panels() ? -60 : 60);
1479 DragMove(move_vector
.x(), move_vector
.y());
1480 EXPECT_EQ(CorrectContainerIdDuringDrag(), window
->parent()->id());
1482 // While still dragging create a modal window and make it a transient child of
1484 scoped_ptr
<aura::Window
> child(CreateModalWindow(gfx::Rect(20, 20, 150, 20)));
1485 ::wm::AddTransientChild(window
.get(), child
.get());
1486 EXPECT_EQ(window
.get(), ::wm::GetTransientParent(child
.get()));
1487 EXPECT_EQ(kShellWindowId_SystemModalContainer
, child
->parent()->id());
1489 // End the drag, the |window| should have moved (if it is a panel it will
1490 // no longer be attached to the shelf since we dragged it above).
1492 bounds
.Offset(move_vector
);
1493 EXPECT_EQ(bounds
.ToString(), window
->GetBoundsInScreen().ToString());
1495 // The original |window| should be in the default container (not docked or
1497 EXPECT_EQ(kShellWindowId_DefaultContainer
, window
->parent()->id());
1498 // The transient |child| should still be in system modal container.
1499 EXPECT_EQ(kShellWindowId_SystemModalContainer
, child
->parent()->id());
1500 // The |child| should not have moved.
1501 EXPECT_EQ(gfx::Point(20, 20).ToString(),
1502 child
->GetBoundsInScreen().origin().ToString());
1503 // The |child| should still be a transient child of |window|.
1504 EXPECT_EQ(window
.get(), ::wm::GetTransientParent(child
.get()));
1507 // Tests that side snapping a window undocks it, closes the dock and then snaps.
1508 TEST_P(DockedWindowResizerTest
, SideSnapDocked
) {
1509 if (!SupportsHostWindowResize() || test_panels())
1512 scoped_ptr
<aura::Window
> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
1513 wm::WindowState
* window_state
= wm::GetWindowState(w1
.get());
1514 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
1515 // A window should be docked at the right edge.
1516 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
1517 w1
->GetBoundsInScreen().right());
1518 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1519 DockedWindowLayoutManager
* manager
=
1520 static_cast<DockedWindowLayoutManager
*>(w1
->parent()->layout_manager());
1521 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1522 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1523 EXPECT_TRUE(window_state
->IsDocked());
1524 EXPECT_FALSE(window_state
->IsSnapped());
1526 // Side snap at right edge.
1527 const wm::WMEvent
snap_right(wm::WM_EVENT_SNAP_RIGHT
);
1528 window_state
->OnWMEvent(&snap_right
);
1529 // The window should be snapped at the right edge and the dock should close.
1530 gfx::Rect
work_area(ScreenUtil::GetDisplayWorkAreaBoundsInParent(w1
.get()));
1531 EXPECT_EQ(0, docked_width(manager
));
1532 EXPECT_EQ(work_area
.height(), w1
->bounds().height());
1533 EXPECT_EQ(work_area
.right(), w1
->bounds().right());
1534 EXPECT_EQ(kShellWindowId_DefaultContainer
, w1
->parent()->id());
1535 EXPECT_FALSE(window_state
->IsDocked());
1536 EXPECT_TRUE(window_state
->IsSnapped());
1539 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
1540 // A window should be docked at the right edge.
1541 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
1542 w1
->GetBoundsInScreen().right());
1543 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1544 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1545 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1546 EXPECT_TRUE(window_state
->IsDocked());
1547 EXPECT_FALSE(window_state
->IsSnapped());
1549 // Side snap at left edge.
1550 const wm::WMEvent
snap_left(wm::WM_EVENT_SNAP_LEFT
);
1551 window_state
->OnWMEvent(&snap_left
);
1552 // The window should be snapped at the right edge and the dock should close.
1553 EXPECT_EQ(work_area
.ToString(),
1554 ScreenUtil::GetDisplayWorkAreaBoundsInParent(w1
.get()).ToString());
1555 EXPECT_EQ(0, docked_width(manager
));
1556 EXPECT_EQ(work_area
.height(), w1
->bounds().height());
1557 EXPECT_EQ(work_area
.x(), w1
->bounds().x());
1558 EXPECT_EQ(kShellWindowId_DefaultContainer
, w1
->parent()->id());
1559 EXPECT_FALSE(window_state
->IsDocked());
1560 EXPECT_TRUE(window_state
->IsSnapped());
1563 // Tests that a window is undocked if the window is maximized via a keyboard
1564 // accelerator during a drag.
1565 TEST_P(DockedWindowResizerTest
, MaximizedDuringDrag
) {
1566 if (!SupportsHostWindowResize() || test_panels())
1569 scoped_ptr
<aura::Window
> window(CreateTestWindow(
1570 gfx::Rect(0, 0, ideal_width(), 201)));
1571 wm::WindowState
* window_state
= wm::GetWindowState(window
.get());
1573 // Dock the window to the right edge.
1574 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, window
.get(), 20);
1575 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right(),
1576 window
->GetBoundsInScreen().right());
1577 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
1578 DockedWindowLayoutManager
* manager
=
1579 static_cast<DockedWindowLayoutManager
*>(
1580 window
->parent()->layout_manager());
1581 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1582 EXPECT_EQ(window
->bounds().width(), docked_width(manager
));
1583 EXPECT_TRUE(window_state
->IsDocked());
1585 // Maximize the window while in a real drag. In particular,
1586 // ToplevelWindowEventHandler::ScopedWindowResizer::OnWindowStateTypeChanged()
1587 // must be called in order for the maximized window's size to be correct.
1588 delegate()->set_window_component(HTCAPTION
);
1589 ui::test::EventGenerator
& generator
= GetEventGenerator();
1590 generator
.MoveMouseTo(window
->GetBoundsInScreen().origin());
1591 generator
.PressLeftButton();
1592 generator
.MoveMouseBy(10, 10);
1593 window_state
->Maximize();
1594 generator
.ReleaseLeftButton();
1596 // |window| should get undocked.
1597 EXPECT_EQ(kShellWindowId_DefaultContainer
, window
->parent()->id());
1598 EXPECT_EQ(0, docked_width(manager
));
1600 ScreenUtil::GetMaximizedWindowBoundsInParent(window
.get()).ToString(),
1601 window
->bounds().ToString());
1602 EXPECT_TRUE(window_state
->IsMaximized());
1605 // Tests run twice - on both panels and normal windows
1606 INSTANTIATE_TEST_CASE_P(NormalOrPanel
,
1607 DockedWindowResizerTest
,
1608 testing::Values(ui::wm::WINDOW_TYPE_NORMAL
,
1609 ui::wm::WINDOW_TYPE_PANEL
));