window_watcher.cc revision f2477e01787aa58f445919b809d89e252beef54f
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/shell/window_watcher.h" 6 7#include "ash/display/display_controller.h" 8#include "ash/launcher/launcher.h" 9#include "ash/launcher/launcher_item_delegate_manager.h" 10#include "ash/shelf/shelf_model.h" 11#include "ash/shelf/shelf_util.h" 12#include "ash/shelf/shelf_widget.h" 13#include "ash/shell.h" 14#include "ash/shell/window_watcher_launcher_item_delegate.h" 15#include "ash/shell_window_ids.h" 16#include "ui/aura/root_window.h" 17#include "ui/aura/window.h" 18#include "ui/gfx/display.h" 19 20namespace ash { 21namespace shell { 22 23class WindowWatcher::WorkspaceWindowWatcher : public aura::WindowObserver { 24 public: 25 explicit WorkspaceWindowWatcher(WindowWatcher* watcher) : watcher_(watcher) { 26 } 27 28 virtual ~WorkspaceWindowWatcher() { 29 } 30 31 virtual void OnWindowAdded(aura::Window* new_window) OVERRIDE { 32 new_window->AddObserver(watcher_); 33 } 34 35 virtual void OnWillRemoveWindow(aura::Window* window) OVERRIDE { 36 DCHECK(window->children().empty()); 37 window->RemoveObserver(watcher_); 38 } 39 40 void RootWindowAdded(aura::Window* root) { 41 aura::Window* panel_container = ash::Shell::GetContainer( 42 root, 43 internal::kShellWindowId_PanelContainer); 44 panel_container->AddObserver(watcher_); 45 46 aura::Window* container = 47 Launcher::ForWindow(root)->shelf_widget()->window_container(); 48 container->AddObserver(this); 49 for (size_t i = 0; i < container->children().size(); ++i) 50 container->children()[i]->AddObserver(watcher_); 51 } 52 53 void RootWindowRemoved(aura::Window* root) { 54 aura::Window* panel_container = ash::Shell::GetContainer( 55 root, 56 internal::kShellWindowId_PanelContainer); 57 panel_container->RemoveObserver(watcher_); 58 59 aura::Window* container = 60 Launcher::ForWindow(root)->shelf_widget()->window_container(); 61 container->RemoveObserver(this); 62 for (size_t i = 0; i < container->children().size(); ++i) 63 container->children()[i]->RemoveObserver(watcher_); 64 } 65 66 private: 67 WindowWatcher* watcher_; 68 69 DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowWatcher); 70}; 71 72WindowWatcher::WindowWatcher() { 73 workspace_window_watcher_.reset(new WorkspaceWindowWatcher(this)); 74 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 75 for (aura::Window::Windows::iterator iter = root_windows.begin(); 76 iter != root_windows.end(); ++ iter) { 77 workspace_window_watcher_->RootWindowAdded(*iter); 78 } 79} 80 81WindowWatcher::~WindowWatcher() { 82 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 83 for (aura::Window::Windows::iterator iter = root_windows.begin(); 84 iter != root_windows.end(); ++ iter) { 85 workspace_window_watcher_->RootWindowRemoved(*iter); 86 } 87} 88 89aura::Window* WindowWatcher::GetWindowByID(ash::LauncherID id) { 90 IDToWindow::const_iterator i = id_to_window_.find(id); 91 return i != id_to_window_.end() ? i->second : NULL; 92} 93 94// aura::WindowObserver overrides: 95void WindowWatcher::OnWindowAdded(aura::Window* new_window) { 96 if (new_window->type() != aura::client::WINDOW_TYPE_NORMAL && 97 new_window->type() != aura::client::WINDOW_TYPE_PANEL) 98 return; 99 100 static int image_count = 0; 101 ShelfModel* model = Shell::GetInstance()->shelf_model(); 102 LauncherItem item; 103 item.type = new_window->type() == aura::client::WINDOW_TYPE_PANEL ? 104 ash::TYPE_APP_PANEL : ash::TYPE_PLATFORM_APP; 105 ash::LauncherID id = model->next_id(); 106 id_to_window_[id] = new_window; 107 108 SkBitmap icon_bitmap; 109 icon_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 16, 16); 110 icon_bitmap.allocPixels(); 111 icon_bitmap.eraseARGB(255, 112 image_count == 0 ? 255 : 0, 113 image_count == 1 ? 255 : 0, 114 image_count == 2 ? 255 : 0); 115 image_count = (image_count + 1) % 3; 116 item.image = gfx::ImageSkia(gfx::ImageSkiaRep(icon_bitmap, 1.0f)); 117 118 model->Add(item); 119 120 ash::LauncherItemDelegateManager* manager = 121 ash::Shell::GetInstance()->launcher_item_delegate_manager(); 122 scoped_ptr<LauncherItemDelegate> delegate( 123 new WindowWatcherLauncherItemDelegate(id, this)); 124 manager->SetLauncherItemDelegate(id, delegate.Pass()); 125 SetLauncherIDForWindow(id, new_window); 126} 127 128void WindowWatcher::OnWillRemoveWindow(aura::Window* window) { 129 for (IDToWindow::iterator i = id_to_window_.begin(); 130 i != id_to_window_.end(); ++i) { 131 if (i->second == window) { 132 ShelfModel* model = Shell::GetInstance()->shelf_model(); 133 int index = model->ItemIndexByID(i->first); 134 DCHECK_NE(-1, index); 135 model->RemoveItemAt(index); 136 id_to_window_.erase(i); 137 break; 138 } 139 } 140} 141 142void WindowWatcher::OnDisplayBoundsChanged(const gfx::Display& display) { 143} 144 145void WindowWatcher::OnDisplayAdded(const gfx::Display& new_display) { 146 aura::Window* root = Shell::GetInstance()->display_controller()-> 147 GetRootWindowForDisplayId(new_display.id()); 148 workspace_window_watcher_->RootWindowAdded(root); 149} 150 151void WindowWatcher::OnDisplayRemoved(const gfx::Display& old_display) { 152 // All windows in the display has already been removed, so no need to 153 // remove observers. 154} 155 156} // namespace shell 157} // namespace ash 158