Clear wallet data when sync is disabled.
[chromium-blink-merge.git] / ash / wm / drag_window_resizer_unittest.cc
blobcfe72adb58b6a66db4772fee7a824b040ad75fc4
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/wm/drag_window_controller.h"
15 #include "ash/wm/window_util.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/stringprintf.h"
18 #include "ui/aura/client/aura_constants.h"
19 #include "ui/aura/test/test_window_delegate.h"
20 #include "ui/aura/window_event_dispatcher.h"
21 #include "ui/base/hit_test.h"
22 #include "ui/base/ui_base_types.h"
23 #include "ui/compositor/layer_tree_owner.h"
24 #include "ui/gfx/geometry/insets.h"
25 #include "ui/gfx/screen.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() {}
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(aura::WINDOW_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(aura::WINDOW_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(aura::WINDOW_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(aura::WINDOW_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(aura::WINDOW_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(aura::WINDOW_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 WarpMouseCursorIfNecessary(aura::Window* target_root,
125 const gfx::Point& point_in_screen) {
126 MouseCursorEventFilter* event_filter =
127 Shell::GetInstance()->mouse_cursor_filter();
128 bool is_warped = event_filter->WarpMouseCursorIfNecessaryForTest(
129 target_root, point_in_screen);
130 return is_warped;
133 aura::test::TestWindowDelegate delegate_;
134 aura::test::TestWindowDelegate delegate2_;
135 aura::test::TestWindowDelegate delegate3_;
136 aura::test::TestWindowDelegate delegate4_;
137 aura::test::TestWindowDelegate delegate5_;
138 aura::test::TestWindowDelegate delegate6_;
140 scoped_ptr<aura::Window> window_;
141 scoped_ptr<aura::Window> always_on_top_window_;
142 scoped_ptr<aura::Window> system_modal_window_;
143 scoped_ptr<aura::Window> panel_window_;
144 aura::Window* transient_child_;
145 scoped_ptr<aura::Window> transient_parent_;
147 private:
148 DISALLOW_COPY_AND_ASSIGN(DragWindowResizerTest);
151 // Verifies a window can be moved from the primary display to another.
152 TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplays) {
153 if (!SupportsMultipleDisplays())
154 return;
156 // The secondary display is logically on the right, but on the system (e.g. X)
157 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
158 UpdateDisplay("800x600,400x300");
159 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
160 ASSERT_EQ(2U, root_windows.size());
162 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
163 Shell::GetScreen()->GetPrimaryDisplay());
164 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
166 // Grab (0, 0) of the window.
167 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
168 window_.get(), gfx::Point(), HTCAPTION));
169 ASSERT_TRUE(resizer.get());
170 // Drag the pointer to the right. Once it reaches the right edge of the
171 // primary display, it warps to the secondary.
172 resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0);
173 resizer->CompleteDrag();
174 // The whole window is on the secondary display now. The parent should be
175 // changed.
176 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
177 EXPECT_EQ("0,10 50x60", window_->bounds().ToString());
180 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
181 Shell::GetScreen()->GetPrimaryDisplay());
182 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
184 // Grab (0, 0) of the window and move the pointer to (790, 10).
185 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
186 window_.get(), gfx::Point(), HTCAPTION));
187 ASSERT_TRUE(resizer.get());
188 resizer->Drag(CalculateDragPoint(*resizer, 795, 10), 0);
189 // Window should be adjusted for minimum visibility (10px) during the drag.
190 EXPECT_EQ("790,10 50x60", window_->bounds().ToString());
191 resizer->CompleteDrag();
192 // Since the pointer is still on the primary root window, the parent should
193 // not be changed.
194 // Window origin should be adjusted for minimum visibility (10px).
195 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
196 EXPECT_EQ("790,10 50x60", window_->bounds().ToString());
199 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
200 Shell::GetScreen()->GetPrimaryDisplay());
201 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
203 // Grab the top-right edge of the window and move the pointer to (0, 10)
204 // in the secondary root window's coordinates.
205 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
206 window_.get(), gfx::Point(49, 0), HTCAPTION));
207 ASSERT_TRUE(resizer.get());
208 resizer->Drag(CalculateDragPoint(*resizer, 751, 10), ui::EF_CONTROL_DOWN);
209 resizer->CompleteDrag();
210 // Since the pointer is on the secondary, the parent should be changed
211 // even though only small fraction of the window is within the secondary
212 // root window's bounds.
213 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
214 // Window origin should be adjusted for minimum visibility (10px).
215 int expected_x = -50 + 10;
216 EXPECT_EQ(base::IntToString(expected_x) + ",10 50x60",
217 window_->bounds().ToString());
219 // Dropping a window that is larger than the destination work area
220 // will shrink to fit to the work area.
221 window_->SetBoundsInScreen(gfx::Rect(0, 0, 700, 500),
222 Shell::GetScreen()->GetPrimaryDisplay());
223 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
225 // Grab the top-right edge of the window and move the pointer to (0, 10)
226 // in the secondary root window's coordinates.
227 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
228 window_.get(), gfx::Point(699, 0), HTCAPTION));
229 ASSERT_TRUE(resizer.get());
230 resizer->Drag(CalculateDragPoint(*resizer, 101, 10), ui::EF_CONTROL_DOWN);
231 resizer->CompleteDrag();
232 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
233 // Window size should be adjusted to fit to the work area
234 EXPECT_EQ("400x253", window_->bounds().size().ToString());
235 gfx::Rect window_bounds_in_screen = window_->GetBoundsInScreen();
236 gfx::Rect intersect(window_->GetRootWindow()->GetBoundsInScreen());
237 intersect.Intersect(window_bounds_in_screen);
239 EXPECT_LE(10, intersect.width());
240 EXPECT_LE(10, intersect.height());
241 EXPECT_TRUE(window_bounds_in_screen.Contains(gfx::Point(800, 10)));
244 // Dropping a window that is larger than the destination work area
245 // will shrink to fit to the work area.
246 window_->SetBoundsInScreen(gfx::Rect(0, 0, 700, 500),
247 Shell::GetScreen()->GetPrimaryDisplay());
248 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
250 // Grab the top-left edge of the window and move the pointer to (150, 10)
251 // in the secondary root window's coordinates. Make sure the window is
252 // shrink in such a way that it keeps the cursor within.
253 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
254 window_.get(), gfx::Point(0, 0), HTCAPTION));
255 ASSERT_TRUE(resizer.get());
256 resizer->Drag(CalculateDragPoint(*resizer, 799, 10), ui::EF_CONTROL_DOWN);
257 resizer->Drag(CalculateDragPoint(*resizer, 850, 10), ui::EF_CONTROL_DOWN);
258 resizer->CompleteDrag();
259 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
260 // Window size should be adjusted to fit to the work area
261 EXPECT_EQ("400x253", window_->bounds().size().ToString());
262 gfx::Rect window_bounds_in_screen = window_->GetBoundsInScreen();
263 gfx::Rect intersect(window_->GetRootWindow()->GetBoundsInScreen());
264 intersect.Intersect(window_bounds_in_screen);
265 EXPECT_LE(10, intersect.width());
266 EXPECT_LE(10, intersect.height());
267 EXPECT_TRUE(window_bounds_in_screen.Contains(gfx::Point(850, 10)));
271 // Verifies that dragging the active window to another display makes the new
272 // root window the active root window.
273 TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplaysActiveRoot) {
274 if (!SupportsMultipleDisplays())
275 return;
277 // The secondary display is logically on the right, but on the system (e.g. X)
278 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
279 UpdateDisplay("800x600,800x600");
280 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
281 ASSERT_EQ(2U, root_windows.size());
283 aura::test::TestWindowDelegate delegate;
284 scoped_ptr<aura::Window> window(new aura::Window(&delegate));
285 window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
286 window->Init(aura::WINDOW_LAYER_TEXTURED);
287 ParentWindowInPrimaryRootWindow(window.get());
288 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
289 Shell::GetScreen()->GetPrimaryDisplay());
290 window->Show();
291 EXPECT_TRUE(ash::wm::CanActivateWindow(window.get()));
292 ash::wm::ActivateWindow(window.get());
293 EXPECT_EQ(root_windows[0], window->GetRootWindow());
294 EXPECT_EQ(root_windows[0], ash::Shell::GetTargetRootWindow());
296 // Grab (0, 0) of the window.
297 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
298 window.get(), gfx::Point(), HTCAPTION));
299 ASSERT_TRUE(resizer.get());
300 // Drag the pointer to the right. Once it reaches the right edge of the
301 // primary display, it warps to the secondary.
302 resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0);
303 resizer->CompleteDrag();
304 // The whole window is on the secondary display now. The parent should be
305 // changed.
306 EXPECT_EQ(root_windows[1], window->GetRootWindow());
307 EXPECT_EQ(root_windows[1], ash::Shell::GetTargetRootWindow());
311 // Verifies a window can be moved from the secondary display to primary.
312 TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplaysRightToLeft) {
313 if (!SupportsMultipleDisplays())
314 return;
316 UpdateDisplay("800x600,800x600");
317 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
318 ASSERT_EQ(2U, root_windows.size());
320 window_->SetBoundsInScreen(
321 gfx::Rect(800, 00, 50, 60),
322 Shell::GetScreen()->GetDisplayNearestWindow(root_windows[1]));
323 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
325 // Grab (0, 0) of the window.
326 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
327 window_.get(), gfx::Point(), HTCAPTION));
328 ASSERT_TRUE(resizer.get());
329 // Move the mouse near the right edge, (798, 0), of the primary display.
330 resizer->Drag(CalculateDragPoint(*resizer, -2, 0), ui::EF_CONTROL_DOWN);
331 resizer->CompleteDrag();
332 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
333 // Window origin should be adjusted for minimum visibility (10px).
334 int expected_x = 800 - 10;
335 EXPECT_EQ(base::IntToString(expected_x) + ",0 50x60",
336 window_->bounds().ToString());
340 // Verifies the drag window is shown correctly.
341 TEST_F(DragWindowResizerTest, DragWindowController) {
342 if (!SupportsMultipleDisplays())
343 return;
345 UpdateDisplay("800x600,800x600");
346 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
347 ASSERT_EQ(2U, root_windows.size());
349 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
350 Shell::GetScreen()->GetPrimaryDisplay());
351 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
352 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
354 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
355 window_.get(), gfx::Point(), HTCAPTION));
356 ASSERT_TRUE(resizer.get());
357 DragWindowResizer* drag_resizer = DragWindowResizer::instance_;
358 ASSERT_TRUE(drag_resizer);
359 EXPECT_EQ(0u, drag_resizer->drag_window_controllers_.size());
361 // The pointer is inside the primary root. The drag window controller
362 // should be NULL.
363 resizer->Drag(CalculateDragPoint(*resizer, 10, 10), 0);
364 EXPECT_EQ(0u, drag_resizer->drag_window_controllers_.size());
366 // The window spans both root windows.
367 resizer->Drag(CalculateDragPoint(*resizer, 798, 10), 0);
368 EXPECT_EQ(1u, drag_resizer->drag_window_controllers_.size());
369 DragWindowController* controller =
370 drag_resizer->drag_window_controllers_[0];
371 ASSERT_TRUE(controller);
373 ASSERT_TRUE(controller->drag_widget_);
374 ui::Layer* drag_layer =
375 controller->drag_widget_->GetNativeWindow()->layer();
376 ASSERT_TRUE(drag_layer);
377 // Check if |resizer->layer_| is properly set to the drag widget.
378 const std::vector<ui::Layer*>& layers = drag_layer->children();
379 EXPECT_FALSE(layers.empty());
380 EXPECT_EQ(controller->layer_owner_->root(), layers.back());
382 // |window_| should be opaque since the pointer is still on the primary
383 // root window. The drag window should be semi-transparent.
384 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
385 ASSERT_TRUE(controller->drag_widget_);
386 EXPECT_GT(1.0f, drag_layer->opacity());
388 // Enter the pointer to the secondary display.
389 resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0);
390 EXPECT_EQ(1u, drag_resizer->drag_window_controllers_.size());
391 controller = drag_resizer->drag_window_controllers_[0];
392 ASSERT_TRUE(controller);
393 // |window_| should be transparent, and the drag window should be opaque.
394 EXPECT_GT(1.0f, window_->layer()->opacity());
395 EXPECT_FLOAT_EQ(1.0f, drag_layer->opacity());
397 resizer->CompleteDrag();
398 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
399 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
402 // Do the same test with RevertDrag().
403 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
404 Shell::GetScreen()->GetPrimaryDisplay());
405 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
406 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
408 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
409 window_.get(), gfx::Point(), HTCAPTION));
410 ASSERT_TRUE(resizer.get());
411 DragWindowResizer* drag_resizer = DragWindowResizer::instance_;
412 ASSERT_TRUE(drag_resizer);
413 EXPECT_EQ(0u, drag_resizer->drag_window_controllers_.size());
415 resizer->Drag(CalculateDragPoint(*resizer, 0, 610), 0);
416 resizer->RevertDrag();
417 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
418 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
422 // Verifies if the resizer sets and resets
423 // MouseCursorEventFilter::mouse_warp_mode_ as expected.
424 TEST_F(DragWindowResizerTest, WarpMousePointer) {
425 MouseCursorEventFilter* event_filter =
426 Shell::GetInstance()->mouse_cursor_filter();
427 ASSERT_TRUE(event_filter);
428 window_->SetBounds(gfx::Rect(0, 0, 50, 60));
430 EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS,
431 event_filter->mouse_warp_mode_);
433 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
434 window_.get(), gfx::Point(), HTCAPTION));
435 // While dragging a window, warp should be allowed.
436 EXPECT_EQ(MouseCursorEventFilter::WARP_DRAG,
437 event_filter->mouse_warp_mode_);
438 resizer->CompleteDrag();
440 EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS,
441 event_filter->mouse_warp_mode_);
444 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
445 window_.get(), gfx::Point(), HTCAPTION));
446 EXPECT_EQ(MouseCursorEventFilter::WARP_DRAG,
447 event_filter->mouse_warp_mode_);
448 resizer->RevertDrag();
450 EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS,
451 event_filter->mouse_warp_mode_);
454 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
455 window_.get(), gfx::Point(), HTRIGHT));
456 // While resizing a window, warp should NOT be allowed.
457 EXPECT_EQ(MouseCursorEventFilter::WARP_NONE,
458 event_filter->mouse_warp_mode_);
459 resizer->CompleteDrag();
461 EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS,
462 event_filter->mouse_warp_mode_);
465 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
466 window_.get(), gfx::Point(), HTRIGHT));
467 EXPECT_EQ(MouseCursorEventFilter::WARP_NONE,
468 event_filter->mouse_warp_mode_);
469 resizer->RevertDrag();
471 EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS,
472 event_filter->mouse_warp_mode_);
475 // Verifies cursor's device scale factor is updated whe a window is moved across
476 // root windows with different device scale factors (http://crbug.com/154183).
477 TEST_F(DragWindowResizerTest, CursorDeviceScaleFactor) {
478 if (!SupportsMultipleDisplays())
479 return;
481 // The secondary display is logically on the right, but on the system (e.g. X)
482 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
483 UpdateDisplay("400x400,800x800*2");
484 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
485 ASSERT_EQ(2U, root_windows.size());
487 test::CursorManagerTestApi cursor_test_api(
488 Shell::GetInstance()->cursor_manager());
489 // Move window from the root window with 1.0 device scale factor to the root
490 // window with 2.0 device scale factor.
492 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
493 Shell::GetScreen()->GetPrimaryDisplay());
494 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
495 // Grab (0, 0) of the window.
496 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
497 window_.get(), gfx::Point(), HTCAPTION));
498 EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
499 ASSERT_TRUE(resizer.get());
500 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
501 WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(399, 200));
502 EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
503 resizer->CompleteDrag();
504 EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
507 // Move window from the root window with 2.0 device scale factor to the root
508 // window with 1.0 device scale factor.
510 // Make sure the window is on the default container first.
511 aura::Window* default_container =
512 GetRootWindowController(root_windows[1])
513 ->GetContainer(kShellWindowId_DefaultContainer);
514 default_container->AddChild(window_.get());
515 window_->SetBoundsInScreen(
516 gfx::Rect(600, 0, 50, 60),
517 Shell::GetScreen()->GetDisplayNearestWindow(root_windows[1]));
518 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
519 // Grab (0, 0) of the window.
520 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
521 window_.get(), gfx::Point(), HTCAPTION));
522 EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
523 ASSERT_TRUE(resizer.get());
524 resizer->Drag(CalculateDragPoint(*resizer, -200, 200), 0);
525 WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(400, 200));
526 EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
527 resizer->CompleteDrag();
528 EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
532 // Verifies several kinds of windows can be moved across displays.
533 TEST_F(DragWindowResizerTest, MoveWindowAcrossDisplays) {
534 if (!SupportsMultipleDisplays())
535 return;
537 // The secondary display is logically on the right, but on the system (e.g. X)
538 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
539 UpdateDisplay("400x400,400x400");
541 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
542 ASSERT_EQ(2U, root_windows.size());
544 // Normal window can be moved across display.
546 aura::Window* window = window_.get();
547 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
548 Shell::GetScreen()->GetPrimaryDisplay());
549 // Grab (0, 0) of the window.
550 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
551 window, gfx::Point(), HTCAPTION));
552 ASSERT_TRUE(resizer.get());
553 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
554 EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0],
555 gfx::Point(399, 200)));
556 resizer->CompleteDrag();
559 // Always on top window can be moved across display.
561 aura::Window* window = always_on_top_window_.get();
562 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
563 Shell::GetScreen()->GetPrimaryDisplay());
564 // Grab (0, 0) of the window.
565 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
566 window, gfx::Point(), HTCAPTION));
567 ASSERT_TRUE(resizer.get());
568 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
569 EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0],
570 gfx::Point(399, 200)));
571 resizer->CompleteDrag();
574 // System modal window can be moved across display.
576 aura::Window* window = system_modal_window_.get();
577 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
578 Shell::GetScreen()->GetPrimaryDisplay());
579 // Grab (0, 0) of the window.
580 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
581 window, gfx::Point(), HTCAPTION));
582 ASSERT_TRUE(resizer.get());
583 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
584 EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0],
585 gfx::Point(399, 200)));
586 resizer->CompleteDrag();
589 // Transient window cannot be moved across display.
591 aura::Window* window = transient_child_;
592 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
593 Shell::GetScreen()->GetPrimaryDisplay());
594 // Grab (0, 0) of the window.
595 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
596 window, gfx::Point(), HTCAPTION));
597 ASSERT_TRUE(resizer.get());
598 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
599 EXPECT_FALSE(WarpMouseCursorIfNecessary(
600 root_windows[0],
601 gfx::Point(399, 200)));
602 resizer->CompleteDrag();
605 // The parent of transient window can be moved across display.
607 aura::Window* window = transient_parent_.get();
608 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
609 Shell::GetScreen()->GetPrimaryDisplay());
610 // Grab (0, 0) of the window.
611 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
612 window, gfx::Point(), HTCAPTION));
613 ASSERT_TRUE(resizer.get());
614 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
615 EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0],
616 gfx::Point(399, 200)));
617 resizer->CompleteDrag();
620 // Panel window can be moved across display.
622 aura::Window* window = panel_window_.get();
623 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
624 Shell::GetScreen()->GetPrimaryDisplay());
625 // Grab (0, 0) of the window.
626 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
627 window, gfx::Point(), HTCAPTION));
628 ASSERT_TRUE(resizer.get());
629 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
630 EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0],
631 gfx::Point(399, 200)));
632 resizer->CompleteDrag();
636 } // namespace ash