blob: 2b6a6213d78e39836a585ece87089bae03235015 [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]2c5db9e2014-02-27 13:58:1428#include "ash/switchable_windows.h"
[email protected]e74aaf0a2012-10-12 18:42:2829#include "ash/system/status_area_widget.h"
[email protected]8674b312012-10-12 19:02:4430#include "ash/system/tray/system_tray_delegate.h"
[email protected]a825e8312014-05-05 22:05:0131#include "ash/system/tray/system_tray_notifier.h"
[email protected]2b8a9bb2013-07-01 22:43:4032#include "ash/touch/touch_hud_debug.h"
33#include "ash/touch/touch_hud_projection.h"
[email protected]80549c152013-07-02 01:42:4734#include "ash/touch/touch_observer_hud.h"
35#include "ash/wm/always_on_top_controller.h"
sky3f7af8812016-04-21 19:30:0336#include "ash/wm/aura/aura_layout_manager_adapter.h"
skyf961b3562016-04-20 00:53:5037#include "ash/wm/aura/wm_window_aura.h"
sky1e30f062016-04-14 21:19:1638#include "ash/wm/common/workspace/workspace_layout_manager_delegate.h"
[email protected]beb4e5c2013-06-18 15:37:0739#include "ash/wm/dock/docked_window_layout_manager.h"
[email protected]68d51332014-06-06 13:51:1340#include "ash/wm/lock_layout_manager.h"
[email protected]b8642ec2014-04-17 05:20:3941#include "ash/wm/panels/attached_panel_window_targeter.h"
[email protected]7095a652013-03-07 19:41:4942#include "ash/wm/panels/panel_layout_manager.h"
[email protected]100659412013-06-21 22:59:5543#include "ash/wm/panels/panel_window_event_handler.h"
[email protected]d90b8392012-06-13 09:34:5644#include "ash/wm/root_window_layout_manager.h"
[email protected]2a2caa02013-01-22 20:50:3645#include "ash/wm/stacking_controller.h"
[email protected]e74aaf0a2012-10-12 18:42:2846#include "ash/wm/status_area_layout_manager.h"
[email protected]e6e41d2f2012-10-29 19:22:1947#include "ash/wm/system_background_controller.h"
[email protected]d90b8392012-06-13 09:34:5648#include "ash/wm/system_modal_container_layout_manager.h"
[email protected]8d625fb2012-07-18 16:40:0649#include "ash/wm/window_properties.h"
[email protected]a41b4e12013-09-20 04:36:3450#include "ash/wm/window_state.h"
sky8d5646fe2016-04-15 17:03:4651#include "ash/wm/window_state_aura.h"
[email protected]700849f2013-04-30 17:49:2052#include "ash/wm/window_util.h"
[email protected]1af71f72014-01-29 20:00:5553#include "ash/wm/workspace/workspace_layout_manager.h"
[email protected]d90b8392012-06-13 09:34:5654#include "ash/wm/workspace_controller.h"
[email protected]e6e41d2f2012-10-29 19:22:1955#include "base/command_line.h"
sky1e30f062016-04-14 21:19:1656#include "base/memory/ptr_util.h"
[email protected]1e84c632013-06-27 23:12:2157#include "base/time/time.h"
[email protected]f1853122012-06-27 16:21:2658#include "ui/aura/client/aura_constants.h"
[email protected]2374d1812014-03-04 03:42:2759#include "ui/aura/client/screen_position_client.h"
[email protected]f1853122012-06-27 16:21:2660#include "ui/aura/window.h"
[email protected]cf6fea22013-08-07 14:24:0161#include "ui/aura/window_delegate.h"
[email protected]fcc51c952014-02-21 21:31:2662#include "ui/aura/window_event_dispatcher.h"
[email protected]f1853122012-06-27 16:21:2663#include "ui/aura/window_observer.h"
[email protected]8b3e3d82013-08-20 14:36:3064#include "ui/aura/window_tracker.h"
[email protected]cf6fea22013-08-07 14:24:0165#include "ui/base/hit_test.h"
[email protected]431552c2012-10-23 00:38:3366#include "ui/base/models/menu_model.h"
[email protected]f8e6aad2013-08-30 21:49:1167#include "ui/gfx/display.h"
[email protected]8d625fb2012-07-18 16:40:0668#include "ui/gfx/screen.h"
[email protected]86459e2c2013-04-10 13:39:2469#include "ui/keyboard/keyboard_controller.h"
70#include "ui/keyboard/keyboard_util.h"
[email protected]431552c2012-10-23 00:38:3371#include "ui/views/controls/menu/menu_runner.h"
72#include "ui/views/view_model.h"
73#include "ui/views/view_model_utils.h"
[email protected]ee3ed10772014-03-11 22:02:0174#include "ui/wm/core/capture_controller.h"
[email protected]e319c7e2014-03-14 19:56:1475#include "ui/wm/core/easy_resize_window_targeter.h"
[email protected]ee3ed10772014-03-11 22:02:0176#include "ui/wm/core/visibility_controller.h"
77#include "ui/wm/core/window_util.h"
[email protected]af4552b22014-03-21 19:45:0178#include "ui/wm/public/drag_drop_client.h"
79#include "ui/wm/public/tooltip_client.h"
[email protected]5b251f12013-12-19 01:50:0580#include "ui/wm/public/window_types.h"
[email protected]d90b8392012-06-13 09:34:5681
[email protected]252eb232013-08-14 22:09:2782#if defined(OS_CHROMEOS)
[email protected]7d487592014-07-24 03:54:5083#include "ash/ash_touch_exploration_manager_chromeos.h"
[email protected]252eb232013-08-14 22:09:2784#include "ash/wm/boot_splash_screen_chromeos.h"
[email protected]a825e8312014-05-05 22:05:0185#include "ui/chromeos/touch_exploration_controller.h"
[email protected]252eb232013-08-14 22:09:2786#endif
87
[email protected]d90b8392012-06-13 09:34:5688namespace ash {
89namespace {
90
[email protected]252eb232013-08-14 22:09:2791#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:4992// Duration for the animation that hides the boot splash screen, in
93// milliseconds. This should be short enough in relation to
94// wm/window_animation.cc's brightness/grayscale fade animation that the login
95// background image animation isn't hidden by the splash screen animation.
96const int kBootSplashScreenHideDurationMs = 500;
[email protected]252eb232013-08-14 22:09:2797#endif
[email protected]bca9a7e2012-11-10 06:25:4998
[email protected]d90b8392012-06-13 09:34:5699// Creates a new window for use as a container.
100aura::Window* CreateContainer(int window_id,
101 const char* name,
102 aura::Window* parent) {
103 aura::Window* container = new aura::Window(NULL);
104 container->set_id(window_id);
105 container->SetName(name);
danakjb161836d2015-04-03 05:14:18106 container->Init(ui::LAYER_NOT_DRAWN);
[email protected]d90b8392012-06-13 09:34:56107 parent->AddChild(container);
[email protected]093b8d642014-04-03 20:59:28108 if (window_id != kShellWindowId_UnparentedControlContainer)
[email protected]d90b8392012-06-13 09:34:56109 container->Show();
110 return container;
111}
112
[email protected]2816c2462013-12-17 02:22:25113float ToRelativeValue(int value, int src, int dst) {
114 return static_cast<float>(value) / static_cast<float>(src) * dst;
115}
116
117void MoveOriginRelativeToSize(const gfx::Size& src_size,
118 const gfx::Size& dst_size,
119 gfx::Rect* bounds_in_out) {
120 gfx::Point origin = bounds_in_out->origin();
121 bounds_in_out->set_origin(gfx::Point(
122 ToRelativeValue(origin.x(), src_size.width(), dst_size.width()),
123 ToRelativeValue(origin.y(), src_size.height(), dst_size.height())));
124}
125
[email protected]95058572012-08-20 14:57:29126// Reparents |window| to |new_parent|.
127void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
[email protected]2816c2462013-12-17 02:22:25128 const gfx::Size src_size = window->parent()->bounds().size();
129 const gfx::Size dst_size = new_parent->bounds().size();
[email protected]95058572012-08-20 14:57:29130 // Update the restore bounds to make it relative to the display.
[email protected]a41b4e12013-09-20 04:36:34131 wm::WindowState* state = wm::GetWindowState(window);
132 gfx::Rect restore_bounds;
133 bool has_restore_bounds = state->HasRestoreBounds();
[email protected]2816c2462013-12-17 02:22:25134
[email protected]9cfd3d12014-02-25 15:33:45135 bool update_bounds = (state->IsNormalOrSnapped() || state->IsMinimized()) &&
[email protected]093b8d642014-04-03 20:59:28136 new_parent->id() != kShellWindowId_DockedContainer;
[email protected]2816c2462013-12-17 02:22:25137 gfx::Rect local_bounds;
138 if (update_bounds) {
skyf961b3562016-04-20 00:53:50139 local_bounds = wm::WmWindowAura::GetAuraWindow(state->window())->bounds();
[email protected]2816c2462013-12-17 02:22:25140 MoveOriginRelativeToSize(src_size, dst_size, &local_bounds);
141 }
142
143 if (has_restore_bounds) {
[email protected]a41b4e12013-09-20 04:36:34144 restore_bounds = state->GetRestoreBoundsInParent();
[email protected]2816c2462013-12-17 02:22:25145 MoveOriginRelativeToSize(src_size, dst_size, &restore_bounds);
146 }
147
[email protected]95058572012-08-20 14:57:29148 new_parent->AddChild(window);
[email protected]2816c2462013-12-17 02:22:25149
[email protected]8663b7a62014-01-18 01:24:21150 // Docked windows have bounds handled by the layout manager in AddChild().
[email protected]2816c2462013-12-17 02:22:25151 if (update_bounds)
152 window->SetBounds(local_bounds);
153
[email protected]a41b4e12013-09-20 04:36:34154 if (has_restore_bounds)
155 state->SetRestoreBoundsInParent(restore_bounds);
[email protected]95058572012-08-20 14:57:29156}
157
158// Reparents the appropriate set of windows from |src| to |dst|.
[email protected]bf9cdb362013-10-25 19:22:45159void ReparentAllWindows(aura::Window* src, aura::Window* dst) {
[email protected]95058572012-08-20 14:57:29160 // Set of windows to move.
[email protected]f1853122012-06-27 16:21:26161 const int kContainerIdsToMove[] = {
[email protected]093b8d642014-04-03 20:59:28162 kShellWindowId_DefaultContainer,
163 kShellWindowId_DockedContainer,
164 kShellWindowId_PanelContainer,
165 kShellWindowId_AlwaysOnTopContainer,
166 kShellWindowId_SystemModalContainer,
167 kShellWindowId_LockSystemModalContainer,
tengsf98986c2014-12-06 01:42:21168 kShellWindowId_UnparentedControlContainer,
oshima022a9542015-05-01 00:15:02169 kShellWindowId_OverlayContainer,
170 };
171 const int kExtraContainerIdsToMoveInUnifiedMode[] = {
172 kShellWindowId_LockScreenContainer,
173 kShellWindowId_LockScreenBackgroundContainer,
174 };
175 std::vector<int> container_ids(
176 kContainerIdsToMove,
177 kContainerIdsToMove + arraysize(kContainerIdsToMove));
178 // Check the default_multi_display_mode because this is also necessary
179 // in trasition between mirror <-> unified mode.
oshima628a6172015-08-01 01:33:14180 if (Shell::GetInstance()
181 ->display_manager()
182 ->current_default_multi_display_mode() == DisplayManager::UNIFIED) {
oshima022a9542015-05-01 00:15:02183 for (int id : kExtraContainerIdsToMoveInUnifiedMode)
184 container_ids.push_back(id);
185 }
186
187 for (int id : container_ids) {
[email protected]f1853122012-06-27 16:21:26188 aura::Window* src_container = Shell::GetContainer(src, id);
189 aura::Window* dst_container = Shell::GetContainer(dst, id);
[email protected]5b6021902013-02-26 05:33:29190 while (!src_container->children().empty()) {
191 // Restart iteration from the source container windows each time as they
192 // may change as a result of moving other windows.
193 aura::Window::Windows::const_iterator iter =
194 src_container->children().begin();
195 while (iter != src_container->children().end() &&
[email protected]093b8d642014-04-03 20:59:28196 SystemModalContainerLayoutManager::IsModalBackground(*iter)) {
[email protected]5b6021902013-02-26 05:33:29197 ++iter;
198 }
199 // If the entire window list is modal background windows then stop.
200 if (iter == src_container->children().end())
201 break;
202 ReparentWindow(*iter, dst_container);
[email protected]f1853122012-06-27 16:21:26203 }
204 }
205}
206
[email protected]8d625fb2012-07-18 16:40:06207// Mark the container window so that a widget added to this container will
208// use the virtual screeen coordinates instead of parent.
209void SetUsesScreenCoordinates(aura::Window* container) {
[email protected]093b8d642014-04-03 20:59:28210 container->SetProperty(kUsesScreenCoordinatesKey, true);
[email protected]8d625fb2012-07-18 16:40:06211}
212
[email protected]e887c6c2013-07-08 19:35:53213// Mark the container window so that a widget added to this container will
214// say in the same root window regardless of the bounds specified.
215void DescendantShouldStayInSameRootWindow(aura::Window* container) {
[email protected]093b8d642014-04-03 20:59:28216 container->SetProperty(kStayInSameRootWindowKey, true);
[email protected]e887c6c2013-07-08 19:35:53217}
218
[email protected]c5be8d672014-01-07 13:33:41219void SetUsesEasyResizeTargeter(aura::Window* container) {
220 gfx::Insets mouse_extend(-kResizeOutsideBoundsSize,
221 -kResizeOutsideBoundsSize,
222 -kResizeOutsideBoundsSize,
223 -kResizeOutsideBoundsSize);
224 gfx::Insets touch_extend = mouse_extend.Scale(
225 kResizeOutsideBoundsScaleForTouch);
dchenga94547472016-04-08 08:41:11226 container->SetEventTargeter(
227 std::unique_ptr<ui::EventTargeter>(new ::wm::EasyResizeWindowTargeter(
228 container, mouse_extend, touch_extend)));
[email protected]c5be8d672014-01-07 13:33:41229}
230
[email protected]cf6fea22013-08-07 14:24:01231// A window delegate which does nothing. Used to create a window that
232// is a event target, but do nothing.
233class EmptyWindowDelegate : public aura::WindowDelegate {
234 public:
235 EmptyWindowDelegate() {}
dcheng1f4538e2014-10-27 23:57:05236 ~EmptyWindowDelegate() override {}
[email protected]cf6fea22013-08-07 14:24:01237
238 // aura::WindowDelegate overrides:
dcheng1f4538e2014-10-27 23:57:05239 gfx::Size GetMinimumSize() const override { return gfx::Size(); }
240 gfx::Size GetMaximumSize() const override { return gfx::Size(); }
241 void OnBoundsChanged(const gfx::Rect& old_bounds,
242 const gfx::Rect& new_bounds) override {}
243 gfx::NativeCursor GetCursor(const gfx::Point& point) override {
[email protected]62c9f102014-03-27 06:07:04244 return gfx::kNullCursor;
245 }
dcheng1f4538e2014-10-27 23:57:05246 int GetNonClientComponent(const gfx::Point& point) const override {
[email protected]cf6fea22013-08-07 14:24:01247 return HTNOWHERE;
248 }
dcheng1f4538e2014-10-27 23:57:05249 bool ShouldDescendIntoChildForEventHandling(
[email protected]cf6fea22013-08-07 14:24:01250 aura::Window* child,
mostynb10d6b382014-10-03 16:23:45251 const gfx::Point& location) override {
[email protected]cf6fea22013-08-07 14:24:01252 return false;
253 }
dcheng1f4538e2014-10-27 23:57:05254 bool CanFocus() override { return false; }
255 void OnCaptureLost() override {}
danakj85d970e2015-04-04 00:15:24256 void OnPaint(const ui::PaintContext& context) override {}
dcheng1f4538e2014-10-27 23:57:05257 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
258 void OnWindowDestroying(aura::Window* window) override {}
259 void OnWindowDestroyed(aura::Window* window) override { delete this; }
260 void OnWindowTargetVisibilityChanged(bool visible) override {}
261 bool HasHitTestMask() const override { return false; }
262 void GetHitTestMask(gfx::Path* mask) const override {}
[email protected]cf6fea22013-08-07 14:24:01263
264 private:
265 DISALLOW_COPY_AND_ASSIGN(EmptyWindowDelegate);
266};
267
sky1e30f062016-04-14 21:19:16268class WorkspaceLayoutManagerDelegateImpl
269 : public wm::WorkspaceLayoutManagerDelegate {
270 public:
271 explicit WorkspaceLayoutManagerDelegateImpl(aura::Window* root_window)
272 : root_window_(root_window) {}
273 ~WorkspaceLayoutManagerDelegateImpl() override = default;
274
275 void set_shelf(ShelfLayoutManager* shelf) { shelf_ = shelf; }
276
277 // WorkspaceLayoutManagerDelegate:
278 void UpdateShelfVisibility() override {
279 if (shelf_)
280 shelf_->UpdateVisibilityState();
281 }
282 void OnFullscreenStateChanged(bool is_fullscreen) override {
283 if (shelf_) {
284 ash::Shell::GetInstance()->NotifyFullscreenStateChange(is_fullscreen,
285 root_window_);
286 }
287 }
288
289 private:
290 aura::Window* root_window_;
291 ShelfLayoutManager* shelf_ = nullptr;
292
293 DISALLOW_COPY_AND_ASSIGN(WorkspaceLayoutManagerDelegateImpl);
294};
295
[email protected]d90b8392012-06-13 09:34:56296} // namespace
297
[email protected]f5c9dbc2014-04-11 08:13:45298void RootWindowController::CreateForPrimaryDisplay(AshWindowTreeHost* host) {
[email protected]2f2620332014-02-28 10:07:38299 RootWindowController* controller = new RootWindowController(host);
[email protected]608de6c2013-10-29 00:14:28300 controller->Init(RootWindowController::PRIMARY,
[email protected]a273d33a2013-10-17 12:41:21301 Shell::GetInstance()->delegate()->IsFirstRunAfterBoot());
[email protected]d90b8392012-06-13 09:34:56302}
303
[email protected]f5c9dbc2014-04-11 08:13:45304void RootWindowController::CreateForSecondaryDisplay(AshWindowTreeHost* host) {
[email protected]2f2620332014-02-28 10:07:38305 RootWindowController* controller = new RootWindowController(host);
[email protected]608de6c2013-10-29 00:14:28306 controller->Init(RootWindowController::SECONDARY, false /* first run */);
307}
308
[email protected]88d71122012-10-18 07:11:01309// static
[email protected]ccff3d72013-02-06 04:26:28310RootWindowController* RootWindowController::ForWindow(
311 const aura::Window* window) {
oshima9eea82da2014-09-13 01:11:07312 CHECK(Shell::HasInstance());
[email protected]a0afeb12012-12-10 22:57:09313 return GetRootWindowController(window->GetRootWindow());
314}
315
316// static
[email protected]d17642d2013-09-12 23:44:38317RootWindowController* RootWindowController::ForTargetRootWindow() {
oshima9eea82da2014-09-13 01:11:07318 CHECK(Shell::HasInstance());
[email protected]093b8d642014-04-03 20:59:28319 return GetRootWindowController(Shell::GetTargetRootWindow());
[email protected]a0afeb12012-12-10 22:57:09320}
321
[email protected]a5c78802013-12-12 22:07:01322// static
323aura::Window* RootWindowController::GetContainerForWindow(
324 aura::Window* window) {
325 aura::Window* container = window->parent();
[email protected]5b251f12013-12-19 01:50:05326 while (container && container->type() != ui::wm::WINDOW_TYPE_UNKNOWN)
[email protected]a5c78802013-12-12 22:07:01327 container = container->parent();
328 return container;
329}
330
[email protected]a273d33a2013-10-17 12:41:21331RootWindowController::~RootWindowController() {
332 Shutdown();
[email protected]f5c9dbc2014-04-11 08:13:45333 ash_host_.reset();
[email protected]a273d33a2013-10-17 12:41:21334 // The CaptureClient needs to be around for as long as the RootWindow is
335 // valid.
336 capture_client_.reset();
337}
338
[email protected]f5c9dbc2014-04-11 08:13:45339aura::WindowTreeHost* RootWindowController::GetHost() {
340 return ash_host_->AsWindowTreeHost();
341}
342
343const aura::WindowTreeHost* RootWindowController::GetHost() const {
344 return ash_host_->AsWindowTreeHost();
345}
346
347aura::Window* RootWindowController::GetRootWindow() {
348 return GetHost()->window();
349}
350
351const aura::Window* RootWindowController::GetRootWindow() const {
352 return GetHost()->window();
353}
354
[email protected]0bf61732013-07-02 04:35:10355void RootWindowController::SetWallpaperController(
356 DesktopBackgroundWidgetController* controller) {
357 wallpaper_controller_.reset(controller);
358}
359
360void RootWindowController::SetAnimatingWallpaperController(
361 AnimatingDesktopController* controller) {
362 if (animating_wallpaper_controller_.get())
363 animating_wallpaper_controller_->StopAnimating();
364 animating_wallpaper_controller_.reset(controller);
365}
366
[email protected]6675e1c2012-09-11 09:15:45367void RootWindowController::Shutdown() {
[email protected]a825e8312014-05-05 22:05:01368 Shell* shell = Shell::GetInstance();
369 shell->RemoveShellObserver(this);
370
371#if defined(OS_CHROMEOS)
[email protected]7d487592014-07-24 03:54:50372 if (touch_exploration_manager_) {
373 touch_exploration_manager_.reset();
[email protected]a825e8312014-05-05 22:05:01374 }
375#endif
[email protected]d141b922013-07-09 08:13:17376
[email protected]0bf61732013-07-02 04:35:10377 if (animating_wallpaper_controller_.get())
378 animating_wallpaper_controller_->StopAnimating();
379 wallpaper_controller_.reset();
380 animating_wallpaper_controller_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45381 aura::Window* root_window = GetRootWindow();
[email protected]d17642d2013-09-12 23:44:38382 // Change the target root window before closing child windows. If any child
[email protected]c98a4922013-09-05 20:01:42383 // being removed triggers a relayout of the shelf it will try to build a
[email protected]d17642d2013-09-12 23:44:38384 // window list adding windows from the target root window's containers which
[email protected]c98a4922013-09-05 20:01:42385 // may have already gone away.
[email protected]f5c9dbc2014-04-11 08:13:45386 if (Shell::GetTargetRootWindow() == root_window) {
[email protected]a825e8312014-05-05 22:05:01387 shell->set_target_root_window(
[email protected]f5c9dbc2014-04-11 08:13:45388 Shell::GetPrimaryRootWindow() == root_window
389 ? NULL
390 : Shell::GetPrimaryRootWindow());
[email protected]f634dd32012-07-23 22:49:07391 }
[email protected]c98a4922013-09-05 20:01:42392
393 CloseChildWindows();
[email protected]f5c9dbc2014-04-11 08:13:45394 GetRootWindowSettings(root_window)->controller = NULL;
[email protected]d90b8392012-06-13 09:34:56395 workspace_controller_.reset();
[email protected]6675e1c2012-09-11 09:15:45396 // Forget with the display ID so that display lookup
397 // ends up with invalid display.
[email protected]f5c9dbc2014-04-11 08:13:45398 GetRootWindowSettings(root_window)->display_id =
[email protected]f8e6aad2013-08-30 21:49:11399 gfx::Display::kInvalidDisplayID;
[email protected]8f5209c2014-05-22 20:36:11400 ash_host_->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28401
[email protected]956a6a42012-10-29 23:58:10402 system_background_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45403 aura::client::SetScreenPositionClient(root_window, NULL);
[email protected]d90b8392012-06-13 09:34:56404}
405
[email protected]c0ce80e2012-10-05 23:28:27406SystemModalContainerLayoutManager*
[email protected]8674b312012-10-12 19:02:44407RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
[email protected]a5c78802013-12-12 22:07:01408 aura::Window* modal_container = NULL;
[email protected]8674b312012-10-12 19:02:44409 if (window) {
[email protected]a5c78802013-12-12 22:07:01410 aura::Window* window_container = GetContainerForWindow(window);
411 if (window_container &&
412 window_container->id() >= kShellWindowId_LockScreenContainer) {
413 modal_container = GetContainer(kShellWindowId_LockSystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35414 } else {
[email protected]a5c78802013-12-12 22:07:01415 modal_container = GetContainer(kShellWindowId_SystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35416 }
[email protected]8674b312012-10-12 19:02:44417 } else {
[email protected]a44afbbd2013-07-24 21:49:35418 int modal_window_id = Shell::GetInstance()->session_state_delegate()
419 ->IsUserSessionBlocked() ? kShellWindowId_LockSystemModalContainer :
420 kShellWindowId_SystemModalContainer;
[email protected]a5c78802013-12-12 22:07:01421 modal_container = GetContainer(modal_window_id);
[email protected]8674b312012-10-12 19:02:44422 }
[email protected]a5c78802013-12-12 22:07:01423 return modal_container ? static_cast<SystemModalContainerLayoutManager*>(
424 modal_container->layout_manager()) : NULL;
[email protected]c0ce80e2012-10-05 23:28:27425}
426
[email protected]d90b8392012-06-13 09:34:56427aura::Window* RootWindowController::GetContainer(int container_id) {
[email protected]f5c9dbc2014-04-11 08:13:45428 return GetRootWindow()->GetChildById(container_id);
[email protected]d90b8392012-06-13 09:34:56429}
430
[email protected]d8a24952013-08-05 20:05:05431const aura::Window* RootWindowController::GetContainer(int container_id) const {
[email protected]f5c9dbc2014-04-11 08:13:45432 return ash_host_->AsWindowTreeHost()->window()->GetChildById(container_id);
[email protected]d8a24952013-08-05 20:05:05433}
434
[email protected]864b58552013-12-19 04:19:38435void RootWindowController::ShowShelf() {
436 if (!shelf_->shelf())
[email protected]e74aaf0a2012-10-12 18:42:28437 return;
[email protected]864b58552013-12-19 04:19:38438 shelf_->shelf()->SetVisible(true);
[email protected]478c6c32013-03-09 02:50:58439 shelf_->status_area_widget()->Show();
[email protected]e74aaf0a2012-10-12 18:42:28440}
441
[email protected]864b58552013-12-19 04:19:38442void RootWindowController::OnShelfCreated() {
[email protected]756bda12013-07-03 08:17:06443 if (panel_layout_manager_)
[email protected]864b58552013-12-19 04:19:38444 panel_layout_manager_->SetShelf(shelf_->shelf());
[email protected]7115bd32013-07-19 08:25:39445 if (docked_layout_manager_) {
[email protected]864b58552013-12-19 04:19:38446 docked_layout_manager_->SetShelf(shelf_->shelf());
[email protected]7115bd32013-07-19 08:25:39447 if (shelf_->shelf_layout_manager())
448 docked_layout_manager_->AddObserver(shelf_->shelf_layout_manager());
449 }
[email protected]b8642ec2014-04-17 05:20:39450
451 // Notify shell observers that the shelf has been created.
452 Shell::GetInstance()->OnShelfCreatedForRootWindow(GetRootWindow());
[email protected]756bda12013-07-03 08:17:06453}
454
[email protected]16059276d2012-10-22 18:59:50455void RootWindowController::UpdateAfterLoginStatusChange(
456 user::LoginStatus status) {
[email protected]cf6fea22013-08-07 14:24:01457 if (status != user::LOGGED_IN_NONE)
458 mouse_event_target_.reset();
[email protected]80549c152013-07-02 01:42:47459 if (shelf_->status_area_widget())
[email protected]478c6c32013-03-09 02:50:58460 shelf_->status_area_widget()->UpdateAfterLoginStatusChange(status);
[email protected]16059276d2012-10-22 18:59:50461}
462
[email protected]bca9a7e2012-11-10 06:25:49463void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
[email protected]252eb232013-08-14 22:09:27464#if defined(OS_CHROMEOS)
pgal.u-szegedd84534d32014-10-29 12:34:30465 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]bca9a7e2012-11-10 06:25:49466 switches::kAshAnimateFromBootSplashScreen) &&
467 boot_splash_screen_.get()) {
468 // Make the splash screen fade out so it doesn't obscure the desktop
469 // wallpaper's brightness/grayscale animation.
470 boot_splash_screen_->StartHideAnimation(
471 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
472 }
[email protected]252eb232013-08-14 22:09:27473#endif
[email protected]bca9a7e2012-11-10 06:25:49474}
475
[email protected]0bf61732013-07-02 04:35:10476void RootWindowController::OnWallpaperAnimationFinished(views::Widget* widget) {
477 // Make sure the wallpaper is visible.
[email protected]bca9a7e2012-11-10 06:25:49478 system_background_->SetColor(SK_ColorBLACK);
[email protected]252eb232013-08-14 22:09:27479#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:49480 boot_splash_screen_.reset();
[email protected]252eb232013-08-14 22:09:27481#endif
[email protected]0bf61732013-07-02 04:35:10482
483 Shell::GetInstance()->user_wallpaper_delegate()->
484 OnWallpaperAnimationFinished();
485 // Only removes old component when wallpaper animation finished. If we
486 // remove the old one before the new wallpaper is done fading in there will
487 // be a white flash during the animation.
488 if (animating_wallpaper_controller()) {
489 DesktopBackgroundWidgetController* controller =
490 animating_wallpaper_controller()->GetController(true);
491 // |desktop_widget_| should be the same animating widget we try to move
492 // to |kDesktopController|. Otherwise, we may close |desktop_widget_|
493 // before move it to |kDesktopController|.
494 DCHECK_EQ(controller->widget(), widget);
495 // Release the old controller and close its background widget.
496 SetWallpaperController(controller);
497 }
[email protected]697f04c2012-10-03 01:15:10498}
499
[email protected]d90b8392012-06-13 09:34:56500void RootWindowController::CloseChildWindows() {
[email protected]cf6fea22013-08-07 14:24:01501 mouse_event_target_.reset();
502
[email protected]2a57beb52014-06-09 20:02:26503 // Remove observer as deactivating keyboard causes |docked_layout_manager_|
504 // to fire notifications.
505 if (docked_layout_manager_ && shelf_ && shelf_->shelf_layout_manager())
506 docked_layout_manager_->RemoveObserver(shelf_->shelf_layout_manager());
507
[email protected]b6ba05d902013-10-04 21:38:45508 // Deactivate keyboard container before closing child windows and shutting
509 // down associated layout managers.
[email protected]a0b3fb882014-04-07 19:26:03510 DeactivateKeyboard(keyboard::KeyboardController::GetInstance());
[email protected]b6ba05d902013-10-04 21:38:45511
[email protected]79a87b7e2013-01-25 05:08:22512 // panel_layout_manager_ needs to be shut down before windows are destroyed.
513 if (panel_layout_manager_) {
514 panel_layout_manager_->Shutdown();
515 panel_layout_manager_ = NULL;
516 }
[email protected]7115bd32013-07-19 08:25:39517 // docked_layout_manager_ needs to be shut down before windows are destroyed.
518 if (docked_layout_manager_) {
[email protected]7115bd32013-07-19 08:25:39519 docked_layout_manager_->Shutdown();
520 docked_layout_manager_ = NULL;
521 }
[email protected]f5c9dbc2014-04-11 08:13:45522 aura::Window* root_window = GetRootWindow();
523 aura::client::SetDragDropClient(root_window, NULL);
[email protected]8b3e3d82013-08-20 14:36:30524
[email protected]478c6c32013-03-09 02:50:58525 // TODO(harrym): Remove when Status Area Widget is a child view.
[email protected]bb42c932013-10-31 06:52:06526 if (shelf_) {
527 shelf_->ShutdownStatusAreaWidget();
[email protected]478c6c32013-03-09 02:50:58528
[email protected]bb42c932013-10-31 06:52:06529 if (shelf_->shelf_layout_manager())
530 shelf_->shelf_layout_manager()->PrepareForShutdown();
531 }
[email protected]e74aaf0a2012-10-12 18:42:28532
[email protected]d90b8392012-06-13 09:34:56533 // Close background widget first as it depends on tooltip.
[email protected]0bf61732013-07-02 04:35:10534 wallpaper_controller_.reset();
535 animating_wallpaper_controller_.reset();
[email protected]b4ddc7a2012-08-07 04:17:32536
[email protected]d90b8392012-06-13 09:34:56537 workspace_controller_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45538 aura::client::SetTooltipClient(root_window, NULL);
[email protected]d90b8392012-06-13 09:34:56539
[email protected]0fbfa972013-10-02 19:23:33540 // Explicitly destroy top level windows. We do this as during part of
541 // destruction such windows may query the RootWindow for state.
oshimaf38efa92015-10-27 19:06:52542 aura::WindowTracker non_toplevel_windows;
543 non_toplevel_windows.Add(root_window);
544 while (!non_toplevel_windows.windows().empty()) {
545 const aura::Window* non_toplevel_window =
546 *non_toplevel_windows.windows().begin();
547 non_toplevel_windows.Remove(const_cast<aura::Window*>(non_toplevel_window));
[email protected]8b3e3d82013-08-20 14:36:30548 aura::WindowTracker toplevel_windows;
549 for (size_t i = 0; i < non_toplevel_window->children().size(); ++i) {
550 aura::Window* child = non_toplevel_window->children()[i];
[email protected]0fbfa972013-10-02 19:23:33551 if (!child->owned_by_parent())
552 continue;
[email protected]8b3e3d82013-08-20 14:36:30553 if (child->delegate())
554 toplevel_windows.Add(child);
555 else
oshimaf38efa92015-10-27 19:06:52556 non_toplevel_windows.Add(child);
[email protected]8b3e3d82013-08-20 14:36:30557 }
558 while (!toplevel_windows.windows().empty())
559 delete *toplevel_windows.windows().begin();
[email protected]d90b8392012-06-13 09:34:56560 }
[email protected]8b3e3d82013-08-20 14:36:30561 // And then remove the containers.
[email protected]f5c9dbc2014-04-11 08:13:45562 while (!root_window->children().empty()) {
563 aura::Window* window = root_window->children()[0];
[email protected]0fbfa972013-10-02 19:23:33564 if (window->owned_by_parent()) {
565 delete window;
566 } else {
[email protected]f5c9dbc2014-04-11 08:13:45567 root_window->RemoveChild(window);
[email protected]0fbfa972013-10-02 19:23:33568 }
569 }
[email protected]478c6c32013-03-09 02:50:58570
[email protected]bb42c932013-10-31 06:52:06571 shelf_.reset();
[email protected]d90b8392012-06-13 09:34:56572}
573
[email protected]bf9cdb362013-10-25 19:22:45574void RootWindowController::MoveWindowsTo(aura::Window* dst) {
[email protected]8039e06c2013-01-17 23:34:50575 // Forget the shelf early so that shelf don't update itself using wrong
576 // display info.
sky1e30f062016-04-14 21:19:16577 workspace_controller_->SetShelf(nullptr);
578 workspace_controller_->layout_manager()->DeleteDelegate();
[email protected]f5c9dbc2014-04-11 08:13:45579 ReparentAllWindows(GetRootWindow(), dst);
[email protected]f1853122012-06-27 16:21:26580}
581
[email protected]478c6c32013-03-09 02:50:58582ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
[email protected]80549c152013-07-02 01:42:47583 return shelf_->shelf_layout_manager();
[email protected]478c6c32013-03-09 02:50:58584}
585
[email protected]a0afeb12012-12-10 22:57:09586SystemTray* RootWindowController::GetSystemTray() {
587 // We assume in throughout the code that this will not return NULL. If code
588 // triggers this for valid reasons, it should test status_area_widget first.
[email protected]80549c152013-07-02 01:42:47589 CHECK(shelf_->status_area_widget());
[email protected]478c6c32013-03-09 02:50:58590 return shelf_->status_area_widget()->system_tray();
[email protected]a0afeb12012-12-10 22:57:09591}
592
[email protected]940fb1c2013-06-18 16:54:28593void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
594 ui::MenuSourceType source_type) {
msw141c6b22016-03-04 00:55:30595 ShellDelegate* delegate = Shell::GetInstance()->delegate();
596 DCHECK(delegate);
dchenga94547472016-04-08 08:41:11597 std::unique_ptr<ui::MenuModel> menu_model(
msw953caf1f2016-03-18 00:33:29598 delegate->CreateContextMenu(shelf_->shelf(), nullptr));
[email protected]7f7f65c2013-04-17 16:47:13599 if (!menu_model)
[email protected]8e837ec2013-01-31 01:48:33600 return;
[email protected]431552c2012-10-23 00:38:33601
[email protected]6175fc42013-04-05 05:58:58602 // Background controller may not be set yet if user clicked on status are
603 // before initial animation completion. See crbug.com/222218
[email protected]0bf61732013-07-02 04:35:10604 if (!wallpaper_controller_.get())
[email protected]431552c2012-10-23 00:38:33605 return;
606
[email protected]0a37a5d2014-07-15 00:42:23607 views::MenuRunner menu_runner(menu_model.get(),
608 views::MenuRunner::CONTEXT_MENU);
[email protected]0bf61732013-07-02 04:35:10609 if (menu_runner.RunMenuAt(wallpaper_controller_->widget(),
[email protected]fd6c0a62014-05-01 07:50:35610 NULL,
611 gfx::Rect(location_in_screen, gfx::Size()),
612 views::MENU_ANCHOR_TOPLEFT,
[email protected]0a37a5d2014-07-15 00:42:23613 source_type) == views::MenuRunner::MENU_DELETED) {
[email protected]6175fc42013-04-05 05:58:58614 return;
615 }
616
[email protected]431552c2012-10-23 00:38:33617 Shell::GetInstance()->UpdateShelfVisibility();
618}
619
[email protected]e74aaf0a2012-10-12 18:42:28620void RootWindowController::UpdateShelfVisibility() {
[email protected]478c6c32013-03-09 02:50:58621 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]e74aaf0a2012-10-12 18:42:28622}
623
varkhad99fa94f2015-06-29 22:35:46624aura::Window* RootWindowController::GetWindowForFullscreenMode() {
625 aura::Window* topmost_window = NULL;
626 aura::Window* active_window = wm::GetActiveWindow();
[email protected]f5c9dbc2014-04-11 08:13:45627 if (active_window && active_window->GetRootWindow() == GetRootWindow() &&
[email protected]2c5db9e2014-02-27 13:58:14628 IsSwitchableContainer(active_window->parent())) {
629 // Use the active window when it is on the current root window to determine
630 // the fullscreen state to allow temporarily using a panel or docked window
631 // (which are always above the default container) while a fullscreen
632 // window is open. We only use the active window when in a switchable
633 // container as the launcher should not exit fullscreen mode.
634 topmost_window = active_window;
635 } else {
636 // Otherwise, use the topmost window on the root window's default container
637 // when there is no active window on this root window.
638 const aura::Window::Windows& windows =
639 GetContainer(kShellWindowId_DefaultContainer)->children();
640 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin();
641 iter != windows.rend(); ++iter) {
bruthigb7056f62015-06-04 21:04:53642 if (wm::IsWindowUserPositionable(*iter) &&
[email protected]2c5db9e2014-02-27 13:58:14643 (*iter)->layer()->GetTargetVisibility()) {
644 topmost_window = *iter;
645 break;
646 }
[email protected]2c9171d22013-12-10 21:55:10647 }
648 }
649 while (topmost_window) {
650 if (wm::GetWindowState(topmost_window)->IsFullscreen())
651 return topmost_window;
[email protected]e319c7e2014-03-14 19:56:14652 topmost_window = ::wm::GetTransientParent(topmost_window);
[email protected]2ee2f5d2013-01-10 23:37:16653 }
[email protected]700849f2013-04-30 17:49:20654 return NULL;
[email protected]2ee2f5d2013-01-10 23:37:16655}
656
[email protected]b6ba05d902013-10-04 21:38:45657void RootWindowController::ActivateKeyboard(
658 keyboard::KeyboardController* keyboard_controller) {
659 if (!keyboard::IsKeyboardEnabled() ||
660 GetContainer(kShellWindowId_VirtualKeyboardContainer)) {
661 return;
662 }
663 DCHECK(keyboard_controller);
bshe9858b4a2014-09-16 20:46:38664 keyboard_controller->AddObserver(shelf()->shelf_layout_manager());
665 keyboard_controller->AddObserver(panel_layout_manager_);
666 keyboard_controller->AddObserver(docked_layout_manager_);
667 keyboard_controller->AddObserver(workspace_controller_->layout_manager());
rsadam7bd510bb2014-12-09 20:10:56668 keyboard_controller->AddObserver(
669 always_on_top_controller_->GetLayoutManager());
bshe9858b4a2014-09-16 20:46:38670 Shell::GetInstance()->delegate()->VirtualKeyboardActivated(true);
bshec3875422014-09-29 13:21:30671 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]b2da9b602014-03-05 18:39:52672 DCHECK(parent);
[email protected]b6ba05d902013-10-04 21:38:45673 aura::Window* keyboard_container =
674 keyboard_controller->GetContainerWindow();
675 keyboard_container->set_id(kShellWindowId_VirtualKeyboardContainer);
676 parent->AddChild(keyboard_container);
[email protected]b6ba05d902013-10-04 21:38:45677}
[email protected]86459e2c2013-04-10 13:39:24678
[email protected]b6ba05d902013-10-04 21:38:45679void RootWindowController::DeactivateKeyboard(
680 keyboard::KeyboardController* keyboard_controller) {
[email protected]e1b299b2014-01-29 23:53:41681 if (!keyboard_controller ||
682 !keyboard_controller->keyboard_container_initialized()) {
[email protected]b6ba05d902013-10-04 21:38:45683 return;
[email protected]e1b299b2014-01-29 23:53:41684 }
[email protected]b6ba05d902013-10-04 21:38:45685 aura::Window* keyboard_container =
686 keyboard_controller->GetContainerWindow();
[email protected]f5c9dbc2014-04-11 08:13:45687 if (keyboard_container->GetRootWindow() == GetRootWindow()) {
bshec3875422014-09-29 13:21:30688 aura::Window* parent =
689 GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]b2da9b602014-03-05 18:39:52690 DCHECK(parent);
691 parent->RemoveChild(keyboard_container);
bshe9858b4a2014-09-16 20:46:38692 // Virtual keyboard may be deactivated while still showing, notify all
693 // observers that keyboard bounds changed to 0 before remove them.
694 keyboard_controller->NotifyKeyboardBoundsChanging(gfx::Rect());
695 keyboard_controller->RemoveObserver(shelf()->shelf_layout_manager());
696 keyboard_controller->RemoveObserver(panel_layout_manager_);
697 keyboard_controller->RemoveObserver(docked_layout_manager_);
698 keyboard_controller->RemoveObserver(
699 workspace_controller_->layout_manager());
rsadam7bd510bb2014-12-09 20:10:56700 keyboard_controller->RemoveObserver(
701 always_on_top_controller_->GetLayoutManager());
bshe9858b4a2014-09-16 20:46:38702 Shell::GetInstance()->delegate()->VirtualKeyboardActivated(false);
[email protected]86459e2c2013-04-10 13:39:24703 }
704}
705
[email protected]602022b2014-03-31 17:07:31706bool RootWindowController::IsVirtualKeyboardWindow(aura::Window* window) {
bshec3875422014-09-29 13:21:30707 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]602022b2014-03-31 17:07:31708 return parent ? parent->Contains(window) : false;
709}
710
[email protected]a4cd6d32012-09-12 03:42:13711////////////////////////////////////////////////////////////////////////////////
712// RootWindowController, private:
713
[email protected]f5c9dbc2014-04-11 08:13:45714RootWindowController::RootWindowController(AshWindowTreeHost* ash_host)
715 : ash_host_(ash_host),
[email protected]a273d33a2013-10-17 12:41:21716 root_window_layout_(NULL),
717 docked_layout_manager_(NULL),
718 panel_layout_manager_(NULL),
719 touch_hud_debug_(NULL),
720 touch_hud_projection_(NULL) {
[email protected]f5c9dbc2014-04-11 08:13:45721 aura::Window* root_window = GetRootWindow();
722 GetRootWindowSettings(root_window)->controller = this;
[email protected]a273d33a2013-10-17 12:41:21723
724 stacking_controller_.reset(new StackingController);
[email protected]f5c9dbc2014-04-11 08:13:45725 aura::client::SetWindowTreeClient(root_window, stacking_controller_.get());
726 capture_client_.reset(new ::wm::ScopedCaptureClient(root_window));
[email protected]a273d33a2013-10-17 12:41:21727}
728
[email protected]608de6c2013-10-29 00:14:28729void RootWindowController::Init(RootWindowType root_window_type,
730 bool first_run_after_boot) {
[email protected]f5c9dbc2014-04-11 08:13:45731 aura::Window* root_window = GetRootWindow();
[email protected]51f438112013-11-18 19:32:50732 Shell* shell = Shell::GetInstance();
[email protected]f5c9dbc2014-04-11 08:13:45733 shell->InitRootWindow(root_window);
[email protected]a273d33a2013-10-17 12:41:21734
[email protected]f5c9dbc2014-04-11 08:13:45735 CreateContainersInRootWindow(root_window);
[email protected]608de6c2013-10-29 00:14:28736
[email protected]a273d33a2013-10-17 12:41:21737 CreateSystemBackground(first_run_after_boot);
738
739 InitLayoutManagers();
740 InitTouchHuds();
741
742 if (Shell::GetPrimaryRootWindowController()->
743 GetSystemModalLayoutManager(NULL)->has_modal_background()) {
744 GetSystemModalLayoutManager(NULL)->CreateModalBackground();
745 }
746
[email protected]a273d33a2013-10-17 12:41:21747 shell->AddShellObserver(this);
748
[email protected]608de6c2013-10-29 00:14:28749 if (root_window_type == PRIMARY) {
[email protected]a3565792013-10-18 12:52:37750 root_window_layout()->OnWindowResized();
bshe9858b4a2014-09-16 20:46:38751 shell->InitKeyboard();
[email protected]a273d33a2013-10-17 12:41:21752 } else {
753 root_window_layout()->OnWindowResized();
[email protected]f5c9dbc2014-04-11 08:13:45754 ash_host_->AsWindowTreeHost()->Show();
[email protected]a273d33a2013-10-17 12:41:21755
[email protected]864b58552013-12-19 04:19:38756 // Create a shelf if a user is already logged in.
[email protected]a273d33a2013-10-17 12:41:21757 if (shell->session_state_delegate()->NumberOfLoggedInUsers())
[email protected]864b58552013-12-19 04:19:38758 shelf()->CreateShelf();
[email protected]0e3e7cb2014-04-12 05:18:25759
760 // Notify shell observers about new root window.
761 shell->OnRootWindowAdded(root_window);
[email protected]a273d33a2013-10-17 12:41:21762 }
[email protected]a825e8312014-05-05 22:05:01763
764#if defined(OS_CHROMEOS)
pgal.u-szegedd84534d32014-10-29 12:34:30765 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]2e0b2352014-07-28 13:28:28766 switches::kAshDisableTouchExplorationMode)) {
[email protected]7d487592014-07-24 03:54:50767 touch_exploration_manager_.reset(new AshTouchExplorationManager(this));
[email protected]a825e8312014-05-05 22:05:01768 }
769#endif
[email protected]a273d33a2013-10-17 12:41:21770}
771
[email protected]756bda12013-07-03 08:17:06772void RootWindowController::InitLayoutManagers() {
[email protected]f5c9dbc2014-04-11 08:13:45773 aura::Window* root_window = GetRootWindow();
774 root_window_layout_ = new RootWindowLayoutManager(root_window);
775 root_window->SetLayoutManager(root_window_layout_);
[email protected]756bda12013-07-03 08:17:06776
777 aura::Window* default_container =
778 GetContainer(kShellWindowId_DefaultContainer);
779 // Workspace manager has its own layout managers.
sky1e30f062016-04-14 21:19:16780
781 WorkspaceLayoutManagerDelegateImpl* workspace_layout_manager_delegate =
782 new WorkspaceLayoutManagerDelegateImpl(root_window);
783 workspace_controller_.reset(new WorkspaceController(
784 default_container, base::WrapUnique(workspace_layout_manager_delegate)));
[email protected]756bda12013-07-03 08:17:06785
786 aura::Window* always_on_top_container =
787 GetContainer(kShellWindowId_AlwaysOnTopContainer);
rsadam7bd510bb2014-12-09 20:10:56788 always_on_top_controller_.reset(
789 new AlwaysOnTopController(always_on_top_container));
[email protected]756bda12013-07-03 08:17:06790
791 DCHECK(!shelf_.get());
[email protected]093b8d642014-04-03 20:59:28792 aura::Window* shelf_container = GetContainer(kShellWindowId_ShelfContainer);
[email protected]756bda12013-07-03 08:17:06793 // TODO(harrym): Remove when status area is view.
[email protected]093b8d642014-04-03 20:59:28794 aura::Window* status_container = GetContainer(kShellWindowId_StatusContainer);
[email protected]756bda12013-07-03 08:17:06795 shelf_.reset(new ShelfWidget(
796 shelf_container, status_container, workspace_controller()));
sky1e30f062016-04-14 21:19:16797 workspace_layout_manager_delegate->set_shelf(shelf_->shelf_layout_manager());
[email protected]756bda12013-07-03 08:17:06798
[email protected]cf6fea22013-08-07 14:24:01799 if (!Shell::GetInstance()->session_state_delegate()->
800 IsActiveUserSessionStarted()) {
801 // This window exists only to be a event target on login screen.
802 // It does not have to handle events, nor be visible.
803 mouse_event_target_.reset(new aura::Window(new EmptyWindowDelegate));
danakjb161836d2015-04-03 05:14:18804 mouse_event_target_->Init(ui::LAYER_NOT_DRAWN);
[email protected]cf6fea22013-08-07 14:24:01805
806 aura::Window* lock_background_container =
[email protected]093b8d642014-04-03 20:59:28807 GetContainer(kShellWindowId_LockScreenBackgroundContainer);
[email protected]cf6fea22013-08-07 14:24:01808 lock_background_container->AddChild(mouse_event_target_.get());
809 mouse_event_target_->Show();
810 }
811
[email protected]756bda12013-07-03 08:17:06812 // Create Docked windows layout manager
sky3f7af8812016-04-21 19:30:03813 wm::WmWindow* docked_container =
814 wm::WmWindowAura::Get(GetContainer(kShellWindowId_DockedContainer));
[email protected]756bda12013-07-03 08:17:06815 docked_layout_manager_ =
[email protected]093b8d642014-04-03 20:59:28816 new DockedWindowLayoutManager(docked_container, workspace_controller());
sky3f7af8812016-04-21 19:30:03817 docked_container->SetLayoutManager(base::WrapUnique(docked_layout_manager_));
[email protected]756bda12013-07-03 08:17:06818
[email protected]1ca79d42014-07-18 16:26:10819 // Installs SnapLayoutManager to containers who set the
820 // |kSnapsChildrenToPhysicalPixelBoundary| property.
821 wm::InstallSnapLayoutManagerToContainers(root_window);
822
[email protected]756bda12013-07-03 08:17:06823 // Create Panel layout manager
[email protected]093b8d642014-04-03 20:59:28824 aura::Window* panel_container = GetContainer(kShellWindowId_PanelContainer);
825 panel_layout_manager_ = new PanelLayoutManager(panel_container);
[email protected]756bda12013-07-03 08:17:06826 panel_container->SetLayoutManager(panel_layout_manager_);
[email protected]3537d472014-01-15 05:45:31827 panel_container_handler_.reset(new PanelWindowEventHandler);
828 panel_container->AddPreTargetHandler(panel_container_handler_.get());
[email protected]b8642ec2014-04-17 05:20:39829
830 // Install an AttachedPanelWindowTargeter on the panel container to make it
831 // easier to correctly target shelf buttons with touch.
832 gfx::Insets mouse_extend(-kResizeOutsideBoundsSize,
833 -kResizeOutsideBoundsSize,
834 -kResizeOutsideBoundsSize,
835 -kResizeOutsideBoundsSize);
836 gfx::Insets touch_extend = mouse_extend.Scale(
837 kResizeOutsideBoundsScaleForTouch);
dchenga94547472016-04-08 08:41:11838 panel_container->SetEventTargeter(
839 std::unique_ptr<ui::EventTargeter>(new AttachedPanelWindowTargeter(
840 panel_container, mouse_extend, touch_extend, panel_layout_manager_)));
[email protected]756bda12013-07-03 08:17:06841}
842
843void RootWindowController::InitTouchHuds() {
pgal.u-szegedd84534d32014-10-29 12:34:30844 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
[email protected]756bda12013-07-03 08:17:06845 if (command_line->HasSwitch(switches::kAshTouchHud))
[email protected]f5c9dbc2014-04-11 08:13:45846 set_touch_hud_debug(new TouchHudDebug(GetRootWindow()));
[email protected]756bda12013-07-03 08:17:06847 if (Shell::GetInstance()->is_touch_hud_projection_enabled())
848 EnableTouchHudProjection();
849}
850
851void RootWindowController::CreateSystemBackground(
852 bool is_first_run_after_boot) {
853 SkColor color = SK_ColorBLACK;
854#if defined(OS_CHROMEOS)
855 if (is_first_run_after_boot)
856 color = kChromeOsBootColor;
857#endif
858 system_background_.reset(
[email protected]f5c9dbc2014-04-11 08:13:45859 new SystemBackgroundController(GetRootWindow(), color));
[email protected]756bda12013-07-03 08:17:06860
861#if defined(OS_CHROMEOS)
862 // Make a copy of the system's boot splash screen so we can composite it
863 // onscreen until the desktop background is ready.
864 if (is_first_run_after_boot &&
pgal.u-szegedd84534d32014-10-29 12:34:30865 (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]756bda12013-07-03 08:17:06866 switches::kAshCopyHostBackgroundAtBoot) ||
pgal.u-szegedd84534d32014-10-29 12:34:30867 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]756bda12013-07-03 08:17:06868 switches::kAshAnimateFromBootSplashScreen)))
[email protected]f5c9dbc2014-04-11 08:13:45869 boot_splash_screen_.reset(new BootSplashScreen(GetHost()));
[email protected]756bda12013-07-03 08:17:06870#endif
871}
872
[email protected]a4cd6d32012-09-12 03:42:13873void RootWindowController::CreateContainersInRootWindow(
[email protected]41baaed2013-11-09 04:18:26874 aura::Window* root_window) {
[email protected]a4cd6d32012-09-12 03:42:13875 // These containers are just used by PowerButtonController to animate groups
876 // of containers simultaneously without messing up the current transformations
877 // on those containers. These are direct children of the root window; all of
878 // the other containers are their children.
[email protected]e6e41d2f2012-10-29 19:22:19879
880 // The desktop background container is not part of the lock animation, so it
881 // is not included in those animate groups.
[email protected]a4cd6d32012-09-12 03:42:13882 // When screen is locked desktop background is moved to lock screen background
883 // container (moved back on unlock). We want to make sure that there's an
884 // opaque layer occluding the non-lock-screen layers.
[email protected]e6e41d2f2012-10-29 19:22:19885 aura::Window* desktop_background_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27886 kShellWindowId_DesktopBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13887 "DesktopBackgroundContainer",
888 root_window);
[email protected]e319c7e2014-03-14 19:56:14889 ::wm::SetChildWindowVisibilityChangesAnimated(desktop_background_container);
[email protected]a4cd6d32012-09-12 03:42:13890
891 aura::Window* non_lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27892 kShellWindowId_NonLockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13893 "NonLockScreenContainersContainer",
894 root_window);
oshimaf52e1be2015-05-06 21:29:34895 // Clip all windows inside this container, as half pixel of the window's
896 // texture may become visible when the screen is scaled. crbug.com/368591.
897 non_lock_screen_containers->layer()->SetMasksToBounds(true);
[email protected]a4cd6d32012-09-12 03:42:13898
899 aura::Window* lock_background_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27900 kShellWindowId_LockScreenBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13901 "LockScreenBackgroundContainer",
902 root_window);
[email protected]e319c7e2014-03-14 19:56:14903 ::wm::SetChildWindowVisibilityChangesAnimated(lock_background_containers);
[email protected]a4cd6d32012-09-12 03:42:13904
905 aura::Window* lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27906 kShellWindowId_LockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13907 "LockScreenContainersContainer",
908 root_window);
909 aura::Window* lock_screen_related_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27910 kShellWindowId_LockScreenRelatedContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13911 "LockScreenRelatedContainersContainer",
912 root_window);
913
[email protected]c0ce80e2012-10-05 23:28:27914 CreateContainer(kShellWindowId_UnparentedControlContainer,
[email protected]a4cd6d32012-09-12 03:42:13915 "UnparentedControlContainer",
916 non_lock_screen_containers);
917
918 aura::Window* default_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27919 kShellWindowId_DefaultContainer,
[email protected]a4cd6d32012-09-12 03:42:13920 "DefaultContainer",
921 non_lock_screen_containers);
[email protected]e319c7e2014-03-14 19:56:14922 ::wm::SetChildWindowVisibilityChangesAnimated(default_container);
[email protected]1ca79d42014-07-18 16:26:10923 wm::SetSnapsChildrenToPhysicalPixelBoundary(default_container);
[email protected]a4cd6d32012-09-12 03:42:13924 SetUsesScreenCoordinates(default_container);
[email protected]c5be8d672014-01-07 13:33:41925 SetUsesEasyResizeTargeter(default_container);
[email protected]a4cd6d32012-09-12 03:42:13926
927 aura::Window* always_on_top_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27928 kShellWindowId_AlwaysOnTopContainer,
[email protected]a4cd6d32012-09-12 03:42:13929 "AlwaysOnTopContainer",
930 non_lock_screen_containers);
[email protected]e319c7e2014-03-14 19:56:14931 ::wm::SetChildWindowVisibilityChangesAnimated(always_on_top_container);
[email protected]1ca79d42014-07-18 16:26:10932 wm::SetSnapsChildrenToPhysicalPixelBoundary(always_on_top_container);
[email protected]a4cd6d32012-09-12 03:42:13933 SetUsesScreenCoordinates(always_on_top_container);
934
[email protected]beb4e5c2013-06-18 15:37:07935 aura::Window* docked_container = CreateContainer(
936 kShellWindowId_DockedContainer,
937 "DockedContainer",
938 non_lock_screen_containers);
[email protected]e319c7e2014-03-14 19:56:14939 ::wm::SetChildWindowVisibilityChangesAnimated(docked_container);
[email protected]1ca79d42014-07-18 16:26:10940 wm::SetSnapsChildrenToPhysicalPixelBoundary(docked_container);
[email protected]beb4e5c2013-06-18 15:37:07941 SetUsesScreenCoordinates(docked_container);
[email protected]1ff0c492014-01-21 20:20:44942 SetUsesEasyResizeTargeter(docked_container);
[email protected]beb4e5c2013-06-18 15:37:07943
[email protected]3f13cf12013-07-12 05:13:59944 aura::Window* shelf_container =
[email protected]478c6c32013-03-09 02:50:58945 CreateContainer(kShellWindowId_ShelfContainer,
[email protected]3f13cf12013-07-12 05:13:59946 "ShelfContainer",
[email protected]a4cd6d32012-09-12 03:42:13947 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10948 wm::SetSnapsChildrenToPhysicalPixelBoundary(shelf_container);
[email protected]3f13cf12013-07-12 05:13:59949 SetUsesScreenCoordinates(shelf_container);
950 DescendantShouldStayInSameRootWindow(shelf_container);
[email protected]a4cd6d32012-09-12 03:42:13951
[email protected]f2026eb2013-10-22 14:28:56952 aura::Window* panel_container = CreateContainer(
953 kShellWindowId_PanelContainer,
954 "PanelContainer",
955 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10956 wm::SetSnapsChildrenToPhysicalPixelBoundary(panel_container);
[email protected]f2026eb2013-10-22 14:28:56957 SetUsesScreenCoordinates(panel_container);
958
959 aura::Window* shelf_bubble_container =
960 CreateContainer(kShellWindowId_ShelfBubbleContainer,
961 "ShelfBubbleContainer",
962 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10963 wm::SetSnapsChildrenToPhysicalPixelBoundary(shelf_bubble_container);
[email protected]f2026eb2013-10-22 14:28:56964 SetUsesScreenCoordinates(shelf_bubble_container);
965 DescendantShouldStayInSameRootWindow(shelf_bubble_container);
966
[email protected]dc851a4e52012-10-03 00:05:55967 aura::Window* app_list_container =
[email protected]c0ce80e2012-10-05 23:28:27968 CreateContainer(kShellWindowId_AppListContainer,
[email protected]dc851a4e52012-10-03 00:05:55969 "AppListContainer",
970 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10971 wm::SetSnapsChildrenToPhysicalPixelBoundary(app_list_container);
[email protected]dc851a4e52012-10-03 00:05:55972 SetUsesScreenCoordinates(app_list_container);
[email protected]a4cd6d32012-09-12 03:42:13973
974 aura::Window* modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27975 kShellWindowId_SystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13976 "SystemModalContainer",
977 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10978 wm::SetSnapsChildrenToPhysicalPixelBoundary(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13979 modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27980 new SystemModalContainerLayoutManager(modal_container));
[email protected]e319c7e2014-03-14 19:56:14981 ::wm::SetChildWindowVisibilityChangesAnimated(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13982 SetUsesScreenCoordinates(modal_container);
[email protected]c5be8d672014-01-07 13:33:41983 SetUsesEasyResizeTargeter(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13984
[email protected]a4cd6d32012-09-12 03:42:13985 // TODO(beng): Figure out if we can make this use
986 // SystemModalContainerEventFilter instead of stops_event_propagation.
987 aura::Window* lock_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27988 kShellWindowId_LockScreenContainer,
[email protected]a4cd6d32012-09-12 03:42:13989 "LockScreenContainer",
990 lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10991 wm::SetSnapsChildrenToPhysicalPixelBoundary(lock_container);
oshima96f6a502015-05-02 08:43:32992 lock_container->SetLayoutManager(new LockLayoutManager(lock_container));
[email protected]a4cd6d32012-09-12 03:42:13993 SetUsesScreenCoordinates(lock_container);
994 // TODO(beng): stopsevents
995
996 aura::Window* lock_modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27997 kShellWindowId_LockSystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13998 "LockSystemModalContainer",
999 lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:101000 wm::SetSnapsChildrenToPhysicalPixelBoundary(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:131001 lock_modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:271002 new SystemModalContainerLayoutManager(lock_modal_container));
[email protected]e319c7e2014-03-14 19:56:141003 ::wm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:131004 SetUsesScreenCoordinates(lock_modal_container);
[email protected]c5be8d672014-01-07 13:33:411005 SetUsesEasyResizeTargeter(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:131006
1007 aura::Window* status_container =
[email protected]c0ce80e2012-10-05 23:28:271008 CreateContainer(kShellWindowId_StatusContainer,
[email protected]a4cd6d32012-09-12 03:42:131009 "StatusContainer",
1010 lock_screen_related_containers);
[email protected]1ca79d42014-07-18 16:26:101011 wm::SetSnapsChildrenToPhysicalPixelBoundary(status_container);
[email protected]a4cd6d32012-09-12 03:42:131012 SetUsesScreenCoordinates(status_container);
[email protected]e887c6c2013-07-08 19:35:531013 DescendantShouldStayInSameRootWindow(status_container);
[email protected]a4cd6d32012-09-12 03:42:131014
1015 aura::Window* settings_bubble_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:271016 kShellWindowId_SettingBubbleContainer,
[email protected]a4cd6d32012-09-12 03:42:131017 "SettingBubbleContainer",
1018 lock_screen_related_containers);
[email protected]e319c7e2014-03-14 19:56:141019 ::wm::SetChildWindowVisibilityChangesAnimated(settings_bubble_container);
[email protected]1ca79d42014-07-18 16:26:101020 wm::SetSnapsChildrenToPhysicalPixelBoundary(settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:131021 SetUsesScreenCoordinates(settings_bubble_container);
[email protected]e887c6c2013-07-08 19:35:531022 DescendantShouldStayInSameRootWindow(settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:131023
kevers23f3987d2014-09-17 13:50:121024 aura::Window* virtual_keyboard_parent_container =
bshec3875422014-09-29 13:21:301025 CreateContainer(kShellWindowId_ImeWindowParentContainer,
kevers23f3987d2014-09-17 13:50:121026 "VirtualKeyboardParentContainer",
1027 lock_screen_related_containers);
1028 wm::SetSnapsChildrenToPhysicalPixelBoundary(
1029 virtual_keyboard_parent_container);
1030 SetUsesScreenCoordinates(virtual_keyboard_parent_container);
1031
[email protected]a4cd6d32012-09-12 03:42:131032 aura::Window* menu_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:271033 kShellWindowId_MenuContainer,
[email protected]a4cd6d32012-09-12 03:42:131034 "MenuContainer",
1035 lock_screen_related_containers);
[email protected]e319c7e2014-03-14 19:56:141036 ::wm::SetChildWindowVisibilityChangesAnimated(menu_container);
[email protected]1ca79d42014-07-18 16:26:101037 wm::SetSnapsChildrenToPhysicalPixelBoundary(menu_container);
[email protected]a4cd6d32012-09-12 03:42:131038 SetUsesScreenCoordinates(menu_container);
1039
1040 aura::Window* drag_drop_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:271041 kShellWindowId_DragImageAndTooltipContainer,
[email protected]a4cd6d32012-09-12 03:42:131042 "DragImageAndTooltipContainer",
1043 lock_screen_related_containers);
[email protected]e319c7e2014-03-14 19:56:141044 ::wm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
[email protected]1ca79d42014-07-18 16:26:101045 wm::SetSnapsChildrenToPhysicalPixelBoundary(drag_drop_container);
[email protected]a4cd6d32012-09-12 03:42:131046 SetUsesScreenCoordinates(drag_drop_container);
1047
1048 aura::Window* overlay_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:271049 kShellWindowId_OverlayContainer,
[email protected]a4cd6d32012-09-12 03:42:131050 "OverlayContainer",
1051 lock_screen_related_containers);
[email protected]1ca79d42014-07-18 16:26:101052 wm::SetSnapsChildrenToPhysicalPixelBoundary(overlay_container);
[email protected]a4cd6d32012-09-12 03:42:131053 SetUsesScreenCoordinates(overlay_container);
[email protected]a07615f2012-10-24 08:23:081054
[email protected]b2da9b602014-03-05 18:39:521055#if defined(OS_CHROMEOS)
1056 aura::Window* mouse_cursor_container = CreateContainer(
1057 kShellWindowId_MouseCursorContainer,
1058 "MouseCursorContainer",
1059 root_window);
1060 SetUsesScreenCoordinates(mouse_cursor_container);
1061#endif
1062
[email protected]a07615f2012-10-24 08:23:081063 CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
[email protected]b2da9b602014-03-05 18:39:521064 "PowerButtonAnimationContainer", root_window);
[email protected]a4cd6d32012-09-12 03:42:131065}
1066
[email protected]d141b922013-07-09 08:13:171067void RootWindowController::EnableTouchHudProjection() {
1068 if (touch_hud_projection_)
1069 return;
[email protected]f5c9dbc2014-04-11 08:13:451070 set_touch_hud_projection(new TouchHudProjection(GetRootWindow()));
[email protected]d141b922013-07-09 08:13:171071}
1072
1073void RootWindowController::DisableTouchHudProjection() {
1074 if (!touch_hud_projection_)
1075 return;
1076 touch_hud_projection_->Remove();
1077}
1078
1079void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
1080 shelf_->shelf_layout_manager()->UpdateVisibilityState();
1081}
1082
1083void RootWindowController::OnTouchHudProjectionToggled(bool enabled) {
1084 if (enabled)
1085 EnableTouchHudProjection();
1086 else
1087 DisableTouchHudProjection();
1088}
1089
[email protected]6b2d4a0b2013-09-06 06:29:541090RootWindowController* GetRootWindowController(
[email protected]bf9cdb362013-10-25 19:22:451091 const aura::Window* root_window) {
[email protected]6b2d4a0b2013-09-06 06:29:541092 return root_window ? GetRootWindowSettings(root_window)->controller : NULL;
1093}
1094
[email protected]d90b8392012-06-13 09:34:561095} // namespace ash