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.
5 #ifndef COMPONENTS_VIEW_MANAGER_GESTURE_MANAGER_H_
6 #define COMPONENTS_VIEW_MANAGER_GESTURE_MANAGER_H_
11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/scoped_vector.h"
18 namespace view_manager
{
20 class GestureManagerDelegate
;
21 class GestureManagerTest
;
24 struct GestureStateChange
{
26 ~GestureStateChange();
28 uint32_t chosen_gesture
;
29 std::set
<uint32_t> canceled_gestures
;
32 using ChangeMap
= std::map
<const ServerView
*, GestureStateChange
>;
34 // GestureManager handles incoming pointer events. It determines the set of
35 // views (at most one per connection) that are interested in the event and
36 // informs the delegate at the appropriate time.
38 // Each pointer may have any number of views associated with it, and each view
39 // may have any number of gestures associated with it. Gesture are identified
40 // the by the pair of the connection id of the view and the client supplied
41 // gesture. The same gesture may be used in multiple pointers (see example
44 // Gestures have the following states:
45 // . initial: Initial state for new gestures. From this state the gesture may
46 // become chosen or canceled. Once a gesture moves out of this state it can
48 // . chosen: the gesture has been chosen. From this state the gesture may be
50 // . canceled: the gesture has been canceled.
51 // Gestures are active as long as they are included in the set of
52 // |possible_gesture_ids|. Gestures can be removed at any time by removing the
53 // gesture from |possible_gesture_ids|.
55 // A particular pointer has two distinct states:
56 // . initial: none of the gestures associated with the pointer have been
58 // . chosen: when a gesture associated with the pointer has been chosen.
59 // Pointers are removed when a POINTER_UP or POINTER_CANCEL event is received.
61 // When a pointer is chosen all other gestures associated with the pointer are
62 // implicitly canceled. If the chosen gesture is canceled the pointer remains
63 // in the chosen state and no gestures can be chosen.
65 // Event propagation (ProcessEvent()) is handled in two distinct ways:
66 // . Until a gesture has been chosen for the pointer, views are notified in
67 // order (deepest first). The next view (ancestor) is notified once
68 // SetGestures() has been invoked for the previous (descendant) view.
69 // . Once a gesture has been chosen, then incoming events are immediately
72 // The following example highlights various states and transitions:
73 // . A POINTER_DOWN event is received for the pointer p1. The views that
74 // contain the location of the event (starting with the deepest) are v1, v2,
75 // v3 and v4. Both v1 and v2 have the property kViewManagerKeyWantsTouchEvents
76 // set, so only v1 and v2 are considered. v1 is the deepest view, so the
77 // touch event is set to it and only it first.
78 // . v1 responds with possible gestures g1 and g2. v1 does not specify either
79 // of the gestures as chosen.
80 // . As the response from v1 has been received and there is no chosen gesture
81 // the POINTER_DOWN event is sent to v2.
82 // . v2 responds with gestures g3 and g4, neither of which are chosen.
83 // . A POINTER_MOVE for p1 is received. As no gestures have been chosen event
84 // of the POINTER_MOVE continues with v1 first.
85 // . v1 returns g1 and g2 as possible gestures and does not choose one.
86 // . The POINTER_MOVE is sent to v2.
87 // . v2 returns g3 and g4 as possible gestures and does not choose one.
88 // At this point p1 has the possible gestures g1, g2, g3, g4. Gestures g1 and
89 // g2 are associated with v1. Gestures g3 and g4 are associated with v2.
90 // . A POINTER_DOWN event is received for the pointer p2. v1 and v2 again
91 // contain the location of the pointer. v1 is handed the event first.
92 // . A POINTER_MOVE event is received for the pointer p2. As the response from
93 // v1 has not been received yet, the event is not sent yet (it is queued up).
94 // . v1 responds to the POINTER_DOWN for p2 with g1 and g2 and chooses g1.
95 // At this point g2, g3 and g4 are all canceled with g1 chosen. p2 is in the
96 // chosen state, as is p1 (p1 enters the chosen state as it contains the chosen
98 // . The POINTER_DOWN event for p2 is sent to v2. As p2 is in the chosen state
99 // the POINTER_MOVE event that was queued up is sent to both v1 and v2 at the
100 // same time (no waiting for response).
102 // TODO(sky): add some sort of timeout to deal with hung processes.
103 class GestureManager
{
105 using GestureAndConnectionId
= uint64_t;
107 static const uint32_t kInvalidGestureId
;
109 GestureManager(GestureManagerDelegate
* delegate
, const ServerView
* root
);
112 // Processes the current event. See GestureManager description for details.
113 bool ProcessEvent(const mojo::Event
& event
);
115 // Sets the gestures for the specified view and pointer.
116 scoped_ptr
<ChangeMap
> SetGestures(
117 const ServerView
* view
,
119 uint32_t chosen_gesture_id
,
120 const std::set
<uint32_t>& possible_gesture_ids
,
121 const std::set
<uint32_t>& canceled_gesture_ids
);
124 friend class GestureManagerTest
;
128 struct PointerAndView
;
129 class ScheduledDeleteProcessor
;
131 // Returns the Pointer for |pointer_id|, or null if one doesn't exist.
132 Pointer
* GetPointerById(int32_t pointer_id
);
134 // Notification that |pointer| has no gestures. This deletes |pointer|.
135 void PointerHasNoGestures(Pointer
* pointer
);
137 // Returns the Gesture for the specified arguments, creating if necessary.
138 Gesture
* GetGesture(const ServerView
* view
, uint32_t gesture_id
);
140 // Called from Pointer when a gesture is associated with a pointer.
141 void AttachGesture(Gesture
* gesture
,
143 const ServerView
* view
);
145 // Called from Pointer when a gesture is no longer associated with a
147 void DetachGesture(Gesture
* gesture
,
149 const ServerView
* view
);
151 // Cancels the supplied gesture (if it isn't canceled already). Notifies all
152 // pointers containing |gesture| that |gesture| has been canceled.
153 void CancelGesture(Gesture
* gesture
,
155 const ServerView
* view
);
157 // Chooses the supplied gesture. Notifies all pointers containing |gesture|
158 // that |gesture| has been chosen.
159 void ChooseGesture(Gesture
* gesture
,
161 const ServerView
* view
);
163 // Deletes |pointer| after processing the current event. We delay deletion
164 // until after the event as immediate deletion can cause problems for Pointer
165 // (this is because the same Pointer may be on multiple frames of the stack).
166 void ScheduleDelete(Pointer
* pointer
);
168 GestureManagerDelegate
* delegate_
;
169 const ServerView
* root_view_
;
171 // Map for looking up gestures. Gestures are identified by the pair of
172 // connection id and supplied gesture id.
173 std::map
<GestureAndConnectionId
, Gesture
*> gesture_map_
;
175 ScopedVector
<Pointer
> active_pointers_
;
177 // See comment in ScheduleDelete() for details.
178 ScopedVector
<Pointer
> pointers_to_delete_
;
180 // Accumulates changes as the result of SetGestures().
181 scoped_ptr
<ChangeMap
> current_change_
;
183 DISALLOW_COPY_AND_ASSIGN(GestureManager
);
186 } // namespace view_manager
188 #endif // COMPONENTS_VIEW_MANAGER_GESTURE_MANAGER_H_