mouse_cursor_event_filter_unittest.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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 17namespace ash { 18 19class MouseCursorEventFilterTest : public test::AshTestBase { 20 public: 21 MouseCursorEventFilterTest() {} 22 virtual ~MouseCursorEventFilterTest() {} 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()->WarpMouseCursorIfNecessary( 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()->WarpMouseCursorIfNecessary( 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. 65TEST_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. 109TEST_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, 499) is inside the primary root window. 131 EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[1], 132 gfx::Point(500, 499))); 133 EXPECT_EQ("498,499", // 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. 139TEST_F(MouseCursorEventFilterTest, WarpMouseDifferentScaleDisplays) { 140 if (!SupportsMultipleDisplays()) 141 return; 142 143 UpdateDisplay("500x500,600x600*2"); 144 145 ASSERT_EQ( 146 DisplayLayout::RIGHT, 147 Shell::GetInstance()->display_manager()-> 148 GetCurrentDisplayLayout().position); 149 150 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 151 aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(900, 123)); 152 153 // This emulates the dragging to the 2nd display, which has 154 // higher scale factor, by having 2nd display's root as target 155 // but have the edge of 1st display. 156 EXPECT_TRUE(WarpMouseCursorIfNecessaryWithDragRoot( 157 root_windows[1], root_windows[1], gfx::Point(498, 123))); 158 EXPECT_EQ("502,123", 159 aura::Env::GetInstance()->last_mouse_location().ToString()); 160 161 // Touch the edge of 2nd display again and make sure it warps to 162 // 1st dislay. 163 EXPECT_TRUE(WarpMouseCursorIfNecessaryWithDragRoot( 164 root_windows[1], root_windows[1], gfx::Point(500, 123))); 165 EXPECT_EQ("496,123", 166 aura::Env::GetInstance()->last_mouse_location().ToString()); 167 168 // Draging back from 1x to 2x. 169 EXPECT_TRUE(WarpMouseCursorIfNecessaryWithDragRoot( 170 root_windows[1], root_windows[0], gfx::Point(500, 123))); 171 EXPECT_EQ("496,123", 172 aura::Env::GetInstance()->last_mouse_location().ToString()); 173 174 UpdateDisplay("500x500*2,600x600"); 175 // Draging back from 1x to 2x. 176 EXPECT_TRUE(WarpMouseCursorIfNecessaryWithDragRoot( 177 root_windows[0], root_windows[1], gfx::Point(250, 123))); 178 EXPECT_EQ("246,123", 179 aura::Env::GetInstance()->last_mouse_location().ToString()); 180} 181 182TEST_F(MouseCursorEventFilterTest, DoNotWarpTwice) { 183 if (!SupportsMultipleDisplays()) 184 return; 185 186 UpdateDisplay("500x500,600x600"); 187 188 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 189 aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(623, 123)); 190 191 // Touch the right edge of the primary root window. Pointer should warp. 192 EXPECT_TRUE(event_filter()->WarpMouseCursorIfNecessary(root_windows[0], 193 gfx::Point(499, 11))); 194 EXPECT_EQ("501,11", // by 2px. 195 aura::Env::GetInstance()->last_mouse_location().ToString()); 196 197 // Touch the left edge of the secondary root window immediately. This should 198 // be ignored. 199 EXPECT_FALSE(event_filter()->WarpMouseCursorIfNecessary(root_windows[1], 200 gfx::Point(500, 11))); 201 202 // Touch the left edge of the secondary root window again, pointer should 203 // warp for this time. 204 EXPECT_TRUE(event_filter()->WarpMouseCursorIfNecessary(root_windows[1], 205 gfx::Point(500, 11))); 206 EXPECT_EQ("498,11", // by 2px. 207 aura::Env::GetInstance()->last_mouse_location().ToString()); 208} 209 210// Verifies if MouseCursorEventFilter::set_mouse_warp_mode() works as expected. 211TEST_F(MouseCursorEventFilterTest, SetMouseWarpModeFlag) { 212 if (!SupportsMultipleDisplays()) 213 return; 214 215 UpdateDisplay("500x500,500x500"); 216 217 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 218 aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(1, 1)); 219 220 event_filter()->set_mouse_warp_mode(MouseCursorEventFilter::WARP_NONE); 221 EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], 222 gfx::Point(499, 11))); 223 EXPECT_EQ("1,1", 224 aura::Env::GetInstance()->last_mouse_location().ToString()); 225 226 event_filter()->set_mouse_warp_mode(MouseCursorEventFilter::WARP_ALWAYS); 227 EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(499, 11))); 228 EXPECT_EQ("501,11", 229 aura::Env::GetInstance()->last_mouse_location().ToString()); 230} 231 232// Verifies if MouseCursorEventFilter's bounds calculation works correctly. 233TEST_F(MouseCursorEventFilterTest, IndicatorBoundsTestOnRight) { 234 if (!SupportsMultipleDisplays()) 235 return; 236 237 UpdateDisplay("360x360,700x700"); 238 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 239 240 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 241 DisplayLayout layout(DisplayLayout::RIGHT, 0); 242 display_manager->SetLayoutForCurrentDisplays(layout); 243 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); 244 EXPECT_EQ("359,16 1x344", event_filter()->src_indicator_bounds_.ToString()); 245 EXPECT_EQ("360,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); 246 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); 247 EXPECT_EQ("360,16 1x344", event_filter()->src_indicator_bounds_.ToString()); 248 EXPECT_EQ("359,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); 249 250 // Move 2nd display downwards a bit. 251 layout.offset = 5; 252 display_manager->SetLayoutForCurrentDisplays(layout); 253 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); 254 // This is same as before because the 2nd display's y is above 255 // the indicator's x. 256 EXPECT_EQ("359,16 1x344", event_filter()->src_indicator_bounds_.ToString()); 257 EXPECT_EQ("360,5 1x355", event_filter()->dst_indicator_bounds_.ToString()); 258 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); 259 EXPECT_EQ("360,21 1x339", event_filter()->src_indicator_bounds_.ToString()); 260 EXPECT_EQ("359,5 1x355", event_filter()->dst_indicator_bounds_.ToString()); 261 262 // Move it down further so that the shared edge is shorter than 263 // minimum hole size (160). 264 layout.offset = 200; 265 display_manager->SetLayoutForCurrentDisplays(layout); 266 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); 267 EXPECT_EQ("359,200 1x160", event_filter()->src_indicator_bounds_.ToString()); 268 EXPECT_EQ("360,200 1x160", event_filter()->dst_indicator_bounds_.ToString()); 269 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); 270 EXPECT_EQ("360,200 1x160", event_filter()->src_indicator_bounds_.ToString()); 271 EXPECT_EQ("359,200 1x160", event_filter()->dst_indicator_bounds_.ToString()); 272 273 // Now move 2nd display upwards 274 layout.offset = -5; 275 display_manager->SetLayoutForCurrentDisplays(layout); 276 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); 277 EXPECT_EQ("359,16 1x344", event_filter()->src_indicator_bounds_.ToString()); 278 EXPECT_EQ("360,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); 279 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); 280 // 16 px are reserved on 2nd display from top, so y must be 281 // (16 - 5) = 11 282 EXPECT_EQ("360,11 1x349", event_filter()->src_indicator_bounds_.ToString()); 283 EXPECT_EQ("359,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); 284 285 event_filter()->HideSharedEdgeIndicator(); 286} 287 288TEST_F(MouseCursorEventFilterTest, IndicatorBoundsTestOnLeft) { 289 if (!SupportsMultipleDisplays()) 290 return; 291 292 UpdateDisplay("360x360,700x700"); 293 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 294 295 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 296 DisplayLayout layout(DisplayLayout::LEFT, 0); 297 display_manager->SetLayoutForCurrentDisplays(layout); 298 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); 299 EXPECT_EQ("0,16 1x344", event_filter()->src_indicator_bounds_.ToString()); 300 EXPECT_EQ("-1,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); 301 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); 302 EXPECT_EQ("-1,16 1x344", event_filter()->src_indicator_bounds_.ToString()); 303 EXPECT_EQ("0,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); 304 305 layout.offset = 250; 306 display_manager->SetLayoutForCurrentDisplays(layout); 307 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); 308 EXPECT_EQ("0,250 1x110", event_filter()->src_indicator_bounds_.ToString()); 309 EXPECT_EQ("-1,250 1x110", event_filter()->dst_indicator_bounds_.ToString()); 310 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); 311 EXPECT_EQ("-1,250 1x110", event_filter()->src_indicator_bounds_.ToString()); 312 EXPECT_EQ("0,250 1x110", event_filter()->dst_indicator_bounds_.ToString()); 313 event_filter()->HideSharedEdgeIndicator(); 314} 315 316TEST_F(MouseCursorEventFilterTest, IndicatorBoundsTestOnTopBottom) { 317 if (!SupportsMultipleDisplays()) 318 return; 319 320 UpdateDisplay("360x360,700x700"); 321 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 322 323 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 324 DisplayLayout layout(DisplayLayout::TOP, 0); 325 display_manager->SetLayoutForCurrentDisplays(layout); 326 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); 327 EXPECT_EQ("0,0 360x1", event_filter()->src_indicator_bounds_.ToString()); 328 EXPECT_EQ("0,-1 360x1", event_filter()->dst_indicator_bounds_.ToString()); 329 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); 330 EXPECT_EQ("0,-1 360x1", event_filter()->src_indicator_bounds_.ToString()); 331 EXPECT_EQ("0,0 360x1", event_filter()->dst_indicator_bounds_.ToString()); 332 333 layout.offset = 250; 334 display_manager->SetLayoutForCurrentDisplays(layout); 335 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); 336 EXPECT_EQ("250,0 110x1", event_filter()->src_indicator_bounds_.ToString()); 337 EXPECT_EQ("250,-1 110x1", event_filter()->dst_indicator_bounds_.ToString()); 338 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); 339 EXPECT_EQ("250,-1 110x1", event_filter()->src_indicator_bounds_.ToString()); 340 EXPECT_EQ("250,0 110x1", event_filter()->dst_indicator_bounds_.ToString()); 341 342 layout.position = DisplayLayout::BOTTOM; 343 layout.offset = 0; 344 display_manager->SetLayoutForCurrentDisplays(layout); 345 event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); 346 EXPECT_EQ("0,359 360x1", event_filter()->src_indicator_bounds_.ToString()); 347 EXPECT_EQ("0,360 360x1", event_filter()->dst_indicator_bounds_.ToString()); 348 event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); 349 EXPECT_EQ("0,360 360x1", event_filter()->src_indicator_bounds_.ToString()); 350 EXPECT_EQ("0,359 360x1", event_filter()->dst_indicator_bounds_.ToString()); 351 352 event_filter()->HideSharedEdgeIndicator(); 353} 354 355// Verifies cursor's device scale factor is updated when a cursor has moved 356// across root windows with different device scale factors 357// (http://crbug.com/154183). 358TEST_F(MouseCursorEventFilterTest, CursorDeviceScaleFactor) { 359 if (!SupportsMultipleDisplays()) 360 return; 361 362 UpdateDisplay("400x400,800x800*2"); 363 DisplayManager* display_manager = Shell::GetInstance()->display_manager(); 364 display_manager->SetLayoutForCurrentDisplays( 365 DisplayLayout(DisplayLayout::RIGHT, 0)); 366 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 367 ASSERT_EQ(2U, root_windows.size()); 368 test::CursorManagerTestApi cursor_test_api( 369 Shell::GetInstance()->cursor_manager()); 370 371 EXPECT_EQ(1.0f, cursor_test_api.GetDisplay().device_scale_factor()); 372 WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(399, 200)); 373 EXPECT_EQ(2.0f, cursor_test_api.GetDisplay().device_scale_factor()); 374 WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(400, 200)); 375 EXPECT_EQ(1.0f, cursor_test_api.GetDisplay().device_scale_factor()); 376} 377 378} // namespace ash 379