| 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 |