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

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

Issue 2192553002: mash: Convert ShelfWindowWatcher to wm common types (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cleanup 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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/shelf/shelf_window_watcher.h" 5 #include "ash/shelf/shelf_window_watcher.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "ash/aura/wm_window_aura.h"
11 #include "ash/common/shelf/shelf_constants.h" 10 #include "ash/common/shelf/shelf_constants.h"
12 #include "ash/common/shelf/shelf_model.h" 11 #include "ash/common/shelf/shelf_model.h"
13 #include "ash/common/shell_window_ids.h" 12 #include "ash/common/shell_window_ids.h"
14 #include "ash/common/wm/window_state.h" 13 #include "ash/common/wm/window_state.h"
15 #include "ash/display/window_tree_host_manager.h" 14 #include "ash/common/wm_shell.h"
16 #include "ash/shelf/shelf_util.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" 17 #include "ash/shelf/shelf_window_watcher_item_delegate.h"
18 #include "ash/shell.h"
19 #include "ash/wm/window_state_aura.h"
20 #include "ash/wm/window_util.h"
21 #include "ui/aura/window.h"
22 #include "ui/base/resource/resource_bundle.h" 18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/display/display.h"
23 #include "ui/display/screen.h" 20 #include "ui/display/screen.h"
24 #include "ui/gfx/image/image_skia.h" 21 #include "ui/gfx/image/image_skia.h"
25 #include "ui/wm/public/activation_client.h"
26 22
23 namespace ash {
27 namespace { 24 namespace {
28 25
29 // Sets ShelfItem property by using the value of |details|. 26 // Sets ShelfItem property by using the value of |details|.
30 void SetShelfItemDetailsForShelfItem(ash::ShelfItem* item, 27 void SetShelfItemDetailsForShelfItem(ash::ShelfItem* item,
31 const ash::ShelfItemDetails& details) { 28 const ash::ShelfItemDetails& details) {
32 item->type = details.type; 29 item->type = details.type;
33 if (details.image_resource_id != ash::kInvalidImageResourceID) { 30 if (details.image_resource_id != ash::kInvalidImageResourceID) {
34 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 31 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
35 item->image = *rb.GetImageSkiaNamed(details.image_resource_id); 32 item->image = *rb.GetImageSkiaNamed(details.image_resource_id);
36 } 33 }
37 } 34 }
38 35
39 // Returns true if |window| has a ShelfItem added by ShelfWindowWatcher. 36 // Returns true if |window| has a ShelfItem added by ShelfWindowWatcher.
40 bool HasShelfItemForWindow(aura::Window* window) { 37 bool HasShelfItemForWindow(WmWindow* window) {
41 if (ash::GetShelfItemDetailsForWindow(window) != NULL && 38 return window->GetShelfItemDetails() &&
42 ash::GetShelfIDForWindow(window) != ash::kInvalidShelfID) 39 window->GetIntProperty(WmWindowProperty::SHELF_ID) != kInvalidShelfID;
43 return true;
44 return false;
45 }
46
47 // Returns true if |window| is in the process of being dragged.
48 bool IsDragging(aura::Window* window) {
49 return ash::wm::GetWindowState(window)->is_dragged();
50 } 40 }
51 41
52 } // namespace 42 } // namespace
53 43
54 namespace ash { 44 ShelfWindowWatcher::ContainerWindowObserver::ContainerWindowObserver(
55
56 ShelfWindowWatcher::RootWindowObserver::RootWindowObserver(
57 ShelfWindowWatcher* window_watcher) 45 ShelfWindowWatcher* window_watcher)
58 : window_watcher_(window_watcher) {} 46 : window_watcher_(window_watcher) {}
59 47
60 ShelfWindowWatcher::RootWindowObserver::~RootWindowObserver() {} 48 ShelfWindowWatcher::ContainerWindowObserver::~ContainerWindowObserver() {}
61 49
62 void ShelfWindowWatcher::RootWindowObserver::OnWindowDestroying( 50 void ShelfWindowWatcher::ContainerWindowObserver::OnWindowTreeChanged(
63 aura::Window* window) { 51 WmWindow* window,
64 window_watcher_->OnRootWindowRemoved(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 }
65 } 59 }
66 60
67 ShelfWindowWatcher::RemovedWindowObserver::RemovedWindowObserver( 61 void ShelfWindowWatcher::ContainerWindowObserver::OnWindowDestroying(
62 WmWindow* window) {
63 window_watcher_->OnContainerWindowDestroying(window);
64 }
65
66 ////////////////////////////////////////////////////////////////////////////////
67
68 ShelfWindowWatcher::UserWindowObserver::UserWindowObserver(
68 ShelfWindowWatcher* window_watcher) 69 ShelfWindowWatcher* window_watcher)
69 : window_watcher_(window_watcher) {} 70 : window_watcher_(window_watcher) {}
70 71
71 ShelfWindowWatcher::RemovedWindowObserver::~RemovedWindowObserver() {} 72 ShelfWindowWatcher::UserWindowObserver::~UserWindowObserver() {}
72 73
73 void ShelfWindowWatcher::RemovedWindowObserver::OnWindowParentChanged( 74 void ShelfWindowWatcher::UserWindowObserver::OnWindowPropertyChanged(
74 aura::Window* window, 75 WmWindow* window,
75 aura::Window* parent) { 76 WmWindowProperty property) {
76 // When |parent| is NULL, this |window| will be destroyed. In that case, its 77 if (property == WmWindowProperty::SHELF_ITEM_DETAILS)
77 // item will be removed at OnWindowDestroyed(). 78 window_watcher_->OnUserWindowShelfItemDetailsChanged(window);
78 if (!parent)
79 return;
80
81 // When |parent| is changed from default container to docked container
82 // during the dragging, |window|'s item should not be removed because it will
83 // be re-parented to default container again after finishing the dragging.
84 // We don't need to check |parent| is default container because this observer
85 // is already removed from |window| when |window| is re-parented to default
86 // container.
87 if (IsDragging(window) && parent->id() == kShellWindowId_DockedContainer)
88 return;
89
90 // When |window| is re-parented to other containers or |window| is re-parented
91 // not to |docked_container| during the dragging, its item should be removed
92 // and stop observing this |window|.
93 window_watcher_->FinishObservingRemovedWindow(window);
94 } 79 }
95 80
96 void ShelfWindowWatcher::RemovedWindowObserver::OnWindowDestroyed( 81 void ShelfWindowWatcher::UserWindowObserver::OnWindowDestroying(
97 aura::Window* window) { 82 WmWindow* window) {
98 DCHECK(HasShelfItemForWindow(window)); 83 window_watcher_->OnUserWindowDestroying(window);
99 window_watcher_->FinishObservingRemovedWindow(window);
100 } 84 }
101 85
86 ////////////////////////////////////////////////////////////////////////////////
87
102 ShelfWindowWatcher::ShelfWindowWatcher(ShelfModel* model) 88 ShelfWindowWatcher::ShelfWindowWatcher(ShelfModel* model)
103 : model_(model), 89 : model_(model),
104 root_window_observer_(this), 90 container_window_observer_(this),
105 removed_window_observer_(this), 91 user_window_observer_(this),
106 observed_windows_(this), 92 observed_container_windows_(&container_window_observer_),
107 observed_root_windows_(&root_window_observer_), 93 observed_user_windows_(&user_window_observer_) {
108 observed_removed_windows_(&removed_window_observer_) { 94 WmShell::Get()->AddActivationObserver(this);
109 Shell::GetInstance()->activation_client()->AddObserver(this); 95 for (WmWindow* root : WmShell::Get()->GetAllRootWindows()) {
110 for (aura::Window* root : Shell::GetAllRootWindows()) 96 observed_container_windows_.Add(
111 OnRootWindowAdded(WmWindowAura::Get(root)); 97 root->GetChildByShellWindowId(kShellWindowId_DefaultContainer));
98 }
112 99
113 display::Screen::GetScreen()->AddObserver(this); 100 display::Screen::GetScreen()->AddObserver(this);
114 } 101 }
115 102
116 ShelfWindowWatcher::~ShelfWindowWatcher() { 103 ShelfWindowWatcher::~ShelfWindowWatcher() {
117 display::Screen::GetScreen()->RemoveObserver(this); 104 display::Screen::GetScreen()->RemoveObserver(this);
118 Shell::GetInstance()->activation_client()->RemoveObserver(this); 105 WmShell::Get()->RemoveActivationObserver(this);
119 } 106 }
120 107
121 void ShelfWindowWatcher::AddShelfItem(aura::Window* window) { 108 void ShelfWindowWatcher::AddShelfItem(WmWindow* window) {
122 const ShelfItemDetails* item_details = GetShelfItemDetailsForWindow(window); 109 const ShelfItemDetails* item_details = window->GetShelfItemDetails();
123 ShelfItem item; 110 ShelfItem item;
124 ShelfID id = model_->next_id(); 111 ShelfID id = model_->next_id();
125 item.status = wm::IsActiveWindow(window) ? STATUS_ACTIVE : STATUS_RUNNING; 112 item.status = window->IsActive() ? STATUS_ACTIVE : STATUS_RUNNING;
126 SetShelfItemDetailsForShelfItem(&item, *item_details); 113 SetShelfItemDetailsForShelfItem(&item, *item_details);
127 SetShelfIDForWindow(id, window); 114 window->SetIntProperty(WmWindowProperty::SHELF_ID, id);
128 std::unique_ptr<ShelfItemDelegate> item_delegate( 115 std::unique_ptr<ShelfItemDelegate> item_delegate(
129 new ShelfWindowWatcherItemDelegate(window)); 116 new ShelfWindowWatcherItemDelegate(window));
130 model_->SetShelfItemDelegate(id, std::move(item_delegate)); 117 model_->SetShelfItemDelegate(id, std::move(item_delegate));
131 model_->Add(item); 118 model_->Add(item);
132 } 119 }
133 120
134 void ShelfWindowWatcher::RemoveShelfItem(aura::Window* window) { 121 void ShelfWindowWatcher::RemoveShelfItem(WmWindow* window) {
135 model_->RemoveItemAt(model_->ItemIndexByID(GetShelfIDForWindow(window))); 122 int shelf_id = window->GetIntProperty(WmWindowProperty::SHELF_ID);
136 SetShelfIDForWindow(kInvalidShelfID, window); 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);
137 } 128 }
138 129
139 void ShelfWindowWatcher::OnRootWindowAdded(WmWindow* root_window_wm) { 130 void ShelfWindowWatcher::OnContainerWindowDestroying(WmWindow* container) {
140 aura::Window* root_window = WmWindowAura::GetAuraWindow(root_window_wm); 131 observed_container_windows_.Remove(container);
141 observed_root_windows_.Add(root_window);
142
143 aura::Window* default_container =
144 Shell::GetContainer(root_window, kShellWindowId_DefaultContainer);
145 observed_windows_.Add(default_container);
146 for (size_t i = 0; i < default_container->children().size(); ++i)
147 observed_windows_.Add(default_container->children()[i]);
148 } 132 }
149 133
150 void ShelfWindowWatcher::OnRootWindowRemoved(aura::Window* root_window) { 134 void ShelfWindowWatcher::UpdateShelfItemStatus(WmWindow* window,
151 observed_root_windows_.Remove(root_window);
152 }
153
154 void ShelfWindowWatcher::UpdateShelfItemStatus(aura::Window* window,
155 bool is_active) { 135 bool is_active) {
156 int index = GetShelfItemIndexForWindow(window); 136 int index = GetShelfItemIndexForWindow(window);
157 DCHECK_GE(index, 0); 137 DCHECK_GE(index, 0);
158 138
159 ShelfItem item = model_->items()[index]; 139 ShelfItem item = model_->items()[index];
160 item.status = is_active ? STATUS_ACTIVE : STATUS_RUNNING; 140 item.status = is_active ? STATUS_ACTIVE : STATUS_RUNNING;
161 model_->Set(index, item); 141 model_->Set(index, item);
162 } 142 }
163 143
164 int ShelfWindowWatcher::GetShelfItemIndexForWindow(aura::Window* window) const { 144 int ShelfWindowWatcher::GetShelfItemIndexForWindow(WmWindow* window) const {
165 return model_->ItemIndexByID(GetShelfIDForWindow(window)); 145 return model_->ItemIndexByID(
146 window->GetIntProperty(WmWindowProperty::SHELF_ID));
166 } 147 }
167 148
168 void ShelfWindowWatcher::StartObservingRemovedWindow(aura::Window* window) { 149 void ShelfWindowWatcher::OnUserWindowAdded(WmWindow* window) {
169 observed_removed_windows_.Add(window); 150 // The window may already be tracked from when it was added to a different
170 } 151 // display or because it an existing window added ShelfItemDetails to itself.
msw 2016/07/27 18:36:10 nit: "it an"
James Cook 2016/07/27 20:14:06 Done.
152 if (observed_user_windows_.IsObserving(window))
153 return;
171 154
172 void ShelfWindowWatcher::FinishObservingRemovedWindow(aura::Window* window) { 155 observed_user_windows_.Add(window);
173 observed_removed_windows_.Remove(window);
174 RemoveShelfItem(window);
175 }
176
177 void ShelfWindowWatcher::OnWindowActivated(
178 aura::client::ActivationChangeObserver::ActivationReason reason,
179 aura::Window* gained_active,
180 aura::Window* lost_active) {
181 if (gained_active && HasShelfItemForWindow(gained_active))
182 UpdateShelfItemStatus(gained_active, true);
183 if (lost_active && HasShelfItemForWindow(lost_active))
184 UpdateShelfItemStatus(lost_active, false);
185 }
186
187 void ShelfWindowWatcher::OnWindowAdded(aura::Window* window) {
188 observed_windows_.Add(window);
189
190 if (observed_removed_windows_.IsObserving(window)) {
191 // When |window| is added and it is already observed by
192 // |dragged_window_observer_|, |window| already has its item.
193 DCHECK(HasShelfItemForWindow(window));
194 observed_removed_windows_.Remove(window);
195 return;
196 }
197 156
198 // Add ShelfItem if |window| already has a ShelfItemDetails when it is 157 // Add ShelfItem if |window| already has a ShelfItemDetails when it is
199 // created. Don't make a new ShelfItem for the re-parented |window| that 158 // created.
200 // already has a ShelfItem. 159 if (window->GetShelfItemDetails() &&
201 if (GetShelfIDForWindow(window) == kInvalidShelfID && 160 window->GetIntProperty(WmWindowProperty::SHELF_ID) == kInvalidShelfID)
msw 2016/07/27 18:36:10 nit: curlies
James Cook 2016/07/27 20:14:06 Done.
202 GetShelfItemDetailsForWindow(window))
203 AddShelfItem(window); 161 AddShelfItem(window);
204 } 162 }
205 163
206 void ShelfWindowWatcher::OnWillRemoveWindow(aura::Window* window) { 164 void ShelfWindowWatcher::OnUserWindowDestroying(WmWindow* window) {
207 // Remove a child window of default container. 165 if (observed_user_windows_.IsObserving(window))
208 if (observed_windows_.IsObserving(window)) 166 observed_user_windows_.Remove(window);
209 observed_windows_.Remove(window);
210 167
211 // Don't remove |window| item immediately. Instead, defer handling of removing
212 // |window|'s item to RemovedWindowObserver because |window| could be added
213 // again to default container.
214 if (HasShelfItemForWindow(window)) 168 if (HasShelfItemForWindow(window))
215 StartObservingRemovedWindow(window); 169 RemoveShelfItem(window);
216 } 170 }
217 171
218 void ShelfWindowWatcher::OnWindowDestroying(aura::Window* window) { 172 void ShelfWindowWatcher::OnUserWindowShelfItemDetailsChanged(WmWindow* window) {
219 // Remove the default container. 173 if (!window->GetShelfItemDetails()) {
220 if (observed_windows_.IsObserving(window))
221 observed_windows_.Remove(window);
222 }
223
224 void ShelfWindowWatcher::OnWindowPropertyChanged(aura::Window* window,
225 const void* key,
226 intptr_t old) {
227 if (key != kShelfItemDetailsKey)
228 return;
229
230 if (GetShelfItemDetailsForWindow(window) == NULL) {
231 // Removes ShelfItem for |window| when it has a ShelfItem. 174 // Removes ShelfItem for |window| when it has a ShelfItem.
232 if (reinterpret_cast<ShelfItemDetails*>(old) != NULL) 175 if (window->GetIntProperty(WmWindowProperty::SHELF_ID) != kInvalidShelfID)
233 RemoveShelfItem(window); 176 RemoveShelfItem(window);
234 return; 177 return;
235 } 178 }
236 179
237 // When ShelfItemDetails is changed, update ShelfItem. 180 // When ShelfItemDetails is changed, update ShelfItem.
238 if (HasShelfItemForWindow(window)) { 181 if (HasShelfItemForWindow(window)) {
239 int index = GetShelfItemIndexForWindow(window); 182 int index = GetShelfItemIndexForWindow(window);
240 DCHECK_GE(index, 0); 183 DCHECK_GE(index, 0);
241 ShelfItem item = model_->items()[index]; 184 ShelfItem item = model_->items()[index];
242 const ShelfItemDetails* details = GetShelfItemDetailsForWindow(window); 185 const ShelfItemDetails* details = window->GetShelfItemDetails();
243 SetShelfItemDetailsForShelfItem(&item, *details); 186 SetShelfItemDetailsForShelfItem(&item, *details);
244 model_->Set(index, item); 187 model_->Set(index, item);
245 return; 188 return;
246 } 189 }
247 190
248 // Creates a new ShelfItem for |window|. 191 // Creates a new ShelfItem for |window|.
249 AddShelfItem(window); 192 AddShelfItem(window);
250 } 193 }
251 194
195 void ShelfWindowWatcher::OnWindowActivated(WmWindow* gained_active,
196 WmWindow* lost_active) {
197 if (gained_active && HasShelfItemForWindow(gained_active))
198 UpdateShelfItemStatus(gained_active, true);
199 if (lost_active && HasShelfItemForWindow(lost_active))
200 UpdateShelfItemStatus(lost_active, false);
201 }
202
252 void ShelfWindowWatcher::OnDisplayAdded(const display::Display& new_display) { 203 void ShelfWindowWatcher::OnDisplayAdded(const display::Display& new_display) {
253 // Add a new RootWindow and its ActivationClient to observed list. 204 WmWindow* root = WmShell::Get()->GetRootWindowForDisplayId(new_display.id());
254 aura::Window* root_window = Shell::GetInstance()
255 ->window_tree_host_manager()
256 ->GetRootWindowForDisplayId(new_display.id());
257 205
258 // When the primary root window's display get removed, the existing root 206 // When the primary root window's display get removed, the existing root
259 // window is taken over by the new display and the observer is already set. 207 // window is taken over by the new display and the observer is already set.
260 if (!observed_root_windows_.IsObserving(root_window)) 208 WmWindow* container =
261 OnRootWindowAdded(WmWindowAura::Get(root_window)); 209 root->GetChildByShellWindowId(kShellWindowId_DefaultContainer);
210 if (!observed_container_windows_.IsObserving(container))
211 observed_container_windows_.Add(container);
262 } 212 }
263 213
264 void ShelfWindowWatcher::OnDisplayRemoved(const display::Display& old_display) { 214 void ShelfWindowWatcher::OnDisplayRemoved(const display::Display& old_display) {
265 // When this is called, RootWindow of |old_display| is already removed.
266 // Instead, we remove an observer from RootWindow and ActivationClient in the
267 // OnRootWindowDestroyed().
268 // Do nothing here.
269 } 215 }
270 216
271 void ShelfWindowWatcher::OnDisplayMetricsChanged(const display::Display&, 217 void ShelfWindowWatcher::OnDisplayMetricsChanged(const display::Display&,
272 uint32_t) {} 218 uint32_t) {}
273 219
274 } // namespace ash 220 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698