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 #ifndef ASH_DISPLAY_MOUSE_CURSOR_EVENT_FILTER_H 6 #define ASH_DISPLAY_MOUSE_CURSOR_EVENT_FILTER_H 7 8 #include "ash/ash_export.h" 9 #include "ash/display/display_controller.h" 10 #include "base/compiler_specific.h" 11 #include "base/gtest_prod_util.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "ui/events/event_handler.h" 14 #include "ui/gfx/rect.h" 15 16 namespace aura { 17 class RootWindow; 18 class Window; 19 } 20 21 namespace ash { 22 class SharedDisplayEdgeIndicator; 23 24 // An event filter that controls mouse location in extended desktop 25 // environment. 26 class ASH_EXPORT MouseCursorEventFilter : public ui::EventHandler, 27 public DisplayController::Observer { 28 public: 29 enum MouseWarpMode { 30 WARP_ALWAYS, // Always warp the mouse when possible. 31 WARP_DRAG, // Used when dragging a window. Top and bottom 32 // corner of the shared edge is reserved for window 33 // snapping. 34 WARP_NONE, // No mouse warping. Used when resizing the window. 35 }; 36 37 MouseCursorEventFilter(); 38 virtual ~MouseCursorEventFilter(); 39 40 void set_mouse_warp_mode(MouseWarpMode mouse_warp_mode) { 41 mouse_warp_mode_ = mouse_warp_mode; 42 } 43 44 // Shows/Hide the indicator for window dragging. The |from| 45 // is the window where the dragging started. 46 void ShowSharedEdgeIndicator(aura::Window* from); 47 void HideSharedEdgeIndicator(); 48 49 // DisplayController::Observer: 50 virtual void OnDisplaysInitialized() OVERRIDE; 51 virtual void OnDisplayConfigurationChanged() OVERRIDE; 52 53 // ui::EventHandler: 54 virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE; 55 56 private: 57 friend class DragWindowResizerTest; 58 friend class MouseCursorEventFilterTest; 59 FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest, DoNotWarpTwice); 60 FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest, SetMouseWarpModeFlag); 61 FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest, 62 IndicatorBoundsTestOnRight); 63 FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest, 64 IndicatorBoundsTestOnLeft); 65 FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest, 66 IndicatorBoundsTestOnTopBottom); 67 FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest, 68 WarpMouseDifferentScaleDisplaysInNative); 69 70 FRIEND_TEST_ALL_PREFIXES(DragWindowResizerTest, WarpMousePointer); 71 72 // Moves the cursor to the point inside the root that is closest to 73 // the point_in_screen, which is outside of the root window. 74 static void MoveCursorTo(aura::Window* root, 75 const gfx::Point& point_in_screen); 76 77 // Warps the mouse cursor to an alternate root window when the 78 // mouse location in |event|, hits the edge of the event target's root and 79 // the mouse cursor is considered to be in an alternate display. 80 // Returns true if/ the cursor was moved. 81 bool WarpMouseCursorIfNecessary(ui::MouseEvent* event); 82 83 bool WarpMouseCursorInNativeCoords(const gfx::Point& point_in_native, 84 const gfx::Point& point_in_screen); 85 86 // Update the edge/indicator bounds based on the current 87 // display configuration. 88 void UpdateHorizontalEdgeBounds(); 89 void UpdateVerticalEdgeBounds(); 90 91 // Returns the source and destination window. When the 92 // mouse_warp_mode_ is WARP_DRAG, src_window is the root window 93 // where the drag starts. When the mouse_warp_mode_ is WARP_ALWAYS, 94 // the src_window is always the primary root window, because there 95 // is no difference between moving src to dst and moving dst to src. 96 void GetSrcAndDstRootWindows(aura::Window** src_window, 97 aura::Window** dst_window); 98 99 void reset_was_mouse_warped_for_test() { was_mouse_warped_ = false; } 100 101 bool WarpMouseCursorIfNecessaryForTest(aura::Window* target_root, 102 const gfx::Point& point_in_screen); 103 104 MouseWarpMode mouse_warp_mode_; 105 106 // This flag is used to suppress the accidental mouse warp back to the 107 // original display. 108 bool was_mouse_warped_; 109 110 // The bounds for warp hole windows. |dst_indicator_bounds_| is kept 111 // in the instance for testing. 112 gfx::Rect src_indicator_bounds_; 113 gfx::Rect dst_indicator_bounds_; 114 115 gfx::Rect src_edge_bounds_in_native_; 116 gfx::Rect dst_edge_bounds_in_native_; 117 118 // The root window in which the dragging started. 119 aura::Window* drag_source_root_; 120 121 float scale_when_drag_started_; 122 123 // Shows the area where a window can be dragged in to/out from 124 // another display. 125 scoped_ptr<SharedDisplayEdgeIndicator> shared_display_edge_indicator_; 126 127 DISALLOW_COPY_AND_ASSIGN(MouseCursorEventFilter); 128 }; 129 130 } // namespace ash 131 132 #endif // ASH_DISPLAY_MOUSE_CURSOR_EVENT_FILTER_H 133