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/common/wm/workspace/workspace_layout_manager.h" | 5 #include "ash/common/wm/workspace/workspace_layout_manager.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "ash/common/session/session_state_delegate.h" | 9 #include "ash/common/session/session_state_delegate.h" |
10 #include "ash/common/wm/always_on_top_controller.h" | 10 #include "ash/common/wm/always_on_top_controller.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 WorkspaceLayoutManager::WorkspaceLayoutManager( | 27 WorkspaceLayoutManager::WorkspaceLayoutManager( |
28 WmWindow* window, | 28 WmWindow* window, |
29 std::unique_ptr<wm::WorkspaceLayoutManagerDelegate> delegate) | 29 std::unique_ptr<wm::WorkspaceLayoutManagerDelegate> delegate) |
30 : window_(window), | 30 : window_(window), |
31 root_window_(window->GetRootWindow()), | 31 root_window_(window->GetRootWindow()), |
32 root_window_controller_(root_window_->GetRootWindowController()), | 32 root_window_controller_(root_window_->GetRootWindowController()), |
33 shell_(window_->GetShell()), | 33 shell_(window_->GetShell()), |
34 delegate_(std::move(delegate)), | 34 delegate_(std::move(delegate)), |
35 work_area_in_parent_(wm::GetDisplayWorkAreaBounds(window_)), | 35 work_area_in_parent_(wm::GetDisplayWorkAreaBounds(window_)), |
36 is_fullscreen_(wm::GetWindowForFullscreenMode(window) != nullptr) { | 36 is_fullscreen_(wm::GetWindowForFullscreenMode(window) != nullptr) { |
| 37 shell_->AddShellObserver(this); |
37 shell_->AddActivationObserver(this); | 38 shell_->AddActivationObserver(this); |
38 root_window_->AddObserver(this); | 39 root_window_->AddObserver(this); |
39 root_window_controller_->AddObserver(this); | 40 root_window_controller_->AddObserver(this); |
40 DCHECK(window->GetBoolProperty( | 41 DCHECK(window->GetBoolProperty( |
41 WmWindowProperty::SNAP_CHILDREN_TO_PIXEL_BOUNDARY)); | 42 WmWindowProperty::SNAP_CHILDREN_TO_PIXEL_BOUNDARY)); |
42 } | 43 } |
43 | 44 |
44 WorkspaceLayoutManager::~WorkspaceLayoutManager() { | 45 WorkspaceLayoutManager::~WorkspaceLayoutManager() { |
45 if (root_window_) | 46 if (root_window_) |
46 root_window_->RemoveObserver(this); | 47 root_window_->RemoveObserver(this); |
47 for (WmWindow* window : windows_) | 48 for (WmWindow* window : windows_) { |
| 49 wm::WindowState* window_state = window->GetWindowState(); |
| 50 window_state->RemoveObserver(this); |
48 window->RemoveObserver(this); | 51 window->RemoveObserver(this); |
| 52 } |
49 root_window_->GetRootWindowController()->RemoveObserver(this); | 53 root_window_->GetRootWindowController()->RemoveObserver(this); |
50 shell_->RemoveActivationObserver(this); | 54 shell_->RemoveActivationObserver(this); |
| 55 shell_->RemoveShellObserver(this); |
51 } | 56 } |
52 | 57 |
53 void WorkspaceLayoutManager::DeleteDelegate() { | 58 void WorkspaceLayoutManager::DeleteDelegate() { |
54 delegate_.reset(); | 59 delegate_.reset(); |
55 } | 60 } |
56 | 61 |
57 void WorkspaceLayoutManager::SetMaximizeBackdropDelegate( | 62 void WorkspaceLayoutManager::SetMaximizeBackdropDelegate( |
58 std::unique_ptr<WorkspaceLayoutManagerBackdropDelegate> delegate) { | 63 std::unique_ptr<WorkspaceLayoutManagerBackdropDelegate> delegate) { |
59 backdrop_delegate_.reset(delegate.release()); | 64 backdrop_delegate_.reset(delegate.release()); |
60 } | 65 } |
61 | 66 |
62 ////////////////////////////////////////////////////////////////////////////// | 67 ////////////////////////////////////////////////////////////////////////////// |
63 // WorkspaceLayoutManager, aura::LayoutManager implementation: | 68 // WorkspaceLayoutManager, aura::LayoutManager implementation: |
64 | 69 |
65 void WorkspaceLayoutManager::OnWindowResized() {} | 70 void WorkspaceLayoutManager::OnWindowResized() {} |
66 | 71 |
67 void WorkspaceLayoutManager::OnWindowAddedToLayout(WmWindow* child) { | 72 void WorkspaceLayoutManager::OnWindowAddedToLayout(WmWindow* child) { |
68 wm::WindowState* window_state = child->GetWindowState(); | 73 wm::WindowState* window_state = child->GetWindowState(); |
69 wm::WMEvent event(wm::WM_EVENT_ADDED_TO_WORKSPACE); | 74 wm::WMEvent event(wm::WM_EVENT_ADDED_TO_WORKSPACE); |
70 window_state->OnWMEvent(&event); | 75 window_state->OnWMEvent(&event); |
71 windows_.insert(child); | 76 windows_.insert(child); |
72 child->AddObserver(this); | 77 child->AddObserver(this); |
73 window_state->AddObserver(this); | 78 window_state->AddObserver(this); |
74 UpdateShelfVisibility(); | 79 UpdateShelfVisibility(); |
75 UpdateFullscreenState(); | 80 UpdateFullscreenState(); |
76 if (backdrop_delegate_) | 81 if (backdrop_delegate_) |
77 backdrop_delegate_->OnWindowAddedToLayout(child); | 82 backdrop_delegate_->OnWindowAddedToLayout(child); |
78 WindowPositioner::RearrangeVisibleWindowOnShow(child); | 83 WindowPositioner::RearrangeVisibleWindowOnShow(child); |
| 84 if (WmShell::Get()->IsPinned()) |
| 85 child->GetWindowState()->DisableAlwaysOnTop(nullptr); |
79 } | 86 } |
80 | 87 |
81 void WorkspaceLayoutManager::OnWillRemoveWindowFromLayout(WmWindow* child) { | 88 void WorkspaceLayoutManager::OnWillRemoveWindowFromLayout(WmWindow* child) { |
82 windows_.erase(child); | 89 windows_.erase(child); |
83 child->RemoveObserver(this); | 90 child->RemoveObserver(this); |
84 child->GetWindowState()->RemoveObserver(this); | 91 child->GetWindowState()->RemoveObserver(this); |
85 | 92 |
86 if (child->GetTargetVisibility()) | 93 if (child->GetTargetVisibility()) |
87 WindowPositioner::RearrangeVisibleWindowOnHideOrRemove(child); | 94 WindowPositioner::RearrangeVisibleWindowOnHideOrRemove(child); |
88 } | 95 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 } | 174 } |
168 if (backdrop_delegate_) | 175 if (backdrop_delegate_) |
169 backdrop_delegate_->OnDisplayWorkAreaInsetsChanged(); | 176 backdrop_delegate_->OnDisplayWorkAreaInsetsChanged(); |
170 } | 177 } |
171 | 178 |
172 void WorkspaceLayoutManager::OnFullscreenStateChanged(bool is_fullscreen) { | 179 void WorkspaceLayoutManager::OnFullscreenStateChanged(bool is_fullscreen) { |
173 if (is_fullscreen_ == is_fullscreen) | 180 if (is_fullscreen_ == is_fullscreen) |
174 return; | 181 return; |
175 | 182 |
176 is_fullscreen_ = is_fullscreen; | 183 is_fullscreen_ = is_fullscreen; |
177 WmWindow* fullscreen_window = | 184 if (WmShell::Get()->IsPinned()) { |
178 is_fullscreen ? wm::GetWindowForFullscreenMode(window_) : nullptr; | 185 // If this is in pinned mode, then this event does not trigger the |
179 // Changing always on top state may change window's parent. Iterate on a copy | 186 // always-on-top state change, because it is kept disabled regardless of |
180 // of |windows_| to avoid invalidating an iterator. Since both workspace and | 187 // the fullscreen state change. |
181 // always_on_top containers' layouts are managed by this class all the | 188 return; |
182 // appropriate windows will be included in the iteration. | |
183 WindowSet windows(windows_); | |
184 for (auto window : windows) { | |
185 wm::WindowState* window_state = window->GetWindowState(); | |
186 if (is_fullscreen) | |
187 window_state->DisableAlwaysOnTop(fullscreen_window); | |
188 else | |
189 window_state->RestoreAlwaysOnTop(); | |
190 } | 189 } |
| 190 |
| 191 UpdateAlwaysOnTop(is_fullscreen_ ? wm::GetWindowForFullscreenMode(window_) |
| 192 : nullptr); |
191 } | 193 } |
192 | 194 |
193 ////////////////////////////////////////////////////////////////////////////// | 195 ////////////////////////////////////////////////////////////////////////////// |
194 // WorkspaceLayoutManager, aura::WindowObserver implementation: | 196 // WorkspaceLayoutManager, aura::WindowObserver implementation: |
195 | 197 |
196 void WorkspaceLayoutManager::OnWindowTreeChanged( | 198 void WorkspaceLayoutManager::OnWindowTreeChanged( |
197 WmWindow* window, | 199 WmWindow* window, |
198 const WmWindowObserver::TreeChangeParams& params) { | 200 const WmWindowObserver::TreeChangeParams& params) { |
199 if (!params.target->GetWindowState()->IsActive()) | 201 if (!params.target->GetWindowState()->IsActive()) |
200 return; | 202 return; |
(...skipping 11 matching lines...) Expand all Loading... |
212 UpdateFullscreenState(); | 214 UpdateFullscreenState(); |
213 UpdateShelfVisibility(); | 215 UpdateShelfVisibility(); |
214 } | 216 } |
215 } | 217 } |
216 | 218 |
217 void WorkspaceLayoutManager::OnWindowPropertyChanged( | 219 void WorkspaceLayoutManager::OnWindowPropertyChanged( |
218 WmWindow* window, | 220 WmWindow* window, |
219 WmWindowProperty property) { | 221 WmWindowProperty property) { |
220 if (property == WmWindowProperty::ALWAYS_ON_TOP && | 222 if (property == WmWindowProperty::ALWAYS_ON_TOP && |
221 window->GetBoolProperty(WmWindowProperty::ALWAYS_ON_TOP)) { | 223 window->GetBoolProperty(WmWindowProperty::ALWAYS_ON_TOP)) { |
222 root_window_controller_->GetAlwaysOnTopController() | 224 WmWindow* container = |
223 ->GetContainer(window) | 225 root_window_controller_->GetAlwaysOnTopController()->GetContainer( |
224 ->AddChild(window); | 226 window); |
| 227 if (window->GetParent() != container) |
| 228 container->AddChild(window); |
225 } | 229 } |
226 } | 230 } |
227 | 231 |
228 void WorkspaceLayoutManager::OnWindowStackingChanged(WmWindow* window) { | 232 void WorkspaceLayoutManager::OnWindowStackingChanged(WmWindow* window) { |
229 UpdateShelfVisibility(); | 233 UpdateShelfVisibility(); |
230 UpdateFullscreenState(); | 234 UpdateFullscreenState(); |
231 if (backdrop_delegate_) | 235 if (backdrop_delegate_) |
232 backdrop_delegate_->OnWindowStackingChanged(window); | 236 backdrop_delegate_->OnWindowStackingChanged(window); |
233 } | 237 } |
234 | 238 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 old_type == wm::WINDOW_STATE_TYPE_FULLSCREEN) { | 281 old_type == wm::WINDOW_STATE_TYPE_FULLSCREEN) { |
278 UpdateFullscreenState(); | 282 UpdateFullscreenState(); |
279 } | 283 } |
280 | 284 |
281 UpdateShelfVisibility(); | 285 UpdateShelfVisibility(); |
282 if (backdrop_delegate_) | 286 if (backdrop_delegate_) |
283 backdrop_delegate_->OnPostWindowStateTypeChange(window_state, old_type); | 287 backdrop_delegate_->OnPostWindowStateTypeChange(window_state, old_type); |
284 } | 288 } |
285 | 289 |
286 ////////////////////////////////////////////////////////////////////////////// | 290 ////////////////////////////////////////////////////////////////////////////// |
| 291 // WorkspaceLayoutManager, ShellObserver implementation: |
| 292 |
| 293 void WorkspaceLayoutManager::OnPinnedStateChanged(WmWindow* pinned_window) { |
| 294 if (!WmShell::Get()->IsPinned() && is_fullscreen_) { |
| 295 // On exiting from pinned mode, if the workspace is still in fullscreen |
| 296 // mode, then this event does not trigger the restoring yet. On exiting |
| 297 // from fullscreen, the temporarily disabled always-on-top property will be |
| 298 // restored. |
| 299 return; |
| 300 } |
| 301 |
| 302 UpdateAlwaysOnTop(WmShell::Get()->IsPinned() ? pinned_window : nullptr); |
| 303 } |
| 304 |
| 305 ////////////////////////////////////////////////////////////////////////////// |
287 // WorkspaceLayoutManager, private: | 306 // WorkspaceLayoutManager, private: |
288 | 307 |
289 void WorkspaceLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange( | 308 void WorkspaceLayoutManager::AdjustAllWindowsBoundsForWorkAreaChange( |
290 const wm::WMEvent* event) { | 309 const wm::WMEvent* event) { |
291 DCHECK(event->type() == wm::WM_EVENT_DISPLAY_BOUNDS_CHANGED || | 310 DCHECK(event->type() == wm::WM_EVENT_DISPLAY_BOUNDS_CHANGED || |
292 event->type() == wm::WM_EVENT_WORKAREA_BOUNDS_CHANGED); | 311 event->type() == wm::WM_EVENT_WORKAREA_BOUNDS_CHANGED); |
293 | 312 |
294 work_area_in_parent_ = wm::GetDisplayWorkAreaBounds(window_); | 313 work_area_in_parent_ = wm::GetDisplayWorkAreaBounds(window_); |
295 | 314 |
296 // Don't do any adjustments of the insets while we are in screen locked mode. | 315 // Don't do any adjustments of the insets while we are in screen locked mode. |
(...skipping 25 matching lines...) Expand all Loading... |
322 // technically any container could get a fullscreen window. | 341 // technically any container could get a fullscreen window. |
323 if (!delegate_) | 342 if (!delegate_) |
324 return; | 343 return; |
325 bool is_fullscreen = wm::GetWindowForFullscreenMode(window_) != nullptr; | 344 bool is_fullscreen = wm::GetWindowForFullscreenMode(window_) != nullptr; |
326 if (is_fullscreen != is_fullscreen_) { | 345 if (is_fullscreen != is_fullscreen_) { |
327 delegate_->OnFullscreenStateChanged(is_fullscreen); | 346 delegate_->OnFullscreenStateChanged(is_fullscreen); |
328 is_fullscreen_ = is_fullscreen; | 347 is_fullscreen_ = is_fullscreen; |
329 } | 348 } |
330 } | 349 } |
331 | 350 |
| 351 void WorkspaceLayoutManager::UpdateAlwaysOnTop(WmWindow* window_on_top) { |
| 352 // Changing always on top state may change window's parent. Iterate on a copy |
| 353 // of |windows_| to avoid invalidating an iterator. Since both workspace and |
| 354 // always_on_top containers' layouts are managed by this class all the |
| 355 // appropriate windows will be included in the iteration. |
| 356 WindowSet windows(windows_); |
| 357 for (auto window : windows) { |
| 358 wm::WindowState* window_state = window->GetWindowState(); |
| 359 if (window_on_top) |
| 360 window_state->DisableAlwaysOnTop(window_on_top); |
| 361 else |
| 362 window_state->RestoreAlwaysOnTop(); |
| 363 } |
| 364 } |
| 365 |
332 } // namespace ash | 366 } // namespace ash |
OLD | NEW |