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

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

Issue 2734653002: chromeos: Move files in //ash/common to //ash (Closed)
Patch Set: fix a11y tests, fix docs Created 3 years, 9 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/common/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/shelf/shelf_window_watcher_item_delegate.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/public/cpp/shell_window_ids.h"
17 #include "ash/public/cpp/window_properties.h"
18 #include "ash/shell.h"
19 #include "ash/wm/window_properties.h"
20 #include "ash/wm/window_state_aura.h"
21 #include "ash/wm/window_util.h"
22 #include "ui/aura/client/aura_constants.h"
23 #include "ui/aura/env.h"
24 #include "ui/aura/window.h"
25 #include "ui/display/display.h"
26 #include "ui/display/screen.h"
27 #include "ui/wm/public/activation_client.h"
28
29 namespace ash {
30 namespace {
31
32 // Returns the shelf item type, with special temporary behavior for Mash:
33 // Mash provides a default shelf item type (TYPE_APP) for non-ignored windows.
34 ShelfItemType GetShelfItemType(aura::Window* window) {
35 if (aura::Env::GetInstance()->mode() == aura::Env::Mode::LOCAL ||
36 window->GetProperty(kShelfItemTypeKey) != TYPE_UNDEFINED) {
37 return static_cast<ShelfItemType>(window->GetProperty(kShelfItemTypeKey));
38 }
39 return wm::GetWindowState(window)->ignored_by_shelf() ? TYPE_UNDEFINED
40 : TYPE_APP;
41 }
42
43 // Update the ShelfItem from relevant window properties.
44 void UpdateShelfItemForWindow(ShelfItem* item, aura::Window* window) {
45 item->type = GetShelfItemType(window);
46
47 item->status = STATUS_RUNNING;
48 if (wm::IsActiveWindow(window))
49 item->status = STATUS_ACTIVE;
50 else if (window->GetProperty(aura::client::kDrawAttentionKey))
51 item->status = STATUS_ATTENTION;
52
53 const std::string* app_id = window->GetProperty(aura::client::kAppIdKey);
54 item->app_id = app_id ? *app_id : std::string();
55
56 // Prefer app icons over window icons, they're typically larger.
57 gfx::ImageSkia* image = window->GetProperty(aura::client::kAppIconKey);
58 if (!image || image->isNull())
59 image = window->GetProperty(aura::client::kWindowIconKey);
60 item->image = image ? *image : gfx::ImageSkia();
61
62 item->title = window->GetTitle();
63
64 // Do not show tooltips for visible attached app panel windows.
65 item->shows_tooltip = item->type != TYPE_APP_PANEL || !window->IsVisible() ||
66 !window->GetProperty(kPanelAttachedKey);
67 }
68
69 } // namespace
70
71 ShelfWindowWatcher::ContainerWindowObserver::ContainerWindowObserver(
72 ShelfWindowWatcher* window_watcher)
73 : window_watcher_(window_watcher) {}
74
75 ShelfWindowWatcher::ContainerWindowObserver::~ContainerWindowObserver() {}
76
77 void ShelfWindowWatcher::ContainerWindowObserver::OnWindowHierarchyChanged(
78 const HierarchyChangeParams& params) {
79 if (!params.old_parent && params.new_parent &&
80 (params.new_parent->id() == kShellWindowId_DefaultContainer ||
81 params.new_parent->id() == kShellWindowId_PanelContainer)) {
82 // A new window was created in the default container or the panel container.
83 window_watcher_->OnUserWindowAdded(params.target);
84 }
85 }
86
87 void ShelfWindowWatcher::ContainerWindowObserver::OnWindowDestroying(
88 aura::Window* window) {
89 window_watcher_->OnContainerWindowDestroying(window);
90 }
91
92 ////////////////////////////////////////////////////////////////////////////////
93
94 ShelfWindowWatcher::UserWindowObserver::UserWindowObserver(
95 ShelfWindowWatcher* window_watcher)
96 : window_watcher_(window_watcher) {}
97
98 ShelfWindowWatcher::UserWindowObserver::~UserWindowObserver() {}
99
100 void ShelfWindowWatcher::UserWindowObserver::OnWindowPropertyChanged(
101 aura::Window* window,
102 const void* key,
103 intptr_t old) {
104 if (key == aura::client::kAppIconKey || key == aura::client::kAppIdKey ||
105 key == aura::client::kDrawAttentionKey ||
106 key == aura::client::kWindowIconKey || key == kPanelAttachedKey ||
107 key == kShelfItemTypeKey) {
108 window_watcher_->OnUserWindowPropertyChanged(window);
109 }
110 }
111
112 void ShelfWindowWatcher::UserWindowObserver::OnWindowDestroying(
113 aura::Window* window) {
114 window_watcher_->OnUserWindowDestroying(window);
115 }
116
117 void ShelfWindowWatcher::UserWindowObserver::OnWindowVisibilityChanged(
118 aura::Window* window,
119 bool visible) {
120 // OnWindowVisibilityChanged() is called for descendants too. We only care
121 // about changes to the visibility of windows we know about.
122 if (!window_watcher_->observed_user_windows_.IsObserving(window))
123 return;
124
125 // The tooltip behavior for panel windows depends on the panel visibility.
126 window_watcher_->OnUserWindowPropertyChanged(window);
127 }
128
129 void ShelfWindowWatcher::UserWindowObserver::OnWindowTitleChanged(
130 aura::Window* window) {
131 window_watcher_->OnUserWindowPropertyChanged(window);
132 }
133
134 ////////////////////////////////////////////////////////////////////////////////
135
136 ShelfWindowWatcher::ShelfWindowWatcher(ShelfModel* model)
137 : model_(model),
138 container_window_observer_(this),
139 user_window_observer_(this),
140 observed_container_windows_(&container_window_observer_),
141 observed_user_windows_(&user_window_observer_) {
142 Shell::GetInstance()->activation_client()->AddObserver(this);
143 for (const auto& display : display::Screen::GetScreen()->GetAllDisplays())
144 OnDisplayAdded(display);
145 display::Screen::GetScreen()->AddObserver(this);
146 }
147
148 ShelfWindowWatcher::~ShelfWindowWatcher() {
149 display::Screen::GetScreen()->RemoveObserver(this);
150 Shell::GetInstance()->activation_client()->RemoveObserver(this);
151 }
152
153 void ShelfWindowWatcher::AddShelfItem(aura::Window* window) {
154 user_windows_with_items_.insert(window);
155 ShelfItem item;
156 ShelfID id = model_->next_id();
157 UpdateShelfItemForWindow(&item, window);
158 window->SetProperty(kShelfIDKey, id);
159 std::unique_ptr<ShelfItemDelegate> item_delegate(
160 new ShelfWindowWatcherItemDelegate(id, WmWindow::Get(window)));
161 model_->SetShelfItemDelegate(id, std::move(item_delegate));
162 // Panels are inserted on the left so as not to push all existing panels over.
163 model_->AddAt(item.type == TYPE_APP_PANEL ? 0 : model_->item_count(), item);
164 }
165
166 void ShelfWindowWatcher::RemoveShelfItem(aura::Window* window) {
167 user_windows_with_items_.erase(window);
168 int shelf_id = window->GetProperty(kShelfIDKey);
169 DCHECK_NE(shelf_id, kInvalidShelfID);
170 int index = model_->ItemIndexByID(shelf_id);
171 DCHECK_GE(index, 0);
172 model_->RemoveItemAt(index);
173 window->SetProperty(kShelfIDKey, kInvalidShelfID);
174 }
175
176 void ShelfWindowWatcher::OnContainerWindowDestroying(aura::Window* container) {
177 observed_container_windows_.Remove(container);
178 }
179
180 int ShelfWindowWatcher::GetShelfItemIndexForWindow(aura::Window* window) const {
181 return model_->ItemIndexByID(window->GetProperty(kShelfIDKey));
182 }
183
184 void ShelfWindowWatcher::OnUserWindowAdded(aura::Window* window) {
185 // The window may already be tracked from a prior display or parent container.
186 if (observed_user_windows_.IsObserving(window))
187 return;
188
189 observed_user_windows_.Add(window);
190
191 // Add, update, or remove a ShelfItem for |window|, as needed.
192 OnUserWindowPropertyChanged(window);
193 }
194
195 void ShelfWindowWatcher::OnUserWindowDestroying(aura::Window* window) {
196 if (observed_user_windows_.IsObserving(window))
197 observed_user_windows_.Remove(window);
198
199 if (user_windows_with_items_.count(window) > 0)
200 RemoveShelfItem(window);
201 DCHECK_EQ(0u, user_windows_with_items_.count(window));
202 }
203
204 void ShelfWindowWatcher::OnUserWindowPropertyChanged(aura::Window* window) {
205 if (GetShelfItemType(window) == TYPE_UNDEFINED) {
206 // Remove |window|'s ShelfItem if it was added by this ShelfWindowWatcher.
207 if (user_windows_with_items_.count(window) > 0)
208 RemoveShelfItem(window);
209 return;
210 }
211
212 // Update an existing ShelfItem for |window| when a property has changed.
213 int index = GetShelfItemIndexForWindow(window);
214 if (index > 0) {
215 ShelfItem item = model_->items()[index];
216 UpdateShelfItemForWindow(&item, window);
217 model_->Set(index, item);
218 return;
219 }
220
221 // Creates a new ShelfItem for |window|.
222 AddShelfItem(window);
223 }
224
225 void ShelfWindowWatcher::OnWindowActivated(ActivationReason reason,
226 aura::Window* gained_active,
227 aura::Window* lost_active) {
228 if (gained_active && user_windows_with_items_.count(gained_active) > 0)
229 OnUserWindowPropertyChanged(gained_active);
230 if (lost_active && user_windows_with_items_.count(lost_active) > 0)
231 OnUserWindowPropertyChanged(lost_active);
232 }
233
234 void ShelfWindowWatcher::OnDisplayAdded(const display::Display& new_display) {
235 WmWindow* root = WmShell::Get()->GetRootWindowForDisplayId(new_display.id());
236 aura::Window* aura_root = WmWindow::GetAuraWindow(root);
237
238 // When the primary root window's display is removed, the existing root window
239 // is taken over by the new display, and the observer is already set.
240 aura::Window* default_container =
241 aura_root->GetChildById(kShellWindowId_DefaultContainer);
242 if (!observed_container_windows_.IsObserving(default_container)) {
243 for (aura::Window* window : default_container->children())
244 OnUserWindowAdded(window);
245 observed_container_windows_.Add(default_container);
246 }
247 aura::Window* panel_container =
248 aura_root->GetChildById(kShellWindowId_PanelContainer);
249 if (!observed_container_windows_.IsObserving(panel_container)) {
250 for (aura::Window* window : panel_container->children())
251 OnUserWindowAdded(window);
252 observed_container_windows_.Add(panel_container);
253 }
254 }
255
256 void ShelfWindowWatcher::OnDisplayRemoved(const display::Display& old_display) {
257 }
258
259 void ShelfWindowWatcher::OnDisplayMetricsChanged(const display::Display&,
260 uint32_t) {}
261
262 } // 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