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