Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / ash / display / mouse_cursor_event_filter_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/display/mouse_cursor_event_filter.h"
6
7 #include "ash/shell.h"
8 #include "ash/test/ash_test_base.h"
9 #include "ash/test/cursor_manager_test_api.h"
10 #include "ash/display/display_layout_store.h"
11 #include "ash/display/display_manager.h"
12 #include "ui/aura/env.h"
13 #include "ui/aura/window_event_dispatcher.h"
14 #include "ui/gfx/display.h"
15 #include "ui/gfx/screen.h"
16
17 namespace ash {
18
19 class MouseCursorEventFilterTest : public test::AshTestBase {
20  public:
21   MouseCursorEventFilterTest() {}
22   ~MouseCursorEventFilterTest() override {}
23
24  protected:
25   MouseCursorEventFilter* event_filter() {
26     return Shell::GetInstance()->mouse_cursor_filter();
27   }
28
29   bool WarpMouseCursorIfNecessary(aura::Window* target_root,
30                                   gfx::Point point_in_screen) {
31     bool is_warped = event_filter()->WarpMouseCursorIfNecessaryForTest(
32         target_root, point_in_screen);
33     event_filter()->reset_was_mouse_warped_for_test();
34     return is_warped;
35   }
36
37   bool WarpMouseCursorIfNecessaryWithDragRoot(
38       aura::Window* drag_source_root,
39       aura::Window* target_root,
40       gfx::Point point_in_screen) {
41     gfx::Point location = drag_source_root->bounds().CenterPoint();
42     ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, location,
43                            location, 0, 0);
44     ui::Event::DispatcherApi(&pressed).set_target(drag_source_root);
45     event_filter()->OnMouseEvent(&pressed);
46     bool is_warped = event_filter()->WarpMouseCursorIfNecessaryForTest(
47         target_root, point_in_screen);
48     event_filter()->reset_was_mouse_warped_for_test();
49
50     ui::MouseEvent released(ui::ET_MOUSE_RELEASED, location,
51                             location, 0, 0);
52     ui::Event::DispatcherApi(&released).set_target(drag_source_root);
53     event_filter()->OnMouseEvent(&released);
54     return is_warped;
55   }
56
57  private:
58   MouseCursorEventFilter* event_filter_;
59
60   DISALLOW_COPY_AND_ASSIGN(MouseCursorEventFilterTest);
61 };
62
63 // Verifies if the mouse pointer correctly moves to another display when there
64 // are two displays.
65 TEST_F(MouseCursorEventFilterTest, WarpMouse) {
66   if (!SupportsMultipleDisplays())
67     return;
68
69   UpdateDisplay("500x500,500x500");
70
71   ASSERT_EQ(
72       DisplayLayout::RIGHT,
73       Shell::GetInstance()->display_manager()->layout_store()->
74           default_display_layout().position);
75
76   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
77   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(11, 11)));
78   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(11, 11)));
79
80   // Touch the right edge of the primary root window. Pointer should warp.
81   EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(499, 11)));
82   EXPECT_EQ("501,11",  // by 2px.
83             aura::Env::GetInstance()->last_mouse_location().ToString());
84
85   // Touch the left edge of the secondary root window. Pointer should warp.
86   EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(500, 11)));
87   EXPECT_EQ("498,11",  // by 2px.
88             aura::Env::GetInstance()->last_mouse_location().ToString());
89
90   // Touch the left edge of the primary root window.
91   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(0, 11)));
92   // Touch the top edge of the primary root window.
93   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(11, 0)));
94   // Touch the bottom edge of the primary root window.
95   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0],
96                                           gfx::Point(11, 499)));
97   // Touch the right edge of the secondary root window.
98   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1],
99                                           gfx::Point(999, 11)));
100   // Touch the top edge of the secondary root window.
101   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(11, 0)));
102   // Touch the bottom edge of the secondary root window.
103   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1],
104                                           gfx::Point(11, 499)));
105 }
106
107 // Verifies if the mouse pointer correctly moves to another display even when
108 // two displays are not the same size.
109 TEST_F(MouseCursorEventFilterTest, WarpMouseDifferentSizeDisplays) {
110   if (!SupportsMultipleDisplays())
111     return;
112
113   UpdateDisplay("500x500,600x600");  // the second one is larger.
114
115   ASSERT_EQ(
116       DisplayLayout::RIGHT,
117       Shell::GetInstance()->display_manager()->
118           GetCurrentDisplayLayout().position);
119
120   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
121   aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(623, 123));
122
123   // Touch the left edge of the secondary root window. Pointer should NOT warp
124   // because 1px left of (0, 500) is outside the primary root window.
125   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(0, 500)));
126   EXPECT_EQ("623,123",  // by 2px.
127             aura::Env::GetInstance()->last_mouse_location().ToString());
128
129   // Touch the left edge of the secondary root window. Pointer should warp
130   // because 1px left of (0, 480) is inside the primary root window.
131   EXPECT_TRUE(
132       WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(500, 480)));
133   EXPECT_EQ("498,480",  // by 2px.
134             aura::Env::GetInstance()->last_mouse_location().ToString());
135 }
136
137 // Verifies if the mouse pointer correctly moves between displays with
138 // different scale factors. In native coords mode, there is no
139 // difference between drag and move.
140 TEST_F(MouseCursorEventFilterTest, WarpMouseDifferentScaleDisplaysInNative) {
141   if (!SupportsMultipleDisplays())
142     return;
143
144   UpdateDisplay("500x500,600x600*2");
145
146   ASSERT_EQ(DisplayLayout::RIGHT,
147             Shell::GetInstance()
148                 ->display_manager()
149                 ->GetCurrentDisplayLayout()
150                 .position);
151
152   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
153   aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(900, 123));
154
155   EXPECT_TRUE(event_filter()->WarpMouseCursorIfNecessaryForTest(
156       root_windows[0], gfx::Point(499, 123)));
157   EXPECT_EQ("500,123",
158             aura::Env::GetInstance()->last_mouse_location().ToString());
159
160   event_filter()->reset_was_mouse_warped_for_test();
161
162   // Touch the edge of 2nd display again and make sure it warps to
163   // 1st dislay.
164   EXPECT_TRUE(event_filter()->WarpMouseCursorIfNecessaryForTest(
165       root_windows[1], gfx::Point(500, 123)));
166   EXPECT_EQ("498,123",
167             aura::Env::GetInstance()->last_mouse_location().ToString());
168 }
169
170 // Verifies if MouseCursorEventFilter::set_mouse_warp_mode() works as expected.
171 TEST_F(MouseCursorEventFilterTest, SetMouseWarpModeFlag) {
172   if (!SupportsMultipleDisplays())
173     return;
174
175   UpdateDisplay("500x500,500x500");
176
177   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
178   aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(1, 1));
179
180   event_filter()->set_mouse_warp_mode(MouseCursorEventFilter::WARP_NONE);
181   EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0],
182                                           gfx::Point(499, 11)));
183   EXPECT_EQ("1,1",
184             aura::Env::GetInstance()->last_mouse_location().ToString());
185
186   event_filter()->set_mouse_warp_mode(MouseCursorEventFilter::WARP_ALWAYS);
187   EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(499, 11)));
188   EXPECT_EQ("501,11",
189             aura::Env::GetInstance()->last_mouse_location().ToString());
190 }
191
192 // Verifies if MouseCursorEventFilter's bounds calculation works correctly.
193 TEST_F(MouseCursorEventFilterTest, IndicatorBoundsTestOnRight) {
194   if (!SupportsMultipleDisplays())
195     return;
196
197   UpdateDisplay("360x360,700x700");
198   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
199
200   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
201   DisplayLayout layout(DisplayLayout::RIGHT, 0);
202   display_manager->SetLayoutForCurrentDisplays(layout);
203   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
204   EXPECT_EQ("359,16 1x344", event_filter()->src_indicator_bounds_.ToString());
205   EXPECT_EQ("360,0 1x360", event_filter()->dst_indicator_bounds_.ToString());
206   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
207   EXPECT_EQ("360,16 1x344", event_filter()->src_indicator_bounds_.ToString());
208   EXPECT_EQ("359,0 1x360", event_filter()->dst_indicator_bounds_.ToString());
209
210   // Move 2nd display downwards a bit.
211   layout.offset = 5;
212   display_manager->SetLayoutForCurrentDisplays(layout);
213   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
214   // This is same as before because the 2nd display's y is above
215   // the indicator's x.
216   EXPECT_EQ("359,16 1x344", event_filter()->src_indicator_bounds_.ToString());
217   EXPECT_EQ("360,5 1x355", event_filter()->dst_indicator_bounds_.ToString());
218   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
219   EXPECT_EQ("360,21 1x339", event_filter()->src_indicator_bounds_.ToString());
220   EXPECT_EQ("359,5 1x355", event_filter()->dst_indicator_bounds_.ToString());
221
222   // Move it down further so that the shared edge is shorter than
223   // minimum hole size (160).
224   layout.offset = 200;
225   display_manager->SetLayoutForCurrentDisplays(layout);
226   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
227   EXPECT_EQ("359,200 1x160", event_filter()->src_indicator_bounds_.ToString());
228   EXPECT_EQ("360,200 1x160", event_filter()->dst_indicator_bounds_.ToString());
229   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
230   EXPECT_EQ("360,200 1x160", event_filter()->src_indicator_bounds_.ToString());
231   EXPECT_EQ("359,200 1x160", event_filter()->dst_indicator_bounds_.ToString());
232
233   // Now move 2nd display upwards
234   layout.offset = -5;
235   display_manager->SetLayoutForCurrentDisplays(layout);
236   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
237   EXPECT_EQ("359,16 1x344", event_filter()->src_indicator_bounds_.ToString());
238   EXPECT_EQ("360,0 1x360", event_filter()->dst_indicator_bounds_.ToString());
239   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
240   // 16 px are reserved on 2nd display from top, so y must be
241   // (16 - 5) = 11
242   EXPECT_EQ("360,11 1x349", event_filter()->src_indicator_bounds_.ToString());
243   EXPECT_EQ("359,0 1x360", event_filter()->dst_indicator_bounds_.ToString());
244
245   event_filter()->HideSharedEdgeIndicator();
246 }
247
248 TEST_F(MouseCursorEventFilterTest, IndicatorBoundsTestOnLeft) {
249   if (!SupportsMultipleDisplays())
250     return;
251
252   UpdateDisplay("360x360,700x700");
253   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
254
255   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
256   DisplayLayout layout(DisplayLayout::LEFT, 0);
257   display_manager->SetLayoutForCurrentDisplays(layout);
258   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
259   EXPECT_EQ("0,16 1x344", event_filter()->src_indicator_bounds_.ToString());
260   EXPECT_EQ("-1,0 1x360", event_filter()->dst_indicator_bounds_.ToString());
261   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
262   EXPECT_EQ("-1,16 1x344", event_filter()->src_indicator_bounds_.ToString());
263   EXPECT_EQ("0,0 1x360", event_filter()->dst_indicator_bounds_.ToString());
264
265   layout.offset = 250;
266   display_manager->SetLayoutForCurrentDisplays(layout);
267   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
268   EXPECT_EQ("0,250 1x110", event_filter()->src_indicator_bounds_.ToString());
269   EXPECT_EQ("-1,250 1x110", event_filter()->dst_indicator_bounds_.ToString());
270   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
271   EXPECT_EQ("-1,250 1x110", event_filter()->src_indicator_bounds_.ToString());
272   EXPECT_EQ("0,250 1x110", event_filter()->dst_indicator_bounds_.ToString());
273   event_filter()->HideSharedEdgeIndicator();
274 }
275
276 TEST_F(MouseCursorEventFilterTest, IndicatorBoundsTestOnTopBottom) {
277   if (!SupportsMultipleDisplays())
278     return;
279
280   UpdateDisplay("360x360,700x700");
281   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
282
283   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
284   DisplayLayout layout(DisplayLayout::TOP, 0);
285   display_manager->SetLayoutForCurrentDisplays(layout);
286   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
287   EXPECT_EQ("0,0 360x1", event_filter()->src_indicator_bounds_.ToString());
288   EXPECT_EQ("0,-1 360x1", event_filter()->dst_indicator_bounds_.ToString());
289   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
290   EXPECT_EQ("0,-1 360x1", event_filter()->src_indicator_bounds_.ToString());
291   EXPECT_EQ("0,0 360x1", event_filter()->dst_indicator_bounds_.ToString());
292
293   layout.offset = 250;
294   display_manager->SetLayoutForCurrentDisplays(layout);
295   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
296   EXPECT_EQ("250,0 110x1", event_filter()->src_indicator_bounds_.ToString());
297   EXPECT_EQ("250,-1 110x1", event_filter()->dst_indicator_bounds_.ToString());
298   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
299   EXPECT_EQ("250,-1 110x1", event_filter()->src_indicator_bounds_.ToString());
300   EXPECT_EQ("250,0 110x1", event_filter()->dst_indicator_bounds_.ToString());
301
302   layout.position = DisplayLayout::BOTTOM;
303   layout.offset = 0;
304   display_manager->SetLayoutForCurrentDisplays(layout);
305   event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */);
306   EXPECT_EQ("0,359 360x1", event_filter()->src_indicator_bounds_.ToString());
307   EXPECT_EQ("0,360 360x1", event_filter()->dst_indicator_bounds_.ToString());
308   event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */);
309   EXPECT_EQ("0,360 360x1", event_filter()->src_indicator_bounds_.ToString());
310   EXPECT_EQ("0,359 360x1", event_filter()->dst_indicator_bounds_.ToString());
311
312   event_filter()->HideSharedEdgeIndicator();
313 }
314
315 // Verifies cursor's device scale factor is updated when a cursor has moved
316 // across root windows with different device scale factors
317 // (http://crbug.com/154183).
318 TEST_F(MouseCursorEventFilterTest, CursorDeviceScaleFactor) {
319   if (!SupportsMultipleDisplays())
320     return;
321
322   UpdateDisplay("400x400,800x800*2");
323   DisplayManager* display_manager = Shell::GetInstance()->display_manager();
324   display_manager->SetLayoutForCurrentDisplays(
325       DisplayLayout(DisplayLayout::RIGHT, 0));
326   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
327   ASSERT_EQ(2U, root_windows.size());
328   test::CursorManagerTestApi cursor_test_api(
329       Shell::GetInstance()->cursor_manager());
330
331   EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
332   WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(399, 200));
333   EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
334   WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(400, 200));
335   EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
336 }
337
338 }  // namespace ash