1 // Copyright 2015 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 COMPONENTS_EXO_POINTER_H_
6 #define COMPONENTS_EXO_POINTER_H_
7 
8 #include <memory>
9 
10 #include "base/macros.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/optional.h"
13 #include "base/unguessable_token.h"
14 #include "components/exo/surface_observer.h"
15 #include "components/exo/surface_tree_host.h"
16 #include "components/exo/wm_helper.h"
17 #include "third_party/skia/include/core/SkBitmap.h"
18 #include "ui/aura/client/cursor_client_observer.h"
19 #include "ui/aura/client/focus_change_observer.h"
20 #include "ui/base/cursor/cursor.h"
21 #include "ui/base/mojom/cursor_type.mojom-forward.h"
22 #include "ui/events/event_handler.h"
23 #include "ui/events/types/event_type.h"
24 #include "ui/gfx/geometry/point.h"
25 #include "ui/gfx/geometry/point_f.h"
26 #include "ui/gfx/native_widget_types.h"
27 
28 namespace viz {
29 class CopyOutputResult;
30 }
31 
32 namespace ui {
33 class LocatedEvent;
34 class MouseEvent;
35 }  // namespace ui
36 
37 namespace exo {
38 class PointerConstraintDelegate;
39 class PointerDelegate;
40 class PointerGesturePinchDelegate;
41 class RelativePointerDelegate;
42 class Seat;
43 class Surface;
44 class SurfaceTreeHost;
45 
46 // This class implements a client pointer that represents one or more input
47 // devices, such as mice, which control the pointer location and pointer focus.
48 class Pointer : public SurfaceTreeHost,
49                 public SurfaceObserver,
50                 public ui::EventHandler,
51                 public aura::client::CursorClientObserver,
52                 public aura::client::FocusChangeObserver {
53  public:
54   Pointer(PointerDelegate* delegate, Seat* seat);
55   ~Pointer() override;
56 
delegate()57   PointerDelegate* delegate() const { return delegate_; }
58 
59   // Set the pointer surface, i.e., the surface that contains the pointer image
60   // (cursor). The |hotspot| argument defines the position of the pointer
61   // surface relative to the pointer location. Its top-left corner is always at
62   // (x, y) - (hotspot.x, hotspot.y), where (x, y) are the coordinates of the
63   // pointer location, in surface local coordinates.
64   void SetCursor(Surface* surface, const gfx::Point& hotspot);
65 
66   // Set the pointer cursor type. This is similar to SetCursor, but this method
67   // accepts ui::mojom::CursorType instead of the surface for the pointer image.
68   void SetCursorType(ui::mojom::CursorType cursor_type);
69 
70   // Set delegate for pinch events.
71   void SetGesturePinchDelegate(PointerGesturePinchDelegate* delegate);
72 
73   // Overridden from SurfaceDelegate:
74   void OnSurfaceCommit() override;
75 
76   // Overridden from SurfaceObserver:
77   void OnSurfaceDestroying(Surface* surface) override;
78 
79   // Overridden from ui::EventHandler:
80   void OnMouseEvent(ui::MouseEvent* event) override;
81   void OnScrollEvent(ui::ScrollEvent* event) override;
82   void OnGestureEvent(ui::GestureEvent* event) override;
83 
84   // Overridden from aura::client::CursorClientObserver:
85   void OnCursorSizeChanged(ui::CursorSize cursor_size) override;
86   void OnCursorDisplayChanged(const display::Display& display) override;
87 
88   // Overridden from aura::client::FocusChangeObserver;
89   void OnWindowFocused(aura::Window* gained_focus,
90                        aura::Window* lost_focus) override;
91 
92   // Relative motion registration.
93   void RegisterRelativePointerDelegate(RelativePointerDelegate* delegate);
94   void UnregisterRelativePointerDelegate(RelativePointerDelegate* delegate);
95 
96   // Enable the pointer constraint on the given surface. Returns true if the
97   // lock was granted, false otherwise.
98   //
99   // TODO(crbug.com/957455): For legacy reasons, locking the pointer will also
100   // hide the cursor.
101   bool ConstrainPointer(PointerConstraintDelegate* delegate);
102 
103   // Disable the pointer constraint. This is designed to be called by the
104   // delegate, so it does not call OnConstraintBroken(), which should be done
105   // separately if the constraint was broken by something other than the
106   // delegate.
107   void UnconstrainPointer();
108 
109  private:
110   // Capture the pointer for the given surface. Returns true iff the capture
111   // succeeded.
112   bool EnablePointerCapture(Surface* capture_surface);
113 
114   // Remove the currently active pointer capture (if there is one).
115   void DisablePointerCapture();
116 
117   // Returns the effective target for |event|.
118   Surface* GetEffectiveTargetForEvent(ui::LocatedEvent* event) const;
119 
120   // Change pointer focus to |surface|.
121   void SetFocus(Surface* surface,
122                 const gfx::PointF& location,
123                 int button_flags);
124 
125   // Updates the root_surface in |SurfaceTreeHost| from which the cursor
126   // is captured.
127   void UpdatePointerSurface(Surface* surface);
128 
129   // Asynchronously update the cursor by capturing a snapshot of
130   // |SurfaceTreeHost::root_surface()|.
131   void CaptureCursor(const gfx::Point& hotspot);
132 
133   // Called when cursor snapshot has been captured.
134   void OnCursorCaptured(const gfx::Point& hotspot,
135                         std::unique_ptr<viz::CopyOutputResult> result);
136 
137   // Update |cursor_| to |cursor_bitmap_| transformed for the current display.
138   void UpdateCursor();
139 
140   // Convert the given |location_in_target| to coordinates in the root window.
141   gfx::PointF GetLocationInRoot(Surface* target,
142                                 gfx::PointF location_in_target);
143 
144   // Called to check if cursor should be moved to the center of the window when
145   // sending relative movements.
146   bool ShouldMoveToCenter();
147 
148   // Moves the cursor to center of the active display.
149   void MoveCursorToCenterOfActiveDisplay();
150 
151   // Process the delta for relative pointer motion. Returns true if relative
152   // motion was sent to the delegate, false otherwise.
153   bool HandleRelativePointerMotion(base::TimeTicks time_stamp,
154                                    gfx::PointF location_in_target);
155 
156   // The delegate instance that all events are dispatched to.
157   PointerDelegate* const delegate_;
158 
159   Seat* const seat_;
160 
161   // The delegate instance that all pinch related events are dispatched to.
162   PointerGesturePinchDelegate* pinch_delegate_ = nullptr;
163 
164   // The delegate instance that relative movement events are dispatched to.
165   RelativePointerDelegate* relative_pointer_delegate_ = nullptr;
166 
167   // The delegate instance that controls when to lock/unlock this pointer.
168   PointerConstraintDelegate* pointer_constraint_delegate_ = nullptr;
169 
170   // The current focus surface for the pointer.
171   Surface* focus_surface_ = nullptr;
172 
173   // The location of the pointer in the current focus surface.
174   gfx::PointF location_;
175 
176   // The location of the pointer when pointer capture is first enabled.
177   base::Optional<gfx::Point> location_when_pointer_capture_enabled_;
178 
179   // If this is not nullptr, a synthetic move was sent and this points to the
180   // location of a generated move that was sent which should not be forwarded.
181   base::Optional<gfx::Point> location_synthetic_move_;
182 
183   // The window with pointer capture. Pointer capture is enabled if and only if
184   // this is not null.
185   aura::Window* capture_window_ = nullptr;
186 
187   // The position of the pointer surface relative to the pointer location.
188   gfx::Point hotspot_;
189 
190   // Latest cursor snapshot.
191   SkBitmap cursor_bitmap_;
192 
193   // The current cursor.
194   ui::Cursor cursor_;
195 
196   // Hotspot to use with latest cursor snapshot.
197   gfx::Point cursor_hotspot_;
198 
199   // Scale at which cursor snapshot is captured.
200   float capture_scale_;
201 
202   // Density ratio of the cursor snapshot. The bitmap is scaled on displays with
203   // a different ratio.
204   float capture_ratio_;
205 
206   // Source used for cursor capture copy output requests.
207   const base::UnguessableToken cursor_capture_source_id_;
208 
209   // Last received event type.
210   ui::EventType last_event_type_ = ui::ET_UNKNOWN;
211 
212   // Weak pointer factory used for cursor capture callbacks.
213   base::WeakPtrFactory<Pointer> cursor_capture_weak_ptr_factory_{this};
214 
215   DISALLOW_COPY_AND_ASSIGN(Pointer);
216 };
217 
218 }  // namespace exo
219 
220 #endif  // COMPONENTS_EXO_POINTER_H_
221