window_watcher.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)// found in the LICENSE file. 4d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 5d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "ash/shell/window_watcher.h" 6d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 7d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "ash/display/display_controller.h" 8d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "ash/shelf/shelf.h" 9d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "ash/shelf/shelf_item_delegate_manager.h" 10d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "ash/shelf/shelf_model.h" 11d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "ash/shelf/shelf_util.h" 12d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "ash/shelf/shelf_widget.h" 13d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "ash/shell.h" 14#include "ash/shell/window_watcher_shelf_item_delegate.h" 15#include "ash/shell_window_ids.h" 16#include "ui/aura/window.h" 17#include "ui/aura/window_event_dispatcher.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 Shelf::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 Shelf::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::ShelfID 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() != ui::wm::WINDOW_TYPE_NORMAL && 97 new_window->type() != ui::wm::WINDOW_TYPE_PANEL) 98 return; 99 100 static int image_count = 0; 101 ShelfModel* model = Shell::GetInstance()->shelf_model(); 102 ShelfItem item; 103 item.type = new_window->type() == ui::wm::WINDOW_TYPE_PANEL 104 ? ash::TYPE_APP_PANEL 105 : ash::TYPE_PLATFORM_APP; 106 ash::ShelfID id = model->next_id(); 107 id_to_window_[id] = new_window; 108 109 SkBitmap icon_bitmap; 110 icon_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 16, 16); 111 icon_bitmap.allocPixels(); 112 icon_bitmap.eraseARGB(255, 113 image_count == 0 ? 255 : 0, 114 image_count == 1 ? 255 : 0, 115 image_count == 2 ? 255 : 0); 116 image_count = (image_count + 1) % 3; 117 item.image = gfx::ImageSkia(gfx::ImageSkiaRep(icon_bitmap, 1.0f)); 118 119 model->Add(item); 120 121 ShelfItemDelegateManager* manager = 122 Shell::GetInstance()->shelf_item_delegate_manager(); 123 scoped_ptr<ShelfItemDelegate> delegate( 124 new WindowWatcherShelfItemDelegate(id, this)); 125 manager->SetShelfItemDelegate(id, delegate.Pass()); 126 SetShelfIDForWindow(id, new_window); 127} 128 129void WindowWatcher::OnWillRemoveWindow(aura::Window* window) { 130 for (IDToWindow::iterator i = id_to_window_.begin(); 131 i != id_to_window_.end(); ++i) { 132 if (i->second == window) { 133 ShelfModel* model = Shell::GetInstance()->shelf_model(); 134 int index = model->ItemIndexByID(i->first); 135 DCHECK_NE(-1, index); 136 model->RemoveItemAt(index); 137 id_to_window_.erase(i); 138 break; 139 } 140 } 141} 142 143void WindowWatcher::OnDisplayBoundsChanged(const gfx::Display& display) { 144} 145 146void WindowWatcher::OnDisplayAdded(const gfx::Display& new_display) { 147 aura::Window* root = Shell::GetInstance()->display_controller()-> 148 GetRootWindowForDisplayId(new_display.id()); 149 workspace_window_watcher_->RootWindowAdded(root); 150} 151 152void WindowWatcher::OnDisplayRemoved(const gfx::Display& old_display) { 153 // All windows in the display has already been removed, so no need to 154 // remove observers. 155} 156 157} // namespace shell 158} // namespace ash 159