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"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/accessibility/accessible_view_state.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/dragdrop/drag_drop_types.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/events/event.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/keycodes/keyboard_codes.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/focus/view_storage.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/fill_layout.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget_delegate.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/widget/widget_deletion_observer.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum EventType {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EVENT_ENTER,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EVENT_EXIT
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MouseEnterExitEvent : public ui::MouseEvent {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MouseEnterExitEvent(const ui::MouseEvent& event, ui::EventType type)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : ui::MouseEvent(event,
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       static_cast<View*>(NULL),
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       static_cast<View*>(NULL)) {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(type == ui::ET_MOUSE_ENTERED ||
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           type == ui::ET_MOUSE_EXITED);
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetType(type);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~MouseEnterExitEvent() {}
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const char RootView::kViewClassName[] = "RootView";
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RootView, public:
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creation and lifetime -------------------------------------------------------
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RootView::RootView(Widget* widget)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : widget_(widget),
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_pressed_handler_(NULL),
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_move_handler_(NULL),
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_click_handler_(NULL),
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      explicit_mouse_handler_(false),
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_mouse_event_flags_(0),
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_mouse_event_x_(-1),
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_mouse_event_y_(-1),
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      touch_pressed_handler_(NULL),
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_handler_(NULL),
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scroll_gesture_handler_(NULL),
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      focus_search_(this, false, false),
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      focus_traversable_parent_(NULL),
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      focus_traversable_parent_view_(NULL),
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      event_dispatch_target_(NULL) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RootView::~RootView() {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we have children remove them explicitly so to make sure a remove
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notification is sent for each one of them.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_children())
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RemoveAllChildViews(true);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tree operations -------------------------------------------------------------
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::SetContentsView(View* contents_view) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(contents_view && GetWidget()->native_widget()) <<
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Can't be called until after the native widget is created!";
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The ContentsView must be set up _after_ the window is created so that its
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Widget pointer is valid.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetLayoutManager(new FillLayout);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_children())
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RemoveAllChildViews(true);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddChildView(contents_view);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Force a layout now, since the attached hierarchy won't be ready for the
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // containing window's bounds. Note that we call Layout directly rather than
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // calling the widget's size changed handler, since the RootView's bounds may
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not have changed, which will cause the Layout not to be done otherwise.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Layout();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)View* RootView::GetContentsView() {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return child_count() > 0 ? child_at(0) : NULL;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::NotifyNativeViewHierarchyChanged(bool attached,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                gfx::NativeView native_view) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PropagateNativeViewHierarchyChanged(attached, native_view, this);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Input -----------------------------------------------------------------------
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RootView::DispatchKeyEvent(ui::KeyEvent* event) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View* v = NULL;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetFocusManager())  // NULL in unittests.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v = GetFocusManager()->GetFocusedView();
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Special case to handle right-click context menus triggered by the
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // keyboard.
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (v && v->enabled() && ((event->key_code() == ui::VKEY_APPS) ||
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     (event->key_code() == ui::VKEY_F10 && event->IsShiftDown()))) {
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    v->ShowContextMenu(v->GetKeyboardContextMenuLocation(),
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       ui::MENU_SOURCE_KEYBOARD);
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event->StopPropagation();
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (; v && v != this && !event->handled(); v = v->parent())
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DispatchEventToTarget(v, event);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RootView::DispatchScrollEvent(ui::ScrollEvent* event) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (View* v = GetEventHandlerForPoint(event->location());
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       v && v != this && !event->stopped_propagation(); v = v->parent()) {
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DispatchEventToTarget(v, event);
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (event->handled() || event->type() != ui::ET_SCROLL)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Convert unprocessed scroll events into mouse-wheel events.
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::MouseWheelEvent wheel(*event);
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (OnMouseWheel(wheel))
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event->SetHandled();
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RootView::DispatchTouchEvent(ui::TouchEvent* event) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO: this looks all wrong. On a TOUCH_PRESSED we should figure out the
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // view and target that view with all touches with the same id until the
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // release (or keep it if captured).
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If touch_pressed_handler_ is non null, we are currently processing
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a touch down on the screen situation. In that case we send the
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // event to touch_pressed_handler_
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (touch_pressed_handler_) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::TouchEvent touch_event(*event, static_cast<View*>(this),
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               touch_pressed_handler_);
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DispatchEventToTarget(touch_pressed_handler_, &touch_event);
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (touch_event.handled())
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      event->SetHandled();
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (touch_event.stopped_propagation())
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      event->StopPropagation();
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Walk up the tree until we find a view that wants the touch event.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (touch_pressed_handler_ = GetEventHandlerForPoint(event->location());
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       touch_pressed_handler_ && (touch_pressed_handler_ != this);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       touch_pressed_handler_ = touch_pressed_handler_->parent()) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!touch_pressed_handler_->enabled()) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Disabled views eat events but are treated as not handled.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // See if this view wants to handle the touch
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::TouchEvent touch_event(*event, static_cast<View*>(this),
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               touch_pressed_handler_);
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DispatchEventToTarget(touch_pressed_handler_, &touch_event);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (touch_event.handled())
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      event->SetHandled();
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (touch_event.stopped_propagation())
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      event->StopPropagation();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The view could have removed itself from the tree when handling
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // OnTouchEvent(). So handle as per OnMousePressed. NB: we
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // assume that the RootView itself cannot be so removed.
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!touch_pressed_handler_)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The touch event wasn't processed. Go up the view hierarchy and dispatch
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the touch event.
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!event->handled())
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If a View consumed the event, that means future touch-events should go to
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // that View. If the event wasn't consumed, then reset the handler.
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!event->stopped_propagation())
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      touch_pressed_handler_ = NULL;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset touch_pressed_handler_ to indicate that no processing is occurring.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  touch_pressed_handler_ = NULL;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RootView::DispatchGestureEvent(ui::GestureEvent* event) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (gesture_handler_) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // |gesture_handler_| (or |scroll_gesture_handler_|) can be deleted during
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // processing.
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    View* handler = scroll_gesture_handler_ &&
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (event->IsScrollGestureEvent() || event->IsFlingScrollEvent())  ?
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            scroll_gesture_handler_ : gesture_handler_;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::GestureEvent handler_event(*event, static_cast<View*>(this), handler);
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DispatchEventToTarget(handler, &handler_event);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event->type() == ui::ET_GESTURE_END &&
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        event->details().touch_points() <= 1) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // In case a drag was in progress, reset all the handlers. Otherwise, just
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // reset the gesture handler.
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (gesture_handler_ == mouse_pressed_handler_)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SetMouseHandler(NULL);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gesture_handler_ = NULL;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (scroll_gesture_handler_ &&
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (event->type() == ui::ET_GESTURE_SCROLL_END ||
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         event->type() == ui::ET_SCROLL_FLING_START)) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scroll_gesture_handler_ = NULL;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (handler_event.stopped_propagation()) {
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      event->StopPropagation();
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (handler_event.handled()) {
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      event->SetHandled();
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN &&
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !scroll_gesture_handler_) {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Some view started processing gesture events, however it does not
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // process scroll-gesture events. In such case, we allow the event to
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // bubble up, and install a different scroll-gesture handler different
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // from the default gesture handler.
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (scroll_gesture_handler_ = gesture_handler_->parent();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          scroll_gesture_handler_ && scroll_gesture_handler_ != this;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          scroll_gesture_handler_ = scroll_gesture_handler_->parent()) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ui::GestureEvent gesture_event(*event, static_cast<View*>(this),
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       scroll_gesture_handler_);
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DispatchEventToTarget(scroll_gesture_handler_, &gesture_event);
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (gesture_event.stopped_propagation()) {
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          event->StopPropagation();
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          return;
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        } else if (gesture_event.handled()) {
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          event->SetHandled();
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          return;
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scroll_gesture_handler_ = NULL;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If there was no handler for a SCROLL_BEGIN event, then subsequent scroll
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // events are not dispatched to any views.
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (event->type()) {
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case ui::ET_GESTURE_SCROLL_UPDATE:
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case ui::ET_GESTURE_SCROLL_END:
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case ui::ET_SCROLL_FLING_START:
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Walk up the tree until we find a view that wants the gesture event.
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (gesture_handler_ = GetEventHandlerForPoint(event->location());
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_handler_ && (gesture_handler_ != this);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_handler_ = gesture_handler_->parent()) {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!gesture_handler_->enabled()) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Disabled views eat events but are treated as not handled.
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // See if this view wants to handle the Gesture.
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::GestureEvent gesture_event(*event, static_cast<View*>(this),
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   gesture_handler_);
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DispatchEventToTarget(gesture_handler_, &gesture_event);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The view could have removed itself from the tree when handling
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // OnGestureEvent(). So handle as per OnMousePressed. NB: we
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // assume that the RootView itself cannot be so removed.
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!gesture_handler_)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (gesture_event.handled()) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (gesture_event.type() == ui::ET_GESTURE_SCROLL_BEGIN)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        scroll_gesture_handler_ = gesture_handler_;
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (gesture_event.stopped_propagation())
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        event->StopPropagation();
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      else
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        event->SetHandled();
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The gesture event wasn't processed. Go up the view hierarchy and
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // dispatch the gesture event.
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gesture_handler_ = NULL;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Focus -----------------------------------------------------------------------
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::SetFocusTraversableParent(FocusTraversable* focus_traversable) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(focus_traversable != this);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  focus_traversable_parent_ = focus_traversable;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::SetFocusTraversableParentView(View* view) {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  focus_traversable_parent_view_ = view;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// System events ---------------------------------------------------------------
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::ThemeChanged() {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View::PropagateThemeChanged();
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::LocaleChanged() {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View::PropagateLocaleChanged();
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RootView, FocusTraversable implementation:
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FocusSearch* RootView::GetFocusSearch() {
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &focus_search_;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FocusTraversable* RootView::GetFocusTraversableParent() {
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return focus_traversable_parent_;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)View* RootView::GetFocusTraversableParentView() {
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return focus_traversable_parent_view_;
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RootView, View overrides:
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Widget* RootView::GetWidget() const {
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return widget_;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Widget* RootView::GetWidget() {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return const_cast<Widget*>(const_cast<const RootView*>(this)->GetWidget());
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RootView::IsDrawn() const {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return visible();
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
367b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char* RootView::GetClassName() const {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return kViewClassName;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::SchedulePaintInRect(const gfx::Rect& rect) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (layer()) {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layer()->SchedulePaint(rect);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Rect xrect = ConvertRectToParent(rect);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Rect invalid_rect = gfx::IntersectRects(GetLocalBounds(), xrect);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!invalid_rect.IsEmpty())
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_->SchedulePaintInRect(invalid_rect);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RootView::OnMousePressed(const ui::MouseEvent& event) {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateCursor(event);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetMouseLocationAndFlags(event);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If mouse_pressed_handler_ is non null, we are currently processing
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a pressed -> drag -> released session. In that case we send the
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // event to mouse_pressed_handler_
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_pressed_handler_) {
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::MouseEvent mouse_pressed_event(event, static_cast<View*>(this),
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       mouse_pressed_handler_);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    drag_info_.Reset();
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DispatchEventToTarget(mouse_pressed_handler_, &mouse_pressed_event);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!explicit_mouse_handler_);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool hit_disabled_view = false;
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Walk up the tree until we find a view that wants the mouse event.
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (mouse_pressed_handler_ = GetEventHandlerForPoint(event.location());
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       mouse_pressed_handler_ && (mouse_pressed_handler_ != this);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       mouse_pressed_handler_ = mouse_pressed_handler_->parent()) {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "OnMousePressed testing "
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << mouse_pressed_handler_->GetClassName();
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!mouse_pressed_handler_->enabled()) {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Disabled views should eat events instead of propagating them upwards.
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hit_disabled_view = true;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // See if this view wants to handle the mouse press.
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::MouseEvent mouse_pressed_event(event, static_cast<View*>(this),
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       mouse_pressed_handler_);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Remove the double-click flag if the handler is different than the
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // one which got the first click part of the double-click.
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mouse_pressed_handler_ != last_click_handler_)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_pressed_event.set_flags(event.flags() & ~ui::EF_IS_DOUBLE_CLICK);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    drag_info_.Reset();
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    {
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      WidgetDeletionObserver widget_deletion_observer(widget_);
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DispatchEventToTarget(mouse_pressed_handler_, &mouse_pressed_event);
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (!widget_deletion_observer.IsWidgetAlive())
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return mouse_pressed_event.handled();
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The view could have removed itself from the tree when handling
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // OnMousePressed().  In this case, the removal notification will have
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // reset mouse_pressed_handler_ to NULL out from under us.  Detect this
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // case and stop.  (See comments in view.h.)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // NOTE: Don't return true here, because we don't want the frame to
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // forward future events to us when there's no handler.
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!mouse_pressed_handler_)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the view handled the event, leave mouse_pressed_handler_ set and
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // return true, which will cause subsequent drag/release events to get
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // forwarded to that view.
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (mouse_pressed_event.handled()) {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_click_handler_ = mouse_pressed_handler_;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DVLOG(1) << "OnMousePressed handled by "
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << mouse_pressed_handler_->GetClassName();
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset mouse_pressed_handler_ to indicate that no processing is occurring.
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_pressed_handler_ = NULL;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In the event that a double-click is not handled after traversing the
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // entire hierarchy (even as a single-click when sent to a different view),
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it must be marked as handled to avoid anything happening from default
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // processing if it the first click-part was handled by us.
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (last_click_handler_ && (event.flags() & ui::EF_IS_DOUBLE_CLICK))
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hit_disabled_view = true;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_click_handler_ = NULL;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hit_disabled_view;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RootView::OnMouseDragged(const ui::MouseEvent& event) {
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_pressed_handler_) {
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetMouseLocationAndFlags(event);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::MouseEvent mouse_event(event, static_cast<View*>(this),
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               mouse_pressed_handler_);
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DispatchEventToTarget(mouse_pressed_handler_, &mouse_event);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::OnMouseReleased(const ui::MouseEvent& event) {
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateCursor(event);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_pressed_handler_) {
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::MouseEvent mouse_released(event, static_cast<View*>(this),
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  mouse_pressed_handler_);
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We allow the view to delete us from the event dispatch callback. As such,
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // configure state such that we're done first, then call View.
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    View* mouse_pressed_handler = mouse_pressed_handler_;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetMouseHandler(NULL);
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DispatchEventToTarget(mouse_pressed_handler, &mouse_released);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // WARNING: we may have been deleted.
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::OnMouseCaptureLost() {
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO: this likely needs to reset touch handler too.
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_pressed_handler_ || gesture_handler_) {
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Synthesize a release event for UpdateCursor.
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mouse_pressed_handler_) {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Point last_point(last_mouse_event_x_, last_mouse_event_y_);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::MouseEvent release_event(ui::ET_MOUSE_RELEASED,
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   last_point, last_point,
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   last_mouse_event_flags_);
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UpdateCursor(release_event);
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We allow the view to delete us from OnMouseCaptureLost. As such,
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // configure state such that we're done first, then call View.
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    View* mouse_pressed_handler = mouse_pressed_handler_;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    View* gesture_handler = gesture_handler_;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetMouseHandler(NULL);
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mouse_pressed_handler)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_pressed_handler->OnMouseCaptureLost();
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_handler->OnMouseCaptureLost();
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // WARNING: we may have been deleted.
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::OnMouseMoved(const ui::MouseEvent& event) {
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View* v = GetEventHandlerForPoint(event.location());
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Find the first enabled view, or the existing move handler, whichever comes
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first.  The check for the existing handler is because if a view becomes
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // disabled while handling moves, it's wrong to suddenly send ET_MOUSE_EXITED
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and ET_MOUSE_ENTERED events, because the mouse hasn't actually exited yet.
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (v && !v->enabled() && (v != mouse_move_handler_))
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    v = v->parent();
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (v && v != this) {
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (v != mouse_move_handler_) {
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (mouse_move_handler_ != NULL &&
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (!mouse_move_handler_->notify_enter_exit_on_child() ||
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           !mouse_move_handler_->Contains(v))) {
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        MouseEnterExitEvent exit(event, ui::ET_MOUSE_EXITED);
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DispatchEventToTarget(mouse_move_handler_, &exit);
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NotifyEnterExitOfDescendant(event, ui::ET_MOUSE_EXITED,
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            mouse_move_handler_, v);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      View* old_handler = mouse_move_handler_;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_move_handler_ = v;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!mouse_move_handler_->notify_enter_exit_on_child() ||
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !mouse_move_handler_->Contains(old_handler)) {
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        MouseEnterExitEvent entered(event, ui::ET_MOUSE_ENTERED);
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        entered.ConvertLocationToTarget(static_cast<View*>(this),
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        mouse_move_handler_);
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DispatchEventToTarget(mouse_move_handler_, &entered);
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NotifyEnterExitOfDescendant(entered, ui::ET_MOUSE_ENTERED, v,
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            old_handler);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::MouseEvent moved_event(event, static_cast<View*>(this),
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               mouse_move_handler_);
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mouse_move_handler_->OnMouseMoved(moved_event);
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(moved_event.flags() & ui::EF_IS_NON_CLIENT))
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_->SetCursor(mouse_move_handler_->GetCursor(moved_event));
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (mouse_move_handler_ != NULL) {
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MouseEnterExitEvent exited(event, ui::ET_MOUSE_EXITED);
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DispatchEventToTarget(mouse_move_handler_, &exited);
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NotifyEnterExitOfDescendant(event, ui::ET_MOUSE_EXITED,
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mouse_move_handler_, v);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // On Aura the non-client area extends slightly outside the root view for
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // some windows.  Let the non-client cursor handling code set the cursor
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // as we do above.
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(event.flags() & ui::EF_IS_NON_CLIENT))
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_->SetCursor(gfx::kNullCursor);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mouse_move_handler_ = NULL;
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::OnMouseExited(const ui::MouseEvent& event) {
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (mouse_move_handler_ != NULL) {
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MouseEnterExitEvent exited(event, ui::ET_MOUSE_EXITED);
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DispatchEventToTarget(mouse_move_handler_, &exited);
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NotifyEnterExitOfDescendant(event, ui::ET_MOUSE_EXITED,
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mouse_move_handler_, NULL);
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mouse_move_handler_ = NULL;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RootView::OnMouseWheel(const ui::MouseWheelEvent& event) {
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (View* v = GetEventHandlerForPoint(event.location());
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       v && v != this && !event.handled(); v = v->parent())
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DispatchEventToTarget(v, const_cast<ui::MouseWheelEvent*>(&event));
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return event.handled();
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::SetMouseHandler(View* new_mh) {
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we're clearing the mouse handler, clear explicit_mouse_handler_ as well.
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit_mouse_handler_ = (new_mh != NULL);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mouse_pressed_handler_ = new_mh;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gesture_handler_ = new_mh;
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scroll_gesture_handler_ = new_mh;
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  drag_info_.Reset();
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::GetAccessibleState(ui::AccessibleViewState* state) {
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state->name = widget_->widget_delegate()->GetAccessibleWindowTitle();
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state->role = widget_->widget_delegate()->GetAccessibleWindowRole();
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void RootView::UpdateParentLayer() {
59590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (layer())
59690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ReparentLayer(gfx::Vector2d(GetMirroredX(), y()), widget_->GetLayer());
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RootView, protected:
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
602a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void RootView::ViewHierarchyChanged(
603a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    const ViewHierarchyChangedDetails& details) {
604a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  widget_->ViewHierarchyChanged(details);
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
606a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!details.is_add) {
607a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (!explicit_mouse_handler_ && mouse_pressed_handler_ == details.child)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_pressed_handler_ = NULL;
609a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (mouse_move_handler_ == details.child)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      mouse_move_handler_ = NULL;
611a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (touch_pressed_handler_ == details.child)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      touch_pressed_handler_ = NULL;
613a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (gesture_handler_ == details.child)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gesture_handler_ = NULL;
615a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (scroll_gesture_handler_ == details.child)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scroll_gesture_handler_ = NULL;
617a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (event_dispatch_target_ == details.child)
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      event_dispatch_target_ = NULL;
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
622a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void RootView::VisibilityChanged(View* /*starting_from*/, bool is_visible) {
623a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!is_visible) {
624a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // When the root view is being hidden (e.g. when widget is minimized)
625a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // handlers are reset, so that after it is reshown, events are not captured
626a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // by old handlers.
627a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    mouse_pressed_handler_ = NULL;
628a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    mouse_move_handler_ = NULL;
629a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    touch_pressed_handler_ = NULL;
630a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    gesture_handler_ = NULL;
631a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    scroll_gesture_handler_ = NULL;
632a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    event_dispatch_target_ = NULL;
633a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
634a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
635a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::OnPaint(gfx::Canvas* canvas) {
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!layer() || !layer()->fills_bounds_opaquely())
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->DrawColor(SK_ColorBLACK, SkXfermode::kClear_Mode);
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO (pkotwicz): Remove this once we switch over to Aura desktop.
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is needed so that we can set the background behind the RWHV when the
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // RWHV is not visible. Not needed once there is a view between the RootView
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and RWHV.
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  View::OnPaint(canvas);
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Vector2d RootView::CalculateOffsetToAncestorWithLayer(
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ui::Layer** layer_parent) {
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Vector2d offset(View::CalculateOffsetToAncestorWithLayer(layer_parent));
65090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!layer() && layer_parent)
65190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    *layer_parent = widget_->GetLayer();
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return offset;
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)View::DragInfo* RootView::GetDragInfo() {
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return &drag_info_;
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RootView, private:
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Input -----------------------------------------------------------------------
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::UpdateCursor(const ui::MouseEvent& event) {
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!(event.flags() & ui::EF_IS_NON_CLIENT)) {
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    View* v = GetEventHandlerForPoint(event.location());
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::MouseEvent me(event, static_cast<View*>(this), v);
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widget_->SetCursor(v->GetCursor(me));
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RootView::SetMouseLocationAndFlags(const ui::MouseEvent& event) {
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_mouse_event_flags_ = event.flags();
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_mouse_event_x_ = event.x();
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_mouse_event_y_ = event.y();
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RootView::DispatchEventToTarget(View* target, ui::Event* event) {
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  View* old_target = event_dispatch_target_;
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  event_dispatch_target_ = target;
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (DispatchEvent(target, event))
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    event_dispatch_target_ = old_target;
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RootView::NotifyEnterExitOfDescendant(const ui::MouseEvent& event,
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           ui::EventType type,
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           View* view,
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           View* sibling) {
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (View* p = view->parent(); p; p = p->parent()) {
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!p->notify_enter_exit_on_child())
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (sibling && p->Contains(sibling))
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // It is necessary to recreate the notify-event for each dispatch, since one
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // of the callbacks can mark the event as handled, and that would cause
6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // incorrect event dispatch.
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MouseEnterExitEvent notify_event(event, type);
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DispatchEventToTarget(p, &notify_event);
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool RootView::CanDispatchToTarget(ui::EventTarget* target) {
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return event_dispatch_target_ == target;
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
708