summaryrefslogtreecommitdiffstats
path: root/views/focus/focus_manager.cc
diff options
context:
space:
mode:
authoryutak@chromium.org <yutak@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-12 23:52:20 +0000
committeryutak@chromium.org <yutak@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-12 23:52:20 +0000
commit6d21eb72d7333889badc108afe21dd1bc52e1135 (patch)
treea45694ee7b3b43fffc8db3dbe113c4ab52e246b9 /views/focus/focus_manager.cc
parent8e0c43541d22b356b7eac90cfce4a4ebdd69c8f1 (diff)
downloadchromium_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.cc39
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);
}