Index: ui/aura/root_window.cc |
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc |
index 002d2317cbe93700f934071e08f5381e33f00b8f..055d2db0812bc2f5ff15bd8c45b2ad6894b023f1 100644 |
--- a/ui/aura/root_window.cc |
+++ b/ui/aura/root_window.cc |
@@ -122,6 +122,7 @@ RootWindow::~RootWindow() { |
TRACE_EVENT0("shutdown", "RootWindow::Destructor"); |
ui::GestureRecognizer::Get()->RemoveGestureEventHelper(this); |
+ STLDeleteValues(&gesture_event_queues_); |
// An observer may have been added by an animation on the RootWindow. |
window()->layer()->GetAnimator()->RemoveObserver(this); |
@@ -353,12 +354,7 @@ void RootWindow::RemoveRootWindowObserver(RootWindowObserver* observer) { |
void RootWindow::ProcessedTouchEvent(ui::TouchEvent* event, |
Window* window, |
ui::EventResult result) { |
- scoped_ptr<ui::GestureRecognizer::Gestures> gestures; |
- gestures.reset(ui::GestureRecognizer::Get()-> |
- ProcessTouchEventForGesture(*event, result, window)); |
- DispatchDetails details = ProcessGestures(gestures.get()); |
- if (details.dispatcher_destroyed) |
- return; |
+ gesture_event_queues_[window]->OnTouchEventAck(*event, result); |
} |
void RootWindow::HoldPointerMoves() { |
@@ -497,6 +493,7 @@ void RootWindow::OnWindowHidden(Window* invisible, WindowHiddenReason reason) { |
void RootWindow::CleanupGestureState(Window* window) { |
ui::GestureRecognizer::Get()->CancelActiveTouches(window); |
ui::GestureRecognizer::Get()->CleanupStateForConsumer(window); |
+ gesture_event_queues_.erase(window); |
const Window::Windows& windows = window->children(); |
for (Window::Windows::const_iterator iter = windows.begin(); |
iter != windows.end(); |
@@ -617,10 +614,6 @@ bool RootWindow::CanDispatchToConsumer(ui::GestureConsumer* consumer) { |
return (consumer_window && consumer_window->GetRootWindow() == window()); |
} |
-void RootWindow::DispatchPostponedGestureEvent(ui::GestureEvent* event) { |
- DispatchGestureEvent(event); |
-} |
- |
void RootWindow::DispatchCancelTouchEvent(ui::TouchEvent* event) { |
OnHostTouchEvent(event); |
} |
@@ -663,7 +656,37 @@ bool RootWindow::OnHostScrollEvent(ui::ScrollEvent* event) { |
return event->handled(); |
} |
+void RootWindow::OnTouchEventForGestures( |
+ ui::TouchEvent* event, |
+ ui::TouchPointState::RequiresAck requires_ack) { |
+ Window* target = GetTouchEventTarget(event); |
+ if (target) |
+ event->ConvertLocationToTarget(target, window()); |
+ if (!gesture_event_queues_[target]) |
+ gesture_event_queues_[target] = new ui::GestureEventQueue(this); |
+ ui::GestureEventQueue* gesture_event_queue = gesture_event_queues_[target]; |
+ gesture_event_queue->OnTouchEvent(*event); |
+ // Get the list of GestureEvents from GestureRecognizer. |
+ scoped_ptr<ui::GestureRecognizer::Gestures> gestures; |
+ gestures.reset( |
+ ui::GestureRecognizer::Get()->ProcessTouchEventForGesture( |
+ *event, target, gesture_event_queue)); |
+ for (ui::GestureRecognizer::Gestures::iterator it = gestures->begin(); |
+ it != gestures->end(); |
+ ++it) { |
+ gesture_event_queue->QueueGestureEvent(*it, requires_ack); |
+ } |
+ gestures->weak_clear(); |
+} |
+ |
bool RootWindow::OnHostTouchEvent(ui::TouchEvent* event) { |
+ TransformEventForDeviceScaleFactor(event); |
+ |
+ Window* target = GetTouchEventTarget(event); |
+ |
+ if (target) |
+ event->ConvertLocationToTarget(window(), target); |
+ |
if ((event->type() == ui::ET_TOUCH_MOVED)) { |
if (move_hold_count_) { |
Window* null_window = static_cast<Window*>(NULL); |
@@ -680,7 +703,9 @@ bool RootWindow::OnHostTouchEvent(ui::TouchEvent* event) { |
DispatchDetails details = DispatchHeldEvents(); |
if (details.dispatcher_destroyed) |
return false; |
- details = DispatchTouchEventImpl(event); |
+ details = DispatchTouchEventImpl(event, target); |
+ if (event->result() == ui::ER_UNHANDLED) |
+ OnTouchEventForGestures(event, ui::TouchPointState::NO_ACK); |
if (details.dispatcher_destroyed) |
return true; |
return event->handled(); |
@@ -878,7 +903,10 @@ ui::EventDispatchDetails RootWindow::DispatchMouseEventToTarget( |
} |
ui::EventDispatchDetails RootWindow::DispatchTouchEventImpl( |
- ui::TouchEvent* event) { |
+ ui::TouchEvent* event, Window* target) { |
+ if (!target) |
+ return DispatchDetails(); |
+ |
switch (event->type()) { |
case ui::ET_TOUCH_PRESSED: |
touch_ids_down_ |= (1 << event->touch_id()); |
@@ -899,51 +927,8 @@ ui::EventDispatchDetails RootWindow::DispatchTouchEventImpl( |
default: |
break; |
} |
- TransformEventForDeviceScaleFactor(event); |
- Window* target = client::GetCaptureWindow(window()); |
- if (!target) { |
- target = ConsumerToWindow( |
- ui::GestureRecognizer::Get()->GetTouchLockedTarget(*event)); |
- if (!target) { |
- target = ConsumerToWindow(ui::GestureRecognizer::Get()-> |
- GetTargetForLocation(event->location())); |
- } |
- } |
- |
- // The gesture recognizer processes touch events in the system coordinates. So |
- // keep a copy of the touch event here before possibly converting the event to |
- // a window's local coordinate system. |
- ui::TouchEvent event_for_gr(*event); |
- |
- ui::EventResult result = ui::ER_UNHANDLED; |
- if (!target && !window()->bounds().Contains(event->location())) { |
- // If the initial touch is outside the root window, target the root. |
- target = window(); |
- DispatchDetails details = DispatchEvent(target ? target : NULL, event); |
- if (details.dispatcher_destroyed) |
- return details; |
- result = event->result(); |
- } else { |
- // We only come here when the first contact was within the root window. |
- if (!target) { |
- target = window()->GetEventHandlerForPoint(event->location()); |
- if (!target) |
- return DispatchDetails(); |
- } |
- |
- event->ConvertLocationToTarget(window(), target); |
- DispatchDetails details = DispatchEvent(target, event); |
- if (details.dispatcher_destroyed) |
- return details; |
- result = event->result(); |
- } |
- |
- // Get the list of GestureEvents from GestureRecognizer. |
- scoped_ptr<ui::GestureRecognizer::Gestures> gestures; |
- gestures.reset(ui::GestureRecognizer::Get()-> |
- ProcessTouchEventForGesture(event_for_gr, result, target)); |
- |
- return ProcessGestures(gestures.get()); |
+ DispatchDetails details = DispatchEvent(target, event); |
+ return details; |
} |
ui::EventDispatchDetails RootWindow::DispatchHeldEvents() { |
@@ -977,8 +962,10 @@ ui::EventDispatchDetails RootWindow::DispatchHeldEvents() { |
if (!dispatch_details.dispatcher_destroyed) |
held_move_event_.reset(); |
} else if (held_move_event_ && held_move_event_->IsTouchEvent()) { |
+ ui::TouchEvent* touch_event = |
+ static_cast<ui::TouchEvent*>(held_move_event_.get()); |
dispatch_details = DispatchTouchEventImpl( |
- static_cast<ui::TouchEvent*>(held_move_event_.get())); |
+ touch_event, GetTouchEventTarget(touch_event)); |
if (!dispatch_details.dispatcher_destroyed) |
held_move_event_.reset(); |
} |
@@ -1036,4 +1023,28 @@ void RootWindow::PreDispatchLocatedEvent(Window* target, |
} |
} |
+Window* RootWindow::GetTouchEventTarget(ui::TouchEvent* event) { |
+ Window* target = client::GetCaptureWindow(window()); |
+ if (!target) { |
+ target = ConsumerToWindow( |
+ ui::GestureRecognizer::Get()->GetTouchLockedTarget(*event)); |
+ if (!target) { |
+ target = ConsumerToWindow(ui::GestureRecognizer::Get()-> |
+ GetTargetForLocation(event->location())); |
+ } |
+ } |
+ |
+ if (!target && !window()->bounds().Contains(event->location())) { |
+ // If the initial touch is outside the root window, target the root. |
+ target = window(); |
+ if (!target) |
+ target = this->window(); |
+ } else { |
+ // We only come here when the first contact was within the root window. |
+ if (!target) |
+ target = window()->GetEventHandlerForPoint(event->location()); |
+ } |
+ return target; |
+} |
+ |
} // namespace aura |