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

Side by Side Diff: ash/wm/screen_pinning_controller.cc

Issue 2320273002: Refactors DimWindow and moves to ash/common (Closed)
Patch Set: feedback and member initializer ordering Created 4 years, 3 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
« no previous file with comments | « ash/wm/screen_pinning_controller.h ('k') | ash/wm/system_modal_container_layout_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/wm/screen_pinning_controller.h" 5 #include "ash/wm/screen_pinning_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "ash/aura/wm_window_aura.h" 10 #include "ash/aura/wm_window_aura.h"
11 #include "ash/common/shell_window_ids.h" 11 #include "ash/common/shell_window_ids.h"
12 #include "ash/common/wm/window_dimmer.h"
12 #include "ash/common/wm/window_state.h" 13 #include "ash/common/wm/window_state.h"
13 #include "ash/common/wm_shell.h" 14 #include "ash/common/wm_shell.h"
14 #include "ash/common/wm_window.h" 15 #include "ash/common/wm_window.h"
15 #include "ash/common/wm_window_observer.h" 16 #include "ash/common/wm_window_observer.h"
17 #include "ash/common/wm_window_user_data.h"
16 #include "ash/display/window_tree_host_manager.h" 18 #include "ash/display/window_tree_host_manager.h"
17 #include "ash/shell.h" 19 #include "ash/shell.h"
18 #include "ash/wm/dim_window.h"
19 #include "base/auto_reset.h" 20 #include "base/auto_reset.h"
20 #include "base/logging.h" 21 #include "base/logging.h"
21 #include "base/stl_util.h" 22 #include "base/memory/ptr_util.h"
22 #include "ui/aura/window_observer.h" 23 #include "ui/aura/window_observer.h"
23 24
24 namespace ash { 25 namespace ash {
25 namespace { 26 namespace {
26 27
27 WmWindow* CreateDimWindow(WmWindow* container) {
28 DimWindow* dim_window = new DimWindow(WmWindowAura::GetAuraWindow(container));
29 dim_window->SetDimOpacity(1); // Set whole black.
30 WmWindow* result = WmWindowAura::Get(dim_window);
31 result->SetFullscreen();
32 result->Show();
33 return result;
34 }
35
36 // Returns a list of WmWindows corresponding to SystemModalContainers, 28 // Returns a list of WmWindows corresponding to SystemModalContainers,
37 // except ones whose root is shared with |pinned_window|. 29 // except ones whose root is shared with |pinned_window|.
38 std::vector<WmWindow*> GetSystemModalWindowsExceptPinned( 30 std::vector<WmWindow*> GetSystemModalWindowsExceptPinned(
39 WmWindow* pinned_window) { 31 WmWindow* pinned_window) {
40 WmWindow* pinned_root = pinned_window->GetRootWindow(); 32 WmWindow* pinned_root = pinned_window->GetRootWindow();
41 33
42 std::vector<WmWindow*> result; 34 std::vector<WmWindow*> result;
43 for (WmWindow* system_modal : 35 for (WmWindow* system_modal :
44 WmWindowAura::FromAuraWindows(Shell::GetContainersFromAllRootWindows( 36 WmWindowAura::FromAuraWindows(Shell::GetContainersFromAllRootWindows(
45 kShellWindowId_SystemModalContainer, nullptr))) { 37 kShellWindowId_SystemModalContainer, nullptr))) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 void OnWindowDestroying(aura::Window* window) override { 139 void OnWindowDestroying(aura::Window* window) override {
148 // Just in case. There is nothing we can do here. 140 // Just in case. There is nothing we can do here.
149 window->RemoveObserver(this); 141 window->RemoveObserver(this);
150 } 142 }
151 143
152 private: 144 private:
153 ScreenPinningController* controller_; 145 ScreenPinningController* controller_;
154 DISALLOW_COPY_AND_ASSIGN(SystemModalContainerWindowObserver); 146 DISALLOW_COPY_AND_ASSIGN(SystemModalContainerWindowObserver);
155 }; 147 };
156 148
157 // Tracks DimWindow's life.
158 class ScreenPinningController::DimWindowObserver : public aura::WindowObserver {
159 public:
160 explicit DimWindowObserver(ScreenPinningController* controller)
161 : controller_(controller) {}
162
163 void OnWindowParentChanged(aura::Window* window,
164 aura::Window* parent) override {
165 // In case of parent change, there is nothing we can do for that change.
166 // Also, it is unsafe to delete the moving window here, because it could
167 // cause SEGV. Instead, we just hide it.
168 // Note that, the window is still tracked by the ScreenPinningController,
169 // so that it should be deleted on "unpin", at least.
170 window->Hide();
171 }
172
173 void OnWindowDestroying(aura::Window* window) override {
174 controller_->OnDimWindowDestroying(WmWindowAura::Get(window));
175 }
176
177 private:
178 ScreenPinningController* controller_;
179 DISALLOW_COPY_AND_ASSIGN(DimWindowObserver);
180 };
181
182 ScreenPinningController::ScreenPinningController( 149 ScreenPinningController::ScreenPinningController(
183 WindowTreeHostManager* window_tree_host_manager) 150 WindowTreeHostManager* window_tree_host_manager)
184 : window_tree_host_manager_(window_tree_host_manager), 151 : window_dimmers_(base::MakeUnique<WmWindowUserData<WindowDimmer>>()),
152 window_tree_host_manager_(window_tree_host_manager),
185 pinned_container_window_observer_( 153 pinned_container_window_observer_(
186 new PinnedContainerWindowObserver(this)), 154 base::MakeUnique<PinnedContainerWindowObserver>(this)),
187 pinned_container_child_window_observer_( 155 pinned_container_child_window_observer_(
188 new PinnedContainerChildWindowObserver(this)), 156 base::MakeUnique<PinnedContainerChildWindowObserver>(this)),
189 system_modal_container_window_observer_( 157 system_modal_container_window_observer_(
190 new SystemModalContainerWindowObserver(this)), 158 base::MakeUnique<SystemModalContainerWindowObserver>(this)),
191 system_modal_container_child_window_observer_( 159 system_modal_container_child_window_observer_(
192 new SystemModalContainerChildWindowObserver(this)), 160 base::MakeUnique<SystemModalContainerChildWindowObserver>(this)) {
193 dim_window_observer_(new DimWindowObserver(this)) {
194 window_tree_host_manager_->AddObserver(this); 161 window_tree_host_manager_->AddObserver(this);
195 } 162 }
196 163
197 ScreenPinningController::~ScreenPinningController() { 164 ScreenPinningController::~ScreenPinningController() {
198 window_tree_host_manager_->RemoveObserver(this); 165 window_tree_host_manager_->RemoveObserver(this);
199 } 166 }
200 167
201 bool ScreenPinningController::IsPinned() const { 168 bool ScreenPinningController::IsPinned() const {
202 return pinned_window_ != nullptr; 169 return pinned_window_ != nullptr;
203 } 170 }
204 171
205 void ScreenPinningController::SetPinnedWindow(WmWindow* pinned_window) { 172 void ScreenPinningController::SetPinnedWindow(WmWindow* pinned_window) {
173 window_dimmers_->clear();
174
206 if (pinned_window->GetWindowState()->IsPinned()) { 175 if (pinned_window->GetWindowState()->IsPinned()) {
207 if (pinned_window_) { 176 if (pinned_window_) {
208 LOG(DFATAL) << "Pinned mode is enabled, while it is already in " 177 LOG(DFATAL) << "Pinned mode is enabled, while it is already in "
209 << "the pinned mode"; 178 << "the pinned mode";
210 return; 179 return;
211 } 180 }
212 181
213 WmWindow* container = pinned_window->GetParent(); 182 WmWindow* container = pinned_window->GetParent();
214 std::vector<WmWindow*> system_modal_containers = 183 std::vector<WmWindow*> system_modal_containers =
215 GetSystemModalWindowsExceptPinned(pinned_window); 184 GetSystemModalWindowsExceptPinned(pinned_window);
216 185
217 // Set up the container which has the pinned window. 186 // Set up the container which has the pinned window.
218 pinned_window_ = pinned_window; 187 pinned_window_ = pinned_window;
219 background_window_ = CreateDimWindow(container);
220 container->StackChildAtTop(pinned_window); 188 container->StackChildAtTop(pinned_window);
221 container->StackChildBelow(background_window_, pinned_window); 189 container->StackChildBelow(CreateWindowDimmer(container), pinned_window);
222 190
223 // Set the dim windows to the system containers, other than the one which 191 // Set the dim windows to the system containers, other than the one which
224 // the root window of the pinned window holds. 192 // the root window of the pinned window holds.
225 for (WmWindow* system_modal : system_modal_containers) { 193 for (WmWindow* system_modal : system_modal_containers)
226 WmWindow* dim_window = CreateDimWindow(system_modal); 194 system_modal->StackChildAtBottom(CreateWindowDimmer(system_modal));
227 system_modal->StackChildAtBottom(dim_window);
228 dim_windows_.push_back(dim_window);
229 WmWindowAura::GetAuraWindow(dim_window)
230 ->AddObserver(dim_window_observer_.get());
231 }
232 195
233 // Set observers. 196 // Set observers.
234 WmWindowAura::GetAuraWindow(container)->AddObserver( 197 WmWindowAura::GetAuraWindow(container)->AddObserver(
235 pinned_container_window_observer_.get()); 198 pinned_container_window_observer_.get());
236 AddObserverToChildren(container, 199 AddObserverToChildren(container,
237 pinned_container_child_window_observer_.get()); 200 pinned_container_child_window_observer_.get());
238 for (WmWindow* system_modal : system_modal_containers) { 201 for (WmWindow* system_modal : system_modal_containers) {
239 WmWindowAura::GetAuraWindow(system_modal) 202 WmWindowAura::GetAuraWindow(system_modal)
240 ->AddObserver(system_modal_container_window_observer_.get()); 203 ->AddObserver(system_modal_container_window_observer_.get());
241 AddObserverToChildren( 204 AddObserverToChildren(
(...skipping 16 matching lines...) Expand all
258 RemoveObserverFromChildren( 221 RemoveObserverFromChildren(
259 system_modal, system_modal_container_child_window_observer_.get()); 222 system_modal, system_modal_container_child_window_observer_.get());
260 WmWindowAura::GetAuraWindow(system_modal) 223 WmWindowAura::GetAuraWindow(system_modal)
261 ->RemoveObserver(system_modal_container_window_observer_.get()); 224 ->RemoveObserver(system_modal_container_window_observer_.get());
262 } 225 }
263 RemoveObserverFromChildren(container, 226 RemoveObserverFromChildren(container,
264 pinned_container_child_window_observer_.get()); 227 pinned_container_child_window_observer_.get());
265 WmWindowAura::GetAuraWindow(container)->RemoveObserver( 228 WmWindowAura::GetAuraWindow(container)->RemoveObserver(
266 pinned_container_window_observer_.get()); 229 pinned_container_window_observer_.get());
267 230
268 // Delete the dim windows. This works, but do not use RAII, because
269 // the window is owned by the parent.
270 // Note: dim_windows_ will be updated during the deletion. So, copy is
271 // needed.
272 for (WmWindow* dim_window : std::vector<WmWindow*>(dim_windows_)) {
273 delete WmWindowAura::GetAuraWindow(dim_window);
274 }
275 DCHECK(dim_windows_.empty());
276 delete WmWindowAura::GetAuraWindow(background_window_);
277 background_window_ = nullptr;
278
279 pinned_window_ = nullptr; 231 pinned_window_ = nullptr;
280 } 232 }
281 233
282 WmShell::Get()->NotifyPinnedStateChanged(pinned_window); 234 WmShell::Get()->NotifyPinnedStateChanged(pinned_window);
283 } 235 }
284 236
285 void ScreenPinningController::OnWindowAddedToPinnedContainer( 237 void ScreenPinningController::OnWindowAddedToPinnedContainer(
286 WmWindow* new_window) { 238 WmWindow* new_window) {
287 KeepPinnedWindowOnTop(); 239 KeepPinnedWindowOnTop();
288 WmWindowAura::GetAuraWindow(new_window) 240 WmWindowAura::GetAuraWindow(new_window)
289 ->AddObserver(pinned_container_child_window_observer_.get()); 241 ->AddObserver(pinned_container_child_window_observer_.get());
290 } 242 }
291 243
292 void ScreenPinningController::OnWillRemoveWindowFromPinnedContainer( 244 void ScreenPinningController::OnWillRemoveWindowFromPinnedContainer(
293 WmWindow* window) { 245 WmWindow* window) {
294 WmWindowAura::GetAuraWindow(window)->RemoveObserver( 246 WmWindowAura::GetAuraWindow(window)->RemoveObserver(
295 pinned_container_child_window_observer_.get()); 247 pinned_container_child_window_observer_.get());
296 if (window == pinned_window_) { 248 if (window == pinned_window_) {
297 pinned_window_->GetWindowState()->Restore(); 249 pinned_window_->GetWindowState()->Restore();
298 return; 250 return;
299 } 251 }
300 if (window == background_window_) {
301 background_window_ = nullptr;
302 return;
303 }
304 } 252 }
305 253
306 void ScreenPinningController::OnPinnedContainerWindowStackingChanged( 254 void ScreenPinningController::OnPinnedContainerWindowStackingChanged(
307 WmWindow* window) { 255 WmWindow* window) {
308 KeepPinnedWindowOnTop(); 256 KeepPinnedWindowOnTop();
309 } 257 }
310 258
311 void ScreenPinningController::OnWindowAddedToSystemModalContainer( 259 void ScreenPinningController::OnWindowAddedToSystemModalContainer(
312 WmWindow* new_window) { 260 WmWindow* new_window) {
313 KeepDimWindowAtBottom(new_window->GetParent()); 261 KeepDimWindowAtBottom(new_window->GetParent());
314 WmWindowAura::GetAuraWindow(new_window) 262 WmWindowAura::GetAuraWindow(new_window)
315 ->AddObserver(system_modal_container_child_window_observer_.get()); 263 ->AddObserver(system_modal_container_child_window_observer_.get());
316 } 264 }
317 265
318 void ScreenPinningController::OnWillRemoveWindowFromSystemModalContainer( 266 void ScreenPinningController::OnWillRemoveWindowFromSystemModalContainer(
319 WmWindow* window) { 267 WmWindow* window) {
320 WmWindowAura::GetAuraWindow(window)->RemoveObserver( 268 WmWindowAura::GetAuraWindow(window)->RemoveObserver(
321 system_modal_container_child_window_observer_.get()); 269 system_modal_container_child_window_observer_.get());
322 } 270 }
323 271
324 void ScreenPinningController::OnSystemModalContainerWindowStackingChanged( 272 void ScreenPinningController::OnSystemModalContainerWindowStackingChanged(
325 WmWindow* window) { 273 WmWindow* window) {
326 KeepDimWindowAtBottom(window->GetParent()); 274 KeepDimWindowAtBottom(window->GetParent());
327 } 275 }
328 276
329 void ScreenPinningController::OnDimWindowDestroying(WmWindow* window) { 277 WmWindow* ScreenPinningController::CreateWindowDimmer(WmWindow* container) {
330 dim_windows_.erase( 278 std::unique_ptr<WindowDimmer> window_dimmer =
331 std::find(dim_windows_.begin(), dim_windows_.end(), window)); 279 base::MakeUnique<WindowDimmer>(container);
280 window_dimmer->SetDimOpacity(1); // Fully opaque.
281 window_dimmer->window()->SetFullscreen();
282 window_dimmer->window()->Show();
283 WmWindow* window = window_dimmer->window();
284 window_dimmers_->Set(container, std::move(window_dimmer));
285 return window;
332 } 286 }
333 287
334 void ScreenPinningController::OnDisplayConfigurationChanged() { 288 void ScreenPinningController::OnDisplayConfigurationChanged() {
335 // Note: this is called on display attached or detached. 289 // Note: this is called on display attached or detached.
336 if (!IsPinned()) 290 if (!IsPinned())
337 return; 291 return;
338 292
339 // On display detaching, all necessary windows are transfered to the 293 // On display detaching, all necessary windows are transfered to the
340 // primary display's tree, and called this. 294 // primary display's tree, and called this.
341 // So, delete the dim windows which are not a part of target system modal 295 // So, delete WindowDimmers which are not a part of target system modal
342 // container. 296 // container.
343 // On display attaching, the new system modal container does not have the 297 // On display attaching, the new system modal container does not have the
344 // dim window. So create it. 298 // WindowDimmer. So create it.
345 299
346 // First, delete unnecessary dim windows. 300 // First, delete unnecessary WindowDimmers.
347 // The delete will update dim_windows_, so create the copy is needed. 301 for (WmWindow* container : window_dimmers_->GetWindows()) {
348 for (WmWindow* dim_window : std::vector<WmWindow*>(dim_windows_)) { 302 if (container != pinned_window_->GetParent() &&
349 if (!dim_window->GetTargetVisibility()) 303 !window_dimmers_->Get(container)->window()->GetTargetVisibility()) {
350 delete WmWindowAura::GetAuraWindow(dim_window); 304 window_dimmers_->Set(container, nullptr);
305 }
351 } 306 }
352 307
353 // Then, create missing dim_windows. 308 // Then, create missing WindowDimmers.
354 std::vector<WmWindow*> system_modal_containers = 309 std::vector<WmWindow*> system_modal_containers =
355 GetSystemModalWindowsExceptPinned(pinned_window_); 310 GetSystemModalWindowsExceptPinned(pinned_window_);
356 for (WmWindow* system_modal : system_modal_containers) { 311 for (WmWindow* system_modal : system_modal_containers) {
357 const std::vector<WmWindow*> children = system_modal->GetChildren(); 312 if (window_dimmers_->Get(system_modal)) {
358 if (!children.empty() && base::ContainsValue(dim_windows_, children[0])) { 313 // |system_modal| already has a WindowDimmer.
359 // The system modal dialog has the dim window.
360 continue; 314 continue;
361 } 315 }
362 316
363 // This is the new system modal dialog. 317 // This is the new system modal dialog.
364 WmWindow* dim_window = CreateDimWindow(system_modal); 318 system_modal->StackChildAtBottom(CreateWindowDimmer(system_modal));
365 system_modal->StackChildAtBottom(dim_window);
366 dim_windows_.push_back(dim_window);
367 WmWindowAura::GetAuraWindow(dim_window)
368 ->AddObserver(dim_window_observer_.get());
369 319
370 // Set observers to the tree. 320 // Set observers to the tree.
371 WmWindowAura::GetAuraWindow(system_modal) 321 WmWindowAura::GetAuraWindow(system_modal)
372 ->AddObserver(system_modal_container_window_observer_.get()); 322 ->AddObserver(system_modal_container_window_observer_.get());
373 AddObserverToChildren(system_modal, 323 AddObserverToChildren(system_modal,
374 system_modal_container_child_window_observer_.get()); 324 system_modal_container_child_window_observer_.get());
375 } 325 }
376 } 326 }
377 327
378 void ScreenPinningController::KeepPinnedWindowOnTop() { 328 void ScreenPinningController::KeepPinnedWindowOnTop() {
379 if (in_restacking_) 329 if (in_restacking_)
380 return; 330 return;
381 331
382 base::AutoReset<bool> auto_reset(&in_restacking_, true); 332 base::AutoReset<bool> auto_reset(&in_restacking_, true);
383 WmWindow* container = pinned_window_->GetParent(); 333 WmWindow* container = pinned_window_->GetParent();
384 container->StackChildAtTop(pinned_window_); 334 container->StackChildAtTop(pinned_window_);
385 container->StackChildBelow(background_window_, pinned_window_); 335 WindowDimmer* pinned_window_dimmer = window_dimmers_->Get(container);
336 if (pinned_window_dimmer && pinned_window_dimmer->window())
337 container->StackChildBelow(pinned_window_dimmer->window(), pinned_window_);
386 } 338 }
387 339
388 void ScreenPinningController::KeepDimWindowAtBottom(WmWindow* container) { 340 void ScreenPinningController::KeepDimWindowAtBottom(WmWindow* container) {
389 if (in_restacking_) 341 if (in_restacking_)
390 return; 342 return;
391 343
392 base::AutoReset<bool> auto_reset(&in_restacking_, true); 344 WindowDimmer* window_dimmer = window_dimmers_->Get(container);
393 for (WmWindow* dim_window : dim_windows_) { 345 if (window_dimmer) {
394 if (dim_window->GetParent() == container) { 346 base::AutoReset<bool> auto_reset(&in_restacking_, true);
395 container->StackChildAtBottom(dim_window); 347 container->StackChildAtBottom(window_dimmer->window());
396 break;
397 }
398 } 348 }
399 } 349 }
400 350
401 } // namespace ash 351 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/screen_pinning_controller.h ('k') | ash/wm/system_modal_container_layout_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698