blob: 0bacb01d815de51094e617c9fa6e6b9b011538c5 [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]0bf61732013-07-02 04:35:1012#include "ash/desktop_background/user_wallpaper_delegate.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]2b8a9bb2013-07-01 22:43:4025#include "ash/touch/touch_hud_debug.h"
26#include "ash/touch/touch_hud_projection.h"
[email protected]80549c152013-07-02 01:42:4727#include "ash/touch/touch_observer_hud.h"
28#include "ash/wm/always_on_top_controller.h"
[email protected]d90b8392012-06-13 09:34:5629#include "ash/wm/base_layout_manager.h"
[email protected]bca9a7e2012-11-10 06:25:4930#include "ash/wm/boot_splash_screen.h"
[email protected]beb4e5c2013-06-18 15:37:0731#include "ash/wm/dock/docked_window_layout_manager.h"
[email protected]7095a652013-03-07 19:41:4932#include "ash/wm/panels/panel_layout_manager.h"
[email protected]100659412013-06-21 22:59:5533#include "ash/wm/panels/panel_window_event_handler.h"
[email protected]d90b8392012-06-13 09:34:5634#include "ash/wm/property_util.h"
35#include "ash/wm/root_window_layout_manager.h"
36#include "ash/wm/screen_dimmer.h"
[email protected]2a2caa02013-01-22 20:50:3637#include "ash/wm/stacking_controller.h"
[email protected]e74aaf0a2012-10-12 18:42:2838#include "ash/wm/status_area_layout_manager.h"
[email protected]e6e41d2f2012-10-29 19:22:1939#include "ash/wm/system_background_controller.h"
[email protected]d90b8392012-06-13 09:34:5640#include "ash/wm/system_modal_container_layout_manager.h"
[email protected]5dc51db82012-09-11 03:39:0141#include "ash/wm/toplevel_window_event_handler.h"
[email protected]8d625fb2012-07-18 16:40:0642#include "ash/wm/window_properties.h"
[email protected]700849f2013-04-30 17:49:2043#include "ash/wm/window_util.h"
[email protected]d90b8392012-06-13 09:34:5644#include "ash/wm/workspace_controller.h"
[email protected]e6e41d2f2012-10-29 19:22:1945#include "base/command_line.h"
[email protected]1e84c632013-06-27 23:12:2146#include "base/time/time.h"
[email protected]f1853122012-06-27 16:21:2647#include "ui/aura/client/aura_constants.h"
[email protected]d90b8392012-06-13 09:34:5648#include "ui/aura/client/tooltip_client.h"
49#include "ui/aura/root_window.h"
[email protected]f1853122012-06-27 16:21:2650#include "ui/aura/window.h"
51#include "ui/aura/window_observer.h"
[email protected]431552c2012-10-23 00:38:3352#include "ui/base/models/menu_model.h"
[email protected]8d625fb2012-07-18 16:40:0653#include "ui/gfx/screen.h"
[email protected]86459e2c2013-04-10 13:39:2454#include "ui/keyboard/keyboard_controller.h"
55#include "ui/keyboard/keyboard_util.h"
[email protected]431552c2012-10-23 00:38:3356#include "ui/views/controls/menu/menu_runner.h"
[email protected]b5756e22012-11-30 01:32:0257#include "ui/views/corewm/visibility_controller.h"
[email protected]431552c2012-10-23 00:38:3358#include "ui/views/view_model.h"
59#include "ui/views/view_model_utils.h"
[email protected]d90b8392012-06-13 09:34:5660
61namespace ash {
62namespace {
63
[email protected]bca9a7e2012-11-10 06:25:4964// Duration for the animation that hides the boot splash screen, in
65// milliseconds. This should be short enough in relation to
66// wm/window_animation.cc's brightness/grayscale fade animation that the login
67// background image animation isn't hidden by the splash screen animation.
68const int kBootSplashScreenHideDurationMs = 500;
69
[email protected]d90b8392012-06-13 09:34:5670// Creates a new window for use as a container.
71aura::Window* CreateContainer(int window_id,
72 const char* name,
73 aura::Window* parent) {
74 aura::Window* container = new aura::Window(NULL);
75 container->set_id(window_id);
76 container->SetName(name);
77 container->Init(ui::LAYER_NOT_DRAWN);
78 parent->AddChild(container);
79 if (window_id != internal::kShellWindowId_UnparentedControlContainer)
80 container->Show();
81 return container;
82}
83
[email protected]95058572012-08-20 14:57:2984// Returns all the children of the workspace windows, eg the standard top-level
85// windows.
86std::vector<aura::Window*> GetWorkspaceWindows(aura::RootWindow* root) {
87 using aura::Window;
88
89 std::vector<Window*> windows;
90 Window* container = Shell::GetContainer(
91 root, internal::kShellWindowId_DefaultContainer);
92 for (Window::Windows::const_reverse_iterator i =
93 container->children().rbegin();
94 i != container->children().rend(); ++i) {
95 Window* workspace_window = *i;
96 if (workspace_window->id() == internal::kShellWindowId_WorkspaceContainer) {
97 windows.insert(windows.end(), workspace_window->children().begin(),
98 workspace_window->children().end());
99 }
100 }
101 return windows;
102}
103
104// Reparents |window| to |new_parent|.
105void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
106 // Update the restore bounds to make it relative to the display.
107 gfx::Rect restore_bounds(GetRestoreBoundsInParent(window));
108 new_parent->AddChild(window);
109 if (!restore_bounds.IsEmpty())
110 SetRestoreBoundsInParent(window, restore_bounds);
111}
112
113// Reparents the appropriate set of windows from |src| to |dst|.
114void ReparentAllWindows(aura::RootWindow* src, aura::RootWindow* dst) {
115 // Set of windows to move.
[email protected]f1853122012-06-27 16:21:26116 const int kContainerIdsToMove[] = {
117 internal::kShellWindowId_DefaultContainer,
[email protected]beb4e5c2013-06-18 15:37:07118 internal::kShellWindowId_DockedContainer,
[email protected]95db9c12013-01-31 11:47:44119 internal::kShellWindowId_PanelContainer,
[email protected]f1853122012-06-27 16:21:26120 internal::kShellWindowId_AlwaysOnTopContainer,
121 internal::kShellWindowId_SystemModalContainer,
122 internal::kShellWindowId_LockSystemModalContainer,
[email protected]6274d312012-10-04 22:06:41123 internal::kShellWindowId_InputMethodContainer,
[email protected]a9754872013-01-25 07:44:00124 internal::kShellWindowId_UnparentedControlContainer,
[email protected]f1853122012-06-27 16:21:26125 };
[email protected]ef0e32cc2012-10-31 20:57:33126 // For workspace windows we need to manually reparent the windows. This way
127 // workspace can move the windows to the appropriate workspace.
[email protected]c96b9812012-10-17 16:04:04128 std::vector<aura::Window*> windows(GetWorkspaceWindows(src));
129 internal::WorkspaceController* workspace_controller =
130 GetRootWindowController(dst)->workspace_controller();
131 for (size_t i = 0; i < windows.size(); ++i) {
132 aura::Window* new_parent =
133 workspace_controller->GetParentForNewWindow(windows[i]);
134 ReparentWindow(windows[i], new_parent);
[email protected]95058572012-08-20 14:57:29135 }
[email protected]f1853122012-06-27 16:21:26136 for (size_t i = 0; i < arraysize(kContainerIdsToMove); i++) {
137 int id = kContainerIdsToMove[i];
[email protected]c96b9812012-10-17 16:04:04138 if (id == internal::kShellWindowId_DefaultContainer)
[email protected]95058572012-08-20 14:57:29139 continue;
140
[email protected]f1853122012-06-27 16:21:26141 aura::Window* src_container = Shell::GetContainer(src, id);
142 aura::Window* dst_container = Shell::GetContainer(dst, id);
[email protected]5b6021902013-02-26 05:33:29143 while (!src_container->children().empty()) {
144 // Restart iteration from the source container windows each time as they
145 // may change as a result of moving other windows.
146 aura::Window::Windows::const_iterator iter =
147 src_container->children().begin();
148 while (iter != src_container->children().end() &&
149 internal::SystemModalContainerLayoutManager::IsModalBackground(
150 *iter)) {
151 ++iter;
152 }
153 // If the entire window list is modal background windows then stop.
154 if (iter == src_container->children().end())
155 break;
156 ReparentWindow(*iter, dst_container);
[email protected]f1853122012-06-27 16:21:26157 }
158 }
159}
160
[email protected]8d625fb2012-07-18 16:40:06161// Mark the container window so that a widget added to this container will
162// use the virtual screeen coordinates instead of parent.
163void SetUsesScreenCoordinates(aura::Window* container) {
164 container->SetProperty(internal::kUsesScreenCoordinatesKey, true);
165}
166
[email protected]e887c6c2013-07-08 19:35:53167// Mark the container window so that a widget added to this container will
168// say in the same root window regardless of the bounds specified.
169void DescendantShouldStayInSameRootWindow(aura::Window* container) {
170 container->SetProperty(internal::kStayInSameRootWindowKey, true);
171}
172
[email protected]d90b8392012-06-13 09:34:56173} // namespace
174
175namespace internal {
176
177RootWindowController::RootWindowController(aura::RootWindow* root_window)
[email protected]e74aaf0a2012-10-12 18:42:28178 : root_window_(root_window),
179 root_window_layout_(NULL),
[email protected]beb4e5c2013-06-18 15:37:07180 docked_layout_manager_(NULL),
[email protected]bff17552013-04-25 04:44:55181 panel_layout_manager_(NULL),
[email protected]2b8a9bb2013-07-01 22:43:40182 touch_hud_debug_(NULL),
183 touch_hud_projection_(NULL) {
[email protected]d90b8392012-06-13 09:34:56184 SetRootWindowController(root_window, this);
[email protected]c0ce80e2012-10-05 23:28:27185 screen_dimmer_.reset(new ScreenDimmer(root_window));
[email protected]2a2caa02013-01-22 20:50:36186
[email protected]0bf61732013-07-02 04:35:10187 stacking_controller_.reset(new StackingController);
[email protected]2a2caa02013-01-22 20:50:36188 aura::client::SetStackingClient(root_window, stacking_controller_.get());
[email protected]d90b8392012-06-13 09:34:56189}
190
191RootWindowController::~RootWindowController() {
[email protected]6675e1c2012-09-11 09:15:45192 Shutdown();
193 root_window_.reset();
194}
195
[email protected]88d71122012-10-18 07:11:01196// static
[email protected]a0afeb12012-12-10 22:57:09197RootWindowController* RootWindowController::ForLauncher(aura::Window* window) {
[email protected]8c0ec432013-05-10 04:33:39198 return GetRootWindowController(window->GetRootWindow());
[email protected]88d71122012-10-18 07:11:01199}
200
[email protected]a0afeb12012-12-10 22:57:09201// static
[email protected]ccff3d72013-02-06 04:26:28202RootWindowController* RootWindowController::ForWindow(
203 const aura::Window* window) {
[email protected]a0afeb12012-12-10 22:57:09204 return GetRootWindowController(window->GetRootWindow());
205}
206
207// static
208RootWindowController* RootWindowController::ForActiveRootWindow() {
209 return GetRootWindowController(Shell::GetActiveRootWindow());
210}
211
[email protected]756bda12013-07-03 08:17:06212void RootWindowController::EnableTouchHudProjection() {
213 if (touch_hud_projection_)
214 return;
215 set_touch_hud_projection(new TouchHudProjection(root_window_.get()));
216}
217
218void RootWindowController::DisableTouchHudProjection() {
219 if (!touch_hud_projection_)
220 return;
221 touch_hud_projection_->Remove();
222}
223
[email protected]0bf61732013-07-02 04:35:10224void RootWindowController::SetWallpaperController(
225 DesktopBackgroundWidgetController* controller) {
226 wallpaper_controller_.reset(controller);
227}
228
229void RootWindowController::SetAnimatingWallpaperController(
230 AnimatingDesktopController* controller) {
231 if (animating_wallpaper_controller_.get())
232 animating_wallpaper_controller_->StopAnimating();
233 animating_wallpaper_controller_.reset(controller);
234}
235
[email protected]6675e1c2012-09-11 09:15:45236void RootWindowController::Shutdown() {
[email protected]0bf61732013-07-02 04:35:10237 if (animating_wallpaper_controller_.get())
238 animating_wallpaper_controller_->StopAnimating();
239 wallpaper_controller_.reset();
240 animating_wallpaper_controller_.reset();
241
[email protected]6675e1c2012-09-11 09:15:45242 CloseChildWindows();
[email protected]7f7f65c2013-04-17 16:47:13243 if (Shell::GetActiveRootWindow() == root_window_) {
[email protected]f634dd32012-07-23 22:49:07244 Shell::GetInstance()->set_active_root_window(
245 Shell::GetPrimaryRootWindow() == root_window_.get() ?
246 NULL : Shell::GetPrimaryRootWindow());
247 }
[email protected]d90b8392012-06-13 09:34:56248 SetRootWindowController(root_window_.get(), NULL);
[email protected]d90b8392012-06-13 09:34:56249 screen_dimmer_.reset();
250 workspace_controller_.reset();
[email protected]6675e1c2012-09-11 09:15:45251 // Forget with the display ID so that display lookup
252 // ends up with invalid display.
253 root_window_->ClearProperty(kDisplayIdKey);
254 // And this root window should no longer process events.
255 root_window_->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28256
[email protected]956a6a42012-10-29 23:58:10257 system_background_.reset();
[email protected]d90b8392012-06-13 09:34:56258}
259
[email protected]c0ce80e2012-10-05 23:28:27260SystemModalContainerLayoutManager*
[email protected]8674b312012-10-12 19:02:44261RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
262 aura::Window* container = NULL;
263 if (window) {
[email protected]3b162e12012-11-09 11:52:35264 if (window->parent() &&
265 window->parent()->id() >= kShellWindowId_LockScreenContainer) {
266 container = GetContainer(kShellWindowId_LockSystemModalContainer);
267 } else {
[email protected]8674b312012-10-12 19:02:44268 container = GetContainer(kShellWindowId_SystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35269 }
[email protected]8674b312012-10-12 19:02:44270 } else {
[email protected]945f9cae2012-12-12 09:54:29271 user::LoginStatus login = Shell::GetInstance()->system_tray_delegate() ?
272 Shell::GetInstance()->system_tray_delegate()->GetUserLoginStatus() :
[email protected]8674b312012-10-12 19:02:44273 user::LOGGED_IN_NONE;
274 int modal_window_id = (login == user::LOGGED_IN_LOCKED ||
275 login == user::LOGGED_IN_NONE) ?
276 kShellWindowId_LockSystemModalContainer :
277 kShellWindowId_SystemModalContainer;
278 container = GetContainer(modal_window_id);
279 }
[email protected]bb0c7cd42013-05-20 23:39:45280 return container ? static_cast<SystemModalContainerLayoutManager*>(
281 container->layout_manager()) : NULL;
[email protected]c0ce80e2012-10-05 23:28:27282}
283
[email protected]d90b8392012-06-13 09:34:56284aura::Window* RootWindowController::GetContainer(int container_id) {
285 return root_window_->GetChildById(container_id);
286}
287
[email protected]756bda12013-07-03 08:17:06288void RootWindowController::Init(bool first_run_after_boot) {
289 root_window_->SetCursor(ui::kCursorPointer);
[email protected]d90b8392012-06-13 09:34:56290 CreateContainersInRootWindow(root_window_.get());
[email protected]756bda12013-07-03 08:17:06291 CreateSystemBackground(first_run_after_boot);
[email protected]d90b8392012-06-13 09:34:56292
[email protected]756bda12013-07-03 08:17:06293 InitLayoutManagers();
294 InitKeyboard();
295 InitTouchHuds();
[email protected]bca9a7e2012-11-10 06:25:49296
[email protected]756bda12013-07-03 08:17:06297 if (Shell::GetPrimaryRootWindowController()->
298 GetSystemModalLayoutManager(NULL)->has_modal_background()) {
299 GetSystemModalLayoutManager(NULL)->CreateModalBackground();
300 }
[email protected]e74aaf0a2012-10-12 18:42:28301}
302
303void RootWindowController::ShowLauncher() {
[email protected]80549c152013-07-02 01:42:47304 if (!shelf_->launcher())
[email protected]e74aaf0a2012-10-12 18:42:28305 return;
[email protected]478c6c32013-03-09 02:50:58306 shelf_->launcher()->SetVisible(true);
307 shelf_->status_area_widget()->Show();
[email protected]e74aaf0a2012-10-12 18:42:28308}
309
[email protected]756bda12013-07-03 08:17:06310void RootWindowController::OnLauncherCreated() {
311 if (panel_layout_manager_)
312 panel_layout_manager_->SetLauncher(shelf_->launcher());
313 if (docked_layout_manager_)
314 docked_layout_manager_->SetLauncher(shelf_->launcher());
315}
316
[email protected]16059276d2012-10-22 18:59:50317void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
[email protected]80549c152013-07-02 01:42:47318 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]16059276d2012-10-22 18:59:50319}
320
321void RootWindowController::UpdateAfterLoginStatusChange(
322 user::LoginStatus status) {
[email protected]80549c152013-07-02 01:42:47323 if (shelf_->status_area_widget())
[email protected]478c6c32013-03-09 02:50:58324 shelf_->status_area_widget()->UpdateAfterLoginStatusChange(status);
[email protected]16059276d2012-10-22 18:59:50325}
326
[email protected]bca9a7e2012-11-10 06:25:49327void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
328 if (CommandLine::ForCurrentProcess()->HasSwitch(
329 switches::kAshAnimateFromBootSplashScreen) &&
330 boot_splash_screen_.get()) {
331 // Make the splash screen fade out so it doesn't obscure the desktop
332 // wallpaper's brightness/grayscale animation.
333 boot_splash_screen_->StartHideAnimation(
334 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
335 }
336}
337
[email protected]0bf61732013-07-02 04:35:10338void RootWindowController::OnWallpaperAnimationFinished(views::Widget* widget) {
339 // Make sure the wallpaper is visible.
[email protected]bca9a7e2012-11-10 06:25:49340 system_background_->SetColor(SK_ColorBLACK);
341 boot_splash_screen_.reset();
[email protected]0bf61732013-07-02 04:35:10342
343 Shell::GetInstance()->user_wallpaper_delegate()->
344 OnWallpaperAnimationFinished();
345 // Only removes old component when wallpaper animation finished. If we
346 // remove the old one before the new wallpaper is done fading in there will
347 // be a white flash during the animation.
348 if (animating_wallpaper_controller()) {
349 DesktopBackgroundWidgetController* controller =
350 animating_wallpaper_controller()->GetController(true);
351 // |desktop_widget_| should be the same animating widget we try to move
352 // to |kDesktopController|. Otherwise, we may close |desktop_widget_|
353 // before move it to |kDesktopController|.
354 DCHECK_EQ(controller->widget(), widget);
355 // Release the old controller and close its background widget.
356 SetWallpaperController(controller);
357 }
[email protected]697f04c2012-10-03 01:15:10358}
359
[email protected]d90b8392012-06-13 09:34:56360void RootWindowController::CloseChildWindows() {
[email protected]80549c152013-07-02 01:42:47361 if (!shelf_.get())
362 return;
[email protected]79a87b7e2013-01-25 05:08:22363 // panel_layout_manager_ needs to be shut down before windows are destroyed.
364 if (panel_layout_manager_) {
365 panel_layout_manager_->Shutdown();
366 panel_layout_manager_ = NULL;
367 }
368
[email protected]478c6c32013-03-09 02:50:58369 // TODO(harrym): Remove when Status Area Widget is a child view.
[email protected]80549c152013-07-02 01:42:47370 shelf_->ShutdownStatusAreaWidget();
[email protected]478c6c32013-03-09 02:50:58371
[email protected]80549c152013-07-02 01:42:47372 if (shelf_->shelf_layout_manager())
[email protected]478c6c32013-03-09 02:50:58373 shelf_->shelf_layout_manager()->set_workspace_controller(NULL);
[email protected]e74aaf0a2012-10-12 18:42:28374
[email protected]d90b8392012-06-13 09:34:56375 // Close background widget first as it depends on tooltip.
[email protected]0bf61732013-07-02 04:35:10376 wallpaper_controller_.reset();
377 animating_wallpaper_controller_.reset();
[email protected]b4ddc7a2012-08-07 04:17:32378
[email protected]d90b8392012-06-13 09:34:56379 workspace_controller_.reset();
380 aura::client::SetTooltipClient(root_window_.get(), NULL);
381
382 while (!root_window_->children().empty()) {
383 aura::Window* child = root_window_->children()[0];
384 delete child;
385 }
[email protected]478c6c32013-03-09 02:50:58386
387 shelf_.reset(NULL);
[email protected]d90b8392012-06-13 09:34:56388}
389
[email protected]f1853122012-06-27 16:21:26390void RootWindowController::MoveWindowsTo(aura::RootWindow* dst) {
[email protected]8039e06c2013-01-17 23:34:50391 // Forget the shelf early so that shelf don't update itself using wrong
392 // display info.
393 workspace_controller_->SetShelf(NULL);
[email protected]95058572012-08-20 14:57:29394 ReparentAllWindows(root_window_.get(), dst);
[email protected]f1853122012-06-27 16:21:26395}
396
[email protected]478c6c32013-03-09 02:50:58397ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
[email protected]80549c152013-07-02 01:42:47398 return shelf_->shelf_layout_manager();
[email protected]478c6c32013-03-09 02:50:58399}
400
[email protected]a0afeb12012-12-10 22:57:09401SystemTray* RootWindowController::GetSystemTray() {
402 // We assume in throughout the code that this will not return NULL. If code
403 // triggers this for valid reasons, it should test status_area_widget first.
[email protected]80549c152013-07-02 01:42:47404 CHECK(shelf_->status_area_widget());
[email protected]478c6c32013-03-09 02:50:58405 return shelf_->status_area_widget()->system_tray();
[email protected]a0afeb12012-12-10 22:57:09406}
407
[email protected]940fb1c2013-06-18 16:54:28408void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
409 ui::MenuSourceType source_type) {
[email protected]431552c2012-10-23 00:38:33410 DCHECK(Shell::GetInstance()->delegate());
411 scoped_ptr<ui::MenuModel> menu_model(
[email protected]8c0ec432013-05-10 04:33:39412 Shell::GetInstance()->delegate()->CreateContextMenu(root_window()));
[email protected]7f7f65c2013-04-17 16:47:13413 if (!menu_model)
[email protected]8e837ec2013-01-31 01:48:33414 return;
[email protected]431552c2012-10-23 00:38:33415
[email protected]6175fc42013-04-05 05:58:58416 // Background controller may not be set yet if user clicked on status are
417 // before initial animation completion. See crbug.com/222218
[email protected]0bf61732013-07-02 04:35:10418 if (!wallpaper_controller_.get())
[email protected]431552c2012-10-23 00:38:33419 return;
420
[email protected]6175fc42013-04-05 05:58:58421 views::MenuRunner menu_runner(menu_model.get());
[email protected]0bf61732013-07-02 04:35:10422 if (menu_runner.RunMenuAt(wallpaper_controller_->widget(),
[email protected]6175fc42013-04-05 05:58:58423 NULL, gfx::Rect(location_in_screen, gfx::Size()),
[email protected]940fb1c2013-06-18 16:54:28424 views::MenuItemView::TOPLEFT, source_type,
425 views::MenuRunner::CONTEXT_MENU) ==
[email protected]6175fc42013-04-05 05:58:58426 views::MenuRunner::MENU_DELETED) {
427 return;
428 }
429
[email protected]431552c2012-10-23 00:38:33430 Shell::GetInstance()->UpdateShelfVisibility();
431}
432
[email protected]e74aaf0a2012-10-12 18:42:28433void RootWindowController::UpdateShelfVisibility() {
[email protected]478c6c32013-03-09 02:50:58434 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]e74aaf0a2012-10-12 18:42:28435}
436
[email protected]700849f2013-04-30 17:49:20437aura::Window* RootWindowController::GetFullscreenWindow() const {
[email protected]2ee2f5d2013-01-10 23:37:16438 aura::Window* container = workspace_controller_->GetActiveWorkspaceWindow();
439 for (size_t i = 0; i < container->children().size(); ++i) {
440 aura::Window* child = container->children()[i];
[email protected]0bf61732013-07-02 04:35:10441 if (wm::IsWindowFullscreen(child))
[email protected]700849f2013-04-30 17:49:20442 return child;
[email protected]2ee2f5d2013-01-10 23:37:16443 }
[email protected]700849f2013-04-30 17:49:20444 return NULL;
[email protected]2ee2f5d2013-01-10 23:37:16445}
446
[email protected]86459e2c2013-04-10 13:39:24447void RootWindowController::InitKeyboard() {
448 if (keyboard::IsKeyboardEnabled()) {
449 aura::Window* parent = root_window();
450
451 keyboard::KeyboardControllerProxy* proxy =
452 Shell::GetInstance()->delegate()->CreateKeyboardControllerProxy();
453 keyboard_controller_.reset(
454 new keyboard::KeyboardController(proxy));
[email protected]5416f282013-04-29 20:52:48455
456 keyboard_controller_->AddObserver(shelf()->shelf_layout_manager());
457 keyboard_controller_->AddObserver(panel_layout_manager_);
458
[email protected]86459e2c2013-04-10 13:39:24459 aura::Window* keyboard_container =
460 keyboard_controller_->GetContainerWindow();
461 parent->AddChild(keyboard_container);
[email protected]e0f71132013-04-17 12:32:51462 keyboard_container->SetBounds(parent->bounds());
[email protected]86459e2c2013-04-10 13:39:24463 }
464}
465
466
[email protected]a4cd6d32012-09-12 03:42:13467////////////////////////////////////////////////////////////////////////////////
468// RootWindowController, private:
469
[email protected]756bda12013-07-03 08:17:06470void RootWindowController::InitLayoutManagers() {
471 root_window_layout_ =
472 new RootWindowLayoutManager(root_window_.get());
473 root_window_->SetLayoutManager(root_window_layout_);
474
475 aura::Window* default_container =
476 GetContainer(kShellWindowId_DefaultContainer);
477 // Workspace manager has its own layout managers.
478 workspace_controller_.reset(
479 new WorkspaceController(default_container));
480
481 aura::Window* always_on_top_container =
482 GetContainer(kShellWindowId_AlwaysOnTopContainer);
483 always_on_top_container->SetLayoutManager(
484 new BaseLayoutManager(
485 always_on_top_container->GetRootWindow()));
486 always_on_top_controller_.reset(new internal::AlwaysOnTopController);
487 always_on_top_controller_->SetAlwaysOnTopContainer(always_on_top_container);
488
489 DCHECK(!shelf_.get());
490 aura::Window* shelf_container =
491 GetContainer(internal::kShellWindowId_ShelfContainer);
492 // TODO(harrym): Remove when status area is view.
493 aura::Window* status_container =
494 GetContainer(internal::kShellWindowId_StatusContainer);
495 shelf_.reset(new ShelfWidget(
496 shelf_container, status_container, workspace_controller()));
497
498 // Create Docked windows layout manager
499 aura::Window* docked_container = GetContainer(
500 internal::kShellWindowId_DockedContainer);
501 docked_layout_manager_ =
502 new internal::DockedWindowLayoutManager(docked_container);
503 docked_container_handler_.reset(
504 new ToplevelWindowEventHandler(docked_container));
505 docked_container->SetLayoutManager(docked_layout_manager_);
506
507 // Create Panel layout manager
508 aura::Window* panel_container = GetContainer(
509 internal::kShellWindowId_PanelContainer);
510 panel_layout_manager_ =
511 new internal::PanelLayoutManager(panel_container);
512 panel_container_handler_.reset(
513 new PanelWindowEventHandler(panel_container));
514 panel_container->SetLayoutManager(panel_layout_manager_);
515}
516
517void RootWindowController::InitTouchHuds() {
518 CommandLine* command_line = CommandLine::ForCurrentProcess();
519 if (command_line->HasSwitch(switches::kAshTouchHud))
520 set_touch_hud_debug(new TouchHudDebug(root_window_.get()));
521 if (Shell::GetInstance()->is_touch_hud_projection_enabled())
522 EnableTouchHudProjection();
523}
524
525void RootWindowController::CreateSystemBackground(
526 bool is_first_run_after_boot) {
527 SkColor color = SK_ColorBLACK;
528#if defined(OS_CHROMEOS)
529 if (is_first_run_after_boot)
530 color = kChromeOsBootColor;
531#endif
532 system_background_.reset(
533 new SystemBackgroundController(root_window_.get(), color));
534
535#if defined(OS_CHROMEOS)
536 // Make a copy of the system's boot splash screen so we can composite it
537 // onscreen until the desktop background is ready.
538 if (is_first_run_after_boot &&
539 (CommandLine::ForCurrentProcess()->HasSwitch(
540 switches::kAshCopyHostBackgroundAtBoot) ||
541 CommandLine::ForCurrentProcess()->HasSwitch(
542 switches::kAshAnimateFromBootSplashScreen)))
543 boot_splash_screen_.reset(new BootSplashScreen(root_window_.get()));
544#endif
545}
546
[email protected]a4cd6d32012-09-12 03:42:13547void RootWindowController::CreateContainersInRootWindow(
548 aura::RootWindow* root_window) {
549 // These containers are just used by PowerButtonController to animate groups
550 // of containers simultaneously without messing up the current transformations
551 // on those containers. These are direct children of the root window; all of
552 // the other containers are their children.
[email protected]e6e41d2f2012-10-29 19:22:19553
554 // The desktop background container is not part of the lock animation, so it
555 // is not included in those animate groups.
[email protected]a4cd6d32012-09-12 03:42:13556 // When screen is locked desktop background is moved to lock screen background
557 // container (moved back on unlock). We want to make sure that there's an
558 // opaque layer occluding the non-lock-screen layers.
[email protected]e6e41d2f2012-10-29 19:22:19559 aura::Window* desktop_background_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27560 kShellWindowId_DesktopBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13561 "DesktopBackgroundContainer",
562 root_window);
[email protected]b5756e22012-11-30 01:32:02563 views::corewm::SetChildWindowVisibilityChangesAnimated(
564 desktop_background_container);
[email protected]a4cd6d32012-09-12 03:42:13565
566 aura::Window* non_lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27567 kShellWindowId_NonLockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13568 "NonLockScreenContainersContainer",
569 root_window);
570
571 aura::Window* lock_background_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27572 kShellWindowId_LockScreenBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13573 "LockScreenBackgroundContainer",
574 root_window);
[email protected]b5756e22012-11-30 01:32:02575 views::corewm::SetChildWindowVisibilityChangesAnimated(
576 lock_background_containers);
[email protected]a4cd6d32012-09-12 03:42:13577
578 aura::Window* lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27579 kShellWindowId_LockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13580 "LockScreenContainersContainer",
581 root_window);
582 aura::Window* lock_screen_related_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27583 kShellWindowId_LockScreenRelatedContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13584 "LockScreenRelatedContainersContainer",
585 root_window);
586
[email protected]c0ce80e2012-10-05 23:28:27587 CreateContainer(kShellWindowId_UnparentedControlContainer,
[email protected]a4cd6d32012-09-12 03:42:13588 "UnparentedControlContainer",
589 non_lock_screen_containers);
590
591 aura::Window* default_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27592 kShellWindowId_DefaultContainer,
[email protected]a4cd6d32012-09-12 03:42:13593 "DefaultContainer",
594 non_lock_screen_containers);
[email protected]b5756e22012-11-30 01:32:02595 views::corewm::SetChildWindowVisibilityChangesAnimated(default_container);
[email protected]a4cd6d32012-09-12 03:42:13596 SetUsesScreenCoordinates(default_container);
597
598 aura::Window* always_on_top_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27599 kShellWindowId_AlwaysOnTopContainer,
[email protected]a4cd6d32012-09-12 03:42:13600 "AlwaysOnTopContainer",
601 non_lock_screen_containers);
602 always_on_top_container_handler_.reset(
603 new ToplevelWindowEventHandler(always_on_top_container));
[email protected]b5756e22012-11-30 01:32:02604 views::corewm::SetChildWindowVisibilityChangesAnimated(
605 always_on_top_container);
[email protected]a4cd6d32012-09-12 03:42:13606 SetUsesScreenCoordinates(always_on_top_container);
607
[email protected]beb4e5c2013-06-18 15:37:07608 aura::Window* docked_container = CreateContainer(
609 kShellWindowId_DockedContainer,
610 "DockedContainer",
611 non_lock_screen_containers);
612 SetUsesScreenCoordinates(docked_container);
613
[email protected]a4cd6d32012-09-12 03:42:13614 aura::Window* panel_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27615 kShellWindowId_PanelContainer,
[email protected]a4cd6d32012-09-12 03:42:13616 "PanelContainer",
617 non_lock_screen_containers);
618 SetUsesScreenCoordinates(panel_container);
619
620 aura::Window* launcher_container =
[email protected]478c6c32013-03-09 02:50:58621 CreateContainer(kShellWindowId_ShelfContainer,
[email protected]a4cd6d32012-09-12 03:42:13622 "LauncherContainer",
623 non_lock_screen_containers);
624 SetUsesScreenCoordinates(launcher_container);
625
[email protected]dc851a4e52012-10-03 00:05:55626 aura::Window* app_list_container =
[email protected]c0ce80e2012-10-05 23:28:27627 CreateContainer(kShellWindowId_AppListContainer,
[email protected]dc851a4e52012-10-03 00:05:55628 "AppListContainer",
629 non_lock_screen_containers);
630 SetUsesScreenCoordinates(app_list_container);
[email protected]a4cd6d32012-09-12 03:42:13631
632 aura::Window* modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27633 kShellWindowId_SystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13634 "SystemModalContainer",
635 non_lock_screen_containers);
636 modal_container_handler_.reset(
637 new ToplevelWindowEventHandler(modal_container));
[email protected]a4cd6d32012-09-12 03:42:13638 modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27639 new SystemModalContainerLayoutManager(modal_container));
[email protected]b5756e22012-11-30 01:32:02640 views::corewm::SetChildWindowVisibilityChangesAnimated(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13641 SetUsesScreenCoordinates(modal_container);
642
643 aura::Window* input_method_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27644 kShellWindowId_InputMethodContainer,
[email protected]a4cd6d32012-09-12 03:42:13645 "InputMethodContainer",
646 non_lock_screen_containers);
647 SetUsesScreenCoordinates(input_method_container);
648
649 // TODO(beng): Figure out if we can make this use
650 // SystemModalContainerEventFilter instead of stops_event_propagation.
651 aura::Window* lock_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27652 kShellWindowId_LockScreenContainer,
[email protected]a4cd6d32012-09-12 03:42:13653 "LockScreenContainer",
654 lock_screen_containers);
655 lock_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27656 new BaseLayoutManager(root_window));
[email protected]a4cd6d32012-09-12 03:42:13657 SetUsesScreenCoordinates(lock_container);
658 // TODO(beng): stopsevents
659
660 aura::Window* lock_modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27661 kShellWindowId_LockSystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13662 "LockSystemModalContainer",
663 lock_screen_containers);
664 lock_modal_container_handler_.reset(
665 new ToplevelWindowEventHandler(lock_modal_container));
[email protected]a4cd6d32012-09-12 03:42:13666 lock_modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27667 new SystemModalContainerLayoutManager(lock_modal_container));
[email protected]b5756e22012-11-30 01:32:02668 views::corewm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13669 SetUsesScreenCoordinates(lock_modal_container);
670
671 aura::Window* status_container =
[email protected]c0ce80e2012-10-05 23:28:27672 CreateContainer(kShellWindowId_StatusContainer,
[email protected]a4cd6d32012-09-12 03:42:13673 "StatusContainer",
674 lock_screen_related_containers);
675 SetUsesScreenCoordinates(status_container);
[email protected]e887c6c2013-07-08 19:35:53676 DescendantShouldStayInSameRootWindow(status_container);
[email protected]a4cd6d32012-09-12 03:42:13677
678 aura::Window* settings_bubble_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27679 kShellWindowId_SettingBubbleContainer,
[email protected]a4cd6d32012-09-12 03:42:13680 "SettingBubbleContainer",
681 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02682 views::corewm::SetChildWindowVisibilityChangesAnimated(
683 settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13684 SetUsesScreenCoordinates(settings_bubble_container);
[email protected]e887c6c2013-07-08 19:35:53685 DescendantShouldStayInSameRootWindow(settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13686
687 aura::Window* menu_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27688 kShellWindowId_MenuContainer,
[email protected]a4cd6d32012-09-12 03:42:13689 "MenuContainer",
690 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02691 views::corewm::SetChildWindowVisibilityChangesAnimated(menu_container);
[email protected]a4cd6d32012-09-12 03:42:13692 SetUsesScreenCoordinates(menu_container);
693
694 aura::Window* drag_drop_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27695 kShellWindowId_DragImageAndTooltipContainer,
[email protected]a4cd6d32012-09-12 03:42:13696 "DragImageAndTooltipContainer",
697 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02698 views::corewm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
[email protected]a4cd6d32012-09-12 03:42:13699 SetUsesScreenCoordinates(drag_drop_container);
700
701 aura::Window* overlay_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27702 kShellWindowId_OverlayContainer,
[email protected]a4cd6d32012-09-12 03:42:13703 "OverlayContainer",
704 lock_screen_related_containers);
705 SetUsesScreenCoordinates(overlay_container);
[email protected]a07615f2012-10-24 08:23:08706
707 CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
708 "PowerButtonAnimationContainer", root_window) ;
[email protected]a4cd6d32012-09-12 03:42:13709}
710
[email protected]d90b8392012-06-13 09:34:56711} // namespace internal
712} // namespace ash