blob: 8e1d400eadca2be0c7f939e0cdc4f32a8e5c1203 [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]8d625fb2012-07-18 16:40:0612#include "ash/display/display_controller.h"
[email protected]6bdf7952012-11-14 10:10:5813#include "ash/display/display_manager.h"
[email protected]e74aaf0a2012-10-12 18:42:2814#include "ash/focus_cycler.h"
[email protected]fcb123d2013-04-17 15:58:4915#include "ash/session_state_delegate.h"
[email protected]478c6c32013-03-09 02:50:5816#include "ash/shelf/shelf_layout_manager.h"
17#include "ash/shelf/shelf_types.h"
18#include "ash/shelf/shelf_widget.h"
[email protected]d90b8392012-06-13 09:34:5619#include "ash/shell.h"
[email protected]e74aaf0a2012-10-12 18:42:2820#include "ash/shell_delegate.h"
[email protected]d90b8392012-06-13 09:34:5621#include "ash/shell_factory.h"
22#include "ash/shell_window_ids.h"
[email protected]e74aaf0a2012-10-12 18:42:2823#include "ash/system/status_area_widget.h"
[email protected]8674b312012-10-12 19:02:4424#include "ash/system/tray/system_tray_delegate.h"
[email protected]58175042013-04-01 19:27:1325#include "ash/touch/touch_observer_hud.h"
[email protected]d90b8392012-06-13 09:34:5626#include "ash/wm/base_layout_manager.h"
[email protected]bca9a7e2012-11-10 06:25:4927#include "ash/wm/boot_splash_screen.h"
[email protected]beb4e5c2013-06-18 15:37:0728#include "ash/wm/dock/docked_window_layout_manager.h"
[email protected]7095a652013-03-07 19:41:4929#include "ash/wm/panels/panel_layout_manager.h"
[email protected]d90b8392012-06-13 09:34:5630#include "ash/wm/property_util.h"
31#include "ash/wm/root_window_layout_manager.h"
32#include "ash/wm/screen_dimmer.h"
[email protected]2a2caa02013-01-22 20:50:3633#include "ash/wm/stacking_controller.h"
[email protected]e74aaf0a2012-10-12 18:42:2834#include "ash/wm/status_area_layout_manager.h"
[email protected]e6e41d2f2012-10-29 19:22:1935#include "ash/wm/system_background_controller.h"
[email protected]d90b8392012-06-13 09:34:5636#include "ash/wm/system_modal_container_layout_manager.h"
[email protected]5dc51db82012-09-11 03:39:0137#include "ash/wm/toplevel_window_event_handler.h"
[email protected]8d625fb2012-07-18 16:40:0638#include "ash/wm/window_properties.h"
[email protected]700849f2013-04-30 17:49:2039#include "ash/wm/window_util.h"
[email protected]d90b8392012-06-13 09:34:5640#include "ash/wm/workspace_controller.h"
[email protected]e6e41d2f2012-10-29 19:22:1941#include "base/command_line.h"
[email protected]bca9a7e2012-11-10 06:25:4942#include "base/time.h"
[email protected]f1853122012-06-27 16:21:2643#include "ui/aura/client/aura_constants.h"
[email protected]d90b8392012-06-13 09:34:5644#include "ui/aura/client/tooltip_client.h"
45#include "ui/aura/root_window.h"
[email protected]f1853122012-06-27 16:21:2646#include "ui/aura/window.h"
47#include "ui/aura/window_observer.h"
[email protected]431552c2012-10-23 00:38:3348#include "ui/base/models/menu_model.h"
[email protected]8d625fb2012-07-18 16:40:0649#include "ui/gfx/display.h"
50#include "ui/gfx/screen.h"
[email protected]86459e2c2013-04-10 13:39:2451#include "ui/keyboard/keyboard_controller.h"
52#include "ui/keyboard/keyboard_util.h"
[email protected]431552c2012-10-23 00:38:3353#include "ui/views/controls/menu/menu_runner.h"
[email protected]b5756e22012-11-30 01:32:0254#include "ui/views/corewm/visibility_controller.h"
[email protected]431552c2012-10-23 00:38:3355#include "ui/views/view_model.h"
56#include "ui/views/view_model_utils.h"
[email protected]d90b8392012-06-13 09:34:5657
58namespace ash {
59namespace {
60
[email protected]bca9a7e2012-11-10 06:25:4961// Duration for the animation that hides the boot splash screen, in
62// milliseconds. This should be short enough in relation to
63// wm/window_animation.cc's brightness/grayscale fade animation that the login
64// background image animation isn't hidden by the splash screen animation.
65const int kBootSplashScreenHideDurationMs = 500;
66
[email protected]d90b8392012-06-13 09:34:5667// Creates a new window for use as a container.
68aura::Window* CreateContainer(int window_id,
69 const char* name,
70 aura::Window* parent) {
71 aura::Window* container = new aura::Window(NULL);
72 container->set_id(window_id);
73 container->SetName(name);
74 container->Init(ui::LAYER_NOT_DRAWN);
75 parent->AddChild(container);
76 if (window_id != internal::kShellWindowId_UnparentedControlContainer)
77 container->Show();
78 return container;
79}
80
[email protected]95058572012-08-20 14:57:2981// Returns all the children of the workspace windows, eg the standard top-level
82// windows.
83std::vector<aura::Window*> GetWorkspaceWindows(aura::RootWindow* root) {
84 using aura::Window;
85
86 std::vector<Window*> windows;
87 Window* container = Shell::GetContainer(
88 root, internal::kShellWindowId_DefaultContainer);
89 for (Window::Windows::const_reverse_iterator i =
90 container->children().rbegin();
91 i != container->children().rend(); ++i) {
92 Window* workspace_window = *i;
93 if (workspace_window->id() == internal::kShellWindowId_WorkspaceContainer) {
94 windows.insert(windows.end(), workspace_window->children().begin(),
95 workspace_window->children().end());
96 }
97 }
98 return windows;
99}
100
101// Reparents |window| to |new_parent|.
102void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
103 // Update the restore bounds to make it relative to the display.
104 gfx::Rect restore_bounds(GetRestoreBoundsInParent(window));
105 new_parent->AddChild(window);
106 if (!restore_bounds.IsEmpty())
107 SetRestoreBoundsInParent(window, restore_bounds);
108}
109
110// Reparents the appropriate set of windows from |src| to |dst|.
111void ReparentAllWindows(aura::RootWindow* src, aura::RootWindow* dst) {
112 // Set of windows to move.
[email protected]f1853122012-06-27 16:21:26113 const int kContainerIdsToMove[] = {
114 internal::kShellWindowId_DefaultContainer,
[email protected]beb4e5c2013-06-18 15:37:07115 internal::kShellWindowId_DockedContainer,
[email protected]95db9c12013-01-31 11:47:44116 internal::kShellWindowId_PanelContainer,
[email protected]f1853122012-06-27 16:21:26117 internal::kShellWindowId_AlwaysOnTopContainer,
118 internal::kShellWindowId_SystemModalContainer,
119 internal::kShellWindowId_LockSystemModalContainer,
[email protected]6274d312012-10-04 22:06:41120 internal::kShellWindowId_InputMethodContainer,
[email protected]a9754872013-01-25 07:44:00121 internal::kShellWindowId_UnparentedControlContainer,
[email protected]f1853122012-06-27 16:21:26122 };
[email protected]ef0e32cc2012-10-31 20:57:33123 // For workspace windows we need to manually reparent the windows. This way
124 // workspace can move the windows to the appropriate workspace.
[email protected]c96b9812012-10-17 16:04:04125 std::vector<aura::Window*> windows(GetWorkspaceWindows(src));
126 internal::WorkspaceController* workspace_controller =
127 GetRootWindowController(dst)->workspace_controller();
128 for (size_t i = 0; i < windows.size(); ++i) {
129 aura::Window* new_parent =
130 workspace_controller->GetParentForNewWindow(windows[i]);
131 ReparentWindow(windows[i], new_parent);
[email protected]95058572012-08-20 14:57:29132 }
[email protected]f1853122012-06-27 16:21:26133 for (size_t i = 0; i < arraysize(kContainerIdsToMove); i++) {
134 int id = kContainerIdsToMove[i];
[email protected]c96b9812012-10-17 16:04:04135 if (id == internal::kShellWindowId_DefaultContainer)
[email protected]95058572012-08-20 14:57:29136 continue;
137
[email protected]f1853122012-06-27 16:21:26138 aura::Window* src_container = Shell::GetContainer(src, id);
139 aura::Window* dst_container = Shell::GetContainer(dst, id);
[email protected]5b6021902013-02-26 05:33:29140 while (!src_container->children().empty()) {
141 // Restart iteration from the source container windows each time as they
142 // may change as a result of moving other windows.
143 aura::Window::Windows::const_iterator iter =
144 src_container->children().begin();
145 while (iter != src_container->children().end() &&
146 internal::SystemModalContainerLayoutManager::IsModalBackground(
147 *iter)) {
148 ++iter;
149 }
150 // If the entire window list is modal background windows then stop.
151 if (iter == src_container->children().end())
152 break;
153 ReparentWindow(*iter, dst_container);
[email protected]f1853122012-06-27 16:21:26154 }
155 }
156}
157
[email protected]8d625fb2012-07-18 16:40:06158// Mark the container window so that a widget added to this container will
159// use the virtual screeen coordinates instead of parent.
160void SetUsesScreenCoordinates(aura::Window* container) {
161 container->SetProperty(internal::kUsesScreenCoordinatesKey, true);
162}
163
[email protected]d90b8392012-06-13 09:34:56164} // namespace
165
166namespace internal {
167
168RootWindowController::RootWindowController(aura::RootWindow* root_window)
[email protected]e74aaf0a2012-10-12 18:42:28169 : root_window_(root_window),
170 root_window_layout_(NULL),
[email protected]beb4e5c2013-06-18 15:37:07171 docked_layout_manager_(NULL),
[email protected]bff17552013-04-25 04:44:55172 panel_layout_manager_(NULL),
173 touch_observer_hud_(NULL) {
[email protected]d90b8392012-06-13 09:34:56174 SetRootWindowController(root_window, this);
[email protected]c0ce80e2012-10-05 23:28:27175 screen_dimmer_.reset(new ScreenDimmer(root_window));
[email protected]2a2caa02013-01-22 20:50:36176
177 stacking_controller_.reset(new ash::StackingController);
178 aura::client::SetStackingClient(root_window, stacking_controller_.get());
[email protected]d90b8392012-06-13 09:34:56179}
180
181RootWindowController::~RootWindowController() {
[email protected]6675e1c2012-09-11 09:15:45182 Shutdown();
183 root_window_.reset();
184}
185
[email protected]88d71122012-10-18 07:11:01186// static
[email protected]a0afeb12012-12-10 22:57:09187RootWindowController* RootWindowController::ForLauncher(aura::Window* window) {
[email protected]8c0ec432013-05-10 04:33:39188 return GetRootWindowController(window->GetRootWindow());
[email protected]88d71122012-10-18 07:11:01189}
190
[email protected]a0afeb12012-12-10 22:57:09191// static
[email protected]ccff3d72013-02-06 04:26:28192RootWindowController* RootWindowController::ForWindow(
193 const aura::Window* window) {
[email protected]a0afeb12012-12-10 22:57:09194 return GetRootWindowController(window->GetRootWindow());
195}
196
197// static
198RootWindowController* RootWindowController::ForActiveRootWindow() {
199 return GetRootWindowController(Shell::GetActiveRootWindow());
200}
201
[email protected]6675e1c2012-09-11 09:15:45202void RootWindowController::Shutdown() {
203 CloseChildWindows();
[email protected]7f7f65c2013-04-17 16:47:13204 if (Shell::GetActiveRootWindow() == root_window_) {
[email protected]f634dd32012-07-23 22:49:07205 Shell::GetInstance()->set_active_root_window(
206 Shell::GetPrimaryRootWindow() == root_window_.get() ?
207 NULL : Shell::GetPrimaryRootWindow());
208 }
[email protected]d90b8392012-06-13 09:34:56209 SetRootWindowController(root_window_.get(), NULL);
[email protected]d90b8392012-06-13 09:34:56210 screen_dimmer_.reset();
211 workspace_controller_.reset();
[email protected]6675e1c2012-09-11 09:15:45212 // Forget with the display ID so that display lookup
213 // ends up with invalid display.
214 root_window_->ClearProperty(kDisplayIdKey);
215 // And this root window should no longer process events.
216 root_window_->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28217
[email protected]956a6a42012-10-29 23:58:10218 system_background_.reset();
[email protected]d90b8392012-06-13 09:34:56219}
220
[email protected]c0ce80e2012-10-05 23:28:27221SystemModalContainerLayoutManager*
[email protected]8674b312012-10-12 19:02:44222RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
223 aura::Window* container = NULL;
224 if (window) {
[email protected]3b162e12012-11-09 11:52:35225 if (window->parent() &&
226 window->parent()->id() >= kShellWindowId_LockScreenContainer) {
227 container = GetContainer(kShellWindowId_LockSystemModalContainer);
228 } else {
[email protected]8674b312012-10-12 19:02:44229 container = GetContainer(kShellWindowId_SystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35230 }
[email protected]8674b312012-10-12 19:02:44231 } else {
[email protected]945f9cae2012-12-12 09:54:29232 user::LoginStatus login = Shell::GetInstance()->system_tray_delegate() ?
233 Shell::GetInstance()->system_tray_delegate()->GetUserLoginStatus() :
[email protected]8674b312012-10-12 19:02:44234 user::LOGGED_IN_NONE;
235 int modal_window_id = (login == user::LOGGED_IN_LOCKED ||
236 login == user::LOGGED_IN_NONE) ?
237 kShellWindowId_LockSystemModalContainer :
238 kShellWindowId_SystemModalContainer;
239 container = GetContainer(modal_window_id);
240 }
[email protected]bb0c7cd42013-05-20 23:39:45241 return container ? static_cast<SystemModalContainerLayoutManager*>(
242 container->layout_manager()) : NULL;
[email protected]c0ce80e2012-10-05 23:28:27243}
244
[email protected]d90b8392012-06-13 09:34:56245aura::Window* RootWindowController::GetContainer(int container_id) {
246 return root_window_->GetChildById(container_id);
247}
248
249void RootWindowController::InitLayoutManagers() {
250 root_window_layout_ =
[email protected]c0ce80e2012-10-05 23:28:27251 new RootWindowLayoutManager(root_window_.get());
[email protected]d90b8392012-06-13 09:34:56252 root_window_->SetLayoutManager(root_window_layout_);
253
254 aura::Window* default_container =
[email protected]c0ce80e2012-10-05 23:28:27255 GetContainer(kShellWindowId_DefaultContainer);
[email protected]d90b8392012-06-13 09:34:56256 // Workspace manager has its own layout managers.
257 workspace_controller_.reset(
[email protected]c0ce80e2012-10-05 23:28:27258 new WorkspaceController(default_container));
[email protected]d90b8392012-06-13 09:34:56259
260 aura::Window* always_on_top_container =
[email protected]c0ce80e2012-10-05 23:28:27261 GetContainer(kShellWindowId_AlwaysOnTopContainer);
[email protected]d90b8392012-06-13 09:34:56262 always_on_top_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27263 new BaseLayoutManager(
[email protected]d90b8392012-06-13 09:34:56264 always_on_top_container->GetRootWindow()));
265}
266
[email protected]e74aaf0a2012-10-12 18:42:28267void RootWindowController::InitForPrimaryDisplay() {
[email protected]478c6c32013-03-09 02:50:58268 DCHECK(!shelf_.get());
269 aura::Window* shelf_container =
270 GetContainer(ash::internal::kShellWindowId_ShelfContainer);
271 // TODO(harrym): Remove when status area is view.
[email protected]16059276d2012-10-22 18:59:50272 aura::Window* status_container =
273 GetContainer(ash::internal::kShellWindowId_StatusContainer);
[email protected]478c6c32013-03-09 02:50:58274 shelf_.reset(new ash::ShelfWidget(
275 shelf_container, status_container, workspace_controller()));
[email protected]e74aaf0a2012-10-12 18:42:28276
[email protected]beb4e5c2013-06-18 15:37:07277 // Create Docked windows layout manager
278 aura::Window* docked_container = GetContainer(
279 internal::kShellWindowId_DockedContainer);
280 docked_layout_manager_ =
281 new internal::DockedWindowLayoutManager(docked_container);
282 docked_container_handler_.reset(
283 new ToplevelWindowEventHandler(docked_container));
284 docked_container->SetLayoutManager(docked_layout_manager_);
285
[email protected]8c0ec432013-05-10 04:33:39286 // Create Panel layout manager
287 aura::Window* panel_container = GetContainer(
288 internal::kShellWindowId_PanelContainer);
289 panel_layout_manager_ =
290 new internal::PanelLayoutManager(panel_container);
291 panel_container_handler_.reset(
292 new ToplevelWindowEventHandler(panel_container));
293 panel_container->SetLayoutManager(panel_layout_manager_);
294
[email protected]8e6986a2013-05-31 19:29:55295 // TODO(stevenjb/oshima): Remove this call to CreateLauncher() and call
296 // ash::Shell::CreateLauncher() explicitly in ash_shell and ash_unittests
297 // so that the behavior and construction order is consistent betwheen Ash
298 // and Chrome.
[email protected]c8d19f82013-05-18 09:09:41299 if (Shell::GetInstance()->session_state_delegate()->NumberOfLoggedInUsers())
[email protected]478c6c32013-03-09 02:50:58300 shelf_->CreateLauncher();
[email protected]86459e2c2013-04-10 13:39:24301
[email protected]86459e2c2013-04-10 13:39:24302 InitKeyboard();
[email protected]e74aaf0a2012-10-12 18:42:28303}
304
[email protected]d90b8392012-06-13 09:34:56305void RootWindowController::CreateContainers() {
306 CreateContainersInRootWindow(root_window_.get());
[email protected]58175042013-04-01 19:27:13307
308 // Create touch observer HUD if needed. HUD should be created after the
309 // containers have been created, so that its widget can be added to them.
310 CommandLine* command_line = CommandLine::ForCurrentProcess();
[email protected]bff17552013-04-25 04:44:55311 if (command_line->HasSwitch(switches::kAshTouchHud))
312 touch_observer_hud_ = new TouchObserverHUD(root_window_.get());
[email protected]d90b8392012-06-13 09:34:56313}
314
[email protected]697f04c2012-10-03 01:15:10315void RootWindowController::CreateSystemBackground(
316 bool is_first_run_after_boot) {
[email protected]bca9a7e2012-11-10 06:25:49317 SkColor color = SK_ColorBLACK;
[email protected]697f04c2012-10-03 01:15:10318#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:49319 if (is_first_run_after_boot)
320 color = kChromeOsBootColor;
[email protected]697f04c2012-10-03 01:15:10321#endif
[email protected]e6e41d2f2012-10-29 19:22:19322 system_background_.reset(
[email protected]bca9a7e2012-11-10 06:25:49323 new SystemBackgroundController(root_window_.get(), color));
324
325#if defined(OS_CHROMEOS)
326 // Make a copy of the system's boot splash screen so we can composite it
327 // onscreen until the desktop background is ready.
328 if (is_first_run_after_boot &&
329 (CommandLine::ForCurrentProcess()->HasSwitch(
330 switches::kAshCopyHostBackgroundAtBoot) ||
331 CommandLine::ForCurrentProcess()->HasSwitch(
332 switches::kAshAnimateFromBootSplashScreen)))
333 boot_splash_screen_.reset(new BootSplashScreen(root_window_.get()));
334#endif
[email protected]697f04c2012-10-03 01:15:10335}
336
[email protected]478c6c32013-03-09 02:50:58337void RootWindowController::OnLauncherCreated() {
[email protected]e74aaf0a2012-10-12 18:42:28338 if (panel_layout_manager_)
[email protected]478c6c32013-03-09 02:50:58339 panel_layout_manager_->SetLauncher(shelf_->launcher());
[email protected]beb4e5c2013-06-18 15:37:07340 if (docked_layout_manager_)
341 docked_layout_manager_->SetLauncher(shelf_->launcher());
[email protected]e74aaf0a2012-10-12 18:42:28342}
343
344void RootWindowController::ShowLauncher() {
[email protected]478c6c32013-03-09 02:50:58345 if (!shelf_.get() || !shelf_->launcher())
[email protected]e74aaf0a2012-10-12 18:42:28346 return;
[email protected]478c6c32013-03-09 02:50:58347 shelf_->launcher()->SetVisible(true);
348 shelf_->status_area_widget()->Show();
[email protected]e74aaf0a2012-10-12 18:42:28349}
350
[email protected]16059276d2012-10-22 18:59:50351void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
352 // TODO(oshima): remove if when launcher per display is enabled by
353 // default.
[email protected]7f7f65c2013-04-17 16:47:13354 if (shelf_)
[email protected]478c6c32013-03-09 02:50:58355 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]16059276d2012-10-22 18:59:50356}
357
358void RootWindowController::UpdateAfterLoginStatusChange(
359 user::LoginStatus status) {
[email protected]478c6c32013-03-09 02:50:58360 if (shelf_.get() && shelf_->status_area_widget())
361 shelf_->status_area_widget()->UpdateAfterLoginStatusChange(status);
[email protected]16059276d2012-10-22 18:59:50362}
363
[email protected]bca9a7e2012-11-10 06:25:49364void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
365 if (CommandLine::ForCurrentProcess()->HasSwitch(
366 switches::kAshAnimateFromBootSplashScreen) &&
367 boot_splash_screen_.get()) {
368 // Make the splash screen fade out so it doesn't obscure the desktop
369 // wallpaper's brightness/grayscale animation.
370 boot_splash_screen_->StartHideAnimation(
371 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
372 }
373}
374
[email protected]697f04c2012-10-03 01:15:10375void RootWindowController::HandleDesktopBackgroundVisible() {
[email protected]bca9a7e2012-11-10 06:25:49376 system_background_->SetColor(SK_ColorBLACK);
377 boot_splash_screen_.reset();
[email protected]697f04c2012-10-03 01:15:10378}
379
[email protected]d90b8392012-06-13 09:34:56380void RootWindowController::CloseChildWindows() {
[email protected]79a87b7e2013-01-25 05:08:22381 // panel_layout_manager_ needs to be shut down before windows are destroyed.
382 if (panel_layout_manager_) {
383 panel_layout_manager_->Shutdown();
384 panel_layout_manager_ = NULL;
385 }
386
[email protected]478c6c32013-03-09 02:50:58387 // TODO(harrym): Remove when Status Area Widget is a child view.
[email protected]7f7f65c2013-04-17 16:47:13388 if (shelf_)
[email protected]478c6c32013-03-09 02:50:58389 shelf_->ShutdownStatusAreaWidget();
390
391 if (shelf_.get() && shelf_->shelf_layout_manager())
392 shelf_->shelf_layout_manager()->set_workspace_controller(NULL);
[email protected]e74aaf0a2012-10-12 18:42:28393
[email protected]d90b8392012-06-13 09:34:56394 // Close background widget first as it depends on tooltip.
[email protected]d86de6b22012-10-05 19:32:58395 root_window_->SetProperty(kDesktopController,
[email protected]b4ddc7a2012-08-07 04:17:32396 static_cast<DesktopBackgroundWidgetController*>(NULL));
[email protected]d86de6b22012-10-05 19:32:58397 root_window_->SetProperty(kAnimatingDesktopController,
398 static_cast<AnimatingDesktopController*>(NULL));
[email protected]b4ddc7a2012-08-07 04:17:32399
[email protected]d90b8392012-06-13 09:34:56400 workspace_controller_.reset();
401 aura::client::SetTooltipClient(root_window_.get(), NULL);
402
403 while (!root_window_->children().empty()) {
404 aura::Window* child = root_window_->children()[0];
405 delete child;
406 }
[email protected]478c6c32013-03-09 02:50:58407
408 shelf_.reset(NULL);
[email protected]d90b8392012-06-13 09:34:56409}
410
[email protected]f1853122012-06-27 16:21:26411void RootWindowController::MoveWindowsTo(aura::RootWindow* dst) {
[email protected]8039e06c2013-01-17 23:34:50412 // Forget the shelf early so that shelf don't update itself using wrong
413 // display info.
414 workspace_controller_->SetShelf(NULL);
[email protected]95058572012-08-20 14:57:29415 ReparentAllWindows(root_window_.get(), dst);
[email protected]f1853122012-06-27 16:21:26416}
417
[email protected]478c6c32013-03-09 02:50:58418ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
419 return shelf_.get() ? shelf_->shelf_layout_manager() : NULL;
420}
421
[email protected]a0afeb12012-12-10 22:57:09422SystemTray* RootWindowController::GetSystemTray() {
423 // We assume in throughout the code that this will not return NULL. If code
424 // triggers this for valid reasons, it should test status_area_widget first.
[email protected]478c6c32013-03-09 02:50:58425 CHECK(shelf_.get() && shelf_->status_area_widget());
426 return shelf_->status_area_widget()->system_tray();
[email protected]a0afeb12012-12-10 22:57:09427}
428
[email protected]431552c2012-10-23 00:38:33429void RootWindowController::ShowContextMenu(
430 const gfx::Point& location_in_screen) {
[email protected]431552c2012-10-23 00:38:33431 DCHECK(Shell::GetInstance()->delegate());
432 scoped_ptr<ui::MenuModel> menu_model(
[email protected]8c0ec432013-05-10 04:33:39433 Shell::GetInstance()->delegate()->CreateContextMenu(root_window()));
[email protected]7f7f65c2013-04-17 16:47:13434 if (!menu_model)
[email protected]8e837ec2013-01-31 01:48:33435 return;
[email protected]431552c2012-10-23 00:38:33436
[email protected]6175fc42013-04-05 05:58:58437 internal::DesktopBackgroundWidgetController* background =
438 root_window_->GetProperty(kDesktopController);
439 // Background controller may not be set yet if user clicked on status are
440 // before initial animation completion. See crbug.com/222218
441 if (!background)
[email protected]431552c2012-10-23 00:38:33442 return;
443
[email protected]6175fc42013-04-05 05:58:58444 views::MenuRunner menu_runner(menu_model.get());
445 if (menu_runner.RunMenuAt(background->widget(),
446 NULL, gfx::Rect(location_in_screen, gfx::Size()),
447 views::MenuItemView::TOPLEFT, views::MenuRunner::CONTEXT_MENU) ==
448 views::MenuRunner::MENU_DELETED) {
449 return;
450 }
451
[email protected]431552c2012-10-23 00:38:33452 Shell::GetInstance()->UpdateShelfVisibility();
453}
454
[email protected]e74aaf0a2012-10-12 18:42:28455void RootWindowController::UpdateShelfVisibility() {
[email protected]478c6c32013-03-09 02:50:58456 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]e74aaf0a2012-10-12 18:42:28457}
458
[email protected]700849f2013-04-30 17:49:20459aura::Window* RootWindowController::GetFullscreenWindow() const {
[email protected]2ee2f5d2013-01-10 23:37:16460 aura::Window* container = workspace_controller_->GetActiveWorkspaceWindow();
461 for (size_t i = 0; i < container->children().size(); ++i) {
462 aura::Window* child = container->children()[i];
[email protected]700849f2013-04-30 17:49:20463 if (ash::wm::IsWindowFullscreen(child))
464 return child;
[email protected]2ee2f5d2013-01-10 23:37:16465 }
[email protected]700849f2013-04-30 17:49:20466 return NULL;
[email protected]2ee2f5d2013-01-10 23:37:16467}
468
[email protected]86459e2c2013-04-10 13:39:24469void RootWindowController::InitKeyboard() {
470 if (keyboard::IsKeyboardEnabled()) {
471 aura::Window* parent = root_window();
472
473 keyboard::KeyboardControllerProxy* proxy =
474 Shell::GetInstance()->delegate()->CreateKeyboardControllerProxy();
475 keyboard_controller_.reset(
476 new keyboard::KeyboardController(proxy));
[email protected]5416f282013-04-29 20:52:48477
478 keyboard_controller_->AddObserver(shelf()->shelf_layout_manager());
479 keyboard_controller_->AddObserver(panel_layout_manager_);
480
[email protected]86459e2c2013-04-10 13:39:24481 aura::Window* keyboard_container =
482 keyboard_controller_->GetContainerWindow();
483 parent->AddChild(keyboard_container);
[email protected]e0f71132013-04-17 12:32:51484 keyboard_container->SetBounds(parent->bounds());
[email protected]86459e2c2013-04-10 13:39:24485 }
486}
487
488
[email protected]a4cd6d32012-09-12 03:42:13489////////////////////////////////////////////////////////////////////////////////
490// RootWindowController, private:
491
492void RootWindowController::CreateContainersInRootWindow(
493 aura::RootWindow* root_window) {
494 // These containers are just used by PowerButtonController to animate groups
495 // of containers simultaneously without messing up the current transformations
496 // on those containers. These are direct children of the root window; all of
497 // the other containers are their children.
[email protected]e6e41d2f2012-10-29 19:22:19498
499 // The desktop background container is not part of the lock animation, so it
500 // is not included in those animate groups.
[email protected]a4cd6d32012-09-12 03:42:13501 // When screen is locked desktop background is moved to lock screen background
502 // container (moved back on unlock). We want to make sure that there's an
503 // opaque layer occluding the non-lock-screen layers.
[email protected]e6e41d2f2012-10-29 19:22:19504 aura::Window* desktop_background_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27505 kShellWindowId_DesktopBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13506 "DesktopBackgroundContainer",
507 root_window);
[email protected]b5756e22012-11-30 01:32:02508 views::corewm::SetChildWindowVisibilityChangesAnimated(
509 desktop_background_container);
[email protected]a4cd6d32012-09-12 03:42:13510
511 aura::Window* non_lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27512 kShellWindowId_NonLockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13513 "NonLockScreenContainersContainer",
514 root_window);
515
516 aura::Window* lock_background_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27517 kShellWindowId_LockScreenBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13518 "LockScreenBackgroundContainer",
519 root_window);
[email protected]b5756e22012-11-30 01:32:02520 views::corewm::SetChildWindowVisibilityChangesAnimated(
521 lock_background_containers);
[email protected]a4cd6d32012-09-12 03:42:13522
523 aura::Window* lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27524 kShellWindowId_LockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13525 "LockScreenContainersContainer",
526 root_window);
527 aura::Window* lock_screen_related_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27528 kShellWindowId_LockScreenRelatedContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13529 "LockScreenRelatedContainersContainer",
530 root_window);
531
[email protected]c0ce80e2012-10-05 23:28:27532 CreateContainer(kShellWindowId_UnparentedControlContainer,
[email protected]a4cd6d32012-09-12 03:42:13533 "UnparentedControlContainer",
534 non_lock_screen_containers);
535
536 aura::Window* default_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27537 kShellWindowId_DefaultContainer,
[email protected]a4cd6d32012-09-12 03:42:13538 "DefaultContainer",
539 non_lock_screen_containers);
[email protected]b5756e22012-11-30 01:32:02540 views::corewm::SetChildWindowVisibilityChangesAnimated(default_container);
[email protected]a4cd6d32012-09-12 03:42:13541 SetUsesScreenCoordinates(default_container);
542
543 aura::Window* always_on_top_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27544 kShellWindowId_AlwaysOnTopContainer,
[email protected]a4cd6d32012-09-12 03:42:13545 "AlwaysOnTopContainer",
546 non_lock_screen_containers);
547 always_on_top_container_handler_.reset(
548 new ToplevelWindowEventHandler(always_on_top_container));
[email protected]b5756e22012-11-30 01:32:02549 views::corewm::SetChildWindowVisibilityChangesAnimated(
550 always_on_top_container);
[email protected]a4cd6d32012-09-12 03:42:13551 SetUsesScreenCoordinates(always_on_top_container);
552
[email protected]beb4e5c2013-06-18 15:37:07553 aura::Window* docked_container = CreateContainer(
554 kShellWindowId_DockedContainer,
555 "DockedContainer",
556 non_lock_screen_containers);
557 SetUsesScreenCoordinates(docked_container);
558
[email protected]a4cd6d32012-09-12 03:42:13559 aura::Window* panel_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27560 kShellWindowId_PanelContainer,
[email protected]a4cd6d32012-09-12 03:42:13561 "PanelContainer",
562 non_lock_screen_containers);
563 SetUsesScreenCoordinates(panel_container);
564
565 aura::Window* launcher_container =
[email protected]478c6c32013-03-09 02:50:58566 CreateContainer(kShellWindowId_ShelfContainer,
[email protected]a4cd6d32012-09-12 03:42:13567 "LauncherContainer",
568 non_lock_screen_containers);
569 SetUsesScreenCoordinates(launcher_container);
570
[email protected]dc851a4e52012-10-03 00:05:55571 aura::Window* app_list_container =
[email protected]c0ce80e2012-10-05 23:28:27572 CreateContainer(kShellWindowId_AppListContainer,
[email protected]dc851a4e52012-10-03 00:05:55573 "AppListContainer",
574 non_lock_screen_containers);
575 SetUsesScreenCoordinates(app_list_container);
[email protected]a4cd6d32012-09-12 03:42:13576
577 aura::Window* modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27578 kShellWindowId_SystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13579 "SystemModalContainer",
580 non_lock_screen_containers);
581 modal_container_handler_.reset(
582 new ToplevelWindowEventHandler(modal_container));
[email protected]a4cd6d32012-09-12 03:42:13583 modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27584 new SystemModalContainerLayoutManager(modal_container));
[email protected]b5756e22012-11-30 01:32:02585 views::corewm::SetChildWindowVisibilityChangesAnimated(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13586 SetUsesScreenCoordinates(modal_container);
587
588 aura::Window* input_method_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27589 kShellWindowId_InputMethodContainer,
[email protected]a4cd6d32012-09-12 03:42:13590 "InputMethodContainer",
591 non_lock_screen_containers);
592 SetUsesScreenCoordinates(input_method_container);
593
594 // TODO(beng): Figure out if we can make this use
595 // SystemModalContainerEventFilter instead of stops_event_propagation.
596 aura::Window* lock_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27597 kShellWindowId_LockScreenContainer,
[email protected]a4cd6d32012-09-12 03:42:13598 "LockScreenContainer",
599 lock_screen_containers);
600 lock_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27601 new BaseLayoutManager(root_window));
[email protected]a4cd6d32012-09-12 03:42:13602 SetUsesScreenCoordinates(lock_container);
603 // TODO(beng): stopsevents
604
605 aura::Window* lock_modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27606 kShellWindowId_LockSystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13607 "LockSystemModalContainer",
608 lock_screen_containers);
609 lock_modal_container_handler_.reset(
610 new ToplevelWindowEventHandler(lock_modal_container));
[email protected]a4cd6d32012-09-12 03:42:13611 lock_modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27612 new SystemModalContainerLayoutManager(lock_modal_container));
[email protected]b5756e22012-11-30 01:32:02613 views::corewm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13614 SetUsesScreenCoordinates(lock_modal_container);
615
616 aura::Window* status_container =
[email protected]c0ce80e2012-10-05 23:28:27617 CreateContainer(kShellWindowId_StatusContainer,
[email protected]a4cd6d32012-09-12 03:42:13618 "StatusContainer",
619 lock_screen_related_containers);
620 SetUsesScreenCoordinates(status_container);
621
622 aura::Window* settings_bubble_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27623 kShellWindowId_SettingBubbleContainer,
[email protected]a4cd6d32012-09-12 03:42:13624 "SettingBubbleContainer",
625 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02626 views::corewm::SetChildWindowVisibilityChangesAnimated(
627 settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13628 SetUsesScreenCoordinates(settings_bubble_container);
629
630 aura::Window* menu_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27631 kShellWindowId_MenuContainer,
[email protected]a4cd6d32012-09-12 03:42:13632 "MenuContainer",
633 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02634 views::corewm::SetChildWindowVisibilityChangesAnimated(menu_container);
[email protected]a4cd6d32012-09-12 03:42:13635 SetUsesScreenCoordinates(menu_container);
636
637 aura::Window* drag_drop_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27638 kShellWindowId_DragImageAndTooltipContainer,
[email protected]a4cd6d32012-09-12 03:42:13639 "DragImageAndTooltipContainer",
640 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02641 views::corewm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
[email protected]a4cd6d32012-09-12 03:42:13642 SetUsesScreenCoordinates(drag_drop_container);
643
644 aura::Window* overlay_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27645 kShellWindowId_OverlayContainer,
[email protected]a4cd6d32012-09-12 03:42:13646 "OverlayContainer",
647 lock_screen_related_containers);
648 SetUsesScreenCoordinates(overlay_container);
[email protected]a07615f2012-10-24 08:23:08649
650 CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
651 "PowerButtonAnimationContainer", root_window) ;
[email protected]a4cd6d32012-09-12 03:42:13652}
653
[email protected]d90b8392012-06-13 09:34:56654} // namespace internal
655} // namespace ash