blob: 30e3ba71060f95708ebd4e41995dc81fe59a420b [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]7095a652013-03-07 19:41:4928#include "ash/wm/panels/panel_layout_manager.h"
[email protected]d90b8392012-06-13 09:34:5629#include "ash/wm/property_util.h"
30#include "ash/wm/root_window_layout_manager.h"
31#include "ash/wm/screen_dimmer.h"
[email protected]2a2caa02013-01-22 20:50:3632#include "ash/wm/stacking_controller.h"
[email protected]e74aaf0a2012-10-12 18:42:2833#include "ash/wm/status_area_layout_manager.h"
[email protected]e6e41d2f2012-10-29 19:22:1934#include "ash/wm/system_background_controller.h"
[email protected]d90b8392012-06-13 09:34:5635#include "ash/wm/system_modal_container_layout_manager.h"
[email protected]5dc51db82012-09-11 03:39:0136#include "ash/wm/toplevel_window_event_handler.h"
[email protected]8d625fb2012-07-18 16:40:0637#include "ash/wm/window_properties.h"
[email protected]700849f2013-04-30 17:49:2038#include "ash/wm/window_util.h"
[email protected]d90b8392012-06-13 09:34:5639#include "ash/wm/workspace_controller.h"
[email protected]e6e41d2f2012-10-29 19:22:1940#include "base/command_line.h"
[email protected]bca9a7e2012-11-10 06:25:4941#include "base/time.h"
[email protected]f1853122012-06-27 16:21:2642#include "ui/aura/client/aura_constants.h"
[email protected]d90b8392012-06-13 09:34:5643#include "ui/aura/client/tooltip_client.h"
44#include "ui/aura/root_window.h"
[email protected]f1853122012-06-27 16:21:2645#include "ui/aura/window.h"
46#include "ui/aura/window_observer.h"
[email protected]431552c2012-10-23 00:38:3347#include "ui/base/models/menu_model.h"
[email protected]8d625fb2012-07-18 16:40:0648#include "ui/gfx/display.h"
49#include "ui/gfx/screen.h"
[email protected]86459e2c2013-04-10 13:39:2450#include "ui/keyboard/keyboard_controller.h"
51#include "ui/keyboard/keyboard_util.h"
[email protected]431552c2012-10-23 00:38:3352#include "ui/views/controls/menu/menu_runner.h"
[email protected]b5756e22012-11-30 01:32:0253#include "ui/views/corewm/visibility_controller.h"
[email protected]431552c2012-10-23 00:38:3354#include "ui/views/view_model.h"
55#include "ui/views/view_model_utils.h"
[email protected]d90b8392012-06-13 09:34:5656
57namespace ash {
58namespace {
59
[email protected]bca9a7e2012-11-10 06:25:4960// Duration for the animation that hides the boot splash screen, in
61// milliseconds. This should be short enough in relation to
62// wm/window_animation.cc's brightness/grayscale fade animation that the login
63// background image animation isn't hidden by the splash screen animation.
64const int kBootSplashScreenHideDurationMs = 500;
65
[email protected]d90b8392012-06-13 09:34:5666// Creates a new window for use as a container.
67aura::Window* CreateContainer(int window_id,
68 const char* name,
69 aura::Window* parent) {
70 aura::Window* container = new aura::Window(NULL);
71 container->set_id(window_id);
72 container->SetName(name);
73 container->Init(ui::LAYER_NOT_DRAWN);
74 parent->AddChild(container);
75 if (window_id != internal::kShellWindowId_UnparentedControlContainer)
76 container->Show();
77 return container;
78}
79
[email protected]95058572012-08-20 14:57:2980// Returns all the children of the workspace windows, eg the standard top-level
81// windows.
82std::vector<aura::Window*> GetWorkspaceWindows(aura::RootWindow* root) {
83 using aura::Window;
84
85 std::vector<Window*> windows;
86 Window* container = Shell::GetContainer(
87 root, internal::kShellWindowId_DefaultContainer);
88 for (Window::Windows::const_reverse_iterator i =
89 container->children().rbegin();
90 i != container->children().rend(); ++i) {
91 Window* workspace_window = *i;
92 if (workspace_window->id() == internal::kShellWindowId_WorkspaceContainer) {
93 windows.insert(windows.end(), workspace_window->children().begin(),
94 workspace_window->children().end());
95 }
96 }
97 return windows;
98}
99
100// Reparents |window| to |new_parent|.
101void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
102 // Update the restore bounds to make it relative to the display.
103 gfx::Rect restore_bounds(GetRestoreBoundsInParent(window));
104 new_parent->AddChild(window);
105 if (!restore_bounds.IsEmpty())
106 SetRestoreBoundsInParent(window, restore_bounds);
107}
108
109// Reparents the appropriate set of windows from |src| to |dst|.
110void ReparentAllWindows(aura::RootWindow* src, aura::RootWindow* dst) {
111 // Set of windows to move.
[email protected]f1853122012-06-27 16:21:26112 const int kContainerIdsToMove[] = {
113 internal::kShellWindowId_DefaultContainer,
[email protected]95db9c12013-01-31 11:47:44114 internal::kShellWindowId_PanelContainer,
[email protected]f1853122012-06-27 16:21:26115 internal::kShellWindowId_AlwaysOnTopContainer,
116 internal::kShellWindowId_SystemModalContainer,
117 internal::kShellWindowId_LockSystemModalContainer,
[email protected]6274d312012-10-04 22:06:41118 internal::kShellWindowId_InputMethodContainer,
[email protected]a9754872013-01-25 07:44:00119 internal::kShellWindowId_UnparentedControlContainer,
[email protected]f1853122012-06-27 16:21:26120 };
[email protected]ef0e32cc2012-10-31 20:57:33121 // For workspace windows we need to manually reparent the windows. This way
122 // workspace can move the windows to the appropriate workspace.
[email protected]c96b9812012-10-17 16:04:04123 std::vector<aura::Window*> windows(GetWorkspaceWindows(src));
124 internal::WorkspaceController* workspace_controller =
125 GetRootWindowController(dst)->workspace_controller();
126 for (size_t i = 0; i < windows.size(); ++i) {
127 aura::Window* new_parent =
128 workspace_controller->GetParentForNewWindow(windows[i]);
129 ReparentWindow(windows[i], new_parent);
[email protected]95058572012-08-20 14:57:29130 }
[email protected]f1853122012-06-27 16:21:26131 for (size_t i = 0; i < arraysize(kContainerIdsToMove); i++) {
132 int id = kContainerIdsToMove[i];
[email protected]c96b9812012-10-17 16:04:04133 if (id == internal::kShellWindowId_DefaultContainer)
[email protected]95058572012-08-20 14:57:29134 continue;
135
[email protected]f1853122012-06-27 16:21:26136 aura::Window* src_container = Shell::GetContainer(src, id);
137 aura::Window* dst_container = Shell::GetContainer(dst, id);
[email protected]5b6021902013-02-26 05:33:29138 while (!src_container->children().empty()) {
139 // Restart iteration from the source container windows each time as they
140 // may change as a result of moving other windows.
141 aura::Window::Windows::const_iterator iter =
142 src_container->children().begin();
143 while (iter != src_container->children().end() &&
144 internal::SystemModalContainerLayoutManager::IsModalBackground(
145 *iter)) {
146 ++iter;
147 }
148 // If the entire window list is modal background windows then stop.
149 if (iter == src_container->children().end())
150 break;
151 ReparentWindow(*iter, dst_container);
[email protected]f1853122012-06-27 16:21:26152 }
153 }
154}
155
[email protected]8d625fb2012-07-18 16:40:06156// Mark the container window so that a widget added to this container will
157// use the virtual screeen coordinates instead of parent.
158void SetUsesScreenCoordinates(aura::Window* container) {
159 container->SetProperty(internal::kUsesScreenCoordinatesKey, true);
160}
161
[email protected]d90b8392012-06-13 09:34:56162} // namespace
163
164namespace internal {
165
166RootWindowController::RootWindowController(aura::RootWindow* root_window)
[email protected]e74aaf0a2012-10-12 18:42:28167 : root_window_(root_window),
168 root_window_layout_(NULL),
[email protected]bff17552013-04-25 04:44:55169 panel_layout_manager_(NULL),
170 touch_observer_hud_(NULL) {
[email protected]d90b8392012-06-13 09:34:56171 SetRootWindowController(root_window, this);
[email protected]c0ce80e2012-10-05 23:28:27172 screen_dimmer_.reset(new ScreenDimmer(root_window));
[email protected]2a2caa02013-01-22 20:50:36173
174 stacking_controller_.reset(new ash::StackingController);
175 aura::client::SetStackingClient(root_window, stacking_controller_.get());
[email protected]d90b8392012-06-13 09:34:56176}
177
178RootWindowController::~RootWindowController() {
[email protected]6675e1c2012-09-11 09:15:45179 Shutdown();
180 root_window_.reset();
181}
182
[email protected]88d71122012-10-18 07:11:01183// static
[email protected]a0afeb12012-12-10 22:57:09184RootWindowController* RootWindowController::ForLauncher(aura::Window* window) {
[email protected]8c0ec432013-05-10 04:33:39185 return GetRootWindowController(window->GetRootWindow());
[email protected]88d71122012-10-18 07:11:01186}
187
[email protected]a0afeb12012-12-10 22:57:09188// static
[email protected]ccff3d72013-02-06 04:26:28189RootWindowController* RootWindowController::ForWindow(
190 const aura::Window* window) {
[email protected]a0afeb12012-12-10 22:57:09191 return GetRootWindowController(window->GetRootWindow());
192}
193
194// static
195RootWindowController* RootWindowController::ForActiveRootWindow() {
196 return GetRootWindowController(Shell::GetActiveRootWindow());
197}
198
[email protected]6675e1c2012-09-11 09:15:45199void RootWindowController::Shutdown() {
200 CloseChildWindows();
[email protected]7f7f65c2013-04-17 16:47:13201 if (Shell::GetActiveRootWindow() == root_window_) {
[email protected]f634dd32012-07-23 22:49:07202 Shell::GetInstance()->set_active_root_window(
203 Shell::GetPrimaryRootWindow() == root_window_.get() ?
204 NULL : Shell::GetPrimaryRootWindow());
205 }
[email protected]d90b8392012-06-13 09:34:56206 SetRootWindowController(root_window_.get(), NULL);
[email protected]d90b8392012-06-13 09:34:56207 screen_dimmer_.reset();
208 workspace_controller_.reset();
[email protected]6675e1c2012-09-11 09:15:45209 // Forget with the display ID so that display lookup
210 // ends up with invalid display.
211 root_window_->ClearProperty(kDisplayIdKey);
212 // And this root window should no longer process events.
213 root_window_->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28214
[email protected]956a6a42012-10-29 23:58:10215 system_background_.reset();
[email protected]d90b8392012-06-13 09:34:56216}
217
[email protected]c0ce80e2012-10-05 23:28:27218SystemModalContainerLayoutManager*
[email protected]8674b312012-10-12 19:02:44219RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
220 aura::Window* container = NULL;
221 if (window) {
[email protected]3b162e12012-11-09 11:52:35222 if (window->parent() &&
223 window->parent()->id() >= kShellWindowId_LockScreenContainer) {
224 container = GetContainer(kShellWindowId_LockSystemModalContainer);
225 } else {
[email protected]8674b312012-10-12 19:02:44226 container = GetContainer(kShellWindowId_SystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35227 }
[email protected]8674b312012-10-12 19:02:44228 } else {
[email protected]945f9cae2012-12-12 09:54:29229 user::LoginStatus login = Shell::GetInstance()->system_tray_delegate() ?
230 Shell::GetInstance()->system_tray_delegate()->GetUserLoginStatus() :
[email protected]8674b312012-10-12 19:02:44231 user::LOGGED_IN_NONE;
232 int modal_window_id = (login == user::LOGGED_IN_LOCKED ||
233 login == user::LOGGED_IN_NONE) ?
234 kShellWindowId_LockSystemModalContainer :
235 kShellWindowId_SystemModalContainer;
236 container = GetContainer(modal_window_id);
237 }
[email protected]bb0c7cd42013-05-20 23:39:45238 return container ? static_cast<SystemModalContainerLayoutManager*>(
239 container->layout_manager()) : NULL;
[email protected]c0ce80e2012-10-05 23:28:27240}
241
[email protected]d90b8392012-06-13 09:34:56242aura::Window* RootWindowController::GetContainer(int container_id) {
243 return root_window_->GetChildById(container_id);
244}
245
246void RootWindowController::InitLayoutManagers() {
247 root_window_layout_ =
[email protected]c0ce80e2012-10-05 23:28:27248 new RootWindowLayoutManager(root_window_.get());
[email protected]d90b8392012-06-13 09:34:56249 root_window_->SetLayoutManager(root_window_layout_);
250
251 aura::Window* default_container =
[email protected]c0ce80e2012-10-05 23:28:27252 GetContainer(kShellWindowId_DefaultContainer);
[email protected]d90b8392012-06-13 09:34:56253 // Workspace manager has its own layout managers.
254 workspace_controller_.reset(
[email protected]c0ce80e2012-10-05 23:28:27255 new WorkspaceController(default_container));
[email protected]d90b8392012-06-13 09:34:56256
257 aura::Window* always_on_top_container =
[email protected]c0ce80e2012-10-05 23:28:27258 GetContainer(kShellWindowId_AlwaysOnTopContainer);
[email protected]d90b8392012-06-13 09:34:56259 always_on_top_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27260 new BaseLayoutManager(
[email protected]d90b8392012-06-13 09:34:56261 always_on_top_container->GetRootWindow()));
262}
263
[email protected]e74aaf0a2012-10-12 18:42:28264void RootWindowController::InitForPrimaryDisplay() {
[email protected]478c6c32013-03-09 02:50:58265 DCHECK(!shelf_.get());
266 aura::Window* shelf_container =
267 GetContainer(ash::internal::kShellWindowId_ShelfContainer);
268 // TODO(harrym): Remove when status area is view.
[email protected]16059276d2012-10-22 18:59:50269 aura::Window* status_container =
270 GetContainer(ash::internal::kShellWindowId_StatusContainer);
[email protected]478c6c32013-03-09 02:50:58271 shelf_.reset(new ash::ShelfWidget(
272 shelf_container, status_container, workspace_controller()));
[email protected]e74aaf0a2012-10-12 18:42:28273
[email protected]8c0ec432013-05-10 04:33:39274 // Create Panel layout manager
275 aura::Window* panel_container = GetContainer(
276 internal::kShellWindowId_PanelContainer);
277 panel_layout_manager_ =
278 new internal::PanelLayoutManager(panel_container);
279 panel_container_handler_.reset(
280 new ToplevelWindowEventHandler(panel_container));
281 panel_container->SetLayoutManager(panel_layout_manager_);
282
[email protected]8e6986a2013-05-31 19:29:55283 // TODO(stevenjb/oshima): Remove this call to CreateLauncher() and call
284 // ash::Shell::CreateLauncher() explicitly in ash_shell and ash_unittests
285 // so that the behavior and construction order is consistent betwheen Ash
286 // and Chrome.
[email protected]c8d19f82013-05-18 09:09:41287 if (Shell::GetInstance()->session_state_delegate()->NumberOfLoggedInUsers())
[email protected]478c6c32013-03-09 02:50:58288 shelf_->CreateLauncher();
[email protected]86459e2c2013-04-10 13:39:24289
[email protected]86459e2c2013-04-10 13:39:24290 InitKeyboard();
[email protected]e74aaf0a2012-10-12 18:42:28291}
292
[email protected]d90b8392012-06-13 09:34:56293void RootWindowController::CreateContainers() {
294 CreateContainersInRootWindow(root_window_.get());
[email protected]58175042013-04-01 19:27:13295
296 // Create touch observer HUD if needed. HUD should be created after the
297 // containers have been created, so that its widget can be added to them.
298 CommandLine* command_line = CommandLine::ForCurrentProcess();
[email protected]bff17552013-04-25 04:44:55299 if (command_line->HasSwitch(switches::kAshTouchHud))
300 touch_observer_hud_ = new TouchObserverHUD(root_window_.get());
[email protected]d90b8392012-06-13 09:34:56301}
302
[email protected]697f04c2012-10-03 01:15:10303void RootWindowController::CreateSystemBackground(
304 bool is_first_run_after_boot) {
[email protected]bca9a7e2012-11-10 06:25:49305 SkColor color = SK_ColorBLACK;
[email protected]697f04c2012-10-03 01:15:10306#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:49307 if (is_first_run_after_boot)
308 color = kChromeOsBootColor;
[email protected]697f04c2012-10-03 01:15:10309#endif
[email protected]e6e41d2f2012-10-29 19:22:19310 system_background_.reset(
[email protected]bca9a7e2012-11-10 06:25:49311 new SystemBackgroundController(root_window_.get(), color));
312
313#if defined(OS_CHROMEOS)
314 // Make a copy of the system's boot splash screen so we can composite it
315 // onscreen until the desktop background is ready.
316 if (is_first_run_after_boot &&
317 (CommandLine::ForCurrentProcess()->HasSwitch(
318 switches::kAshCopyHostBackgroundAtBoot) ||
319 CommandLine::ForCurrentProcess()->HasSwitch(
320 switches::kAshAnimateFromBootSplashScreen)))
321 boot_splash_screen_.reset(new BootSplashScreen(root_window_.get()));
322#endif
[email protected]697f04c2012-10-03 01:15:10323}
324
[email protected]478c6c32013-03-09 02:50:58325void RootWindowController::OnLauncherCreated() {
[email protected]e74aaf0a2012-10-12 18:42:28326 if (panel_layout_manager_)
[email protected]478c6c32013-03-09 02:50:58327 panel_layout_manager_->SetLauncher(shelf_->launcher());
[email protected]e74aaf0a2012-10-12 18:42:28328}
329
330void RootWindowController::ShowLauncher() {
[email protected]478c6c32013-03-09 02:50:58331 if (!shelf_.get() || !shelf_->launcher())
[email protected]e74aaf0a2012-10-12 18:42:28332 return;
[email protected]478c6c32013-03-09 02:50:58333 shelf_->launcher()->SetVisible(true);
334 shelf_->status_area_widget()->Show();
[email protected]e74aaf0a2012-10-12 18:42:28335}
336
[email protected]16059276d2012-10-22 18:59:50337void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
338 // TODO(oshima): remove if when launcher per display is enabled by
339 // default.
[email protected]7f7f65c2013-04-17 16:47:13340 if (shelf_)
[email protected]478c6c32013-03-09 02:50:58341 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]16059276d2012-10-22 18:59:50342}
343
344void RootWindowController::UpdateAfterLoginStatusChange(
345 user::LoginStatus status) {
[email protected]478c6c32013-03-09 02:50:58346 if (shelf_.get() && shelf_->status_area_widget())
347 shelf_->status_area_widget()->UpdateAfterLoginStatusChange(status);
[email protected]16059276d2012-10-22 18:59:50348}
349
[email protected]bca9a7e2012-11-10 06:25:49350void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
351 if (CommandLine::ForCurrentProcess()->HasSwitch(
352 switches::kAshAnimateFromBootSplashScreen) &&
353 boot_splash_screen_.get()) {
354 // Make the splash screen fade out so it doesn't obscure the desktop
355 // wallpaper's brightness/grayscale animation.
356 boot_splash_screen_->StartHideAnimation(
357 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
358 }
359}
360
[email protected]697f04c2012-10-03 01:15:10361void RootWindowController::HandleDesktopBackgroundVisible() {
[email protected]bca9a7e2012-11-10 06:25:49362 system_background_->SetColor(SK_ColorBLACK);
363 boot_splash_screen_.reset();
[email protected]697f04c2012-10-03 01:15:10364}
365
[email protected]d90b8392012-06-13 09:34:56366void RootWindowController::CloseChildWindows() {
[email protected]79a87b7e2013-01-25 05:08:22367 // panel_layout_manager_ needs to be shut down before windows are destroyed.
368 if (panel_layout_manager_) {
369 panel_layout_manager_->Shutdown();
370 panel_layout_manager_ = NULL;
371 }
372
[email protected]478c6c32013-03-09 02:50:58373 // TODO(harrym): Remove when Status Area Widget is a child view.
[email protected]7f7f65c2013-04-17 16:47:13374 if (shelf_)
[email protected]478c6c32013-03-09 02:50:58375 shelf_->ShutdownStatusAreaWidget();
376
377 if (shelf_.get() && shelf_->shelf_layout_manager())
378 shelf_->shelf_layout_manager()->set_workspace_controller(NULL);
[email protected]e74aaf0a2012-10-12 18:42:28379
[email protected]d90b8392012-06-13 09:34:56380 // Close background widget first as it depends on tooltip.
[email protected]d86de6b22012-10-05 19:32:58381 root_window_->SetProperty(kDesktopController,
[email protected]b4ddc7a2012-08-07 04:17:32382 static_cast<DesktopBackgroundWidgetController*>(NULL));
[email protected]d86de6b22012-10-05 19:32:58383 root_window_->SetProperty(kAnimatingDesktopController,
384 static_cast<AnimatingDesktopController*>(NULL));
[email protected]b4ddc7a2012-08-07 04:17:32385
[email protected]d90b8392012-06-13 09:34:56386 workspace_controller_.reset();
387 aura::client::SetTooltipClient(root_window_.get(), NULL);
388
389 while (!root_window_->children().empty()) {
390 aura::Window* child = root_window_->children()[0];
391 delete child;
392 }
[email protected]478c6c32013-03-09 02:50:58393
394 shelf_.reset(NULL);
[email protected]d90b8392012-06-13 09:34:56395}
396
[email protected]f1853122012-06-27 16:21:26397void RootWindowController::MoveWindowsTo(aura::RootWindow* dst) {
[email protected]8039e06c2013-01-17 23:34:50398 // Forget the shelf early so that shelf don't update itself using wrong
399 // display info.
400 workspace_controller_->SetShelf(NULL);
[email protected]95058572012-08-20 14:57:29401 ReparentAllWindows(root_window_.get(), dst);
[email protected]f1853122012-06-27 16:21:26402}
403
[email protected]478c6c32013-03-09 02:50:58404ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
405 return shelf_.get() ? shelf_->shelf_layout_manager() : NULL;
406}
407
[email protected]a0afeb12012-12-10 22:57:09408SystemTray* RootWindowController::GetSystemTray() {
409 // We assume in throughout the code that this will not return NULL. If code
410 // triggers this for valid reasons, it should test status_area_widget first.
[email protected]478c6c32013-03-09 02:50:58411 CHECK(shelf_.get() && shelf_->status_area_widget());
412 return shelf_->status_area_widget()->system_tray();
[email protected]a0afeb12012-12-10 22:57:09413}
414
[email protected]431552c2012-10-23 00:38:33415void RootWindowController::ShowContextMenu(
416 const gfx::Point& location_in_screen) {
[email protected]431552c2012-10-23 00:38:33417 DCHECK(Shell::GetInstance()->delegate());
418 scoped_ptr<ui::MenuModel> menu_model(
[email protected]8c0ec432013-05-10 04:33:39419 Shell::GetInstance()->delegate()->CreateContextMenu(root_window()));
[email protected]7f7f65c2013-04-17 16:47:13420 if (!menu_model)
[email protected]8e837ec2013-01-31 01:48:33421 return;
[email protected]431552c2012-10-23 00:38:33422
[email protected]6175fc42013-04-05 05:58:58423 internal::DesktopBackgroundWidgetController* background =
424 root_window_->GetProperty(kDesktopController);
425 // Background controller may not be set yet if user clicked on status are
426 // before initial animation completion. See crbug.com/222218
427 if (!background)
[email protected]431552c2012-10-23 00:38:33428 return;
429
[email protected]6175fc42013-04-05 05:58:58430 views::MenuRunner menu_runner(menu_model.get());
431 if (menu_runner.RunMenuAt(background->widget(),
432 NULL, gfx::Rect(location_in_screen, gfx::Size()),
433 views::MenuItemView::TOPLEFT, views::MenuRunner::CONTEXT_MENU) ==
434 views::MenuRunner::MENU_DELETED) {
435 return;
436 }
437
[email protected]431552c2012-10-23 00:38:33438 Shell::GetInstance()->UpdateShelfVisibility();
439}
440
[email protected]e74aaf0a2012-10-12 18:42:28441void RootWindowController::UpdateShelfVisibility() {
[email protected]478c6c32013-03-09 02:50:58442 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]e74aaf0a2012-10-12 18:42:28443}
444
[email protected]700849f2013-04-30 17:49:20445aura::Window* RootWindowController::GetFullscreenWindow() const {
[email protected]2ee2f5d2013-01-10 23:37:16446 aura::Window* container = workspace_controller_->GetActiveWorkspaceWindow();
447 for (size_t i = 0; i < container->children().size(); ++i) {
448 aura::Window* child = container->children()[i];
[email protected]700849f2013-04-30 17:49:20449 if (ash::wm::IsWindowFullscreen(child))
450 return child;
[email protected]2ee2f5d2013-01-10 23:37:16451 }
[email protected]700849f2013-04-30 17:49:20452 return NULL;
[email protected]2ee2f5d2013-01-10 23:37:16453}
454
[email protected]86459e2c2013-04-10 13:39:24455void RootWindowController::InitKeyboard() {
456 if (keyboard::IsKeyboardEnabled()) {
457 aura::Window* parent = root_window();
458
459 keyboard::KeyboardControllerProxy* proxy =
460 Shell::GetInstance()->delegate()->CreateKeyboardControllerProxy();
461 keyboard_controller_.reset(
462 new keyboard::KeyboardController(proxy));
[email protected]5416f282013-04-29 20:52:48463
464 keyboard_controller_->AddObserver(shelf()->shelf_layout_manager());
465 keyboard_controller_->AddObserver(panel_layout_manager_);
466
[email protected]86459e2c2013-04-10 13:39:24467 aura::Window* keyboard_container =
468 keyboard_controller_->GetContainerWindow();
469 parent->AddChild(keyboard_container);
[email protected]e0f71132013-04-17 12:32:51470 keyboard_container->SetBounds(parent->bounds());
[email protected]86459e2c2013-04-10 13:39:24471 }
472}
473
474
[email protected]a4cd6d32012-09-12 03:42:13475////////////////////////////////////////////////////////////////////////////////
476// RootWindowController, private:
477
478void RootWindowController::CreateContainersInRootWindow(
479 aura::RootWindow* root_window) {
480 // These containers are just used by PowerButtonController to animate groups
481 // of containers simultaneously without messing up the current transformations
482 // on those containers. These are direct children of the root window; all of
483 // the other containers are their children.
[email protected]e6e41d2f2012-10-29 19:22:19484
485 // The desktop background container is not part of the lock animation, so it
486 // is not included in those animate groups.
[email protected]a4cd6d32012-09-12 03:42:13487 // When screen is locked desktop background is moved to lock screen background
488 // container (moved back on unlock). We want to make sure that there's an
489 // opaque layer occluding the non-lock-screen layers.
[email protected]e6e41d2f2012-10-29 19:22:19490 aura::Window* desktop_background_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27491 kShellWindowId_DesktopBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13492 "DesktopBackgroundContainer",
493 root_window);
[email protected]b5756e22012-11-30 01:32:02494 views::corewm::SetChildWindowVisibilityChangesAnimated(
495 desktop_background_container);
[email protected]a4cd6d32012-09-12 03:42:13496
497 aura::Window* non_lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27498 kShellWindowId_NonLockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13499 "NonLockScreenContainersContainer",
500 root_window);
501
502 aura::Window* lock_background_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27503 kShellWindowId_LockScreenBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13504 "LockScreenBackgroundContainer",
505 root_window);
[email protected]b5756e22012-11-30 01:32:02506 views::corewm::SetChildWindowVisibilityChangesAnimated(
507 lock_background_containers);
[email protected]a4cd6d32012-09-12 03:42:13508
509 aura::Window* lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27510 kShellWindowId_LockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13511 "LockScreenContainersContainer",
512 root_window);
513 aura::Window* lock_screen_related_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27514 kShellWindowId_LockScreenRelatedContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13515 "LockScreenRelatedContainersContainer",
516 root_window);
517
[email protected]c0ce80e2012-10-05 23:28:27518 CreateContainer(kShellWindowId_UnparentedControlContainer,
[email protected]a4cd6d32012-09-12 03:42:13519 "UnparentedControlContainer",
520 non_lock_screen_containers);
521
522 aura::Window* default_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27523 kShellWindowId_DefaultContainer,
[email protected]a4cd6d32012-09-12 03:42:13524 "DefaultContainer",
525 non_lock_screen_containers);
[email protected]b5756e22012-11-30 01:32:02526 views::corewm::SetChildWindowVisibilityChangesAnimated(default_container);
[email protected]a4cd6d32012-09-12 03:42:13527 SetUsesScreenCoordinates(default_container);
528
529 aura::Window* always_on_top_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27530 kShellWindowId_AlwaysOnTopContainer,
[email protected]a4cd6d32012-09-12 03:42:13531 "AlwaysOnTopContainer",
532 non_lock_screen_containers);
533 always_on_top_container_handler_.reset(
534 new ToplevelWindowEventHandler(always_on_top_container));
[email protected]b5756e22012-11-30 01:32:02535 views::corewm::SetChildWindowVisibilityChangesAnimated(
536 always_on_top_container);
[email protected]a4cd6d32012-09-12 03:42:13537 SetUsesScreenCoordinates(always_on_top_container);
538
539 aura::Window* panel_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27540 kShellWindowId_PanelContainer,
[email protected]a4cd6d32012-09-12 03:42:13541 "PanelContainer",
542 non_lock_screen_containers);
543 SetUsesScreenCoordinates(panel_container);
544
545 aura::Window* launcher_container =
[email protected]478c6c32013-03-09 02:50:58546 CreateContainer(kShellWindowId_ShelfContainer,
[email protected]a4cd6d32012-09-12 03:42:13547 "LauncherContainer",
548 non_lock_screen_containers);
549 SetUsesScreenCoordinates(launcher_container);
550
[email protected]dc851a4e52012-10-03 00:05:55551 aura::Window* app_list_container =
[email protected]c0ce80e2012-10-05 23:28:27552 CreateContainer(kShellWindowId_AppListContainer,
[email protected]dc851a4e52012-10-03 00:05:55553 "AppListContainer",
554 non_lock_screen_containers);
555 SetUsesScreenCoordinates(app_list_container);
[email protected]a4cd6d32012-09-12 03:42:13556
557 aura::Window* modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27558 kShellWindowId_SystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13559 "SystemModalContainer",
560 non_lock_screen_containers);
561 modal_container_handler_.reset(
562 new ToplevelWindowEventHandler(modal_container));
[email protected]a4cd6d32012-09-12 03:42:13563 modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27564 new SystemModalContainerLayoutManager(modal_container));
[email protected]b5756e22012-11-30 01:32:02565 views::corewm::SetChildWindowVisibilityChangesAnimated(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13566 SetUsesScreenCoordinates(modal_container);
567
568 aura::Window* input_method_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27569 kShellWindowId_InputMethodContainer,
[email protected]a4cd6d32012-09-12 03:42:13570 "InputMethodContainer",
571 non_lock_screen_containers);
572 SetUsesScreenCoordinates(input_method_container);
573
574 // TODO(beng): Figure out if we can make this use
575 // SystemModalContainerEventFilter instead of stops_event_propagation.
576 aura::Window* lock_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27577 kShellWindowId_LockScreenContainer,
[email protected]a4cd6d32012-09-12 03:42:13578 "LockScreenContainer",
579 lock_screen_containers);
580 lock_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27581 new BaseLayoutManager(root_window));
[email protected]a4cd6d32012-09-12 03:42:13582 SetUsesScreenCoordinates(lock_container);
583 // TODO(beng): stopsevents
584
585 aura::Window* lock_modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27586 kShellWindowId_LockSystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13587 "LockSystemModalContainer",
588 lock_screen_containers);
589 lock_modal_container_handler_.reset(
590 new ToplevelWindowEventHandler(lock_modal_container));
[email protected]a4cd6d32012-09-12 03:42:13591 lock_modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27592 new SystemModalContainerLayoutManager(lock_modal_container));
[email protected]b5756e22012-11-30 01:32:02593 views::corewm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13594 SetUsesScreenCoordinates(lock_modal_container);
595
596 aura::Window* status_container =
[email protected]c0ce80e2012-10-05 23:28:27597 CreateContainer(kShellWindowId_StatusContainer,
[email protected]a4cd6d32012-09-12 03:42:13598 "StatusContainer",
599 lock_screen_related_containers);
600 SetUsesScreenCoordinates(status_container);
601
602 aura::Window* settings_bubble_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27603 kShellWindowId_SettingBubbleContainer,
[email protected]a4cd6d32012-09-12 03:42:13604 "SettingBubbleContainer",
605 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02606 views::corewm::SetChildWindowVisibilityChangesAnimated(
607 settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13608 SetUsesScreenCoordinates(settings_bubble_container);
609
610 aura::Window* menu_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27611 kShellWindowId_MenuContainer,
[email protected]a4cd6d32012-09-12 03:42:13612 "MenuContainer",
613 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02614 views::corewm::SetChildWindowVisibilityChangesAnimated(menu_container);
[email protected]a4cd6d32012-09-12 03:42:13615 SetUsesScreenCoordinates(menu_container);
616
617 aura::Window* drag_drop_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27618 kShellWindowId_DragImageAndTooltipContainer,
[email protected]a4cd6d32012-09-12 03:42:13619 "DragImageAndTooltipContainer",
620 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02621 views::corewm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
[email protected]a4cd6d32012-09-12 03:42:13622 SetUsesScreenCoordinates(drag_drop_container);
623
624 aura::Window* overlay_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27625 kShellWindowId_OverlayContainer,
[email protected]a4cd6d32012-09-12 03:42:13626 "OverlayContainer",
627 lock_screen_related_containers);
628 SetUsesScreenCoordinates(overlay_container);
[email protected]a07615f2012-10-24 08:23:08629
630 CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
631 "PowerButtonAnimationContainer", root_window) ;
[email protected]a4cd6d32012-09-12 03:42:13632}
633
[email protected]d90b8392012-06-13 09:34:56634} // namespace internal
635} // namespace ash