platformKeys: Add per-extension sign permissions.
[chromium-blink-merge.git] / ash / wm / drag_window_resizer_unittest.cc
blobb0044af477daaa66e70234b52b241429ca4fdb84
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 event_filter->reset_was_mouse_warped_for_test();
131 return is_warped;
134 aura::test::TestWindowDelegate delegate_;
135 aura::test::TestWindowDelegate delegate2_;
136 aura::test::TestWindowDelegate delegate3_;
137 aura::test::TestWindowDelegate delegate4_;
138 aura::test::TestWindowDelegate delegate5_;
139 aura::test::TestWindowDelegate delegate6_;
141 scoped_ptr<aura::Window> window_;
142 scoped_ptr<aura::Window> always_on_top_window_;
143 scoped_ptr<aura::Window> system_modal_window_;
144 scoped_ptr<aura::Window> panel_window_;
145 aura::Window* transient_child_;
146 scoped_ptr<aura::Window> transient_parent_;
148 private:
149 DISALLOW_COPY_AND_ASSIGN(DragWindowResizerTest);
152 // Verifies a window can be moved from the primary display to another.
153 TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplays) {
154 if (!SupportsMultipleDisplays())
155 return;
157 // The secondary display is logically on the right, but on the system (e.g. X)
158 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
159 UpdateDisplay("800x600,400x300");
160 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
161 ASSERT_EQ(2U, root_windows.size());
163 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
164 Shell::GetScreen()->GetPrimaryDisplay());
165 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
167 // Grab (0, 0) of the window.
168 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
169 window_.get(), gfx::Point(), HTCAPTION));
170 ASSERT_TRUE(resizer.get());
171 // Drag the pointer to the right. Once it reaches the right edge of the
172 // primary display, it warps to the secondary.
173 resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0);
174 resizer->CompleteDrag();
175 // The whole window is on the secondary display now. The parent should be
176 // changed.
177 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
178 EXPECT_EQ("0,10 50x60", window_->bounds().ToString());
181 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
182 Shell::GetScreen()->GetPrimaryDisplay());
183 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
185 // Grab (0, 0) of the window and move the pointer to (790, 10).
186 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
187 window_.get(), gfx::Point(), HTCAPTION));
188 ASSERT_TRUE(resizer.get());
189 resizer->Drag(CalculateDragPoint(*resizer, 795, 10), 0);
190 // Window should be adjusted for minimum visibility (10px) during the drag.
191 EXPECT_EQ("790,10 50x60", window_->bounds().ToString());
192 resizer->CompleteDrag();
193 // Since the pointer is still on the primary root window, the parent should
194 // not be changed.
195 // Window origin should be adjusted for minimum visibility (10px).
196 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
197 EXPECT_EQ("790,10 50x60", window_->bounds().ToString());
200 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
201 Shell::GetScreen()->GetPrimaryDisplay());
202 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
204 // Grab the top-right edge of the window and move the pointer to (0, 10)
205 // in the secondary root window's coordinates.
206 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
207 window_.get(), gfx::Point(49, 0), HTCAPTION));
208 ASSERT_TRUE(resizer.get());
209 resizer->Drag(CalculateDragPoint(*resizer, 751, 10), ui::EF_CONTROL_DOWN);
210 resizer->CompleteDrag();
211 // Since the pointer is on the secondary, the parent should be changed
212 // even though only small fraction of the window is within the secondary
213 // root window's bounds.
214 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
215 // Window origin should be adjusted for minimum visibility (10px).
216 int expected_x = -50 + 10;
217 EXPECT_EQ(base::IntToString(expected_x) + ",10 50x60",
218 window_->bounds().ToString());
220 // Dropping a window that is larger than the destination work area
221 // will shrink to fit to the work area.
222 window_->SetBoundsInScreen(gfx::Rect(0, 0, 700, 500),
223 Shell::GetScreen()->GetPrimaryDisplay());
224 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
226 // Grab the top-right edge of the window and move the pointer to (0, 10)
227 // in the secondary root window's coordinates.
228 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
229 window_.get(), gfx::Point(699, 0), HTCAPTION));
230 ASSERT_TRUE(resizer.get());
231 resizer->Drag(CalculateDragPoint(*resizer, 101, 10), ui::EF_CONTROL_DOWN);
232 resizer->CompleteDrag();
233 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
234 // Window size should be adjusted to fit to the work area
235 EXPECT_EQ("400x253", window_->bounds().size().ToString());
236 gfx::Rect window_bounds_in_screen = window_->GetBoundsInScreen();
237 gfx::Rect intersect(window_->GetRootWindow()->GetBoundsInScreen());
238 intersect.Intersect(window_bounds_in_screen);
240 EXPECT_LE(10, intersect.width());
241 EXPECT_LE(10, intersect.height());
242 EXPECT_TRUE(window_bounds_in_screen.Contains(gfx::Point(800, 10)));
245 // Dropping a window that is larger than the destination work area
246 // will shrink to fit to the work area.
247 window_->SetBoundsInScreen(gfx::Rect(0, 0, 700, 500),
248 Shell::GetScreen()->GetPrimaryDisplay());
249 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
251 // Grab the top-left edge of the window and move the pointer to (150, 10)
252 // in the secondary root window's coordinates. Make sure the window is
253 // shrink in such a way that it keeps the cursor within.
254 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
255 window_.get(), gfx::Point(0, 0), HTCAPTION));
256 ASSERT_TRUE(resizer.get());
257 resizer->Drag(CalculateDragPoint(*resizer, 799, 10), ui::EF_CONTROL_DOWN);
258 resizer->Drag(CalculateDragPoint(*resizer, 850, 10), ui::EF_CONTROL_DOWN);
259 resizer->CompleteDrag();
260 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
261 // Window size should be adjusted to fit to the work area
262 EXPECT_EQ("400x253", window_->bounds().size().ToString());
263 gfx::Rect window_bounds_in_screen = window_->GetBoundsInScreen();
264 gfx::Rect intersect(window_->GetRootWindow()->GetBoundsInScreen());
265 intersect.Intersect(window_bounds_in_screen);
266 EXPECT_LE(10, intersect.width());
267 EXPECT_LE(10, intersect.height());
268 EXPECT_TRUE(window_bounds_in_screen.Contains(gfx::Point(850, 10)));
272 // Verifies that dragging the active window to another display makes the new
273 // root window the active root window.
274 TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplaysActiveRoot) {
275 if (!SupportsMultipleDisplays())
276 return;
278 // The secondary display is logically on the right, but on the system (e.g. X)
279 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
280 UpdateDisplay("800x600,800x600");
281 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
282 ASSERT_EQ(2U, root_windows.size());
284 aura::test::TestWindowDelegate delegate;
285 scoped_ptr<aura::Window> window(new aura::Window(&delegate));
286 window->SetType(ui::wm::WINDOW_TYPE_NORMAL);
287 window->Init(aura::WINDOW_LAYER_TEXTURED);
288 ParentWindowInPrimaryRootWindow(window.get());
289 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
290 Shell::GetScreen()->GetPrimaryDisplay());
291 window->Show();
292 EXPECT_TRUE(ash::wm::CanActivateWindow(window.get()));
293 ash::wm::ActivateWindow(window.get());
294 EXPECT_EQ(root_windows[0], window->GetRootWindow());
295 EXPECT_EQ(root_windows[0], ash::Shell::GetTargetRootWindow());
297 // Grab (0, 0) of the window.
298 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
299 window.get(), gfx::Point(), HTCAPTION));
300 ASSERT_TRUE(resizer.get());
301 // Drag the pointer to the right. Once it reaches the right edge of the
302 // primary display, it warps to the secondary.
303 resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0);
304 resizer->CompleteDrag();
305 // The whole window is on the secondary display now. The parent should be
306 // changed.
307 EXPECT_EQ(root_windows[1], window->GetRootWindow());
308 EXPECT_EQ(root_windows[1], ash::Shell::GetTargetRootWindow());
312 // Verifies a window can be moved from the secondary display to primary.
313 TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplaysRightToLeft) {
314 if (!SupportsMultipleDisplays())
315 return;
317 UpdateDisplay("800x600,800x600");
318 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
319 ASSERT_EQ(2U, root_windows.size());
321 window_->SetBoundsInScreen(
322 gfx::Rect(800, 00, 50, 60),
323 Shell::GetScreen()->GetDisplayNearestWindow(root_windows[1]));
324 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
326 // Grab (0, 0) of the window.
327 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
328 window_.get(), gfx::Point(), HTCAPTION));
329 ASSERT_TRUE(resizer.get());
330 // Move the mouse near the right edge, (798, 0), of the primary display.
331 resizer->Drag(CalculateDragPoint(*resizer, -2, 0), ui::EF_CONTROL_DOWN);
332 resizer->CompleteDrag();
333 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
334 // Window origin should be adjusted for minimum visibility (10px).
335 int expected_x = 800 - 10;
336 EXPECT_EQ(base::IntToString(expected_x) + ",0 50x60",
337 window_->bounds().ToString());
341 // Verifies the drag window is shown correctly.
342 TEST_F(DragWindowResizerTest, DragWindowController) {
343 if (!SupportsMultipleDisplays())
344 return;
346 UpdateDisplay("800x600,800x600");
347 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
348 ASSERT_EQ(2U, root_windows.size());
350 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
351 Shell::GetScreen()->GetPrimaryDisplay());
352 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
353 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
355 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
356 window_.get(), gfx::Point(), HTCAPTION));
357 ASSERT_TRUE(resizer.get());
358 DragWindowResizer* drag_resizer = DragWindowResizer::instance_;
359 ASSERT_TRUE(drag_resizer);
360 EXPECT_EQ(0u, drag_resizer->drag_window_controllers_.size());
362 // The pointer is inside the primary root. The drag window controller
363 // should be NULL.
364 resizer->Drag(CalculateDragPoint(*resizer, 10, 10), 0);
365 EXPECT_EQ(0u, drag_resizer->drag_window_controllers_.size());
367 // The window spans both root windows.
368 resizer->Drag(CalculateDragPoint(*resizer, 798, 10), 0);
369 EXPECT_EQ(1u, drag_resizer->drag_window_controllers_.size());
370 DragWindowController* controller =
371 drag_resizer->drag_window_controllers_[0];
372 ASSERT_TRUE(controller);
374 ASSERT_TRUE(controller->drag_widget_);
375 ui::Layer* drag_layer =
376 controller->drag_widget_->GetNativeWindow()->layer();
377 ASSERT_TRUE(drag_layer);
378 // Check if |resizer->layer_| is properly set to the drag widget.
379 const std::vector<ui::Layer*>& layers = drag_layer->children();
380 EXPECT_FALSE(layers.empty());
381 EXPECT_EQ(controller->layer_owner_->root(), layers.back());
383 // |window_| should be opaque since the pointer is still on the primary
384 // root window. The drag window should be semi-transparent.
385 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
386 ASSERT_TRUE(controller->drag_widget_);
387 EXPECT_GT(1.0f, drag_layer->opacity());
389 // Enter the pointer to the secondary display.
390 resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0);
391 EXPECT_EQ(1u, drag_resizer->drag_window_controllers_.size());
392 controller = drag_resizer->drag_window_controllers_[0];
393 ASSERT_TRUE(controller);
394 // |window_| should be transparent, and the drag window should be opaque.
395 EXPECT_GT(1.0f, window_->layer()->opacity());
396 EXPECT_FLOAT_EQ(1.0f, drag_layer->opacity());
398 resizer->CompleteDrag();
399 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
400 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
403 // Do the same test with RevertDrag().
404 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
405 Shell::GetScreen()->GetPrimaryDisplay());
406 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
407 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
409 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
410 window_.get(), gfx::Point(), HTCAPTION));
411 ASSERT_TRUE(resizer.get());
412 DragWindowResizer* drag_resizer = DragWindowResizer::instance_;
413 ASSERT_TRUE(drag_resizer);
414 EXPECT_EQ(0u, drag_resizer->drag_window_controllers_.size());
416 resizer->Drag(CalculateDragPoint(*resizer, 0, 610), 0);
417 resizer->RevertDrag();
418 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
419 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
423 // Verifies if the resizer sets and resets
424 // MouseCursorEventFilter::mouse_warp_mode_ as expected.
425 TEST_F(DragWindowResizerTest, WarpMousePointer) {
426 MouseCursorEventFilter* event_filter =
427 Shell::GetInstance()->mouse_cursor_filter();
428 ASSERT_TRUE(event_filter);
429 window_->SetBounds(gfx::Rect(0, 0, 50, 60));
431 EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS,
432 event_filter->mouse_warp_mode_);
434 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
435 window_.get(), gfx::Point(), HTCAPTION));
436 // While dragging a window, warp should be allowed.
437 EXPECT_EQ(MouseCursorEventFilter::WARP_DRAG,
438 event_filter->mouse_warp_mode_);
439 resizer->CompleteDrag();
441 EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS,
442 event_filter->mouse_warp_mode_);
445 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
446 window_.get(), gfx::Point(), HTCAPTION));
447 EXPECT_EQ(MouseCursorEventFilter::WARP_DRAG,
448 event_filter->mouse_warp_mode_);
449 resizer->RevertDrag();
451 EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS,
452 event_filter->mouse_warp_mode_);
455 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
456 window_.get(), gfx::Point(), HTRIGHT));
457 // While resizing a window, warp should NOT be allowed.
458 EXPECT_EQ(MouseCursorEventFilter::WARP_NONE,
459 event_filter->mouse_warp_mode_);
460 resizer->CompleteDrag();
462 EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS,
463 event_filter->mouse_warp_mode_);
466 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
467 window_.get(), gfx::Point(), HTRIGHT));
468 EXPECT_EQ(MouseCursorEventFilter::WARP_NONE,
469 event_filter->mouse_warp_mode_);
470 resizer->RevertDrag();
472 EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS,
473 event_filter->mouse_warp_mode_);
476 // Verifies cursor's device scale factor is updated whe a window is moved across
477 // root windows with different device scale factors (http://crbug.com/154183).
478 TEST_F(DragWindowResizerTest, CursorDeviceScaleFactor) {
479 if (!SupportsMultipleDisplays())
480 return;
482 // The secondary display is logically on the right, but on the system (e.g. X)
483 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
484 UpdateDisplay("400x400,800x800*2");
485 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
486 ASSERT_EQ(2U, root_windows.size());
488 test::CursorManagerTestApi cursor_test_api(
489 Shell::GetInstance()->cursor_manager());
490 // Move window from the root window with 1.0 device scale factor to the root
491 // window with 2.0 device scale factor.
493 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
494 Shell::GetScreen()->GetPrimaryDisplay());
495 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
496 // Grab (0, 0) of the window.
497 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
498 window_.get(), gfx::Point(), HTCAPTION));
499 EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
500 ASSERT_TRUE(resizer.get());
501 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
502 WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(399, 200));
503 EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
504 resizer->CompleteDrag();
505 EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
508 // Move window from the root window with 2.0 device scale factor to the root
509 // window with 1.0 device scale factor.
511 // Make sure the window is on the default container first.
512 aura::Window* default_container =
513 GetRootWindowController(root_windows[1])
514 ->GetContainer(kShellWindowId_DefaultContainer);
515 default_container->AddChild(window_.get());
516 window_->SetBoundsInScreen(
517 gfx::Rect(600, 0, 50, 60),
518 Shell::GetScreen()->GetDisplayNearestWindow(root_windows[1]));
519 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
520 // Grab (0, 0) of the window.
521 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
522 window_.get(), gfx::Point(), HTCAPTION));
523 EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
524 ASSERT_TRUE(resizer.get());
525 resizer->Drag(CalculateDragPoint(*resizer, -200, 200), 0);
526 WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(400, 200));
527 EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
528 resizer->CompleteDrag();
529 EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
533 // Verifies several kinds of windows can be moved across displays.
534 TEST_F(DragWindowResizerTest, MoveWindowAcrossDisplays) {
535 if (!SupportsMultipleDisplays())
536 return;
538 // The secondary display is logically on the right, but on the system (e.g. X)
539 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc.
540 UpdateDisplay("400x400,400x400");
542 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
543 ASSERT_EQ(2U, root_windows.size());
545 // Normal window can be moved across display.
547 aura::Window* window = window_.get();
548 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
549 Shell::GetScreen()->GetPrimaryDisplay());
550 // Grab (0, 0) of the window.
551 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
552 window, gfx::Point(), HTCAPTION));
553 ASSERT_TRUE(resizer.get());
554 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
555 EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0],
556 gfx::Point(399, 200)));
557 resizer->CompleteDrag();
560 // Always on top window can be moved across display.
562 aura::Window* window = always_on_top_window_.get();
563 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
564 Shell::GetScreen()->GetPrimaryDisplay());
565 // Grab (0, 0) of the window.
566 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
567 window, gfx::Point(), HTCAPTION));
568 ASSERT_TRUE(resizer.get());
569 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
570 EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0],
571 gfx::Point(399, 200)));
572 resizer->CompleteDrag();
575 // System modal window can be moved across display.
577 aura::Window* window = system_modal_window_.get();
578 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
579 Shell::GetScreen()->GetPrimaryDisplay());
580 // Grab (0, 0) of the window.
581 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
582 window, gfx::Point(), HTCAPTION));
583 ASSERT_TRUE(resizer.get());
584 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
585 EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0],
586 gfx::Point(399, 200)));
587 resizer->CompleteDrag();
590 // Transient window cannot be moved across display.
592 aura::Window* window = transient_child_;
593 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
594 Shell::GetScreen()->GetPrimaryDisplay());
595 // Grab (0, 0) of the window.
596 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
597 window, gfx::Point(), HTCAPTION));
598 ASSERT_TRUE(resizer.get());
599 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
600 EXPECT_FALSE(WarpMouseCursorIfNecessary(
601 root_windows[0],
602 gfx::Point(399, 200)));
603 resizer->CompleteDrag();
606 // The parent of transient window can be moved across display.
608 aura::Window* window = transient_parent_.get();
609 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
610 Shell::GetScreen()->GetPrimaryDisplay());
611 // Grab (0, 0) of the window.
612 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
613 window, gfx::Point(), HTCAPTION));
614 ASSERT_TRUE(resizer.get());
615 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
616 EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0],
617 gfx::Point(399, 200)));
618 resizer->CompleteDrag();
621 // Panel window can be moved across display.
623 aura::Window* window = panel_window_.get();
624 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
625 Shell::GetScreen()->GetPrimaryDisplay());
626 // Grab (0, 0) of the window.
627 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer(
628 window, gfx::Point(), HTCAPTION));
629 ASSERT_TRUE(resizer.get());
630 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0);
631 EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0],
632 gfx::Point(399, 200)));
633 resizer->CompleteDrag();
637 } // namespace ash