blob: bbd611e11dc3d9765c0ce49453c863d85087d85e [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]ef80e4302012-12-04 19:37:3115#include "ash/shelf_types.h"
[email protected]d90b8392012-06-13 09:34:5616#include "ash/shell.h"
[email protected]e74aaf0a2012-10-12 18:42:2817#include "ash/shell_delegate.h"
[email protected]d90b8392012-06-13 09:34:5618#include "ash/shell_factory.h"
19#include "ash/shell_window_ids.h"
[email protected]e74aaf0a2012-10-12 18:42:2820#include "ash/system/status_area_widget.h"
[email protected]8674b312012-10-12 19:02:4421#include "ash/system/tray/system_tray_delegate.h"
[email protected]d90b8392012-06-13 09:34:5622#include "ash/wm/base_layout_manager.h"
[email protected]bca9a7e2012-11-10 06:25:4923#include "ash/wm/boot_splash_screen.h"
[email protected]e74aaf0a2012-10-12 18:42:2824#include "ash/wm/panel_layout_manager.h"
25#include "ash/wm/panel_window_event_filter.h"
[email protected]d90b8392012-06-13 09:34:5626#include "ash/wm/property_util.h"
27#include "ash/wm/root_window_layout_manager.h"
28#include "ash/wm/screen_dimmer.h"
[email protected]e74aaf0a2012-10-12 18:42:2829#include "ash/wm/shelf_layout_manager.h"
[email protected]2a2caa02013-01-22 20:50:3630#include "ash/wm/stacking_controller.h"
[email protected]e74aaf0a2012-10-12 18:42:2831#include "ash/wm/status_area_layout_manager.h"
[email protected]e6e41d2f2012-10-29 19:22:1932#include "ash/wm/system_background_controller.h"
[email protected]d90b8392012-06-13 09:34:5633#include "ash/wm/system_modal_container_layout_manager.h"
[email protected]5dc51db82012-09-11 03:39:0134#include "ash/wm/toplevel_window_event_handler.h"
[email protected]8d625fb2012-07-18 16:40:0635#include "ash/wm/window_properties.h"
[email protected]d90b8392012-06-13 09:34:5636#include "ash/wm/workspace_controller.h"
[email protected]e6e41d2f2012-10-29 19:22:1937#include "base/command_line.h"
[email protected]bca9a7e2012-11-10 06:25:4938#include "base/time.h"
[email protected]f1853122012-06-27 16:21:2639#include "ui/aura/client/activation_client.h"
40#include "ui/aura/client/aura_constants.h"
41#include "ui/aura/client/capture_client.h"
[email protected]8cfb6722012-11-28 03:28:4642#include "ui/aura/client/focus_client.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]1d030242012-06-28 18:34:0847#include "ui/aura/window_tracker.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]431552c2012-10-23 00:38:3351#include "ui/views/controls/menu/menu_model_adapter.h"
52#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,
114 internal::kShellWindowId_AlwaysOnTopContainer,
115 internal::kShellWindowId_SystemModalContainer,
116 internal::kShellWindowId_LockSystemModalContainer,
[email protected]6274d312012-10-04 22:06:41117 internal::kShellWindowId_InputMethodContainer,
[email protected]a9754872013-01-25 07:44:00118 internal::kShellWindowId_UnparentedControlContainer,
[email protected]f1853122012-06-27 16:21:26119 };
[email protected]ef0e32cc2012-10-31 20:57:33120 // For workspace windows we need to manually reparent the windows. This way
121 // workspace can move the windows to the appropriate workspace.
[email protected]c96b9812012-10-17 16:04:04122 std::vector<aura::Window*> windows(GetWorkspaceWindows(src));
123 internal::WorkspaceController* workspace_controller =
124 GetRootWindowController(dst)->workspace_controller();
125 for (size_t i = 0; i < windows.size(); ++i) {
126 aura::Window* new_parent =
127 workspace_controller->GetParentForNewWindow(windows[i]);
128 ReparentWindow(windows[i], new_parent);
[email protected]95058572012-08-20 14:57:29129 }
[email protected]f1853122012-06-27 16:21:26130 for (size_t i = 0; i < arraysize(kContainerIdsToMove); i++) {
131 int id = kContainerIdsToMove[i];
[email protected]c96b9812012-10-17 16:04:04132 if (id == internal::kShellWindowId_DefaultContainer)
[email protected]95058572012-08-20 14:57:29133 continue;
134
[email protected]f1853122012-06-27 16:21:26135 aura::Window* src_container = Shell::GetContainer(src, id);
136 aura::Window* dst_container = Shell::GetContainer(dst, id);
137 aura::Window::Windows children = src_container->children();
138 for (aura::Window::Windows::iterator iter = children.begin();
139 iter != children.end(); ++iter) {
140 aura::Window* window = *iter;
141 // Don't move modal screen.
[email protected]c0ce80e2012-10-05 23:28:27142 if (internal::SystemModalContainerLayoutManager::IsModalBackground(
143 window))
[email protected]f1853122012-06-27 16:21:26144 continue;
[email protected]f059c6942012-07-21 14:27:57145
[email protected]95058572012-08-20 14:57:29146 ReparentWindow(window, dst_container);
[email protected]f1853122012-06-27 16:21:26147 }
148 }
149}
150
[email protected]8d625fb2012-07-18 16:40:06151// Mark the container window so that a widget added to this container will
152// use the virtual screeen coordinates instead of parent.
153void SetUsesScreenCoordinates(aura::Window* container) {
154 container->SetProperty(internal::kUsesScreenCoordinatesKey, true);
155}
156
[email protected]d90b8392012-06-13 09:34:56157} // namespace
158
159namespace internal {
160
161RootWindowController::RootWindowController(aura::RootWindow* root_window)
[email protected]e74aaf0a2012-10-12 18:42:28162 : root_window_(root_window),
163 root_window_layout_(NULL),
164 status_area_widget_(NULL),
165 shelf_(NULL),
166 panel_layout_manager_(NULL) {
[email protected]d90b8392012-06-13 09:34:56167 SetRootWindowController(root_window, this);
[email protected]c0ce80e2012-10-05 23:28:27168 screen_dimmer_.reset(new ScreenDimmer(root_window));
[email protected]2a2caa02013-01-22 20:50:36169
170 stacking_controller_.reset(new ash::StackingController);
171 aura::client::SetStackingClient(root_window, stacking_controller_.get());
[email protected]d90b8392012-06-13 09:34:56172}
173
174RootWindowController::~RootWindowController() {
[email protected]6675e1c2012-09-11 09:15:45175 Shutdown();
176 root_window_.reset();
177}
178
[email protected]88d71122012-10-18 07:11:01179// static
[email protected]a0afeb12012-12-10 22:57:09180RootWindowController* RootWindowController::ForLauncher(aura::Window* window) {
[email protected]88d71122012-10-18 07:11:01181 if (Shell::IsLauncherPerDisplayEnabled())
182 return GetRootWindowController(window->GetRootWindow());
183 else
184 return Shell::GetPrimaryRootWindowController();
185}
186
[email protected]a0afeb12012-12-10 22:57:09187// static
188RootWindowController* RootWindowController::ForWindow(aura::Window* window) {
189 return GetRootWindowController(window->GetRootWindow());
190}
191
192// static
193RootWindowController* RootWindowController::ForActiveRootWindow() {
194 return GetRootWindowController(Shell::GetActiveRootWindow());
195}
196
[email protected]6675e1c2012-09-11 09:15:45197void RootWindowController::Shutdown() {
198 CloseChildWindows();
[email protected]f634dd32012-07-23 22:49:07199 if (Shell::GetActiveRootWindow() == root_window_.get()) {
200 Shell::GetInstance()->set_active_root_window(
201 Shell::GetPrimaryRootWindow() == root_window_.get() ?
202 NULL : Shell::GetPrimaryRootWindow());
203 }
[email protected]d90b8392012-06-13 09:34:56204 SetRootWindowController(root_window_.get(), NULL);
[email protected]d90b8392012-06-13 09:34:56205 screen_dimmer_.reset();
206 workspace_controller_.reset();
[email protected]6675e1c2012-09-11 09:15:45207 // Forget with the display ID so that display lookup
208 // ends up with invalid display.
209 root_window_->ClearProperty(kDisplayIdKey);
210 // And this root window should no longer process events.
211 root_window_->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28212
[email protected]956a6a42012-10-29 23:58:10213 system_background_.reset();
214
[email protected]e74aaf0a2012-10-12 18:42:28215 // Launcher widget has an InputMethodBridge that references to
216 // |input_method_filter_|'s |input_method_|. So explicitly release
217 // |launcher_| before |input_method_filter_|. And this needs to be
218 // after we delete all containers in case there are still live
219 // browser windows which access LauncherModel during close.
220 launcher_.reset();
[email protected]d90b8392012-06-13 09:34:56221}
222
[email protected]c0ce80e2012-10-05 23:28:27223SystemModalContainerLayoutManager*
[email protected]8674b312012-10-12 19:02:44224RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
225 aura::Window* container = NULL;
226 if (window) {
[email protected]3b162e12012-11-09 11:52:35227 if (window->parent() &&
228 window->parent()->id() >= kShellWindowId_LockScreenContainer) {
229 container = GetContainer(kShellWindowId_LockSystemModalContainer);
230 } else {
[email protected]8674b312012-10-12 19:02:44231 container = GetContainer(kShellWindowId_SystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35232 }
[email protected]8674b312012-10-12 19:02:44233 } else {
[email protected]945f9cae2012-12-12 09:54:29234 user::LoginStatus login = Shell::GetInstance()->system_tray_delegate() ?
235 Shell::GetInstance()->system_tray_delegate()->GetUserLoginStatus() :
[email protected]8674b312012-10-12 19:02:44236 user::LOGGED_IN_NONE;
237 int modal_window_id = (login == user::LOGGED_IN_LOCKED ||
238 login == user::LOGGED_IN_NONE) ?
239 kShellWindowId_LockSystemModalContainer :
240 kShellWindowId_SystemModalContainer;
241 container = GetContainer(modal_window_id);
242 }
[email protected]c0ce80e2012-10-05 23:28:27243 return static_cast<SystemModalContainerLayoutManager*>(
[email protected]8674b312012-10-12 19:02:44244 container->layout_manager());
[email protected]c0ce80e2012-10-05 23:28:27245}
246
[email protected]d90b8392012-06-13 09:34:56247aura::Window* RootWindowController::GetContainer(int container_id) {
248 return root_window_->GetChildById(container_id);
249}
250
251void RootWindowController::InitLayoutManagers() {
252 root_window_layout_ =
[email protected]c0ce80e2012-10-05 23:28:27253 new RootWindowLayoutManager(root_window_.get());
[email protected]d90b8392012-06-13 09:34:56254 root_window_->SetLayoutManager(root_window_layout_);
255
256 aura::Window* default_container =
[email protected]c0ce80e2012-10-05 23:28:27257 GetContainer(kShellWindowId_DefaultContainer);
[email protected]d90b8392012-06-13 09:34:56258 // Workspace manager has its own layout managers.
259 workspace_controller_.reset(
[email protected]c0ce80e2012-10-05 23:28:27260 new WorkspaceController(default_container));
[email protected]d90b8392012-06-13 09:34:56261
262 aura::Window* always_on_top_container =
[email protected]c0ce80e2012-10-05 23:28:27263 GetContainer(kShellWindowId_AlwaysOnTopContainer);
[email protected]d90b8392012-06-13 09:34:56264 always_on_top_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27265 new BaseLayoutManager(
[email protected]d90b8392012-06-13 09:34:56266 always_on_top_container->GetRootWindow()));
267}
268
[email protected]e74aaf0a2012-10-12 18:42:28269void RootWindowController::InitForPrimaryDisplay() {
270 DCHECK(!status_area_widget_);
[email protected]16059276d2012-10-22 18:59:50271 aura::Window* status_container =
272 GetContainer(ash::internal::kShellWindowId_StatusContainer);
[email protected]e74aaf0a2012-10-12 18:42:28273 // Initialize Primary RootWindow specific items.
[email protected]16059276d2012-10-22 18:59:50274 status_area_widget_ = new internal::StatusAreaWidget(status_container);
[email protected]51ed5992012-11-07 10:14:39275 status_area_widget_->CreateTrayViews();
[email protected]e74aaf0a2012-10-12 18:42:28276 // Login screen manages status area visibility by itself.
[email protected]51ed5992012-11-07 10:14:39277 ShellDelegate* shell_delegate = Shell::GetInstance()->delegate();
[email protected]02dbd1a2012-11-08 22:50:13278 if (shell_delegate->IsSessionStarted())
[email protected]e74aaf0a2012-10-12 18:42:28279 status_area_widget_->Show();
280
281 Shell::GetInstance()->focus_cycler()->AddWidget(status_area_widget_);
282
283 internal::ShelfLayoutManager* shelf_layout_manager =
284 new internal::ShelfLayoutManager(status_area_widget_);
285 GetContainer(internal::kShellWindowId_LauncherContainer)->
286 SetLayoutManager(shelf_layout_manager);
287 shelf_ = shelf_layout_manager;
288
289 internal::StatusAreaLayoutManager* status_area_layout_manager =
290 new internal::StatusAreaLayoutManager(shelf_layout_manager);
291 GetContainer(internal::kShellWindowId_StatusContainer)->
292 SetLayoutManager(status_area_layout_manager);
293
294 shelf_layout_manager->set_workspace_controller(
295 workspace_controller());
296
297 workspace_controller()->SetShelf(shelf_);
298
[email protected]e5a3deba2012-12-15 20:18:28299 // TODO(oshima): Disable panels on non primary display for now.
300 // crbug.com/166195.
301 if (root_window_ == Shell::GetPrimaryRootWindow()) {
302 // Create Panel layout manager
303 aura::Window* panel_container = GetContainer(
304 internal::kShellWindowId_PanelContainer);
305 panel_layout_manager_ =
306 new internal::PanelLayoutManager(panel_container);
307 panel_container->AddPreTargetHandler(
308 new internal::PanelWindowEventFilter(
309 panel_container, panel_layout_manager_));
310 panel_container->SetLayoutManager(panel_layout_manager_);
311 }
[email protected]e74aaf0a2012-10-12 18:42:28312
[email protected]02dbd1a2012-11-08 22:50:13313 if (shell_delegate->IsUserLoggedIn())
[email protected]e74aaf0a2012-10-12 18:42:28314 CreateLauncher();
315}
316
[email protected]d90b8392012-06-13 09:34:56317void RootWindowController::CreateContainers() {
318 CreateContainersInRootWindow(root_window_.get());
319}
320
[email protected]697f04c2012-10-03 01:15:10321void RootWindowController::CreateSystemBackground(
322 bool is_first_run_after_boot) {
[email protected]bca9a7e2012-11-10 06:25:49323 SkColor color = SK_ColorBLACK;
[email protected]697f04c2012-10-03 01:15:10324#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:49325 if (is_first_run_after_boot)
326 color = kChromeOsBootColor;
[email protected]697f04c2012-10-03 01:15:10327#endif
[email protected]e6e41d2f2012-10-29 19:22:19328 system_background_.reset(
[email protected]bca9a7e2012-11-10 06:25:49329 new SystemBackgroundController(root_window_.get(), color));
330
331#if defined(OS_CHROMEOS)
332 // Make a copy of the system's boot splash screen so we can composite it
333 // onscreen until the desktop background is ready.
334 if (is_first_run_after_boot &&
335 (CommandLine::ForCurrentProcess()->HasSwitch(
336 switches::kAshCopyHostBackgroundAtBoot) ||
337 CommandLine::ForCurrentProcess()->HasSwitch(
338 switches::kAshAnimateFromBootSplashScreen)))
339 boot_splash_screen_.reset(new BootSplashScreen(root_window_.get()));
340#endif
[email protected]697f04c2012-10-03 01:15:10341}
342
[email protected]e74aaf0a2012-10-12 18:42:28343void RootWindowController::CreateLauncher() {
344 if (launcher_.get())
345 return;
346
347 aura::Window* default_container =
348 GetContainer(internal::kShellWindowId_DefaultContainer);
[email protected]0af58042012-12-13 03:21:35349 // Get the delegate first to make sure the launcher model is created.
350 LauncherDelegate* launcher_delegate =
351 Shell::GetInstance()->GetLauncherDelegate();
352 launcher_.reset(new Launcher(Shell::GetInstance()->launcher_model(),
353 launcher_delegate,
354 default_container,
355 shelf_));
[email protected]e74aaf0a2012-10-12 18:42:28356
357 launcher_->SetFocusCycler(Shell::GetInstance()->focus_cycler());
358 shelf_->SetLauncher(launcher_.get());
359
360 if (panel_layout_manager_)
361 panel_layout_manager_->SetLauncher(launcher_.get());
362
363 ShellDelegate* delegate = Shell::GetInstance()->delegate();
364 if (delegate)
365 launcher_->SetVisible(delegate->IsSessionStarted());
366 launcher_->widget()->Show();
367}
368
369void RootWindowController::ShowLauncher() {
370 if (!launcher_.get())
371 return;
372 launcher_->SetVisible(true);
[email protected]cb47bcb32012-11-05 21:36:38373 status_area_widget_->Show();
[email protected]e74aaf0a2012-10-12 18:42:28374}
375
[email protected]16059276d2012-10-22 18:59:50376void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
377 // TODO(oshima): remove if when launcher per display is enabled by
378 // default.
379 if (shelf_)
380 shelf_->UpdateVisibilityState();
381}
382
383void RootWindowController::UpdateAfterLoginStatusChange(
384 user::LoginStatus status) {
385 if (status_area_widget_)
386 status_area_widget_->UpdateAfterLoginStatusChange(status);
387}
388
[email protected]bca9a7e2012-11-10 06:25:49389void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
390 if (CommandLine::ForCurrentProcess()->HasSwitch(
391 switches::kAshAnimateFromBootSplashScreen) &&
392 boot_splash_screen_.get()) {
393 // Make the splash screen fade out so it doesn't obscure the desktop
394 // wallpaper's brightness/grayscale animation.
395 boot_splash_screen_->StartHideAnimation(
396 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
397 }
398}
399
[email protected]697f04c2012-10-03 01:15:10400void RootWindowController::HandleDesktopBackgroundVisible() {
[email protected]bca9a7e2012-11-10 06:25:49401 system_background_->SetColor(SK_ColorBLACK);
402 boot_splash_screen_.reset();
[email protected]697f04c2012-10-03 01:15:10403}
404
[email protected]d90b8392012-06-13 09:34:56405void RootWindowController::CloseChildWindows() {
[email protected]e74aaf0a2012-10-12 18:42:28406 // The status area needs to be shut down before the windows are destroyed.
[email protected]8674b312012-10-12 19:02:44407 if (status_area_widget_) {
[email protected]e74aaf0a2012-10-12 18:42:28408 status_area_widget_->Shutdown();
[email protected]8674b312012-10-12 19:02:44409 status_area_widget_ = NULL;
410 }
[email protected]e74aaf0a2012-10-12 18:42:28411
[email protected]79a87b7e2013-01-25 05:08:22412 // panel_layout_manager_ needs to be shut down before windows are destroyed.
413 if (panel_layout_manager_) {
414 panel_layout_manager_->Shutdown();
415 panel_layout_manager_ = NULL;
416 }
417
[email protected]e74aaf0a2012-10-12 18:42:28418 // Closing the windows frees the workspace controller.
419 if (shelf_)
420 shelf_->set_workspace_controller(NULL);
421
[email protected]d90b8392012-06-13 09:34:56422 // Close background widget first as it depends on tooltip.
[email protected]d86de6b22012-10-05 19:32:58423 root_window_->SetProperty(kDesktopController,
[email protected]b4ddc7a2012-08-07 04:17:32424 static_cast<DesktopBackgroundWidgetController*>(NULL));
[email protected]d86de6b22012-10-05 19:32:58425 root_window_->SetProperty(kAnimatingDesktopController,
426 static_cast<AnimatingDesktopController*>(NULL));
[email protected]b4ddc7a2012-08-07 04:17:32427
[email protected]d90b8392012-06-13 09:34:56428 workspace_controller_.reset();
429 aura::client::SetTooltipClient(root_window_.get(), NULL);
430
431 while (!root_window_->children().empty()) {
432 aura::Window* child = root_window_->children()[0];
433 delete child;
434 }
[email protected]83482fbf2012-11-21 14:02:09435 launcher_.reset();
[email protected]e74aaf0a2012-10-12 18:42:28436 // All containers are deleted, so reset shelf_.
437 shelf_ = NULL;
[email protected]d90b8392012-06-13 09:34:56438}
439
[email protected]f1853122012-06-27 16:21:26440void RootWindowController::MoveWindowsTo(aura::RootWindow* dst) {
[email protected]8cfb6722012-11-28 03:28:46441 aura::Window* focused = aura::client::GetFocusClient(dst)->GetFocusedWindow();
[email protected]dbf835d82012-09-11 18:23:09442 aura::WindowTracker tracker;
443 if (focused)
444 tracker.Add(focused);
[email protected]f1853122012-06-27 16:21:26445 aura::client::ActivationClient* activation_client =
446 aura::client::GetActivationClient(dst);
447 aura::Window* active = activation_client->GetActiveWindow();
[email protected]dbf835d82012-09-11 18:23:09448 if (active && focused != active)
449 tracker.Add(active);
[email protected]f1853122012-06-27 16:21:26450 // Deactivate the window to close menu / bubble windows.
451 activation_client->DeactivateWindow(active);
452 // Release capture if any.
453 aura::client::GetCaptureClient(root_window_.get())->
454 SetCapture(NULL);
[email protected]dbf835d82012-09-11 18:23:09455 // Clear the focused window if any. This is necessary because a
456 // window may be deleted when losing focus (fullscreen flash for
457 // example). If the focused window is still alive after move, it'll
458 // be re-focused below.
[email protected]550543e2013-01-11 22:43:44459 aura::client::GetFocusClient(dst)->FocusWindow(NULL);
[email protected]f1853122012-06-27 16:21:26460
[email protected]8039e06c2013-01-17 23:34:50461 // Forget the shelf early so that shelf don't update itself using wrong
462 // display info.
463 workspace_controller_->SetShelf(NULL);
464
[email protected]95058572012-08-20 14:57:29465 ReparentAllWindows(root_window_.get(), dst);
[email protected]f1853122012-06-27 16:21:26466
467 // Restore focused or active window if it's still alive.
[email protected]1d030242012-06-28 18:34:08468 if (focused && tracker.Contains(focused) && dst->Contains(focused)) {
[email protected]550543e2013-01-11 22:43:44469 aura::client::GetFocusClient(dst)->FocusWindow(focused);
[email protected]1d030242012-06-28 18:34:08470 } else if (active && tracker.Contains(active) && dst->Contains(active)) {
[email protected]f1853122012-06-27 16:21:26471 activation_client->ActivateWindow(active);
472 }
473}
474
[email protected]a0afeb12012-12-10 22:57:09475SystemTray* RootWindowController::GetSystemTray() {
476 // We assume in throughout the code that this will not return NULL. If code
477 // triggers this for valid reasons, it should test status_area_widget first.
478 internal::StatusAreaWidget* status_area = status_area_widget();
479 CHECK(status_area);
480 return status_area->system_tray();
481}
482
[email protected]431552c2012-10-23 00:38:33483void RootWindowController::ShowContextMenu(
484 const gfx::Point& location_in_screen) {
485 aura::RootWindow* target = Shell::IsLauncherPerDisplayEnabled() ?
486 root_window() : Shell::GetPrimaryRootWindow();
487 DCHECK(Shell::GetInstance()->delegate());
488 scoped_ptr<ui::MenuModel> menu_model(
489 Shell::GetInstance()->delegate()->CreateContextMenu(target));
[email protected]8e837ec2013-01-31 01:48:33490 if (!menu_model.get())
491 return;
[email protected]431552c2012-10-23 00:38:33492
493 views::MenuModelAdapter menu_model_adapter(menu_model.get());
494 views::MenuRunner menu_runner(menu_model_adapter.CreateMenu());
495 views::Widget* widget =
496 root_window_->GetProperty(kDesktopController)->widget();
497
498 if (menu_runner.RunMenuAt(
499 widget, NULL, gfx::Rect(location_in_screen, gfx::Size()),
500 views::MenuItemView::TOPLEFT, views::MenuRunner::CONTEXT_MENU) ==
501 views::MenuRunner::MENU_DELETED)
502 return;
503
504 Shell::GetInstance()->UpdateShelfVisibility();
505}
506
[email protected]e74aaf0a2012-10-12 18:42:28507void RootWindowController::UpdateShelfVisibility() {
508 shelf_->UpdateVisibilityState();
509}
510
511void RootWindowController::SetShelfAutoHideBehavior(
512 ShelfAutoHideBehavior behavior) {
513 shelf_->SetAutoHideBehavior(behavior);
514}
515
516ShelfAutoHideBehavior RootWindowController::GetShelfAutoHideBehavior() const {
517 return shelf_->auto_hide_behavior();
518}
519
520bool RootWindowController::SetShelfAlignment(ShelfAlignment alignment) {
521 return shelf_->SetAlignment(alignment);
522}
523
524ShelfAlignment RootWindowController::GetShelfAlignment() {
[email protected]1fcfb992012-12-05 01:47:23525 return shelf_->GetAlignment();
[email protected]e74aaf0a2012-10-12 18:42:28526}
527
[email protected]2ee2f5d2013-01-10 23:37:16528bool RootWindowController::IsImmersiveMode() const {
529 aura::Window* container = workspace_controller_->GetActiveWorkspaceWindow();
530 for (size_t i = 0; i < container->children().size(); ++i) {
531 aura::Window* child = container->children()[i];
532 if (child->IsVisible() && child->GetProperty(kImmersiveModeKey))
533 return true;
534 }
535 return false;
536}
537
[email protected]a4cd6d32012-09-12 03:42:13538////////////////////////////////////////////////////////////////////////////////
539// RootWindowController, private:
540
541void RootWindowController::CreateContainersInRootWindow(
542 aura::RootWindow* root_window) {
543 // These containers are just used by PowerButtonController to animate groups
544 // of containers simultaneously without messing up the current transformations
545 // on those containers. These are direct children of the root window; all of
546 // the other containers are their children.
[email protected]e6e41d2f2012-10-29 19:22:19547
548 // The desktop background container is not part of the lock animation, so it
549 // is not included in those animate groups.
[email protected]a4cd6d32012-09-12 03:42:13550 // When screen is locked desktop background is moved to lock screen background
551 // container (moved back on unlock). We want to make sure that there's an
552 // opaque layer occluding the non-lock-screen layers.
[email protected]e6e41d2f2012-10-29 19:22:19553 aura::Window* desktop_background_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27554 kShellWindowId_DesktopBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13555 "DesktopBackgroundContainer",
556 root_window);
[email protected]b5756e22012-11-30 01:32:02557 views::corewm::SetChildWindowVisibilityChangesAnimated(
558 desktop_background_container);
[email protected]a4cd6d32012-09-12 03:42:13559
560 aura::Window* non_lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27561 kShellWindowId_NonLockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13562 "NonLockScreenContainersContainer",
563 root_window);
564
565 aura::Window* lock_background_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27566 kShellWindowId_LockScreenBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13567 "LockScreenBackgroundContainer",
568 root_window);
[email protected]b5756e22012-11-30 01:32:02569 views::corewm::SetChildWindowVisibilityChangesAnimated(
570 lock_background_containers);
[email protected]a4cd6d32012-09-12 03:42:13571
572 aura::Window* lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27573 kShellWindowId_LockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13574 "LockScreenContainersContainer",
575 root_window);
576 aura::Window* lock_screen_related_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27577 kShellWindowId_LockScreenRelatedContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13578 "LockScreenRelatedContainersContainer",
579 root_window);
580
[email protected]c0ce80e2012-10-05 23:28:27581 CreateContainer(kShellWindowId_UnparentedControlContainer,
[email protected]a4cd6d32012-09-12 03:42:13582 "UnparentedControlContainer",
583 non_lock_screen_containers);
584
585 aura::Window* default_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27586 kShellWindowId_DefaultContainer,
[email protected]a4cd6d32012-09-12 03:42:13587 "DefaultContainer",
588 non_lock_screen_containers);
[email protected]b5756e22012-11-30 01:32:02589 views::corewm::SetChildWindowVisibilityChangesAnimated(default_container);
[email protected]a4cd6d32012-09-12 03:42:13590 SetUsesScreenCoordinates(default_container);
591
592 aura::Window* always_on_top_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27593 kShellWindowId_AlwaysOnTopContainer,
[email protected]a4cd6d32012-09-12 03:42:13594 "AlwaysOnTopContainer",
595 non_lock_screen_containers);
596 always_on_top_container_handler_.reset(
597 new ToplevelWindowEventHandler(always_on_top_container));
[email protected]b5756e22012-11-30 01:32:02598 views::corewm::SetChildWindowVisibilityChangesAnimated(
599 always_on_top_container);
[email protected]a4cd6d32012-09-12 03:42:13600 SetUsesScreenCoordinates(always_on_top_container);
601
602 aura::Window* panel_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27603 kShellWindowId_PanelContainer,
[email protected]a4cd6d32012-09-12 03:42:13604 "PanelContainer",
605 non_lock_screen_containers);
606 SetUsesScreenCoordinates(panel_container);
607
608 aura::Window* launcher_container =
[email protected]c0ce80e2012-10-05 23:28:27609 CreateContainer(kShellWindowId_LauncherContainer,
[email protected]a4cd6d32012-09-12 03:42:13610 "LauncherContainer",
611 non_lock_screen_containers);
612 SetUsesScreenCoordinates(launcher_container);
613
[email protected]dc851a4e52012-10-03 00:05:55614 aura::Window* app_list_container =
[email protected]c0ce80e2012-10-05 23:28:27615 CreateContainer(kShellWindowId_AppListContainer,
[email protected]dc851a4e52012-10-03 00:05:55616 "AppListContainer",
617 non_lock_screen_containers);
618 SetUsesScreenCoordinates(app_list_container);
[email protected]a4cd6d32012-09-12 03:42:13619
620 aura::Window* modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27621 kShellWindowId_SystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13622 "SystemModalContainer",
623 non_lock_screen_containers);
624 modal_container_handler_.reset(
625 new ToplevelWindowEventHandler(modal_container));
[email protected]a4cd6d32012-09-12 03:42:13626 modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27627 new SystemModalContainerLayoutManager(modal_container));
[email protected]b5756e22012-11-30 01:32:02628 views::corewm::SetChildWindowVisibilityChangesAnimated(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13629 SetUsesScreenCoordinates(modal_container);
630
631 aura::Window* input_method_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27632 kShellWindowId_InputMethodContainer,
[email protected]a4cd6d32012-09-12 03:42:13633 "InputMethodContainer",
634 non_lock_screen_containers);
635 SetUsesScreenCoordinates(input_method_container);
636
637 // TODO(beng): Figure out if we can make this use
638 // SystemModalContainerEventFilter instead of stops_event_propagation.
639 aura::Window* lock_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27640 kShellWindowId_LockScreenContainer,
[email protected]a4cd6d32012-09-12 03:42:13641 "LockScreenContainer",
642 lock_screen_containers);
643 lock_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27644 new BaseLayoutManager(root_window));
[email protected]a4cd6d32012-09-12 03:42:13645 SetUsesScreenCoordinates(lock_container);
646 // TODO(beng): stopsevents
647
648 aura::Window* lock_modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27649 kShellWindowId_LockSystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13650 "LockSystemModalContainer",
651 lock_screen_containers);
652 lock_modal_container_handler_.reset(
653 new ToplevelWindowEventHandler(lock_modal_container));
[email protected]a4cd6d32012-09-12 03:42:13654 lock_modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27655 new SystemModalContainerLayoutManager(lock_modal_container));
[email protected]b5756e22012-11-30 01:32:02656 views::corewm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13657 SetUsesScreenCoordinates(lock_modal_container);
658
659 aura::Window* status_container =
[email protected]c0ce80e2012-10-05 23:28:27660 CreateContainer(kShellWindowId_StatusContainer,
[email protected]a4cd6d32012-09-12 03:42:13661 "StatusContainer",
662 lock_screen_related_containers);
663 SetUsesScreenCoordinates(status_container);
664
665 aura::Window* settings_bubble_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27666 kShellWindowId_SettingBubbleContainer,
[email protected]a4cd6d32012-09-12 03:42:13667 "SettingBubbleContainer",
668 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02669 views::corewm::SetChildWindowVisibilityChangesAnimated(
670 settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13671 SetUsesScreenCoordinates(settings_bubble_container);
672
673 aura::Window* menu_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27674 kShellWindowId_MenuContainer,
[email protected]a4cd6d32012-09-12 03:42:13675 "MenuContainer",
676 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02677 views::corewm::SetChildWindowVisibilityChangesAnimated(menu_container);
[email protected]a4cd6d32012-09-12 03:42:13678 SetUsesScreenCoordinates(menu_container);
679
680 aura::Window* drag_drop_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27681 kShellWindowId_DragImageAndTooltipContainer,
[email protected]a4cd6d32012-09-12 03:42:13682 "DragImageAndTooltipContainer",
683 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02684 views::corewm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
[email protected]a4cd6d32012-09-12 03:42:13685 SetUsesScreenCoordinates(drag_drop_container);
686
687 aura::Window* overlay_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27688 kShellWindowId_OverlayContainer,
[email protected]a4cd6d32012-09-12 03:42:13689 "OverlayContainer",
690 lock_screen_related_containers);
691 SetUsesScreenCoordinates(overlay_container);
[email protected]a07615f2012-10-24 08:23:08692
693 CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
694 "PowerButtonAnimationContainer", root_window) ;
[email protected]a4cd6d32012-09-12 03:42:13695}
696
[email protected]d90b8392012-06-13 09:34:56697} // namespace internal
698} // namespace ash