Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(622)

Side by Side Diff: components/exo/touch.cc

Issue 2560633002: exo: Implement v6 of touch protocol including shape and frame event (Closed)
Patch Set: extend event_generator to test touch radius Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/exo/touch.h" 5 #include "components/exo/touch.h"
6 6
7 #include <algorithm>
8 #include <cmath>
9 #include <limits>
10
7 #include "components/exo/surface.h" 11 #include "components/exo/surface.h"
8 #include "components/exo/touch_delegate.h" 12 #include "components/exo/touch_delegate.h"
9 #include "components/exo/wm_helper.h" 13 #include "components/exo/wm_helper.h"
10 #include "ui/aura/window.h" 14 #include "ui/aura/window.h"
11 #include "ui/events/event.h" 15 #include "ui/events/event.h"
12 16
13 namespace exo { 17 namespace exo {
14 namespace { 18 namespace {
15 19 template <typename T>
16 // Helper function that returns an iterator to the first item in |vector| 20 static bool AlmostEqual(T x, T y) {
reveman 2016/12/07 03:16:18 This would need some explaining and maybe a rename
denniskempin 2016/12/07 18:32:18 We don't really have to do this, but the protocol
reveman 2016/12/07 22:58:00 I don't think we'll break any clients by sending a
denniskempin 2016/12/07 23:40:54 sgtm. Let's go with always sending the update. It'
17 // with |value|. 21 return std::abs(x - y) <=
18 template <typename T, typename U> 22 std::numeric_limits<T>::epsilon() * std::max(std::abs(x), std::abs(y));
19 typename T::iterator FindVectorItem(T& vector, U value) {
20 return std::find(vector.begin(), vector.end(), value);
21 } 23 }
22
23 // Helper function that returns true if |vector| contains an item with |value|.
24 template <typename T, typename U>
25 bool VectorContainsItem(T& vector, U value) {
26 return FindVectorItem(vector, value) != vector.end();
27 } 24 }
28 25
29 } // namespace
30
31 //////////////////////////////////////////////////////////////////////////////// 26 ////////////////////////////////////////////////////////////////////////////////
32 // Touch, public: 27 // Touch, public:
33 28
34 Touch::Touch(TouchDelegate* delegate) : delegate_(delegate) { 29 Touch::Touch(TouchDelegate* delegate) : delegate_(delegate) {
35 WMHelper::GetInstance()->AddPreTargetHandler(this); 30 WMHelper::GetInstance()->AddPreTargetHandler(this);
36 } 31 }
37 32
38 Touch::~Touch() { 33 Touch::~Touch() {
39 delegate_->OnTouchDestroying(this); 34 delegate_->OnTouchDestroying(this);
40 if (focus_) 35 if (focus_)
41 focus_->RemoveSurfaceObserver(this); 36 focus_->RemoveSurfaceObserver(this);
42 WMHelper::GetInstance()->RemovePreTargetHandler(this); 37 WMHelper::GetInstance()->RemovePreTargetHandler(this);
43 } 38 }
44 39
45 //////////////////////////////////////////////////////////////////////////////// 40 ////////////////////////////////////////////////////////////////////////////////
46 // ui::EventHandler overrides: 41 // ui::EventHandler overrides:
47 42
48 void Touch::OnTouchEvent(ui::TouchEvent* event) { 43 void Touch::OnTouchEvent(ui::TouchEvent* event) {
44 auto touch_details_iter = FindTouch(event->touch_id());
45
49 switch (event->type()) { 46 switch (event->type()) {
50 case ui::ET_TOUCH_PRESSED: { 47 case ui::ET_TOUCH_PRESSED: {
51 // Early out if event doesn't contain a valid target for touch device. 48 // Early out if event doesn't contain a valid target for touch device.
52 Surface* target = GetEffectiveTargetForEvent(event); 49 Surface* target = GetEffectiveTargetForEvent(event);
53 if (!target) 50 if (!target)
54 return; 51 return;
55 52
56 // If this is the first touch point then target becomes the focus surface 53 // If this is the first touch point then target becomes the focus surface
57 // until all touch points have been released. 54 // until all touch points have been released.
58 if (touch_points_.empty()) { 55 if (touch_points_.empty()) {
59 DCHECK(!focus_); 56 DCHECK(!focus_);
60 focus_ = target; 57 focus_ = target;
61 focus_->AddSurfaceObserver(this); 58 focus_->AddSurfaceObserver(this);
62 } 59 }
63 60
64 DCHECK(!VectorContainsItem(touch_points_, event->touch_id())); 61 DCHECK(touch_details_iter == touch_points_.end());
65 touch_points_.push_back(event->touch_id()); 62 touch_details_iter =
63 touch_points_.insert(touch_details_iter, {event->touch_id(), 0, 0});
66 64
67 // Convert location to focus surface coordinate space. 65 // Convert location to focus surface coordinate space.
68 DCHECK(focus_); 66 DCHECK(focus_);
69 gfx::Point location = event->location(); 67 gfx::Point location = event->location();
70 aura::Window::ConvertPointToTarget(target->window(), focus_->window(), 68 aura::Window::ConvertPointToTarget(target->window(), focus_->window(),
71 &location); 69 &location);
72 70
73 // Generate a touch down event for the focus surface. Note that this can 71 // Generate a touch down event for the focus surface. Note that this can
74 // be different from the target surface. 72 // be different from the target surface.
75 delegate_->OnTouchDown(focus_, event->time_stamp(), event->touch_id(), 73 delegate_->OnTouchDown(focus_, event->time_stamp(), event->touch_id(),
76 location); 74 location);
77 } break; 75 } break;
78 case ui::ET_TOUCH_RELEASED: { 76 case ui::ET_TOUCH_RELEASED: {
79 auto it = FindVectorItem(touch_points_, event->touch_id()); 77 if (touch_details_iter != touch_points_.end()) {
80 if (it != touch_points_.end()) { 78 touch_points_.erase(touch_details_iter);
81 touch_points_.erase(it); 79 touch_details_iter = touch_points_.end();
82 80
83 // Reset focus surface if this is the last touch point. 81 // Reset focus surface if this is the last touch point.
84 if (touch_points_.empty()) { 82 if (touch_points_.empty()) {
85 DCHECK(focus_); 83 DCHECK(focus_);
86 focus_->RemoveSurfaceObserver(this); 84 focus_->RemoveSurfaceObserver(this);
87 focus_ = nullptr; 85 focus_ = nullptr;
88 } 86 }
89 87
90 delegate_->OnTouchUp(event->time_stamp(), event->touch_id()); 88 delegate_->OnTouchUp(event->time_stamp(), event->touch_id());
91 } 89 }
92 } break; 90 } break;
93 case ui::ET_TOUCH_MOVED: { 91 case ui::ET_TOUCH_MOVED: {
94 auto it = FindVectorItem(touch_points_, event->touch_id()); 92 if (touch_details_iter != touch_points_.end()) {
95 if (it != touch_points_.end()) {
96 DCHECK(focus_); 93 DCHECK(focus_);
97 // Convert location to focus surface coordinate space. 94 // Convert location to focus surface coordinate space.
98 gfx::Point location = event->location(); 95 gfx::Point location = event->location();
99 aura::Window::ConvertPointToTarget( 96 aura::Window::ConvertPointToTarget(
100 static_cast<aura::Window*>(event->target()), focus_->window(), 97 static_cast<aura::Window*>(event->target()), focus_->window(),
101 &location); 98 &location);
102 99
103 delegate_->OnTouchMotion(event->time_stamp(), event->touch_id(), 100 delegate_->OnTouchMotion(event->time_stamp(), event->touch_id(),
104 location); 101 location);
105 } 102 }
106 } break; 103 } break;
107 case ui::ET_TOUCH_CANCELLED: { 104 case ui::ET_TOUCH_CANCELLED: {
108 auto it = FindVectorItem(touch_points_, event->touch_id()); 105 if (touch_details_iter != touch_points_.end()) {
109 if (it != touch_points_.end()) {
110 DCHECK(focus_); 106 DCHECK(focus_);
111 focus_->RemoveSurfaceObserver(this); 107 focus_->RemoveSurfaceObserver(this);
112 focus_ = nullptr; 108 focus_ = nullptr;
113 109
114 // Cancel the full set of touch sequences as soon as one is canceled. 110 // Cancel the full set of touch sequences as soon as one is canceled.
115 touch_points_.clear(); 111 touch_points_.clear();
112 touch_details_iter = touch_points_.end();
116 delegate_->OnTouchCancel(); 113 delegate_->OnTouchCancel();
117 } 114 }
118 } break; 115 } break;
119 default: 116 default:
120 NOTREACHED(); 117 NOTREACHED();
121 break; 118 return;
122 } 119 }
120 if (touch_details_iter != touch_points_.end()) {
121 float major = event->pointer_details().radius_x;
122 float minor = event->pointer_details().radius_y;
123 if (!AlmostEqual(major, touch_details_iter->major) ||
124 !AlmostEqual(minor, touch_details_iter->minor)) {
125 touch_details_iter->major = major;
126 touch_details_iter->minor = minor;
127 delegate_->OnTouchShape(event->touch_id(), major, minor);
128 }
129 }
130 // todo(denniskempin): Extend ui::TouchEvent to signal end of sequence of
131 // touch events to send TouchFrame once after all touches have been updated.
132 delegate_->OnTouchFrame();
123 } 133 }
124 134
125 //////////////////////////////////////////////////////////////////////////////// 135 ////////////////////////////////////////////////////////////////////////////////
126 // SurfaceObserver overrides: 136 // SurfaceObserver overrides:
127 137
128 void Touch::OnSurfaceDestroying(Surface* surface) { 138 void Touch::OnSurfaceDestroying(Surface* surface) {
129 DCHECK(surface == focus_); 139 DCHECK(surface == focus_);
130 focus_ = nullptr; 140 focus_ = nullptr;
131 surface->RemoveSurfaceObserver(this); 141 surface->RemoveSurfaceObserver(this);
132 142
133 // Cancel touch sequences. 143 // Cancel touch sequences.
134 DCHECK_NE(touch_points_.size(), 0u); 144 DCHECK_NE(touch_points_.size(), 0u);
135 touch_points_.clear(); 145 touch_points_.clear();
136 delegate_->OnTouchCancel(); 146 delegate_->OnTouchCancel();
137 } 147 }
138 148
139 //////////////////////////////////////////////////////////////////////////////// 149 ////////////////////////////////////////////////////////////////////////////////
140 // Touch, private: 150 // Touch, private:
141 151
142 Surface* Touch::GetEffectiveTargetForEvent(ui::Event* event) const { 152 Surface* Touch::GetEffectiveTargetForEvent(ui::Event* event) const {
143 Surface* target = 153 Surface* target =
144 Surface::AsSurface(static_cast<aura::Window*>(event->target())); 154 Surface::AsSurface(static_cast<aura::Window*>(event->target()));
145 if (!target) 155 if (!target)
146 return nullptr; 156 return nullptr;
147 157
148 return delegate_->CanAcceptTouchEventsForSurface(target) ? target : nullptr; 158 return delegate_->CanAcceptTouchEventsForSurface(target) ? target : nullptr;
149 } 159 }
150 160
161 std::vector<Touch::TouchDetails>::iterator Touch::FindTouch(int id) {
162 return std::find_if(touch_points_.begin(), touch_points_.end(),
163 [id](TouchDetails touch) { return touch.id == id; });
164 }
165
151 } // namespace exo 166 } // namespace exo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698