blob: 69777902b3b07bc370895d0dcaaa824fbc0c0683 [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]8b3e3d82013-08-20 14:36:307#include <queue>
[email protected]8d625fb2012-07-18 16:40:068#include <vector>
9
[email protected]44d444c2013-01-30 01:47:4410#include "ash/ash_constants.h"
[email protected]e6e41d2f2012-10-29 19:22:1911#include "ash/ash_switches.h"
[email protected]a273d33a2013-10-17 12:41:2112#include "ash/desktop_background/desktop_background_controller.h"
[email protected]b4ddc7a2012-08-07 04:17:3213#include "ash/desktop_background/desktop_background_widget_controller.h"
[email protected]0bf61732013-07-02 04:35:1014#include "ash/desktop_background/user_wallpaper_delegate.h"
[email protected]6bdf7952012-11-14 10:10:5815#include "ash/display/display_manager.h"
[email protected]e74aaf0a2012-10-12 18:42:2816#include "ash/focus_cycler.h"
[email protected]a273d33a2013-10-17 12:41:2117#include "ash/high_contrast/high_contrast_controller.h"
[email protected]f5c9dbc2014-04-11 08:13:4518#include "ash/host/ash_window_tree_host.h"
[email protected]f8e6aad2013-08-30 21:49:1119#include "ash/root_window_settings.h"
[email protected]fdf74bf2014-04-30 21:24:0220#include "ash/session/session_state_delegate.h"
[email protected]478c6c32013-03-09 02:50:5821#include "ash/shelf/shelf_layout_manager.h"
22#include "ash/shelf/shelf_types.h"
23#include "ash/shelf/shelf_widget.h"
[email protected]d90b8392012-06-13 09:34:5624#include "ash/shell.h"
[email protected]e74aaf0a2012-10-12 18:42:2825#include "ash/shell_delegate.h"
[email protected]d90b8392012-06-13 09:34:5626#include "ash/shell_factory.h"
27#include "ash/shell_window_ids.h"
[email protected]2c5db9e2014-02-27 13:58:1428#include "ash/switchable_windows.h"
[email protected]e74aaf0a2012-10-12 18:42:2829#include "ash/system/status_area_widget.h"
[email protected]8674b312012-10-12 19:02:4430#include "ash/system/tray/system_tray_delegate.h"
[email protected]a825e8312014-05-05 22:05:0131#include "ash/system/tray/system_tray_notifier.h"
[email protected]2b8a9bb2013-07-01 22:43:4032#include "ash/touch/touch_hud_debug.h"
33#include "ash/touch/touch_hud_projection.h"
[email protected]80549c152013-07-02 01:42:4734#include "ash/touch/touch_observer_hud.h"
35#include "ash/wm/always_on_top_controller.h"
[email protected]beb4e5c2013-06-18 15:37:0736#include "ash/wm/dock/docked_window_layout_manager.h"
[email protected]68d51332014-06-06 13:51:1337#include "ash/wm/lock_layout_manager.h"
[email protected]b8642ec2014-04-17 05:20:3938#include "ash/wm/panels/attached_panel_window_targeter.h"
[email protected]7095a652013-03-07 19:41:4939#include "ash/wm/panels/panel_layout_manager.h"
[email protected]100659412013-06-21 22:59:5540#include "ash/wm/panels/panel_window_event_handler.h"
[email protected]d90b8392012-06-13 09:34:5641#include "ash/wm/root_window_layout_manager.h"
[email protected]2a2caa02013-01-22 20:50:3642#include "ash/wm/stacking_controller.h"
[email protected]e74aaf0a2012-10-12 18:42:2843#include "ash/wm/status_area_layout_manager.h"
[email protected]e6e41d2f2012-10-29 19:22:1944#include "ash/wm/system_background_controller.h"
[email protected]d90b8392012-06-13 09:34:5645#include "ash/wm/system_modal_container_layout_manager.h"
[email protected]8d625fb2012-07-18 16:40:0646#include "ash/wm/window_properties.h"
[email protected]a41b4e12013-09-20 04:36:3447#include "ash/wm/window_state.h"
[email protected]700849f2013-04-30 17:49:2048#include "ash/wm/window_util.h"
[email protected]1af71f72014-01-29 20:00:5549#include "ash/wm/workspace/workspace_layout_manager.h"
[email protected]d90b8392012-06-13 09:34:5650#include "ash/wm/workspace_controller.h"
[email protected]e6e41d2f2012-10-29 19:22:1951#include "base/command_line.h"
[email protected]1e84c632013-06-27 23:12:2152#include "base/time/time.h"
[email protected]f1853122012-06-27 16:21:2653#include "ui/aura/client/aura_constants.h"
[email protected]2374d1812014-03-04 03:42:2754#include "ui/aura/client/screen_position_client.h"
[email protected]f1853122012-06-27 16:21:2655#include "ui/aura/window.h"
[email protected]cf6fea22013-08-07 14:24:0156#include "ui/aura/window_delegate.h"
[email protected]fcc51c952014-02-21 21:31:2657#include "ui/aura/window_event_dispatcher.h"
[email protected]f1853122012-06-27 16:21:2658#include "ui/aura/window_observer.h"
[email protected]8b3e3d82013-08-20 14:36:3059#include "ui/aura/window_tracker.h"
[email protected]cf6fea22013-08-07 14:24:0160#include "ui/base/hit_test.h"
[email protected]431552c2012-10-23 00:38:3361#include "ui/base/models/menu_model.h"
[email protected]f8e6aad2013-08-30 21:49:1162#include "ui/gfx/display.h"
[email protected]8d625fb2012-07-18 16:40:0663#include "ui/gfx/screen.h"
[email protected]86459e2c2013-04-10 13:39:2464#include "ui/keyboard/keyboard_controller.h"
65#include "ui/keyboard/keyboard_util.h"
[email protected]431552c2012-10-23 00:38:3366#include "ui/views/controls/menu/menu_runner.h"
67#include "ui/views/view_model.h"
68#include "ui/views/view_model_utils.h"
[email protected]ee3ed10772014-03-11 22:02:0169#include "ui/wm/core/capture_controller.h"
[email protected]e319c7e2014-03-14 19:56:1470#include "ui/wm/core/easy_resize_window_targeter.h"
[email protected]ee3ed10772014-03-11 22:02:0171#include "ui/wm/core/visibility_controller.h"
72#include "ui/wm/core/window_util.h"
[email protected]af4552b22014-03-21 19:45:0173#include "ui/wm/public/drag_drop_client.h"
74#include "ui/wm/public/tooltip_client.h"
[email protected]5b251f12013-12-19 01:50:0575#include "ui/wm/public/window_types.h"
[email protected]d90b8392012-06-13 09:34:5676
[email protected]252eb232013-08-14 22:09:2777#if defined(OS_CHROMEOS)
[email protected]7d487592014-07-24 03:54:5078#include "ash/ash_touch_exploration_manager_chromeos.h"
[email protected]252eb232013-08-14 22:09:2779#include "ash/wm/boot_splash_screen_chromeos.h"
[email protected]a825e8312014-05-05 22:05:0180#include "ui/chromeos/touch_exploration_controller.h"
[email protected]252eb232013-08-14 22:09:2781#endif
82
[email protected]d90b8392012-06-13 09:34:5683namespace ash {
84namespace {
85
[email protected]252eb232013-08-14 22:09:2786#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:4987// Duration for the animation that hides the boot splash screen, in
88// milliseconds. This should be short enough in relation to
89// wm/window_animation.cc's brightness/grayscale fade animation that the login
90// background image animation isn't hidden by the splash screen animation.
91const int kBootSplashScreenHideDurationMs = 500;
[email protected]252eb232013-08-14 22:09:2792#endif
[email protected]bca9a7e2012-11-10 06:25:4993
[email protected]d90b8392012-06-13 09:34:5694// Creates a new window for use as a container.
95aura::Window* CreateContainer(int window_id,
96 const char* name,
97 aura::Window* parent) {
98 aura::Window* container = new aura::Window(NULL);
99 container->set_id(window_id);
100 container->SetName(name);
danakjb161836d2015-04-03 05:14:18101 container->Init(ui::LAYER_NOT_DRAWN);
[email protected]d90b8392012-06-13 09:34:56102 parent->AddChild(container);
[email protected]093b8d642014-04-03 20:59:28103 if (window_id != kShellWindowId_UnparentedControlContainer)
[email protected]d90b8392012-06-13 09:34:56104 container->Show();
105 return container;
106}
107
[email protected]2816c2462013-12-17 02:22:25108float ToRelativeValue(int value, int src, int dst) {
109 return static_cast<float>(value) / static_cast<float>(src) * dst;
110}
111
112void MoveOriginRelativeToSize(const gfx::Size& src_size,
113 const gfx::Size& dst_size,
114 gfx::Rect* bounds_in_out) {
115 gfx::Point origin = bounds_in_out->origin();
116 bounds_in_out->set_origin(gfx::Point(
117 ToRelativeValue(origin.x(), src_size.width(), dst_size.width()),
118 ToRelativeValue(origin.y(), src_size.height(), dst_size.height())));
119}
120
[email protected]95058572012-08-20 14:57:29121// Reparents |window| to |new_parent|.
122void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
[email protected]2816c2462013-12-17 02:22:25123 const gfx::Size src_size = window->parent()->bounds().size();
124 const gfx::Size dst_size = new_parent->bounds().size();
[email protected]95058572012-08-20 14:57:29125 // Update the restore bounds to make it relative to the display.
[email protected]a41b4e12013-09-20 04:36:34126 wm::WindowState* state = wm::GetWindowState(window);
127 gfx::Rect restore_bounds;
128 bool has_restore_bounds = state->HasRestoreBounds();
[email protected]2816c2462013-12-17 02:22:25129
[email protected]9cfd3d12014-02-25 15:33:45130 bool update_bounds = (state->IsNormalOrSnapped() || state->IsMinimized()) &&
[email protected]093b8d642014-04-03 20:59:28131 new_parent->id() != kShellWindowId_DockedContainer;
[email protected]2816c2462013-12-17 02:22:25132 gfx::Rect local_bounds;
133 if (update_bounds) {
134 local_bounds = state->window()->bounds();
135 MoveOriginRelativeToSize(src_size, dst_size, &local_bounds);
136 }
137
138 if (has_restore_bounds) {
[email protected]a41b4e12013-09-20 04:36:34139 restore_bounds = state->GetRestoreBoundsInParent();
[email protected]2816c2462013-12-17 02:22:25140 MoveOriginRelativeToSize(src_size, dst_size, &restore_bounds);
141 }
142
[email protected]95058572012-08-20 14:57:29143 new_parent->AddChild(window);
[email protected]2816c2462013-12-17 02:22:25144
[email protected]8663b7a62014-01-18 01:24:21145 // Docked windows have bounds handled by the layout manager in AddChild().
[email protected]2816c2462013-12-17 02:22:25146 if (update_bounds)
147 window->SetBounds(local_bounds);
148
[email protected]a41b4e12013-09-20 04:36:34149 if (has_restore_bounds)
150 state->SetRestoreBoundsInParent(restore_bounds);
[email protected]95058572012-08-20 14:57:29151}
152
153// Reparents the appropriate set of windows from |src| to |dst|.
[email protected]bf9cdb362013-10-25 19:22:45154void ReparentAllWindows(aura::Window* src, aura::Window* dst) {
[email protected]95058572012-08-20 14:57:29155 // Set of windows to move.
[email protected]f1853122012-06-27 16:21:26156 const int kContainerIdsToMove[] = {
[email protected]093b8d642014-04-03 20:59:28157 kShellWindowId_DefaultContainer,
158 kShellWindowId_DockedContainer,
159 kShellWindowId_PanelContainer,
160 kShellWindowId_AlwaysOnTopContainer,
161 kShellWindowId_SystemModalContainer,
162 kShellWindowId_LockSystemModalContainer,
tengsf98986c2014-12-06 01:42:21163 kShellWindowId_UnparentedControlContainer,
oshima022a9542015-05-01 00:15:02164 kShellWindowId_OverlayContainer,
165 };
166 const int kExtraContainerIdsToMoveInUnifiedMode[] = {
167 kShellWindowId_LockScreenContainer,
168 kShellWindowId_LockScreenBackgroundContainer,
169 };
170 std::vector<int> container_ids(
171 kContainerIdsToMove,
172 kContainerIdsToMove + arraysize(kContainerIdsToMove));
173 // Check the default_multi_display_mode because this is also necessary
174 // in trasition between mirror <-> unified mode.
oshima628a6172015-08-01 01:33:14175 if (Shell::GetInstance()
176 ->display_manager()
177 ->current_default_multi_display_mode() == DisplayManager::UNIFIED) {
oshima022a9542015-05-01 00:15:02178 for (int id : kExtraContainerIdsToMoveInUnifiedMode)
179 container_ids.push_back(id);
180 }
181
182 for (int id : container_ids) {
[email protected]f1853122012-06-27 16:21:26183 aura::Window* src_container = Shell::GetContainer(src, id);
184 aura::Window* dst_container = Shell::GetContainer(dst, id);
[email protected]5b6021902013-02-26 05:33:29185 while (!src_container->children().empty()) {
186 // Restart iteration from the source container windows each time as they
187 // may change as a result of moving other windows.
188 aura::Window::Windows::const_iterator iter =
189 src_container->children().begin();
190 while (iter != src_container->children().end() &&
[email protected]093b8d642014-04-03 20:59:28191 SystemModalContainerLayoutManager::IsModalBackground(*iter)) {
[email protected]5b6021902013-02-26 05:33:29192 ++iter;
193 }
194 // If the entire window list is modal background windows then stop.
195 if (iter == src_container->children().end())
196 break;
197 ReparentWindow(*iter, dst_container);
[email protected]f1853122012-06-27 16:21:26198 }
199 }
200}
201
[email protected]8d625fb2012-07-18 16:40:06202// Mark the container window so that a widget added to this container will
203// use the virtual screeen coordinates instead of parent.
204void SetUsesScreenCoordinates(aura::Window* container) {
[email protected]093b8d642014-04-03 20:59:28205 container->SetProperty(kUsesScreenCoordinatesKey, true);
[email protected]8d625fb2012-07-18 16:40:06206}
207
[email protected]e887c6c2013-07-08 19:35:53208// Mark the container window so that a widget added to this container will
209// say in the same root window regardless of the bounds specified.
210void DescendantShouldStayInSameRootWindow(aura::Window* container) {
[email protected]093b8d642014-04-03 20:59:28211 container->SetProperty(kStayInSameRootWindowKey, true);
[email protected]e887c6c2013-07-08 19:35:53212}
213
[email protected]c5be8d672014-01-07 13:33:41214void SetUsesEasyResizeTargeter(aura::Window* container) {
215 gfx::Insets mouse_extend(-kResizeOutsideBoundsSize,
216 -kResizeOutsideBoundsSize,
217 -kResizeOutsideBoundsSize,
218 -kResizeOutsideBoundsSize);
219 gfx::Insets touch_extend = mouse_extend.Scale(
220 kResizeOutsideBoundsScaleForTouch);
[email protected]95f642cb2014-01-31 01:35:41221 container->SetEventTargeter(scoped_ptr<ui::EventTargeter>(
[email protected]c5be8d672014-01-07 13:33:41222 new ::wm::EasyResizeWindowTargeter(container, mouse_extend,
223 touch_extend)));
224}
225
[email protected]cf6fea22013-08-07 14:24:01226// A window delegate which does nothing. Used to create a window that
227// is a event target, but do nothing.
228class EmptyWindowDelegate : public aura::WindowDelegate {
229 public:
230 EmptyWindowDelegate() {}
dcheng1f4538e2014-10-27 23:57:05231 ~EmptyWindowDelegate() override {}
[email protected]cf6fea22013-08-07 14:24:01232
233 // aura::WindowDelegate overrides:
dcheng1f4538e2014-10-27 23:57:05234 gfx::Size GetMinimumSize() const override { return gfx::Size(); }
235 gfx::Size GetMaximumSize() const override { return gfx::Size(); }
236 void OnBoundsChanged(const gfx::Rect& old_bounds,
237 const gfx::Rect& new_bounds) override {}
238 gfx::NativeCursor GetCursor(const gfx::Point& point) override {
[email protected]62c9f102014-03-27 06:07:04239 return gfx::kNullCursor;
240 }
dcheng1f4538e2014-10-27 23:57:05241 int GetNonClientComponent(const gfx::Point& point) const override {
[email protected]cf6fea22013-08-07 14:24:01242 return HTNOWHERE;
243 }
dcheng1f4538e2014-10-27 23:57:05244 bool ShouldDescendIntoChildForEventHandling(
[email protected]cf6fea22013-08-07 14:24:01245 aura::Window* child,
mostynb10d6b382014-10-03 16:23:45246 const gfx::Point& location) override {
[email protected]cf6fea22013-08-07 14:24:01247 return false;
248 }
dcheng1f4538e2014-10-27 23:57:05249 bool CanFocus() override { return false; }
250 void OnCaptureLost() override {}
danakj85d970e2015-04-04 00:15:24251 void OnPaint(const ui::PaintContext& context) override {}
dcheng1f4538e2014-10-27 23:57:05252 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
253 void OnWindowDestroying(aura::Window* window) override {}
254 void OnWindowDestroyed(aura::Window* window) override { delete this; }
255 void OnWindowTargetVisibilityChanged(bool visible) override {}
256 bool HasHitTestMask() const override { return false; }
257 void GetHitTestMask(gfx::Path* mask) const override {}
[email protected]cf6fea22013-08-07 14:24:01258
259 private:
260 DISALLOW_COPY_AND_ASSIGN(EmptyWindowDelegate);
261};
262
[email protected]d90b8392012-06-13 09:34:56263} // namespace
264
[email protected]f5c9dbc2014-04-11 08:13:45265void RootWindowController::CreateForPrimaryDisplay(AshWindowTreeHost* host) {
[email protected]2f2620332014-02-28 10:07:38266 RootWindowController* controller = new RootWindowController(host);
[email protected]608de6c2013-10-29 00:14:28267 controller->Init(RootWindowController::PRIMARY,
[email protected]a273d33a2013-10-17 12:41:21268 Shell::GetInstance()->delegate()->IsFirstRunAfterBoot());
[email protected]d90b8392012-06-13 09:34:56269}
270
[email protected]f5c9dbc2014-04-11 08:13:45271void RootWindowController::CreateForSecondaryDisplay(AshWindowTreeHost* host) {
[email protected]2f2620332014-02-28 10:07:38272 RootWindowController* controller = new RootWindowController(host);
[email protected]608de6c2013-10-29 00:14:28273 controller->Init(RootWindowController::SECONDARY, false /* first run */);
274}
275
[email protected]88d71122012-10-18 07:11:01276// static
[email protected]76bc4632014-06-16 19:07:46277RootWindowController* RootWindowController::ForShelf(
278 const aura::Window* window) {
oshima9eea82da2014-09-13 01:11:07279 CHECK(Shell::HasInstance());
[email protected]8c0ec432013-05-10 04:33:39280 return GetRootWindowController(window->GetRootWindow());
[email protected]88d71122012-10-18 07:11:01281}
282
[email protected]a0afeb12012-12-10 22:57:09283// static
[email protected]ccff3d72013-02-06 04:26:28284RootWindowController* RootWindowController::ForWindow(
285 const aura::Window* window) {
oshima9eea82da2014-09-13 01:11:07286 CHECK(Shell::HasInstance());
[email protected]a0afeb12012-12-10 22:57:09287 return GetRootWindowController(window->GetRootWindow());
288}
289
290// static
[email protected]d17642d2013-09-12 23:44:38291RootWindowController* RootWindowController::ForTargetRootWindow() {
oshima9eea82da2014-09-13 01:11:07292 CHECK(Shell::HasInstance());
[email protected]093b8d642014-04-03 20:59:28293 return GetRootWindowController(Shell::GetTargetRootWindow());
[email protected]a0afeb12012-12-10 22:57:09294}
295
[email protected]a5c78802013-12-12 22:07:01296// static
297aura::Window* RootWindowController::GetContainerForWindow(
298 aura::Window* window) {
299 aura::Window* container = window->parent();
[email protected]5b251f12013-12-19 01:50:05300 while (container && container->type() != ui::wm::WINDOW_TYPE_UNKNOWN)
[email protected]a5c78802013-12-12 22:07:01301 container = container->parent();
302 return container;
303}
304
[email protected]a273d33a2013-10-17 12:41:21305RootWindowController::~RootWindowController() {
306 Shutdown();
[email protected]f5c9dbc2014-04-11 08:13:45307 ash_host_.reset();
[email protected]a273d33a2013-10-17 12:41:21308 // The CaptureClient needs to be around for as long as the RootWindow is
309 // valid.
310 capture_client_.reset();
311}
312
[email protected]f5c9dbc2014-04-11 08:13:45313aura::WindowTreeHost* RootWindowController::GetHost() {
314 return ash_host_->AsWindowTreeHost();
315}
316
317const aura::WindowTreeHost* RootWindowController::GetHost() const {
318 return ash_host_->AsWindowTreeHost();
319}
320
321aura::Window* RootWindowController::GetRootWindow() {
322 return GetHost()->window();
323}
324
325const aura::Window* RootWindowController::GetRootWindow() const {
326 return GetHost()->window();
327}
328
[email protected]0bf61732013-07-02 04:35:10329void RootWindowController::SetWallpaperController(
330 DesktopBackgroundWidgetController* controller) {
331 wallpaper_controller_.reset(controller);
332}
333
334void RootWindowController::SetAnimatingWallpaperController(
335 AnimatingDesktopController* controller) {
336 if (animating_wallpaper_controller_.get())
337 animating_wallpaper_controller_->StopAnimating();
338 animating_wallpaper_controller_.reset(controller);
339}
340
[email protected]6675e1c2012-09-11 09:15:45341void RootWindowController::Shutdown() {
[email protected]a825e8312014-05-05 22:05:01342 Shell* shell = Shell::GetInstance();
343 shell->RemoveShellObserver(this);
344
345#if defined(OS_CHROMEOS)
[email protected]7d487592014-07-24 03:54:50346 if (touch_exploration_manager_) {
347 touch_exploration_manager_.reset();
[email protected]a825e8312014-05-05 22:05:01348 }
349#endif
[email protected]d141b922013-07-09 08:13:17350
[email protected]0bf61732013-07-02 04:35:10351 if (animating_wallpaper_controller_.get())
352 animating_wallpaper_controller_->StopAnimating();
353 wallpaper_controller_.reset();
354 animating_wallpaper_controller_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45355 aura::Window* root_window = GetRootWindow();
[email protected]d17642d2013-09-12 23:44:38356 // Change the target root window before closing child windows. If any child
[email protected]c98a4922013-09-05 20:01:42357 // being removed triggers a relayout of the shelf it will try to build a
[email protected]d17642d2013-09-12 23:44:38358 // window list adding windows from the target root window's containers which
[email protected]c98a4922013-09-05 20:01:42359 // may have already gone away.
[email protected]f5c9dbc2014-04-11 08:13:45360 if (Shell::GetTargetRootWindow() == root_window) {
[email protected]a825e8312014-05-05 22:05:01361 shell->set_target_root_window(
[email protected]f5c9dbc2014-04-11 08:13:45362 Shell::GetPrimaryRootWindow() == root_window
363 ? NULL
364 : Shell::GetPrimaryRootWindow());
[email protected]f634dd32012-07-23 22:49:07365 }
[email protected]c98a4922013-09-05 20:01:42366
367 CloseChildWindows();
[email protected]f5c9dbc2014-04-11 08:13:45368 GetRootWindowSettings(root_window)->controller = NULL;
[email protected]d90b8392012-06-13 09:34:56369 workspace_controller_.reset();
[email protected]6675e1c2012-09-11 09:15:45370 // Forget with the display ID so that display lookup
371 // ends up with invalid display.
[email protected]f5c9dbc2014-04-11 08:13:45372 GetRootWindowSettings(root_window)->display_id =
[email protected]f8e6aad2013-08-30 21:49:11373 gfx::Display::kInvalidDisplayID;
[email protected]8f5209c2014-05-22 20:36:11374 ash_host_->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28375
[email protected]956a6a42012-10-29 23:58:10376 system_background_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45377 aura::client::SetScreenPositionClient(root_window, NULL);
[email protected]d90b8392012-06-13 09:34:56378}
379
[email protected]c0ce80e2012-10-05 23:28:27380SystemModalContainerLayoutManager*
[email protected]8674b312012-10-12 19:02:44381RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
[email protected]a5c78802013-12-12 22:07:01382 aura::Window* modal_container = NULL;
[email protected]8674b312012-10-12 19:02:44383 if (window) {
[email protected]a5c78802013-12-12 22:07:01384 aura::Window* window_container = GetContainerForWindow(window);
385 if (window_container &&
386 window_container->id() >= kShellWindowId_LockScreenContainer) {
387 modal_container = GetContainer(kShellWindowId_LockSystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35388 } else {
[email protected]a5c78802013-12-12 22:07:01389 modal_container = GetContainer(kShellWindowId_SystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35390 }
[email protected]8674b312012-10-12 19:02:44391 } else {
[email protected]a44afbbd2013-07-24 21:49:35392 int modal_window_id = Shell::GetInstance()->session_state_delegate()
393 ->IsUserSessionBlocked() ? kShellWindowId_LockSystemModalContainer :
394 kShellWindowId_SystemModalContainer;
[email protected]a5c78802013-12-12 22:07:01395 modal_container = GetContainer(modal_window_id);
[email protected]8674b312012-10-12 19:02:44396 }
[email protected]a5c78802013-12-12 22:07:01397 return modal_container ? static_cast<SystemModalContainerLayoutManager*>(
398 modal_container->layout_manager()) : NULL;
[email protected]c0ce80e2012-10-05 23:28:27399}
400
[email protected]d90b8392012-06-13 09:34:56401aura::Window* RootWindowController::GetContainer(int container_id) {
[email protected]f5c9dbc2014-04-11 08:13:45402 return GetRootWindow()->GetChildById(container_id);
[email protected]d90b8392012-06-13 09:34:56403}
404
[email protected]d8a24952013-08-05 20:05:05405const aura::Window* RootWindowController::GetContainer(int container_id) const {
[email protected]f5c9dbc2014-04-11 08:13:45406 return ash_host_->AsWindowTreeHost()->window()->GetChildById(container_id);
[email protected]d8a24952013-08-05 20:05:05407}
408
[email protected]864b58552013-12-19 04:19:38409void RootWindowController::ShowShelf() {
410 if (!shelf_->shelf())
[email protected]e74aaf0a2012-10-12 18:42:28411 return;
[email protected]864b58552013-12-19 04:19:38412 shelf_->shelf()->SetVisible(true);
[email protected]478c6c32013-03-09 02:50:58413 shelf_->status_area_widget()->Show();
[email protected]e74aaf0a2012-10-12 18:42:28414}
415
[email protected]864b58552013-12-19 04:19:38416void RootWindowController::OnShelfCreated() {
[email protected]756bda12013-07-03 08:17:06417 if (panel_layout_manager_)
[email protected]864b58552013-12-19 04:19:38418 panel_layout_manager_->SetShelf(shelf_->shelf());
[email protected]7115bd32013-07-19 08:25:39419 if (docked_layout_manager_) {
[email protected]864b58552013-12-19 04:19:38420 docked_layout_manager_->SetShelf(shelf_->shelf());
[email protected]7115bd32013-07-19 08:25:39421 if (shelf_->shelf_layout_manager())
422 docked_layout_manager_->AddObserver(shelf_->shelf_layout_manager());
423 }
[email protected]b8642ec2014-04-17 05:20:39424
425 // Notify shell observers that the shelf has been created.
426 Shell::GetInstance()->OnShelfCreatedForRootWindow(GetRootWindow());
[email protected]756bda12013-07-03 08:17:06427}
428
[email protected]16059276d2012-10-22 18:59:50429void RootWindowController::UpdateAfterLoginStatusChange(
430 user::LoginStatus status) {
[email protected]cf6fea22013-08-07 14:24:01431 if (status != user::LOGGED_IN_NONE)
432 mouse_event_target_.reset();
[email protected]80549c152013-07-02 01:42:47433 if (shelf_->status_area_widget())
[email protected]478c6c32013-03-09 02:50:58434 shelf_->status_area_widget()->UpdateAfterLoginStatusChange(status);
[email protected]16059276d2012-10-22 18:59:50435}
436
[email protected]bca9a7e2012-11-10 06:25:49437void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
[email protected]252eb232013-08-14 22:09:27438#if defined(OS_CHROMEOS)
pgal.u-szegedd84534d32014-10-29 12:34:30439 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]bca9a7e2012-11-10 06:25:49440 switches::kAshAnimateFromBootSplashScreen) &&
441 boot_splash_screen_.get()) {
442 // Make the splash screen fade out so it doesn't obscure the desktop
443 // wallpaper's brightness/grayscale animation.
444 boot_splash_screen_->StartHideAnimation(
445 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
446 }
[email protected]252eb232013-08-14 22:09:27447#endif
[email protected]bca9a7e2012-11-10 06:25:49448}
449
[email protected]0bf61732013-07-02 04:35:10450void RootWindowController::OnWallpaperAnimationFinished(views::Widget* widget) {
451 // Make sure the wallpaper is visible.
[email protected]bca9a7e2012-11-10 06:25:49452 system_background_->SetColor(SK_ColorBLACK);
[email protected]252eb232013-08-14 22:09:27453#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:49454 boot_splash_screen_.reset();
[email protected]252eb232013-08-14 22:09:27455#endif
[email protected]0bf61732013-07-02 04:35:10456
457 Shell::GetInstance()->user_wallpaper_delegate()->
458 OnWallpaperAnimationFinished();
459 // Only removes old component when wallpaper animation finished. If we
460 // remove the old one before the new wallpaper is done fading in there will
461 // be a white flash during the animation.
462 if (animating_wallpaper_controller()) {
463 DesktopBackgroundWidgetController* controller =
464 animating_wallpaper_controller()->GetController(true);
465 // |desktop_widget_| should be the same animating widget we try to move
466 // to |kDesktopController|. Otherwise, we may close |desktop_widget_|
467 // before move it to |kDesktopController|.
468 DCHECK_EQ(controller->widget(), widget);
469 // Release the old controller and close its background widget.
470 SetWallpaperController(controller);
471 }
[email protected]697f04c2012-10-03 01:15:10472}
473
[email protected]d90b8392012-06-13 09:34:56474void RootWindowController::CloseChildWindows() {
[email protected]cf6fea22013-08-07 14:24:01475 mouse_event_target_.reset();
476
[email protected]2a57beb52014-06-09 20:02:26477 // Remove observer as deactivating keyboard causes |docked_layout_manager_|
478 // to fire notifications.
479 if (docked_layout_manager_ && shelf_ && shelf_->shelf_layout_manager())
480 docked_layout_manager_->RemoveObserver(shelf_->shelf_layout_manager());
481
[email protected]b6ba05d902013-10-04 21:38:45482 // Deactivate keyboard container before closing child windows and shutting
483 // down associated layout managers.
[email protected]a0b3fb882014-04-07 19:26:03484 DeactivateKeyboard(keyboard::KeyboardController::GetInstance());
[email protected]b6ba05d902013-10-04 21:38:45485
[email protected]79a87b7e2013-01-25 05:08:22486 // panel_layout_manager_ needs to be shut down before windows are destroyed.
487 if (panel_layout_manager_) {
488 panel_layout_manager_->Shutdown();
489 panel_layout_manager_ = NULL;
490 }
[email protected]7115bd32013-07-19 08:25:39491 // docked_layout_manager_ needs to be shut down before windows are destroyed.
492 if (docked_layout_manager_) {
[email protected]7115bd32013-07-19 08:25:39493 docked_layout_manager_->Shutdown();
494 docked_layout_manager_ = NULL;
495 }
[email protected]f5c9dbc2014-04-11 08:13:45496 aura::Window* root_window = GetRootWindow();
497 aura::client::SetDragDropClient(root_window, NULL);
[email protected]8b3e3d82013-08-20 14:36:30498
[email protected]478c6c32013-03-09 02:50:58499 // TODO(harrym): Remove when Status Area Widget is a child view.
[email protected]bb42c932013-10-31 06:52:06500 if (shelf_) {
501 shelf_->ShutdownStatusAreaWidget();
[email protected]478c6c32013-03-09 02:50:58502
[email protected]bb42c932013-10-31 06:52:06503 if (shelf_->shelf_layout_manager())
504 shelf_->shelf_layout_manager()->PrepareForShutdown();
505 }
[email protected]e74aaf0a2012-10-12 18:42:28506
[email protected]d90b8392012-06-13 09:34:56507 // Close background widget first as it depends on tooltip.
[email protected]0bf61732013-07-02 04:35:10508 wallpaper_controller_.reset();
509 animating_wallpaper_controller_.reset();
[email protected]b4ddc7a2012-08-07 04:17:32510
[email protected]d90b8392012-06-13 09:34:56511 workspace_controller_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45512 aura::client::SetTooltipClient(root_window, NULL);
[email protected]d90b8392012-06-13 09:34:56513
[email protected]0fbfa972013-10-02 19:23:33514 // Explicitly destroy top level windows. We do this as during part of
515 // destruction such windows may query the RootWindow for state.
oshimaf38efa92015-10-27 19:06:52516 aura::WindowTracker non_toplevel_windows;
517 non_toplevel_windows.Add(root_window);
518 while (!non_toplevel_windows.windows().empty()) {
519 const aura::Window* non_toplevel_window =
520 *non_toplevel_windows.windows().begin();
521 non_toplevel_windows.Remove(const_cast<aura::Window*>(non_toplevel_window));
[email protected]8b3e3d82013-08-20 14:36:30522 aura::WindowTracker toplevel_windows;
523 for (size_t i = 0; i < non_toplevel_window->children().size(); ++i) {
524 aura::Window* child = non_toplevel_window->children()[i];
[email protected]0fbfa972013-10-02 19:23:33525 if (!child->owned_by_parent())
526 continue;
[email protected]8b3e3d82013-08-20 14:36:30527 if (child->delegate())
528 toplevel_windows.Add(child);
529 else
oshimaf38efa92015-10-27 19:06:52530 non_toplevel_windows.Add(child);
[email protected]8b3e3d82013-08-20 14:36:30531 }
532 while (!toplevel_windows.windows().empty())
533 delete *toplevel_windows.windows().begin();
[email protected]d90b8392012-06-13 09:34:56534 }
[email protected]8b3e3d82013-08-20 14:36:30535 // And then remove the containers.
[email protected]f5c9dbc2014-04-11 08:13:45536 while (!root_window->children().empty()) {
537 aura::Window* window = root_window->children()[0];
[email protected]0fbfa972013-10-02 19:23:33538 if (window->owned_by_parent()) {
539 delete window;
540 } else {
[email protected]f5c9dbc2014-04-11 08:13:45541 root_window->RemoveChild(window);
[email protected]0fbfa972013-10-02 19:23:33542 }
543 }
[email protected]478c6c32013-03-09 02:50:58544
[email protected]bb42c932013-10-31 06:52:06545 shelf_.reset();
[email protected]d90b8392012-06-13 09:34:56546}
547
[email protected]bf9cdb362013-10-25 19:22:45548void RootWindowController::MoveWindowsTo(aura::Window* dst) {
[email protected]8039e06c2013-01-17 23:34:50549 // Forget the shelf early so that shelf don't update itself using wrong
550 // display info.
551 workspace_controller_->SetShelf(NULL);
[email protected]f5c9dbc2014-04-11 08:13:45552 ReparentAllWindows(GetRootWindow(), dst);
[email protected]f1853122012-06-27 16:21:26553}
554
[email protected]478c6c32013-03-09 02:50:58555ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
[email protected]80549c152013-07-02 01:42:47556 return shelf_->shelf_layout_manager();
[email protected]478c6c32013-03-09 02:50:58557}
558
[email protected]a0afeb12012-12-10 22:57:09559SystemTray* RootWindowController::GetSystemTray() {
560 // We assume in throughout the code that this will not return NULL. If code
561 // triggers this for valid reasons, it should test status_area_widget first.
[email protected]80549c152013-07-02 01:42:47562 CHECK(shelf_->status_area_widget());
[email protected]478c6c32013-03-09 02:50:58563 return shelf_->status_area_widget()->system_tray();
[email protected]a0afeb12012-12-10 22:57:09564}
565
[email protected]940fb1c2013-06-18 16:54:28566void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
567 ui::MenuSourceType source_type) {
[email protected]431552c2012-10-23 00:38:33568 DCHECK(Shell::GetInstance()->delegate());
569 scoped_ptr<ui::MenuModel> menu_model(
[email protected]f5c9dbc2014-04-11 08:13:45570 Shell::GetInstance()->delegate()->CreateContextMenu(
571 GetRootWindow(), NULL, NULL));
[email protected]7f7f65c2013-04-17 16:47:13572 if (!menu_model)
[email protected]8e837ec2013-01-31 01:48:33573 return;
[email protected]431552c2012-10-23 00:38:33574
[email protected]6175fc42013-04-05 05:58:58575 // Background controller may not be set yet if user clicked on status are
576 // before initial animation completion. See crbug.com/222218
[email protected]0bf61732013-07-02 04:35:10577 if (!wallpaper_controller_.get())
[email protected]431552c2012-10-23 00:38:33578 return;
579
[email protected]0a37a5d2014-07-15 00:42:23580 views::MenuRunner menu_runner(menu_model.get(),
581 views::MenuRunner::CONTEXT_MENU);
[email protected]0bf61732013-07-02 04:35:10582 if (menu_runner.RunMenuAt(wallpaper_controller_->widget(),
[email protected]fd6c0a62014-05-01 07:50:35583 NULL,
584 gfx::Rect(location_in_screen, gfx::Size()),
585 views::MENU_ANCHOR_TOPLEFT,
[email protected]0a37a5d2014-07-15 00:42:23586 source_type) == views::MenuRunner::MENU_DELETED) {
[email protected]6175fc42013-04-05 05:58:58587 return;
588 }
589
[email protected]431552c2012-10-23 00:38:33590 Shell::GetInstance()->UpdateShelfVisibility();
591}
592
[email protected]e74aaf0a2012-10-12 18:42:28593void RootWindowController::UpdateShelfVisibility() {
[email protected]478c6c32013-03-09 02:50:58594 shelf_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]e74aaf0a2012-10-12 18:42:28595}
596
varkhad99fa94f2015-06-29 22:35:46597aura::Window* RootWindowController::GetWindowForFullscreenMode() {
598 aura::Window* topmost_window = NULL;
599 aura::Window* active_window = wm::GetActiveWindow();
[email protected]f5c9dbc2014-04-11 08:13:45600 if (active_window && active_window->GetRootWindow() == GetRootWindow() &&
[email protected]2c5db9e2014-02-27 13:58:14601 IsSwitchableContainer(active_window->parent())) {
602 // Use the active window when it is on the current root window to determine
603 // the fullscreen state to allow temporarily using a panel or docked window
604 // (which are always above the default container) while a fullscreen
605 // window is open. We only use the active window when in a switchable
606 // container as the launcher should not exit fullscreen mode.
607 topmost_window = active_window;
608 } else {
609 // Otherwise, use the topmost window on the root window's default container
610 // when there is no active window on this root window.
611 const aura::Window::Windows& windows =
612 GetContainer(kShellWindowId_DefaultContainer)->children();
613 for (aura::Window::Windows::const_reverse_iterator iter = windows.rbegin();
614 iter != windows.rend(); ++iter) {
bruthigb7056f62015-06-04 21:04:53615 if (wm::IsWindowUserPositionable(*iter) &&
[email protected]2c5db9e2014-02-27 13:58:14616 (*iter)->layer()->GetTargetVisibility()) {
617 topmost_window = *iter;
618 break;
619 }
[email protected]2c9171d22013-12-10 21:55:10620 }
621 }
622 while (topmost_window) {
623 if (wm::GetWindowState(topmost_window)->IsFullscreen())
624 return topmost_window;
[email protected]e319c7e2014-03-14 19:56:14625 topmost_window = ::wm::GetTransientParent(topmost_window);
[email protected]2ee2f5d2013-01-10 23:37:16626 }
[email protected]700849f2013-04-30 17:49:20627 return NULL;
[email protected]2ee2f5d2013-01-10 23:37:16628}
629
[email protected]b6ba05d902013-10-04 21:38:45630void RootWindowController::ActivateKeyboard(
631 keyboard::KeyboardController* keyboard_controller) {
632 if (!keyboard::IsKeyboardEnabled() ||
633 GetContainer(kShellWindowId_VirtualKeyboardContainer)) {
634 return;
635 }
636 DCHECK(keyboard_controller);
bshe9858b4a2014-09-16 20:46:38637 keyboard_controller->AddObserver(shelf()->shelf_layout_manager());
638 keyboard_controller->AddObserver(panel_layout_manager_);
639 keyboard_controller->AddObserver(docked_layout_manager_);
640 keyboard_controller->AddObserver(workspace_controller_->layout_manager());
rsadam7bd510bb2014-12-09 20:10:56641 keyboard_controller->AddObserver(
642 always_on_top_controller_->GetLayoutManager());
bshe9858b4a2014-09-16 20:46:38643 Shell::GetInstance()->delegate()->VirtualKeyboardActivated(true);
bshec3875422014-09-29 13:21:30644 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]b2da9b602014-03-05 18:39:52645 DCHECK(parent);
[email protected]b6ba05d902013-10-04 21:38:45646 aura::Window* keyboard_container =
647 keyboard_controller->GetContainerWindow();
648 keyboard_container->set_id(kShellWindowId_VirtualKeyboardContainer);
649 parent->AddChild(keyboard_container);
[email protected]b6ba05d902013-10-04 21:38:45650}
[email protected]86459e2c2013-04-10 13:39:24651
[email protected]b6ba05d902013-10-04 21:38:45652void RootWindowController::DeactivateKeyboard(
653 keyboard::KeyboardController* keyboard_controller) {
[email protected]e1b299b2014-01-29 23:53:41654 if (!keyboard_controller ||
655 !keyboard_controller->keyboard_container_initialized()) {
[email protected]b6ba05d902013-10-04 21:38:45656 return;
[email protected]e1b299b2014-01-29 23:53:41657 }
[email protected]b6ba05d902013-10-04 21:38:45658 aura::Window* keyboard_container =
659 keyboard_controller->GetContainerWindow();
[email protected]f5c9dbc2014-04-11 08:13:45660 if (keyboard_container->GetRootWindow() == GetRootWindow()) {
bshec3875422014-09-29 13:21:30661 aura::Window* parent =
662 GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]b2da9b602014-03-05 18:39:52663 DCHECK(parent);
664 parent->RemoveChild(keyboard_container);
bshe9858b4a2014-09-16 20:46:38665 // Virtual keyboard may be deactivated while still showing, notify all
666 // observers that keyboard bounds changed to 0 before remove them.
667 keyboard_controller->NotifyKeyboardBoundsChanging(gfx::Rect());
668 keyboard_controller->RemoveObserver(shelf()->shelf_layout_manager());
669 keyboard_controller->RemoveObserver(panel_layout_manager_);
670 keyboard_controller->RemoveObserver(docked_layout_manager_);
671 keyboard_controller->RemoveObserver(
672 workspace_controller_->layout_manager());
rsadam7bd510bb2014-12-09 20:10:56673 keyboard_controller->RemoveObserver(
674 always_on_top_controller_->GetLayoutManager());
bshe9858b4a2014-09-16 20:46:38675 Shell::GetInstance()->delegate()->VirtualKeyboardActivated(false);
[email protected]86459e2c2013-04-10 13:39:24676 }
677}
678
[email protected]602022b2014-03-31 17:07:31679bool RootWindowController::IsVirtualKeyboardWindow(aura::Window* window) {
bshec3875422014-09-29 13:21:30680 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]602022b2014-03-31 17:07:31681 return parent ? parent->Contains(window) : false;
682}
683
[email protected]a4cd6d32012-09-12 03:42:13684////////////////////////////////////////////////////////////////////////////////
685// RootWindowController, private:
686
[email protected]f5c9dbc2014-04-11 08:13:45687RootWindowController::RootWindowController(AshWindowTreeHost* ash_host)
688 : ash_host_(ash_host),
[email protected]a273d33a2013-10-17 12:41:21689 root_window_layout_(NULL),
690 docked_layout_manager_(NULL),
691 panel_layout_manager_(NULL),
692 touch_hud_debug_(NULL),
693 touch_hud_projection_(NULL) {
[email protected]f5c9dbc2014-04-11 08:13:45694 aura::Window* root_window = GetRootWindow();
695 GetRootWindowSettings(root_window)->controller = this;
[email protected]a273d33a2013-10-17 12:41:21696
697 stacking_controller_.reset(new StackingController);
[email protected]f5c9dbc2014-04-11 08:13:45698 aura::client::SetWindowTreeClient(root_window, stacking_controller_.get());
699 capture_client_.reset(new ::wm::ScopedCaptureClient(root_window));
[email protected]a273d33a2013-10-17 12:41:21700}
701
[email protected]608de6c2013-10-29 00:14:28702void RootWindowController::Init(RootWindowType root_window_type,
703 bool first_run_after_boot) {
[email protected]f5c9dbc2014-04-11 08:13:45704 aura::Window* root_window = GetRootWindow();
[email protected]51f438112013-11-18 19:32:50705 Shell* shell = Shell::GetInstance();
[email protected]f5c9dbc2014-04-11 08:13:45706 shell->InitRootWindow(root_window);
[email protected]a273d33a2013-10-17 12:41:21707
[email protected]f5c9dbc2014-04-11 08:13:45708 ash_host_->AsWindowTreeHost()->SetCursor(ui::kCursorPointer);
709 CreateContainersInRootWindow(root_window);
[email protected]608de6c2013-10-29 00:14:28710
[email protected]a273d33a2013-10-17 12:41:21711 CreateSystemBackground(first_run_after_boot);
712
713 InitLayoutManagers();
714 InitTouchHuds();
715
716 if (Shell::GetPrimaryRootWindowController()->
717 GetSystemModalLayoutManager(NULL)->has_modal_background()) {
718 GetSystemModalLayoutManager(NULL)->CreateModalBackground();
719 }
720
[email protected]a273d33a2013-10-17 12:41:21721 shell->AddShellObserver(this);
722
[email protected]608de6c2013-10-29 00:14:28723 if (root_window_type == PRIMARY) {
[email protected]a3565792013-10-18 12:52:37724 root_window_layout()->OnWindowResized();
bshe9858b4a2014-09-16 20:46:38725 shell->InitKeyboard();
[email protected]a273d33a2013-10-17 12:41:21726 } else {
727 root_window_layout()->OnWindowResized();
[email protected]f5c9dbc2014-04-11 08:13:45728 ash_host_->AsWindowTreeHost()->Show();
[email protected]a273d33a2013-10-17 12:41:21729
[email protected]864b58552013-12-19 04:19:38730 // Create a shelf if a user is already logged in.
[email protected]a273d33a2013-10-17 12:41:21731 if (shell->session_state_delegate()->NumberOfLoggedInUsers())
[email protected]864b58552013-12-19 04:19:38732 shelf()->CreateShelf();
[email protected]0e3e7cb2014-04-12 05:18:25733
734 // Notify shell observers about new root window.
735 shell->OnRootWindowAdded(root_window);
[email protected]a273d33a2013-10-17 12:41:21736 }
[email protected]a825e8312014-05-05 22:05:01737
738#if defined(OS_CHROMEOS)
pgal.u-szegedd84534d32014-10-29 12:34:30739 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]2e0b2352014-07-28 13:28:28740 switches::kAshDisableTouchExplorationMode)) {
[email protected]7d487592014-07-24 03:54:50741 touch_exploration_manager_.reset(new AshTouchExplorationManager(this));
[email protected]a825e8312014-05-05 22:05:01742 }
743#endif
[email protected]a273d33a2013-10-17 12:41:21744}
745
[email protected]756bda12013-07-03 08:17:06746void RootWindowController::InitLayoutManagers() {
[email protected]f5c9dbc2014-04-11 08:13:45747 aura::Window* root_window = GetRootWindow();
748 root_window_layout_ = new RootWindowLayoutManager(root_window);
749 root_window->SetLayoutManager(root_window_layout_);
[email protected]756bda12013-07-03 08:17:06750
751 aura::Window* default_container =
752 GetContainer(kShellWindowId_DefaultContainer);
753 // Workspace manager has its own layout managers.
754 workspace_controller_.reset(
755 new WorkspaceController(default_container));
756
757 aura::Window* always_on_top_container =
758 GetContainer(kShellWindowId_AlwaysOnTopContainer);
rsadam7bd510bb2014-12-09 20:10:56759 always_on_top_controller_.reset(
760 new AlwaysOnTopController(always_on_top_container));
[email protected]756bda12013-07-03 08:17:06761
762 DCHECK(!shelf_.get());
[email protected]093b8d642014-04-03 20:59:28763 aura::Window* shelf_container = GetContainer(kShellWindowId_ShelfContainer);
[email protected]756bda12013-07-03 08:17:06764 // TODO(harrym): Remove when status area is view.
[email protected]093b8d642014-04-03 20:59:28765 aura::Window* status_container = GetContainer(kShellWindowId_StatusContainer);
[email protected]756bda12013-07-03 08:17:06766 shelf_.reset(new ShelfWidget(
767 shelf_container, status_container, workspace_controller()));
768
[email protected]cf6fea22013-08-07 14:24:01769 if (!Shell::GetInstance()->session_state_delegate()->
770 IsActiveUserSessionStarted()) {
771 // This window exists only to be a event target on login screen.
772 // It does not have to handle events, nor be visible.
773 mouse_event_target_.reset(new aura::Window(new EmptyWindowDelegate));
danakjb161836d2015-04-03 05:14:18774 mouse_event_target_->Init(ui::LAYER_NOT_DRAWN);
[email protected]cf6fea22013-08-07 14:24:01775
776 aura::Window* lock_background_container =
[email protected]093b8d642014-04-03 20:59:28777 GetContainer(kShellWindowId_LockScreenBackgroundContainer);
[email protected]cf6fea22013-08-07 14:24:01778 lock_background_container->AddChild(mouse_event_target_.get());
779 mouse_event_target_->Show();
780 }
781
[email protected]756bda12013-07-03 08:17:06782 // Create Docked windows layout manager
[email protected]093b8d642014-04-03 20:59:28783 aura::Window* docked_container = GetContainer(kShellWindowId_DockedContainer);
[email protected]756bda12013-07-03 08:17:06784 docked_layout_manager_ =
[email protected]093b8d642014-04-03 20:59:28785 new DockedWindowLayoutManager(docked_container, workspace_controller());
[email protected]756bda12013-07-03 08:17:06786 docked_container->SetLayoutManager(docked_layout_manager_);
787
[email protected]1ca79d42014-07-18 16:26:10788 // Installs SnapLayoutManager to containers who set the
789 // |kSnapsChildrenToPhysicalPixelBoundary| property.
790 wm::InstallSnapLayoutManagerToContainers(root_window);
791
[email protected]756bda12013-07-03 08:17:06792 // Create Panel layout manager
[email protected]093b8d642014-04-03 20:59:28793 aura::Window* panel_container = GetContainer(kShellWindowId_PanelContainer);
794 panel_layout_manager_ = new PanelLayoutManager(panel_container);
[email protected]756bda12013-07-03 08:17:06795 panel_container->SetLayoutManager(panel_layout_manager_);
[email protected]3537d472014-01-15 05:45:31796 panel_container_handler_.reset(new PanelWindowEventHandler);
797 panel_container->AddPreTargetHandler(panel_container_handler_.get());
[email protected]b8642ec2014-04-17 05:20:39798
799 // Install an AttachedPanelWindowTargeter on the panel container to make it
800 // easier to correctly target shelf buttons with touch.
801 gfx::Insets mouse_extend(-kResizeOutsideBoundsSize,
802 -kResizeOutsideBoundsSize,
803 -kResizeOutsideBoundsSize,
804 -kResizeOutsideBoundsSize);
805 gfx::Insets touch_extend = mouse_extend.Scale(
806 kResizeOutsideBoundsScaleForTouch);
807 panel_container->SetEventTargeter(scoped_ptr<ui::EventTargeter>(
808 new AttachedPanelWindowTargeter(panel_container,
809 mouse_extend,
810 touch_extend,
811 panel_layout_manager_)));
[email protected]756bda12013-07-03 08:17:06812}
813
814void RootWindowController::InitTouchHuds() {
pgal.u-szegedd84534d32014-10-29 12:34:30815 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
[email protected]756bda12013-07-03 08:17:06816 if (command_line->HasSwitch(switches::kAshTouchHud))
[email protected]f5c9dbc2014-04-11 08:13:45817 set_touch_hud_debug(new TouchHudDebug(GetRootWindow()));
[email protected]756bda12013-07-03 08:17:06818 if (Shell::GetInstance()->is_touch_hud_projection_enabled())
819 EnableTouchHudProjection();
820}
821
822void RootWindowController::CreateSystemBackground(
823 bool is_first_run_after_boot) {
824 SkColor color = SK_ColorBLACK;
825#if defined(OS_CHROMEOS)
826 if (is_first_run_after_boot)
827 color = kChromeOsBootColor;
828#endif
829 system_background_.reset(
[email protected]f5c9dbc2014-04-11 08:13:45830 new SystemBackgroundController(GetRootWindow(), color));
[email protected]756bda12013-07-03 08:17:06831
832#if defined(OS_CHROMEOS)
833 // Make a copy of the system's boot splash screen so we can composite it
834 // onscreen until the desktop background is ready.
835 if (is_first_run_after_boot &&
pgal.u-szegedd84534d32014-10-29 12:34:30836 (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]756bda12013-07-03 08:17:06837 switches::kAshCopyHostBackgroundAtBoot) ||
pgal.u-szegedd84534d32014-10-29 12:34:30838 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]756bda12013-07-03 08:17:06839 switches::kAshAnimateFromBootSplashScreen)))
[email protected]f5c9dbc2014-04-11 08:13:45840 boot_splash_screen_.reset(new BootSplashScreen(GetHost()));
[email protected]756bda12013-07-03 08:17:06841#endif
842}
843
[email protected]a4cd6d32012-09-12 03:42:13844void RootWindowController::CreateContainersInRootWindow(
[email protected]41baaed2013-11-09 04:18:26845 aura::Window* root_window) {
[email protected]a4cd6d32012-09-12 03:42:13846 // These containers are just used by PowerButtonController to animate groups
847 // of containers simultaneously without messing up the current transformations
848 // on those containers. These are direct children of the root window; all of
849 // the other containers are their children.
[email protected]e6e41d2f2012-10-29 19:22:19850
851 // The desktop background container is not part of the lock animation, so it
852 // is not included in those animate groups.
[email protected]a4cd6d32012-09-12 03:42:13853 // When screen is locked desktop background is moved to lock screen background
854 // container (moved back on unlock). We want to make sure that there's an
855 // opaque layer occluding the non-lock-screen layers.
[email protected]e6e41d2f2012-10-29 19:22:19856 aura::Window* desktop_background_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27857 kShellWindowId_DesktopBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13858 "DesktopBackgroundContainer",
859 root_window);
[email protected]e319c7e2014-03-14 19:56:14860 ::wm::SetChildWindowVisibilityChangesAnimated(desktop_background_container);
[email protected]a4cd6d32012-09-12 03:42:13861
862 aura::Window* non_lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27863 kShellWindowId_NonLockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13864 "NonLockScreenContainersContainer",
865 root_window);
oshimaf52e1be2015-05-06 21:29:34866 // Clip all windows inside this container, as half pixel of the window's
867 // texture may become visible when the screen is scaled. crbug.com/368591.
868 non_lock_screen_containers->layer()->SetMasksToBounds(true);
[email protected]a4cd6d32012-09-12 03:42:13869
870 aura::Window* lock_background_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27871 kShellWindowId_LockScreenBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13872 "LockScreenBackgroundContainer",
873 root_window);
[email protected]e319c7e2014-03-14 19:56:14874 ::wm::SetChildWindowVisibilityChangesAnimated(lock_background_containers);
[email protected]a4cd6d32012-09-12 03:42:13875
876 aura::Window* lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27877 kShellWindowId_LockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13878 "LockScreenContainersContainer",
879 root_window);
880 aura::Window* lock_screen_related_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27881 kShellWindowId_LockScreenRelatedContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13882 "LockScreenRelatedContainersContainer",
883 root_window);
884
[email protected]c0ce80e2012-10-05 23:28:27885 CreateContainer(kShellWindowId_UnparentedControlContainer,
[email protected]a4cd6d32012-09-12 03:42:13886 "UnparentedControlContainer",
887 non_lock_screen_containers);
888
889 aura::Window* default_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27890 kShellWindowId_DefaultContainer,
[email protected]a4cd6d32012-09-12 03:42:13891 "DefaultContainer",
892 non_lock_screen_containers);
[email protected]e319c7e2014-03-14 19:56:14893 ::wm::SetChildWindowVisibilityChangesAnimated(default_container);
[email protected]1ca79d42014-07-18 16:26:10894 wm::SetSnapsChildrenToPhysicalPixelBoundary(default_container);
[email protected]a4cd6d32012-09-12 03:42:13895 SetUsesScreenCoordinates(default_container);
[email protected]c5be8d672014-01-07 13:33:41896 SetUsesEasyResizeTargeter(default_container);
[email protected]a4cd6d32012-09-12 03:42:13897
898 aura::Window* always_on_top_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27899 kShellWindowId_AlwaysOnTopContainer,
[email protected]a4cd6d32012-09-12 03:42:13900 "AlwaysOnTopContainer",
901 non_lock_screen_containers);
[email protected]e319c7e2014-03-14 19:56:14902 ::wm::SetChildWindowVisibilityChangesAnimated(always_on_top_container);
[email protected]1ca79d42014-07-18 16:26:10903 wm::SetSnapsChildrenToPhysicalPixelBoundary(always_on_top_container);
[email protected]a4cd6d32012-09-12 03:42:13904 SetUsesScreenCoordinates(always_on_top_container);
905
[email protected]beb4e5c2013-06-18 15:37:07906 aura::Window* docked_container = CreateContainer(
907 kShellWindowId_DockedContainer,
908 "DockedContainer",
909 non_lock_screen_containers);
[email protected]e319c7e2014-03-14 19:56:14910 ::wm::SetChildWindowVisibilityChangesAnimated(docked_container);
[email protected]1ca79d42014-07-18 16:26:10911 wm::SetSnapsChildrenToPhysicalPixelBoundary(docked_container);
[email protected]beb4e5c2013-06-18 15:37:07912 SetUsesScreenCoordinates(docked_container);
[email protected]1ff0c492014-01-21 20:20:44913 SetUsesEasyResizeTargeter(docked_container);
[email protected]beb4e5c2013-06-18 15:37:07914
[email protected]3f13cf12013-07-12 05:13:59915 aura::Window* shelf_container =
[email protected]478c6c32013-03-09 02:50:58916 CreateContainer(kShellWindowId_ShelfContainer,
[email protected]3f13cf12013-07-12 05:13:59917 "ShelfContainer",
[email protected]a4cd6d32012-09-12 03:42:13918 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10919 wm::SetSnapsChildrenToPhysicalPixelBoundary(shelf_container);
[email protected]3f13cf12013-07-12 05:13:59920 SetUsesScreenCoordinates(shelf_container);
921 DescendantShouldStayInSameRootWindow(shelf_container);
[email protected]a4cd6d32012-09-12 03:42:13922
[email protected]f2026eb2013-10-22 14:28:56923 aura::Window* panel_container = CreateContainer(
924 kShellWindowId_PanelContainer,
925 "PanelContainer",
926 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10927 wm::SetSnapsChildrenToPhysicalPixelBoundary(panel_container);
[email protected]f2026eb2013-10-22 14:28:56928 SetUsesScreenCoordinates(panel_container);
929
930 aura::Window* shelf_bubble_container =
931 CreateContainer(kShellWindowId_ShelfBubbleContainer,
932 "ShelfBubbleContainer",
933 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10934 wm::SetSnapsChildrenToPhysicalPixelBoundary(shelf_bubble_container);
[email protected]f2026eb2013-10-22 14:28:56935 SetUsesScreenCoordinates(shelf_bubble_container);
936 DescendantShouldStayInSameRootWindow(shelf_bubble_container);
937
[email protected]dc851a4e52012-10-03 00:05:55938 aura::Window* app_list_container =
[email protected]c0ce80e2012-10-05 23:28:27939 CreateContainer(kShellWindowId_AppListContainer,
[email protected]dc851a4e52012-10-03 00:05:55940 "AppListContainer",
941 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10942 wm::SetSnapsChildrenToPhysicalPixelBoundary(app_list_container);
[email protected]dc851a4e52012-10-03 00:05:55943 SetUsesScreenCoordinates(app_list_container);
[email protected]a4cd6d32012-09-12 03:42:13944
945 aura::Window* modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27946 kShellWindowId_SystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13947 "SystemModalContainer",
948 non_lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10949 wm::SetSnapsChildrenToPhysicalPixelBoundary(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13950 modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27951 new SystemModalContainerLayoutManager(modal_container));
[email protected]e319c7e2014-03-14 19:56:14952 ::wm::SetChildWindowVisibilityChangesAnimated(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13953 SetUsesScreenCoordinates(modal_container);
[email protected]c5be8d672014-01-07 13:33:41954 SetUsesEasyResizeTargeter(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13955
[email protected]a4cd6d32012-09-12 03:42:13956 // TODO(beng): Figure out if we can make this use
957 // SystemModalContainerEventFilter instead of stops_event_propagation.
958 aura::Window* lock_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27959 kShellWindowId_LockScreenContainer,
[email protected]a4cd6d32012-09-12 03:42:13960 "LockScreenContainer",
961 lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10962 wm::SetSnapsChildrenToPhysicalPixelBoundary(lock_container);
oshima96f6a502015-05-02 08:43:32963 lock_container->SetLayoutManager(new LockLayoutManager(lock_container));
[email protected]a4cd6d32012-09-12 03:42:13964 SetUsesScreenCoordinates(lock_container);
965 // TODO(beng): stopsevents
966
967 aura::Window* lock_modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27968 kShellWindowId_LockSystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13969 "LockSystemModalContainer",
970 lock_screen_containers);
[email protected]1ca79d42014-07-18 16:26:10971 wm::SetSnapsChildrenToPhysicalPixelBoundary(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13972 lock_modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27973 new SystemModalContainerLayoutManager(lock_modal_container));
[email protected]e319c7e2014-03-14 19:56:14974 ::wm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13975 SetUsesScreenCoordinates(lock_modal_container);
[email protected]c5be8d672014-01-07 13:33:41976 SetUsesEasyResizeTargeter(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13977
978 aura::Window* status_container =
[email protected]c0ce80e2012-10-05 23:28:27979 CreateContainer(kShellWindowId_StatusContainer,
[email protected]a4cd6d32012-09-12 03:42:13980 "StatusContainer",
981 lock_screen_related_containers);
[email protected]1ca79d42014-07-18 16:26:10982 wm::SetSnapsChildrenToPhysicalPixelBoundary(status_container);
[email protected]a4cd6d32012-09-12 03:42:13983 SetUsesScreenCoordinates(status_container);
[email protected]e887c6c2013-07-08 19:35:53984 DescendantShouldStayInSameRootWindow(status_container);
[email protected]a4cd6d32012-09-12 03:42:13985
986 aura::Window* settings_bubble_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27987 kShellWindowId_SettingBubbleContainer,
[email protected]a4cd6d32012-09-12 03:42:13988 "SettingBubbleContainer",
989 lock_screen_related_containers);
[email protected]e319c7e2014-03-14 19:56:14990 ::wm::SetChildWindowVisibilityChangesAnimated(settings_bubble_container);
[email protected]1ca79d42014-07-18 16:26:10991 wm::SetSnapsChildrenToPhysicalPixelBoundary(settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13992 SetUsesScreenCoordinates(settings_bubble_container);
[email protected]e887c6c2013-07-08 19:35:53993 DescendantShouldStayInSameRootWindow(settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13994
kevers23f3987d2014-09-17 13:50:12995 aura::Window* virtual_keyboard_parent_container =
bshec3875422014-09-29 13:21:30996 CreateContainer(kShellWindowId_ImeWindowParentContainer,
kevers23f3987d2014-09-17 13:50:12997 "VirtualKeyboardParentContainer",
998 lock_screen_related_containers);
999 wm::SetSnapsChildrenToPhysicalPixelBoundary(
1000 virtual_keyboard_parent_container);
1001 SetUsesScreenCoordinates(virtual_keyboard_parent_container);
1002
[email protected]a4cd6d32012-09-12 03:42:131003 aura::Window* menu_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:271004 kShellWindowId_MenuContainer,
[email protected]a4cd6d32012-09-12 03:42:131005 "MenuContainer",
1006 lock_screen_related_containers);
[email protected]e319c7e2014-03-14 19:56:141007 ::wm::SetChildWindowVisibilityChangesAnimated(menu_container);
[email protected]1ca79d42014-07-18 16:26:101008 wm::SetSnapsChildrenToPhysicalPixelBoundary(menu_container);
[email protected]a4cd6d32012-09-12 03:42:131009 SetUsesScreenCoordinates(menu_container);
1010
1011 aura::Window* drag_drop_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:271012 kShellWindowId_DragImageAndTooltipContainer,
[email protected]a4cd6d32012-09-12 03:42:131013 "DragImageAndTooltipContainer",
1014 lock_screen_related_containers);
[email protected]e319c7e2014-03-14 19:56:141015 ::wm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
[email protected]1ca79d42014-07-18 16:26:101016 wm::SetSnapsChildrenToPhysicalPixelBoundary(drag_drop_container);
[email protected]a4cd6d32012-09-12 03:42:131017 SetUsesScreenCoordinates(drag_drop_container);
1018
1019 aura::Window* overlay_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:271020 kShellWindowId_OverlayContainer,
[email protected]a4cd6d32012-09-12 03:42:131021 "OverlayContainer",
1022 lock_screen_related_containers);
[email protected]1ca79d42014-07-18 16:26:101023 wm::SetSnapsChildrenToPhysicalPixelBoundary(overlay_container);
[email protected]a4cd6d32012-09-12 03:42:131024 SetUsesScreenCoordinates(overlay_container);
[email protected]a07615f2012-10-24 08:23:081025
[email protected]b2da9b602014-03-05 18:39:521026#if defined(OS_CHROMEOS)
1027 aura::Window* mouse_cursor_container = CreateContainer(
1028 kShellWindowId_MouseCursorContainer,
1029 "MouseCursorContainer",
1030 root_window);
1031 SetUsesScreenCoordinates(mouse_cursor_container);
1032#endif
1033
[email protected]a07615f2012-10-24 08:23:081034 CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
[email protected]b2da9b602014-03-05 18:39:521035 "PowerButtonAnimationContainer", root_window);
[email protected]a4cd6d32012-09-12 03:42:131036}
1037
[email protected]d141b922013-07-09 08:13:171038void RootWindowController::EnableTouchHudProjection() {
1039 if (touch_hud_projection_)
1040 return;
[email protected]f5c9dbc2014-04-11 08:13:451041 set_touch_hud_projection(new TouchHudProjection(GetRootWindow()));
[email protected]d141b922013-07-09 08:13:171042}
1043
1044void RootWindowController::DisableTouchHudProjection() {
1045 if (!touch_hud_projection_)
1046 return;
1047 touch_hud_projection_->Remove();
1048}
1049
1050void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
1051 shelf_->shelf_layout_manager()->UpdateVisibilityState();
1052}
1053
1054void RootWindowController::OnTouchHudProjectionToggled(bool enabled) {
1055 if (enabled)
1056 EnableTouchHudProjection();
1057 else
1058 DisableTouchHudProjection();
1059}
1060
[email protected]6b2d4a0b2013-09-06 06:29:541061RootWindowController* GetRootWindowController(
[email protected]bf9cdb362013-10-25 19:22:451062 const aura::Window* root_window) {
[email protected]6b2d4a0b2013-09-06 06:29:541063 return root_window ? GetRootWindowSettings(root_window)->controller : NULL;
1064}
1065
[email protected]d90b8392012-06-13 09:34:561066} // namespace ash