Commit 6942fdd7 authored by tdanderson's avatar tdanderson Committed by Commit bot

Condense RootView::DispatchGestureEvent() to a single loop

Remove the unnecessary code from RootView::DispatchGestureEvent()
by condensing it to a single loop and moving parts of
the implementation into RootView::PreDispatchEvent() and
RootView::PostDispatchEvent().

BUG=404228
TEST=covered by existing unit tests

Review URL: https://codereview.chromium.org/517023004

Cr-Commit-Position: refs/heads/master@{#293055}
parent 3992d7bb
...@@ -250,12 +250,6 @@ ui::EventTarget* RootView::GetRootTarget() { ...@@ -250,12 +250,6 @@ ui::EventTarget* RootView::GetRootTarget() {
} }
ui::EventDispatchDetails RootView::OnEventFromSource(ui::Event* event) { 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()) if (event->IsKeyEvent())
return EventProcessor::OnEventFromSource(event); return EventProcessor::OnEventFromSource(event);
...@@ -263,6 +257,14 @@ ui::EventDispatchDetails RootView::OnEventFromSource(ui::Event* event) { ...@@ -263,6 +257,14 @@ ui::EventDispatchDetails RootView::OnEventFromSource(ui::Event* event) {
return EventProcessor::OnEventFromSource(event); return EventProcessor::OnEventFromSource(event);
if (event->IsGestureEvent()) { 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(); ui::GestureEvent* gesture_event = event->AsGestureEvent();
// Do not dispatch ui::ET_GESTURE_BEGIN events. // Do not dispatch ui::ET_GESTURE_BEGIN events.
...@@ -644,127 +646,40 @@ View::DragInfo* RootView::GetDragInfo() { ...@@ -644,127 +646,40 @@ View::DragInfo* RootView::GetDragInfo() {
// Input ----------------------------------------------------------------------- // Input -----------------------------------------------------------------------
void RootView::DispatchGestureEvent(ui::GestureEvent* event) { void RootView::DispatchGestureEvent(ui::GestureEvent* event) {
if (gesture_handler_) { bool gesture_handler_set_before_dispatch = !!gesture_handler_;
if (gesture_handler_->enabled()) { View* target =
// |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_ =
static_cast<View*>(targeter()->FindTargetForEvent(this, event)); static_cast<View*>(targeter()->FindTargetForEvent(this, event));
while (gesture_handler_ && gesture_handler_ != this) { while (target && target != this) {
// Disabled views are permitted to be targets of gesture events, but // Create and dispatch a copy of |event|.
// gesture events should never actually be dispatched to them. ui::GestureEvent event_copy(*event, static_cast<View*>(this), target);
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_);
ui::EventDispatchDetails dispatch_details = ui::EventDispatchDetails dispatch_details =
DispatchEvent(gesture_handler_, &gesture_event); DispatchEvent(target, &event_copy);
if (dispatch_details.dispatcher_destroyed) if (dispatch_details.dispatcher_destroyed)
return; return;
// The view could have removed itself from the tree when handling if (event_copy.stopped_propagation())
// OnGestureEvent(). So handle as per OnMousePressed. NB: we event->StopPropagation();
// assume that the RootView itself cannot be so removed. else if (event_copy.handled())
if (!gesture_handler_) event->SetHandled();
return;
if (gesture_event.handled()) { // If the event was handled by the previous dispatch or if the target
if (gesture_event.stopped_propagation()) // was destroyed, do not allow any further processing of |event|.
event->StopPropagation(); if (event->handled() || dispatch_details.target_destroyed)
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;
}
return; return;
}
// The gesture event wasn't processed. Go up the view hierarchy and // The event was not handled by |target|, so continue processing by
// dispatch the gesture event. // re-targeting the event.
gesture_handler_ = static_cast<View*>( target = static_cast<View*>(targeter()->FindNextBestTarget(target, event));
targeter()->FindNextBestTarget(gesture_handler_, 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) { void RootView::UpdateCursor(const ui::MouseEvent& event) {
...@@ -808,13 +723,38 @@ bool RootView::CanDispatchToTarget(ui::EventTarget* target) { ...@@ -808,13 +723,38 @@ bool RootView::CanDispatchToTarget(ui::EventTarget* target) {
ui::EventDispatchDetails RootView::PreDispatchEvent(ui::EventTarget* target, ui::EventDispatchDetails RootView::PreDispatchEvent(ui::EventTarget* target,
ui::Event* event) { 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_; old_dispatch_target_ = event_dispatch_target_;
event_dispatch_target_ = static_cast<View*>(target); event_dispatch_target_ = view;
return DispatchDetails(); return DispatchDetails();
} }
ui::EventDispatchDetails RootView::PostDispatchEvent(ui::EventTarget* target, ui::EventDispatchDetails RootView::PostDispatchEvent(ui::EventTarget* target,
const ui::Event& event) { 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; DispatchDetails details;
if (target != event_dispatch_target_) if (target != event_dispatch_target_)
details.target_destroyed = true; details.target_destroyed = true;
......
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