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

Side by Side Diff: mojo/services/window_manager/basic_focus_rules.cc

Issue 1049993002: Get mojo_shell building inside chromium checkout. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix presubmit Created 5 years, 8 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
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "mojo/services/window_manager/basic_focus_rules.h"
6
7 #include "base/macros.h"
8 #include "third_party/mojo_services/src/view_manager/public/cpp/view.h"
9
10 using mojo::View;
11
12 namespace window_manager {
13
14 BasicFocusRules::BasicFocusRules(View* window_container)
15 : window_container_(window_container) {
16 }
17
18 BasicFocusRules::~BasicFocusRules() {}
19
20 bool BasicFocusRules::SupportsChildActivation(View* view) const {
21 return true;
22 }
23
24 bool BasicFocusRules::IsToplevelView(View* view) const {
25 if (!IsViewParentedToWindowContainer(view))
26 return false;
27
28 // The window must exist within a container that supports activation.
29 // The window cannot be blocked by a modal transient.
30 return SupportsChildActivation(view->parent());
31 }
32
33 bool BasicFocusRules::CanActivateView(View* view) const {
34 if (!view)
35 return true;
36
37 // Only toplevel windows can be activated
38 if (!IsToplevelView(view))
39 return false;
40
41 // The view must be visible.
42 if (!view->visible())
43 return false;
44
45 // TODO(erg): The aura version of this class asks the aura::Window's
46 // ActivationDelegate whether the window is activatable.
47
48 // A window must be focusable to be activatable. We don't call
49 // CanFocusWindow() from here because it will call back to us via
50 // GetActivatableWindow().
51 if (!CanFocusViewImpl(view))
52 return false;
53
54 // TODO(erg): In the aura version, we also check whether the window is
55 // blocked by a modal transient window.
56
57 return true;
58 }
59
60 bool BasicFocusRules::CanFocusView(View* view) const {
61 // It is possible to focus a NULL window, it is equivalent to clearing focus.
62 if (!view)
63 return true;
64
65 // The focused view is always inside the active view, so views that aren't
66 // activatable can't contain the focused view.
67 View* activatable = GetActivatableView(view);
68 if (!activatable || !activatable->Contains(view))
69 return false;
70 return CanFocusViewImpl(view);
71 }
72
73 View* BasicFocusRules::GetToplevelView(View* view) const {
74 View* parent = view->parent();
75 View* child = view;
76 while (parent) {
77 if (IsToplevelView(child))
78 return child;
79
80 parent = parent->parent();
81 child = child->parent();
82 }
83
84 return nullptr;
85 }
86
87 View* BasicFocusRules::GetActivatableView(View* view) const {
88 View* parent = view->parent();
89 View* child = view;
90 while (parent) {
91 if (CanActivateView(child))
92 return child;
93
94 // TODO(erg): In the aura version of this class, we have a whole bunch of
95 // checks to support modal transient windows, and transient parents.
96
97 parent = parent->parent();
98 child = child->parent();
99 }
100
101 return nullptr;
102 }
103
104 View* BasicFocusRules::GetFocusableView(View* view) const {
105 if (CanFocusView(view))
106 return view;
107
108 // |view| may be in a hierarchy that is non-activatable, in which case we
109 // need to cut over to the activatable hierarchy.
110 View* activatable = GetActivatableView(view);
111 if (!activatable) {
112 // There may not be a related activatable hierarchy to cut over to, in which
113 // case we try an unrelated one.
114 View* toplevel = GetToplevelView(view);
115 if (toplevel)
116 activatable = GetNextActivatableView(toplevel);
117 if (!activatable)
118 return nullptr;
119 }
120
121 if (!activatable->Contains(view)) {
122 // If there's already a child window focused in the activatable hierarchy,
123 // just use that (i.e. don't shift focus), otherwise we need to at least cut
124 // over to the activatable hierarchy.
125 View* focused = GetFocusableView(activatable);
126 return activatable->Contains(focused) ? focused : activatable;
127 }
128
129 while (view && !CanFocusView(view))
130 view = view->parent();
131 return view;
132 }
133
134 View* BasicFocusRules::GetNextActivatableView(View* activatable) const {
135 DCHECK(activatable);
136
137 // In the basic scenarios handled by BasicFocusRules, the pool of activatable
138 // windows is limited to the |ignore|'s siblings.
139 const View::Children& siblings = activatable->parent()->children();
140 DCHECK(!siblings.empty());
141
142 for (auto rit = siblings.rbegin(); rit != siblings.rend(); ++rit) {
143 View* cur = *rit;
144 if (cur == activatable)
145 continue;
146 if (CanActivateView(cur))
147 return cur;
148 }
149 return nullptr;
150 }
151
152 // TODO(erg): aura::Window::CanFocus() exists. View::CanFocus() does
153 // not. This is a hack that does everything that Window::CanFocus() currently
154 // does that doesn't require a delegate or an EventClient.
155 bool BasicFocusRules::CanFocusViewImpl(View* view) const {
156 // TODO(erg): In unit tests, views will never be drawn, so we can't rely on
157 // IsDrawn() here.
158 if (IsViewParentedToWindowContainer(view))
159 return view->visible();
160
161 // TODO(erg): Add the intermediary delegate and event client checks once we
162 // have those.
163
164 return CanFocusViewImpl(view->parent());
165 }
166
167 bool BasicFocusRules::IsViewParentedToWindowContainer(View* view) const {
168 return view->parent() == window_container_;
169 }
170
171 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/services/window_manager/basic_focus_rules.h ('k') | mojo/services/window_manager/capture_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698