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

Side by Side Diff: ui/views/corewm/base_focus_rules.cc

Issue 11414304: Fleshes out the basic set of focus rules a bit more. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years 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
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/corewm/base_focus_rules.h" 5 #include "ui/views/corewm/base_focus_rules.h"
6 6
7 #include "ui/aura/client/activation_delegate.h"
8 #include "ui/aura/client/focus_client.h"
7 #include "ui/aura/root_window.h" 9 #include "ui/aura/root_window.h"
8 #include "ui/aura/window.h" 10 #include "ui/aura/window.h"
11 #include "ui/views/corewm/window_modality_controller.h"
9 12
10 namespace views { 13 namespace views {
11 namespace corewm { 14 namespace corewm {
15 namespace {
16
17 aura::Window* GetFocusedWindow(aura::Window* context) {
18 aura::client::FocusClient* focus_client =
19 aura::client::GetFocusClient(context);
20 return focus_client ? focus_client->GetFocusedWindow() : NULL;
21 }
22
23 } // namespace
12 24
13 //////////////////////////////////////////////////////////////////////////////// 25 ////////////////////////////////////////////////////////////////////////////////
14 // BaseFocusRules, public: 26 // BaseFocusRules, protected:
15 27
16 BaseFocusRules::BaseFocusRules() { 28 BaseFocusRules::BaseFocusRules() {
17 } 29 }
18 30
19 BaseFocusRules::~BaseFocusRules() { 31 BaseFocusRules::~BaseFocusRules() {
20 } 32 }
21 33
34 bool BaseFocusRules::IsWindowConsideredVisibleForActivation(
35 aura::Window* window) {
36 return window->IsVisible();
37 }
38
22 //////////////////////////////////////////////////////////////////////////////// 39 ////////////////////////////////////////////////////////////////////////////////
23 // BaseFocusRules, FocusRules implementation: 40 // BaseFocusRules, FocusRules implementation:
24 41
25 bool BaseFocusRules::CanActivateWindow(aura::Window* window) { 42 bool BaseFocusRules::CanActivateWindow(aura::Window* window) {
26 return !window || 43 // It is possible to activate a NULL window, it is equivalent to clearing
27 (window->IsVisible() && window->parent() == window->GetRootWindow()); 44 // activation.
45 if (!window)
sadrul 2012/12/04 16:19:40 The doc claims the window needs to be non-NULL. Bu
46 return true;
47
48 // The window must in a valid hierarchy.
49 if (!window->GetRootWindow())
50 return false;
51
52 // The window must be visible.
53 if (!IsWindowConsideredVisibleForActivation(window))
54 return false;
55
56 // The window's activation delegate must allow this window to be activated.
57 if (aura::client::GetActivationDelegate(window) &&
58 !aura::client::GetActivationDelegate(window)->ShouldActivate()) {
59 return false;
60 }
61
62 // The window must exist within a container that supports activation.
63 // The window cannot be blocked by a modal transient.
64 return SupportsChildActivation(window->parent()) &&
65 !GetModalTransientForActivatableWindow(window);
28 } 66 }
29 67
30 bool BaseFocusRules::CanFocusWindow(aura::Window* window) { 68 bool BaseFocusRules::CanFocusWindow(aura::Window* window) {
31 // See FocusRules: NULL is a valid focusable window (when clearing focus). 69 // It is possible to focus a NULL window, it is equivalent to clearing focus.
32 return !window || window->CanFocus(); 70 if (!window)
71 return true;
72
73 // The focused window is always inside the active window, so windows that
74 // aren't activatable can't contain the focused window.
75 aura::Window* activatable = GetActivatableWindow(window);
76 if (!activatable->Contains(window))
77 return false;
78 return window->CanFocus();
33 } 79 }
34 80
35 aura::Window* BaseFocusRules::GetActivatableWindow(aura::Window* window) { 81 aura::Window* BaseFocusRules::GetActivatableWindow(aura::Window* window) {
36 // BasicFocusRules considers only direct children of the RootWindow as
37 // activatable.
38 aura::Window* parent = window->parent(); 82 aura::Window* parent = window->parent();
39 aura::Window* activatable = window; 83 aura::Window* child = window;
40 aura::RootWindow* root_window = window->GetRootWindow(); 84 while (parent) {
41 while (parent != root_window) { 85 if (CanActivateWindow(child))
42 activatable = parent; 86 return child;
87
88 if (child->transient_parent())
89 return GetActivatableWindow(child->transient_parent());
90
43 parent = parent->parent(); 91 parent = parent->parent();
92 child = child->parent();
44 } 93 }
45 return activatable; 94 return NULL;
46 } 95 }
47 96
48 aura::Window* BaseFocusRules::GetFocusableWindow(aura::Window* window) { 97 aura::Window* BaseFocusRules::GetFocusableWindow(aura::Window* window) {
98 if (CanFocusWindow(window))
99 return window;
100
101 // |window| may be in a hierarchy that is non-activatable, in which case we
102 // need to cut over to the activatable hierarchy.
103 aura::Window* activatable = GetActivatableWindow(window);
104 if (!activatable)
105 return GetFocusedWindow(window);
106
107 if (!activatable->Contains(window)) {
108 // If there's already a child window focused in the activatable hierarchy,
109 // just use that (i.e. don't shift focus), otherwise we need to at least cut
110 // over to the activatable hierarchy.
111 aura::Window* focused = GetFocusedWindow(activatable);
112 return activatable->Contains(focused) ? focused : activatable;
113 }
114
49 while (window && !CanFocusWindow(window)) 115 while (window && !CanFocusWindow(window))
50 window = window->parent(); 116 window = window->parent();
51 return window; 117 return window;
52 } 118 }
53 119
54 aura::Window* BaseFocusRules::GetNextActivatableWindow(aura::Window* ignore) { 120 aura::Window* BaseFocusRules::GetNextActivatableWindow(aura::Window* ignore) {
55 DCHECK(ignore); 121 DCHECK(ignore);
56 122
57 // Can be called from the RootWindow's destruction, which has a NULL parent. 123 // Can be called from the RootWindow's destruction, which has a NULL parent.
58 if (!ignore->parent()) 124 if (!ignore->parent())
(...skipping 22 matching lines...) Expand all
81 // Focus cycling is currently very primitive: we just climb the tree. 147 // Focus cycling is currently very primitive: we just climb the tree.
82 // If need be, we could add the ability to look at siblings, descend etc. 148 // If need be, we could add the ability to look at siblings, descend etc.
83 // For test coverage, see FocusControllerImplicitTestBase subclasses in 149 // For test coverage, see FocusControllerImplicitTestBase subclasses in
84 // focus_controller_unittest.cc. 150 // focus_controller_unittest.cc.
85 return GetFocusableWindow(ignore->parent()); 151 return GetFocusableWindow(ignore->parent());
86 } 152 }
87 153
88 154
89 } // namespace corewm 155 } // namespace corewm
90 } // namespace views 156 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698