blob: 6d5fb627771b00a7534a0422c56dff3b984f8eaf [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"
[email protected]cf6fea22013-08-07 14:24:0151#include "ui/aura/window_delegate.h"
[email protected]f1853122012-06-27 16:21:2652#include "ui/aura/window_observer.h"
[email protected]cf6fea22013-08-07 14:24:0153#include "ui/base/hit_test.h"
[email protected]431552c2012-10-23 00:38:3354#include "ui/base/models/menu_model.h"
[email protected]8d625fb2012-07-18 16:40:0655#include "ui/gfx/screen.h"
[email protected]86459e2c2013-04-10 13:39:2456#include "ui/keyboard/keyboard_controller.h"
57#include "ui/keyboard/keyboard_util.h"
[email protected]431552c2012-10-23 00:38:3358#include "ui/views/controls/menu/menu_runner.h"
[email protected]b5756e22012-11-30 01:32:0259#include "ui/views/corewm/visibility_controller.h"
[email protected]431552c2012-10-23 00:38:3360#include "ui/views/view_model.h"
61#include "ui/views/view_model_utils.h"
[email protected]d90b8392012-06-13 09:34:5662
63namespace ash {
64namespace {
65
[email protected]bca9a7e2012-11-10 06:25:4966// Duration for the animation that hides the boot splash screen, in
67// milliseconds. This should be short enough in relation to
68// wm/window_animation.cc's brightness/grayscale fade animation that the login
69// background image animation isn't hidden by the splash screen animation.
70const int kBootSplashScreenHideDurationMs = 500;
71
[email protected]d90b8392012-06-13 09:34:5672// Creates a new window for use as a container.
73aura::Window* CreateContainer(int window_id,
74 const char* name,
75 aura::Window* parent) {
76 aura::Window* container = new aura::Window(NULL);
77 container->set_id(window_id);
78 container->SetName(name);
79 container->Init(ui::LAYER_NOT_DRAWN);
80 parent->AddChild(container);
81 if (window_id != internal::kShellWindowId_UnparentedControlContainer)
82 container->Show();
83 return container;
84}
85
[email protected]95058572012-08-20 14:57:2986// Reparents |window| to |new_parent|.
87void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
88 // Update the restore bounds to make it relative to the display.
89 gfx::Rect restore_bounds(GetRestoreBoundsInParent(window));
90 new_parent->AddChild(window);
91 if (!restore_bounds.IsEmpty())
92 SetRestoreBoundsInParent(window, restore_bounds);
93}
94
95// Reparents the appropriate set of windows from |src| to |dst|.
96void ReparentAllWindows(aura::RootWindow* src, aura::RootWindow* dst) {
97 // Set of windows to move.
[email protected]f1853122012-06-27 16:21:2698 const int kContainerIdsToMove[] = {
99 internal::kShellWindowId_DefaultContainer,
[email protected]beb4e5c2013-06-18 15:37:07100 internal::kShellWindowId_DockedContainer,
[email protected]95db9c12013-01-31 11:47:44101 internal::kShellWindowId_PanelContainer,
[email protected]f1853122012-06-27 16:21:26102 internal::kShellWindowId_AlwaysOnTopContainer,
103 internal::kShellWindowId_SystemModalContainer,
104 internal::kShellWindowId_LockSystemModalContainer,
[email protected]6274d312012-10-04 22:06:41105 internal::kShellWindowId_InputMethodContainer,
[email protected]a9754872013-01-25 07:44:00106 internal::kShellWindowId_UnparentedControlContainer,
[email protected]f1853122012-06-27 16:21:26107 };
[email protected]f1853122012-06-27 16:21:26108 for (size_t i = 0; i < arraysize(kContainerIdsToMove); i++) {
109 int id = kContainerIdsToMove[i];
110 aura::Window* src_container = Shell::GetContainer(src, id);
111 aura::Window* dst_container = Shell::GetContainer(dst, id);
[email protected]5b6021902013-02-26 05:33:29112 while (!src_container->children().empty()) {
113 // Restart iteration from the source container windows each time as they
114 // may change as a result of moving other windows.
115 aura::Window::Windows::const_iterator iter =
116 src_container->children().begin();
117 while (iter != src_container->children().end() &&
118 internal::SystemModalContainerLayoutManager::IsModalBackground(
119 *iter)) {
120 ++iter;
121 }
122 // If the entire window list is modal background windows then stop.
123 if (iter == src_container->children().end())
124 break;
125 ReparentWindow(*iter, dst_container);
[email protected]f1853122012-06-27 16:21:26126 }
127 }
128}
129
[email protected]8d625fb2012-07-18 16:40:06130// Mark the container window so that a widget added to this container will
131// use the virtual screeen coordinates instead of parent.
132void SetUsesScreenCoordinates(aura::Window* container) {
133 container->SetProperty(internal::kUsesScreenCoordinatesKey, true);
134}
135
[email protected]e887c6c2013-07-08 19:35:53136// Mark the container window so that a widget added to this container will
137// say in the same root window regardless of the bounds specified.
138void DescendantShouldStayInSameRootWindow(aura::Window* container) {
139 container->SetProperty(internal::kStayInSameRootWindowKey, true);
140}
141
[email protected]cf6fea22013-08-07 14:24:01142// A window delegate which does nothing. Used to create a window that
143// is a event target, but do nothing.
144class EmptyWindowDelegate : public aura::WindowDelegate {
145 public:
146 EmptyWindowDelegate() {}
147 virtual ~EmptyWindowDelegate() {}
148
149 // aura::WindowDelegate overrides:
150 virtual gfx::Size GetMinimumSize() const OVERRIDE {
151 return gfx::Size();
152 }
153 virtual gfx::Size GetMaximumSize() const OVERRIDE {
154 return gfx::Size();
155 }
156 virtual void OnBoundsChanged(const gfx::Rect& old_bounds,
157 const gfx::Rect& new_bounds) OVERRIDE {
158 }
159 virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE {
160 return gfx::kNullCursor;
161 }
162 virtual int GetNonClientComponent(
163 const gfx::Point& point) const OVERRIDE {
164 return HTNOWHERE;
165 }
166 virtual bool ShouldDescendIntoChildForEventHandling(
167 aura::Window* child,
168 const gfx::Point& location) OVERRIDE {
169 return false;
170 }
171 virtual bool CanFocus() OVERRIDE {
172 return false;
173 }
174 virtual void OnCaptureLost() OVERRIDE {
175 }
176 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
177 }
178 virtual void OnDeviceScaleFactorChanged(
179 float device_scale_factor) OVERRIDE {
180 }
181 virtual void OnWindowDestroying() OVERRIDE {}
[email protected]febe1fd62013-08-07 16:07:24182 virtual void OnWindowDestroyed() OVERRIDE {
183 delete this;
184 }
[email protected]cf6fea22013-08-07 14:24:01185 virtual void OnWindowTargetVisibilityChanged(bool visible) OVERRIDE {
186 }
187 virtual bool HasHitTestMask() const OVERRIDE {
188 return false;
189 }
190 virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE {}
191 virtual scoped_refptr<ui::Texture> CopyTexture() OVERRIDE {
192 NOTREACHED();
193 return scoped_refptr<ui::Texture>();
194 }
195
196 private:
197 DISALLOW_COPY_AND_ASSIGN(EmptyWindowDelegate);
198};
199
[email protected]d90b8392012-06-13 09:34:56200} // namespace
201
202namespace internal {
203
204RootWindowController::RootWindowController(aura::RootWindow* root_window)
[email protected]e74aaf0a2012-10-12 18:42:28205 : root_window_(root_window),
206 root_window_layout_(NULL),
[email protected]beb4e5c2013-06-18 15:37:07207 docked_layout_manager_(NULL),
[email protected]bff17552013-04-25 04:44:55208 panel_layout_manager_(NULL),
[email protected]2b8a9bb2013-07-01 22:43:40209 touch_hud_debug_(NULL),
210 touch_hud_projection_(NULL) {
[email protected]d90b8392012-06-13 09:34:56211 SetRootWindowController(root_window, this);
[email protected]c0ce80e2012-10-05 23:28:27212 screen_dimmer_.reset(new ScreenDimmer(root_window));
[email protected]2a2caa02013-01-22 20:50:36213
[email protected]0bf61732013-07-02 04:35:10214 stacking_controller_.reset(new StackingController);
[email protected]2a2caa02013-01-22 20:50:36215 aura::client::SetStackingClient(root_window, stacking_controller_.get());
[email protected]d90b8392012-06-13 09:34:56216}
217
218RootWindowController::~RootWindowController() {
[email protected]6675e1c2012-09-11 09:15:45219 Shutdown();
220 root_window_.reset();
221}
222
[email protected]88d71122012-10-18 07:11:01223// static
[email protected]a0afeb12012-12-10 22:57:09224RootWindowController* RootWindowController::ForLauncher(aura::Window* window) {
[email protected]8c0ec432013-05-10 04:33:39225 return GetRootWindowController(window->GetRootWindow());
[email protected]88d71122012-10-18 07:11:01226}
227
[email protected]a0afeb12012-12-10 22:57:09228// static
[email protected]ccff3d72013-02-06 04:26:28229RootWindowController* RootWindowController::ForWindow(
230 const aura::Window* window) {
[email protected]a0afeb12012-12-10 22:57:09231 return GetRootWindowController(window->GetRootWindow());
232}
233
234// static
235RootWindowController* RootWindowController::ForActiveRootWindow() {
236 return GetRootWindowController(Shell::GetActiveRootWindow());
237}
238
[email protected]0bf61732013-07-02 04:35:10239void RootWindowController::SetWallpaperController(
240 DesktopBackgroundWidgetController* controller) {
241 wallpaper_controller_.reset(controller);
242}
243
244void RootWindowController::SetAnimatingWallpaperController(
245 AnimatingDesktopController* controller) {
246 if (animating_wallpaper_controller_.get())
247 animating_wallpaper_controller_->StopAnimating();
248 animating_wallpaper_controller_.reset(controller);
249}
250
[email protected]6675e1c2012-09-11 09:15:45251void RootWindowController::Shutdown() {
[email protected]d141b922013-07-09 08:13:17252 Shell::GetInstance()->RemoveShellObserver(this);
253
[email protected]0bf61732013-07-02 04:35:10254 if (animating_wallpaper_controller_.get())
255 animating_wallpaper_controller_->StopAnimating();
256 wallpaper_controller_.reset();
257 animating_wallpaper_controller_.reset();
258
[email protected]6675e1c2012-09-11 09:15:45259 CloseChildWindows();
[email protected]7f7f65c2013-04-17 16:47:13260 if (Shell::GetActiveRootWindow() == root_window_) {
[email protected]f634dd32012-07-23 22:49:07261 Shell::GetInstance()->set_active_root_window(
262 Shell::GetPrimaryRootWindow() == root_window_.get() ?
263 NULL : Shell::GetPrimaryRootWindow());
264 }
[email protected]d90b8392012-06-13 09:34:56265 SetRootWindowController(root_window_.get(), NULL);
[email protected]d90b8392012-06-13 09:34:56266 screen_dimmer_.reset();
267 workspace_controller_.reset();
[email protected]6675e1c2012-09-11 09:15:45268 // Forget with the display ID so that display lookup
269 // ends up with invalid display.
270 root_window_->ClearProperty(kDisplayIdKey);
271 // And this root window should no longer process events.
272 root_window_->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28273
[email protected]956a6a42012-10-29 23:58:10274 system_background_.reset();
[email protected]d90b8392012-06-13 09:34:56275}
276
[email protected]c0ce80e2012-10-05 23:28:27277SystemModalContainerLayoutManager*
[email protected]8674b312012-10-12 19:02:44278RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
279 aura::Window* container = NULL;
280 if (window) {
[email protected]3b162e12012-11-09 11:52:35281 if (window->parent() &&
282 window->parent()->id() >= kShellWindowId_LockScreenContainer) {
283 container = GetContainer(kShellWindowId_LockSystemModalContainer);
284 } else {
[email protected]8674b312012-10-12 19:02:44285 container = GetContainer(kShellWindowId_SystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35286 }
[email protected]8674b312012-10-12 19:02:44287 } else {
[email protected]a44afbbd2013-07-24 21:49:35288 int modal_window_id = Shell::GetInstance()->session_state_delegate()
289 ->IsUserSessionBlocked() ? kShellWindowId_LockSystemModalContainer :
290 kShellWindowId_SystemModalContainer;
[email protected]8674b312012-10-12 19:02:44291 container = GetContainer(modal_window_id);
292 }
[email protected]bb0c7cd42013-05-20 23:39:45293 return container ? static_cast<SystemModalContainerLayoutManager*>(
294 container->layout_manager()) : NULL;
[email protected]c0ce80e2012-10-05 23:28:27295}
296
[email protected]d90b8392012-06-13 09:34:56297aura::Window* RootWindowController::GetContainer(int container_id) {
298 return root_window_->GetChildById(container_id);
299}
300
[email protected]d8a24952013-08-05 20:05:05301const aura::Window* RootWindowController::GetContainer(int container_id) const {
302 return root_window_->GetChildById(container_id);
303}
304
[email protected]756bda12013-07-03 08:17:06305void RootWindowController::Init(bool first_run_after_boot) {
306 root_window_->SetCursor(ui::kCursorPointer);
[email protected]d90b8392012-06-13 09:34:56307 CreateContainersInRootWindow(root_window_.get());
[email protected]756bda12013-07-03 08:17:06308 CreateSystemBackground(first_run_after_boot);
[email protected]d90b8392012-06-13 09:34:56309
[email protected]756bda12013-07-03 08:17:06310 InitLayoutManagers();
311 InitKeyboard();
312 InitTouchHuds();
[email protected]bca9a7e2012-11-10 06:25:49313
[email protected]756bda12013-07-03 08:17:06314 if (Shell::GetPrimaryRootWindowController()->
315 GetSystemModalLayoutManager(NULL)->has_modal_background()) {
316 GetSystemModalLayoutManager(NULL)->CreateModalBackground();
317 }
[email protected]d141b922013-07-09 08:13:17318
319 Shell::GetInstance()->AddShellObserver(this);
[email protected]e74aaf0a2012-10-12 18:42:28320}
321
322void RootWindowController::ShowLauncher() {
[email protected]80549c152013-07-02 01:42:47323 if (!shelf_->launcher())
[email protected]e74aaf0a2012-10-12 18:42:28324 return;
[email protected]478c6c32013-03-09 02:50:58325 shelf_->launcher()->SetVisible(true);
326 shelf_->status_area_widget()->Show();
[email protected]e74aaf0a2012-10-12 18:42:28327}
328
[email protected]756bda12013-07-03 08:17:06329void RootWindowController::OnLauncherCreated() {
330 if (panel_layout_manager_)
331 panel_layout_manager_->SetLauncher(shelf_->launcher());
[email protected]7115bd32013-07-19 08:25:39332 if (docked_layout_manager_) {
[email protected]756bda12013-07-03 08:17:06333 docked_layout_manager_->SetLauncher(shelf_->launcher());
[email protected]7115bd32013-07-19 08:25:39334 if (shelf_->shelf_layout_manager())
335 docked_layout_manager_->AddObserver(shelf_->shelf_layout_manager());
336 }
[email protected]756bda12013-07-03 08:17:06337}
338
[email protected]16059276d2012-10-22 18:59:50339void RootWindowController::UpdateAfterLoginStatusChange(
340 user::LoginStatus status) {
[email protected]cf6fea22013-08-07 14:24:01341 if (status != user::LOGGED_IN_NONE)
342 mouse_event_target_.reset();
[email protected]80549c152013-07-02 01:42:47343 if (shelf_->status_area_widget())
[email protected]478c6c32013-03-09 02:50:58344 shelf_->status_area_widget()->UpdateAfterLoginStatusChange(status);
[email protected]16059276d2012-10-22 18:59:50345}
346
[email protected]bca9a7e2012-11-10 06:25:49347void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
348 if (CommandLine::ForCurrentProcess()->HasSwitch(
349 switches::kAshAnimateFromBootSplashScreen) &&
350 boot_splash_screen_.get()) {
351 // Make the splash screen fade out so it doesn't obscure the desktop
352 // wallpaper's brightness/grayscale animation.
353 boot_splash_screen_->StartHideAnimation(
354 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
355 }
356}
357
[email protected]0bf61732013-07-02 04:35:10358void RootWindowController::OnWallpaperAnimationFinished(views::Widget* widget) {
359 // Make sure the wallpaper is visible.
[email protected]bca9a7e2012-11-10 06:25:49360 system_background_->SetColor(SK_ColorBLACK);
361 boot_splash_screen_.reset();
[email protected]0bf61732013-07-02 04:35:10362
363 Shell::GetInstance()->user_wallpaper_delegate()->
364 OnWallpaperAnimationFinished();
365 // Only removes old component when wallpaper animation finished. If we
366 // remove the old one before the new wallpaper is done fading in there will
367 // be a white flash during the animation.
368 if (animating_wallpaper_controller()) {
369 DesktopBackgroundWidgetController* controller =
370 animating_wallpaper_controller()->GetController(true);
371 // |desktop_widget_| should be the same animating widget we try to move
372 // to |kDesktopController|. Otherwise, we may close |desktop_widget_|
373 // before move it to |kDesktopController|.
374 DCHECK_EQ(controller->widget(), widget);
375 // Release the old controller and close its background widget.
376 SetWallpaperController(controller);
377 }
[email protected]697f04c2012-10-03 01:15:10378}
379
[email protected]d90b8392012-06-13 09:34:56380void RootWindowController::CloseChildWindows() {
[email protected]cf6fea22013-08-07 14:24:01381 mouse_event_target_.reset();
382
[email protected]80549c152013-07-02 01:42:47383 if (!shelf_.get())
384 return;
[email protected]79a87b7e2013-01-25 05:08:22385 // panel_layout_manager_ needs to be shut down before windows are destroyed.
386 if (panel_layout_manager_) {
387 panel_layout_manager_->Shutdown();
388 panel_layout_manager_ = NULL;
389 }
[email protected]7115bd32013-07-19 08:25:39390 // docked_layout_manager_ needs to be shut down before windows are destroyed.
391 if (docked_layout_manager_) {
392 if (shelf_->shelf_layout_manager())
393 docked_layout_manager_->RemoveObserver(shelf_->shelf_layout_manager());
394 docked_layout_manager_->Shutdown();
395 docked_layout_manager_ = NULL;
396 }
[email protected]79a87b7e2013-01-25 05:08:22397
[email protected]478c6c32013-03-09 02:50:58398 // TODO(harrym): Remove when Status Area Widget is a child view.
[email protected]80549c152013-07-02 01:42:47399 shelf_->ShutdownStatusAreaWidget();
[email protected]478c6c32013-03-09 02:50:58400
[email protected]80549c152013-07-02 01:42:47401 if (shelf_->shelf_layout_manager())
[email protected]a3e412712013-07-11 09:32:58402 shelf_->shelf_layout_manager()->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28403
[email protected]d90b8392012-06-13 09:34:56404 // Close background widget first as it depends on tooltip.
[email protected]0bf61732013-07-02 04:35:10405 wallpaper_controller_.reset();
406 animating_wallpaper_controller_.reset();
[email protected]b4ddc7a2012-08-07 04:17:32407
[email protected]d90b8392012-06-13 09:34:56408 workspace_controller_.reset();
409 aura::client::SetTooltipClient(root_window_.get(), NULL);
410
411 while (!root_window_->children().empty()) {
412 aura::Window* child = root_window_->children()[0];
413 delete child;
414 }
[email protected]478c6c32013-03-09 02:50:58415
416 shelf_.reset(NULL);
[email protected]d90b8392012-06-13 09:34:56417}
418
[email protected]f1853122012-06-27 16:21:26419void RootWindowController::MoveWindowsTo(aura::RootWindow* dst) {
[email protected]8039e06c2013-01-17 23:34:50420 // Forget the shelf early so that shelf don't update itself using wrong
421 // display info.
422 workspace_controller_->SetShelf(NULL);
[email protected]95058572012-08-20 14:57:29423 ReparentAllWindows(root_window_.get(), dst);
[email protected]f1853122012-06-27 16:21:26424}
425
[email protected]478c6c32013-03-09 02:50:58426ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
[email protected]80549c152013-07-02 01:42:47427 return shelf_->shelf_layout_manager();
[email protected]478c6c32013-03-09 02:50:58428}
429
[email protected]a0afeb12012-12-10 22:57:09430SystemTray* RootWindowController::GetSystemTray() {
431 // We assume in throughout the code that this will not return NULL. If code
432 // triggers this for valid reasons, it should test status_area_widget first.
[email protected]80549c152013-07-02 01:42:47433 CHECK(shelf_->status_area_widget());
[email protected]478c6c32013-03-09 02:50:58434 return shelf_->status_area_widget()->system_tray();
[email protected]a0afeb12012-12-10 22:57:09435}
436
[email protected]940fb1c2013-06-18 16:54:28437void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
438 ui::MenuSourceType source_type) {
[email protected]431552c2012-10-23 00:38:33439 DCHECK(Shell::GetInstance()->delegate());
440 scoped_ptr<ui::MenuModel> menu_model(
[email protected]8c0ec432013-05-10 04:33:39441 Shell::GetInstance()->delegate()->CreateContextMenu(root_window()));
[email protected]7f7f65c2013-04-17 16:47:13442 if (!menu_model)
[email protected]8e837ec2013-01-31 01:48:33443 return;
[email protected]431552c2012-10-23 00:38:33444
[email protected]6175fc42013-04-05 05:58:58445 // Background controller may not be set yet if user clicked on status are
446 // before initial animation completion. See crbug.com/222218
[email protected]0bf61732013-07-02 04:35:10447 if (!wallpaper_controller_.get())
[email protected]431552c2012-10-23 00:38:33448 return;
449
[email protected]6175fc42013-04-05 05:58:58450 views::MenuRunner menu_runner(menu_model.get());
[email protected]0bf61732013-07-02 04:35:10451 if (menu_runner.RunMenuAt(wallpaper_controller_->widget(),
[email protected]6175fc42013-04-05 05:58:58452 NULL, gfx::Rect(location_in_screen, gfx::Size()),
[email protected]940fb1c2013-06-18 16:54:28453 views::MenuItemView::TOPLEFT, source_type,
454 views::MenuRunner::CONTEXT_MENU) ==
[email protected]6175fc42013-04-05 05:58:58455 views::MenuRunner::MENU_DELETED) {
456 return;
457 }
458
[email protected]431552c2012-10-23 00:38:33459 Shell::GetInstance()->UpdateShelfVisibility();
460}
461
[email protected]e74aaf0a2012-10-12 18:42:28462void RootWindowController::UpdateShelfVisibility() {
[email protected]478c6c32013-03-09 02:50:58463 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]e74aaf0a2012-10-12 18:42:28464}
465
[email protected]d8a24952013-08-05 20:05:05466const aura::Window* RootWindowController::GetFullscreenWindow() const {
467 const aura::Window* container = GetContainer(kShellWindowId_DefaultContainer);
[email protected]2ee2f5d2013-01-10 23:37:16468 for (size_t i = 0; i < container->children().size(); ++i) {
469 aura::Window* child = container->children()[i];
[email protected]0bf61732013-07-02 04:35:10470 if (wm::IsWindowFullscreen(child))
[email protected]700849f2013-04-30 17:49:20471 return child;
[email protected]2ee2f5d2013-01-10 23:37:16472 }
[email protected]700849f2013-04-30 17:49:20473 return NULL;
[email protected]2ee2f5d2013-01-10 23:37:16474}
475
[email protected]86459e2c2013-04-10 13:39:24476void RootWindowController::InitKeyboard() {
477 if (keyboard::IsKeyboardEnabled()) {
478 aura::Window* parent = root_window();
479
480 keyboard::KeyboardControllerProxy* proxy =
481 Shell::GetInstance()->delegate()->CreateKeyboardControllerProxy();
482 keyboard_controller_.reset(
483 new keyboard::KeyboardController(proxy));
[email protected]5416f282013-04-29 20:52:48484
485 keyboard_controller_->AddObserver(shelf()->shelf_layout_manager());
486 keyboard_controller_->AddObserver(panel_layout_manager_);
487
[email protected]86459e2c2013-04-10 13:39:24488 aura::Window* keyboard_container =
489 keyboard_controller_->GetContainerWindow();
490 parent->AddChild(keyboard_container);
[email protected]e0f71132013-04-17 12:32:51491 keyboard_container->SetBounds(parent->bounds());
[email protected]86459e2c2013-04-10 13:39:24492 }
493}
494
495
[email protected]a4cd6d32012-09-12 03:42:13496////////////////////////////////////////////////////////////////////////////////
497// RootWindowController, private:
498
[email protected]756bda12013-07-03 08:17:06499void RootWindowController::InitLayoutManagers() {
500 root_window_layout_ =
501 new RootWindowLayoutManager(root_window_.get());
502 root_window_->SetLayoutManager(root_window_layout_);
503
504 aura::Window* default_container =
505 GetContainer(kShellWindowId_DefaultContainer);
506 // Workspace manager has its own layout managers.
507 workspace_controller_.reset(
508 new WorkspaceController(default_container));
509
510 aura::Window* always_on_top_container =
511 GetContainer(kShellWindowId_AlwaysOnTopContainer);
512 always_on_top_container->SetLayoutManager(
513 new BaseLayoutManager(
514 always_on_top_container->GetRootWindow()));
515 always_on_top_controller_.reset(new internal::AlwaysOnTopController);
516 always_on_top_controller_->SetAlwaysOnTopContainer(always_on_top_container);
517
518 DCHECK(!shelf_.get());
519 aura::Window* shelf_container =
520 GetContainer(internal::kShellWindowId_ShelfContainer);
521 // TODO(harrym): Remove when status area is view.
522 aura::Window* status_container =
523 GetContainer(internal::kShellWindowId_StatusContainer);
524 shelf_.reset(new ShelfWidget(
525 shelf_container, status_container, workspace_controller()));
526
[email protected]cf6fea22013-08-07 14:24:01527 if (!Shell::GetInstance()->session_state_delegate()->
528 IsActiveUserSessionStarted()) {
529 // This window exists only to be a event target on login screen.
530 // It does not have to handle events, nor be visible.
531 mouse_event_target_.reset(new aura::Window(new EmptyWindowDelegate));
532 mouse_event_target_->Init(ui::LAYER_NOT_DRAWN);
533
534 aura::Window* lock_background_container =
535 GetContainer(internal::kShellWindowId_LockScreenBackgroundContainer);
536 lock_background_container->AddChild(mouse_event_target_.get());
537 mouse_event_target_->Show();
538 }
539
[email protected]756bda12013-07-03 08:17:06540 // Create Docked windows layout manager
541 aura::Window* docked_container = GetContainer(
542 internal::kShellWindowId_DockedContainer);
543 docked_layout_manager_ =
544 new internal::DockedWindowLayoutManager(docked_container);
545 docked_container_handler_.reset(
546 new ToplevelWindowEventHandler(docked_container));
547 docked_container->SetLayoutManager(docked_layout_manager_);
548
549 // Create Panel layout manager
550 aura::Window* panel_container = GetContainer(
551 internal::kShellWindowId_PanelContainer);
552 panel_layout_manager_ =
553 new internal::PanelLayoutManager(panel_container);
554 panel_container_handler_.reset(
555 new PanelWindowEventHandler(panel_container));
556 panel_container->SetLayoutManager(panel_layout_manager_);
557}
558
559void RootWindowController::InitTouchHuds() {
560 CommandLine* command_line = CommandLine::ForCurrentProcess();
561 if (command_line->HasSwitch(switches::kAshTouchHud))
562 set_touch_hud_debug(new TouchHudDebug(root_window_.get()));
563 if (Shell::GetInstance()->is_touch_hud_projection_enabled())
564 EnableTouchHudProjection();
565}
566
567void RootWindowController::CreateSystemBackground(
568 bool is_first_run_after_boot) {
569 SkColor color = SK_ColorBLACK;
570#if defined(OS_CHROMEOS)
571 if (is_first_run_after_boot)
572 color = kChromeOsBootColor;
573#endif
574 system_background_.reset(
575 new SystemBackgroundController(root_window_.get(), color));
576
577#if defined(OS_CHROMEOS)
578 // Make a copy of the system's boot splash screen so we can composite it
579 // onscreen until the desktop background is ready.
580 if (is_first_run_after_boot &&
581 (CommandLine::ForCurrentProcess()->HasSwitch(
582 switches::kAshCopyHostBackgroundAtBoot) ||
583 CommandLine::ForCurrentProcess()->HasSwitch(
584 switches::kAshAnimateFromBootSplashScreen)))
585 boot_splash_screen_.reset(new BootSplashScreen(root_window_.get()));
586#endif
587}
588
[email protected]a4cd6d32012-09-12 03:42:13589void RootWindowController::CreateContainersInRootWindow(
590 aura::RootWindow* root_window) {
591 // These containers are just used by PowerButtonController to animate groups
592 // of containers simultaneously without messing up the current transformations
593 // on those containers. These are direct children of the root window; all of
594 // the other containers are their children.
[email protected]e6e41d2f2012-10-29 19:22:19595
596 // The desktop background container is not part of the lock animation, so it
597 // is not included in those animate groups.
[email protected]a4cd6d32012-09-12 03:42:13598 // When screen is locked desktop background is moved to lock screen background
599 // container (moved back on unlock). We want to make sure that there's an
600 // opaque layer occluding the non-lock-screen layers.
[email protected]e6e41d2f2012-10-29 19:22:19601 aura::Window* desktop_background_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27602 kShellWindowId_DesktopBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13603 "DesktopBackgroundContainer",
604 root_window);
[email protected]b5756e22012-11-30 01:32:02605 views::corewm::SetChildWindowVisibilityChangesAnimated(
606 desktop_background_container);
[email protected]a4cd6d32012-09-12 03:42:13607
608 aura::Window* non_lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27609 kShellWindowId_NonLockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13610 "NonLockScreenContainersContainer",
611 root_window);
612
613 aura::Window* lock_background_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27614 kShellWindowId_LockScreenBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13615 "LockScreenBackgroundContainer",
616 root_window);
[email protected]b5756e22012-11-30 01:32:02617 views::corewm::SetChildWindowVisibilityChangesAnimated(
618 lock_background_containers);
[email protected]a4cd6d32012-09-12 03:42:13619
620 aura::Window* lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27621 kShellWindowId_LockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13622 "LockScreenContainersContainer",
623 root_window);
624 aura::Window* lock_screen_related_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27625 kShellWindowId_LockScreenRelatedContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13626 "LockScreenRelatedContainersContainer",
627 root_window);
628
[email protected]c0ce80e2012-10-05 23:28:27629 CreateContainer(kShellWindowId_UnparentedControlContainer,
[email protected]a4cd6d32012-09-12 03:42:13630 "UnparentedControlContainer",
631 non_lock_screen_containers);
632
633 aura::Window* default_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27634 kShellWindowId_DefaultContainer,
[email protected]a4cd6d32012-09-12 03:42:13635 "DefaultContainer",
636 non_lock_screen_containers);
[email protected]b5756e22012-11-30 01:32:02637 views::corewm::SetChildWindowVisibilityChangesAnimated(default_container);
[email protected]a4cd6d32012-09-12 03:42:13638 SetUsesScreenCoordinates(default_container);
639
640 aura::Window* always_on_top_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27641 kShellWindowId_AlwaysOnTopContainer,
[email protected]a4cd6d32012-09-12 03:42:13642 "AlwaysOnTopContainer",
643 non_lock_screen_containers);
644 always_on_top_container_handler_.reset(
645 new ToplevelWindowEventHandler(always_on_top_container));
[email protected]b5756e22012-11-30 01:32:02646 views::corewm::SetChildWindowVisibilityChangesAnimated(
647 always_on_top_container);
[email protected]a4cd6d32012-09-12 03:42:13648 SetUsesScreenCoordinates(always_on_top_container);
649
[email protected]beb4e5c2013-06-18 15:37:07650 aura::Window* docked_container = CreateContainer(
651 kShellWindowId_DockedContainer,
652 "DockedContainer",
653 non_lock_screen_containers);
654 SetUsesScreenCoordinates(docked_container);
655
[email protected]a4cd6d32012-09-12 03:42:13656 aura::Window* panel_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27657 kShellWindowId_PanelContainer,
[email protected]a4cd6d32012-09-12 03:42:13658 "PanelContainer",
659 non_lock_screen_containers);
660 SetUsesScreenCoordinates(panel_container);
661
[email protected]3f13cf12013-07-12 05:13:59662 aura::Window* shelf_container =
[email protected]478c6c32013-03-09 02:50:58663 CreateContainer(kShellWindowId_ShelfContainer,
[email protected]3f13cf12013-07-12 05:13:59664 "ShelfContainer",
[email protected]a4cd6d32012-09-12 03:42:13665 non_lock_screen_containers);
[email protected]3f13cf12013-07-12 05:13:59666 SetUsesScreenCoordinates(shelf_container);
667 DescendantShouldStayInSameRootWindow(shelf_container);
[email protected]a4cd6d32012-09-12 03:42:13668
[email protected]dc851a4e52012-10-03 00:05:55669 aura::Window* app_list_container =
[email protected]c0ce80e2012-10-05 23:28:27670 CreateContainer(kShellWindowId_AppListContainer,
[email protected]dc851a4e52012-10-03 00:05:55671 "AppListContainer",
672 non_lock_screen_containers);
673 SetUsesScreenCoordinates(app_list_container);
[email protected]a4cd6d32012-09-12 03:42:13674
675 aura::Window* modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27676 kShellWindowId_SystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13677 "SystemModalContainer",
678 non_lock_screen_containers);
679 modal_container_handler_.reset(
680 new ToplevelWindowEventHandler(modal_container));
[email protected]a4cd6d32012-09-12 03:42:13681 modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27682 new SystemModalContainerLayoutManager(modal_container));
[email protected]b5756e22012-11-30 01:32:02683 views::corewm::SetChildWindowVisibilityChangesAnimated(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13684 SetUsesScreenCoordinates(modal_container);
685
686 aura::Window* input_method_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27687 kShellWindowId_InputMethodContainer,
[email protected]a4cd6d32012-09-12 03:42:13688 "InputMethodContainer",
689 non_lock_screen_containers);
690 SetUsesScreenCoordinates(input_method_container);
691
692 // TODO(beng): Figure out if we can make this use
693 // SystemModalContainerEventFilter instead of stops_event_propagation.
694 aura::Window* lock_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27695 kShellWindowId_LockScreenContainer,
[email protected]a4cd6d32012-09-12 03:42:13696 "LockScreenContainer",
697 lock_screen_containers);
698 lock_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27699 new BaseLayoutManager(root_window));
[email protected]a4cd6d32012-09-12 03:42:13700 SetUsesScreenCoordinates(lock_container);
701 // TODO(beng): stopsevents
702
703 aura::Window* lock_modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27704 kShellWindowId_LockSystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13705 "LockSystemModalContainer",
706 lock_screen_containers);
707 lock_modal_container_handler_.reset(
708 new ToplevelWindowEventHandler(lock_modal_container));
[email protected]a4cd6d32012-09-12 03:42:13709 lock_modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27710 new SystemModalContainerLayoutManager(lock_modal_container));
[email protected]b5756e22012-11-30 01:32:02711 views::corewm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13712 SetUsesScreenCoordinates(lock_modal_container);
713
714 aura::Window* status_container =
[email protected]c0ce80e2012-10-05 23:28:27715 CreateContainer(kShellWindowId_StatusContainer,
[email protected]a4cd6d32012-09-12 03:42:13716 "StatusContainer",
717 lock_screen_related_containers);
718 SetUsesScreenCoordinates(status_container);
[email protected]e887c6c2013-07-08 19:35:53719 DescendantShouldStayInSameRootWindow(status_container);
[email protected]a4cd6d32012-09-12 03:42:13720
721 aura::Window* settings_bubble_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27722 kShellWindowId_SettingBubbleContainer,
[email protected]a4cd6d32012-09-12 03:42:13723 "SettingBubbleContainer",
724 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02725 views::corewm::SetChildWindowVisibilityChangesAnimated(
726 settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13727 SetUsesScreenCoordinates(settings_bubble_container);
[email protected]e887c6c2013-07-08 19:35:53728 DescendantShouldStayInSameRootWindow(settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13729
730 aura::Window* menu_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27731 kShellWindowId_MenuContainer,
[email protected]a4cd6d32012-09-12 03:42:13732 "MenuContainer",
733 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02734 views::corewm::SetChildWindowVisibilityChangesAnimated(menu_container);
[email protected]a4cd6d32012-09-12 03:42:13735 SetUsesScreenCoordinates(menu_container);
736
737 aura::Window* drag_drop_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27738 kShellWindowId_DragImageAndTooltipContainer,
[email protected]a4cd6d32012-09-12 03:42:13739 "DragImageAndTooltipContainer",
740 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02741 views::corewm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
[email protected]a4cd6d32012-09-12 03:42:13742 SetUsesScreenCoordinates(drag_drop_container);
743
744 aura::Window* overlay_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27745 kShellWindowId_OverlayContainer,
[email protected]a4cd6d32012-09-12 03:42:13746 "OverlayContainer",
747 lock_screen_related_containers);
748 SetUsesScreenCoordinates(overlay_container);
[email protected]a07615f2012-10-24 08:23:08749
750 CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
751 "PowerButtonAnimationContainer", root_window) ;
[email protected]a4cd6d32012-09-12 03:42:13752}
753
[email protected]d141b922013-07-09 08:13:17754void RootWindowController::EnableTouchHudProjection() {
755 if (touch_hud_projection_)
756 return;
757 set_touch_hud_projection(new TouchHudProjection(root_window_.get()));
758}
759
760void RootWindowController::DisableTouchHudProjection() {
761 if (!touch_hud_projection_)
762 return;
763 touch_hud_projection_->Remove();
764}
765
766void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
767 shelf_->shelf_layout_manager()->UpdateVisibilityState();
768}
769
770void RootWindowController::OnTouchHudProjectionToggled(bool enabled) {
771 if (enabled)
772 EnableTouchHudProjection();
773 else
774 DisableTouchHudProjection();
775}
776
[email protected]d90b8392012-06-13 09:34:56777} // namespace internal
778} // namespace ash