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

Side by Side Diff: ash/common/wm_root_window_controller.cc

Issue 2628973002: Moves definitions of RootWindowController into root_window_controller.cc (Closed)
Patch Set: merged to trunk Created 3 years, 11 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
« no previous file with comments | « ash/BUILD.gn ('k') | ash/root_window_controller.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/root_window_controller.h"
6
7 #include "ash/aura/wm_window_aura.h"
8 #include "ash/common/session/session_state_delegate.h"
9 #include "ash/common/shelf/shelf_layout_manager.h"
10 #include "ash/common/shelf/shelf_widget.h"
11 #include "ash/common/shelf/wm_shelf.h"
12 #include "ash/common/shell_delegate.h"
13 #include "ash/common/system/status_area_widget.h"
14 #include "ash/common/wallpaper/wallpaper_delegate.h"
15 #include "ash/common/wallpaper/wallpaper_widget_controller.h"
16 #include "ash/common/wm/always_on_top_controller.h"
17 #include "ash/common/wm/container_finder.h"
18 #include "ash/common/wm/dock/docked_window_layout_manager.h"
19 #include "ash/common/wm/lock_layout_manager.h"
20 #include "ash/common/wm/panels/panel_layout_manager.h"
21 #include "ash/common/wm/root_window_layout_manager.h"
22 #include "ash/common/wm/system_modal_container_layout_manager.h"
23 #include "ash/common/wm/window_state.h"
24 #include "ash/common/wm/wm_snap_to_pixel_layout_manager.h"
25 #include "ash/common/wm/workspace/workspace_layout_manager.h"
26 #include "ash/common/wm/workspace_controller.h"
27 #include "ash/common/wm_shell.h"
28 #include "ash/common/wm_window.h"
29 #include "ash/public/cpp/shell_window_ids.h"
30 #include "ash/root_window_controller.h"
31 #include "ash/shell.h"
32 #include "base/memory/ptr_util.h"
33 #include "ui/aura/env.h"
34 #include "ui/aura/mus/window_mus.h"
35 #include "ui/aura/mus/window_tree_client.h"
36 #include "ui/aura/window.h"
37 #include "ui/aura/window_event_dispatcher.h"
38 #include "ui/aura/window_tree_host.h"
39 #include "ui/base/models/menu_model.h"
40 #include "ui/events/event_targeter.h"
41 #include "ui/events/event_utils.h"
42 #include "ui/views/controls/menu/menu_model_adapter.h"
43 #include "ui/views/controls/menu/menu_runner.h"
44 #include "ui/wm/core/coordinate_conversion.h"
45
46 // TODO(sky): this file is temporary and here to make review easier. The
47 // contents of this file will be folded into root_window_controller.cc shortly.
48 namespace ash {
49 namespace {
50
51 // Scales |value| that is originally between 0 and |src_max| to be between
52 // 0 and |dst_max|.
53 float ToRelativeValue(int value, int src_max, int dst_max) {
54 return static_cast<float>(value) / static_cast<float>(src_max) * dst_max;
55 }
56
57 // Uses ToRelativeValue() to scale the origin of |bounds_in_out|. The
58 // width/height are not changed.
59 void MoveOriginRelativeToSize(const gfx::Size& src_size,
60 const gfx::Size& dst_size,
61 gfx::Rect* bounds_in_out) {
62 gfx::Point origin = bounds_in_out->origin();
63 bounds_in_out->set_origin(gfx::Point(
64 ToRelativeValue(origin.x(), src_size.width(), dst_size.width()),
65 ToRelativeValue(origin.y(), src_size.height(), dst_size.height())));
66 }
67
68 // Reparents |window| to |new_parent|.
69 // TODO(sky): This should take an aura::Window. http://crbug.com/671246.
70 void ReparentWindow(WmWindow* window, WmWindow* new_parent) {
71 const gfx::Size src_size = window->GetParent()->GetBounds().size();
72 const gfx::Size dst_size = new_parent->GetBounds().size();
73 // Update the restore bounds to make it relative to the display.
74 wm::WindowState* state = window->GetWindowState();
75 gfx::Rect restore_bounds;
76 bool has_restore_bounds = state->HasRestoreBounds();
77
78 bool update_bounds =
79 (state->IsNormalOrSnapped() || state->IsMinimized()) &&
80 new_parent->GetShellWindowId() != kShellWindowId_DockedContainer;
81 gfx::Rect local_bounds;
82 if (update_bounds) {
83 local_bounds = state->window()->GetBounds();
84 MoveOriginRelativeToSize(src_size, dst_size, &local_bounds);
85 }
86
87 if (has_restore_bounds) {
88 restore_bounds = state->GetRestoreBoundsInParent();
89 MoveOriginRelativeToSize(src_size, dst_size, &restore_bounds);
90 }
91
92 new_parent->AddChild(window);
93
94 // Docked windows have bounds handled by the layout manager in AddChild().
95 if (update_bounds)
96 window->SetBounds(local_bounds);
97
98 if (has_restore_bounds)
99 state->SetRestoreBoundsInParent(restore_bounds);
100 }
101
102 // Reparents the appropriate set of windows from |src| to |dst|.
103 // TODO(sky): This should take an aura::Window. http://crbug.com/671246.
104 void ReparentAllWindows(WmWindow* src, WmWindow* dst) {
105 // Set of windows to move.
106 const int kContainerIdsToMove[] = {
107 kShellWindowId_DefaultContainer,
108 kShellWindowId_DockedContainer,
109 kShellWindowId_PanelContainer,
110 kShellWindowId_AlwaysOnTopContainer,
111 kShellWindowId_SystemModalContainer,
112 kShellWindowId_LockSystemModalContainer,
113 kShellWindowId_UnparentedControlContainer,
114 kShellWindowId_OverlayContainer,
115 };
116 const int kExtraContainerIdsToMoveInUnifiedMode[] = {
117 kShellWindowId_LockScreenContainer,
118 kShellWindowId_LockScreenWallpaperContainer,
119 };
120 std::vector<int> container_ids(
121 kContainerIdsToMove,
122 kContainerIdsToMove + arraysize(kContainerIdsToMove));
123 // Check the display mode as this is also necessary when trasitioning between
124 // mirror and unified mode.
125 if (WmShell::Get()->IsInUnifiedModeIgnoreMirroring()) {
126 for (int id : kExtraContainerIdsToMoveInUnifiedMode)
127 container_ids.push_back(id);
128 }
129
130 for (int id : container_ids) {
131 WmWindow* src_container = src->GetChildByShellWindowId(id);
132 WmWindow* dst_container = dst->GetChildByShellWindowId(id);
133 while (!src_container->GetChildren().empty()) {
134 // Restart iteration from the source container windows each time as they
135 // may change as a result of moving other windows.
136 WmWindow::Windows src_container_children = src_container->GetChildren();
137 WmWindow::Windows::const_iterator iter = src_container_children.begin();
138 while (iter != src_container_children.end() &&
139 SystemModalContainerLayoutManager::IsModalBackground(*iter)) {
140 ++iter;
141 }
142 // If the entire window list is modal background windows then stop.
143 if (iter == src_container_children.end())
144 break;
145 ReparentWindow(*iter, dst_container);
146 }
147 }
148 }
149
150 // Creates a new window for use as a container.
151 // TODO(sky): This should create an aura::Window. http://crbug.com/671246.
152 WmWindow* CreateContainer(int window_id, const char* name, WmWindow* parent) {
153 WmWindow* window = WmShell::Get()->NewWindow(ui::wm::WINDOW_TYPE_UNKNOWN,
154 ui::LAYER_NOT_DRAWN);
155 window->SetShellWindowId(window_id);
156 window->SetName(name);
157 parent->AddChild(window);
158 if (window_id != kShellWindowId_UnparentedControlContainer)
159 window->Show();
160 return window;
161 }
162
163 // TODO(sky): This should take an aura::Window. http://crbug.com/671246.
164 bool ShouldDestroyWindowInCloseChildWindows(WmWindow* window) {
165 if (!WmWindowAura::GetAuraWindow(window)->owned_by_parent())
166 return false;
167
168 if (!WmShell::Get()->IsRunningInMash())
169 return true;
170
171 aura::WindowMus* window_mus =
172 aura::WindowMus::Get(WmWindowAura::GetAuraWindow(window));
173 return Shell::window_tree_client()->WasCreatedByThisClient(window_mus) ||
174 Shell::window_tree_client()->IsRoot(window_mus);
175 }
176
177 } // namespace
178
179 void RootWindowController::SetWallpaperWidgetController(
180 WallpaperWidgetController* controller) {
181 wallpaper_widget_controller_.reset(controller);
182 }
183
184 void RootWindowController::SetAnimatingWallpaperWidgetController(
185 AnimatingWallpaperWidgetController* controller) {
186 if (animating_wallpaper_widget_controller_.get())
187 animating_wallpaper_widget_controller_->StopAnimating();
188 animating_wallpaper_widget_controller_.reset(controller);
189 }
190
191 wm::WorkspaceWindowState RootWindowController::GetWorkspaceWindowState() {
192 return workspace_controller_ ? workspace_controller()->GetWindowState()
193 : wm::WORKSPACE_WINDOW_STATE_DEFAULT;
194 }
195
196 SystemModalContainerLayoutManager*
197 RootWindowController::GetSystemModalLayoutManager(WmWindow* window) {
198 WmWindow* modal_container = nullptr;
199 if (window) {
200 WmWindow* window_container = wm::GetContainerForWindow(window);
201 if (window_container &&
202 window_container->GetShellWindowId() >=
203 kShellWindowId_LockScreenContainer) {
204 modal_container = GetWmContainer(kShellWindowId_LockSystemModalContainer);
205 } else {
206 modal_container = GetWmContainer(kShellWindowId_SystemModalContainer);
207 }
208 } else {
209 int modal_window_id =
210 WmShell::Get()->GetSessionStateDelegate()->IsUserSessionBlocked()
211 ? kShellWindowId_LockSystemModalContainer
212 : kShellWindowId_SystemModalContainer;
213 modal_container = GetWmContainer(modal_window_id);
214 }
215 return modal_container ? static_cast<SystemModalContainerLayoutManager*>(
216 modal_container->GetLayoutManager())
217 : nullptr;
218 }
219
220 bool RootWindowController::HasShelf() {
221 return wm_shelf_->shelf_widget() != nullptr;
222 }
223
224 WmShelf* RootWindowController::GetShelf() {
225 return wm_shelf_.get();
226 }
227
228 void RootWindowController::CreateShelf() {
229 if (wm_shelf_->IsShelfInitialized())
230 return;
231 wm_shelf_->InitializeShelf();
232
233 if (panel_layout_manager_)
234 panel_layout_manager_->SetShelf(wm_shelf_.get());
235 if (docked_window_layout_manager_) {
236 docked_window_layout_manager_->SetShelf(wm_shelf_.get());
237 if (wm_shelf_->shelf_layout_manager())
238 docked_window_layout_manager_->AddObserver(
239 wm_shelf_->shelf_layout_manager());
240 }
241
242 // Notify shell observers that the shelf has been created.
243 // TODO(jamescook): Move this into WmShelf::InitializeShelf(). This will
244 // require changing AttachedPanelWidgetTargeter's access to WmShelf.
245 WmShell::Get()->NotifyShelfCreatedForRootWindow(
246 WmWindowAura::Get(GetRootWindow()));
247
248 wm_shelf_->shelf_widget()->PostCreateShelf();
249 }
250
251 void RootWindowController::ShowShelf() {
252 if (!wm_shelf_->IsShelfInitialized())
253 return;
254 // TODO(jamescook): Move this into WmShelf.
255 wm_shelf_->shelf_widget()->SetShelfVisibility(true);
256 wm_shelf_->shelf_widget()->status_area_widget()->Show();
257 }
258
259 const WmWindow* RootWindowController::GetWindow() const {
260 return WmWindowAura::Get(GetRootWindow());
261 }
262
263 const WmWindow* RootWindowController::GetWmContainer(int container_id) const {
264 const aura::Window* window = GetContainer(container_id);
265 return WmWindowAura::Get(window);
266 }
267
268 void RootWindowController::ConfigureWidgetInitParamsForContainer(
269 views::Widget* widget,
270 int shell_container_id,
271 views::Widget::InitParams* init_params) {
272 init_params->parent = GetContainer(shell_container_id);
273 }
274
275 WmWindow* RootWindowController::FindEventTarget(
276 const gfx::Point& location_in_screen) {
277 gfx::Point location_in_root(location_in_screen);
278 aura::Window* root_window = GetRootWindow();
279 ::wm::ConvertPointFromScreen(root_window, &location_in_root);
280 ui::MouseEvent test_event(ui::ET_MOUSE_MOVED, location_in_root,
281 location_in_root, ui::EventTimeForNow(),
282 ui::EF_NONE, ui::EF_NONE);
283 ui::EventTarget* event_handler =
284 static_cast<ui::EventTarget*>(root_window)
285 ->GetEventTargeter()
286 ->FindTargetForEvent(root_window, &test_event);
287 return WmWindowAura::Get(static_cast<aura::Window*>(event_handler));
288 }
289
290 gfx::Point RootWindowController::GetLastMouseLocationInRoot() {
291 return window_tree_host_->dispatcher()->GetLastMouseLocationInRoot();
292 }
293
294 void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
295 ui::MenuSourceType source_type) {
296 ShellDelegate* delegate = WmShell::Get()->delegate();
297 DCHECK(delegate);
298 menu_model_.reset(delegate->CreateContextMenu(wm_shelf_.get(), nullptr));
299 if (!menu_model_)
300 return;
301
302 menu_model_adapter_ = base::MakeUnique<views::MenuModelAdapter>(
303 menu_model_.get(),
304 base::Bind(&RootWindowController::OnMenuClosed, base::Unretained(this)));
305
306 // The wallpaper controller may not be set yet if the user clicked on the
307 // status area before the initial animation completion. See crbug.com/222218
308 if (!wallpaper_widget_controller())
309 return;
310
311 menu_runner_ = base::MakeUnique<views::MenuRunner>(
312 menu_model_adapter_->CreateMenu(),
313 views::MenuRunner::CONTEXT_MENU | views::MenuRunner::ASYNC);
314 ignore_result(
315 menu_runner_->RunMenuAt(wallpaper_widget_controller()->widget(), nullptr,
316 gfx::Rect(location_in_screen, gfx::Size()),
317 views::MENU_ANCHOR_TOPLEFT, source_type));
318 }
319
320 void RootWindowController::UpdateAfterLoginStatusChange(LoginStatus status) {
321 StatusAreaWidget* status_area_widget =
322 wm_shelf_->shelf_widget()->status_area_widget();
323 if (status_area_widget)
324 status_area_widget->UpdateAfterLoginStatusChange(status);
325 }
326
327 void RootWindowController::MoveWindowsTo(aura::Window* dst) {
328 // Clear the workspace controller, so it doesn't incorrectly update the shelf.
329 workspace_controller_.reset();
330 ReparentAllWindows(GetWindow(), WmWindowAura::Get(dst));
331 }
332
333 void RootWindowController::CreateContainers() {
334 WmWindow* root = GetWindow();
335 // These containers are just used by PowerButtonController to animate groups
336 // of containers simultaneously without messing up the current transformations
337 // on those containers. These are direct children of the root window; all of
338 // the other containers are their children.
339
340 // The wallpaper container is not part of the lock animation, so it is not
341 // included in those animate groups. When the screen is locked, the wallpaper
342 // is moved to the lock screen wallpaper container (and moved back on unlock).
343 // Ensure that there's an opaque layer occluding the non-lock-screen layers.
344 WmWindow* wallpaper_container = CreateContainer(
345 kShellWindowId_WallpaperContainer, "WallpaperContainer", root);
346 wallpaper_container->SetChildWindowVisibilityChangesAnimated();
347
348 WmWindow* non_lock_screen_containers =
349 CreateContainer(kShellWindowId_NonLockScreenContainersContainer,
350 "NonLockScreenContainersContainer", root);
351 // Clip all windows inside this container, as half pixel of the window's
352 // texture may become visible when the screen is scaled. crbug.com/368591.
353 non_lock_screen_containers->SetMasksToBounds(true);
354
355 WmWindow* lock_wallpaper_containers =
356 CreateContainer(kShellWindowId_LockScreenWallpaperContainer,
357 "LockScreenWallpaperContainer", root);
358 lock_wallpaper_containers->SetChildWindowVisibilityChangesAnimated();
359
360 WmWindow* lock_screen_containers =
361 CreateContainer(kShellWindowId_LockScreenContainersContainer,
362 "LockScreenContainersContainer", root);
363 WmWindow* lock_screen_related_containers =
364 CreateContainer(kShellWindowId_LockScreenRelatedContainersContainer,
365 "LockScreenRelatedContainersContainer", root);
366
367 CreateContainer(kShellWindowId_UnparentedControlContainer,
368 "UnparentedControlContainer", non_lock_screen_containers);
369
370 WmWindow* default_container =
371 CreateContainer(kShellWindowId_DefaultContainer, "DefaultContainer",
372 non_lock_screen_containers);
373 default_container->SetChildWindowVisibilityChangesAnimated();
374 default_container->SetSnapsChildrenToPhysicalPixelBoundary();
375 default_container->SetBoundsInScreenBehaviorForChildren(
376 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
377 default_container->SetChildrenUseExtendedHitRegion();
378
379 WmWindow* always_on_top_container =
380 CreateContainer(kShellWindowId_AlwaysOnTopContainer,
381 "AlwaysOnTopContainer", non_lock_screen_containers);
382 always_on_top_container->SetChildWindowVisibilityChangesAnimated();
383 always_on_top_container->SetSnapsChildrenToPhysicalPixelBoundary();
384 always_on_top_container->SetBoundsInScreenBehaviorForChildren(
385 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
386
387 WmWindow* docked_container =
388 CreateContainer(kShellWindowId_DockedContainer, "DockedContainer",
389 non_lock_screen_containers);
390 docked_container->SetChildWindowVisibilityChangesAnimated();
391 docked_container->SetSnapsChildrenToPhysicalPixelBoundary();
392 docked_container->SetBoundsInScreenBehaviorForChildren(
393 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
394 docked_container->SetChildrenUseExtendedHitRegion();
395
396 WmWindow* shelf_container =
397 CreateContainer(kShellWindowId_ShelfContainer, "ShelfContainer",
398 non_lock_screen_containers);
399 shelf_container->SetSnapsChildrenToPhysicalPixelBoundary();
400 shelf_container->SetBoundsInScreenBehaviorForChildren(
401 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
402 shelf_container->SetLockedToRoot(true);
403
404 WmWindow* panel_container =
405 CreateContainer(kShellWindowId_PanelContainer, "PanelContainer",
406 non_lock_screen_containers);
407 panel_container->SetSnapsChildrenToPhysicalPixelBoundary();
408 panel_container->SetBoundsInScreenBehaviorForChildren(
409 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
410
411 WmWindow* shelf_bubble_container =
412 CreateContainer(kShellWindowId_ShelfBubbleContainer,
413 "ShelfBubbleContainer", non_lock_screen_containers);
414 shelf_bubble_container->SetSnapsChildrenToPhysicalPixelBoundary();
415 shelf_bubble_container->SetBoundsInScreenBehaviorForChildren(
416 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
417 shelf_bubble_container->SetLockedToRoot(true);
418
419 WmWindow* app_list_container =
420 CreateContainer(kShellWindowId_AppListContainer, "AppListContainer",
421 non_lock_screen_containers);
422 app_list_container->SetSnapsChildrenToPhysicalPixelBoundary();
423 app_list_container->SetBoundsInScreenBehaviorForChildren(
424 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
425
426 WmWindow* modal_container =
427 CreateContainer(kShellWindowId_SystemModalContainer,
428 "SystemModalContainer", non_lock_screen_containers);
429 modal_container->SetSnapsChildrenToPhysicalPixelBoundary();
430 modal_container->SetChildWindowVisibilityChangesAnimated();
431 modal_container->SetBoundsInScreenBehaviorForChildren(
432 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
433 modal_container->SetChildrenUseExtendedHitRegion();
434
435 // TODO(beng): Figure out if we can make this use
436 // SystemModalContainerEventFilter instead of stops_event_propagation.
437 WmWindow* lock_container =
438 CreateContainer(kShellWindowId_LockScreenContainer, "LockScreenContainer",
439 lock_screen_containers);
440 lock_container->SetSnapsChildrenToPhysicalPixelBoundary();
441 lock_container->SetBoundsInScreenBehaviorForChildren(
442 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
443 // TODO(beng): stopsevents
444
445 WmWindow* lock_modal_container =
446 CreateContainer(kShellWindowId_LockSystemModalContainer,
447 "LockSystemModalContainer", lock_screen_containers);
448 lock_modal_container->SetSnapsChildrenToPhysicalPixelBoundary();
449 lock_modal_container->SetChildWindowVisibilityChangesAnimated();
450 lock_modal_container->SetBoundsInScreenBehaviorForChildren(
451 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
452 lock_modal_container->SetChildrenUseExtendedHitRegion();
453
454 WmWindow* status_container =
455 CreateContainer(kShellWindowId_StatusContainer, "StatusContainer",
456 lock_screen_related_containers);
457 status_container->SetSnapsChildrenToPhysicalPixelBoundary();
458 status_container->SetBoundsInScreenBehaviorForChildren(
459 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
460 status_container->SetLockedToRoot(true);
461
462 WmWindow* settings_bubble_container =
463 CreateContainer(kShellWindowId_SettingBubbleContainer,
464 "SettingBubbleContainer", lock_screen_related_containers);
465 settings_bubble_container->SetChildWindowVisibilityChangesAnimated();
466 settings_bubble_container->SetSnapsChildrenToPhysicalPixelBoundary();
467 settings_bubble_container->SetBoundsInScreenBehaviorForChildren(
468 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
469 settings_bubble_container->SetLockedToRoot(true);
470
471 WmWindow* virtual_keyboard_parent_container = CreateContainer(
472 kShellWindowId_ImeWindowParentContainer, "VirtualKeyboardParentContainer",
473 lock_screen_related_containers);
474 virtual_keyboard_parent_container->SetSnapsChildrenToPhysicalPixelBoundary();
475 virtual_keyboard_parent_container->SetBoundsInScreenBehaviorForChildren(
476 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
477
478 WmWindow* menu_container =
479 CreateContainer(kShellWindowId_MenuContainer, "MenuContainer",
480 lock_screen_related_containers);
481 menu_container->SetChildWindowVisibilityChangesAnimated();
482 menu_container->SetSnapsChildrenToPhysicalPixelBoundary();
483 menu_container->SetBoundsInScreenBehaviorForChildren(
484 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
485
486 WmWindow* drag_drop_container = CreateContainer(
487 kShellWindowId_DragImageAndTooltipContainer,
488 "DragImageAndTooltipContainer", lock_screen_related_containers);
489 drag_drop_container->SetChildWindowVisibilityChangesAnimated();
490 drag_drop_container->SetSnapsChildrenToPhysicalPixelBoundary();
491 drag_drop_container->SetBoundsInScreenBehaviorForChildren(
492 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
493
494 WmWindow* overlay_container =
495 CreateContainer(kShellWindowId_OverlayContainer, "OverlayContainer",
496 lock_screen_related_containers);
497 overlay_container->SetSnapsChildrenToPhysicalPixelBoundary();
498 overlay_container->SetBoundsInScreenBehaviorForChildren(
499 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
500
501 WmWindow* mouse_cursor_container = CreateContainer(
502 kShellWindowId_MouseCursorContainer, "MouseCursorContainer", root);
503 mouse_cursor_container->SetBoundsInScreenBehaviorForChildren(
504 WmWindow::BoundsInScreenBehavior::USE_SCREEN_COORDINATES);
505
506 CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
507 "PowerButtonAnimationContainer", root);
508 }
509
510 void RootWindowController::CreateLayoutManagers() {
511 GetShelf()->CreateShelfWidget(GetWindow());
512
513 WmWindow* root = GetWindow();
514 root_window_layout_manager_ = new wm::RootWindowLayoutManager(root);
515 root->SetLayoutManager(base::WrapUnique(root_window_layout_manager_));
516
517 WmWindow* default_container = GetWmContainer(kShellWindowId_DefaultContainer);
518 // Installs WorkspaceLayoutManager on |default_container|.
519 workspace_controller_.reset(new WorkspaceController(default_container));
520
521 WmWindow* modal_container =
522 GetWmContainer(kShellWindowId_SystemModalContainer);
523 DCHECK(modal_container);
524 modal_container->SetLayoutManager(
525 base::MakeUnique<SystemModalContainerLayoutManager>(modal_container));
526
527 WmWindow* lock_modal_container =
528 GetWmContainer(kShellWindowId_LockSystemModalContainer);
529 DCHECK(lock_modal_container);
530 lock_modal_container->SetLayoutManager(
531 base::MakeUnique<SystemModalContainerLayoutManager>(
532 lock_modal_container));
533
534 WmWindow* lock_container = GetWmContainer(kShellWindowId_LockScreenContainer);
535 DCHECK(lock_container);
536 lock_container->SetLayoutManager(
537 base::MakeUnique<LockLayoutManager>(lock_container));
538
539 WmWindow* always_on_top_container =
540 GetWmContainer(kShellWindowId_AlwaysOnTopContainer);
541 DCHECK(always_on_top_container);
542 always_on_top_controller_ =
543 base::MakeUnique<AlwaysOnTopController>(always_on_top_container);
544
545 // Create Docked windows layout manager
546 WmWindow* docked_container = GetWmContainer(kShellWindowId_DockedContainer);
547 docked_window_layout_manager_ =
548 new DockedWindowLayoutManager(docked_container);
549 docked_container->SetLayoutManager(
550 base::WrapUnique(docked_window_layout_manager_));
551
552 // Create Panel layout manager
553 WmWindow* panel_container = GetWmContainer(kShellWindowId_PanelContainer);
554 panel_layout_manager_ = new PanelLayoutManager(panel_container);
555 panel_container->SetLayoutManager(base::WrapUnique(panel_layout_manager_));
556
557 wm::WmSnapToPixelLayoutManager::InstallOnContainers(root);
558 }
559
560 void RootWindowController::ResetRootForNewWindowsIfNecessary() {
561 WmShell* shell = WmShell::Get();
562 // Change the target root window before closing child windows. If any child
563 // being removed triggers a relayout of the shelf it will try to build a
564 // window list adding windows from the target root window's containers which
565 // may have already gone away.
566 WmWindow* root = GetWindow();
567 if (shell->GetRootWindowForNewWindows() == root) {
568 // The root window for new windows is being destroyed. Switch to the primary
569 // root window if possible.
570 WmWindow* primary_root = shell->GetPrimaryRootWindow();
571 shell->set_root_window_for_new_windows(primary_root == root ? nullptr
572 : primary_root);
573 }
574 }
575
576 // TODO(sky): fold into CloseChildWindows() when move back.
577 void RootWindowController::CloseChildWindowsImpl() {
578 // NOTE: this may be called multiple times.
579
580 // |panel_layout_manager_| needs to be shut down before windows are destroyed.
581 if (panel_layout_manager_) {
582 panel_layout_manager_->Shutdown();
583 panel_layout_manager_ = nullptr;
584 }
585
586 // |docked_window_layout_manager_| needs to be shut down before windows are
587 // destroyed.
588 if (docked_window_layout_manager_) {
589 docked_window_layout_manager_->Shutdown();
590 docked_window_layout_manager_ = nullptr;
591 }
592
593 WmShelf* shelf = GetShelf();
594 shelf->ShutdownShelfWidget();
595
596 workspace_controller_.reset();
597
598 // Explicitly destroy top level windows. We do this because such windows may
599 // query the RootWindow for state.
600 WmWindowTracker non_toplevel_windows;
601 WmWindow* root = GetWindow();
602 non_toplevel_windows.Add(root);
603 while (!non_toplevel_windows.windows().empty()) {
604 WmWindow* non_toplevel_window = non_toplevel_windows.Pop();
605 WmWindowTracker toplevel_windows;
606 for (WmWindow* child : non_toplevel_window->GetChildren()) {
607 if (!ShouldDestroyWindowInCloseChildWindows(child))
608 continue;
609 if (child->HasNonClientArea())
610 toplevel_windows.Add(child);
611 else
612 non_toplevel_windows.Add(child);
613 }
614 while (!toplevel_windows.windows().empty())
615 toplevel_windows.Pop()->Destroy();
616 }
617 // And then remove the containers.
618 while (!root->GetChildren().empty()) {
619 WmWindow* child = root->GetChildren()[0];
620 if (ShouldDestroyWindowInCloseChildWindows(child))
621 child->Destroy();
622 else
623 root->RemoveChild(child);
624 }
625
626 shelf->DestroyShelfWidget();
627
628 // CloseChildWindows() may be called twice during the shutdown of ash
629 // unittests. Avoid notifying WmShelf that the shelf has been destroyed twice.
630 if (shelf->IsShelfInitialized())
631 shelf->ShutdownShelf();
632 }
633
634 void RootWindowController::OnMenuClosed() {
635 menu_runner_.reset();
636 menu_model_adapter_.reset();
637 menu_model_.reset();
638 wm_shelf_->UpdateVisibilityState();
639 }
640
641 } // namespace ash
OLDNEW
« no previous file with comments | « ash/BUILD.gn ('k') | ash/root_window_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698