Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / ash / shell / window_watcher.cc
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/shelf/shelf.h"
9 #include "ash/shelf/shelf_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_shelf_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
20 namespace ash {
21 namespace shell {
22
23 class 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
72 WindowWatcher::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
81 WindowWatcher::~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
89 aura::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:
95 void 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
129 void 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
143 void WindowWatcher::OnDisplayBoundsChanged(const gfx::Display& display) {
144 }
145
146 void 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
152 void 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