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

Unified Diff: ui/views/widget/root_view.cc

Issue 517023004: Condense RootView::DispatchGestureEvent() to a single loop (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: always reset gesture handler to NULL on gesture-end Created 6 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698