Home | History | Annotate | Download | only in wm
      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