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

Side by Side Diff: athena/screen/screen_manager_impl.cc

Issue 863033002: Delete athena/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 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
« no previous file with comments | « athena/screen/screen_manager_impl.h ('k') | athena/screen/screen_manager_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "athena/screen/screen_manager_impl.h"
6
7 #include "athena/input/public/accelerator_manager.h"
8 #include "athena/screen/modal_window_controller.h"
9 #include "athena/screen/screen_accelerator_handler.h"
10 #include "athena/util/container_priorities.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "ui/aura/client/aura_constants.h"
14 #include "ui/aura/client/screen_position_client.h"
15 #include "ui/aura/test/test_screen.h"
16 #include "ui/aura/window.h"
17 #include "ui/aura/window_property.h"
18 #include "ui/aura/window_targeter.h"
19 #include "ui/aura/window_tree_host.h"
20 #include "ui/gfx/display.h"
21 #include "ui/gfx/screen.h"
22 #include "ui/wm/core/base_focus_rules.h"
23 #include "ui/wm/core/capture_controller.h"
24 #include "ui/wm/core/default_screen_position_client.h"
25 #include "ui/wm/core/focus_controller.h"
26 #include "ui/wm/core/window_util.h"
27
28 DECLARE_WINDOW_PROPERTY_TYPE(athena::ScreenManager::ContainerParams*);
29
30 namespace athena {
31 namespace {
32
33 DEFINE_OWNED_WINDOW_PROPERTY_KEY(ScreenManager::ContainerParams,
34 kContainerParamsKey,
35 nullptr);
36
37 ScreenManagerImpl* instance = nullptr;
38
39 // A functor to find a container that has the higher priority.
40 struct HigherPriorityFinder {
41 HigherPriorityFinder(int p) : priority(p) {}
42 bool operator()(aura::Window* window) {
43 return window->GetProperty(kContainerParamsKey)->z_order_priority >
44 priority;
45 }
46 int priority;
47 };
48
49 bool BlockEvents(aura::Window* container) {
50 ScreenManager::ContainerParams* params =
51 container->GetProperty(kContainerParamsKey);
52 return params && params->block_events && container->IsVisible();
53 }
54
55 bool DefaultContainer(aura::Window* container) {
56 ScreenManager::ContainerParams* params =
57 container->GetProperty(kContainerParamsKey);
58 return params && params->default_parent;
59 }
60
61 bool HasModalContainerPriority(aura::Window* container) {
62 ScreenManager::ContainerParams* params =
63 container->GetProperty(kContainerParamsKey);
64 return params && params->modal_container_priority != -1;
65 }
66
67 bool IsSystemModal(aura::Window* window) {
68 return window->GetProperty(aura::client::kModalKey) == ui::MODAL_TYPE_SYSTEM;
69 }
70
71 // Returns the container which contains |window|.
72 aura::Window* GetContainer(aura::Window* window) {
73 aura::Window* container = window;
74 while (container && !container->GetProperty(kContainerParamsKey))
75 container = container->parent();
76 return container;
77 }
78
79 class AthenaFocusRules : public wm::BaseFocusRules {
80 public:
81 AthenaFocusRules() {}
82 ~AthenaFocusRules() override {}
83
84 // wm::BaseFocusRules:
85 virtual bool SupportsChildActivation(aura::Window* window) const override {
86 ScreenManager::ContainerParams* params =
87 window->GetProperty(kContainerParamsKey);
88 return params && params->can_activate_children;
89 }
90 virtual bool CanActivateWindow(aura::Window* window) const override {
91 if (!window)
92 return true;
93
94 // Check if containers of higher z-order than |window| have 'block_events'
95 // fields.
96 if (window->GetRootWindow()) {
97 const aura::Window::Windows& containers =
98 window->GetRootWindow()->children();
99 aura::Window::Windows::const_iterator iter =
100 std::find(containers.begin(), containers.end(), GetContainer(window));
101 DCHECK(iter != containers.end());
102 for (++iter; iter != containers.end(); ++iter) {
103 if (BlockEvents(*iter))
104 return false;
105 }
106 }
107 return BaseFocusRules::CanActivateWindow(window);
108 }
109
110 aura::Window* GetTopmostWindowToActivateInContainer(
111 aura::Window* container,
112 aura::Window* ignore) const {
113 for (aura::Window::Windows::const_reverse_iterator i =
114 container->children().rbegin();
115 i != container->children().rend();
116 ++i) {
117 if (*i != ignore && CanActivateWindow(*i))
118 return *i;
119 }
120 return NULL;
121 }
122
123 virtual aura::Window* GetNextActivatableWindow(
124 aura::Window* ignore) const override {
125 const aura::Window::Windows& containers =
126 ignore->GetRootWindow()->children();
127 auto starting_container_iter = containers.begin();
128 for (auto container_iter = containers.begin();
129 container_iter != containers.end();
130 container_iter++) {
131 if ((*container_iter)->Contains(ignore)) {
132 starting_container_iter = container_iter;
133 break;
134 }
135 }
136
137 // Find next window from the front containers.
138 aura::Window* next = nullptr;
139 for (auto container_iter = starting_container_iter;
140 !next && container_iter != containers.end();
141 container_iter++) {
142 next = GetTopmostWindowToActivateInContainer(*container_iter, ignore);
143 }
144
145 // Find next window from the back containers.
146 auto container_iter = starting_container_iter;
147 while (!next && container_iter != containers.begin()) {
148 container_iter--;
149 next = GetTopmostWindowToActivateInContainer(*container_iter, ignore);
150 }
151 return next;
152 }
153
154 private:
155 DISALLOW_COPY_AND_ASSIGN(AthenaFocusRules);
156 };
157
158 class AthenaScreenPositionClient : public wm::DefaultScreenPositionClient {
159 public:
160 AthenaScreenPositionClient() {
161 }
162 ~AthenaScreenPositionClient() override {}
163
164 private:
165 // aura::client::ScreenPositionClient:
166 void ConvertHostPointToScreen(aura::Window* window,
167 gfx::Point* point) override {
168 // TODO(oshima): Implement this when adding multiple display support.
169 NOTREACHED();
170 }
171
172 DISALLOW_COPY_AND_ASSIGN(AthenaScreenPositionClient);
173 };
174
175 class AthenaWindowTargeter : public aura::WindowTargeter {
176 public:
177 explicit AthenaWindowTargeter(aura::Window* root_window)
178 : root_window_(root_window) {}
179
180 ~AthenaWindowTargeter() override {}
181
182 private:
183 // aura::WindowTargeter:
184 virtual bool SubtreeCanAcceptEvent(
185 ui::EventTarget* target,
186 const ui::LocatedEvent& event) const override {
187 const aura::Window::Windows& containers = root_window_->children();
188 auto r_iter =
189 std::find_if(containers.rbegin(), containers.rend(), &BlockEvents);
190 if (r_iter == containers.rend())
191 return aura::WindowTargeter::SubtreeCanAcceptEvent(target, event);
192
193 aura::Window* window = static_cast<aura::Window*>(target);
194 for (;; --r_iter) {
195 if ((*r_iter)->Contains(window))
196 return aura::WindowTargeter::SubtreeCanAcceptEvent(target, event);
197 if (r_iter == containers.rbegin())
198 break;
199 }
200 return false;
201 }
202
203 virtual ui::EventTarget* FindTargetForLocatedEvent(
204 ui::EventTarget* root,
205 ui::LocatedEvent* event) override {
206 ui::EventTarget* target =
207 aura::WindowTargeter::FindTargetForLocatedEvent(root, event);
208 if (target)
209 return target;
210 // If the root target is blocking the event, return the container even if
211 // there is no target found so that windows behind it will not be searched.
212 const ScreenManager::ContainerParams* params =
213 static_cast<aura::Window*>(root)->GetProperty(kContainerParamsKey);
214 return (params && params->block_events) ? root : nullptr;
215 }
216
217 // Not owned.
218 aura::Window* root_window_;
219
220 DISALLOW_COPY_AND_ASSIGN(AthenaWindowTargeter);
221 };
222
223 } // namespace
224
225 ScreenManagerImpl::ScreenManagerImpl(aura::Window* root_window)
226 : root_window_(root_window),
227 last_requested_rotation_(gfx::Display::ROTATE_0),
228 rotation_locked_(false) {
229 DCHECK(root_window_);
230 DCHECK(!instance);
231 instance = this;
232 }
233
234 ScreenManagerImpl::~ScreenManagerImpl() {
235 aura::client::SetScreenPositionClient(root_window_, nullptr);
236 aura::client::SetWindowTreeClient(root_window_, nullptr);
237 wm::FocusController* focus_controller =
238 static_cast<wm::FocusController*>(focus_client_.get());
239 root_window_->RemovePreTargetHandler(focus_controller);
240 aura::client::SetActivationClient(root_window_, nullptr);
241 aura::client::SetFocusClient(root_window_, nullptr);
242 aura::Window::Windows children = root_window_->children();
243 // Close All children:
244 for (aura::Window::Windows::iterator iter = children.begin();
245 iter != children.end();
246 ++iter) {
247 delete *iter;
248 }
249 instance = nullptr;
250 }
251
252 void ScreenManagerImpl::Init() {
253 wm::FocusController* focus_controller =
254 new wm::FocusController(new AthenaFocusRules());
255
256 aura::client::SetFocusClient(root_window_, focus_controller);
257 root_window_->AddPreTargetHandler(focus_controller);
258 aura::client::SetActivationClient(root_window_, focus_controller);
259 focus_client_.reset(focus_controller);
260
261 capture_client_.reset(new ::wm::ScopedCaptureClient(root_window_));
262 accelerator_handler_.reset(new ScreenAcceleratorHandler());
263
264 aura::client::SetWindowTreeClient(root_window_, this);
265
266 screen_position_client_.reset(new AthenaScreenPositionClient());
267 aura::client::SetScreenPositionClient(root_window_,
268 screen_position_client_.get());
269 root_window_->SetEventTargeter(
270 make_scoped_ptr(new AthenaWindowTargeter(root_window_)));
271 }
272
273 aura::Window* ScreenManagerImpl::FindContainerByPriority(int priority) {
274 for (aura::Window* window : root_window_->children()) {
275 if (window->GetProperty(kContainerParamsKey)->z_order_priority == priority)
276 return window;
277 }
278 return nullptr;
279 }
280
281 aura::Window* ScreenManagerImpl::CreateContainer(
282 const ContainerParams& params) {
283 const aura::Window::Windows& children = root_window_->children();
284
285 if (params.default_parent) {
286 CHECK(std::find_if(children.begin(), children.end(), &DefaultContainer) ==
287 children.end());
288 }
289 // mmodal container's priority must be higher than the container's priority.
290 DCHECK(params.modal_container_priority == -1 ||
291 params.modal_container_priority > params.z_order_priority);
292 // Default parent must specify modal_container_priority.
293 DCHECK(!params.default_parent || params.modal_container_priority != -1);
294
295 aura::Window* container = new aura::Window(nullptr);
296 CHECK_GE(params.z_order_priority, 0);
297 container->Init(aura::WINDOW_LAYER_NOT_DRAWN);
298 container->SetName(params.name);
299
300 DCHECK(!FindContainerByPriority(params.z_order_priority))
301 << "The container with the priority " << params.z_order_priority
302 << " already exists.";
303
304 container->SetProperty(kContainerParamsKey, new ContainerParams(params));
305
306 root_window_->AddChild(container);
307
308 aura::Window::Windows::const_iterator iter =
309 std::find_if(children.begin(),
310 children.end(),
311 HigherPriorityFinder(params.z_order_priority));
312 if (iter != children.end())
313 root_window_->StackChildBelow(container, *iter);
314
315 container->Show();
316 return container;
317 }
318
319 aura::Window* ScreenManagerImpl::GetContext() {
320 return root_window_;
321 }
322
323 void ScreenManagerImpl::SetRotation(gfx::Display::Rotation rotation) {
324 last_requested_rotation_ = rotation;
325 if (rotation_locked_ || rotation ==
326 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().rotation()) {
327 return;
328 }
329
330 // TODO(flackr): Use display manager to update display rotation:
331 // http://crbug.com/401044.
332 static_cast<aura::TestScreen*>(gfx::Screen::GetNativeScreen())->
333 SetDisplayRotation(rotation);
334 }
335
336 void ScreenManagerImpl::SetRotationLocked(bool rotation_locked) {
337 rotation_locked_ = rotation_locked;
338 if (!rotation_locked_)
339 SetRotation(last_requested_rotation_);
340 }
341
342 int ScreenManagerImpl::GetModalContainerPriority(aura::Window* window,
343 aura::Window* parent) {
344 const aura::Window::Windows& children = root_window_->children();
345 if (window->GetProperty(aura::client::kAlwaysOnTopKey)) {
346 // Use top most modal container.
347 auto iter = std::find_if(
348 children.rbegin(), children.rend(), &HasModalContainerPriority);
349 DCHECK(iter != children.rend());
350 return (*iter)->GetProperty(kContainerParamsKey)->modal_container_priority;
351 } else {
352 // use the container closest to the parent which has modal
353 // container priority.
354 auto iter = std::find(children.rbegin(), children.rend(), parent);
355 DCHECK(iter != children.rend());
356 iter = std::find_if(iter, children.rend(), &HasModalContainerPriority);
357 DCHECK(iter != children.rend());
358 return (*iter)->GetProperty(kContainerParamsKey)->modal_container_priority;
359 }
360 }
361
362 aura::Window* ScreenManagerImpl::GetDefaultParent(aura::Window* context,
363 aura::Window* window,
364 const gfx::Rect& bounds) {
365 aura::Window* parent = wm::GetTransientParent(window);
366 if (parent)
367 parent = GetContainer(parent);
368 else
369 parent = GetDefaultContainer();
370
371 if (IsSystemModal(window)) {
372 DCHECK(window->type() == ui::wm::WINDOW_TYPE_NORMAL ||
373 window->type() == ui::wm::WINDOW_TYPE_POPUP);
374 int priority = GetModalContainerPriority(window, parent);
375
376 parent = FindContainerByPriority(priority);
377 if (!parent) {
378 ModalWindowController* controller = new ModalWindowController(priority);
379 parent = controller->modal_container();
380 }
381 }
382 return parent;
383 }
384
385 aura::Window* ScreenManagerImpl::GetDefaultContainer() {
386 const aura::Window::Windows& children = root_window_->children();
387 return *(std::find_if(children.begin(), children.end(), &DefaultContainer));
388 }
389
390 ScreenManager::ContainerParams::ContainerParams(const std::string& n,
391 int priority)
392 : name(n),
393 can_activate_children(false),
394 block_events(false),
395 z_order_priority(priority),
396 default_parent(false),
397 modal_container_priority(-1) {
398 }
399
400 // static
401 ScreenManager* ScreenManager::Create(aura::Window* root_window) {
402 (new ScreenManagerImpl(root_window))->Init();
403 DCHECK(instance);
404 return instance;
405 }
406
407 // static
408 ScreenManager* ScreenManager::Get() {
409 DCHECK(instance);
410 return instance;
411 }
412
413 // static
414 void ScreenManager::Shutdown() {
415 DCHECK(instance);
416 delete instance;
417 DCHECK(!instance);
418 }
419
420 } // namespace athena
OLDNEW
« no previous file with comments | « athena/screen/screen_manager_impl.h ('k') | athena/screen/screen_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698