123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- // Copyright 2016 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/wm/container_finder.h"
- #include "ash/public/cpp/shell_window_ids.h"
- #include "ash/public/cpp/window_properties.h"
- #include "ash/root_window_controller.h"
- #include "ash/session/session_controller_impl.h"
- #include "ash/shell.h"
- #include "ash/wm/always_on_top_controller.h"
- #include "ash/wm/window_state.h"
- #include "ash/wm/window_util.h"
- #include "components/app_restore/window_properties.h"
- #include "ui/aura/client/aura_constants.h"
- #include "ui/aura/window.h"
- #include "ui/gfx/geometry/rect.h"
- #include "ui/wm/core/window_util.h"
- namespace ash {
- namespace {
- aura::Window* FindContainerRoot(const gfx::Rect& bounds_in_screen) {
- if (bounds_in_screen == gfx::Rect())
- return Shell::GetRootWindowForNewWindows();
- return window_util::GetRootWindowMatching(bounds_in_screen);
- }
- bool HasTransientParentWindow(const aura::Window* window) {
- const aura::Window* transient_parent = ::wm::GetTransientParent(window);
- return transient_parent &&
- transient_parent->GetType() != aura::client::WINDOW_TYPE_UNKNOWN;
- }
- aura::Window* GetSystemModalContainer(aura::Window* root,
- aura::Window* window) {
- DCHECK_EQ(ui::MODAL_TYPE_SYSTEM,
- window->GetProperty(aura::client::kModalKey));
- // If |window| is already in a system modal container in |root|, re-use it.
- for (auto modal_container_id : kSystemModalContainerIds) {
- aura::Window* modal_container = root->GetChildById(modal_container_id);
- if (window->parent() == modal_container)
- return modal_container;
- }
- aura::Window* transient_parent = ::wm::GetTransientParent(window);
- // If screen lock is not active and user session is active,
- // all modal windows are placed into the normal modal container.
- // In case of missing transient parent (it could happen for alerts from
- // background pages) assume that the window belongs to user session.
- if (!Shell::Get()->session_controller()->IsUserSessionBlocked() ||
- !transient_parent) {
- return root->GetChildById(kShellWindowId_SystemModalContainer);
- }
- // Otherwise those that originate from LockScreen container and above are
- // placed in the screen lock modal container.
- int window_container_id = transient_parent->parent()->GetId();
- if (window_container_id < kShellWindowId_LockScreenContainer)
- return root->GetChildById(kShellWindowId_SystemModalContainer);
- return root->GetChildById(kShellWindowId_LockSystemModalContainer);
- }
- aura::Window* GetContainerFromAlwaysOnTopController(aura::Window* root,
- aura::Window* window) {
- return RootWindowController::ForWindow(root)
- ->always_on_top_controller()
- ->GetContainer(window);
- }
- } // namespace
- aura::Window* GetContainerForWindow(aura::Window* window) {
- aura::Window* parent = window->parent();
- // The first parent with an explicit shell window ID is the container.
- while (parent && parent->GetId() == kShellWindowId_Invalid)
- parent = parent->parent();
- return parent;
- }
- aura::Window* GetDefaultParentForWindow(aura::Window* window,
- const gfx::Rect& bounds_in_screen) {
- aura::Window* target_root = nullptr;
- aura::Window* transient_parent = ::wm::GetTransientParent(window);
- if (transient_parent) {
- // Transient window should use the same root as its transient parent.
- target_root = transient_parent->GetRootWindow();
- } else {
- target_root = FindContainerRoot(bounds_in_screen);
- }
- // For window restore, the window may be created before the associated window
- // restore data can be retrieved. In this case, we will place it in a hidden
- // container and will move it to a desk container when the window restore data
- // can be retrieved. An example would be ARC windows, which can be created
- // before their associated tasks are, which are required to retrieve window
- // restore data.
- if (window->GetProperty(app_restore::kParentToHiddenContainerKey))
- return target_root->GetChildById(kShellWindowId_UnparentedContainer);
- switch (window->GetType()) {
- case aura::client::WINDOW_TYPE_NORMAL:
- case aura::client::WINDOW_TYPE_POPUP:
- if (window->GetProperty(aura::client::kModalKey) == ui::MODAL_TYPE_SYSTEM)
- return GetSystemModalContainer(target_root, window);
- if (HasTransientParentWindow(window))
- return GetContainerForWindow(transient_parent);
- return GetContainerFromAlwaysOnTopController(target_root, window);
- case aura::client::WINDOW_TYPE_CONTROL:
- return target_root->GetChildById(kShellWindowId_UnparentedContainer);
- case aura::client::WINDOW_TYPE_MENU:
- return target_root->GetChildById(kShellWindowId_MenuContainer);
- case aura::client::WINDOW_TYPE_TOOLTIP:
- return target_root->GetChildById(
- kShellWindowId_DragImageAndTooltipContainer);
- default:
- NOTREACHED() << "Window " << window->GetId() << " has unhandled type "
- << window->GetType();
- break;
- }
- return nullptr;
- }
- aura::Window::Windows GetContainersForAllRootWindows(
- int container_id,
- aura::Window* priority_root) {
- aura::Window::Windows containers;
- for (aura::Window* root : Shell::GetAllRootWindows()) {
- aura::Window* container = root->GetChildById(container_id);
- if (!container)
- continue;
- if (priority_root && priority_root->Contains(container))
- containers.insert(containers.begin(), container);
- else
- containers.push_back(container);
- }
- return containers;
- }
- } // namespace ash
|