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