Index: ui/views/widget/root_view.cc |
diff --git a/ui/views/widget/root_view.cc b/ui/views/widget/root_view.cc |
index 35e85a37a00f975c5cc780bf40ed941a84c365ef..f3ad2a08d6849b779e7bf5634218b57b6144176f 100644 |
--- a/ui/views/widget/root_view.cc |
+++ b/ui/views/widget/root_view.cc |
@@ -19,6 +19,7 @@ |
#include "ui/views/views_switches.h" |
#include "ui/views/widget/widget.h" |
#include "ui/views/widget/widget_delegate.h" |
+#include "ui/views/widget/widget_deletion_observer.h" |
#if defined(USE_AURA) |
#include "ui/base/cursor/cursor.h" |
@@ -140,11 +141,7 @@ |
void RootView::DispatchScrollEvent(ui::ScrollEvent* event) { |
for (View* v = GetEventHandlerForPoint(event->location()); |
v && v != this && !event->stopped_propagation(); v = v->parent()) { |
- ui::EventDispatchDetails dispatch_details = DispatchEventToTarget(v, event); |
- if (dispatch_details.dispatcher_destroyed || |
- dispatch_details.target_destroyed) { |
- return; |
- } |
+ DispatchEventToTarget(v, event); |
} |
if (event->handled() || event->type() != ui::ET_SCROLL) |
@@ -168,14 +165,11 @@ |
if (touch_pressed_handler_) { |
ui::TouchEvent touch_event(*event, static_cast<View*>(this), |
touch_pressed_handler_); |
- ui::EventDispatchDetails dispatch_details = |
- DispatchEventToTarget(touch_pressed_handler_, &touch_event); |
+ DispatchEventToTarget(touch_pressed_handler_, &touch_event); |
if (touch_event.handled()) |
event->SetHandled(); |
if (touch_event.stopped_propagation()) |
event->StopPropagation(); |
- if (dispatch_details.dispatcher_destroyed) |
- return; |
return; |
} |
@@ -191,14 +185,11 @@ |
// See if this view wants to handle the touch |
ui::TouchEvent touch_event(*event, static_cast<View*>(this), |
touch_pressed_handler_); |
- ui::EventDispatchDetails dispatch_details = |
- DispatchEventToTarget(touch_pressed_handler_, &touch_event); |
+ DispatchEventToTarget(touch_pressed_handler_, &touch_event); |
if (touch_event.handled()) |
event->SetHandled(); |
if (touch_event.stopped_propagation()) |
event->StopPropagation(); |
- if (dispatch_details.dispatcher_destroyed) |
- return; |
// The view could have removed itself from the tree when handling |
// OnTouchEvent(). So handle as per OnMousePressed. NB: we |
@@ -233,10 +224,7 @@ |
(event->IsScrollGestureEvent() || event->IsFlingScrollEvent()) ? |
scroll_gesture_handler_ : gesture_handler_; |
ui::GestureEvent handler_event(*event, static_cast<View*>(this), handler); |
- ui::EventDispatchDetails dispatch_details = |
- DispatchEventToTarget(handler, &handler_event); |
- if (dispatch_details.dispatcher_destroyed) |
- return; |
+ DispatchEventToTarget(handler, &handler_event); |
if (event->type() == ui::ET_GESTURE_END && |
event->details().touch_points() <= 1) { |
@@ -273,15 +261,12 @@ |
scroll_gesture_handler_ = scroll_gesture_handler_->parent()) { |
ui::GestureEvent gesture_event(*event, static_cast<View*>(this), |
scroll_gesture_handler_); |
- ui::EventDispatchDetails dispatch_details = |
- DispatchEventToTarget(scroll_gesture_handler_, &gesture_event); |
+ DispatchEventToTarget(scroll_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) { |
return; |
} |
} |
@@ -327,10 +312,7 @@ |
// See if this view wants to handle the Gesture. |
ui::GestureEvent gesture_event(*event, static_cast<View*>(this), |
gesture_handler_); |
- ui::EventDispatchDetails dispatch_details = |
- DispatchEventToTarget(gesture_handler_, &gesture_event); |
- if (dispatch_details.dispatcher_destroyed) |
- return; |
+ DispatchEventToTarget(gesture_handler_, &gesture_event); |
// The view could have removed itself from the tree when handling |
// OnGestureEvent(). So handle as per OnMousePressed. NB: we |
@@ -437,10 +419,7 @@ |
ui::MouseEvent mouse_pressed_event(event, static_cast<View*>(this), |
mouse_pressed_handler_); |
drag_info_.Reset(); |
- ui::EventDispatchDetails dispatch_details = |
- DispatchEventToTarget(mouse_pressed_handler_, &mouse_pressed_event); |
- if (dispatch_details.dispatcher_destroyed) |
- return true; |
+ DispatchEventToTarget(mouse_pressed_handler_, &mouse_pressed_event); |
return true; |
} |
DCHECK(!explicit_mouse_handler_); |
@@ -468,10 +447,12 @@ |
mouse_pressed_event.set_flags(event.flags() & ~ui::EF_IS_DOUBLE_CLICK); |
drag_info_.Reset(); |
- ui::EventDispatchDetails dispatch_details = |
- DispatchEventToTarget(mouse_pressed_handler_, &mouse_pressed_event); |
- if (dispatch_details.dispatcher_destroyed) |
- return mouse_pressed_event.handled(); |
+ { |
+ WidgetDeletionObserver widget_deletion_observer(widget_); |
+ DispatchEventToTarget(mouse_pressed_handler_, &mouse_pressed_event); |
+ if (!widget_deletion_observer.IsWidgetAlive()) |
+ return mouse_pressed_event.handled(); |
+ } |
// The view could have removed itself from the tree when handling |
// OnMousePressed(). In this case, the removal notification will have |
@@ -514,10 +495,7 @@ |
ui::MouseEvent mouse_event(event, static_cast<View*>(this), |
mouse_pressed_handler_); |
- ui::EventDispatchDetails dispatch_details = |
- DispatchEventToTarget(mouse_pressed_handler_, &mouse_event); |
- if (dispatch_details.dispatcher_destroyed) |
- return false; |
+ DispatchEventToTarget(mouse_pressed_handler_, &mouse_event); |
} |
return false; |
} |
@@ -532,10 +510,8 @@ |
// configure state such that we're done first, then call View. |
View* mouse_pressed_handler = mouse_pressed_handler_; |
SetMouseHandler(NULL); |
- ui::EventDispatchDetails dispatch_details = |
- DispatchEventToTarget(mouse_pressed_handler, &mouse_released); |
- if (dispatch_details.dispatcher_destroyed) |
- return; |
+ DispatchEventToTarget(mouse_pressed_handler, &mouse_released); |
+ // WARNING: we may have been deleted. |
} |
} |
@@ -579,10 +555,7 @@ |
(!mouse_move_handler_->notify_enter_exit_on_child() || |
!mouse_move_handler_->Contains(v))) { |
MouseEnterExitEvent exit(event, ui::ET_MOUSE_EXITED); |
- ui::EventDispatchDetails dispatch_details = |
- DispatchEventToTarget(mouse_move_handler_, &exit); |
- if (dispatch_details.dispatcher_destroyed) |
- return; |
+ DispatchEventToTarget(mouse_move_handler_, &exit); |
NotifyEnterExitOfDescendant(event, ui::ET_MOUSE_EXITED, |
mouse_move_handler_, v); |
} |
@@ -593,10 +566,7 @@ |
MouseEnterExitEvent entered(event, ui::ET_MOUSE_ENTERED); |
entered.ConvertLocationToTarget(static_cast<View*>(this), |
mouse_move_handler_); |
- ui::EventDispatchDetails dispatch_details = |
- DispatchEventToTarget(mouse_move_handler_, &entered); |
- if (dispatch_details.dispatcher_destroyed) |
- return; |
+ DispatchEventToTarget(mouse_move_handler_, &entered); |
NotifyEnterExitOfDescendant(entered, ui::ET_MOUSE_ENTERED, v, |
old_handler); |
} |
@@ -608,10 +578,7 @@ |
widget_->SetCursor(mouse_move_handler_->GetCursor(moved_event)); |
} else if (mouse_move_handler_ != NULL) { |
MouseEnterExitEvent exited(event, ui::ET_MOUSE_EXITED); |
- ui::EventDispatchDetails dispatch_details = |
- DispatchEventToTarget(mouse_move_handler_, &exited); |
- if (dispatch_details.dispatcher_destroyed) |
- return; |
+ DispatchEventToTarget(mouse_move_handler_, &exited); |
NotifyEnterExitOfDescendant(event, ui::ET_MOUSE_EXITED, |
mouse_move_handler_, v); |
// On Aura the non-client area extends slightly outside the root view for |
@@ -626,10 +593,7 @@ |
void RootView::OnMouseExited(const ui::MouseEvent& event) { |
if (mouse_move_handler_ != NULL) { |
MouseEnterExitEvent exited(event, ui::ET_MOUSE_EXITED); |
- ui::EventDispatchDetails dispatch_details = |
- DispatchEventToTarget(mouse_move_handler_, &exited); |
- if (dispatch_details.dispatcher_destroyed) |
- return; |
+ DispatchEventToTarget(mouse_move_handler_, &exited); |
NotifyEnterExitOfDescendant(event, ui::ET_MOUSE_EXITED, |
mouse_move_handler_, NULL); |
mouse_move_handler_ = NULL; |
@@ -638,14 +602,8 @@ |
bool RootView::OnMouseWheel(const ui::MouseWheelEvent& event) { |
for (View* v = GetEventHandlerForPoint(event.location()); |
- v && v != this && !event.handled(); v = v->parent()) { |
- ui::EventDispatchDetails dispatch_details = |
- DispatchEventToTarget(v, const_cast<ui::MouseWheelEvent*>(&event)); |
- if (dispatch_details.dispatcher_destroyed || |
- dispatch_details.target_destroyed) { |
- return event.handled(); |
- } |
- } |
+ v && v != this && !event.handled(); v = v->parent()) |
+ DispatchEventToTarget(v, const_cast<ui::MouseWheelEvent*>(&event)); |
return event.handled(); |
} |
@@ -744,14 +702,12 @@ |
last_mouse_event_y_ = event.y(); |
} |
-ui::EventDispatchDetails RootView::DispatchEventToTarget(View* target, |
- ui::Event* event) { |
+void RootView::DispatchEventToTarget(View* target, ui::Event* event) { |
View* old_target = event_dispatch_target_; |
event_dispatch_target_ = target; |
ui::EventDispatchDetails details = DispatchEvent(target, event); |
if (!details.dispatcher_destroyed) |
event_dispatch_target_ = old_target; |
- return details; |
} |
void RootView::NotifyEnterExitOfDescendant(const ui::MouseEvent& event, |
@@ -767,24 +723,20 @@ |
// of the callbacks can mark the event as handled, and that would cause |
// incorrect event dispatch. |
MouseEnterExitEvent notify_event(event, type); |
- ui::EventDispatchDetails dispatch_details = |
- DispatchEventToTarget(p, ¬ify_event); |
- if (dispatch_details.dispatcher_destroyed || |
- dispatch_details.target_destroyed) { |
+ DispatchEventToTarget(p, ¬ify_event); |
+ } |
+} |
+ |
+ |
+void RootView::DispatchKeyEventStartAt(View* view, ui::KeyEvent* event) { |
+ if (event->handled() || !view) |
+ return; |
+ |
+ for (; view && view != this; view = view->parent()) { |
+ DispatchEventToTarget(view, event); |
+ // Do this check here rather than in the if as |view| may have been deleted. |
+ if (event->handled()) |
return; |
- } |
- } |
-} |
- |
- |
-void RootView::DispatchKeyEventStartAt(View* view, ui::KeyEvent* event) { |
- for (; view && view != this && !event->handled(); view = view->parent()) { |
- ui::EventDispatchDetails dispatch_details = |
- DispatchEventToTarget(view, event); |
- if (dispatch_details.dispatcher_destroyed || |
- dispatch_details.target_destroyed) { |
- return; |
- } |
} |
} |