1 // Copyright (c) 2012 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/drag_window_resizer.h"
7 #include "ash/display/mouse_cursor_event_filter.h"
8 #include "ash/root_window_controller.h"
9 #include "ash/shelf/shelf_layout_manager.h"
10 #include "ash/shell.h"
11 #include "ash/shell_window_ids.h"
12 #include "ash/test/ash_test_base.h"
13 #include "ash/test/cursor_manager_test_api.h"
14 #include "ash/test/display_manager_test_api.h"
15 #include "ash/wm/drag_window_controller.h"
16 #include "ash/wm/window_util.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/stringprintf.h"
19 #include "ui/aura/client/aura_constants.h"
20 #include "ui/aura/env.h"
21 #include "ui/aura/test/test_window_delegate.h"
22 #include "ui/base/hit_test.h"
23 #include "ui/base/ui_base_types.h"
24 #include "ui/compositor/layer_tree_owner.h"
25 #include "ui/gfx/geometry/insets.h"
26 #include "ui/views/widget/widget.h"
27 #include "ui/wm/core/window_util.h"
32 const int kRootHeight
= 600;
36 class DragWindowResizerTest
: public test::AshTestBase
{
38 DragWindowResizerTest() {}
39 ~DragWindowResizerTest() override
{}
41 void SetUp() override
{
43 UpdateDisplay(base::StringPrintf("800x%d", kRootHeight
));
45 aura::Window
* root
= Shell::GetPrimaryRootWindow();
46 gfx::Rect
root_bounds(root
->bounds());
47 EXPECT_EQ(kRootHeight
, root_bounds
.height());
48 EXPECT_EQ(800, root_bounds
.width());
49 Shell::GetInstance()->SetDisplayWorkAreaInsets(root
, gfx::Insets());
50 window_
.reset(new aura::Window(&delegate_
));
51 window_
->SetType(ui::wm::WINDOW_TYPE_NORMAL
);
52 window_
->Init(ui::LAYER_NOT_DRAWN
);
53 ParentWindowInPrimaryRootWindow(window_
.get());
56 always_on_top_window_
.reset(new aura::Window(&delegate2_
));
57 always_on_top_window_
->SetType(ui::wm::WINDOW_TYPE_NORMAL
);
58 always_on_top_window_
->SetProperty(aura::client::kAlwaysOnTopKey
, true);
59 always_on_top_window_
->Init(ui::LAYER_NOT_DRAWN
);
60 ParentWindowInPrimaryRootWindow(always_on_top_window_
.get());
61 always_on_top_window_
->set_id(2);
63 system_modal_window_
.reset(new aura::Window(&delegate3_
));
64 system_modal_window_
->SetType(ui::wm::WINDOW_TYPE_NORMAL
);
65 system_modal_window_
->SetProperty(aura::client::kModalKey
,
66 ui::MODAL_TYPE_SYSTEM
);
67 system_modal_window_
->Init(ui::LAYER_NOT_DRAWN
);
68 ParentWindowInPrimaryRootWindow(system_modal_window_
.get());
69 system_modal_window_
->set_id(3);
71 transient_child_
= new aura::Window(&delegate4_
);
72 transient_child_
->SetType(ui::wm::WINDOW_TYPE_NORMAL
);
73 transient_child_
->Init(ui::LAYER_NOT_DRAWN
);
74 ParentWindowInPrimaryRootWindow(transient_child_
);
75 transient_child_
->set_id(4);
77 transient_parent_
.reset(new aura::Window(&delegate5_
));
78 transient_parent_
->SetType(ui::wm::WINDOW_TYPE_NORMAL
);
79 transient_parent_
->Init(ui::LAYER_NOT_DRAWN
);
80 ParentWindowInPrimaryRootWindow(transient_parent_
.get());
81 ::wm::AddTransientChild(transient_parent_
.get(), transient_child_
);
82 transient_parent_
->set_id(5);
84 panel_window_
.reset(new aura::Window(&delegate6_
));
85 panel_window_
->SetType(ui::wm::WINDOW_TYPE_PANEL
);
86 panel_window_
->Init(ui::LAYER_NOT_DRAWN
);
87 ParentWindowInPrimaryRootWindow(panel_window_
.get());
90 void TearDown() override
{
92 always_on_top_window_
.reset();
93 system_modal_window_
.reset();
94 transient_parent_
.reset();
95 panel_window_
.reset();
96 AshTestBase::TearDown();
100 gfx::Point
CalculateDragPoint(const WindowResizer
& resizer
,
103 gfx::Point location
= resizer
.GetInitialLocation();
104 location
.set_x(location
.x() + delta_x
);
105 location
.set_y(location
.y() + delta_y
);
109 ShelfLayoutManager
* shelf_layout_manager() {
110 return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
113 static WindowResizer
* CreateDragWindowResizer(
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 bool TestIfMouseWarpsAt(const gfx::Point
& point_in_screen
) {
125 return test::DisplayManagerTestApi::TestIfMouseWarpsAt(GetEventGenerator(),
129 aura::test::TestWindowDelegate delegate_
;
130 aura::test::TestWindowDelegate delegate2_
;
131 aura::test::TestWindowDelegate delegate3_
;
132 aura::test::TestWindowDelegate delegate4_
;
133 aura::test::TestWindowDelegate delegate5_
;
134 aura::test::TestWindowDelegate delegate6_
;
136 scoped_ptr
<aura::Window
> window_
;
137 scoped_ptr
<aura::Window
> always_on_top_window_
;
138 scoped_ptr
<aura::Window
> system_modal_window_
;
139 scoped_ptr
<aura::Window
> panel_window_
;
140 aura::Window
* transient_child_
;
141 scoped_ptr
<aura::Window
> transient_parent_
;
144 DISALLOW_COPY_AND_ASSIGN(DragWindowResizerTest
);
147 // Verifies a window can be moved from the primary display to another.
148 TEST_F(DragWindowResizerTest
, WindowDragWithMultiDisplays
) {
149 if (!SupportsMultipleDisplays())
152 // The secondary display is logically on the right, but on the system (e.g. X)
153 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
154 UpdateDisplay("800x600,400x300");
155 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
156 ASSERT_EQ(2U, root_windows
.size());
158 window_
->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
159 Shell::GetScreen()->GetPrimaryDisplay());
160 EXPECT_EQ(root_windows
[0], window_
->GetRootWindow());
162 // Grab (0, 0) of the window.
163 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
164 window_
.get(), gfx::Point(), HTCAPTION
));
165 ASSERT_TRUE(resizer
.get());
166 // Drag the pointer to the right. Once it reaches the right edge of the
167 // primary display, it warps to the secondary.
168 resizer
->Drag(CalculateDragPoint(*resizer
, 800, 10), 0);
169 resizer
->CompleteDrag();
170 // The whole window is on the secondary display now. The parent should be
172 EXPECT_EQ(root_windows
[1], window_
->GetRootWindow());
173 EXPECT_EQ("0,10 50x60", window_
->bounds().ToString());
176 window_
->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
177 Shell::GetScreen()->GetPrimaryDisplay());
178 EXPECT_EQ(root_windows
[0], window_
->GetRootWindow());
180 // Grab (0, 0) of the window and move the pointer to (790, 10).
181 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
182 window_
.get(), gfx::Point(), HTCAPTION
));
183 ASSERT_TRUE(resizer
.get());
184 resizer
->Drag(CalculateDragPoint(*resizer
, 795, 10), 0);
185 // Window should be adjusted for minimum visibility (10px) during the drag.
186 EXPECT_EQ("790,10 50x60", window_
->bounds().ToString());
187 resizer
->CompleteDrag();
188 // Since the pointer is still on the primary root window, the parent should
190 // Window origin should be adjusted for minimum visibility (10px).
191 EXPECT_EQ(root_windows
[0], window_
->GetRootWindow());
192 EXPECT_EQ("790,10 50x60", window_
->bounds().ToString());
195 window_
->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
196 Shell::GetScreen()->GetPrimaryDisplay());
197 EXPECT_EQ(root_windows
[0], window_
->GetRootWindow());
199 // Grab the top-right edge of the window and move the pointer to (0, 10)
200 // in the secondary root window's coordinates.
201 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
202 window_
.get(), gfx::Point(49, 0), HTCAPTION
));
203 ASSERT_TRUE(resizer
.get());
204 resizer
->Drag(CalculateDragPoint(*resizer
, 751, 10), ui::EF_CONTROL_DOWN
);
205 resizer
->CompleteDrag();
206 // Since the pointer is on the secondary, the parent should be changed
207 // even though only small fraction of the window is within the secondary
208 // root window's bounds.
209 EXPECT_EQ(root_windows
[1], window_
->GetRootWindow());
210 // Window origin should be adjusted for minimum visibility (10px).
211 int expected_x
= -50 + 10;
212 EXPECT_EQ(base::IntToString(expected_x
) + ",10 50x60",
213 window_
->bounds().ToString());
215 // Dropping a window that is larger than the destination work area
216 // will shrink to fit to the work area.
217 window_
->SetBoundsInScreen(gfx::Rect(0, 0, 700, 500),
218 Shell::GetScreen()->GetPrimaryDisplay());
219 EXPECT_EQ(root_windows
[0], window_
->GetRootWindow());
221 // Grab the top-right edge of the window and move the pointer to (0, 10)
222 // in the secondary root window's coordinates.
223 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
224 window_
.get(), gfx::Point(699, 0), HTCAPTION
));
225 ASSERT_TRUE(resizer
.get());
226 resizer
->Drag(CalculateDragPoint(*resizer
, 101, 10), ui::EF_CONTROL_DOWN
);
227 resizer
->CompleteDrag();
228 EXPECT_EQ(root_windows
[1], window_
->GetRootWindow());
229 // Window size should be adjusted to fit to the work area
230 EXPECT_EQ("400x253", window_
->bounds().size().ToString());
231 gfx::Rect window_bounds_in_screen
= window_
->GetBoundsInScreen();
232 gfx::Rect
intersect(window_
->GetRootWindow()->GetBoundsInScreen());
233 intersect
.Intersect(window_bounds_in_screen
);
235 EXPECT_LE(10, intersect
.width());
236 EXPECT_LE(10, intersect
.height());
237 EXPECT_TRUE(window_bounds_in_screen
.Contains(gfx::Point(800, 10)));
240 // Dropping a window that is larger than the destination work area
241 // will shrink to fit to the work area.
242 window_
->SetBoundsInScreen(gfx::Rect(0, 0, 700, 500),
243 Shell::GetScreen()->GetPrimaryDisplay());
244 EXPECT_EQ(root_windows
[0], window_
->GetRootWindow());
246 // Grab the top-left edge of the window and move the pointer to (150, 10)
247 // in the secondary root window's coordinates. Make sure the window is
248 // shrink in such a way that it keeps the cursor within.
249 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
250 window_
.get(), gfx::Point(0, 0), HTCAPTION
));
251 ASSERT_TRUE(resizer
.get());
252 resizer
->Drag(CalculateDragPoint(*resizer
, 799, 10), ui::EF_CONTROL_DOWN
);
253 resizer
->Drag(CalculateDragPoint(*resizer
, 850, 10), ui::EF_CONTROL_DOWN
);
254 resizer
->CompleteDrag();
255 EXPECT_EQ(root_windows
[1], window_
->GetRootWindow());
256 // Window size should be adjusted to fit to the work area
257 EXPECT_EQ("400x253", window_
->bounds().size().ToString());
258 gfx::Rect window_bounds_in_screen
= window_
->GetBoundsInScreen();
259 gfx::Rect
intersect(window_
->GetRootWindow()->GetBoundsInScreen());
260 intersect
.Intersect(window_bounds_in_screen
);
261 EXPECT_LE(10, intersect
.width());
262 EXPECT_LE(10, intersect
.height());
263 EXPECT_TRUE(window_bounds_in_screen
.Contains(gfx::Point(850, 10)));
267 // Verifies that dragging the active window to another display makes the new
268 // root window the active root window.
269 TEST_F(DragWindowResizerTest
, WindowDragWithMultiDisplaysActiveRoot
) {
270 if (!SupportsMultipleDisplays())
273 // The secondary display is logically on the right, but on the system (e.g. X)
274 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
275 UpdateDisplay("800x600,800x600");
276 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
277 ASSERT_EQ(2U, root_windows
.size());
279 aura::test::TestWindowDelegate delegate
;
280 scoped_ptr
<aura::Window
> window(new aura::Window(&delegate
));
281 window
->SetType(ui::wm::WINDOW_TYPE_NORMAL
);
282 window
->Init(ui::LAYER_TEXTURED
);
283 ParentWindowInPrimaryRootWindow(window
.get());
284 window
->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
285 Shell::GetScreen()->GetPrimaryDisplay());
287 EXPECT_TRUE(ash::wm::CanActivateWindow(window
.get()));
288 ash::wm::ActivateWindow(window
.get());
289 EXPECT_EQ(root_windows
[0], window
->GetRootWindow());
290 EXPECT_EQ(root_windows
[0], ash::Shell::GetTargetRootWindow());
292 // Grab (0, 0) of the window.
293 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
294 window
.get(), gfx::Point(), HTCAPTION
));
295 ASSERT_TRUE(resizer
.get());
296 // Drag the pointer to the right. Once it reaches the right edge of the
297 // primary display, it warps to the secondary.
298 resizer
->Drag(CalculateDragPoint(*resizer
, 800, 10), 0);
299 resizer
->CompleteDrag();
300 // The whole window is on the secondary display now. The parent should be
302 EXPECT_EQ(root_windows
[1], window
->GetRootWindow());
303 EXPECT_EQ(root_windows
[1], ash::Shell::GetTargetRootWindow());
307 // Verifies a window can be moved from the secondary display to primary.
308 TEST_F(DragWindowResizerTest
, WindowDragWithMultiDisplaysRightToLeft
) {
309 if (!SupportsMultipleDisplays())
312 UpdateDisplay("800x600,800x600");
313 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
314 ASSERT_EQ(2U, root_windows
.size());
316 window_
->SetBoundsInScreen(
317 gfx::Rect(800, 00, 50, 60),
318 Shell::GetScreen()->GetDisplayNearestWindow(root_windows
[1]));
319 EXPECT_EQ(root_windows
[1], window_
->GetRootWindow());
321 // Grab (0, 0) of the window.
322 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
323 window_
.get(), gfx::Point(), HTCAPTION
));
324 ASSERT_TRUE(resizer
.get());
325 // Move the mouse near the right edge, (798, 0), of the primary display.
326 resizer
->Drag(CalculateDragPoint(*resizer
, -2, 0), ui::EF_CONTROL_DOWN
);
327 resizer
->CompleteDrag();
328 EXPECT_EQ(root_windows
[0], window_
->GetRootWindow());
329 // Window origin should be adjusted for minimum visibility (10px).
330 int expected_x
= 800 - 10;
331 EXPECT_EQ(base::IntToString(expected_x
) + ",0 50x60",
332 window_
->bounds().ToString());
336 // Verifies the drag window is shown correctly.
337 TEST_F(DragWindowResizerTest
, DragWindowController
) {
338 if (!SupportsMultipleDisplays())
341 UpdateDisplay("800x600,800x600");
342 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
343 ASSERT_EQ(2U, root_windows
.size());
345 window_
->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
346 Shell::GetScreen()->GetPrimaryDisplay());
347 EXPECT_EQ(root_windows
[0], window_
->GetRootWindow());
348 EXPECT_FLOAT_EQ(1.0f
, window_
->layer()->opacity());
350 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
351 window_
.get(), gfx::Point(), HTCAPTION
));
352 ASSERT_TRUE(resizer
.get());
353 DragWindowResizer
* drag_resizer
= DragWindowResizer::instance_
;
354 ASSERT_TRUE(drag_resizer
);
355 EXPECT_EQ(0u, drag_resizer
->drag_window_controllers_
.size());
357 // The pointer is inside the primary root. The drag window controller
359 resizer
->Drag(CalculateDragPoint(*resizer
, 10, 10), 0);
360 EXPECT_EQ(0u, drag_resizer
->drag_window_controllers_
.size());
362 // The window spans both root windows.
363 resizer
->Drag(CalculateDragPoint(*resizer
, 798, 10), 0);
364 EXPECT_EQ(1u, drag_resizer
->drag_window_controllers_
.size());
365 DragWindowController
* controller
=
366 drag_resizer
->drag_window_controllers_
[0];
367 ASSERT_TRUE(controller
);
369 ASSERT_TRUE(controller
->drag_widget_
);
370 ui::Layer
* drag_layer
=
371 controller
->drag_widget_
->GetNativeWindow()->layer();
372 ASSERT_TRUE(drag_layer
);
373 // Check if |resizer->layer_| is properly set to the drag widget.
374 const std::vector
<ui::Layer
*>& layers
= drag_layer
->children();
375 EXPECT_FALSE(layers
.empty());
376 EXPECT_EQ(controller
->layer_owner_
->root(), layers
.back());
378 // |window_| should be opaque since the pointer is still on the primary
379 // root window. The drag window should be semi-transparent.
380 EXPECT_FLOAT_EQ(1.0f
, window_
->layer()->opacity());
381 ASSERT_TRUE(controller
->drag_widget_
);
382 EXPECT_GT(1.0f
, drag_layer
->opacity());
384 // Enter the pointer to the secondary display.
385 resizer
->Drag(CalculateDragPoint(*resizer
, 800, 10), 0);
386 EXPECT_EQ(1u, drag_resizer
->drag_window_controllers_
.size());
387 controller
= drag_resizer
->drag_window_controllers_
[0];
388 ASSERT_TRUE(controller
);
389 // |window_| should be transparent, and the drag window should be opaque.
390 EXPECT_GT(1.0f
, window_
->layer()->opacity());
391 EXPECT_FLOAT_EQ(1.0f
, drag_layer
->opacity());
393 resizer
->CompleteDrag();
394 EXPECT_EQ(root_windows
[1], window_
->GetRootWindow());
395 EXPECT_FLOAT_EQ(1.0f
, window_
->layer()->opacity());
398 // Do the same test with RevertDrag().
399 window_
->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
400 Shell::GetScreen()->GetPrimaryDisplay());
401 EXPECT_EQ(root_windows
[0], window_
->GetRootWindow());
402 EXPECT_FLOAT_EQ(1.0f
, window_
->layer()->opacity());
404 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
405 window_
.get(), gfx::Point(), HTCAPTION
));
406 ASSERT_TRUE(resizer
.get());
407 DragWindowResizer
* drag_resizer
= DragWindowResizer::instance_
;
408 ASSERT_TRUE(drag_resizer
);
409 EXPECT_EQ(0u, drag_resizer
->drag_window_controllers_
.size());
411 resizer
->Drag(CalculateDragPoint(*resizer
, 0, 610), 0);
412 resizer
->RevertDrag();
413 EXPECT_EQ(root_windows
[0], window_
->GetRootWindow());
414 EXPECT_FLOAT_EQ(1.0f
, window_
->layer()->opacity());
418 // Verifies if the resizer sets and resets
419 // MouseCursorEventFilter::mouse_warp_mode_ as expected.
420 TEST_F(DragWindowResizerTest
, WarpMousePointer
) {
421 MouseCursorEventFilter
* event_filter
=
422 Shell::GetInstance()->mouse_cursor_filter();
423 ASSERT_TRUE(event_filter
);
424 window_
->SetBounds(gfx::Rect(0, 0, 50, 60));
426 EXPECT_TRUE(event_filter
->mouse_warp_enabled_
);
428 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
429 window_
.get(), gfx::Point(), HTCAPTION
));
430 // While dragging a window, warp should be allowed.
431 EXPECT_TRUE(event_filter
->mouse_warp_enabled_
);
432 resizer
->CompleteDrag();
434 EXPECT_TRUE(event_filter
->mouse_warp_enabled_
);
437 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
438 window_
.get(), gfx::Point(), HTCAPTION
));
439 EXPECT_TRUE(event_filter
->mouse_warp_enabled_
);
440 resizer
->RevertDrag();
442 EXPECT_TRUE(event_filter
->mouse_warp_enabled_
);
445 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
446 window_
.get(), gfx::Point(), HTRIGHT
));
447 // While resizing a window, warp should NOT be allowed.
448 EXPECT_FALSE(event_filter
->mouse_warp_enabled_
);
449 resizer
->CompleteDrag();
451 EXPECT_TRUE(event_filter
->mouse_warp_enabled_
);
454 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
455 window_
.get(), gfx::Point(), HTRIGHT
));
456 EXPECT_FALSE(event_filter
->mouse_warp_enabled_
);
457 resizer
->RevertDrag();
459 EXPECT_TRUE(event_filter
->mouse_warp_enabled_
);
462 // Verifies cursor's device scale factor is updated whe a window is moved across
463 // root windows with different device scale factors (http://crbug.com/154183).
464 TEST_F(DragWindowResizerTest
, CursorDeviceScaleFactor
) {
465 if (!SupportsMultipleDisplays())
468 // The secondary display is logically on the right, but on the system (e.g. X)
469 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
470 UpdateDisplay("400x400,800x800*2");
471 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
472 ASSERT_EQ(2U, root_windows
.size());
474 test::CursorManagerTestApi
cursor_test_api(
475 Shell::GetInstance()->cursor_manager());
476 // Move window from the root window with 1.0 device scale factor to the root
477 // window with 2.0 device scale factor.
479 window_
->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
480 Shell::GetScreen()->GetPrimaryDisplay());
481 EXPECT_EQ(root_windows
[0], window_
->GetRootWindow());
482 // Grab (0, 0) of the window.
483 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
484 window_
.get(), gfx::Point(), HTCAPTION
));
485 EXPECT_EQ(1.0f
, cursor_test_api
.GetCurrentCursor().device_scale_factor());
486 ASSERT_TRUE(resizer
.get());
487 resizer
->Drag(CalculateDragPoint(*resizer
, 399, 200), 0);
488 TestIfMouseWarpsAt(gfx::Point(399, 200));
489 EXPECT_EQ(2.0f
, cursor_test_api
.GetCurrentCursor().device_scale_factor());
490 resizer
->CompleteDrag();
491 EXPECT_EQ(2.0f
, cursor_test_api
.GetCurrentCursor().device_scale_factor());
494 // Move window from the root window with 2.0 device scale factor to the root
495 // window with 1.0 device scale factor.
497 // Make sure the window is on the default container first.
498 aura::Window
* default_container
=
499 GetRootWindowController(root_windows
[1])
500 ->GetContainer(kShellWindowId_DefaultContainer
);
501 default_container
->AddChild(window_
.get());
502 window_
->SetBoundsInScreen(
503 gfx::Rect(600, 0, 50, 60),
504 Shell::GetScreen()->GetDisplayNearestWindow(root_windows
[1]));
505 EXPECT_EQ(root_windows
[1], window_
->GetRootWindow());
506 // Grab (0, 0) of the window.
507 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
508 window_
.get(), gfx::Point(), HTCAPTION
));
509 EXPECT_EQ(2.0f
, cursor_test_api
.GetCurrentCursor().device_scale_factor());
510 ASSERT_TRUE(resizer
.get());
511 resizer
->Drag(CalculateDragPoint(*resizer
, -200, 200), 0);
512 TestIfMouseWarpsAt(gfx::Point(400, 200));
513 EXPECT_EQ(1.0f
, cursor_test_api
.GetCurrentCursor().device_scale_factor());
514 resizer
->CompleteDrag();
515 EXPECT_EQ(1.0f
, cursor_test_api
.GetCurrentCursor().device_scale_factor());
519 // Verifies several kinds of windows can be moved across displays.
520 TEST_F(DragWindowResizerTest
, MoveWindowAcrossDisplays
) {
521 if (!SupportsMultipleDisplays())
524 // The secondary display is logically on the right, but on the system (e.g. X)
525 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
526 UpdateDisplay("400x400,400x400");
528 aura::Window::Windows root_windows
= Shell::GetAllRootWindows();
529 ASSERT_EQ(2U, root_windows
.size());
531 // Normal window can be moved across display.
533 aura::Window
* window
= window_
.get();
534 window
->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
535 Shell::GetScreen()->GetPrimaryDisplay());
536 // Grab (0, 0) of the window.
537 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
538 window
, gfx::Point(), HTCAPTION
));
539 ASSERT_TRUE(resizer
.get());
540 resizer
->Drag(CalculateDragPoint(*resizer
, 399, 200), 0);
541 EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
543 aura::Env::GetInstance()->last_mouse_location().ToString());
544 resizer
->CompleteDrag();
547 // Always on top window can be moved across display.
549 aura::Window
* window
= always_on_top_window_
.get();
550 window
->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
551 Shell::GetScreen()->GetPrimaryDisplay());
552 // Grab (0, 0) of the window.
553 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
554 window
, gfx::Point(), HTCAPTION
));
555 ASSERT_TRUE(resizer
.get());
556 resizer
->Drag(CalculateDragPoint(*resizer
, 399, 200), 0);
557 EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
559 aura::Env::GetInstance()->last_mouse_location().ToString());
560 resizer
->CompleteDrag();
563 // System modal window can be moved across display.
565 aura::Window
* window
= system_modal_window_
.get();
566 window
->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
567 Shell::GetScreen()->GetPrimaryDisplay());
568 aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(0, 0));
569 // Grab (0, 0) of the window.
570 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
571 window
, gfx::Point(), HTCAPTION
));
572 ASSERT_TRUE(resizer
.get());
573 resizer
->Drag(CalculateDragPoint(*resizer
, 399, 200), 0);
574 EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
576 aura::Env::GetInstance()->last_mouse_location().ToString());
577 resizer
->CompleteDrag();
580 // Transient window cannot be moved across display.
582 aura::Window
* window
= transient_child_
;
583 window
->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
584 Shell::GetScreen()->GetPrimaryDisplay());
585 // Grab (0, 0) of the window.
586 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
587 window
, gfx::Point(), HTCAPTION
));
588 ASSERT_TRUE(resizer
.get());
589 resizer
->Drag(CalculateDragPoint(*resizer
, 399, 200), 0);
590 EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
592 aura::Env::GetInstance()->last_mouse_location().ToString());
593 resizer
->CompleteDrag();
596 // The parent of transient window can be moved across display.
598 aura::Window
* window
= transient_parent_
.get();
599 window
->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
600 Shell::GetScreen()->GetPrimaryDisplay());
601 // Grab (0, 0) of the window.
602 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
603 window
, gfx::Point(), HTCAPTION
));
604 ASSERT_TRUE(resizer
.get());
605 resizer
->Drag(CalculateDragPoint(*resizer
, 399, 200), 0);
606 EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
608 aura::Env::GetInstance()->last_mouse_location().ToString());
609 resizer
->CompleteDrag();
612 // Panel window can be moved across display.
614 aura::Window
* window
= panel_window_
.get();
615 window
->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
616 Shell::GetScreen()->GetPrimaryDisplay());
617 // Grab (0, 0) of the window.
618 scoped_ptr
<WindowResizer
> resizer(CreateDragWindowResizer(
619 window
, gfx::Point(), HTCAPTION
));
620 ASSERT_TRUE(resizer
.get());
621 resizer
->Drag(CalculateDragPoint(*resizer
, 399, 200), 0);
622 EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
624 aura::Env::GetInstance()->last_mouse_location().ToString());
625 resizer
->CompleteDrag();