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 "ash/wm/always_on_top_controller.h"
6
7#include "ash/shell.h"
8#include "ash/shell_window_ids.h"
9#include "ash/wm/property_util.h"
10#include "ui/aura/client/aura_constants.h"
11#include "ui/aura/window.h"
12
13namespace ash {
14namespace internal {
15
16AlwaysOnTopController::AlwaysOnTopController()
17    : always_on_top_container_(NULL) {
18}
19
20AlwaysOnTopController::~AlwaysOnTopController() {
21  if (always_on_top_container_)
22    always_on_top_container_->RemoveObserver(this);
23}
24
25void AlwaysOnTopController::SetAlwaysOnTopContainer(
26    aura::Window* always_on_top_container) {
27  // Container should be empty.
28  DCHECK(always_on_top_container->children().empty());
29
30  // We are not handling any containers yet.
31  DCHECK(always_on_top_container_ == NULL);
32
33  always_on_top_container_ = always_on_top_container;
34  always_on_top_container_->AddObserver(this);
35}
36
37aura::Window* AlwaysOnTopController::GetContainer(aura::Window* window) const {
38  DCHECK(always_on_top_container_);
39  if (window->GetProperty(aura::client::kAlwaysOnTopKey))
40    return always_on_top_container_;
41  return Shell::GetContainer(always_on_top_container_->GetRootWindow(),
42                             kShellWindowId_DefaultContainer);
43}
44
45void AlwaysOnTopController::OnWindowAdded(aura::Window* child) {
46  // Observe direct child of the containers.
47  if (child->parent() == always_on_top_container_)
48    child->AddObserver(this);
49}
50
51void AlwaysOnTopController::OnWillRemoveWindow(aura::Window* child) {
52  child->RemoveObserver(this);
53}
54
55void AlwaysOnTopController::OnWindowPropertyChanged(aura::Window* window,
56                                                    const void* key,
57                                                    intptr_t old) {
58  if (key == aura::client::kAlwaysOnTopKey) {
59    DCHECK(window->type() == aura::client::WINDOW_TYPE_NORMAL ||
60           window->type() == aura::client::WINDOW_TYPE_POPUP);
61    aura::Window* container = GetContainer(window);
62    if (window->parent() != container)
63      container->AddChild(window);
64  }
65}
66
67void AlwaysOnTopController::OnWindowDestroyed(aura::Window* window) {
68  if (window == always_on_top_container_)
69    always_on_top_container_ = NULL;
70}
71
72}  // namespace internal
73}  // namespace ash
74