| Index: ui/views/widget/root_view.cc
|
| diff --git a/ui/views/widget/root_view.cc b/ui/views/widget/root_view.cc
|
| index a546ad5206e5fb7af1c7fc6fedc94b73d1cb67ef..57457aad554901722dd85057affaeee14738b8e5 100644
|
| --- a/ui/views/widget/root_view.cc
|
| +++ b/ui/views/widget/root_view.cc
|
| @@ -250,12 +250,6 @@ ui::EventTarget* RootView::GetRootTarget() {
|
| }
|
|
|
| ui::EventDispatchDetails RootView::OnEventFromSource(ui::Event* event) {
|
| - // TODO(tdanderson): Replace the calls to Dispatch*Event() with calls to
|
| - // EventProcessor::OnEventFromSource() once the code for
|
| - // that event type has been refactored, and then
|
| - // eventually remove this function altogether. See
|
| - // crbug.com/348083.
|
| -
|
| if (event->IsKeyEvent())
|
| return EventProcessor::OnEventFromSource(event);
|
|
|
| @@ -263,6 +257,14 @@ ui::EventDispatchDetails RootView::OnEventFromSource(ui::Event* event) {
|
| return EventProcessor::OnEventFromSource(event);
|
|
|
| if (event->IsGestureEvent()) {
|
| + // TODO(tdanderson): Once DispatchGestureEvent() has been removed, move
|
| + // all of this logic into an override of a new
|
| + // virtual method
|
| + // EventProcessor::OnEventProcessingStarted() (which
|
| + // returns false if no processing should take place).
|
| + // Also move the implementation of
|
| + // PrepareEventForDispatch() into this new method.
|
| + // Then RootView::OnEventFromSource() can be removed.
|
| ui::GestureEvent* gesture_event = event->AsGestureEvent();
|
|
|
| // Do not dispatch ui::ET_GESTURE_BEGIN events.
|
| @@ -644,127 +646,40 @@ View::DragInfo* RootView::GetDragInfo() {
|
| // Input -----------------------------------------------------------------------
|
|
|
| void RootView::DispatchGestureEvent(ui::GestureEvent* event) {
|
| - if (gesture_handler_) {
|
| - if (gesture_handler_->enabled()) {
|
| - // |gesture_handler_| can be deleted during processing. In particular, it
|
| - // will be set to NULL if the view is deleted or removed from the tree as
|
| - // a result of an event dispatch.
|
| - ui::GestureEvent handler_event(*event,
|
| - static_cast<View*>(this),
|
| - gesture_handler_);
|
| - ui::EventDispatchDetails dispatch_details =
|
| - DispatchEvent(gesture_handler_, &handler_event);
|
| - if (dispatch_details.dispatcher_destroyed)
|
| - return;
|
| -
|
| - if (handler_event.stopped_propagation())
|
| - event->StopPropagation();
|
| - else if (handler_event.handled())
|
| - event->SetHandled();
|
| - } else {
|
| - // Disabled views are permitted to be targets of gesture events, but
|
| - // gesture events should never actually be dispatched to them.
|
| - event->SetHandled();
|
| - }
|
| -
|
| - if (event->type() == ui::ET_GESTURE_END) {
|
| - DCHECK_EQ(1, event->details().touch_points());
|
| - // In case a drag was in progress, reset all the handlers. Otherwise, just
|
| - // reset the gesture handler.
|
| - if (gesture_handler_ == mouse_pressed_handler_)
|
| - SetMouseHandler(NULL);
|
| - else
|
| - gesture_handler_ = NULL;
|
| - }
|
| -
|
| - if (event->handled())
|
| - return;
|
| -
|
| - if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN) {
|
| - // Some view started processing gesture events, however it does not
|
| - // process scroll-gesture events. In such case, we allow the event to
|
| - // bubble up. |gesture_handler_| is changed to its nearest ancestor
|
| - // that handles scroll-gesture events.
|
| - gesture_handler_ = static_cast<View*>(
|
| - targeter()->FindNextBestTarget(gesture_handler_, event));
|
| - while (gesture_handler_ && gesture_handler_ != this) {
|
| - ui::GestureEvent gesture_event(*event,
|
| - static_cast<View*>(this),
|
| - gesture_handler_);
|
| - ui::EventDispatchDetails dispatch_details =
|
| - DispatchEvent(gesture_handler_, &gesture_event);
|
| - if (gesture_event.stopped_propagation()) {
|
| - event->StopPropagation();
|
| - return;
|
| - } else if (gesture_event.handled()) {
|
| - event->SetHandled();
|
| - return;
|
| - } else if (dispatch_details.dispatcher_destroyed ||
|
| - dispatch_details.target_destroyed) {
|
| - return;
|
| - }
|
| - gesture_handler_ = static_cast<View*>(
|
| - targeter()->FindNextBestTarget(gesture_handler_, event));
|
| - }
|
| - gesture_handler_ = NULL;
|
| - }
|
| -
|
| - return;
|
| - }
|
| -
|
| - // Walk up the tree until we find a view that wants the gesture event.
|
| - gesture_handler_ =
|
| + bool gesture_handler_set_before_dispatch = !!gesture_handler_;
|
| + View* target =
|
| static_cast<View*>(targeter()->FindTargetForEvent(this, event));
|
| - while (gesture_handler_ && gesture_handler_ != this) {
|
| - // Disabled views are permitted to be targets of gesture events, but
|
| - // gesture events should never actually be dispatched to them.
|
| - if (!gesture_handler_->enabled()) {
|
| - event->SetHandled();
|
| -
|
| - // Last ui::ET_GESTURE_END should not set the gesture_handler_.
|
| - if (event->type() == ui::ET_GESTURE_END) {
|
| - DCHECK_EQ(1, event->details().touch_points());
|
| - gesture_handler_ = NULL;
|
| - }
|
| -
|
| - return;
|
| - }
|
| -
|
| - // See if this view wants to handle the Gesture.
|
| - ui::GestureEvent gesture_event(*event,
|
| - static_cast<View*>(this),
|
| - gesture_handler_);
|
| + while (target && target != this) {
|
| + // Create and dispatch a copy of |event|.
|
| + ui::GestureEvent event_copy(*event, static_cast<View*>(this), target);
|
| ui::EventDispatchDetails dispatch_details =
|
| - DispatchEvent(gesture_handler_, &gesture_event);
|
| + DispatchEvent(target, &event_copy);
|
| if (dispatch_details.dispatcher_destroyed)
|
| return;
|
|
|
| - // The view could have removed itself from the tree when handling
|
| - // OnGestureEvent(). So handle as per OnMousePressed. NB: we
|
| - // assume that the RootView itself cannot be so removed.
|
| - if (!gesture_handler_)
|
| - return;
|
| + if (event_copy.stopped_propagation())
|
| + event->StopPropagation();
|
| + else if (event_copy.handled())
|
| + event->SetHandled();
|
|
|
| - if (gesture_event.handled()) {
|
| - if (gesture_event.stopped_propagation())
|
| - event->StopPropagation();
|
| - else
|
| - event->SetHandled();
|
| - // Last ui::ET_GESTURE_END should not set the gesture_handler_.
|
| - if (gesture_event.type() == ui::ET_GESTURE_END) {
|
| - DCHECK_EQ(1, event->details().touch_points());
|
| - gesture_handler_ = NULL;
|
| - }
|
| + // If the event was handled by the previous dispatch or if the target
|
| + // was destroyed, do not allow any further processing of |event|.
|
| + if (event->handled() || dispatch_details.target_destroyed)
|
| return;
|
| - }
|
|
|
| - // The gesture event wasn't processed. Go up the view hierarchy and
|
| - // dispatch the gesture event.
|
| - gesture_handler_ = static_cast<View*>(
|
| - targeter()->FindNextBestTarget(gesture_handler_, event));
|
| + // The event was not handled by |target|, so continue processing by
|
| + // re-targeting the event.
|
| + target = static_cast<View*>(targeter()->FindNextBestTarget(target, event));
|
| }
|
|
|
| - gesture_handler_ = NULL;
|
| + // |event| was not handled, so if |gesture_handler_| was not set by the
|
| + // dispatch of a previous gesture event, then no default gesture handler
|
| + // should be set prior to the next gesture event being received.
|
| + // TODO(tdanderson): Move this into a new virtual function
|
| + // EventProcessor::OnEventProcessingFinished(), to be called
|
| + // at the end of EventProcessor::OnEventFromSource().
|
| + if (!gesture_handler_set_before_dispatch)
|
| + gesture_handler_ = NULL;
|
| }
|
|
|
| void RootView::UpdateCursor(const ui::MouseEvent& event) {
|
| @@ -808,13 +723,38 @@ bool RootView::CanDispatchToTarget(ui::EventTarget* target) {
|
|
|
| ui::EventDispatchDetails RootView::PreDispatchEvent(ui::EventTarget* target,
|
| ui::Event* event) {
|
| + View* view = static_cast<View*>(target);
|
| + if (event->IsGestureEvent()) {
|
| + // Update |gesture_handler_| to indicate which View is currently handling
|
| + // gesture events.
|
| + gesture_handler_ = view;
|
| +
|
| + // Disabled views are permitted to be targets of gesture events, but
|
| + // gesture events should never actually be dispatched to them. Prevent
|
| + // dispatch by marking the event as handled.
|
| + if (!view->enabled())
|
| + event->SetHandled();
|
| + }
|
| +
|
| old_dispatch_target_ = event_dispatch_target_;
|
| - event_dispatch_target_ = static_cast<View*>(target);
|
| + event_dispatch_target_ = view;
|
| return DispatchDetails();
|
| }
|
|
|
| ui::EventDispatchDetails RootView::PostDispatchEvent(ui::EventTarget* target,
|
| const ui::Event& event) {
|
| + // The GESTURE_END event corresponding to the removal of the final touch
|
| + // point marks the end of a gesture sequence, so reset |gesture_handler_|
|
| + // to NULL.
|
| + if (event.type() == ui::ET_GESTURE_END) {
|
| + // In case a drag was in progress, reset all the handlers. Otherwise, just
|
| + // reset the gesture handler.
|
| + if (gesture_handler_ && gesture_handler_ == mouse_pressed_handler_)
|
| + SetMouseHandler(NULL);
|
| + else
|
| + gesture_handler_ = NULL;
|
| + }
|
| +
|
| DispatchDetails details;
|
| if (target != event_dispatch_target_)
|
| details.target_destroyed = true;
|
|
|