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