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. 4 5 #include "ash/wm/drag_window_resizer.h" 6 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/stringprintf.h" 17 #include "ui/aura/client/aura_constants.h" 18 #include "ui/aura/root_window.h" 19 #include "ui/aura/test/test_window_delegate.h" 20 #include "ui/base/hit_test.h" 21 #include "ui/base/ui_base_types.h" 22 #include "ui/gfx/insets.h" 23 #include "ui/gfx/screen.h" 24 #include "ui/views/widget/widget.h" 25 26 namespace ash { 27 namespace internal { 28 namespace { 29 30 const int kRootHeight = 600; 31 32 } // namespace 33 34 class DragWindowResizerTest : public test::AshTestBase { 35 public: 36 DragWindowResizerTest() {} 37 virtual ~DragWindowResizerTest() {} 38 39 virtual void SetUp() OVERRIDE { 40 AshTestBase::SetUp(); 41 UpdateDisplay(base::StringPrintf("800x%d", kRootHeight)); 42 43 aura::RootWindow* root = Shell::GetPrimaryRootWindow(); 44 gfx::Rect root_bounds(root->bounds()); 45 EXPECT_EQ(kRootHeight, root_bounds.height()); 46 EXPECT_EQ(800, root_bounds.width()); 47 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets()); 48 window_.reset(new aura::Window(&delegate_)); 49 window_->SetType(aura::client::WINDOW_TYPE_NORMAL); 50 window_->Init(ui::LAYER_NOT_DRAWN); 51 SetDefaultParentByPrimaryRootWindow(window_.get()); 52 window_->set_id(1); 53 54 always_on_top_window_.reset(new aura::Window(&delegate2_)); 55 always_on_top_window_->SetType(aura::client::WINDOW_TYPE_NORMAL); 56 always_on_top_window_->SetProperty(aura::client::kAlwaysOnTopKey, true); 57 always_on_top_window_->Init(ui::LAYER_NOT_DRAWN); 58 SetDefaultParentByPrimaryRootWindow(always_on_top_window_.get()); 59 always_on_top_window_->set_id(2); 60 61 system_modal_window_.reset(new aura::Window(&delegate3_)); 62 system_modal_window_->SetType(aura::client::WINDOW_TYPE_NORMAL); 63 system_modal_window_->SetProperty(aura::client::kModalKey, 64 ui::MODAL_TYPE_SYSTEM); 65 system_modal_window_->Init(ui::LAYER_NOT_DRAWN); 66 SetDefaultParentByPrimaryRootWindow(system_modal_window_.get()); 67 system_modal_window_->set_id(3); 68 69 transient_child_ = new aura::Window(&delegate4_); 70 transient_child_->SetType(aura::client::WINDOW_TYPE_NORMAL); 71 transient_child_->Init(ui::LAYER_NOT_DRAWN); 72 SetDefaultParentByPrimaryRootWindow(transient_child_); 73 transient_child_->set_id(4); 74 75 transient_parent_.reset(new aura::Window(&delegate5_)); 76 transient_parent_->SetType(aura::client::WINDOW_TYPE_NORMAL); 77 transient_parent_->Init(ui::LAYER_NOT_DRAWN); 78 SetDefaultParentByPrimaryRootWindow(transient_parent_.get()); 79 transient_parent_->AddTransientChild(transient_child_); 80 transient_parent_->set_id(5); 81 82 panel_window_.reset(new aura::Window(&delegate6_)); 83 panel_window_->SetType(aura::client::WINDOW_TYPE_PANEL); 84 panel_window_->Init(ui::LAYER_NOT_DRAWN); 85 SetDefaultParentByPrimaryRootWindow(panel_window_.get()); 86 } 87 88 virtual void TearDown() OVERRIDE { 89 window_.reset(); 90 always_on_top_window_.reset(); 91 system_modal_window_.reset(); 92 transient_parent_.reset(); 93 panel_window_.reset(); 94 AshTestBase::TearDown(); 95 } 96 97 protected: 98 gfx::Point CalculateDragPoint(const WindowResizer& resizer, 99 int delta_x, 100 int delta_y) const { 101 gfx::Point location = resizer.GetInitialLocation(); 102 location.set_x(location.x() + delta_x); 103 location.set_y(location.y() + delta_y); 104 return location; 105 } 106 107 internal::ShelfLayoutManager* shelf_layout_manager() { 108 return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager(); 109 } 110 111 static WindowResizer* CreateDragWindowResizer( 112 aura::Window* window, 113 const gfx::Point& point_in_parent, 114 int window_component) { 115 return CreateWindowResizer( 116 window, 117 point_in_parent, 118 window_component, 119 aura::client::WINDOW_MOVE_SOURCE_MOUSE).release(); 120 } 121 122 aura::test::TestWindowDelegate delegate_; 123 aura::test::TestWindowDelegate delegate2_; 124 aura::test::TestWindowDelegate delegate3_; 125 aura::test::TestWindowDelegate delegate4_; 126 aura::test::TestWindowDelegate delegate5_; 127 aura::test::TestWindowDelegate delegate6_; 128 129 scoped_ptr<aura::Window> window_; 130 scoped_ptr<aura::Window> always_on_top_window_; 131 scoped_ptr<aura::Window> system_modal_window_; 132 scoped_ptr<aura::Window> panel_window_; 133 aura::Window* transient_child_; 134 scoped_ptr<aura::Window> transient_parent_; 135 136 private: 137 DISALLOW_COPY_AND_ASSIGN(DragWindowResizerTest); 138 }; 139 140 // Verifies a window can be moved from the primary display to another. 141 TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplays) { 142 if (!SupportsMultipleDisplays()) 143 return; 144 145 // The secondary display is logically on the right, but on the system (e.g. X) 146 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc. 147 UpdateDisplay("800x600,800x600"); 148 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); 149 ASSERT_EQ(2U, root_windows.size()); 150 151 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), 152 Shell::GetScreen()->GetPrimaryDisplay()); 153 EXPECT_EQ(root_windows[0], window_->GetRootWindow()); 154 { 155 // Grab (0, 0) of the window. 156 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 157 window_.get(), gfx::Point(), HTCAPTION)); 158 ASSERT_TRUE(resizer.get()); 159 // Drag the pointer to the right. Once it reaches the right edge of the 160 // primary display, it warps to the secondary. 161 resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0); 162 resizer->CompleteDrag(0); 163 // The whole window is on the secondary display now. The parent should be 164 // changed. 165 EXPECT_EQ(root_windows[1], window_->GetRootWindow()); 166 EXPECT_EQ("0,10 50x60", window_->bounds().ToString()); 167 } 168 169 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), 170 Shell::GetScreen()->GetPrimaryDisplay()); 171 EXPECT_EQ(root_windows[0], window_->GetRootWindow()); 172 { 173 // Grab (0, 0) of the window and move the pointer to (790, 10). 174 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 175 window_.get(), gfx::Point(), HTCAPTION)); 176 ASSERT_TRUE(resizer.get()); 177 resizer->Drag(CalculateDragPoint(*resizer, 790, 10), 0); 178 resizer->CompleteDrag(0); 179 // Since the pointer is still on the primary root window, the parent should 180 // not be changed. 181 EXPECT_EQ(root_windows[0], window_->GetRootWindow()); 182 EXPECT_EQ("790,10 50x60", window_->bounds().ToString()); 183 } 184 185 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), 186 Shell::GetScreen()->GetPrimaryDisplay()); 187 EXPECT_EQ(root_windows[0], window_->GetRootWindow()); 188 { 189 // Grab the top-right edge of the window and move the pointer to (0, 10) 190 // in the secondary root window's coordinates. 191 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 192 window_.get(), gfx::Point(49, 0), HTCAPTION)); 193 ASSERT_TRUE(resizer.get()); 194 resizer->Drag(CalculateDragPoint(*resizer, 751, 10), ui::EF_CONTROL_DOWN); 195 resizer->CompleteDrag(0); 196 // Since the pointer is on the secondary, the parent should be changed 197 // even though only small fraction of the window is within the secondary 198 // root window's bounds. 199 EXPECT_EQ(root_windows[1], window_->GetRootWindow()); 200 EXPECT_EQ("-49,10 50x60", window_->bounds().ToString()); 201 } 202 } 203 204 // Verifies that dragging the active window to another display makes the new 205 // root window the active root window. 206 TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplaysActiveRoot) { 207 if (!SupportsMultipleDisplays()) 208 return; 209 210 // The secondary display is logically on the right, but on the system (e.g. X) 211 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc. 212 UpdateDisplay("800x600,800x600"); 213 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); 214 ASSERT_EQ(2U, root_windows.size()); 215 216 aura::test::TestWindowDelegate delegate; 217 scoped_ptr<aura::Window> window(new aura::Window(&delegate)); 218 window->SetType(aura::client::WINDOW_TYPE_NORMAL); 219 window->Init(ui::LAYER_TEXTURED); 220 SetDefaultParentByPrimaryRootWindow(window.get()); 221 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), 222 Shell::GetScreen()->GetPrimaryDisplay()); 223 window->Show(); 224 EXPECT_TRUE(ash::wm::CanActivateWindow(window.get())); 225 ash::wm::ActivateWindow(window.get()); 226 EXPECT_EQ(root_windows[0], window->GetRootWindow()); 227 EXPECT_EQ(root_windows[0], ash::Shell::GetActiveRootWindow()); 228 { 229 // Grab (0, 0) of the window. 230 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 231 window.get(), gfx::Point(), HTCAPTION)); 232 ASSERT_TRUE(resizer.get()); 233 // Drag the pointer to the right. Once it reaches the right edge of the 234 // primary display, it warps to the secondary. 235 resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0); 236 resizer->CompleteDrag(0); 237 // The whole window is on the secondary display now. The parent should be 238 // changed. 239 EXPECT_EQ(root_windows[1], window->GetRootWindow()); 240 EXPECT_EQ(root_windows[1], ash::Shell::GetActiveRootWindow()); 241 } 242 } 243 244 // Verifies a window can be moved from the secondary display to primary. 245 TEST_F(DragWindowResizerTest, WindowDragWithMultiDisplaysRightToLeft) { 246 if (!SupportsMultipleDisplays()) 247 return; 248 249 UpdateDisplay("800x600,800x600"); 250 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); 251 ASSERT_EQ(2U, root_windows.size()); 252 253 window_->SetBoundsInScreen( 254 gfx::Rect(800, 00, 50, 60), 255 Shell::GetScreen()->GetDisplayNearestWindow(root_windows[1])); 256 EXPECT_EQ(root_windows[1], window_->GetRootWindow()); 257 { 258 // Grab (0, 0) of the window. 259 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 260 window_.get(), gfx::Point(), HTCAPTION)); 261 ASSERT_TRUE(resizer.get()); 262 // Move the mouse near the right edge, (798, 0), of the primary display. 263 resizer->Drag(CalculateDragPoint(*resizer, -2, 0), ui::EF_CONTROL_DOWN); 264 resizer->CompleteDrag(0); 265 EXPECT_EQ(root_windows[0], window_->GetRootWindow()); 266 EXPECT_EQ("798,0 50x60", window_->bounds().ToString()); 267 } 268 } 269 270 // Verifies the drag window is shown correctly. 271 TEST_F(DragWindowResizerTest, DragWindowController) { 272 if (!SupportsMultipleDisplays()) 273 return; 274 275 UpdateDisplay("800x600,800x600"); 276 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); 277 ASSERT_EQ(2U, root_windows.size()); 278 279 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), 280 Shell::GetScreen()->GetPrimaryDisplay()); 281 EXPECT_EQ(root_windows[0], window_->GetRootWindow()); 282 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity()); 283 { 284 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 285 window_.get(), gfx::Point(), HTCAPTION)); 286 ASSERT_TRUE(resizer.get()); 287 internal::DragWindowResizer* drag_resizer = DragWindowResizer::instance_; 288 ASSERT_TRUE(drag_resizer); 289 EXPECT_FALSE(drag_resizer->drag_window_controller_.get()); 290 291 // The pointer is inside the primary root. The drag window controller 292 // should be NULL. 293 resizer->Drag(CalculateDragPoint(*resizer, 10, 10), 0); 294 EXPECT_FALSE(drag_resizer->drag_window_controller_.get()); 295 296 // The window spans both root windows. 297 resizer->Drag(CalculateDragPoint(*resizer, 798, 10), 0); 298 DragWindowController* controller = 299 drag_resizer->drag_window_controller_.get(); 300 ASSERT_TRUE(controller); 301 302 ASSERT_TRUE(controller->drag_widget_); 303 ui::Layer* drag_layer = 304 controller->drag_widget_->GetNativeWindow()->layer(); 305 ASSERT_TRUE(drag_layer); 306 // Check if |resizer->layer_| is properly set to the drag widget. 307 const std::vector<ui::Layer*>& layers = drag_layer->children(); 308 EXPECT_FALSE(layers.empty()); 309 EXPECT_EQ(controller->layer_, layers.back()); 310 311 // |window_| should be opaque since the pointer is still on the primary 312 // root window. The drag window should be semi-transparent. 313 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity()); 314 ASSERT_TRUE(controller->drag_widget_); 315 EXPECT_GT(1.0f, drag_layer->opacity()); 316 317 // Enter the pointer to the secondary display. 318 resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0); 319 controller = drag_resizer->drag_window_controller_.get(); 320 ASSERT_TRUE(controller); 321 // |window_| should be transparent, and the drag window should be opaque. 322 EXPECT_GT(1.0f, window_->layer()->opacity()); 323 EXPECT_FLOAT_EQ(1.0f, drag_layer->opacity()); 324 325 resizer->CompleteDrag(0); 326 EXPECT_EQ(root_windows[1], window_->GetRootWindow()); 327 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity()); 328 } 329 330 // Do the same test with RevertDrag(). 331 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), 332 Shell::GetScreen()->GetPrimaryDisplay()); 333 EXPECT_EQ(root_windows[0], window_->GetRootWindow()); 334 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity()); 335 { 336 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 337 window_.get(), gfx::Point(), HTCAPTION)); 338 ASSERT_TRUE(resizer.get()); 339 internal::DragWindowResizer* drag_resizer = DragWindowResizer::instance_; 340 ASSERT_TRUE(drag_resizer); 341 EXPECT_FALSE(drag_resizer->drag_window_controller_.get()); 342 343 resizer->Drag(CalculateDragPoint(*resizer, 0, 610), 0); 344 resizer->RevertDrag(); 345 EXPECT_EQ(root_windows[0], window_->GetRootWindow()); 346 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity()); 347 } 348 } 349 350 // Verifies if the resizer sets and resets 351 // MouseCursorEventFilter::mouse_warp_mode_ as expected. 352 TEST_F(DragWindowResizerTest, WarpMousePointer) { 353 MouseCursorEventFilter* event_filter = 354 Shell::GetInstance()->mouse_cursor_filter(); 355 ASSERT_TRUE(event_filter); 356 window_->SetBounds(gfx::Rect(0, 0, 50, 60)); 357 358 EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS, 359 event_filter->mouse_warp_mode_); 360 { 361 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 362 window_.get(), gfx::Point(), HTCAPTION)); 363 // While dragging a window, warp should be allowed. 364 EXPECT_EQ(MouseCursorEventFilter::WARP_DRAG, 365 event_filter->mouse_warp_mode_); 366 resizer->CompleteDrag(0); 367 } 368 EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS, 369 event_filter->mouse_warp_mode_); 370 371 { 372 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 373 window_.get(), gfx::Point(), HTCAPTION)); 374 EXPECT_EQ(MouseCursorEventFilter::WARP_DRAG, 375 event_filter->mouse_warp_mode_); 376 resizer->RevertDrag(); 377 } 378 EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS, 379 event_filter->mouse_warp_mode_); 380 381 { 382 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 383 window_.get(), gfx::Point(), HTRIGHT)); 384 // While resizing a window, warp should NOT be allowed. 385 EXPECT_EQ(MouseCursorEventFilter::WARP_NONE, 386 event_filter->mouse_warp_mode_); 387 resizer->CompleteDrag(0); 388 } 389 EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS, 390 event_filter->mouse_warp_mode_); 391 392 { 393 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 394 window_.get(), gfx::Point(), HTRIGHT)); 395 EXPECT_EQ(MouseCursorEventFilter::WARP_NONE, 396 event_filter->mouse_warp_mode_); 397 resizer->RevertDrag(); 398 } 399 EXPECT_EQ(MouseCursorEventFilter::WARP_ALWAYS, 400 event_filter->mouse_warp_mode_); 401 } 402 403 // Verifies cursor's device scale factor is updated whe a window is moved across 404 // root windows with different device scale factors (http://crbug.com/154183). 405 TEST_F(DragWindowResizerTest, CursorDeviceScaleFactor) { 406 if (!SupportsMultipleDisplays()) 407 return; 408 409 // The secondary display is logically on the right, but on the system (e.g. X) 410 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc. 411 UpdateDisplay("400x400,800x800*2"); 412 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); 413 ASSERT_EQ(2U, root_windows.size()); 414 415 test::CursorManagerTestApi cursor_test_api( 416 Shell::GetInstance()->cursor_manager()); 417 MouseCursorEventFilter* event_filter = 418 Shell::GetInstance()->mouse_cursor_filter(); 419 // Move window from the root window with 1.0 device scale factor to the root 420 // window with 2.0 device scale factor. 421 { 422 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), 423 Shell::GetScreen()->GetPrimaryDisplay()); 424 EXPECT_EQ(root_windows[0], window_->GetRootWindow()); 425 // Grab (0, 0) of the window. 426 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 427 window_.get(), gfx::Point(), HTCAPTION)); 428 EXPECT_EQ(1.0f, cursor_test_api.GetDisplay().device_scale_factor()); 429 ASSERT_TRUE(resizer.get()); 430 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0); 431 event_filter->WarpMouseCursorIfNecessary(root_windows[0], 432 gfx::Point(399, 200)); 433 EXPECT_EQ(2.0f, cursor_test_api.GetDisplay().device_scale_factor()); 434 resizer->CompleteDrag(0); 435 EXPECT_EQ(2.0f, cursor_test_api.GetDisplay().device_scale_factor()); 436 } 437 438 // Move window from the root window with 2.0 device scale factor to the root 439 // window with 1.0 device scale factor. 440 { 441 window_->SetBoundsInScreen( 442 gfx::Rect(600, 0, 50, 60), 443 Shell::GetScreen()->GetDisplayNearestWindow(root_windows[1])); 444 EXPECT_EQ(root_windows[1], window_->GetRootWindow()); 445 // Grab (0, 0) of the window. 446 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 447 window_.get(), gfx::Point(), HTCAPTION)); 448 EXPECT_EQ(2.0f, cursor_test_api.GetDisplay().device_scale_factor()); 449 ASSERT_TRUE(resizer.get()); 450 resizer->Drag(CalculateDragPoint(*resizer, -200, 200), 0); 451 event_filter->WarpMouseCursorIfNecessary(root_windows[1], 452 gfx::Point(400, 200)); 453 EXPECT_EQ(1.0f, cursor_test_api.GetDisplay().device_scale_factor()); 454 resizer->CompleteDrag(0); 455 EXPECT_EQ(1.0f, cursor_test_api.GetDisplay().device_scale_factor()); 456 } 457 } 458 459 // Verifies several kinds of windows can be moved across displays. 460 TEST_F(DragWindowResizerTest, MoveWindowAcrossDisplays) { 461 if (!SupportsMultipleDisplays()) 462 return; 463 464 // The secondary display is logically on the right, but on the system (e.g. X) 465 // layer, it's below the primary one. See UpdateDisplay() in ash_test_base.cc. 466 UpdateDisplay("400x400,400x400"); 467 468 Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); 469 ASSERT_EQ(2U, root_windows.size()); 470 MouseCursorEventFilter* event_filter = 471 Shell::GetInstance()->mouse_cursor_filter(); 472 473 // Normal window can be moved across display. 474 { 475 aura::Window* window = window_.get(); 476 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), 477 Shell::GetScreen()->GetPrimaryDisplay()); 478 // Grab (0, 0) of the window. 479 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 480 window, gfx::Point(), HTCAPTION)); 481 ASSERT_TRUE(resizer.get()); 482 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0); 483 EXPECT_TRUE(event_filter->WarpMouseCursorIfNecessary(root_windows[0], 484 gfx::Point(399, 200))); 485 resizer->CompleteDrag(0); 486 } 487 488 // Always on top window can be moved across display. 489 { 490 aura::Window* window = always_on_top_window_.get(); 491 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), 492 Shell::GetScreen()->GetPrimaryDisplay()); 493 // Grab (0, 0) of the window. 494 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 495 window, gfx::Point(), HTCAPTION)); 496 ASSERT_TRUE(resizer.get()); 497 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0); 498 EXPECT_TRUE(event_filter->WarpMouseCursorIfNecessary(root_windows[0], 499 gfx::Point(399, 200))); 500 resizer->CompleteDrag(0); 501 } 502 503 // System modal window can be moved across display. 504 { 505 aura::Window* window = system_modal_window_.get(); 506 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), 507 Shell::GetScreen()->GetPrimaryDisplay()); 508 // Grab (0, 0) of the window. 509 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 510 window, gfx::Point(), HTCAPTION)); 511 ASSERT_TRUE(resizer.get()); 512 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0); 513 EXPECT_TRUE(event_filter->WarpMouseCursorIfNecessary(root_windows[0], 514 gfx::Point(399, 200))); 515 resizer->CompleteDrag(0); 516 } 517 518 // Transient window cannot be moved across display. 519 { 520 aura::Window* window = transient_child_; 521 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), 522 Shell::GetScreen()->GetPrimaryDisplay()); 523 // Grab (0, 0) of the window. 524 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 525 window, gfx::Point(), HTCAPTION)); 526 ASSERT_TRUE(resizer.get()); 527 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0); 528 EXPECT_FALSE(event_filter->WarpMouseCursorIfNecessary( 529 root_windows[0], 530 gfx::Point(399, 200))); 531 resizer->CompleteDrag(0); 532 } 533 534 // The parent of transient window can be moved across display. 535 { 536 aura::Window* window = transient_parent_.get(); 537 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), 538 Shell::GetScreen()->GetPrimaryDisplay()); 539 // Grab (0, 0) of the window. 540 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 541 window, gfx::Point(), HTCAPTION)); 542 ASSERT_TRUE(resizer.get()); 543 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0); 544 EXPECT_TRUE(event_filter->WarpMouseCursorIfNecessary(root_windows[0], 545 gfx::Point(399, 200))); 546 resizer->CompleteDrag(0); 547 } 548 549 // Panel window can be moved across display. 550 { 551 aura::Window* window = panel_window_.get(); 552 window->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60), 553 Shell::GetScreen()->GetPrimaryDisplay()); 554 // Grab (0, 0) of the window. 555 scoped_ptr<WindowResizer> resizer(CreateDragWindowResizer( 556 window, gfx::Point(), HTCAPTION)); 557 ASSERT_TRUE(resizer.get()); 558 resizer->Drag(CalculateDragPoint(*resizer, 399, 200), 0); 559 EXPECT_TRUE(event_filter->WarpMouseCursorIfNecessary(root_windows[0], 560 gfx::Point(399, 200))); 561 resizer->CompleteDrag(0); 562 } 563 } 564 565 } // namespace internal 566 } // namespace ash 567