[M108 Migration] Support standard build for armv7hl architecture
[platform/framework/web/chromium-efl.git] / ash / root_window_controller.cc
1 // Copyright 2012 The Chromium Authors
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 <algorithm>
8 #include <memory>
9 #include <queue>
10 #include <vector>
11
12 #include "ash/accessibility/chromevox/touch_exploration_controller.h"
13 #include "ash/accessibility/chromevox/touch_exploration_manager.h"
14 #include "ash/accessibility/ui/accessibility_panel_layout_manager.h"
15 #include "ash/ambient/ambient_controller.h"
16 #include "ash/app_list/app_list_controller_impl.h"
17 #include "ash/app_menu/app_menu_model_adapter.h"
18 #include "ash/constants/ash_constants.h"
19 #include "ash/constants/ash_features.h"
20 #include "ash/constants/ash_switches.h"
21 #include "ash/curtain/security_curtain_widget_controller.h"
22 #include "ash/focus_cycler.h"
23 #include "ash/host/ash_window_tree_host.h"
24 #include "ash/keyboard/arc/arc_virtual_keyboard_container_layout_manager.h"
25 #include "ash/keyboard/keyboard_controller_impl.h"
26 #include "ash/keyboard/ui/keyboard_layout_manager.h"
27 #include "ash/keyboard/ui/keyboard_ui_controller.h"
28 #include "ash/keyboard/ui/keyboard_util.h"
29 #include "ash/keyboard/virtual_keyboard_container_layout_manager.h"
30 #include "ash/lock_screen_action/lock_screen_action_background_controller.h"
31 #include "ash/login_status.h"
32 #include "ash/public/cpp/app_menu_constants.h"
33 #include "ash/public/cpp/shelf_types.h"
34 #include "ash/public/cpp/shell_window_ids.h"
35 #include "ash/public/cpp/window_properties.h"
36 #include "ash/resources/vector_icons/vector_icons.h"
37 #include "ash/root_window_settings.h"
38 #include "ash/scoped_animation_disabler.h"
39 #include "ash/screen_util.h"
40 #include "ash/session/session_controller_impl.h"
41 #include "ash/shelf/shelf.h"
42 #include "ash/shelf/shelf_context_menu_model.h"
43 #include "ash/shelf/shelf_layout_manager.h"
44 #include "ash/shelf/shelf_widget.h"
45 #include "ash/shelf/shelf_window_targeter.h"
46 #include "ash/shell.h"
47 #include "ash/strings/grit/ash_strings.h"
48 #include "ash/style/ash_color_provider_source.h"
49 #include "ash/system/status_area_widget.h"
50 #include "ash/system/tray/tray_background_view.h"
51 #include "ash/system/unified/unified_system_tray.h"
52 #include "ash/touch/touch_hud_debug.h"
53 #include "ash/touch/touch_hud_projection.h"
54 #include "ash/touch/touch_observer_hud.h"
55 #include "ash/wallpaper/wallpaper_widget_controller.h"
56 #include "ash/wm/always_on_top_controller.h"
57 #include "ash/wm/container_finder.h"
58 #include "ash/wm/desks/desks_controller.h"
59 #include "ash/wm/desks/desks_util.h"
60 #include "ash/wm/fullscreen_window_finder.h"
61 #include "ash/wm/lock_action_handler_layout_manager.h"
62 #include "ash/wm/lock_layout_manager.h"
63 #include "ash/wm/mru_window_tracker.h"
64 #include "ash/wm/overlay_layout_manager.h"
65 #include "ash/wm/overview/overview_controller.h"
66 #include "ash/wm/overview/overview_session.h"
67 #include "ash/wm/root_window_layout_manager.h"
68 #include "ash/wm/splitview/split_view_controller.h"
69 #include "ash/wm/splitview/split_view_utils.h"
70 #include "ash/wm/stacking_controller.h"
71 #include "ash/wm/switchable_windows.h"
72 #include "ash/wm/system_modal_container_layout_manager.h"
73 #include "ash/wm/system_wallpaper_controller.h"
74 #include "ash/wm/tablet_mode/tablet_mode_controller.h"
75 #include "ash/wm/window_properties.h"
76 #include "ash/wm/window_state.h"
77 #include "ash/wm/window_util.h"
78 #include "ash/wm/work_area_insets.h"
79 #include "ash/wm/workspace/workspace_layout_manager.h"
80 #include "ash/wm/workspace_controller.h"
81 #include "base/bind.h"
82 #include "base/command_line.h"
83 #include "base/cxx17_backports.h"
84 #include "base/metrics/histogram_macros.h"
85 #include "base/ranges/algorithm.h"
86 #include "base/time/time.h"
87 #include "ui/aura/client/aura_constants.h"
88 #include "ui/aura/client/drag_drop_client.h"
89 #include "ui/aura/client/screen_position_client.h"
90 #include "ui/aura/client/window_types.h"
91 #include "ui/aura/null_window_targeter.h"
92 #include "ui/aura/window.h"
93 #include "ui/aura/window_event_dispatcher.h"
94 #include "ui/aura/window_observer.h"
95 #include "ui/aura/window_tracker.h"
96 #include "ui/base/l10n/l10n_util.h"
97 #include "ui/base/models/menu_model.h"
98 #include "ui/base/models/simple_menu_model.h"
99 #include "ui/compositor/layer.h"
100 #include "ui/display/types/display_constants.h"
101 #include "ui/events/event_utils.h"
102 #include "ui/views/controls/menu/menu_model_adapter.h"
103 #include "ui/views/controls/menu/menu_runner.h"
104 #include "ui/views/view_model.h"
105 #include "ui/views/view_model_utils.h"
106 #include "ui/views/widget/widget.h"
107 #include "ui/wm/core/capture_controller.h"
108 #include "ui/wm/core/coordinate_conversion.h"
109 #include "ui/wm/core/visibility_controller.h"
110 #include "ui/wm/core/window_properties.h"
111 #include "ui/wm/core/window_util.h"
112 #include "ui/wm/public/tooltip_client.h"
113
114 namespace ash {
115 namespace {
116
117 bool IsInShelfContainer(aura::Window* container) {
118   if (!container)
119     return false;
120   int id = container->GetId();
121   if (id == ash::kShellWindowId_ShelfContainer ||
122       id == ash::kShellWindowId_ShelfBubbleContainer) {
123     return true;
124   }
125   return IsInShelfContainer(container->parent());
126 }
127
128 bool IsWindowAboveContainer(aura::Window* window,
129                             aura::Window* blocking_container) {
130   std::vector<aura::Window*> target_path;
131   std::vector<aura::Window*> blocking_path;
132
133   while (window) {
134     target_path.push_back(window);
135     window = window->parent();
136   }
137
138   while (blocking_container) {
139     blocking_path.push_back(blocking_container);
140     blocking_container = blocking_container->parent();
141   }
142
143   // The root window is put at the end so that we compare windows at
144   // the same depth.
145   while (!blocking_path.empty()) {
146     if (target_path.empty())
147       return false;
148
149     aura::Window* target = target_path.back();
150     target_path.pop_back();
151     aura::Window* blocking = blocking_path.back();
152     blocking_path.pop_back();
153
154     // Still on the same path, continue.
155     if (target == blocking)
156       continue;
157
158     // This can happen only if unparented window is passed because
159     // first element must be the same root.
160     if (!target->parent() || !blocking->parent())
161       return false;
162
163     aura::Window* common_parent = target->parent();
164     DCHECK_EQ(common_parent, blocking->parent());
165     const aura::Window::Windows& windows = common_parent->children();
166     auto blocking_iter = base::ranges::find(windows, blocking);
167     // If the target window is above blocking window, the window can handle
168     // events.
169     return std::find(blocking_iter, windows.end(), target) != windows.end();
170   }
171
172   return true;
173 }
174
175 // Scales |value| that is originally between 0 and |src_max| to be between
176 // 0 and |dst_max|.
177 float ToRelativeValue(int value, int src_max, int dst_max) {
178   return static_cast<float>(value) / static_cast<float>(src_max) * dst_max;
179 }
180
181 // Uses ToRelativeValue() to scale the origin of |bounds_in_out|. The
182 // width/height are not changed.
183 void MoveOriginRelativeToSize(const gfx::Size& src_size,
184                               const gfx::Size& dst_size,
185                               gfx::Rect* bounds_in_out) {
186   gfx::Point origin = bounds_in_out->origin();
187   bounds_in_out->set_origin(gfx::Point(
188       ToRelativeValue(origin.x(), src_size.width(), dst_size.width()),
189       ToRelativeValue(origin.y(), src_size.height(), dst_size.height())));
190 }
191
192 // Reparents |window| to |new_parent|.
193 void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
194   const gfx::Size src_size = window->parent()->bounds().size();
195   const gfx::Size dst_size = new_parent->bounds().size();
196   // Update the restore bounds to make it relative to the display.
197   WindowState* state = WindowState::Get(window);
198   gfx::Rect restore_bounds;
199   const bool has_restore_bounds = state && state->HasRestoreBounds();
200
201   const bool update_bounds =
202       state && (state->IsNormalOrSnapped() || state->IsMinimized());
203   gfx::Rect work_area_in_new_parent =
204       screen_util::GetDisplayWorkAreaBoundsInParent(new_parent);
205
206   gfx::Rect local_bounds;
207   if (update_bounds) {
208     local_bounds = state->window()->bounds();
209     MoveOriginRelativeToSize(src_size, dst_size, &local_bounds);
210     local_bounds.AdjustToFit(work_area_in_new_parent);
211   }
212
213   if (has_restore_bounds) {
214     restore_bounds = state->GetRestoreBoundsInParent();
215     MoveOriginRelativeToSize(src_size, dst_size, &restore_bounds);
216     restore_bounds.AdjustToFit(work_area_in_new_parent);
217   }
218
219   new_parent->AddChild(window);
220
221   // Docked windows have bounds handled by the layout manager in AddChild().
222   if (update_bounds)
223     window->SetBounds(local_bounds);
224
225   if (has_restore_bounds)
226     state->SetRestoreBoundsInParent(restore_bounds);
227 }
228
229 // Reparents the appropriate set of windows from |src| to |dst|.
230 void ReparentAllWindows(aura::Window* src, aura::Window* dst) {
231   // Set of windows to move.
232   constexpr int kContainerIdsToMove[] = {
233       kShellWindowId_AlwaysOnTopContainer,
234       kShellWindowId_FloatContainer,
235       kShellWindowId_PipContainer,
236       kShellWindowId_SystemModalContainer,
237       kShellWindowId_LockSystemModalContainer,
238       kShellWindowId_UnparentedContainer,
239       kShellWindowId_OverlayContainer,
240       kShellWindowId_LockActionHandlerContainer,
241       kShellWindowId_MenuContainer,
242   };
243   constexpr int kExtraContainerIdsToMoveInUnifiedMode[] = {
244       kShellWindowId_LockScreenContainer,
245   };
246
247   // Desk container ids are different depends on whether Bento feature is
248   // enabled or not.
249   std::vector<int> container_ids = desks_util::GetDesksContainersIds();
250   for (const int id : kContainerIdsToMove)
251     container_ids.emplace_back(id);
252
253   // Check the display mode as this is also necessary when trasitioning between
254   // mirror and unified mode.
255   if (Shell::Get()->display_manager()->current_default_multi_display_mode() ==
256       display::DisplayManager::UNIFIED) {
257     for (const int id : kExtraContainerIdsToMoveInUnifiedMode)
258       container_ids.emplace_back(id);
259   }
260
261   const std::vector<aura::Window*> mru_list =
262       Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(kAllDesks);
263   for (int id : container_ids) {
264     aura::Window* src_container = src->GetChildById(id);
265     aura::Window* dst_container = dst->GetChildById(id);
266     const bool switchable_container = IsSwitchableContainer(src_container);
267     while (!src_container->children().empty()) {
268       // Restart iteration from the source container windows each time as they
269       // may change as a result of moving other windows.
270       const aura::Window::Windows& src_container_children =
271           src_container->children();
272       auto iter = src_container_children.rbegin();
273       while (iter != src_container_children.rend() &&
274              SystemModalContainerLayoutManager::IsModalBackground(*iter)) {
275         ++iter;
276       }
277       // If the entire window list is modal background windows then stop.
278       if (iter == src_container_children.rend())
279         break;
280
281       // |iter| is invalidated after ReparentWindow. Cache it to use afterwards.
282       aura::Window* const window = *iter;
283       ReparentWindow(window, dst_container);
284
285       aura::Window* stacking_target = nullptr;
286       if (switchable_container) {
287         // Find the first window that comes after |window| in the MRU list that
288         // shares the same parent.
289         bool found_window = false;
290         for (aura::Window* window_iter : mru_list) {
291           // First determine the position of |window| in the |mru_list|.
292           if (!found_window && window == window_iter) {
293             found_window = true;
294             continue;
295           }
296
297           if (!found_window || window_iter->parent() != dst_container)
298             continue;
299
300           // Once |window| is found, the next item in |mru_list| with the same
301           // parent (container) is the stacking target.
302           stacking_target = window_iter;
303           break;
304         }
305       }
306
307       // |stacking_target| may be null if |switchable_container| is false, which
308       // means the children of that container wouldn't be in the MRU list or if
309       // |window| was the last item in the MRU list with parent id |id|. In
310       // this case stack |window| at the bottom.
311       if (stacking_target)
312         dst_container->StackChildAbove(window, stacking_target);
313       else
314         dst_container->StackChildAtBottom(window);
315     }
316   }
317 }
318
319 bool ShouldDestroyWindowInCloseChildWindows(aura::Window* window) {
320   return window->owned_by_parent();
321 }
322
323 // Clears the workspace controllers from the properties of all virtual desks
324 // containers in |root|.
325 void ClearWorkspaceControllers(aura::Window* root) {
326   for (auto* desk_container : desks_util::GetDesksContainers(root))
327     SetWorkspaceController(desk_container, nullptr);
328 }
329
330 class RootWindowTargeter : public aura::WindowTargeter {
331  public:
332   RootWindowTargeter() = default;
333
334   RootWindowTargeter(const RootWindowTargeter&) = delete;
335   RootWindowTargeter& operator=(const RootWindowTargeter&) = delete;
336
337   ~RootWindowTargeter() override = default;
338
339  protected:
340   aura::Window* FindTargetForLocatedEvent(aura::Window* window,
341                                           ui::LocatedEvent* event) override {
342     if (!window->parent() && !window->bounds().Contains(event->location()) &&
343         IsEventInsideDisplayForTelemetryHack(window, event)) {
344       auto* dispatcher = window->GetHost()->dispatcher();
345       bool has_capture_target = !!dispatcher->mouse_pressed_handler() ||
346                                 !!aura::client::GetCaptureWindow(window);
347
348       // Make sure that event location is within the root window bounds if
349       // 1) mouse event isn't captured.
350       // 2) A mouse is clicked without movement and capture.
351       //
352       // The event can be outside on some scale factor due to rounding, or due
353       // to not well calibrated a touch screen, or Detect this situation and
354       // adjust the location.
355       bool bounded_click = ShouldConstrainMouseClick(event, has_capture_target);
356       if (!has_capture_target || bounded_click) {
357         gfx::Point new_location =
358             FitPointToBounds(event->location(), window->bounds());
359         // Do not change |location_f|. It's used to compute pixel position and
360         // such client should know what they're doing.
361         event->set_location(new_location);
362         event->set_root_location(new_location);
363       }
364     }
365     return aura::WindowTargeter::FindTargetForLocatedEvent(window, event);
366   }
367
368   // Stop-gap workaround for telemetry tests that send events far outside of the
369   // display (e.g. 512, -4711). Fix the test and remove this (crbgu.com/904623).
370   bool IsEventInsideDisplayForTelemetryHack(aura::Window* window,
371                                             ui::LocatedEvent* event) {
372     constexpr int ExtraMarginForTelemetryTest = -10;
373     gfx::Rect bounds = window->bounds();
374     bounds.Inset(ExtraMarginForTelemetryTest);
375     return bounds.Contains(event->location());
376   }
377
378  private:
379   // Returns true if the mouse event should be constrainted.
380   bool ShouldConstrainMouseClick(ui::LocatedEvent* event,
381                                  bool has_capture_target) {
382     if (event->type() == ui::ET_MOUSE_PRESSED && !has_capture_target) {
383       last_mouse_event_type_ = ui::ET_MOUSE_PRESSED;
384       return true;
385     }
386     if (last_mouse_event_type_ == ui::ET_MOUSE_PRESSED &&
387         event->type() == ui::ET_MOUSE_RELEASED && has_capture_target) {
388       last_mouse_event_type_ = ui::ET_UNKNOWN;
389       return true;
390     }
391     // For other cases, reset the state
392     if (event->type() != ui::ET_MOUSE_CAPTURE_CHANGED)
393       last_mouse_event_type_ = ui::ET_UNKNOWN;
394     return false;
395   }
396
397   gfx::Point FitPointToBounds(const gfx::Point p, const gfx::Rect& bounds) {
398     return gfx::Point(base::clamp(p.x(), bounds.x(), bounds.right() - 1),
399                       base::clamp(p.y(), bounds.y(), bounds.bottom() - 1));
400   }
401
402   ui::EventType last_mouse_event_type_ = ui::ET_UNKNOWN;
403 };
404
405 class RootWindowMenuModelAdapter : public AppMenuModelAdapter {
406  public:
407   RootWindowMenuModelAdapter(std::unique_ptr<ui::SimpleMenuModel> model,
408                              views::Widget* widget_owner,
409                              ui::MenuSourceType source_type,
410                              base::OnceClosure on_menu_closed_callback,
411                              bool is_tablet_mode)
412       : AppMenuModelAdapter(std::string(),
413                             std::move(model),
414                             widget_owner,
415                             source_type,
416                             std::move(on_menu_closed_callback),
417                             is_tablet_mode) {}
418
419   RootWindowMenuModelAdapter(const RootWindowMenuModelAdapter&) = delete;
420   RootWindowMenuModelAdapter& operator=(const RootWindowMenuModelAdapter&) =
421       delete;
422
423   ~RootWindowMenuModelAdapter() override = default;
424
425  private:
426   // AppMenuModelAdapter overrides:
427   void RecordHistogramOnMenuClosed() override {
428     const base::TimeDelta user_journey_time =
429         base::TimeTicks::Now() - menu_open_time();
430
431     UMA_HISTOGRAM_TIMES("Apps.ContextMenuUserJourneyTime.Desktop",
432                         user_journey_time);
433     UMA_HISTOGRAM_ENUMERATION("Apps.ContextMenuShowSource.Desktop",
434                               source_type(), ui::MENU_SOURCE_TYPE_LAST);
435     if (is_tablet_mode()) {
436       UMA_HISTOGRAM_TIMES("Apps.ContextMenuUserJourneyTime.Desktop.TabletMode",
437                           user_journey_time);
438       UMA_HISTOGRAM_ENUMERATION("Apps.ContextMenuShowSource.Desktop.TabletMode",
439                                 source_type(), ui::MENU_SOURCE_TYPE_LAST);
440     } else {
441       UMA_HISTOGRAM_TIMES(
442           "Apps.ContextMenuUserJourneyTime.Desktop.ClamshellMode",
443           user_journey_time);
444       UMA_HISTOGRAM_ENUMERATION(
445           "Apps.ContextMenuShowSource.Desktop.ClamshellMode", source_type(),
446           ui::MENU_SOURCE_TYPE_LAST);
447     }
448   }
449 };
450
451 // A layout manager that fills its container when the child window's resize
452 // behavior is set to be maximizable.
453 class FillLayoutManager : public aura::LayoutManager {
454  public:
455   explicit FillLayoutManager(aura::Window* container) : container_(container) {}
456   ~FillLayoutManager() override = default;
457   FillLayoutManager(const FillLayoutManager&) = delete;
458   FillLayoutManager& operator=(const FillLayoutManager&) = delete;
459
460   // aura::LayoutManager:
461   void OnWindowResized() override { Relayout(); }
462   void OnWindowAddedToLayout(aura::Window* child) override { Relayout(); }
463   void OnWillRemoveWindowFromLayout(aura::Window* child) override {}
464   void OnWindowRemovedFromLayout(aura::Window* child) override {}
465   void OnChildWindowVisibilityChanged(aura::Window* child,
466                                       bool visible) override {}
467   void SetChildBounds(aura::Window* child,
468                       const gfx::Rect& requested_bounds) override {}
469
470  private:
471   void Relayout() {
472     // Fill the window that is set to be maximizable.
473     const gfx::Rect fullscreen(container_->bounds().size());
474     for (auto* child : container_->children()) {
475       const int resize_behavior =
476           child->GetProperty(aura::client::kResizeBehaviorKey);
477       if (resize_behavior & aura::client::kResizeBehaviorCanMaximize)
478         SetChildBoundsDirect(child, fullscreen);
479     }
480   }
481
482   aura::Window* container_;
483 };
484
485 }  // namespace
486
487 // static
488 std::vector<RootWindowController*>*
489     RootWindowController::root_window_controllers_ = nullptr;
490
491 RootWindowController::~RootWindowController() {
492   Shutdown();
493   DCHECK(!wallpaper_widget_controller_.get());
494   work_area_insets_.reset();
495   ash_host_.reset();
496   // The CaptureClient needs to be around for as long as the RootWindow is
497   // valid.
498   capture_client_.reset();
499   root_window_controllers_->erase(
500       base::ranges::find(*root_window_controllers_, this));
501 }
502
503 RootWindowController* RootWindowController::CreateForPrimaryDisplay(
504     AshWindowTreeHost* host) {
505   RootWindowController* controller = new RootWindowController(host);
506   controller->Init(RootWindowType::PRIMARY);
507   return controller;
508 }
509
510 RootWindowController* RootWindowController::CreateForSecondaryDisplay(
511     AshWindowTreeHost* host) {
512   RootWindowController* controller = new RootWindowController(host);
513   controller->Init(RootWindowType::SECONDARY);
514   return controller;
515 }
516
517 // static
518 RootWindowController* RootWindowController::ForWindow(
519     const aura::Window* window) {
520   DCHECK(window);
521   CHECK(Shell::HasInstance());
522   return GetRootWindowSettings(window->GetRootWindow())->controller;
523 }
524
525 // static
526 RootWindowController* RootWindowController::ForTargetRootWindow() {
527   CHECK(Shell::HasInstance());
528   return ForWindow(Shell::GetRootWindowForNewWindows());
529 }
530
531 aura::WindowTreeHost* RootWindowController::GetHost() {
532   return window_tree_host_;
533 }
534
535 const aura::WindowTreeHost* RootWindowController::GetHost() const {
536   return window_tree_host_;
537 }
538
539 aura::Window* RootWindowController::GetRootWindow() {
540   return GetHost()->window();
541 }
542
543 const aura::Window* RootWindowController::GetRootWindow() const {
544   return GetHost()->window();
545 }
546
547 ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
548   return shelf_->shelf_layout_manager();
549 }
550
551 SystemModalContainerLayoutManager*
552 RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
553   aura::Window* modal_container = nullptr;
554   if (window) {
555     aura::Window* window_container = GetContainerForWindow(window);
556     if (window_container &&
557         window_container->GetId() >= kShellWindowId_LockScreenContainer) {
558       modal_container = GetContainer(kShellWindowId_LockSystemModalContainer);
559     } else {
560       modal_container = GetContainer(kShellWindowId_SystemModalContainer);
561     }
562   } else {
563     int modal_window_id =
564         Shell::Get()->session_controller()->IsUserSessionBlocked()
565             ? kShellWindowId_LockSystemModalContainer
566             : kShellWindowId_SystemModalContainer;
567     modal_container = GetContainer(modal_window_id);
568   }
569   return modal_container ? static_cast<SystemModalContainerLayoutManager*>(
570                                modal_container->layout_manager())
571                          : nullptr;
572 }
573
574 StatusAreaWidget* RootWindowController::GetStatusAreaWidget() {
575   ShelfWidget* shelf_widget = shelf_->shelf_widget();
576   return shelf_widget ? shelf_widget->status_area_widget() : nullptr;
577 }
578
579 bool RootWindowController::IsSystemTrayVisible() {
580   TrayBackgroundView* tray = GetStatusAreaWidget()->unified_system_tray();
581   return tray && tray->GetWidget()->IsVisible() && tray->GetVisible();
582 }
583
584 bool RootWindowController::CanWindowReceiveEvents(aura::Window* window) {
585   if (GetRootWindow() != window->GetRootWindow())
586     return false;
587
588   aura::Window* blocking_container = nullptr;
589   aura::Window* modal_container = nullptr;
590   window_util::GetBlockingContainersForRoot(
591       GetRootWindow(), &blocking_container, &modal_container);
592   SystemModalContainerLayoutManager* modal_layout_manager = nullptr;
593   modal_layout_manager = static_cast<SystemModalContainerLayoutManager*>(
594       modal_container->layout_manager());
595
596   if (modal_layout_manager->has_window_dimmer())
597     blocking_container = modal_container;
598   else
599     modal_container = nullptr;  // Don't check modal dialogs.
600
601   // In normal session.
602   if (!blocking_container)
603     return true;
604
605   if (!IsWindowAboveContainer(window, blocking_container))
606     return false;
607
608   if (modal_container) {
609     // If the window is in the target modal container, only allow the top most
610     // one.
611     if (modal_container->Contains(window))
612       return modal_layout_manager->IsPartOfActiveModalWindow(window);
613     // Don't allow shelf to process events if there is a visible modal dialog.
614     if (IsInShelfContainer(window->parent()))
615       return false;
616   }
617   return true;
618 }
619
620 aura::Window* RootWindowController::FindEventTarget(
621     const gfx::Point& location_in_screen) {
622   gfx::Point location_in_root(location_in_screen);
623   aura::Window* root_window = GetRootWindow();
624   ::wm::ConvertPointFromScreen(root_window, &location_in_root);
625   ui::MouseEvent test_event(ui::ET_MOUSE_MOVED, location_in_root,
626                             location_in_root, ui::EventTimeForNow(),
627                             ui::EF_NONE, ui::EF_NONE);
628   ui::EventTarget* event_handler =
629       root_window->GetHost()
630           ->dispatcher()
631           ->GetDefaultEventTargeter()
632           ->FindTargetForEvent(root_window, &test_event);
633   return static_cast<aura::Window*>(event_handler);
634 }
635
636 gfx::Point RootWindowController::GetLastMouseLocationInRoot() {
637   return window_tree_host_->dispatcher()->GetLastMouseLocationInRoot();
638 }
639
640 aura::Window* RootWindowController::GetContainer(int container_id) {
641   return GetRootWindow()->GetChildById(container_id);
642 }
643
644 const aura::Window* RootWindowController::GetContainer(int container_id) const {
645   return window_tree_host_->window()->GetChildById(container_id);
646 }
647
648 void RootWindowController::Shutdown() {
649   auto targeter = GetRootWindow()->SetEventTargeter(
650       std::make_unique<aura::NullWindowTargeter>());
651
652   touch_exploration_manager_.reset();
653   wallpaper_widget_controller_.reset();
654   CloseAmbientWidget(/*immediately=*/true);
655
656   CloseChildWindows();
657   aura::Window* root_window = GetRootWindow();
658   GetRootWindowSettings(root_window)->controller = nullptr;
659   // Forget with the display ID so that display lookup
660   // ends up with invalid display.
661   GetRootWindowSettings(root_window)->display_id = display::kInvalidDisplayId;
662   if (ash_host_)
663     ash_host_->PrepareForShutdown();
664
665   system_wallpaper_.reset();
666   security_curtain_widget_controller_.reset();
667   lock_screen_action_background_controller_.reset();
668   aura::client::SetScreenPositionClient(root_window, nullptr);
669
670   // The targeter may still on the stack, so delete it later.
671   if (targeter) {
672     base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE,
673                                                     std::move(targeter));
674   }
675 }
676
677 void RootWindowController::CloseChildWindows() {
678   // Child windows can be closed by secondary monitor disconnection, Shell
679   // shutdown, or both. Avoid running the related cleanup code twice.
680   if (did_close_child_windows_)
681     return;
682   did_close_child_windows_ = true;
683
684   aura::Window* root = GetRootWindow();
685
686   Shell::Get()->desks_controller()->OnRootWindowClosing(root);
687
688   // Notify the keyboard controller before closing child windows and shutting
689   // down associated layout managers.
690   Shell::Get()->keyboard_controller()->OnRootWindowClosing(root);
691
692   OverviewController* overview_controller = Shell::Get()->overview_controller();
693   if (overview_controller && overview_controller->InOverviewSession())
694     overview_controller->overview_session()->OnRootWindowClosing(root);
695
696   shelf_->ShutdownShelfWidget();
697
698   ClearWorkspaceControllers(root);
699   always_on_top_controller_->ClearLayoutManagers();
700
701   // Explicitly destroy top level windows. We do this because such windows may
702   // query the RootWindow for state.
703   aura::WindowTracker non_toplevel_windows;
704   non_toplevel_windows.Add(root);
705   while (!non_toplevel_windows.windows().empty()) {
706     aura::Window* non_toplevel_window = non_toplevel_windows.Pop();
707     aura::WindowTracker toplevel_windows;
708     for (aura::Window* child : non_toplevel_window->children()) {
709       if (!ShouldDestroyWindowInCloseChildWindows(child))
710         continue;
711       if (child->delegate())
712         toplevel_windows.Add(child);
713       else
714         non_toplevel_windows.Add(child);
715     }
716     while (!toplevel_windows.windows().empty())
717       delete toplevel_windows.Pop();
718   }
719
720   // Reset layout manager so that it won't fire unnecessary layout evetns.
721   root->SetLayoutManager(nullptr);
722   // And then remove the containers.
723   while (!root->children().empty()) {
724     aura::Window* child = root->children()[0];
725     if (ShouldDestroyWindowInCloseChildWindows(child))
726       delete child;
727     else
728       root->RemoveChild(child);
729   }
730
731   // Removing the containers destroys ShelfLayoutManager. ShelfWidget outlives
732   // ShelfLayoutManager because ShelfLayoutManager holds a pointer to it.
733   shelf_->DestroyShelfWidget();
734
735   ::wm::SetTooltipClient(GetRootWindow(), nullptr);
736 }
737
738 void RootWindowController::MoveWindowsTo(aura::Window* dst) {
739   // Suspend unnecessary updates of the shelf visibility indefinitely since it
740   // is going away.
741   if (GetShelfLayoutManager())
742     GetShelfLayoutManager()->SuspendVisibilityUpdateForShutdown();
743
744   // Clear the workspace controller to avoid a lot of unnecessary operations
745   // when window are removed.
746   // TODO(afakhry): Should we also clear the WorkspaceLayoutManagers of the pip,
747   // always-on-top, and other containers?
748   aura::Window* root = GetRootWindow();
749   ClearWorkspaceControllers(root);
750
751   ReparentAllWindows(root, dst);
752 }
753
754 void RootWindowController::InitTouchHuds() {
755   // Enable touch debugging features when each display is initialized.
756   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
757   if (command_line->HasSwitch(switches::kAshTouchHud))
758     set_touch_hud_debug(new TouchHudDebug(GetRootWindow()));
759
760   // TouchHudProjection manages its own lifetime.
761   if (command_line->HasSwitch(switches::kShowTaps))
762     touch_hud_projection_ = new TouchHudProjection(GetRootWindow());
763 }
764
765 aura::Window* RootWindowController::GetWindowForFullscreenMode() {
766   return GetWindowForFullscreenModeInRoot(GetRootWindow());
767 }
768
769 bool RootWindowController::IsInFullscreenMode() {
770   auto* window = GetWindowForFullscreenMode();
771   return window && WindowState::Get(window)->GetHideShelfWhenFullscreen();
772 }
773
774 void RootWindowController::SetTouchAccessibilityAnchorPoint(
775     const gfx::Point& anchor_point) {
776   if (touch_exploration_manager_)
777     touch_exploration_manager_->SetTouchAccessibilityAnchorPoint(anchor_point);
778 }
779
780 void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
781                                            ui::MenuSourceType source_type) {
782   const int64_t display_id = display::Screen::GetScreen()
783                                  ->GetDisplayNearestWindow(GetRootWindow())
784                                  .id();
785
786   const bool tablet_mode =
787       Shell::Get()->tablet_mode_controller()->InTabletMode();
788   root_window_menu_model_adapter_ =
789       std::make_unique<RootWindowMenuModelAdapter>(
790           std::make_unique<ShelfContextMenuModel>(nullptr, display_id),
791           wallpaper_widget_controller()->GetWidget(), source_type,
792           base::BindOnce(&RootWindowController::OnMenuClosed,
793                          base::Unretained(this)),
794           tablet_mode);
795
796   // Appends the apps sort options in ShelfContextMenuModel in tablet mode. Note
797   // that the launcher UI is fullscreen in tablet mode, so the whole root window
798   // can be perceived by users to be part of the launcher.
799   auto* const app_list_controller = Shell::Get()->app_list_controller();
800   if (features::IsLauncherAppSortEnabled() && tablet_mode &&
801       app_list_controller->IsVisible(display_id) &&
802       app_list_controller->GetCurrentAppListPage() ==
803           AppListState::kStateApps) {
804     ui::SimpleMenuModel* menu_model = root_window_menu_model_adapter_->model();
805     sort_apps_submenu_ = std::make_unique<ui::SimpleMenuModel>(
806         static_cast<ShelfContextMenuModel*>(menu_model));
807     sort_apps_submenu_->AddItemWithIcon(
808         REORDER_BY_NAME_ALPHABETICAL,
809         l10n_util::GetStringUTF16(
810             IDS_ASH_LAUNCHER_APPS_GRID_CONTEXT_MENU_REORDER_BY_NAME),
811         ui::ImageModel::FromVectorIcon(kSortAlphabeticalIcon,
812                                        ui::kColorAshSystemUIMenuIcon));
813     sort_apps_submenu_->AddItemWithIcon(
814         REORDER_BY_COLOR,
815         l10n_util::GetStringUTF16(
816             IDS_ASH_LAUNCHER_APPS_GRID_CONTEXT_MENU_REORDER_BY_COLOR),
817         ui::ImageModel::FromVectorIcon(kSortColorIcon,
818                                        ui::kColorAshSystemUIMenuIcon));
819     menu_model->AddSeparator(ui::NORMAL_SEPARATOR);
820     menu_model->AddSubMenuWithIcon(
821         REORDER_SUBMENU,
822         l10n_util::GetStringUTF16(
823             IDS_ASH_LAUNCHER_APPS_GRID_CONTEXT_MENU_REORDER_TITLE),
824         sort_apps_submenu_.get(),
825         ui::ImageModel::FromVectorIcon(kReorderIcon,
826                                        ui::kColorAshSystemUIMenuIcon));
827
828     // Append the "Show all suggestions" / "Hide all suggestions" item.
829     menu_model->AddSeparator(ui::NORMAL_SEPARATOR);
830     if (app_list_controller->ShouldHideContinueSection()) {
831       menu_model->AddItemWithIcon(
832           ShelfContextMenuModel::MENU_SHOW_CONTINUE_SECTION,
833           l10n_util::GetStringUTF16(IDS_ASH_LAUNCHER_SHOW_CONTINUE_SECTION),
834           ui::ImageModel::FromVectorIcon(kLauncherShowContinueSectionIcon,
835                                          ui::kColorAshSystemUIMenuIcon));
836     } else {
837       menu_model->AddItemWithIcon(
838           ShelfContextMenuModel::MENU_HIDE_CONTINUE_SECTION,
839           l10n_util::GetStringUTF16(IDS_ASH_LAUNCHER_HIDE_CONTINUE_SECTION),
840           ui::ImageModel::FromVectorIcon(kLauncherHideContinueSectionIcon,
841                                          ui::kColorAshSystemUIMenuIcon));
842     }
843   }
844
845   root_window_menu_model_adapter_->Run(
846       gfx::Rect(location_in_screen, gfx::Size()),
847       views::MenuAnchorPosition::kBubbleRight,
848       views::MenuRunner::CONTEXT_MENU |
849           views::MenuRunner::USE_ASH_SYS_UI_LAYOUT |
850           views::MenuRunner::FIXED_ANCHOR);
851 }
852
853 void RootWindowController::HideContextMenu() {
854   if (root_window_menu_model_adapter_)
855     root_window_menu_model_adapter_->Cancel();
856 }
857
858 void RootWindowController::HideContextMenuNoAnimation() {
859   if (!IsContextMenuShown())
860     return;
861
862   views::Widget* submenu_widget =
863       root_window_menu_model_adapter_->GetSubmenuWidget();
864   DCHECK(submenu_widget);
865   ScopedAnimationDisabler disable(submenu_widget->GetNativeWindow());
866   root_window_menu_model_adapter_->Cancel();
867 }
868
869 bool RootWindowController::IsContextMenuShown() const {
870   return root_window_menu_model_adapter_ &&
871          root_window_menu_model_adapter_->IsShowingMenu();
872 }
873
874 void RootWindowController::UpdateAfterLoginStatusChange(LoginStatus status) {
875   StatusAreaWidget* status_area_widget =
876       shelf_->shelf_widget()->status_area_widget();
877   if (status_area_widget)
878     status_area_widget->UpdateAfterLoginStatusChange(status);
879 }
880
881 void RootWindowController::CreateAmbientWidget() {
882   DCHECK(!ambient_widget_);
883
884   auto* ambient_controller = Shell::Get()->ambient_controller();
885   if (ambient_controller && ambient_controller->IsShown()) {
886     ambient_widget_ = ambient_controller->CreateWidget(
887         GetRootWindow()->GetChildById(kShellWindowId_AmbientModeContainer));
888   }
889 }
890
891 void RootWindowController::CloseAmbientWidget(bool immediately) {
892   if (ambient_widget_) {
893     if (immediately)
894       ambient_widget_->CloseNow();
895     else
896       ambient_widget_->CloseWithReason(views::Widget::ClosedReason::kLostFocus);
897   }
898
899   ambient_widget_.reset();
900 }
901
902 bool RootWindowController::HasAmbientWidget() const {
903   return !!ambient_widget_;
904 }
905
906 AccessibilityPanelLayoutManager*
907 RootWindowController::GetAccessibilityPanelLayoutManagerForTest() {
908   return GetAccessibilityPanelLayoutManager();
909 }
910
911 void RootWindowController::SetSecurityCurtainWidgetController(
912     std::unique_ptr<curtain::SecurityCurtainWidgetController> controller) {
913   DCHECK(!security_curtain_widget_controller_);
914   security_curtain_widget_controller_ = std::move(controller);
915 }
916
917 void RootWindowController::ClearSecurityCurtainWidgetController() {
918   security_curtain_widget_controller_ = nullptr;
919 }
920
921 curtain::SecurityCurtainWidgetController*
922 RootWindowController::security_curtain_widget_controller() {
923   return security_curtain_widget_controller_.get();
924 }
925
926 ////////////////////////////////////////////////////////////////////////////////
927 // RootWindowController, private:
928
929 RootWindowController::RootWindowController(AshWindowTreeHost* ash_host)
930     : ash_host_(ash_host),
931       window_tree_host_(ash_host->AsWindowTreeHost()),
932       shelf_(std::make_unique<Shelf>()),
933       lock_screen_action_background_controller_(
934           LockScreenActionBackgroundController::Create()),
935       work_area_insets_(std::make_unique<WorkAreaInsets>(this)) {
936   DCHECK(ash_host_);
937   DCHECK(window_tree_host_);
938
939   if (!root_window_controllers_)
940     root_window_controllers_ = new std::vector<RootWindowController*>;
941   root_window_controllers_->push_back(this);
942
943   aura::Window* root_window = GetRootWindow();
944   GetRootWindowSettings(root_window)->controller = this;
945
946   stacking_controller_ = std::make_unique<StackingController>();
947   aura::client::SetWindowParentingClient(root_window,
948                                          stacking_controller_.get());
949   capture_client_ = std::make_unique<::wm::ScopedCaptureClient>(root_window);
950 }
951
952 void RootWindowController::Init(RootWindowType root_window_type) {
953   aura::Window* root_window = GetRootWindow();
954   // Create |split_view_controller_| for every display.
955   split_view_controller_ = std::make_unique<SplitViewController>(root_window);
956   Shell* shell = Shell::Get();
957   shell->InitRootWindow(root_window);
958   auto old_targeter =
959       root_window->SetEventTargeter(std::make_unique<RootWindowTargeter>());
960   DCHECK(!old_targeter);
961
962   std::unique_ptr<RootWindowLayoutManager> root_window_layout_manager =
963       std::make_unique<RootWindowLayoutManager>(root_window);
964   root_window_layout_manager_ = root_window_layout_manager.get();
965
966   CreateContainers();
967   CreateSystemWallpaper(root_window_type);
968
969   InitLayoutManagers(std::move(root_window_layout_manager));
970   InitTouchHuds();
971
972   // `shelf_` was created in the constructor.
973   shelf_->shelf_widget()->PostCreateShelf();
974
975   color_provider_source_ = std::make_unique<AshColorProviderSource>();
976   if (Shell::GetPrimaryRootWindowController()
977           ->GetSystemModalLayoutManager(nullptr)
978           ->has_window_dimmer()) {
979     GetSystemModalLayoutManager(nullptr)->CreateModalBackground();
980   }
981
982   wallpaper_widget_controller_ =
983       std::make_unique<WallpaperWidgetController>(root_window);
984
985   wallpaper_widget_controller_->Init(
986       Shell::Get()->session_controller()->IsUserSessionBlocked());
987   root_window_layout_manager_->OnWindowResized();
988
989   CreateAmbientWidget();
990
991   // Explicitly update the desks controller before notifying the ShellObservers.
992   // This is to make sure the desks' states are correct before clients are
993   // updated.
994   Shell::Get()->desks_controller()->OnRootWindowAdded(root_window);
995
996   if (root_window_type == RootWindowType::PRIMARY) {
997     shell->keyboard_controller()->RebuildKeyboardIfEnabled();
998   } else {
999     window_tree_host_->Show();
1000
1001     // Notify shell observers about new root window.
1002     shell->OnRootWindowAdded(root_window);
1003   }
1004
1005   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
1006           switches::kAshDisableTouchExplorationMode)) {
1007     touch_exploration_manager_ =
1008         std::make_unique<TouchExplorationManager>(this);
1009   }
1010 }
1011
1012 void RootWindowController::InitLayoutManagers(
1013     std::unique_ptr<RootWindowLayoutManager> root_window_layout_manager) {
1014   // Create the shelf and status area widgets. Creates the ShelfLayoutManager
1015   // as a side-effect.
1016   DCHECK(!shelf_->shelf_widget());
1017   aura::Window* root = GetRootWindow();
1018   shelf_->CreateShelfWidget(root);
1019
1020   root->SetLayoutManager(std::move(root_window_layout_manager));
1021
1022   for (auto* container : desks_util::GetDesksContainers(root)) {
1023     // Installs WorkspaceLayoutManager on the container.
1024     SetWorkspaceController(container, new WorkspaceController(container));
1025   }
1026
1027   aura::Window* modal_container =
1028       GetContainer(kShellWindowId_SystemModalContainer);
1029   modal_container->SetLayoutManager(
1030       std::make_unique<SystemModalContainerLayoutManager>(modal_container));
1031
1032   aura::Window* lock_modal_container =
1033       GetContainer(kShellWindowId_LockSystemModalContainer);
1034   DCHECK(lock_modal_container);
1035   lock_modal_container->SetLayoutManager(
1036       std::make_unique<SystemModalContainerLayoutManager>(
1037           lock_modal_container));
1038
1039   aura::Window* lock_action_handler_container =
1040       GetContainer(kShellWindowId_LockActionHandlerContainer);
1041   DCHECK(lock_action_handler_container);
1042   lock_screen_action_background_controller_->SetParentWindow(
1043       lock_action_handler_container);
1044   lock_action_handler_container->SetLayoutManager(
1045       std::make_unique<LockActionHandlerLayoutManager>(
1046           lock_action_handler_container, shelf_.get(),
1047           lock_screen_action_background_controller_.get()));
1048
1049   aura::Window* lock_container =
1050       GetContainer(kShellWindowId_LockScreenContainer);
1051   DCHECK(lock_container);
1052   lock_container->SetLayoutManager(
1053       std::make_unique<LockLayoutManager>(lock_container, shelf_.get()));
1054
1055   aura::Window* always_on_top_container =
1056       GetContainer(kShellWindowId_AlwaysOnTopContainer);
1057   aura::Window* pip_container = GetContainer(kShellWindowId_PipContainer);
1058   DCHECK(always_on_top_container);
1059   DCHECK(pip_container);
1060   always_on_top_controller_ = std::make_unique<AlwaysOnTopController>(
1061       always_on_top_container, pip_container);
1062
1063   // Make it easier to resize windows that partially overlap the shelf. Must
1064   // occur after the ShelfLayoutManager is constructed by ShelfWidget.
1065   aura::Window* shelf_container = GetContainer(kShellWindowId_ShelfContainer);
1066   shelf_container->SetEventTargeter(
1067       std::make_unique<ShelfWindowTargeter>(shelf_container, shelf_.get()));
1068 }
1069
1070 void RootWindowController::CreateContainers() {
1071   // CreateContainer() depends on root_window_layout_manager_.
1072   DCHECK(root_window_layout_manager_);
1073
1074   aura::Window* root = GetRootWindow();
1075
1076   // Add a NOT_DRAWN layer in between the root_window's layer and its current
1077   // children so that we only need to initiate two LayerAnimationSequences for
1078   // fullscreen animations such as the screen rotation animation and the desk
1079   // switch animation. Those animations take a screenshot of this container,
1080   // stack it ontop and animate the screenshot instead of the individual
1081   // elements.
1082   aura::Window* screen_rotation_container =
1083       CreateContainer(kShellWindowId_ScreenAnimationContainer,
1084                       "ScreenAnimationContainer", root);
1085
1086   // Everything that needs to be included in the docked magnifier, when enabled,
1087   // should be a descendant of MagnifiedContainer. The DockedMagnifierContainer
1088   // should not be a descendant of this container, otherwise there would be a
1089   // cycle (docked magnifier trying to magnify itself).
1090   aura::Window* magnified_container =
1091       CreateContainer(kShellWindowId_MagnifiedContainer, "MagnifiedContainer",
1092                       screen_rotation_container);
1093
1094   CreateContainer(kShellWindowId_DockedMagnifierContainer,
1095                   "DockedMagnifierContainer", screen_rotation_container);
1096
1097   // These containers are just used by PowerButtonController to animate groups
1098   // of containers simultaneously without messing up the current transformations
1099   // on those containers. These are direct children of the magnified_container
1100   // window; all of the other containers are their children.
1101
1102   // The wallpaper container is not part of the lock animation, so it is not
1103   // included in those animate groups. When the screen is locked, the wallpaper
1104   // is moved to the lock screen wallpaper container (and moved back on unlock).
1105   // Ensure that there's an opaque layer occluding the non-lock-screen layers.
1106   aura::Window* wallpaper_container =
1107       CreateContainer(kShellWindowId_WallpaperContainer, "WallpaperContainer",
1108                       magnified_container);
1109   ::wm::SetChildWindowVisibilityChangesAnimated(wallpaper_container);
1110   wallpaper_container->SetLayoutManager(
1111       std::make_unique<FillLayoutManager>(wallpaper_container));
1112
1113   if (features::AreGlanceablesEnabled()) {
1114     aura::Window* glanceables_container =
1115         CreateContainer(kShellWindowId_GlanceablesContainer,
1116                         "GlanceablesContainer", magnified_container);
1117     glanceables_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1118     glanceables_container->SetLayoutManager(
1119         std::make_unique<FillLayoutManager>(glanceables_container));
1120   }
1121
1122   aura::Window* non_lock_screen_containers =
1123       CreateContainer(kShellWindowId_NonLockScreenContainersContainer,
1124                       "NonLockScreenContainersContainer", magnified_container);
1125   // Clip all windows inside this container, as half pixel of the window's
1126   // texture may become visible when the screen is scaled. crbug.com/368591.
1127   non_lock_screen_containers->layer()->SetMasksToBounds(true);
1128
1129   aura::Window* lock_wallpaper_container =
1130       CreateContainer(kShellWindowId_LockScreenWallpaperContainer,
1131                       "LockScreenWallpaperContainer", magnified_container);
1132   ::wm::SetChildWindowVisibilityChangesAnimated(lock_wallpaper_container);
1133   lock_wallpaper_container->SetLayoutManager(
1134       std::make_unique<FillLayoutManager>(lock_wallpaper_container));
1135
1136   aura::Window* lock_screen_containers =
1137       CreateContainer(kShellWindowId_LockScreenContainersContainer,
1138                       "LockScreenContainersContainer", magnified_container);
1139   aura::Window* lock_screen_related_containers = CreateContainer(
1140       kShellWindowId_LockScreenRelatedContainersContainer,
1141       "LockScreenRelatedContainersContainer", magnified_container);
1142
1143   aura::Window* app_list_tablet_mode_container =
1144       CreateContainer(kShellWindowId_HomeScreenContainer, "HomeScreenContainer",
1145                       non_lock_screen_containers);
1146   app_list_tablet_mode_container->SetProperty(::wm::kUsesScreenCoordinatesKey,
1147                                               true);
1148
1149   CreateContainer(kShellWindowId_UnparentedContainer, "UnparentedContainer",
1150                   non_lock_screen_containers);
1151
1152   for (const auto& id : desks_util::GetDesksContainersIds()) {
1153     aura::Window* container = CreateContainer(
1154         id, desks_util::GetDeskContainerName(id), non_lock_screen_containers);
1155     ::wm::SetChildWindowVisibilityChangesAnimated(container);
1156     container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1157     container->SetProperty(kForceVisibleInMiniViewKey, true);
1158     window_util::SetChildrenUseExtendedHitRegionForWindow(container);
1159
1160     // Hide the non-active containers.
1161     if (id != desks_util::GetActiveDeskContainerId())
1162       container->Hide();
1163   }
1164
1165   aura::Window* always_on_top_container =
1166       CreateContainer(kShellWindowId_AlwaysOnTopContainer,
1167                       "AlwaysOnTopContainer", non_lock_screen_containers);
1168   ::wm::SetChildWindowVisibilityChangesAnimated(always_on_top_container);
1169   always_on_top_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1170
1171   aura::Window* float_container =
1172       CreateContainer(kShellWindowId_FloatContainer, "FloatContainer",
1173                       non_lock_screen_containers);
1174   wm::SetChildWindowVisibilityChangesAnimated(float_container);
1175   float_container->SetProperty(wm::kUsesScreenCoordinatesKey, true);
1176   window_util::SetChildrenUseExtendedHitRegionForWindow(float_container);
1177
1178   aura::Window* app_list_container =
1179       CreateContainer(kShellWindowId_AppListContainer, "AppListContainer",
1180                       non_lock_screen_containers);
1181   app_list_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1182
1183   aura::Window* pip_container = CreateContainer(
1184       kShellWindowId_PipContainer, "PipContainer", non_lock_screen_containers);
1185   ::wm::SetChildWindowVisibilityChangesAnimated(pip_container);
1186   pip_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1187
1188   aura::Window* arc_ime_parent_container = CreateContainer(
1189       kShellWindowId_ArcImeWindowParentContainer, "ArcImeWindowParentContainer",
1190       non_lock_screen_containers);
1191   arc_ime_parent_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1192   arc_ime_parent_container->SetLayoutManager(
1193       std::make_unique<ArcVirtualKeyboardContainerLayoutManager>(
1194           arc_ime_parent_container));
1195   aura::Window* arc_vk_container =
1196       CreateContainer(kShellWindowId_ArcVirtualKeyboardContainer,
1197                       "ArcVirtualKeyboardContainer", arc_ime_parent_container);
1198   arc_vk_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1199
1200   aura::Window* shelf_container_parent = lock_screen_related_containers;
1201   aura::Window* shelf_container = CreateContainer(
1202       kShellWindowId_ShelfContainer, "ShelfContainer", shelf_container_parent);
1203   shelf_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1204   shelf_container->SetProperty(kLockedToRootKey, true);
1205
1206   aura::Window* shelf_bubble_container =
1207       CreateContainer(kShellWindowId_ShelfBubbleContainer,
1208                       "ShelfBubbleContainer", non_lock_screen_containers);
1209   shelf_bubble_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1210   shelf_bubble_container->SetProperty(kLockedToRootKey, true);
1211
1212   aura::Window* modal_container =
1213       CreateContainer(kShellWindowId_SystemModalContainer,
1214                       "SystemModalContainer", non_lock_screen_containers);
1215   ::wm::SetChildWindowVisibilityChangesAnimated(modal_container);
1216   modal_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1217   window_util::SetChildrenUseExtendedHitRegionForWindow(modal_container);
1218
1219   aura::Window* lock_container =
1220       CreateContainer(kShellWindowId_LockScreenContainer, "LockScreenContainer",
1221                       lock_screen_containers);
1222   lock_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1223
1224   aura::Window* lock_action_handler_container =
1225       CreateContainer(kShellWindowId_LockActionHandlerContainer,
1226                       "LockActionHandlerContainer", lock_screen_containers);
1227   ::wm::SetChildWindowVisibilityChangesAnimated(lock_action_handler_container);
1228   lock_action_handler_container->SetProperty(::wm::kUsesScreenCoordinatesKey,
1229                                              true);
1230
1231   aura::Window* lock_modal_container =
1232       CreateContainer(kShellWindowId_LockSystemModalContainer,
1233                       "LockSystemModalContainer", lock_screen_containers);
1234   ::wm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
1235   lock_modal_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1236   window_util::SetChildrenUseExtendedHitRegionForWindow(lock_modal_container);
1237
1238   aura::Window* power_menu_container =
1239       CreateContainer(kShellWindowId_PowerMenuContainer, "PowerMenuContainer",
1240                       lock_screen_related_containers);
1241   power_menu_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1242
1243   aura::Window* settings_bubble_container =
1244       CreateContainer(kShellWindowId_SettingBubbleContainer,
1245                       "SettingBubbleContainer", lock_screen_related_containers);
1246   ::wm::SetChildWindowVisibilityChangesAnimated(settings_bubble_container);
1247   settings_bubble_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1248   settings_bubble_container->SetProperty(kLockedToRootKey, true);
1249
1250   aura::Window* virtual_keyboard_parent_container = CreateContainer(
1251       kShellWindowId_ImeWindowParentContainer, "ImeWindowParentContainer",
1252       lock_screen_related_containers);
1253   virtual_keyboard_parent_container->SetProperty(
1254       ::wm::kUsesScreenCoordinatesKey, true);
1255   virtual_keyboard_parent_container->SetLayoutManager(
1256       std::make_unique<VirtualKeyboardContainerLayoutManager>(
1257           virtual_keyboard_parent_container));
1258   aura::Window* virtual_keyboard_container = CreateContainer(
1259       kShellWindowId_VirtualKeyboardContainer, "VirtualKeyboardContainer",
1260       virtual_keyboard_parent_container);
1261   virtual_keyboard_container->SetProperty(::wm::kUsesScreenCoordinatesKey,
1262                                           true);
1263   virtual_keyboard_container->SetLayoutManager(
1264       std::make_unique<keyboard::KeyboardLayoutManager>(
1265           keyboard::KeyboardUIController::Get()));
1266
1267   aura::Window* accessibility_panel_container = CreateContainer(
1268       kShellWindowId_AccessibilityPanelContainer, "AccessibilityPanelContainer",
1269       lock_screen_related_containers);
1270   ::wm::SetChildWindowVisibilityChangesAnimated(accessibility_panel_container);
1271   accessibility_panel_container->SetProperty(::wm::kUsesScreenCoordinatesKey,
1272                                              true);
1273   accessibility_panel_container->SetProperty(kLockedToRootKey, true);
1274   accessibility_panel_container->SetLayoutManager(
1275       std::make_unique<AccessibilityPanelLayoutManager>());
1276
1277   aura::Window* menu_container =
1278       CreateContainer(kShellWindowId_MenuContainer, "MenuContainer",
1279                       lock_screen_related_containers);
1280   ::wm::SetChildWindowVisibilityChangesAnimated(menu_container);
1281   menu_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1282
1283   aura::Window* accessibility_bubble_container = CreateContainer(
1284       kShellWindowId_AccessibilityBubbleContainer,
1285       "AccessibilityBubbleContainer", lock_screen_related_containers);
1286   accessibility_bubble_container->SetProperty(::wm::kUsesScreenCoordinatesKey,
1287                                               true);
1288
1289   aura::Window* drag_drop_container = CreateContainer(
1290       kShellWindowId_DragImageAndTooltipContainer,
1291       "DragImageAndTooltipContainer", lock_screen_related_containers);
1292   ::wm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
1293   drag_drop_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1294
1295   aura::Window* overlay_container =
1296       CreateContainer(kShellWindowId_OverlayContainer, "OverlayContainer",
1297                       lock_screen_related_containers);
1298   overlay_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1299   overlay_container->SetLayoutManager(
1300       std::make_unique<OverlayLayoutManager>(overlay_container));
1301
1302   if (chromeos::features::IsAmbientModeEnabled()) {
1303     aura::Window* ambient_container =
1304         CreateContainer(kShellWindowId_AmbientModeContainer,
1305                         "AmbientModeContainer", lock_screen_related_containers);
1306     ::wm::SetChildWindowVisibilityChangesAnimated(ambient_container);
1307     ambient_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1308     ambient_container->SetLayoutManager(
1309         std::make_unique<FillLayoutManager>(ambient_container));
1310   }
1311
1312   aura::Window* mouse_cursor_container =
1313       CreateContainer(kShellWindowId_MouseCursorContainer,
1314                       "MouseCursorContainer", magnified_container);
1315   mouse_cursor_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
1316
1317   aura::Window* always_on_top_wallpaper_container =
1318       CreateContainer(kShellWindowId_AlwaysOnTopWallpaperContainer,
1319                       "AlwaysOnTopWallpaperContainer", magnified_container);
1320   always_on_top_wallpaper_container->SetLayoutManager(
1321       std::make_unique<FillLayoutManager>(always_on_top_wallpaper_container));
1322
1323   CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
1324                   "PowerButtonAnimationContainer", magnified_container);
1325 }
1326
1327 aura::Window* RootWindowController::CreateContainer(int window_id,
1328                                                     const char* name,
1329                                                     aura::Window* parent) {
1330   aura::Window* window =
1331       new aura::Window(nullptr, aura::client::WINDOW_TYPE_UNKNOWN);
1332   window->Init(ui::LAYER_NOT_DRAWN);
1333   window->SetId(window_id);
1334   window->SetName(name);
1335   parent->AddChild(window);
1336   if (window_id != kShellWindowId_UnparentedContainer)
1337     window->Show();
1338   root_window_layout_manager_->AddContainer(window);
1339   return window;
1340 }
1341
1342 void RootWindowController::CreateSystemWallpaper(
1343     RootWindowType root_window_type) {
1344   SkColor color = SK_ColorBLACK;
1345   // The splash screen appears on the primary display at boot. If this is a
1346   // secondary monitor (either connected at boot or connected later) or if the
1347   // browser restarted for a second login then don't use the boot color.
1348   const bool is_boot_splash_screen =
1349       root_window_type == RootWindowType::PRIMARY &&
1350       base::CommandLine::ForCurrentProcess()->HasSwitch(
1351           switches::kFirstExecAfterBoot);
1352   if (is_boot_splash_screen)
1353     color = kChromeOsBootColor;
1354   system_wallpaper_ =
1355       std::make_unique<SystemWallpaperController>(GetRootWindow(), color);
1356 }
1357
1358 AccessibilityPanelLayoutManager*
1359 RootWindowController::GetAccessibilityPanelLayoutManager() const {
1360   aura::Window* container = const_cast<aura::Window*>(
1361       GetContainer(kShellWindowId_AccessibilityPanelContainer));
1362   auto* layout_manager = static_cast<AccessibilityPanelLayoutManager*>(
1363       container->layout_manager());
1364   return layout_manager;
1365 }
1366
1367 void RootWindowController::OnMenuClosed() {
1368   root_window_menu_model_adapter_.reset();
1369   sort_apps_submenu_.reset();
1370   shelf_->UpdateVisibilityState();
1371 }
1372
1373 }  // namespace ash