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

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

Issue 2462753002: Use Ash's ShelfWindowWatcher for app panel windows. (Closed)
Patch Set: Address comments. Created 4 years, 1 month 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/common/shelf/shelf_window_watcher.h" 5 #include "ash/common/shelf/shelf_window_watcher.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "ash/common/shelf/shelf_constants.h" 10 #include "ash/common/shelf/shelf_constants.h"
11 #include "ash/common/shelf/shelf_model.h" 11 #include "ash/common/shelf/shelf_model.h"
12 #include "ash/common/shelf/shelf_window_watcher_item_delegate.h" 12 #include "ash/common/shelf/shelf_window_watcher_item_delegate.h"
13 #include "ash/common/wm/window_state.h" 13 #include "ash/common/wm/window_state.h"
14 #include "ash/common/wm_shell.h" 14 #include "ash/common/wm_shell.h"
15 #include "ash/common/wm_window.h" 15 #include "ash/common/wm_window.h"
16 #include "ash/common/wm_window_property.h" 16 #include "ash/common/wm_window_property.h"
17 #include "ash/public/cpp/shell_window_ids.h" 17 #include "ash/public/cpp/shell_window_ids.h"
18 #include "ui/base/resource/resource_bundle.h" 18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/display/display.h" 19 #include "ui/display/display.h"
20 #include "ui/display/screen.h" 20 #include "ui/display/screen.h"
21 #include "ui/gfx/image/image_skia.h" 21 #include "ui/gfx/image/image_skia.h"
22 #include "ui/resources/grit/ui_resources.h"
22 23
23 namespace ash { 24 namespace ash {
24 namespace { 25 namespace {
25 26
26 // Update the ShelfItem from relevant window properties. 27 // Update the ShelfItem from relevant window properties.
27 void UpdateShelfItemForWindow(ShelfItem* item, WmWindow* window) { 28 void UpdateShelfItemForWindow(ShelfItem* item, WmWindow* window) {
28 item->type = static_cast<ShelfItemType>( 29 item->type = static_cast<ShelfItemType>(
29 window->GetIntProperty(WmWindowProperty::SHELF_ITEM_TYPE)); 30 window->GetIntProperty(WmWindowProperty::SHELF_ITEM_TYPE));
30 const int icon =
31 window->GetIntProperty(WmWindowProperty::SHELF_ICON_RESOURCE_ID);
32 if (icon != kInvalidImageResourceID)
33 item->image = *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(icon);
34 }
35 31
36 // Returns true if |window| has a ShelfItem added by ShelfWindowWatcher. 32 item->status = STATUS_RUNNING;
37 bool HasShelfItemForWindow(WmWindow* window) { 33 if (window->IsActive())
38 return window->GetIntProperty(WmWindowProperty::SHELF_ITEM_TYPE) != 34 item->status = STATUS_ACTIVE;
39 TYPE_UNDEFINED && 35 else if (window->GetBoolProperty(WmWindowProperty::DRAW_ATTENTION))
40 window->GetIntProperty(WmWindowProperty::SHELF_ID) != kInvalidShelfID; 36 item->status = STATUS_ATTENTION;
37
38 item->app_id = window->GetStringProperty(WmWindowProperty::APP_ID);
39
40 // Prefer app icons over window icons, they're typically larger.
41 gfx::ImageSkia image = window->GetAppIcon();
42 if (image.isNull())
43 image = window->GetWindowIcon();
44 if (image.isNull()) {
45 int icon = window->GetIntProperty(WmWindowProperty::SHELF_ICON_RESOURCE_ID);
46 if (icon != kInvalidImageResourceID)
47 image = *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(icon);
48 }
49 item->image = image;
41 } 50 }
42 51
43 } // namespace 52 } // namespace
44 53
45 ShelfWindowWatcher::ContainerWindowObserver::ContainerWindowObserver( 54 ShelfWindowWatcher::ContainerWindowObserver::ContainerWindowObserver(
46 ShelfWindowWatcher* window_watcher) 55 ShelfWindowWatcher* window_watcher)
47 : window_watcher_(window_watcher) {} 56 : window_watcher_(window_watcher) {}
48 57
49 ShelfWindowWatcher::ContainerWindowObserver::~ContainerWindowObserver() {} 58 ShelfWindowWatcher::ContainerWindowObserver::~ContainerWindowObserver() {}
50 59
51 void ShelfWindowWatcher::ContainerWindowObserver::OnWindowTreeChanged( 60 void ShelfWindowWatcher::ContainerWindowObserver::OnWindowTreeChanged(
52 WmWindow* window, 61 WmWindow* window,
53 const TreeChangeParams& params) { 62 const TreeChangeParams& params) {
54 if (!params.old_parent && params.new_parent && 63 if (!params.old_parent && params.new_parent &&
55 params.new_parent->GetShellWindowId() == 64 (params.new_parent->GetShellWindowId() ==
56 kShellWindowId_DefaultContainer) { 65 kShellWindowId_DefaultContainer ||
57 // A new window was created in the default container. 66 params.new_parent->GetShellWindowId() ==
67 kShellWindowId_PanelContainer)) {
68 // A new window was created in the default container or the panel container.
58 window_watcher_->OnUserWindowAdded(params.target); 69 window_watcher_->OnUserWindowAdded(params.target);
59 } 70 }
60 } 71 }
61 72
62 void ShelfWindowWatcher::ContainerWindowObserver::OnWindowDestroying( 73 void ShelfWindowWatcher::ContainerWindowObserver::OnWindowDestroying(
63 WmWindow* window) { 74 WmWindow* window) {
64 window_watcher_->OnContainerWindowDestroying(window); 75 window_watcher_->OnContainerWindowDestroying(window);
65 } 76 }
66 77
67 //////////////////////////////////////////////////////////////////////////////// 78 ////////////////////////////////////////////////////////////////////////////////
68 79
69 ShelfWindowWatcher::UserWindowObserver::UserWindowObserver( 80 ShelfWindowWatcher::UserWindowObserver::UserWindowObserver(
70 ShelfWindowWatcher* window_watcher) 81 ShelfWindowWatcher* window_watcher)
71 : window_watcher_(window_watcher) {} 82 : window_watcher_(window_watcher) {}
72 83
73 ShelfWindowWatcher::UserWindowObserver::~UserWindowObserver() {} 84 ShelfWindowWatcher::UserWindowObserver::~UserWindowObserver() {}
74 85
75 void ShelfWindowWatcher::UserWindowObserver::OnWindowPropertyChanged( 86 void ShelfWindowWatcher::UserWindowObserver::OnWindowPropertyChanged(
76 WmWindow* window, 87 WmWindow* window,
77 WmWindowProperty property) { 88 WmWindowProperty property) {
78 if (property == WmWindowProperty::SHELF_ITEM_TYPE || 89 if (property == WmWindowProperty::APP_ICON ||
79 property == WmWindowProperty::SHELF_ICON_RESOURCE_ID) { 90 property == WmWindowProperty::APP_ID ||
91 property == WmWindowProperty::DRAW_ATTENTION ||
92 property == WmWindowProperty::SHELF_ITEM_TYPE ||
93 property == WmWindowProperty::SHELF_ICON_RESOURCE_ID ||
94 property == WmWindowProperty::WINDOW_ICON) {
80 window_watcher_->OnUserWindowPropertyChanged(window); 95 window_watcher_->OnUserWindowPropertyChanged(window);
81 } 96 }
82 } 97 }
83 98
84 void ShelfWindowWatcher::UserWindowObserver::OnWindowDestroying( 99 void ShelfWindowWatcher::UserWindowObserver::OnWindowDestroying(
85 WmWindow* window) { 100 WmWindow* window) {
86 window_watcher_->OnUserWindowDestroying(window); 101 window_watcher_->OnUserWindowDestroying(window);
87 } 102 }
88 103
89 //////////////////////////////////////////////////////////////////////////////// 104 ////////////////////////////////////////////////////////////////////////////////
90 105
91 ShelfWindowWatcher::ShelfWindowWatcher(ShelfModel* model) 106 ShelfWindowWatcher::ShelfWindowWatcher(ShelfModel* model)
92 : model_(model), 107 : model_(model),
93 container_window_observer_(this), 108 container_window_observer_(this),
94 user_window_observer_(this), 109 user_window_observer_(this),
95 observed_container_windows_(&container_window_observer_), 110 observed_container_windows_(&container_window_observer_),
96 observed_user_windows_(&user_window_observer_) { 111 observed_user_windows_(&user_window_observer_) {
97 WmShell::Get()->AddActivationObserver(this); 112 WmShell::Get()->AddActivationObserver(this);
98 for (WmWindow* root : WmShell::Get()->GetAllRootWindows()) { 113 for (WmWindow* root : WmShell::Get()->GetAllRootWindows()) {
99 observed_container_windows_.Add( 114 observed_container_windows_.Add(
100 root->GetChildByShellWindowId(kShellWindowId_DefaultContainer)); 115 root->GetChildByShellWindowId(kShellWindowId_DefaultContainer));
116 observed_container_windows_.Add(
117 root->GetChildByShellWindowId(kShellWindowId_PanelContainer));
101 } 118 }
102 119
103 display::Screen::GetScreen()->AddObserver(this); 120 display::Screen::GetScreen()->AddObserver(this);
104 } 121 }
105 122
106 ShelfWindowWatcher::~ShelfWindowWatcher() { 123 ShelfWindowWatcher::~ShelfWindowWatcher() {
107 display::Screen::GetScreen()->RemoveObserver(this); 124 display::Screen::GetScreen()->RemoveObserver(this);
108 WmShell::Get()->RemoveActivationObserver(this); 125 WmShell::Get()->RemoveActivationObserver(this);
109 } 126 }
110 127
111 void ShelfWindowWatcher::AddShelfItem(WmWindow* window) { 128 void ShelfWindowWatcher::AddShelfItem(WmWindow* window) {
129 user_windows_with_items_.insert(window);
112 ShelfItem item; 130 ShelfItem item;
113 ShelfID id = model_->next_id(); 131 ShelfID id = model_->next_id();
114 item.status = window->IsActive() ? STATUS_ACTIVE : STATUS_RUNNING;
115 UpdateShelfItemForWindow(&item, window); 132 UpdateShelfItemForWindow(&item, window);
116 window->SetIntProperty(WmWindowProperty::SHELF_ID, id); 133 window->SetIntProperty(WmWindowProperty::SHELF_ID, id);
117 std::unique_ptr<ShelfItemDelegate> item_delegate( 134 std::unique_ptr<ShelfItemDelegate> item_delegate(
118 new ShelfWindowWatcherItemDelegate(window)); 135 new ShelfWindowWatcherItemDelegate(id, window));
119 model_->SetShelfItemDelegate(id, std::move(item_delegate)); 136 model_->SetShelfItemDelegate(id, std::move(item_delegate));
120 model_->Add(item); 137 // Panels are inserted on the left so as not to push all existing panels over.
138 model_->AddAt(item.type == TYPE_APP_PANEL ? 0 : model_->item_count(), item);
121 } 139 }
122 140
123 void ShelfWindowWatcher::RemoveShelfItem(WmWindow* window) { 141 void ShelfWindowWatcher::RemoveShelfItem(WmWindow* window) {
142 user_windows_with_items_.erase(window);
124 int shelf_id = window->GetIntProperty(WmWindowProperty::SHELF_ID); 143 int shelf_id = window->GetIntProperty(WmWindowProperty::SHELF_ID);
125 DCHECK_NE(shelf_id, kInvalidShelfID); 144 DCHECK_NE(shelf_id, kInvalidShelfID);
126 int index = model_->ItemIndexByID(shelf_id); 145 int index = model_->ItemIndexByID(shelf_id);
127 DCHECK_GE(index, 0); 146 DCHECK_GE(index, 0);
128 model_->RemoveItemAt(index); 147 model_->RemoveItemAt(index);
129 window->SetIntProperty(WmWindowProperty::SHELF_ID, kInvalidShelfID); 148 window->SetIntProperty(WmWindowProperty::SHELF_ID, kInvalidShelfID);
130 } 149 }
131 150
132 void ShelfWindowWatcher::OnContainerWindowDestroying(WmWindow* container) { 151 void ShelfWindowWatcher::OnContainerWindowDestroying(WmWindow* container) {
133 observed_container_windows_.Remove(container); 152 observed_container_windows_.Remove(container);
134 } 153 }
135 154
136 void ShelfWindowWatcher::UpdateShelfItemStatus(WmWindow* window,
137 bool is_active) {
138 int index = GetShelfItemIndexForWindow(window);
139 DCHECK_GE(index, 0);
140
141 ShelfItem item = model_->items()[index];
142 item.status = is_active ? STATUS_ACTIVE : STATUS_RUNNING;
143 model_->Set(index, item);
144 }
145
146 int ShelfWindowWatcher::GetShelfItemIndexForWindow(WmWindow* window) const { 155 int ShelfWindowWatcher::GetShelfItemIndexForWindow(WmWindow* window) const {
147 return model_->ItemIndexByID( 156 return model_->ItemIndexByID(
148 window->GetIntProperty(WmWindowProperty::SHELF_ID)); 157 window->GetIntProperty(WmWindowProperty::SHELF_ID));
149 } 158 }
150 159
151 void ShelfWindowWatcher::OnUserWindowAdded(WmWindow* window) { 160 void ShelfWindowWatcher::OnUserWindowAdded(WmWindow* window) {
152 // The window may already be tracked from when it was added to a different 161 // The window may already be tracked from a prior display or parent container.
153 // display or because an existing window added its shelf item properties.
154 if (observed_user_windows_.IsObserving(window)) 162 if (observed_user_windows_.IsObserving(window))
155 return; 163 return;
156 164
157 observed_user_windows_.Add(window); 165 observed_user_windows_.Add(window);
158 166
159 // Add a ShelfItem if |window| has a valid ShelfItemType on creation. 167 // Add, update, or remove a ShelfItem for |window|, as needed.
160 if (window->GetIntProperty(WmWindowProperty::SHELF_ITEM_TYPE) != 168 OnUserWindowPropertyChanged(window);
161 TYPE_UNDEFINED &&
162 window->GetIntProperty(WmWindowProperty::SHELF_ID) == kInvalidShelfID) {
163 AddShelfItem(window);
164 }
165 } 169 }
166 170
167 void ShelfWindowWatcher::OnUserWindowDestroying(WmWindow* window) { 171 void ShelfWindowWatcher::OnUserWindowDestroying(WmWindow* window) {
168 if (observed_user_windows_.IsObserving(window)) 172 if (observed_user_windows_.IsObserving(window))
169 observed_user_windows_.Remove(window); 173 observed_user_windows_.Remove(window);
170 174
171 if (HasShelfItemForWindow(window)) 175 if (user_windows_with_items_.count(window) > 0)
172 RemoveShelfItem(window); 176 RemoveShelfItem(window);
177 DCHECK_EQ(0u, user_windows_with_items_.count(window));
173 } 178 }
174 179
175 void ShelfWindowWatcher::OnUserWindowPropertyChanged(WmWindow* window) { 180 void ShelfWindowWatcher::OnUserWindowPropertyChanged(WmWindow* window) {
176 if (window->GetIntProperty(WmWindowProperty::SHELF_ITEM_TYPE) == 181 if (window->GetIntProperty(WmWindowProperty::SHELF_ITEM_TYPE) ==
177 TYPE_UNDEFINED) { 182 TYPE_UNDEFINED) {
178 // Removes ShelfItem for |window| when it has a ShelfItem. 183 // Remove |window|'s ShelfItem if it was added by this ShelfWindowWatcher.
179 if (window->GetIntProperty(WmWindowProperty::SHELF_ID) != kInvalidShelfID) 184 if (user_windows_with_items_.count(window) > 0)
180 RemoveShelfItem(window); 185 RemoveShelfItem(window);
181 return; 186 return;
182 } 187 }
183 188
184 // Update an existing ShelfItem for |window| when a property has changed. 189 // Update an existing ShelfItem for |window| when a property has changed.
185 if (HasShelfItemForWindow(window)) { 190 int index = GetShelfItemIndexForWindow(window);
186 int index = GetShelfItemIndexForWindow(window); 191 if (index > 0) {
187 DCHECK_GE(index, 0);
188 ShelfItem item = model_->items()[index]; 192 ShelfItem item = model_->items()[index];
189 UpdateShelfItemForWindow(&item, window); 193 UpdateShelfItemForWindow(&item, window);
190 model_->Set(index, item); 194 model_->Set(index, item);
191 return; 195 return;
192 } 196 }
193 197
194 // Creates a new ShelfItem for |window|. 198 // Creates a new ShelfItem for |window|.
195 AddShelfItem(window); 199 AddShelfItem(window);
196 } 200 }
197 201
198 void ShelfWindowWatcher::OnWindowActivated(WmWindow* gained_active, 202 void ShelfWindowWatcher::OnWindowActivated(WmWindow* gained_active,
199 WmWindow* lost_active) { 203 WmWindow* lost_active) {
200 if (gained_active && HasShelfItemForWindow(gained_active)) 204 if (gained_active && user_windows_with_items_.count(gained_active) > 0)
201 UpdateShelfItemStatus(gained_active, true); 205 OnUserWindowPropertyChanged(gained_active);
202 if (lost_active && HasShelfItemForWindow(lost_active)) 206 if (lost_active && user_windows_with_items_.count(lost_active) > 0)
203 UpdateShelfItemStatus(lost_active, false); 207 OnUserWindowPropertyChanged(lost_active);
204 } 208 }
205 209
206 void ShelfWindowWatcher::OnDisplayAdded(const display::Display& new_display) { 210 void ShelfWindowWatcher::OnDisplayAdded(const display::Display& new_display) {
207 WmWindow* root = WmShell::Get()->GetRootWindowForDisplayId(new_display.id()); 211 WmWindow* root = WmShell::Get()->GetRootWindowForDisplayId(new_display.id());
208 212
209 // When the primary root window's display get removed, the existing root 213 // When the primary root window's display get removed, the existing root
210 // window is taken over by the new display and the observer is already set. 214 // window is taken over by the new display and the observer is already set.
211 WmWindow* container = 215 WmWindow* default_container =
212 root->GetChildByShellWindowId(kShellWindowId_DefaultContainer); 216 root->GetChildByShellWindowId(kShellWindowId_DefaultContainer);
213 if (!observed_container_windows_.IsObserving(container)) 217 if (!observed_container_windows_.IsObserving(default_container))
214 observed_container_windows_.Add(container); 218 observed_container_windows_.Add(default_container);
219 WmWindow* panel_container =
220 root->GetChildByShellWindowId(kShellWindowId_PanelContainer);
221 if (!observed_container_windows_.IsObserving(panel_container))
222 observed_container_windows_.Add(panel_container);
215 } 223 }
216 224
217 void ShelfWindowWatcher::OnDisplayRemoved(const display::Display& old_display) { 225 void ShelfWindowWatcher::OnDisplayRemoved(const display::Display& old_display) {
218 } 226 }
219 227
220 void ShelfWindowWatcher::OnDisplayMetricsChanged(const display::Display&, 228 void ShelfWindowWatcher::OnDisplayMetricsChanged(const display::Display&,
221 uint32_t) {} 229 uint32_t) {}
222 230
223 } // namespace ash 231 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/shelf/shelf_window_watcher.h ('k') | ash/common/shelf/shelf_window_watcher_item_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698