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

Side by Side Diff: chrome/renderer/gesture_manager.cc

Issue 3388013: Forward touch events to a RenderWidget's associated WebWidget (Closed)
Patch Set: removed commented-out include Created 10 years, 3 months 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
(Empty)
1 // Copyright (c) 2010 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 #include "chrome/renderer/gesture_manager.h"
6
7 #include "chrome/renderer/render_widget.h"
8 #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
9 #include "third_party/WebKit/WebKit/chromium/public/WebWidget.h"
10
11 using WebKit::WebInputEvent;
12 using WebKit::WebMouseEvent;
13 using WebKit::WebPoint;
14 using WebKit::WebTouchEvent;
15 using WebKit::WebTouchPoint;
16 using WebKit::WebWidget;
17
18
19 // TODO(rjkroege): Make these configurable programmatically.
20 // Maximum hold down (s) for a touch to be treated as a click.
21 static const double kMaxClickDownTime = .8;
22
23 // Minimum hold down (s) for a touch to be treated as a click.
24 static const double kMinClickDownTime = .01;
25
26 // Maximum manhattan displacement for touch motion to
27 // still be considered as a click.
28 static const int kMaxManhattanDistance = 20;
29
30 GestureManager::~GestureManager() {
31 }
32
33 GestureManager* GestureManager::Get() {
34 return Singleton<GestureManager>::get();
35 }
36
37 bool GestureManager::ProcessTouchEventForGesture(const WebTouchEvent& event,
38 RenderWidget* source,
39 bool previouslyHandled) {
40 bool handled = false;
41 for (int i = 0; i < event.touchPointsLength; i++) {
42 const WebTouchPoint& p = event.touchPoints[i];
43 switch (candidate_gesture_) {
44 case NO_GESTURE:
45 if (!previouslyHandled && p.state == WebTouchPoint::StatePressed) {
46 candidate_gesture_ = PENDING_SYNTHETIC_CLICK;
47 first_touch_time_ = event.timeStampSeconds;
48 first_touch_position_ = p.position;
49 }
50 break;
51 case PENDING_SYNTHETIC_CLICK:
52 if (p.state == WebTouchPoint::StateCancelled) {
53 candidate_gesture_ = NO_GESTURE;
54 } else if (p.state == WebTouchPoint::StatePressed) {
55 NOTREACHED();
56 // Cleanup? Possibly not necessary.
57 candidate_gesture_ = NO_GESTURE;
58 } else if (p.state == WebTouchPoint::StateReleased
59 && IsInClickTimeWindow(event.timeStampSeconds)
60 && IsInsideManhattanSquare(p)
61 && !previouslyHandled) {
62 candidate_gesture_ = NO_GESTURE;
63 DispatchSyntheticClick(source, event, p);
64 handled = true;
65 } else if ((p.state == WebTouchPoint::StateStationary
66 || p.state == WebTouchPoint::StateMoved)
67 && IsInClickTimeWindow(event.timeStampSeconds)
68 && IsInsideManhattanSquare(p)
69 && !previouslyHandled) {
70 candidate_gesture_ = PENDING_SYNTHETIC_CLICK;
71 } else if (p.state == WebTouchPoint::StateMoved
72 && !IsInsideManhattanSquare(p)
73 && !previouslyHandled) {
74 ScrollViaTouchMotion(p, source);
75 candidate_gesture_ = SCROLL;
76 handled = true;
77 } else if (p.state == WebTouchPoint::StateReleased) {
78 candidate_gesture_ = NO_GESTURE;
79 }
80 break;
81 case SCROLL:
82 if (p.state == WebTouchPoint::StateMoved && !previouslyHandled) {
83 ScrollViaTouchMotion(p, source);
84 handled = true;
85 } else if (p.state == WebTouchPoint::StateReleased) {
86 candidate_gesture_ = NO_GESTURE;
87 } else if (p.state == WebTouchPoint::StateCancelled) {
88 // It may be necessary to anul the scroll here.
89 candidate_gesture_ = NO_GESTURE;
90 }
91 break;
92 }
93 }
94 return handled;
95 }
96
97 GestureManager::GestureManager()
98 : candidate_gesture_(GestureManager::NO_GESTURE),
99 first_touch_time_(0.0) {
100 }
101
102 void GestureManager::DispatchSyntheticClick(RenderWidget* w,
103 const WebTouchEvent& event,
104 const WebTouchPoint& p) {
105 WebMouseEvent fake_mouse_down, fake_mouse_up;
106
107 fake_mouse_down.type = WebInputEvent::MouseDown;
108 fake_mouse_down.timeStampSeconds = event.timeStampSeconds;
109 fake_mouse_down.button = WebMouseEvent::ButtonLeft;
110 fake_mouse_down.clickCount = 1;
111 fake_mouse_down.x = p.position.x;
112 fake_mouse_down.y = p.position.y;
113 fake_mouse_down.windowX = p.position.x;
114 fake_mouse_down.windowY = p.position.y;
115 fake_mouse_down.globalX = p.screenPosition.x;
116 fake_mouse_down.globalY = p.screenPosition.y;
117
118 fake_mouse_up.type = WebInputEvent::MouseUp;
119 fake_mouse_up.timeStampSeconds = event.timeStampSeconds;
120 fake_mouse_up.button = WebMouseEvent::ButtonLeft;
121 fake_mouse_up.clickCount = 1;
122 fake_mouse_up.x = p.position.x;
123 fake_mouse_up.y = p.position.y;
124 fake_mouse_up.windowX = p.position.x;
125 fake_mouse_up.windowY = p.position.y;
126 fake_mouse_up.globalX = p.screenPosition.x;
127 fake_mouse_up.globalY = p.screenPosition.y;
128
129 w->webwidget()->handleInputEvent(fake_mouse_down);
130 w->webwidget()->handleInputEvent(fake_mouse_up);
131 }
132
133 bool GestureManager::IsInClickTimeWindow(const double ts) {
134 double delta = ts - first_touch_time_;
135 return delta >= kMinClickDownTime
136 && delta < kMaxClickDownTime;
137 }
138
139 bool GestureManager::IsInsideManhattanSquare(const WebTouchPoint& p) {
140 int manhattanDistance = abs(p.position.x - first_touch_position_.x) +
141 abs(p.position.y - first_touch_position_.y);
142 return manhattanDistance < kMaxManhattanDistance;
143 }
144
145 void GestureManager::ScrollViaTouchMotion(const WebTouchPoint& tp,
146 RenderWidget *rw) {
147 rw->webwidget()->gestureScroll(tp.position, tp.screenPosition,
148 tp.position.x - first_touch_position_.x,
149 tp.position.y - first_touch_position_.y);
150 first_touch_position_ = tp.position;
151 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698