15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/root_view.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/accessibility/ax_view_state.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/base/cursor/cursor.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/dragdrop/drag_drop_types.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/base/ui_base_switches_util.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h"
16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/keycodes/keyboard_codes.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/views/drag_controller.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/focus/view_storage.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/fill_layout.h"
22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/views/view_targeter.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/views/views_switches.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget_delegate.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)typedef ui::EventDispatchDetails DispatchDetails;
28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum EventType {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EVENT_ENTER,
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EVENT_EXIT
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MouseEnterExitEvent : public ui::MouseEvent {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MouseEnterExitEvent(const ui::MouseEvent& event, ui::EventType type)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : ui::MouseEvent(event,
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       static_cast<View*>(NULL),
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       static_cast<View*>(NULL)) {
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(type == ui::ET_MOUSE_ENTERED ||
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           type == ui::ET_MOUSE_EXITED);
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetType(type);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~MouseEnterExitEvent() {}
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// This event handler receives events in the pre-target phase and takes care of
56e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// the following:
57e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch//   - Shows keyboard-triggered context menus.
58e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass PreEventDispatchHandler : public ui::EventHandler {
59e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch public:
60e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  explicit PreEventDispatchHandler(View* owner)
61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      : owner_(owner) {
62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
63e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  virtual ~PreEventDispatchHandler() {}
64e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
65e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch private:
66e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // ui::EventHandler:
67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
68e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    CHECK_EQ(ui::EP_PRETARGET, event->phase());
69e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (event->handled())
70e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      return;
71e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
72e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    View* v = NULL;
73e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (owner_->GetFocusManager())  // Can be NULL in unittests.
74e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      v = owner_->GetFocusManager()->GetFocusedView();
75e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
76e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    // Special case to handle keyboard-triggered context menus.
77e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (v && v->enabled() && ((event->key_code() == ui::VKEY_APPS) ||
78e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch       (event->key_code() == ui::VKEY_F10 && event->IsShiftDown()))) {
79e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      // Clamp the menu location within the visible bounds of each ancestor view
80e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      // to avoid showing the menu over a completely different view or window.
81e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      gfx::Point location = v->GetKeyboardContextMenuLocation();
82e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      for (View* parent = v->parent(); parent; parent = parent->parent()) {
83e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        const gfx::Rect& parent_bounds = parent->GetBoundsInScreen();
84e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        location.SetToMax(parent_bounds.origin());
85e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch        location.SetToMin(parent_bounds.bottom_right());
86e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      }
87e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      v->ShowContextMenu(location, ui::MENU_SOURCE_KEYBOARD);
88e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      event->StopPropagation();
89e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    }
90e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
91e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  View* owner_;
93e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  DISALLOW_COPY_AND_ASSIGN(PreEventDispatchHandler);
95e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch};
96e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// This event handler receives events in the post-target phase and takes care of
98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// the following:
99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)//   - Generates context menu, or initiates drag-and-drop, from gesture events.
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class PostEventDispatchHandler : public ui::EventHandler {
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public:
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PostEventDispatchHandler()
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : touch_dnd_enabled_(::switches::IsTouchDragDropEnabled()) {
104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual ~PostEventDispatchHandler() {}
106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private:
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Overridden from ui::EventHandler:
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DCHECK_EQ(ui::EP_POSTTARGET, event->phase());
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (event->handled())
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return;
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    View* target = static_cast<View*>(event->target());
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    gfx::Point location = event->location();
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (touch_dnd_enabled_ &&
117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        event->type() == ui::ET_GESTURE_LONG_PRESS &&
118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        (!target->drag_controller() ||
119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         target->drag_controller()->CanStartDragForView(
120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)             target, location, location))) {
121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (target->DoDrag(*event, location,
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH)) {
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        event->StopPropagation();
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return;
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (target->context_menu_controller() &&
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        (event->type() == ui::ET_GESTURE_LONG_PRESS ||
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         event->type() == ui::ET_GESTURE_LONG_TAP ||
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         event->type() == ui::ET_GESTURE_TWO_FINGER_TAP)) {
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      gfx::Point screen_location(location);
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      View::ConvertPointToScreen(target, &screen_location);
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      target->ShowContextMenu(screen_location, ui::MENU_SOURCE_TOUCH);
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      event->StopPropagation();
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool touch_dnd_enabled_;
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PostEventDispatchHandler);
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char RootView::kViewClassName[] = "RootView";
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RootView, public:
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creation and lifetime -------------------------------------------------------
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RootView::RootView(Widget* widget)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : widget_(widget),
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_pressed_handler_(NULL),
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_move_handler_(NULL),
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_click_handler_(NULL),
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      explicit_mouse_handler_(false),
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_mouse_event_flags_(0),
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_mouse_event_x_(-1),
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_mouse_event_y_(-1),
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_handler_(NULL),
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scroll_gesture_handler_(NULL),
163e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      pre_dispatch_handler_(new internal::PreEventDispatchHandler(this)),
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      post_dispatch_handler_(new internal::PostEventDispatchHandler),
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      focus_search_(this, false, false),
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      focus_traversable_parent_(NULL),
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      focus_traversable_parent_view_(NULL),
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      event_dispatch_target_(NULL),
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      old_dispatch_target_(NULL) {
170e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  AddPreTargetHandler(pre_dispatch_handler_.get());
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  AddPostTargetHandler(post_dispatch_handler_.get());
172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SetEventTargeter(scoped_ptr<ui::EventTargeter>(new ViewTargeter()));
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RootView::~RootView() {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we have children remove them explicitly so to make sure a remove
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notification is sent for each one of them.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_children())
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RemoveAllChildViews(true);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tree operations -------------------------------------------------------------
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::SetContentsView(View* contents_view) {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(contents_view && GetWidget()->native_widget()) <<
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Can't be called until after the native widget is created!";
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The ContentsView must be set up _after_ the window is created so that its
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Widget pointer is valid.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetLayoutManager(new FillLayout);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_children())
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RemoveAllChildViews(true);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddChildView(contents_view);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Force a layout now, since the attached hierarchy won't be ready for the
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // containing window's bounds. Note that we call Layout directly rather than
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // calling the widget's size changed handler, since the RootView's bounds may
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not have changed, which will cause the Layout not to be done otherwise.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Layout();
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)View* RootView::GetContentsView() {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return child_count() > 0 ? child_at(0) : NULL;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void RootView::NotifyNativeViewHierarchyChanged() {
206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  PropagateNativeViewHierarchyChanged();
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Focus -----------------------------------------------------------------------
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::SetFocusTraversableParent(FocusTraversable* focus_traversable) {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(focus_traversable != this);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  focus_traversable_parent_ = focus_traversable;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::SetFocusTraversableParentView(View* view) {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  focus_traversable_parent_view_ = view;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// System events ---------------------------------------------------------------
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::ThemeChanged() {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View::PropagateThemeChanged();
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::LocaleChanged() {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View::PropagateLocaleChanged();
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RootView, FocusTraversable implementation:
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FocusSearch* RootView::GetFocusSearch() {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &focus_search_;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FocusTraversable* RootView::GetFocusTraversableParent() {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return focus_traversable_parent_;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)View* RootView::GetFocusTraversableParentView() {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return focus_traversable_parent_view_;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// RootView, ui::EventProcessor overrides:
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ui::EventTarget* RootView::GetRootTarget() {
249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return this;
250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ui::EventDispatchDetails RootView::OnEventFromSource(ui::Event* event) {
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(tdanderson): Replace the calls to Dispatch*Event() with calls to
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  //                   EventProcessor::OnEventFromSource() once the code for
255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  //                   that event type has been refactored, and then
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  //                   eventually remove this function altogether. See
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  //                   crbug.com/348083.
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (event->IsKeyEvent())
259c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return EventProcessor::OnEventFromSource(event);
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  else if (event->IsScrollEvent())
261010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return EventProcessor::OnEventFromSource(event);
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  else if (event->IsTouchEvent())
263e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    NOTREACHED() << "Touch events should not be sent to RootView.";
264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  else if (event->IsGestureEvent())
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DispatchGestureEvent(static_cast<ui::GestureEvent*>(event));
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  else if (event->IsMouseEvent())
267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NOTREACHED() << "Should not be called with a MouseEvent.";
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  else
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NOTREACHED() << "Invalid event type.";
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return DispatchDetails();
272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RootView, View overrides:
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Widget* RootView::GetWidget() const {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return widget_;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Widget* RootView::GetWidget() {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return const_cast<Widget*>(const_cast<const RootView*>(this)->GetWidget());
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RootView::IsDrawn() const {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return visible();
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void RootView::Layout() {
29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  View::Layout();
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  widget_->OnRootViewLayout();
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
29358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
294b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char* RootView::GetClassName() const {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return kViewClassName;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::SchedulePaintInRect(const gfx::Rect& rect) {
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (layer()) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layer()->SchedulePaint(rect);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Rect xrect = ConvertRectToParent(rect);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Rect invalid_rect = gfx::IntersectRects(GetLocalBounds(), xrect);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!invalid_rect.IsEmpty())
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_->SchedulePaintInRect(invalid_rect);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RootView::OnMousePressed(const ui::MouseEvent& event) {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateCursor(event);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetMouseLocationAndFlags(event);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If mouse_pressed_handler_ is non null, we are currently processing
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a pressed -> drag -> released session. In that case we send the
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // event to mouse_pressed_handler_
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_pressed_handler_) {
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::MouseEvent mouse_pressed_event(event, static_cast<View*>(this),
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       mouse_pressed_handler_);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    drag_info_.Reset();
320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ui::EventDispatchDetails dispatch_details =
321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        DispatchEvent(mouse_pressed_handler_, &mouse_pressed_event);
322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (dispatch_details.dispatcher_destroyed)
323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return true;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!explicit_mouse_handler_);
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool hit_disabled_view = false;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Walk up the tree until we find a view that wants the mouse event.
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (mouse_pressed_handler_ = GetEventHandlerForPoint(event.location());
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       mouse_pressed_handler_ && (mouse_pressed_handler_ != this);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       mouse_pressed_handler_ = mouse_pressed_handler_->parent()) {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "OnMousePressed testing "
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << mouse_pressed_handler_->GetClassName();
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!mouse_pressed_handler_->enabled()) {
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Disabled views should eat events instead of propagating them upwards.
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hit_disabled_view = true;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // See if this view wants to handle the mouse press.
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::MouseEvent mouse_pressed_event(event, static_cast<View*>(this),
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       mouse_pressed_handler_);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Remove the double-click flag if the handler is different than the
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // one which got the first click part of the double-click.
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mouse_pressed_handler_ != last_click_handler_)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_pressed_event.set_flags(event.flags() & ~ui::EF_IS_DOUBLE_CLICK);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    drag_info_.Reset();
351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ui::EventDispatchDetails dispatch_details =
352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        DispatchEvent(mouse_pressed_handler_, &mouse_pressed_event);
353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (dispatch_details.dispatcher_destroyed)
354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return mouse_pressed_event.handled();
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The view could have removed itself from the tree when handling
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // OnMousePressed().  In this case, the removal notification will have
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // reset mouse_pressed_handler_ to NULL out from under us.  Detect this
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // case and stop.  (See comments in view.h.)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // NOTE: Don't return true here, because we don't want the frame to
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // forward future events to us when there's no handler.
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!mouse_pressed_handler_)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the view handled the event, leave mouse_pressed_handler_ set and
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // return true, which will cause subsequent drag/release events to get
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // forwarded to that view.
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (mouse_pressed_event.handled()) {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_click_handler_ = mouse_pressed_handler_;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "OnMousePressed handled by "
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << mouse_pressed_handler_->GetClassName();
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset mouse_pressed_handler_ to indicate that no processing is occurring.
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_pressed_handler_ = NULL;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In the event that a double-click is not handled after traversing the
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // entire hierarchy (even as a single-click when sent to a different view),
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it must be marked as handled to avoid anything happening from default
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // processing if it the first click-part was handled by us.
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (last_click_handler_ && (event.flags() & ui::EF_IS_DOUBLE_CLICK))
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hit_disabled_view = true;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_click_handler_ = NULL;
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hit_disabled_view;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RootView::OnMouseDragged(const ui::MouseEvent& event) {
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_pressed_handler_) {
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetMouseLocationAndFlags(event);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::MouseEvent mouse_event(event, static_cast<View*>(this),
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               mouse_pressed_handler_);
397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ui::EventDispatchDetails dispatch_details =
398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        DispatchEvent(mouse_pressed_handler_, &mouse_event);
399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (dispatch_details.dispatcher_destroyed)
400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return false;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::OnMouseReleased(const ui::MouseEvent& event) {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateCursor(event);
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_pressed_handler_) {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::MouseEvent mouse_released(event, static_cast<View*>(this),
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  mouse_pressed_handler_);
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We allow the view to delete us from the event dispatch callback. As such,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // configure state such that we're done first, then call View.
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    View* mouse_pressed_handler = mouse_pressed_handler_;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetMouseHandler(NULL);
415a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ui::EventDispatchDetails dispatch_details =
416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        DispatchEvent(mouse_pressed_handler, &mouse_released);
417a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (dispatch_details.dispatcher_destroyed)
418a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::OnMouseCaptureLost() {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO: this likely needs to reset touch handler too.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_pressed_handler_ || gesture_handler_) {
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Synthesize a release event for UpdateCursor.
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mouse_pressed_handler_) {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Point last_point(last_mouse_event_x_, last_mouse_event_y_);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED,
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   last_point, last_point,
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   last_mouse_event_flags_,
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   0);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UpdateCursor(release_event);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We allow the view to delete us from OnMouseCaptureLost. As such,
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // configure state such that we're done first, then call View.
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    View* mouse_pressed_handler = mouse_pressed_handler_;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    View* gesture_handler = gesture_handler_;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetMouseHandler(NULL);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mouse_pressed_handler)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_pressed_handler->OnMouseCaptureLost();
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_handler->OnMouseCaptureLost();
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // WARNING: we may have been deleted.
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::OnMouseMoved(const ui::MouseEvent& event) {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View* v = GetEventHandlerForPoint(event.location());
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Find the first enabled view, or the existing move handler, whichever comes
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first.  The check for the existing handler is because if a view becomes
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // disabled while handling moves, it's wrong to suddenly send ET_MOUSE_EXITED
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and ET_MOUSE_ENTERED events, because the mouse hasn't actually exited yet.
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (v && !v->enabled() && (v != mouse_move_handler_))
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v = v->parent();
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (v && v != this) {
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (v != mouse_move_handler_) {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (mouse_move_handler_ != NULL &&
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (!mouse_move_handler_->notify_enter_exit_on_child() ||
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           !mouse_move_handler_->Contains(v))) {
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        MouseEnterExitEvent exit(event, ui::ET_MOUSE_EXITED);
462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        exit.ConvertLocationToTarget(static_cast<View*>(this),
463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                     mouse_move_handler_);
464a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        ui::EventDispatchDetails dispatch_details =
465a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            DispatchEvent(mouse_move_handler_, &exit);
466a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        if (dispatch_details.dispatcher_destroyed)
467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          return;
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NotifyEnterExitOfDescendant(event, ui::ET_MOUSE_EXITED,
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            mouse_move_handler_, v);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      View* old_handler = mouse_move_handler_;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_move_handler_ = v;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!mouse_move_handler_->notify_enter_exit_on_child() ||
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !mouse_move_handler_->Contains(old_handler)) {
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        MouseEnterExitEvent entered(event, ui::ET_MOUSE_ENTERED);
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        entered.ConvertLocationToTarget(static_cast<View*>(this),
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        mouse_move_handler_);
478a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        ui::EventDispatchDetails dispatch_details =
479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            DispatchEvent(mouse_move_handler_, &entered);
480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        if (dispatch_details.dispatcher_destroyed)
481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          return;
482a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        NotifyEnterExitOfDescendant(event, ui::ET_MOUSE_ENTERED,
483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            mouse_move_handler_, old_handler);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::MouseEvent moved_event(event, static_cast<View*>(this),
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               mouse_move_handler_);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mouse_move_handler_->OnMouseMoved(moved_event);
489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // TODO(tdanderson): It may be possible to avoid setting the cursor twice
490a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    //                   (once here and once from CompoundEventFilter) on a
491a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    //                   mousemove. See crbug.com/351469.
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(moved_event.flags() & ui::EF_IS_NON_CLIENT))
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_->SetCursor(mouse_move_handler_->GetCursor(moved_event));
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (mouse_move_handler_ != NULL) {
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MouseEnterExitEvent exited(event, ui::ET_MOUSE_EXITED);
496a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ui::EventDispatchDetails dispatch_details =
497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        DispatchEvent(mouse_move_handler_, &exited);
498a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (dispatch_details.dispatcher_destroyed)
499a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NotifyEnterExitOfDescendant(event, ui::ET_MOUSE_EXITED,
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mouse_move_handler_, v);
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // On Aura the non-client area extends slightly outside the root view for
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // some windows.  Let the non-client cursor handling code set the cursor
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // as we do above.
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(event.flags() & ui::EF_IS_NON_CLIENT))
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_->SetCursor(gfx::kNullCursor);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mouse_move_handler_ = NULL;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::OnMouseExited(const ui::MouseEvent& event) {
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_move_handler_ != NULL) {
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MouseEnterExitEvent exited(event, ui::ET_MOUSE_EXITED);
514a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ui::EventDispatchDetails dispatch_details =
515a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        DispatchEvent(mouse_move_handler_, &exited);
516a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (dispatch_details.dispatcher_destroyed)
517a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NotifyEnterExitOfDescendant(event, ui::ET_MOUSE_EXITED,
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mouse_move_handler_, NULL);
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mouse_move_handler_ = NULL;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RootView::OnMouseWheel(const ui::MouseWheelEvent& event) {
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (View* v = GetEventHandlerForPoint(event.location());
526a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       v && v != this && !event.handled(); v = v->parent()) {
527a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ui::EventDispatchDetails dispatch_details =
528a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        DispatchEvent(v, const_cast<ui::MouseWheelEvent*>(&event));
529a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (dispatch_details.dispatcher_destroyed ||
530a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        dispatch_details.target_destroyed) {
531a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return event.handled();
532a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
533a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return event.handled();
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::SetMouseHandler(View* new_mh) {
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we're clearing the mouse handler, clear explicit_mouse_handler_ as well.
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit_mouse_handler_ = (new_mh != NULL);
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_pressed_handler_ = new_mh;
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gesture_handler_ = new_mh;
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scroll_gesture_handler_ = new_mh;
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  drag_info_.Reset();
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RootView::GetAccessibleState(ui::AXViewState* state) {
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state->name = widget_->widget_delegate()->GetAccessibleWindowTitle();
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state->role = widget_->widget_delegate()->GetAccessibleWindowRole();
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void RootView::UpdateParentLayer() {
55290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (layer())
55390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ReparentLayer(gfx::Vector2d(GetMirroredX(), y()), widget_->GetLayer());
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RootView, protected:
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
559a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void RootView::DispatchGestureEvent(ui::GestureEvent* event) {
560a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (gesture_handler_) {
561a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // |gesture_handler_| (or |scroll_gesture_handler_|) can be deleted during
562a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // processing.
563a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    View* handler = scroll_gesture_handler_ &&
564a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        (event->IsScrollGestureEvent() || event->IsFlingScrollEvent())  ?
565a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            scroll_gesture_handler_ : gesture_handler_;
566a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ui::GestureEvent handler_event(*event, static_cast<View*>(this), handler);
567a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ui::EventDispatchDetails dispatch_details =
568a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        DispatchEvent(handler, &handler_event);
569a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (dispatch_details.dispatcher_destroyed)
570a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
571a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
572a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (event->type() == ui::ET_GESTURE_END &&
573a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        event->details().touch_points() <= 1) {
574a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // In case a drag was in progress, reset all the handlers. Otherwise, just
575a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // reset the gesture handler.
576a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (gesture_handler_ == mouse_pressed_handler_)
577a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        SetMouseHandler(NULL);
578a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      else
579a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        gesture_handler_ = NULL;
580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
581a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
582a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (scroll_gesture_handler_ &&
583a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        (event->type() == ui::ET_GESTURE_SCROLL_END ||
584a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         event->type() == ui::ET_SCROLL_FLING_START)) {
585a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      scroll_gesture_handler_ = NULL;
586a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
588a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (handler_event.stopped_propagation()) {
589a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      event->StopPropagation();
590a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    } else if (handler_event.handled()) {
592a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      event->SetHandled();
593a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
594a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
595a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
596a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN &&
597a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        !scroll_gesture_handler_) {
598a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // Some view started processing gesture events, however it does not
599a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // process scroll-gesture events. In such case, we allow the event to
600a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // bubble up, and install a different scroll-gesture handler different
601a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // from the default gesture handler.
602a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      for (scroll_gesture_handler_ = gesture_handler_->parent();
603a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          scroll_gesture_handler_ && scroll_gesture_handler_ != this;
604a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          scroll_gesture_handler_ = scroll_gesture_handler_->parent()) {
605a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        ui::GestureEvent gesture_event(*event, static_cast<View*>(this),
606a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                       scroll_gesture_handler_);
607a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        ui::EventDispatchDetails dispatch_details =
608a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            DispatchEvent(scroll_gesture_handler_, &gesture_event);
609a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        if (gesture_event.stopped_propagation()) {
610a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          event->StopPropagation();
611a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          return;
612a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        } else if (gesture_event.handled()) {
613a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          event->SetHandled();
614a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          return;
615a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        } else if (dispatch_details.dispatcher_destroyed ||
616a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   dispatch_details.target_destroyed) {
617a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          return;
618a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        }
619a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      scroll_gesture_handler_ = NULL;
621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
622a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
623a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
624a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
625a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
626a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // If there was no handler for a SCROLL_BEGIN event, then subsequent scroll
627a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // events are not dispatched to any views.
628a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  switch (event->type()) {
629a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case ui::ET_GESTURE_SCROLL_UPDATE:
630a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case ui::ET_GESTURE_SCROLL_END:
631a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    case ui::ET_SCROLL_FLING_START:
632a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
633a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    default:
634a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      break;
635a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
636a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
637a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  View* gesture_handler = NULL;
638a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (views::switches::IsRectBasedTargetingEnabled() &&
639a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      !event->details().bounding_box().IsEmpty()) {
640a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // TODO(tdanderson): Pass in the bounding box to GetEventHandlerForRect()
641a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // once crbug.com/313392 is resolved.
642a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gfx::Rect touch_rect(event->details().bounding_box());
643a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    touch_rect.set_origin(event->location());
644a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    touch_rect.Offset(-touch_rect.width() / 2, -touch_rect.height() / 2);
645a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gesture_handler = GetEventHandlerForRect(touch_rect);
646a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } else {
647a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gesture_handler = GetEventHandlerForPoint(event->location());
648a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
649a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
650a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Walk up the tree until we find a view that wants the gesture event.
651a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (gesture_handler_ = gesture_handler;
652a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       gesture_handler_ && (gesture_handler_ != this);
653a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       gesture_handler_ = gesture_handler_->parent()) {
654a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!gesture_handler_->enabled()) {
655a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // Disabled views eat events but are treated as not handled.
656a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
657a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
658a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
659a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // See if this view wants to handle the Gesture.
660a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ui::GestureEvent gesture_event(*event, static_cast<View*>(this),
661a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   gesture_handler_);
662a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ui::EventDispatchDetails dispatch_details =
663a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        DispatchEvent(gesture_handler_, &gesture_event);
664a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (dispatch_details.dispatcher_destroyed)
665a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
666a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
667a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // The view could have removed itself from the tree when handling
668a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // OnGestureEvent(). So handle as per OnMousePressed. NB: we
669a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // assume that the RootView itself cannot be so removed.
670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!gesture_handler_)
671a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
672a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
673a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (gesture_event.handled()) {
674a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (gesture_event.type() == ui::ET_GESTURE_SCROLL_BEGIN)
675a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        scroll_gesture_handler_ = gesture_handler_;
676a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (gesture_event.stopped_propagation())
677a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        event->StopPropagation();
678a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      else
679a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        event->SetHandled();
680a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      // Last ui::ET_GESTURE_END should not set the gesture_handler_.
681a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (gesture_event.type() == ui::ET_GESTURE_END &&
682a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          event->details().touch_points() <= 1) {
683a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        gesture_handler_ = NULL;
684a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      }
685a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
686a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
687a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
688a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // The gesture event wasn't processed. Go up the view hierarchy and
689a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // dispatch the gesture event.
690a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
691a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
692a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  gesture_handler_ = NULL;
693a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
694a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
695a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void RootView::ViewHierarchyChanged(
696a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const ViewHierarchyChangedDetails& details) {
697a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  widget_->ViewHierarchyChanged(details);
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
699a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!details.is_add) {
700a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (!explicit_mouse_handler_ && mouse_pressed_handler_ == details.child)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_pressed_handler_ = NULL;
702a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (mouse_move_handler_ == details.child)
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_move_handler_ = NULL;
704a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (gesture_handler_ == details.child)
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_handler_ = NULL;
706a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (scroll_gesture_handler_ == details.child)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scroll_gesture_handler_ = NULL;
708a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (event_dispatch_target_ == details.child)
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      event_dispatch_target_ = NULL;
710a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (old_dispatch_target_ == details.child)
711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      old_dispatch_target_ = NULL;
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void RootView::VisibilityChanged(View* /*starting_from*/, bool is_visible) {
716a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!is_visible) {
717a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // When the root view is being hidden (e.g. when widget is minimized)
718a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // handlers are reset, so that after it is reshown, events are not captured
719a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // by old handlers.
7201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    explicit_mouse_handler_ = false;
721a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    mouse_pressed_handler_ = NULL;
722a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    mouse_move_handler_ = NULL;
723a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    gesture_handler_ = NULL;
724a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    scroll_gesture_handler_ = NULL;
725a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    event_dispatch_target_ = NULL;
726a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    old_dispatch_target_ = NULL;
727a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
728a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
729a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::OnPaint(gfx::Canvas* canvas) {
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!layer() || !layer()->fills_bounds_opaquely())
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->DrawColor(SK_ColorBLACK, SkXfermode::kClear_Mode);
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View::OnPaint(canvas);
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Vector2d RootView::CalculateOffsetToAncestorWithLayer(
7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::Layer** layer_parent) {
7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2d offset(View::CalculateOffsetToAncestorWithLayer(layer_parent));
74090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!layer() && layer_parent)
74190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    *layer_parent = widget_->GetLayer();
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return offset;
7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)View::DragInfo* RootView::GetDragInfo() {
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return &drag_info_;
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RootView, private:
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Input -----------------------------------------------------------------------
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::UpdateCursor(const ui::MouseEvent& event) {
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!(event.flags() & ui::EF_IS_NON_CLIENT)) {
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    View* v = GetEventHandlerForPoint(event.location());
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::MouseEvent me(event, static_cast<View*>(this), v);
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_->SetCursor(v->GetCursor(me));
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::SetMouseLocationAndFlags(const ui::MouseEvent& event) {
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_mouse_event_flags_ = event.flags();
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_mouse_event_x_ = event.x();
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_mouse_event_y_ = event.y();
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RootView::NotifyEnterExitOfDescendant(const ui::MouseEvent& event,
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           ui::EventType type,
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           View* view,
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           View* sibling) {
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (View* p = view->parent(); p; p = p->parent()) {
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!p->notify_enter_exit_on_child())
7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (sibling && p->Contains(sibling))
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // It is necessary to recreate the notify-event for each dispatch, since one
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // of the callbacks can mark the event as handled, and that would cause
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // incorrect event dispatch.
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MouseEnterExitEvent notify_event(event, type);
781a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    ui::EventDispatchDetails dispatch_details = DispatchEvent(p, &notify_event);
782a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (dispatch_details.dispatcher_destroyed ||
783a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        dispatch_details.target_destroyed) {
784424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      return;
785a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
786424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
787424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
788424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool RootView::CanDispatchToTarget(ui::EventTarget* target) {
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return event_dispatch_target_ == target;
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
793a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ui::EventDispatchDetails RootView::PreDispatchEvent(ui::EventTarget* target,
794a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                    ui::Event* event) {
795a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  old_dispatch_target_ = event_dispatch_target_;
796a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  event_dispatch_target_ = static_cast<View*>(target);
797a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return DispatchDetails();
798a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
799a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
800a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ui::EventDispatchDetails RootView::PostDispatchEvent(ui::EventTarget* target,
801a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                     const ui::Event& event) {
802a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DispatchDetails details;
803a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (target != event_dispatch_target_)
804a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    details.target_destroyed = true;
805a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
806a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  event_dispatch_target_ = old_dispatch_target_;
807a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  old_dispatch_target_ = NULL;
808a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
809a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef NDEBUG
810a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!event_dispatch_target_ || Contains(event_dispatch_target_));
811a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
812a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
813a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return details;
814a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
815a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
818