diff options
Diffstat (limited to 'chromium/ash/display/mouse_cursor_event_filter_unittest.cc')
-rw-r--r-- | chromium/ash/display/mouse_cursor_event_filter_unittest.cc | 380 |
1 files changed, 380 insertions, 0 deletions
diff --git a/chromium/ash/display/mouse_cursor_event_filter_unittest.cc b/chromium/ash/display/mouse_cursor_event_filter_unittest.cc new file mode 100644 index 00000000000..7fa79fd6f3b --- /dev/null +++ b/chromium/ash/display/mouse_cursor_event_filter_unittest.cc @@ -0,0 +1,380 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/display/mouse_cursor_event_filter.h" + +#include "ash/shell.h" +#include "ash/test/ash_test_base.h" +#include "ash/test/cursor_manager_test_api.h" +#include "ash/display/display_layout_store.h" +#include "ash/display/display_manager.h" +#include "ui/aura/env.h" +#include "ui/aura/root_window.h" +#include "ui/gfx/display.h" +#include "ui/gfx/screen.h" + +namespace ash { +namespace internal { + +class MouseCursorEventFilterTest : public test::AshTestBase { + public: + MouseCursorEventFilterTest() {} + virtual ~MouseCursorEventFilterTest() {} + + protected: + MouseCursorEventFilter* event_filter() { + return Shell::GetInstance()->mouse_cursor_filter(); + } + + bool WarpMouseCursorIfNecessary(aura::Window* target_root, + gfx::Point point_in_screen) { + bool is_warped = event_filter()->WarpMouseCursorIfNecessary( + target_root, point_in_screen); + event_filter()->reset_was_mouse_warped_for_test(); + return is_warped; + } + + bool WarpMouseCursorIfNecessaryWithDragRoot( + aura::Window* drag_source_root, + aura::Window* target_root, + gfx::Point point_in_screen) { + gfx::Point location = drag_source_root->bounds().CenterPoint(); + ui::MouseEvent pressed(ui::ET_MOUSE_PRESSED, location, + location, 0); + ui::Event::DispatcherApi(&pressed).set_target(drag_source_root); + event_filter()->OnMouseEvent(&pressed); + bool is_warped = event_filter()->WarpMouseCursorIfNecessary( + target_root, point_in_screen); + event_filter()->reset_was_mouse_warped_for_test(); + + ui::MouseEvent released(ui::ET_MOUSE_RELEASED, location, + location, 0); + ui::Event::DispatcherApi(&released).set_target(drag_source_root); + event_filter()->OnMouseEvent(&released); + return is_warped; + } + + private: + MouseCursorEventFilter* event_filter_; + + DISALLOW_COPY_AND_ASSIGN(MouseCursorEventFilterTest); +}; + +// Verifies if the mouse pointer correctly moves to another display when there +// are two displays. +TEST_F(MouseCursorEventFilterTest, WarpMouse) { + if (!SupportsMultipleDisplays()) + return; + + UpdateDisplay("500x500,500x500"); + + ASSERT_EQ( + DisplayLayout::RIGHT, + Shell::GetInstance()->display_manager()->layout_store()-> + default_display_layout().position); + + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(11, 11))); + EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(11, 11))); + + // Touch the right edge of the primary root window. Pointer should warp. + EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(499, 11))); + EXPECT_EQ("501,11", // by 2px. + aura::Env::GetInstance()->last_mouse_location().ToString()); + + // Touch the left edge of the secondary root window. Pointer should warp. + EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(500, 11))); + EXPECT_EQ("498,11", // by 2px. + aura::Env::GetInstance()->last_mouse_location().ToString()); + + // Touch the left edge of the primary root window. + EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(0, 11))); + // Touch the top edge of the primary root window. + EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(11, 0))); + // Touch the bottom edge of the primary root window. + EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], + gfx::Point(11, 499))); + // Touch the right edge of the secondary root window. + EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1], + gfx::Point(999, 11))); + // Touch the top edge of the secondary root window. + EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(11, 0))); + // Touch the bottom edge of the secondary root window. + EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1], + gfx::Point(11, 499))); +} + +// Verifies if the mouse pointer correctly moves to another display even when +// two displays are not the same size. +TEST_F(MouseCursorEventFilterTest, WarpMouseDifferentSizeDisplays) { + if (!SupportsMultipleDisplays()) + return; + + UpdateDisplay("500x500,600x600"); // the second one is larger. + + ASSERT_EQ( + DisplayLayout::RIGHT, + Shell::GetInstance()->display_manager()-> + GetCurrentDisplayLayout().position); + + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(623, 123)); + + // Touch the left edge of the secondary root window. Pointer should NOT warp + // because 1px left of (0, 500) is outside the primary root window. + EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(0, 500))); + EXPECT_EQ("623,123", // by 2px. + aura::Env::GetInstance()->last_mouse_location().ToString()); + + // Touch the left edge of the secondary root window. Pointer should warp + // because 1px left of (0, 499) is inside the primary root window. + EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[1], + gfx::Point(500, 499))); + EXPECT_EQ("498,499", // by 2px. + aura::Env::GetInstance()->last_mouse_location().ToString()); +} + +// Verifies if the mouse pointer correctly moves between displays with +// different scale factors. +TEST_F(MouseCursorEventFilterTest, WarpMouseDifferentScaleDisplays) { + if (!SupportsMultipleDisplays()) + return; + + UpdateDisplay("500x500,600x600*2"); + + ASSERT_EQ( + DisplayLayout::RIGHT, + Shell::GetInstance()->display_manager()-> + GetCurrentDisplayLayout().position); + + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(900, 123)); + + // This emulates the dragging to the 2nd display, which has + // higher scale factor, by having 2nd display's root as target + // but have the edge of 1st display. + EXPECT_TRUE(WarpMouseCursorIfNecessaryWithDragRoot( + root_windows[1], root_windows[1], gfx::Point(498, 123))); + EXPECT_EQ("502,123", + aura::Env::GetInstance()->last_mouse_location().ToString()); + + // Touch the edge of 2nd display again and make sure it warps to + // 1st dislay. + EXPECT_TRUE(WarpMouseCursorIfNecessaryWithDragRoot( + root_windows[1], root_windows[1], gfx::Point(500, 123))); + EXPECT_EQ("496,123", + aura::Env::GetInstance()->last_mouse_location().ToString()); + + // Draging back from 1x to 2x. + EXPECT_TRUE(WarpMouseCursorIfNecessaryWithDragRoot( + root_windows[1], root_windows[0], gfx::Point(500, 123))); + EXPECT_EQ("496,123", + aura::Env::GetInstance()->last_mouse_location().ToString()); + + UpdateDisplay("500x500*2,600x600"); + // Draging back from 1x to 2x. + EXPECT_TRUE(WarpMouseCursorIfNecessaryWithDragRoot( + root_windows[0], root_windows[1], gfx::Point(250, 123))); + EXPECT_EQ("246,123", + aura::Env::GetInstance()->last_mouse_location().ToString()); +} + +TEST_F(MouseCursorEventFilterTest, DoNotWarpTwice) { + if (!SupportsMultipleDisplays()) + return; + + UpdateDisplay("500x500,600x600"); + + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(623, 123)); + + // Touch the right edge of the primary root window. Pointer should warp. + EXPECT_TRUE(event_filter()->WarpMouseCursorIfNecessary(root_windows[0], + gfx::Point(499, 11))); + EXPECT_EQ("501,11", // by 2px. + aura::Env::GetInstance()->last_mouse_location().ToString()); + + // Touch the left edge of the secondary root window immediately. This should + // be ignored. + EXPECT_FALSE(event_filter()->WarpMouseCursorIfNecessary(root_windows[1], + gfx::Point(500, 11))); + + // Touch the left edge of the secondary root window again, pointer should + // warp for this time. + EXPECT_TRUE(event_filter()->WarpMouseCursorIfNecessary(root_windows[1], + gfx::Point(500, 11))); + EXPECT_EQ("498,11", // by 2px. + aura::Env::GetInstance()->last_mouse_location().ToString()); +} + +// Verifies if MouseCursorEventFilter::set_mouse_warp_mode() works as expected. +TEST_F(MouseCursorEventFilterTest, SetMouseWarpModeFlag) { + if (!SupportsMultipleDisplays()) + return; + + UpdateDisplay("500x500,500x500"); + + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(1, 1)); + + event_filter()->set_mouse_warp_mode(MouseCursorEventFilter::WARP_NONE); + EXPECT_FALSE(WarpMouseCursorIfNecessary(root_windows[0], + gfx::Point(499, 11))); + EXPECT_EQ("1,1", + aura::Env::GetInstance()->last_mouse_location().ToString()); + + event_filter()->set_mouse_warp_mode(MouseCursorEventFilter::WARP_ALWAYS); + EXPECT_TRUE(WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(499, 11))); + EXPECT_EQ("501,11", + aura::Env::GetInstance()->last_mouse_location().ToString()); +} + +// Verifies if MouseCursorEventFilter's bounds calculation works correctly. +TEST_F(MouseCursorEventFilterTest, IndicatorBoundsTestOnRight) { + if (!SupportsMultipleDisplays()) + return; + + UpdateDisplay("360x360,700x700"); + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); + DisplayLayout layout(DisplayLayout::RIGHT, 0); + display_manager->SetLayoutForCurrentDisplays(layout); + event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); + EXPECT_EQ("359,16 1x344", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("360,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); + EXPECT_EQ("360,16 1x344", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("359,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); + + // Move 2nd display downwards a bit. + layout.offset = 5; + display_manager->SetLayoutForCurrentDisplays(layout); + event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); + // This is same as before because the 2nd display's y is above + // the indicator's x. + EXPECT_EQ("359,16 1x344", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("360,5 1x355", event_filter()->dst_indicator_bounds_.ToString()); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); + EXPECT_EQ("360,21 1x339", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("359,5 1x355", event_filter()->dst_indicator_bounds_.ToString()); + + // Move it down further so that the shared edge is shorter than + // minimum hole size (160). + layout.offset = 200; + display_manager->SetLayoutForCurrentDisplays(layout); + event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); + EXPECT_EQ("359,200 1x160", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("360,200 1x160", event_filter()->dst_indicator_bounds_.ToString()); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); + EXPECT_EQ("360,200 1x160", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("359,200 1x160", event_filter()->dst_indicator_bounds_.ToString()); + + // Now move 2nd display upwards + layout.offset = -5; + display_manager->SetLayoutForCurrentDisplays(layout); + event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); + EXPECT_EQ("359,16 1x344", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("360,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); + // 16 px are reserved on 2nd display from top, so y must be + // (16 - 5) = 11 + EXPECT_EQ("360,11 1x349", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("359,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); + + event_filter()->HideSharedEdgeIndicator(); +} + +TEST_F(MouseCursorEventFilterTest, IndicatorBoundsTestOnLeft) { + if (!SupportsMultipleDisplays()) + return; + + UpdateDisplay("360x360,700x700"); + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); + DisplayLayout layout(DisplayLayout::LEFT, 0); + display_manager->SetLayoutForCurrentDisplays(layout); + event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); + EXPECT_EQ("0,16 1x344", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("-1,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); + EXPECT_EQ("-1,16 1x344", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("0,0 1x360", event_filter()->dst_indicator_bounds_.ToString()); + + layout.offset = 250; + display_manager->SetLayoutForCurrentDisplays(layout); + event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); + EXPECT_EQ("0,250 1x110", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("-1,250 1x110", event_filter()->dst_indicator_bounds_.ToString()); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); + EXPECT_EQ("-1,250 1x110", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("0,250 1x110", event_filter()->dst_indicator_bounds_.ToString()); + event_filter()->HideSharedEdgeIndicator(); +} + +TEST_F(MouseCursorEventFilterTest, IndicatorBoundsTestOnTopBottom) { + if (!SupportsMultipleDisplays()) + return; + + UpdateDisplay("360x360,700x700"); + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); + DisplayLayout layout(DisplayLayout::TOP, 0); + display_manager->SetLayoutForCurrentDisplays(layout); + event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); + EXPECT_EQ("0,0 360x1", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("0,-1 360x1", event_filter()->dst_indicator_bounds_.ToString()); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); + EXPECT_EQ("0,-1 360x1", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("0,0 360x1", event_filter()->dst_indicator_bounds_.ToString()); + + layout.offset = 250; + display_manager->SetLayoutForCurrentDisplays(layout); + event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); + EXPECT_EQ("250,0 110x1", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("250,-1 110x1", event_filter()->dst_indicator_bounds_.ToString()); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); + EXPECT_EQ("250,-1 110x1", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("250,0 110x1", event_filter()->dst_indicator_bounds_.ToString()); + + layout.position = DisplayLayout::BOTTOM; + layout.offset = 0; + display_manager->SetLayoutForCurrentDisplays(layout); + event_filter()->ShowSharedEdgeIndicator(root_windows[0] /* primary */); + EXPECT_EQ("0,359 360x1", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("0,360 360x1", event_filter()->dst_indicator_bounds_.ToString()); + event_filter()->ShowSharedEdgeIndicator(root_windows[1] /* secondary */); + EXPECT_EQ("0,360 360x1", event_filter()->src_indicator_bounds_.ToString()); + EXPECT_EQ("0,359 360x1", event_filter()->dst_indicator_bounds_.ToString()); + + event_filter()->HideSharedEdgeIndicator(); +} + +// Verifies cursor's device scale factor is updated when a cursor has moved +// across root windows with different device scale factors +// (http://crbug.com/154183). +TEST_F(MouseCursorEventFilterTest, CursorDeviceScaleFactor) { + if (!SupportsMultipleDisplays()) + return; + + UpdateDisplay("400x400,800x800*2"); + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); + display_manager->SetLayoutForCurrentDisplays( + DisplayLayout(DisplayLayout::RIGHT, 0)); + aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + ASSERT_EQ(2U, root_windows.size()); + test::CursorManagerTestApi cursor_test_api( + Shell::GetInstance()->cursor_manager()); + + EXPECT_EQ(1.0f, cursor_test_api.GetDisplay().device_scale_factor()); + WarpMouseCursorIfNecessary(root_windows[0], gfx::Point(399, 200)); + EXPECT_EQ(2.0f, cursor_test_api.GetDisplay().device_scale_factor()); + WarpMouseCursorIfNecessary(root_windows[1], gfx::Point(400, 200)); + EXPECT_EQ(1.0f, cursor_test_api.GetDisplay().device_scale_factor()); +} + +} // namespace internal +} // namespace ash |