172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h"
621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/view_ids.h"
772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/accessible_pane_view.h"
821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/views/frame/browser_view.h"
921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/base/accessibility/accessible_view_state.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/button/menu_button.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/controls/native/native_view_host.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/focus/focus_search.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/focus/view_storage.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/widget/tooltip_manager.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "views/widget/widget.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickAccessiblePaneView::AccessiblePaneView()
19731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    : pane_has_focus_(false),
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      focus_manager_(NULL),
2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      home_key_(ui::VKEY_HOME, false, false, false),
2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      end_key_(ui::VKEY_END, false, false, false),
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      escape_key_(ui::VKEY_ESCAPE, false, false, false),
2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      left_key_(ui::VKEY_LEFT, false, false, false),
2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      right_key_(ui::VKEY_RIGHT, false, false, false),
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      last_focused_view_storage_id_(-1) {
283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  focus_search_.reset(new views::FocusSearch(this, true, true));
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
31731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickAccessiblePaneView::~AccessiblePaneView() {
32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (pane_has_focus_) {
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    focus_manager_->RemoveFocusChangeListener(this);
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
37731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool AccessiblePaneView::SetPaneFocus(int view_storage_id,
38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                      views::View* initial_focus) {
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!IsVisible())
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Save the storage id to the last focused view. This would be used to request
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // focus to the view when the traversal is ended.
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  last_focused_view_storage_id_ = view_storage_id;
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!focus_manager_)
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    focus_manager_ = GetFocusManager();
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Use the provided initial focus if it's visible and enabled, otherwise
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // use the first focusable child.
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!initial_focus ||
5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      !Contains(initial_focus) ||
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !initial_focus->IsVisible() ||
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      !initial_focus->IsEnabled()) {
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    initial_focus = GetFirstFocusableChild();
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Return false if there are no focusable children.
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!initial_focus)
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Set focus to the initial view. If it's a location bar, use a special
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // method that tells it to select all, also.
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (initial_focus->GetClassName() == LocationBarView::kViewClassName) {
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    static_cast<LocationBarView*>(initial_focus)->FocusLocation(true);
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    focus_manager_->SetFocusedView(initial_focus);
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // If we already have pane focus, we're done.
71731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (pane_has_focus_)
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Otherwise, set accelerators and start listening for focus change events.
75731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pane_has_focus_ = true;
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  focus_manager_->RegisterAccelerator(home_key_, this);
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  focus_manager_->RegisterAccelerator(end_key_, this);
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  focus_manager_->RegisterAccelerator(escape_key_, this);
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  focus_manager_->RegisterAccelerator(left_key_, this);
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  focus_manager_->RegisterAccelerator(right_key_, this);
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  focus_manager_->AddFocusChangeListener(this);
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
86731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool AccessiblePaneView::SetPaneFocusAndFocusDefault(
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int view_storage_id) {
88731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return SetPaneFocus(view_storage_id, GetDefaultFocusableChild());
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenviews::View* AccessiblePaneView::GetDefaultFocusableChild() {
92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return NULL;
93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
95731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid AccessiblePaneView::RemovePaneFocus() {
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  focus_manager_->RemoveFocusChangeListener(this);
97731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  pane_has_focus_ = false;
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  focus_manager_->UnregisterAccelerator(home_key_, this);
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  focus_manager_->UnregisterAccelerator(end_key_, this);
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  focus_manager_->UnregisterAccelerator(escape_key_, this);
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  focus_manager_->UnregisterAccelerator(left_key_, this);
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  focus_manager_->UnregisterAccelerator(right_key_, this);
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid AccessiblePaneView::LocationBarSelectAll() {
107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  views::View* focused_view = GetFocusManager()->GetFocusedView();
108731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (focused_view &&
109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      focused_view->GetClassName() == LocationBarView::kViewClassName) {
110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    static_cast<LocationBarView*>(focused_view)->SelectAll();
111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid AccessiblePaneView::RestoreLastFocusedView() {
11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  views::ViewStorage* view_storage = views::ViewStorage::GetInstance();
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::View* last_focused_view =
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      view_storage->RetrieveView(last_focused_view_storage_id_);
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (last_focused_view) {
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    focus_manager_->SetFocusedViewWithReason(
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        last_focused_view, views::FocusManager::kReasonFocusRestore);
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Focus the location bar
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    views::View* view = GetAncestorWithClassName(BrowserView::kViewClassName);
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (view) {
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      BrowserView* browser_view = static_cast<BrowserView*>(view);
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      browser_view->SetFocusToLocationBar(false);
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
131731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickviews::View* AccessiblePaneView::GetFirstFocusableChild() {
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FocusTraversable* dummy_focus_traversable;
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::View* dummy_focus_traversable_view;
1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return focus_search_->FindNextFocusableView(
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NULL, false, views::FocusSearch::DOWN, false,
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &dummy_focus_traversable, &dummy_focus_traversable_view);
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickviews::View* AccessiblePaneView::GetLastFocusableChild() {
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FocusTraversable* dummy_focus_traversable;
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::View* dummy_focus_traversable_view;
1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return focus_search_->FindNextFocusableView(
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      this, true, views::FocusSearch::DOWN, false,
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      &dummy_focus_traversable, &dummy_focus_traversable_view);
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// View overrides:
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickviews::FocusTraversable* AccessiblePaneView::GetPaneFocusTraversable() {
151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (pane_has_focus_)
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return this;
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool AccessiblePaneView::AcceleratorPressed(
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const views::Accelerator& accelerator) {
159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Special case: don't handle any accelerators for the location bar,
160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // so that it behaves exactly the same whether you focus it with Ctrl+L
161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // or F6 or Alt+D or Alt+Shift+T.
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::View* focused_view = focus_manager_->GetFocusedView();
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if ((focused_view->GetClassName() == LocationBarView::kViewClassName ||
164731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick       focused_view->GetClassName() == views::NativeViewHost::kViewClassName)) {
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (accelerator.GetKeyCode()) {
16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case ui::VKEY_ESCAPE:
170731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      RemovePaneFocus();
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      RestoreLastFocusedView();
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return true;
17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case ui::VKEY_LEFT:
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      focus_manager_->AdvanceFocus(true);
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return true;
17672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case ui::VKEY_RIGHT:
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      focus_manager_->AdvanceFocus(false);
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return true;
17972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case ui::VKEY_HOME:
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      focus_manager_->SetFocusedViewWithReason(
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          GetFirstFocusableChild(), views::FocusManager::kReasonFocusTraversal);
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return true;
18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    case ui::VKEY_END:
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      focus_manager_->SetFocusedViewWithReason(
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          GetLastFocusableChild(), views::FocusManager::kReasonFocusTraversal);
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return true;
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
192731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid AccessiblePaneView::SetVisible(bool flag) {
193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (IsVisible() && !flag && pane_has_focus_) {
194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    RemovePaneFocus();
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RestoreLastFocusedView();
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  View::SetVisible(flag);
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid AccessiblePaneView::GetAccessibleState(ui::AccessibleViewState* state) {
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  state->role = ui::AccessibilityTypes::ROLE_PANE;
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// FocusChangeListener overrides:
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
207731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid AccessiblePaneView::FocusWillChange(views::View* focused_before,
208731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                         views::View* focused_now) {
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!focused_now)
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  views::FocusManager::FocusChangeReason reason =
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      focus_manager_->focus_change_reason();
214731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
215731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (focused_now->GetClassName() == LocationBarView::kViewClassName &&
216731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      reason == views::FocusManager::kReasonFocusTraversal) {
217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // Tabbing to the location bar should select all. Defer so that it happens
218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // after the focus.
219731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    MessageLoop::current()->PostTask(
220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        FROM_HERE, method_factory_.NewRunnableMethod(
221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            &AccessiblePaneView::LocationBarSelectAll));
222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
22472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!Contains(focused_now) ||
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      reason == views::FocusManager::kReasonDirectFocusChange) {
226731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // We should remove pane focus (i.e. make most of the controls
227731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // not focusable again) either because the focus is leaving the pane,
228731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // or because the focus changed within the pane due to the user
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // directly focusing to a specific view (e.g., clicking on it).
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //
231731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // Defer rather than calling RemovePaneFocus right away, because we can't
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // remove |this| as a focus change listener while FocusManager is in the
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // middle of iterating over the list of listeners.
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->PostTask(
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        FROM_HERE, method_factory_.NewRunnableMethod(
236731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            &AccessiblePaneView::RemovePaneFocus));
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// FocusTraversable overrides:
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
243731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickviews::FocusSearch* AccessiblePaneView::GetFocusSearch() {
244731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(pane_has_focus_);
2453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return focus_search_.get();
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
248731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickviews::FocusTraversable* AccessiblePaneView::GetFocusTraversableParent() {
249731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(pane_has_focus_);
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
253731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickviews::View* AccessiblePaneView::GetFocusTraversableParentView() {
254731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(pane_has_focus_);
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
257