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