diff options
author | yutak@chromium.org <yutak@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-12 23:52:20 +0000 |
---|---|---|
committer | yutak@chromium.org <yutak@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-12 23:52:20 +0000 |
commit | 6d21eb72d7333889badc108afe21dd1bc52e1135 (patch) | |
tree | a45694ee7b3b43fffc8db3dbe113c4ab52e246b9 /views/focus/focus_manager.cc | |
parent | 8e0c43541d22b356b7eac90cfce4a4ebdd69c8f1 (diff) | |
download | chromium_src-6d21eb72d7333889badc108afe21dd1bc52e1135.zip chromium_src-6d21eb72d7333889badc108afe21dd1bc52e1135.tar.gz chromium_src-6d21eb72d7333889badc108afe21dd1bc52e1135.tar.bz2 |
Fix reversed focus traversal order issue.
This change fixes several problems in handling focus traversal and resolves TabbedPane's traversal order issue.
Reversed focus traversal is very tricky, and the original traversal code overlooked several things.
(1) A focusable view may have a FocusTraverasble.
(2) When we are going down, we have to check if the current view has a FocusTraversable.
(3) When we are going up from a FocusTraversable, the parent view may gain the next focus.
This change fixes these issues.
BUG=6871
TEST=See issue 6871.
Review URL: http://codereview.chromium.org/125062
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18335 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'views/focus/focus_manager.cc')
-rw-r--r-- | views/focus/focus_manager.cc | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/views/focus/focus_manager.cc b/views/focus/focus_manager.cc index ab67301..abbc456 100644 --- a/views/focus/focus_manager.cc +++ b/views/focus/focus_manager.cc @@ -360,12 +360,19 @@ View* FocusManager::GetNextFocusableView(View* original_starting_view, View* starting_view = NULL; if (original_starting_view) { - // If the starting view has a focus traversable, use it. - // This is the case with WidgetWins for example. - focus_traversable = original_starting_view->GetFocusTraversable(); - - // Otherwise default to the root view. - if (!focus_traversable) { + if (!reverse) { + // If the starting view has a focus traversable, use it. + // This is the case with WidgetWins for example. + focus_traversable = original_starting_view->GetFocusTraversable(); + + // Otherwise default to the root view. + if (!focus_traversable) { + focus_traversable = original_starting_view->GetRootView(); + starting_view = original_starting_view; + } + } else { + // When you are going back, starting view's FocusTraversable should not be + // used. focus_traversable = original_starting_view->GetRootView(); starting_view = original_starting_view; } @@ -374,8 +381,7 @@ View* FocusManager::GetNextFocusableView(View* original_starting_view, } // Traverse the FocusTraversable tree down to find the focusable view. - View* v = FindFocusableView(focus_traversable, starting_view, - reverse, dont_loop); + View* v = FindFocusableView(focus_traversable, starting_view, reverse); if (v) { return v; } else { @@ -386,15 +392,17 @@ View* FocusManager::GetNextFocusableView(View* original_starting_view, while (parent_focus_traversable) { FocusTraversable* new_focus_traversable = NULL; View* new_starting_view = NULL; - v = parent_focus_traversable ->FindNextFocusableView( - starting_view, reverse, FocusTraversable::UP, dont_loop, - &new_focus_traversable, &new_starting_view); + // When we are going backward, the parent view might gain the next focus. + bool check_starting_view = reverse; + v = parent_focus_traversable->FindNextFocusableView( + starting_view, reverse, FocusTraversable::UP, + check_starting_view, &new_focus_traversable, &new_starting_view); if (new_focus_traversable) { DCHECK(!v); // There is a FocusTraversable, traverse it down. - v = FindFocusableView(new_focus_traversable, NULL, reverse, dont_loop); + v = FindFocusableView(new_focus_traversable, NULL, reverse); } if (v) @@ -563,14 +571,13 @@ FocusManager* FocusManager::GetParentFocusManager() const { // FocusTraversable hierarchy. View* FocusManager::FindFocusableView(FocusTraversable* focus_traversable, View* starting_view, - bool reverse, - bool dont_loop) { + bool reverse) { FocusTraversable* new_focus_traversable = NULL; View* new_starting_view = NULL; View* v = focus_traversable->FindNextFocusableView(starting_view, reverse, FocusTraversable::DOWN, - dont_loop, + false, &new_focus_traversable, &new_starting_view); @@ -584,7 +591,7 @@ View* FocusManager::FindFocusableView(FocusTraversable* focus_traversable, v = focus_traversable->FindNextFocusableView(starting_view, reverse, FocusTraversable::DOWN, - dont_loop, + false, &new_focus_traversable, &new_starting_view); } |