Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 17 matching lines...) Expand all Loading... | |
| 28 | 28 |
| 29 bool FocusManager::arrow_key_traversal_enabled_ = false; | 29 bool FocusManager::arrow_key_traversal_enabled_ = false; |
| 30 | 30 |
| 31 FocusManager::FocusManager(Widget* widget, FocusManagerDelegate* delegate) | 31 FocusManager::FocusManager(Widget* widget, FocusManagerDelegate* delegate) |
| 32 : widget_(widget), | 32 : widget_(widget), |
| 33 delegate_(delegate), | 33 delegate_(delegate), |
| 34 focused_view_(NULL), | 34 focused_view_(NULL), |
| 35 accelerator_manager_(new ui::AcceleratorManager), | 35 accelerator_manager_(new ui::AcceleratorManager), |
| 36 shortcut_handling_suspended_(false), | 36 shortcut_handling_suspended_(false), |
| 37 focus_change_reason_(kReasonDirectFocusChange), | 37 focus_change_reason_(kReasonDirectFocusChange), |
| 38 is_changing_focus_(false) { | 38 is_changing_focus_(false), |
| 39 keyboard_accessible_(false) { | |
| 39 DCHECK(widget_); | 40 DCHECK(widget_); |
| 40 stored_focused_view_storage_id_ = | 41 stored_focused_view_storage_id_ = |
| 41 ViewStorage::GetInstance()->CreateStorageID(); | 42 ViewStorage::GetInstance()->CreateStorageID(); |
| 42 } | 43 } |
| 43 | 44 |
| 44 FocusManager::~FocusManager() { | 45 FocusManager::~FocusManager() { |
| 45 } | 46 } |
| 46 | 47 |
| 47 bool FocusManager::OnKeyEvent(const ui::KeyEvent& event) { | 48 bool FocusManager::OnKeyEvent(const ui::KeyEvent& event) { |
| 48 const int key_code = event.key_code(); | 49 const int key_code = event.key_code(); |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 // the starting views widget or |widget_|. | 291 // the starting views widget or |widget_|. |
| 291 Widget* widget = original_starting_view->GetWidget(); | 292 Widget* widget = original_starting_view->GetWidget(); |
| 292 if (widget->widget_delegate()->ShouldAdvanceFocusToTopLevelWidget()) | 293 if (widget->widget_delegate()->ShouldAdvanceFocusToTopLevelWidget()) |
| 293 widget = widget_; | 294 widget = widget_; |
| 294 return GetNextFocusableView(NULL, widget, reverse, true); | 295 return GetNextFocusableView(NULL, widget, reverse, true); |
| 295 } | 296 } |
| 296 } | 297 } |
| 297 return NULL; | 298 return NULL; |
| 298 } | 299 } |
| 299 | 300 |
| 301 void FocusManager::SetKeyboardAccessible(bool keyboard_accessible) { | |
| 302 if (keyboard_accessible == keyboard_accessible_) | |
| 303 return; | |
| 304 | |
| 305 keyboard_accessible_ = keyboard_accessible; | |
| 306 // Disabling keyboard accessibility may cause the focused view to become not | |
| 307 // focusable. Hence advance focus if necessary. | |
| 308 AdvanceFocusIfNecessary(); | |
| 309 } | |
| 310 | |
| 300 void FocusManager::SetFocusedViewWithReason( | 311 void FocusManager::SetFocusedViewWithReason( |
| 301 View* view, FocusChangeReason reason) { | 312 View* view, FocusChangeReason reason) { |
| 302 if (focused_view_ == view) | 313 if (focused_view_ == view) |
| 303 return; | 314 return; |
| 304 | 315 |
| 305 base::AutoReset<bool> auto_changing_focus(&is_changing_focus_, true); | 316 base::AutoReset<bool> auto_changing_focus(&is_changing_focus_, true); |
| 306 // Update the reason for the focus change (since this is checked by | 317 // Update the reason for the focus change (since this is checked by |
| 307 // some listeners), then notify all listeners. | 318 // some listeners), then notify all listeners. |
| 308 focus_change_reason_ = reason; | 319 focus_change_reason_ = reason; |
| 309 FOR_EACH_OBSERVER(FocusChangeListener, focus_change_listeners_, | 320 FOR_EACH_OBSERVER(FocusChangeListener, focus_change_listeners_, |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 334 } | 345 } |
| 335 | 346 |
| 336 void FocusManager::AdvanceFocusIfNecessary() { | 347 void FocusManager::AdvanceFocusIfNecessary() { |
| 337 // If widget is inactive, there is no focused view to check. The stored view | 348 // If widget is inactive, there is no focused view to check. The stored view |
| 338 // will also be checked for focusability when it is being restored. | 349 // will also be checked for focusability when it is being restored. |
| 339 if (!widget_->IsActive()) | 350 if (!widget_->IsActive()) |
| 340 return; | 351 return; |
| 341 | 352 |
| 342 // If widget is active and focused view is not focusable, advance focus or, | 353 // If widget is active and focused view is not focusable, advance focus or, |
| 343 // if not possible, clear focus. | 354 // if not possible, clear focus. |
| 344 if (focused_view_ && !focused_view_->IsAccessibilityFocusable()) { | 355 if (focused_view_ && !IsFocusable(focused_view_)) { |
| 345 AdvanceFocus(false); | 356 AdvanceFocus(false); |
| 346 if (focused_view_ && !focused_view_->IsAccessibilityFocusable()) | 357 if (focused_view_ && !IsFocusable(focused_view_)) |
| 347 ClearFocus(); | 358 ClearFocus(); |
| 348 } | 359 } |
| 349 } | 360 } |
| 350 | 361 |
| 351 void FocusManager::StoreFocusedView(bool clear_native_focus) { | 362 void FocusManager::StoreFocusedView(bool clear_native_focus) { |
| 352 View* focused_view = focused_view_; | 363 View* focused_view = focused_view_; |
| 353 // Don't do anything if no focused view. Storing the view (which is NULL), in | 364 // Don't do anything if no focused view. Storing the view (which is NULL), in |
| 354 // this case, would clobber the view that was previously saved. | 365 // this case, would clobber the view that was previously saved. |
| 355 if (!focused_view_) | 366 if (!focused_view_) |
| 356 return; | 367 return; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 371 } | 382 } |
| 372 | 383 |
| 373 if (v) | 384 if (v) |
| 374 v->SchedulePaint(); // Remove focus border. | 385 v->SchedulePaint(); // Remove focus border. |
| 375 } | 386 } |
| 376 | 387 |
| 377 bool FocusManager::RestoreFocusedView() { | 388 bool FocusManager::RestoreFocusedView() { |
| 378 View* view = GetStoredFocusView(); | 389 View* view = GetStoredFocusView(); |
| 379 if (view) { | 390 if (view) { |
| 380 if (ContainsView(view)) { | 391 if (ContainsView(view)) { |
| 392 // Todo change this. | |
| 381 if (!view->IsFocusable() && view->IsAccessibilityFocusable()) { | 393 if (!view->IsFocusable() && view->IsAccessibilityFocusable()) { |
|
karandeepb
2016/03/15 02:19:51
I can't understand the rationale behind this line
tapted
2016/03/15 05:05:31
So I think `RequestFocus` can be overridden by a V
karandeepb
2016/03/17 07:24:46
Thanks!
| |
| 382 // RequestFocus would fail, but we want to restore focus to controls | 394 // RequestFocus would fail, but we want to restore focus to controls |
| 383 // that had focus in accessibility mode. | 395 // that had focus in accessibility mode. |
| 384 SetFocusedViewWithReason(view, kReasonFocusRestore); | 396 SetFocusedViewWithReason(view, kReasonFocusRestore); |
| 385 } else { | 397 } else { |
| 386 // This usually just sets the focus if this view is focusable, but | 398 // This usually just sets the focus if this view is focusable, but |
| 387 // let the view override RequestFocus if necessary. | 399 // let the view override RequestFocus if necessary. |
| 388 view->RequestFocus(); | 400 view->RequestFocus(); |
| 389 | 401 |
| 390 // If it succeeded, the reason would be incorrect; set it to | 402 // If it succeeded, the reason would be incorrect; set it to |
| 391 // focus restore. | 403 // focus restore. |
| 392 if (focused_view_ == view) | 404 if (focused_view_ == view) |
| 393 focus_change_reason_ = kReasonFocusRestore; | 405 focus_change_reason_ = kReasonFocusRestore; |
| 394 } | 406 } |
| 395 } | 407 } |
| 396 return true; | 408 // The |keyboard_accessible_| mode may have changed while the widget was |
| 409 // inactive. | |
| 410 AdvanceFocusIfNecessary(); | |
| 397 } | 411 } |
| 398 return false; | 412 return view == focused_view_; |
| 399 } | 413 } |
| 400 | 414 |
| 401 void FocusManager::SetStoredFocusView(View* focus_view) { | 415 void FocusManager::SetStoredFocusView(View* focus_view) { |
| 402 ViewStorage* view_storage = ViewStorage::GetInstance(); | 416 ViewStorage* view_storage = ViewStorage::GetInstance(); |
| 403 if (!view_storage) { | 417 if (!view_storage) { |
| 404 // This should never happen but bug 981648 seems to indicate it could. | 418 // This should never happen but bug 981648 seems to indicate it could. |
| 405 NOTREACHED(); | 419 NOTREACHED(); |
| 406 return; | 420 return; |
| 407 } | 421 } |
| 408 | 422 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 535 return true; | 549 return true; |
| 536 } | 550 } |
| 537 if (key_code == ui::VKEY_RIGHT || key_code == ui::VKEY_DOWN) { | 551 if (key_code == ui::VKEY_RIGHT || key_code == ui::VKEY_DOWN) { |
| 538 AdvanceFocus(false); | 552 AdvanceFocus(false); |
| 539 return true; | 553 return true; |
| 540 } | 554 } |
| 541 | 555 |
| 542 return false; | 556 return false; |
| 543 } | 557 } |
| 544 | 558 |
| 559 bool FocusManager::IsFocusable(View* view) const { | |
| 560 DCHECK(view); | |
| 561 return keyboard_accessible_ ? view->IsAccessibilityFocusable() | |
| 562 : view->IsFocusable(); | |
| 563 } | |
| 564 | |
| 545 } // namespace views | 565 } // namespace views |
| OLD | NEW |