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

Side by Side Diff: ash/common/wm/system_modal_container_layout_manager.cc

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

Powered by Google App Engine
This is Rietveld 408576698