blob: 7039d56fee50c49e4b8da5a3cf5ecdd682fab72e [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]0bf61732013-07-02 04:35:10212void RootWindowController::SetWallpaperController(
213 DesktopBackgroundWidgetController* controller) {
214 wallpaper_controller_.reset(controller);
215}
216
217void RootWindowController::SetAnimatingWallpaperController(
218 AnimatingDesktopController* controller) {
219 if (animating_wallpaper_controller_.get())
220 animating_wallpaper_controller_->StopAnimating();
221 animating_wallpaper_controller_.reset(controller);
222}
223
[email protected]6675e1c2012-09-11 09:15:45224void RootWindowController::Shutdown() {
[email protected]d141b922013-07-09 08:13:17225 Shell::GetInstance()->RemoveShellObserver(this);
226
[email protected]0bf61732013-07-02 04:35:10227 if (animating_wallpaper_controller_.get())
228 animating_wallpaper_controller_->StopAnimating();
229 wallpaper_controller_.reset();
230 animating_wallpaper_controller_.reset();
231
[email protected]6675e1c2012-09-11 09:15:45232 CloseChildWindows();
[email protected]7f7f65c2013-04-17 16:47:13233 if (Shell::GetActiveRootWindow() == root_window_) {
[email protected]f634dd32012-07-23 22:49:07234 Shell::GetInstance()->set_active_root_window(
235 Shell::GetPrimaryRootWindow() == root_window_.get() ?
236 NULL : Shell::GetPrimaryRootWindow());
237 }
[email protected]d90b8392012-06-13 09:34:56238 SetRootWindowController(root_window_.get(), NULL);
[email protected]d90b8392012-06-13 09:34:56239 screen_dimmer_.reset();
240 workspace_controller_.reset();
[email protected]6675e1c2012-09-11 09:15:45241 // Forget with the display ID so that display lookup
242 // ends up with invalid display.
243 root_window_->ClearProperty(kDisplayIdKey);
244 // And this root window should no longer process events.
245 root_window_->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28246
[email protected]956a6a42012-10-29 23:58:10247 system_background_.reset();
[email protected]d90b8392012-06-13 09:34:56248}
249
[email protected]c0ce80e2012-10-05 23:28:27250SystemModalContainerLayoutManager*
[email protected]8674b312012-10-12 19:02:44251RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
252 aura::Window* container = NULL;
253 if (window) {
[email protected]3b162e12012-11-09 11:52:35254 if (window->parent() &&
255 window->parent()->id() >= kShellWindowId_LockScreenContainer) {
256 container = GetContainer(kShellWindowId_LockSystemModalContainer);
257 } else {
[email protected]8674b312012-10-12 19:02:44258 container = GetContainer(kShellWindowId_SystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35259 }
[email protected]8674b312012-10-12 19:02:44260 } else {
[email protected]945f9cae2012-12-12 09:54:29261 user::LoginStatus login = Shell::GetInstance()->system_tray_delegate() ?
262 Shell::GetInstance()->system_tray_delegate()->GetUserLoginStatus() :
[email protected]8674b312012-10-12 19:02:44263 user::LOGGED_IN_NONE;
264 int modal_window_id = (login == user::LOGGED_IN_LOCKED ||
265 login == user::LOGGED_IN_NONE) ?
266 kShellWindowId_LockSystemModalContainer :
267 kShellWindowId_SystemModalContainer;
268 container = GetContainer(modal_window_id);
269 }
[email protected]bb0c7cd42013-05-20 23:39:45270 return container ? static_cast<SystemModalContainerLayoutManager*>(
271 container->layout_manager()) : NULL;
[email protected]c0ce80e2012-10-05 23:28:27272}
273
[email protected]d90b8392012-06-13 09:34:56274aura::Window* RootWindowController::GetContainer(int container_id) {
275 return root_window_->GetChildById(container_id);
276}
277
[email protected]756bda12013-07-03 08:17:06278void RootWindowController::Init(bool first_run_after_boot) {
279 root_window_->SetCursor(ui::kCursorPointer);
[email protected]d90b8392012-06-13 09:34:56280 CreateContainersInRootWindow(root_window_.get());
[email protected]756bda12013-07-03 08:17:06281 CreateSystemBackground(first_run_after_boot);
[email protected]d90b8392012-06-13 09:34:56282
[email protected]756bda12013-07-03 08:17:06283 InitLayoutManagers();
284 InitKeyboard();
285 InitTouchHuds();
[email protected]bca9a7e2012-11-10 06:25:49286
[email protected]756bda12013-07-03 08:17:06287 if (Shell::GetPrimaryRootWindowController()->
288 GetSystemModalLayoutManager(NULL)->has_modal_background()) {
289 GetSystemModalLayoutManager(NULL)->CreateModalBackground();
290 }
[email protected]d141b922013-07-09 08:13:17291
292 Shell::GetInstance()->AddShellObserver(this);
[email protected]e74aaf0a2012-10-12 18:42:28293}
294
295void RootWindowController::ShowLauncher() {
[email protected]80549c152013-07-02 01:42:47296 if (!shelf_->launcher())
[email protected]e74aaf0a2012-10-12 18:42:28297 return;
[email protected]478c6c32013-03-09 02:50:58298 shelf_->launcher()->SetVisible(true);
299 shelf_->status_area_widget()->Show();
[email protected]e74aaf0a2012-10-12 18:42:28300}
301
[email protected]756bda12013-07-03 08:17:06302void RootWindowController::OnLauncherCreated() {
303 if (panel_layout_manager_)
304 panel_layout_manager_->SetLauncher(shelf_->launcher());
[email protected]7115bd32013-07-19 08:25:39305 if (docked_layout_manager_) {
[email protected]756bda12013-07-03 08:17:06306 docked_layout_manager_->SetLauncher(shelf_->launcher());
[email protected]7115bd32013-07-19 08:25:39307 if (shelf_->shelf_layout_manager())
308 docked_layout_manager_->AddObserver(shelf_->shelf_layout_manager());
309 }
[email protected]756bda12013-07-03 08:17:06310}
311
[email protected]16059276d2012-10-22 18:59:50312void RootWindowController::UpdateAfterLoginStatusChange(
313 user::LoginStatus status) {
[email protected]80549c152013-07-02 01:42:47314 if (shelf_->status_area_widget())
[email protected]478c6c32013-03-09 02:50:58315 shelf_->status_area_widget()->UpdateAfterLoginStatusChange(status);
[email protected]16059276d2012-10-22 18:59:50316}
317
[email protected]bca9a7e2012-11-10 06:25:49318void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
319 if (CommandLine::ForCurrentProcess()->HasSwitch(
320 switches::kAshAnimateFromBootSplashScreen) &&
321 boot_splash_screen_.get()) {
322 // Make the splash screen fade out so it doesn't obscure the desktop
323 // wallpaper's brightness/grayscale animation.
324 boot_splash_screen_->StartHideAnimation(
325 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
326 }
327}
328
[email protected]0bf61732013-07-02 04:35:10329void RootWindowController::OnWallpaperAnimationFinished(views::Widget* widget) {
330 // Make sure the wallpaper is visible.
[email protected]bca9a7e2012-11-10 06:25:49331 system_background_->SetColor(SK_ColorBLACK);
332 boot_splash_screen_.reset();
[email protected]0bf61732013-07-02 04:35:10333
334 Shell::GetInstance()->user_wallpaper_delegate()->
335 OnWallpaperAnimationFinished();
336 // Only removes old component when wallpaper animation finished. If we
337 // remove the old one before the new wallpaper is done fading in there will
338 // be a white flash during the animation.
339 if (animating_wallpaper_controller()) {
340 DesktopBackgroundWidgetController* controller =
341 animating_wallpaper_controller()->GetController(true);
342 // |desktop_widget_| should be the same animating widget we try to move
343 // to |kDesktopController|. Otherwise, we may close |desktop_widget_|
344 // before move it to |kDesktopController|.
345 DCHECK_EQ(controller->widget(), widget);
346 // Release the old controller and close its background widget.
347 SetWallpaperController(controller);
348 }
[email protected]697f04c2012-10-03 01:15:10349}
350
[email protected]d90b8392012-06-13 09:34:56351void RootWindowController::CloseChildWindows() {
[email protected]80549c152013-07-02 01:42:47352 if (!shelf_.get())
353 return;
[email protected]79a87b7e2013-01-25 05:08:22354 // panel_layout_manager_ needs to be shut down before windows are destroyed.
355 if (panel_layout_manager_) {
356 panel_layout_manager_->Shutdown();
357 panel_layout_manager_ = NULL;
358 }
[email protected]7115bd32013-07-19 08:25:39359 // docked_layout_manager_ needs to be shut down before windows are destroyed.
360 if (docked_layout_manager_) {
361 if (shelf_->shelf_layout_manager())
362 docked_layout_manager_->RemoveObserver(shelf_->shelf_layout_manager());
363 docked_layout_manager_->Shutdown();
364 docked_layout_manager_ = NULL;
365 }
[email protected]79a87b7e2013-01-25 05:08:22366
[email protected]478c6c32013-03-09 02:50:58367 // TODO(harrym): Remove when Status Area Widget is a child view.
[email protected]80549c152013-07-02 01:42:47368 shelf_->ShutdownStatusAreaWidget();
[email protected]478c6c32013-03-09 02:50:58369
[email protected]80549c152013-07-02 01:42:47370 if (shelf_->shelf_layout_manager())
[email protected]a3e412712013-07-11 09:32:58371 shelf_->shelf_layout_manager()->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28372
[email protected]d90b8392012-06-13 09:34:56373 // Close background widget first as it depends on tooltip.
[email protected]0bf61732013-07-02 04:35:10374 wallpaper_controller_.reset();
375 animating_wallpaper_controller_.reset();
[email protected]b4ddc7a2012-08-07 04:17:32376
[email protected]d90b8392012-06-13 09:34:56377 workspace_controller_.reset();
378 aura::client::SetTooltipClient(root_window_.get(), NULL);
379
380 while (!root_window_->children().empty()) {
381 aura::Window* child = root_window_->children()[0];
382 delete child;
383 }
[email protected]478c6c32013-03-09 02:50:58384
385 shelf_.reset(NULL);
[email protected]d90b8392012-06-13 09:34:56386}
387
[email protected]f1853122012-06-27 16:21:26388void RootWindowController::MoveWindowsTo(aura::RootWindow* dst) {
[email protected]8039e06c2013-01-17 23:34:50389 // Forget the shelf early so that shelf don't update itself using wrong
390 // display info.
391 workspace_controller_->SetShelf(NULL);
[email protected]95058572012-08-20 14:57:29392 ReparentAllWindows(root_window_.get(), dst);
[email protected]f1853122012-06-27 16:21:26393}
394
[email protected]478c6c32013-03-09 02:50:58395ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
[email protected]80549c152013-07-02 01:42:47396 return shelf_->shelf_layout_manager();
[email protected]478c6c32013-03-09 02:50:58397}
398
[email protected]a0afeb12012-12-10 22:57:09399SystemTray* RootWindowController::GetSystemTray() {
400 // We assume in throughout the code that this will not return NULL. If code
401 // triggers this for valid reasons, it should test status_area_widget first.
[email protected]80549c152013-07-02 01:42:47402 CHECK(shelf_->status_area_widget());
[email protected]478c6c32013-03-09 02:50:58403 return shelf_->status_area_widget()->system_tray();
[email protected]a0afeb12012-12-10 22:57:09404}
405
[email protected]940fb1c2013-06-18 16:54:28406void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
407 ui::MenuSourceType source_type) {
[email protected]431552c2012-10-23 00:38:33408 DCHECK(Shell::GetInstance()->delegate());
409 scoped_ptr<ui::MenuModel> menu_model(
[email protected]8c0ec432013-05-10 04:33:39410 Shell::GetInstance()->delegate()->CreateContextMenu(root_window()));
[email protected]7f7f65c2013-04-17 16:47:13411 if (!menu_model)
[email protected]8e837ec2013-01-31 01:48:33412 return;
[email protected]431552c2012-10-23 00:38:33413
[email protected]6175fc42013-04-05 05:58:58414 // Background controller may not be set yet if user clicked on status are
415 // before initial animation completion. See crbug.com/222218
[email protected]0bf61732013-07-02 04:35:10416 if (!wallpaper_controller_.get())
[email protected]431552c2012-10-23 00:38:33417 return;
418
[email protected]6175fc42013-04-05 05:58:58419 views::MenuRunner menu_runner(menu_model.get());
[email protected]0bf61732013-07-02 04:35:10420 if (menu_runner.RunMenuAt(wallpaper_controller_->widget(),
[email protected]6175fc42013-04-05 05:58:58421 NULL, gfx::Rect(location_in_screen, gfx::Size()),
[email protected]940fb1c2013-06-18 16:54:28422 views::MenuItemView::TOPLEFT, source_type,
423 views::MenuRunner::CONTEXT_MENU) ==
[email protected]6175fc42013-04-05 05:58:58424 views::MenuRunner::MENU_DELETED) {
425 return;
426 }
427
[email protected]431552c2012-10-23 00:38:33428 Shell::GetInstance()->UpdateShelfVisibility();
429}
430
[email protected]e74aaf0a2012-10-12 18:42:28431void RootWindowController::UpdateShelfVisibility() {
[email protected]478c6c32013-03-09 02:50:58432 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]e74aaf0a2012-10-12 18:42:28433}
434
[email protected]700849f2013-04-30 17:49:20435aura::Window* RootWindowController::GetFullscreenWindow() const {
[email protected]2ee2f5d2013-01-10 23:37:16436 aura::Window* container = workspace_controller_->GetActiveWorkspaceWindow();
437 for (size_t i = 0; i < container->children().size(); ++i) {
438 aura::Window* child = container->children()[i];
[email protected]0bf61732013-07-02 04:35:10439 if (wm::IsWindowFullscreen(child))
[email protected]700849f2013-04-30 17:49:20440 return child;
[email protected]2ee2f5d2013-01-10 23:37:16441 }
[email protected]700849f2013-04-30 17:49:20442 return NULL;
[email protected]2ee2f5d2013-01-10 23:37:16443}
444
[email protected]86459e2c2013-04-10 13:39:24445void RootWindowController::InitKeyboard() {
446 if (keyboard::IsKeyboardEnabled()) {
447 aura::Window* parent = root_window();
448
449 keyboard::KeyboardControllerProxy* proxy =
450 Shell::GetInstance()->delegate()->CreateKeyboardControllerProxy();
451 keyboard_controller_.reset(
452 new keyboard::KeyboardController(proxy));
[email protected]5416f282013-04-29 20:52:48453
454 keyboard_controller_->AddObserver(shelf()->shelf_layout_manager());
455 keyboard_controller_->AddObserver(panel_layout_manager_);
456
[email protected]86459e2c2013-04-10 13:39:24457 aura::Window* keyboard_container =
458 keyboard_controller_->GetContainerWindow();
459 parent->AddChild(keyboard_container);
[email protected]e0f71132013-04-17 12:32:51460 keyboard_container->SetBounds(parent->bounds());
[email protected]86459e2c2013-04-10 13:39:24461 }
462}
463
464
[email protected]a4cd6d32012-09-12 03:42:13465////////////////////////////////////////////////////////////////////////////////
466// RootWindowController, private:
467
[email protected]756bda12013-07-03 08:17:06468void RootWindowController::InitLayoutManagers() {
469 root_window_layout_ =
470 new RootWindowLayoutManager(root_window_.get());
471 root_window_->SetLayoutManager(root_window_layout_);
472
473 aura::Window* default_container =
474 GetContainer(kShellWindowId_DefaultContainer);
475 // Workspace manager has its own layout managers.
476 workspace_controller_.reset(
477 new WorkspaceController(default_container));
478
479 aura::Window* always_on_top_container =
480 GetContainer(kShellWindowId_AlwaysOnTopContainer);
481 always_on_top_container->SetLayoutManager(
482 new BaseLayoutManager(
483 always_on_top_container->GetRootWindow()));
484 always_on_top_controller_.reset(new internal::AlwaysOnTopController);
485 always_on_top_controller_->SetAlwaysOnTopContainer(always_on_top_container);
486
487 DCHECK(!shelf_.get());
488 aura::Window* shelf_container =
489 GetContainer(internal::kShellWindowId_ShelfContainer);
490 // TODO(harrym): Remove when status area is view.
491 aura::Window* status_container =
492 GetContainer(internal::kShellWindowId_StatusContainer);
493 shelf_.reset(new ShelfWidget(
494 shelf_container, status_container, workspace_controller()));
495
496 // Create Docked windows layout manager
497 aura::Window* docked_container = GetContainer(
498 internal::kShellWindowId_DockedContainer);
499 docked_layout_manager_ =
500 new internal::DockedWindowLayoutManager(docked_container);
501 docked_container_handler_.reset(
502 new ToplevelWindowEventHandler(docked_container));
503 docked_container->SetLayoutManager(docked_layout_manager_);
504
505 // Create Panel layout manager
506 aura::Window* panel_container = GetContainer(
507 internal::kShellWindowId_PanelContainer);
508 panel_layout_manager_ =
509 new internal::PanelLayoutManager(panel_container);
510 panel_container_handler_.reset(
511 new PanelWindowEventHandler(panel_container));
512 panel_container->SetLayoutManager(panel_layout_manager_);
513}
514
515void RootWindowController::InitTouchHuds() {
516 CommandLine* command_line = CommandLine::ForCurrentProcess();
517 if (command_line->HasSwitch(switches::kAshTouchHud))
518 set_touch_hud_debug(new TouchHudDebug(root_window_.get()));
519 if (Shell::GetInstance()->is_touch_hud_projection_enabled())
520 EnableTouchHudProjection();
521}
522
523void RootWindowController::CreateSystemBackground(
524 bool is_first_run_after_boot) {
525 SkColor color = SK_ColorBLACK;
526#if defined(OS_CHROMEOS)
527 if (is_first_run_after_boot)
528 color = kChromeOsBootColor;
529#endif
530 system_background_.reset(
531 new SystemBackgroundController(root_window_.get(), color));
532
533#if defined(OS_CHROMEOS)
534 // Make a copy of the system's boot splash screen so we can composite it
535 // onscreen until the desktop background is ready.
536 if (is_first_run_after_boot &&
537 (CommandLine::ForCurrentProcess()->HasSwitch(
538 switches::kAshCopyHostBackgroundAtBoot) ||
539 CommandLine::ForCurrentProcess()->HasSwitch(
540 switches::kAshAnimateFromBootSplashScreen)))
541 boot_splash_screen_.reset(new BootSplashScreen(root_window_.get()));
542#endif
543}
544
[email protected]a4cd6d32012-09-12 03:42:13545void RootWindowController::CreateContainersInRootWindow(
546 aura::RootWindow* root_window) {
547 // These containers are just used by PowerButtonController to animate groups
548 // of containers simultaneously without messing up the current transformations
549 // on those containers. These are direct children of the root window; all of
550 // the other containers are their children.
[email protected]e6e41d2f2012-10-29 19:22:19551
552 // The desktop background container is not part of the lock animation, so it
553 // is not included in those animate groups.
[email protected]a4cd6d32012-09-12 03:42:13554 // When screen is locked desktop background is moved to lock screen background
555 // container (moved back on unlock). We want to make sure that there's an
556 // opaque layer occluding the non-lock-screen layers.
[email protected]e6e41d2f2012-10-29 19:22:19557 aura::Window* desktop_background_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27558 kShellWindowId_DesktopBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13559 "DesktopBackgroundContainer",
560 root_window);
[email protected]b5756e22012-11-30 01:32:02561 views::corewm::SetChildWindowVisibilityChangesAnimated(
562 desktop_background_container);
[email protected]a4cd6d32012-09-12 03:42:13563
564 aura::Window* non_lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27565 kShellWindowId_NonLockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13566 "NonLockScreenContainersContainer",
567 root_window);
568
569 aura::Window* lock_background_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27570 kShellWindowId_LockScreenBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13571 "LockScreenBackgroundContainer",
572 root_window);
[email protected]b5756e22012-11-30 01:32:02573 views::corewm::SetChildWindowVisibilityChangesAnimated(
574 lock_background_containers);
[email protected]a4cd6d32012-09-12 03:42:13575
576 aura::Window* lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27577 kShellWindowId_LockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13578 "LockScreenContainersContainer",
579 root_window);
580 aura::Window* lock_screen_related_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27581 kShellWindowId_LockScreenRelatedContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13582 "LockScreenRelatedContainersContainer",
583 root_window);
584
[email protected]c0ce80e2012-10-05 23:28:27585 CreateContainer(kShellWindowId_UnparentedControlContainer,
[email protected]a4cd6d32012-09-12 03:42:13586 "UnparentedControlContainer",
587 non_lock_screen_containers);
588
589 aura::Window* default_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27590 kShellWindowId_DefaultContainer,
[email protected]a4cd6d32012-09-12 03:42:13591 "DefaultContainer",
592 non_lock_screen_containers);
[email protected]b5756e22012-11-30 01:32:02593 views::corewm::SetChildWindowVisibilityChangesAnimated(default_container);
[email protected]a4cd6d32012-09-12 03:42:13594 SetUsesScreenCoordinates(default_container);
595
596 aura::Window* always_on_top_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27597 kShellWindowId_AlwaysOnTopContainer,
[email protected]a4cd6d32012-09-12 03:42:13598 "AlwaysOnTopContainer",
599 non_lock_screen_containers);
600 always_on_top_container_handler_.reset(
601 new ToplevelWindowEventHandler(always_on_top_container));
[email protected]b5756e22012-11-30 01:32:02602 views::corewm::SetChildWindowVisibilityChangesAnimated(
603 always_on_top_container);
[email protected]a4cd6d32012-09-12 03:42:13604 SetUsesScreenCoordinates(always_on_top_container);
605
[email protected]beb4e5c2013-06-18 15:37:07606 aura::Window* docked_container = CreateContainer(
607 kShellWindowId_DockedContainer,
608 "DockedContainer",
609 non_lock_screen_containers);
610 SetUsesScreenCoordinates(docked_container);
611
[email protected]a4cd6d32012-09-12 03:42:13612 aura::Window* panel_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27613 kShellWindowId_PanelContainer,
[email protected]a4cd6d32012-09-12 03:42:13614 "PanelContainer",
615 non_lock_screen_containers);
616 SetUsesScreenCoordinates(panel_container);
617
[email protected]3f13cf12013-07-12 05:13:59618 aura::Window* shelf_container =
[email protected]478c6c32013-03-09 02:50:58619 CreateContainer(kShellWindowId_ShelfContainer,
[email protected]3f13cf12013-07-12 05:13:59620 "ShelfContainer",
[email protected]a4cd6d32012-09-12 03:42:13621 non_lock_screen_containers);
[email protected]3f13cf12013-07-12 05:13:59622 SetUsesScreenCoordinates(shelf_container);
623 DescendantShouldStayInSameRootWindow(shelf_container);
[email protected]a4cd6d32012-09-12 03:42:13624
[email protected]dc851a4e52012-10-03 00:05:55625 aura::Window* app_list_container =
[email protected]c0ce80e2012-10-05 23:28:27626 CreateContainer(kShellWindowId_AppListContainer,
[email protected]dc851a4e52012-10-03 00:05:55627 "AppListContainer",
628 non_lock_screen_containers);
629 SetUsesScreenCoordinates(app_list_container);
[email protected]a4cd6d32012-09-12 03:42:13630
631 aura::Window* modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27632 kShellWindowId_SystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13633 "SystemModalContainer",
634 non_lock_screen_containers);
635 modal_container_handler_.reset(
636 new ToplevelWindowEventHandler(modal_container));
[email protected]a4cd6d32012-09-12 03:42:13637 modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27638 new SystemModalContainerLayoutManager(modal_container));
[email protected]b5756e22012-11-30 01:32:02639 views::corewm::SetChildWindowVisibilityChangesAnimated(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13640 SetUsesScreenCoordinates(modal_container);
641
642 aura::Window* input_method_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27643 kShellWindowId_InputMethodContainer,
[email protected]a4cd6d32012-09-12 03:42:13644 "InputMethodContainer",
645 non_lock_screen_containers);
646 SetUsesScreenCoordinates(input_method_container);
647
648 // TODO(beng): Figure out if we can make this use
649 // SystemModalContainerEventFilter instead of stops_event_propagation.
650 aura::Window* lock_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27651 kShellWindowId_LockScreenContainer,
[email protected]a4cd6d32012-09-12 03:42:13652 "LockScreenContainer",
653 lock_screen_containers);
654 lock_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27655 new BaseLayoutManager(root_window));
[email protected]a4cd6d32012-09-12 03:42:13656 SetUsesScreenCoordinates(lock_container);
657 // TODO(beng): stopsevents
658
659 aura::Window* lock_modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27660 kShellWindowId_LockSystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13661 "LockSystemModalContainer",
662 lock_screen_containers);
663 lock_modal_container_handler_.reset(
664 new ToplevelWindowEventHandler(lock_modal_container));
[email protected]a4cd6d32012-09-12 03:42:13665 lock_modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27666 new SystemModalContainerLayoutManager(lock_modal_container));
[email protected]b5756e22012-11-30 01:32:02667 views::corewm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13668 SetUsesScreenCoordinates(lock_modal_container);
669
670 aura::Window* status_container =
[email protected]c0ce80e2012-10-05 23:28:27671 CreateContainer(kShellWindowId_StatusContainer,
[email protected]a4cd6d32012-09-12 03:42:13672 "StatusContainer",
673 lock_screen_related_containers);
674 SetUsesScreenCoordinates(status_container);
[email protected]e887c6c2013-07-08 19:35:53675 DescendantShouldStayInSameRootWindow(status_container);
[email protected]a4cd6d32012-09-12 03:42:13676
677 aura::Window* settings_bubble_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27678 kShellWindowId_SettingBubbleContainer,
[email protected]a4cd6d32012-09-12 03:42:13679 "SettingBubbleContainer",
680 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02681 views::corewm::SetChildWindowVisibilityChangesAnimated(
682 settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13683 SetUsesScreenCoordinates(settings_bubble_container);
[email protected]e887c6c2013-07-08 19:35:53684 DescendantShouldStayInSameRootWindow(settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13685
686 aura::Window* menu_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27687 kShellWindowId_MenuContainer,
[email protected]a4cd6d32012-09-12 03:42:13688 "MenuContainer",
689 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02690 views::corewm::SetChildWindowVisibilityChangesAnimated(menu_container);
[email protected]a4cd6d32012-09-12 03:42:13691 SetUsesScreenCoordinates(menu_container);
692
693 aura::Window* drag_drop_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27694 kShellWindowId_DragImageAndTooltipContainer,
[email protected]a4cd6d32012-09-12 03:42:13695 "DragImageAndTooltipContainer",
696 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02697 views::corewm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
[email protected]a4cd6d32012-09-12 03:42:13698 SetUsesScreenCoordinates(drag_drop_container);
699
700 aura::Window* overlay_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27701 kShellWindowId_OverlayContainer,
[email protected]a4cd6d32012-09-12 03:42:13702 "OverlayContainer",
703 lock_screen_related_containers);
704 SetUsesScreenCoordinates(overlay_container);
[email protected]a07615f2012-10-24 08:23:08705
706 CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
707 "PowerButtonAnimationContainer", root_window) ;
[email protected]a4cd6d32012-09-12 03:42:13708}
709
[email protected]d141b922013-07-09 08:13:17710void RootWindowController::EnableTouchHudProjection() {
711 if (touch_hud_projection_)
712 return;
713 set_touch_hud_projection(new TouchHudProjection(root_window_.get()));
714}
715
716void RootWindowController::DisableTouchHudProjection() {
717 if (!touch_hud_projection_)
718 return;
719 touch_hud_projection_->Remove();
720}
721
722void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
723 shelf_->shelf_layout_manager()->UpdateVisibilityState();
724}
725
726void RootWindowController::OnTouchHudProjectionToggled(bool enabled) {
727 if (enabled)
728 EnableTouchHudProjection();
729 else
730 DisableTouchHudProjection();
731}
732
[email protected]d90b8392012-06-13 09:34:56733} // namespace internal
734} // namespace ash