Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(904)

Side by Side Diff: ash/shelf/shelf_window_watcher.cc

Issue 2211463002: mash: Move ShelfWindowWatcher[ItemDelegate] to ash/common. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Move ShelfWindowWatcher to WmShell. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ash/shelf/shelf_window_watcher.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "ash/common/shelf/shelf_constants.h"
11 #include "ash/common/shelf/shelf_model.h"
12 #include "ash/common/shell_window_ids.h"
13 #include "ash/common/wm/window_state.h"
14 #include "ash/common/wm_shell.h"
15 #include "ash/common/wm_window.h"
16 #include "ash/common/wm_window_property.h"
17 #include "ash/shelf/shelf_window_watcher_item_delegate.h"
18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/display/display.h"
20 #include "ui/display/screen.h"
21 #include "ui/gfx/image/image_skia.h"
22
23 namespace ash {
24 namespace {
25
26 // Sets ShelfItem property by using the value of |details|.
27 void SetShelfItemDetailsForShelfItem(ash::ShelfItem* item,
28 const ash::ShelfItemDetails& details) {
29 item->type = details.type;
30 if (details.image_resource_id != ash::kInvalidImageResourceID) {
31 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
32 item->image = *rb.GetImageSkiaNamed(details.image_resource_id);
33 }
34 }
35
36 // Returns true if |window| has a ShelfItem added by ShelfWindowWatcher.
37 bool HasShelfItemForWindow(WmWindow* window) {
38 return window->GetShelfItemDetails() &&
39 window->GetIntProperty(WmWindowProperty::SHELF_ID) != kInvalidShelfID;
40 }
41
42 } // namespace
43
44 ShelfWindowWatcher::ContainerWindowObserver::ContainerWindowObserver(
45 ShelfWindowWatcher* window_watcher)
46 : window_watcher_(window_watcher) {}
47
48 ShelfWindowWatcher::ContainerWindowObserver::~ContainerWindowObserver() {}
49
50 void ShelfWindowWatcher::ContainerWindowObserver::OnWindowTreeChanged(
51 WmWindow* window,
52 const TreeChangeParams& params) {
53 if (!params.old_parent && params.new_parent &&
54 params.new_parent->GetShellWindowId() ==
55 kShellWindowId_DefaultContainer) {
56 // A new window was created in the default container.
57 window_watcher_->OnUserWindowAdded(params.target);
58 }
59 }
60
61 void ShelfWindowWatcher::ContainerWindowObserver::OnWindowDestroying(
62 WmWindow* window) {
63 window_watcher_->OnContainerWindowDestroying(window);
64 }
65
66 ////////////////////////////////////////////////////////////////////////////////
67
68 ShelfWindowWatcher::UserWindowObserver::UserWindowObserver(
69 ShelfWindowWatcher* window_watcher)
70 : window_watcher_(window_watcher) {}
71
72 ShelfWindowWatcher::UserWindowObserver::~UserWindowObserver() {}
73
74 void ShelfWindowWatcher::UserWindowObserver::OnWindowPropertyChanged(
75 WmWindow* window,
76 WmWindowProperty property) {
77 if (property == WmWindowProperty::SHELF_ITEM_DETAILS)
78 window_watcher_->OnUserWindowShelfItemDetailsChanged(window);
79 }
80
81 void ShelfWindowWatcher::UserWindowObserver::OnWindowDestroying(
82 WmWindow* window) {
83 window_watcher_->OnUserWindowDestroying(window);
84 }
85
86 ////////////////////////////////////////////////////////////////////////////////
87
88 ShelfWindowWatcher::ShelfWindowWatcher(ShelfModel* model)
89 : model_(model),
90 container_window_observer_(this),
91 user_window_observer_(this),
92 observed_container_windows_(&container_window_observer_),
93 observed_user_windows_(&user_window_observer_) {
94 WmShell::Get()->AddActivationObserver(this);
95 for (WmWindow* root : WmShell::Get()->GetAllRootWindows()) {
96 observed_container_windows_.Add(
97 root->GetChildByShellWindowId(kShellWindowId_DefaultContainer));
98 }
99
100 display::Screen::GetScreen()->AddObserver(this);
101 }
102
103 ShelfWindowWatcher::~ShelfWindowWatcher() {
104 display::Screen::GetScreen()->RemoveObserver(this);
105 WmShell::Get()->RemoveActivationObserver(this);
106 }
107
108 void ShelfWindowWatcher::AddShelfItem(WmWindow* window) {
109 const ShelfItemDetails* item_details = window->GetShelfItemDetails();
110 ShelfItem item;
111 ShelfID id = model_->next_id();
112 item.status = window->IsActive() ? STATUS_ACTIVE : STATUS_RUNNING;
113 SetShelfItemDetailsForShelfItem(&item, *item_details);
114 window->SetIntProperty(WmWindowProperty::SHELF_ID, id);
115 std::unique_ptr<ShelfItemDelegate> item_delegate(
116 new ShelfWindowWatcherItemDelegate(window));
117 model_->SetShelfItemDelegate(id, std::move(item_delegate));
118 model_->Add(item);
119 }
120
121 void ShelfWindowWatcher::RemoveShelfItem(WmWindow* window) {
122 int shelf_id = window->GetIntProperty(WmWindowProperty::SHELF_ID);
123 DCHECK_NE(shelf_id, kInvalidShelfID);
124 int index = model_->ItemIndexByID(shelf_id);
125 DCHECK_GE(index, 0);
126 model_->RemoveItemAt(index);
127 window->SetIntProperty(WmWindowProperty::SHELF_ID, kInvalidShelfID);
128 }
129
130 void ShelfWindowWatcher::OnContainerWindowDestroying(WmWindow* container) {
131 observed_container_windows_.Remove(container);
132 }
133
134 void ShelfWindowWatcher::UpdateShelfItemStatus(WmWindow* window,
135 bool is_active) {
136 int index = GetShelfItemIndexForWindow(window);
137 DCHECK_GE(index, 0);
138
139 ShelfItem item = model_->items()[index];
140 item.status = is_active ? STATUS_ACTIVE : STATUS_RUNNING;
141 model_->Set(index, item);
142 }
143
144 int ShelfWindowWatcher::GetShelfItemIndexForWindow(WmWindow* window) const {
145 return model_->ItemIndexByID(
146 window->GetIntProperty(WmWindowProperty::SHELF_ID));
147 }
148
149 void ShelfWindowWatcher::OnUserWindowAdded(WmWindow* window) {
150 // The window may already be tracked from when it was added to a different
151 // display or because an existing window added ShelfItemDetails to itself.
152 if (observed_user_windows_.IsObserving(window))
153 return;
154
155 observed_user_windows_.Add(window);
156
157 // Add ShelfItem if |window| already has a ShelfItemDetails when it is
158 // created.
159 if (window->GetShelfItemDetails() &&
160 window->GetIntProperty(WmWindowProperty::SHELF_ID) == kInvalidShelfID) {
161 AddShelfItem(window);
162 }
163 }
164
165 void ShelfWindowWatcher::OnUserWindowDestroying(WmWindow* window) {
166 if (observed_user_windows_.IsObserving(window))
167 observed_user_windows_.Remove(window);
168
169 if (HasShelfItemForWindow(window))
170 RemoveShelfItem(window);
171 }
172
173 void ShelfWindowWatcher::OnUserWindowShelfItemDetailsChanged(WmWindow* window) {
174 if (!window->GetShelfItemDetails()) {
175 // Removes ShelfItem for |window| when it has a ShelfItem.
176 if (window->GetIntProperty(WmWindowProperty::SHELF_ID) != kInvalidShelfID)
177 RemoveShelfItem(window);
178 return;
179 }
180
181 // When ShelfItemDetails is changed, update ShelfItem.
182 if (HasShelfItemForWindow(window)) {
183 int index = GetShelfItemIndexForWindow(window);
184 DCHECK_GE(index, 0);
185 ShelfItem item = model_->items()[index];
186 const ShelfItemDetails* details = window->GetShelfItemDetails();
187 SetShelfItemDetailsForShelfItem(&item, *details);
188 model_->Set(index, item);
189 return;
190 }
191
192 // Creates a new ShelfItem for |window|.
193 AddShelfItem(window);
194 }
195
196 void ShelfWindowWatcher::OnWindowActivated(WmWindow* gained_active,
197 WmWindow* lost_active) {
198 if (gained_active && HasShelfItemForWindow(gained_active))
199 UpdateShelfItemStatus(gained_active, true);
200 if (lost_active && HasShelfItemForWindow(lost_active))
201 UpdateShelfItemStatus(lost_active, false);
202 }
203
204 void ShelfWindowWatcher::OnDisplayAdded(const display::Display& new_display) {
205 WmWindow* root = WmShell::Get()->GetRootWindowForDisplayId(new_display.id());
206
207 // When the primary root window's display get removed, the existing root
208 // window is taken over by the new display and the observer is already set.
209 WmWindow* container =
210 root->GetChildByShellWindowId(kShellWindowId_DefaultContainer);
211 if (!observed_container_windows_.IsObserving(container))
212 observed_container_windows_.Add(container);
213 }
214
215 void ShelfWindowWatcher::OnDisplayRemoved(const display::Display& old_display) {
216 }
217
218 void ShelfWindowWatcher::OnDisplayMetricsChanged(const display::Display&,
219 uint32_t) {}
220
221 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698