Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(395)

Side by Side Diff: ui/views/focus/focus_manager.cc

Issue 23475012: Fixes focus traversal bug (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: OVERRIDE Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/views/focus/focus_manager.h ('k') | ui/views/focus/focus_manager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/focus/focus_manager.h" 5 #include "ui/views/focus/focus_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 } 132 }
133 133
134 // Tests whether a view is valid, whether it still belongs to the window 134 // Tests whether a view is valid, whether it still belongs to the window
135 // hierarchy of the FocusManager. 135 // hierarchy of the FocusManager.
136 bool FocusManager::ContainsView(View* view) { 136 bool FocusManager::ContainsView(View* view) {
137 Widget* widget = view->GetWidget(); 137 Widget* widget = view->GetWidget();
138 return widget ? widget->GetFocusManager() == this : false; 138 return widget ? widget->GetFocusManager() == this : false;
139 } 139 }
140 140
141 void FocusManager::AdvanceFocus(bool reverse) { 141 void FocusManager::AdvanceFocus(bool reverse) {
142 View* v = GetNextFocusableView(focused_view_, reverse, false); 142 View* v = GetNextFocusableView(focused_view_, NULL, reverse, false);
143 // Note: Do not skip this next block when v == focused_view_. If the user 143 // Note: Do not skip this next block when v == focused_view_. If the user
144 // tabs past the last focusable element in a webpage, we'll get here, and if 144 // tabs past the last focusable element in a webpage, we'll get here, and if
145 // the TabContentsContainerView is the only focusable view (possible in 145 // the TabContentsContainerView is the only focusable view (possible in
146 // fullscreen mode), we need to run this block in order to cycle around to the 146 // fullscreen mode), we need to run this block in order to cycle around to the
147 // first element on the page. 147 // first element on the page.
148 if (v) { 148 if (v) {
149 views::View* focused_view = focused_view_; 149 views::View* focused_view = focused_view_;
150 v->AboutToRequestFocusFromTabTraversal(reverse); 150 v->AboutToRequestFocusFromTabTraversal(reverse);
151 // AboutToRequestFocusFromTabTraversal() may have changed focus. If it did, 151 // AboutToRequestFocusFromTabTraversal() may have changed focus. If it did,
152 // don't change focus again. 152 // don't change focus again.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 pane->RequestFocus(); 212 pane->RequestFocus();
213 focused_view = GetFocusedView(); 213 focused_view = GetFocusedView();
214 if (pane == focused_view || pane->Contains(focused_view)) 214 if (pane == focused_view || pane->Contains(focused_view))
215 return true; 215 return true;
216 } 216 }
217 217
218 return false; 218 return false;
219 } 219 }
220 220
221 View* FocusManager::GetNextFocusableView(View* original_starting_view, 221 View* FocusManager::GetNextFocusableView(View* original_starting_view,
222 Widget* starting_widget,
222 bool reverse, 223 bool reverse,
223 bool dont_loop) { 224 bool dont_loop) {
224 FocusTraversable* focus_traversable = NULL; 225 FocusTraversable* focus_traversable = NULL;
225 226
226 // Let's revalidate the focused view. 227 // Let's revalidate the focused view.
227 ValidateFocusedView(); 228 ValidateFocusedView();
228 229
229 View* starting_view = NULL; 230 View* starting_view = NULL;
230 if (original_starting_view) { 231 if (original_starting_view) {
231 // Search up the containment hierarchy to see if a view is acting as 232 // Search up the containment hierarchy to see if a view is acting as
(...skipping 23 matching lines...) Expand all
255 } 256 }
256 } else { 257 } else {
257 // When you are going back, starting view's FocusTraversable 258 // When you are going back, starting view's FocusTraversable
258 // should not be used. 259 // should not be used.
259 focus_traversable = 260 focus_traversable =
260 original_starting_view->GetWidget()->GetFocusTraversable(); 261 original_starting_view->GetWidget()->GetFocusTraversable();
261 starting_view = original_starting_view; 262 starting_view = original_starting_view;
262 } 263 }
263 } 264 }
264 } else { 265 } else {
265 focus_traversable = widget_->GetFocusTraversable(); 266 Widget* widget = starting_widget ? starting_widget : widget_;
267 focus_traversable = widget->GetFocusTraversable();
266 } 268 }
267 269
268 // Traverse the FocusTraversable tree down to find the focusable view. 270 // Traverse the FocusTraversable tree down to find the focusable view.
269 View* v = FindFocusableView(focus_traversable, starting_view, reverse); 271 View* v = FindFocusableView(focus_traversable, starting_view, reverse);
270 if (v) { 272 if (v) {
271 return v; 273 return v;
272 } else { 274 } else {
273 // Let's go up in the FocusTraversable tree. 275 // Let's go up in the FocusTraversable tree.
274 FocusTraversable* parent_focus_traversable = 276 FocusTraversable* parent_focus_traversable =
275 focus_traversable->GetFocusTraversableParent(); 277 focus_traversable->GetFocusTraversableParent();
(...skipping 20 matching lines...) Expand all
296 starting_view = focus_traversable->GetFocusTraversableParentView(); 298 starting_view = focus_traversable->GetFocusTraversableParentView();
297 parent_focus_traversable = 299 parent_focus_traversable =
298 parent_focus_traversable->GetFocusTraversableParent(); 300 parent_focus_traversable->GetFocusTraversableParent();
299 } 301 }
300 302
301 // If we get here, we have reached the end of the focus hierarchy, let's 303 // If we get here, we have reached the end of the focus hierarchy, let's
302 // loop. Make sure there was at least a view to start with, to prevent 304 // loop. Make sure there was at least a view to start with, to prevent
303 // infinitely looping in empty windows. 305 // infinitely looping in empty windows.
304 if (!dont_loop && original_starting_view) { 306 if (!dont_loop && original_starting_view) {
305 // Easy, just clear the selection and press tab again. 307 // Easy, just clear the selection and press tab again.
306 // By calling with NULL as the starting view, we'll start from the 308 // By calling with NULL as the starting view, we'll start from either
307 // top_root_view. 309 // the starting views widget or |widget_|.
308 return GetNextFocusableView(NULL, reverse, true); 310 Widget* widget = original_starting_view->GetWidget();
311 if (widget->widget_delegate()->ShouldAdvanceFocusToTopLevelWidget())
312 widget = widget_;
313 return GetNextFocusableView(NULL, widget, reverse, true);
309 } 314 }
310 } 315 }
311 return NULL; 316 return NULL;
312 } 317 }
313 318
314 void FocusManager::SetFocusedViewWithReason( 319 void FocusManager::SetFocusedViewWithReason(
315 View* view, FocusChangeReason reason) { 320 View* view, FocusChangeReason reason) {
316 if (focused_view_ == view) 321 if (focused_view_ == view)
317 return; 322 return;
318 323
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 } 540 }
536 if (key_code == ui::VKEY_RIGHT || key_code == ui::VKEY_DOWN) { 541 if (key_code == ui::VKEY_RIGHT || key_code == ui::VKEY_DOWN) {
537 AdvanceFocus(false); 542 AdvanceFocus(false);
538 return true; 543 return true;
539 } 544 }
540 545
541 return false; 546 return false;
542 } 547 }
543 548
544 } // namespace views 549 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/focus/focus_manager.h ('k') | ui/views/focus/focus_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698