1 // 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.
10 #include "ash/accelerators/focus_manager_factory.h"
11 #include "ash/ash_switches.h"
12 #include "ash/caps_lock_delegate.h"
13 #include "ash/desktop_background/desktop_background_controller.h"
14 #include "ash/desktop_background/desktop_background_resources.h"
15 #include "ash/desktop_background/desktop_background_view.h"
16 #include "ash/display/display_controller.h"
17 #include "ash/display/mouse_cursor_event_filter.h"
18 #include "ash/display/multi_display_manager.h"
19 #include "ash/display/screen_position_controller.h"
20 #include "ash/drag_drop/drag_drop_controller.h"
21 #include "ash/focus_cycler.h"
22 #include "ash/high_contrast/high_contrast_controller.h"
23 #include "ash/magnifier/magnification_controller.h"
24 #include "ash/root_window_controller.h"
25 #include "ash/screen_ash.h"
26 #include "ash/shell_delegate.h"
27 #include "ash/shell_factory.h"
28 #include "ash/shell_window_ids.h"
29 #include "ash/system/status_area_widget.h"
30 #include "ash/system/tray/system_tray_delegate.h"
31 #include "ash/tooltips/tooltip_controller.h"
32 #include "ash/touch/touch_observer_hud.h"
33 #include "ash/wm/activation_controller.h"
34 #include "ash/wm/always_on_top_controller.h"
35 #include "ash/wm/app_list_controller.h"
36 #include "ash/wm/base_layout_manager.h"
37 #include "ash/wm/capture_controller.h"
38 #include "ash/wm/coordinate_conversion.h"
39 #include "ash/wm/custom_frame_view_ash.h"
40 #include "ash/wm/dialog_frame_view.h"
41 #include "ash/wm/event_client_impl.h"
42 #include "ash/wm/event_rewriter_event_filter.h"
43 #include "ash/wm/overlay_event_filter.h"
44 #include "ash/wm/power_button_controller.h"
45 #include "ash/wm/property_util.h"
46 #include "ash/wm/resize_shadow_controller.h"
47 #include "ash/wm/root_window_layout_manager.h"
48 #include "ash/wm/screen_dimmer.h"
49 #include "ash/wm/session_state_controller.h"
50 #include "ash/wm/session_state_controller_impl.h"
51 #include "ash/wm/session_state_controller_impl2.h"
52 #include "ash/wm/shadow_controller.h"
53 #include "ash/wm/stacking_controller.h"
54 #include "ash/wm/system_gesture_event_filter.h"
55 #include "ash/wm/system_modal_container_event_filter.h"
56 #include "ash/wm/system_modal_container_layout_manager.h"
57 #include "ash/wm/user_activity_detector.h"
58 #include "ash/wm/video_detector.h"
59 #include "ash/wm/visibility_controller.h"
60 #include "ash/wm/window_cycle_controller.h"
61 #include "ash/wm/window_modality_controller.h"
62 #include "ash/wm/window_properties.h"
63 #include "ash/wm/window_util.h"
64 #include "ash/wm/workspace_controller.h"
65 #include "base/bind.h"
66 #include "base/command_line.h"
67 #include "base/debug/leak_annotations.h"
68 #include "ui/aura/client/aura_constants.h"
69 #include "ui/aura/client/user_action_client.h"
70 #include "ui/aura/display_manager.h"
71 #include "ui/aura/env.h"
72 #include "ui/aura/focus_manager.h"
73 #include "ui/aura/layout_manager.h"
74 #include "ui/aura/root_window.h"
75 #include "ui/aura/shared/compound_event_filter.h"
76 #include "ui/aura/shared/input_method_event_filter.h"
77 #include "ui/aura/ui_controls_aura.h"
78 #include "ui/aura/window.h"
79 #include "ui/compositor/layer.h"
80 #include "ui/compositor/layer_animator.h"
81 #include "ui/gfx/display.h"
82 #include "ui/gfx/image/image_skia.h"
83 #include "ui/gfx/screen.h"
84 #include "ui/gfx/size.h"
85 #include "ui/ui_controls/ui_controls.h"
86 #include "ui/views/focus/focus_manager_factory.h"
87 #include "ui/views/widget/native_widget_aura.h"
88 #include "ui/views/widget/widget.h"
90 #if !defined(OS_MACOSX)
91 #include "ash/accelerators/accelerator_controller.h"
92 #include "ash/accelerators/accelerator_filter.h"
93 #include "ash/accelerators/nested_dispatcher_controller.h"
96 #if defined(OS_CHROMEOS)
97 #include "ash/display/output_configurator_animation.h"
98 #include "base/message_pump_aurax11.h"
99 #include "chromeos/display/output_configurator.h"
100 #include "content/public/browser/gpu_data_manager.h"
101 #include "content/public/common/gpu_feature_type.h"
102 #endif // defined(OS_CHROMEOS)
111 // This dummy class is used for shell unit tests. We dont have chrome delegate
113 class DummyUserWallpaperDelegate
: public UserWallpaperDelegate
{
115 DummyUserWallpaperDelegate() {}
117 virtual ~DummyUserWallpaperDelegate() {}
119 virtual ash::WindowVisibilityAnimationType
GetAnimationType() OVERRIDE
{
120 return WINDOW_VISIBILITY_ANIMATION_TYPE_FADE
;
123 virtual void UpdateWallpaper() OVERRIDE
{
126 virtual void InitializeWallpaper() OVERRIDE
{
127 ash::Shell::GetInstance()->desktop_background_controller()->
128 CreateEmptyWallpaper();
131 virtual void OpenSetWallpaperPage() OVERRIDE
{
134 virtual bool CanOpenSetWallpaperPage() OVERRIDE
{
138 virtual void OnWallpaperAnimationFinished() OVERRIDE
{
141 virtual void OnWallpaperBootAnimationFinished() OVERRIDE
{
145 DISALLOW_COPY_AND_ASSIGN(DummyUserWallpaperDelegate
);
151 Shell
* Shell::instance_
= NULL
;
153 bool Shell::initially_hide_cursor_
= false;
155 ////////////////////////////////////////////////////////////////////////////////
158 Shell::TestApi::TestApi(Shell
* shell
) : shell_(shell
) {}
160 internal::RootWindowLayoutManager
* Shell::TestApi::root_window_layout() {
161 return shell_
->GetPrimaryRootWindowController()->root_window_layout();
164 aura::shared::InputMethodEventFilter
*
165 Shell::TestApi::input_method_event_filter() {
166 return shell_
->input_method_filter_
.get();
169 internal::SystemGestureEventFilter
*
170 Shell::TestApi::system_gesture_event_filter() {
171 return shell_
->system_gesture_filter_
.get();
174 internal::WorkspaceController
* Shell::TestApi::workspace_controller() {
175 return shell_
->GetPrimaryRootWindowController()->workspace_controller();
178 internal::ScreenPositionController
*
179 Shell::TestApi::screen_position_controller() {
180 return shell_
->screen_position_controller_
.get();
183 ////////////////////////////////////////////////////////////////////////////////
186 Shell::Shell(ShellDelegate
* delegate
)
187 : screen_(new ScreenAsh
),
188 active_root_window_(NULL
),
190 #if defined(OS_CHROMEOS)
191 output_configurator_(new chromeos::OutputConfigurator()),
192 output_configurator_animation_(
193 new internal::OutputConfiguratorAnimation()),
194 #endif // defined(OS_CHROMEOS)
195 browser_context_(NULL
),
196 simulate_modal_window_open_for_testing_(false) {
197 DCHECK(delegate_
.get());
198 ANNOTATE_LEAKING_OBJECT_PTR(screen_
); // see crbug.com/156466
199 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE
, screen_
);
200 if (!gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE
))
201 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, screen_
);
202 ui_controls::InstallUIControlsAura(internal::CreateUIControls());
203 #if defined(OS_CHROMEOS)
204 content::GpuFeatureType blacklisted_features
=
205 content::GpuDataManager::GetInstance()->GetBlacklistedFeatures();
206 bool is_panel_fitting_disabled
=
207 (blacklisted_features
& content::GPU_FEATURE_TYPE_PANEL_FITTING
) ||
208 CommandLine::ForCurrentProcess()->HasSwitch(
209 switches::kAshDisablePanelFitting
);
210 output_configurator_
->Init(!is_panel_fitting_disabled
);
212 output_configurator_
->AddObserver(output_configurator_animation_
.get());
213 base::MessagePumpAuraX11::Current()->AddDispatcherForRootWindow(
214 output_configurator());
215 #endif // defined(OS_CHROMEOS)
219 views::FocusManagerFactory::Install(NULL
);
221 // Remove the focus from any window. This will prevent overhead and side
222 // effects (e.g. crashes) from changing focus during shutdown.
223 // See bug crbug.com/134502.
224 if (active_root_window_
)
225 active_root_window_
->GetFocusManager()->SetFocusedWindow(NULL
, NULL
);
227 // Please keep in same order as in Init() because it's easy to miss one.
228 RemoveEnvEventFilter(user_activity_detector_
.get());
229 RemoveEnvEventFilter(event_rewriter_filter_
.get());
230 RemoveEnvEventFilter(overlay_filter_
.get());
231 RemoveEnvEventFilter(input_method_filter_
.get());
232 RemoveEnvEventFilter(window_modality_controller_
.get());
233 if (mouse_cursor_filter_
.get())
234 RemoveEnvEventFilter(mouse_cursor_filter_
.get());
235 RemoveEnvEventFilter(system_gesture_filter_
.get());
236 #if !defined(OS_MACOSX)
237 RemoveEnvEventFilter(accelerator_filter_
.get());
239 if (touch_observer_hud_
.get())
240 RemoveEnvEventFilter(touch_observer_hud_
.get());
242 // TooltipController is deleted with the Shell so removing its references.
243 RemoveEnvEventFilter(tooltip_controller_
.get());
245 // AppList needs to be released before shelf layout manager, which is
246 // destroyed with launcher container in the loop below. However, app list
247 // container is now on top of launcher container and released after it.
248 // TODO(xiyuan): Move it back when app list container is no longer needed.
249 app_list_controller_
.reset();
251 // Destroy SystemTrayDelegate before destroying the status area(s).
252 system_tray_delegate_
.reset();
254 // Destroy all child windows including widgets.
255 display_controller_
->CloseChildWindows();
257 // These need a valid Shell instance to clean up properly, so explicitly
258 // delete them before invalidating the instance.
260 drag_drop_controller_
.reset();
261 magnification_controller_
.reset();
262 power_button_controller_
.reset();
263 session_state_controller_
.reset();
264 resize_shadow_controller_
.reset();
265 shadow_controller_
.reset();
266 tooltip_controller_
.reset();
267 event_client_
.reset();
268 window_cycle_controller_
.reset();
269 capture_controller_
.reset();
270 nested_dispatcher_controller_
.reset();
271 user_action_client_
.reset();
272 visibility_controller_
.reset();
274 // This also deletes all RootWindows.
275 display_controller_
.reset();
276 screen_position_controller_
.reset();
278 // Delete the activation controller after other controllers and launcher
279 // because they might have registered ActivationChangeObserver.
280 activation_controller_
.reset();
282 DCHECK(instance_
== this);
285 #if defined(OS_CHROMEOS)
286 output_configurator_
->RemoveObserver(output_configurator_animation_
.get());
287 base::MessagePumpAuraX11::Current()->RemoveDispatcherForRootWindow(
288 output_configurator());
289 #endif // defined(OS_CHROMEOS)
293 Shell
* Shell::CreateInstance(ShellDelegate
* delegate
) {
295 aura::Env::GetInstance()->SetDisplayManager(
296 new internal::MultiDisplayManager());
297 instance_
= new Shell(delegate
);
303 Shell
* Shell::GetInstance() {
309 bool Shell::HasInstance() {
314 void Shell::DeleteInstance() {
320 internal::RootWindowController
* Shell::GetPrimaryRootWindowController() {
321 return GetRootWindowController(GetPrimaryRootWindow());
325 Shell::RootWindowControllerList
Shell::GetAllRootWindowControllers() {
326 return Shell::GetInstance()->display_controller()->
327 GetAllRootWindowControllers();
331 aura::RootWindow
* Shell::GetPrimaryRootWindow() {
332 return GetInstance()->display_controller()->GetPrimaryRootWindow();
336 aura::RootWindow
* Shell::GetActiveRootWindow() {
337 return GetInstance()->active_root_window_
;
341 gfx::Screen
* Shell::GetScreen() {
342 return gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE
);
346 Shell::RootWindowList
Shell::GetAllRootWindows() {
347 return Shell::GetInstance()->display_controller()->
352 aura::Window
* Shell::GetContainer(aura::RootWindow
* root_window
,
354 return root_window
->GetChildById(container_id
);
358 const aura::Window
* Shell::GetContainer(const aura::RootWindow
* root_window
,
360 return root_window
->GetChildById(container_id
);
364 std::vector
<aura::Window
*> Shell::GetAllContainers(int container_id
) {
365 std::vector
<aura::Window
*> containers
;
366 RootWindowList root_windows
= GetAllRootWindows();
367 for (RootWindowList::const_iterator it
= root_windows
.begin();
368 it
!= root_windows
.end(); ++it
) {
369 aura::Window
* container
= (*it
)->GetChildById(container_id
);
371 containers
.push_back(container
);
377 bool Shell::IsLauncherPerDisplayEnabled() {
378 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
379 return command_line
->HasSwitch(switches::kAshLauncherPerDisplay
);
383 // Install the custom factory first so that views::FocusManagers for Tray,
384 // Launcher, and WallPaper could be created by the factory.
385 views::FocusManagerFactory::Install(new AshFocusManagerFactory
);
387 env_filter_
.reset(new aura::shared::CompoundEventFilter
);
388 AddEnvEventFilter(env_filter_
.get());
390 focus_manager_
.reset(new aura::FocusManager
);
391 activation_controller_
.reset(
392 new internal::ActivationController(focus_manager_
.get()));
394 focus_cycler_
.reset(new internal::FocusCycler());
396 screen_position_controller_
.reset(new internal::ScreenPositionController
);
397 display_controller_
.reset(new DisplayController
);
398 display_controller_
->InitPrimaryDisplay();
399 aura::RootWindow
* root_window
= display_controller_
->GetPrimaryRootWindow();
400 active_root_window_
= root_window
;
402 cursor_manager_
.SetDeviceScaleFactor(
403 root_window
->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
405 #if !defined(OS_MACOSX)
406 nested_dispatcher_controller_
.reset(new NestedDispatcherController
);
407 accelerator_controller_
.reset(new AcceleratorController
);
410 // The order in which event filters are added is significant.
411 user_activity_detector_
.reset(new UserActivityDetector
);
412 AddEnvEventFilter(user_activity_detector_
.get());
414 event_rewriter_filter_
.reset(new internal::EventRewriterEventFilter
);
415 AddEnvEventFilter(event_rewriter_filter_
.get());
417 overlay_filter_
.reset(new internal::OverlayEventFilter
);
418 AddEnvEventFilter(overlay_filter_
.get());
419 AddShellObserver(overlay_filter_
.get());
421 input_method_filter_
.reset(new aura::shared::InputMethodEventFilter());
422 AddEnvEventFilter(input_method_filter_
.get());
424 #if !defined(OS_MACOSX)
425 accelerator_filter_
.reset(new internal::AcceleratorFilter
);
426 AddEnvEventFilter(accelerator_filter_
.get());
429 system_gesture_filter_
.reset(new internal::SystemGestureEventFilter
);
430 AddEnvEventFilter(system_gesture_filter_
.get());
432 capture_controller_
.reset(new internal::CaptureController
);
434 internal::RootWindowController
* root_window_controller
=
435 new internal::RootWindowController(root_window
);
436 root_window_controller
->CreateContainers();
437 root_window_controller
->CreateSystemBackground(
438 delegate_
->IsFirstRunAfterBoot());
440 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
442 if (command_line
->HasSwitch(switches::kAshTouchHud
)) {
443 touch_observer_hud_
.reset(new internal::TouchObserverHUD
);
444 AddEnvEventFilter(touch_observer_hud_
.get());
447 mouse_cursor_filter_
.reset(new internal::MouseCursorEventFilter());
448 AddEnvEventFilter(mouse_cursor_filter_
.get());
450 // Create Controllers that may need root window.
451 // TODO(oshima): Move as many controllers before creating
452 // RootWindowController as possible.
453 stacking_controller_
.reset(new internal::StackingController
);
454 visibility_controller_
.reset(new internal::VisibilityController
);
455 drag_drop_controller_
.reset(new internal::DragDropController
);
456 user_action_client_
.reset(delegate_
->CreateUserActionClient());
457 window_modality_controller_
.reset(new internal::WindowModalityController
);
458 AddEnvEventFilter(window_modality_controller_
.get());
460 magnification_controller_
.reset(
461 internal::MagnificationController::CreateInstance());
463 high_contrast_controller_
.reset(new HighContrastController
);
464 video_detector_
.reset(new VideoDetector
);
465 window_cycle_controller_
.reset(
466 new WindowCycleController(activation_controller_
.get()));
468 tooltip_controller_
.reset(new internal::TooltipController(
469 drag_drop_controller_
.get()));
470 AddEnvEventFilter(tooltip_controller_
.get());
472 event_client_
.reset(new internal::EventClientImpl
);
474 InitRootWindowController(root_window_controller
);
476 // This controller needs to be set before SetupManagedWindowMode.
477 desktop_background_controller_
.reset(new DesktopBackgroundController());
478 user_wallpaper_delegate_
.reset(delegate_
->CreateUserWallpaperDelegate());
479 if (!user_wallpaper_delegate_
.get())
480 user_wallpaper_delegate_
.reset(new DummyUserWallpaperDelegate());
482 // StatusAreaWidget uses Shell's CapsLockDelegate.
483 caps_lock_delegate_
.reset(delegate_
->CreateCapsLockDelegate());
485 if (!command_line
->HasSwitch(switches::kAuraNoShadows
)) {
486 resize_shadow_controller_
.reset(new internal::ResizeShadowController());
487 shadow_controller_
.reset(new internal::ShadowController());
490 // Initialize system_tray_delegate_ before initializing StatusAreaWidget.
491 system_tray_delegate_
.reset(delegate()->CreateSystemTrayDelegate());
492 if (!system_tray_delegate_
.get())
493 system_tray_delegate_
.reset(SystemTrayDelegate::CreateDummyDelegate());
495 // Creates StatusAreaWidget.
496 root_window_controller
->InitForPrimaryDisplay();
498 // Initialize system_tray_delegate_ after StatusAreaWidget is created.
499 system_tray_delegate_
->Initialize();
501 display_controller_
->InitSecondaryDisplays();
504 root_window_controller
->root_window_layout()->OnWindowResized();
506 // It needs to be created after OnWindowResized has been called, otherwise the
507 // widget will not paint when restoring after a browser crash. Also it needs
508 // to be created after InitSecondaryDisplays() to initialize the wallpapers in
510 user_wallpaper_delegate_
->InitializeWallpaper();
512 if (command_line
->HasSwitch(ash::switches::kAshNewLockAnimationsEnabled
))
513 session_state_controller_
.reset(new SessionStateControllerImpl2
);
515 session_state_controller_
.reset(new SessionStateControllerImpl
);
516 power_button_controller_
.reset(new PowerButtonController(
517 session_state_controller_
.get()));
518 AddShellObserver(session_state_controller_
.get());
520 if (initially_hide_cursor_
)
521 cursor_manager_
.ShowCursor(false);
523 // Cursor might have been hidden by somethign other than chrome.
524 // Let the first mouse event show the cursor.
525 env_filter_
->set_cursor_hidden_by_filter(true);
528 void Shell::AddEnvEventFilter(aura::EventFilter
* filter
) {
529 AddPreTargetHandler(filter
);
532 void Shell::RemoveEnvEventFilter(aura::EventFilter
* filter
) {
533 RemovePreTargetHandler(filter
);
536 void Shell::ShowContextMenu(const gfx::Point
& location_in_screen
) {
537 // No context menus if user have not logged in.
538 if (!delegate_
->IsUserLoggedIn())
540 // No context menus when screen is locked.
541 if (IsScreenLocked())
544 aura::RootWindow
* root
=
545 wm::GetRootWindowMatching(gfx::Rect(location_in_screen
, gfx::Size()));
546 GetRootWindowController(root
)->ShowContextMenu(location_in_screen
);
549 void Shell::ToggleAppList() {
550 if (!app_list_controller_
.get())
551 app_list_controller_
.reset(new internal::AppListController
);
552 app_list_controller_
->SetVisible(!app_list_controller_
->IsVisible());
555 bool Shell::GetAppListTargetVisibility() const {
556 return app_list_controller_
.get() &&
557 app_list_controller_
->GetTargetVisibility();
560 aura::Window
* Shell::GetAppListWindow() {
561 return app_list_controller_
.get() ? app_list_controller_
->GetWindow() : NULL
;
564 bool Shell::IsScreenLocked() const {
565 return delegate_
->IsScreenLocked();
568 bool Shell::IsModalWindowOpen() const {
569 if (simulate_modal_window_open_for_testing_
)
571 const std::vector
<aura::Window
*> containers
= GetAllContainers(
572 internal::kShellWindowId_SystemModalContainer
);
573 for (std::vector
<aura::Window
*>::const_iterator cit
= containers
.begin();
574 cit
!= containers
.end(); ++cit
) {
575 for (aura::Window::Windows::const_iterator wit
= (*cit
)->children().begin();
576 wit
!= (*cit
)->children().end(); ++wit
) {
577 if ((*wit
)->GetProperty(aura::client::kModalKey
) ==
578 ui::MODAL_TYPE_SYSTEM
&& (*wit
)->TargetVisibility()) {
586 views::NonClientFrameView
* Shell::CreateDefaultNonClientFrameView(
587 views::Widget
* widget
) {
588 if (CommandLine::ForCurrentProcess()->HasSwitch(
589 switches::kAuraGoogleDialogFrames
)) {
590 return new internal::DialogFrameView
;
592 // Use translucent-style window frames for dialogs.
593 CustomFrameViewAsh
* frame_view
= new CustomFrameViewAsh
;
594 frame_view
->Init(widget
);
598 void Shell::RotateFocus(Direction direction
) {
599 focus_cycler_
->RotateFocus(
600 direction
== FORWARD
? internal::FocusCycler::FORWARD
:
601 internal::FocusCycler::BACKWARD
);
604 void Shell::SetDisplayWorkAreaInsets(Window
* contains
,
605 const gfx::Insets
& insets
) {
606 internal::MultiDisplayManager
* display_manager
=
607 static_cast<internal::MultiDisplayManager
*>(
608 aura::Env::GetInstance()->display_manager());
609 if (!display_manager
->UpdateWorkAreaOfDisplayNearestWindow(contains
, insets
))
611 FOR_EACH_OBSERVER(ShellObserver
, observers_
,
612 OnDisplayWorkAreaInsetsChanged());
615 void Shell::OnLoginStateChanged(user::LoginStatus status
) {
616 FOR_EACH_OBSERVER(ShellObserver
, observers_
, OnLoginStateChanged(status
));
617 RootWindowControllerList controllers
= GetAllRootWindowControllers();
618 for (RootWindowControllerList::iterator iter
= controllers
.begin();
619 iter
!= controllers
.end(); ++iter
)
620 (*iter
)->OnLoginStateChanged(status
);
623 void Shell::UpdateAfterLoginStatusChange(user::LoginStatus status
) {
624 RootWindowControllerList controllers
= GetAllRootWindowControllers();
625 for (RootWindowControllerList::iterator iter
= controllers
.begin();
626 iter
!= controllers
.end(); ++iter
)
627 (*iter
)->UpdateAfterLoginStatusChange(status
);
630 void Shell::OnAppTerminating() {
631 FOR_EACH_OBSERVER(ShellObserver
, observers_
, OnAppTerminating());
634 void Shell::OnLockStateChanged(bool locked
) {
635 FOR_EACH_OBSERVER(ShellObserver
, observers_
, OnLockStateChanged(locked
));
638 void Shell::CreateLauncher() {
639 GetPrimaryRootWindowController()->CreateLauncher();
642 void Shell::ShowLauncher() {
643 GetPrimaryRootWindowController()->ShowLauncher();
646 void Shell::AddShellObserver(ShellObserver
* observer
) {
647 observers_
.AddObserver(observer
);
650 void Shell::RemoveShellObserver(ShellObserver
* observer
) {
651 observers_
.RemoveObserver(observer
);
654 void Shell::UpdateShelfVisibility() {
655 RootWindowControllerList controllers
= GetAllRootWindowControllers();
656 for (RootWindowControllerList::iterator iter
= controllers
.begin();
657 iter
!= controllers
.end(); ++iter
)
658 if ((*iter
)->shelf())
659 (*iter
)->UpdateShelfVisibility();
662 void Shell::SetShelfAutoHideBehavior(ShelfAutoHideBehavior behavior
,
663 aura::RootWindow
* root_window
) {
664 GetRootWindowController(root_window
)->SetShelfAutoHideBehavior(behavior
);
667 ShelfAutoHideBehavior
Shell::GetShelfAutoHideBehavior(
668 aura::RootWindow
* root_window
) const {
669 return GetRootWindowController(root_window
)->GetShelfAutoHideBehavior();
672 bool Shell::IsShelfAutoHideMenuHideChecked(aura::RootWindow
* root_window
) {
673 return GetRootWindowController(root_window
)->GetShelfAutoHideBehavior() ==
674 ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS
;
677 ShelfAutoHideBehavior
Shell::GetToggledShelfAutoHideBehavior(
678 aura::RootWindow
* root_window
) {
679 return GetRootWindowController(root_window
)->
680 GetToggledShelfAutoHideBehavior();
683 void Shell::SetShelfAlignment(ShelfAlignment alignment
,
684 aura::RootWindow
* root_window
) {
685 if (GetRootWindowController(root_window
)->SetShelfAlignment(alignment
))
686 FOR_EACH_OBSERVER(ShellObserver
, observers_
, OnShelfAlignmentChanged());
689 ShelfAlignment
Shell::GetShelfAlignment(aura::RootWindow
* root_window
) {
690 return GetRootWindowController(root_window
)->GetShelfAlignment();
693 void Shell::SetDimming(bool should_dim
) {
694 RootWindowControllerList controllers
= GetAllRootWindowControllers();
695 for (RootWindowControllerList::iterator iter
= controllers
.begin();
696 iter
!= controllers
.end(); ++iter
)
697 (*iter
)->screen_dimmer()->SetDimming(should_dim
);
700 void Shell::CreateModalBackground(aura::Window
* window
) {
701 if (!modality_filter_
.get()) {
702 modality_filter_
.reset(new internal::SystemModalContainerEventFilter(this));
703 AddEnvEventFilter(modality_filter_
.get());
705 RootWindowControllerList controllers
= GetAllRootWindowControllers();
706 for (RootWindowControllerList::iterator iter
= controllers
.begin();
707 iter
!= controllers
.end(); ++iter
)
708 (*iter
)->GetSystemModalLayoutManager(window
)->CreateModalBackground();
711 void Shell::OnModalWindowRemoved(aura::Window
* removed
) {
712 RootWindowControllerList controllers
= GetAllRootWindowControllers();
713 bool activated
= false;
714 for (RootWindowControllerList::iterator iter
= controllers
.begin();
715 iter
!= controllers
.end() && !activated
; ++iter
) {
716 activated
= (*iter
)->GetSystemModalLayoutManager(removed
)->
717 ActivateNextModalWindow();
720 RemoveEnvEventFilter(modality_filter_
.get());
721 modality_filter_
.reset();
722 for (RootWindowControllerList::iterator iter
= controllers
.begin();
723 iter
!= controllers
.end(); ++iter
)
724 (*iter
)->GetSystemModalLayoutManager(removed
)->DestroyModalBackground();
728 WebNotificationTray
* Shell::GetWebNotificationTray() {
729 return GetPrimaryRootWindowController()->status_area_widget()->
730 web_notification_tray();
733 internal::StatusAreaWidget
* Shell::status_area_widget() {
734 return GetPrimaryRootWindowController()->status_area_widget();
737 SystemTray
* Shell::system_tray() {
738 // We assume in throughout the code that this will not return NULL. If code
739 // triggers this for valid reasons, it should test status_area_widget first.
740 internal::StatusAreaWidget
* status_area
= status_area_widget();
742 return status_area
->system_tray();
745 void Shell::InitRootWindowForSecondaryDisplay(aura::RootWindow
* root
) {
746 root
->set_focus_manager(focus_manager_
.get());
747 internal::RootWindowController
* controller
=
748 new internal::RootWindowController(root
);
749 controller
->CreateContainers();
750 InitRootWindowController(controller
);
751 if (IsLauncherPerDisplayEnabled())
752 controller
->InitForPrimaryDisplay();
753 controller
->root_window_layout()->OnWindowResized();
754 desktop_background_controller_
->OnRootWindowAdded(root
);
755 high_contrast_controller_
->OnRootWindowAdded(root
);
756 root
->ShowRootWindow();
757 // Activate new root for testing.
758 active_root_window_
= root
;
761 void Shell::DoInitialWorkspaceAnimation() {
762 return GetPrimaryRootWindowController()->workspace_controller()->
763 DoInitialAnimation();
766 void Shell::InitRootWindowController(
767 internal::RootWindowController
* controller
) {
768 aura::RootWindow
* root_window
= controller
->root_window();
769 DCHECK(activation_controller_
.get());
770 DCHECK(visibility_controller_
.get());
771 DCHECK(drag_drop_controller_
.get());
772 DCHECK(capture_controller_
.get());
773 DCHECK(window_cycle_controller_
.get());
775 root_window
->set_focus_manager(focus_manager_
.get());
776 input_method_filter_
->SetInputMethodPropertyInRootWindow(root_window
);
777 aura::client::SetActivationClient(root_window
, activation_controller_
.get());
778 aura::client::SetVisibilityClient(root_window
, visibility_controller_
.get());
779 aura::client::SetDragDropClient(root_window
, drag_drop_controller_
.get());
780 aura::client::SetCaptureClient(root_window
, capture_controller_
.get());
781 aura::client::SetScreenPositionClient(root_window
,
782 screen_position_controller_
.get());
783 aura::client::SetCursorClient(root_window
, &cursor_manager_
);
784 aura::client::SetTooltipClient(root_window
, tooltip_controller_
.get());
785 aura::client::SetEventClient(root_window
, event_client_
.get());
787 if (nested_dispatcher_controller_
.get()) {
788 aura::client::SetDispatcherClient(root_window
,
789 nested_dispatcher_controller_
.get());
791 if (user_action_client_
.get())
792 aura::client::SetUserActionClient(root_window
, user_action_client_
.get());
794 root_window
->SetCursor(ui::kCursorPointer
);
795 controller
->InitLayoutManagers();
797 // TODO(oshima): Move the instance to RootWindowController when
798 // the extended desktop is enabled by default.
799 internal::AlwaysOnTopController
* always_on_top_controller
=
800 new internal::AlwaysOnTopController
;
801 always_on_top_controller
->SetAlwaysOnTopContainer(
802 root_window
->GetChildById(internal::kShellWindowId_AlwaysOnTopContainer
));
803 root_window
->SetProperty(internal::kAlwaysOnTopControllerKey
,
804 always_on_top_controller
);
805 if (GetPrimaryRootWindowController()->GetSystemModalLayoutManager(NULL
)->
806 has_modal_background()) {
807 controller
->GetSystemModalLayoutManager(NULL
)->CreateModalBackground();
810 window_cycle_controller_
->OnRootWindowAdded(root_window
);
813 ////////////////////////////////////////////////////////////////////////////////
816 bool Shell::CanWindowReceiveEvents(aura::Window
* window
) {
817 RootWindowControllerList controllers
= GetAllRootWindowControllers();
818 for (RootWindowControllerList::iterator iter
= controllers
.begin();
819 iter
!= controllers
.end(); ++iter
) {
820 if ((*iter
)->GetSystemModalLayoutManager(window
)->
821 CanWindowReceiveEvents(window
)) {
828 bool Shell::CanAcceptEvents() {
832 ui::EventTarget
* Shell::GetParentTarget() {