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
3// found in the LICENSE file.
4
5#include "ui/wm/core/window_util.h"
6
7#include "ui/aura/window.h"
8#include "ui/compositor/layer.h"
9#include "ui/compositor/layer_tree_owner.h"
10#include "ui/wm/core/transient_window_manager.h"
11#include "ui/wm/public/activation_client.h"
12
13namespace {
14
15// Invokes RecreateLayer() on all the children of |to_clone|, adding the newly
16// cloned children to |parent|.
17//
18// WARNING: It is assumed that |parent| is ultimately owned by a LayerTreeOwner.
19void CloneChildren(ui::Layer* to_clone, ui::Layer* parent) {
20  typedef std::vector<ui::Layer*> Layers;
21  // Make a copy of the children since RecreateLayer() mutates it.
22  Layers children(to_clone->children());
23  for (Layers::const_iterator i = children.begin(); i != children.end(); ++i) {
24    ui::LayerOwner* owner = (*i)->owner();
25    ui::Layer* old_layer = owner ? owner->RecreateLayer().release() : NULL;
26    if (old_layer) {
27      parent->Add(old_layer);
28      // RecreateLayer() moves the existing children to the new layer. Create a
29      // copy of those.
30      CloneChildren(owner->layer(), old_layer);
31    }
32  }
33}
34
35}  // namespace
36
37namespace wm {
38
39void ActivateWindow(aura::Window* window) {
40  DCHECK(window);
41  DCHECK(window->GetRootWindow());
42  aura::client::GetActivationClient(window->GetRootWindow())->ActivateWindow(
43      window);
44}
45
46void DeactivateWindow(aura::Window* window) {
47  DCHECK(window);
48  DCHECK(window->GetRootWindow());
49  aura::client::GetActivationClient(window->GetRootWindow())->DeactivateWindow(
50      window);
51}
52
53bool IsActiveWindow(aura::Window* window) {
54  DCHECK(window);
55  if (!window->GetRootWindow())
56    return false;
57  aura::client::ActivationClient* client =
58      aura::client::GetActivationClient(window->GetRootWindow());
59  return client && client->GetActiveWindow() == window;
60}
61
62bool CanActivateWindow(aura::Window* window) {
63  DCHECK(window);
64  if (!window->GetRootWindow())
65    return false;
66  aura::client::ActivationClient* client =
67      aura::client::GetActivationClient(window->GetRootWindow());
68  return client && client->CanActivateWindow(window);
69}
70
71aura::Window* GetActivatableWindow(aura::Window* window) {
72  aura::client::ActivationClient* client =
73      aura::client::GetActivationClient(window->GetRootWindow());
74  return client ? client->GetActivatableWindow(window) : NULL;
75}
76
77aura::Window* GetToplevelWindow(aura::Window* window) {
78  aura::client::ActivationClient* client =
79      aura::client::GetActivationClient(window->GetRootWindow());
80  return client ? client->GetToplevelWindow(window) : NULL;
81}
82
83scoped_ptr<ui::LayerTreeOwner> RecreateLayers(ui::LayerOwner* root) {
84  scoped_ptr<ui::LayerTreeOwner> old_layer(
85      new ui::LayerTreeOwner(root->RecreateLayer().release()));
86  if (old_layer->root())
87    CloneChildren(root->layer(), old_layer->root());
88  return old_layer.Pass();
89}
90
91aura::Window* GetTransientParent(aura::Window* window) {
92  return const_cast<aura::Window*>(GetTransientParent(
93                                 const_cast<const aura::Window*>(window)));
94}
95
96const aura::Window* GetTransientParent(const aura::Window* window) {
97  const TransientWindowManager* manager = TransientWindowManager::Get(window);
98  return manager ? manager->transient_parent() : NULL;
99}
100
101const std::vector<aura::Window*>& GetTransientChildren(
102    const aura::Window* window) {
103  const TransientWindowManager* manager = TransientWindowManager::Get(window);
104  if (manager)
105    return manager->transient_children();
106
107  static std::vector<aura::Window*>* shared = new std::vector<aura::Window*>;
108  return *shared;
109}
110
111void AddTransientChild(aura::Window* parent, aura::Window* child) {
112  TransientWindowManager::Get(parent)->AddTransientChild(child);
113}
114
115void RemoveTransientChild(aura::Window* parent, aura::Window* child) {
116  TransientWindowManager::Get(parent)->RemoveTransientChild(child);
117}
118
119bool HasTransientAncestor(const aura::Window* window,
120                          const aura::Window* ancestor) {
121  const aura::Window* transient_parent = GetTransientParent(window);
122  if (transient_parent == ancestor)
123    return true;
124  return transient_parent ?
125      HasTransientAncestor(transient_parent, ancestor) : false;
126}
127
128}  // namespace wm
129