blob: e3ca18578eced81aa90f8481f75ce8706e1fef75 [file] [log] [blame]
[email protected]d90b8392012-06-13 09:34:561// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ash/root_window_controller.h"
6
[email protected]8d625fb2012-07-18 16:40:067#include <vector>
8
[email protected]e6e41d2f2012-10-29 19:22:199#include "ash/ash_switches.h"
[email protected]b4ddc7a2012-08-07 04:17:3210#include "ash/desktop_background/desktop_background_widget_controller.h"
[email protected]8d625fb2012-07-18 16:40:0611#include "ash/display/display_controller.h"
[email protected]6bdf7952012-11-14 10:10:5812#include "ash/display/display_manager.h"
[email protected]e74aaf0a2012-10-12 18:42:2813#include "ash/focus_cycler.h"
[email protected]ef80e4302012-12-04 19:37:3114#include "ash/shelf_types.h"
[email protected]d90b8392012-06-13 09:34:5615#include "ash/shell.h"
[email protected]e74aaf0a2012-10-12 18:42:2816#include "ash/shell_delegate.h"
[email protected]d90b8392012-06-13 09:34:5617#include "ash/shell_factory.h"
18#include "ash/shell_window_ids.h"
[email protected]e74aaf0a2012-10-12 18:42:2819#include "ash/system/status_area_widget.h"
[email protected]8674b312012-10-12 19:02:4420#include "ash/system/tray/system_tray_delegate.h"
[email protected]d90b8392012-06-13 09:34:5621#include "ash/wm/base_layout_manager.h"
[email protected]bca9a7e2012-11-10 06:25:4922#include "ash/wm/boot_splash_screen.h"
[email protected]e74aaf0a2012-10-12 18:42:2823#include "ash/wm/panel_layout_manager.h"
24#include "ash/wm/panel_window_event_filter.h"
[email protected]d90b8392012-06-13 09:34:5625#include "ash/wm/property_util.h"
26#include "ash/wm/root_window_layout_manager.h"
27#include "ash/wm/screen_dimmer.h"
[email protected]e74aaf0a2012-10-12 18:42:2828#include "ash/wm/shelf_layout_manager.h"
[email protected]e74aaf0a2012-10-12 18:42:2829#include "ash/wm/status_area_layout_manager.h"
[email protected]e6e41d2f2012-10-29 19:22:1930#include "ash/wm/system_background_controller.h"
[email protected]d90b8392012-06-13 09:34:5631#include "ash/wm/system_modal_container_layout_manager.h"
[email protected]5dc51db82012-09-11 03:39:0132#include "ash/wm/toplevel_window_event_handler.h"
[email protected]8d625fb2012-07-18 16:40:0633#include "ash/wm/window_properties.h"
[email protected]d90b8392012-06-13 09:34:5634#include "ash/wm/workspace_controller.h"
[email protected]e6e41d2f2012-10-29 19:22:1935#include "base/command_line.h"
[email protected]bca9a7e2012-11-10 06:25:4936#include "base/time.h"
[email protected]f1853122012-06-27 16:21:2637#include "ui/aura/client/activation_client.h"
38#include "ui/aura/client/aura_constants.h"
39#include "ui/aura/client/capture_client.h"
[email protected]8cfb6722012-11-28 03:28:4640#include "ui/aura/client/focus_client.h"
[email protected]d90b8392012-06-13 09:34:5641#include "ui/aura/client/tooltip_client.h"
42#include "ui/aura/root_window.h"
[email protected]f1853122012-06-27 16:21:2643#include "ui/aura/window.h"
44#include "ui/aura/window_observer.h"
[email protected]1d030242012-06-28 18:34:0845#include "ui/aura/window_tracker.h"
[email protected]431552c2012-10-23 00:38:3346#include "ui/base/models/menu_model.h"
[email protected]8d625fb2012-07-18 16:40:0647#include "ui/gfx/display.h"
48#include "ui/gfx/screen.h"
[email protected]431552c2012-10-23 00:38:3349#include "ui/views/controls/menu/menu_model_adapter.h"
50#include "ui/views/controls/menu/menu_runner.h"
[email protected]b5756e22012-11-30 01:32:0251#include "ui/views/corewm/visibility_controller.h"
[email protected]431552c2012-10-23 00:38:3352#include "ui/views/view_model.h"
53#include "ui/views/view_model_utils.h"
[email protected]d90b8392012-06-13 09:34:5654
55namespace ash {
56namespace {
57
[email protected]bca9a7e2012-11-10 06:25:4958#if defined(OS_CHROMEOS)
59// Background color used for the Chrome OS boot splash screen.
60const SkColor kChromeOsBootColor = SkColorSetARGB(0xff, 0xfe, 0xfe, 0xfe);
61#endif
62
63// Duration for the animation that hides the boot splash screen, in
64// milliseconds. This should be short enough in relation to
65// wm/window_animation.cc's brightness/grayscale fade animation that the login
66// background image animation isn't hidden by the splash screen animation.
67const int kBootSplashScreenHideDurationMs = 500;
68
[email protected]d90b8392012-06-13 09:34:5669// Creates a new window for use as a container.
70aura::Window* CreateContainer(int window_id,
71 const char* name,
72 aura::Window* parent) {
73 aura::Window* container = new aura::Window(NULL);
74 container->set_id(window_id);
75 container->SetName(name);
76 container->Init(ui::LAYER_NOT_DRAWN);
77 parent->AddChild(container);
78 if (window_id != internal::kShellWindowId_UnparentedControlContainer)
79 container->Show();
80 return container;
81}
82
[email protected]95058572012-08-20 14:57:2983// Returns all the children of the workspace windows, eg the standard top-level
84// windows.
85std::vector<aura::Window*> GetWorkspaceWindows(aura::RootWindow* root) {
86 using aura::Window;
87
88 std::vector<Window*> windows;
89 Window* container = Shell::GetContainer(
90 root, internal::kShellWindowId_DefaultContainer);
91 for (Window::Windows::const_reverse_iterator i =
92 container->children().rbegin();
93 i != container->children().rend(); ++i) {
94 Window* workspace_window = *i;
95 if (workspace_window->id() == internal::kShellWindowId_WorkspaceContainer) {
96 windows.insert(windows.end(), workspace_window->children().begin(),
97 workspace_window->children().end());
98 }
99 }
100 return windows;
101}
102
103// Reparents |window| to |new_parent|.
104void ReparentWindow(aura::Window* window, aura::Window* new_parent) {
105 // Update the restore bounds to make it relative to the display.
106 gfx::Rect restore_bounds(GetRestoreBoundsInParent(window));
107 new_parent->AddChild(window);
108 if (!restore_bounds.IsEmpty())
109 SetRestoreBoundsInParent(window, restore_bounds);
110}
111
112// Reparents the appropriate set of windows from |src| to |dst|.
113void ReparentAllWindows(aura::RootWindow* src, aura::RootWindow* dst) {
114 // Set of windows to move.
[email protected]f1853122012-06-27 16:21:26115 const int kContainerIdsToMove[] = {
116 internal::kShellWindowId_DefaultContainer,
117 internal::kShellWindowId_AlwaysOnTopContainer,
118 internal::kShellWindowId_SystemModalContainer,
119 internal::kShellWindowId_LockSystemModalContainer,
[email protected]6274d312012-10-04 22:06:41120 internal::kShellWindowId_InputMethodContainer,
[email protected]f1853122012-06-27 16:21:26121 };
[email protected]ef0e32cc2012-10-31 20:57:33122 // For workspace windows we need to manually reparent the windows. This way
123 // workspace can move the windows to the appropriate workspace.
[email protected]c96b9812012-10-17 16:04:04124 std::vector<aura::Window*> windows(GetWorkspaceWindows(src));
125 internal::WorkspaceController* workspace_controller =
126 GetRootWindowController(dst)->workspace_controller();
127 for (size_t i = 0; i < windows.size(); ++i) {
128 aura::Window* new_parent =
129 workspace_controller->GetParentForNewWindow(windows[i]);
130 ReparentWindow(windows[i], new_parent);
[email protected]95058572012-08-20 14:57:29131 }
[email protected]f1853122012-06-27 16:21:26132 for (size_t i = 0; i < arraysize(kContainerIdsToMove); i++) {
133 int id = kContainerIdsToMove[i];
[email protected]c96b9812012-10-17 16:04:04134 if (id == internal::kShellWindowId_DefaultContainer)
[email protected]95058572012-08-20 14:57:29135 continue;
136
[email protected]f1853122012-06-27 16:21:26137 aura::Window* src_container = Shell::GetContainer(src, id);
138 aura::Window* dst_container = Shell::GetContainer(dst, id);
139 aura::Window::Windows children = src_container->children();
140 for (aura::Window::Windows::iterator iter = children.begin();
141 iter != children.end(); ++iter) {
142 aura::Window* window = *iter;
143 // Don't move modal screen.
[email protected]c0ce80e2012-10-05 23:28:27144 if (internal::SystemModalContainerLayoutManager::IsModalBackground(
145 window))
[email protected]f1853122012-06-27 16:21:26146 continue;
[email protected]f059c6942012-07-21 14:27:57147
[email protected]95058572012-08-20 14:57:29148 ReparentWindow(window, dst_container);
[email protected]f1853122012-06-27 16:21:26149 }
150 }
151}
152
[email protected]8d625fb2012-07-18 16:40:06153// Mark the container window so that a widget added to this container will
154// use the virtual screeen coordinates instead of parent.
155void SetUsesScreenCoordinates(aura::Window* container) {
156 container->SetProperty(internal::kUsesScreenCoordinatesKey, true);
157}
158
[email protected]d90b8392012-06-13 09:34:56159} // namespace
160
161namespace internal {
162
163RootWindowController::RootWindowController(aura::RootWindow* root_window)
[email protected]e74aaf0a2012-10-12 18:42:28164 : root_window_(root_window),
165 root_window_layout_(NULL),
166 status_area_widget_(NULL),
167 shelf_(NULL),
168 panel_layout_manager_(NULL) {
[email protected]d90b8392012-06-13 09:34:56169 SetRootWindowController(root_window, this);
[email protected]c0ce80e2012-10-05 23:28:27170 screen_dimmer_.reset(new ScreenDimmer(root_window));
[email protected]d90b8392012-06-13 09:34:56171}
172
173RootWindowController::~RootWindowController() {
[email protected]6675e1c2012-09-11 09:15:45174 Shutdown();
175 root_window_.reset();
176}
177
[email protected]88d71122012-10-18 07:11:01178// static
[email protected]a0afeb12012-12-10 22:57:09179RootWindowController* RootWindowController::ForLauncher(aura::Window* window) {
[email protected]88d71122012-10-18 07:11:01180 if (Shell::IsLauncherPerDisplayEnabled())
181 return GetRootWindowController(window->GetRootWindow());
182 else
183 return Shell::GetPrimaryRootWindowController();
184}
185
[email protected]a0afeb12012-12-10 22:57:09186// static
187RootWindowController* RootWindowController::ForWindow(aura::Window* window) {
188 return GetRootWindowController(window->GetRootWindow());
189}
190
191// static
192RootWindowController* RootWindowController::ForActiveRootWindow() {
193 return GetRootWindowController(Shell::GetActiveRootWindow());
194}
195
[email protected]6675e1c2012-09-11 09:15:45196void RootWindowController::Shutdown() {
197 CloseChildWindows();
[email protected]f634dd32012-07-23 22:49:07198 if (Shell::GetActiveRootWindow() == root_window_.get()) {
199 Shell::GetInstance()->set_active_root_window(
200 Shell::GetPrimaryRootWindow() == root_window_.get() ?
201 NULL : Shell::GetPrimaryRootWindow());
202 }
[email protected]d90b8392012-06-13 09:34:56203 SetRootWindowController(root_window_.get(), NULL);
[email protected]d90b8392012-06-13 09:34:56204 screen_dimmer_.reset();
205 workspace_controller_.reset();
[email protected]6675e1c2012-09-11 09:15:45206 // Forget with the display ID so that display lookup
207 // ends up with invalid display.
208 root_window_->ClearProperty(kDisplayIdKey);
209 // And this root window should no longer process events.
210 root_window_->PrepareForShutdown();
[email protected]e74aaf0a2012-10-12 18:42:28211
[email protected]956a6a42012-10-29 23:58:10212 system_background_.reset();
213
[email protected]e74aaf0a2012-10-12 18:42:28214 // Launcher widget has an InputMethodBridge that references to
215 // |input_method_filter_|'s |input_method_|. So explicitly release
216 // |launcher_| before |input_method_filter_|. And this needs to be
217 // after we delete all containers in case there are still live
218 // browser windows which access LauncherModel during close.
219 launcher_.reset();
[email protected]d90b8392012-06-13 09:34:56220}
221
[email protected]c0ce80e2012-10-05 23:28:27222SystemModalContainerLayoutManager*
[email protected]8674b312012-10-12 19:02:44223RootWindowController::GetSystemModalLayoutManager(aura::Window* window) {
224 aura::Window* container = NULL;
225 if (window) {
[email protected]3b162e12012-11-09 11:52:35226 if (window->parent() &&
227 window->parent()->id() >= kShellWindowId_LockScreenContainer) {
228 container = GetContainer(kShellWindowId_LockSystemModalContainer);
229 } else {
[email protected]8674b312012-10-12 19:02:44230 container = GetContainer(kShellWindowId_SystemModalContainer);
[email protected]3b162e12012-11-09 11:52:35231 }
[email protected]8674b312012-10-12 19:02:44232 } else {
[email protected]a0afeb12012-12-10 22:57:09233 user::LoginStatus login = Shell::GetInstance()->tray_delegate() ?
[email protected]8674b312012-10-12 19:02:44234 Shell::GetInstance()->tray_delegate()->GetUserLoginStatus() :
235 user::LOGGED_IN_NONE;
236 int modal_window_id = (login == user::LOGGED_IN_LOCKED ||
237 login == user::LOGGED_IN_NONE) ?
238 kShellWindowId_LockSystemModalContainer :
239 kShellWindowId_SystemModalContainer;
240 container = GetContainer(modal_window_id);
241 }
[email protected]c0ce80e2012-10-05 23:28:27242 return static_cast<SystemModalContainerLayoutManager*>(
[email protected]8674b312012-10-12 19:02:44243 container->layout_manager());
[email protected]c0ce80e2012-10-05 23:28:27244}
245
[email protected]d90b8392012-06-13 09:34:56246aura::Window* RootWindowController::GetContainer(int container_id) {
247 return root_window_->GetChildById(container_id);
248}
249
250void RootWindowController::InitLayoutManagers() {
251 root_window_layout_ =
[email protected]c0ce80e2012-10-05 23:28:27252 new RootWindowLayoutManager(root_window_.get());
[email protected]d90b8392012-06-13 09:34:56253 root_window_->SetLayoutManager(root_window_layout_);
254
255 aura::Window* default_container =
[email protected]c0ce80e2012-10-05 23:28:27256 GetContainer(kShellWindowId_DefaultContainer);
[email protected]d90b8392012-06-13 09:34:56257 // Workspace manager has its own layout managers.
258 workspace_controller_.reset(
[email protected]c0ce80e2012-10-05 23:28:27259 new WorkspaceController(default_container));
[email protected]d90b8392012-06-13 09:34:56260
261 aura::Window* always_on_top_container =
[email protected]c0ce80e2012-10-05 23:28:27262 GetContainer(kShellWindowId_AlwaysOnTopContainer);
[email protected]d90b8392012-06-13 09:34:56263 always_on_top_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27264 new BaseLayoutManager(
[email protected]d90b8392012-06-13 09:34:56265 always_on_top_container->GetRootWindow()));
266}
267
[email protected]e74aaf0a2012-10-12 18:42:28268void RootWindowController::InitForPrimaryDisplay() {
269 DCHECK(!status_area_widget_);
[email protected]16059276d2012-10-22 18:59:50270 aura::Window* status_container =
271 GetContainer(ash::internal::kShellWindowId_StatusContainer);
[email protected]e74aaf0a2012-10-12 18:42:28272 // Initialize Primary RootWindow specific items.
[email protected]16059276d2012-10-22 18:59:50273 status_area_widget_ = new internal::StatusAreaWidget(status_container);
[email protected]51ed5992012-11-07 10:14:39274 status_area_widget_->CreateTrayViews();
[email protected]e74aaf0a2012-10-12 18:42:28275 // Login screen manages status area visibility by itself.
[email protected]51ed5992012-11-07 10:14:39276 ShellDelegate* shell_delegate = Shell::GetInstance()->delegate();
[email protected]02dbd1a2012-11-08 22:50:13277 if (shell_delegate->IsSessionStarted())
[email protected]e74aaf0a2012-10-12 18:42:28278 status_area_widget_->Show();
279
280 Shell::GetInstance()->focus_cycler()->AddWidget(status_area_widget_);
281
282 internal::ShelfLayoutManager* shelf_layout_manager =
283 new internal::ShelfLayoutManager(status_area_widget_);
284 GetContainer(internal::kShellWindowId_LauncherContainer)->
285 SetLayoutManager(shelf_layout_manager);
286 shelf_ = shelf_layout_manager;
287
288 internal::StatusAreaLayoutManager* status_area_layout_manager =
289 new internal::StatusAreaLayoutManager(shelf_layout_manager);
290 GetContainer(internal::kShellWindowId_StatusContainer)->
291 SetLayoutManager(status_area_layout_manager);
292
293 shelf_layout_manager->set_workspace_controller(
294 workspace_controller());
295
296 workspace_controller()->SetShelf(shelf_);
297
298 // Create Panel layout manager
299 aura::Window* panel_container = GetContainer(
300 internal::kShellWindowId_PanelContainer);
301 panel_layout_manager_ =
302 new internal::PanelLayoutManager(panel_container);
[email protected]304594c2012-11-13 16:35:27303 panel_container->AddPreTargetHandler(
[email protected]e74aaf0a2012-10-12 18:42:28304 new internal::PanelWindowEventFilter(
305 panel_container, panel_layout_manager_));
306 panel_container->SetLayoutManager(panel_layout_manager_);
307
[email protected]02dbd1a2012-11-08 22:50:13308 if (shell_delegate->IsUserLoggedIn())
[email protected]e74aaf0a2012-10-12 18:42:28309 CreateLauncher();
310}
311
[email protected]d90b8392012-06-13 09:34:56312void RootWindowController::CreateContainers() {
313 CreateContainersInRootWindow(root_window_.get());
314}
315
[email protected]697f04c2012-10-03 01:15:10316void RootWindowController::CreateSystemBackground(
317 bool is_first_run_after_boot) {
[email protected]bca9a7e2012-11-10 06:25:49318 SkColor color = SK_ColorBLACK;
[email protected]697f04c2012-10-03 01:15:10319#if defined(OS_CHROMEOS)
[email protected]bca9a7e2012-11-10 06:25:49320 if (is_first_run_after_boot)
321 color = kChromeOsBootColor;
[email protected]697f04c2012-10-03 01:15:10322#endif
[email protected]e6e41d2f2012-10-29 19:22:19323 system_background_.reset(
[email protected]bca9a7e2012-11-10 06:25:49324 new SystemBackgroundController(root_window_.get(), color));
325
326#if defined(OS_CHROMEOS)
327 // Make a copy of the system's boot splash screen so we can composite it
328 // onscreen until the desktop background is ready.
329 if (is_first_run_after_boot &&
330 (CommandLine::ForCurrentProcess()->HasSwitch(
331 switches::kAshCopyHostBackgroundAtBoot) ||
332 CommandLine::ForCurrentProcess()->HasSwitch(
333 switches::kAshAnimateFromBootSplashScreen)))
334 boot_splash_screen_.reset(new BootSplashScreen(root_window_.get()));
335#endif
[email protected]697f04c2012-10-03 01:15:10336}
337
[email protected]e74aaf0a2012-10-12 18:42:28338void RootWindowController::CreateLauncher() {
339 if (launcher_.get())
340 return;
341
342 aura::Window* default_container =
343 GetContainer(internal::kShellWindowId_DefaultContainer);
344 launcher_.reset(new Launcher(default_container, shelf_));
345
346 launcher_->SetFocusCycler(Shell::GetInstance()->focus_cycler());
347 shelf_->SetLauncher(launcher_.get());
348
349 if (panel_layout_manager_)
350 panel_layout_manager_->SetLauncher(launcher_.get());
351
352 ShellDelegate* delegate = Shell::GetInstance()->delegate();
353 if (delegate)
354 launcher_->SetVisible(delegate->IsSessionStarted());
355 launcher_->widget()->Show();
356}
357
358void RootWindowController::ShowLauncher() {
359 if (!launcher_.get())
360 return;
361 launcher_->SetVisible(true);
[email protected]cb47bcb32012-11-05 21:36:38362 status_area_widget_->Show();
[email protected]e74aaf0a2012-10-12 18:42:28363}
364
[email protected]16059276d2012-10-22 18:59:50365void RootWindowController::OnLoginStateChanged(user::LoginStatus status) {
366 // TODO(oshima): remove if when launcher per display is enabled by
367 // default.
368 if (shelf_)
369 shelf_->UpdateVisibilityState();
370}
371
372void RootWindowController::UpdateAfterLoginStatusChange(
373 user::LoginStatus status) {
374 if (status_area_widget_)
375 status_area_widget_->UpdateAfterLoginStatusChange(status);
376}
377
[email protected]bca9a7e2012-11-10 06:25:49378void RootWindowController::HandleInitialDesktopBackgroundAnimationStarted() {
379 if (CommandLine::ForCurrentProcess()->HasSwitch(
380 switches::kAshAnimateFromBootSplashScreen) &&
381 boot_splash_screen_.get()) {
382 // Make the splash screen fade out so it doesn't obscure the desktop
383 // wallpaper's brightness/grayscale animation.
384 boot_splash_screen_->StartHideAnimation(
385 base::TimeDelta::FromMilliseconds(kBootSplashScreenHideDurationMs));
386 }
387}
388
[email protected]697f04c2012-10-03 01:15:10389void RootWindowController::HandleDesktopBackgroundVisible() {
[email protected]bca9a7e2012-11-10 06:25:49390 system_background_->SetColor(SK_ColorBLACK);
391 boot_splash_screen_.reset();
[email protected]697f04c2012-10-03 01:15:10392}
393
[email protected]d90b8392012-06-13 09:34:56394void RootWindowController::CloseChildWindows() {
[email protected]e74aaf0a2012-10-12 18:42:28395 // The status area needs to be shut down before the windows are destroyed.
[email protected]8674b312012-10-12 19:02:44396 if (status_area_widget_) {
[email protected]e74aaf0a2012-10-12 18:42:28397 status_area_widget_->Shutdown();
[email protected]8674b312012-10-12 19:02:44398 status_area_widget_ = NULL;
399 }
[email protected]e74aaf0a2012-10-12 18:42:28400
401 // Closing the windows frees the workspace controller.
402 if (shelf_)
403 shelf_->set_workspace_controller(NULL);
404
[email protected]d90b8392012-06-13 09:34:56405 // Close background widget first as it depends on tooltip.
[email protected]d86de6b22012-10-05 19:32:58406 root_window_->SetProperty(kDesktopController,
[email protected]b4ddc7a2012-08-07 04:17:32407 static_cast<DesktopBackgroundWidgetController*>(NULL));
[email protected]d86de6b22012-10-05 19:32:58408 root_window_->SetProperty(kAnimatingDesktopController,
409 static_cast<AnimatingDesktopController*>(NULL));
[email protected]b4ddc7a2012-08-07 04:17:32410
[email protected]d90b8392012-06-13 09:34:56411 workspace_controller_.reset();
412 aura::client::SetTooltipClient(root_window_.get(), NULL);
413
414 while (!root_window_->children().empty()) {
415 aura::Window* child = root_window_->children()[0];
416 delete child;
417 }
[email protected]83482fbf2012-11-21 14:02:09418 launcher_.reset();
[email protected]e74aaf0a2012-10-12 18:42:28419 // All containers are deleted, so reset shelf_.
420 shelf_ = NULL;
[email protected]d90b8392012-06-13 09:34:56421}
422
[email protected]f1853122012-06-27 16:21:26423void RootWindowController::MoveWindowsTo(aura::RootWindow* dst) {
[email protected]8cfb6722012-11-28 03:28:46424 aura::Window* focused = aura::client::GetFocusClient(dst)->GetFocusedWindow();
[email protected]dbf835d82012-09-11 18:23:09425 aura::WindowTracker tracker;
426 if (focused)
427 tracker.Add(focused);
[email protected]f1853122012-06-27 16:21:26428 aura::client::ActivationClient* activation_client =
429 aura::client::GetActivationClient(dst);
430 aura::Window* active = activation_client->GetActiveWindow();
[email protected]dbf835d82012-09-11 18:23:09431 if (active && focused != active)
432 tracker.Add(active);
[email protected]f1853122012-06-27 16:21:26433 // Deactivate the window to close menu / bubble windows.
434 activation_client->DeactivateWindow(active);
435 // Release capture if any.
436 aura::client::GetCaptureClient(root_window_.get())->
437 SetCapture(NULL);
[email protected]dbf835d82012-09-11 18:23:09438 // Clear the focused window if any. This is necessary because a
439 // window may be deleted when losing focus (fullscreen flash for
440 // example). If the focused window is still alive after move, it'll
441 // be re-focused below.
[email protected]8cfb6722012-11-28 03:28:46442 aura::client::GetFocusClient(dst)->FocusWindow(NULL, NULL);
[email protected]f1853122012-06-27 16:21:26443
[email protected]95058572012-08-20 14:57:29444 ReparentAllWindows(root_window_.get(), dst);
[email protected]f1853122012-06-27 16:21:26445
446 // Restore focused or active window if it's still alive.
[email protected]1d030242012-06-28 18:34:08447 if (focused && tracker.Contains(focused) && dst->Contains(focused)) {
[email protected]8cfb6722012-11-28 03:28:46448 aura::client::GetFocusClient(dst)->FocusWindow(focused, NULL);
[email protected]1d030242012-06-28 18:34:08449 } else if (active && tracker.Contains(active) && dst->Contains(active)) {
[email protected]f1853122012-06-27 16:21:26450 activation_client->ActivateWindow(active);
451 }
452}
453
[email protected]a0afeb12012-12-10 22:57:09454SystemTray* RootWindowController::GetSystemTray() {
455 // We assume in throughout the code that this will not return NULL. If code
456 // triggers this for valid reasons, it should test status_area_widget first.
457 internal::StatusAreaWidget* status_area = status_area_widget();
458 CHECK(status_area);
459 return status_area->system_tray();
460}
461
[email protected]431552c2012-10-23 00:38:33462void RootWindowController::ShowContextMenu(
463 const gfx::Point& location_in_screen) {
464 aura::RootWindow* target = Shell::IsLauncherPerDisplayEnabled() ?
465 root_window() : Shell::GetPrimaryRootWindow();
466 DCHECK(Shell::GetInstance()->delegate());
467 scoped_ptr<ui::MenuModel> menu_model(
468 Shell::GetInstance()->delegate()->CreateContextMenu(target));
469
470 views::MenuModelAdapter menu_model_adapter(menu_model.get());
471 views::MenuRunner menu_runner(menu_model_adapter.CreateMenu());
472 views::Widget* widget =
473 root_window_->GetProperty(kDesktopController)->widget();
474
475 if (menu_runner.RunMenuAt(
476 widget, NULL, gfx::Rect(location_in_screen, gfx::Size()),
477 views::MenuItemView::TOPLEFT, views::MenuRunner::CONTEXT_MENU) ==
478 views::MenuRunner::MENU_DELETED)
479 return;
480
481 Shell::GetInstance()->UpdateShelfVisibility();
482}
483
[email protected]e74aaf0a2012-10-12 18:42:28484void RootWindowController::UpdateShelfVisibility() {
485 shelf_->UpdateVisibilityState();
486}
487
488void RootWindowController::SetShelfAutoHideBehavior(
489 ShelfAutoHideBehavior behavior) {
490 shelf_->SetAutoHideBehavior(behavior);
491}
492
493ShelfAutoHideBehavior RootWindowController::GetShelfAutoHideBehavior() const {
494 return shelf_->auto_hide_behavior();
495}
496
497bool RootWindowController::SetShelfAlignment(ShelfAlignment alignment) {
498 return shelf_->SetAlignment(alignment);
499}
500
501ShelfAlignment RootWindowController::GetShelfAlignment() {
[email protected]1fcfb992012-12-05 01:47:23502 return shelf_->GetAlignment();
[email protected]e74aaf0a2012-10-12 18:42:28503}
504
[email protected]a4cd6d32012-09-12 03:42:13505////////////////////////////////////////////////////////////////////////////////
506// RootWindowController, private:
507
508void RootWindowController::CreateContainersInRootWindow(
509 aura::RootWindow* root_window) {
510 // These containers are just used by PowerButtonController to animate groups
511 // of containers simultaneously without messing up the current transformations
512 // on those containers. These are direct children of the root window; all of
513 // the other containers are their children.
[email protected]e6e41d2f2012-10-29 19:22:19514
515 // The desktop background container is not part of the lock animation, so it
516 // is not included in those animate groups.
[email protected]a4cd6d32012-09-12 03:42:13517 // When screen is locked desktop background is moved to lock screen background
518 // container (moved back on unlock). We want to make sure that there's an
519 // opaque layer occluding the non-lock-screen layers.
[email protected]e6e41d2f2012-10-29 19:22:19520 aura::Window* desktop_background_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27521 kShellWindowId_DesktopBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13522 "DesktopBackgroundContainer",
523 root_window);
[email protected]b5756e22012-11-30 01:32:02524 views::corewm::SetChildWindowVisibilityChangesAnimated(
525 desktop_background_container);
[email protected]a4cd6d32012-09-12 03:42:13526
527 aura::Window* non_lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27528 kShellWindowId_NonLockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13529 "NonLockScreenContainersContainer",
530 root_window);
531
532 aura::Window* lock_background_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27533 kShellWindowId_LockScreenBackgroundContainer,
[email protected]a4cd6d32012-09-12 03:42:13534 "LockScreenBackgroundContainer",
535 root_window);
[email protected]b5756e22012-11-30 01:32:02536 views::corewm::SetChildWindowVisibilityChangesAnimated(
537 lock_background_containers);
[email protected]a4cd6d32012-09-12 03:42:13538
539 aura::Window* lock_screen_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27540 kShellWindowId_LockScreenContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13541 "LockScreenContainersContainer",
542 root_window);
543 aura::Window* lock_screen_related_containers = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27544 kShellWindowId_LockScreenRelatedContainersContainer,
[email protected]a4cd6d32012-09-12 03:42:13545 "LockScreenRelatedContainersContainer",
546 root_window);
547
[email protected]c0ce80e2012-10-05 23:28:27548 CreateContainer(kShellWindowId_UnparentedControlContainer,
[email protected]a4cd6d32012-09-12 03:42:13549 "UnparentedControlContainer",
550 non_lock_screen_containers);
551
552 aura::Window* default_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27553 kShellWindowId_DefaultContainer,
[email protected]a4cd6d32012-09-12 03:42:13554 "DefaultContainer",
555 non_lock_screen_containers);
[email protected]b5756e22012-11-30 01:32:02556 views::corewm::SetChildWindowVisibilityChangesAnimated(default_container);
[email protected]a4cd6d32012-09-12 03:42:13557 SetUsesScreenCoordinates(default_container);
558
559 aura::Window* always_on_top_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27560 kShellWindowId_AlwaysOnTopContainer,
[email protected]a4cd6d32012-09-12 03:42:13561 "AlwaysOnTopContainer",
562 non_lock_screen_containers);
563 always_on_top_container_handler_.reset(
564 new ToplevelWindowEventHandler(always_on_top_container));
[email protected]b5756e22012-11-30 01:32:02565 views::corewm::SetChildWindowVisibilityChangesAnimated(
566 always_on_top_container);
[email protected]a4cd6d32012-09-12 03:42:13567 SetUsesScreenCoordinates(always_on_top_container);
568
569 aura::Window* panel_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27570 kShellWindowId_PanelContainer,
[email protected]a4cd6d32012-09-12 03:42:13571 "PanelContainer",
572 non_lock_screen_containers);
573 SetUsesScreenCoordinates(panel_container);
574
575 aura::Window* launcher_container =
[email protected]c0ce80e2012-10-05 23:28:27576 CreateContainer(kShellWindowId_LauncherContainer,
[email protected]a4cd6d32012-09-12 03:42:13577 "LauncherContainer",
578 non_lock_screen_containers);
579 SetUsesScreenCoordinates(launcher_container);
580
[email protected]dc851a4e52012-10-03 00:05:55581 aura::Window* app_list_container =
[email protected]c0ce80e2012-10-05 23:28:27582 CreateContainer(kShellWindowId_AppListContainer,
[email protected]dc851a4e52012-10-03 00:05:55583 "AppListContainer",
584 non_lock_screen_containers);
585 SetUsesScreenCoordinates(app_list_container);
[email protected]a4cd6d32012-09-12 03:42:13586
587 aura::Window* modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27588 kShellWindowId_SystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13589 "SystemModalContainer",
590 non_lock_screen_containers);
591 modal_container_handler_.reset(
592 new ToplevelWindowEventHandler(modal_container));
[email protected]a4cd6d32012-09-12 03:42:13593 modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27594 new SystemModalContainerLayoutManager(modal_container));
[email protected]b5756e22012-11-30 01:32:02595 views::corewm::SetChildWindowVisibilityChangesAnimated(modal_container);
[email protected]a4cd6d32012-09-12 03:42:13596 SetUsesScreenCoordinates(modal_container);
597
598 aura::Window* input_method_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27599 kShellWindowId_InputMethodContainer,
[email protected]a4cd6d32012-09-12 03:42:13600 "InputMethodContainer",
601 non_lock_screen_containers);
602 SetUsesScreenCoordinates(input_method_container);
603
604 // TODO(beng): Figure out if we can make this use
605 // SystemModalContainerEventFilter instead of stops_event_propagation.
606 aura::Window* lock_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27607 kShellWindowId_LockScreenContainer,
[email protected]a4cd6d32012-09-12 03:42:13608 "LockScreenContainer",
609 lock_screen_containers);
610 lock_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27611 new BaseLayoutManager(root_window));
[email protected]a4cd6d32012-09-12 03:42:13612 SetUsesScreenCoordinates(lock_container);
613 // TODO(beng): stopsevents
614
615 aura::Window* lock_modal_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27616 kShellWindowId_LockSystemModalContainer,
[email protected]a4cd6d32012-09-12 03:42:13617 "LockSystemModalContainer",
618 lock_screen_containers);
619 lock_modal_container_handler_.reset(
620 new ToplevelWindowEventHandler(lock_modal_container));
[email protected]a4cd6d32012-09-12 03:42:13621 lock_modal_container->SetLayoutManager(
[email protected]c0ce80e2012-10-05 23:28:27622 new SystemModalContainerLayoutManager(lock_modal_container));
[email protected]b5756e22012-11-30 01:32:02623 views::corewm::SetChildWindowVisibilityChangesAnimated(lock_modal_container);
[email protected]a4cd6d32012-09-12 03:42:13624 SetUsesScreenCoordinates(lock_modal_container);
625
626 aura::Window* status_container =
[email protected]c0ce80e2012-10-05 23:28:27627 CreateContainer(kShellWindowId_StatusContainer,
[email protected]a4cd6d32012-09-12 03:42:13628 "StatusContainer",
629 lock_screen_related_containers);
630 SetUsesScreenCoordinates(status_container);
631
632 aura::Window* settings_bubble_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27633 kShellWindowId_SettingBubbleContainer,
[email protected]a4cd6d32012-09-12 03:42:13634 "SettingBubbleContainer",
635 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02636 views::corewm::SetChildWindowVisibilityChangesAnimated(
637 settings_bubble_container);
[email protected]a4cd6d32012-09-12 03:42:13638 SetUsesScreenCoordinates(settings_bubble_container);
639
640 aura::Window* menu_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27641 kShellWindowId_MenuContainer,
[email protected]a4cd6d32012-09-12 03:42:13642 "MenuContainer",
643 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02644 views::corewm::SetChildWindowVisibilityChangesAnimated(menu_container);
[email protected]a4cd6d32012-09-12 03:42:13645 SetUsesScreenCoordinates(menu_container);
646
647 aura::Window* drag_drop_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27648 kShellWindowId_DragImageAndTooltipContainer,
[email protected]a4cd6d32012-09-12 03:42:13649 "DragImageAndTooltipContainer",
650 lock_screen_related_containers);
[email protected]b5756e22012-11-30 01:32:02651 views::corewm::SetChildWindowVisibilityChangesAnimated(drag_drop_container);
[email protected]a4cd6d32012-09-12 03:42:13652 SetUsesScreenCoordinates(drag_drop_container);
653
654 aura::Window* overlay_container = CreateContainer(
[email protected]c0ce80e2012-10-05 23:28:27655 kShellWindowId_OverlayContainer,
[email protected]a4cd6d32012-09-12 03:42:13656 "OverlayContainer",
657 lock_screen_related_containers);
658 SetUsesScreenCoordinates(overlay_container);
[email protected]a07615f2012-10-24 08:23:08659
660 CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
661 "PowerButtonAnimationContainer", root_window) ;
[email protected]a4cd6d32012-09-12 03:42:13662}
663
[email protected]d90b8392012-06-13 09:34:56664} // namespace internal
665} // namespace ash