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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/renderer/gesture_manager.cc
diff --git a/chrome/renderer/gesture_manager.cc b/chrome/renderer/gesture_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7f57a84dbfa7ba406498d5580571c749c5a7760d
--- /dev/null
+++ b/chrome/renderer/gesture_manager.cc
@@ -0,0 +1,151 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/renderer/gesture_manager.h"
+
+#include "chrome/renderer/render_widget.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h"
+#include "third_party/WebKit/WebKit/chromium/public/WebWidget.h"
+
+using WebKit::WebInputEvent;
+using WebKit::WebMouseEvent;
+using WebKit::WebPoint;
+using WebKit::WebTouchEvent;
+using WebKit::WebTouchPoint;
+using WebKit::WebWidget;
+
+
+// TODO(rjkroege): Make these configurable programmatically.
+// Maximum hold down (s) for a touch to be treated as a click.
+static const double kMaxClickDownTime = .8;
+
+// Minimum hold down (s) for a touch to be treated as a click.
+static const double kMinClickDownTime = .01;
+
+// Maximum manhattan displacement for touch motion to
+// still be considered as a click.
+static const int kMaxManhattanDistance = 20;
+
+GestureManager::~GestureManager() {
+}
+
+GestureManager* GestureManager::Get() {
+ return Singleton<GestureManager>::get();
+}
+
+bool GestureManager::ProcessTouchEventForGesture(const WebTouchEvent& event,
+ RenderWidget* source,
+ bool previouslyHandled) {
+ bool handled = false;
+ for (int i = 0; i < event.touchPointsLength; i++) {
+ const WebTouchPoint& p = event.touchPoints[i];
+ switch (candidate_gesture_) {
+ case NO_GESTURE:
+ if (!previouslyHandled && p.state == WebTouchPoint::StatePressed) {
+ candidate_gesture_ = PENDING_SYNTHETIC_CLICK;
+ first_touch_time_ = event.timeStampSeconds;
+ first_touch_position_ = p.position;
+ }
+ break;
+ case PENDING_SYNTHETIC_CLICK:
+ if (p.state == WebTouchPoint::StateCancelled) {
+ candidate_gesture_ = NO_GESTURE;
+ } else if (p.state == WebTouchPoint::StatePressed) {
+ NOTREACHED();
+ // Cleanup? Possibly not necessary.
+ candidate_gesture_ = NO_GESTURE;
+ } else if (p.state == WebTouchPoint::StateReleased
+ && IsInClickTimeWindow(event.timeStampSeconds)
+ && IsInsideManhattanSquare(p)
+ && !previouslyHandled) {
+ candidate_gesture_ = NO_GESTURE;
+ DispatchSyntheticClick(source, event, p);
+ handled = true;
+ } else if ((p.state == WebTouchPoint::StateStationary
+ || p.state == WebTouchPoint::StateMoved)
+ && IsInClickTimeWindow(event.timeStampSeconds)
+ && IsInsideManhattanSquare(p)
+ && !previouslyHandled) {
+ candidate_gesture_ = PENDING_SYNTHETIC_CLICK;
+ } else if (p.state == WebTouchPoint::StateMoved
+ && !IsInsideManhattanSquare(p)
+ && !previouslyHandled) {
+ ScrollViaTouchMotion(p, source);
+ candidate_gesture_ = SCROLL;
+ handled = true;
+ } else if (p.state == WebTouchPoint::StateReleased) {
+ candidate_gesture_ = NO_GESTURE;
+ }
+ break;
+ case SCROLL:
+ if (p.state == WebTouchPoint::StateMoved && !previouslyHandled) {
+ ScrollViaTouchMotion(p, source);
+ handled = true;
+ } else if (p.state == WebTouchPoint::StateReleased) {
+ candidate_gesture_ = NO_GESTURE;
+ } else if (p.state == WebTouchPoint::StateCancelled) {
+ // It may be necessary to anul the scroll here.
+ candidate_gesture_ = NO_GESTURE;
+ }
+ break;
+ }
+ }
+ return handled;
+}
+
+GestureManager::GestureManager()
+ : candidate_gesture_(GestureManager::NO_GESTURE),
+ first_touch_time_(0.0) {
+}
+
+void GestureManager::DispatchSyntheticClick(RenderWidget* w,
+ const WebTouchEvent& event,
+ const WebTouchPoint& p) {
+ WebMouseEvent fake_mouse_down, fake_mouse_up;
+
+ fake_mouse_down.type = WebInputEvent::MouseDown;
+ fake_mouse_down.timeStampSeconds = event.timeStampSeconds;
+ fake_mouse_down.button = WebMouseEvent::ButtonLeft;
+ fake_mouse_down.clickCount = 1;
+ fake_mouse_down.x = p.position.x;
+ fake_mouse_down.y = p.position.y;
+ fake_mouse_down.windowX = p.position.x;
+ fake_mouse_down.windowY = p.position.y;
+ fake_mouse_down.globalX = p.screenPosition.x;
+ fake_mouse_down.globalY = p.screenPosition.y;
+
+ fake_mouse_up.type = WebInputEvent::MouseUp;
+ fake_mouse_up.timeStampSeconds = event.timeStampSeconds;
+ fake_mouse_up.button = WebMouseEvent::ButtonLeft;
+ fake_mouse_up.clickCount = 1;
+ fake_mouse_up.x = p.position.x;
+ fake_mouse_up.y = p.position.y;
+ fake_mouse_up.windowX = p.position.x;
+ fake_mouse_up.windowY = p.position.y;
+ fake_mouse_up.globalX = p.screenPosition.x;
+ fake_mouse_up.globalY = p.screenPosition.y;
+
+ w->webwidget()->handleInputEvent(fake_mouse_down);
+ w->webwidget()->handleInputEvent(fake_mouse_up);
+}
+
+bool GestureManager::IsInClickTimeWindow(const double ts) {
+ double delta = ts - first_touch_time_;
+ return delta >= kMinClickDownTime
+ && delta < kMaxClickDownTime;
+}
+
+bool GestureManager::IsInsideManhattanSquare(const WebTouchPoint& p) {
+ int manhattanDistance = abs(p.position.x - first_touch_position_.x) +
+ abs(p.position.y - first_touch_position_.y);
+ return manhattanDistance < kMaxManhattanDistance;
+}
+
+void GestureManager::ScrollViaTouchMotion(const WebTouchPoint& tp,
+ RenderWidget *rw) {
+ rw->webwidget()->gestureScroll(tp.position, tp.screenPosition,
+ tp.position.x - first_touch_position_.x,
+ tp.position.y - first_touch_position_.y);
+ first_touch_position_ = tp.position;
+}

Powered by Google App Engine
This is Rietveld 408576698