| OLD | NEW |
| 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/common/wm/container_finder.h" | 10 #include "ash/common/wm/container_finder.h" |
| 11 #include "ash/common/wm/window_dimmer.h" | 11 #include "ash/common/wm/window_dimmer.h" |
| 12 #include "ash/common/wm/window_state.h" | 12 #include "ash/common/wm/window_state.h" |
| 13 #include "ash/common/wm_window.h" | 13 #include "ash/common/wm_window.h" |
| 14 #include "ash/common/wm_window_user_data.h" | |
| 15 #include "ash/display/window_tree_host_manager.h" | 14 #include "ash/display/window_tree_host_manager.h" |
| 16 #include "ash/public/cpp/shell_window_ids.h" | 15 #include "ash/public/cpp/shell_window_ids.h" |
| 17 #include "ash/shell.h" | 16 #include "ash/shell.h" |
| 18 #include "base/auto_reset.h" | 17 #include "base/auto_reset.h" |
| 19 #include "base/logging.h" | 18 #include "base/logging.h" |
| 20 #include "base/memory/ptr_util.h" | 19 #include "base/memory/ptr_util.h" |
| 20 #include "ui/aura/window.h" |
| 21 #include "ui/aura/window_observer.h" | 21 #include "ui/aura/window_observer.h" |
| 22 #include "ui/wm/core/window_util.h" |
| 22 | 23 |
| 23 namespace ash { | 24 namespace ash { |
| 24 namespace { | 25 namespace { |
| 25 | 26 |
| 27 DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(WindowDimmer, kWindowDimmerKey, nullptr); |
| 28 |
| 26 // Returns a list of WmWindows corresponding to SystemModalContainers, | 29 // Returns a list of WmWindows corresponding to SystemModalContainers, |
| 27 // except ones whose root is shared with |pinned_window|. | 30 // except ones whose root is shared with |pinned_window|. |
| 28 std::vector<WmWindow*> GetSystemModalWindowsExceptPinned( | 31 std::vector<WmWindow*> GetSystemModalWindowsExceptPinned( |
| 29 WmWindow* pinned_window) { | 32 WmWindow* pinned_window) { |
| 30 WmWindow* pinned_root = pinned_window->GetRootWindow(); | 33 WmWindow* pinned_root = pinned_window->GetRootWindow(); |
| 31 | 34 |
| 32 std::vector<WmWindow*> result; | 35 std::vector<WmWindow*> result; |
| 33 for (WmWindow* system_modal : wm::GetContainersFromAllRootWindows( | 36 for (aura::Window* system_modal : wm::GetContainersFromAllRootWindows( |
| 34 kShellWindowId_SystemModalContainer)) { | 37 kShellWindowId_SystemModalContainer)) { |
| 35 if (system_modal->GetRootWindow() == pinned_root) | 38 if (WmWindow::Get(system_modal)->GetRootWindow() == pinned_root) |
| 36 continue; | 39 continue; |
| 37 result.push_back(system_modal); | 40 result.push_back(WmWindow::Get(system_modal)); |
| 38 } | 41 } |
| 39 return result; | 42 return result; |
| 40 } | 43 } |
| 41 | 44 |
| 42 void AddObserverToChildren(WmWindow* container, | 45 void AddObserverToChildren(WmWindow* container, |
| 43 aura::WindowObserver* observer) { | 46 aura::WindowObserver* observer) { |
| 44 for (WmWindow* child : container->GetChildren()) { | 47 for (WmWindow* child : container->GetChildren()) { |
| 45 WmWindow::GetAuraWindow(child)->AddObserver(observer); | 48 WmWindow::GetAuraWindow(child)->AddObserver(observer); |
| 46 } | 49 } |
| 47 } | 50 } |
| 48 | 51 |
| 49 void RemoveObserverFromChildren(WmWindow* container, | 52 void RemoveObserverFromChildren(WmWindow* container, |
| 50 aura::WindowObserver* observer) { | 53 aura::WindowObserver* observer) { |
| 51 for (WmWindow* child : container->GetChildren()) { | 54 for (WmWindow* child : container->GetChildren()) { |
| 52 WmWindow::GetAuraWindow(child)->RemoveObserver(observer); | 55 WmWindow::GetAuraWindow(child)->RemoveObserver(observer); |
| 53 } | 56 } |
| 54 } | 57 } |
| 55 | 58 |
| 59 // Returns true if the WindowDimmer's window associated with |window| is |
| 60 // visible. |
| 61 bool IsWindowDimmerWindowVisible(aura::Window* window) { |
| 62 // Expect this is only called for windows with a WindowDimmer. |
| 63 DCHECK(window->GetProperty(kWindowDimmerKey)); |
| 64 return window->GetProperty(kWindowDimmerKey) |
| 65 ->window() |
| 66 ->layer() |
| 67 ->GetTargetVisibility(); |
| 68 } |
| 69 |
| 56 } // namespace | 70 } // namespace |
| 57 | 71 |
| 58 // Adapter to fire OnPinnedContainerWindowStackingChanged(). | 72 // Adapter to fire OnPinnedContainerWindowStackingChanged(). |
| 59 class ScreenPinningController::PinnedContainerChildWindowObserver | 73 class ScreenPinningController::PinnedContainerChildWindowObserver |
| 60 : public aura::WindowObserver { | 74 : public aura::WindowObserver { |
| 61 public: | 75 public: |
| 62 explicit PinnedContainerChildWindowObserver( | 76 explicit PinnedContainerChildWindowObserver( |
| 63 ScreenPinningController* controller) | 77 ScreenPinningController* controller) |
| 64 : controller_(controller) {} | 78 : controller_(controller) {} |
| 65 | 79 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 window->RemoveObserver(this); | 149 window->RemoveObserver(this); |
| 136 } | 150 } |
| 137 | 151 |
| 138 private: | 152 private: |
| 139 ScreenPinningController* controller_; | 153 ScreenPinningController* controller_; |
| 140 DISALLOW_COPY_AND_ASSIGN(SystemModalContainerWindowObserver); | 154 DISALLOW_COPY_AND_ASSIGN(SystemModalContainerWindowObserver); |
| 141 }; | 155 }; |
| 142 | 156 |
| 143 ScreenPinningController::ScreenPinningController( | 157 ScreenPinningController::ScreenPinningController( |
| 144 WindowTreeHostManager* window_tree_host_manager) | 158 WindowTreeHostManager* window_tree_host_manager) |
| 145 : window_dimmers_(base::MakeUnique<WmWindowUserData<WindowDimmer>>()), | 159 : window_tree_host_manager_(window_tree_host_manager), |
| 146 window_tree_host_manager_(window_tree_host_manager), | |
| 147 pinned_container_window_observer_( | 160 pinned_container_window_observer_( |
| 148 base::MakeUnique<PinnedContainerWindowObserver>(this)), | 161 base::MakeUnique<PinnedContainerWindowObserver>(this)), |
| 149 pinned_container_child_window_observer_( | 162 pinned_container_child_window_observer_( |
| 150 base::MakeUnique<PinnedContainerChildWindowObserver>(this)), | 163 base::MakeUnique<PinnedContainerChildWindowObserver>(this)), |
| 151 system_modal_container_window_observer_( | 164 system_modal_container_window_observer_( |
| 152 base::MakeUnique<SystemModalContainerWindowObserver>(this)), | 165 base::MakeUnique<SystemModalContainerWindowObserver>(this)), |
| 153 system_modal_container_child_window_observer_( | 166 system_modal_container_child_window_observer_( |
| 154 base::MakeUnique<SystemModalContainerChildWindowObserver>(this)) { | 167 base::MakeUnique<SystemModalContainerChildWindowObserver>(this)) { |
| 155 window_tree_host_manager_->AddObserver(this); | 168 window_tree_host_manager_->AddObserver(this); |
| 156 } | 169 } |
| 157 | 170 |
| 158 ScreenPinningController::~ScreenPinningController() { | 171 ScreenPinningController::~ScreenPinningController() { |
| 159 window_tree_host_manager_->RemoveObserver(this); | 172 window_tree_host_manager_->RemoveObserver(this); |
| 160 } | 173 } |
| 161 | 174 |
| 162 bool ScreenPinningController::IsPinned() const { | 175 bool ScreenPinningController::IsPinned() const { |
| 163 return pinned_window_ != nullptr; | 176 return pinned_window_ != nullptr; |
| 164 } | 177 } |
| 165 | 178 |
| 166 void ScreenPinningController::SetPinnedWindow(WmWindow* pinned_window) { | 179 void ScreenPinningController::SetPinnedWindow(WmWindow* pinned_window) { |
| 167 window_dimmers_->clear(); | 180 for (aura::Window* window : windows_with_dimmers_.windows()) |
| 181 window->ClearProperty(kWindowDimmerKey); |
| 182 windows_with_dimmers_.RemoveAll(); |
| 168 | 183 |
| 169 if (pinned_window->GetWindowState()->IsPinned()) { | 184 if (pinned_window->GetWindowState()->IsPinned()) { |
| 170 if (pinned_window_) { | 185 if (pinned_window_) { |
| 171 LOG(DFATAL) << "Pinned mode is enabled, while it is already in " | 186 LOG(DFATAL) << "Pinned mode is enabled, while it is already in " |
| 172 << "the pinned mode"; | 187 << "the pinned mode"; |
| 173 return; | 188 return; |
| 174 } | 189 } |
| 175 | 190 |
| 176 WmWindow* container = pinned_window->GetParent(); | 191 WmWindow* container = pinned_window->GetParent(); |
| 177 std::vector<WmWindow*> system_modal_containers = | 192 std::vector<WmWindow*> system_modal_containers = |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 system_modal_container_child_window_observer_.get()); | 278 system_modal_container_child_window_observer_.get()); |
| 264 } | 279 } |
| 265 | 280 |
| 266 void ScreenPinningController::OnSystemModalContainerWindowStackingChanged( | 281 void ScreenPinningController::OnSystemModalContainerWindowStackingChanged( |
| 267 WmWindow* window) { | 282 WmWindow* window) { |
| 268 KeepDimWindowAtBottom(window->GetParent()); | 283 KeepDimWindowAtBottom(window->GetParent()); |
| 269 } | 284 } |
| 270 | 285 |
| 271 WmWindow* ScreenPinningController::CreateWindowDimmer(WmWindow* container) { | 286 WmWindow* ScreenPinningController::CreateWindowDimmer(WmWindow* container) { |
| 272 std::unique_ptr<WindowDimmer> window_dimmer = | 287 std::unique_ptr<WindowDimmer> window_dimmer = |
| 273 base::MakeUnique<WindowDimmer>(container); | 288 base::MakeUnique<WindowDimmer>(container->aura_window()); |
| 274 window_dimmer->SetDimOpacity(1); // Fully opaque. | 289 window_dimmer->SetDimOpacity(1); // Fully opaque. |
| 275 window_dimmer->window()->SetFullscreen(true); | 290 ::wm::SetWindowFullscreen(window_dimmer->window(), true); |
| 276 window_dimmer->window()->Show(); | 291 window_dimmer->window()->Show(); |
| 277 WmWindow* window = window_dimmer->window(); | 292 WmWindow* window = WmWindow::Get(window_dimmer->window()); |
| 278 window_dimmers_->Set(container, std::move(window_dimmer)); | 293 // |container| takes ownership of |window_dimmer|. |
| 294 container->aura_window()->SetProperty(kWindowDimmerKey, |
| 295 window_dimmer.release()); |
| 296 windows_with_dimmers_.Add(container->aura_window()); |
| 279 return window; | 297 return window; |
| 280 } | 298 } |
| 281 | 299 |
| 282 void ScreenPinningController::OnDisplayConfigurationChanged() { | 300 void ScreenPinningController::OnDisplayConfigurationChanged() { |
| 283 // Note: this is called on display attached or detached. | 301 // Note: this is called on display attached or detached. |
| 284 if (!IsPinned()) | 302 if (!IsPinned()) |
| 285 return; | 303 return; |
| 286 | 304 |
| 287 // On display detaching, all necessary windows are transfered to the | 305 // On display detaching, all necessary windows are transfered to the |
| 288 // primary display's tree, and called this. | 306 // primary display's tree, and called this. |
| 289 // So, delete WindowDimmers which are not a part of target system modal | 307 // So, delete WindowDimmers which are not a part of target system modal |
| 290 // container. | 308 // container. |
| 291 // On display attaching, the new system modal container does not have the | 309 // On display attaching, the new system modal container does not have the |
| 292 // WindowDimmer. So create it. | 310 // WindowDimmer. So create it. |
| 293 | 311 |
| 294 // First, delete unnecessary WindowDimmers. | 312 // First, delete unnecessary WindowDimmers. |
| 295 for (WmWindow* container : window_dimmers_->GetWindows()) { | 313 { |
| 296 if (container != pinned_window_->GetParent() && | 314 aura::Window::Windows windows = windows_with_dimmers_.windows(); |
| 297 !window_dimmers_->Get(container)->window()->GetTargetVisibility()) { | 315 for (aura::Window* container : windows) { |
| 298 window_dimmers_->Set(container, nullptr); | 316 if (WmWindow::Get(container) != pinned_window_->GetParent() && |
| 317 !IsWindowDimmerWindowVisible(container)) { |
| 318 windows_with_dimmers_.Remove(container); |
| 319 container->ClearProperty(kWindowDimmerKey); |
| 320 } |
| 299 } | 321 } |
| 300 } | 322 } |
| 301 | 323 |
| 302 // Then, create missing WindowDimmers. | 324 // Then, create missing WindowDimmers. |
| 303 std::vector<WmWindow*> system_modal_containers = | 325 std::vector<WmWindow*> system_modal_containers = |
| 304 GetSystemModalWindowsExceptPinned(pinned_window_); | 326 GetSystemModalWindowsExceptPinned(pinned_window_); |
| 305 for (WmWindow* system_modal : system_modal_containers) { | 327 for (WmWindow* system_modal : system_modal_containers) { |
| 306 if (window_dimmers_->Get(system_modal)) { | 328 if (system_modal->aura_window()->GetProperty(kWindowDimmerKey)) { |
| 307 // |system_modal| already has a WindowDimmer. | 329 // |system_modal| already has a WindowDimmer. |
| 308 continue; | 330 continue; |
| 309 } | 331 } |
| 310 | 332 |
| 311 // This is the new system modal dialog. | 333 // This is the new system modal dialog. |
| 312 system_modal->StackChildAtBottom(CreateWindowDimmer(system_modal)); | 334 system_modal->StackChildAtBottom(CreateWindowDimmer(system_modal)); |
| 313 | 335 |
| 314 // Set observers to the tree. | 336 // Set observers to the tree. |
| 315 WmWindow::GetAuraWindow(system_modal) | 337 WmWindow::GetAuraWindow(system_modal) |
| 316 ->AddObserver(system_modal_container_window_observer_.get()); | 338 ->AddObserver(system_modal_container_window_observer_.get()); |
| 317 AddObserverToChildren(system_modal, | 339 AddObserverToChildren(system_modal, |
| 318 system_modal_container_child_window_observer_.get()); | 340 system_modal_container_child_window_observer_.get()); |
| 319 } | 341 } |
| 320 } | 342 } |
| 321 | 343 |
| 322 void ScreenPinningController::KeepPinnedWindowOnTop() { | 344 void ScreenPinningController::KeepPinnedWindowOnTop() { |
| 323 if (in_restacking_) | 345 if (in_restacking_) |
| 324 return; | 346 return; |
| 325 | 347 |
| 326 base::AutoReset<bool> auto_reset(&in_restacking_, true); | 348 base::AutoReset<bool> auto_reset(&in_restacking_, true); |
| 327 WmWindow* container = pinned_window_->GetParent(); | 349 WmWindow* container = pinned_window_->GetParent(); |
| 328 container->StackChildAtTop(pinned_window_); | 350 container->StackChildAtTop(pinned_window_); |
| 329 WindowDimmer* pinned_window_dimmer = window_dimmers_->Get(container); | 351 WindowDimmer* pinned_window_dimmer = |
| 330 if (pinned_window_dimmer && pinned_window_dimmer->window()) | 352 container->aura_window()->GetProperty(kWindowDimmerKey); |
| 331 container->StackChildBelow(pinned_window_dimmer->window(), pinned_window_); | 353 if (pinned_window_dimmer && pinned_window_dimmer->window()) { |
| 354 container->StackChildBelow(WmWindow::Get(pinned_window_dimmer->window()), |
| 355 pinned_window_); |
| 356 } |
| 332 } | 357 } |
| 333 | 358 |
| 334 void ScreenPinningController::KeepDimWindowAtBottom(WmWindow* container) { | 359 void ScreenPinningController::KeepDimWindowAtBottom(WmWindow* container) { |
| 335 if (in_restacking_) | 360 if (in_restacking_) |
| 336 return; | 361 return; |
| 337 | 362 |
| 338 WindowDimmer* window_dimmer = window_dimmers_->Get(container); | 363 WindowDimmer* window_dimmer = |
| 364 container->aura_window()->GetProperty(kWindowDimmerKey); |
| 339 if (window_dimmer) { | 365 if (window_dimmer) { |
| 340 base::AutoReset<bool> auto_reset(&in_restacking_, true); | 366 base::AutoReset<bool> auto_reset(&in_restacking_, true); |
| 341 container->StackChildAtBottom(window_dimmer->window()); | 367 container->StackChildAtBottom(WmWindow::Get(window_dimmer->window())); |
| 342 } | 368 } |
| 343 } | 369 } |
| 344 | 370 |
| 345 } // namespace ash | 371 } // namespace ash |
| OLD | NEW |