blob: 3e46f50e254cbff414712c233875fbe719332b9a [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());
305 if (docked_layout_manager_)
306 docked_layout_manager_->SetLauncher(shelf_->launcher());
307}
308
[email protected]16059276d2012-10-22 18:59:50309void RootWindowController::UpdateAfterLoginStatusChange(
310 user::LoginStatus status) {
[email protected]80549c152013-07-02 01:42:47311 if (shelf_->status_area_widget())
[email protected]478c6c32013-03-09 02:50:58312 shelf_->status_area_widget()->UpdateAfterLoginStatusChange(status);
[email protected]16059276d2012-10-22 18:59:50313}
314
[email protected]bca9a7e2012-11-10 06:25:49315void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
316 if (CommandLine::ForCurrentProcess()->HasSwitch(
317 switches::kAshAnimateFromBootSplashScreen) &&
318 boot_splash_screen_.get()) {
319 // Make the splash screen fade out so it doesn't obscure the desktop
320 // wallpaper's brightness/grayscale animation.
321 boot_splash_screen_->StartHideAnimation(
322 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
323 }
324}
325
[email protected]0bf61732013-07-02 04:35:10326void RootWindowController::OnWallpaperAnimationFinished(views::Widget* widget) {
327 // Make sure the wallpaper is visible.
[email protected]bca9a7e2012-11-10 06:25:49328 system_background_->SetColor(SK_ColorBLACK);
329 boot_splash_screen_.reset();
[email protected]0bf61732013-07-02 04:35:10330
331 Shell::GetInstance()->user_wallpaper_delegate()->
332 OnWallpaperAnimationFinished();
333 // Only removes old component when wallpaper animation finished. If we
334 // remove the old one before the new wallpaper is done fading in there will
335 // be a white flash during the animation.
336 if (animating_wallpaper_controller()) {
337 DesktopBackgroundWidgetController* controller =
338 animating_wallpaper_controller()->GetController(true);
339 // |desktop_widget_| should be the same animating widget we try to move
340 // to |kDesktopController|. Otherwise, we may close |desktop_widget_|
341 // before move it to |kDesktopController|.
342 DCHECK_EQ(controller->widget(), widget);
343 // Release the old controller and close its background widget.
344 SetWallpaperController(controller);
345 }
[email protected]697f04c2012-10-03 01:15:10346}
347
[email protected]d90b8392012-06-13 09:34:56348void RootWindowController::CloseChildWindows() {
[email protected]80549c152013-07-02 01:42:47349 if (!shelf_.get())
350 return;
[email protected]79a87b7e2013-01-25 05:08:22351 // panel_layout_manager_ needs to be shut down before windows are destroyed.
352 if (panel_layout_manager_) {
353 panel_layout_manager_->Shutdown();
354 panel_layout_manager_ = NULL;
355 }
356
[email protected]478c6c32013-03-09 02:50:58357 // TODO(harrym): Remove when Status Area Widget is a child view.
[email protected]80549c152013-07-02 01:42:47358 shelf_->ShutdownStatusAreaWidget();
[email protected]478c6c32013-03-09 02:50:58359
[email protected]80549c152013-07-02 01:42:47360 if (shelf_->shelf_layout_manager())
[email protected]a3e412712013-07-11 09:32:58361 shelf_->shelf_layout_manager()->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28362
[email protected]d90b8392012-06-13 09:34:56363 // Close background widget first as it depends on tooltip.
[email protected]0bf61732013-07-02 04:35:10364 wallpaper_controller_.reset();
365 animating_wallpaper_controller_.reset();
[email protected]b4ddc7a2012-08-07 04:17:32366
[email protected]d90b8392012-06-13 09:34:56367 workspace_controller_.reset();
368 aura::client::SetTooltipClient(root_window_.get(), NULL);
369
370 while (!root_window_->children().empty()) {
371 aura::Window* child = root_window_->children()[0];
372 delete child;
373 }
[email protected]478c6c32013-03-09 02:50:58374
375 shelf_.reset(NULL);
[email protected]d90b8392012-06-13 09:34:56376}
377
[email protected]f1853122012-06-27 16:21:26378void RootWindowController::MoveWindowsTo(aura::RootWindow* dst) {
[email protected]8039e06c2013-01-17 23:34:50379 // Forget the shelf early so that shelf don't update itself using wrong
380 // display info.
381 workspace_controller_->SetShelf(NULL);
[email protected]95058572012-08-20 14:57:29382 ReparentAllWindows(root_window_.get(), dst);
[email protected]f1853122012-06-27 16:21:26383}
384
[email protected]478c6c32013-03-09 02:50:58385ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
[email protected]80549c152013-07-02 01:42:47386 return shelf_->shelf_layout_manager();
[email protected]478c6c32013-03-09 02:50:58387}
388
[email protected]a0afeb12012-12-10 22:57:09389SystemTray* RootWindowController::GetSystemTray() {
390 // We assume in throughout the code that this will not return NULL. If code
391 // triggers this for valid reasons, it should test status_area_widget first.
[email protected]80549c152013-07-02 01:42:47392 CHECK(shelf_->status_area_widget());
[email protected]478c6c32013-03-09 02:50:58393 return shelf_->status_area_widget()->system_tray();
[email protected]a0afeb12012-12-10 22:57:09394}
395
[email protected]940fb1c2013-06-18 16:54:28396void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
397 ui::MenuSourceType source_type) {
[email protected]431552c2012-10-23 00:38:33398 DCHECK(Shell::GetInstance()->delegate());
399 scoped_ptr<ui::MenuModel> menu_model(
[email protected]8c0ec432013-05-10 04:33:39400 Shell::GetInstance()->delegate()->CreateContextMenu(root_window()));
[email protected]7f7f65c2013-04-17 16:47:13401 if (!menu_model)
[email protected]8e837ec2013-01-31 01:48:33402 return;
[email protected]431552c2012-10-23 00:38:33403
[email protected]6175fc42013-04-05 05:58:58404 // Background controller may not be set yet if user clicked on status are
405 // before initial animation completion. See crbug.com/222218
[email protected]0bf61732013-07-02 04:35:10406 if (!wallpaper_controller_.get())
[email protected]431552c2012-10-23 00:38:33407 return;
408
[email protected]6175fc42013-04-05 05:58:58409 views::MenuRunner menu_runner(menu_model.get());
[email protected]0bf61732013-07-02 04:35:10410 if (menu_runner.RunMenuAt(wallpaper_controller_->widget(),
[email protected]6175fc42013-04-05 05:58:58411 NULL, gfx::Rect(location_in_screen, gfx::Size()),
[email protected]940fb1c2013-06-18 16:54:28412 views::MenuItemView::TOPLEFT, source_type,
413 views::MenuRunner::CONTEXT_MENU) ==
[email protected]6175fc42013-04-05 05:58:58414 views::MenuRunner::MENU_DELETED) {
415 return;
416 }
417
[email protected]431552c2012-10-23 00:38:33418 Shell::GetInstance()->UpdateShelfVisibility();
419}
420
[email protected]e74aaf0a2012-10-12 18:42:28421void RootWindowController::UpdateShelfVisibility() {
[email protected]478c6c32013-03-09 02:50:58422 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]e74aaf0a2012-10-12 18:42:28423}
424
[email protected]700849f2013-04-30 17:49:20425aura::Window* RootWindowController::GetFullscreenWindow() const {
[email protected]2ee2f5d2013-01-10 23:37:16426 aura::Window* container = workspace_controller_->GetActiveWorkspaceWindow();
427 for (size_t i = 0; i < container->children().size(); ++i) {
428 aura::Window* child = container->children()[i];
[email protected]0bf61732013-07-02 04:35:10429 if (wm::IsWindowFullscreen(child))
[email protected]700849f2013-04-30 17:49:20430 return child;
[email protected]2ee2f5d2013-01-10 23:37:16431 }
[email protected]700849f2013-04-30 17:49:20432 return NULL;
[email protected]2ee2f5d2013-01-10 23:37:16433}
434
[email protected]86459e2c2013-04-10 13:39:24435void RootWindowController::InitKeyboard() {
436 if (keyboard::IsKeyboardEnabled()) {
437 aura::Window* parent = root_window();
438
439 keyboard::KeyboardControllerProxy* proxy =
440 Shell::GetInstance()->delegate()->CreateKeyboardControllerProxy();
441 keyboard_controller_.reset(
442 new keyboard::KeyboardController(proxy));
[email protected]5416f282013-04-29 20:52:48443
444 keyboard_controller_->AddObserver(shelf()->shelf_layout_manager());
445 keyboard_controller_->AddObserver(panel_layout_manager_);
446
[email protected]86459e2c2013-04-10 13:39:24447 aura::Window* keyboard_container =
448 keyboard_controller_->GetContainerWindow();
449 parent->AddChild(keyboard_container);
[email protected]e0f71132013-04-17 12:32:51450 keyboard_container->SetBounds(parent->bounds());
[email protected]86459e2c2013-04-10 13:39:24451 }
452}
453
454
[email protected]a4cd6d32012-09-12 03:42:13455////////////////////////////////////////////////////////////////////////////////
456// RootWindowController, private:
457
[email protected]756bda12013-07-03 08:17:06458void RootWindowController::InitLayoutManagers() {
459 root_window_layout_ =
460 new RootWindowLayoutManager(root_window_.get());
461 root_window_->SetLayoutManager(root_window_layout_);
462
463 aura::Window* default_container =
464 GetContainer(kShellWindowId_DefaultContainer);
465 // Workspace manager has its own layout managers.
466 workspace_controller_.reset(
467 new WorkspaceController(default_container));
468
469 aura::Window* always_on_top_container =
470 GetContainer(kShellWindowId_AlwaysOnTopContainer);
471 always_on_top_container->SetLayoutManager(
472 new BaseLayoutManager(
473 always_on_top_container->GetRootWindow()));
474 always_on_top_controller_.reset(new internal::AlwaysOnTopController);
475 always_on_top_controller_->SetAlwaysOnTopContainer(always_on_top_container);
476
477 DCHECK(!shelf_.get());
478 aura::Window* shelf_container =
479 GetContainer(internal::kShellWindowId_ShelfContainer);
480 // TODO(harrym): Remove when status area is view.
481 aura::Window* status_container =
482 GetContainer(internal::kShellWindowId_StatusContainer);
483 shelf_.reset(new ShelfWidget(
484 shelf_container, status_container, workspace_controller()));
485
486 // Create Docked windows layout manager
487 aura::Window* docked_container = GetContainer(
488 internal::kShellWindowId_DockedContainer);
489 docked_layout_manager_ =
490 new internal::DockedWindowLayoutManager(docked_container);
491 docked_container_handler_.reset(
492 new ToplevelWindowEventHandler(docked_container));
493 docked_container->SetLayoutManager(docked_layout_manager_);
494
495 // Create Panel layout manager
496 aura::Window* panel_container = GetContainer(
497 internal::kShellWindowId_PanelContainer);
498 panel_layout_manager_ =
499 new internal::PanelLayoutManager(panel_container);
500 panel_container_handler_.reset(
501 new PanelWindowEventHandler(panel_container));
502 panel_container->SetLayoutManager(panel_layout_manager_);
503}
504
505void RootWindowController::InitTouchHuds() {
506 CommandLine* command_line = CommandLine::ForCurrentProcess();
507 if (command_line->HasSwitch(switches::kAshTouchHud))
508 set_touch_hud_debug(new TouchHudDebug(root_window_.get()));
509 if (Shell::GetInstance()->is_touch_hud_projection_enabled())
510 EnableTouchHudProjection();
511}
512
513void RootWindowController::CreateSystemBackground(
514 bool is_first_run_after_boot) {
515 SkColor color = SK_ColorBLACK;
516#if defined(OS_CHROMEOS)
517 if (is_first_run_after_boot)
518 color = kChromeOsBootColor;
519#endif
520 system_background_.reset(
521 new SystemBackgroundController(root_window_.get(), color));
522
523#if defined(OS_CHROMEOS)
524 // Make a copy of the system's boot splash screen so we can composite it
525 // onscreen until the desktop background is ready.
526 if (is_first_run_after_boot &&
527 (CommandLine::ForCurrentProcess()->HasSwitch(
528 switches::kAshCopyHostBackgroundAtBoot) ||
529 CommandLine::ForCurrentProcess()->HasSwitch(
530 switches::kAshAnimateFromBootSplashScreen)))
531 boot_splash_screen_.reset(new BootSplashScreen(root_window_.get()));
532#endif
533}
534
[email protected]a4cd6d32012-09-12 03:42:13535void RootWindowController::CreateContainersInRootWindow(
536 aura::RootWindow* root_window) {
537 // These containers are just used by PowerButtonController to animate groups
538 // of containers simultaneously without messing up the current transformations
539 // on those containers. These are direct children of the root window; all of
540 // the other containers are their children.
[email protected]e6e41d2f2012-10-29 19:22:19541
542 // The desktop background container is not part of the lock animation, so it
543 // is not included in those animate groups.
[email protected]a4cd6d32012-09-12 03:42:13544 // When screen is locked desktop background is moved to lock screen background
545 // container (moved back on unlock). We want to make sure that there's an
546 // opaque layer occluding the non-lock-screen layers.
[email protected]e6e41d2f2012-10-29 19:22:19547 aura::Window* desktop_background_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27548 kShellWindowId_DesktopBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13549 "DesktopBackgroundContainer",
550 root_window);
[email protected]b5756e22012-11-30 01:32:02551 views::corewm::SetChildWindowVisibilityChangesAnimated(
552 desktop_background_container);
[email protected]a4cd6d32012-09-12 03:42:13553
554 aura::Window* non_lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27555 kShellWindowId_NonLockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13556 "NonLockScreenContainersContainer",
557 root_window);
558
559 aura::Window* lock_background_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27560 kShellWindowId_LockScreenBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13561 "LockScreenBackgroundContainer",
562 root_window);
[email protected]b5756e22012-11-30 01:32:02563 views::corewm::SetChildWindowVisibilityChangesAnimated(
564 lock_background_containers);
[email protected]a4cd6d32012-09-12 03:42:13565
566 aura::Window* lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27567 kShellWindowId_LockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13568 "LockScreenContainersContainer",
569 root_window);
570 aura::Window* lock_screen_related_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27571 kShellWindowId_LockScreenRelatedContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13572 "LockScreenRelatedContainersContainer",
573 root_window);
574
[email protected]c0ce80e2012-10-05 23:28:27575 CreateContainer(kShellWindowId_UnparentedControlContainer,
[email protected]a4cd6d32012-09-12 03:42:13576 "UnparentedControlContainer",
577 non_lock_screen_containers);
578
579 aura::Window* default_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27580 kShellWindowId_DefaultContainer,
[email protected]a4cd6d32012-09-12 03:42:13581 "DefaultContainer",
582 non_lock_screen_containers);
[email protected]b5756e22012-11-30 01:32:02583 views::corewm::SetChildWindowVisibilityChangesAnimated(default_container);
[email protected]a4cd6d32012-09-12 03:42:13584 SetUsesScreenCoordinates(default_container);
585
586 aura::Window* always_on_top_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27587 kShellWindowId_AlwaysOnTopContainer,
[email protected]a4cd6d32012-09-12 03:42:13588 "AlwaysOnTopContainer",
589 non_lock_screen_containers);
590 always_on_top_container_handler_.reset(
591 new ToplevelWindowEventHandler(always_on_top_container));
[email protected]b5756e22012-11-30 01:32:02592 views::corewm::SetChildWindowVisibilityChangesAnimated(
593 always_on_top_container);
[email protected]a4cd6d32012-09-12 03:42:13594 SetUsesScreenCoordinates(always_on_top_container);
595
[email protected]beb4e5c2013-06-18 15:37:07596 aura::Window* docked_container = CreateContainer(
597 kShellWindowId_DockedContainer,
598 "DockedContainer",
599 non_lock_screen_containers);
600 SetUsesScreenCoordinates(docked_container);
601
[email protected]a4cd6d32012-09-12 03:42:13602 aura::Window* panel_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27603 kShellWindowId_PanelContainer,
[email protected]a4cd6d32012-09-12 03:42:13604 "PanelContainer",
605 non_lock_screen_containers);
606 SetUsesScreenCoordinates(panel_container);
607
[email protected]3f13cf12013-07-12 05:13:59608 aura::Window* shelf_container =
[email protected]478c6c32013-03-09 02:50:58609 CreateContainer(kShellWindowId_ShelfContainer,
[email protected]3f13cf12013-07-12 05:13:59610 "ShelfContainer",
[email protected]a4cd6d32012-09-12 03:42:13611 non_lock_screen_containers);
[email protected]3f13cf12013-07-12 05:13:59612 SetUsesScreenCoordinates(shelf_container);
613 DescendantShouldStayInSameRootWindow(shelf_container);
[email protected]a4cd6d32012-09-12 03:42:13614
[email protected]dc851a4e52012-10-03 00:05:55615 aura::Window* app_list_container =
[email protected]c0ce80e2012-10-05 23:28:27616 CreateContainer(kShellWindowId_AppListContainer,
[email protected]dc851a4e52012-10-03 00:05:55617 "AppListContainer",
618 non_lock_screen_containers);
619 SetUsesScreenCoordinates(app_list_container);
[email protected]a4cd6d32012-09-12 03:42:13620
621 aura::Window* modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27622 kShellWindowId_SystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13623 "SystemModalContainer",
624 non_lock_screen_containers);
625 modal_container_handler_.reset(
626 new ToplevelWindowEventHandler(modal_container));
[email protected]a4cd6d32012-09-12 03:42:13627 modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27628 new SystemModalContainerLayoutManager(modal_container));
[email protected]b5756e22012-11-30 01:32:02629 views::corewm::SetChildWindowVisibilityChangesAnimated(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13630 SetUsesScreenCoordinates(modal_container);
631
632 aura::Window* input_method_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27633 kShellWindowId_InputMethodContainer,
[email protected]a4cd6d32012-09-12 03:42:13634 "InputMethodContainer",
635 non_lock_screen_containers);
636 SetUsesScreenCoordinates(input_method_container);
637
638 // TODO(beng): Figure out if we can make this use
639 // SystemModalContainerEventFilter instead of stops_event_propagation.
640 aura::Window* lock_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27641 kShellWindowId_LockScreenContainer,
[email protected]a4cd6d32012-09-12 03:42:13642 "LockScreenContainer",
643 lock_screen_containers);
644 lock_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27645 new BaseLayoutManager(root_window));
[email protected]a4cd6d32012-09-12 03:42:13646 SetUsesScreenCoordinates(lock_container);
647 // TODO(beng): stopsevents
648
649 aura::Window* lock_modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27650 kShellWindowId_LockSystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13651 "LockSystemModalContainer",
652 lock_screen_containers);
653 lock_modal_container_handler_.reset(
654 new ToplevelWindowEventHandler(lock_modal_container));
[email protected]a4cd6d32012-09-12 03:42:13655 lock_modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27656 new SystemModalContainerLayoutManager(lock_modal_container));
[email protected]b5756e22012-11-30 01:32:02657 views::corewm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13658 SetUsesScreenCoordinates(lock_modal_container);
659
660 aura::Window* status_container =
[email protected]c0ce80e2012-10-05 23:28:27661 CreateContainer(kShellWindowId_StatusContainer,
[email protected]a4cd6d32012-09-12 03:42:13662 "StatusContainer",
663 lock_screen_related_containers);
664 SetUsesScreenCoordinates(status_container);
[email protected]e887c6c2013-07-08 19:35:53665 DescendantShouldStayInSameRootWindow(status_container);
[email protected]a4cd6d32012-09-12 03:42:13666
667 aura::Window* settings_bubble_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27668 kShellWindowId_SettingBubbleContainer,
[email protected]a4cd6d32012-09-12 03:42:13669 "SettingBubbleContainer",
670 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02671 views::corewm::SetChildWindowVisibilityChangesAnimated(
672 settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13673 SetUsesScreenCoordinates(settings_bubble_container);
[email protected]e887c6c2013-07-08 19:35:53674 DescendantShouldStayInSameRootWindow(settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13675
676 aura::Window* menu_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27677 kShellWindowId_MenuContainer,
[email protected]a4cd6d32012-09-12 03:42:13678 "MenuContainer",
679 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02680 views::corewm::SetChildWindowVisibilityChangesAnimated(menu_container);
[email protected]a4cd6d32012-09-12 03:42:13681 SetUsesScreenCoordinates(menu_container);
682
683 aura::Window* drag_drop_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27684 kShellWindowId_DragImageAndTooltipContainer,
[email protected]a4cd6d32012-09-12 03:42:13685 "DragImageAndTooltipContainer",
686 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02687 views::corewm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
[email protected]a4cd6d32012-09-12 03:42:13688 SetUsesScreenCoordinates(drag_drop_container);
689
690 aura::Window* overlay_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27691 kShellWindowId_OverlayContainer,
[email protected]a4cd6d32012-09-12 03:42:13692 "OverlayContainer",
693 lock_screen_related_containers);
694 SetUsesScreenCoordinates(overlay_container);
[email protected]a07615f2012-10-24 08:23:08695
696 CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
697 "PowerButtonAnimationContainer", root_window) ;
[email protected]a4cd6d32012-09-12 03:42:13698}
699
[email protected]d141b922013-07-09 08:13:17700void RootWindowController::EnableTouchHudProjection() {
701 if (touch_hud_projection_)
702 return;
703 set_touch_hud_projection(new TouchHudProjection(root_window_.get()));
704}
705
706void RootWindowController::DisableTouchHudProjection() {
707 if (!touch_hud_projection_)
708 return;
709 touch_hud_projection_->Remove();
710}
711
712void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
713 shelf_->shelf_layout_manager()->UpdateVisibilityState();
714}
715
716void RootWindowController::OnTouchHudProjectionToggled(bool enabled) {
717 if (enabled)
718 EnableTouchHudProjection();
719 else
720 DisableTouchHudProjection();
721}
722
[email protected]d90b8392012-06-13 09:34:56723} // namespace internal
724} // namespace ash