15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef ASH_DISPLAY_MOUSE_CURSOR_EVENT_FILTER_H
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ASH_DISPLAY_MOUSE_CURSOR_EVENT_FILTER_H
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/ash_export.h"
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ash/display/display_controller.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_handler.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace aura {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RootWindow;
181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class Window;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SharedDisplayEdgeIndicator;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An event filter that controls mouse location in extended desktop
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// environment.
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class ASH_EXPORT MouseCursorEventFilter : public ui::EventHandler,
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                          public DisplayController::Observer {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum MouseWarpMode {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WARP_ALWAYS,   // Always warp the mouse when possible.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WARP_DRAG,     // Used when dragging a window. Top and bottom
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   // corner of the shared edge is reserved for window
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   // snapping.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WARP_NONE,     // No mouse warping. Used when resizing the window.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MouseCursorEventFilter();
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MouseCursorEventFilter();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_mouse_warp_mode(MouseWarpMode mouse_warp_mode) {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mouse_warp_mode_ = mouse_warp_mode;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shows/Hide the indicator for window dragging. The |from|
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is the window where the dragging started.
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void ShowSharedEdgeIndicator(aura::Window* from);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HideSharedEdgeIndicator();
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // DisplayController::Observer:
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnDisplaysInitialized() OVERRIDE;
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnDisplayConfigurationChanged() OVERRIDE;
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // ui::EventHandler:
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  friend class DragWindowResizerTest;
58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  friend class MouseCursorEventFilterTest;
59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest, DoNotWarpTwice);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest, SetMouseWarpModeFlag);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           IndicatorBoundsTestOnRight);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           IndicatorBoundsTestOnLeft);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           IndicatorBoundsTestOnTopBottom);
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(MouseCursorEventFilterTest,
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                           WarpMouseDifferentScaleDisplaysInNative);
69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(DragWindowResizerTest, WarpMousePointer);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Moves the cursor to the point inside the root that is closest to
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // the point_in_screen, which is outside of the root window.
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static void MoveCursorTo(aura::Window* root,
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           const gfx::Point& point_in_screen);
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Warps the mouse cursor to an alternate root window when the
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // mouse location in |event|, hits the edge of the event target's root and
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // the mouse cursor is considered to be in an alternate display.
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns true if/ the cursor was moved.
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool WarpMouseCursorIfNecessary(ui::MouseEvent* event);
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool WarpMouseCursorInNativeCoords(const gfx::Point& point_in_native,
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                     const gfx::Point& point_in_screen);
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Update the edge/indicator bounds based on the current
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // display configuration.
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void UpdateHorizontalEdgeBounds();
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void UpdateVerticalEdgeBounds();
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Returns the source and destination window. When the
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // mouse_warp_mode_ is WARP_DRAG, src_window is the root window
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // where the drag starts. When the mouse_warp_mode_ is WARP_ALWAYS,
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // the src_window is always the primary root window, because there
95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // is no difference between moving src to dst and moving dst to src.
96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void GetSrcAndDstRootWindows(aura::Window** src_window,
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                               aura::Window** dst_window);
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void reset_was_mouse_warped_for_test() { was_mouse_warped_ = false; }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool WarpMouseCursorIfNecessaryForTest(aura::Window* target_root,
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                         const gfx::Point& point_in_screen);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MouseWarpMode mouse_warp_mode_;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // This flag is used to suppress the accidental mouse warp back to the
107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // original display.
108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool was_mouse_warped_;
109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The bounds for warp hole windows. |dst_indicator_bounds_| is kept
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the instance for testing.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect src_indicator_bounds_;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect dst_indicator_bounds_;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  gfx::Rect src_edge_bounds_in_native_;
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  gfx::Rect dst_edge_bounds_in_native_;
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The root window in which the dragging started.
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  aura::Window* drag_source_root_;
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  float scale_when_drag_started_;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shows the area where a window can be dragged in to/out from
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // another display.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SharedDisplayEdgeIndicator> shared_display_edge_indicator_;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MouseCursorEventFilter);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // ASH_DISPLAY_MOUSE_CURSOR_EVENT_FILTER_H
133