Move policy and rationale permission handling to public Window class.
[chromium-blink-merge.git] / ash / wm / drag_window_resizer_unittest.cc
blob2b3faa372e7e484eea41e34c4b6ef5848f002c95
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"
29 namespace ash {
30 namespace {
32 const int kRootHeight = 600;
34 } // namespace
36 class DragWindowResizerTest : public test::AshTestBase {
37 public:
38 DragWindowResizerTest() : transient_child_(nullptr) {}
39 ~DragWindowResizerTest() override {}
41 void SetUp() override {
42 AshTestBase::SetUp();
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());
54 window_->set_id(1);
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 {
91 window_.reset();
92 always_on_top_window_.reset();
93 system_modal_window_.reset();
94 transient_parent_.reset();
95 panel_window_.reset();
96 AshTestBase::TearDown();
99 protected:
100 gfx::Point CalculateDragPoint(const WindowResizer& resizer,
101 int delta_x,
102 int delta_y) const {
103 gfx::Point location = resizer.GetInitialLocation();
104 location.set_x(location.x() + delta_x);
105 location.set_y(location.y() + delta_y);
106 return location;
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(
118 window,
119 point_in_parent,
120 window_component,
121 aura::client::WINDOW_MOVE_SOURCE_MOUSE).release();
124 bool TestIfMouseWarpsAt(const gfx::Point& point_in_screen) {
125 return test::DisplayManagerTestApi::TestIfMouseWarpsAt(GetEventGenerator(),
126 point_in_screen);
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_;
143 private:
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())
150 return;
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
171 // changed.
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 (775, 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 (25px) during the drag.
186 EXPECT_EQ("775,10 50x60", window_->bounds().ToString());
187 resizer->CompleteDrag();
188 // Since the pointer is still on the primary root window, the parent should
189 // not be changed.
190 // Window origin should be adjusted for minimum visibility (25px).
191 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
192 EXPECT_EQ("775,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 (25px).
211 int expected_x = -50 + kMinimumOnScreenArea;
213 EXPECT_EQ(base::IntToString(expected_x) + ",10 50x60",
214 window_->bounds().ToString());
216 // Dropping a window that is larger than the destination work area
217 // will shrink to fit to the work area.
218 window_->SetBoundsInScreen(gfx::Rect(0, 0, 700, 500),
219 Shell::GetScreen()->GetPrimaryDisplay());
220 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
222 // Grab the top-right edge of the window and move the pointer to (0, 10)
223 // in the secondary root window's coordinates.
224 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
225 window_.get(), gfx::Point(699, 0), HTCAPTION));
226 ASSERT_TRUE(resizer.get());
227 resizer->Drag(CalculateDragPoint(*resizer, 101, 10), ui::EF_CONTROL_DOWN);
228 resizer->CompleteDrag();
229 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
230 // Window size should be adjusted to fit to the work area
231 EXPECT_EQ("400x253", window_->bounds().size().ToString());
232 gfx::Rect window_bounds_in_screen = window_->GetBoundsInScreen();
233 gfx::Rect intersect(window_->GetRootWindow()->GetBoundsInScreen());
234 intersect.Intersect(window_bounds_in_screen);
236 EXPECT_LE(10, intersect.width());
237 EXPECT_LE(10, intersect.height());
238 EXPECT_TRUE(window_bounds_in_screen.Contains(gfx::Point(800, 10)));
241 // Dropping a window that is larger than the destination work area
242 // will shrink to fit to the work area.
243 window_->SetBoundsInScreen(gfx::Rect(0, 0, 700, 500),
244 Shell::GetScreen()->GetPrimaryDisplay());
245 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
247 // Grab the top-left edge of the window and move the pointer to (150, 10)
248 // in the secondary root window's coordinates. Make sure the window is
249 // shrink in such a way that it keeps the cursor within.
250 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
251 window_.get(), gfx::Point(0, 0), HTCAPTION));
252 ASSERT_TRUE(resizer.get());
253 resizer->Drag(CalculateDragPoint(*resizer, 799, 10), ui::EF_CONTROL_DOWN);
254 resizer->Drag(CalculateDragPoint(*resizer, 850, 10), ui::EF_CONTROL_DOWN);
255 resizer->CompleteDrag();
256 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
257 // Window size should be adjusted to fit to the work area
258 EXPECT_EQ("400x253", window_->bounds().size().ToString());
259 gfx::Rect window_bounds_in_screen = window_->GetBoundsInScreen();
260 gfx::Rect intersect(window_->GetRootWindow()->GetBoundsInScreen());
261 intersect.Intersect(window_bounds_in_screen);
262 EXPECT_LE(10, intersect.width());
263 EXPECT_LE(10, intersect.height());
264 EXPECT_TRUE(window_bounds_in_screen.Contains(gfx::Point(850, 10)));
268 // Verifies that dragging the active window to another display makes the new
269 // root window the active root window.
270 TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplaysActiveRoot) {
271 if (!SupportsMultipleDisplays())
272 return;
274 // The secondary display is logically on the right, but on the system (e.g. X)
275 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
276 UpdateDisplay("800x600,800x600");
277 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
278 ASSERT_EQ(2U, root_windows.size());
280 aura::test::TestWindowDelegate delegate;
281 scoped_ptr<aura::Window> window(new aura::Window(&delegate));
282 window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
283 window->Init(ui::LAYER_TEXTURED);
284 ParentWindowInPrimaryRootWindow(window.get());
285 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
286 Shell::GetScreen()->GetPrimaryDisplay());
287 window->Show();
288 EXPECT_TRUE(ash::wm::CanActivateWindow(window.get()));
289 ash::wm::ActivateWindow(window.get());
290 EXPECT_EQ(root_windows[0], window->GetRootWindow());
291 EXPECT_EQ(root_windows[0], ash::Shell::GetTargetRootWindow());
293 // Grab (0, 0) of the window.
294 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
295 window.get(), gfx::Point(), HTCAPTION));
296 ASSERT_TRUE(resizer.get());
297 // Drag the pointer to the right. Once it reaches the right edge of the
298 // primary display, it warps to the secondary.
299 resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0);
300 resizer->CompleteDrag();
301 // The whole window is on the secondary display now. The parent should be
302 // changed.
303 EXPECT_EQ(root_windows[1], window->GetRootWindow());
304 EXPECT_EQ(root_windows[1], ash::Shell::GetTargetRootWindow());
308 // Verifies a window can be moved from the secondary display to primary.
309 TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplaysRightToLeft) {
310 if (!SupportsMultipleDisplays())
311 return;
313 UpdateDisplay("800x600,800x600");
314 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
315 ASSERT_EQ(2U, root_windows.size());
317 window_->SetBoundsInScreen(
318 gfx::Rect(800, 00, 50, 60),
319 Shell::GetScreen()->GetDisplayNearestWindow(root_windows[1]));
320 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
322 // Grab (0, 0) of the window.
323 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
324 window_.get(), gfx::Point(), HTCAPTION));
325 ASSERT_TRUE(resizer.get());
326 // Move the mouse near the right edge, (798, 0), of the primary display.
327 resizer->Drag(CalculateDragPoint(*resizer, -2, 0), ui::EF_CONTROL_DOWN);
328 resizer->CompleteDrag();
329 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
330 // Window origin should be adjusted for minimum visibility (25px).
331 EXPECT_EQ("775,0 50x60", window_->bounds().ToString());
335 // Verifies the drag window is shown correctly.
336 TEST_F(DragWindowResizerTest, DragWindowController) {
337 if (!SupportsMultipleDisplays())
338 return;
340 UpdateDisplay("800x600,800x600");
341 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
342 ASSERT_EQ(2U, root_windows.size());
344 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
345 Shell::GetScreen()->GetPrimaryDisplay());
346 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
347 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
349 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
350 window_.get(), gfx::Point(), HTCAPTION));
351 ASSERT_TRUE(resizer.get());
352 DragWindowResizer* drag_resizer = DragWindowResizer::instance_;
353 ASSERT_TRUE(drag_resizer);
354 EXPECT_EQ(0u, drag_resizer->drag_window_controllers_.size());
356 // The pointer is inside the primary root. The drag window controller
357 // should be NULL.
358 resizer->Drag(CalculateDragPoint(*resizer, 10, 10), 0);
359 EXPECT_EQ(0u, drag_resizer->drag_window_controllers_.size());
361 // The window spans both root windows.
362 resizer->Drag(CalculateDragPoint(*resizer, 798, 10), 0);
363 EXPECT_EQ(1u, drag_resizer->drag_window_controllers_.size());
364 DragWindowController* controller =
365 drag_resizer->drag_window_controllers_[0];
366 ASSERT_TRUE(controller);
368 ASSERT_TRUE(controller->drag_widget_);
369 ui::Layer* drag_layer =
370 controller->drag_widget_->GetNativeWindow()->layer();
371 ASSERT_TRUE(drag_layer);
372 // Check if |resizer->layer_| is properly set to the drag widget.
373 const std::vector<ui::Layer*>& layers = drag_layer->children();
374 EXPECT_FALSE(layers.empty());
375 EXPECT_EQ(controller->layer_owner_->root(), layers.back());
377 // |window_| should be opaque since the pointer is still on the primary
378 // root window. The drag window should be semi-transparent.
379 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
380 ASSERT_TRUE(controller->drag_widget_);
381 EXPECT_GT(1.0f, drag_layer->opacity());
383 // Enter the pointer to the secondary display.
384 resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0);
385 EXPECT_EQ(1u, drag_resizer->drag_window_controllers_.size());
386 controller = drag_resizer->drag_window_controllers_[0];
387 ASSERT_TRUE(controller);
388 // |window_| should be transparent, and the drag window should be opaque.
389 EXPECT_GT(1.0f, window_->layer()->opacity());
390 EXPECT_FLOAT_EQ(1.0f, drag_layer->opacity());
392 resizer->CompleteDrag();
393 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
394 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
397 // Do the same test with RevertDrag().
398 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
399 Shell::GetScreen()->GetPrimaryDisplay());
400 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
401 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
403 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
404 window_.get(), gfx::Point(), HTCAPTION));
405 ASSERT_TRUE(resizer.get());
406 DragWindowResizer* drag_resizer = DragWindowResizer::instance_;
407 ASSERT_TRUE(drag_resizer);
408 EXPECT_EQ(0u, drag_resizer->drag_window_controllers_.size());
410 resizer->Drag(CalculateDragPoint(*resizer, 0, 610), 0);
411 resizer->RevertDrag();
412 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
413 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
417 // Verifies if the resizer sets and resets
418 // MouseCursorEventFilter::mouse_warp_mode_ as expected.
419 TEST_F(DragWindowResizerTest, WarpMousePointer) {
420 MouseCursorEventFilter* event_filter =
421 Shell::GetInstance()->mouse_cursor_filter();
422 ASSERT_TRUE(event_filter);
423 window_->SetBounds(gfx::Rect(0, 0, 50, 60));
425 EXPECT_TRUE(event_filter->mouse_warp_enabled_);
427 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
428 window_.get(), gfx::Point(), HTCAPTION));
429 // While dragging a window, warp should be allowed.
430 EXPECT_TRUE(event_filter->mouse_warp_enabled_);
431 resizer->CompleteDrag();
433 EXPECT_TRUE(event_filter->mouse_warp_enabled_);
436 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
437 window_.get(), gfx::Point(), HTCAPTION));
438 EXPECT_TRUE(event_filter->mouse_warp_enabled_);
439 resizer->RevertDrag();
441 EXPECT_TRUE(event_filter->mouse_warp_enabled_);
444 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
445 window_.get(), gfx::Point(), HTRIGHT));
446 // While resizing a window, warp should NOT be allowed.
447 EXPECT_FALSE(event_filter->mouse_warp_enabled_);
448 resizer->CompleteDrag();
450 EXPECT_TRUE(event_filter->mouse_warp_enabled_);
453 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
454 window_.get(), gfx::Point(), HTRIGHT));
455 EXPECT_FALSE(event_filter->mouse_warp_enabled_);
456 resizer->RevertDrag();
458 EXPECT_TRUE(event_filter->mouse_warp_enabled_);
461 // Verifies cursor's device scale factor is updated whe a window is moved across
462 // root windows with different device scale factors (http://crbug.com/154183).
463 TEST_F(DragWindowResizerTest, CursorDeviceScaleFactor) {
464 if (!SupportsMultipleDisplays())
465 return;
467 // The secondary display is logically on the right, but on the system (e.g. X)
468 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
469 UpdateDisplay("400x400,800x800*2");
470 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
471 ASSERT_EQ(2U, root_windows.size());
473 test::CursorManagerTestApi cursor_test_api(
474 Shell::GetInstance()->cursor_manager());
475 // Move window from the root window with 1.0 device scale factor to the root
476 // window with 2.0 device scale factor.
478 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
479 Shell::GetScreen()->GetPrimaryDisplay());
480 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
481 // Grab (0, 0) of the window.
482 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
483 window_.get(), gfx::Point(), HTCAPTION));
484 EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
485 ASSERT_TRUE(resizer.get());
486 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
487 TestIfMouseWarpsAt(gfx::Point(399, 200));
488 EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
489 resizer->CompleteDrag();
490 EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
493 // Move window from the root window with 2.0 device scale factor to the root
494 // window with 1.0 device scale factor.
496 // Make sure the window is on the default container first.
497 aura::Window* default_container =
498 GetRootWindowController(root_windows[1])
499 ->GetContainer(kShellWindowId_DefaultContainer);
500 default_container->AddChild(window_.get());
501 window_->SetBoundsInScreen(
502 gfx::Rect(600, 0, 50, 60),
503 Shell::GetScreen()->GetDisplayNearestWindow(root_windows[1]));
504 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
505 // Grab (0, 0) of the window.
506 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
507 window_.get(), gfx::Point(), HTCAPTION));
508 EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
509 ASSERT_TRUE(resizer.get());
510 resizer->Drag(CalculateDragPoint(*resizer, -200, 200), 0);
511 TestIfMouseWarpsAt(gfx::Point(400, 200));
512 EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
513 resizer->CompleteDrag();
514 EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
518 // Verifies several kinds of windows can be moved across displays.
519 TEST_F(DragWindowResizerTest, MoveWindowAcrossDisplays) {
520 if (!SupportsMultipleDisplays())
521 return;
523 // The secondary display is logically on the right, but on the system (e.g. X)
524 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
525 UpdateDisplay("400x400,400x400");
527 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
528 ASSERT_EQ(2U, root_windows.size());
530 // Normal window can be moved across display.
532 aura::Window* window = window_.get();
533 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
534 Shell::GetScreen()->GetPrimaryDisplay());
535 // Grab (0, 0) of the window.
536 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
537 window, gfx::Point(), HTCAPTION));
538 ASSERT_TRUE(resizer.get());
539 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
540 EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
541 EXPECT_EQ("401,200",
542 aura::Env::GetInstance()->last_mouse_location().ToString());
543 resizer->CompleteDrag();
546 // Always on top window can be moved across display.
548 aura::Window* window = always_on_top_window_.get();
549 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
550 Shell::GetScreen()->GetPrimaryDisplay());
551 // Grab (0, 0) of the window.
552 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
553 window, gfx::Point(), HTCAPTION));
554 ASSERT_TRUE(resizer.get());
555 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
556 EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
557 EXPECT_EQ("401,200",
558 aura::Env::GetInstance()->last_mouse_location().ToString());
559 resizer->CompleteDrag();
562 // System modal window can be moved across display.
564 aura::Window* window = system_modal_window_.get();
565 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
566 Shell::GetScreen()->GetPrimaryDisplay());
567 aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(0, 0));
568 // Grab (0, 0) of the window.
569 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
570 window, gfx::Point(), HTCAPTION));
571 ASSERT_TRUE(resizer.get());
572 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
573 EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
574 EXPECT_EQ("401,200",
575 aura::Env::GetInstance()->last_mouse_location().ToString());
576 resizer->CompleteDrag();
579 // Transient window cannot be moved across display.
581 aura::Window* window = transient_child_;
582 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
583 Shell::GetScreen()->GetPrimaryDisplay());
584 // Grab (0, 0) of the window.
585 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
586 window, gfx::Point(), HTCAPTION));
587 ASSERT_TRUE(resizer.get());
588 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
589 EXPECT_FALSE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
590 EXPECT_EQ("399,200",
591 aura::Env::GetInstance()->last_mouse_location().ToString());
592 resizer->CompleteDrag();
595 // The parent of transient window can be moved across display.
597 aura::Window* window = transient_parent_.get();
598 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
599 Shell::GetScreen()->GetPrimaryDisplay());
600 // Grab (0, 0) of the window.
601 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
602 window, gfx::Point(), HTCAPTION));
603 ASSERT_TRUE(resizer.get());
604 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
605 EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
606 EXPECT_EQ("401,200",
607 aura::Env::GetInstance()->last_mouse_location().ToString());
608 resizer->CompleteDrag();
611 // Panel window can be moved across display.
613 aura::Window* window = panel_window_.get();
614 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
615 Shell::GetScreen()->GetPrimaryDisplay());
616 // Grab (0, 0) of the window.
617 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
618 window, gfx::Point(), HTCAPTION));
619 ASSERT_TRUE(resizer.get());
620 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
621 EXPECT_TRUE(TestIfMouseWarpsAt(gfx::Point(399, 200)));
622 EXPECT_EQ("401,200",
623 aura::Env::GetInstance()->last_mouse_location().ToString());
624 resizer->CompleteDrag();
628 } // namespace ash