blob: 5fa1934d18fc2ce54b53b7df1c3748fafff22ac0 [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]478c6c32013-03-09 02:50:5815#include "ash/shelf/shelf_layout_manager.h"
16#include "ash/shelf/shelf_types.h"
17#include "ash/shelf/shelf_widget.h"
[email protected]d90b8392012-06-13 09:34:5618#include "ash/shell.h"
[email protected]e74aaf0a2012-10-12 18:42:2819#include "ash/shell_delegate.h"
[email protected]d90b8392012-06-13 09:34:5620#include "ash/shell_factory.h"
21#include "ash/shell_window_ids.h"
[email protected]e74aaf0a2012-10-12 18:42:2822#include "ash/system/status_area_widget.h"
[email protected]8674b312012-10-12 19:02:4423#include "ash/system/tray/system_tray_delegate.h"
[email protected]58175042013-04-01 19:27:1324#include "ash/touch/touch_observer_hud.h"
[email protected]d90b8392012-06-13 09:34:5625#include "ash/wm/base_layout_manager.h"
[email protected]bca9a7e2012-11-10 06:25:4926#include "ash/wm/boot_splash_screen.h"
[email protected]7095a652013-03-07 19:41:4927#include "ash/wm/panels/panel_layout_manager.h"
[email protected]d90b8392012-06-13 09:34:5628#include "ash/wm/property_util.h"
29#include "ash/wm/root_window_layout_manager.h"
30#include "ash/wm/screen_dimmer.h"
[email protected]2a2caa02013-01-22 20:50:3631#include "ash/wm/stacking_controller.h"
[email protected]e74aaf0a2012-10-12 18:42:2832#include "ash/wm/status_area_layout_manager.h"
[email protected]e6e41d2f2012-10-29 19:22:1933#include "ash/wm/system_background_controller.h"
[email protected]d90b8392012-06-13 09:34:5634#include "ash/wm/system_modal_container_layout_manager.h"
[email protected]5dc51db82012-09-11 03:39:0135#include "ash/wm/toplevel_window_event_handler.h"
[email protected]8d625fb2012-07-18 16:40:0636#include "ash/wm/window_properties.h"
[email protected]d90b8392012-06-13 09:34:5637#include "ash/wm/workspace_controller.h"
[email protected]e6e41d2f2012-10-29 19:22:1938#include "base/command_line.h"
[email protected]bca9a7e2012-11-10 06:25:4939#include "base/time.h"
[email protected]f1853122012-06-27 16:21:2640#include "ui/aura/client/activation_client.h"
41#include "ui/aura/client/aura_constants.h"
42#include "ui/aura/client/capture_client.h"
[email protected]8cfb6722012-11-28 03:28:4643#include "ui/aura/client/focus_client.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]1d030242012-06-28 18:34:0848#include "ui/aura/window_tracker.h"
[email protected]431552c2012-10-23 00:38:3349#include "ui/base/models/menu_model.h"
[email protected]8d625fb2012-07-18 16:40:0650#include "ui/gfx/display.h"
51#include "ui/gfx/screen.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]e74aaf0a2012-10-12 18:42:28169 shelf_(NULL),
170 panel_layout_manager_(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]88d71122012-10-18 07:11:01185 if (Shell::IsLauncherPerDisplayEnabled())
186 return GetRootWindowController(window->GetRootWindow());
187 else
188 return Shell::GetPrimaryRootWindowController();
189}
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() {
[email protected]58175042013-04-01 19:27:13203 // Remove touch observer HUD.
204 SetTouchObserverHUD(NULL);
205
[email protected]6675e1c2012-09-11 09:15:45206 CloseChildWindows();
[email protected]f634dd32012-07-23 22:49:07207 if (Shell::GetActiveRootWindow() == root_window_.get()) {
208 Shell::GetInstance()->set_active_root_window(
209 Shell::GetPrimaryRootWindow() == root_window_.get() ?
210 NULL : Shell::GetPrimaryRootWindow());
211 }
[email protected]d90b8392012-06-13 09:34:56212 SetRootWindowController(root_window_.get(), NULL);
[email protected]d90b8392012-06-13 09:34:56213 screen_dimmer_.reset();
214 workspace_controller_.reset();
[email protected]6675e1c2012-09-11 09:15:45215 // Forget with the display ID so that display lookup
216 // ends up with invalid display.
217 root_window_->ClearProperty(kDisplayIdKey);
218 // And this root window should no longer process events.
219 root_window_->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28220
[email protected]956a6a42012-10-29 23:58:10221 system_background_.reset();
[email protected]d90b8392012-06-13 09:34:56222}
223
[email protected]c0ce80e2012-10-05 23:28:27224SystemModalContainerLayoutManager*
[email protected]8674b312012-10-12 19:02:44225RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
226 aura::Window* container = NULL;
227 if (window) {
[email protected]3b162e12012-11-09 11:52:35228 if (window->parent() &&
229 window->parent()->id() >= kShellWindowId_LockScreenContainer) {
230 container = GetContainer(kShellWindowId_LockSystemModalContainer);
231 } else {
[email protected]8674b312012-10-12 19:02:44232 container = GetContainer(kShellWindowId_SystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35233 }
[email protected]8674b312012-10-12 19:02:44234 } else {
[email protected]945f9cae2012-12-12 09:54:29235 user::LoginStatus login = Shell::GetInstance()->system_tray_delegate() ?
236 Shell::GetInstance()->system_tray_delegate()->GetUserLoginStatus() :
[email protected]8674b312012-10-12 19:02:44237 user::LOGGED_IN_NONE;
238 int modal_window_id = (login == user::LOGGED_IN_LOCKED ||
239 login == user::LOGGED_IN_NONE) ?
240 kShellWindowId_LockSystemModalContainer :
241 kShellWindowId_SystemModalContainer;
242 container = GetContainer(modal_window_id);
243 }
[email protected]c0ce80e2012-10-05 23:28:27244 return static_cast<SystemModalContainerLayoutManager*>(
[email protected]8674b312012-10-12 19:02:44245 container->layout_manager());
[email protected]c0ce80e2012-10-05 23:28:27246}
247
[email protected]d90b8392012-06-13 09:34:56248aura::Window* RootWindowController::GetContainer(int container_id) {
249 return root_window_->GetChildById(container_id);
250}
251
252void RootWindowController::InitLayoutManagers() {
253 root_window_layout_ =
[email protected]c0ce80e2012-10-05 23:28:27254 new RootWindowLayoutManager(root_window_.get());
[email protected]d90b8392012-06-13 09:34:56255 root_window_->SetLayoutManager(root_window_layout_);
256
257 aura::Window* default_container =
[email protected]c0ce80e2012-10-05 23:28:27258 GetContainer(kShellWindowId_DefaultContainer);
[email protected]d90b8392012-06-13 09:34:56259 // Workspace manager has its own layout managers.
260 workspace_controller_.reset(
[email protected]c0ce80e2012-10-05 23:28:27261 new WorkspaceController(default_container));
[email protected]d90b8392012-06-13 09:34:56262
263 aura::Window* always_on_top_container =
[email protected]c0ce80e2012-10-05 23:28:27264 GetContainer(kShellWindowId_AlwaysOnTopContainer);
[email protected]d90b8392012-06-13 09:34:56265 always_on_top_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27266 new BaseLayoutManager(
[email protected]d90b8392012-06-13 09:34:56267 always_on_top_container->GetRootWindow()));
268}
269
[email protected]e74aaf0a2012-10-12 18:42:28270void RootWindowController::InitForPrimaryDisplay() {
[email protected]478c6c32013-03-09 02:50:58271 DCHECK(!shelf_.get());
272 aura::Window* shelf_container =
273 GetContainer(ash::internal::kShellWindowId_ShelfContainer);
274 // TODO(harrym): Remove when status area is view.
[email protected]16059276d2012-10-22 18:59:50275 aura::Window* status_container =
276 GetContainer(ash::internal::kShellWindowId_StatusContainer);
[email protected]478c6c32013-03-09 02:50:58277 shelf_.reset(new ash::ShelfWidget(
278 shelf_container, status_container, workspace_controller()));
[email protected]e74aaf0a2012-10-12 18:42:28279
[email protected]95db9c12013-01-31 11:47:44280 if (Shell::IsLauncherPerDisplayEnabled() ||
281 root_window_ == Shell::GetPrimaryRootWindow()) {
[email protected]e5a3deba2012-12-15 20:18:28282 // Create Panel layout manager
283 aura::Window* panel_container = GetContainer(
284 internal::kShellWindowId_PanelContainer);
285 panel_layout_manager_ =
286 new internal::PanelLayoutManager(panel_container);
[email protected]582022052013-02-20 15:19:04287 panel_container_handler_.reset(
288 new ToplevelWindowEventHandler(panel_container));
[email protected]e5a3deba2012-12-15 20:18:28289 panel_container->SetLayoutManager(panel_layout_manager_);
290 }
[email protected]478c6c32013-03-09 02:50:58291 if (Shell::GetInstance()->delegate()->IsUserLoggedIn())
292 shelf_->CreateLauncher();
[email protected]e74aaf0a2012-10-12 18:42:28293}
294
[email protected]d90b8392012-06-13 09:34:56295void RootWindowController::CreateContainers() {
296 CreateContainersInRootWindow(root_window_.get());
[email protected]58175042013-04-01 19:27:13297
298 // Create touch observer HUD if needed. HUD should be created after the
299 // containers have been created, so that its widget can be added to them.
300 CommandLine* command_line = CommandLine::ForCurrentProcess();
301 if (command_line->HasSwitch(switches::kAshTouchHud)) {
302 int64 id = root_window_->GetProperty(kDisplayIdKey);
303 const gfx::Display& display = Shell::GetInstance()->display_manager()->
304 GetDisplayForId(id);
305 SetTouchObserverHUD(new TouchObserverHUD(display));
306 }
[email protected]d90b8392012-06-13 09:34:56307}
308
[email protected]697f04c2012-10-03 01:15:10309void RootWindowController::CreateSystemBackground(
310 bool is_first_run_after_boot) {
[email protected]bca9a7e2012-11-10 06:25:49311 SkColor color = SK_ColorBLACK;
[email protected]697f04c2012-10-03 01:15:10312#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:49313 if (is_first_run_after_boot)
314 color = kChromeOsBootColor;
[email protected]697f04c2012-10-03 01:15:10315#endif
[email protected]e6e41d2f2012-10-29 19:22:19316 system_background_.reset(
[email protected]bca9a7e2012-11-10 06:25:49317 new SystemBackgroundController(root_window_.get(), color));
318
319#if defined(OS_CHROMEOS)
320 // Make a copy of the system's boot splash screen so we can composite it
321 // onscreen until the desktop background is ready.
322 if (is_first_run_after_boot &&
323 (CommandLine::ForCurrentProcess()->HasSwitch(
324 switches::kAshCopyHostBackgroundAtBoot) ||
325 CommandLine::ForCurrentProcess()->HasSwitch(
326 switches::kAshAnimateFromBootSplashScreen)))
327 boot_splash_screen_.reset(new BootSplashScreen(root_window_.get()));
328#endif
[email protected]697f04c2012-10-03 01:15:10329}
330
[email protected]478c6c32013-03-09 02:50:58331void RootWindowController::OnLauncherCreated() {
[email protected]e74aaf0a2012-10-12 18:42:28332 if (panel_layout_manager_)
[email protected]478c6c32013-03-09 02:50:58333 panel_layout_manager_->SetLauncher(shelf_->launcher());
[email protected]e74aaf0a2012-10-12 18:42:28334}
335
336void RootWindowController::ShowLauncher() {
[email protected]478c6c32013-03-09 02:50:58337 if (!shelf_.get() || !shelf_->launcher())
[email protected]e74aaf0a2012-10-12 18:42:28338 return;
[email protected]478c6c32013-03-09 02:50:58339 shelf_->launcher()->SetVisible(true);
340 shelf_->status_area_widget()->Show();
[email protected]e74aaf0a2012-10-12 18:42:28341}
342
[email protected]16059276d2012-10-22 18:59:50343void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
344 // TODO(oshima): remove if when launcher per display is enabled by
345 // default.
[email protected]478c6c32013-03-09 02:50:58346 if (shelf_.get())
347 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]16059276d2012-10-22 18:59:50348}
349
350void RootWindowController::UpdateAfterLoginStatusChange(
351 user::LoginStatus status) {
[email protected]478c6c32013-03-09 02:50:58352 if (shelf_.get() && shelf_->status_area_widget())
353 shelf_->status_area_widget()->UpdateAfterLoginStatusChange(status);
[email protected]16059276d2012-10-22 18:59:50354}
355
[email protected]bca9a7e2012-11-10 06:25:49356void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
357 if (CommandLine::ForCurrentProcess()->HasSwitch(
358 switches::kAshAnimateFromBootSplashScreen) &&
359 boot_splash_screen_.get()) {
360 // Make the splash screen fade out so it doesn't obscure the desktop
361 // wallpaper's brightness/grayscale animation.
362 boot_splash_screen_->StartHideAnimation(
363 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
364 }
365}
366
[email protected]697f04c2012-10-03 01:15:10367void RootWindowController::HandleDesktopBackgroundVisible() {
[email protected]bca9a7e2012-11-10 06:25:49368 system_background_->SetColor(SK_ColorBLACK);
369 boot_splash_screen_.reset();
[email protected]697f04c2012-10-03 01:15:10370}
371
[email protected]d90b8392012-06-13 09:34:56372void RootWindowController::CloseChildWindows() {
[email protected]79a87b7e2013-01-25 05:08:22373 // panel_layout_manager_ needs to be shut down before windows are destroyed.
374 if (panel_layout_manager_) {
375 panel_layout_manager_->Shutdown();
376 panel_layout_manager_ = NULL;
377 }
378
[email protected]478c6c32013-03-09 02:50:58379 // TODO(harrym): Remove when Status Area Widget is a child view.
380 if (shelf_.get())
381 shelf_->ShutdownStatusAreaWidget();
382
383 if (shelf_.get() && shelf_->shelf_layout_manager())
384 shelf_->shelf_layout_manager()->set_workspace_controller(NULL);
[email protected]e74aaf0a2012-10-12 18:42:28385
[email protected]d90b8392012-06-13 09:34:56386 // Close background widget first as it depends on tooltip.
[email protected]d86de6b22012-10-05 19:32:58387 root_window_->SetProperty(kDesktopController,
[email protected]b4ddc7a2012-08-07 04:17:32388 static_cast<DesktopBackgroundWidgetController*>(NULL));
[email protected]d86de6b22012-10-05 19:32:58389 root_window_->SetProperty(kAnimatingDesktopController,
390 static_cast<AnimatingDesktopController*>(NULL));
[email protected]b4ddc7a2012-08-07 04:17:32391
[email protected]d90b8392012-06-13 09:34:56392 workspace_controller_.reset();
393 aura::client::SetTooltipClient(root_window_.get(), NULL);
394
395 while (!root_window_->children().empty()) {
396 aura::Window* child = root_window_->children()[0];
397 delete child;
398 }
[email protected]478c6c32013-03-09 02:50:58399
400 shelf_.reset(NULL);
[email protected]d90b8392012-06-13 09:34:56401}
402
[email protected]f1853122012-06-27 16:21:26403void RootWindowController::MoveWindowsTo(aura::RootWindow* dst) {
[email protected]8cfb6722012-11-28 03:28:46404 aura::Window* focused = aura::client::GetFocusClient(dst)->GetFocusedWindow();
[email protected]dbf835d82012-09-11 18:23:09405 aura::WindowTracker tracker;
406 if (focused)
407 tracker.Add(focused);
[email protected]f1853122012-06-27 16:21:26408 aura::client::ActivationClient* activation_client =
409 aura::client::GetActivationClient(dst);
410 aura::Window* active = activation_client->GetActiveWindow();
[email protected]dbf835d82012-09-11 18:23:09411 if (active && focused != active)
412 tracker.Add(active);
[email protected]f1853122012-06-27 16:21:26413 // Deactivate the window to close menu / bubble windows.
414 activation_client->DeactivateWindow(active);
415 // Release capture if any.
416 aura::client::GetCaptureClient(root_window_.get())->
417 SetCapture(NULL);
[email protected]dbf835d82012-09-11 18:23:09418 // Clear the focused window if any. This is necessary because a
419 // window may be deleted when losing focus (fullscreen flash for
420 // example). If the focused window is still alive after move, it'll
421 // be re-focused below.
[email protected]550543e2013-01-11 22:43:44422 aura::client::GetFocusClient(dst)->FocusWindow(NULL);
[email protected]f1853122012-06-27 16:21:26423
[email protected]8039e06c2013-01-17 23:34:50424 // Forget the shelf early so that shelf don't update itself using wrong
425 // display info.
426 workspace_controller_->SetShelf(NULL);
427
[email protected]95058572012-08-20 14:57:29428 ReparentAllWindows(root_window_.get(), dst);
[email protected]f1853122012-06-27 16:21:26429
430 // Restore focused or active window if it's still alive.
[email protected]1d030242012-06-28 18:34:08431 if (focused && tracker.Contains(focused) && dst->Contains(focused)) {
[email protected]550543e2013-01-11 22:43:44432 aura::client::GetFocusClient(dst)->FocusWindow(focused);
[email protected]1d030242012-06-28 18:34:08433 } else if (active && tracker.Contains(active) && dst->Contains(active)) {
[email protected]f1853122012-06-27 16:21:26434 activation_client->ActivateWindow(active);
435 }
436}
437
[email protected]58175042013-04-01 19:27:13438void RootWindowController::SetTouchObserverHUD(TouchObserverHUD* hud) {
439 if (touch_observer_hud_.get())
440 root_window_->RemovePreTargetHandler(touch_observer_hud_.get());
441 if (hud)
442 root_window_->AddPreTargetHandler(hud);
443 touch_observer_hud_.reset(hud);
444}
445
[email protected]478c6c32013-03-09 02:50:58446ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
447 return shelf_.get() ? shelf_->shelf_layout_manager() : NULL;
448}
449
[email protected]a0afeb12012-12-10 22:57:09450SystemTray* RootWindowController::GetSystemTray() {
451 // We assume in throughout the code that this will not return NULL. If code
452 // triggers this for valid reasons, it should test status_area_widget first.
[email protected]478c6c32013-03-09 02:50:58453 CHECK(shelf_.get() && shelf_->status_area_widget());
454 return shelf_->status_area_widget()->system_tray();
[email protected]a0afeb12012-12-10 22:57:09455}
456
[email protected]431552c2012-10-23 00:38:33457void RootWindowController::ShowContextMenu(
458 const gfx::Point& location_in_screen) {
459 aura::RootWindow* target = Shell::IsLauncherPerDisplayEnabled() ?
460 root_window() : Shell::GetPrimaryRootWindow();
461 DCHECK(Shell::GetInstance()->delegate());
462 scoped_ptr<ui::MenuModel> menu_model(
463 Shell::GetInstance()->delegate()->CreateContextMenu(target));
[email protected]8e837ec2013-01-31 01:48:33464 if (!menu_model.get())
465 return;
[email protected]431552c2012-10-23 00:38:33466
[email protected]6175fc42013-04-05 05:58:58467 internal::DesktopBackgroundWidgetController* background =
468 root_window_->GetProperty(kDesktopController);
469 // Background controller may not be set yet if user clicked on status are
470 // before initial animation completion. See crbug.com/222218
471 if (!background)
[email protected]431552c2012-10-23 00:38:33472 return;
473
[email protected]6175fc42013-04-05 05:58:58474 views::MenuRunner menu_runner(menu_model.get());
475 if (menu_runner.RunMenuAt(background->widget(),
476 NULL, gfx::Rect(location_in_screen, gfx::Size()),
477 views::MenuItemView::TOPLEFT, views::MenuRunner::CONTEXT_MENU) ==
478 views::MenuRunner::MENU_DELETED) {
479 return;
480 }
481
[email protected]431552c2012-10-23 00:38:33482 Shell::GetInstance()->UpdateShelfVisibility();
483}
484
[email protected]e74aaf0a2012-10-12 18:42:28485void RootWindowController::UpdateShelfVisibility() {
[email protected]478c6c32013-03-09 02:50:58486 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]e74aaf0a2012-10-12 18:42:28487}
488
[email protected]2ee2f5d2013-01-10 23:37:16489bool RootWindowController::IsImmersiveMode() const {
490 aura::Window* container = workspace_controller_->GetActiveWorkspaceWindow();
491 for (size_t i = 0; i < container->children().size(); ++i) {
492 aura::Window* child = container->children()[i];
493 if (child->IsVisible() && child->GetProperty(kImmersiveModeKey))
494 return true;
495 }
496 return false;
497}
498
[email protected]a4cd6d32012-09-12 03:42:13499////////////////////////////////////////////////////////////////////////////////
500// RootWindowController, private:
501
502void RootWindowController::CreateContainersInRootWindow(
503 aura::RootWindow* root_window) {
504 // These containers are just used by PowerButtonController to animate groups
505 // of containers simultaneously without messing up the current transformations
506 // on those containers. These are direct children of the root window; all of
507 // the other containers are their children.
[email protected]e6e41d2f2012-10-29 19:22:19508
509 // The desktop background container is not part of the lock animation, so it
510 // is not included in those animate groups.
[email protected]a4cd6d32012-09-12 03:42:13511 // When screen is locked desktop background is moved to lock screen background
512 // container (moved back on unlock). We want to make sure that there's an
513 // opaque layer occluding the non-lock-screen layers.
[email protected]e6e41d2f2012-10-29 19:22:19514 aura::Window* desktop_background_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27515 kShellWindowId_DesktopBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13516 "DesktopBackgroundContainer",
517 root_window);
[email protected]b5756e22012-11-30 01:32:02518 views::corewm::SetChildWindowVisibilityChangesAnimated(
519 desktop_background_container);
[email protected]a4cd6d32012-09-12 03:42:13520
521 aura::Window* non_lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27522 kShellWindowId_NonLockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13523 "NonLockScreenContainersContainer",
524 root_window);
525
526 aura::Window* lock_background_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27527 kShellWindowId_LockScreenBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13528 "LockScreenBackgroundContainer",
529 root_window);
[email protected]b5756e22012-11-30 01:32:02530 views::corewm::SetChildWindowVisibilityChangesAnimated(
531 lock_background_containers);
[email protected]a4cd6d32012-09-12 03:42:13532
533 aura::Window* lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27534 kShellWindowId_LockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13535 "LockScreenContainersContainer",
536 root_window);
537 aura::Window* lock_screen_related_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27538 kShellWindowId_LockScreenRelatedContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13539 "LockScreenRelatedContainersContainer",
540 root_window);
541
[email protected]c0ce80e2012-10-05 23:28:27542 CreateContainer(kShellWindowId_UnparentedControlContainer,
[email protected]a4cd6d32012-09-12 03:42:13543 "UnparentedControlContainer",
544 non_lock_screen_containers);
545
546 aura::Window* default_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27547 kShellWindowId_DefaultContainer,
[email protected]a4cd6d32012-09-12 03:42:13548 "DefaultContainer",
549 non_lock_screen_containers);
[email protected]b5756e22012-11-30 01:32:02550 views::corewm::SetChildWindowVisibilityChangesAnimated(default_container);
[email protected]a4cd6d32012-09-12 03:42:13551 SetUsesScreenCoordinates(default_container);
552
553 aura::Window* always_on_top_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27554 kShellWindowId_AlwaysOnTopContainer,
[email protected]a4cd6d32012-09-12 03:42:13555 "AlwaysOnTopContainer",
556 non_lock_screen_containers);
557 always_on_top_container_handler_.reset(
558 new ToplevelWindowEventHandler(always_on_top_container));
[email protected]b5756e22012-11-30 01:32:02559 views::corewm::SetChildWindowVisibilityChangesAnimated(
560 always_on_top_container);
[email protected]a4cd6d32012-09-12 03:42:13561 SetUsesScreenCoordinates(always_on_top_container);
562
563 aura::Window* panel_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27564 kShellWindowId_PanelContainer,
[email protected]a4cd6d32012-09-12 03:42:13565 "PanelContainer",
566 non_lock_screen_containers);
567 SetUsesScreenCoordinates(panel_container);
568
569 aura::Window* launcher_container =
[email protected]478c6c32013-03-09 02:50:58570 CreateContainer(kShellWindowId_ShelfContainer,
[email protected]a4cd6d32012-09-12 03:42:13571 "LauncherContainer",
572 non_lock_screen_containers);
573 SetUsesScreenCoordinates(launcher_container);
574
[email protected]dc851a4e52012-10-03 00:05:55575 aura::Window* app_list_container =
[email protected]c0ce80e2012-10-05 23:28:27576 CreateContainer(kShellWindowId_AppListContainer,
[email protected]dc851a4e52012-10-03 00:05:55577 "AppListContainer",
578 non_lock_screen_containers);
579 SetUsesScreenCoordinates(app_list_container);
[email protected]a4cd6d32012-09-12 03:42:13580
581 aura::Window* modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27582 kShellWindowId_SystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13583 "SystemModalContainer",
584 non_lock_screen_containers);
585 modal_container_handler_.reset(
586 new ToplevelWindowEventHandler(modal_container));
[email protected]a4cd6d32012-09-12 03:42:13587 modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27588 new SystemModalContainerLayoutManager(modal_container));
[email protected]b5756e22012-11-30 01:32:02589 views::corewm::SetChildWindowVisibilityChangesAnimated(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13590 SetUsesScreenCoordinates(modal_container);
591
592 aura::Window* input_method_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27593 kShellWindowId_InputMethodContainer,
[email protected]a4cd6d32012-09-12 03:42:13594 "InputMethodContainer",
595 non_lock_screen_containers);
596 SetUsesScreenCoordinates(input_method_container);
597
598 // TODO(beng): Figure out if we can make this use
599 // SystemModalContainerEventFilter instead of stops_event_propagation.
600 aura::Window* lock_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27601 kShellWindowId_LockScreenContainer,
[email protected]a4cd6d32012-09-12 03:42:13602 "LockScreenContainer",
603 lock_screen_containers);
604 lock_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27605 new BaseLayoutManager(root_window));
[email protected]a4cd6d32012-09-12 03:42:13606 SetUsesScreenCoordinates(lock_container);
607 // TODO(beng): stopsevents
608
609 aura::Window* lock_modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27610 kShellWindowId_LockSystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13611 "LockSystemModalContainer",
612 lock_screen_containers);
613 lock_modal_container_handler_.reset(
614 new ToplevelWindowEventHandler(lock_modal_container));
[email protected]a4cd6d32012-09-12 03:42:13615 lock_modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27616 new SystemModalContainerLayoutManager(lock_modal_container));
[email protected]b5756e22012-11-30 01:32:02617 views::corewm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13618 SetUsesScreenCoordinates(lock_modal_container);
619
620 aura::Window* status_container =
[email protected]c0ce80e2012-10-05 23:28:27621 CreateContainer(kShellWindowId_StatusContainer,
[email protected]a4cd6d32012-09-12 03:42:13622 "StatusContainer",
623 lock_screen_related_containers);
624 SetUsesScreenCoordinates(status_container);
625
626 aura::Window* settings_bubble_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27627 kShellWindowId_SettingBubbleContainer,
[email protected]a4cd6d32012-09-12 03:42:13628 "SettingBubbleContainer",
629 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02630 views::corewm::SetChildWindowVisibilityChangesAnimated(
631 settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13632 SetUsesScreenCoordinates(settings_bubble_container);
633
634 aura::Window* menu_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27635 kShellWindowId_MenuContainer,
[email protected]a4cd6d32012-09-12 03:42:13636 "MenuContainer",
637 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02638 views::corewm::SetChildWindowVisibilityChangesAnimated(menu_container);
[email protected]a4cd6d32012-09-12 03:42:13639 SetUsesScreenCoordinates(menu_container);
640
641 aura::Window* drag_drop_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27642 kShellWindowId_DragImageAndTooltipContainer,
[email protected]a4cd6d32012-09-12 03:42:13643 "DragImageAndTooltipContainer",
644 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02645 views::corewm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
[email protected]a4cd6d32012-09-12 03:42:13646 SetUsesScreenCoordinates(drag_drop_container);
647
648 aura::Window* overlay_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27649 kShellWindowId_OverlayContainer,
[email protected]a4cd6d32012-09-12 03:42:13650 "OverlayContainer",
651 lock_screen_related_containers);
652 SetUsesScreenCoordinates(overlay_container);
[email protected]a07615f2012-10-24 08:23:08653
654 CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
655 "PowerButtonAnimationContainer", root_window) ;
[email protected]a4cd6d32012-09-12 03:42:13656}
657
[email protected]d90b8392012-06-13 09:34:56658} // namespace internal
659} // namespace ash