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(ui::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 restores the pre-docked
1195 TEST_P(DockedWindowResizerTest
, ResizingKeepsSize
) {
1196 if (!SupportsHostWindowResize())
1199 // Wider display to start since panels are limited to half the display width.
1200 UpdateDisplay("1000x600");
1201 const gfx::Size
original_size(201, 201);
1202 scoped_ptr
<aura::Window
> w1(
1203 CreateTestWindow(gfx::Rect(gfx::Point(), original_size
)));
1205 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
1206 // Window should be docked at the right edge.
1207 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
1208 w1
->GetBoundsInScreen().right());
1209 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1210 DockedWindowLayoutManager
* manager
=
1211 static_cast<DockedWindowLayoutManager
*>(w1
->parent()->layout_manager());
1212 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1213 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1215 // Resize the window left by a bit and test that the dock expands.
1216 int previous_width
= w1
->bounds().width();
1217 const int kResizeSpan1
= 30;
1218 ASSERT_NO_FATAL_FAILURE(ResizeStartAtOffsetFromWindowOrigin(w1
.get(),
1221 DragMove(-kResizeSpan1
, 0);
1222 // Alignment stays "RIGHT" during the drag because the only docked window
1223 // is being resized.
1224 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1225 // Release the mouse and the window should be attached to the edge.
1227 // The window should get docked.
1228 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1229 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1230 // w1 is now wider and the dock should expand to be as wide as w1.
1231 EXPECT_EQ(previous_width
+ kResizeSpan1
, w1
->bounds().width());
1232 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1234 // Undock by dragging almost to the left edge.
1235 DragToVerticalPositionRelativeToEdge(DOCKED_EDGE_LEFT
, w1
.get(), 100, 20);
1236 // Size should be restored to what it was originally.
1237 EXPECT_EQ(original_size
.ToString(), w1
->bounds().size().ToString());
1240 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
1241 // Width should be reset to initial ideal width (25px).
1242 EXPECT_EQ(ideal_width(), w1
->bounds().width());
1244 // Undock again by dragging left.
1245 DragToVerticalPositionRelativeToEdge(DOCKED_EDGE_LEFT
, w1
.get(), 100, 20);
1246 // Size should be restored to what it was originally.
1247 EXPECT_EQ(original_size
.ToString(), w1
->bounds().size().ToString());
1250 // Dock a window, resize it and test that it stays docked.
1251 TEST_P(DockedWindowResizerTest
, ResizingKeepsDockedState
) {
1252 if (!SupportsHostWindowResize())
1255 // Wider display to start since panels are limited to half the display width.
1256 UpdateDisplay("1000x600");
1257 scoped_ptr
<aura::Window
> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
1259 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
1260 // Window should be docked at the right edge.
1261 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
1262 w1
->GetBoundsInScreen().right());
1263 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1264 DockedWindowLayoutManager
* manager
=
1265 static_cast<DockedWindowLayoutManager
*>(w1
->parent()->layout_manager());
1266 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1267 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1269 // Resize the window left by a bit and test that the dock expands.
1270 int previous_width
= w1
->bounds().width();
1271 const int kResizeSpan1
= 30;
1272 ASSERT_NO_FATAL_FAILURE(ResizeStartAtOffsetFromWindowOrigin(
1273 w1
.get(), 0, 20, HTLEFT
));
1274 DragMove(-kResizeSpan1
, 0);
1275 // Normally alignment would be reset to "NONE" during the drag when there is
1276 // only a single window docked and it is being dragged. However because that
1277 // window is being resized rather than moved the alignment is not changed.
1278 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1279 // Release the mouse and the window should be attached to the edge.
1281 // The window should stay docked.
1282 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1283 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1284 // w1 is now wider and the dock should expand to be as wide as w1.
1285 EXPECT_EQ(previous_width
+ kResizeSpan1
, w1
->bounds().width());
1286 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1288 // Resize the window by dragging its right edge left a bit and test that the
1289 // window stays docked.
1290 previous_width
= w1
->bounds().width();
1291 const int kResizeSpan2
= 15;
1292 ASSERT_NO_FATAL_FAILURE(ResizeStartAtOffsetFromWindowOrigin(
1293 w1
.get(), w1
->bounds().width(), 20, HTRIGHT
));
1294 DragMove(-kResizeSpan2
, 0);
1295 // Alignment stays "RIGHT" during the drag because the window is being
1296 // resized rather than dragged.
1297 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1298 // Release the mouse and the window should be attached to the edge.
1300 // The window should stay docked.
1301 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1302 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1303 // The dock should stay as wide as w1 is now (a bit less than before).
1304 EXPECT_EQ(previous_width
- kResizeSpan2
, w1
->bounds().width());
1305 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1308 // Dock two windows, resize one. Test the docked windows area size.
1309 TEST_P(DockedWindowResizerTest
, ResizeTwoWindows
) {
1310 if (!SupportsHostWindowResize())
1313 // Wider display to start since panels are limited to half the display width.
1314 UpdateDisplay("1000x600");
1315 scoped_ptr
<aura::Window
> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
1316 scoped_ptr
<aura::Window
> w2(CreateTestWindow(gfx::Rect(0, 0, 210, 201)));
1318 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
1319 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w2
.get(), 100);
1320 // Both windows should now be docked at the right edge.
1321 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1322 EXPECT_EQ(kShellWindowId_DockedContainer
, w2
->parent()->id());
1323 // Dock width should be set to ideal width.
1324 DockedWindowLayoutManager
* manager
=
1325 static_cast<DockedWindowLayoutManager
*>(w1
->parent()->layout_manager());
1326 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1327 EXPECT_EQ(ideal_width(), docked_width(manager
));
1329 // Resize the first window left by a bit and test that the dock expands.
1330 int previous_width
= w1
->bounds().width();
1331 const int kResizeSpan1
= 30;
1332 ASSERT_NO_FATAL_FAILURE(ResizeStartAtOffsetFromWindowOrigin(w1
.get(),
1335 DragMove(-kResizeSpan1
, 0);
1337 // w1 is now wider than before.
1338 EXPECT_EQ(previous_width
+ kResizeSpan1
, w1
->bounds().width());
1339 // Both windows should get resized since they both don't have min/max size.
1340 EXPECT_EQ(w1
->bounds().width(), w2
->bounds().width());
1341 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1343 // Resize the second window left by a bit more and test that the dock expands.
1344 previous_width
= w2
->bounds().width();
1345 ASSERT_NO_FATAL_FAILURE(ResizeStartAtOffsetFromWindowOrigin(w2
.get(),
1348 DragMove(-kResizeSpan1
, 0);
1350 // w2 should get wider since it was resized by a user.
1351 EXPECT_EQ(previous_width
+ kResizeSpan1
, w2
->bounds().width());
1352 // w1 should stay as wide as w2 since both were flush with the dock edge.
1353 EXPECT_EQ(w2
->bounds().width(), w1
->bounds().width());
1354 EXPECT_EQ(w2
->bounds().width(), docked_width(manager
));
1356 // Undock w2 and then dock it back.
1357 DragToVerticalPositionRelativeToEdge(DOCKED_EDGE_RIGHT
, w2
.get(), -400, 100);
1358 EXPECT_EQ(kShellWindowId_DefaultContainer
, w2
->parent()->id());
1359 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w2
.get(), 100);
1360 EXPECT_EQ(kShellWindowId_DockedContainer
, w2
->parent()->id());
1361 // w2 should become same width as w1.
1362 EXPECT_EQ(w1
->bounds().width(), w2
->bounds().width());
1363 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1365 // Make w1 even wider.
1366 ASSERT_NO_FATAL_FAILURE(ResizeStartAtOffsetFromWindowOrigin(w1
.get(),
1369 DragMove(-kResizeSpan1
, 0);
1371 // Making w1 wider should make both windows wider since w2 no longer remembers
1373 EXPECT_EQ(w1
->bounds().width(), w2
->bounds().width());
1374 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1377 // Tests that dragging a window down to shelf attaches a panel but does not
1378 // attach a regular window.
1379 TEST_P(DockedWindowResizerTest
, DragToShelf
) {
1380 if (!SupportsHostWindowResize())
1383 scoped_ptr
<aura::Window
> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
1384 // Work area should cover the whole screen.
1385 EXPECT_EQ(ScreenUtil::GetDisplayBoundsInParent(w1
.get()).width(),
1386 ScreenUtil::GetDisplayWorkAreaBoundsInParent(w1
.get()).width());
1388 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
1389 // A window should be docked at the right edge.
1390 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
1391 w1
->GetBoundsInScreen().right());
1392 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1393 DockedWindowLayoutManager
* manager
=
1394 static_cast<DockedWindowLayoutManager
*>(w1
->parent()->layout_manager());
1395 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1396 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1398 // Detach and drag down to shelf.
1399 ASSERT_NO_FATAL_FAILURE(DragStart(w1
.get()));
1401 // Alignment is set to "NONE" when drag starts.
1402 EXPECT_EQ(DOCKED_ALIGNMENT_NONE
, docked_alignment(manager
));
1403 // Release the mouse and the window should be no longer attached to the edge.
1405 EXPECT_EQ(DOCKED_ALIGNMENT_NONE
, docked_alignment(manager
));
1407 // Drag down almost to shelf. A panel will snap, a regular window won't.
1408 ShelfWidget
* shelf
= Shelf::ForPrimaryDisplay()->shelf_widget();
1409 const int shelf_y
= shelf
->GetWindowBoundsInScreen().y();
1410 const int kDistanceFromShelf
= 10;
1411 ASSERT_NO_FATAL_FAILURE(DragStart(w1
.get()));
1412 DragMove(0, -kDistanceFromShelf
+ shelf_y
- w1
->bounds().bottom());
1414 if (test_panels()) {
1415 // The panel should be touching the shelf and attached.
1416 EXPECT_EQ(shelf_y
, w1
->bounds().bottom());
1417 EXPECT_TRUE(wm::GetWindowState(w1
.get())->panel_attached());
1419 // The window should not be touching the shelf.
1420 EXPECT_EQ(shelf_y
- kDistanceFromShelf
, w1
->bounds().bottom());
1424 // Tests that docking and undocking a |window| with a transient child properly
1425 // maintains the parent of that transient child to be the same as the |window|.
1426 TEST_P(DockedWindowResizerTest
, DragWindowWithTransientChild
) {
1427 if (!SupportsHostWindowResize())
1430 // Create a window with a transient child.
1431 scoped_ptr
<aura::Window
> window(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
1432 scoped_ptr
<aura::Window
> child(CreateTestWindowInShellWithDelegateAndType(
1433 NULL
, ui::wm::WINDOW_TYPE_NORMAL
, 0, gfx::Rect(20, 20, 150, 20)));
1434 ::wm::AddTransientChild(window
.get(), child
.get());
1435 if (window
->parent() != child
->parent())
1436 window
->parent()->AddChild(child
.get());
1437 EXPECT_EQ(window
.get(), ::wm::GetTransientParent(child
.get()));
1439 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, window
.get(), 20);
1441 // A window should be docked at the right edge.
1442 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
1443 EXPECT_EQ(kShellWindowId_DockedContainer
, child
->parent()->id());
1445 // Drag the child - it should move freely and stay where it is dragged.
1446 ASSERT_NO_FATAL_FAILURE(DragStart(child
.get()));
1449 EXPECT_EQ(gfx::Point(20 + 500, 20 + 20).ToString(),
1450 child
->GetBoundsInScreen().origin().ToString());
1452 // Undock the window by dragging left.
1453 ASSERT_NO_FATAL_FAILURE(DragStart(window
.get()));
1457 // The window should be undocked and the transient child should be reparented.
1458 EXPECT_EQ(kShellWindowId_DefaultContainer
, window
->parent()->id());
1459 EXPECT_EQ(kShellWindowId_DefaultContainer
, child
->parent()->id());
1460 // The child should not have moved.
1461 EXPECT_EQ(gfx::Point(20 + 500, 20 + 20).ToString(),
1462 child
->GetBoundsInScreen().origin().ToString());
1465 // Tests that reparenting windows during the drag does not affect system modal
1466 // windows that are transient children of the dragged windows.
1467 TEST_P(DockedWindowResizerTest
, DragWindowWithModalTransientChild
) {
1468 if (!SupportsHostWindowResize())
1472 scoped_ptr
<aura::Window
> window(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
1473 gfx::Rect
bounds(window
->bounds());
1475 // Start dragging the window.
1476 ASSERT_NO_FATAL_FAILURE(DragStart(window
.get()));
1477 gfx::Vector2d
move_vector(40, test_panels() ? -60 : 60);
1478 DragMove(move_vector
.x(), move_vector
.y());
1479 EXPECT_EQ(CorrectContainerIdDuringDrag(), window
->parent()->id());
1481 // While still dragging create a modal window and make it a transient child of
1483 scoped_ptr
<aura::Window
> child(CreateModalWindow(gfx::Rect(20, 20, 150, 20)));
1484 ::wm::AddTransientChild(window
.get(), child
.get());
1485 EXPECT_EQ(window
.get(), ::wm::GetTransientParent(child
.get()));
1486 EXPECT_EQ(kShellWindowId_SystemModalContainer
, child
->parent()->id());
1488 // End the drag, the |window| should have moved (if it is a panel it will
1489 // no longer be attached to the shelf since we dragged it above).
1491 bounds
.Offset(move_vector
);
1492 EXPECT_EQ(bounds
.ToString(), window
->GetBoundsInScreen().ToString());
1494 // The original |window| should be in the default container (not docked or
1496 EXPECT_EQ(kShellWindowId_DefaultContainer
, window
->parent()->id());
1497 // The transient |child| should still be in system modal container.
1498 EXPECT_EQ(kShellWindowId_SystemModalContainer
, child
->parent()->id());
1499 // The |child| should not have moved.
1500 EXPECT_EQ(gfx::Point(20, 20).ToString(),
1501 child
->GetBoundsInScreen().origin().ToString());
1502 // The |child| should still be a transient child of |window|.
1503 EXPECT_EQ(window
.get(), ::wm::GetTransientParent(child
.get()));
1506 // Tests that side snapping a window undocks it, closes the dock and then snaps.
1507 TEST_P(DockedWindowResizerTest
, SideSnapDocked
) {
1508 if (!SupportsHostWindowResize() || test_panels())
1511 scoped_ptr
<aura::Window
> w1(CreateTestWindow(gfx::Rect(0, 0, 201, 201)));
1512 wm::WindowState
* window_state
= wm::GetWindowState(w1
.get());
1513 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
1514 // A window should be docked at the right edge.
1515 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
1516 w1
->GetBoundsInScreen().right());
1517 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1518 DockedWindowLayoutManager
* manager
=
1519 static_cast<DockedWindowLayoutManager
*>(w1
->parent()->layout_manager());
1520 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1521 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1522 EXPECT_TRUE(window_state
->IsDocked());
1523 EXPECT_FALSE(window_state
->IsSnapped());
1525 // Side snap at right edge.
1526 const wm::WMEvent
snap_right(wm::WM_EVENT_SNAP_RIGHT
);
1527 window_state
->OnWMEvent(&snap_right
);
1528 // The window should be snapped at the right edge and the dock should close.
1529 gfx::Rect
work_area(ScreenUtil::GetDisplayWorkAreaBoundsInParent(w1
.get()));
1530 EXPECT_EQ(0, docked_width(manager
));
1531 EXPECT_EQ(work_area
.height(), w1
->bounds().height());
1532 EXPECT_EQ(work_area
.right(), w1
->bounds().right());
1533 EXPECT_EQ(kShellWindowId_DefaultContainer
, w1
->parent()->id());
1534 EXPECT_FALSE(window_state
->IsDocked());
1535 EXPECT_TRUE(window_state
->IsSnapped());
1538 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, w1
.get(), 20);
1539 // A window should be docked at the right edge.
1540 EXPECT_EQ(w1
->GetRootWindow()->GetBoundsInScreen().right(),
1541 w1
->GetBoundsInScreen().right());
1542 EXPECT_EQ(kShellWindowId_DockedContainer
, w1
->parent()->id());
1543 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1544 EXPECT_EQ(w1
->bounds().width(), docked_width(manager
));
1545 EXPECT_TRUE(window_state
->IsDocked());
1546 EXPECT_FALSE(window_state
->IsSnapped());
1548 // Side snap at left edge.
1549 const wm::WMEvent
snap_left(wm::WM_EVENT_SNAP_LEFT
);
1550 window_state
->OnWMEvent(&snap_left
);
1551 // The window should be snapped at the right edge and the dock should close.
1552 EXPECT_EQ(work_area
.ToString(),
1553 ScreenUtil::GetDisplayWorkAreaBoundsInParent(w1
.get()).ToString());
1554 EXPECT_EQ(0, docked_width(manager
));
1555 EXPECT_EQ(work_area
.height(), w1
->bounds().height());
1556 EXPECT_EQ(work_area
.x(), w1
->bounds().x());
1557 EXPECT_EQ(kShellWindowId_DefaultContainer
, w1
->parent()->id());
1558 EXPECT_FALSE(window_state
->IsDocked());
1559 EXPECT_TRUE(window_state
->IsSnapped());
1562 // Tests that a window is undocked if the window is maximized via a keyboard
1563 // accelerator during a drag.
1564 TEST_P(DockedWindowResizerTest
, MaximizedDuringDrag
) {
1565 if (!SupportsHostWindowResize() || test_panels())
1568 scoped_ptr
<aura::Window
> window(CreateTestWindow(
1569 gfx::Rect(0, 0, ideal_width(), 201)));
1570 wm::WindowState
* window_state
= wm::GetWindowState(window
.get());
1572 // Dock the window to the right edge.
1573 DragToVerticalPositionAndToEdge(DOCKED_EDGE_RIGHT
, window
.get(), 20);
1574 EXPECT_EQ(window
->GetRootWindow()->GetBoundsInScreen().right(),
1575 window
->GetBoundsInScreen().right());
1576 EXPECT_EQ(kShellWindowId_DockedContainer
, window
->parent()->id());
1577 DockedWindowLayoutManager
* manager
=
1578 static_cast<DockedWindowLayoutManager
*>(
1579 window
->parent()->layout_manager());
1580 EXPECT_EQ(DOCKED_ALIGNMENT_RIGHT
, docked_alignment(manager
));
1581 EXPECT_EQ(window
->bounds().width(), docked_width(manager
));
1582 EXPECT_TRUE(window_state
->IsDocked());
1584 // Maximize the window while in a real drag. In particular,
1585 // ToplevelWindowEventHandler::ScopedWindowResizer::OnWindowStateTypeChanged()
1586 // must be called in order for the maximized window's size to be correct.
1587 delegate()->set_window_component(HTCAPTION
);
1588 ui::test::EventGenerator
& generator
= GetEventGenerator();
1589 generator
.MoveMouseTo(window
->GetBoundsInScreen().origin());
1590 generator
.PressLeftButton();
1591 generator
.MoveMouseBy(10, 10);
1592 window_state
->Maximize();
1593 generator
.ReleaseLeftButton();
1595 // |window| should get undocked.
1596 EXPECT_EQ(kShellWindowId_DefaultContainer
, window
->parent()->id());
1597 EXPECT_EQ(0, docked_width(manager
));
1599 ScreenUtil::GetMaximizedWindowBoundsInParent(window
.get()).ToString(),
1600 window
->bounds().ToString());
1601 EXPECT_TRUE(window_state
->IsMaximized());
1604 // Tests run twice - on both panels and normal windows
1605 INSTANTIATE_TEST_CASE_P(NormalOrPanel
,
1606 DockedWindowResizerTest
,
1607 testing::Values(ui::wm::WINDOW_TYPE_NORMAL
,
1608 ui::wm::WINDOW_TYPE_PANEL
));