blob: a2d8219fc72ff44a9f43147c2d3836b57e3d3122 [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"
[email protected]beb4e5c2013-06-18 15:37:0736#include "ash/wm/dock/docked_window_layout_manager.h"
[email protected]68d51332014-06-06 13:51:1337#include "ash/wm/lock_layout_manager.h"
[email protected]b8642ec2014-04-17 05:20:3938#include "ash/wm/panels/attached_panel_window_targeter.h"
[email protected]7095a652013-03-07 19:41:4939#include "ash/wm/panels/panel_layout_manager.h"
[email protected]100659412013-06-21 22:59:5540#include "ash/wm/panels/panel_window_event_handler.h"
[email protected]d90b8392012-06-13 09:34:5641#include "ash/wm/root_window_layout_manager.h"
[email protected]2a2caa02013-01-22 20:50:3642#include "ash/wm/stacking_controller.h"
[email protected]e74aaf0a2012-10-12 18:42:2843#include "ash/wm/status_area_layout_manager.h"
[email protected]e6e41d2f2012-10-29 19:22:1944#include "ash/wm/system_background_controller.h"
[email protected]d90b8392012-06-13 09:34:5645#include "ash/wm/system_modal_container_layout_manager.h"
[email protected]8d625fb2012-07-18 16:40:0646#include "ash/wm/window_properties.h"
[email protected]a41b4e12013-09-20 04:36:3447#include "ash/wm/window_state.h"
[email protected]700849f2013-04-30 17:49:2048#include "ash/wm/window_util.h"
[email protected]1af71f72014-01-29 20:00:5549#include "ash/wm/workspace/workspace_layout_manager.h"
[email protected]d90b8392012-06-13 09:34:5650#include "ash/wm/workspace_controller.h"
[email protected]e6e41d2f2012-10-29 19:22:1951#include "base/command_line.h"
[email protected]1e84c632013-06-27 23:12:2152#include "base/time/time.h"
[email protected]f1853122012-06-27 16:21:2653#include "ui/aura/client/aura_constants.h"
[email protected]2374d1812014-03-04 03:42:2754#include "ui/aura/client/screen_position_client.h"
[email protected]f1853122012-06-27 16:21:2655#include "ui/aura/window.h"
[email protected]cf6fea22013-08-07 14:24:0156#include "ui/aura/window_delegate.h"
[email protected]fcc51c952014-02-21 21:31:2657#include "ui/aura/window_event_dispatcher.h"
[email protected]f1853122012-06-27 16:21:2658#include "ui/aura/window_observer.h"
[email protected]8b3e3d82013-08-20 14:36:3059#include "ui/aura/window_tracker.h"
[email protected]cf6fea22013-08-07 14:24:0160#include "ui/base/hit_test.h"
[email protected]431552c2012-10-23 00:38:3361#include "ui/base/models/menu_model.h"
[email protected]f8e6aad2013-08-30 21:49:1162#include "ui/gfx/display.h"
[email protected]8d625fb2012-07-18 16:40:0663#include "ui/gfx/screen.h"
[email protected]86459e2c2013-04-10 13:39:2464#include "ui/keyboard/keyboard_controller.h"
65#include "ui/keyboard/keyboard_util.h"
[email protected]431552c2012-10-23 00:38:3366#include "ui/views/controls/menu/menu_runner.h"
67#include "ui/views/view_model.h"
68#include "ui/views/view_model_utils.h"
[email protected]ee3ed10772014-03-11 22:02:0169#include "ui/wm/core/capture_controller.h"
[email protected]e319c7e2014-03-14 19:56:1470#include "ui/wm/core/easy_resize_window_targeter.h"
[email protected]ee3ed10772014-03-11 22:02:0171#include "ui/wm/core/visibility_controller.h"
72#include "ui/wm/core/window_util.h"
[email protected]af4552b22014-03-21 19:45:0173#include "ui/wm/public/drag_drop_client.h"
74#include "ui/wm/public/tooltip_client.h"
[email protected]5b251f12013-12-19 01:50:0575#include "ui/wm/public/window_types.h"
[email protected]d90b8392012-06-13 09:34:5676
[email protected]252eb232013-08-14 22:09:2777#if defined(OS_CHROMEOS)
[email protected]7d487592014-07-24 03:54:5078#include "ash/ash_touch_exploration_manager_chromeos.h"
[email protected]252eb232013-08-14 22:09:2779#include "ash/wm/boot_splash_screen_chromeos.h"
[email protected]a825e8312014-05-05 22:05:0180#include "ui/chromeos/touch_exploration_controller.h"
[email protected]252eb232013-08-14 22:09:2781#endif
82
[email protected]d90b8392012-06-13 09:34:5683namespace ash {
84namespace {
85
[email protected]252eb232013-08-14 22:09:2786#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:4987// Duration for the animation that hides the boot splash screen, in
88// milliseconds. This should be short enough in relation to
89// wm/window_animation.cc's brightness/grayscale fade animation that the login
90// background image animation isn't hidden by the splash screen animation.
91const int kBootSplashScreenHideDurationMs = 500;
[email protected]252eb232013-08-14 22:09:2792#endif
[email protected]bca9a7e2012-11-10 06:25:4993
[email protected]d90b8392012-06-13 09:34:5694// Creates a new window for use as a container.
95aura::Window* CreateContainer(int window_id,
96 const char* name,
97 aura::Window* parent) {
98 aura::Window* container = new aura::Window(NULL);
99 container->set_id(window_id);
100 container->SetName(name);
danakjb161836d2015-04-03 05:14:18101 container->Init(ui::LAYER_NOT_DRAWN);
[email protected]d90b8392012-06-13 09:34:56102 parent->AddChild(container);
[email protected]093b8d642014-04-03 20:59:28103 if (window_id != kShellWindowId_UnparentedControlContainer)
[email protected]d90b8392012-06-13 09:34:56104 container->Show();
105 return container;
106}
107
[email protected]2816c2462013-12-17 02:22:25108float ToRelativeValue(int value, int src, int dst) {
109 return static_cast<float>(value) / static_cast<float>(src) * dst;
110}
111
112void MoveOriginRelativeToSize(const gfx::Size& src_size,
113 const gfx::Size& dst_size,
114 gfx::Rect* bounds_in_out) {
115 gfx::Point origin = bounds_in_out->origin();
116 bounds_in_out->set_origin(gfx::Point(
117 ToRelativeValue(origin.x(), src_size.width(), dst_size.width()),
118 ToRelativeValue(origin.y(), src_size.height(), dst_size.height())));
119}
120
[email protected]95058572012-08-20 14:57:29121// Reparents |window| to |new_parent|.
122void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
[email protected]2816c2462013-12-17 02:22:25123 const gfx::Size src_size = window->parent()->bounds().size();
124 const gfx::Size dst_size = new_parent->bounds().size();
[email protected]95058572012-08-20 14:57:29125 // Update the restore bounds to make it relative to the display.
[email protected]a41b4e12013-09-20 04:36:34126 wm::WindowState* state = wm::GetWindowState(window);
127 gfx::Rect restore_bounds;
128 bool has_restore_bounds = state->HasRestoreBounds();
[email protected]2816c2462013-12-17 02:22:25129
[email protected]9cfd3d12014-02-25 15:33:45130 bool update_bounds = (state->IsNormalOrSnapped() || state->IsMinimized()) &&
[email protected]093b8d642014-04-03 20:59:28131 new_parent->id() != kShellWindowId_DockedContainer;
[email protected]2816c2462013-12-17 02:22:25132 gfx::Rect local_bounds;
133 if (update_bounds) {
134 local_bounds = state->window()->bounds();
135 MoveOriginRelativeToSize(src_size, dst_size, &local_bounds);
136 }
137
138 if (has_restore_bounds) {
[email protected]a41b4e12013-09-20 04:36:34139 restore_bounds = state->GetRestoreBoundsInParent();
[email protected]2816c2462013-12-17 02:22:25140 MoveOriginRelativeToSize(src_size, dst_size, &restore_bounds);
141 }
142
[email protected]95058572012-08-20 14:57:29143 new_parent->AddChild(window);
[email protected]2816c2462013-12-17 02:22:25144
[email protected]8663b7a62014-01-18 01:24:21145 // Docked windows have bounds handled by the layout manager in AddChild().
[email protected]2816c2462013-12-17 02:22:25146 if (update_bounds)
147 window->SetBounds(local_bounds);
148
[email protected]a41b4e12013-09-20 04:36:34149 if (has_restore_bounds)
150 state->SetRestoreBoundsInParent(restore_bounds);
[email protected]95058572012-08-20 14:57:29151}
152
153// Reparents the appropriate set of windows from |src| to |dst|.
[email protected]bf9cdb362013-10-25 19:22:45154void ReparentAllWindows(aura::Window* src, aura::Window* dst) {
[email protected]95058572012-08-20 14:57:29155 // Set of windows to move.
[email protected]f1853122012-06-27 16:21:26156 const int kContainerIdsToMove[] = {
[email protected]093b8d642014-04-03 20:59:28157 kShellWindowId_DefaultContainer,
158 kShellWindowId_DockedContainer,
159 kShellWindowId_PanelContainer,
160 kShellWindowId_AlwaysOnTopContainer,
161 kShellWindowId_SystemModalContainer,
162 kShellWindowId_LockSystemModalContainer,
tengsf98986c2014-12-06 01:42:21163 kShellWindowId_UnparentedControlContainer,
oshima022a9542015-05-01 00:15:02164 kShellWindowId_OverlayContainer,
165 };
166 const int kExtraContainerIdsToMoveInUnifiedMode[] = {
167 kShellWindowId_LockScreenContainer,
168 kShellWindowId_LockScreenBackgroundContainer,
169 };
170 std::vector<int> container_ids(
171 kContainerIdsToMove,
172 kContainerIdsToMove + arraysize(kContainerIdsToMove));
173 // Check the default_multi_display_mode because this is also necessary
174 // in trasition between mirror <-> unified mode.
oshima628a6172015-08-01 01:33:14175 if (Shell::GetInstance()
176 ->display_manager()
177 ->current_default_multi_display_mode() == DisplayManager::UNIFIED) {
oshima022a9542015-05-01 00:15:02178 for (int id : kExtraContainerIdsToMoveInUnifiedMode)
179 container_ids.push_back(id);
180 }
181
182 for (int id : container_ids) {
[email protected]f1853122012-06-27 16:21:26183 aura::Window* src_container = Shell::GetContainer(src, id);
184 aura::Window* dst_container = Shell::GetContainer(dst, id);
[email protected]5b6021902013-02-26 05:33:29185 while (!src_container->children().empty()) {
186 // Restart iteration from the source container windows each time as they
187 // may change as a result of moving other windows.
188 aura::Window::Windows::const_iterator iter =
189 src_container->children().begin();
190 while (iter != src_container->children().end() &&
[email protected]093b8d642014-04-03 20:59:28191 SystemModalContainerLayoutManager::IsModalBackground(*iter)) {
[email protected]5b6021902013-02-26 05:33:29192 ++iter;
193 }
194 // If the entire window list is modal background windows then stop.
195 if (iter == src_container->children().end())
196 break;
197 ReparentWindow(*iter, dst_container);
[email protected]f1853122012-06-27 16:21:26198 }
199 }
200}
201
[email protected]8d625fb2012-07-18 16:40:06202// Mark the container window so that a widget added to this container will
203// use the virtual screeen coordinates instead of parent.
204void SetUsesScreenCoordinates(aura::Window* container) {
[email protected]093b8d642014-04-03 20:59:28205 container->SetProperty(kUsesScreenCoordinatesKey, true);
[email protected]8d625fb2012-07-18 16:40:06206}
207
[email protected]e887c6c2013-07-08 19:35:53208// Mark the container window so that a widget added to this container will
209// say in the same root window regardless of the bounds specified.
210void DescendantShouldStayInSameRootWindow(aura::Window* container) {
[email protected]093b8d642014-04-03 20:59:28211 container->SetProperty(kStayInSameRootWindowKey, true);
[email protected]e887c6c2013-07-08 19:35:53212}
213
[email protected]c5be8d672014-01-07 13:33:41214void SetUsesEasyResizeTargeter(aura::Window* container) {
215 gfx::Insets mouse_extend(-kResizeOutsideBoundsSize,
216 -kResizeOutsideBoundsSize,
217 -kResizeOutsideBoundsSize,
218 -kResizeOutsideBoundsSize);
219 gfx::Insets touch_extend = mouse_extend.Scale(
220 kResizeOutsideBoundsScaleForTouch);
[email protected]95f642cb2014-01-31 01:35:41221 container->SetEventTargeter(scoped_ptr<ui::EventTargeter>(
[email protected]c5be8d672014-01-07 13:33:41222 new ::wm::EasyResizeWindowTargeter(container, mouse_extend,
223 touch_extend)));
224}
225
[email protected]cf6fea22013-08-07 14:24:01226// A window delegate which does nothing. Used to create a window that
227// is a event target, but do nothing.
228class EmptyWindowDelegate : public aura::WindowDelegate {
229 public:
230 EmptyWindowDelegate() {}
dcheng1f4538e2014-10-27 23:57:05231 ~EmptyWindowDelegate() override {}
[email protected]cf6fea22013-08-07 14:24:01232
233 // aura::WindowDelegate overrides:
dcheng1f4538e2014-10-27 23:57:05234 gfx::Size GetMinimumSize() const override { return gfx::Size(); }
235 gfx::Size GetMaximumSize() const override { return gfx::Size(); }
236 void OnBoundsChanged(const gfx::Rect& old_bounds,
237 const gfx::Rect& new_bounds) override {}
238 gfx::NativeCursor GetCursor(const gfx::Point& point) override {
[email protected]62c9f102014-03-27 06:07:04239 return gfx::kNullCursor;
240 }
dcheng1f4538e2014-10-27 23:57:05241 int GetNonClientComponent(const gfx::Point& point) const override {
[email protected]cf6fea22013-08-07 14:24:01242 return HTNOWHERE;
243 }
dcheng1f4538e2014-10-27 23:57:05244 bool ShouldDescendIntoChildForEventHandling(
[email protected]cf6fea22013-08-07 14:24:01245 aura::Window* child,
mostynb10d6b382014-10-03 16:23:45246 const gfx::Point& location) override {
[email protected]cf6fea22013-08-07 14:24:01247 return false;
248 }
dcheng1f4538e2014-10-27 23:57:05249 bool CanFocus() override { return false; }
250 void OnCaptureLost() override {}
danakj85d970e2015-04-04 00:15:24251 void OnPaint(const ui::PaintContext& context) override {}
dcheng1f4538e2014-10-27 23:57:05252 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
253 void OnWindowDestroying(aura::Window* window) override {}
254 void OnWindowDestroyed(aura::Window* window) override { delete this; }
255 void OnWindowTargetVisibilityChanged(bool visible) override {}
256 bool HasHitTestMask() const override { return false; }
257 void GetHitTestMask(gfx::Path* mask) const override {}
[email protected]cf6fea22013-08-07 14:24:01258
259 private:
260 DISALLOW_COPY_AND_ASSIGN(EmptyWindowDelegate);
261};
262
[email protected]d90b8392012-06-13 09:34:56263} // namespace
264
[email protected]f5c9dbc2014-04-11 08:13:45265void RootWindowController::CreateForPrimaryDisplay(AshWindowTreeHost* host) {
[email protected]2f2620332014-02-28 10:07:38266 RootWindowController* controller = new RootWindowController(host);
[email protected]608de6c2013-10-29 00:14:28267 controller->Init(RootWindowController::PRIMARY,
[email protected]a273d33a2013-10-17 12:41:21268 Shell::GetInstance()->delegate()->IsFirstRunAfterBoot());
[email protected]d90b8392012-06-13 09:34:56269}
270
[email protected]f5c9dbc2014-04-11 08:13:45271void RootWindowController::CreateForSecondaryDisplay(AshWindowTreeHost* host) {
[email protected]2f2620332014-02-28 10:07:38272 RootWindowController* controller = new RootWindowController(host);
[email protected]608de6c2013-10-29 00:14:28273 controller->Init(RootWindowController::SECONDARY, false /* first run */);
274}
275
[email protected]88d71122012-10-18 07:11:01276// static
[email protected]ccff3d72013-02-06 04:26:28277RootWindowController* RootWindowController::ForWindow(
278 const aura::Window* window) {
oshima9eea82da2014-09-13 01:11:07279 CHECK(Shell::HasInstance());
[email protected]a0afeb12012-12-10 22:57:09280 return GetRootWindowController(window->GetRootWindow());
281}
282
283// static
[email protected]d17642d2013-09-12 23:44:38284RootWindowController* RootWindowController::ForTargetRootWindow() {
oshima9eea82da2014-09-13 01:11:07285 CHECK(Shell::HasInstance());
[email protected]093b8d642014-04-03 20:59:28286 return GetRootWindowController(Shell::GetTargetRootWindow());
[email protected]a0afeb12012-12-10 22:57:09287}
288
[email protected]a5c78802013-12-12 22:07:01289// static
290aura::Window* RootWindowController::GetContainerForWindow(
291 aura::Window* window) {
292 aura::Window* container = window->parent();
[email protected]5b251f12013-12-19 01:50:05293 while (container && container->type() != ui::wm::WINDOW_TYPE_UNKNOWN)
[email protected]a5c78802013-12-12 22:07:01294 container = container->parent();
295 return container;
296}
297
[email protected]a273d33a2013-10-17 12:41:21298RootWindowController::~RootWindowController() {
299 Shutdown();
[email protected]f5c9dbc2014-04-11 08:13:45300 ash_host_.reset();
[email protected]a273d33a2013-10-17 12:41:21301 // The CaptureClient needs to be around for as long as the RootWindow is
302 // valid.
303 capture_client_.reset();
304}
305
[email protected]f5c9dbc2014-04-11 08:13:45306aura::WindowTreeHost* RootWindowController::GetHost() {
307 return ash_host_->AsWindowTreeHost();
308}
309
310const aura::WindowTreeHost* RootWindowController::GetHost() const {
311 return ash_host_->AsWindowTreeHost();
312}
313
314aura::Window* RootWindowController::GetRootWindow() {
315 return GetHost()->window();
316}
317
318const aura::Window* RootWindowController::GetRootWindow() const {
319 return GetHost()->window();
320}
321
[email protected]0bf61732013-07-02 04:35:10322void RootWindowController::SetWallpaperController(
323 DesktopBackgroundWidgetController* controller) {
324 wallpaper_controller_.reset(controller);
325}
326
327void RootWindowController::SetAnimatingWallpaperController(
328 AnimatingDesktopController* controller) {
329 if (animating_wallpaper_controller_.get())
330 animating_wallpaper_controller_->StopAnimating();
331 animating_wallpaper_controller_.reset(controller);
332}
333
[email protected]6675e1c2012-09-11 09:15:45334void RootWindowController::Shutdown() {
[email protected]a825e8312014-05-05 22:05:01335 Shell* shell = Shell::GetInstance();
336 shell->RemoveShellObserver(this);
337
338#if defined(OS_CHROMEOS)
[email protected]7d487592014-07-24 03:54:50339 if (touch_exploration_manager_) {
340 touch_exploration_manager_.reset();
[email protected]a825e8312014-05-05 22:05:01341 }
342#endif
[email protected]d141b922013-07-09 08:13:17343
[email protected]0bf61732013-07-02 04:35:10344 if (animating_wallpaper_controller_.get())
345 animating_wallpaper_controller_->StopAnimating();
346 wallpaper_controller_.reset();
347 animating_wallpaper_controller_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45348 aura::Window* root_window = GetRootWindow();
[email protected]d17642d2013-09-12 23:44:38349 // Change the target root window before closing child windows. If any child
[email protected]c98a4922013-09-05 20:01:42350 // being removed triggers a relayout of the shelf it will try to build a
[email protected]d17642d2013-09-12 23:44:38351 // window list adding windows from the target root window's containers which
[email protected]c98a4922013-09-05 20:01:42352 // may have already gone away.
[email protected]f5c9dbc2014-04-11 08:13:45353 if (Shell::GetTargetRootWindow() == root_window) {
[email protected]a825e8312014-05-05 22:05:01354 shell->set_target_root_window(
[email protected]f5c9dbc2014-04-11 08:13:45355 Shell::GetPrimaryRootWindow() == root_window
356 ? NULL
357 : Shell::GetPrimaryRootWindow());
[email protected]f634dd32012-07-23 22:49:07358 }
[email protected]c98a4922013-09-05 20:01:42359
360 CloseChildWindows();
[email protected]f5c9dbc2014-04-11 08:13:45361 GetRootWindowSettings(root_window)->controller = NULL;
[email protected]d90b8392012-06-13 09:34:56362 workspace_controller_.reset();
[email protected]6675e1c2012-09-11 09:15:45363 // Forget with the display ID so that display lookup
364 // ends up with invalid display.
[email protected]f5c9dbc2014-04-11 08:13:45365 GetRootWindowSettings(root_window)->display_id =
[email protected]f8e6aad2013-08-30 21:49:11366 gfx::Display::kInvalidDisplayID;
[email protected]8f5209c2014-05-22 20:36:11367 ash_host_->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28368
[email protected]956a6a42012-10-29 23:58:10369 system_background_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45370 aura::client::SetScreenPositionClient(root_window, NULL);
[email protected]d90b8392012-06-13 09:34:56371}
372
[email protected]c0ce80e2012-10-05 23:28:27373SystemModalContainerLayoutManager*
[email protected]8674b312012-10-12 19:02:44374RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
[email protected]a5c78802013-12-12 22:07:01375 aura::Window* modal_container = NULL;
[email protected]8674b312012-10-12 19:02:44376 if (window) {
[email protected]a5c78802013-12-12 22:07:01377 aura::Window* window_container = GetContainerForWindow(window);
378 if (window_container &&
379 window_container->id() >= kShellWindowId_LockScreenContainer) {
380 modal_container = GetContainer(kShellWindowId_LockSystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35381 } else {
[email protected]a5c78802013-12-12 22:07:01382 modal_container = GetContainer(kShellWindowId_SystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35383 }
[email protected]8674b312012-10-12 19:02:44384 } else {
[email protected]a44afbbd2013-07-24 21:49:35385 int modal_window_id = Shell::GetInstance()->session_state_delegate()
386 ->IsUserSessionBlocked() ? kShellWindowId_LockSystemModalContainer :
387 kShellWindowId_SystemModalContainer;
[email protected]a5c78802013-12-12 22:07:01388 modal_container = GetContainer(modal_window_id);
[email protected]8674b312012-10-12 19:02:44389 }
[email protected]a5c78802013-12-12 22:07:01390 return modal_container ? static_cast<SystemModalContainerLayoutManager*>(
391 modal_container->layout_manager()) : NULL;
[email protected]c0ce80e2012-10-05 23:28:27392}
393
[email protected]d90b8392012-06-13 09:34:56394aura::Window* RootWindowController::GetContainer(int container_id) {
[email protected]f5c9dbc2014-04-11 08:13:45395 return GetRootWindow()->GetChildById(container_id);
[email protected]d90b8392012-06-13 09:34:56396}
397
[email protected]d8a24952013-08-05 20:05:05398const aura::Window* RootWindowController::GetContainer(int container_id) const {
[email protected]f5c9dbc2014-04-11 08:13:45399 return ash_host_->AsWindowTreeHost()->window()->GetChildById(container_id);
[email protected]d8a24952013-08-05 20:05:05400}
401
[email protected]864b58552013-12-19 04:19:38402void RootWindowController::ShowShelf() {
403 if (!shelf_->shelf())
[email protected]e74aaf0a2012-10-12 18:42:28404 return;
[email protected]864b58552013-12-19 04:19:38405 shelf_->shelf()->SetVisible(true);
[email protected]478c6c32013-03-09 02:50:58406 shelf_->status_area_widget()->Show();
[email protected]e74aaf0a2012-10-12 18:42:28407}
408
[email protected]864b58552013-12-19 04:19:38409void RootWindowController::OnShelfCreated() {
[email protected]756bda12013-07-03 08:17:06410 if (panel_layout_manager_)
[email protected]864b58552013-12-19 04:19:38411 panel_layout_manager_->SetShelf(shelf_->shelf());
[email protected]7115bd32013-07-19 08:25:39412 if (docked_layout_manager_) {
[email protected]864b58552013-12-19 04:19:38413 docked_layout_manager_->SetShelf(shelf_->shelf());
[email protected]7115bd32013-07-19 08:25:39414 if (shelf_->shelf_layout_manager())
415 docked_layout_manager_->AddObserver(shelf_->shelf_layout_manager());
416 }
[email protected]b8642ec2014-04-17 05:20:39417
418 // Notify shell observers that the shelf has been created.
419 Shell::GetInstance()->OnShelfCreatedForRootWindow(GetRootWindow());
[email protected]756bda12013-07-03 08:17:06420}
421
[email protected]16059276d2012-10-22 18:59:50422void RootWindowController::UpdateAfterLoginStatusChange(
423 user::LoginStatus status) {
[email protected]cf6fea22013-08-07 14:24:01424 if (status != user::LOGGED_IN_NONE)
425 mouse_event_target_.reset();
[email protected]80549c152013-07-02 01:42:47426 if (shelf_->status_area_widget())
[email protected]478c6c32013-03-09 02:50:58427 shelf_->status_area_widget()->UpdateAfterLoginStatusChange(status);
[email protected]16059276d2012-10-22 18:59:50428}
429
[email protected]bca9a7e2012-11-10 06:25:49430void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
[email protected]252eb232013-08-14 22:09:27431#if defined(OS_CHROMEOS)
pgal.u-szegedd84534d32014-10-29 12:34:30432 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]bca9a7e2012-11-10 06:25:49433 switches::kAshAnimateFromBootSplashScreen) &&
434 boot_splash_screen_.get()) {
435 // Make the splash screen fade out so it doesn't obscure the desktop
436 // wallpaper's brightness/grayscale animation.
437 boot_splash_screen_->StartHideAnimation(
438 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
439 }
[email protected]252eb232013-08-14 22:09:27440#endif
[email protected]bca9a7e2012-11-10 06:25:49441}
442
[email protected]0bf61732013-07-02 04:35:10443void RootWindowController::OnWallpaperAnimationFinished(views::Widget* widget) {
444 // Make sure the wallpaper is visible.
[email protected]bca9a7e2012-11-10 06:25:49445 system_background_->SetColor(SK_ColorBLACK);
[email protected]252eb232013-08-14 22:09:27446#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:49447 boot_splash_screen_.reset();
[email protected]252eb232013-08-14 22:09:27448#endif
[email protected]0bf61732013-07-02 04:35:10449
450 Shell::GetInstance()->user_wallpaper_delegate()->
451 OnWallpaperAnimationFinished();
452 // Only removes old component when wallpaper animation finished. If we
453 // remove the old one before the new wallpaper is done fading in there will
454 // be a white flash during the animation.
455 if (animating_wallpaper_controller()) {
456 DesktopBackgroundWidgetController* controller =
457 animating_wallpaper_controller()->GetController(true);
458 // |desktop_widget_| should be the same animating widget we try to move
459 // to |kDesktopController|. Otherwise, we may close |desktop_widget_|
460 // before move it to |kDesktopController|.
461 DCHECK_EQ(controller->widget(), widget);
462 // Release the old controller and close its background widget.
463 SetWallpaperController(controller);
464 }
[email protected]697f04c2012-10-03 01:15:10465}
466
[email protected]d90b8392012-06-13 09:34:56467void RootWindowController::CloseChildWindows() {
[email protected]cf6fea22013-08-07 14:24:01468 mouse_event_target_.reset();
469
[email protected]2a57beb52014-06-09 20:02:26470 // Remove observer as deactivating keyboard causes |docked_layout_manager_|
471 // to fire notifications.
472 if (docked_layout_manager_ && shelf_ && shelf_->shelf_layout_manager())
473 docked_layout_manager_->RemoveObserver(shelf_->shelf_layout_manager());
474
[email protected]b6ba05d902013-10-04 21:38:45475 // Deactivate keyboard container before closing child windows and shutting
476 // down associated layout managers.
[email protected]a0b3fb882014-04-07 19:26:03477 DeactivateKeyboard(keyboard::KeyboardController::GetInstance());
[email protected]b6ba05d902013-10-04 21:38:45478
[email protected]79a87b7e2013-01-25 05:08:22479 // panel_layout_manager_ needs to be shut down before windows are destroyed.
480 if (panel_layout_manager_) {
481 panel_layout_manager_->Shutdown();
482 panel_layout_manager_ = NULL;
483 }
[email protected]7115bd32013-07-19 08:25:39484 // docked_layout_manager_ needs to be shut down before windows are destroyed.
485 if (docked_layout_manager_) {
[email protected]7115bd32013-07-19 08:25:39486 docked_layout_manager_->Shutdown();
487 docked_layout_manager_ = NULL;
488 }
[email protected]f5c9dbc2014-04-11 08:13:45489 aura::Window* root_window = GetRootWindow();
490 aura::client::SetDragDropClient(root_window, NULL);
[email protected]8b3e3d82013-08-20 14:36:30491
[email protected]478c6c32013-03-09 02:50:58492 // TODO(harrym): Remove when Status Area Widget is a child view.
[email protected]bb42c932013-10-31 06:52:06493 if (shelf_) {
494 shelf_->ShutdownStatusAreaWidget();
[email protected]478c6c32013-03-09 02:50:58495
[email protected]bb42c932013-10-31 06:52:06496 if (shelf_->shelf_layout_manager())
497 shelf_->shelf_layout_manager()->PrepareForShutdown();
498 }
[email protected]e74aaf0a2012-10-12 18:42:28499
[email protected]d90b8392012-06-13 09:34:56500 // Close background widget first as it depends on tooltip.
[email protected]0bf61732013-07-02 04:35:10501 wallpaper_controller_.reset();
502 animating_wallpaper_controller_.reset();
[email protected]b4ddc7a2012-08-07 04:17:32503
[email protected]d90b8392012-06-13 09:34:56504 workspace_controller_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45505 aura::client::SetTooltipClient(root_window, NULL);
[email protected]d90b8392012-06-13 09:34:56506
[email protected]0fbfa972013-10-02 19:23:33507 // Explicitly destroy top level windows. We do this as during part of
508 // destruction such windows may query the RootWindow for state.
oshimaf38efa92015-10-27 19:06:52509 aura::WindowTracker non_toplevel_windows;
510 non_toplevel_windows.Add(root_window);
511 while (!non_toplevel_windows.windows().empty()) {
512 const aura::Window* non_toplevel_window =
513 *non_toplevel_windows.windows().begin();
514 non_toplevel_windows.Remove(const_cast<aura::Window*>(non_toplevel_window));
[email protected]8b3e3d82013-08-20 14:36:30515 aura::WindowTracker toplevel_windows;
516 for (size_t i = 0; i < non_toplevel_window->children().size(); ++i) {
517 aura::Window* child = non_toplevel_window->children()[i];
[email protected]0fbfa972013-10-02 19:23:33518 if (!child->owned_by_parent())
519 continue;
[email protected]8b3e3d82013-08-20 14:36:30520 if (child->delegate())
521 toplevel_windows.Add(child);
522 else
oshimaf38efa92015-10-27 19:06:52523 non_toplevel_windows.Add(child);
[email protected]8b3e3d82013-08-20 14:36:30524 }
525 while (!toplevel_windows.windows().empty())
526 delete *toplevel_windows.windows().begin();
[email protected]d90b8392012-06-13 09:34:56527 }
[email protected]8b3e3d82013-08-20 14:36:30528 // And then remove the containers.
[email protected]f5c9dbc2014-04-11 08:13:45529 while (!root_window->children().empty()) {
530 aura::Window* window = root_window->children()[0];
[email protected]0fbfa972013-10-02 19:23:33531 if (window->owned_by_parent()) {
532 delete window;
533 } else {
[email protected]f5c9dbc2014-04-11 08:13:45534 root_window->RemoveChild(window);
[email protected]0fbfa972013-10-02 19:23:33535 }
536 }
[email protected]478c6c32013-03-09 02:50:58537
[email protected]bb42c932013-10-31 06:52:06538 shelf_.reset();
[email protected]d90b8392012-06-13 09:34:56539}
540
[email protected]bf9cdb362013-10-25 19:22:45541void RootWindowController::MoveWindowsTo(aura::Window* dst) {
[email protected]8039e06c2013-01-17 23:34:50542 // Forget the shelf early so that shelf don't update itself using wrong
543 // display info.
544 workspace_controller_->SetShelf(NULL);
[email protected]f5c9dbc2014-04-11 08:13:45545 ReparentAllWindows(GetRootWindow(), dst);
[email protected]f1853122012-06-27 16:21:26546}
547
[email protected]478c6c32013-03-09 02:50:58548ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
[email protected]80549c152013-07-02 01:42:47549 return shelf_->shelf_layout_manager();
[email protected]478c6c32013-03-09 02:50:58550}
551
[email protected]a0afeb12012-12-10 22:57:09552SystemTray* RootWindowController::GetSystemTray() {
553 // We assume in throughout the code that this will not return NULL. If code
554 // triggers this for valid reasons, it should test status_area_widget first.
[email protected]80549c152013-07-02 01:42:47555 CHECK(shelf_->status_area_widget());
[email protected]478c6c32013-03-09 02:50:58556 return shelf_->status_area_widget()->system_tray();
[email protected]a0afeb12012-12-10 22:57:09557}
558
[email protected]940fb1c2013-06-18 16:54:28559void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
560 ui::MenuSourceType source_type) {
msw141c6b22016-03-04 00:55:30561 ShellDelegate* delegate = Shell::GetInstance()->delegate();
562 DCHECK(delegate);
[email protected]431552c2012-10-23 00:38:33563 scoped_ptr<ui::MenuModel> menu_model(
msw953caf1f2016-03-18 00:33:29564 delegate->CreateContextMenu(shelf_->shelf(), nullptr));
[email protected]7f7f65c2013-04-17 16:47:13565 if (!menu_model)
[email protected]8e837ec2013-01-31 01:48:33566 return;
[email protected]431552c2012-10-23 00:38:33567
[email protected]6175fc42013-04-05 05:58:58568 // Background controller may not be set yet if user clicked on status are
569 // before initial animation completion. See crbug.com/222218
[email protected]0bf61732013-07-02 04:35:10570 if (!wallpaper_controller_.get())
[email protected]431552c2012-10-23 00:38:33571 return;
572
[email protected]0a37a5d2014-07-15 00:42:23573 views::MenuRunner menu_runner(menu_model.get(),
574 views::MenuRunner::CONTEXT_MENU);
[email protected]0bf61732013-07-02 04:35:10575 if (menu_runner.RunMenuAt(wallpaper_controller_->widget(),
[email protected]fd6c0a62014-05-01 07:50:35576 NULL,
577 gfx::Rect(location_in_screen, gfx::Size()),
578 views::MENU_ANCHOR_TOPLEFT,
[email protected]0a37a5d2014-07-15 00:42:23579 source_type) == views::MenuRunner::MENU_DELETED) {
[email protected]6175fc42013-04-05 05:58:58580 return;
581 }
582
[email protected]431552c2012-10-23 00:38:33583 Shell::GetInstance()->UpdateShelfVisibility();
584}
585
[email protected]e74aaf0a2012-10-12 18:42:28586void RootWindowController::UpdateShelfVisibility() {
[email protected]478c6c32013-03-09 02:50:58587 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]e74aaf0a2012-10-12 18:42:28588}
589
varkhad99fa94f2015-06-29 22:35:46590aura::Window* RootWindowController::GetWindowForFullscreenMode() {
591 aura::Window* topmost_window = NULL;
592 aura::Window* active_window = wm::GetActiveWindow();
[email protected]f5c9dbc2014-04-11 08:13:45593 if (active_window && active_window->GetRootWindow() == GetRootWindow() &&
[email protected]2c5db9e2014-02-27 13:58:14594 IsSwitchableContainer(active_window->parent())) {
595 // Use the active window when it is on the current root window to determine
596 // the fullscreen state to allow temporarily using a panel or docked window
597 // (which are always above the default container) while a fullscreen
598 // window is open. We only use the active window when in a switchable
599 // container as the launcher should not exit fullscreen mode.
600 topmost_window = active_window;
601 } else {
602 // Otherwise, use the topmost window on the root window's default container
603 // when there is no active window on this root window.
604 const aura::Window::Windows& windows =
605 GetContainer(kShellWindowId_DefaultContainer)->children();
606 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin();
607 iter != windows.rend(); ++iter) {
bruthigb7056f62015-06-04 21:04:53608 if (wm::IsWindowUserPositionable(*iter) &&
[email protected]2c5db9e2014-02-27 13:58:14609 (*iter)->layer()->GetTargetVisibility()) {
610 topmost_window = *iter;
611 break;
612 }
[email protected]2c9171d22013-12-10 21:55:10613 }
614 }
615 while (topmost_window) {
616 if (wm::GetWindowState(topmost_window)->IsFullscreen())
617 return topmost_window;
[email protected]e319c7e2014-03-14 19:56:14618 topmost_window = ::wm::GetTransientParent(topmost_window);
[email protected]2ee2f5d2013-01-10 23:37:16619 }
[email protected]700849f2013-04-30 17:49:20620 return NULL;
[email protected]2ee2f5d2013-01-10 23:37:16621}
622
[email protected]b6ba05d902013-10-04 21:38:45623void RootWindowController::ActivateKeyboard(
624 keyboard::KeyboardController* keyboard_controller) {
625 if (!keyboard::IsKeyboardEnabled() ||
626 GetContainer(kShellWindowId_VirtualKeyboardContainer)) {
627 return;
628 }
629 DCHECK(keyboard_controller);
bshe9858b4a2014-09-16 20:46:38630 keyboard_controller->AddObserver(shelf()->shelf_layout_manager());
631 keyboard_controller->AddObserver(panel_layout_manager_);
632 keyboard_controller->AddObserver(docked_layout_manager_);
633 keyboard_controller->AddObserver(workspace_controller_->layout_manager());
rsadam7bd510bb2014-12-09 20:10:56634 keyboard_controller->AddObserver(
635 always_on_top_controller_->GetLayoutManager());
bshe9858b4a2014-09-16 20:46:38636 Shell::GetInstance()->delegate()->VirtualKeyboardActivated(true);
bshec3875422014-09-29 13:21:30637 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]b2da9b602014-03-05 18:39:52638 DCHECK(parent);
[email protected]b6ba05d902013-10-04 21:38:45639 aura::Window* keyboard_container =
640 keyboard_controller->GetContainerWindow();
641 keyboard_container->set_id(kShellWindowId_VirtualKeyboardContainer);
642 parent->AddChild(keyboard_container);
[email protected]b6ba05d902013-10-04 21:38:45643}
[email protected]86459e2c2013-04-10 13:39:24644
[email protected]b6ba05d902013-10-04 21:38:45645void RootWindowController::DeactivateKeyboard(
646 keyboard::KeyboardController* keyboard_controller) {
[email protected]e1b299b2014-01-29 23:53:41647 if (!keyboard_controller ||
648 !keyboard_controller->keyboard_container_initialized()) {
[email protected]b6ba05d902013-10-04 21:38:45649 return;
[email protected]e1b299b2014-01-29 23:53:41650 }
[email protected]b6ba05d902013-10-04 21:38:45651 aura::Window* keyboard_container =
652 keyboard_controller->GetContainerWindow();
[email protected]f5c9dbc2014-04-11 08:13:45653 if (keyboard_container->GetRootWindow() == GetRootWindow()) {
bshec3875422014-09-29 13:21:30654 aura::Window* parent =
655 GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]b2da9b602014-03-05 18:39:52656 DCHECK(parent);
657 parent->RemoveChild(keyboard_container);
bshe9858b4a2014-09-16 20:46:38658 // Virtual keyboard may be deactivated while still showing, notify all
659 // observers that keyboard bounds changed to 0 before remove them.
660 keyboard_controller->NotifyKeyboardBoundsChanging(gfx::Rect());
661 keyboard_controller->RemoveObserver(shelf()->shelf_layout_manager());
662 keyboard_controller->RemoveObserver(panel_layout_manager_);
663 keyboard_controller->RemoveObserver(docked_layout_manager_);
664 keyboard_controller->RemoveObserver(
665 workspace_controller_->layout_manager());
rsadam7bd510bb2014-12-09 20:10:56666 keyboard_controller->RemoveObserver(
667 always_on_top_controller_->GetLayoutManager());
bshe9858b4a2014-09-16 20:46:38668 Shell::GetInstance()->delegate()->VirtualKeyboardActivated(false);
[email protected]86459e2c2013-04-10 13:39:24669 }
670}
671
[email protected]602022b2014-03-31 17:07:31672bool RootWindowController::IsVirtualKeyboardWindow(aura::Window* window) {
bshec3875422014-09-29 13:21:30673 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]602022b2014-03-31 17:07:31674 return parent ? parent->Contains(window) : false;
675}
676
[email protected]a4cd6d32012-09-12 03:42:13677////////////////////////////////////////////////////////////////////////////////
678// RootWindowController, private:
679
[email protected]f5c9dbc2014-04-11 08:13:45680RootWindowController::RootWindowController(AshWindowTreeHost* ash_host)
681 : ash_host_(ash_host),
[email protected]a273d33a2013-10-17 12:41:21682 root_window_layout_(NULL),
683 docked_layout_manager_(NULL),
684 panel_layout_manager_(NULL),
685 touch_hud_debug_(NULL),
686 touch_hud_projection_(NULL) {
[email protected]f5c9dbc2014-04-11 08:13:45687 aura::Window* root_window = GetRootWindow();
688 GetRootWindowSettings(root_window)->controller = this;
[email protected]a273d33a2013-10-17 12:41:21689
690 stacking_controller_.reset(new StackingController);
[email protected]f5c9dbc2014-04-11 08:13:45691 aura::client::SetWindowTreeClient(root_window, stacking_controller_.get());
692 capture_client_.reset(new ::wm::ScopedCaptureClient(root_window));
[email protected]a273d33a2013-10-17 12:41:21693}
694
[email protected]608de6c2013-10-29 00:14:28695void RootWindowController::Init(RootWindowType root_window_type,
696 bool first_run_after_boot) {
[email protected]f5c9dbc2014-04-11 08:13:45697 aura::Window* root_window = GetRootWindow();
[email protected]51f438112013-11-18 19:32:50698 Shell* shell = Shell::GetInstance();
[email protected]f5c9dbc2014-04-11 08:13:45699 shell->InitRootWindow(root_window);
[email protected]a273d33a2013-10-17 12:41:21700
[email protected]f5c9dbc2014-04-11 08:13:45701 CreateContainersInRootWindow(root_window);
[email protected]608de6c2013-10-29 00:14:28702
[email protected]a273d33a2013-10-17 12:41:21703 CreateSystemBackground(first_run_after_boot);
704
705 InitLayoutManagers();
706 InitTouchHuds();
707
708 if (Shell::GetPrimaryRootWindowController()->
709 GetSystemModalLayoutManager(NULL)->has_modal_background()) {
710 GetSystemModalLayoutManager(NULL)->CreateModalBackground();
711 }
712
[email protected]a273d33a2013-10-17 12:41:21713 shell->AddShellObserver(this);
714
[email protected]608de6c2013-10-29 00:14:28715 if (root_window_type == PRIMARY) {
[email protected]a3565792013-10-18 12:52:37716 root_window_layout()->OnWindowResized();
bshe9858b4a2014-09-16 20:46:38717 shell->InitKeyboard();
[email protected]a273d33a2013-10-17 12:41:21718 } else {
719 root_window_layout()->OnWindowResized();
[email protected]f5c9dbc2014-04-11 08:13:45720 ash_host_->AsWindowTreeHost()->Show();
[email protected]a273d33a2013-10-17 12:41:21721
[email protected]864b58552013-12-19 04:19:38722 // Create a shelf if a user is already logged in.
[email protected]a273d33a2013-10-17 12:41:21723 if (shell->session_state_delegate()->NumberOfLoggedInUsers())
[email protected]864b58552013-12-19 04:19:38724 shelf()->CreateShelf();
[email protected]0e3e7cb2014-04-12 05:18:25725
726 // Notify shell observers about new root window.
727 shell->OnRootWindowAdded(root_window);
[email protected]a273d33a2013-10-17 12:41:21728 }
[email protected]a825e8312014-05-05 22:05:01729
730#if defined(OS_CHROMEOS)
pgal.u-szegedd84534d32014-10-29 12:34:30731 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]2e0b2352014-07-28 13:28:28732 switches::kAshDisableTouchExplorationMode)) {
[email protected]7d487592014-07-24 03:54:50733 touch_exploration_manager_.reset(new AshTouchExplorationManager(this));
[email protected]a825e8312014-05-05 22:05:01734 }
735#endif
[email protected]a273d33a2013-10-17 12:41:21736}
737
[email protected]756bda12013-07-03 08:17:06738void RootWindowController::InitLayoutManagers() {
[email protected]f5c9dbc2014-04-11 08:13:45739 aura::Window* root_window = GetRootWindow();
740 root_window_layout_ = new RootWindowLayoutManager(root_window);
741 root_window->SetLayoutManager(root_window_layout_);
[email protected]756bda12013-07-03 08:17:06742
743 aura::Window* default_container =
744 GetContainer(kShellWindowId_DefaultContainer);
745 // Workspace manager has its own layout managers.
746 workspace_controller_.reset(
747 new WorkspaceController(default_container));
748
749 aura::Window* always_on_top_container =
750 GetContainer(kShellWindowId_AlwaysOnTopContainer);
rsadam7bd510bb2014-12-09 20:10:56751 always_on_top_controller_.reset(
752 new AlwaysOnTopController(always_on_top_container));
[email protected]756bda12013-07-03 08:17:06753
754 DCHECK(!shelf_.get());
[email protected]093b8d642014-04-03 20:59:28755 aura::Window* shelf_container = GetContainer(kShellWindowId_ShelfContainer);
[email protected]756bda12013-07-03 08:17:06756 // TODO(harrym): Remove when status area is view.
[email protected]093b8d642014-04-03 20:59:28757 aura::Window* status_container = GetContainer(kShellWindowId_StatusContainer);
[email protected]756bda12013-07-03 08:17:06758 shelf_.reset(new ShelfWidget(
759 shelf_container, status_container, workspace_controller()));
760
[email protected]cf6fea22013-08-07 14:24:01761 if (!Shell::GetInstance()->session_state_delegate()->
762 IsActiveUserSessionStarted()) {
763 // This window exists only to be a event target on login screen.
764 // It does not have to handle events, nor be visible.
765 mouse_event_target_.reset(new aura::Window(new EmptyWindowDelegate));
danakjb161836d2015-04-03 05:14:18766 mouse_event_target_->Init(ui::LAYER_NOT_DRAWN);
[email protected]cf6fea22013-08-07 14:24:01767
768 aura::Window* lock_background_container =
[email protected]093b8d642014-04-03 20:59:28769 GetContainer(kShellWindowId_LockScreenBackgroundContainer);
[email protected]cf6fea22013-08-07 14:24:01770 lock_background_container->AddChild(mouse_event_target_.get());
771 mouse_event_target_->Show();
772 }
773
[email protected]756bda12013-07-03 08:17:06774 // Create Docked windows layout manager
[email protected]093b8d642014-04-03 20:59:28775 aura::Window* docked_container = GetContainer(kShellWindowId_DockedContainer);
[email protected]756bda12013-07-03 08:17:06776 docked_layout_manager_ =
[email protected]093b8d642014-04-03 20:59:28777 new DockedWindowLayoutManager(docked_container, workspace_controller());
[email protected]756bda12013-07-03 08:17:06778 docked_container->SetLayoutManager(docked_layout_manager_);
779
[email protected]1ca79d42014-07-18 16:26:10780 // Installs SnapLayoutManager to containers who set the
781 // |kSnapsChildrenToPhysicalPixelBoundary| property.
782 wm::InstallSnapLayoutManagerToContainers(root_window);
783
[email protected]756bda12013-07-03 08:17:06784 // Create Panel layout manager
[email protected]093b8d642014-04-03 20:59:28785 aura::Window* panel_container = GetContainer(kShellWindowId_PanelContainer);
786 panel_layout_manager_ = new PanelLayoutManager(panel_container);
[email protected]756bda12013-07-03 08:17:06787 panel_container->SetLayoutManager(panel_layout_manager_);
[email protected]3537d472014-01-15 05:45:31788 panel_container_handler_.reset(new PanelWindowEventHandler);
789 panel_container->AddPreTargetHandler(panel_container_handler_.get());
[email protected]b8642ec2014-04-17 05:20:39790
791 // Install an AttachedPanelWindowTargeter on the panel container to make it
792 // easier to correctly target shelf buttons with touch.
793 gfx::Insets mouse_extend(-kResizeOutsideBoundsSize,
794 -kResizeOutsideBoundsSize,
795 -kResizeOutsideBoundsSize,
796 -kResizeOutsideBoundsSize);
797 gfx::Insets touch_extend = mouse_extend.Scale(
798 kResizeOutsideBoundsScaleForTouch);
799 panel_container->SetEventTargeter(scoped_ptr<ui::EventTargeter>(
800 new AttachedPanelWindowTargeter(panel_container,
801 mouse_extend,
802 touch_extend,
803 panel_layout_manager_)));
[email protected]756bda12013-07-03 08:17:06804}
805
806void RootWindowController::InitTouchHuds() {
pgal.u-szegedd84534d32014-10-29 12:34:30807 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
[email protected]756bda12013-07-03 08:17:06808 if (command_line->HasSwitch(switches::kAshTouchHud))
[email protected]f5c9dbc2014-04-11 08:13:45809 set_touch_hud_debug(new TouchHudDebug(GetRootWindow()));
[email protected]756bda12013-07-03 08:17:06810 if (Shell::GetInstance()->is_touch_hud_projection_enabled())
811 EnableTouchHudProjection();
812}
813
814void RootWindowController::CreateSystemBackground(
815 bool is_first_run_after_boot) {
816 SkColor color = SK_ColorBLACK;
817#if defined(OS_CHROMEOS)
818 if (is_first_run_after_boot)
819 color = kChromeOsBootColor;
820#endif
821 system_background_.reset(
[email protected]f5c9dbc2014-04-11 08:13:45822 new SystemBackgroundController(GetRootWindow(), color));
[email protected]756bda12013-07-03 08:17:06823
824#if defined(OS_CHROMEOS)
825 // Make a copy of the system's boot splash screen so we can composite it
826 // onscreen until the desktop background is ready.
827 if (is_first_run_after_boot &&
pgal.u-szegedd84534d32014-10-29 12:34:30828 (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]756bda12013-07-03 08:17:06829 switches::kAshCopyHostBackgroundAtBoot) ||
pgal.u-szegedd84534d32014-10-29 12:34:30830 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]756bda12013-07-03 08:17:06831 switches::kAshAnimateFromBootSplashScreen)))
[email protected]f5c9dbc2014-04-11 08:13:45832 boot_splash_screen_.reset(new BootSplashScreen(GetHost()));
[email protected]756bda12013-07-03 08:17:06833#endif
834}
835
[email protected]a4cd6d32012-09-12 03:42:13836void RootWindowController::CreateContainersInRootWindow(
[email protected]41baaed2013-11-09 04:18:26837 aura::Window* root_window) {
[email protected]a4cd6d32012-09-12 03:42:13838 // These containers are just used by PowerButtonController to animate groups
839 // of containers simultaneously without messing up the current transformations
840 // on those containers. These are direct children of the root window; all of
841 // the other containers are their children.
[email protected]e6e41d2f2012-10-29 19:22:19842
843 // The desktop background container is not part of the lock animation, so it
844 // is not included in those animate groups.
[email protected]a4cd6d32012-09-12 03:42:13845 // When screen is locked desktop background is moved to lock screen background
846 // container (moved back on unlock). We want to make sure that there's an
847 // opaque layer occluding the non-lock-screen layers.
[email protected]e6e41d2f2012-10-29 19:22:19848 aura::Window* desktop_background_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27849 kShellWindowId_DesktopBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13850 "DesktopBackgroundContainer",
851 root_window);
[email protected]e319c7e2014-03-14 19:56:14852 ::wm::SetChildWindowVisibilityChangesAnimated(desktop_background_container);
[email protected]a4cd6d32012-09-12 03:42:13853
854 aura::Window* non_lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27855 kShellWindowId_NonLockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13856 "NonLockScreenContainersContainer",
857 root_window);
oshimaf52e1be2015-05-06 21:29:34858 // Clip all windows inside this container, as half pixel of the window's
859 // texture may become visible when the screen is scaled. crbug.com/368591.
860 non_lock_screen_containers->layer()->SetMasksToBounds(true);
[email protected]a4cd6d32012-09-12 03:42:13861
862 aura::Window* lock_background_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27863 kShellWindowId_LockScreenBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13864 "LockScreenBackgroundContainer",
865 root_window);
[email protected]e319c7e2014-03-14 19:56:14866 ::wm::SetChildWindowVisibilityChangesAnimated(lock_background_containers);
[email protected]a4cd6d32012-09-12 03:42:13867
868 aura::Window* lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27869 kShellWindowId_LockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13870 "LockScreenContainersContainer",
871 root_window);
872 aura::Window* lock_screen_related_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27873 kShellWindowId_LockScreenRelatedContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13874 "LockScreenRelatedContainersContainer",
875 root_window);
876
[email protected]c0ce80e2012-10-05 23:28:27877 CreateContainer(kShellWindowId_UnparentedControlContainer,
[email protected]a4cd6d32012-09-12 03:42:13878 "UnparentedControlContainer",
879 non_lock_screen_containers);
880
881 aura::Window* default_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27882 kShellWindowId_DefaultContainer,
[email protected]a4cd6d32012-09-12 03:42:13883 "DefaultContainer",
884 non_lock_screen_containers);
[email protected]e319c7e2014-03-14 19:56:14885 ::wm::SetChildWindowVisibilityChangesAnimated(default_container);
[email protected]1ca79d42014-07-18 16:26:10886 wm::SetSnapsChildrenToPhysicalPixelBoundary(default_container);
[email protected]a4cd6d32012-09-12 03:42:13887 SetUsesScreenCoordinates(default_container);
[email protected]c5be8d672014-01-07 13:33:41888 SetUsesEasyResizeTargeter(default_container);
[email protected]a4cd6d32012-09-12 03:42:13889
890 aura::Window* always_on_top_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27891 kShellWindowId_AlwaysOnTopContainer,
[email protected]a4cd6d32012-09-12 03:42:13892 "AlwaysOnTopContainer",
893 non_lock_screen_containers);
[email protected]e319c7e2014-03-14 19:56:14894 ::wm::SetChildWindowVisibilityChangesAnimated(always_on_top_container);
[email protected]1ca79d42014-07-18 16:26:10895 wm::SetSnapsChildrenToPhysicalPixelBoundary(always_on_top_container);
[email protected]a4cd6d32012-09-12 03:42:13896 SetUsesScreenCoordinates(always_on_top_container);
897
[email protected]beb4e5c2013-06-18 15:37:07898 aura::Window* docked_container = CreateContainer(
899 kShellWindowId_DockedContainer,
900 "DockedContainer",
901 non_lock_screen_containers);
[email protected]e319c7e2014-03-14 19:56:14902 ::wm::SetChildWindowVisibilityChangesAnimated(docked_container);
[email protected]1ca79d42014-07-18 16:26:10903 wm::SetSnapsChildrenToPhysicalPixelBoundary(docked_container);
[email protected]beb4e5c2013-06-18 15:37:07904 SetUsesScreenCoordinates(docked_container);
[email protected]1ff0c492014-01-21 20:20:44905 SetUsesEasyResizeTargeter(docked_container);
[email protected]beb4e5c2013-06-18 15:37:07906
[email protected]3f13cf12013-07-12 05:13:59907 aura::Window* shelf_container =
[email protected]478c6c32013-03-09 02:50:58908 CreateContainer(kShellWindowId_ShelfContainer,
[email protected]3f13cf12013-07-12 05:13:59909 "ShelfContainer",
[email protected]a4cd6d32012-09-12 03:42:13910 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10911 wm::SetSnapsChildrenToPhysicalPixelBoundary(shelf_container);
[email protected]3f13cf12013-07-12 05:13:59912 SetUsesScreenCoordinates(shelf_container);
913 DescendantShouldStayInSameRootWindow(shelf_container);
[email protected]a4cd6d32012-09-12 03:42:13914
[email protected]f2026eb2013-10-22 14:28:56915 aura::Window* panel_container = CreateContainer(
916 kShellWindowId_PanelContainer,
917 "PanelContainer",
918 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10919 wm::SetSnapsChildrenToPhysicalPixelBoundary(panel_container);
[email protected]f2026eb2013-10-22 14:28:56920 SetUsesScreenCoordinates(panel_container);
921
922 aura::Window* shelf_bubble_container =
923 CreateContainer(kShellWindowId_ShelfBubbleContainer,
924 "ShelfBubbleContainer",
925 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10926 wm::SetSnapsChildrenToPhysicalPixelBoundary(shelf_bubble_container);
[email protected]f2026eb2013-10-22 14:28:56927 SetUsesScreenCoordinates(shelf_bubble_container);
928 DescendantShouldStayInSameRootWindow(shelf_bubble_container);
929
[email protected]dc851a4e52012-10-03 00:05:55930 aura::Window* app_list_container =
[email protected]c0ce80e2012-10-05 23:28:27931 CreateContainer(kShellWindowId_AppListContainer,
[email protected]dc851a4e52012-10-03 00:05:55932 "AppListContainer",
933 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10934 wm::SetSnapsChildrenToPhysicalPixelBoundary(app_list_container);
[email protected]dc851a4e52012-10-03 00:05:55935 SetUsesScreenCoordinates(app_list_container);
[email protected]a4cd6d32012-09-12 03:42:13936
937 aura::Window* modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27938 kShellWindowId_SystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13939 "SystemModalContainer",
940 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10941 wm::SetSnapsChildrenToPhysicalPixelBoundary(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13942 modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27943 new SystemModalContainerLayoutManager(modal_container));
[email protected]e319c7e2014-03-14 19:56:14944 ::wm::SetChildWindowVisibilityChangesAnimated(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13945 SetUsesScreenCoordinates(modal_container);
[email protected]c5be8d672014-01-07 13:33:41946 SetUsesEasyResizeTargeter(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13947
[email protected]a4cd6d32012-09-12 03:42:13948 // TODO(beng): Figure out if we can make this use
949 // SystemModalContainerEventFilter instead of stops_event_propagation.
950 aura::Window* lock_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27951 kShellWindowId_LockScreenContainer,
[email protected]a4cd6d32012-09-12 03:42:13952 "LockScreenContainer",
953 lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10954 wm::SetSnapsChildrenToPhysicalPixelBoundary(lock_container);
oshima96f6a502015-05-02 08:43:32955 lock_container->SetLayoutManager(new LockLayoutManager(lock_container));
[email protected]a4cd6d32012-09-12 03:42:13956 SetUsesScreenCoordinates(lock_container);
957 // TODO(beng): stopsevents
958
959 aura::Window* lock_modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27960 kShellWindowId_LockSystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13961 "LockSystemModalContainer",
962 lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10963 wm::SetSnapsChildrenToPhysicalPixelBoundary(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13964 lock_modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27965 new SystemModalContainerLayoutManager(lock_modal_container));
[email protected]e319c7e2014-03-14 19:56:14966 ::wm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13967 SetUsesScreenCoordinates(lock_modal_container);
[email protected]c5be8d672014-01-07 13:33:41968 SetUsesEasyResizeTargeter(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13969
970 aura::Window* status_container =
[email protected]c0ce80e2012-10-05 23:28:27971 CreateContainer(kShellWindowId_StatusContainer,
[email protected]a4cd6d32012-09-12 03:42:13972 "StatusContainer",
973 lock_screen_related_containers);
[email protected]1ca79d42014-07-18 16:26:10974 wm::SetSnapsChildrenToPhysicalPixelBoundary(status_container);
[email protected]a4cd6d32012-09-12 03:42:13975 SetUsesScreenCoordinates(status_container);
[email protected]e887c6c2013-07-08 19:35:53976 DescendantShouldStayInSameRootWindow(status_container);
[email protected]a4cd6d32012-09-12 03:42:13977
978 aura::Window* settings_bubble_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27979 kShellWindowId_SettingBubbleContainer,
[email protected]a4cd6d32012-09-12 03:42:13980 "SettingBubbleContainer",
981 lock_screen_related_containers);
[email protected]e319c7e2014-03-14 19:56:14982 ::wm::SetChildWindowVisibilityChangesAnimated(settings_bubble_container);
[email protected]1ca79d42014-07-18 16:26:10983 wm::SetSnapsChildrenToPhysicalPixelBoundary(settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13984 SetUsesScreenCoordinates(settings_bubble_container);
[email protected]e887c6c2013-07-08 19:35:53985 DescendantShouldStayInSameRootWindow(settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13986
kevers23f3987d2014-09-17 13:50:12987 aura::Window* virtual_keyboard_parent_container =
bshec3875422014-09-29 13:21:30988 CreateContainer(kShellWindowId_ImeWindowParentContainer,
kevers23f3987d2014-09-17 13:50:12989 "VirtualKeyboardParentContainer",
990 lock_screen_related_containers);
991 wm::SetSnapsChildrenToPhysicalPixelBoundary(
992 virtual_keyboard_parent_container);
993 SetUsesScreenCoordinates(virtual_keyboard_parent_container);
994
[email protected]a4cd6d32012-09-12 03:42:13995 aura::Window* menu_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27996 kShellWindowId_MenuContainer,
[email protected]a4cd6d32012-09-12 03:42:13997 "MenuContainer",
998 lock_screen_related_containers);
[email protected]e319c7e2014-03-14 19:56:14999 ::wm::SetChildWindowVisibilityChangesAnimated(menu_container);
[email protected]1ca79d42014-07-18 16:26:101000 wm::SetSnapsChildrenToPhysicalPixelBoundary(menu_container);
[email protected]a4cd6d32012-09-12 03:42:131001 SetUsesScreenCoordinates(menu_container);
1002
1003 aura::Window* drag_drop_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:271004 kShellWindowId_DragImageAndTooltipContainer,
[email protected]a4cd6d32012-09-12 03:42:131005 "DragImageAndTooltipContainer",
1006 lock_screen_related_containers);
[email protected]e319c7e2014-03-14 19:56:141007 ::wm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
[email protected]1ca79d42014-07-18 16:26:101008 wm::SetSnapsChildrenToPhysicalPixelBoundary(drag_drop_container);
[email protected]a4cd6d32012-09-12 03:42:131009 SetUsesScreenCoordinates(drag_drop_container);
1010
1011 aura::Window* overlay_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:271012 kShellWindowId_OverlayContainer,
[email protected]a4cd6d32012-09-12 03:42:131013 "OverlayContainer",
1014 lock_screen_related_containers);
[email protected]1ca79d42014-07-18 16:26:101015 wm::SetSnapsChildrenToPhysicalPixelBoundary(overlay_container);
[email protected]a4cd6d32012-09-12 03:42:131016 SetUsesScreenCoordinates(overlay_container);
[email protected]a07615f2012-10-24 08:23:081017
[email protected]b2da9b602014-03-05 18:39:521018#if defined(OS_CHROMEOS)
1019 aura::Window* mouse_cursor_container = CreateContainer(
1020 kShellWindowId_MouseCursorContainer,
1021 "MouseCursorContainer",
1022 root_window);
1023 SetUsesScreenCoordinates(mouse_cursor_container);
1024#endif
1025
[email protected]a07615f2012-10-24 08:23:081026 CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
[email protected]b2da9b602014-03-05 18:39:521027 "PowerButtonAnimationContainer", root_window);
[email protected]a4cd6d32012-09-12 03:42:131028}
1029
[email protected]d141b922013-07-09 08:13:171030void RootWindowController::EnableTouchHudProjection() {
1031 if (touch_hud_projection_)
1032 return;
[email protected]f5c9dbc2014-04-11 08:13:451033 set_touch_hud_projection(new TouchHudProjection(GetRootWindow()));
[email protected]d141b922013-07-09 08:13:171034}
1035
1036void RootWindowController::DisableTouchHudProjection() {
1037 if (!touch_hud_projection_)
1038 return;
1039 touch_hud_projection_->Remove();
1040}
1041
1042void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
1043 shelf_->shelf_layout_manager()->UpdateVisibilityState();
1044}
1045
1046void RootWindowController::OnTouchHudProjectionToggled(bool enabled) {
1047 if (enabled)
1048 EnableTouchHudProjection();
1049 else
1050 DisableTouchHudProjection();
1051}
1052
[email protected]6b2d4a0b2013-09-06 06:29:541053RootWindowController* GetRootWindowController(
[email protected]bf9cdb362013-10-25 19:22:451054 const aura::Window* root_window) {
[email protected]6b2d4a0b2013-09-06 06:29:541055 return root_window ? GetRootWindowSettings(root_window)->controller : NULL;
1056}
1057
[email protected]d90b8392012-06-13 09:34:561058} // namespace ash