OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/shelf/shelf_window_watcher.h" | 5 #include "ash/shelf/shelf_window_watcher.h" |
6 | 6 |
7 #include "ash/ash_switches.h" | 7 #include "ash/ash_switches.h" |
8 #include "ash/display/display_controller.h" | 8 #include "ash/display/display_controller.h" |
9 #include "ash/shelf/shelf_constants.h" | 9 #include "ash/shelf/shelf_constants.h" |
10 #include "ash/shelf/shelf_item_delegate_manager.h" | 10 #include "ash/shelf/shelf_item_delegate_manager.h" |
11 #include "ash/shelf/shelf_model.h" | 11 #include "ash/shelf/shelf_model.h" |
12 #include "ash/shelf/shelf_util.h" | 12 #include "ash/shelf/shelf_util.h" |
13 #include "ash/shelf/shelf_window_watcher_item_delegate.h" | 13 #include "ash/shelf/shelf_window_watcher_item_delegate.h" |
14 #include "ash/shell.h" | 14 #include "ash/shell.h" |
15 #include "ash/shell_window_ids.h" | 15 #include "ash/shell_window_ids.h" |
16 #include "ash/wm/window_state.h" | 16 #include "ash/wm/window_state.h" |
17 #include "ash/wm/window_util.h" | 17 #include "ash/wm/window_util.h" |
18 #include "base/memory/scoped_ptr.h" | 18 #include "base/memory/scoped_ptr.h" |
19 #include "ui/aura/client/activation_client.h" | 19 #include "ui/aura/client/activation_client.h" |
20 #include "ui/aura/window.h" | 20 #include "ui/aura/window.h" |
21 #include "ui/base/resource/resource_bundle.h" | 21 #include "ui/base/resource/resource_bundle.h" |
22 #include "ui/gfx/image/image_skia.h" | 22 #include "ui/gfx/image/image_skia.h" |
23 #include "ui/gfx/screen.h" | 23 #include "ui/gfx/screen.h" |
24 | 24 |
25 namespace { | 25 namespace { |
26 | 26 |
27 // Sets LauncherItem property by using the value of |details|. | 27 // Sets ShelfItem property by using the value of |details|. |
28 void SetShelfItemDetailsForLauncherItem( | 28 void SetShelfItemDetailsForShelfItem(ash::ShelfItem* item, |
29 ash::LauncherItem* item, | 29 const ash::ShelfItemDetails& details) { |
30 const ash::ShelfItemDetails& details) { | |
31 item->type = details.type; | 30 item->type = details.type; |
32 if (details.image_resource_id != ash::kInvalidImageResourceID) { | 31 if (details.image_resource_id != ash::kInvalidImageResourceID) { |
33 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 32 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
34 item->image = *rb.GetImageSkiaNamed(details.image_resource_id); | 33 item->image = *rb.GetImageSkiaNamed(details.image_resource_id); |
35 } | 34 } |
36 } | 35 } |
37 | 36 |
38 // Returns true if |window| has a LauncherItem added by ShelfWindowWatcher. | 37 // Returns true if |window| has a ShelfItem added by ShelfWindowWatcher. |
39 bool HasLauncherItemForWindow(aura::Window* window) { | 38 bool HasShelfItemForWindow(aura::Window* window) { |
40 if (ash::GetShelfItemDetailsForWindow(window) != NULL && | 39 if (ash::GetShelfItemDetailsForWindow(window) != NULL && |
41 ash::GetLauncherIDForWindow(window) != ash::kInvalidShelfID) | 40 ash::GetShelfIDForWindow(window) != ash::kInvalidShelfID) |
42 return true; | 41 return true; |
43 return false; | 42 return false; |
44 } | 43 } |
45 | 44 |
46 // Returns true if |window| is in the process of being dragged. | 45 // Returns true if |window| is in the process of being dragged. |
47 bool IsDragging(aura::Window* window) { | 46 bool IsDragging(aura::Window* window) { |
48 return ash::wm::GetWindowState(window)->is_dragged(); | 47 return ash::wm::GetWindowState(window)->is_dragged(); |
49 } | 48 } |
50 | 49 |
51 } // namespace | 50 } // namespace |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 return; | 93 return; |
95 | 94 |
96 // When |window| is re-parented to other containers or |window| is re-parented | 95 // When |window| is re-parented to other containers or |window| is re-parented |
97 // not to |docked_container| during the dragging, its item should be removed | 96 // not to |docked_container| during the dragging, its item should be removed |
98 // and stop observing this |window|. | 97 // and stop observing this |window|. |
99 window_watcher_->FinishObservingRemovedWindow(window); | 98 window_watcher_->FinishObservingRemovedWindow(window); |
100 } | 99 } |
101 | 100 |
102 void ShelfWindowWatcher::RemovedWindowObserver::OnWindowDestroyed( | 101 void ShelfWindowWatcher::RemovedWindowObserver::OnWindowDestroyed( |
103 aura::Window* window) { | 102 aura::Window* window) { |
104 DCHECK(HasLauncherItemForWindow(window)); | 103 DCHECK(HasShelfItemForWindow(window)); |
105 window_watcher_->FinishObservingRemovedWindow(window); | 104 window_watcher_->FinishObservingRemovedWindow(window); |
106 } | 105 } |
107 | 106 |
108 ShelfWindowWatcher::ShelfWindowWatcher( | 107 ShelfWindowWatcher::ShelfWindowWatcher( |
109 ShelfModel* model, | 108 ShelfModel* model, |
110 ShelfItemDelegateManager* item_delegate_manager) | 109 ShelfItemDelegateManager* item_delegate_manager) |
111 : model_(model), | 110 : model_(model), |
112 item_delegate_manager_(item_delegate_manager), | 111 item_delegate_manager_(item_delegate_manager), |
113 root_window_observer_(this), | 112 root_window_observer_(this), |
114 removed_window_observer_(this), | 113 removed_window_observer_(this), |
115 observed_windows_(this), | 114 observed_windows_(this), |
116 observed_root_windows_(&root_window_observer_), | 115 observed_root_windows_(&root_window_observer_), |
117 observed_removed_windows_(&removed_window_observer_), | 116 observed_removed_windows_(&removed_window_observer_), |
118 observed_activation_clients_(this) { | 117 observed_activation_clients_(this) { |
119 // We can't assume all RootWindows have the same ActivationClient. | 118 // We can't assume all RootWindows have the same ActivationClient. |
120 // Add a RootWindow and its ActivationClient to the observed list. | 119 // Add a RootWindow and its ActivationClient to the observed list. |
121 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); | 120 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
122 for (aura::Window::Windows::const_iterator it = root_windows.begin(); | 121 for (aura::Window::Windows::const_iterator it = root_windows.begin(); |
123 it != root_windows.end(); ++it) | 122 it != root_windows.end(); ++it) |
124 OnRootWindowAdded(*it); | 123 OnRootWindowAdded(*it); |
125 | 124 |
126 Shell::GetScreen()->AddObserver(this); | 125 Shell::GetScreen()->AddObserver(this); |
127 } | 126 } |
128 | 127 |
129 ShelfWindowWatcher::~ShelfWindowWatcher() { | 128 ShelfWindowWatcher::~ShelfWindowWatcher() { |
130 Shell::GetScreen()->RemoveObserver(this); | 129 Shell::GetScreen()->RemoveObserver(this); |
131 } | 130 } |
132 | 131 |
133 void ShelfWindowWatcher::AddLauncherItem(aura::Window* window) { | 132 void ShelfWindowWatcher::AddShelfItem(aura::Window* window) { |
134 const ShelfItemDetails* item_details = | 133 const ShelfItemDetails* item_details = |
135 GetShelfItemDetailsForWindow(window); | 134 GetShelfItemDetailsForWindow(window); |
136 LauncherItem item; | 135 ShelfItem item; |
137 LauncherID id = model_->next_id(); | 136 ShelfID id = model_->next_id(); |
138 item.status = wm::IsActiveWindow(window) ? STATUS_ACTIVE: STATUS_RUNNING; | 137 item.status = wm::IsActiveWindow(window) ? STATUS_ACTIVE: STATUS_RUNNING; |
139 SetShelfItemDetailsForLauncherItem(&item, *item_details); | 138 SetShelfItemDetailsForShelfItem(&item, *item_details); |
140 SetLauncherIDForWindow(id, window); | 139 SetShelfIDForWindow(id, window); |
141 scoped_ptr<ShelfItemDelegate> item_delegate( | 140 scoped_ptr<ShelfItemDelegate> item_delegate( |
142 new ShelfWindowWatcherItemDelegate(window, model_)); | 141 new ShelfWindowWatcherItemDelegate(window, model_)); |
143 // |item_delegate| is owned by |item_delegate_manager_|. | 142 // |item_delegate| is owned by |item_delegate_manager_|. |
144 item_delegate_manager_->SetShelfItemDelegate(id, item_delegate.Pass()); | 143 item_delegate_manager_->SetShelfItemDelegate(id, item_delegate.Pass()); |
145 model_->Add(item); | 144 model_->Add(item); |
146 } | 145 } |
147 | 146 |
148 void ShelfWindowWatcher::RemoveLauncherItem(aura::Window* window) { | 147 void ShelfWindowWatcher::RemoveShelfItem(aura::Window* window) { |
149 model_->RemoveItemAt(model_->ItemIndexByID(GetLauncherIDForWindow(window))); | 148 model_->RemoveItemAt(model_->ItemIndexByID(GetShelfIDForWindow(window))); |
150 SetLauncherIDForWindow(kInvalidShelfID, window); | 149 SetShelfIDForWindow(kInvalidShelfID, window); |
151 } | 150 } |
152 | 151 |
153 void ShelfWindowWatcher::OnRootWindowAdded(aura::Window* root_window) { | 152 void ShelfWindowWatcher::OnRootWindowAdded(aura::Window* root_window) { |
154 // |observed_activation_clients_| can have the same ActivationClient multiple | 153 // |observed_activation_clients_| can have the same ActivationClient multiple |
155 // times - which would be handled by the |observed_activation_clients_|. | 154 // times - which would be handled by the |observed_activation_clients_|. |
156 observed_activation_clients_.Add( | 155 observed_activation_clients_.Add( |
157 aura::client::GetActivationClient(root_window)); | 156 aura::client::GetActivationClient(root_window)); |
158 observed_root_windows_.Add(root_window); | 157 observed_root_windows_.Add(root_window); |
159 | 158 |
160 aura::Window* default_container = Shell::GetContainer( | 159 aura::Window* default_container = Shell::GetContainer( |
161 root_window, | 160 root_window, |
162 kShellWindowId_DefaultContainer); | 161 kShellWindowId_DefaultContainer); |
163 observed_windows_.Add(default_container); | 162 observed_windows_.Add(default_container); |
164 for (size_t i = 0; i < default_container->children().size(); ++i) | 163 for (size_t i = 0; i < default_container->children().size(); ++i) |
165 observed_windows_.Add(default_container->children()[i]); | 164 observed_windows_.Add(default_container->children()[i]); |
166 } | 165 } |
167 | 166 |
168 void ShelfWindowWatcher::OnRootWindowRemoved(aura::Window* root_window) { | 167 void ShelfWindowWatcher::OnRootWindowRemoved(aura::Window* root_window) { |
169 observed_root_windows_.Remove(root_window); | 168 observed_root_windows_.Remove(root_window); |
170 observed_activation_clients_.Remove( | 169 observed_activation_clients_.Remove( |
171 aura::client::GetActivationClient(root_window)); | 170 aura::client::GetActivationClient(root_window)); |
172 } | 171 } |
173 | 172 |
174 void ShelfWindowWatcher::UpdateShelfItemStatus(aura::Window* window, | 173 void ShelfWindowWatcher::UpdateShelfItemStatus(aura::Window* window, |
175 bool is_active) { | 174 bool is_active) { |
176 int index = GetLauncherItemIndexForWindow(window); | 175 int index = GetShelfItemIndexForWindow(window); |
177 DCHECK_GE(index, 0); | 176 DCHECK_GE(index, 0); |
178 | 177 |
179 LauncherItem item = model_->items()[index]; | 178 ShelfItem item = model_->items()[index]; |
180 item.status = is_active ? STATUS_ACTIVE : STATUS_RUNNING; | 179 item.status = is_active ? STATUS_ACTIVE : STATUS_RUNNING; |
181 model_->Set(index, item); | 180 model_->Set(index, item); |
182 } | 181 } |
183 | 182 |
184 int ShelfWindowWatcher::GetLauncherItemIndexForWindow( | 183 int ShelfWindowWatcher::GetShelfItemIndexForWindow( |
185 aura::Window* window) const { | 184 aura::Window* window) const { |
186 return model_->ItemIndexByID(GetLauncherIDForWindow(window)); | 185 return model_->ItemIndexByID(GetShelfIDForWindow(window)); |
187 } | 186 } |
188 | 187 |
189 void ShelfWindowWatcher::StartObservingRemovedWindow(aura::Window* window) { | 188 void ShelfWindowWatcher::StartObservingRemovedWindow(aura::Window* window) { |
190 observed_removed_windows_.Add(window); | 189 observed_removed_windows_.Add(window); |
191 } | 190 } |
192 | 191 |
193 void ShelfWindowWatcher::FinishObservingRemovedWindow(aura::Window* window) { | 192 void ShelfWindowWatcher::FinishObservingRemovedWindow(aura::Window* window) { |
194 observed_removed_windows_.Remove(window); | 193 observed_removed_windows_.Remove(window); |
195 RemoveLauncherItem(window); | 194 RemoveShelfItem(window); |
196 } | 195 } |
197 | 196 |
198 void ShelfWindowWatcher::OnWindowActivated(aura::Window* gained_active, | 197 void ShelfWindowWatcher::OnWindowActivated(aura::Window* gained_active, |
199 aura::Window* lost_active) { | 198 aura::Window* lost_active) { |
200 if (gained_active && HasLauncherItemForWindow(gained_active)) | 199 if (gained_active && HasShelfItemForWindow(gained_active)) |
201 UpdateShelfItemStatus(gained_active, true); | 200 UpdateShelfItemStatus(gained_active, true); |
202 if (lost_active && HasLauncherItemForWindow(lost_active)) | 201 if (lost_active && HasShelfItemForWindow(lost_active)) |
203 UpdateShelfItemStatus(lost_active, false); | 202 UpdateShelfItemStatus(lost_active, false); |
204 } | 203 } |
205 | 204 |
206 void ShelfWindowWatcher::OnWindowAdded(aura::Window* window) { | 205 void ShelfWindowWatcher::OnWindowAdded(aura::Window* window) { |
207 observed_windows_.Add(window); | 206 observed_windows_.Add(window); |
208 | 207 |
209 if (observed_removed_windows_.IsObserving(window)) { | 208 if (observed_removed_windows_.IsObserving(window)) { |
210 // When |window| is added and it is already observed by | 209 // When |window| is added and it is already observed by |
211 // |dragged_window_observer_|, |window| already has its item. | 210 // |dragged_window_observer_|, |window| already has its item. |
212 DCHECK(HasLauncherItemForWindow(window)); | 211 DCHECK(HasShelfItemForWindow(window)); |
213 observed_removed_windows_.Remove(window); | 212 observed_removed_windows_.Remove(window); |
214 return; | 213 return; |
215 } | 214 } |
216 | 215 |
217 // Add LauncherItem if |window| already has a ShelfItemDetails when it is | 216 // Add ShelfItem if |window| already has a ShelfItemDetails when it is |
218 // created. Don't make a new LauncherItem for the re-parented |window| that | 217 // created. Don't make a new ShelfItem for the re-parented |window| that |
219 // already has a LauncherItem. | 218 // already has a ShelfItem. |
220 if (GetLauncherIDForWindow(window) == kInvalidShelfID && | 219 if (GetShelfIDForWindow(window) == kInvalidShelfID && |
221 GetShelfItemDetailsForWindow(window)) | 220 GetShelfItemDetailsForWindow(window)) |
222 AddLauncherItem(window); | 221 AddShelfItem(window); |
223 } | 222 } |
224 | 223 |
225 void ShelfWindowWatcher::OnWillRemoveWindow(aura::Window* window) { | 224 void ShelfWindowWatcher::OnWillRemoveWindow(aura::Window* window) { |
226 // Remove a child window of default container. | 225 // Remove a child window of default container. |
227 if (observed_windows_.IsObserving(window)) | 226 if (observed_windows_.IsObserving(window)) |
228 observed_windows_.Remove(window); | 227 observed_windows_.Remove(window); |
229 | 228 |
230 // Don't remove |window| item immediately. Instead, defer handling of removing | 229 // Don't remove |window| item immediately. Instead, defer handling of removing |
231 // |window|'s item to RemovedWindowObserver because |window| could be added | 230 // |window|'s item to RemovedWindowObserver because |window| could be added |
232 // again to default container. | 231 // again to default container. |
233 if (HasLauncherItemForWindow(window)) | 232 if (HasShelfItemForWindow(window)) |
234 StartObservingRemovedWindow(window); | 233 StartObservingRemovedWindow(window); |
235 } | 234 } |
236 | 235 |
237 void ShelfWindowWatcher::OnWindowDestroying(aura::Window* window) { | 236 void ShelfWindowWatcher::OnWindowDestroying(aura::Window* window) { |
238 // Remove the default container. | 237 // Remove the default container. |
239 if (observed_windows_.IsObserving(window)) | 238 if (observed_windows_.IsObserving(window)) |
240 observed_windows_.Remove(window); | 239 observed_windows_.Remove(window); |
241 } | 240 } |
242 | 241 |
243 void ShelfWindowWatcher::OnWindowPropertyChanged(aura::Window* window, | 242 void ShelfWindowWatcher::OnWindowPropertyChanged(aura::Window* window, |
244 const void* key, | 243 const void* key, |
245 intptr_t old) { | 244 intptr_t old) { |
246 if (key != kShelfItemDetailsKey) | 245 if (key != kShelfItemDetailsKey) |
247 return; | 246 return; |
248 | 247 |
249 if (GetShelfItemDetailsForWindow(window) == NULL) { | 248 if (GetShelfItemDetailsForWindow(window) == NULL) { |
250 // Removes LauncherItem for |window| when it has a LauncherItem. | 249 // Removes ShelfItem for |window| when it has a ShelfItem. |
251 if (reinterpret_cast<ShelfItemDetails*>(old) != NULL) | 250 if (reinterpret_cast<ShelfItemDetails*>(old) != NULL) |
252 RemoveLauncherItem(window); | 251 RemoveShelfItem(window); |
253 return; | 252 return; |
254 } | 253 } |
255 | 254 |
256 // When ShelfItemDetails is changed, update LauncherItem. | 255 // When ShelfItemDetails is changed, update ShelfItem. |
257 if (HasLauncherItemForWindow(window)) { | 256 if (HasShelfItemForWindow(window)) { |
258 int index = GetLauncherItemIndexForWindow(window); | 257 int index = GetShelfItemIndexForWindow(window); |
259 DCHECK_GE(index, 0); | 258 DCHECK_GE(index, 0); |
260 LauncherItem item = model_->items()[index]; | 259 ShelfItem item = model_->items()[index]; |
261 const ShelfItemDetails* details = | 260 const ShelfItemDetails* details = |
262 GetShelfItemDetailsForWindow(window); | 261 GetShelfItemDetailsForWindow(window); |
263 SetShelfItemDetailsForLauncherItem(&item, *details); | 262 SetShelfItemDetailsForShelfItem(&item, *details); |
264 model_->Set(index, item); | 263 model_->Set(index, item); |
265 return; | 264 return; |
266 } | 265 } |
267 | 266 |
268 // Creates a new LauncherItem for |window|. | 267 // Creates a new ShelfItem for |window|. |
269 AddLauncherItem(window); | 268 AddShelfItem(window); |
270 } | 269 } |
271 | 270 |
272 void ShelfWindowWatcher::OnDisplayBoundsChanged(const gfx::Display& display) { | 271 void ShelfWindowWatcher::OnDisplayBoundsChanged(const gfx::Display& display) { |
273 } | 272 } |
274 | 273 |
275 void ShelfWindowWatcher::OnDisplayAdded(const gfx::Display& new_display) { | 274 void ShelfWindowWatcher::OnDisplayAdded(const gfx::Display& new_display) { |
276 // Add a new RootWindow and its ActivationClient to observed list. | 275 // Add a new RootWindow and its ActivationClient to observed list. |
277 aura::Window* root_window = Shell::GetInstance()->display_controller()-> | 276 aura::Window* root_window = Shell::GetInstance()->display_controller()-> |
278 GetRootWindowForDisplayId(new_display.id()); | 277 GetRootWindowForDisplayId(new_display.id()); |
279 | 278 |
280 // When the primary root window's display get removed, the existing root | 279 // When the primary root window's display get removed, the existing root |
281 // window is taken over by the new display and the observer is already set. | 280 // window is taken over by the new display and the observer is already set. |
282 if (!observed_root_windows_.IsObserving(root_window)) | 281 if (!observed_root_windows_.IsObserving(root_window)) |
283 OnRootWindowAdded(root_window); | 282 OnRootWindowAdded(root_window); |
284 } | 283 } |
285 | 284 |
286 void ShelfWindowWatcher::OnDisplayRemoved(const gfx::Display& old_display) { | 285 void ShelfWindowWatcher::OnDisplayRemoved(const gfx::Display& old_display) { |
287 // When this is called, RootWindow of |old_display| is already removed. | 286 // When this is called, RootWindow of |old_display| is already removed. |
288 // Instead, we remove an observer from RootWindow and ActivationClient in the | 287 // Instead, we remove an observer from RootWindow and ActivationClient in the |
289 // OnRootWindowDestroyed(). | 288 // OnRootWindowDestroyed(). |
290 // Do nothing here. | 289 // Do nothing here. |
291 } | 290 } |
292 | 291 |
293 } // namespace internal | 292 } // namespace internal |
294 } // namespace ash | 293 } // namespace ash |
OLD | NEW |