forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontainer_finder.cc
144 lines (125 loc) · 5.57 KB
/
container_finder.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// 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/full_restore/full_restore_utils.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 full restore, the window may be created before the associated full
// 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 full 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 full
// restore data.
if (window->GetProperty(full_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