blob: f7332c34a7501304580ce2cac17360449539fa55 [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
sky0702b272016-06-03 22:10:4110#include "ash/aura/aura_layout_manager_adapter.h"
11#include "ash/aura/wm_shelf_aura.h"
12#include "ash/aura/wm_window_aura.h"
jamescooke044e1c2016-06-13 20:56:1813#include "ash/common/ash_constants.h"
mswd9b1b342016-06-17 20:19:5714#include "ash/common/ash_switches.h"
jamescook26f32092016-06-17 04:26:5215#include "ash/common/focus_cycler.h"
mswb2416052016-06-24 21:23:4516#include "ash/common/login_status.h"
skyc096d9f2016-06-02 13:46:2617#include "ash/common/root_window_controller_common.h"
jamescook2b624c5a2016-06-08 01:34:0218#include "ash/common/session/session_state_delegate.h"
jamescook1b474d6a2016-06-04 05:56:0019#include "ash/common/shelf/shelf_types.h"
skyc096d9f2016-06-02 13:46:2620#include "ash/common/shell_window_ids.h"
jamescook2a4d1eb2016-06-09 20:10:0721#include "ash/common/system/tray/system_tray_delegate.h"
skyd6063772016-06-01 17:52:2122#include "ash/common/wm/always_on_top_controller.h"
23#include "ash/common/wm/container_finder.h"
24#include "ash/common/wm/dock/docked_window_layout_manager.h"
25#include "ash/common/wm/fullscreen_window_finder.h"
26#include "ash/common/wm/panels/panel_layout_manager.h"
skyc096d9f2016-06-02 13:46:2627#include "ash/common/wm/root_window_layout_manager.h"
skyd6063772016-06-01 17:52:2128#include "ash/common/wm/switchable_windows.h"
29#include "ash/common/wm/window_state.h"
skyd6063772016-06-01 17:52:2130#include "ash/common/wm/workspace/workspace_layout_manager.h"
31#include "ash/common/wm/workspace/workspace_layout_manager_delegate.h"
sky0702b272016-06-03 22:10:4132#include "ash/common/wm_shell.h"
33#include "ash/common/wm_window.h"
[email protected]a273d33a2013-10-17 12:41:2134#include "ash/desktop_background/desktop_background_controller.h"
[email protected]b4ddc7a2012-08-07 04:17:3235#include "ash/desktop_background/desktop_background_widget_controller.h"
[email protected]0bf61732013-07-02 04:35:1036#include "ash/desktop_background/user_wallpaper_delegate.h"
[email protected]6bdf7952012-11-14 10:10:5837#include "ash/display/display_manager.h"
[email protected]a273d33a2013-10-17 12:41:2138#include "ash/high_contrast/high_contrast_controller.h"
[email protected]f5c9dbc2014-04-11 08:13:4539#include "ash/host/ash_window_tree_host.h"
[email protected]f8e6aad2013-08-30 21:49:1140#include "ash/root_window_settings.h"
[email protected]478c6c32013-03-09 02:50:5841#include "ash/shelf/shelf_layout_manager.h"
[email protected]478c6c32013-03-09 02:50:5842#include "ash/shelf/shelf_widget.h"
[email protected]d90b8392012-06-13 09:34:5643#include "ash/shell.h"
[email protected]e74aaf0a2012-10-12 18:42:2844#include "ash/shell_delegate.h"
[email protected]d90b8392012-06-13 09:34:5645#include "ash/shell_factory.h"
[email protected]e74aaf0a2012-10-12 18:42:2846#include "ash/system/status_area_widget.h"
[email protected]a825e8312014-05-05 22:05:0147#include "ash/system/tray/system_tray_notifier.h"
[email protected]2b8a9bb2013-07-01 22:43:4048#include "ash/touch/touch_hud_debug.h"
49#include "ash/touch/touch_hud_projection.h"
[email protected]80549c152013-07-02 01:42:4750#include "ash/touch/touch_observer_hud.h"
[email protected]68d51332014-06-06 13:51:1351#include "ash/wm/lock_layout_manager.h"
[email protected]b8642ec2014-04-17 05:20:3952#include "ash/wm/panels/attached_panel_window_targeter.h"
[email protected]100659412013-06-21 22:59:5553#include "ash/wm/panels/panel_window_event_handler.h"
[email protected]2a2caa02013-01-22 20:50:3654#include "ash/wm/stacking_controller.h"
[email protected]e74aaf0a2012-10-12 18:42:2855#include "ash/wm/status_area_layout_manager.h"
[email protected]e6e41d2f2012-10-29 19:22:1956#include "ash/wm/system_background_controller.h"
[email protected]d90b8392012-06-13 09:34:5657#include "ash/wm/system_modal_container_layout_manager.h"
[email protected]8d625fb2012-07-18 16:40:0658#include "ash/wm/window_properties.h"
sky8d5646fe2016-04-15 17:03:4659#include "ash/wm/window_state_aura.h"
[email protected]700849f2013-04-30 17:49:2060#include "ash/wm/window_util.h"
[email protected]d90b8392012-06-13 09:34:5661#include "ash/wm/workspace_controller.h"
[email protected]e6e41d2f2012-10-29 19:22:1962#include "base/command_line.h"
jonrossa90d8982016-05-16 18:14:2563#include "base/macros.h"
sky1e30f062016-04-14 21:19:1664#include "base/memory/ptr_util.h"
[email protected]1e84c632013-06-27 23:12:2165#include "base/time/time.h"
[email protected]f1853122012-06-27 16:21:2666#include "ui/aura/client/aura_constants.h"
[email protected]2374d1812014-03-04 03:42:2767#include "ui/aura/client/screen_position_client.h"
[email protected]f1853122012-06-27 16:21:2668#include "ui/aura/window.h"
[email protected]cf6fea22013-08-07 14:24:0169#include "ui/aura/window_delegate.h"
[email protected]fcc51c952014-02-21 21:31:2670#include "ui/aura/window_event_dispatcher.h"
[email protected]f1853122012-06-27 16:21:2671#include "ui/aura/window_observer.h"
[email protected]8b3e3d82013-08-20 14:36:3072#include "ui/aura/window_tracker.h"
[email protected]cf6fea22013-08-07 14:24:0173#include "ui/base/hit_test.h"
[email protected]431552c2012-10-23 00:38:3374#include "ui/base/models/menu_model.h"
oshimaf84b0da722016-04-27 19:47:1975#include "ui/display/display.h"
76#include "ui/display/screen.h"
[email protected]86459e2c2013-04-10 13:39:2477#include "ui/keyboard/keyboard_controller.h"
78#include "ui/keyboard/keyboard_util.h"
jonrossa90d8982016-05-16 18:14:2579#include "ui/views/controls/menu/menu_model_adapter.h"
[email protected]431552c2012-10-23 00:38:3380#include "ui/views/controls/menu/menu_runner.h"
81#include "ui/views/view_model.h"
82#include "ui/views/view_model_utils.h"
[email protected]ee3ed10772014-03-11 22:02:0183#include "ui/wm/core/capture_controller.h"
84#include "ui/wm/core/visibility_controller.h"
85#include "ui/wm/core/window_util.h"
[email protected]af4552b22014-03-21 19:45:0186#include "ui/wm/public/drag_drop_client.h"
87#include "ui/wm/public/tooltip_client.h"
[email protected]5b251f12013-12-19 01:50:0588#include "ui/wm/public/window_types.h"
[email protected]d90b8392012-06-13 09:34:5689
[email protected]252eb232013-08-14 22:09:2790#if defined(OS_CHROMEOS)
[email protected]7d487592014-07-24 03:54:5091#include "ash/ash_touch_exploration_manager_chromeos.h"
[email protected]252eb232013-08-14 22:09:2792#include "ash/wm/boot_splash_screen_chromeos.h"
[email protected]a825e8312014-05-05 22:05:0193#include "ui/chromeos/touch_exploration_controller.h"
[email protected]252eb232013-08-14 22:09:2794#endif
95
[email protected]d90b8392012-06-13 09:34:5696namespace ash {
97namespace {
98
[email protected]252eb232013-08-14 22:09:2799#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:49100// Duration for the animation that hides the boot splash screen, in
101// milliseconds. This should be short enough in relation to
102// wm/window_animation.cc's brightness/grayscale fade animation that the login
103// background image animation isn't hidden by the splash screen animation.
104const int kBootSplashScreenHideDurationMs = 500;
[email protected]252eb232013-08-14 22:09:27105#endif
[email protected]bca9a7e2012-11-10 06:25:49106
[email protected]2816c2462013-12-17 02:22:25107float ToRelativeValue(int value, int src, int dst) {
108 return static_cast<float>(value) / static_cast<float>(src) * dst;
109}
110
111void MoveOriginRelativeToSize(const gfx::Size& src_size,
112 const gfx::Size& dst_size,
113 gfx::Rect* bounds_in_out) {
114 gfx::Point origin = bounds_in_out->origin();
115 bounds_in_out->set_origin(gfx::Point(
116 ToRelativeValue(origin.x(), src_size.width(), dst_size.width()),
117 ToRelativeValue(origin.y(), src_size.height(), dst_size.height())));
118}
119
[email protected]95058572012-08-20 14:57:29120// Reparents |window| to |new_parent|.
121void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
[email protected]2816c2462013-12-17 02:22:25122 const gfx::Size src_size = window->parent()->bounds().size();
123 const gfx::Size dst_size = new_parent->bounds().size();
[email protected]95058572012-08-20 14:57:29124 // Update the restore bounds to make it relative to the display.
[email protected]a41b4e12013-09-20 04:36:34125 wm::WindowState* state = wm::GetWindowState(window);
126 gfx::Rect restore_bounds;
127 bool has_restore_bounds = state->HasRestoreBounds();
[email protected]2816c2462013-12-17 02:22:25128
[email protected]9cfd3d12014-02-25 15:33:45129 bool update_bounds = (state->IsNormalOrSnapped() || state->IsMinimized()) &&
[email protected]093b8d642014-04-03 20:59:28130 new_parent->id() != kShellWindowId_DockedContainer;
[email protected]2816c2462013-12-17 02:22:25131 gfx::Rect local_bounds;
132 if (update_bounds) {
sky0702b272016-06-03 22:10:41133 local_bounds = WmWindowAura::GetAuraWindow(state->window())->bounds();
[email protected]2816c2462013-12-17 02:22:25134 MoveOriginRelativeToSize(src_size, dst_size, &local_bounds);
135 }
136
137 if (has_restore_bounds) {
[email protected]a41b4e12013-09-20 04:36:34138 restore_bounds = state->GetRestoreBoundsInParent();
[email protected]2816c2462013-12-17 02:22:25139 MoveOriginRelativeToSize(src_size, dst_size, &restore_bounds);
140 }
141
[email protected]95058572012-08-20 14:57:29142 new_parent->AddChild(window);
[email protected]2816c2462013-12-17 02:22:25143
[email protected]8663b7a62014-01-18 01:24:21144 // Docked windows have bounds handled by the layout manager in AddChild().
[email protected]2816c2462013-12-17 02:22:25145 if (update_bounds)
146 window->SetBounds(local_bounds);
147
[email protected]a41b4e12013-09-20 04:36:34148 if (has_restore_bounds)
149 state->SetRestoreBoundsInParent(restore_bounds);
[email protected]95058572012-08-20 14:57:29150}
151
152// Reparents the appropriate set of windows from |src| to |dst|.
[email protected]bf9cdb362013-10-25 19:22:45153void ReparentAllWindows(aura::Window* src, aura::Window* dst) {
[email protected]95058572012-08-20 14:57:29154 // Set of windows to move.
[email protected]f1853122012-06-27 16:21:26155 const int kContainerIdsToMove[] = {
[email protected]093b8d642014-04-03 20:59:28156 kShellWindowId_DefaultContainer,
157 kShellWindowId_DockedContainer,
158 kShellWindowId_PanelContainer,
159 kShellWindowId_AlwaysOnTopContainer,
160 kShellWindowId_SystemModalContainer,
161 kShellWindowId_LockSystemModalContainer,
tengsf98986c2014-12-06 01:42:21162 kShellWindowId_UnparentedControlContainer,
oshima022a9542015-05-01 00:15:02163 kShellWindowId_OverlayContainer,
164 };
165 const int kExtraContainerIdsToMoveInUnifiedMode[] = {
166 kShellWindowId_LockScreenContainer,
167 kShellWindowId_LockScreenBackgroundContainer,
168 };
169 std::vector<int> container_ids(
170 kContainerIdsToMove,
171 kContainerIdsToMove + arraysize(kContainerIdsToMove));
172 // Check the default_multi_display_mode because this is also necessary
173 // in trasition between mirror <-> unified mode.
oshima628a6172015-08-01 01:33:14174 if (Shell::GetInstance()
175 ->display_manager()
176 ->current_default_multi_display_mode() == DisplayManager::UNIFIED) {
oshima022a9542015-05-01 00:15:02177 for (int id : kExtraContainerIdsToMoveInUnifiedMode)
178 container_ids.push_back(id);
179 }
180
181 for (int id : container_ids) {
[email protected]f1853122012-06-27 16:21:26182 aura::Window* src_container = Shell::GetContainer(src, id);
183 aura::Window* dst_container = Shell::GetContainer(dst, id);
[email protected]5b6021902013-02-26 05:33:29184 while (!src_container->children().empty()) {
185 // Restart iteration from the source container windows each time as they
186 // may change as a result of moving other windows.
187 aura::Window::Windows::const_iterator iter =
188 src_container->children().begin();
189 while (iter != src_container->children().end() &&
[email protected]093b8d642014-04-03 20:59:28190 SystemModalContainerLayoutManager::IsModalBackground(*iter)) {
[email protected]5b6021902013-02-26 05:33:29191 ++iter;
192 }
193 // If the entire window list is modal background windows then stop.
194 if (iter == src_container->children().end())
195 break;
196 ReparentWindow(*iter, dst_container);
[email protected]f1853122012-06-27 16:21:26197 }
198 }
199}
200
oshima9a61ecf2016-06-18 10:43:05201bool IsWindowAboveContainer(aura::Window* window,
202 aura::Window* blocking_container) {
203 std::vector<aura::Window*> target_path;
204 std::vector<aura::Window*> blocking_path;
205
206 while (window) {
207 target_path.push_back(window);
208 window = window->parent();
209 }
210
211 while (blocking_container) {
212 blocking_path.push_back(blocking_container);
213 blocking_container = blocking_container->parent();
214 }
215
216 // The root window is put at the end so that we compare windows at
217 // the same depth.
218 while (!blocking_path.empty()) {
219 if (target_path.empty())
220 return false;
221
222 aura::Window* target = target_path.back();
223 target_path.pop_back();
224 aura::Window* blocking = blocking_path.back();
225 blocking_path.pop_back();
226
227 // Still on the same path, continue.
228 if (target == blocking)
229 continue;
230
231 // This can happen only if unparented window is passed because
232 // first element must be the same root.
233 if (!target->parent() || !blocking->parent())
234 return false;
235
236 aura::Window* common_parent = target->parent();
237 DCHECK_EQ(common_parent, blocking->parent());
238 aura::Window::Windows windows = common_parent->children();
239 auto blocking_iter = std::find(windows.begin(), windows.end(), blocking);
240 // If the target window is above blocking window, the window can handle
241 // events.
242 return std::find(blocking_iter, windows.end(), target) != windows.end();
243 }
244
245 return true;
246}
247
[email protected]cf6fea22013-08-07 14:24:01248// A window delegate which does nothing. Used to create a window that
249// is a event target, but do nothing.
250class EmptyWindowDelegate : public aura::WindowDelegate {
251 public:
252 EmptyWindowDelegate() {}
dcheng1f4538e2014-10-27 23:57:05253 ~EmptyWindowDelegate() override {}
[email protected]cf6fea22013-08-07 14:24:01254
255 // aura::WindowDelegate overrides:
dcheng1f4538e2014-10-27 23:57:05256 gfx::Size GetMinimumSize() const override { return gfx::Size(); }
257 gfx::Size GetMaximumSize() const override { return gfx::Size(); }
258 void OnBoundsChanged(const gfx::Rect& old_bounds,
259 const gfx::Rect& new_bounds) override {}
260 gfx::NativeCursor GetCursor(const gfx::Point& point) override {
[email protected]62c9f102014-03-27 06:07:04261 return gfx::kNullCursor;
262 }
dcheng1f4538e2014-10-27 23:57:05263 int GetNonClientComponent(const gfx::Point& point) const override {
[email protected]cf6fea22013-08-07 14:24:01264 return HTNOWHERE;
265 }
dcheng1f4538e2014-10-27 23:57:05266 bool ShouldDescendIntoChildForEventHandling(
[email protected]cf6fea22013-08-07 14:24:01267 aura::Window* child,
mostynb10d6b382014-10-03 16:23:45268 const gfx::Point& location) override {
[email protected]cf6fea22013-08-07 14:24:01269 return false;
270 }
dcheng1f4538e2014-10-27 23:57:05271 bool CanFocus() override { return false; }
272 void OnCaptureLost() override {}
danakj85d970e2015-04-04 00:15:24273 void OnPaint(const ui::PaintContext& context) override {}
dcheng1f4538e2014-10-27 23:57:05274 void OnDeviceScaleFactorChanged(float device_scale_factor) override {}
275 void OnWindowDestroying(aura::Window* window) override {}
276 void OnWindowDestroyed(aura::Window* window) override { delete this; }
277 void OnWindowTargetVisibilityChanged(bool visible) override {}
278 bool HasHitTestMask() const override { return false; }
279 void GetHitTestMask(gfx::Path* mask) const override {}
[email protected]cf6fea22013-08-07 14:24:01280
281 private:
282 DISALLOW_COPY_AND_ASSIGN(EmptyWindowDelegate);
283};
284
sky1e30f062016-04-14 21:19:16285class WorkspaceLayoutManagerDelegateImpl
286 : public wm::WorkspaceLayoutManagerDelegate {
287 public:
288 explicit WorkspaceLayoutManagerDelegateImpl(aura::Window* root_window)
289 : root_window_(root_window) {}
290 ~WorkspaceLayoutManagerDelegateImpl() override = default;
291
292 void set_shelf(ShelfLayoutManager* shelf) { shelf_ = shelf; }
293
294 // WorkspaceLayoutManagerDelegate:
295 void UpdateShelfVisibility() override {
296 if (shelf_)
297 shelf_->UpdateVisibilityState();
298 }
299 void OnFullscreenStateChanged(bool is_fullscreen) override {
300 if (shelf_) {
sky80556bc42016-06-07 22:46:13301 ash::Shell::GetInstance()->NotifyFullscreenStateChange(
302 is_fullscreen, WmWindowAura::Get(root_window_));
sky1e30f062016-04-14 21:19:16303 }
304 }
305
306 private:
307 aura::Window* root_window_;
308 ShelfLayoutManager* shelf_ = nullptr;
309
310 DISALLOW_COPY_AND_ASSIGN(WorkspaceLayoutManagerDelegateImpl);
311};
312
[email protected]d90b8392012-06-13 09:34:56313} // namespace
314
[email protected]f5c9dbc2014-04-11 08:13:45315void RootWindowController::CreateForPrimaryDisplay(AshWindowTreeHost* host) {
[email protected]2f2620332014-02-28 10:07:38316 RootWindowController* controller = new RootWindowController(host);
[email protected]608de6c2013-10-29 00:14:28317 controller->Init(RootWindowController::PRIMARY,
[email protected]a273d33a2013-10-17 12:41:21318 Shell::GetInstance()->delegate()->IsFirstRunAfterBoot());
[email protected]d90b8392012-06-13 09:34:56319}
320
[email protected]f5c9dbc2014-04-11 08:13:45321void RootWindowController::CreateForSecondaryDisplay(AshWindowTreeHost* host) {
[email protected]2f2620332014-02-28 10:07:38322 RootWindowController* controller = new RootWindowController(host);
[email protected]608de6c2013-10-29 00:14:28323 controller->Init(RootWindowController::SECONDARY, false /* first run */);
324}
325
[email protected]88d71122012-10-18 07:11:01326// static
[email protected]ccff3d72013-02-06 04:26:28327RootWindowController* RootWindowController::ForWindow(
328 const aura::Window* window) {
oshima9eea82da2014-09-13 01:11:07329 CHECK(Shell::HasInstance());
[email protected]a0afeb12012-12-10 22:57:09330 return GetRootWindowController(window->GetRootWindow());
331}
332
333// static
[email protected]d17642d2013-09-12 23:44:38334RootWindowController* RootWindowController::ForTargetRootWindow() {
oshima9eea82da2014-09-13 01:11:07335 CHECK(Shell::HasInstance());
[email protected]093b8d642014-04-03 20:59:28336 return GetRootWindowController(Shell::GetTargetRootWindow());
[email protected]a0afeb12012-12-10 22:57:09337}
338
[email protected]a273d33a2013-10-17 12:41:21339RootWindowController::~RootWindowController() {
340 Shutdown();
[email protected]f5c9dbc2014-04-11 08:13:45341 ash_host_.reset();
[email protected]a273d33a2013-10-17 12:41:21342 // The CaptureClient needs to be around for as long as the RootWindow is
343 // valid.
344 capture_client_.reset();
345}
346
[email protected]f5c9dbc2014-04-11 08:13:45347aura::WindowTreeHost* RootWindowController::GetHost() {
348 return ash_host_->AsWindowTreeHost();
349}
350
351const aura::WindowTreeHost* RootWindowController::GetHost() const {
352 return ash_host_->AsWindowTreeHost();
353}
354
355aura::Window* RootWindowController::GetRootWindow() {
356 return GetHost()->window();
357}
358
359const aura::Window* RootWindowController::GetRootWindow() const {
360 return GetHost()->window();
361}
362
[email protected]0bf61732013-07-02 04:35:10363void RootWindowController::SetWallpaperController(
364 DesktopBackgroundWidgetController* controller) {
365 wallpaper_controller_.reset(controller);
366}
367
368void RootWindowController::SetAnimatingWallpaperController(
369 AnimatingDesktopController* controller) {
370 if (animating_wallpaper_controller_.get())
371 animating_wallpaper_controller_->StopAnimating();
372 animating_wallpaper_controller_.reset(controller);
373}
374
[email protected]6675e1c2012-09-11 09:15:45375void RootWindowController::Shutdown() {
sky88bd4be62016-06-09 17:34:41376 WmShell::Get()->RemoveShellObserver(this);
[email protected]a825e8312014-05-05 22:05:01377
378#if defined(OS_CHROMEOS)
[email protected]7d487592014-07-24 03:54:50379 if (touch_exploration_manager_) {
380 touch_exploration_manager_.reset();
[email protected]a825e8312014-05-05 22:05:01381 }
382#endif
[email protected]d141b922013-07-09 08:13:17383
[email protected]0bf61732013-07-02 04:35:10384 if (animating_wallpaper_controller_.get())
385 animating_wallpaper_controller_->StopAnimating();
386 wallpaper_controller_.reset();
387 animating_wallpaper_controller_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45388 aura::Window* root_window = GetRootWindow();
sky88bd4be62016-06-09 17:34:41389 Shell* shell = Shell::GetInstance();
[email protected]d17642d2013-09-12 23:44:38390 // Change the target root window before closing child windows. If any child
[email protected]c98a4922013-09-05 20:01:42391 // being removed triggers a relayout of the shelf it will try to build a
[email protected]d17642d2013-09-12 23:44:38392 // window list adding windows from the target root window's containers which
[email protected]c98a4922013-09-05 20:01:42393 // may have already gone away.
[email protected]f5c9dbc2014-04-11 08:13:45394 if (Shell::GetTargetRootWindow() == root_window) {
[email protected]a825e8312014-05-05 22:05:01395 shell->set_target_root_window(
[email protected]f5c9dbc2014-04-11 08:13:45396 Shell::GetPrimaryRootWindow() == root_window
397 ? NULL
398 : Shell::GetPrimaryRootWindow());
[email protected]f634dd32012-07-23 22:49:07399 }
[email protected]c98a4922013-09-05 20:01:42400
401 CloseChildWindows();
[email protected]f5c9dbc2014-04-11 08:13:45402 GetRootWindowSettings(root_window)->controller = NULL;
[email protected]d90b8392012-06-13 09:34:56403 workspace_controller_.reset();
[email protected]6675e1c2012-09-11 09:15:45404 // Forget with the display ID so that display lookup
405 // ends up with invalid display.
[email protected]f5c9dbc2014-04-11 08:13:45406 GetRootWindowSettings(root_window)->display_id =
oshimaf84b0da722016-04-27 19:47:19407 display::Display::kInvalidDisplayID;
[email protected]8f5209c2014-05-22 20:36:11408 ash_host_->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28409
[email protected]956a6a42012-10-29 23:58:10410 system_background_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45411 aura::client::SetScreenPositionClient(root_window, NULL);
[email protected]d90b8392012-06-13 09:34:56412}
413
oshima9a61ecf2016-06-18 10:43:05414bool RootWindowController::CanWindowReceiveEvents(aura::Window* window) {
415 if (GetRootWindow() != window->GetRootWindow())
416 return false;
417
418 // Always allow events to fall through to the virtual keyboard even if
419 // displaying a system modal dialog.
420 if (IsVirtualKeyboardWindow(window))
421 return true;
422
423 aura::Window* blocking_container = nullptr;
424
425 int modal_container_id = 0;
426 if (Shell::GetInstance()->session_state_delegate()->IsUserSessionBlocked()) {
427 blocking_container =
428 GetContainer(kShellWindowId_LockScreenContainersContainer);
429 modal_container_id = kShellWindowId_LockSystemModalContainer;
430 } else {
431 modal_container_id = kShellWindowId_SystemModalContainer;
432 }
433 aura::Window* modal_container = GetContainer(modal_container_id);
434 SystemModalContainerLayoutManager* modal_layout_manager = nullptr;
435 modal_layout_manager = static_cast<SystemModalContainerLayoutManager*>(
436 modal_container->layout_manager());
437
438 if (modal_layout_manager->has_modal_background())
439 blocking_container = modal_container;
440 else
441 modal_container = nullptr; // Don't check modal dialogs.
442
443 // In normal session.
444 if (!blocking_container)
445 return true;
446
447 if (!IsWindowAboveContainer(window, blocking_container))
448 return false;
449
450 // If the window is in the target modal container, only allow the top most
451 // one.
452 if (modal_container && modal_container->Contains(window))
453 return modal_layout_manager->IsPartOfActiveModalWindow(window);
454
455 return true;
456}
457
[email protected]c0ce80e2012-10-05 23:28:27458SystemModalContainerLayoutManager*
[email protected]8674b312012-10-12 19:02:44459RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
[email protected]a5c78802013-12-12 22:07:01460 aura::Window* modal_container = NULL;
[email protected]8674b312012-10-12 19:02:44461 if (window) {
sky0702b272016-06-03 22:10:41462 aura::Window* window_container = WmWindowAura::GetAuraWindow(
463 wm::GetContainerForWindow(WmWindowAura::Get(window)));
[email protected]a5c78802013-12-12 22:07:01464 if (window_container &&
465 window_container->id() >= kShellWindowId_LockScreenContainer) {
466 modal_container = GetContainer(kShellWindowId_LockSystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35467 } else {
[email protected]a5c78802013-12-12 22:07:01468 modal_container = GetContainer(kShellWindowId_SystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35469 }
[email protected]8674b312012-10-12 19:02:44470 } else {
[email protected]a44afbbd2013-07-24 21:49:35471 int modal_window_id = Shell::GetInstance()->session_state_delegate()
472 ->IsUserSessionBlocked() ? kShellWindowId_LockSystemModalContainer :
473 kShellWindowId_SystemModalContainer;
[email protected]a5c78802013-12-12 22:07:01474 modal_container = GetContainer(modal_window_id);
[email protected]8674b312012-10-12 19:02:44475 }
[email protected]a5c78802013-12-12 22:07:01476 return modal_container ? static_cast<SystemModalContainerLayoutManager*>(
477 modal_container->layout_manager()) : NULL;
[email protected]c0ce80e2012-10-05 23:28:27478}
479
[email protected]d90b8392012-06-13 09:34:56480aura::Window* RootWindowController::GetContainer(int container_id) {
[email protected]f5c9dbc2014-04-11 08:13:45481 return GetRootWindow()->GetChildById(container_id);
[email protected]d90b8392012-06-13 09:34:56482}
483
[email protected]d8a24952013-08-05 20:05:05484const aura::Window* RootWindowController::GetContainer(int container_id) const {
[email protected]f5c9dbc2014-04-11 08:13:45485 return ash_host_->AsWindowTreeHost()->window()->GetChildById(container_id);
[email protected]d8a24952013-08-05 20:05:05486}
487
[email protected]864b58552013-12-19 04:19:38488void RootWindowController::ShowShelf() {
jamescook612205f2016-05-26 06:02:11489 if (!shelf_widget_->shelf())
[email protected]e74aaf0a2012-10-12 18:42:28490 return;
jamescook612205f2016-05-26 06:02:11491 shelf_widget_->shelf()->SetVisible(true);
492 shelf_widget_->status_area_widget()->Show();
[email protected]e74aaf0a2012-10-12 18:42:28493}
494
jamescook6500ad132016-05-27 06:15:54495void RootWindowController::CreateShelf() {
496 if (shelf_widget_->shelf())
497 return;
jamescookbe6ed822016-06-06 20:08:55498 shelf_widget_->CreateShelf(wm_shelf_aura_.get());
jamescook6500ad132016-05-27 06:15:54499
[email protected]756bda12013-07-03 08:17:06500 if (panel_layout_manager_)
jamescookbe6ed822016-06-06 20:08:55501 panel_layout_manager_->SetShelf(wm_shelf_aura_.get());
[email protected]7115bd32013-07-19 08:25:39502 if (docked_layout_manager_) {
jamescookbe6ed822016-06-06 20:08:55503 docked_layout_manager_->SetShelf(wm_shelf_aura_.get());
jamescook612205f2016-05-26 06:02:11504 if (shelf_widget_->shelf_layout_manager())
505 docked_layout_manager_->AddObserver(
506 shelf_widget_->shelf_layout_manager());
[email protected]7115bd32013-07-19 08:25:39507 }
[email protected]b8642ec2014-04-17 05:20:39508
509 // Notify shell observers that the shelf has been created.
sky80556bc42016-06-07 22:46:13510 Shell::GetInstance()->OnShelfCreatedForRootWindow(
511 WmWindowAura::Get(GetRootWindow()));
jamescook6500ad132016-05-27 06:15:54512
513 shelf_widget_->PostCreateShelf();
[email protected]756bda12013-07-03 08:17:06514}
515
jamescook6afad6d2016-06-01 00:35:01516Shelf* RootWindowController::GetShelf() const {
517 // TODO(jamescook): Shelf should be owned by this class, not by ShelfWidget.
518 return shelf_widget_->shelf();
519}
520
skye79274a2016-06-08 05:39:02521void RootWindowController::UpdateAfterLoginStatusChange(LoginStatus status) {
522 if (status != LoginStatus::NOT_LOGGED_IN)
[email protected]cf6fea22013-08-07 14:24:01523 mouse_event_target_.reset();
jamescook612205f2016-05-26 06:02:11524 if (shelf_widget_->status_area_widget())
525 shelf_widget_->status_area_widget()->UpdateAfterLoginStatusChange(status);
[email protected]16059276d2012-10-22 18:59:50526}
527
[email protected]bca9a7e2012-11-10 06:25:49528void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
[email protected]252eb232013-08-14 22:09:27529#if defined(OS_CHROMEOS)
pgal.u-szegedd84534d32014-10-29 12:34:30530 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]bca9a7e2012-11-10 06:25:49531 switches::kAshAnimateFromBootSplashScreen) &&
532 boot_splash_screen_.get()) {
533 // Make the splash screen fade out so it doesn't obscure the desktop
534 // wallpaper's brightness/grayscale animation.
535 boot_splash_screen_->StartHideAnimation(
536 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
537 }
[email protected]252eb232013-08-14 22:09:27538#endif
[email protected]bca9a7e2012-11-10 06:25:49539}
540
[email protected]0bf61732013-07-02 04:35:10541void RootWindowController::OnWallpaperAnimationFinished(views::Widget* widget) {
542 // Make sure the wallpaper is visible.
[email protected]bca9a7e2012-11-10 06:25:49543 system_background_->SetColor(SK_ColorBLACK);
[email protected]252eb232013-08-14 22:09:27544#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:49545 boot_splash_screen_.reset();
[email protected]252eb232013-08-14 22:09:27546#endif
[email protected]0bf61732013-07-02 04:35:10547
548 Shell::GetInstance()->user_wallpaper_delegate()->
549 OnWallpaperAnimationFinished();
550 // Only removes old component when wallpaper animation finished. If we
551 // remove the old one before the new wallpaper is done fading in there will
552 // be a white flash during the animation.
553 if (animating_wallpaper_controller()) {
554 DesktopBackgroundWidgetController* controller =
555 animating_wallpaper_controller()->GetController(true);
556 // |desktop_widget_| should be the same animating widget we try to move
557 // to |kDesktopController|. Otherwise, we may close |desktop_widget_|
558 // before move it to |kDesktopController|.
559 DCHECK_EQ(controller->widget(), widget);
560 // Release the old controller and close its background widget.
561 SetWallpaperController(controller);
562 }
[email protected]697f04c2012-10-03 01:15:10563}
564
[email protected]d90b8392012-06-13 09:34:56565void RootWindowController::CloseChildWindows() {
[email protected]cf6fea22013-08-07 14:24:01566 mouse_event_target_.reset();
567
[email protected]2a57beb52014-06-09 20:02:26568 // Remove observer as deactivating keyboard causes |docked_layout_manager_|
569 // to fire notifications.
jamescook612205f2016-05-26 06:02:11570 if (docked_layout_manager_ && shelf_widget_ &&
571 shelf_widget_->shelf_layout_manager())
572 docked_layout_manager_->RemoveObserver(
573 shelf_widget_->shelf_layout_manager());
[email protected]2a57beb52014-06-09 20:02:26574
[email protected]b6ba05d902013-10-04 21:38:45575 // Deactivate keyboard container before closing child windows and shutting
576 // down associated layout managers.
[email protected]a0b3fb882014-04-07 19:26:03577 DeactivateKeyboard(keyboard::KeyboardController::GetInstance());
[email protected]b6ba05d902013-10-04 21:38:45578
[email protected]79a87b7e2013-01-25 05:08:22579 // panel_layout_manager_ needs to be shut down before windows are destroyed.
580 if (panel_layout_manager_) {
581 panel_layout_manager_->Shutdown();
582 panel_layout_manager_ = NULL;
583 }
[email protected]7115bd32013-07-19 08:25:39584 // docked_layout_manager_ needs to be shut down before windows are destroyed.
585 if (docked_layout_manager_) {
[email protected]7115bd32013-07-19 08:25:39586 docked_layout_manager_->Shutdown();
587 docked_layout_manager_ = NULL;
588 }
[email protected]f5c9dbc2014-04-11 08:13:45589 aura::Window* root_window = GetRootWindow();
590 aura::client::SetDragDropClient(root_window, NULL);
[email protected]8b3e3d82013-08-20 14:36:30591
jamescook612205f2016-05-26 06:02:11592 if (shelf_widget_)
593 shelf_widget_->Shutdown();
[email protected]e74aaf0a2012-10-12 18:42:28594
jamescookbe6ed822016-06-06 20:08:55595 wm_shelf_aura_->Shutdown();
596
[email protected]d90b8392012-06-13 09:34:56597 // Close background widget first as it depends on tooltip.
[email protected]0bf61732013-07-02 04:35:10598 wallpaper_controller_.reset();
599 animating_wallpaper_controller_.reset();
[email protected]b4ddc7a2012-08-07 04:17:32600
[email protected]d90b8392012-06-13 09:34:56601 workspace_controller_.reset();
[email protected]f5c9dbc2014-04-11 08:13:45602 aura::client::SetTooltipClient(root_window, NULL);
[email protected]d90b8392012-06-13 09:34:56603
[email protected]0fbfa972013-10-02 19:23:33604 // Explicitly destroy top level windows. We do this as during part of
605 // destruction such windows may query the RootWindow for state.
oshimaf38efa92015-10-27 19:06:52606 aura::WindowTracker non_toplevel_windows;
607 non_toplevel_windows.Add(root_window);
608 while (!non_toplevel_windows.windows().empty()) {
609 const aura::Window* non_toplevel_window =
610 *non_toplevel_windows.windows().begin();
611 non_toplevel_windows.Remove(const_cast<aura::Window*>(non_toplevel_window));
[email protected]8b3e3d82013-08-20 14:36:30612 aura::WindowTracker toplevel_windows;
613 for (size_t i = 0; i < non_toplevel_window->children().size(); ++i) {
614 aura::Window* child = non_toplevel_window->children()[i];
[email protected]0fbfa972013-10-02 19:23:33615 if (!child->owned_by_parent())
616 continue;
[email protected]8b3e3d82013-08-20 14:36:30617 if (child->delegate())
618 toplevel_windows.Add(child);
619 else
oshimaf38efa92015-10-27 19:06:52620 non_toplevel_windows.Add(child);
[email protected]8b3e3d82013-08-20 14:36:30621 }
622 while (!toplevel_windows.windows().empty())
623 delete *toplevel_windows.windows().begin();
[email protected]d90b8392012-06-13 09:34:56624 }
[email protected]8b3e3d82013-08-20 14:36:30625 // And then remove the containers.
[email protected]f5c9dbc2014-04-11 08:13:45626 while (!root_window->children().empty()) {
627 aura::Window* window = root_window->children()[0];
[email protected]0fbfa972013-10-02 19:23:33628 if (window->owned_by_parent()) {
629 delete window;
630 } else {
[email protected]f5c9dbc2014-04-11 08:13:45631 root_window->RemoveChild(window);
[email protected]0fbfa972013-10-02 19:23:33632 }
633 }
[email protected]478c6c32013-03-09 02:50:58634
jamescook612205f2016-05-26 06:02:11635 shelf_widget_.reset();
[email protected]d90b8392012-06-13 09:34:56636}
637
[email protected]bf9cdb362013-10-25 19:22:45638void RootWindowController::MoveWindowsTo(aura::Window* dst) {
[email protected]8039e06c2013-01-17 23:34:50639 // Forget the shelf early so that shelf don't update itself using wrong
640 // display info.
sky1e30f062016-04-14 21:19:16641 workspace_controller_->SetShelf(nullptr);
642 workspace_controller_->layout_manager()->DeleteDelegate();
[email protected]f5c9dbc2014-04-11 08:13:45643 ReparentAllWindows(GetRootWindow(), dst);
[email protected]f1853122012-06-27 16:21:26644}
645
[email protected]478c6c32013-03-09 02:50:58646ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() {
jamescook612205f2016-05-26 06:02:11647 return shelf_widget_->shelf_layout_manager();
[email protected]478c6c32013-03-09 02:50:58648}
649
[email protected]a0afeb12012-12-10 22:57:09650SystemTray* RootWindowController::GetSystemTray() {
651 // We assume in throughout the code that this will not return NULL. If code
652 // triggers this for valid reasons, it should test status_area_widget first.
jamescook612205f2016-05-26 06:02:11653 CHECK(shelf_widget_->status_area_widget());
654 return shelf_widget_->status_area_widget()->system_tray();
[email protected]a0afeb12012-12-10 22:57:09655}
656
[email protected]940fb1c2013-06-18 16:54:28657void RootWindowController::ShowContextMenu(const gfx::Point& location_in_screen,
658 ui::MenuSourceType source_type) {
msw141c6b22016-03-04 00:55:30659 ShellDelegate* delegate = Shell::GetInstance()->delegate();
660 DCHECK(delegate);
jamescookda53c142016-06-08 23:38:56661 menu_model_.reset(delegate->CreateContextMenu(wm_shelf_aura_.get(), nullptr));
jonrossa90d8982016-05-16 18:14:25662 if (!menu_model_)
[email protected]8e837ec2013-01-31 01:48:33663 return;
[email protected]431552c2012-10-23 00:38:33664
jonrossa90d8982016-05-16 18:14:25665 menu_model_adapter_.reset(new views::MenuModelAdapter(
666 menu_model_.get(),
667 base::Bind(&RootWindowController::OnMenuClosed, base::Unretained(this))));
668
[email protected]6175fc42013-04-05 05:58:58669 // Background controller may not be set yet if user clicked on status are
670 // before initial animation completion. See crbug.com/222218
[email protected]0bf61732013-07-02 04:35:10671 if (!wallpaper_controller_.get())
[email protected]431552c2012-10-23 00:38:33672 return;
673
jonrossa90d8982016-05-16 18:14:25674 menu_runner_.reset(new views::MenuRunner(
675 menu_model_adapter_->CreateMenu(),
676 views::MenuRunner::CONTEXT_MENU | views::MenuRunner::ASYNC));
677 ignore_result(
678 menu_runner_->RunMenuAt(wallpaper_controller_->widget(), NULL,
679 gfx::Rect(location_in_screen, gfx::Size()),
680 views::MENU_ANCHOR_TOPLEFT, source_type));
[email protected]431552c2012-10-23 00:38:33681}
682
[email protected]e74aaf0a2012-10-12 18:42:28683void RootWindowController::UpdateShelfVisibility() {
jamescook612205f2016-05-26 06:02:11684 shelf_widget_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]e74aaf0a2012-10-12 18:42:28685}
686
varkhad99fa94f2015-06-29 22:35:46687aura::Window* RootWindowController::GetWindowForFullscreenMode() {
sky0702b272016-06-03 22:10:41688 return WmWindowAura::GetAuraWindow(
689 wm::GetWindowForFullscreenMode(WmWindowAura::Get(GetRootWindow())));
[email protected]2ee2f5d2013-01-10 23:37:16690}
691
[email protected]b6ba05d902013-10-04 21:38:45692void RootWindowController::ActivateKeyboard(
693 keyboard::KeyboardController* keyboard_controller) {
694 if (!keyboard::IsKeyboardEnabled() ||
695 GetContainer(kShellWindowId_VirtualKeyboardContainer)) {
696 return;
697 }
698 DCHECK(keyboard_controller);
jamescook612205f2016-05-26 06:02:11699 keyboard_controller->AddObserver(shelf_widget()->shelf_layout_manager());
bshe9858b4a2014-09-16 20:46:38700 keyboard_controller->AddObserver(panel_layout_manager_);
701 keyboard_controller->AddObserver(docked_layout_manager_);
702 keyboard_controller->AddObserver(workspace_controller_->layout_manager());
rsadam7bd510bb2014-12-09 20:10:56703 keyboard_controller->AddObserver(
704 always_on_top_controller_->GetLayoutManager());
bshe9858b4a2014-09-16 20:46:38705 Shell::GetInstance()->delegate()->VirtualKeyboardActivated(true);
bshec3875422014-09-29 13:21:30706 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]b2da9b602014-03-05 18:39:52707 DCHECK(parent);
[email protected]b6ba05d902013-10-04 21:38:45708 aura::Window* keyboard_container =
709 keyboard_controller->GetContainerWindow();
710 keyboard_container->set_id(kShellWindowId_VirtualKeyboardContainer);
711 parent->AddChild(keyboard_container);
[email protected]b6ba05d902013-10-04 21:38:45712}
[email protected]86459e2c2013-04-10 13:39:24713
[email protected]b6ba05d902013-10-04 21:38:45714void RootWindowController::DeactivateKeyboard(
715 keyboard::KeyboardController* keyboard_controller) {
[email protected]e1b299b2014-01-29 23:53:41716 if (!keyboard_controller ||
717 !keyboard_controller->keyboard_container_initialized()) {
[email protected]b6ba05d902013-10-04 21:38:45718 return;
[email protected]e1b299b2014-01-29 23:53:41719 }
[email protected]b6ba05d902013-10-04 21:38:45720 aura::Window* keyboard_container =
721 keyboard_controller->GetContainerWindow();
[email protected]f5c9dbc2014-04-11 08:13:45722 if (keyboard_container->GetRootWindow() == GetRootWindow()) {
bshec3875422014-09-29 13:21:30723 aura::Window* parent =
724 GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]b2da9b602014-03-05 18:39:52725 DCHECK(parent);
726 parent->RemoveChild(keyboard_container);
bshe9858b4a2014-09-16 20:46:38727 // Virtual keyboard may be deactivated while still showing, notify all
728 // observers that keyboard bounds changed to 0 before remove them.
729 keyboard_controller->NotifyKeyboardBoundsChanging(gfx::Rect());
jamescook612205f2016-05-26 06:02:11730 keyboard_controller->RemoveObserver(shelf_widget()->shelf_layout_manager());
bshe9858b4a2014-09-16 20:46:38731 keyboard_controller->RemoveObserver(panel_layout_manager_);
732 keyboard_controller->RemoveObserver(docked_layout_manager_);
733 keyboard_controller->RemoveObserver(
734 workspace_controller_->layout_manager());
rsadam7bd510bb2014-12-09 20:10:56735 keyboard_controller->RemoveObserver(
736 always_on_top_controller_->GetLayoutManager());
bshe9858b4a2014-09-16 20:46:38737 Shell::GetInstance()->delegate()->VirtualKeyboardActivated(false);
[email protected]86459e2c2013-04-10 13:39:24738 }
739}
740
[email protected]602022b2014-03-31 17:07:31741bool RootWindowController::IsVirtualKeyboardWindow(aura::Window* window) {
bshec3875422014-09-29 13:21:30742 aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer);
[email protected]602022b2014-03-31 17:07:31743 return parent ? parent->Contains(window) : false;
744}
745
dmazzoniff86e3472016-06-03 19:52:32746void RootWindowController::SetTouchAccessibilityAnchorPoint(
747 const gfx::Point& anchor_point) {
748#if defined(OS_CHROMEOS)
749 if (touch_exploration_manager_)
750 touch_exploration_manager_->SetTouchAccessibilityAnchorPoint(anchor_point);
751#endif // defined(OS_CHROMEOS)
752}
753
[email protected]a4cd6d32012-09-12 03:42:13754////////////////////////////////////////////////////////////////////////////////
755// RootWindowController, private:
756
[email protected]f5c9dbc2014-04-11 08:13:45757RootWindowController::RootWindowController(AshWindowTreeHost* ash_host)
758 : ash_host_(ash_host),
jamescookbe6ed822016-06-06 20:08:55759 wm_shelf_aura_(new WmShelfAura),
[email protected]a273d33a2013-10-17 12:41:21760 docked_layout_manager_(NULL),
761 panel_layout_manager_(NULL),
762 touch_hud_debug_(NULL),
763 touch_hud_projection_(NULL) {
[email protected]f5c9dbc2014-04-11 08:13:45764 aura::Window* root_window = GetRootWindow();
skyee78dde2016-06-01 01:21:43765 root_window_controller_common_.reset(
sky0702b272016-06-03 22:10:41766 new RootWindowControllerCommon(WmWindowAura::Get(root_window)));
[email protected]f5c9dbc2014-04-11 08:13:45767 GetRootWindowSettings(root_window)->controller = this;
[email protected]a273d33a2013-10-17 12:41:21768
769 stacking_controller_.reset(new StackingController);
[email protected]f5c9dbc2014-04-11 08:13:45770 aura::client::SetWindowTreeClient(root_window, stacking_controller_.get());
771 capture_client_.reset(new ::wm::ScopedCaptureClient(root_window));
[email protected]a273d33a2013-10-17 12:41:21772}
773
[email protected]608de6c2013-10-29 00:14:28774void RootWindowController::Init(RootWindowType root_window_type,
775 bool first_run_after_boot) {
[email protected]f5c9dbc2014-04-11 08:13:45776 aura::Window* root_window = GetRootWindow();
[email protected]51f438112013-11-18 19:32:50777 Shell* shell = Shell::GetInstance();
[email protected]f5c9dbc2014-04-11 08:13:45778 shell->InitRootWindow(root_window);
[email protected]a273d33a2013-10-17 12:41:21779
skyee78dde2016-06-01 01:21:43780 root_window_controller_common_->CreateContainers();
[email protected]608de6c2013-10-29 00:14:28781
[email protected]a273d33a2013-10-17 12:41:21782 CreateSystemBackground(first_run_after_boot);
783
784 InitLayoutManagers();
785 InitTouchHuds();
786
787 if (Shell::GetPrimaryRootWindowController()->
788 GetSystemModalLayoutManager(NULL)->has_modal_background()) {
789 GetSystemModalLayoutManager(NULL)->CreateModalBackground();
790 }
791
sky88bd4be62016-06-09 17:34:41792 WmShell::Get()->AddShellObserver(this);
[email protected]a273d33a2013-10-17 12:41:21793
sky7cd307042016-06-01 21:10:48794 root_window_controller_common_->root_window_layout()->OnWindowResized();
[email protected]608de6c2013-10-29 00:14:28795 if (root_window_type == PRIMARY) {
bshe9858b4a2014-09-16 20:46:38796 shell->InitKeyboard();
[email protected]a273d33a2013-10-17 12:41:21797 } else {
[email protected]f5c9dbc2014-04-11 08:13:45798 ash_host_->AsWindowTreeHost()->Show();
[email protected]a273d33a2013-10-17 12:41:21799
[email protected]864b58552013-12-19 04:19:38800 // Create a shelf if a user is already logged in.
[email protected]a273d33a2013-10-17 12:41:21801 if (shell->session_state_delegate()->NumberOfLoggedInUsers())
jamescook6500ad132016-05-27 06:15:54802 CreateShelf();
[email protected]0e3e7cb2014-04-12 05:18:25803
804 // Notify shell observers about new root window.
sky80556bc42016-06-07 22:46:13805 shell->OnRootWindowAdded(WmWindowAura::Get(root_window));
[email protected]a273d33a2013-10-17 12:41:21806 }
[email protected]a825e8312014-05-05 22:05:01807
808#if defined(OS_CHROMEOS)
pgal.u-szegedd84534d32014-10-29 12:34:30809 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]2e0b2352014-07-28 13:28:28810 switches::kAshDisableTouchExplorationMode)) {
[email protected]7d487592014-07-24 03:54:50811 touch_exploration_manager_.reset(new AshTouchExplorationManager(this));
[email protected]a825e8312014-05-05 22:05:01812 }
813#endif
[email protected]a273d33a2013-10-17 12:41:21814}
815
[email protected]756bda12013-07-03 08:17:06816void RootWindowController::InitLayoutManagers() {
sky7cd307042016-06-01 21:10:48817 root_window_controller_common_->CreateLayoutManagers();
818
[email protected]f5c9dbc2014-04-11 08:13:45819 aura::Window* root_window = GetRootWindow();
[email protected]756bda12013-07-03 08:17:06820
821 aura::Window* default_container =
822 GetContainer(kShellWindowId_DefaultContainer);
823 // Workspace manager has its own layout managers.
sky1e30f062016-04-14 21:19:16824
skye782a262016-05-31 20:28:57825 aura::Window* modal_container =
826 root_window->GetChildById(kShellWindowId_SystemModalContainer);
827 DCHECK(modal_container);
828 modal_container->SetLayoutManager(
829 new SystemModalContainerLayoutManager(modal_container));
830
831 aura::Window* lock_container =
832 root_window->GetChildById(kShellWindowId_LockScreenContainer);
833 DCHECK(lock_container);
834 lock_container->SetLayoutManager(new LockLayoutManager(lock_container));
835
836 aura::Window* lock_modal_container =
837 root_window->GetChildById(kShellWindowId_LockSystemModalContainer);
838 DCHECK(lock_modal_container);
839 lock_modal_container->SetLayoutManager(
840 new SystemModalContainerLayoutManager(lock_modal_container));
841
sky1e30f062016-04-14 21:19:16842 WorkspaceLayoutManagerDelegateImpl* workspace_layout_manager_delegate =
843 new WorkspaceLayoutManagerDelegateImpl(root_window);
844 workspace_controller_.reset(new WorkspaceController(
845 default_container, base::WrapUnique(workspace_layout_manager_delegate)));
[email protected]756bda12013-07-03 08:17:06846
sky0702b272016-06-03 22:10:41847 WmWindow* always_on_top_container =
848 WmWindowAura::Get(GetContainer(kShellWindowId_AlwaysOnTopContainer));
rsadam7bd510bb2014-12-09 20:10:56849 always_on_top_controller_.reset(
850 new AlwaysOnTopController(always_on_top_container));
[email protected]756bda12013-07-03 08:17:06851
jamescook612205f2016-05-26 06:02:11852 DCHECK(!shelf_widget_.get());
sky0702b272016-06-03 22:10:41853 WmWindow* shelf_container =
854 WmWindowAura::Get(GetContainer(kShellWindowId_ShelfContainer));
855 WmWindow* status_container =
856 WmWindowAura::Get(GetContainer(kShellWindowId_StatusContainer));
jamescook612205f2016-05-26 06:02:11857 shelf_widget_.reset(new ShelfWidget(shelf_container, status_container,
jamescookaada0db92016-06-17 22:10:02858 wm_shelf_aura_.get(),
jamescook612205f2016-05-26 06:02:11859 workspace_controller()));
860 workspace_layout_manager_delegate->set_shelf(
861 shelf_widget_->shelf_layout_manager());
[email protected]756bda12013-07-03 08:17:06862
[email protected]cf6fea22013-08-07 14:24:01863 if (!Shell::GetInstance()->session_state_delegate()->
864 IsActiveUserSessionStarted()) {
865 // This window exists only to be a event target on login screen.
866 // It does not have to handle events, nor be visible.
867 mouse_event_target_.reset(new aura::Window(new EmptyWindowDelegate));
danakjb161836d2015-04-03 05:14:18868 mouse_event_target_->Init(ui::LAYER_NOT_DRAWN);
[email protected]cf6fea22013-08-07 14:24:01869
870 aura::Window* lock_background_container =
[email protected]093b8d642014-04-03 20:59:28871 GetContainer(kShellWindowId_LockScreenBackgroundContainer);
[email protected]cf6fea22013-08-07 14:24:01872 lock_background_container->AddChild(mouse_event_target_.get());
873 mouse_event_target_->Show();
874 }
875
[email protected]756bda12013-07-03 08:17:06876 // Create Docked windows layout manager
sky0702b272016-06-03 22:10:41877 WmWindow* docked_container =
878 WmWindowAura::Get(GetContainer(kShellWindowId_DockedContainer));
skyca4122692016-04-26 04:47:57879 docked_layout_manager_ = new DockedWindowLayoutManager(docked_container);
sky3f7af8812016-04-21 19:30:03880 docked_container->SetLayoutManager(base::WrapUnique(docked_layout_manager_));
[email protected]756bda12013-07-03 08:17:06881
[email protected]1ca79d42014-07-18 16:26:10882 // Installs SnapLayoutManager to containers who set the
883 // |kSnapsChildrenToPhysicalPixelBoundary| property.
884 wm::InstallSnapLayoutManagerToContainers(root_window);
885
[email protected]756bda12013-07-03 08:17:06886 // Create Panel layout manager
[email protected]093b8d642014-04-03 20:59:28887 aura::Window* panel_container = GetContainer(kShellWindowId_PanelContainer);
sky0702b272016-06-03 22:10:41888 WmWindow* wm_panel_container = WmWindowAura::Get(panel_container);
skyad0315022016-04-25 19:40:31889 panel_layout_manager_ = new PanelLayoutManager(wm_panel_container);
890 wm_panel_container->SetLayoutManager(base::WrapUnique(panel_layout_manager_));
[email protected]3537d472014-01-15 05:45:31891 panel_container_handler_.reset(new PanelWindowEventHandler);
892 panel_container->AddPreTargetHandler(panel_container_handler_.get());
[email protected]b8642ec2014-04-17 05:20:39893
894 // Install an AttachedPanelWindowTargeter on the panel container to make it
895 // easier to correctly target shelf buttons with touch.
896 gfx::Insets mouse_extend(-kResizeOutsideBoundsSize,
897 -kResizeOutsideBoundsSize,
898 -kResizeOutsideBoundsSize,
899 -kResizeOutsideBoundsSize);
900 gfx::Insets touch_extend = mouse_extend.Scale(
901 kResizeOutsideBoundsScaleForTouch);
dchenga94547472016-04-08 08:41:11902 panel_container->SetEventTargeter(
903 std::unique_ptr<ui::EventTargeter>(new AttachedPanelWindowTargeter(
904 panel_container, mouse_extend, touch_extend, panel_layout_manager_)));
[email protected]756bda12013-07-03 08:17:06905}
906
907void RootWindowController::InitTouchHuds() {
pgal.u-szegedd84534d32014-10-29 12:34:30908 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
[email protected]756bda12013-07-03 08:17:06909 if (command_line->HasSwitch(switches::kAshTouchHud))
[email protected]f5c9dbc2014-04-11 08:13:45910 set_touch_hud_debug(new TouchHudDebug(GetRootWindow()));
[email protected]756bda12013-07-03 08:17:06911 if (Shell::GetInstance()->is_touch_hud_projection_enabled())
912 EnableTouchHudProjection();
913}
914
915void RootWindowController::CreateSystemBackground(
916 bool is_first_run_after_boot) {
917 SkColor color = SK_ColorBLACK;
918#if defined(OS_CHROMEOS)
919 if (is_first_run_after_boot)
920 color = kChromeOsBootColor;
921#endif
922 system_background_.reset(
[email protected]f5c9dbc2014-04-11 08:13:45923 new SystemBackgroundController(GetRootWindow(), color));
[email protected]756bda12013-07-03 08:17:06924
925#if defined(OS_CHROMEOS)
926 // Make a copy of the system's boot splash screen so we can composite it
927 // onscreen until the desktop background is ready.
928 if (is_first_run_after_boot &&
pgal.u-szegedd84534d32014-10-29 12:34:30929 (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]756bda12013-07-03 08:17:06930 switches::kAshCopyHostBackgroundAtBoot) ||
pgal.u-szegedd84534d32014-10-29 12:34:30931 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]756bda12013-07-03 08:17:06932 switches::kAshAnimateFromBootSplashScreen)))
[email protected]f5c9dbc2014-04-11 08:13:45933 boot_splash_screen_.reset(new BootSplashScreen(GetHost()));
[email protected]756bda12013-07-03 08:17:06934#endif
935}
936
[email protected]d141b922013-07-09 08:13:17937void RootWindowController::EnableTouchHudProjection() {
938 if (touch_hud_projection_)
939 return;
[email protected]f5c9dbc2014-04-11 08:13:45940 set_touch_hud_projection(new TouchHudProjection(GetRootWindow()));
[email protected]d141b922013-07-09 08:13:17941}
942
943void RootWindowController::DisableTouchHudProjection() {
944 if (!touch_hud_projection_)
945 return;
946 touch_hud_projection_->Remove();
947}
948
jonrossa90d8982016-05-16 18:14:25949void RootWindowController::OnMenuClosed() {
950 menu_runner_.reset();
951 menu_model_adapter_.reset();
952 menu_model_.reset();
953 Shell::GetInstance()->UpdateShelfVisibility();
954}
955
skye79274a2016-06-08 05:39:02956void RootWindowController::OnLoginStateChanged(LoginStatus status) {
jamescook612205f2016-05-26 06:02:11957 shelf_widget_->shelf_layout_manager()->UpdateVisibilityState();
[email protected]d141b922013-07-09 08:13:17958}
959
960void RootWindowController::OnTouchHudProjectionToggled(bool enabled) {
961 if (enabled)
962 EnableTouchHudProjection();
963 else
964 DisableTouchHudProjection();
965}
966
[email protected]6b2d4a0b2013-09-06 06:29:54967RootWindowController* GetRootWindowController(
[email protected]bf9cdb362013-10-25 19:22:45968 const aura::Window* root_window) {
jamescook5d74ac02016-05-12 19:57:12969 if (!root_window)
970 return nullptr;
971
972 if (Shell::GetInstance()->in_mus()) {
973 // On mus, like desktop aura, each top-level widget has its own root window,
974 // so |root_window| is not necessarily the display's root. For now, just
975 // the use the primary display root.
976 // TODO(jamescook): Multi-display support. This depends on how mus windows
977 // will be owned by displays.
978 aura::Window* primary_root_window = Shell::GetInstance()
979 ->window_tree_host_manager()
980 ->GetPrimaryRootWindow();
981 return GetRootWindowSettings(primary_root_window)->controller;
982 }
983
984 return GetRootWindowSettings(root_window)->controller;
[email protected]6b2d4a0b2013-09-06 06:29:54985}
986
[email protected]d90b8392012-06-13 09:34:56987} // namespace ash