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