1// Copyright 2013 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/default_activation_client.h"
6
7#include "ui/aura/window.h"
8#include "ui/wm/public/activation_change_observer.h"
9#include "ui/wm/public/activation_delegate.h"
10
11namespace wm {
12
13// Takes care of observing root window destruction & destroying the client.
14class DefaultActivationClient::Deleter : public aura::WindowObserver {
15 public:
16  Deleter(DefaultActivationClient* client, aura::Window* root_window)
17      : client_(client),
18        root_window_(root_window) {
19    root_window_->AddObserver(this);
20  }
21
22 private:
23  virtual ~Deleter() {}
24
25  // Overridden from WindowObserver:
26  virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE {
27    DCHECK_EQ(window, root_window_);
28    root_window_->RemoveObserver(this);
29    delete client_;
30    delete this;
31  }
32
33  DefaultActivationClient* client_;
34  aura::Window* root_window_;
35
36  DISALLOW_COPY_AND_ASSIGN(Deleter);
37};
38
39////////////////////////////////////////////////////////////////////////////////
40// DefaultActivationClient, public:
41
42DefaultActivationClient::DefaultActivationClient(aura::Window* root_window)
43    : last_active_(NULL) {
44  aura::client::SetActivationClient(root_window, this);
45  new Deleter(this, root_window);
46}
47
48////////////////////////////////////////////////////////////////////////////////
49// DefaultActivationClient, client::ActivationClient implementation:
50
51void DefaultActivationClient::AddObserver(
52    aura::client::ActivationChangeObserver* observer) {
53  observers_.AddObserver(observer);
54}
55
56void DefaultActivationClient::RemoveObserver(
57    aura::client::ActivationChangeObserver* observer) {
58  observers_.RemoveObserver(observer);
59}
60
61void DefaultActivationClient::ActivateWindow(aura::Window* window) {
62  aura::Window* last_active = GetActiveWindow();
63  if (last_active == window)
64    return;
65
66  last_active_ = last_active;
67  RemoveActiveWindow(window);
68  active_windows_.push_back(window);
69  window->parent()->StackChildAtTop(window);
70  window->AddObserver(this);
71
72  FOR_EACH_OBSERVER(aura::client::ActivationChangeObserver,
73                    observers_,
74                    OnWindowActivated(window, last_active));
75
76  aura::client::ActivationChangeObserver* observer =
77      aura::client::GetActivationChangeObserver(last_active);
78  if (observer)
79    observer->OnWindowActivated(window, last_active);
80  observer = aura::client::GetActivationChangeObserver(window);
81  if (observer)
82    observer->OnWindowActivated(window, last_active);
83}
84
85void DefaultActivationClient::DeactivateWindow(aura::Window* window) {
86  aura::client::ActivationChangeObserver* observer =
87      aura::client::GetActivationChangeObserver(window);
88  if (observer)
89    observer->OnWindowActivated(NULL, window);
90  if (last_active_)
91    ActivateWindow(last_active_);
92}
93
94aura::Window* DefaultActivationClient::GetActiveWindow() {
95  if (active_windows_.empty())
96    return NULL;
97  return active_windows_.back();
98}
99
100aura::Window* DefaultActivationClient::GetActivatableWindow(
101    aura::Window* window) {
102  return NULL;
103}
104
105aura::Window* DefaultActivationClient::GetToplevelWindow(aura::Window* window) {
106  return NULL;
107}
108
109bool DefaultActivationClient::OnWillFocusWindow(aura::Window* window,
110                                                const ui::Event* event) {
111  return true;
112}
113
114bool DefaultActivationClient::CanActivateWindow(aura::Window* window) const {
115  return true;
116}
117
118////////////////////////////////////////////////////////////////////////////////
119// DefaultActivationClient, aura::WindowObserver implementation:
120
121void DefaultActivationClient::OnWindowDestroyed(aura::Window* window) {
122  if (window == last_active_)
123    last_active_ = NULL;
124
125  if (window == GetActiveWindow()) {
126    active_windows_.pop_back();
127    aura::Window* next_active = GetActiveWindow();
128    if (next_active && aura::client::GetActivationChangeObserver(next_active)) {
129      aura::client::GetActivationChangeObserver(next_active)->OnWindowActivated(
130          next_active, NULL);
131    }
132    return;
133  }
134
135  RemoveActiveWindow(window);
136}
137
138////////////////////////////////////////////////////////////////////////////////
139// DefaultActivationClient, private:
140
141DefaultActivationClient::~DefaultActivationClient() {
142  for (unsigned int i = 0; i < active_windows_.size(); ++i) {
143    active_windows_[i]->RemoveObserver(this);
144  }
145}
146
147void DefaultActivationClient::RemoveActiveWindow(aura::Window* window) {
148  for (unsigned int i = 0; i < active_windows_.size(); ++i) {
149    if (active_windows_[i] == window) {
150      active_windows_.erase(active_windows_.begin() + i);
151      window->RemoveObserver(this);
152      return;
153    }
154  }
155}
156
157}  // namespace wm
158