blob: 8c4317f415fe195dbaa3528624fa3ff97d5cb93e [file] [log] [blame]
[email protected]d90b8392012-06-13 09:34:561// 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
3// found in the LICENSE file.
4
5#include "ash/root_window_controller.h"
6
[email protected]8b3e3d82013-08-20 14:36:307#include <queue>
[email protected]8d625fb2012-07-18 16:40:068#include <vector>
9
[email protected]44d444c2013-01-30 01:47:4410#include "ash/ash_constants.h"
[email protected]e6e41d2f2012-10-29 19:22:1911#include "ash/ash_switches.h"
sky0702b272016-06-03 22:10:4112#include "ash/aura/aura_layout_manager_adapter.h"
13#include "ash/aura/wm_shelf_aura.h"
14#include "ash/aura/wm_window_aura.h"
skyc096d9f2016-06-02 13:46:2615#include "ash/common/root_window_controller_common.h"
jamescook2b624c5a2016-06-08 01:34:0216#include "ash/common/session/session_state_delegate.h"
jamescook1b474d6a2016-06-04 05:56:0017#include "ash/common/shelf/shelf_types.h"
skyc096d9f2016-06-02 13:46:2618#include "ash/common/shell_window_ids.h"
skyd6063772016-06-01 17:52:2119#include "ash/common/wm/always_on_top_controller.h"
20#include "ash/common/wm/container_finder.h"
21#include "ash/common/wm/dock/docked_window_layout_manager.h"
22#include "ash/common/wm/fullscreen_window_finder.h"
23#include "ash/common/wm/panels/panel_layout_manager.h"
skyc096d9f2016-06-02 13:46:2624#include "ash/common/wm/root_window_layout_manager.h"
skyd6063772016-06-01 17:52:2125#include "ash/common/wm/switchable_windows.h"
26#include "ash/common/wm/window_state.h"
skyd6063772016-06-01 17:52:2127#include "ash/common/wm/workspace/workspace_layout_manager.h"
28#include "ash/common/wm/workspace/workspace_layout_manager_delegate.h"
sky0702b272016-06-03 22:10:4129#include "ash/common/wm_shell.h"
30#include "ash/common/wm_window.h"
[email protected]a273d33a2013-10-17 12:41:2131#include "ash/desktop_background/desktop_background_controller.h"
[email protected]b4ddc7a2012-08-07 04:17:3232#include "ash/desktop_background/desktop_background_widget_controller.h"
[email protected]0bf61732013-07-02 04:35:1033#include "ash/desktop_background/user_wallpaper_delegate.h"
[email protected]6bdf7952012-11-14 10:10:5834#include "ash/display/display_manager.h"
[email protected]e74aaf0a2012-10-12 18:42:2835#include "ash/focus_cycler.h"
[email protected]a273d33a2013-10-17 12:41:2136#include "ash/high_contrast/high_contrast_controller.h"
[email protected]f5c9dbc2014-04-11 08:13:4537#include "ash/host/ash_window_tree_host.h"
[email protected]f8e6aad2013-08-30 21:49:1138#include "ash/root_window_settings.h"
[email protected]478c6c32013-03-09 02:50:5839#include "ash/shelf/shelf_layout_manager.h"
[email protected]478c6c32013-03-09 02:50:5840#include "ash/shelf/shelf_widget.h"
[email protected]d90b8392012-06-13 09:34:5641#include "ash/shell.h"
[email protected]e74aaf0a2012-10-12 18:42:2842#include "ash/shell_delegate.h"
[email protected]d90b8392012-06-13 09:34:5643#include "ash/shell_factory.h"
[email protected]e74aaf0a2012-10-12 18:42:2844#include "ash/system/status_area_widget.h"
[email protected]8674b312012-10-12 19:02:4445#include "ash/system/tray/system_tray_delegate.h"
[email protected]a825e8312014-05-05 22:05:0146#include "ash/system/tray/system_tray_notifier.h"
[email protected]2b8a9bb2013-07-01 22:43:4047#include "ash/touch/touch_hud_debug.h"
48#include "ash/touch/touch_hud_projection.h"
[email protected]80549c152013-07-02 01:42:4749#include "ash/touch/touch_observer_hud.h"
[email protected]68d51332014-06-06 13:51:1350#include "ash/wm/lock_layout_manager.h"
[email protected]b8642ec2014-04-17 05:20:3951#include "ash/wm/panels/attached_panel_window_targeter.h"
[email protected]100659412013-06-21 22:59:5552#include "ash/wm/panels/panel_window_event_handler.h"
[email protected]2a2caa02013-01-22 20:50:3653#include "ash/wm/stacking_controller.h"
[email protected]e74aaf0a2012-10-12 18:42:2854#include "ash/wm/status_area_layout_manager.h"
[email protected]e6e41d2f2012-10-29 19:22:1955#include "ash/wm/system_background_controller.h"
[email protected]d90b8392012-06-13 09:34:5656#include "ash/wm/system_modal_container_layout_manager.h"
[email protected]8d625fb2012-07-18 16:40:0657#include "ash/wm/window_properties.h"
sky8d5646fe2016-04-15 17:03:4658#include "ash/wm/window_state_aura.h"
[email protected]700849f2013-04-30 17:49:2059#include "ash/wm/window_util.h"
[email protected]d90b8392012-06-13 09:34:5660#include "ash/wm/workspace_controller.h"
[email protected]e6e41d2f2012-10-29 19:22:1961#include "base/command_line.h"
jonrossa90d8982016-05-16 18:14:2562#include "base/macros.h"
sky1e30f062016-04-14 21:19:1663#include "base/memory/ptr_util.h"
[email protected]1e84c632013-06-27 23:12:2164#include "base/time/time.h"
[email protected]f1853122012-06-27 16:21:2665#include "ui/aura/client/aura_constants.h"
[email protected]2374d1812014-03-04 03:42:2766#include "ui/aura/client/screen_position_client.h"
[email protected]f1853122012-06-27 16:21:2667#include "ui/aura/window.h"
[email protected]cf6fea22013-08-07 14:24:0168#include "ui/aura/window_delegate.h"
[email protected]fcc51c952014-02-21 21:31:2669#include "ui/aura/window_event_dispatcher.h"
[email protected]f1853122012-06-27 16:21:2670#include "ui/aura/window_observer.h"
[email protected]8b3e3d82013-08-20 14:36:3071#include "ui/aura/window_tracker.h"
[email protected]cf6fea22013-08-07 14:24:0172#include "ui/base/hit_test.h"
[email protected]431552c2012-10-23 00:38:3373#include "ui/base/models/menu_model.h"
oshimaf84b0da722016-04-27 19:47:1974#include "ui/display/display.h"
75#include "ui/display/screen.h"
[email protected]86459e2c2013-04-10 13:39:2476#include "ui/keyboard/keyboard_controller.h"
77#include "ui/keyboard/keyboard_util.h"
jonrossa90d8982016-05-16 18:14:2578#include "ui/views/controls/menu/menu_model_adapter.h"
[email protected]431552c2012-10-23 00:38:3379#include "ui/views/controls/menu/menu_runner.h"
80#include "ui/views/view_model.h"
81#include "ui/views/view_model_utils.h"
[email protected]ee3ed10772014-03-11 22:02:0182#include "ui/wm/core/capture_controller.h"
83#include "ui/wm/core/visibility_controller.h"
84#include "ui/wm/core/window_util.h"
[email protected]af4552b22014-03-21 19:45:0185#include "ui/wm/public/drag_drop_client.h"
86#include "ui/wm/public/tooltip_client.h"
[email protected]5b251f12013-12-19 01:50:0587#include "ui/wm/public/window_types.h"
[email protected]d90b8392012-06-13 09:34:5688
[email protected]252eb232013-08-14 22:09:2789#if defined(OS_CHROMEOS)
[email protected]7d487592014-07-24 03:54:5090#include "ash/ash_touch_exploration_manager_chromeos.h"
[email protected]252eb232013-08-14 22:09:2791#include "ash/wm/boot_splash_screen_chromeos.h"
[email protected]a825e8312014-05-05 22:05:0192#include "ui/chromeos/touch_exploration_controller.h"
[email protected]252eb232013-08-14 22:09:2793#endif
94
[email protected]d90b8392012-06-13 09:34:5695namespace ash {
96namespace {
97
[email protected]252eb232013-08-14 22:09:2798#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:4999// Duration for the animation that hides the boot splash screen, in
100// milliseconds. This should be short enough in relation to
101// wm/window_animation.cc's brightness/grayscale fade animation that the login
102// background image animation isn't hidden by the splash screen animation.
103const int kBootSplashScreenHideDurationMs = 500;
[email protected]252eb232013-08-14 22:09:27104#endif
[email protected]bca9a7e2012-11-10 06:25:49105
[email protected]2816c2462013-12-17 02:22:25106float ToRelativeValue(int value, int src, int dst) {
107 return static_cast<float>(value) / static_cast<float>(src) * dst;
108}
109
110void MoveOriginRelativeToSize(const gfx::Size& src_size,
111 const gfx::Size& dst_size,
112 gfx::Rect* bounds_in_out) {
113 gfx::Point origin = bounds_in_out->origin();
114 bounds_in_out->set_origin(gfx::Point(
115 ToRelativeValue(origin.x(), src_size.width(), dst_size.width()),
116 ToRelativeValue(origin.y(), src_size.height(), dst_size.height())));
117}
118
[email protected]95058572012-08-20 14:57:29119// Reparents |window| to |new_parent|.
120void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
[email protected]2816c2462013-12-17 02:22:25121 const gfx::Size src_size = window->parent()->bounds().size();
122 const gfx::Size dst_size = new_parent->bounds().size();
[email protected]95058572012-08-20 14:57:29123 // Update the restore bounds to make it relative to the display.
[email protected]a41b4e12013-09-20 04:36:34124 wm::WindowState* state = wm::GetWindowState(window);
125 gfx::Rect restore_bounds;
126 bool has_restore_bounds = state->HasRestoreBounds();
[email protected]2816c2462013-12-17 02:22:25127
[email protected]9cfd3d12014-02-25 15:33:45128 bool update_bounds = (state->IsNormalOrSnapped() || state->IsMinimized()) &&
[email protected]093b8d642014-04-03 20:59:28129 new_parent->id() != kShellWindowId_DockedContainer;
[email protected]2816c2462013-12-17 02:22:25130 gfx::Rect local_bounds;
131 if (update_bounds) {
sky0702b272016-06-03 22:10:41132 local_bounds = WmWindowAura::GetAuraWindow(state->window())->bounds();
[email protected]2816c2462013-12-17 02:22:25133 MoveOriginRelativeToSize(src_size, dst_size, &local_bounds);
134 }
135
136 if (has_restore_bounds) {
[email protected]a41b4e12013-09-20 04:36:34137 restore_bounds = state->GetRestoreBoundsInParent();
[email protected]2816c2462013-12-17 02:22:25138 MoveOriginRelativeToSize(src_size, dst_size, &restore_bounds);
139 }
140
[email protected]95058572012-08-20 14:57:29141 new_parent->AddChild(window);
[email protected]2816c2462013-12-17 02:22:25142
[email protected]8663b7a62014-01-18 01:24:21143 // Docked windows have bounds handled by the layout manager in AddChild().
[email protected]2816c2462013-12-17 02:22:25144 if (update_bounds)
145 window->SetBounds(local_bounds);
146
[email protected]a41b4e12013-09-20 04:36:34147 if (has_restore_bounds)
148 state->SetRestoreBoundsInParent(restore_bounds);
[email protected]95058572012-08-20 14:57:29149}
150
151// Reparents the appropriate set of windows from |src| to |dst|.
[email protected]bf9cdb362013-10-25 19:22:45152void ReparentAllWindows(aura::Window* src, aura::Window* dst) {
[email protected]95058572012-08-20 14:57:29153 // Set of windows to move.
[email protected]f1853122012-06-27 16:21:26154 const int kContainerIdsToMove[] = {
[email protected]093b8d642014-04-03 20:59:28155 kShellWindowId_DefaultContainer,
156 kShellWindowId_DockedContainer,
157 kShellWindowId_PanelContainer,
158 kShellWindowId_AlwaysOnTopContainer,
159 kShellWindowId_SystemModalContainer,
160 kShellWindowId_LockSystemModalContainer,
tengsf98986c2014-12-06 01:42:21161 kShellWindowId_UnparentedControlContainer,
oshima022a9542015-05-01 00:15:02162 kShellWindowId_OverlayContainer,
163 };
164 const int kExtraContainerIdsToMoveInUnifiedMode[] = {
165 kShellWindowId_LockScreenContainer,
166 kShellWindowId_LockScreenBackgroundContainer,
167 };
168 std::vector<int> container_ids(
169 kContainerIdsToMove,
170 kContainerIdsToMove + arraysize(kContainerIdsToMove));
171 // Check the default_multi_display_mode because this is also necessary
172 // in trasition between mirror <-> unified mode.
oshima628a6172015-08-01 01:33:14173 if (Shell::GetInstance()
174 ->display_manager()
175 ->current_default_multi_display_mode() == DisplayManager::UNIFIED) {
oshima022a9542015-05-01 00:15:02176 for (int id : kExtraContainerIdsToMoveInUnifiedMode)
177 container_ids.push_back(id);
178 }
179
180 for (int id : container_ids) {
[email protected]f1853122012-06-27 16:21:26181 aura::Window* src_container = Shell::GetContainer(src, id);
182 aura::Window* dst_container = Shell::GetContainer(dst, id);
[email protected]5b6021902013-02-26 05:33:29183 while (!src_container->children().empty()) {
184 // Restart iteration from the source container windows each time as they
185 // may change as a result of moving other windows.
186 aura::Window::Windows::const_iterator iter =
187 src_container->children().begin();
188 while (iter != src_container->children().end() &&
[email protected]093b8d642014-04-03 20:59:28189 SystemModalContainerLayoutManager::IsModalBackground(*iter)) {
[email protected]5b6021902013-02-26 05:33:29190 ++iter;
191 }
192 // If the entire window list is modal background windows then stop.
193 if (iter == src_container->children().end())
194 break;
195 ReparentWindow(*iter, dst_container);
[email protected]f1853122012-06-27 16:21:26196 }
197 }
198}
199
[email protected]cf6fea22013-08-07 14:24:01200// A window delegate which does nothing. Used to create a window that
201// is a event target, but do nothing.
202class EmptyWindowDelegate : public aura::WindowDelegate {
203 public:
204 EmptyWindowDelegate() {}
dcheng1f4538e2014-10-27 23:57:05205 ~EmptyWindowDelegate() override {}
[email protected]cf6fea22013-08-07 14:24:01206
207 // aura::WindowDelegate overrides:
dcheng1f4538e2014-10-27 23:57:05208 gfx::Size GetMinimumSize() const override { return gfx::Size(); }
209 gfx::Size GetMaximumSize() const override { return gfx::Size(); }
210 void OnBoundsChanged(const gfx::Rect& old_bounds,
211 const gfx::Rect& new_bounds) override {}
212 gfx::NativeCursor GetCursor(const gfx::Point& point) override {
[email protected]62c9f102014-03-27 06:07:04213 return gfx::kNullCursor;
214 }
dcheng1f4538e2014-10-27 23:57:05215 int GetNonClientComponent(const gfx::Point& point) const override {
[email protected]cf6fea22013-08-07 14:24:01216 return HTNOWHERE;
217 }
dcheng1f4538e2014-10-27 23:57:05218 bool ShouldDescendIntoChildForEventHandling(
[email protected]cf6fea22013-08-07 14:24:01219 aura::Window* child,
mostynb10d6b382014-10-03 16:23:45220 const gfx::Point& location) override {
[email protected]cf6fea22013-08-07 14:24:01221 return false;
222 }
dcheng1f4538e2014-10-27 23:57:05223 bool CanFocus() override { return false; }
224 void OnCaptureLost() override {}
danakj85d970e2015-04-04 00:15:24225 void OnPaint(const ui::PaintContext& context) override {}
dcheng1f4538e2014-10-27 23:57:05226 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
227 void OnWindowDestroying(aura::Window* window) override {}
228 void OnWindowDestroyed(aura::Window* window) override { delete this; }
229 void OnWindowTargetVisibilityChanged(bool visible) override {}
230 bool HasHitTestMask() const override { return false; }
231 void GetHitTestMask(gfx::Path* mask) const override {}
[email protected]cf6fea22013-08-07 14:24:01232
233 private:
234 DISALLOW_COPY_AND_ASSIGN(EmptyWindowDelegate);
235};
236
sky1e30f062016-04-14 21:19:16237class WorkspaceLayoutManagerDelegateImpl
238 : public wm::WorkspaceLayoutManagerDelegate {
239 public:
240 explicit WorkspaceLayoutManagerDelegateImpl(aura::Window* root_window)
241 : root_window_(root_window) {}
242 ~WorkspaceLayoutManagerDelegateImpl() override = default;
243
244 void set_shelf(ShelfLayoutManager* shelf) { shelf_ = shelf; }
245
246 // WorkspaceLayoutManagerDelegate:
247 void UpdateShelfVisibility() override {
248 if (shelf_)
249 shelf_->UpdateVisibilityState();
250 }
251 void OnFullscreenStateChanged(bool is_fullscreen) override {
252 if (shelf_) {
sky80556bc42016-06-07 22:46:13253 ash::Shell::GetInstance()->NotifyFullscreenStateChange(
254 is_fullscreen, WmWindowAura::Get(root_window_));
sky1e30f062016-04-14 21:19:16255 }
256 }
257
258 private:
259 aura::Window* root_window_;
260 ShelfLayoutManager* shelf_ = nullptr;
261
262 DISALLOW_COPY_AND_ASSIGN(WorkspaceLayoutManagerDelegateImpl);
263};
264
[email protected]d90b8392012-06-13 09:34:56265} // namespace
266
[email protected]f5c9dbc2014-04-11 08:13:45267void RootWindowController::CreateForPrimaryDisplay(AshWindowTreeHost* host) {
[email protected]2f2620332014-02-28 10:07:38268 RootWindowController* controller = new RootWindowController(host);
[email protected]608de6c2013-10-29 00:14:28269 controller->Init(RootWindowController::PRIMARY,
[email protected]a273d33a2013-10-17 12:41:21270 Shell::GetInstance()->delegate()->IsFirstRunAfterBoot());
[email protected]d90b8392012-06-13 09:34:56271}
272
[email protected]f5c9dbc2014-04-11 08:13:45273void RootWindowController::CreateForSecondaryDisplay(AshWindowTreeHost* host) {
[email protected]2f2620332014-02-28 10:07:38274 RootWindowController* controller = new RootWindowController(host);
[email protected]608de6c2013-10-29 00:14:28275 controller->Init(RootWindowController::SECONDARY, false /* first run */);
276}
277
[email protected]88d71122012-10-18 07:11:01278// static
[email protected]ccff3d72013-02-06 04:26:28279RootWindowController* RootWindowController::ForWindow(
280 const aura::Window* window) {
oshima9eea82da2014-09-13 01:11:07281 CHECK(Shell::HasInstance());
[email protected]a0afeb12012-12-10 22:57:09282 return GetRootWindowController(window->GetRootWindow());
283}
284
285// static
[email protected]d17642d2013-09-12 23:44:38286RootWindowController* RootWindowController::ForTargetRootWindow() {
oshima9eea82da2014-09-13 01:11:07287 CHECK(Shell::HasInstance());
[email protected]093b8d642014-04-03 20:59:28288 return GetRootWindowController(Shell::GetTargetRootWindow());
[email protected]a0afeb12012-12-10 22:57:09289}
290
[email protected]a273d33a2013-10-17 12:41:21291RootWindowController::~RootWindowController() {
292 Shutdown();
[email protected]f5c9dbc2014-04-11 08:13:45293 ash_host_.reset();
[email protected]a273d33a2013-10-17 12:41:21294 // The CaptureClient needs to be around for as long as the RootWindow is
295 // valid.
296 capture_client_.reset();
297}
298
[email protected]f5c9dbc2014-04-11 08:13:45299aura::WindowTreeHost* RootWindowController::GetHost() {
300 return ash_host_->AsWindowTreeHost();
301}
302
303const aura::WindowTreeHost* RootWindowController::GetHost() const {
304 return ash_host_->AsWindowTreeHost();
305}
306
307aura::Window* RootWindowController::GetRootWindow() {
308 return GetHost()->window();
309}
310
311const aura::Window* RootWindowController::GetRootWindow() const {
312 return GetHost()->window();
313}
314
[email protected]0bf61732013-07-02 04:35:10315void RootWindowController::SetWallpaperController(
316 DesktopBackgroundWidgetController* controller) {
317 wallpaper_controller_.reset(controller);
318}
319
320void RootWindowController::SetAnimatingWallpaperController(
321 AnimatingDesktopController* controller) {
322 if (animating_wallpaper_controller_.get())
323 animating_wallpaper_controller_->StopAnimating();
324 animating_wallpaper_controller_.reset(controller);
325}
326
[email protected]6675e1c2012-09-11 09:15:45327void RootWindowController::Shutdown() {
[email protected]a825e8312014-05-05 22:05:01328 Shell* shell = Shell::GetInstance();
329 shell->RemoveShellObserver(this);
330
331#if defined(OS_CHROMEOS)
[email protected]7d487592014-07-24 03:54:50332 if (touch_exploration_manager_) {
333 touch_exploration_manager_.reset();
[email protected]a825e8312014-05-05 22:05:01334 }
335#endif
[email protected]d141b922013-07-09 08:13:17336
[email protected]0bf61732013-07-02 04:35:10337 if (animating_wallpaper_controller_.get())
338 animating_wallpaper_controller_->StopAnimating();
339 wallpaper_controller_.reset();
340 animating_wallpaper_controller_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45341 aura::Window* root_window = GetRootWindow();
[email protected]d17642d2013-09-12 23:44:38342 // Change the target root window before closing child windows. If any child
[email protected]c98a4922013-09-05 20:01:42343 // being removed triggers a relayout of the shelf it will try to build a
[email protected]d17642d2013-09-12 23:44:38344 // window list adding windows from the target root window's containers which
[email protected]c98a4922013-09-05 20:01:42345 // may have already gone away.
[email protected]f5c9dbc2014-04-11 08:13:45346 if (Shell::GetTargetRootWindow() == root_window) {
[email protected]a825e8312014-05-05 22:05:01347 shell->set_target_root_window(
[email protected]f5c9dbc2014-04-11 08:13:45348 Shell::GetPrimaryRootWindow() == root_window
349 ? NULL
350 : Shell::GetPrimaryRootWindow());
[email protected]f634dd32012-07-23 22:49:07351 }
[email protected]c98a4922013-09-05 20:01:42352
353 CloseChildWindows();
[email protected]f5c9dbc2014-04-11 08:13:45354 GetRootWindowSettings(root_window)->controller = NULL;
[email protected]d90b8392012-06-13 09:34:56355 workspace_controller_.reset();
[email protected]6675e1c2012-09-11 09:15:45356 // Forget with the display ID so that display lookup
357 // ends up with invalid display.
[email protected]f5c9dbc2014-04-11 08:13:45358 GetRootWindowSettings(root_window)->display_id =
oshimaf84b0da722016-04-27 19:47:19359 display::Display::kInvalidDisplayID;
[email protected]8f5209c2014-05-22 20:36:11360 ash_host_->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28361
[email protected]956a6a42012-10-29 23:58:10362 system_background_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45363 aura::client::SetScreenPositionClient(root_window, NULL);
[email protected]d90b8392012-06-13 09:34:56364}
365
[email protected]c0ce80e2012-10-05 23:28:27366SystemModalContainerLayoutManager*
[email protected]8674b312012-10-12 19:02:44367RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
[email protected]a5c78802013-12-12 22:07:01368 aura::Window* modal_container = NULL;
[email protected]8674b312012-10-12 19:02:44369 if (window) {
sky0702b272016-06-03 22:10:41370 aura::Window* window_container = WmWindowAura::GetAuraWindow(
371 wm::GetContainerForWindow(WmWindowAura::Get(window)));
[email protected]a5c78802013-12-12 22:07:01372 if (window_container &&
373 window_container->id() >= kShellWindowId_LockScreenContainer) {
374 modal_container = GetContainer(kShellWindowId_LockSystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35375 } else {
[email protected]a5c78802013-12-12 22:07:01376 modal_container = GetContainer(kShellWindowId_SystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35377 }
[email protected]8674b312012-10-12 19:02:44378 } else {
[email protected]a44afbbd2013-07-24 21:49:35379 int modal_window_id = Shell::GetInstance()->session_state_delegate()
380 ->IsUserSessionBlocked() ? kShellWindowId_LockSystemModalContainer :
381 kShellWindowId_SystemModalContainer;
[email protected]a5c78802013-12-12 22:07:01382 modal_container = GetContainer(modal_window_id);
[email protected]8674b312012-10-12 19:02:44383 }
[email protected]a5c78802013-12-12 22:07:01384 return modal_container ? static_cast<SystemModalContainerLayoutManager*>(
385 modal_container->layout_manager()) : NULL;
[email protected]c0ce80e2012-10-05 23:28:27386}
387
[email protected]d90b8392012-06-13 09:34:56388aura::Window* RootWindowController::GetContainer(int container_id) {
[email protected]f5c9dbc2014-04-11 08:13:45389 return GetRootWindow()->GetChildById(container_id);
[email protected]d90b8392012-06-13 09:34:56390}
391
[email protected]d8a24952013-08-05 20:05:05392const aura::Window* RootWindowController::GetContainer(int container_id) const {
[email protected]f5c9dbc2014-04-11 08:13:45393 return ash_host_->AsWindowTreeHost()->window()->GetChildById(container_id);
[email protected]d8a24952013-08-05 20:05:05394}
395
[email protected]864b58552013-12-19 04:19:38396void RootWindowController::ShowShelf() {
jamescook612205f2016-05-26 06:02:11397 if (!shelf_widget_->shelf())
[email protected]e74aaf0a2012-10-12 18:42:28398 return;
jamescook612205f2016-05-26 06:02:11399 shelf_widget_->shelf()->SetVisible(true);
400 shelf_widget_->status_area_widget()->Show();
[email protected]e74aaf0a2012-10-12 18:42:28401}
402
jamescook6500ad132016-05-27 06:15:54403void RootWindowController::CreateShelf() {
404 if (shelf_widget_->shelf())
405 return;
jamescookbe6ed822016-06-06 20:08:55406 shelf_widget_->CreateShelf(wm_shelf_aura_.get());
jamescook6500ad132016-05-27 06:15:54407
[email protected]756bda12013-07-03 08:17:06408 if (panel_layout_manager_)
jamescookbe6ed822016-06-06 20:08:55409 panel_layout_manager_->SetShelf(wm_shelf_aura_.get());
[email protected]7115bd32013-07-19 08:25:39410 if (docked_layout_manager_) {
jamescookbe6ed822016-06-06 20:08:55411 docked_layout_manager_->SetShelf(wm_shelf_aura_.get());
jamescook612205f2016-05-26 06:02:11412 if (shelf_widget_->shelf_layout_manager())
413 docked_layout_manager_->AddObserver(
414 shelf_widget_->shelf_layout_manager());
[email protected]7115bd32013-07-19 08:25:39415 }
[email protected]b8642ec2014-04-17 05:20:39416
417 // Notify shell observers that the shelf has been created.
sky80556bc42016-06-07 22:46:13418 Shell::GetInstance()->OnShelfCreatedForRootWindow(
419 WmWindowAura::Get(GetRootWindow()));
jamescook6500ad132016-05-27 06:15:54420
421 shelf_widget_->PostCreateShelf();
[email protected]756bda12013-07-03 08:17:06422}
423
jamescook6afad6d2016-06-01 00:35:01424Shelf* RootWindowController::GetShelf() const {
425 // TODO(jamescook): Shelf should be owned by this class, not by ShelfWidget.
426 return shelf_widget_->shelf();
427}
428
[email protected]16059276d2012-10-22 18:59:50429void RootWindowController::UpdateAfterLoginStatusChange(
430 user::LoginStatus status) {
[email protected]cf6fea22013-08-07 14:24:01431 if (status != user::LOGGED_IN_NONE)
432 mouse_event_target_.reset();
jamescook612205f2016-05-26 06:02:11433 if (shelf_widget_->status_area_widget())
434 shelf_widget_->status_area_widget()->UpdateAfterLoginStatusChange(status);
[email protected]16059276d2012-10-22 18:59:50435}
436
[email protected]bca9a7e2012-11-10 06:25:49437void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
[email protected]252eb232013-08-14 22:09:27438#if defined(OS_CHROMEOS)
pgal.u-szegedd84534d32014-10-29 12:34:30439 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]bca9a7e2012-11-10 06:25:49440 switches::kAshAnimateFromBootSplashScreen) &&
441 boot_splash_screen_.get()) {
442 // Make the splash screen fade out so it doesn't obscure the desktop
443 // wallpaper's brightness/grayscale animation.
444 boot_splash_screen_->StartHideAnimation(
445 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
446 }
[email protected]252eb232013-08-14 22:09:27447#endif
[email protected]bca9a7e2012-11-10 06:25:49448}
449
[email protected]0bf61732013-07-02 04:35:10450void RootWindowController::OnWallpaperAnimationFinished(views::Widget* widget) {
451 // Make sure the wallpaper is visible.
[email protected]bca9a7e2012-11-10 06:25:49452 system_background_->SetColor(SK_ColorBLACK);
[email protected]252eb232013-08-14 22:09:27453#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:49454 boot_splash_screen_.reset();
[email protected]252eb232013-08-14 22:09:27455#endif
[email protected]0bf61732013-07-02 04:35:10456
457 Shell::GetInstance()->user_wallpaper_delegate()->
458 OnWallpaperAnimationFinished();
459 // Only removes old component when wallpaper animation finished. If we
460 // remove the old one before the new wallpaper is done fading in there will
461 // be a white flash during the animation.
462 if (animating_wallpaper_controller()) {
463 DesktopBackgroundWidgetController* controller =
464 animating_wallpaper_controller()->GetController(true);
465 // |desktop_widget_| should be the same animating widget we try to move
466 // to |kDesktopController|. Otherwise, we may close |desktop_widget_|
467 // before move it to |kDesktopController|.
468 DCHECK_EQ(controller->widget(), widget);
469 // Release the old controller and close its background widget.
470 SetWallpaperController(controller);
471 }
[email protected]697f04c2012-10-03 01:15:10472}
473
[email protected]d90b8392012-06-13 09:34:56474void RootWindowController::CloseChildWindows() {
[email protected]cf6fea22013-08-07 14:24:01475 mouse_event_target_.reset();
476
[email protected]2a57beb52014-06-09 20:02:26477 // Remove observer as deactivating keyboard causes |docked_layout_manager_|
478 // to fire notifications.
jamescook612205f2016-05-26 06:02:11479 if (docked_layout_manager_ && shelf_widget_ &&
480 shelf_widget_->shelf_layout_manager())
481 docked_layout_manager_->RemoveObserver(
482 shelf_widget_->shelf_layout_manager());
[email protected]2a57beb52014-06-09 20:02:26483
[email protected]b6ba05d902013-10-04 21:38:45484 // Deactivate keyboard container before closing child windows and shutting
485 // down associated layout managers.
[email protected]a0b3fb882014-04-07 19:26:03486 DeactivateKeyboard(keyboard::KeyboardController::GetInstance());
[email protected]b6ba05d902013-10-04 21:38:45487
[email protected]79a87b7e2013-01-25 05:08:22488 // panel_layout_manager_ needs to be shut down before windows are destroyed.
489 if (panel_layout_manager_) {
490 panel_layout_manager_->Shutdown();
491 panel_layout_manager_ = NULL;
492 }
[email protected]7115bd32013-07-19 08:25:39493 // docked_layout_manager_ needs to be shut down before windows are destroyed.
494 if (docked_layout_manager_) {
[email protected]7115bd32013-07-19 08:25:39495 docked_layout_manager_->Shutdown();
496 docked_layout_manager_ = NULL;
497 }
[email protected]f5c9dbc2014-04-11 08:13:45498 aura::Window* root_window = GetRootWindow();
499 aura::client::SetDragDropClient(root_window, NULL);
[email protected]8b3e3d82013-08-20 14:36:30500
jamescook612205f2016-05-26 06:02:11501 if (shelf_widget_)
502 shelf_widget_->Shutdown();
[email protected]e74aaf0a2012-10-12 18:42:28503
jamescookbe6ed822016-06-06 20:08:55504 wm_shelf_aura_->Shutdown();
505
[email protected]d90b8392012-06-13 09:34:56506 // Close background widget first as it depends on tooltip.
[email protected]0bf61732013-07-02 04:35:10507 wallpaper_controller_.reset();
508 animating_wallpaper_controller_.reset();
[email protected]b4ddc7a2012-08-07 04:17:32509
[email protected]d90b8392012-06-13 09:34:56510 workspace_controller_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45511 aura::client::SetTooltipClient(root_window, NULL);
[email protected]d90b8392012-06-13 09:34:56512
[email protected]0fbfa972013-10-02 19:23:33513 // Explicitly destroy top level windows. We do this as during part of
514 // destruction such windows may query the RootWindow for state.
oshimaf38efa92015-10-27 19:06:52515 aura::WindowTracker non_toplevel_windows;
516 non_toplevel_windows.Add(root_window);
517 while (!non_toplevel_windows.windows().empty()) {
518 const aura::Window* non_toplevel_window =
519 *non_toplevel_windows.windows().begin();
520 non_toplevel_windows.Remove(const_cast<aura::Window*>(non_toplevel_window));
[email protected]8b3e3d82013-08-20 14:36:30521 aura::WindowTracker toplevel_windows;
522 for (size_t i = 0; i < non_toplevel_window->children().size(); ++i) {
523 aura::Window* child = non_toplevel_window->children()[i];
[email protected]0fbfa972013-10-02 19:23:33524 if (!child->owned_by_parent())
525 continue;
[email protected]8b3e3d82013-08-20 14:36:30526 if (child->delegate())
527 toplevel_windows.Add(child);
528 else
oshimaf38efa92015-10-27 19:06:52529 non_toplevel_windows.Add(child);
[email protected]8b3e3d82013-08-20 14:36:30530 }
531 while (!toplevel_windows.windows().empty())
532 delete *toplevel_windows.windows().begin();
[email protected]d90b8392012-06-13 09:34:56533 }
[email protected]8b3e3d82013-08-20 14:36:30534 // And then remove the containers.
[email protected]f5c9dbc2014-04-11 08:13:45535 while (!root_window->children().empty()) {
536 aura::Window* window = root_window->children()[0];
[email protected]0fbfa972013-10-02 19:23:33537 if (window->owned_by_parent()) {
538 delete window;
539 } else {
[email protected]f5c9dbc2014-04-11 08:13:45540 root_window->RemoveChild(window);
[email protected]0fbfa972013-10-02 19:23:33541 }
542 }
[email protected]478c6c32013-03-09 02:50:58543
jamescook612205f2016-05-26 06:02:11544 shelf_widget_.reset();
[email protected]d90b8392012-06-13 09:34:56545}
546
[email protected]bf9cdb362013-10-25 19:22:45547void RootWindowController::MoveWindowsTo(aura::Window* dst) {
[email protected]8039e06c2013-01-17 23:34:50548 // Forget the shelf early so that shelf don't update itself using wrong
549 // display info.
sky1e30f062016-04-14 21:19:16550 workspace_controller_->SetShelf(nullptr);
551 workspace_controller_->layout_manager()->DeleteDelegate();
[email protected]f5c9dbc2014-04-11 08:13:45552 ReparentAllWindows(GetRootWindow(), dst);
[email protected]f1853122012-06-27 16:21:26553}
554
[email protected]478c6c32013-03-09 02:50:58555ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
jamescook612205f2016-05-26 06:02:11556 return shelf_widget_->shelf_layout_manager();
[email protected]478c6c32013-03-09 02:50:58557}
558
[email protected]a0afeb12012-12-10 22:57:09559SystemTray* RootWindowController::GetSystemTray() {
560 // We assume in throughout the code that this will not return NULL. If code
561 // triggers this for valid reasons, it should test status_area_widget first.
jamescook612205f2016-05-26 06:02:11562 CHECK(shelf_widget_->status_area_widget());
563 return shelf_widget_->status_area_widget()->system_tray();
[email protected]a0afeb12012-12-10 22:57:09564}
565
[email protected]940fb1c2013-06-18 16:54:28566void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
567 ui::MenuSourceType source_type) {
msw141c6b22016-03-04 00:55:30568 ShellDelegate* delegate = Shell::GetInstance()->delegate();
569 DCHECK(delegate);
jamescook612205f2016-05-26 06:02:11570 menu_model_.reset(
571 delegate->CreateContextMenu(shelf_widget_->shelf(), nullptr));
jonrossa90d8982016-05-16 18:14:25572 if (!menu_model_)
[email protected]8e837ec2013-01-31 01:48:33573 return;
[email protected]431552c2012-10-23 00:38:33574
jonrossa90d8982016-05-16 18:14:25575 menu_model_adapter_.reset(new views::MenuModelAdapter(
576 menu_model_.get(),
577 base::Bind(&RootWindowController::OnMenuClosed, base::Unretained(this))));
578
[email protected]6175fc42013-04-05 05:58:58579 // Background controller may not be set yet if user clicked on status are
580 // before initial animation completion. See crbug.com/222218
[email protected]0bf61732013-07-02 04:35:10581 if (!wallpaper_controller_.get())
[email protected]431552c2012-10-23 00:38:33582 return;
583
jonrossa90d8982016-05-16 18:14:25584 menu_runner_.reset(new views::MenuRunner(
585 menu_model_adapter_->CreateMenu(),
586 views::MenuRunner::CONTEXT_MENU | views::MenuRunner::ASYNC));
587 ignore_result(
588 menu_runner_->RunMenuAt(wallpaper_controller_->widget(), NULL,
589 gfx::Rect(location_in_screen, gfx::Size()),
590 views::MENU_ANCHOR_TOPLEFT, source_type));
[email protected]431552c2012-10-23 00:38:33591}
592
[email protected]e74aaf0a2012-10-12 18:42:28593void RootWindowController::UpdateShelfVisibility() {
jamescook612205f2016-05-26 06:02:11594 shelf_widget_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]e74aaf0a2012-10-12 18:42:28595}
596
varkhad99fa94f2015-06-29 22:35:46597aura::Window* RootWindowController::GetWindowForFullscreenMode() {
sky0702b272016-06-03 22:10:41598 return WmWindowAura::GetAuraWindow(
599 wm::GetWindowForFullscreenMode(WmWindowAura::Get(GetRootWindow())));
[email protected]2ee2f5d2013-01-10 23:37:16600}
601
[email protected]b6ba05d902013-10-04 21:38:45602void RootWindowController::ActivateKeyboard(
603 keyboard::KeyboardController* keyboard_controller) {
604 if (!keyboard::IsKeyboardEnabled() ||
605 GetContainer(kShellWindowId_VirtualKeyboardContainer)) {
606 return;
607 }
608 DCHECK(keyboard_controller);
jamescook612205f2016-05-26 06:02:11609 keyboard_controller->AddObserver(shelf_widget()->shelf_layout_manager());
bshe9858b4a2014-09-16 20:46:38610 keyboard_controller->AddObserver(panel_layout_manager_);
611 keyboard_controller->AddObserver(docked_layout_manager_);
612 keyboard_controller->AddObserver(workspace_controller_->layout_manager());
rsadam7bd510bb2014-12-09 20:10:56613 keyboard_controller->AddObserver(
614 always_on_top_controller_->GetLayoutManager());
bshe9858b4a2014-09-16 20:46:38615 Shell::GetInstance()->delegate()->VirtualKeyboardActivated(true);
bshec3875422014-09-29 13:21:30616 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]b2da9b602014-03-05 18:39:52617 DCHECK(parent);
[email protected]b6ba05d902013-10-04 21:38:45618 aura::Window* keyboard_container =
619 keyboard_controller->GetContainerWindow();
620 keyboard_container->set_id(kShellWindowId_VirtualKeyboardContainer);
621 parent->AddChild(keyboard_container);
[email protected]b6ba05d902013-10-04 21:38:45622}
[email protected]86459e2c2013-04-10 13:39:24623
[email protected]b6ba05d902013-10-04 21:38:45624void RootWindowController::DeactivateKeyboard(
625 keyboard::KeyboardController* keyboard_controller) {
[email protected]e1b299b2014-01-29 23:53:41626 if (!keyboard_controller ||
627 !keyboard_controller->keyboard_container_initialized()) {
[email protected]b6ba05d902013-10-04 21:38:45628 return;
[email protected]e1b299b2014-01-29 23:53:41629 }
[email protected]b6ba05d902013-10-04 21:38:45630 aura::Window* keyboard_container =
631 keyboard_controller->GetContainerWindow();
[email protected]f5c9dbc2014-04-11 08:13:45632 if (keyboard_container->GetRootWindow() == GetRootWindow()) {
bshec3875422014-09-29 13:21:30633 aura::Window* parent =
634 GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]b2da9b602014-03-05 18:39:52635 DCHECK(parent);
636 parent->RemoveChild(keyboard_container);
bshe9858b4a2014-09-16 20:46:38637 // Virtual keyboard may be deactivated while still showing, notify all
638 // observers that keyboard bounds changed to 0 before remove them.
639 keyboard_controller->NotifyKeyboardBoundsChanging(gfx::Rect());
jamescook612205f2016-05-26 06:02:11640 keyboard_controller->RemoveObserver(shelf_widget()->shelf_layout_manager());
bshe9858b4a2014-09-16 20:46:38641 keyboard_controller->RemoveObserver(panel_layout_manager_);
642 keyboard_controller->RemoveObserver(docked_layout_manager_);
643 keyboard_controller->RemoveObserver(
644 workspace_controller_->layout_manager());
rsadam7bd510bb2014-12-09 20:10:56645 keyboard_controller->RemoveObserver(
646 always_on_top_controller_->GetLayoutManager());
bshe9858b4a2014-09-16 20:46:38647 Shell::GetInstance()->delegate()->VirtualKeyboardActivated(false);
[email protected]86459e2c2013-04-10 13:39:24648 }
649}
650
[email protected]602022b2014-03-31 17:07:31651bool RootWindowController::IsVirtualKeyboardWindow(aura::Window* window) {
bshec3875422014-09-29 13:21:30652 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]602022b2014-03-31 17:07:31653 return parent ? parent->Contains(window) : false;
654}
655
dmazzoniff86e3472016-06-03 19:52:32656void RootWindowController::SetTouchAccessibilityAnchorPoint(
657 const gfx::Point& anchor_point) {
658#if defined(OS_CHROMEOS)
659 if (touch_exploration_manager_)
660 touch_exploration_manager_->SetTouchAccessibilityAnchorPoint(anchor_point);
661#endif // defined(OS_CHROMEOS)
662}
663
[email protected]a4cd6d32012-09-12 03:42:13664////////////////////////////////////////////////////////////////////////////////
665// RootWindowController, private:
666
[email protected]f5c9dbc2014-04-11 08:13:45667RootWindowController::RootWindowController(AshWindowTreeHost* ash_host)
668 : ash_host_(ash_host),
jamescookbe6ed822016-06-06 20:08:55669 wm_shelf_aura_(new WmShelfAura),
[email protected]a273d33a2013-10-17 12:41:21670 docked_layout_manager_(NULL),
671 panel_layout_manager_(NULL),
672 touch_hud_debug_(NULL),
673 touch_hud_projection_(NULL) {
[email protected]f5c9dbc2014-04-11 08:13:45674 aura::Window* root_window = GetRootWindow();
skyee78dde2016-06-01 01:21:43675 root_window_controller_common_.reset(
sky0702b272016-06-03 22:10:41676 new RootWindowControllerCommon(WmWindowAura::Get(root_window)));
[email protected]f5c9dbc2014-04-11 08:13:45677 GetRootWindowSettings(root_window)->controller = this;
[email protected]a273d33a2013-10-17 12:41:21678
679 stacking_controller_.reset(new StackingController);
[email protected]f5c9dbc2014-04-11 08:13:45680 aura::client::SetWindowTreeClient(root_window, stacking_controller_.get());
681 capture_client_.reset(new ::wm::ScopedCaptureClient(root_window));
[email protected]a273d33a2013-10-17 12:41:21682}
683
[email protected]608de6c2013-10-29 00:14:28684void RootWindowController::Init(RootWindowType root_window_type,
685 bool first_run_after_boot) {
[email protected]f5c9dbc2014-04-11 08:13:45686 aura::Window* root_window = GetRootWindow();
[email protected]51f438112013-11-18 19:32:50687 Shell* shell = Shell::GetInstance();
[email protected]f5c9dbc2014-04-11 08:13:45688 shell->InitRootWindow(root_window);
[email protected]a273d33a2013-10-17 12:41:21689
skyee78dde2016-06-01 01:21:43690 root_window_controller_common_->CreateContainers();
[email protected]608de6c2013-10-29 00:14:28691
[email protected]a273d33a2013-10-17 12:41:21692 CreateSystemBackground(first_run_after_boot);
693
694 InitLayoutManagers();
695 InitTouchHuds();
696
697 if (Shell::GetPrimaryRootWindowController()->
698 GetSystemModalLayoutManager(NULL)->has_modal_background()) {
699 GetSystemModalLayoutManager(NULL)->CreateModalBackground();
700 }
701
[email protected]a273d33a2013-10-17 12:41:21702 shell->AddShellObserver(this);
703
sky7cd307042016-06-01 21:10:48704 root_window_controller_common_->root_window_layout()->OnWindowResized();
[email protected]608de6c2013-10-29 00:14:28705 if (root_window_type == PRIMARY) {
bshe9858b4a2014-09-16 20:46:38706 shell->InitKeyboard();
[email protected]a273d33a2013-10-17 12:41:21707 } else {
[email protected]f5c9dbc2014-04-11 08:13:45708 ash_host_->AsWindowTreeHost()->Show();
[email protected]a273d33a2013-10-17 12:41:21709
[email protected]864b58552013-12-19 04:19:38710 // Create a shelf if a user is already logged in.
[email protected]a273d33a2013-10-17 12:41:21711 if (shell->session_state_delegate()->NumberOfLoggedInUsers())
jamescook6500ad132016-05-27 06:15:54712 CreateShelf();
[email protected]0e3e7cb2014-04-12 05:18:25713
714 // Notify shell observers about new root window.
sky80556bc42016-06-07 22:46:13715 shell->OnRootWindowAdded(WmWindowAura::Get(root_window));
[email protected]a273d33a2013-10-17 12:41:21716 }
[email protected]a825e8312014-05-05 22:05:01717
718#if defined(OS_CHROMEOS)
pgal.u-szegedd84534d32014-10-29 12:34:30719 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]2e0b2352014-07-28 13:28:28720 switches::kAshDisableTouchExplorationMode)) {
[email protected]7d487592014-07-24 03:54:50721 touch_exploration_manager_.reset(new AshTouchExplorationManager(this));
[email protected]a825e8312014-05-05 22:05:01722 }
723#endif
[email protected]a273d33a2013-10-17 12:41:21724}
725
[email protected]756bda12013-07-03 08:17:06726void RootWindowController::InitLayoutManagers() {
sky7cd307042016-06-01 21:10:48727 root_window_controller_common_->CreateLayoutManagers();
728
[email protected]f5c9dbc2014-04-11 08:13:45729 aura::Window* root_window = GetRootWindow();
[email protected]756bda12013-07-03 08:17:06730
731 aura::Window* default_container =
732 GetContainer(kShellWindowId_DefaultContainer);
733 // Workspace manager has its own layout managers.
sky1e30f062016-04-14 21:19:16734
skye782a262016-05-31 20:28:57735 aura::Window* modal_container =
736 root_window->GetChildById(kShellWindowId_SystemModalContainer);
737 DCHECK(modal_container);
738 modal_container->SetLayoutManager(
739 new SystemModalContainerLayoutManager(modal_container));
740
741 aura::Window* lock_container =
742 root_window->GetChildById(kShellWindowId_LockScreenContainer);
743 DCHECK(lock_container);
744 lock_container->SetLayoutManager(new LockLayoutManager(lock_container));
745
746 aura::Window* lock_modal_container =
747 root_window->GetChildById(kShellWindowId_LockSystemModalContainer);
748 DCHECK(lock_modal_container);
749 lock_modal_container->SetLayoutManager(
750 new SystemModalContainerLayoutManager(lock_modal_container));
751
sky1e30f062016-04-14 21:19:16752 WorkspaceLayoutManagerDelegateImpl* workspace_layout_manager_delegate =
753 new WorkspaceLayoutManagerDelegateImpl(root_window);
754 workspace_controller_.reset(new WorkspaceController(
755 default_container, base::WrapUnique(workspace_layout_manager_delegate)));
[email protected]756bda12013-07-03 08:17:06756
sky0702b272016-06-03 22:10:41757 WmWindow* always_on_top_container =
758 WmWindowAura::Get(GetContainer(kShellWindowId_AlwaysOnTopContainer));
rsadam7bd510bb2014-12-09 20:10:56759 always_on_top_controller_.reset(
760 new AlwaysOnTopController(always_on_top_container));
[email protected]756bda12013-07-03 08:17:06761
jamescook612205f2016-05-26 06:02:11762 DCHECK(!shelf_widget_.get());
sky0702b272016-06-03 22:10:41763 WmWindow* shelf_container =
764 WmWindowAura::Get(GetContainer(kShellWindowId_ShelfContainer));
765 WmWindow* status_container =
766 WmWindowAura::Get(GetContainer(kShellWindowId_StatusContainer));
jamescook612205f2016-05-26 06:02:11767 shelf_widget_.reset(new ShelfWidget(shelf_container, status_container,
768 workspace_controller()));
jamescookbe6ed822016-06-06 20:08:55769 wm_shelf_aura_->SetShelfLayoutManager(shelf_widget_->shelf_layout_manager());
jamescook612205f2016-05-26 06:02:11770 workspace_layout_manager_delegate->set_shelf(
771 shelf_widget_->shelf_layout_manager());
[email protected]756bda12013-07-03 08:17:06772
[email protected]cf6fea22013-08-07 14:24:01773 if (!Shell::GetInstance()->session_state_delegate()->
774 IsActiveUserSessionStarted()) {
775 // This window exists only to be a event target on login screen.
776 // It does not have to handle events, nor be visible.
777 mouse_event_target_.reset(new aura::Window(new EmptyWindowDelegate));
danakjb161836d2015-04-03 05:14:18778 mouse_event_target_->Init(ui::LAYER_NOT_DRAWN);
[email protected]cf6fea22013-08-07 14:24:01779
780 aura::Window* lock_background_container =
[email protected]093b8d642014-04-03 20:59:28781 GetContainer(kShellWindowId_LockScreenBackgroundContainer);
[email protected]cf6fea22013-08-07 14:24:01782 lock_background_container->AddChild(mouse_event_target_.get());
783 mouse_event_target_->Show();
784 }
785
[email protected]756bda12013-07-03 08:17:06786 // Create Docked windows layout manager
sky0702b272016-06-03 22:10:41787 WmWindow* docked_container =
788 WmWindowAura::Get(GetContainer(kShellWindowId_DockedContainer));
skyca4122692016-04-26 04:47:57789 docked_layout_manager_ = new DockedWindowLayoutManager(docked_container);
sky3f7af8812016-04-21 19:30:03790 docked_container->SetLayoutManager(base::WrapUnique(docked_layout_manager_));
[email protected]756bda12013-07-03 08:17:06791
[email protected]1ca79d42014-07-18 16:26:10792 // Installs SnapLayoutManager to containers who set the
793 // |kSnapsChildrenToPhysicalPixelBoundary| property.
794 wm::InstallSnapLayoutManagerToContainers(root_window);
795
[email protected]756bda12013-07-03 08:17:06796 // Create Panel layout manager
[email protected]093b8d642014-04-03 20:59:28797 aura::Window* panel_container = GetContainer(kShellWindowId_PanelContainer);
sky0702b272016-06-03 22:10:41798 WmWindow* wm_panel_container = WmWindowAura::Get(panel_container);
skyad0315022016-04-25 19:40:31799 panel_layout_manager_ = new PanelLayoutManager(wm_panel_container);
800 wm_panel_container->SetLayoutManager(base::WrapUnique(panel_layout_manager_));
[email protected]3537d472014-01-15 05:45:31801 panel_container_handler_.reset(new PanelWindowEventHandler);
802 panel_container->AddPreTargetHandler(panel_container_handler_.get());
[email protected]b8642ec2014-04-17 05:20:39803
804 // Install an AttachedPanelWindowTargeter on the panel container to make it
805 // easier to correctly target shelf buttons with touch.
806 gfx::Insets mouse_extend(-kResizeOutsideBoundsSize,
807 -kResizeOutsideBoundsSize,
808 -kResizeOutsideBoundsSize,
809 -kResizeOutsideBoundsSize);
810 gfx::Insets touch_extend = mouse_extend.Scale(
811 kResizeOutsideBoundsScaleForTouch);
dchenga94547472016-04-08 08:41:11812 panel_container->SetEventTargeter(
813 std::unique_ptr<ui::EventTargeter>(new AttachedPanelWindowTargeter(
814 panel_container, mouse_extend, touch_extend, panel_layout_manager_)));
[email protected]756bda12013-07-03 08:17:06815}
816
817void RootWindowController::InitTouchHuds() {
pgal.u-szegedd84534d32014-10-29 12:34:30818 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
[email protected]756bda12013-07-03 08:17:06819 if (command_line->HasSwitch(switches::kAshTouchHud))
[email protected]f5c9dbc2014-04-11 08:13:45820 set_touch_hud_debug(new TouchHudDebug(GetRootWindow()));
[email protected]756bda12013-07-03 08:17:06821 if (Shell::GetInstance()->is_touch_hud_projection_enabled())
822 EnableTouchHudProjection();
823}
824
825void RootWindowController::CreateSystemBackground(
826 bool is_first_run_after_boot) {
827 SkColor color = SK_ColorBLACK;
828#if defined(OS_CHROMEOS)
829 if (is_first_run_after_boot)
830 color = kChromeOsBootColor;
831#endif
832 system_background_.reset(
[email protected]f5c9dbc2014-04-11 08:13:45833 new SystemBackgroundController(GetRootWindow(), color));
[email protected]756bda12013-07-03 08:17:06834
835#if defined(OS_CHROMEOS)
836 // Make a copy of the system's boot splash screen so we can composite it
837 // onscreen until the desktop background is ready.
838 if (is_first_run_after_boot &&
pgal.u-szegedd84534d32014-10-29 12:34:30839 (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]756bda12013-07-03 08:17:06840 switches::kAshCopyHostBackgroundAtBoot) ||
pgal.u-szegedd84534d32014-10-29 12:34:30841 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]756bda12013-07-03 08:17:06842 switches::kAshAnimateFromBootSplashScreen)))
[email protected]f5c9dbc2014-04-11 08:13:45843 boot_splash_screen_.reset(new BootSplashScreen(GetHost()));
[email protected]756bda12013-07-03 08:17:06844#endif
845}
846
[email protected]d141b922013-07-09 08:13:17847void RootWindowController::EnableTouchHudProjection() {
848 if (touch_hud_projection_)
849 return;
[email protected]f5c9dbc2014-04-11 08:13:45850 set_touch_hud_projection(new TouchHudProjection(GetRootWindow()));
[email protected]d141b922013-07-09 08:13:17851}
852
853void RootWindowController::DisableTouchHudProjection() {
854 if (!touch_hud_projection_)
855 return;
856 touch_hud_projection_->Remove();
857}
858
jonrossa90d8982016-05-16 18:14:25859void RootWindowController::OnMenuClosed() {
860 menu_runner_.reset();
861 menu_model_adapter_.reset();
862 menu_model_.reset();
863 Shell::GetInstance()->UpdateShelfVisibility();
864}
865
[email protected]d141b922013-07-09 08:13:17866void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
jamescook612205f2016-05-26 06:02:11867 shelf_widget_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]d141b922013-07-09 08:13:17868}
869
870void RootWindowController::OnTouchHudProjectionToggled(bool enabled) {
871 if (enabled)
872 EnableTouchHudProjection();
873 else
874 DisableTouchHudProjection();
875}
876
[email protected]6b2d4a0b2013-09-06 06:29:54877RootWindowController* GetRootWindowController(
[email protected]bf9cdb362013-10-25 19:22:45878 const aura::Window* root_window) {
jamescook5d74ac02016-05-12 19:57:12879 if (!root_window)
880 return nullptr;
881
882 if (Shell::GetInstance()->in_mus()) {
883 // On mus, like desktop aura, each top-level widget has its own root window,
884 // so |root_window| is not necessarily the display's root. For now, just
885 // the use the primary display root.
886 // TODO(jamescook): Multi-display support. This depends on how mus windows
887 // will be owned by displays.
888 aura::Window* primary_root_window = Shell::GetInstance()
889 ->window_tree_host_manager()
890 ->GetPrimaryRootWindow();
891 return GetRootWindowSettings(primary_root_window)->controller;
892 }
893
894 return GetRootWindowSettings(root_window)->controller;
[email protected]6b2d4a0b2013-09-06 06:29:54895}
896
[email protected]d90b8392012-06-13 09:34:56897} // namespace ash