blob: 3a5733ed3984ef2d98532e3db4ca8cc84fb20e8b [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"
42#include "ash/wm/screen_dimmer.h"
[email protected]2a2caa02013-01-22 20:50:3643#include "ash/wm/stacking_controller.h"
[email protected]e74aaf0a2012-10-12 18:42:2844#include "ash/wm/status_area_layout_manager.h"
[email protected]e6e41d2f2012-10-29 19:22:1945#include "ash/wm/system_background_controller.h"
[email protected]d90b8392012-06-13 09:34:5646#include "ash/wm/system_modal_container_layout_manager.h"
[email protected]8d625fb2012-07-18 16:40:0647#include "ash/wm/window_properties.h"
[email protected]a41b4e12013-09-20 04:36:3448#include "ash/wm/window_state.h"
[email protected]700849f2013-04-30 17:49:2049#include "ash/wm/window_util.h"
[email protected]1af71f72014-01-29 20:00:5550#include "ash/wm/workspace/workspace_layout_manager.h"
[email protected]d90b8392012-06-13 09:34:5651#include "ash/wm/workspace_controller.h"
[email protected]e6e41d2f2012-10-29 19:22:1952#include "base/command_line.h"
[email protected]1e84c632013-06-27 23:12:2153#include "base/time/time.h"
[email protected]f1853122012-06-27 16:21:2654#include "ui/aura/client/aura_constants.h"
[email protected]2374d1812014-03-04 03:42:2755#include "ui/aura/client/screen_position_client.h"
[email protected]f1853122012-06-27 16:21:2656#include "ui/aura/window.h"
[email protected]cf6fea22013-08-07 14:24:0157#include "ui/aura/window_delegate.h"
[email protected]fcc51c952014-02-21 21:31:2658#include "ui/aura/window_event_dispatcher.h"
[email protected]f1853122012-06-27 16:21:2659#include "ui/aura/window_observer.h"
[email protected]8b3e3d82013-08-20 14:36:3060#include "ui/aura/window_tracker.h"
[email protected]cf6fea22013-08-07 14:24:0161#include "ui/base/hit_test.h"
[email protected]431552c2012-10-23 00:38:3362#include "ui/base/models/menu_model.h"
[email protected]f8e6aad2013-08-30 21:49:1163#include "ui/gfx/display.h"
[email protected]8d625fb2012-07-18 16:40:0664#include "ui/gfx/screen.h"
[email protected]86459e2c2013-04-10 13:39:2465#include "ui/keyboard/keyboard_controller.h"
66#include "ui/keyboard/keyboard_util.h"
[email protected]431552c2012-10-23 00:38:3367#include "ui/views/controls/menu/menu_runner.h"
68#include "ui/views/view_model.h"
69#include "ui/views/view_model_utils.h"
[email protected]ee3ed10772014-03-11 22:02:0170#include "ui/wm/core/capture_controller.h"
[email protected]e319c7e2014-03-14 19:56:1471#include "ui/wm/core/easy_resize_window_targeter.h"
[email protected]ee3ed10772014-03-11 22:02:0172#include "ui/wm/core/visibility_controller.h"
73#include "ui/wm/core/window_util.h"
[email protected]af4552b22014-03-21 19:45:0174#include "ui/wm/public/drag_drop_client.h"
75#include "ui/wm/public/tooltip_client.h"
[email protected]5b251f12013-12-19 01:50:0576#include "ui/wm/public/window_types.h"
[email protected]d90b8392012-06-13 09:34:5677
[email protected]252eb232013-08-14 22:09:2778#if defined(OS_CHROMEOS)
[email protected]7d487592014-07-24 03:54:5079#include "ash/ash_touch_exploration_manager_chromeos.h"
[email protected]252eb232013-08-14 22:09:2780#include "ash/wm/boot_splash_screen_chromeos.h"
[email protected]a825e8312014-05-05 22:05:0181#include "ui/chromeos/touch_exploration_controller.h"
[email protected]252eb232013-08-14 22:09:2782#endif
83
[email protected]d90b8392012-06-13 09:34:5684namespace ash {
85namespace {
86
[email protected]252eb232013-08-14 22:09:2787#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:4988// Duration for the animation that hides the boot splash screen, in
89// milliseconds. This should be short enough in relation to
90// wm/window_animation.cc's brightness/grayscale fade animation that the login
91// background image animation isn't hidden by the splash screen animation.
92const int kBootSplashScreenHideDurationMs = 500;
[email protected]252eb232013-08-14 22:09:2793#endif
[email protected]bca9a7e2012-11-10 06:25:4994
[email protected]d90b8392012-06-13 09:34:5695// Creates a new window for use as a container.
96aura::Window* CreateContainer(int window_id,
97 const char* name,
98 aura::Window* parent) {
99 aura::Window* container = new aura::Window(NULL);
100 container->set_id(window_id);
101 container->SetName(name);
danakjb161836d2015-04-03 05:14:18102 container->Init(ui::LAYER_NOT_DRAWN);
[email protected]d90b8392012-06-13 09:34:56103 parent->AddChild(container);
[email protected]093b8d642014-04-03 20:59:28104 if (window_id != kShellWindowId_UnparentedControlContainer)
[email protected]d90b8392012-06-13 09:34:56105 container->Show();
106 return container;
107}
108
[email protected]2816c2462013-12-17 02:22:25109float ToRelativeValue(int value, int src, int dst) {
110 return static_cast<float>(value) / static_cast<float>(src) * dst;
111}
112
113void MoveOriginRelativeToSize(const gfx::Size& src_size,
114 const gfx::Size& dst_size,
115 gfx::Rect* bounds_in_out) {
116 gfx::Point origin = bounds_in_out->origin();
117 bounds_in_out->set_origin(gfx::Point(
118 ToRelativeValue(origin.x(), src_size.width(), dst_size.width()),
119 ToRelativeValue(origin.y(), src_size.height(), dst_size.height())));
120}
121
[email protected]95058572012-08-20 14:57:29122// Reparents |window| to |new_parent|.
123void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
[email protected]2816c2462013-12-17 02:22:25124 const gfx::Size src_size = window->parent()->bounds().size();
125 const gfx::Size dst_size = new_parent->bounds().size();
[email protected]95058572012-08-20 14:57:29126 // Update the restore bounds to make it relative to the display.
[email protected]a41b4e12013-09-20 04:36:34127 wm::WindowState* state = wm::GetWindowState(window);
128 gfx::Rect restore_bounds;
129 bool has_restore_bounds = state->HasRestoreBounds();
[email protected]2816c2462013-12-17 02:22:25130
[email protected]9cfd3d12014-02-25 15:33:45131 bool update_bounds = (state->IsNormalOrSnapped() || state->IsMinimized()) &&
[email protected]093b8d642014-04-03 20:59:28132 new_parent->id() != kShellWindowId_DockedContainer;
[email protected]2816c2462013-12-17 02:22:25133 gfx::Rect local_bounds;
134 if (update_bounds) {
135 local_bounds = state->window()->bounds();
136 MoveOriginRelativeToSize(src_size, dst_size, &local_bounds);
137 }
138
139 if (has_restore_bounds) {
[email protected]a41b4e12013-09-20 04:36:34140 restore_bounds = state->GetRestoreBoundsInParent();
[email protected]2816c2462013-12-17 02:22:25141 MoveOriginRelativeToSize(src_size, dst_size, &restore_bounds);
142 }
143
[email protected]95058572012-08-20 14:57:29144 new_parent->AddChild(window);
[email protected]2816c2462013-12-17 02:22:25145
[email protected]8663b7a62014-01-18 01:24:21146 // Docked windows have bounds handled by the layout manager in AddChild().
[email protected]2816c2462013-12-17 02:22:25147 if (update_bounds)
148 window->SetBounds(local_bounds);
149
[email protected]a41b4e12013-09-20 04:36:34150 if (has_restore_bounds)
151 state->SetRestoreBoundsInParent(restore_bounds);
[email protected]95058572012-08-20 14:57:29152}
153
154// Reparents the appropriate set of windows from |src| to |dst|.
[email protected]bf9cdb362013-10-25 19:22:45155void ReparentAllWindows(aura::Window* src, aura::Window* dst) {
[email protected]95058572012-08-20 14:57:29156 // Set of windows to move.
[email protected]f1853122012-06-27 16:21:26157 const int kContainerIdsToMove[] = {
[email protected]093b8d642014-04-03 20:59:28158 kShellWindowId_DefaultContainer,
159 kShellWindowId_DockedContainer,
160 kShellWindowId_PanelContainer,
161 kShellWindowId_AlwaysOnTopContainer,
162 kShellWindowId_SystemModalContainer,
163 kShellWindowId_LockSystemModalContainer,
tengsf98986c2014-12-06 01:42:21164 kShellWindowId_UnparentedControlContainer,
oshima022a9542015-05-01 00:15:02165 kShellWindowId_OverlayContainer,
166 };
167 const int kExtraContainerIdsToMoveInUnifiedMode[] = {
168 kShellWindowId_LockScreenContainer,
169 kShellWindowId_LockScreenBackgroundContainer,
170 };
171 std::vector<int> container_ids(
172 kContainerIdsToMove,
173 kContainerIdsToMove + arraysize(kContainerIdsToMove));
174 // Check the default_multi_display_mode because this is also necessary
175 // in trasition between mirror <-> unified mode.
176 if (Shell::GetInstance()->display_manager()->default_multi_display_mode() ==
177 DisplayManager::UNIFIED) {
178 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 {}
yukishiino907eabf2015-01-28 04:31:12238 ui::TextInputClient* GetFocusedTextInputClient() override { return nullptr; }
dcheng1f4538e2014-10-27 23:57:05239 gfx::NativeCursor GetCursor(const gfx::Point& point) override {
[email protected]62c9f102014-03-27 06:07:04240 return gfx::kNullCursor;
241 }
dcheng1f4538e2014-10-27 23:57:05242 int GetNonClientComponent(const gfx::Point& point) const override {
[email protected]cf6fea22013-08-07 14:24:01243 return HTNOWHERE;
244 }
dcheng1f4538e2014-10-27 23:57:05245 bool ShouldDescendIntoChildForEventHandling(
[email protected]cf6fea22013-08-07 14:24:01246 aura::Window* child,
mostynb10d6b382014-10-03 16:23:45247 const gfx::Point& location) override {
[email protected]cf6fea22013-08-07 14:24:01248 return false;
249 }
dcheng1f4538e2014-10-27 23:57:05250 bool CanFocus() override { return false; }
251 void OnCaptureLost() override {}
danakj85d970e2015-04-04 00:15:24252 void OnPaint(const ui::PaintContext& context) override {}
dcheng1f4538e2014-10-27 23:57:05253 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
254 void OnWindowDestroying(aura::Window* window) override {}
255 void OnWindowDestroyed(aura::Window* window) override { delete this; }
256 void OnWindowTargetVisibilityChanged(bool visible) override {}
257 bool HasHitTestMask() const override { return false; }
258 void GetHitTestMask(gfx::Path* mask) const override {}
[email protected]cf6fea22013-08-07 14:24:01259
260 private:
261 DISALLOW_COPY_AND_ASSIGN(EmptyWindowDelegate);
262};
263
[email protected]d90b8392012-06-13 09:34:56264} // namespace
265
[email protected]f5c9dbc2014-04-11 08:13:45266void RootWindowController::CreateForPrimaryDisplay(AshWindowTreeHost* host) {
[email protected]2f2620332014-02-28 10:07:38267 RootWindowController* controller = new RootWindowController(host);
[email protected]608de6c2013-10-29 00:14:28268 controller->Init(RootWindowController::PRIMARY,
[email protected]a273d33a2013-10-17 12:41:21269 Shell::GetInstance()->delegate()->IsFirstRunAfterBoot());
[email protected]d90b8392012-06-13 09:34:56270}
271
[email protected]f5c9dbc2014-04-11 08:13:45272void RootWindowController::CreateForSecondaryDisplay(AshWindowTreeHost* host) {
[email protected]2f2620332014-02-28 10:07:38273 RootWindowController* controller = new RootWindowController(host);
[email protected]608de6c2013-10-29 00:14:28274 controller->Init(RootWindowController::SECONDARY, false /* first run */);
275}
276
[email protected]88d71122012-10-18 07:11:01277// static
[email protected]76bc4632014-06-16 19:07:46278RootWindowController* RootWindowController::ForShelf(
279 const aura::Window* window) {
oshima9eea82da2014-09-13 01:11:07280 CHECK(Shell::HasInstance());
[email protected]8c0ec432013-05-10 04:33:39281 return GetRootWindowController(window->GetRootWindow());
[email protected]88d71122012-10-18 07:11:01282}
283
[email protected]a0afeb12012-12-10 22:57:09284// static
[email protected]ccff3d72013-02-06 04:26:28285RootWindowController* RootWindowController::ForWindow(
286 const aura::Window* window) {
oshima9eea82da2014-09-13 01:11:07287 CHECK(Shell::HasInstance());
[email protected]a0afeb12012-12-10 22:57:09288 return GetRootWindowController(window->GetRootWindow());
289}
290
291// static
[email protected]d17642d2013-09-12 23:44:38292RootWindowController* RootWindowController::ForTargetRootWindow() {
oshima9eea82da2014-09-13 01:11:07293 CHECK(Shell::HasInstance());
[email protected]093b8d642014-04-03 20:59:28294 return GetRootWindowController(Shell::GetTargetRootWindow());
[email protected]a0afeb12012-12-10 22:57:09295}
296
[email protected]a5c78802013-12-12 22:07:01297// static
298aura::Window* RootWindowController::GetContainerForWindow(
299 aura::Window* window) {
300 aura::Window* container = window->parent();
[email protected]5b251f12013-12-19 01:50:05301 while (container && container->type() != ui::wm::WINDOW_TYPE_UNKNOWN)
[email protected]a5c78802013-12-12 22:07:01302 container = container->parent();
303 return container;
304}
305
[email protected]a273d33a2013-10-17 12:41:21306RootWindowController::~RootWindowController() {
307 Shutdown();
[email protected]f5c9dbc2014-04-11 08:13:45308 ash_host_.reset();
[email protected]a273d33a2013-10-17 12:41:21309 // The CaptureClient needs to be around for as long as the RootWindow is
310 // valid.
311 capture_client_.reset();
312}
313
[email protected]f5c9dbc2014-04-11 08:13:45314aura::WindowTreeHost* RootWindowController::GetHost() {
315 return ash_host_->AsWindowTreeHost();
316}
317
318const aura::WindowTreeHost* RootWindowController::GetHost() const {
319 return ash_host_->AsWindowTreeHost();
320}
321
322aura::Window* RootWindowController::GetRootWindow() {
323 return GetHost()->window();
324}
325
326const aura::Window* RootWindowController::GetRootWindow() const {
327 return GetHost()->window();
328}
329
[email protected]0bf61732013-07-02 04:35:10330void RootWindowController::SetWallpaperController(
331 DesktopBackgroundWidgetController* controller) {
332 wallpaper_controller_.reset(controller);
333}
334
335void RootWindowController::SetAnimatingWallpaperController(
336 AnimatingDesktopController* controller) {
337 if (animating_wallpaper_controller_.get())
338 animating_wallpaper_controller_->StopAnimating();
339 animating_wallpaper_controller_.reset(controller);
340}
341
[email protected]6675e1c2012-09-11 09:15:45342void RootWindowController::Shutdown() {
[email protected]a825e8312014-05-05 22:05:01343 Shell* shell = Shell::GetInstance();
344 shell->RemoveShellObserver(this);
345
346#if defined(OS_CHROMEOS)
[email protected]7d487592014-07-24 03:54:50347 if (touch_exploration_manager_) {
348 touch_exploration_manager_.reset();
[email protected]a825e8312014-05-05 22:05:01349 }
350#endif
[email protected]d141b922013-07-09 08:13:17351
[email protected]0bf61732013-07-02 04:35:10352 if (animating_wallpaper_controller_.get())
353 animating_wallpaper_controller_->StopAnimating();
354 wallpaper_controller_.reset();
355 animating_wallpaper_controller_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45356 aura::Window* root_window = GetRootWindow();
[email protected]d17642d2013-09-12 23:44:38357 // Change the target root window before closing child windows. If any child
[email protected]c98a4922013-09-05 20:01:42358 // being removed triggers a relayout of the shelf it will try to build a
[email protected]d17642d2013-09-12 23:44:38359 // window list adding windows from the target root window's containers which
[email protected]c98a4922013-09-05 20:01:42360 // may have already gone away.
[email protected]f5c9dbc2014-04-11 08:13:45361 if (Shell::GetTargetRootWindow() == root_window) {
[email protected]a825e8312014-05-05 22:05:01362 shell->set_target_root_window(
[email protected]f5c9dbc2014-04-11 08:13:45363 Shell::GetPrimaryRootWindow() == root_window
364 ? NULL
365 : Shell::GetPrimaryRootWindow());
[email protected]f634dd32012-07-23 22:49:07366 }
[email protected]c98a4922013-09-05 20:01:42367
368 CloseChildWindows();
[email protected]f5c9dbc2014-04-11 08:13:45369 GetRootWindowSettings(root_window)->controller = NULL;
[email protected]d90b8392012-06-13 09:34:56370 screen_dimmer_.reset();
371 workspace_controller_.reset();
[email protected]6675e1c2012-09-11 09:15:45372 // Forget with the display ID so that display lookup
373 // ends up with invalid display.
[email protected]f5c9dbc2014-04-11 08:13:45374 GetRootWindowSettings(root_window)->display_id =
[email protected]f8e6aad2013-08-30 21:49:11375 gfx::Display::kInvalidDisplayID;
[email protected]8f5209c2014-05-22 20:36:11376 ash_host_->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28377
[email protected]956a6a42012-10-29 23:58:10378 system_background_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45379 aura::client::SetScreenPositionClient(root_window, NULL);
[email protected]d90b8392012-06-13 09:34:56380}
381
[email protected]c0ce80e2012-10-05 23:28:27382SystemModalContainerLayoutManager*
[email protected]8674b312012-10-12 19:02:44383RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
[email protected]a5c78802013-12-12 22:07:01384 aura::Window* modal_container = NULL;
[email protected]8674b312012-10-12 19:02:44385 if (window) {
[email protected]a5c78802013-12-12 22:07:01386 aura::Window* window_container = GetContainerForWindow(window);
387 if (window_container &&
388 window_container->id() >= kShellWindowId_LockScreenContainer) {
389 modal_container = GetContainer(kShellWindowId_LockSystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35390 } else {
[email protected]a5c78802013-12-12 22:07:01391 modal_container = GetContainer(kShellWindowId_SystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35392 }
[email protected]8674b312012-10-12 19:02:44393 } else {
[email protected]a44afbbd2013-07-24 21:49:35394 int modal_window_id = Shell::GetInstance()->session_state_delegate()
395 ->IsUserSessionBlocked() ? kShellWindowId_LockSystemModalContainer :
396 kShellWindowId_SystemModalContainer;
[email protected]a5c78802013-12-12 22:07:01397 modal_container = GetContainer(modal_window_id);
[email protected]8674b312012-10-12 19:02:44398 }
[email protected]a5c78802013-12-12 22:07:01399 return modal_container ? static_cast<SystemModalContainerLayoutManager*>(
400 modal_container->layout_manager()) : NULL;
[email protected]c0ce80e2012-10-05 23:28:27401}
402
[email protected]d90b8392012-06-13 09:34:56403aura::Window* RootWindowController::GetContainer(int container_id) {
[email protected]f5c9dbc2014-04-11 08:13:45404 return GetRootWindow()->GetChildById(container_id);
[email protected]d90b8392012-06-13 09:34:56405}
406
[email protected]d8a24952013-08-05 20:05:05407const aura::Window* RootWindowController::GetContainer(int container_id) const {
[email protected]f5c9dbc2014-04-11 08:13:45408 return ash_host_->AsWindowTreeHost()->window()->GetChildById(container_id);
[email protected]d8a24952013-08-05 20:05:05409}
410
[email protected]864b58552013-12-19 04:19:38411void RootWindowController::ShowShelf() {
412 if (!shelf_->shelf())
[email protected]e74aaf0a2012-10-12 18:42:28413 return;
[email protected]864b58552013-12-19 04:19:38414 shelf_->shelf()->SetVisible(true);
[email protected]478c6c32013-03-09 02:50:58415 shelf_->status_area_widget()->Show();
[email protected]e74aaf0a2012-10-12 18:42:28416}
417
[email protected]864b58552013-12-19 04:19:38418void RootWindowController::OnShelfCreated() {
[email protected]756bda12013-07-03 08:17:06419 if (panel_layout_manager_)
[email protected]864b58552013-12-19 04:19:38420 panel_layout_manager_->SetShelf(shelf_->shelf());
[email protected]7115bd32013-07-19 08:25:39421 if (docked_layout_manager_) {
[email protected]864b58552013-12-19 04:19:38422 docked_layout_manager_->SetShelf(shelf_->shelf());
[email protected]7115bd32013-07-19 08:25:39423 if (shelf_->shelf_layout_manager())
424 docked_layout_manager_->AddObserver(shelf_->shelf_layout_manager());
425 }
[email protected]b8642ec2014-04-17 05:20:39426
427 // Notify shell observers that the shelf has been created.
428 Shell::GetInstance()->OnShelfCreatedForRootWindow(GetRootWindow());
[email protected]756bda12013-07-03 08:17:06429}
430
[email protected]16059276d2012-10-22 18:59:50431void RootWindowController::UpdateAfterLoginStatusChange(
432 user::LoginStatus status) {
[email protected]cf6fea22013-08-07 14:24:01433 if (status != user::LOGGED_IN_NONE)
434 mouse_event_target_.reset();
[email protected]80549c152013-07-02 01:42:47435 if (shelf_->status_area_widget())
[email protected]478c6c32013-03-09 02:50:58436 shelf_->status_area_widget()->UpdateAfterLoginStatusChange(status);
[email protected]16059276d2012-10-22 18:59:50437}
438
[email protected]bca9a7e2012-11-10 06:25:49439void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
[email protected]252eb232013-08-14 22:09:27440#if defined(OS_CHROMEOS)
pgal.u-szegedd84534d32014-10-29 12:34:30441 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]bca9a7e2012-11-10 06:25:49442 switches::kAshAnimateFromBootSplashScreen) &&
443 boot_splash_screen_.get()) {
444 // Make the splash screen fade out so it doesn't obscure the desktop
445 // wallpaper's brightness/grayscale animation.
446 boot_splash_screen_->StartHideAnimation(
447 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
448 }
[email protected]252eb232013-08-14 22:09:27449#endif
[email protected]bca9a7e2012-11-10 06:25:49450}
451
[email protected]0bf61732013-07-02 04:35:10452void RootWindowController::OnWallpaperAnimationFinished(views::Widget* widget) {
453 // Make sure the wallpaper is visible.
[email protected]bca9a7e2012-11-10 06:25:49454 system_background_->SetColor(SK_ColorBLACK);
[email protected]252eb232013-08-14 22:09:27455#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:49456 boot_splash_screen_.reset();
[email protected]252eb232013-08-14 22:09:27457#endif
[email protected]0bf61732013-07-02 04:35:10458
459 Shell::GetInstance()->user_wallpaper_delegate()->
460 OnWallpaperAnimationFinished();
461 // Only removes old component when wallpaper animation finished. If we
462 // remove the old one before the new wallpaper is done fading in there will
463 // be a white flash during the animation.
464 if (animating_wallpaper_controller()) {
465 DesktopBackgroundWidgetController* controller =
466 animating_wallpaper_controller()->GetController(true);
467 // |desktop_widget_| should be the same animating widget we try to move
468 // to |kDesktopController|. Otherwise, we may close |desktop_widget_|
469 // before move it to |kDesktopController|.
470 DCHECK_EQ(controller->widget(), widget);
471 // Release the old controller and close its background widget.
472 SetWallpaperController(controller);
473 }
[email protected]697f04c2012-10-03 01:15:10474}
475
[email protected]d90b8392012-06-13 09:34:56476void RootWindowController::CloseChildWindows() {
[email protected]cf6fea22013-08-07 14:24:01477 mouse_event_target_.reset();
478
[email protected]2a57beb52014-06-09 20:02:26479 // Remove observer as deactivating keyboard causes |docked_layout_manager_|
480 // to fire notifications.
481 if (docked_layout_manager_ && shelf_ && shelf_->shelf_layout_manager())
482 docked_layout_manager_->RemoveObserver(shelf_->shelf_layout_manager());
483
[email protected]b6ba05d902013-10-04 21:38:45484 // Deactivate keyboard container before closing child windows and shutting
485 // down associated layout managers.
[email protected]a0b3fb882014-04-07 19:26:03486 DeactivateKeyboard(keyboard::KeyboardController::GetInstance());
[email protected]b6ba05d902013-10-04 21:38:45487
[email protected]79a87b7e2013-01-25 05:08:22488 // panel_layout_manager_ needs to be shut down before windows are destroyed.
489 if (panel_layout_manager_) {
490 panel_layout_manager_->Shutdown();
491 panel_layout_manager_ = NULL;
492 }
[email protected]7115bd32013-07-19 08:25:39493 // docked_layout_manager_ needs to be shut down before windows are destroyed.
494 if (docked_layout_manager_) {
[email protected]7115bd32013-07-19 08:25:39495 docked_layout_manager_->Shutdown();
496 docked_layout_manager_ = NULL;
497 }
[email protected]f5c9dbc2014-04-11 08:13:45498 aura::Window* root_window = GetRootWindow();
499 aura::client::SetDragDropClient(root_window, NULL);
[email protected]8b3e3d82013-08-20 14:36:30500
[email protected]478c6c32013-03-09 02:50:58501 // TODO(harrym): Remove when Status Area Widget is a child view.
[email protected]bb42c932013-10-31 06:52:06502 if (shelf_) {
503 shelf_->ShutdownStatusAreaWidget();
[email protected]478c6c32013-03-09 02:50:58504
[email protected]bb42c932013-10-31 06:52:06505 if (shelf_->shelf_layout_manager())
506 shelf_->shelf_layout_manager()->PrepareForShutdown();
507 }
[email protected]e74aaf0a2012-10-12 18:42:28508
[email protected]d90b8392012-06-13 09:34:56509 // Close background widget first as it depends on tooltip.
[email protected]0bf61732013-07-02 04:35:10510 wallpaper_controller_.reset();
511 animating_wallpaper_controller_.reset();
[email protected]b4ddc7a2012-08-07 04:17:32512
[email protected]d90b8392012-06-13 09:34:56513 workspace_controller_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45514 aura::client::SetTooltipClient(root_window, NULL);
[email protected]d90b8392012-06-13 09:34:56515
[email protected]0fbfa972013-10-02 19:23:33516 // Explicitly destroy top level windows. We do this as during part of
517 // destruction such windows may query the RootWindow for state.
[email protected]8b3e3d82013-08-20 14:36:30518 std::queue<aura::Window*> non_toplevel_windows;
[email protected]f5c9dbc2014-04-11 08:13:45519 non_toplevel_windows.push(root_window);
[email protected]8b3e3d82013-08-20 14:36:30520 while (!non_toplevel_windows.empty()) {
521 aura::Window* non_toplevel_window = non_toplevel_windows.front();
522 non_toplevel_windows.pop();
523 aura::WindowTracker toplevel_windows;
524 for (size_t i = 0; i < non_toplevel_window->children().size(); ++i) {
525 aura::Window* child = non_toplevel_window->children()[i];
[email protected]0fbfa972013-10-02 19:23:33526 if (!child->owned_by_parent())
527 continue;
[email protected]8b3e3d82013-08-20 14:36:30528 if (child->delegate())
529 toplevel_windows.Add(child);
530 else
531 non_toplevel_windows.push(child);
532 }
533 while (!toplevel_windows.windows().empty())
534 delete *toplevel_windows.windows().begin();
[email protected]d90b8392012-06-13 09:34:56535 }
[email protected]8b3e3d82013-08-20 14:36:30536 // And then remove the containers.
[email protected]f5c9dbc2014-04-11 08:13:45537 while (!root_window->children().empty()) {
538 aura::Window* window = root_window->children()[0];
[email protected]0fbfa972013-10-02 19:23:33539 if (window->owned_by_parent()) {
540 delete window;
541 } else {
[email protected]f5c9dbc2014-04-11 08:13:45542 root_window->RemoveChild(window);
[email protected]0fbfa972013-10-02 19:23:33543 }
544 }
[email protected]478c6c32013-03-09 02:50:58545
[email protected]bb42c932013-10-31 06:52:06546 shelf_.reset();
[email protected]d90b8392012-06-13 09:34:56547}
548
[email protected]bf9cdb362013-10-25 19:22:45549void RootWindowController::MoveWindowsTo(aura::Window* dst) {
[email protected]8039e06c2013-01-17 23:34:50550 // Forget the shelf early so that shelf don't update itself using wrong
551 // display info.
552 workspace_controller_->SetShelf(NULL);
[email protected]f5c9dbc2014-04-11 08:13:45553 ReparentAllWindows(GetRootWindow(), dst);
[email protected]f1853122012-06-27 16:21:26554}
555
[email protected]478c6c32013-03-09 02:50:58556ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
[email protected]80549c152013-07-02 01:42:47557 return shelf_->shelf_layout_manager();
[email protected]478c6c32013-03-09 02:50:58558}
559
[email protected]a0afeb12012-12-10 22:57:09560SystemTray* RootWindowController::GetSystemTray() {
561 // We assume in throughout the code that this will not return NULL. If code
562 // triggers this for valid reasons, it should test status_area_widget first.
[email protected]80549c152013-07-02 01:42:47563 CHECK(shelf_->status_area_widget());
[email protected]478c6c32013-03-09 02:50:58564 return shelf_->status_area_widget()->system_tray();
[email protected]a0afeb12012-12-10 22:57:09565}
566
[email protected]940fb1c2013-06-18 16:54:28567void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
568 ui::MenuSourceType source_type) {
[email protected]431552c2012-10-23 00:38:33569 DCHECK(Shell::GetInstance()->delegate());
570 scoped_ptr<ui::MenuModel> menu_model(
[email protected]f5c9dbc2014-04-11 08:13:45571 Shell::GetInstance()->delegate()->CreateContextMenu(
572 GetRootWindow(), NULL, NULL));
[email protected]7f7f65c2013-04-17 16:47:13573 if (!menu_model)
[email protected]8e837ec2013-01-31 01:48:33574 return;
[email protected]431552c2012-10-23 00:38:33575
[email protected]6175fc42013-04-05 05:58:58576 // Background controller may not be set yet if user clicked on status are
577 // before initial animation completion. See crbug.com/222218
[email protected]0bf61732013-07-02 04:35:10578 if (!wallpaper_controller_.get())
[email protected]431552c2012-10-23 00:38:33579 return;
580
[email protected]0a37a5d2014-07-15 00:42:23581 views::MenuRunner menu_runner(menu_model.get(),
582 views::MenuRunner::CONTEXT_MENU);
[email protected]0bf61732013-07-02 04:35:10583 if (menu_runner.RunMenuAt(wallpaper_controller_->widget(),
[email protected]fd6c0a62014-05-01 07:50:35584 NULL,
585 gfx::Rect(location_in_screen, gfx::Size()),
586 views::MENU_ANCHOR_TOPLEFT,
[email protected]0a37a5d2014-07-15 00:42:23587 source_type) == views::MenuRunner::MENU_DELETED) {
[email protected]6175fc42013-04-05 05:58:58588 return;
589 }
590
[email protected]431552c2012-10-23 00:38:33591 Shell::GetInstance()->UpdateShelfVisibility();
592}
593
[email protected]e74aaf0a2012-10-12 18:42:28594void RootWindowController::UpdateShelfVisibility() {
[email protected]478c6c32013-03-09 02:50:58595 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]e74aaf0a2012-10-12 18:42:28596}
597
[email protected]2c9171d22013-12-10 21:55:10598const aura::Window* RootWindowController::GetWindowForFullscreenMode() const {
[email protected]2c9171d22013-12-10 21:55:10599 const aura::Window* topmost_window = NULL;
[email protected]2c5db9e2014-02-27 13:58:14600 const aura::Window* active_window = wm::GetActiveWindow();
[email protected]f5c9dbc2014-04-11 08:13:45601 if (active_window && active_window->GetRootWindow() == GetRootWindow() &&
[email protected]2c5db9e2014-02-27 13:58:14602 IsSwitchableContainer(active_window->parent())) {
603 // Use the active window when it is on the current root window to determine
604 // the fullscreen state to allow temporarily using a panel or docked window
605 // (which are always above the default container) while a fullscreen
606 // window is open. We only use the active window when in a switchable
607 // container as the launcher should not exit fullscreen mode.
608 topmost_window = active_window;
609 } else {
610 // Otherwise, use the topmost window on the root window's default container
611 // when there is no active window on this root window.
612 const aura::Window::Windows& windows =
613 GetContainer(kShellWindowId_DefaultContainer)->children();
614 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin();
615 iter != windows.rend(); ++iter) {
bruthigb7056f62015-06-04 21:04:53616 if (wm::IsWindowUserPositionable(*iter) &&
[email protected]2c5db9e2014-02-27 13:58:14617 (*iter)->layer()->GetTargetVisibility()) {
618 topmost_window = *iter;
619 break;
620 }
[email protected]2c9171d22013-12-10 21:55:10621 }
622 }
623 while (topmost_window) {
624 if (wm::GetWindowState(topmost_window)->IsFullscreen())
625 return topmost_window;
[email protected]e319c7e2014-03-14 19:56:14626 topmost_window = ::wm::GetTransientParent(topmost_window);
[email protected]2ee2f5d2013-01-10 23:37:16627 }
[email protected]700849f2013-04-30 17:49:20628 return NULL;
[email protected]2ee2f5d2013-01-10 23:37:16629}
630
[email protected]b6ba05d902013-10-04 21:38:45631void RootWindowController::ActivateKeyboard(
632 keyboard::KeyboardController* keyboard_controller) {
633 if (!keyboard::IsKeyboardEnabled() ||
634 GetContainer(kShellWindowId_VirtualKeyboardContainer)) {
635 return;
636 }
637 DCHECK(keyboard_controller);
bshe9858b4a2014-09-16 20:46:38638 keyboard_controller->AddObserver(shelf()->shelf_layout_manager());
639 keyboard_controller->AddObserver(panel_layout_manager_);
640 keyboard_controller->AddObserver(docked_layout_manager_);
641 keyboard_controller->AddObserver(workspace_controller_->layout_manager());
rsadam7bd510bb2014-12-09 20:10:56642 keyboard_controller->AddObserver(
643 always_on_top_controller_->GetLayoutManager());
bshe9858b4a2014-09-16 20:46:38644 Shell::GetInstance()->delegate()->VirtualKeyboardActivated(true);
bshec3875422014-09-29 13:21:30645 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]b2da9b602014-03-05 18:39:52646 DCHECK(parent);
[email protected]b6ba05d902013-10-04 21:38:45647 aura::Window* keyboard_container =
648 keyboard_controller->GetContainerWindow();
649 keyboard_container->set_id(kShellWindowId_VirtualKeyboardContainer);
650 parent->AddChild(keyboard_container);
[email protected]b6ba05d902013-10-04 21:38:45651}
[email protected]86459e2c2013-04-10 13:39:24652
[email protected]b6ba05d902013-10-04 21:38:45653void RootWindowController::DeactivateKeyboard(
654 keyboard::KeyboardController* keyboard_controller) {
[email protected]e1b299b2014-01-29 23:53:41655 if (!keyboard_controller ||
656 !keyboard_controller->keyboard_container_initialized()) {
[email protected]b6ba05d902013-10-04 21:38:45657 return;
[email protected]e1b299b2014-01-29 23:53:41658 }
[email protected]b6ba05d902013-10-04 21:38:45659 aura::Window* keyboard_container =
660 keyboard_controller->GetContainerWindow();
[email protected]f5c9dbc2014-04-11 08:13:45661 if (keyboard_container->GetRootWindow() == GetRootWindow()) {
bshec3875422014-09-29 13:21:30662 aura::Window* parent =
663 GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]b2da9b602014-03-05 18:39:52664 DCHECK(parent);
665 parent->RemoveChild(keyboard_container);
bshe9858b4a2014-09-16 20:46:38666 // Virtual keyboard may be deactivated while still showing, notify all
667 // observers that keyboard bounds changed to 0 before remove them.
668 keyboard_controller->NotifyKeyboardBoundsChanging(gfx::Rect());
669 keyboard_controller->RemoveObserver(shelf()->shelf_layout_manager());
670 keyboard_controller->RemoveObserver(panel_layout_manager_);
671 keyboard_controller->RemoveObserver(docked_layout_manager_);
672 keyboard_controller->RemoveObserver(
673 workspace_controller_->layout_manager());
rsadam7bd510bb2014-12-09 20:10:56674 keyboard_controller->RemoveObserver(
675 always_on_top_controller_->GetLayoutManager());
bshe9858b4a2014-09-16 20:46:38676 Shell::GetInstance()->delegate()->VirtualKeyboardActivated(false);
[email protected]86459e2c2013-04-10 13:39:24677 }
678}
679
[email protected]602022b2014-03-31 17:07:31680bool RootWindowController::IsVirtualKeyboardWindow(aura::Window* window) {
bshec3875422014-09-29 13:21:30681 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]602022b2014-03-31 17:07:31682 return parent ? parent->Contains(window) : false;
683}
684
[email protected]a4cd6d32012-09-12 03:42:13685////////////////////////////////////////////////////////////////////////////////
686// RootWindowController, private:
687
[email protected]f5c9dbc2014-04-11 08:13:45688RootWindowController::RootWindowController(AshWindowTreeHost* ash_host)
689 : ash_host_(ash_host),
[email protected]a273d33a2013-10-17 12:41:21690 root_window_layout_(NULL),
691 docked_layout_manager_(NULL),
692 panel_layout_manager_(NULL),
693 touch_hud_debug_(NULL),
694 touch_hud_projection_(NULL) {
[email protected]f5c9dbc2014-04-11 08:13:45695 aura::Window* root_window = GetRootWindow();
696 GetRootWindowSettings(root_window)->controller = this;
697 screen_dimmer_.reset(new ScreenDimmer(root_window));
[email protected]a273d33a2013-10-17 12:41:21698
699 stacking_controller_.reset(new StackingController);
[email protected]f5c9dbc2014-04-11 08:13:45700 aura::client::SetWindowTreeClient(root_window, stacking_controller_.get());
701 capture_client_.reset(new ::wm::ScopedCaptureClient(root_window));
[email protected]a273d33a2013-10-17 12:41:21702}
703
[email protected]608de6c2013-10-29 00:14:28704void RootWindowController::Init(RootWindowType root_window_type,
705 bool first_run_after_boot) {
[email protected]f5c9dbc2014-04-11 08:13:45706 aura::Window* root_window = GetRootWindow();
[email protected]51f438112013-11-18 19:32:50707 Shell* shell = Shell::GetInstance();
[email protected]f5c9dbc2014-04-11 08:13:45708 shell->InitRootWindow(root_window);
[email protected]a273d33a2013-10-17 12:41:21709
[email protected]f5c9dbc2014-04-11 08:13:45710 ash_host_->AsWindowTreeHost()->SetCursor(ui::kCursorPointer);
711 CreateContainersInRootWindow(root_window);
[email protected]608de6c2013-10-29 00:14:28712
[email protected]a273d33a2013-10-17 12:41:21713 CreateSystemBackground(first_run_after_boot);
714
715 InitLayoutManagers();
716 InitTouchHuds();
717
718 if (Shell::GetPrimaryRootWindowController()->
719 GetSystemModalLayoutManager(NULL)->has_modal_background()) {
720 GetSystemModalLayoutManager(NULL)->CreateModalBackground();
721 }
722
[email protected]a273d33a2013-10-17 12:41:21723 shell->AddShellObserver(this);
724
[email protected]608de6c2013-10-29 00:14:28725 if (root_window_type == PRIMARY) {
[email protected]a3565792013-10-18 12:52:37726 root_window_layout()->OnWindowResized();
bshe9858b4a2014-09-16 20:46:38727 shell->InitKeyboard();
[email protected]a273d33a2013-10-17 12:41:21728 } else {
729 root_window_layout()->OnWindowResized();
[email protected]f5c9dbc2014-04-11 08:13:45730 ash_host_->AsWindowTreeHost()->Show();
[email protected]a273d33a2013-10-17 12:41:21731
[email protected]864b58552013-12-19 04:19:38732 // Create a shelf if a user is already logged in.
[email protected]a273d33a2013-10-17 12:41:21733 if (shell->session_state_delegate()->NumberOfLoggedInUsers())
[email protected]864b58552013-12-19 04:19:38734 shelf()->CreateShelf();
[email protected]0e3e7cb2014-04-12 05:18:25735
736 // Notify shell observers about new root window.
737 shell->OnRootWindowAdded(root_window);
[email protected]a273d33a2013-10-17 12:41:21738 }
[email protected]a825e8312014-05-05 22:05:01739
740#if defined(OS_CHROMEOS)
pgal.u-szegedd84534d32014-10-29 12:34:30741 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]2e0b2352014-07-28 13:28:28742 switches::kAshDisableTouchExplorationMode)) {
[email protected]7d487592014-07-24 03:54:50743 touch_exploration_manager_.reset(new AshTouchExplorationManager(this));
[email protected]a825e8312014-05-05 22:05:01744 }
745#endif
[email protected]a273d33a2013-10-17 12:41:21746}
747
[email protected]756bda12013-07-03 08:17:06748void RootWindowController::InitLayoutManagers() {
[email protected]f5c9dbc2014-04-11 08:13:45749 aura::Window* root_window = GetRootWindow();
750 root_window_layout_ = new RootWindowLayoutManager(root_window);
751 root_window->SetLayoutManager(root_window_layout_);
[email protected]756bda12013-07-03 08:17:06752
753 aura::Window* default_container =
754 GetContainer(kShellWindowId_DefaultContainer);
755 // Workspace manager has its own layout managers.
756 workspace_controller_.reset(
757 new WorkspaceController(default_container));
758
759 aura::Window* always_on_top_container =
760 GetContainer(kShellWindowId_AlwaysOnTopContainer);
rsadam7bd510bb2014-12-09 20:10:56761 always_on_top_controller_.reset(
762 new AlwaysOnTopController(always_on_top_container));
[email protected]756bda12013-07-03 08:17:06763
764 DCHECK(!shelf_.get());
[email protected]093b8d642014-04-03 20:59:28765 aura::Window* shelf_container = GetContainer(kShellWindowId_ShelfContainer);
[email protected]756bda12013-07-03 08:17:06766 // TODO(harrym): Remove when status area is view.
[email protected]093b8d642014-04-03 20:59:28767 aura::Window* status_container = GetContainer(kShellWindowId_StatusContainer);
[email protected]756bda12013-07-03 08:17:06768 shelf_.reset(new ShelfWidget(
769 shelf_container, status_container, workspace_controller()));
770
[email protected]cf6fea22013-08-07 14:24:01771 if (!Shell::GetInstance()->session_state_delegate()->
772 IsActiveUserSessionStarted()) {
773 // This window exists only to be a event target on login screen.
774 // It does not have to handle events, nor be visible.
775 mouse_event_target_.reset(new aura::Window(new EmptyWindowDelegate));
danakjb161836d2015-04-03 05:14:18776 mouse_event_target_->Init(ui::LAYER_NOT_DRAWN);
[email protected]cf6fea22013-08-07 14:24:01777
778 aura::Window* lock_background_container =
[email protected]093b8d642014-04-03 20:59:28779 GetContainer(kShellWindowId_LockScreenBackgroundContainer);
[email protected]cf6fea22013-08-07 14:24:01780 lock_background_container->AddChild(mouse_event_target_.get());
781 mouse_event_target_->Show();
782 }
783
[email protected]756bda12013-07-03 08:17:06784 // Create Docked windows layout manager
[email protected]093b8d642014-04-03 20:59:28785 aura::Window* docked_container = GetContainer(kShellWindowId_DockedContainer);
[email protected]756bda12013-07-03 08:17:06786 docked_layout_manager_ =
[email protected]093b8d642014-04-03 20:59:28787 new DockedWindowLayoutManager(docked_container, workspace_controller());
[email protected]756bda12013-07-03 08:17:06788 docked_container->SetLayoutManager(docked_layout_manager_);
789
[email protected]1ca79d42014-07-18 16:26:10790 // Installs SnapLayoutManager to containers who set the
791 // |kSnapsChildrenToPhysicalPixelBoundary| property.
792 wm::InstallSnapLayoutManagerToContainers(root_window);
793
[email protected]756bda12013-07-03 08:17:06794 // Create Panel layout manager
[email protected]093b8d642014-04-03 20:59:28795 aura::Window* panel_container = GetContainer(kShellWindowId_PanelContainer);
796 panel_layout_manager_ = new PanelLayoutManager(panel_container);
[email protected]756bda12013-07-03 08:17:06797 panel_container->SetLayoutManager(panel_layout_manager_);
[email protected]3537d472014-01-15 05:45:31798 panel_container_handler_.reset(new PanelWindowEventHandler);
799 panel_container->AddPreTargetHandler(panel_container_handler_.get());
[email protected]b8642ec2014-04-17 05:20:39800
801 // Install an AttachedPanelWindowTargeter on the panel container to make it
802 // easier to correctly target shelf buttons with touch.
803 gfx::Insets mouse_extend(-kResizeOutsideBoundsSize,
804 -kResizeOutsideBoundsSize,
805 -kResizeOutsideBoundsSize,
806 -kResizeOutsideBoundsSize);
807 gfx::Insets touch_extend = mouse_extend.Scale(
808 kResizeOutsideBoundsScaleForTouch);
809 panel_container->SetEventTargeter(scoped_ptr<ui::EventTargeter>(
810 new AttachedPanelWindowTargeter(panel_container,
811 mouse_extend,
812 touch_extend,
813 panel_layout_manager_)));
[email protected]756bda12013-07-03 08:17:06814}
815
816void RootWindowController::InitTouchHuds() {
pgal.u-szegedd84534d32014-10-29 12:34:30817 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
[email protected]756bda12013-07-03 08:17:06818 if (command_line->HasSwitch(switches::kAshTouchHud))
[email protected]f5c9dbc2014-04-11 08:13:45819 set_touch_hud_debug(new TouchHudDebug(GetRootWindow()));
[email protected]756bda12013-07-03 08:17:06820 if (Shell::GetInstance()->is_touch_hud_projection_enabled())
821 EnableTouchHudProjection();
822}
823
824void RootWindowController::CreateSystemBackground(
825 bool is_first_run_after_boot) {
826 SkColor color = SK_ColorBLACK;
827#if defined(OS_CHROMEOS)
828 if (is_first_run_after_boot)
829 color = kChromeOsBootColor;
830#endif
831 system_background_.reset(
[email protected]f5c9dbc2014-04-11 08:13:45832 new SystemBackgroundController(GetRootWindow(), color));
[email protected]756bda12013-07-03 08:17:06833
834#if defined(OS_CHROMEOS)
835 // Make a copy of the system's boot splash screen so we can composite it
836 // onscreen until the desktop background is ready.
837 if (is_first_run_after_boot &&
pgal.u-szegedd84534d32014-10-29 12:34:30838 (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]756bda12013-07-03 08:17:06839 switches::kAshCopyHostBackgroundAtBoot) ||
pgal.u-szegedd84534d32014-10-29 12:34:30840 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]756bda12013-07-03 08:17:06841 switches::kAshAnimateFromBootSplashScreen)))
[email protected]f5c9dbc2014-04-11 08:13:45842 boot_splash_screen_.reset(new BootSplashScreen(GetHost()));
[email protected]756bda12013-07-03 08:17:06843#endif
844}
845
[email protected]a4cd6d32012-09-12 03:42:13846void RootWindowController::CreateContainersInRootWindow(
[email protected]41baaed2013-11-09 04:18:26847 aura::Window* root_window) {
[email protected]a4cd6d32012-09-12 03:42:13848 // These containers are just used by PowerButtonController to animate groups
849 // of containers simultaneously without messing up the current transformations
850 // on those containers. These are direct children of the root window; all of
851 // the other containers are their children.
[email protected]e6e41d2f2012-10-29 19:22:19852
853 // The desktop background container is not part of the lock animation, so it
854 // is not included in those animate groups.
[email protected]a4cd6d32012-09-12 03:42:13855 // When screen is locked desktop background is moved to lock screen background
856 // container (moved back on unlock). We want to make sure that there's an
857 // opaque layer occluding the non-lock-screen layers.
[email protected]e6e41d2f2012-10-29 19:22:19858 aura::Window* desktop_background_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27859 kShellWindowId_DesktopBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13860 "DesktopBackgroundContainer",
861 root_window);
[email protected]e319c7e2014-03-14 19:56:14862 ::wm::SetChildWindowVisibilityChangesAnimated(desktop_background_container);
[email protected]a4cd6d32012-09-12 03:42:13863
864 aura::Window* non_lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27865 kShellWindowId_NonLockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13866 "NonLockScreenContainersContainer",
867 root_window);
oshimaf52e1be2015-05-06 21:29:34868 // Clip all windows inside this container, as half pixel of the window's
869 // texture may become visible when the screen is scaled. crbug.com/368591.
870 non_lock_screen_containers->layer()->SetMasksToBounds(true);
[email protected]a4cd6d32012-09-12 03:42:13871
872 aura::Window* lock_background_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27873 kShellWindowId_LockScreenBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13874 "LockScreenBackgroundContainer",
875 root_window);
[email protected]e319c7e2014-03-14 19:56:14876 ::wm::SetChildWindowVisibilityChangesAnimated(lock_background_containers);
[email protected]a4cd6d32012-09-12 03:42:13877
878 aura::Window* lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27879 kShellWindowId_LockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13880 "LockScreenContainersContainer",
881 root_window);
882 aura::Window* lock_screen_related_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27883 kShellWindowId_LockScreenRelatedContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13884 "LockScreenRelatedContainersContainer",
885 root_window);
886
[email protected]c0ce80e2012-10-05 23:28:27887 CreateContainer(kShellWindowId_UnparentedControlContainer,
[email protected]a4cd6d32012-09-12 03:42:13888 "UnparentedControlContainer",
889 non_lock_screen_containers);
890
891 aura::Window* default_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27892 kShellWindowId_DefaultContainer,
[email protected]a4cd6d32012-09-12 03:42:13893 "DefaultContainer",
894 non_lock_screen_containers);
[email protected]e319c7e2014-03-14 19:56:14895 ::wm::SetChildWindowVisibilityChangesAnimated(default_container);
[email protected]1ca79d42014-07-18 16:26:10896 wm::SetSnapsChildrenToPhysicalPixelBoundary(default_container);
[email protected]a4cd6d32012-09-12 03:42:13897 SetUsesScreenCoordinates(default_container);
[email protected]c5be8d672014-01-07 13:33:41898 SetUsesEasyResizeTargeter(default_container);
[email protected]a4cd6d32012-09-12 03:42:13899
900 aura::Window* always_on_top_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27901 kShellWindowId_AlwaysOnTopContainer,
[email protected]a4cd6d32012-09-12 03:42:13902 "AlwaysOnTopContainer",
903 non_lock_screen_containers);
[email protected]e319c7e2014-03-14 19:56:14904 ::wm::SetChildWindowVisibilityChangesAnimated(always_on_top_container);
[email protected]1ca79d42014-07-18 16:26:10905 wm::SetSnapsChildrenToPhysicalPixelBoundary(always_on_top_container);
[email protected]a4cd6d32012-09-12 03:42:13906 SetUsesScreenCoordinates(always_on_top_container);
907
[email protected]beb4e5c2013-06-18 15:37:07908 aura::Window* docked_container = CreateContainer(
909 kShellWindowId_DockedContainer,
910 "DockedContainer",
911 non_lock_screen_containers);
[email protected]e319c7e2014-03-14 19:56:14912 ::wm::SetChildWindowVisibilityChangesAnimated(docked_container);
[email protected]1ca79d42014-07-18 16:26:10913 wm::SetSnapsChildrenToPhysicalPixelBoundary(docked_container);
[email protected]beb4e5c2013-06-18 15:37:07914 SetUsesScreenCoordinates(docked_container);
[email protected]1ff0c492014-01-21 20:20:44915 SetUsesEasyResizeTargeter(docked_container);
[email protected]beb4e5c2013-06-18 15:37:07916
[email protected]3f13cf12013-07-12 05:13:59917 aura::Window* shelf_container =
[email protected]478c6c32013-03-09 02:50:58918 CreateContainer(kShellWindowId_ShelfContainer,
[email protected]3f13cf12013-07-12 05:13:59919 "ShelfContainer",
[email protected]a4cd6d32012-09-12 03:42:13920 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10921 wm::SetSnapsChildrenToPhysicalPixelBoundary(shelf_container);
[email protected]3f13cf12013-07-12 05:13:59922 SetUsesScreenCoordinates(shelf_container);
923 DescendantShouldStayInSameRootWindow(shelf_container);
[email protected]a4cd6d32012-09-12 03:42:13924
[email protected]f2026eb2013-10-22 14:28:56925 aura::Window* panel_container = CreateContainer(
926 kShellWindowId_PanelContainer,
927 "PanelContainer",
928 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10929 wm::SetSnapsChildrenToPhysicalPixelBoundary(panel_container);
[email protected]f2026eb2013-10-22 14:28:56930 SetUsesScreenCoordinates(panel_container);
931
932 aura::Window* shelf_bubble_container =
933 CreateContainer(kShellWindowId_ShelfBubbleContainer,
934 "ShelfBubbleContainer",
935 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10936 wm::SetSnapsChildrenToPhysicalPixelBoundary(shelf_bubble_container);
[email protected]f2026eb2013-10-22 14:28:56937 SetUsesScreenCoordinates(shelf_bubble_container);
938 DescendantShouldStayInSameRootWindow(shelf_bubble_container);
939
[email protected]dc851a4e52012-10-03 00:05:55940 aura::Window* app_list_container =
[email protected]c0ce80e2012-10-05 23:28:27941 CreateContainer(kShellWindowId_AppListContainer,
[email protected]dc851a4e52012-10-03 00:05:55942 "AppListContainer",
943 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10944 wm::SetSnapsChildrenToPhysicalPixelBoundary(app_list_container);
[email protected]dc851a4e52012-10-03 00:05:55945 SetUsesScreenCoordinates(app_list_container);
[email protected]a4cd6d32012-09-12 03:42:13946
947 aura::Window* modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27948 kShellWindowId_SystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13949 "SystemModalContainer",
950 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10951 wm::SetSnapsChildrenToPhysicalPixelBoundary(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13952 modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27953 new SystemModalContainerLayoutManager(modal_container));
[email protected]e319c7e2014-03-14 19:56:14954 ::wm::SetChildWindowVisibilityChangesAnimated(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13955 SetUsesScreenCoordinates(modal_container);
[email protected]c5be8d672014-01-07 13:33:41956 SetUsesEasyResizeTargeter(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13957
[email protected]a4cd6d32012-09-12 03:42:13958 // TODO(beng): Figure out if we can make this use
959 // SystemModalContainerEventFilter instead of stops_event_propagation.
960 aura::Window* lock_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27961 kShellWindowId_LockScreenContainer,
[email protected]a4cd6d32012-09-12 03:42:13962 "LockScreenContainer",
963 lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10964 wm::SetSnapsChildrenToPhysicalPixelBoundary(lock_container);
oshima96f6a502015-05-02 08:43:32965 lock_container->SetLayoutManager(new LockLayoutManager(lock_container));
[email protected]a4cd6d32012-09-12 03:42:13966 SetUsesScreenCoordinates(lock_container);
967 // TODO(beng): stopsevents
968
969 aura::Window* lock_modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27970 kShellWindowId_LockSystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13971 "LockSystemModalContainer",
972 lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10973 wm::SetSnapsChildrenToPhysicalPixelBoundary(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13974 lock_modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27975 new SystemModalContainerLayoutManager(lock_modal_container));
[email protected]e319c7e2014-03-14 19:56:14976 ::wm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13977 SetUsesScreenCoordinates(lock_modal_container);
[email protected]c5be8d672014-01-07 13:33:41978 SetUsesEasyResizeTargeter(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13979
980 aura::Window* status_container =
[email protected]c0ce80e2012-10-05 23:28:27981 CreateContainer(kShellWindowId_StatusContainer,
[email protected]a4cd6d32012-09-12 03:42:13982 "StatusContainer",
983 lock_screen_related_containers);
[email protected]1ca79d42014-07-18 16:26:10984 wm::SetSnapsChildrenToPhysicalPixelBoundary(status_container);
[email protected]a4cd6d32012-09-12 03:42:13985 SetUsesScreenCoordinates(status_container);
[email protected]e887c6c2013-07-08 19:35:53986 DescendantShouldStayInSameRootWindow(status_container);
[email protected]a4cd6d32012-09-12 03:42:13987
988 aura::Window* settings_bubble_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27989 kShellWindowId_SettingBubbleContainer,
[email protected]a4cd6d32012-09-12 03:42:13990 "SettingBubbleContainer",
991 lock_screen_related_containers);
[email protected]e319c7e2014-03-14 19:56:14992 ::wm::SetChildWindowVisibilityChangesAnimated(settings_bubble_container);
[email protected]1ca79d42014-07-18 16:26:10993 wm::SetSnapsChildrenToPhysicalPixelBoundary(settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13994 SetUsesScreenCoordinates(settings_bubble_container);
[email protected]e887c6c2013-07-08 19:35:53995 DescendantShouldStayInSameRootWindow(settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13996
kevers23f3987d2014-09-17 13:50:12997 aura::Window* virtual_keyboard_parent_container =
bshec3875422014-09-29 13:21:30998 CreateContainer(kShellWindowId_ImeWindowParentContainer,
kevers23f3987d2014-09-17 13:50:12999 "VirtualKeyboardParentContainer",
1000 lock_screen_related_containers);
1001 wm::SetSnapsChildrenToPhysicalPixelBoundary(
1002 virtual_keyboard_parent_container);
1003 SetUsesScreenCoordinates(virtual_keyboard_parent_container);
1004
[email protected]a4cd6d32012-09-12 03:42:131005 aura::Window* menu_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:271006 kShellWindowId_MenuContainer,
[email protected]a4cd6d32012-09-12 03:42:131007 "MenuContainer",
1008 lock_screen_related_containers);
[email protected]e319c7e2014-03-14 19:56:141009 ::wm::SetChildWindowVisibilityChangesAnimated(menu_container);
[email protected]1ca79d42014-07-18 16:26:101010 wm::SetSnapsChildrenToPhysicalPixelBoundary(menu_container);
[email protected]a4cd6d32012-09-12 03:42:131011 SetUsesScreenCoordinates(menu_container);
1012
1013 aura::Window* drag_drop_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:271014 kShellWindowId_DragImageAndTooltipContainer,
[email protected]a4cd6d32012-09-12 03:42:131015 "DragImageAndTooltipContainer",
1016 lock_screen_related_containers);
[email protected]e319c7e2014-03-14 19:56:141017 ::wm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
[email protected]1ca79d42014-07-18 16:26:101018 wm::SetSnapsChildrenToPhysicalPixelBoundary(drag_drop_container);
[email protected]a4cd6d32012-09-12 03:42:131019 SetUsesScreenCoordinates(drag_drop_container);
1020
1021 aura::Window* overlay_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:271022 kShellWindowId_OverlayContainer,
[email protected]a4cd6d32012-09-12 03:42:131023 "OverlayContainer",
1024 lock_screen_related_containers);
[email protected]1ca79d42014-07-18 16:26:101025 wm::SetSnapsChildrenToPhysicalPixelBoundary(overlay_container);
[email protected]a4cd6d32012-09-12 03:42:131026 SetUsesScreenCoordinates(overlay_container);
[email protected]a07615f2012-10-24 08:23:081027
[email protected]b2da9b602014-03-05 18:39:521028#if defined(OS_CHROMEOS)
1029 aura::Window* mouse_cursor_container = CreateContainer(
1030 kShellWindowId_MouseCursorContainer,
1031 "MouseCursorContainer",
1032 root_window);
1033 SetUsesScreenCoordinates(mouse_cursor_container);
1034#endif
1035
[email protected]a07615f2012-10-24 08:23:081036 CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
[email protected]b2da9b602014-03-05 18:39:521037 "PowerButtonAnimationContainer", root_window);
[email protected]a4cd6d32012-09-12 03:42:131038}
1039
[email protected]d141b922013-07-09 08:13:171040void RootWindowController::EnableTouchHudProjection() {
1041 if (touch_hud_projection_)
1042 return;
[email protected]f5c9dbc2014-04-11 08:13:451043 set_touch_hud_projection(new TouchHudProjection(GetRootWindow()));
[email protected]d141b922013-07-09 08:13:171044}
1045
1046void RootWindowController::DisableTouchHudProjection() {
1047 if (!touch_hud_projection_)
1048 return;
1049 touch_hud_projection_->Remove();
1050}
1051
1052void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
1053 shelf_->shelf_layout_manager()->UpdateVisibilityState();
1054}
1055
1056void RootWindowController::OnTouchHudProjectionToggled(bool enabled) {
1057 if (enabled)
1058 EnableTouchHudProjection();
1059 else
1060 DisableTouchHudProjection();
1061}
1062
[email protected]6b2d4a0b2013-09-06 06:29:541063RootWindowController* GetRootWindowController(
[email protected]bf9cdb362013-10-25 19:22:451064 const aura::Window* root_window) {
[email protected]6b2d4a0b2013-09-06 06:29:541065 return root_window ? GetRootWindowSettings(root_window)->controller : NULL;
1066}
1067
[email protected]d90b8392012-06-13 09:34:561068} // namespace ash