Commit 4af71499 authored by girard@chromium.org's avatar girard@chromium.org

Corrected issues with queued touch events. This fixes gestures in Windows.

The underlying issue is that the GR expects individual touch events (one touch per event) while javascript expects composite events (containing information on each touch point in a single event.)

BUG=130205
TEST=


Review URL: https://chromiumcodereview.appspot.com/10702096

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146180 0039d316-1c4b-4281-b951-d872f2087c98
parent 007673c8
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <algorithm> #include <algorithm>
#include <map> #include <map>
#include <peninputpanel_i.c> #include <peninputpanel_i.c>
#include <stack>
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
...@@ -499,7 +500,7 @@ class LocalTouchEvent : ...@@ -499,7 +500,7 @@ class LocalTouchEvent :
} }
// Returns a copy of the touch event at the specified index. // Returns a copy of the touch event at the specified index.
const LocalTouchEvent& Index( size_t index) { const LocalTouchEvent& Index( size_t index) const {
const int touch_history_size = 40; const int touch_history_size = 40;
static LocalTouchEvent touch_history[touch_history_size]; static LocalTouchEvent touch_history[touch_history_size];
static int touch_history_index; static int touch_history_index;
...@@ -538,11 +539,19 @@ class WebTouchState { ...@@ -538,11 +539,19 @@ class WebTouchState {
bool is_changed() { return touch_event_.data().changedTouchesLength != 0; } bool is_changed() { return touch_event_.data().changedTouchesLength != 0; }
void QueueEvents(ui::GestureConsumer* consumer, ui::GestureRecognizer* gr) { void QueueEvents(ui::GestureConsumer* consumer, ui::GestureRecognizer* gr) {
if (touch_event_.data().touchesLength > 0)
touch_count_.push(touch_event_.data().touchesLength);
for (size_t i = 0; i < touch_event_.data().touchesLength; ++i) { for (size_t i = 0; i < touch_event_.data().touchesLength; ++i) {
gr->QueueTouchEventForGesture(consumer, touch_event_.Index(i)); gr->QueueTouchEventForGesture(consumer, touch_event_.Index(i));
} }
} }
int GetNextTouchCount() {
int result = touch_count_.top();
touch_count_.pop();
return result;
}
private: private:
typedef std::map<unsigned int, int> MapType; typedef std::map<unsigned int, int> MapType;
...@@ -560,6 +569,12 @@ class WebTouchState { ...@@ -560,6 +569,12 @@ class WebTouchState {
// Remove any mappings that are no longer in use. // Remove any mappings that are no longer in use.
void RemoveExpiredMappings(); void RemoveExpiredMappings();
// The gesture recognizer processes touch events one at a time, but WebKit
// (ForwardTouchEvent) takes a set of touch events. |touchCount_| tracks how
// many individual touch events were sent to ForwardTouchEvent, so we can
// send the correct number of AdvanceTouchQueue's
std::stack<int> touch_count_;
LocalTouchEvent touch_event_; LocalTouchEvent touch_event_;
const RenderWidgetHostViewWin* const window_; const RenderWidgetHostViewWin* const window_;
...@@ -1195,9 +1210,16 @@ void RenderWidgetHostViewWin::SetBackground(const SkBitmap& background) { ...@@ -1195,9 +1210,16 @@ void RenderWidgetHostViewWin::SetBackground(const SkBitmap& background) {
void RenderWidgetHostViewWin::ProcessTouchAck( void RenderWidgetHostViewWin::ProcessTouchAck(
WebKit::WebInputEvent::Type type, bool processed) { WebKit::WebInputEvent::Type type, bool processed) {
scoped_ptr<ui::GestureRecognizer::Gestures> gestures;
gestures.reset(gesture_recognizer_->AdvanceTouchQueue(this, processed)); DCHECK(render_widget_host_->has_touch_handler() &&
ProcessGestures(gestures.get()); touch_events_enabled_);
int touch_count = touch_state_->GetNextTouchCount();
for (int i = 0; i < touch_count; ++i) {
scoped_ptr<ui::GestureRecognizer::Gestures> gestures;
gestures.reset(gesture_recognizer_->AdvanceTouchQueue(this, processed));
ProcessGestures(gestures.get());
}
if (type == WebKit::WebInputEvent::TouchStart) if (type == WebKit::WebInputEvent::TouchStart)
UpdateDesiredTouchMode(processed); UpdateDesiredTouchMode(processed);
...@@ -1572,9 +1594,6 @@ void RenderWidgetHostViewWin::OnSetFocus(HWND window) { ...@@ -1572,9 +1594,6 @@ void RenderWidgetHostViewWin::OnSetFocus(HWND window) {
render_widget_host_->GotFocus(); render_widget_host_->GotFocus();
render_widget_host_->SetActive(true); render_widget_host_->SetActive(true);
if (touch_state_->ReleaseTouchPoints() && touch_events_enabled_)
render_widget_host_->ForwardTouchEvent(touch_state_->touch_event());
} }
void RenderWidgetHostViewWin::OnKillFocus(HWND window) { void RenderWidgetHostViewWin::OnKillFocus(HWND window) {
...@@ -1584,9 +1603,6 @@ void RenderWidgetHostViewWin::OnKillFocus(HWND window) { ...@@ -1584,9 +1603,6 @@ void RenderWidgetHostViewWin::OnKillFocus(HWND window) {
render_widget_host_->SetActive(false); render_widget_host_->SetActive(false);
render_widget_host_->Blur(); render_widget_host_->Blur();
if (touch_state_->ReleaseTouchPoints() && touch_events_enabled_)
render_widget_host_->ForwardTouchEvent(touch_state_->touch_event());
} }
void RenderWidgetHostViewWin::OnCaptureChanged(HWND window) { void RenderWidgetHostViewWin::OnCaptureChanged(HWND window) {
...@@ -2281,15 +2297,18 @@ LRESULT RenderWidgetHostViewWin::OnTouchEvent(UINT message, WPARAM wparam, ...@@ -2281,15 +2297,18 @@ LRESULT RenderWidgetHostViewWin::OnTouchEvent(UINT message, WPARAM wparam,
for (size_t start = 0; start < total;) { for (size_t start = 0; start < total;) {
start += touch_state_->UpdateTouchPoints(points + start, total - start); start += touch_state_->UpdateTouchPoints(points + start, total - start);
if (has_touch_handler) { if (has_touch_handler) {
if (touch_state_->is_changed()) if (touch_state_->is_changed()) {
render_widget_host_->ForwardTouchEvent(touch_state_->touch_event()); render_widget_host_->ForwardTouchEvent(touch_state_->touch_event());
touch_state_->QueueEvents(this,gesture_recognizer_.get()); touch_state_->QueueEvents(this, gesture_recognizer_.get());
}
} else { } else {
// TODO: This probably needs to be updated to call Next() const LocalTouchEvent* touch_event = touch_state_->ui_touch_event();
scoped_ptr<ui::GestureRecognizer::Gestures> gestures; for (size_t i = 0; i < touch_event->data().touchesLength; ++i) {
gestures.reset(gesture_recognizer_->ProcessTouchEventForGesture( scoped_ptr<ui::GestureRecognizer::Gestures> gestures;
*touch_state_->ui_touch_event(), ui::TOUCH_STATUS_UNKNOWN, this)); gestures.reset(gesture_recognizer_->ProcessTouchEventForGesture(
ProcessGestures(gestures.get()); touch_event->Index(i), ui::TOUCH_STATUS_UNKNOWN, this));
ProcessGestures(gestures.get());
}
} }
} }
......
...@@ -298,7 +298,7 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture( ...@@ -298,7 +298,7 @@ GestureSequence::Gestures* GestureSequence::ProcessTouchEventForGesture(
GesturePoint* new_point = &points_[event.GetTouchId()]; GesturePoint* new_point = &points_[event.GetTouchId()];
// We shouldn't be able to get two PRESSED events from the same // We shouldn't be able to get two PRESSED events from the same
// finger without either a RELEASE or CANCEL in between. // finger without either a RELEASE or CANCEL in between.
DCHECK(!points_[event.GetTouchId()].in_use()); DCHECK(!new_point->in_use());
new_point->set_point_id(point_count_++); new_point->set_point_id(point_count_++);
new_point->set_touch_id(event.GetTouchId()); new_point->set_touch_id(event.GetTouchId());
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment