blob: b9d13ab72dcbdbe84eacee1aadf7233180725eba [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]8d625fb2012-07-18 16:40:067#include <vector>
8
[email protected]44d444c2013-01-30 01:47:449#include "ash/ash_constants.h"
[email protected]e6e41d2f2012-10-29 19:22:1910#include "ash/ash_switches.h"
[email protected]b4ddc7a2012-08-07 04:17:3211#include "ash/desktop_background/desktop_background_widget_controller.h"
[email protected]6bdf7952012-11-14 10:10:5812#include "ash/display/display_manager.h"
[email protected]e74aaf0a2012-10-12 18:42:2813#include "ash/focus_cycler.h"
[email protected]fcb123d2013-04-17 15:58:4914#include "ash/session_state_delegate.h"
[email protected]478c6c32013-03-09 02:50:5815#include "ash/shelf/shelf_layout_manager.h"
16#include "ash/shelf/shelf_types.h"
17#include "ash/shelf/shelf_widget.h"
[email protected]d90b8392012-06-13 09:34:5618#include "ash/shell.h"
[email protected]e74aaf0a2012-10-12 18:42:2819#include "ash/shell_delegate.h"
[email protected]d90b8392012-06-13 09:34:5620#include "ash/shell_factory.h"
21#include "ash/shell_window_ids.h"
[email protected]e74aaf0a2012-10-12 18:42:2822#include "ash/system/status_area_widget.h"
[email protected]8674b312012-10-12 19:02:4423#include "ash/system/tray/system_tray_delegate.h"
[email protected]2b8a9bb2013-07-01 22:43:4024#include "ash/touch/touch_hud_debug.h"
25#include "ash/touch/touch_hud_projection.h"
[email protected]80549c152013-07-02 01:42:4726#include "ash/touch/touch_observer_hud.h"
27#include "ash/wm/always_on_top_controller.h"
[email protected]d90b8392012-06-13 09:34:5628#include "ash/wm/base_layout_manager.h"
[email protected]bca9a7e2012-11-10 06:25:4929#include "ash/wm/boot_splash_screen.h"
[email protected]beb4e5c2013-06-18 15:37:0730#include "ash/wm/dock/docked_window_layout_manager.h"
[email protected]7095a652013-03-07 19:41:4931#include "ash/wm/panels/panel_layout_manager.h"
[email protected]100659412013-06-21 22:59:5532#include "ash/wm/panels/panel_window_event_handler.h"
[email protected]d90b8392012-06-13 09:34:5633#include "ash/wm/property_util.h"
34#include "ash/wm/root_window_layout_manager.h"
35#include "ash/wm/screen_dimmer.h"
[email protected]2a2caa02013-01-22 20:50:3636#include "ash/wm/stacking_controller.h"
[email protected]e74aaf0a2012-10-12 18:42:2837#include "ash/wm/status_area_layout_manager.h"
[email protected]e6e41d2f2012-10-29 19:22:1938#include "ash/wm/system_background_controller.h"
[email protected]d90b8392012-06-13 09:34:5639#include "ash/wm/system_modal_container_layout_manager.h"
[email protected]5dc51db82012-09-11 03:39:0140#include "ash/wm/toplevel_window_event_handler.h"
[email protected]8d625fb2012-07-18 16:40:0641#include "ash/wm/window_properties.h"
[email protected]700849f2013-04-30 17:49:2042#include "ash/wm/window_util.h"
[email protected]d90b8392012-06-13 09:34:5643#include "ash/wm/workspace_controller.h"
[email protected]e6e41d2f2012-10-29 19:22:1944#include "base/command_line.h"
[email protected]1e84c632013-06-27 23:12:2145#include "base/time/time.h"
[email protected]f1853122012-06-27 16:21:2646#include "ui/aura/client/aura_constants.h"
[email protected]d90b8392012-06-13 09:34:5647#include "ui/aura/client/tooltip_client.h"
48#include "ui/aura/root_window.h"
[email protected]f1853122012-06-27 16:21:2649#include "ui/aura/window.h"
50#include "ui/aura/window_observer.h"
[email protected]431552c2012-10-23 00:38:3351#include "ui/base/models/menu_model.h"
[email protected]8d625fb2012-07-18 16:40:0652#include "ui/gfx/screen.h"
[email protected]86459e2c2013-04-10 13:39:2453#include "ui/keyboard/keyboard_controller.h"
54#include "ui/keyboard/keyboard_util.h"
[email protected]431552c2012-10-23 00:38:3355#include "ui/views/controls/menu/menu_runner.h"
[email protected]b5756e22012-11-30 01:32:0256#include "ui/views/corewm/visibility_controller.h"
[email protected]431552c2012-10-23 00:38:3357#include "ui/views/view_model.h"
58#include "ui/views/view_model_utils.h"
[email protected]d90b8392012-06-13 09:34:5659
60namespace ash {
61namespace {
62
[email protected]bca9a7e2012-11-10 06:25:4963// Duration for the animation that hides the boot splash screen, in
64// milliseconds. This should be short enough in relation to
65// wm/window_animation.cc's brightness/grayscale fade animation that the login
66// background image animation isn't hidden by the splash screen animation.
67const int kBootSplashScreenHideDurationMs = 500;
68
[email protected]d90b8392012-06-13 09:34:5669// Creates a new window for use as a container.
70aura::Window* CreateContainer(int window_id,
71 const char* name,
72 aura::Window* parent) {
73 aura::Window* container = new aura::Window(NULL);
74 container->set_id(window_id);
75 container->SetName(name);
76 container->Init(ui::LAYER_NOT_DRAWN);
77 parent->AddChild(container);
78 if (window_id != internal::kShellWindowId_UnparentedControlContainer)
79 container->Show();
80 return container;
81}
82
[email protected]95058572012-08-20 14:57:2983// Returns all the children of the workspace windows, eg the standard top-level
84// windows.
85std::vector<aura::Window*> GetWorkspaceWindows(aura::RootWindow* root) {
86 using aura::Window;
87
88 std::vector<Window*> windows;
89 Window* container = Shell::GetContainer(
90 root, internal::kShellWindowId_DefaultContainer);
91 for (Window::Windows::const_reverse_iterator i =
92 container->children().rbegin();
93 i != container->children().rend(); ++i) {
94 Window* workspace_window = *i;
95 if (workspace_window->id() == internal::kShellWindowId_WorkspaceContainer) {
96 windows.insert(windows.end(), workspace_window->children().begin(),
97 workspace_window->children().end());
98 }
99 }
100 return windows;
101}
102
103// Reparents |window| to |new_parent|.
104void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
105 // Update the restore bounds to make it relative to the display.
106 gfx::Rect restore_bounds(GetRestoreBoundsInParent(window));
107 new_parent->AddChild(window);
108 if (!restore_bounds.IsEmpty())
109 SetRestoreBoundsInParent(window, restore_bounds);
110}
111
112// Reparents the appropriate set of windows from |src| to |dst|.
113void ReparentAllWindows(aura::RootWindow* src, aura::RootWindow* dst) {
114 // Set of windows to move.
[email protected]f1853122012-06-27 16:21:26115 const int kContainerIdsToMove[] = {
116 internal::kShellWindowId_DefaultContainer,
[email protected]beb4e5c2013-06-18 15:37:07117 internal::kShellWindowId_DockedContainer,
[email protected]95db9c12013-01-31 11:47:44118 internal::kShellWindowId_PanelContainer,
[email protected]f1853122012-06-27 16:21:26119 internal::kShellWindowId_AlwaysOnTopContainer,
120 internal::kShellWindowId_SystemModalContainer,
121 internal::kShellWindowId_LockSystemModalContainer,
[email protected]6274d312012-10-04 22:06:41122 internal::kShellWindowId_InputMethodContainer,
[email protected]a9754872013-01-25 07:44:00123 internal::kShellWindowId_UnparentedControlContainer,
[email protected]f1853122012-06-27 16:21:26124 };
[email protected]ef0e32cc2012-10-31 20:57:33125 // For workspace windows we need to manually reparent the windows. This way
126 // workspace can move the windows to the appropriate workspace.
[email protected]c96b9812012-10-17 16:04:04127 std::vector<aura::Window*> windows(GetWorkspaceWindows(src));
128 internal::WorkspaceController* workspace_controller =
129 GetRootWindowController(dst)->workspace_controller();
130 for (size_t i = 0; i < windows.size(); ++i) {
131 aura::Window* new_parent =
132 workspace_controller->GetParentForNewWindow(windows[i]);
133 ReparentWindow(windows[i], new_parent);
[email protected]95058572012-08-20 14:57:29134 }
[email protected]f1853122012-06-27 16:21:26135 for (size_t i = 0; i < arraysize(kContainerIdsToMove); i++) {
136 int id = kContainerIdsToMove[i];
[email protected]c96b9812012-10-17 16:04:04137 if (id == internal::kShellWindowId_DefaultContainer)
[email protected]95058572012-08-20 14:57:29138 continue;
139
[email protected]f1853122012-06-27 16:21:26140 aura::Window* src_container = Shell::GetContainer(src, id);
141 aura::Window* dst_container = Shell::GetContainer(dst, id);
[email protected]5b6021902013-02-26 05:33:29142 while (!src_container->children().empty()) {
143 // Restart iteration from the source container windows each time as they
144 // may change as a result of moving other windows.
145 aura::Window::Windows::const_iterator iter =
146 src_container->children().begin();
147 while (iter != src_container->children().end() &&
148 internal::SystemModalContainerLayoutManager::IsModalBackground(
149 *iter)) {
150 ++iter;
151 }
152 // If the entire window list is modal background windows then stop.
153 if (iter == src_container->children().end())
154 break;
155 ReparentWindow(*iter, dst_container);
[email protected]f1853122012-06-27 16:21:26156 }
157 }
158}
159
[email protected]8d625fb2012-07-18 16:40:06160// Mark the container window so that a widget added to this container will
161// use the virtual screeen coordinates instead of parent.
162void SetUsesScreenCoordinates(aura::Window* container) {
163 container->SetProperty(internal::kUsesScreenCoordinatesKey, true);
164}
165
[email protected]d90b8392012-06-13 09:34:56166} // namespace
167
168namespace internal {
169
170RootWindowController::RootWindowController(aura::RootWindow* root_window)
[email protected]e74aaf0a2012-10-12 18:42:28171 : root_window_(root_window),
172 root_window_layout_(NULL),
[email protected]beb4e5c2013-06-18 15:37:07173 docked_layout_manager_(NULL),
[email protected]bff17552013-04-25 04:44:55174 panel_layout_manager_(NULL),
[email protected]2b8a9bb2013-07-01 22:43:40175 touch_hud_debug_(NULL),
176 touch_hud_projection_(NULL) {
[email protected]d90b8392012-06-13 09:34:56177 SetRootWindowController(root_window, this);
[email protected]c0ce80e2012-10-05 23:28:27178 screen_dimmer_.reset(new ScreenDimmer(root_window));
[email protected]2a2caa02013-01-22 20:50:36179
180 stacking_controller_.reset(new ash::StackingController);
181 aura::client::SetStackingClient(root_window, stacking_controller_.get());
[email protected]d90b8392012-06-13 09:34:56182}
183
184RootWindowController::~RootWindowController() {
[email protected]6675e1c2012-09-11 09:15:45185 Shutdown();
186 root_window_.reset();
187}
188
[email protected]88d71122012-10-18 07:11:01189// static
[email protected]a0afeb12012-12-10 22:57:09190RootWindowController* RootWindowController::ForLauncher(aura::Window* window) {
[email protected]8c0ec432013-05-10 04:33:39191 return GetRootWindowController(window->GetRootWindow());
[email protected]88d71122012-10-18 07:11:01192}
193
[email protected]a0afeb12012-12-10 22:57:09194// static
[email protected]ccff3d72013-02-06 04:26:28195RootWindowController* RootWindowController::ForWindow(
196 const aura::Window* window) {
[email protected]a0afeb12012-12-10 22:57:09197 return GetRootWindowController(window->GetRootWindow());
198}
199
200// static
201RootWindowController* RootWindowController::ForActiveRootWindow() {
202 return GetRootWindowController(Shell::GetActiveRootWindow());
203}
204
[email protected]6675e1c2012-09-11 09:15:45205void RootWindowController::Shutdown() {
206 CloseChildWindows();
[email protected]7f7f65c2013-04-17 16:47:13207 if (Shell::GetActiveRootWindow() == root_window_) {
[email protected]f634dd32012-07-23 22:49:07208 Shell::GetInstance()->set_active_root_window(
209 Shell::GetPrimaryRootWindow() == root_window_.get() ?
210 NULL : Shell::GetPrimaryRootWindow());
211 }
[email protected]d90b8392012-06-13 09:34:56212 SetRootWindowController(root_window_.get(), NULL);
[email protected]d90b8392012-06-13 09:34:56213 screen_dimmer_.reset();
214 workspace_controller_.reset();
[email protected]6675e1c2012-09-11 09:15:45215 // Forget with the display ID so that display lookup
216 // ends up with invalid display.
217 root_window_->ClearProperty(kDisplayIdKey);
218 // And this root window should no longer process events.
219 root_window_->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28220
[email protected]956a6a42012-10-29 23:58:10221 system_background_.reset();
[email protected]d90b8392012-06-13 09:34:56222}
223
[email protected]c0ce80e2012-10-05 23:28:27224SystemModalContainerLayoutManager*
[email protected]8674b312012-10-12 19:02:44225RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
226 aura::Window* container = NULL;
227 if (window) {
[email protected]3b162e12012-11-09 11:52:35228 if (window->parent() &&
229 window->parent()->id() >= kShellWindowId_LockScreenContainer) {
230 container = GetContainer(kShellWindowId_LockSystemModalContainer);
231 } else {
[email protected]8674b312012-10-12 19:02:44232 container = GetContainer(kShellWindowId_SystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35233 }
[email protected]8674b312012-10-12 19:02:44234 } else {
[email protected]945f9cae2012-12-12 09:54:29235 user::LoginStatus login = Shell::GetInstance()->system_tray_delegate() ?
236 Shell::GetInstance()->system_tray_delegate()->GetUserLoginStatus() :
[email protected]8674b312012-10-12 19:02:44237 user::LOGGED_IN_NONE;
238 int modal_window_id = (login == user::LOGGED_IN_LOCKED ||
239 login == user::LOGGED_IN_NONE) ?
240 kShellWindowId_LockSystemModalContainer :
241 kShellWindowId_SystemModalContainer;
242 container = GetContainer(modal_window_id);
243 }
[email protected]bb0c7cd42013-05-20 23:39:45244 return container ? static_cast<SystemModalContainerLayoutManager*>(
245 container->layout_manager()) : NULL;
[email protected]c0ce80e2012-10-05 23:28:27246}
247
[email protected]d90b8392012-06-13 09:34:56248aura::Window* RootWindowController::GetContainer(int container_id) {
249 return root_window_->GetChildById(container_id);
250}
251
252void RootWindowController::InitLayoutManagers() {
253 root_window_layout_ =
[email protected]c0ce80e2012-10-05 23:28:27254 new RootWindowLayoutManager(root_window_.get());
[email protected]d90b8392012-06-13 09:34:56255 root_window_->SetLayoutManager(root_window_layout_);
256
257 aura::Window* default_container =
[email protected]c0ce80e2012-10-05 23:28:27258 GetContainer(kShellWindowId_DefaultContainer);
[email protected]d90b8392012-06-13 09:34:56259 // Workspace manager has its own layout managers.
260 workspace_controller_.reset(
[email protected]c0ce80e2012-10-05 23:28:27261 new WorkspaceController(default_container));
[email protected]d90b8392012-06-13 09:34:56262
263 aura::Window* always_on_top_container =
[email protected]c0ce80e2012-10-05 23:28:27264 GetContainer(kShellWindowId_AlwaysOnTopContainer);
[email protected]d90b8392012-06-13 09:34:56265 always_on_top_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27266 new BaseLayoutManager(
[email protected]d90b8392012-06-13 09:34:56267 always_on_top_container->GetRootWindow()));
[email protected]80549c152013-07-02 01:42:47268 always_on_top_controller_.reset(new internal::AlwaysOnTopController);
269 always_on_top_controller_->SetAlwaysOnTopContainer(always_on_top_container);
[email protected]d90b8392012-06-13 09:34:56270}
271
[email protected]e74aaf0a2012-10-12 18:42:28272void RootWindowController::InitForPrimaryDisplay() {
[email protected]478c6c32013-03-09 02:50:58273 DCHECK(!shelf_.get());
274 aura::Window* shelf_container =
275 GetContainer(ash::internal::kShellWindowId_ShelfContainer);
276 // TODO(harrym): Remove when status area is view.
[email protected]16059276d2012-10-22 18:59:50277 aura::Window* status_container =
278 GetContainer(ash::internal::kShellWindowId_StatusContainer);
[email protected]478c6c32013-03-09 02:50:58279 shelf_.reset(new ash::ShelfWidget(
280 shelf_container, status_container, workspace_controller()));
[email protected]e74aaf0a2012-10-12 18:42:28281
[email protected]beb4e5c2013-06-18 15:37:07282 // Create Docked windows layout manager
283 aura::Window* docked_container = GetContainer(
284 internal::kShellWindowId_DockedContainer);
285 docked_layout_manager_ =
286 new internal::DockedWindowLayoutManager(docked_container);
287 docked_container_handler_.reset(
288 new ToplevelWindowEventHandler(docked_container));
289 docked_container->SetLayoutManager(docked_layout_manager_);
290
[email protected]8c0ec432013-05-10 04:33:39291 // Create Panel layout manager
292 aura::Window* panel_container = GetContainer(
293 internal::kShellWindowId_PanelContainer);
294 panel_layout_manager_ =
295 new internal::PanelLayoutManager(panel_container);
296 panel_container_handler_.reset(
[email protected]100659412013-06-21 22:59:55297 new PanelWindowEventHandler(panel_container));
[email protected]8c0ec432013-05-10 04:33:39298 panel_container->SetLayoutManager(panel_layout_manager_);
299
[email protected]8e6986a2013-05-31 19:29:55300 // TODO(stevenjb/oshima): Remove this call to CreateLauncher() and call
301 // ash::Shell::CreateLauncher() explicitly in ash_shell and ash_unittests
302 // so that the behavior and construction order is consistent betwheen Ash
303 // and Chrome.
[email protected]c8d19f82013-05-18 09:09:41304 if (Shell::GetInstance()->session_state_delegate()->NumberOfLoggedInUsers())
[email protected]478c6c32013-03-09 02:50:58305 shelf_->CreateLauncher();
[email protected]86459e2c2013-04-10 13:39:24306
[email protected]86459e2c2013-04-10 13:39:24307 InitKeyboard();
[email protected]e74aaf0a2012-10-12 18:42:28308}
309
[email protected]d90b8392012-06-13 09:34:56310void RootWindowController::CreateContainers() {
311 CreateContainersInRootWindow(root_window_.get());
312}
313
[email protected]697f04c2012-10-03 01:15:10314void RootWindowController::CreateSystemBackground(
315 bool is_first_run_after_boot) {
[email protected]bca9a7e2012-11-10 06:25:49316 SkColor color = SK_ColorBLACK;
[email protected]697f04c2012-10-03 01:15:10317#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:49318 if (is_first_run_after_boot)
319 color = kChromeOsBootColor;
[email protected]697f04c2012-10-03 01:15:10320#endif
[email protected]e6e41d2f2012-10-29 19:22:19321 system_background_.reset(
[email protected]bca9a7e2012-11-10 06:25:49322 new SystemBackgroundController(root_window_.get(), color));
323
324#if defined(OS_CHROMEOS)
325 // Make a copy of the system's boot splash screen so we can composite it
326 // onscreen until the desktop background is ready.
327 if (is_first_run_after_boot &&
328 (CommandLine::ForCurrentProcess()->HasSwitch(
329 switches::kAshCopyHostBackgroundAtBoot) ||
330 CommandLine::ForCurrentProcess()->HasSwitch(
331 switches::kAshAnimateFromBootSplashScreen)))
332 boot_splash_screen_.reset(new BootSplashScreen(root_window_.get()));
333#endif
[email protected]697f04c2012-10-03 01:15:10334}
335
[email protected]478c6c32013-03-09 02:50:58336void RootWindowController::OnLauncherCreated() {
[email protected]e74aaf0a2012-10-12 18:42:28337 if (panel_layout_manager_)
[email protected]478c6c32013-03-09 02:50:58338 panel_layout_manager_->SetLauncher(shelf_->launcher());
[email protected]beb4e5c2013-06-18 15:37:07339 if (docked_layout_manager_)
340 docked_layout_manager_->SetLauncher(shelf_->launcher());
[email protected]e74aaf0a2012-10-12 18:42:28341}
342
343void RootWindowController::ShowLauncher() {
[email protected]80549c152013-07-02 01:42:47344 if (!shelf_->launcher())
[email protected]e74aaf0a2012-10-12 18:42:28345 return;
[email protected]478c6c32013-03-09 02:50:58346 shelf_->launcher()->SetVisible(true);
347 shelf_->status_area_widget()->Show();
[email protected]e74aaf0a2012-10-12 18:42:28348}
349
[email protected]16059276d2012-10-22 18:59:50350void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
[email protected]80549c152013-07-02 01:42:47351 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]16059276d2012-10-22 18:59:50352}
353
354void RootWindowController::UpdateAfterLoginStatusChange(
355 user::LoginStatus status) {
[email protected]80549c152013-07-02 01:42:47356 if (shelf_->status_area_widget())
[email protected]478c6c32013-03-09 02:50:58357 shelf_->status_area_widget()->UpdateAfterLoginStatusChange(status);
[email protected]16059276d2012-10-22 18:59:50358}
359
[email protected]bca9a7e2012-11-10 06:25:49360void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
361 if (CommandLine::ForCurrentProcess()->HasSwitch(
362 switches::kAshAnimateFromBootSplashScreen) &&
363 boot_splash_screen_.get()) {
364 // Make the splash screen fade out so it doesn't obscure the desktop
365 // wallpaper's brightness/grayscale animation.
366 boot_splash_screen_->StartHideAnimation(
367 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
368 }
369}
370
[email protected]697f04c2012-10-03 01:15:10371void RootWindowController::HandleDesktopBackgroundVisible() {
[email protected]bca9a7e2012-11-10 06:25:49372 system_background_->SetColor(SK_ColorBLACK);
373 boot_splash_screen_.reset();
[email protected]697f04c2012-10-03 01:15:10374}
375
[email protected]d90b8392012-06-13 09:34:56376void RootWindowController::CloseChildWindows() {
[email protected]80549c152013-07-02 01:42:47377 if (!shelf_.get())
378 return;
[email protected]79a87b7e2013-01-25 05:08:22379 // panel_layout_manager_ needs to be shut down before windows are destroyed.
380 if (panel_layout_manager_) {
381 panel_layout_manager_->Shutdown();
382 panel_layout_manager_ = NULL;
383 }
384
[email protected]478c6c32013-03-09 02:50:58385 // TODO(harrym): Remove when Status Area Widget is a child view.
[email protected]80549c152013-07-02 01:42:47386 shelf_->ShutdownStatusAreaWidget();
[email protected]478c6c32013-03-09 02:50:58387
[email protected]80549c152013-07-02 01:42:47388 if (shelf_->shelf_layout_manager())
[email protected]478c6c32013-03-09 02:50:58389 shelf_->shelf_layout_manager()->set_workspace_controller(NULL);
[email protected]e74aaf0a2012-10-12 18:42:28390
[email protected]d90b8392012-06-13 09:34:56391 // Close background widget first as it depends on tooltip.
[email protected]d86de6b22012-10-05 19:32:58392 root_window_->SetProperty(kDesktopController,
[email protected]b4ddc7a2012-08-07 04:17:32393 static_cast<DesktopBackgroundWidgetController*>(NULL));
[email protected]d86de6b22012-10-05 19:32:58394 root_window_->SetProperty(kAnimatingDesktopController,
395 static_cast<AnimatingDesktopController*>(NULL));
[email protected]b4ddc7a2012-08-07 04:17:32396
[email protected]d90b8392012-06-13 09:34:56397 workspace_controller_.reset();
398 aura::client::SetTooltipClient(root_window_.get(), NULL);
399
400 while (!root_window_->children().empty()) {
401 aura::Window* child = root_window_->children()[0];
402 delete child;
403 }
[email protected]478c6c32013-03-09 02:50:58404
405 shelf_.reset(NULL);
[email protected]d90b8392012-06-13 09:34:56406}
407
[email protected]f1853122012-06-27 16:21:26408void RootWindowController::MoveWindowsTo(aura::RootWindow* dst) {
[email protected]8039e06c2013-01-17 23:34:50409 // Forget the shelf early so that shelf don't update itself using wrong
410 // display info.
411 workspace_controller_->SetShelf(NULL);
[email protected]95058572012-08-20 14:57:29412 ReparentAllWindows(root_window_.get(), dst);
[email protected]f1853122012-06-27 16:21:26413}
414
[email protected]2b8a9bb2013-07-01 22:43:40415void RootWindowController::EnableTouchHudProjection() {
416 if (touch_hud_projection_)
417 return;
418 set_touch_hud_projection(new TouchHudProjection(root_window_.get()));
419}
420
421void RootWindowController::DisableTouchHudProjection() {
422 if (!touch_hud_projection_)
423 return;
424 touch_hud_projection_->Remove();
425}
426
[email protected]478c6c32013-03-09 02:50:58427ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
[email protected]80549c152013-07-02 01:42:47428 return shelf_->shelf_layout_manager();
[email protected]478c6c32013-03-09 02:50:58429}
430
[email protected]a0afeb12012-12-10 22:57:09431SystemTray* RootWindowController::GetSystemTray() {
432 // We assume in throughout the code that this will not return NULL. If code
433 // triggers this for valid reasons, it should test status_area_widget first.
[email protected]80549c152013-07-02 01:42:47434 CHECK(shelf_->status_area_widget());
[email protected]478c6c32013-03-09 02:50:58435 return shelf_->status_area_widget()->system_tray();
[email protected]a0afeb12012-12-10 22:57:09436}
437
[email protected]940fb1c2013-06-18 16:54:28438void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
439 ui::MenuSourceType source_type) {
[email protected]431552c2012-10-23 00:38:33440 DCHECK(Shell::GetInstance()->delegate());
441 scoped_ptr<ui::MenuModel> menu_model(
[email protected]8c0ec432013-05-10 04:33:39442 Shell::GetInstance()->delegate()->CreateContextMenu(root_window()));
[email protected]7f7f65c2013-04-17 16:47:13443 if (!menu_model)
[email protected]8e837ec2013-01-31 01:48:33444 return;
[email protected]431552c2012-10-23 00:38:33445
[email protected]6175fc42013-04-05 05:58:58446 internal::DesktopBackgroundWidgetController* background =
447 root_window_->GetProperty(kDesktopController);
448 // Background controller may not be set yet if user clicked on status are
449 // before initial animation completion. See crbug.com/222218
450 if (!background)
[email protected]431552c2012-10-23 00:38:33451 return;
452
[email protected]6175fc42013-04-05 05:58:58453 views::MenuRunner menu_runner(menu_model.get());
454 if (menu_runner.RunMenuAt(background->widget(),
455 NULL, gfx::Rect(location_in_screen, gfx::Size()),
[email protected]940fb1c2013-06-18 16:54:28456 views::MenuItemView::TOPLEFT, source_type,
457 views::MenuRunner::CONTEXT_MENU) ==
[email protected]6175fc42013-04-05 05:58:58458 views::MenuRunner::MENU_DELETED) {
459 return;
460 }
461
[email protected]431552c2012-10-23 00:38:33462 Shell::GetInstance()->UpdateShelfVisibility();
463}
464
[email protected]e74aaf0a2012-10-12 18:42:28465void RootWindowController::UpdateShelfVisibility() {
[email protected]478c6c32013-03-09 02:50:58466 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]e74aaf0a2012-10-12 18:42:28467}
468
[email protected]2b8a9bb2013-07-01 22:43:40469void RootWindowController::InitTouchHuds() {
470 CommandLine* command_line = CommandLine::ForCurrentProcess();
471 if (command_line->HasSwitch(switches::kAshTouchHud))
472 set_touch_hud_debug(new TouchHudDebug(root_window_.get()));
473 if (Shell::GetInstance()->is_touch_hud_projection_enabled())
474 EnableTouchHudProjection();
475}
476
[email protected]700849f2013-04-30 17:49:20477aura::Window* RootWindowController::GetFullscreenWindow() const {
[email protected]2ee2f5d2013-01-10 23:37:16478 aura::Window* container = workspace_controller_->GetActiveWorkspaceWindow();
479 for (size_t i = 0; i < container->children().size(); ++i) {
480 aura::Window* child = container->children()[i];
[email protected]700849f2013-04-30 17:49:20481 if (ash::wm::IsWindowFullscreen(child))
482 return child;
[email protected]2ee2f5d2013-01-10 23:37:16483 }
[email protected]700849f2013-04-30 17:49:20484 return NULL;
[email protected]2ee2f5d2013-01-10 23:37:16485}
486
[email protected]86459e2c2013-04-10 13:39:24487void RootWindowController::InitKeyboard() {
488 if (keyboard::IsKeyboardEnabled()) {
489 aura::Window* parent = root_window();
490
491 keyboard::KeyboardControllerProxy* proxy =
492 Shell::GetInstance()->delegate()->CreateKeyboardControllerProxy();
493 keyboard_controller_.reset(
494 new keyboard::KeyboardController(proxy));
[email protected]5416f282013-04-29 20:52:48495
496 keyboard_controller_->AddObserver(shelf()->shelf_layout_manager());
497 keyboard_controller_->AddObserver(panel_layout_manager_);
498
[email protected]86459e2c2013-04-10 13:39:24499 aura::Window* keyboard_container =
500 keyboard_controller_->GetContainerWindow();
501 parent->AddChild(keyboard_container);
[email protected]e0f71132013-04-17 12:32:51502 keyboard_container->SetBounds(parent->bounds());
[email protected]86459e2c2013-04-10 13:39:24503 }
504}
505
506
[email protected]a4cd6d32012-09-12 03:42:13507////////////////////////////////////////////////////////////////////////////////
508// RootWindowController, private:
509
510void RootWindowController::CreateContainersInRootWindow(
511 aura::RootWindow* root_window) {
512 // These containers are just used by PowerButtonController to animate groups
513 // of containers simultaneously without messing up the current transformations
514 // on those containers. These are direct children of the root window; all of
515 // the other containers are their children.
[email protected]e6e41d2f2012-10-29 19:22:19516
517 // The desktop background container is not part of the lock animation, so it
518 // is not included in those animate groups.
[email protected]a4cd6d32012-09-12 03:42:13519 // When screen is locked desktop background is moved to lock screen background
520 // container (moved back on unlock). We want to make sure that there's an
521 // opaque layer occluding the non-lock-screen layers.
[email protected]e6e41d2f2012-10-29 19:22:19522 aura::Window* desktop_background_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27523 kShellWindowId_DesktopBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13524 "DesktopBackgroundContainer",
525 root_window);
[email protected]b5756e22012-11-30 01:32:02526 views::corewm::SetChildWindowVisibilityChangesAnimated(
527 desktop_background_container);
[email protected]a4cd6d32012-09-12 03:42:13528
529 aura::Window* non_lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27530 kShellWindowId_NonLockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13531 "NonLockScreenContainersContainer",
532 root_window);
533
534 aura::Window* lock_background_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27535 kShellWindowId_LockScreenBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13536 "LockScreenBackgroundContainer",
537 root_window);
[email protected]b5756e22012-11-30 01:32:02538 views::corewm::SetChildWindowVisibilityChangesAnimated(
539 lock_background_containers);
[email protected]a4cd6d32012-09-12 03:42:13540
541 aura::Window* lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27542 kShellWindowId_LockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13543 "LockScreenContainersContainer",
544 root_window);
545 aura::Window* lock_screen_related_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27546 kShellWindowId_LockScreenRelatedContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13547 "LockScreenRelatedContainersContainer",
548 root_window);
549
[email protected]c0ce80e2012-10-05 23:28:27550 CreateContainer(kShellWindowId_UnparentedControlContainer,
[email protected]a4cd6d32012-09-12 03:42:13551 "UnparentedControlContainer",
552 non_lock_screen_containers);
553
554 aura::Window* default_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27555 kShellWindowId_DefaultContainer,
[email protected]a4cd6d32012-09-12 03:42:13556 "DefaultContainer",
557 non_lock_screen_containers);
[email protected]b5756e22012-11-30 01:32:02558 views::corewm::SetChildWindowVisibilityChangesAnimated(default_container);
[email protected]a4cd6d32012-09-12 03:42:13559 SetUsesScreenCoordinates(default_container);
560
561 aura::Window* always_on_top_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27562 kShellWindowId_AlwaysOnTopContainer,
[email protected]a4cd6d32012-09-12 03:42:13563 "AlwaysOnTopContainer",
564 non_lock_screen_containers);
565 always_on_top_container_handler_.reset(
566 new ToplevelWindowEventHandler(always_on_top_container));
[email protected]b5756e22012-11-30 01:32:02567 views::corewm::SetChildWindowVisibilityChangesAnimated(
568 always_on_top_container);
[email protected]a4cd6d32012-09-12 03:42:13569 SetUsesScreenCoordinates(always_on_top_container);
570
[email protected]beb4e5c2013-06-18 15:37:07571 aura::Window* docked_container = CreateContainer(
572 kShellWindowId_DockedContainer,
573 "DockedContainer",
574 non_lock_screen_containers);
575 SetUsesScreenCoordinates(docked_container);
576
[email protected]a4cd6d32012-09-12 03:42:13577 aura::Window* panel_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27578 kShellWindowId_PanelContainer,
[email protected]a4cd6d32012-09-12 03:42:13579 "PanelContainer",
580 non_lock_screen_containers);
581 SetUsesScreenCoordinates(panel_container);
582
583 aura::Window* launcher_container =
[email protected]478c6c32013-03-09 02:50:58584 CreateContainer(kShellWindowId_ShelfContainer,
[email protected]a4cd6d32012-09-12 03:42:13585 "LauncherContainer",
586 non_lock_screen_containers);
587 SetUsesScreenCoordinates(launcher_container);
588
[email protected]dc851a4e52012-10-03 00:05:55589 aura::Window* app_list_container =
[email protected]c0ce80e2012-10-05 23:28:27590 CreateContainer(kShellWindowId_AppListContainer,
[email protected]dc851a4e52012-10-03 00:05:55591 "AppListContainer",
592 non_lock_screen_containers);
593 SetUsesScreenCoordinates(app_list_container);
[email protected]a4cd6d32012-09-12 03:42:13594
595 aura::Window* modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27596 kShellWindowId_SystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13597 "SystemModalContainer",
598 non_lock_screen_containers);
599 modal_container_handler_.reset(
600 new ToplevelWindowEventHandler(modal_container));
[email protected]a4cd6d32012-09-12 03:42:13601 modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27602 new SystemModalContainerLayoutManager(modal_container));
[email protected]b5756e22012-11-30 01:32:02603 views::corewm::SetChildWindowVisibilityChangesAnimated(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13604 SetUsesScreenCoordinates(modal_container);
605
606 aura::Window* input_method_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27607 kShellWindowId_InputMethodContainer,
[email protected]a4cd6d32012-09-12 03:42:13608 "InputMethodContainer",
609 non_lock_screen_containers);
610 SetUsesScreenCoordinates(input_method_container);
611
612 // TODO(beng): Figure out if we can make this use
613 // SystemModalContainerEventFilter instead of stops_event_propagation.
614 aura::Window* lock_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27615 kShellWindowId_LockScreenContainer,
[email protected]a4cd6d32012-09-12 03:42:13616 "LockScreenContainer",
617 lock_screen_containers);
618 lock_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27619 new BaseLayoutManager(root_window));
[email protected]a4cd6d32012-09-12 03:42:13620 SetUsesScreenCoordinates(lock_container);
621 // TODO(beng): stopsevents
622
623 aura::Window* lock_modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27624 kShellWindowId_LockSystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13625 "LockSystemModalContainer",
626 lock_screen_containers);
627 lock_modal_container_handler_.reset(
628 new ToplevelWindowEventHandler(lock_modal_container));
[email protected]a4cd6d32012-09-12 03:42:13629 lock_modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27630 new SystemModalContainerLayoutManager(lock_modal_container));
[email protected]b5756e22012-11-30 01:32:02631 views::corewm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13632 SetUsesScreenCoordinates(lock_modal_container);
633
634 aura::Window* status_container =
[email protected]c0ce80e2012-10-05 23:28:27635 CreateContainer(kShellWindowId_StatusContainer,
[email protected]a4cd6d32012-09-12 03:42:13636 "StatusContainer",
637 lock_screen_related_containers);
638 SetUsesScreenCoordinates(status_container);
639
640 aura::Window* settings_bubble_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27641 kShellWindowId_SettingBubbleContainer,
[email protected]a4cd6d32012-09-12 03:42:13642 "SettingBubbleContainer",
643 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02644 views::corewm::SetChildWindowVisibilityChangesAnimated(
645 settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13646 SetUsesScreenCoordinates(settings_bubble_container);
647
648 aura::Window* menu_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27649 kShellWindowId_MenuContainer,
[email protected]a4cd6d32012-09-12 03:42:13650 "MenuContainer",
651 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02652 views::corewm::SetChildWindowVisibilityChangesAnimated(menu_container);
[email protected]a4cd6d32012-09-12 03:42:13653 SetUsesScreenCoordinates(menu_container);
654
655 aura::Window* drag_drop_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27656 kShellWindowId_DragImageAndTooltipContainer,
[email protected]a4cd6d32012-09-12 03:42:13657 "DragImageAndTooltipContainer",
658 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02659 views::corewm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
[email protected]a4cd6d32012-09-12 03:42:13660 SetUsesScreenCoordinates(drag_drop_container);
661
662 aura::Window* overlay_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27663 kShellWindowId_OverlayContainer,
[email protected]a4cd6d32012-09-12 03:42:13664 "OverlayContainer",
665 lock_screen_related_containers);
666 SetUsesScreenCoordinates(overlay_container);
[email protected]a07615f2012-10-24 08:23:08667
668 CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
669 "PowerButtonAnimationContainer", root_window) ;
[email protected]a4cd6d32012-09-12 03:42:13670}
671
[email protected]d90b8392012-06-13 09:34:56672} // namespace internal
673} // namespace ash