blob: 7d6b190fae017942f508c57aa6184bc199f63af3 [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"
[email protected]a273d33a2013-10-17 12:41:2112#include "ash/desktop_background/desktop_background_controller.h"
[email protected]b4ddc7a2012-08-07 04:17:3213#include "ash/desktop_background/desktop_background_widget_controller.h"
[email protected]0bf61732013-07-02 04:35:1014#include "ash/desktop_background/user_wallpaper_delegate.h"
[email protected]6bdf7952012-11-14 10:10:5815#include "ash/display/display_manager.h"
[email protected]e74aaf0a2012-10-12 18:42:2816#include "ash/focus_cycler.h"
[email protected]a273d33a2013-10-17 12:41:2117#include "ash/high_contrast/high_contrast_controller.h"
[email protected]f5c9dbc2014-04-11 08:13:4518#include "ash/host/ash_window_tree_host.h"
[email protected]f8e6aad2013-08-30 21:49:1119#include "ash/root_window_settings.h"
[email protected]fdf74bf2014-04-30 21:24:0220#include "ash/session/session_state_delegate.h"
[email protected]478c6c32013-03-09 02:50:5821#include "ash/shelf/shelf_layout_manager.h"
22#include "ash/shelf/shelf_types.h"
23#include "ash/shelf/shelf_widget.h"
[email protected]d90b8392012-06-13 09:34:5624#include "ash/shell.h"
[email protected]e74aaf0a2012-10-12 18:42:2825#include "ash/shell_delegate.h"
[email protected]d90b8392012-06-13 09:34:5626#include "ash/shell_factory.h"
27#include "ash/shell_window_ids.h"
[email protected]e74aaf0a2012-10-12 18:42:2828#include "ash/system/status_area_widget.h"
[email protected]8674b312012-10-12 19:02:4429#include "ash/system/tray/system_tray_delegate.h"
[email protected]a825e8312014-05-05 22:05:0130#include "ash/system/tray/system_tray_notifier.h"
[email protected]2b8a9bb2013-07-01 22:43:4031#include "ash/touch/touch_hud_debug.h"
32#include "ash/touch/touch_hud_projection.h"
[email protected]80549c152013-07-02 01:42:4733#include "ash/touch/touch_observer_hud.h"
sky3f7af8812016-04-21 19:30:0334#include "ash/wm/aura/aura_layout_manager_adapter.h"
sky019ff29c2016-04-26 19:40:5935#include "ash/wm/aura/wm_shelf_aura.h"
skyf961b3562016-04-20 00:53:5036#include "ash/wm/aura/wm_window_aura.h"
sky2f50fdc2016-04-28 05:56:1337#include "ash/wm/common/always_on_top_controller.h"
skycb51abf2016-05-05 18:24:4838#include "ash/wm/common/container_finder.h"
sky75677b502016-04-26 22:41:5939#include "ash/wm/common/dock/docked_window_layout_manager.h"
sky4dc7d0492016-04-28 04:15:2240#include "ash/wm/common/fullscreen_window_finder.h"
sky28a737f32016-05-02 15:44:3141#include "ash/wm/common/panels/panel_layout_manager.h"
sky4dc7d0492016-04-28 04:15:2242#include "ash/wm/common/switchable_windows.h"
sky75677b502016-04-26 22:41:5943#include "ash/wm/common/window_state.h"
sky2f50fdc2016-04-28 05:56:1344#include "ash/wm/common/workspace/workspace_layout_manager.h"
sky1e30f062016-04-14 21:19:1645#include "ash/wm/common/workspace/workspace_layout_manager_delegate.h"
[email protected]68d51332014-06-06 13:51:1346#include "ash/wm/lock_layout_manager.h"
[email protected]b8642ec2014-04-17 05:20:3947#include "ash/wm/panels/attached_panel_window_targeter.h"
[email protected]100659412013-06-21 22:59:5548#include "ash/wm/panels/panel_window_event_handler.h"
[email protected]d90b8392012-06-13 09:34:5649#include "ash/wm/root_window_layout_manager.h"
[email protected]2a2caa02013-01-22 20:50:3650#include "ash/wm/stacking_controller.h"
[email protected]e74aaf0a2012-10-12 18:42:2851#include "ash/wm/status_area_layout_manager.h"
[email protected]e6e41d2f2012-10-29 19:22:1952#include "ash/wm/system_background_controller.h"
[email protected]d90b8392012-06-13 09:34:5653#include "ash/wm/system_modal_container_layout_manager.h"
[email protected]8d625fb2012-07-18 16:40:0654#include "ash/wm/window_properties.h"
sky8d5646fe2016-04-15 17:03:4655#include "ash/wm/window_state_aura.h"
[email protected]700849f2013-04-30 17:49:2056#include "ash/wm/window_util.h"
[email protected]d90b8392012-06-13 09:34:5657#include "ash/wm/workspace_controller.h"
[email protected]e6e41d2f2012-10-29 19:22:1958#include "base/command_line.h"
sky1e30f062016-04-14 21:19:1659#include "base/memory/ptr_util.h"
[email protected]1e84c632013-06-27 23:12:2160#include "base/time/time.h"
[email protected]f1853122012-06-27 16:21:2661#include "ui/aura/client/aura_constants.h"
[email protected]2374d1812014-03-04 03:42:2762#include "ui/aura/client/screen_position_client.h"
[email protected]f1853122012-06-27 16:21:2663#include "ui/aura/window.h"
[email protected]cf6fea22013-08-07 14:24:0164#include "ui/aura/window_delegate.h"
[email protected]fcc51c952014-02-21 21:31:2665#include "ui/aura/window_event_dispatcher.h"
[email protected]f1853122012-06-27 16:21:2666#include "ui/aura/window_observer.h"
[email protected]8b3e3d82013-08-20 14:36:3067#include "ui/aura/window_tracker.h"
[email protected]cf6fea22013-08-07 14:24:0168#include "ui/base/hit_test.h"
[email protected]431552c2012-10-23 00:38:3369#include "ui/base/models/menu_model.h"
oshimaf84b0da722016-04-27 19:47:1970#include "ui/display/display.h"
71#include "ui/display/screen.h"
[email protected]86459e2c2013-04-10 13:39:2472#include "ui/keyboard/keyboard_controller.h"
73#include "ui/keyboard/keyboard_util.h"
[email protected]431552c2012-10-23 00:38:3374#include "ui/views/controls/menu/menu_runner.h"
75#include "ui/views/view_model.h"
76#include "ui/views/view_model_utils.h"
[email protected]ee3ed10772014-03-11 22:02:0177#include "ui/wm/core/capture_controller.h"
[email protected]e319c7e2014-03-14 19:56:1478#include "ui/wm/core/easy_resize_window_targeter.h"
[email protected]ee3ed10772014-03-11 22:02:0179#include "ui/wm/core/visibility_controller.h"
80#include "ui/wm/core/window_util.h"
[email protected]af4552b22014-03-21 19:45:0181#include "ui/wm/public/drag_drop_client.h"
82#include "ui/wm/public/tooltip_client.h"
[email protected]5b251f12013-12-19 01:50:0583#include "ui/wm/public/window_types.h"
[email protected]d90b8392012-06-13 09:34:5684
[email protected]252eb232013-08-14 22:09:2785#if defined(OS_CHROMEOS)
[email protected]7d487592014-07-24 03:54:5086#include "ash/ash_touch_exploration_manager_chromeos.h"
[email protected]252eb232013-08-14 22:09:2787#include "ash/wm/boot_splash_screen_chromeos.h"
[email protected]a825e8312014-05-05 22:05:0188#include "ui/chromeos/touch_exploration_controller.h"
[email protected]252eb232013-08-14 22:09:2789#endif
90
[email protected]d90b8392012-06-13 09:34:5691namespace ash {
92namespace {
93
[email protected]252eb232013-08-14 22:09:2794#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:4995// Duration for the animation that hides the boot splash screen, in
96// milliseconds. This should be short enough in relation to
97// wm/window_animation.cc's brightness/grayscale fade animation that the login
98// background image animation isn't hidden by the splash screen animation.
99const int kBootSplashScreenHideDurationMs = 500;
[email protected]252eb232013-08-14 22:09:27100#endif
[email protected]bca9a7e2012-11-10 06:25:49101
[email protected]d90b8392012-06-13 09:34:56102// Creates a new window for use as a container.
103aura::Window* CreateContainer(int window_id,
104 const char* name,
105 aura::Window* parent) {
106 aura::Window* container = new aura::Window(NULL);
107 container->set_id(window_id);
108 container->SetName(name);
danakjb161836d2015-04-03 05:14:18109 container->Init(ui::LAYER_NOT_DRAWN);
[email protected]d90b8392012-06-13 09:34:56110 parent->AddChild(container);
[email protected]093b8d642014-04-03 20:59:28111 if (window_id != kShellWindowId_UnparentedControlContainer)
[email protected]d90b8392012-06-13 09:34:56112 container->Show();
113 return container;
114}
115
[email protected]2816c2462013-12-17 02:22:25116float ToRelativeValue(int value, int src, int dst) {
117 return static_cast<float>(value) / static_cast<float>(src) * dst;
118}
119
120void MoveOriginRelativeToSize(const gfx::Size& src_size,
121 const gfx::Size& dst_size,
122 gfx::Rect* bounds_in_out) {
123 gfx::Point origin = bounds_in_out->origin();
124 bounds_in_out->set_origin(gfx::Point(
125 ToRelativeValue(origin.x(), src_size.width(), dst_size.width()),
126 ToRelativeValue(origin.y(), src_size.height(), dst_size.height())));
127}
128
[email protected]95058572012-08-20 14:57:29129// Reparents |window| to |new_parent|.
130void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
[email protected]2816c2462013-12-17 02:22:25131 const gfx::Size src_size = window->parent()->bounds().size();
132 const gfx::Size dst_size = new_parent->bounds().size();
[email protected]95058572012-08-20 14:57:29133 // Update the restore bounds to make it relative to the display.
[email protected]a41b4e12013-09-20 04:36:34134 wm::WindowState* state = wm::GetWindowState(window);
135 gfx::Rect restore_bounds;
136 bool has_restore_bounds = state->HasRestoreBounds();
[email protected]2816c2462013-12-17 02:22:25137
[email protected]9cfd3d12014-02-25 15:33:45138 bool update_bounds = (state->IsNormalOrSnapped() || state->IsMinimized()) &&
[email protected]093b8d642014-04-03 20:59:28139 new_parent->id() != kShellWindowId_DockedContainer;
[email protected]2816c2462013-12-17 02:22:25140 gfx::Rect local_bounds;
141 if (update_bounds) {
skyf961b3562016-04-20 00:53:50142 local_bounds = wm::WmWindowAura::GetAuraWindow(state->window())->bounds();
[email protected]2816c2462013-12-17 02:22:25143 MoveOriginRelativeToSize(src_size, dst_size, &local_bounds);
144 }
145
146 if (has_restore_bounds) {
[email protected]a41b4e12013-09-20 04:36:34147 restore_bounds = state->GetRestoreBoundsInParent();
[email protected]2816c2462013-12-17 02:22:25148 MoveOriginRelativeToSize(src_size, dst_size, &restore_bounds);
149 }
150
[email protected]95058572012-08-20 14:57:29151 new_parent->AddChild(window);
[email protected]2816c2462013-12-17 02:22:25152
[email protected]8663b7a62014-01-18 01:24:21153 // Docked windows have bounds handled by the layout manager in AddChild().
[email protected]2816c2462013-12-17 02:22:25154 if (update_bounds)
155 window->SetBounds(local_bounds);
156
[email protected]a41b4e12013-09-20 04:36:34157 if (has_restore_bounds)
158 state->SetRestoreBoundsInParent(restore_bounds);
[email protected]95058572012-08-20 14:57:29159}
160
161// Reparents the appropriate set of windows from |src| to |dst|.
[email protected]bf9cdb362013-10-25 19:22:45162void ReparentAllWindows(aura::Window* src, aura::Window* dst) {
[email protected]95058572012-08-20 14:57:29163 // Set of windows to move.
[email protected]f1853122012-06-27 16:21:26164 const int kContainerIdsToMove[] = {
[email protected]093b8d642014-04-03 20:59:28165 kShellWindowId_DefaultContainer,
166 kShellWindowId_DockedContainer,
167 kShellWindowId_PanelContainer,
168 kShellWindowId_AlwaysOnTopContainer,
169 kShellWindowId_SystemModalContainer,
170 kShellWindowId_LockSystemModalContainer,
tengsf98986c2014-12-06 01:42:21171 kShellWindowId_UnparentedControlContainer,
oshima022a9542015-05-01 00:15:02172 kShellWindowId_OverlayContainer,
173 };
174 const int kExtraContainerIdsToMoveInUnifiedMode[] = {
175 kShellWindowId_LockScreenContainer,
176 kShellWindowId_LockScreenBackgroundContainer,
177 };
178 std::vector<int> container_ids(
179 kContainerIdsToMove,
180 kContainerIdsToMove + arraysize(kContainerIdsToMove));
181 // Check the default_multi_display_mode because this is also necessary
182 // in trasition between mirror <-> unified mode.
oshima628a6172015-08-01 01:33:14183 if (Shell::GetInstance()
184 ->display_manager()
185 ->current_default_multi_display_mode() == DisplayManager::UNIFIED) {
oshima022a9542015-05-01 00:15:02186 for (int id : kExtraContainerIdsToMoveInUnifiedMode)
187 container_ids.push_back(id);
188 }
189
190 for (int id : container_ids) {
[email protected]f1853122012-06-27 16:21:26191 aura::Window* src_container = Shell::GetContainer(src, id);
192 aura::Window* dst_container = Shell::GetContainer(dst, id);
[email protected]5b6021902013-02-26 05:33:29193 while (!src_container->children().empty()) {
194 // Restart iteration from the source container windows each time as they
195 // may change as a result of moving other windows.
196 aura::Window::Windows::const_iterator iter =
197 src_container->children().begin();
198 while (iter != src_container->children().end() &&
[email protected]093b8d642014-04-03 20:59:28199 SystemModalContainerLayoutManager::IsModalBackground(*iter)) {
[email protected]5b6021902013-02-26 05:33:29200 ++iter;
201 }
202 // If the entire window list is modal background windows then stop.
203 if (iter == src_container->children().end())
204 break;
205 ReparentWindow(*iter, dst_container);
[email protected]f1853122012-06-27 16:21:26206 }
207 }
208}
209
[email protected]8d625fb2012-07-18 16:40:06210// Mark the container window so that a widget added to this container will
211// use the virtual screeen coordinates instead of parent.
212void SetUsesScreenCoordinates(aura::Window* container) {
[email protected]093b8d642014-04-03 20:59:28213 container->SetProperty(kUsesScreenCoordinatesKey, true);
[email protected]8d625fb2012-07-18 16:40:06214}
215
[email protected]e887c6c2013-07-08 19:35:53216// Mark the container window so that a widget added to this container will
217// say in the same root window regardless of the bounds specified.
218void DescendantShouldStayInSameRootWindow(aura::Window* container) {
[email protected]093b8d642014-04-03 20:59:28219 container->SetProperty(kStayInSameRootWindowKey, true);
[email protected]e887c6c2013-07-08 19:35:53220}
221
[email protected]c5be8d672014-01-07 13:33:41222void SetUsesEasyResizeTargeter(aura::Window* container) {
223 gfx::Insets mouse_extend(-kResizeOutsideBoundsSize,
224 -kResizeOutsideBoundsSize,
225 -kResizeOutsideBoundsSize,
226 -kResizeOutsideBoundsSize);
227 gfx::Insets touch_extend = mouse_extend.Scale(
228 kResizeOutsideBoundsScaleForTouch);
dchenga94547472016-04-08 08:41:11229 container->SetEventTargeter(
230 std::unique_ptr<ui::EventTargeter>(new ::wm::EasyResizeWindowTargeter(
231 container, mouse_extend, touch_extend)));
[email protected]c5be8d672014-01-07 13:33:41232}
233
[email protected]cf6fea22013-08-07 14:24:01234// A window delegate which does nothing. Used to create a window that
235// is a event target, but do nothing.
236class EmptyWindowDelegate : public aura::WindowDelegate {
237 public:
238 EmptyWindowDelegate() {}
dcheng1f4538e2014-10-27 23:57:05239 ~EmptyWindowDelegate() override {}
[email protected]cf6fea22013-08-07 14:24:01240
241 // aura::WindowDelegate overrides:
dcheng1f4538e2014-10-27 23:57:05242 gfx::Size GetMinimumSize() const override { return gfx::Size(); }
243 gfx::Size GetMaximumSize() const override { return gfx::Size(); }
244 void OnBoundsChanged(const gfx::Rect& old_bounds,
245 const gfx::Rect& new_bounds) override {}
246 gfx::NativeCursor GetCursor(const gfx::Point& point) override {
[email protected]62c9f102014-03-27 06:07:04247 return gfx::kNullCursor;
248 }
dcheng1f4538e2014-10-27 23:57:05249 int GetNonClientComponent(const gfx::Point& point) const override {
[email protected]cf6fea22013-08-07 14:24:01250 return HTNOWHERE;
251 }
dcheng1f4538e2014-10-27 23:57:05252 bool ShouldDescendIntoChildForEventHandling(
[email protected]cf6fea22013-08-07 14:24:01253 aura::Window* child,
mostynb10d6b382014-10-03 16:23:45254 const gfx::Point& location) override {
[email protected]cf6fea22013-08-07 14:24:01255 return false;
256 }
dcheng1f4538e2014-10-27 23:57:05257 bool CanFocus() override { return false; }
258 void OnCaptureLost() override {}
danakj85d970e2015-04-04 00:15:24259 void OnPaint(const ui::PaintContext& context) override {}
dcheng1f4538e2014-10-27 23:57:05260 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
261 void OnWindowDestroying(aura::Window* window) override {}
262 void OnWindowDestroyed(aura::Window* window) override { delete this; }
263 void OnWindowTargetVisibilityChanged(bool visible) override {}
264 bool HasHitTestMask() const override { return false; }
265 void GetHitTestMask(gfx::Path* mask) const override {}
[email protected]cf6fea22013-08-07 14:24:01266
267 private:
268 DISALLOW_COPY_AND_ASSIGN(EmptyWindowDelegate);
269};
270
sky1e30f062016-04-14 21:19:16271class WorkspaceLayoutManagerDelegateImpl
272 : public wm::WorkspaceLayoutManagerDelegate {
273 public:
274 explicit WorkspaceLayoutManagerDelegateImpl(aura::Window* root_window)
275 : root_window_(root_window) {}
276 ~WorkspaceLayoutManagerDelegateImpl() override = default;
277
278 void set_shelf(ShelfLayoutManager* shelf) { shelf_ = shelf; }
279
280 // WorkspaceLayoutManagerDelegate:
281 void UpdateShelfVisibility() override {
282 if (shelf_)
283 shelf_->UpdateVisibilityState();
284 }
285 void OnFullscreenStateChanged(bool is_fullscreen) override {
286 if (shelf_) {
287 ash::Shell::GetInstance()->NotifyFullscreenStateChange(is_fullscreen,
288 root_window_);
289 }
290 }
291
292 private:
293 aura::Window* root_window_;
294 ShelfLayoutManager* shelf_ = nullptr;
295
296 DISALLOW_COPY_AND_ASSIGN(WorkspaceLayoutManagerDelegateImpl);
297};
298
[email protected]d90b8392012-06-13 09:34:56299} // namespace
300
[email protected]f5c9dbc2014-04-11 08:13:45301void RootWindowController::CreateForPrimaryDisplay(AshWindowTreeHost* host) {
[email protected]2f2620332014-02-28 10:07:38302 RootWindowController* controller = new RootWindowController(host);
[email protected]608de6c2013-10-29 00:14:28303 controller->Init(RootWindowController::PRIMARY,
[email protected]a273d33a2013-10-17 12:41:21304 Shell::GetInstance()->delegate()->IsFirstRunAfterBoot());
[email protected]d90b8392012-06-13 09:34:56305}
306
[email protected]f5c9dbc2014-04-11 08:13:45307void RootWindowController::CreateForSecondaryDisplay(AshWindowTreeHost* host) {
[email protected]2f2620332014-02-28 10:07:38308 RootWindowController* controller = new RootWindowController(host);
[email protected]608de6c2013-10-29 00:14:28309 controller->Init(RootWindowController::SECONDARY, false /* first run */);
310}
311
[email protected]88d71122012-10-18 07:11:01312// static
[email protected]ccff3d72013-02-06 04:26:28313RootWindowController* RootWindowController::ForWindow(
314 const aura::Window* window) {
oshima9eea82da2014-09-13 01:11:07315 CHECK(Shell::HasInstance());
[email protected]a0afeb12012-12-10 22:57:09316 return GetRootWindowController(window->GetRootWindow());
317}
318
319// static
[email protected]d17642d2013-09-12 23:44:38320RootWindowController* RootWindowController::ForTargetRootWindow() {
oshima9eea82da2014-09-13 01:11:07321 CHECK(Shell::HasInstance());
[email protected]093b8d642014-04-03 20:59:28322 return GetRootWindowController(Shell::GetTargetRootWindow());
[email protected]a0afeb12012-12-10 22:57:09323}
324
[email protected]a273d33a2013-10-17 12:41:21325RootWindowController::~RootWindowController() {
326 Shutdown();
[email protected]f5c9dbc2014-04-11 08:13:45327 ash_host_.reset();
[email protected]a273d33a2013-10-17 12:41:21328 // The CaptureClient needs to be around for as long as the RootWindow is
329 // valid.
330 capture_client_.reset();
331}
332
[email protected]f5c9dbc2014-04-11 08:13:45333aura::WindowTreeHost* RootWindowController::GetHost() {
334 return ash_host_->AsWindowTreeHost();
335}
336
337const aura::WindowTreeHost* RootWindowController::GetHost() const {
338 return ash_host_->AsWindowTreeHost();
339}
340
341aura::Window* RootWindowController::GetRootWindow() {
342 return GetHost()->window();
343}
344
345const aura::Window* RootWindowController::GetRootWindow() const {
346 return GetHost()->window();
347}
348
[email protected]0bf61732013-07-02 04:35:10349void RootWindowController::SetWallpaperController(
350 DesktopBackgroundWidgetController* controller) {
351 wallpaper_controller_.reset(controller);
352}
353
354void RootWindowController::SetAnimatingWallpaperController(
355 AnimatingDesktopController* controller) {
356 if (animating_wallpaper_controller_.get())
357 animating_wallpaper_controller_->StopAnimating();
358 animating_wallpaper_controller_.reset(controller);
359}
360
[email protected]6675e1c2012-09-11 09:15:45361void RootWindowController::Shutdown() {
[email protected]a825e8312014-05-05 22:05:01362 Shell* shell = Shell::GetInstance();
363 shell->RemoveShellObserver(this);
364
365#if defined(OS_CHROMEOS)
[email protected]7d487592014-07-24 03:54:50366 if (touch_exploration_manager_) {
367 touch_exploration_manager_.reset();
[email protected]a825e8312014-05-05 22:05:01368 }
369#endif
[email protected]d141b922013-07-09 08:13:17370
[email protected]0bf61732013-07-02 04:35:10371 if (animating_wallpaper_controller_.get())
372 animating_wallpaper_controller_->StopAnimating();
373 wallpaper_controller_.reset();
374 animating_wallpaper_controller_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45375 aura::Window* root_window = GetRootWindow();
[email protected]d17642d2013-09-12 23:44:38376 // Change the target root window before closing child windows. If any child
[email protected]c98a4922013-09-05 20:01:42377 // being removed triggers a relayout of the shelf it will try to build a
[email protected]d17642d2013-09-12 23:44:38378 // window list adding windows from the target root window's containers which
[email protected]c98a4922013-09-05 20:01:42379 // may have already gone away.
[email protected]f5c9dbc2014-04-11 08:13:45380 if (Shell::GetTargetRootWindow() == root_window) {
[email protected]a825e8312014-05-05 22:05:01381 shell->set_target_root_window(
[email protected]f5c9dbc2014-04-11 08:13:45382 Shell::GetPrimaryRootWindow() == root_window
383 ? NULL
384 : Shell::GetPrimaryRootWindow());
[email protected]f634dd32012-07-23 22:49:07385 }
[email protected]c98a4922013-09-05 20:01:42386
387 CloseChildWindows();
[email protected]f5c9dbc2014-04-11 08:13:45388 GetRootWindowSettings(root_window)->controller = NULL;
[email protected]d90b8392012-06-13 09:34:56389 workspace_controller_.reset();
[email protected]6675e1c2012-09-11 09:15:45390 // Forget with the display ID so that display lookup
391 // ends up with invalid display.
[email protected]f5c9dbc2014-04-11 08:13:45392 GetRootWindowSettings(root_window)->display_id =
oshimaf84b0da722016-04-27 19:47:19393 display::Display::kInvalidDisplayID;
[email protected]8f5209c2014-05-22 20:36:11394 ash_host_->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28395
[email protected]956a6a42012-10-29 23:58:10396 system_background_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45397 aura::client::SetScreenPositionClient(root_window, NULL);
[email protected]d90b8392012-06-13 09:34:56398}
399
[email protected]c0ce80e2012-10-05 23:28:27400SystemModalContainerLayoutManager*
[email protected]8674b312012-10-12 19:02:44401RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
[email protected]a5c78802013-12-12 22:07:01402 aura::Window* modal_container = NULL;
[email protected]8674b312012-10-12 19:02:44403 if (window) {
skycb51abf2016-05-05 18:24:48404 aura::Window* window_container = wm::WmWindowAura::GetAuraWindow(
405 wm::GetContainerForWindow(wm::WmWindowAura::Get(window)));
[email protected]a5c78802013-12-12 22:07:01406 if (window_container &&
407 window_container->id() >= kShellWindowId_LockScreenContainer) {
408 modal_container = GetContainer(kShellWindowId_LockSystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35409 } else {
[email protected]a5c78802013-12-12 22:07:01410 modal_container = GetContainer(kShellWindowId_SystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35411 }
[email protected]8674b312012-10-12 19:02:44412 } else {
[email protected]a44afbbd2013-07-24 21:49:35413 int modal_window_id = Shell::GetInstance()->session_state_delegate()
414 ->IsUserSessionBlocked() ? kShellWindowId_LockSystemModalContainer :
415 kShellWindowId_SystemModalContainer;
[email protected]a5c78802013-12-12 22:07:01416 modal_container = GetContainer(modal_window_id);
[email protected]8674b312012-10-12 19:02:44417 }
[email protected]a5c78802013-12-12 22:07:01418 return modal_container ? static_cast<SystemModalContainerLayoutManager*>(
419 modal_container->layout_manager()) : NULL;
[email protected]c0ce80e2012-10-05 23:28:27420}
421
[email protected]d90b8392012-06-13 09:34:56422aura::Window* RootWindowController::GetContainer(int container_id) {
[email protected]f5c9dbc2014-04-11 08:13:45423 return GetRootWindow()->GetChildById(container_id);
[email protected]d90b8392012-06-13 09:34:56424}
425
[email protected]d8a24952013-08-05 20:05:05426const aura::Window* RootWindowController::GetContainer(int container_id) const {
[email protected]f5c9dbc2014-04-11 08:13:45427 return ash_host_->AsWindowTreeHost()->window()->GetChildById(container_id);
[email protected]d8a24952013-08-05 20:05:05428}
429
[email protected]864b58552013-12-19 04:19:38430void RootWindowController::ShowShelf() {
431 if (!shelf_->shelf())
[email protected]e74aaf0a2012-10-12 18:42:28432 return;
[email protected]864b58552013-12-19 04:19:38433 shelf_->shelf()->SetVisible(true);
[email protected]478c6c32013-03-09 02:50:58434 shelf_->status_area_widget()->Show();
[email protected]e74aaf0a2012-10-12 18:42:28435}
436
[email protected]864b58552013-12-19 04:19:38437void RootWindowController::OnShelfCreated() {
[email protected]756bda12013-07-03 08:17:06438 if (panel_layout_manager_)
skya9a6deb32016-04-29 01:15:38439 panel_layout_manager_->SetShelf(shelf_->shelf()->wm_shelf());
[email protected]7115bd32013-07-19 08:25:39440 if (docked_layout_manager_) {
sky019ff29c2016-04-26 19:40:59441 docked_layout_manager_->SetShelf(shelf_->shelf()->wm_shelf());
[email protected]7115bd32013-07-19 08:25:39442 if (shelf_->shelf_layout_manager())
443 docked_layout_manager_->AddObserver(shelf_->shelf_layout_manager());
444 }
[email protected]b8642ec2014-04-17 05:20:39445
446 // Notify shell observers that the shelf has been created.
447 Shell::GetInstance()->OnShelfCreatedForRootWindow(GetRootWindow());
[email protected]756bda12013-07-03 08:17:06448}
449
[email protected]16059276d2012-10-22 18:59:50450void RootWindowController::UpdateAfterLoginStatusChange(
451 user::LoginStatus status) {
[email protected]cf6fea22013-08-07 14:24:01452 if (status != user::LOGGED_IN_NONE)
453 mouse_event_target_.reset();
[email protected]80549c152013-07-02 01:42:47454 if (shelf_->status_area_widget())
[email protected]478c6c32013-03-09 02:50:58455 shelf_->status_area_widget()->UpdateAfterLoginStatusChange(status);
[email protected]16059276d2012-10-22 18:59:50456}
457
[email protected]bca9a7e2012-11-10 06:25:49458void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
[email protected]252eb232013-08-14 22:09:27459#if defined(OS_CHROMEOS)
pgal.u-szegedd84534d32014-10-29 12:34:30460 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]bca9a7e2012-11-10 06:25:49461 switches::kAshAnimateFromBootSplashScreen) &&
462 boot_splash_screen_.get()) {
463 // Make the splash screen fade out so it doesn't obscure the desktop
464 // wallpaper's brightness/grayscale animation.
465 boot_splash_screen_->StartHideAnimation(
466 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
467 }
[email protected]252eb232013-08-14 22:09:27468#endif
[email protected]bca9a7e2012-11-10 06:25:49469}
470
[email protected]0bf61732013-07-02 04:35:10471void RootWindowController::OnWallpaperAnimationFinished(views::Widget* widget) {
472 // Make sure the wallpaper is visible.
[email protected]bca9a7e2012-11-10 06:25:49473 system_background_->SetColor(SK_ColorBLACK);
[email protected]252eb232013-08-14 22:09:27474#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:49475 boot_splash_screen_.reset();
[email protected]252eb232013-08-14 22:09:27476#endif
[email protected]0bf61732013-07-02 04:35:10477
478 Shell::GetInstance()->user_wallpaper_delegate()->
479 OnWallpaperAnimationFinished();
480 // Only removes old component when wallpaper animation finished. If we
481 // remove the old one before the new wallpaper is done fading in there will
482 // be a white flash during the animation.
483 if (animating_wallpaper_controller()) {
484 DesktopBackgroundWidgetController* controller =
485 animating_wallpaper_controller()->GetController(true);
486 // |desktop_widget_| should be the same animating widget we try to move
487 // to |kDesktopController|. Otherwise, we may close |desktop_widget_|
488 // before move it to |kDesktopController|.
489 DCHECK_EQ(controller->widget(), widget);
490 // Release the old controller and close its background widget.
491 SetWallpaperController(controller);
492 }
[email protected]697f04c2012-10-03 01:15:10493}
494
[email protected]d90b8392012-06-13 09:34:56495void RootWindowController::CloseChildWindows() {
[email protected]cf6fea22013-08-07 14:24:01496 mouse_event_target_.reset();
497
[email protected]2a57beb52014-06-09 20:02:26498 // Remove observer as deactivating keyboard causes |docked_layout_manager_|
499 // to fire notifications.
500 if (docked_layout_manager_ && shelf_ && shelf_->shelf_layout_manager())
501 docked_layout_manager_->RemoveObserver(shelf_->shelf_layout_manager());
502
[email protected]b6ba05d902013-10-04 21:38:45503 // Deactivate keyboard container before closing child windows and shutting
504 // down associated layout managers.
[email protected]a0b3fb882014-04-07 19:26:03505 DeactivateKeyboard(keyboard::KeyboardController::GetInstance());
[email protected]b6ba05d902013-10-04 21:38:45506
[email protected]79a87b7e2013-01-25 05:08:22507 // panel_layout_manager_ needs to be shut down before windows are destroyed.
508 if (panel_layout_manager_) {
509 panel_layout_manager_->Shutdown();
510 panel_layout_manager_ = NULL;
511 }
[email protected]7115bd32013-07-19 08:25:39512 // docked_layout_manager_ needs to be shut down before windows are destroyed.
513 if (docked_layout_manager_) {
[email protected]7115bd32013-07-19 08:25:39514 docked_layout_manager_->Shutdown();
515 docked_layout_manager_ = NULL;
516 }
[email protected]f5c9dbc2014-04-11 08:13:45517 aura::Window* root_window = GetRootWindow();
518 aura::client::SetDragDropClient(root_window, NULL);
[email protected]8b3e3d82013-08-20 14:36:30519
[email protected]478c6c32013-03-09 02:50:58520 // TODO(harrym): Remove when Status Area Widget is a child view.
[email protected]bb42c932013-10-31 06:52:06521 if (shelf_) {
522 shelf_->ShutdownStatusAreaWidget();
[email protected]478c6c32013-03-09 02:50:58523
[email protected]bb42c932013-10-31 06:52:06524 if (shelf_->shelf_layout_manager())
525 shelf_->shelf_layout_manager()->PrepareForShutdown();
526 }
[email protected]e74aaf0a2012-10-12 18:42:28527
[email protected]d90b8392012-06-13 09:34:56528 // Close background widget first as it depends on tooltip.
[email protected]0bf61732013-07-02 04:35:10529 wallpaper_controller_.reset();
530 animating_wallpaper_controller_.reset();
[email protected]b4ddc7a2012-08-07 04:17:32531
[email protected]d90b8392012-06-13 09:34:56532 workspace_controller_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45533 aura::client::SetTooltipClient(root_window, NULL);
[email protected]d90b8392012-06-13 09:34:56534
[email protected]0fbfa972013-10-02 19:23:33535 // Explicitly destroy top level windows. We do this as during part of
536 // destruction such windows may query the RootWindow for state.
oshimaf38efa92015-10-27 19:06:52537 aura::WindowTracker non_toplevel_windows;
538 non_toplevel_windows.Add(root_window);
539 while (!non_toplevel_windows.windows().empty()) {
540 const aura::Window* non_toplevel_window =
541 *non_toplevel_windows.windows().begin();
542 non_toplevel_windows.Remove(const_cast<aura::Window*>(non_toplevel_window));
[email protected]8b3e3d82013-08-20 14:36:30543 aura::WindowTracker toplevel_windows;
544 for (size_t i = 0; i < non_toplevel_window->children().size(); ++i) {
545 aura::Window* child = non_toplevel_window->children()[i];
[email protected]0fbfa972013-10-02 19:23:33546 if (!child->owned_by_parent())
547 continue;
[email protected]8b3e3d82013-08-20 14:36:30548 if (child->delegate())
549 toplevel_windows.Add(child);
550 else
oshimaf38efa92015-10-27 19:06:52551 non_toplevel_windows.Add(child);
[email protected]8b3e3d82013-08-20 14:36:30552 }
553 while (!toplevel_windows.windows().empty())
554 delete *toplevel_windows.windows().begin();
[email protected]d90b8392012-06-13 09:34:56555 }
[email protected]8b3e3d82013-08-20 14:36:30556 // And then remove the containers.
[email protected]f5c9dbc2014-04-11 08:13:45557 while (!root_window->children().empty()) {
558 aura::Window* window = root_window->children()[0];
[email protected]0fbfa972013-10-02 19:23:33559 if (window->owned_by_parent()) {
560 delete window;
561 } else {
[email protected]f5c9dbc2014-04-11 08:13:45562 root_window->RemoveChild(window);
[email protected]0fbfa972013-10-02 19:23:33563 }
564 }
[email protected]478c6c32013-03-09 02:50:58565
[email protected]bb42c932013-10-31 06:52:06566 shelf_.reset();
[email protected]d90b8392012-06-13 09:34:56567}
568
[email protected]bf9cdb362013-10-25 19:22:45569void RootWindowController::MoveWindowsTo(aura::Window* dst) {
[email protected]8039e06c2013-01-17 23:34:50570 // Forget the shelf early so that shelf don't update itself using wrong
571 // display info.
sky1e30f062016-04-14 21:19:16572 workspace_controller_->SetShelf(nullptr);
573 workspace_controller_->layout_manager()->DeleteDelegate();
[email protected]f5c9dbc2014-04-11 08:13:45574 ReparentAllWindows(GetRootWindow(), dst);
[email protected]f1853122012-06-27 16:21:26575}
576
[email protected]478c6c32013-03-09 02:50:58577ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
[email protected]80549c152013-07-02 01:42:47578 return shelf_->shelf_layout_manager();
[email protected]478c6c32013-03-09 02:50:58579}
580
[email protected]a0afeb12012-12-10 22:57:09581SystemTray* RootWindowController::GetSystemTray() {
582 // We assume in throughout the code that this will not return NULL. If code
583 // triggers this for valid reasons, it should test status_area_widget first.
[email protected]80549c152013-07-02 01:42:47584 CHECK(shelf_->status_area_widget());
[email protected]478c6c32013-03-09 02:50:58585 return shelf_->status_area_widget()->system_tray();
[email protected]a0afeb12012-12-10 22:57:09586}
587
[email protected]940fb1c2013-06-18 16:54:28588void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
589 ui::MenuSourceType source_type) {
msw141c6b22016-03-04 00:55:30590 ShellDelegate* delegate = Shell::GetInstance()->delegate();
591 DCHECK(delegate);
dchenga94547472016-04-08 08:41:11592 std::unique_ptr<ui::MenuModel> menu_model(
msw953caf1f2016-03-18 00:33:29593 delegate->CreateContextMenu(shelf_->shelf(), nullptr));
[email protected]7f7f65c2013-04-17 16:47:13594 if (!menu_model)
[email protected]8e837ec2013-01-31 01:48:33595 return;
[email protected]431552c2012-10-23 00:38:33596
[email protected]6175fc42013-04-05 05:58:58597 // Background controller may not be set yet if user clicked on status are
598 // before initial animation completion. See crbug.com/222218
[email protected]0bf61732013-07-02 04:35:10599 if (!wallpaper_controller_.get())
[email protected]431552c2012-10-23 00:38:33600 return;
601
[email protected]0a37a5d2014-07-15 00:42:23602 views::MenuRunner menu_runner(menu_model.get(),
603 views::MenuRunner::CONTEXT_MENU);
[email protected]0bf61732013-07-02 04:35:10604 if (menu_runner.RunMenuAt(wallpaper_controller_->widget(),
[email protected]fd6c0a62014-05-01 07:50:35605 NULL,
606 gfx::Rect(location_in_screen, gfx::Size()),
607 views::MENU_ANCHOR_TOPLEFT,
[email protected]0a37a5d2014-07-15 00:42:23608 source_type) == views::MenuRunner::MENU_DELETED) {
[email protected]6175fc42013-04-05 05:58:58609 return;
610 }
611
[email protected]431552c2012-10-23 00:38:33612 Shell::GetInstance()->UpdateShelfVisibility();
613}
614
[email protected]e74aaf0a2012-10-12 18:42:28615void RootWindowController::UpdateShelfVisibility() {
[email protected]478c6c32013-03-09 02:50:58616 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]e74aaf0a2012-10-12 18:42:28617}
618
varkhad99fa94f2015-06-29 22:35:46619aura::Window* RootWindowController::GetWindowForFullscreenMode() {
sky4dc7d0492016-04-28 04:15:22620 return wm::WmWindowAura::GetAuraWindow(
621 wm::GetWindowForFullscreenMode(wm::WmWindowAura::Get(GetRootWindow())));
[email protected]2ee2f5d2013-01-10 23:37:16622}
623
[email protected]b6ba05d902013-10-04 21:38:45624void RootWindowController::ActivateKeyboard(
625 keyboard::KeyboardController* keyboard_controller) {
626 if (!keyboard::IsKeyboardEnabled() ||
627 GetContainer(kShellWindowId_VirtualKeyboardContainer)) {
628 return;
629 }
630 DCHECK(keyboard_controller);
bshe9858b4a2014-09-16 20:46:38631 keyboard_controller->AddObserver(shelf()->shelf_layout_manager());
632 keyboard_controller->AddObserver(panel_layout_manager_);
633 keyboard_controller->AddObserver(docked_layout_manager_);
634 keyboard_controller->AddObserver(workspace_controller_->layout_manager());
rsadam7bd510bb2014-12-09 20:10:56635 keyboard_controller->AddObserver(
636 always_on_top_controller_->GetLayoutManager());
bshe9858b4a2014-09-16 20:46:38637 Shell::GetInstance()->delegate()->VirtualKeyboardActivated(true);
bshec3875422014-09-29 13:21:30638 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]b2da9b602014-03-05 18:39:52639 DCHECK(parent);
[email protected]b6ba05d902013-10-04 21:38:45640 aura::Window* keyboard_container =
641 keyboard_controller->GetContainerWindow();
642 keyboard_container->set_id(kShellWindowId_VirtualKeyboardContainer);
643 parent->AddChild(keyboard_container);
[email protected]b6ba05d902013-10-04 21:38:45644}
[email protected]86459e2c2013-04-10 13:39:24645
[email protected]b6ba05d902013-10-04 21:38:45646void RootWindowController::DeactivateKeyboard(
647 keyboard::KeyboardController* keyboard_controller) {
[email protected]e1b299b2014-01-29 23:53:41648 if (!keyboard_controller ||
649 !keyboard_controller->keyboard_container_initialized()) {
[email protected]b6ba05d902013-10-04 21:38:45650 return;
[email protected]e1b299b2014-01-29 23:53:41651 }
[email protected]b6ba05d902013-10-04 21:38:45652 aura::Window* keyboard_container =
653 keyboard_controller->GetContainerWindow();
[email protected]f5c9dbc2014-04-11 08:13:45654 if (keyboard_container->GetRootWindow() == GetRootWindow()) {
bshec3875422014-09-29 13:21:30655 aura::Window* parent =
656 GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]b2da9b602014-03-05 18:39:52657 DCHECK(parent);
658 parent->RemoveChild(keyboard_container);
bshe9858b4a2014-09-16 20:46:38659 // Virtual keyboard may be deactivated while still showing, notify all
660 // observers that keyboard bounds changed to 0 before remove them.
661 keyboard_controller->NotifyKeyboardBoundsChanging(gfx::Rect());
662 keyboard_controller->RemoveObserver(shelf()->shelf_layout_manager());
663 keyboard_controller->RemoveObserver(panel_layout_manager_);
664 keyboard_controller->RemoveObserver(docked_layout_manager_);
665 keyboard_controller->RemoveObserver(
666 workspace_controller_->layout_manager());
rsadam7bd510bb2014-12-09 20:10:56667 keyboard_controller->RemoveObserver(
668 always_on_top_controller_->GetLayoutManager());
bshe9858b4a2014-09-16 20:46:38669 Shell::GetInstance()->delegate()->VirtualKeyboardActivated(false);
[email protected]86459e2c2013-04-10 13:39:24670 }
671}
672
[email protected]602022b2014-03-31 17:07:31673bool RootWindowController::IsVirtualKeyboardWindow(aura::Window* window) {
bshec3875422014-09-29 13:21:30674 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]602022b2014-03-31 17:07:31675 return parent ? parent->Contains(window) : false;
676}
677
[email protected]a4cd6d32012-09-12 03:42:13678////////////////////////////////////////////////////////////////////////////////
679// RootWindowController, private:
680
[email protected]f5c9dbc2014-04-11 08:13:45681RootWindowController::RootWindowController(AshWindowTreeHost* ash_host)
682 : ash_host_(ash_host),
[email protected]a273d33a2013-10-17 12:41:21683 root_window_layout_(NULL),
684 docked_layout_manager_(NULL),
685 panel_layout_manager_(NULL),
686 touch_hud_debug_(NULL),
687 touch_hud_projection_(NULL) {
[email protected]f5c9dbc2014-04-11 08:13:45688 aura::Window* root_window = GetRootWindow();
689 GetRootWindowSettings(root_window)->controller = this;
[email protected]a273d33a2013-10-17 12:41:21690
691 stacking_controller_.reset(new StackingController);
[email protected]f5c9dbc2014-04-11 08:13:45692 aura::client::SetWindowTreeClient(root_window, stacking_controller_.get());
693 capture_client_.reset(new ::wm::ScopedCaptureClient(root_window));
[email protected]a273d33a2013-10-17 12:41:21694}
695
[email protected]608de6c2013-10-29 00:14:28696void RootWindowController::Init(RootWindowType root_window_type,
697 bool first_run_after_boot) {
[email protected]f5c9dbc2014-04-11 08:13:45698 aura::Window* root_window = GetRootWindow();
[email protected]51f438112013-11-18 19:32:50699 Shell* shell = Shell::GetInstance();
[email protected]f5c9dbc2014-04-11 08:13:45700 shell->InitRootWindow(root_window);
[email protected]a273d33a2013-10-17 12:41:21701
[email protected]f5c9dbc2014-04-11 08:13:45702 CreateContainersInRootWindow(root_window);
[email protected]608de6c2013-10-29 00:14:28703
[email protected]a273d33a2013-10-17 12:41:21704 CreateSystemBackground(first_run_after_boot);
705
706 InitLayoutManagers();
707 InitTouchHuds();
708
709 if (Shell::GetPrimaryRootWindowController()->
710 GetSystemModalLayoutManager(NULL)->has_modal_background()) {
711 GetSystemModalLayoutManager(NULL)->CreateModalBackground();
712 }
713
[email protected]a273d33a2013-10-17 12:41:21714 shell->AddShellObserver(this);
715
[email protected]608de6c2013-10-29 00:14:28716 if (root_window_type == PRIMARY) {
[email protected]a3565792013-10-18 12:52:37717 root_window_layout()->OnWindowResized();
bshe9858b4a2014-09-16 20:46:38718 shell->InitKeyboard();
[email protected]a273d33a2013-10-17 12:41:21719 } else {
720 root_window_layout()->OnWindowResized();
[email protected]f5c9dbc2014-04-11 08:13:45721 ash_host_->AsWindowTreeHost()->Show();
[email protected]a273d33a2013-10-17 12:41:21722
[email protected]864b58552013-12-19 04:19:38723 // Create a shelf if a user is already logged in.
[email protected]a273d33a2013-10-17 12:41:21724 if (shell->session_state_delegate()->NumberOfLoggedInUsers())
[email protected]864b58552013-12-19 04:19:38725 shelf()->CreateShelf();
[email protected]0e3e7cb2014-04-12 05:18:25726
727 // Notify shell observers about new root window.
728 shell->OnRootWindowAdded(root_window);
[email protected]a273d33a2013-10-17 12:41:21729 }
[email protected]a825e8312014-05-05 22:05:01730
731#if defined(OS_CHROMEOS)
pgal.u-szegedd84534d32014-10-29 12:34:30732 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]2e0b2352014-07-28 13:28:28733 switches::kAshDisableTouchExplorationMode)) {
[email protected]7d487592014-07-24 03:54:50734 touch_exploration_manager_.reset(new AshTouchExplorationManager(this));
[email protected]a825e8312014-05-05 22:05:01735 }
736#endif
[email protected]a273d33a2013-10-17 12:41:21737}
738
[email protected]756bda12013-07-03 08:17:06739void RootWindowController::InitLayoutManagers() {
[email protected]f5c9dbc2014-04-11 08:13:45740 aura::Window* root_window = GetRootWindow();
741 root_window_layout_ = new RootWindowLayoutManager(root_window);
742 root_window->SetLayoutManager(root_window_layout_);
[email protected]756bda12013-07-03 08:17:06743
744 aura::Window* default_container =
745 GetContainer(kShellWindowId_DefaultContainer);
746 // Workspace manager has its own layout managers.
sky1e30f062016-04-14 21:19:16747
748 WorkspaceLayoutManagerDelegateImpl* workspace_layout_manager_delegate =
749 new WorkspaceLayoutManagerDelegateImpl(root_window);
750 workspace_controller_.reset(new WorkspaceController(
751 default_container, base::WrapUnique(workspace_layout_manager_delegate)));
[email protected]756bda12013-07-03 08:17:06752
sky4dc7d0492016-04-28 04:15:22753 wm::WmWindow* always_on_top_container =
754 wm::WmWindowAura::Get(GetContainer(kShellWindowId_AlwaysOnTopContainer));
rsadam7bd510bb2014-12-09 20:10:56755 always_on_top_controller_.reset(
756 new AlwaysOnTopController(always_on_top_container));
[email protected]756bda12013-07-03 08:17:06757
758 DCHECK(!shelf_.get());
[email protected]093b8d642014-04-03 20:59:28759 aura::Window* shelf_container = GetContainer(kShellWindowId_ShelfContainer);
[email protected]756bda12013-07-03 08:17:06760 // TODO(harrym): Remove when status area is view.
[email protected]093b8d642014-04-03 20:59:28761 aura::Window* status_container = GetContainer(kShellWindowId_StatusContainer);
[email protected]756bda12013-07-03 08:17:06762 shelf_.reset(new ShelfWidget(
763 shelf_container, status_container, workspace_controller()));
sky1e30f062016-04-14 21:19:16764 workspace_layout_manager_delegate->set_shelf(shelf_->shelf_layout_manager());
[email protected]756bda12013-07-03 08:17:06765
[email protected]cf6fea22013-08-07 14:24:01766 if (!Shell::GetInstance()->session_state_delegate()->
767 IsActiveUserSessionStarted()) {
768 // This window exists only to be a event target on login screen.
769 // It does not have to handle events, nor be visible.
770 mouse_event_target_.reset(new aura::Window(new EmptyWindowDelegate));
danakjb161836d2015-04-03 05:14:18771 mouse_event_target_->Init(ui::LAYER_NOT_DRAWN);
[email protected]cf6fea22013-08-07 14:24:01772
773 aura::Window* lock_background_container =
[email protected]093b8d642014-04-03 20:59:28774 GetContainer(kShellWindowId_LockScreenBackgroundContainer);
[email protected]cf6fea22013-08-07 14:24:01775 lock_background_container->AddChild(mouse_event_target_.get());
776 mouse_event_target_->Show();
777 }
778
[email protected]756bda12013-07-03 08:17:06779 // Create Docked windows layout manager
sky3f7af8812016-04-21 19:30:03780 wm::WmWindow* docked_container =
781 wm::WmWindowAura::Get(GetContainer(kShellWindowId_DockedContainer));
skyca4122692016-04-26 04:47:57782 docked_layout_manager_ = new DockedWindowLayoutManager(docked_container);
sky3f7af8812016-04-21 19:30:03783 docked_container->SetLayoutManager(base::WrapUnique(docked_layout_manager_));
[email protected]756bda12013-07-03 08:17:06784
[email protected]1ca79d42014-07-18 16:26:10785 // Installs SnapLayoutManager to containers who set the
786 // |kSnapsChildrenToPhysicalPixelBoundary| property.
787 wm::InstallSnapLayoutManagerToContainers(root_window);
788
[email protected]756bda12013-07-03 08:17:06789 // Create Panel layout manager
[email protected]093b8d642014-04-03 20:59:28790 aura::Window* panel_container = GetContainer(kShellWindowId_PanelContainer);
skyad0315022016-04-25 19:40:31791 wm::WmWindow* wm_panel_container = wm::WmWindowAura::Get(panel_container);
792 panel_layout_manager_ = new PanelLayoutManager(wm_panel_container);
793 wm_panel_container->SetLayoutManager(base::WrapUnique(panel_layout_manager_));
[email protected]3537d472014-01-15 05:45:31794 panel_container_handler_.reset(new PanelWindowEventHandler);
795 panel_container->AddPreTargetHandler(panel_container_handler_.get());
[email protected]b8642ec2014-04-17 05:20:39796
797 // Install an AttachedPanelWindowTargeter on the panel container to make it
798 // easier to correctly target shelf buttons with touch.
799 gfx::Insets mouse_extend(-kResizeOutsideBoundsSize,
800 -kResizeOutsideBoundsSize,
801 -kResizeOutsideBoundsSize,
802 -kResizeOutsideBoundsSize);
803 gfx::Insets touch_extend = mouse_extend.Scale(
804 kResizeOutsideBoundsScaleForTouch);
dchenga94547472016-04-08 08:41:11805 panel_container->SetEventTargeter(
806 std::unique_ptr<ui::EventTargeter>(new AttachedPanelWindowTargeter(
807 panel_container, mouse_extend, touch_extend, panel_layout_manager_)));
[email protected]756bda12013-07-03 08:17:06808}
809
810void RootWindowController::InitTouchHuds() {
pgal.u-szegedd84534d32014-10-29 12:34:30811 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
[email protected]756bda12013-07-03 08:17:06812 if (command_line->HasSwitch(switches::kAshTouchHud))
[email protected]f5c9dbc2014-04-11 08:13:45813 set_touch_hud_debug(new TouchHudDebug(GetRootWindow()));
[email protected]756bda12013-07-03 08:17:06814 if (Shell::GetInstance()->is_touch_hud_projection_enabled())
815 EnableTouchHudProjection();
816}
817
818void RootWindowController::CreateSystemBackground(
819 bool is_first_run_after_boot) {
820 SkColor color = SK_ColorBLACK;
821#if defined(OS_CHROMEOS)
822 if (is_first_run_after_boot)
823 color = kChromeOsBootColor;
824#endif
825 system_background_.reset(
[email protected]f5c9dbc2014-04-11 08:13:45826 new SystemBackgroundController(GetRootWindow(), color));
[email protected]756bda12013-07-03 08:17:06827
828#if defined(OS_CHROMEOS)
829 // Make a copy of the system's boot splash screen so we can composite it
830 // onscreen until the desktop background is ready.
831 if (is_first_run_after_boot &&
pgal.u-szegedd84534d32014-10-29 12:34:30832 (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]756bda12013-07-03 08:17:06833 switches::kAshCopyHostBackgroundAtBoot) ||
pgal.u-szegedd84534d32014-10-29 12:34:30834 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]756bda12013-07-03 08:17:06835 switches::kAshAnimateFromBootSplashScreen)))
[email protected]f5c9dbc2014-04-11 08:13:45836 boot_splash_screen_.reset(new BootSplashScreen(GetHost()));
[email protected]756bda12013-07-03 08:17:06837#endif
838}
839
[email protected]a4cd6d32012-09-12 03:42:13840void RootWindowController::CreateContainersInRootWindow(
[email protected]41baaed2013-11-09 04:18:26841 aura::Window* root_window) {
[email protected]a4cd6d32012-09-12 03:42:13842 // These containers are just used by PowerButtonController to animate groups
843 // of containers simultaneously without messing up the current transformations
844 // on those containers. These are direct children of the root window; all of
845 // the other containers are their children.
[email protected]e6e41d2f2012-10-29 19:22:19846
847 // The desktop background container is not part of the lock animation, so it
848 // is not included in those animate groups.
[email protected]a4cd6d32012-09-12 03:42:13849 // When screen is locked desktop background is moved to lock screen background
850 // container (moved back on unlock). We want to make sure that there's an
851 // opaque layer occluding the non-lock-screen layers.
[email protected]e6e41d2f2012-10-29 19:22:19852 aura::Window* desktop_background_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27853 kShellWindowId_DesktopBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13854 "DesktopBackgroundContainer",
855 root_window);
[email protected]e319c7e2014-03-14 19:56:14856 ::wm::SetChildWindowVisibilityChangesAnimated(desktop_background_container);
[email protected]a4cd6d32012-09-12 03:42:13857
858 aura::Window* non_lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27859 kShellWindowId_NonLockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13860 "NonLockScreenContainersContainer",
861 root_window);
oshimaf52e1be2015-05-06 21:29:34862 // Clip all windows inside this container, as half pixel of the window's
863 // texture may become visible when the screen is scaled. crbug.com/368591.
864 non_lock_screen_containers->layer()->SetMasksToBounds(true);
[email protected]a4cd6d32012-09-12 03:42:13865
866 aura::Window* lock_background_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27867 kShellWindowId_LockScreenBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13868 "LockScreenBackgroundContainer",
869 root_window);
[email protected]e319c7e2014-03-14 19:56:14870 ::wm::SetChildWindowVisibilityChangesAnimated(lock_background_containers);
[email protected]a4cd6d32012-09-12 03:42:13871
872 aura::Window* lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27873 kShellWindowId_LockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13874 "LockScreenContainersContainer",
875 root_window);
876 aura::Window* lock_screen_related_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27877 kShellWindowId_LockScreenRelatedContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13878 "LockScreenRelatedContainersContainer",
879 root_window);
880
[email protected]c0ce80e2012-10-05 23:28:27881 CreateContainer(kShellWindowId_UnparentedControlContainer,
[email protected]a4cd6d32012-09-12 03:42:13882 "UnparentedControlContainer",
883 non_lock_screen_containers);
884
885 aura::Window* default_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27886 kShellWindowId_DefaultContainer,
[email protected]a4cd6d32012-09-12 03:42:13887 "DefaultContainer",
888 non_lock_screen_containers);
[email protected]e319c7e2014-03-14 19:56:14889 ::wm::SetChildWindowVisibilityChangesAnimated(default_container);
[email protected]1ca79d42014-07-18 16:26:10890 wm::SetSnapsChildrenToPhysicalPixelBoundary(default_container);
[email protected]a4cd6d32012-09-12 03:42:13891 SetUsesScreenCoordinates(default_container);
[email protected]c5be8d672014-01-07 13:33:41892 SetUsesEasyResizeTargeter(default_container);
[email protected]a4cd6d32012-09-12 03:42:13893
894 aura::Window* always_on_top_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27895 kShellWindowId_AlwaysOnTopContainer,
[email protected]a4cd6d32012-09-12 03:42:13896 "AlwaysOnTopContainer",
897 non_lock_screen_containers);
[email protected]e319c7e2014-03-14 19:56:14898 ::wm::SetChildWindowVisibilityChangesAnimated(always_on_top_container);
[email protected]1ca79d42014-07-18 16:26:10899 wm::SetSnapsChildrenToPhysicalPixelBoundary(always_on_top_container);
[email protected]a4cd6d32012-09-12 03:42:13900 SetUsesScreenCoordinates(always_on_top_container);
901
[email protected]beb4e5c2013-06-18 15:37:07902 aura::Window* docked_container = CreateContainer(
903 kShellWindowId_DockedContainer,
904 "DockedContainer",
905 non_lock_screen_containers);
[email protected]e319c7e2014-03-14 19:56:14906 ::wm::SetChildWindowVisibilityChangesAnimated(docked_container);
[email protected]1ca79d42014-07-18 16:26:10907 wm::SetSnapsChildrenToPhysicalPixelBoundary(docked_container);
[email protected]beb4e5c2013-06-18 15:37:07908 SetUsesScreenCoordinates(docked_container);
[email protected]1ff0c492014-01-21 20:20:44909 SetUsesEasyResizeTargeter(docked_container);
[email protected]beb4e5c2013-06-18 15:37:07910
[email protected]3f13cf12013-07-12 05:13:59911 aura::Window* shelf_container =
[email protected]478c6c32013-03-09 02:50:58912 CreateContainer(kShellWindowId_ShelfContainer,
[email protected]3f13cf12013-07-12 05:13:59913 "ShelfContainer",
[email protected]a4cd6d32012-09-12 03:42:13914 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10915 wm::SetSnapsChildrenToPhysicalPixelBoundary(shelf_container);
[email protected]3f13cf12013-07-12 05:13:59916 SetUsesScreenCoordinates(shelf_container);
917 DescendantShouldStayInSameRootWindow(shelf_container);
[email protected]a4cd6d32012-09-12 03:42:13918
[email protected]f2026eb2013-10-22 14:28:56919 aura::Window* panel_container = CreateContainer(
920 kShellWindowId_PanelContainer,
921 "PanelContainer",
922 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10923 wm::SetSnapsChildrenToPhysicalPixelBoundary(panel_container);
[email protected]f2026eb2013-10-22 14:28:56924 SetUsesScreenCoordinates(panel_container);
925
926 aura::Window* shelf_bubble_container =
927 CreateContainer(kShellWindowId_ShelfBubbleContainer,
928 "ShelfBubbleContainer",
929 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10930 wm::SetSnapsChildrenToPhysicalPixelBoundary(shelf_bubble_container);
[email protected]f2026eb2013-10-22 14:28:56931 SetUsesScreenCoordinates(shelf_bubble_container);
932 DescendantShouldStayInSameRootWindow(shelf_bubble_container);
933
[email protected]dc851a4e52012-10-03 00:05:55934 aura::Window* app_list_container =
[email protected]c0ce80e2012-10-05 23:28:27935 CreateContainer(kShellWindowId_AppListContainer,
[email protected]dc851a4e52012-10-03 00:05:55936 "AppListContainer",
937 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10938 wm::SetSnapsChildrenToPhysicalPixelBoundary(app_list_container);
[email protected]dc851a4e52012-10-03 00:05:55939 SetUsesScreenCoordinates(app_list_container);
[email protected]a4cd6d32012-09-12 03:42:13940
941 aura::Window* modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27942 kShellWindowId_SystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13943 "SystemModalContainer",
944 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10945 wm::SetSnapsChildrenToPhysicalPixelBoundary(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13946 modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27947 new SystemModalContainerLayoutManager(modal_container));
[email protected]e319c7e2014-03-14 19:56:14948 ::wm::SetChildWindowVisibilityChangesAnimated(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13949 SetUsesScreenCoordinates(modal_container);
[email protected]c5be8d672014-01-07 13:33:41950 SetUsesEasyResizeTargeter(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13951
[email protected]a4cd6d32012-09-12 03:42:13952 // TODO(beng): Figure out if we can make this use
953 // SystemModalContainerEventFilter instead of stops_event_propagation.
954 aura::Window* lock_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27955 kShellWindowId_LockScreenContainer,
[email protected]a4cd6d32012-09-12 03:42:13956 "LockScreenContainer",
957 lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10958 wm::SetSnapsChildrenToPhysicalPixelBoundary(lock_container);
oshima96f6a502015-05-02 08:43:32959 lock_container->SetLayoutManager(new LockLayoutManager(lock_container));
[email protected]a4cd6d32012-09-12 03:42:13960 SetUsesScreenCoordinates(lock_container);
961 // TODO(beng): stopsevents
962
963 aura::Window* lock_modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27964 kShellWindowId_LockSystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13965 "LockSystemModalContainer",
966 lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10967 wm::SetSnapsChildrenToPhysicalPixelBoundary(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13968 lock_modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27969 new SystemModalContainerLayoutManager(lock_modal_container));
[email protected]e319c7e2014-03-14 19:56:14970 ::wm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13971 SetUsesScreenCoordinates(lock_modal_container);
[email protected]c5be8d672014-01-07 13:33:41972 SetUsesEasyResizeTargeter(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13973
974 aura::Window* status_container =
[email protected]c0ce80e2012-10-05 23:28:27975 CreateContainer(kShellWindowId_StatusContainer,
[email protected]a4cd6d32012-09-12 03:42:13976 "StatusContainer",
977 lock_screen_related_containers);
[email protected]1ca79d42014-07-18 16:26:10978 wm::SetSnapsChildrenToPhysicalPixelBoundary(status_container);
[email protected]a4cd6d32012-09-12 03:42:13979 SetUsesScreenCoordinates(status_container);
[email protected]e887c6c2013-07-08 19:35:53980 DescendantShouldStayInSameRootWindow(status_container);
[email protected]a4cd6d32012-09-12 03:42:13981
982 aura::Window* settings_bubble_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27983 kShellWindowId_SettingBubbleContainer,
[email protected]a4cd6d32012-09-12 03:42:13984 "SettingBubbleContainer",
985 lock_screen_related_containers);
[email protected]e319c7e2014-03-14 19:56:14986 ::wm::SetChildWindowVisibilityChangesAnimated(settings_bubble_container);
[email protected]1ca79d42014-07-18 16:26:10987 wm::SetSnapsChildrenToPhysicalPixelBoundary(settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13988 SetUsesScreenCoordinates(settings_bubble_container);
[email protected]e887c6c2013-07-08 19:35:53989 DescendantShouldStayInSameRootWindow(settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13990
kevers23f3987d2014-09-17 13:50:12991 aura::Window* virtual_keyboard_parent_container =
bshec3875422014-09-29 13:21:30992 CreateContainer(kShellWindowId_ImeWindowParentContainer,
kevers23f3987d2014-09-17 13:50:12993 "VirtualKeyboardParentContainer",
994 lock_screen_related_containers);
995 wm::SetSnapsChildrenToPhysicalPixelBoundary(
996 virtual_keyboard_parent_container);
997 SetUsesScreenCoordinates(virtual_keyboard_parent_container);
998
[email protected]a4cd6d32012-09-12 03:42:13999 aura::Window* menu_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:271000 kShellWindowId_MenuContainer,
[email protected]a4cd6d32012-09-12 03:42:131001 "MenuContainer",
1002 lock_screen_related_containers);
[email protected]e319c7e2014-03-14 19:56:141003 ::wm::SetChildWindowVisibilityChangesAnimated(menu_container);
[email protected]1ca79d42014-07-18 16:26:101004 wm::SetSnapsChildrenToPhysicalPixelBoundary(menu_container);
[email protected]a4cd6d32012-09-12 03:42:131005 SetUsesScreenCoordinates(menu_container);
1006
1007 aura::Window* drag_drop_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:271008 kShellWindowId_DragImageAndTooltipContainer,
[email protected]a4cd6d32012-09-12 03:42:131009 "DragImageAndTooltipContainer",
1010 lock_screen_related_containers);
[email protected]e319c7e2014-03-14 19:56:141011 ::wm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
[email protected]1ca79d42014-07-18 16:26:101012 wm::SetSnapsChildrenToPhysicalPixelBoundary(drag_drop_container);
[email protected]a4cd6d32012-09-12 03:42:131013 SetUsesScreenCoordinates(drag_drop_container);
1014
1015 aura::Window* overlay_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:271016 kShellWindowId_OverlayContainer,
[email protected]a4cd6d32012-09-12 03:42:131017 "OverlayContainer",
1018 lock_screen_related_containers);
[email protected]1ca79d42014-07-18 16:26:101019 wm::SetSnapsChildrenToPhysicalPixelBoundary(overlay_container);
[email protected]a4cd6d32012-09-12 03:42:131020 SetUsesScreenCoordinates(overlay_container);
[email protected]a07615f2012-10-24 08:23:081021
[email protected]b2da9b602014-03-05 18:39:521022#if defined(OS_CHROMEOS)
1023 aura::Window* mouse_cursor_container = CreateContainer(
1024 kShellWindowId_MouseCursorContainer,
1025 "MouseCursorContainer",
1026 root_window);
1027 SetUsesScreenCoordinates(mouse_cursor_container);
1028#endif
1029
[email protected]a07615f2012-10-24 08:23:081030 CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
[email protected]b2da9b602014-03-05 18:39:521031 "PowerButtonAnimationContainer", root_window);
[email protected]a4cd6d32012-09-12 03:42:131032}
1033
[email protected]d141b922013-07-09 08:13:171034void RootWindowController::EnableTouchHudProjection() {
1035 if (touch_hud_projection_)
1036 return;
[email protected]f5c9dbc2014-04-11 08:13:451037 set_touch_hud_projection(new TouchHudProjection(GetRootWindow()));
[email protected]d141b922013-07-09 08:13:171038}
1039
1040void RootWindowController::DisableTouchHudProjection() {
1041 if (!touch_hud_projection_)
1042 return;
1043 touch_hud_projection_->Remove();
1044}
1045
1046void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
1047 shelf_->shelf_layout_manager()->UpdateVisibilityState();
1048}
1049
1050void RootWindowController::OnTouchHudProjectionToggled(bool enabled) {
1051 if (enabled)
1052 EnableTouchHudProjection();
1053 else
1054 DisableTouchHudProjection();
1055}
1056
[email protected]6b2d4a0b2013-09-06 06:29:541057RootWindowController* GetRootWindowController(
[email protected]bf9cdb362013-10-25 19:22:451058 const aura::Window* root_window) {
jamescook5d74ac02016-05-12 19:57:121059 if (!root_window)
1060 return nullptr;
1061
1062 if (Shell::GetInstance()->in_mus()) {
1063 // On mus, like desktop aura, each top-level widget has its own root window,
1064 // so |root_window| is not necessarily the display's root. For now, just
1065 // the use the primary display root.
1066 // TODO(jamescook): Multi-display support. This depends on how mus windows
1067 // will be owned by displays.
1068 aura::Window* primary_root_window = Shell::GetInstance()
1069 ->window_tree_host_manager()
1070 ->GetPrimaryRootWindow();
1071 return GetRootWindowSettings(primary_root_window)->controller;
1072 }
1073
1074 return GetRootWindowSettings(root_window)->controller;
[email protected]6b2d4a0b2013-09-06 06:29:541075}
1076
[email protected]d90b8392012-06-13 09:34:561077} // namespace ash