OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/system_modal_container_layout_manager.h" | 5 #include "ash/wm/system_modal_container_layout_manager.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "ash/public/cpp/config.h" | 9 #include "ash/public/cpp/config.h" |
10 #include "ash/public/cpp/shell_window_ids.h" | 10 #include "ash/public/cpp/shell_window_ids.h" |
11 #include "ash/session/session_controller.h" | 11 #include "ash/session/session_controller.h" |
12 #include "ash/shell.h" | 12 #include "ash/shell.h" |
13 #include "ash/shell_port.h" | 13 #include "ash/shell_port.h" |
14 #include "ash/wm/window_dimmer.h" | 14 #include "ash/wm/window_dimmer.h" |
15 #include "ash/wm/window_util.h" | 15 #include "ash/wm/window_util.h" |
16 #include "ash/wm_window.h" | |
17 #include "base/memory/ptr_util.h" | 16 #include "base/memory/ptr_util.h" |
18 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
19 #include "ui/aura/client/aura_constants.h" | 18 #include "ui/aura/client/aura_constants.h" |
20 #include "ui/aura/window.h" | 19 #include "ui/aura/window.h" |
21 #include "ui/keyboard/keyboard_controller.h" | 20 #include "ui/keyboard/keyboard_controller.h" |
| 21 #include "ui/wm/core/window_util.h" |
22 | 22 |
23 namespace ash { | 23 namespace ash { |
24 namespace { | 24 namespace { |
25 | 25 |
26 // The center point of the window can diverge this much from the center point | 26 // The center point of the window can diverge this much from the center point |
27 // of the container to be kept centered upon resizing operations. | 27 // of the container to be kept centered upon resizing operations. |
28 const int kCenterPixelDelta = 32; | 28 const int kCenterPixelDelta = 32; |
29 | 29 |
30 ui::ModalType GetModalType(WmWindow* window) { | 30 ui::ModalType GetModalType(aura::Window* window) { |
31 return static_cast<ui::ModalType>( | 31 return window->GetProperty(aura::client::kModalKey); |
32 window->aura_window()->GetProperty(aura::client::kModalKey)); | |
33 } | 32 } |
34 | 33 |
35 bool HasTransientAncestor(const WmWindow* window, const WmWindow* ancestor) { | 34 bool HasTransientAncestor(const aura::Window* window, |
36 const WmWindow* transient_parent = window->GetTransientParent(); | 35 const aura::Window* ancestor) { |
| 36 const aura::Window* transient_parent = ::wm::GetTransientParent(window); |
37 if (transient_parent == ancestor) | 37 if (transient_parent == ancestor) |
38 return true; | 38 return true; |
39 return transient_parent ? HasTransientAncestor(transient_parent, ancestor) | 39 return transient_parent ? HasTransientAncestor(transient_parent, ancestor) |
40 : false; | 40 : false; |
41 } | 41 } |
42 } | 42 } |
43 | 43 |
44 //////////////////////////////////////////////////////////////////////////////// | 44 //////////////////////////////////////////////////////////////////////////////// |
45 // SystemModalContainerLayoutManager, public: | 45 // SystemModalContainerLayoutManager, public: |
46 | 46 |
47 SystemModalContainerLayoutManager::SystemModalContainerLayoutManager( | 47 SystemModalContainerLayoutManager::SystemModalContainerLayoutManager( |
48 WmWindow* container) | 48 aura::Window* container) |
49 : container_(container) {} | 49 : container_(container) {} |
50 | 50 |
51 SystemModalContainerLayoutManager::~SystemModalContainerLayoutManager() { | 51 SystemModalContainerLayoutManager::~SystemModalContainerLayoutManager() { |
52 if (keyboard::KeyboardController::GetInstance()) | 52 if (keyboard::KeyboardController::GetInstance()) |
53 keyboard::KeyboardController::GetInstance()->RemoveObserver(this); | 53 keyboard::KeyboardController::GetInstance()->RemoveObserver(this); |
54 } | 54 } |
55 | 55 |
56 //////////////////////////////////////////////////////////////////////////////// | 56 //////////////////////////////////////////////////////////////////////////////// |
57 // SystemModalContainerLayoutManager, WmLayoutManager implementation: | 57 // SystemModalContainerLayoutManager, aura::LayoutManager implementation: |
58 | 58 |
59 void SystemModalContainerLayoutManager::OnChildWindowVisibilityChanged( | 59 void SystemModalContainerLayoutManager::OnChildWindowVisibilityChanged( |
60 WmWindow* window, | 60 aura::Window* window, |
61 bool visible) { | 61 bool visible) { |
62 if (GetModalType(window) != ui::MODAL_TYPE_SYSTEM) | 62 if (GetModalType(window) != ui::MODAL_TYPE_SYSTEM) |
63 return; | 63 return; |
64 | 64 |
65 if (window->IsVisible()) { | 65 if (window->IsVisible()) { |
66 DCHECK(!base::ContainsValue(modal_windows_, window)); | 66 DCHECK(!base::ContainsValue(modal_windows_, window)); |
67 AddModalWindow(window); | 67 AddModalWindow(window); |
68 } else { | 68 } else { |
69 if (RemoveModalWindow(window)) | 69 if (RemoveModalWindow(window)) |
70 ShellPort::Get()->OnModalWindowRemoved(window); | 70 ShellPort::Get()->OnModalWindowRemoved(window); |
71 } | 71 } |
72 } | 72 } |
73 | 73 |
74 void SystemModalContainerLayoutManager::OnWindowResized() { | 74 void SystemModalContainerLayoutManager::OnWindowResized() { |
75 PositionDialogsAfterWorkAreaResize(); | 75 PositionDialogsAfterWorkAreaResize(); |
76 } | 76 } |
77 | 77 |
78 void SystemModalContainerLayoutManager::OnWindowAddedToLayout(WmWindow* child) { | 78 void SystemModalContainerLayoutManager::OnWindowAddedToLayout( |
79 DCHECK(child->GetType() == ui::wm::WINDOW_TYPE_NORMAL || | 79 aura::Window* child) { |
80 child->GetType() == ui::wm::WINDOW_TYPE_POPUP); | 80 DCHECK(child->type() == ui::wm::WINDOW_TYPE_NORMAL || |
| 81 child->type() == ui::wm::WINDOW_TYPE_POPUP); |
81 // TODO(mash): IsUserSessionBlocked() depends on knowing the login state. We | 82 // TODO(mash): IsUserSessionBlocked() depends on knowing the login state. We |
82 // need a non-stub version of SessionStateDelegate. crbug.com/648964 | 83 // need a non-stub version of SessionStateDelegate. crbug.com/648964 |
83 if (Shell::GetAshConfig() != Config::MASH) { | 84 if (Shell::GetAshConfig() != Config::MASH) { |
84 DCHECK(container_->aura_window()->id() != | 85 DCHECK(container_->id() != kShellWindowId_LockSystemModalContainer || |
85 kShellWindowId_LockSystemModalContainer || | |
86 Shell::Get()->session_controller()->IsUserSessionBlocked()); | 86 Shell::Get()->session_controller()->IsUserSessionBlocked()); |
87 } | 87 } |
88 // Since this is for SystemModal, there is no good reason to add windows | 88 // Since this is for SystemModal, there is no good reason to add windows |
89 // other than MODAL_TYPE_NONE or MODAL_TYPE_SYSTEM. DCHECK to avoid simple | 89 // other than MODAL_TYPE_NONE or MODAL_TYPE_SYSTEM. DCHECK to avoid simple |
90 // mistake. | 90 // mistake. |
91 DCHECK_NE(GetModalType(child), ui::MODAL_TYPE_CHILD); | 91 DCHECK_NE(GetModalType(child), ui::MODAL_TYPE_CHILD); |
92 DCHECK_NE(GetModalType(child), ui::MODAL_TYPE_WINDOW); | 92 DCHECK_NE(GetModalType(child), ui::MODAL_TYPE_WINDOW); |
93 | 93 |
94 child->aura_window()->AddObserver(this); | 94 child->AddObserver(this); |
95 if (GetModalType(child) == ui::MODAL_TYPE_SYSTEM && child->IsVisible()) | 95 if (GetModalType(child) == ui::MODAL_TYPE_SYSTEM && child->IsVisible()) |
96 AddModalWindow(child); | 96 AddModalWindow(child); |
97 } | 97 } |
98 | 98 |
99 void SystemModalContainerLayoutManager::OnWillRemoveWindowFromLayout( | 99 void SystemModalContainerLayoutManager::OnWillRemoveWindowFromLayout( |
100 WmWindow* child) { | 100 aura::Window* child) { |
101 child->aura_window()->RemoveObserver(this); | 101 child->RemoveObserver(this); |
102 windows_to_center_.erase(child); | 102 windows_to_center_.erase(child); |
103 if (GetModalType(child) == ui::MODAL_TYPE_SYSTEM) | 103 if (GetModalType(child) == ui::MODAL_TYPE_SYSTEM) |
104 RemoveModalWindow(child); | 104 RemoveModalWindow(child); |
105 } | 105 } |
106 | 106 |
107 void SystemModalContainerLayoutManager::SetChildBounds( | 107 void SystemModalContainerLayoutManager::SetChildBounds( |
108 WmWindow* child, | 108 aura::Window* child, |
109 const gfx::Rect& requested_bounds) { | 109 const gfx::Rect& requested_bounds) { |
110 WmSnapToPixelLayoutManager::SetChildBounds(child, requested_bounds); | 110 WmSnapToPixelLayoutManager::SetChildBounds(child, requested_bounds); |
111 if (IsBoundsCentered(requested_bounds)) | 111 if (IsBoundsCentered(requested_bounds)) |
112 windows_to_center_.insert(child); | 112 windows_to_center_.insert(child); |
113 else | 113 else |
114 windows_to_center_.erase(child); | 114 windows_to_center_.erase(child); |
115 } | 115 } |
116 | 116 |
117 //////////////////////////////////////////////////////////////////////////////// | 117 //////////////////////////////////////////////////////////////////////////////// |
118 // SystemModalContainerLayoutManager, aura::WindowObserver implementation: | 118 // SystemModalContainerLayoutManager, aura::WindowObserver implementation: |
119 | 119 |
120 void SystemModalContainerLayoutManager::OnWindowPropertyChanged( | 120 void SystemModalContainerLayoutManager::OnWindowPropertyChanged( |
121 aura::Window* window, | 121 aura::Window* window, |
122 const void* key, | 122 const void* key, |
123 intptr_t old) { | 123 intptr_t old) { |
124 if (key != aura::client::kModalKey || !window->IsVisible()) | 124 if (key != aura::client::kModalKey || !window->IsVisible()) |
125 return; | 125 return; |
126 | 126 |
127 WmWindow* wm_window = WmWindow::Get(window); | |
128 if (window->GetProperty(aura::client::kModalKey) == ui::MODAL_TYPE_SYSTEM) { | 127 if (window->GetProperty(aura::client::kModalKey) == ui::MODAL_TYPE_SYSTEM) { |
129 if (base::ContainsValue(modal_windows_, wm_window)) | 128 if (base::ContainsValue(modal_windows_, window)) |
130 return; | 129 return; |
131 AddModalWindow(wm_window); | 130 AddModalWindow(window); |
132 } else { | 131 } else { |
133 if (RemoveModalWindow(wm_window)) | 132 if (RemoveModalWindow(window)) |
134 ShellPort::Get()->OnModalWindowRemoved(wm_window); | 133 ShellPort::Get()->OnModalWindowRemoved(window); |
135 } | 134 } |
136 } | 135 } |
137 | 136 |
138 //////////////////////////////////////////////////////////////////////////////// | 137 //////////////////////////////////////////////////////////////////////////////// |
139 // SystemModalContainerLayoutManager, Keyboard::KeybaordControllerObserver | 138 // SystemModalContainerLayoutManager, Keyboard::KeybaordControllerObserver |
140 // implementation: | 139 // implementation: |
141 | 140 |
142 void SystemModalContainerLayoutManager::OnKeyboardBoundsChanging( | 141 void SystemModalContainerLayoutManager::OnKeyboardBoundsChanging( |
143 const gfx::Rect& new_bounds) { | 142 const gfx::Rect& new_bounds) { |
144 PositionDialogsAfterWorkAreaResize(); | 143 PositionDialogsAfterWorkAreaResize(); |
145 } | 144 } |
146 | 145 |
147 void SystemModalContainerLayoutManager::OnKeyboardClosed() {} | 146 void SystemModalContainerLayoutManager::OnKeyboardClosed() {} |
148 | 147 |
149 bool SystemModalContainerLayoutManager::IsPartOfActiveModalWindow( | 148 bool SystemModalContainerLayoutManager::IsPartOfActiveModalWindow( |
150 WmWindow* window) { | 149 aura::Window* window) { |
151 return modal_window() && | 150 return modal_window() && |
152 (modal_window()->Contains(window) || | 151 (modal_window()->Contains(window) || |
153 HasTransientAncestor(window->GetToplevelWindowForFocus(), | 152 HasTransientAncestor(::wm::GetToplevelWindow(window), |
154 modal_window())); | 153 modal_window())); |
155 } | 154 } |
156 | 155 |
157 bool SystemModalContainerLayoutManager::ActivateNextModalWindow() { | 156 bool SystemModalContainerLayoutManager::ActivateNextModalWindow() { |
158 if (modal_windows_.empty()) | 157 if (modal_windows_.empty()) |
159 return false; | 158 return false; |
160 modal_window()->Activate(); | 159 wm::ActivateWindow(modal_window()); |
161 return true; | 160 return true; |
162 } | 161 } |
163 | 162 |
164 void SystemModalContainerLayoutManager::CreateModalBackground() { | 163 void SystemModalContainerLayoutManager::CreateModalBackground() { |
165 if (!window_dimmer_) { | 164 if (!window_dimmer_) { |
166 window_dimmer_ = base::MakeUnique<WindowDimmer>(container_->aura_window()); | 165 window_dimmer_ = base::MakeUnique<WindowDimmer>(container_); |
167 window_dimmer_->window()->SetName( | 166 window_dimmer_->window()->SetName( |
168 "SystemModalContainerLayoutManager.ModalBackground"); | 167 "SystemModalContainerLayoutManager.ModalBackground"); |
169 // There isn't always a keyboard controller. | 168 // There isn't always a keyboard controller. |
170 if (keyboard::KeyboardController::GetInstance()) | 169 if (keyboard::KeyboardController::GetInstance()) |
171 keyboard::KeyboardController::GetInstance()->AddObserver(this); | 170 keyboard::KeyboardController::GetInstance()->AddObserver(this); |
172 } | 171 } |
173 window_dimmer_->window()->Show(); | 172 window_dimmer_->window()->Show(); |
174 } | 173 } |
175 | 174 |
176 void SystemModalContainerLayoutManager::DestroyModalBackground() { | 175 void SystemModalContainerLayoutManager::DestroyModalBackground() { |
177 if (!window_dimmer_) | 176 if (!window_dimmer_) |
178 return; | 177 return; |
179 | 178 |
180 if (keyboard::KeyboardController::GetInstance()) | 179 if (keyboard::KeyboardController::GetInstance()) |
181 keyboard::KeyboardController::GetInstance()->RemoveObserver(this); | 180 keyboard::KeyboardController::GetInstance()->RemoveObserver(this); |
182 window_dimmer_.reset(); | 181 window_dimmer_.reset(); |
183 } | 182 } |
184 | 183 |
185 // static | 184 // static |
186 bool SystemModalContainerLayoutManager::IsModalBackground(WmWindow* window) { | 185 bool SystemModalContainerLayoutManager::IsModalBackground( |
187 int id = window->GetParent()->aura_window()->id(); | 186 aura::Window* window) { |
| 187 int id = window->parent()->id(); |
188 if (id != kShellWindowId_SystemModalContainer && | 188 if (id != kShellWindowId_SystemModalContainer && |
189 id != kShellWindowId_LockSystemModalContainer) | 189 id != kShellWindowId_LockSystemModalContainer) |
190 return false; | 190 return false; |
191 SystemModalContainerLayoutManager* layout_manager = | 191 SystemModalContainerLayoutManager* layout_manager = |
192 static_cast<SystemModalContainerLayoutManager*>( | 192 static_cast<SystemModalContainerLayoutManager*>( |
193 window->GetParent()->GetLayoutManager()); | 193 window->parent()->layout_manager()); |
194 return layout_manager->window_dimmer_ && | 194 return layout_manager->window_dimmer_ && |
195 WmWindow::Get(layout_manager->window_dimmer_->window()) == window; | 195 layout_manager->window_dimmer_->window() == window; |
196 } | 196 } |
197 | 197 |
198 //////////////////////////////////////////////////////////////////////////////// | 198 //////////////////////////////////////////////////////////////////////////////// |
199 // SystemModalContainerLayoutManager, private: | 199 // SystemModalContainerLayoutManager, private: |
200 | 200 |
201 void SystemModalContainerLayoutManager::AddModalWindow(WmWindow* window) { | 201 void SystemModalContainerLayoutManager::AddModalWindow(aura::Window* window) { |
202 if (modal_windows_.empty()) { | 202 if (modal_windows_.empty()) { |
203 WmWindow* capture_window = WmWindow::Get(wm::GetCaptureWindow()); | 203 aura::Window* capture_window = wm::GetCaptureWindow(); |
204 if (capture_window) | 204 if (capture_window) |
205 capture_window->ReleaseCapture(); | 205 capture_window->ReleaseCapture(); |
206 } | 206 } |
207 DCHECK(window->IsVisible()); | 207 DCHECK(window->IsVisible()); |
208 DCHECK(!base::ContainsValue(modal_windows_, window)); | 208 DCHECK(!base::ContainsValue(modal_windows_, window)); |
209 | 209 |
210 modal_windows_.push_back(window); | 210 modal_windows_.push_back(window); |
211 ShellPort::Get()->CreateModalBackground(window); | 211 ShellPort::Get()->CreateModalBackground(window); |
212 window->GetParent()->StackChildAtTop(window); | 212 window->parent()->StackChildAtTop(window); |
213 | 213 |
214 gfx::Rect target_bounds = window->GetBounds(); | 214 gfx::Rect target_bounds = window->bounds(); |
215 target_bounds.AdjustToFit(GetUsableDialogArea()); | 215 target_bounds.AdjustToFit(GetUsableDialogArea()); |
216 window->SetBounds(target_bounds); | 216 window->SetBounds(target_bounds); |
217 } | 217 } |
218 | 218 |
219 bool SystemModalContainerLayoutManager::RemoveModalWindow(WmWindow* window) { | 219 bool SystemModalContainerLayoutManager::RemoveModalWindow( |
| 220 aura::Window* window) { |
220 auto it = std::find(modal_windows_.begin(), modal_windows_.end(), window); | 221 auto it = std::find(modal_windows_.begin(), modal_windows_.end(), window); |
221 if (it == modal_windows_.end()) | 222 if (it == modal_windows_.end()) |
222 return false; | 223 return false; |
223 modal_windows_.erase(it); | 224 modal_windows_.erase(it); |
224 return true; | 225 return true; |
225 } | 226 } |
226 | 227 |
227 void SystemModalContainerLayoutManager::PositionDialogsAfterWorkAreaResize() { | 228 void SystemModalContainerLayoutManager::PositionDialogsAfterWorkAreaResize() { |
228 if (modal_windows_.empty()) | 229 if (modal_windows_.empty()) |
229 return; | 230 return; |
230 | 231 |
231 for (WmWindow* window : modal_windows_) | 232 for (aura::Window* window : modal_windows_) |
232 window->SetBounds(GetCenteredAndOrFittedBounds(window)); | 233 window->SetBounds(GetCenteredAndOrFittedBounds(window)); |
233 } | 234 } |
234 | 235 |
235 gfx::Rect SystemModalContainerLayoutManager::GetUsableDialogArea() const { | 236 gfx::Rect SystemModalContainerLayoutManager::GetUsableDialogArea() const { |
236 // Instead of resizing the system modal container, we move only the modal | 237 // Instead of resizing the system modal container, we move only the modal |
237 // windows. This way we avoid flashing lines upon resize animation and if the | 238 // windows. This way we avoid flashing lines upon resize animation and if the |
238 // keyboard will not fill left to right, the background is still covered. | 239 // keyboard will not fill left to right, the background is still covered. |
239 gfx::Rect valid_bounds = container_->GetBounds(); | 240 gfx::Rect valid_bounds = container_->bounds(); |
240 keyboard::KeyboardController* keyboard_controller = | 241 keyboard::KeyboardController* keyboard_controller = |
241 keyboard::KeyboardController::GetInstance(); | 242 keyboard::KeyboardController::GetInstance(); |
242 if (keyboard_controller) { | 243 if (keyboard_controller) { |
243 gfx::Rect bounds = keyboard_controller->current_keyboard_bounds(); | 244 gfx::Rect bounds = keyboard_controller->current_keyboard_bounds(); |
244 if (!bounds.IsEmpty()) { | 245 if (!bounds.IsEmpty()) { |
245 valid_bounds.set_height( | 246 valid_bounds.set_height( |
246 std::max(0, valid_bounds.height() - bounds.height())); | 247 std::max(0, valid_bounds.height() - bounds.height())); |
247 } | 248 } |
248 } | 249 } |
249 return valid_bounds; | 250 return valid_bounds; |
250 } | 251 } |
251 | 252 |
252 gfx::Rect SystemModalContainerLayoutManager::GetCenteredAndOrFittedBounds( | 253 gfx::Rect SystemModalContainerLayoutManager::GetCenteredAndOrFittedBounds( |
253 const WmWindow* window) { | 254 const aura::Window* window) { |
254 gfx::Rect target_bounds; | 255 gfx::Rect target_bounds; |
255 gfx::Rect usable_area = GetUsableDialogArea(); | 256 gfx::Rect usable_area = GetUsableDialogArea(); |
256 if (windows_to_center_.count(window) > 0) { | 257 if (windows_to_center_.count(window) > 0) { |
257 // Keep the dialog centered if it was centered before. | 258 // Keep the dialog centered if it was centered before. |
258 target_bounds = usable_area; | 259 target_bounds = usable_area; |
259 target_bounds.ClampToCenteredSize(window->GetBounds().size()); | 260 target_bounds.ClampToCenteredSize(window->bounds().size()); |
260 } else { | 261 } else { |
261 // Keep the dialog within the usable area. | 262 // Keep the dialog within the usable area. |
262 target_bounds = window->GetBounds(); | 263 target_bounds = window->bounds(); |
263 target_bounds.AdjustToFit(usable_area); | 264 target_bounds.AdjustToFit(usable_area); |
264 } | 265 } |
265 if (usable_area != container_->GetBounds()) { | 266 if (usable_area != container_->bounds()) { |
266 // Don't clamp the dialog for the keyboard. Keep the size as it is but make | 267 // Don't clamp the dialog for the keyboard. Keep the size as it is but make |
267 // sure that the top remains visible. | 268 // sure that the top remains visible. |
268 // TODO(skuhne): M37 should add over scroll functionality to address this. | 269 // TODO(skuhne): M37 should add over scroll functionality to address this. |
269 target_bounds.set_size(window->GetBounds().size()); | 270 target_bounds.set_size(window->bounds().size()); |
270 } | 271 } |
271 return target_bounds; | 272 return target_bounds; |
272 } | 273 } |
273 | 274 |
274 bool SystemModalContainerLayoutManager::IsBoundsCentered( | 275 bool SystemModalContainerLayoutManager::IsBoundsCentered( |
275 const gfx::Rect& bounds) const { | 276 const gfx::Rect& bounds) const { |
276 gfx::Point window_center = bounds.CenterPoint(); | 277 gfx::Point window_center = bounds.CenterPoint(); |
277 gfx::Point container_center = GetUsableDialogArea().CenterPoint(); | 278 gfx::Point container_center = GetUsableDialogArea().CenterPoint(); |
278 return std::abs(window_center.x() - container_center.x()) < | 279 return std::abs(window_center.x() - container_center.x()) < |
279 kCenterPixelDelta && | 280 kCenterPixelDelta && |
280 std::abs(window_center.y() - container_center.y()) < kCenterPixelDelta; | 281 std::abs(window_center.y() - container_center.y()) < kCenterPixelDelta; |
281 } | 282 } |
282 | 283 |
283 } // namespace ash | 284 } // namespace ash |
OLD | NEW |