| Index: ui/views/widget/root_view.cc
|
| diff --git a/ui/views/widget/root_view.cc b/ui/views/widget/root_view.cc
|
| index 01d8b0209c8981735238ea1000c5e9ff8d21c94f..603b906e837669f756b06c0f1d36dca5795b36d1 100644
|
| --- a/ui/views/widget/root_view.cc
|
| +++ b/ui/views/widget/root_view.cc
|
| @@ -28,24 +28,19 @@ enum EventType {
|
| EVENT_EXIT
|
| };
|
|
|
| -// |view| is the view receiving |event|. This function sends the event to all
|
| -// the Views up the hierarchy that has |notify_enter_exit_on_child_| flag turned
|
| -// on, but does not contain |sibling|.
|
| -void NotifyEnterExitOfDescendant(const ui::MouseEvent& event,
|
| - EventType type,
|
| - View* view,
|
| - View* sibling) {
|
| - for (View* p = view->parent(); p; p = p->parent()) {
|
| - if (!p->notify_enter_exit_on_child())
|
| - continue;
|
| - if (sibling && p->Contains(sibling))
|
| - break;
|
| - if (type == EVENT_ENTER)
|
| - p->OnMouseEntered(event);
|
| - else
|
| - p->OnMouseExited(event);
|
| +class MouseEnterExitEvent : public ui::MouseEvent {
|
| + public:
|
| + MouseEnterExitEvent(const ui::MouseEvent& event, ui::EventType type)
|
| + : ui::MouseEvent(event,
|
| + static_cast<View*>(NULL),
|
| + static_cast<View*>(NULL)) {
|
| + DCHECK(type == ui::ET_MOUSE_ENTERED ||
|
| + type == ui::ET_MOUSE_EXITED);
|
| + SetType(type);
|
| }
|
| -}
|
| +
|
| + virtual ~MouseEnterExitEvent() {}
|
| +};
|
|
|
| } // namespace
|
|
|
| @@ -151,7 +146,8 @@ void RootView::DispatchScrollEvent(ui::ScrollEvent* event) {
|
| View* v = GetEventHandlerForPoint(wheel.location());
|
| if (v != focused_view) {
|
| for (; v && v != this; v = v->parent()) {
|
| - if (v->OnMouseWheel(wheel)) {
|
| + DispatchEventToTarget(v, &wheel);
|
| + if (wheel.handled()) {
|
| event->SetHandled();
|
| break;
|
| }
|
| @@ -408,8 +404,7 @@ bool RootView::OnMousePressed(const ui::MouseEvent& event) {
|
| ui::MouseEvent mouse_pressed_event(event, static_cast<View*>(this),
|
| mouse_pressed_handler_);
|
| drag_info_.Reset();
|
| - mouse_pressed_handler_->ProcessMousePressed(mouse_pressed_event,
|
| - &drag_info_);
|
| + DispatchEventToTarget(mouse_pressed_handler_, &mouse_pressed_event);
|
| return true;
|
| }
|
| DCHECK(!explicit_mouse_handler_);
|
| @@ -437,8 +432,7 @@ bool RootView::OnMousePressed(const ui::MouseEvent& event) {
|
| mouse_pressed_event.set_flags(event.flags() & ~ui::EF_IS_DOUBLE_CLICK);
|
|
|
| drag_info_.Reset();
|
| - bool handled = mouse_pressed_handler_->ProcessMousePressed(
|
| - mouse_pressed_event, &drag_info_);
|
| + DispatchEventToTarget(mouse_pressed_handler_, &mouse_pressed_event);
|
|
|
| // The view could have removed itself from the tree when handling
|
| // OnMousePressed(). In this case, the removal notification will have
|
| @@ -453,7 +447,7 @@ bool RootView::OnMousePressed(const ui::MouseEvent& event) {
|
| // If the view handled the event, leave mouse_pressed_handler_ set and
|
| // return true, which will cause subsequent drag/release events to get
|
| // forwarded to that view.
|
| - if (handled) {
|
| + if (mouse_pressed_event.handled()) {
|
| last_click_handler_ = mouse_pressed_handler_;
|
| DVLOG(1) << "OnMousePressed handled by "
|
| << mouse_pressed_handler_->GetClassName();
|
| @@ -481,8 +475,8 @@ bool RootView::OnMouseDragged(const ui::MouseEvent& event) {
|
|
|
| ui::MouseEvent mouse_event(event, static_cast<View*>(this),
|
| mouse_pressed_handler_);
|
| - return mouse_pressed_handler_->ProcessMouseDragged(mouse_event,
|
| - &drag_info_);
|
| + DispatchEventToTarget(mouse_pressed_handler_, &mouse_event);
|
| + return mouse_event.handled();
|
| }
|
| return false;
|
| }
|
| @@ -493,17 +487,11 @@ void RootView::OnMouseReleased(const ui::MouseEvent& event) {
|
| if (mouse_pressed_handler_) {
|
| ui::MouseEvent mouse_released(event, static_cast<View*>(this),
|
| mouse_pressed_handler_);
|
| - // TODO(sadrul|oshima): This is tentative solution to pass target
|
| - // to LauncherDelegate::ItemClicked. Remove this once crbug.com/173235
|
| - // is implemented.
|
| - ui::Event::DispatcherApi api(&mouse_released);
|
| - api.set_target(this);
|
| -
|
| - // We allow the view to delete us from ProcessMouseReleased. As such,
|
| + // We allow the view to delete us from the event dispatch callback. As such,
|
| // configure state such that we're done first, then call View.
|
| View* mouse_pressed_handler = mouse_pressed_handler_;
|
| SetMouseHandler(NULL);
|
| - mouse_pressed_handler->ProcessMouseReleased(mouse_released);
|
| + DispatchEventToTarget(mouse_pressed_handler, &mouse_released);
|
| // WARNING: we may have been deleted.
|
| }
|
| }
|
| @@ -546,28 +534,31 @@ void RootView::OnMouseMoved(const ui::MouseEvent& event) {
|
| if (mouse_move_handler_ != NULL &&
|
| (!mouse_move_handler_->notify_enter_exit_on_child() ||
|
| !mouse_move_handler_->Contains(v))) {
|
| - mouse_move_handler_->OnMouseExited(event);
|
| - NotifyEnterExitOfDescendant(event, EVENT_EXIT, mouse_move_handler_, v);
|
| + MouseEnterExitEvent exit(event, ui::ET_MOUSE_EXITED);
|
| + DispatchEventToTarget(mouse_move_handler_, &exit);
|
| + NotifyEnterExitOfDescendant(event, ui::ET_MOUSE_EXITED,
|
| + mouse_move_handler_, v);
|
| }
|
| View* old_handler = mouse_move_handler_;
|
| mouse_move_handler_ = v;
|
| - ui::MouseEvent entered_event(event, static_cast<View*>(this),
|
| - mouse_move_handler_);
|
| if (!mouse_move_handler_->notify_enter_exit_on_child() ||
|
| !mouse_move_handler_->Contains(old_handler)) {
|
| - mouse_move_handler_->OnMouseEntered(entered_event);
|
| - NotifyEnterExitOfDescendant(entered_event, EVENT_ENTER, v,
|
| + MouseEnterExitEvent entered(event, ui::ET_MOUSE_ENTERED);
|
| + DispatchEventToTarget(mouse_move_handler_, &entered);
|
| + NotifyEnterExitOfDescendant(event, ui::ET_MOUSE_ENTERED, v,
|
| old_handler);
|
| }
|
| }
|
| ui::MouseEvent moved_event(event, static_cast<View*>(this),
|
| mouse_move_handler_);
|
| - mouse_move_handler_->OnMouseMoved(moved_event);
|
| + DispatchEventToTarget(mouse_move_handler_, &moved_event);
|
| if (!(moved_event.flags() & ui::EF_IS_NON_CLIENT))
|
| widget_->SetCursor(mouse_move_handler_->GetCursor(moved_event));
|
| } else if (mouse_move_handler_ != NULL) {
|
| - mouse_move_handler_->OnMouseExited(event);
|
| - NotifyEnterExitOfDescendant(event, EVENT_EXIT, mouse_move_handler_, v);
|
| + MouseEnterExitEvent exited(event, ui::ET_MOUSE_EXITED);
|
| + 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
|
| // some windows. Let the non-client cursor handling code set the cursor
|
| // as we do above.
|
| @@ -579,18 +570,19 @@ void RootView::OnMouseMoved(const ui::MouseEvent& event) {
|
|
|
| void RootView::OnMouseExited(const ui::MouseEvent& event) {
|
| if (mouse_move_handler_ != NULL) {
|
| - mouse_move_handler_->OnMouseExited(event);
|
| - NotifyEnterExitOfDescendant(event, EVENT_EXIT, mouse_move_handler_, NULL);
|
| + MouseEnterExitEvent exited(event, ui::ET_MOUSE_EXITED);
|
| + DispatchEventToTarget(mouse_move_handler_, &exited);
|
| + NotifyEnterExitOfDescendant(event, ui::ET_MOUSE_EXITED,
|
| + mouse_move_handler_, NULL);
|
| mouse_move_handler_ = NULL;
|
| }
|
| }
|
|
|
| bool RootView::OnMouseWheel(const ui::MouseWheelEvent& event) {
|
| - bool consumed = false;
|
| for (View* v = GetFocusManager() ? GetFocusManager()->GetFocusedView() : NULL;
|
| - v && v != this && !consumed; v = v->parent())
|
| - consumed = v->OnMouseWheel(event);
|
| - return consumed;
|
| + v && v != this && !event.handled(); v = v->parent())
|
| + DispatchEventToTarget(v, const_cast<ui::MouseWheelEvent*>(&event));
|
| + return event.handled();
|
| }
|
|
|
| void RootView::SetMouseHandler(View* new_mh) {
|
| @@ -651,6 +643,10 @@ gfx::Vector2d RootView::CalculateOffsetToAncestorWithLayer(
|
| return offset;
|
| }
|
|
|
| +View::DragInfo* RootView::GetDragInfo() {
|
| + return &drag_info_;
|
| +}
|
| +
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // RootView, private:
|
|
|
| @@ -677,6 +673,23 @@ void RootView::DispatchEventToTarget(View* target, ui::Event* event) {
|
| event_dispatch_target_ = old_target;
|
| }
|
|
|
| +void RootView::NotifyEnterExitOfDescendant(const ui::MouseEvent& event,
|
| + ui::EventType type,
|
| + View* view,
|
| + View* sibling) {
|
| + for (View* p = view->parent(); p; p = p->parent()) {
|
| + if (!p->notify_enter_exit_on_child())
|
| + continue;
|
| + if (sibling && p->Contains(sibling))
|
| + break;
|
| + // It is necessary to recreate the notify-event for each dispatch, since one
|
| + // of the callbacks can mark the event as handled, and that would cause
|
| + // incorrect event dispatch.
|
| + MouseEnterExitEvent notify_event(event, type);
|
| + DispatchEventToTarget(p, ¬ify_event);
|
| + }
|
| +}
|
| +
|
| bool RootView::CanDispatchToTarget(ui::EventTarget* target) {
|
| return event_dispatch_target_ == target;
|
| }
|
|
|