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_view.h"
15 #include "ash/desktop_background/user_wallpaper_delegate.h"
16 #include "ash/display/display_controller.h"
17 #include "ash/display/display_manager.h"
18 #include "ash/display/event_transformation_handler.h"
19 #include "ash/display/mouse_cursor_event_filter.h"
20 #include "ash/display/screen_position_controller.h"
21 #include "ash/drag_drop/drag_drop_controller.h"
22 #include "ash/focus_cycler.h"
23 #include "ash/high_contrast/high_contrast_controller.h"
24 #include "ash/host/root_window_host_factory.h"
25 #include "ash/launcher/launcher_delegate.h"
26 #include "ash/launcher/launcher_model.h"
27 #include "ash/magnifier/magnification_controller.h"
28 #include "ash/magnifier/partial_magnification_controller.h"
29 #include "ash/root_window_controller.h"
30 #include "ash/screen_ash.h"
31 #include "ash/shell_delegate.h"
32 #include "ash/shell_factory.h"
33 #include "ash/shell_window_ids.h"
34 #include "ash/system/status_area_widget.h"
35 #include "ash/system/tray/system_tray_delegate.h"
36 #include "ash/system/tray/system_tray_notifier.h"
37 #include "ash/tooltips/tooltip_controller.h"
38 #include "ash/touch/touch_observer_hud.h"
39 #include "ash/wm/activation_controller.h"
40 #include "ash/wm/always_on_top_controller.h"
41 #include "ash/wm/app_list_controller.h"
42 #include "ash/wm/ash_activation_controller.h"
43 #include "ash/wm/ash_focus_rules.h"
44 #include "ash/wm/base_layout_manager.h"
45 #include "ash/wm/capture_controller.h"
46 #include "ash/wm/coordinate_conversion.h"
47 #include "ash/wm/custom_frame_view_ash.h"
48 #include "ash/wm/event_client_impl.h"
49 #include "ash/wm/event_rewriter_event_filter.h"
50 #include "ash/wm/overlay_event_filter.h"
51 #include "ash/wm/power_button_controller.h"
52 #include "ash/wm/property_util.h"
53 #include "ash/wm/resize_shadow_controller.h"
54 #include "ash/wm/root_window_layout_manager.h"
55 #include "ash/wm/screen_dimmer.h"
56 #include "ash/wm/session_state_controller.h"
57 #include "ash/wm/session_state_controller_impl.h"
58 #include "ash/wm/session_state_controller_impl2.h"
59 #include "ash/wm/stacking_controller.h"
60 #include "ash/wm/system_gesture_event_filter.h"
61 #include "ash/wm/system_modal_container_event_filter.h"
62 #include "ash/wm/system_modal_container_layout_manager.h"
63 #include "ash/wm/user_activity_detector.h"
64 #include "ash/wm/video_detector.h"
65 #include "ash/wm/window_animations.h"
66 #include "ash/wm/window_cycle_controller.h"
67 #include "ash/wm/window_properties.h"
68 #include "ash/wm/window_util.h"
69 #include "ash/wm/workspace_controller.h"
70 #include "base/bind.h"
71 #include "base/command_line.h"
72 #include "base/debug/leak_annotations.h"
73 #include "ui/aura/client/aura_constants.h"
74 #include "ui/aura/client/stacking_client.h"
75 #include "ui/aura/client/user_action_client.h"
76 #include "ui/aura/env.h"
77 #include "ui/aura/focus_manager.h"
78 #include "ui/aura/layout_manager.h"
79 #include "ui/aura/root_window.h"
80 #include "ui/aura/window.h"
81 #include "ui/base/ui_base_switches.h"
82 #include "ui/compositor/layer.h"
83 #include "ui/compositor/layer_animator.h"
84 #include "ui/gfx/display.h"
85 #include "ui/gfx/image/image_skia.h"
86 #include "ui/gfx/screen.h"
87 #include "ui/gfx/size.h"
88 #include "ui/views/corewm/compound_event_filter.h"
89 #include "ui/views/corewm/corewm_switches.h"
90 #include "ui/views/corewm/focus_controller.h"
91 #include "ui/views/corewm/input_method_event_filter.h"
92 #include "ui/views/corewm/shadow_controller.h"
93 #include "ui/views/corewm/visibility_controller.h"
94 #include "ui/views/corewm/window_modality_controller.h"
95 #include "ui/views/focus/focus_manager_factory.h"
96 #include "ui/views/widget/native_widget_aura.h"
97 #include "ui/views/widget/widget.h"
98 #include "ui/views/window/dialog_frame_view.h"
100 #if !defined(OS_MACOSX)
101 #include "ash/accelerators/accelerator_controller.h"
102 #include "ash/accelerators/accelerator_filter.h"
103 #include "ash/accelerators/nested_dispatcher_controller.h"
106 #if defined(OS_CHROMEOS)
107 #include "ash/display/display_change_observer_x11.h"
108 #include "ash/display/output_configurator_animation.h"
109 #include "base/chromeos/chromeos_version.h"
110 #include "base/message_pump_aurax11.h"
111 #include "chromeos/display/output_configurator.h"
112 #include "content/public/browser/gpu_data_manager.h"
113 #include "content/public/common/gpu_feature_type.h"
114 #endif // defined(OS_CHROMEOS)
123 // This dummy class is used for shell unit tests. We dont have chrome delegate
125 class DummyUserWallpaperDelegate
: public UserWallpaperDelegate
{
127 DummyUserWallpaperDelegate() {}
129 virtual ~DummyUserWallpaperDelegate() {}
131 virtual int GetAnimationType() OVERRIDE
{
132 return views::corewm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE
;
135 virtual bool ShouldShowInitialAnimation() OVERRIDE
{
139 virtual void UpdateWallpaper() OVERRIDE
{
142 virtual void InitializeWallpaper() OVERRIDE
{
143 ash::Shell::GetInstance()->desktop_background_controller()->
144 CreateEmptyWallpaper();
147 virtual void OpenSetWallpaperPage() OVERRIDE
{
150 virtual bool CanOpenSetWallpaperPage() OVERRIDE
{
154 virtual void OnWallpaperAnimationFinished() OVERRIDE
{
157 virtual void OnWallpaperBootAnimationFinished() OVERRIDE
{
161 DISALLOW_COPY_AND_ASSIGN(DummyUserWallpaperDelegate
);
164 // A Corewm VisibilityController subclass that calls the Ash animation routine
165 // so we can pick up our extended animations. See ash/wm/window_animations.h.
166 class AshVisibilityController
: public views::corewm::VisibilityController
{
168 AshVisibilityController() {}
169 virtual ~AshVisibilityController() {}
172 // Overridden from views::corewm::VisibilityController:
173 virtual bool CallAnimateOnChildWindowVisibilityChanged(
174 aura::Window
* window
,
175 bool visible
) OVERRIDE
{
176 return AnimateOnChildWindowVisibilityChanged(window
, visible
);
179 DISALLOW_COPY_AND_ASSIGN(AshVisibilityController
);
185 Shell
* Shell::instance_
= NULL
;
187 bool Shell::initially_hide_cursor_
= false;
189 ////////////////////////////////////////////////////////////////////////////////
192 Shell::Shell(ShellDelegate
* delegate
)
193 : screen_(new ScreenAsh
),
194 active_root_window_(NULL
),
196 activation_client_(NULL
),
197 #if defined(OS_CHROMEOS)
198 output_configurator_(new chromeos::OutputConfigurator()),
199 output_configurator_animation_(
200 new internal::OutputConfiguratorAnimation()),
201 #endif // defined(OS_CHROMEOS)
202 browser_context_(NULL
),
203 simulate_modal_window_open_for_testing_(false) {
204 DCHECK(delegate_
.get());
205 display_manager_
.reset(new internal::DisplayManager
);
206 ANNOTATE_LEAKING_OBJECT_PTR(screen_
); // see crbug.com/156466
207 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_ALTERNATE
, screen_
);
208 if (!gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_NATIVE
))
209 gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE
, screen_
);
210 #if defined(OS_CHROMEOS)
211 content::GpuFeatureType blacklisted_features
=
212 content::GpuDataManager::GetInstance()->GetBlacklistedFeatures();
213 bool is_panel_fitting_disabled
=
214 (blacklisted_features
& content::GPU_FEATURE_TYPE_PANEL_FITTING
) ||
215 CommandLine::ForCurrentProcess()->HasSwitch(
216 switches::kAshDisablePanelFitting
);
217 output_configurator_
->Init(!is_panel_fitting_disabled
);
219 output_configurator_
->AddObserver(output_configurator_animation_
.get());
220 base::MessagePumpAuraX11::Current()->AddDispatcherForRootWindow(
221 output_configurator());
222 #endif // defined(OS_CHROMEOS)
223 AddPreTargetHandler(this);
227 views::FocusManagerFactory::Install(NULL
);
229 // Remove the focus from any window. This will prevent overhead and side
230 // effects (e.g. crashes) from changing focus during shutdown.
231 // See bug crbug.com/134502.
232 if (active_root_window_
)
233 aura::client::GetFocusClient(active_root_window_
)->FocusWindow(NULL
);
235 // Please keep in same order as in Init() because it's easy to miss one.
236 RemovePreTargetHandler(user_activity_detector_
.get());
237 RemovePreTargetHandler(event_rewriter_filter_
.get());
238 RemovePreTargetHandler(overlay_filter_
.get());
239 RemovePreTargetHandler(input_method_filter_
.get());
240 RemovePreTargetHandler(window_modality_controller_
.get());
241 if (mouse_cursor_filter_
.get())
242 RemovePreTargetHandler(mouse_cursor_filter_
.get());
243 RemovePreTargetHandler(system_gesture_filter_
.get());
244 #if !defined(OS_MACOSX)
245 RemovePreTargetHandler(accelerator_filter_
.get());
247 if (touch_observer_hud_
.get())
248 RemovePreTargetHandler(touch_observer_hud_
.get());
250 // TooltipController is deleted with the Shell so removing its references.
251 RemovePreTargetHandler(tooltip_controller_
.get());
253 // AppList needs to be released before shelf layout manager, which is
254 // destroyed with launcher container in the loop below. However, app list
255 // container is now on top of launcher container and released after it.
256 // TODO(xiyuan): Move it back when app list container is no longer needed.
257 app_list_controller_
.reset();
259 // Destroy SystemTrayDelegate before destroying the status area(s).
260 system_tray_delegate_
.reset();
262 // Destroy all child windows including widgets.
263 display_controller_
->CloseChildWindows();
265 // Destroy SystemTrayNotifier after destroying SystemTray as TrayItems
266 // needs to remove observers from it.
267 system_tray_notifier_
.reset();
269 // These need a valid Shell instance to clean up properly, so explicitly
270 // delete them before invalidating the instance.
271 // Alphabetical. TODO(oshima): sort.
272 drag_drop_controller_
.reset();
273 magnification_controller_
.reset();
274 partial_magnification_controller_
.reset();
275 resize_shadow_controller_
.reset();
276 shadow_controller_
.reset();
277 tooltip_controller_
.reset();
278 event_client_
.reset();
279 window_cycle_controller_
.reset();
280 capture_controller_
.reset();
281 nested_dispatcher_controller_
.reset();
282 user_action_client_
.reset();
283 visibility_controller_
.reset();
284 launcher_delegate_
.reset();
285 launcher_model_
.reset();
287 power_button_controller_
.reset();
288 session_state_controller_
.reset();
290 // This also deletes all RootWindows.
291 display_controller_
.reset();
292 screen_position_controller_
.reset();
294 // Delete the activation controller after other controllers and launcher
295 // because they might have registered ActivationChangeObserver.
296 activation_controller_
.reset();
298 DCHECK(instance_
== this);
301 #if defined(OS_CHROMEOS)
302 output_configurator_
->RemoveObserver(output_configurator_animation_
.get());
303 base::MessagePumpAuraX11::Current()->RemoveDispatcherForRootWindow(
304 output_configurator());
305 #endif // defined(OS_CHROMEOS)
309 Shell
* Shell::CreateInstance(ShellDelegate
* delegate
) {
311 instance_
= new Shell(delegate
);
317 Shell
* Shell::GetInstance() {
323 bool Shell::HasInstance() {
328 void Shell::DeleteInstance() {
334 internal::RootWindowController
* Shell::GetPrimaryRootWindowController() {
335 return GetRootWindowController(GetPrimaryRootWindow());
339 Shell::RootWindowControllerList
Shell::GetAllRootWindowControllers() {
340 return Shell::GetInstance()->display_controller()->
341 GetAllRootWindowControllers();
345 aura::RootWindow
* Shell::GetPrimaryRootWindow() {
346 return GetInstance()->display_controller()->GetPrimaryRootWindow();
350 aura::RootWindow
* Shell::GetActiveRootWindow() {
351 return GetInstance()->active_root_window_
;
355 gfx::Screen
* Shell::GetScreen() {
356 return gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE
);
360 Shell::RootWindowList
Shell::GetAllRootWindows() {
361 return Shell::GetInstance()->display_controller()->
366 aura::Window
* Shell::GetContainer(aura::RootWindow
* root_window
,
368 return root_window
->GetChildById(container_id
);
372 const aura::Window
* Shell::GetContainer(const aura::RootWindow
* root_window
,
374 return root_window
->GetChildById(container_id
);
378 std::vector
<aura::Window
*> Shell::GetContainersFromAllRootWindows(
380 aura::RootWindow
* priority_root
) {
381 std::vector
<aura::Window
*> containers
;
382 RootWindowList root_windows
= GetAllRootWindows();
383 for (RootWindowList::const_iterator it
= root_windows
.begin();
384 it
!= root_windows
.end(); ++it
) {
385 aura::Window
* container
= (*it
)->GetChildById(container_id
);
387 if (priority_root
&& priority_root
->Contains(container
))
388 containers
.insert(containers
.begin(), container
);
390 containers
.push_back(container
);
397 bool Shell::IsLauncherPerDisplayEnabled() {
398 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
399 return command_line
->HasSwitch(switches::kAshLauncherPerDisplay
);
403 #if defined(OS_CHROMEOS)
404 if (base::chromeos::IsRunningOnChromeOS()) {
405 display_change_observer_
.reset(new internal::DisplayChangeObserverX11
);
406 display_change_observer_
->NotifyDisplayChange();
410 // Install the custom factory first so that views::FocusManagers for Tray,
411 // Launcher, and WallPaper could be created by the factory.
412 views::FocusManagerFactory::Install(new AshFocusManagerFactory
);
414 env_filter_
.reset(new views::corewm::CompoundEventFilter
);
415 AddPreTargetHandler(env_filter_
.get());
417 if (views::corewm::UseFocusController()) {
418 views::corewm::FocusController
* focus_controller
=
419 new views::corewm::FocusController(new wm::AshFocusRules
);
420 focus_client_
.reset(focus_controller
);
421 activation_client_
= focus_controller
;
422 activation_client_
->AddObserver(this);
424 focus_client_
.reset(new aura::FocusManager
);
425 activation_controller_
.reset(
426 new internal::ActivationController(
428 new internal::AshActivationController
));
429 activation_client_
= activation_controller_
.get();
430 AddPreTargetHandler(activation_controller_
.get());
433 focus_cycler_
.reset(new internal::FocusCycler());
435 screen_position_controller_
.reset(new internal::ScreenPositionController
);
436 root_window_host_factory_
.reset(delegate_
->CreateRootWindowHostFactory());
437 display_controller_
.reset(new DisplayController
);
438 display_controller_
->InitPrimaryDisplay();
439 aura::RootWindow
* root_window
= display_controller_
->GetPrimaryRootWindow();
440 active_root_window_
= root_window
;
442 cursor_manager_
.SetDeviceScaleFactor(
443 root_window
->AsRootWindowHostDelegate()->GetDeviceScaleFactor());
445 #if !defined(OS_MACOSX)
446 nested_dispatcher_controller_
.reset(new NestedDispatcherController
);
447 accelerator_controller_
.reset(new AcceleratorController
);
450 // The order in which event filters are added is significant.
451 user_activity_detector_
.reset(new UserActivityDetector
);
452 AddPreTargetHandler(user_activity_detector_
.get());
454 event_rewriter_filter_
.reset(new internal::EventRewriterEventFilter
);
455 AddPreTargetHandler(event_rewriter_filter_
.get());
457 overlay_filter_
.reset(new internal::OverlayEventFilter
);
458 AddPreTargetHandler(overlay_filter_
.get());
459 AddShellObserver(overlay_filter_
.get());
461 input_method_filter_
.reset(new views::corewm::InputMethodEventFilter(
462 root_window
->GetAcceleratedWidget()));
463 AddPreTargetHandler(input_method_filter_
.get());
465 #if !defined(OS_MACOSX)
466 accelerator_filter_
.reset(new internal::AcceleratorFilter
);
467 AddPreTargetHandler(accelerator_filter_
.get());
470 event_transformation_handler_
.reset(new internal::EventTransformationHandler
);
471 AddPreTargetHandler(event_transformation_handler_
.get());
473 system_gesture_filter_
.reset(new internal::SystemGestureEventFilter
);
474 AddPreTargetHandler(system_gesture_filter_
.get());
476 capture_controller_
.reset(new internal::CaptureController
);
478 internal::RootWindowController
* root_window_controller
=
479 new internal::RootWindowController(root_window
);
480 root_window_controller
->CreateContainers();
481 root_window_controller
->CreateSystemBackground(
482 delegate_
->IsFirstRunAfterBoot());
484 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
486 if (command_line
->HasSwitch(ash::switches::kAshDisableNewLockAnimations
))
487 session_state_controller_
.reset(new SessionStateControllerImpl
);
489 session_state_controller_
.reset(new SessionStateControllerImpl2
);
490 power_button_controller_
.reset(new PowerButtonController(
491 session_state_controller_
.get()));
492 AddShellObserver(session_state_controller_
.get());
494 if (command_line
->HasSwitch(switches::kAshTouchHud
)) {
495 touch_observer_hud_
.reset(new internal::TouchObserverHUD
);
496 AddPreTargetHandler(touch_observer_hud_
.get());
499 mouse_cursor_filter_
.reset(new internal::MouseCursorEventFilter());
500 AddPreTargetHandler(mouse_cursor_filter_
.get());
502 // Create Controllers that may need root window.
503 // TODO(oshima): Move as many controllers before creating
504 // RootWindowController as possible.
505 stacking_client_
.reset(delegate_
->CreateStackingClient());
506 if (stacking_client_
.get())
507 aura::client::SetStackingClient(stacking_client_
.get());
508 visibility_controller_
.reset(new AshVisibilityController
);
509 drag_drop_controller_
.reset(new internal::DragDropController
);
510 user_action_client_
.reset(delegate_
->CreateUserActionClient());
511 window_modality_controller_
.reset(
512 new views::corewm::WindowModalityController
);
513 AddPreTargetHandler(window_modality_controller_
.get());
515 magnification_controller_
.reset(
516 MagnificationController::CreateInstance());
518 partial_magnification_controller_
.reset(
519 new PartialMagnificationController());
521 high_contrast_controller_
.reset(new HighContrastController
);
522 video_detector_
.reset(new VideoDetector
);
523 window_cycle_controller_
.reset(new WindowCycleController(activation_client_
));
525 tooltip_controller_
.reset(new internal::TooltipController(
526 drag_drop_controller_
.get()));
527 AddPreTargetHandler(tooltip_controller_
.get());
529 event_client_
.reset(new internal::EventClientImpl
);
531 InitRootWindowController(root_window_controller
);
533 // This controller needs to be set before SetupManagedWindowMode.
534 desktop_background_controller_
.reset(new DesktopBackgroundController());
535 user_wallpaper_delegate_
.reset(delegate_
->CreateUserWallpaperDelegate());
536 if (!user_wallpaper_delegate_
.get())
537 user_wallpaper_delegate_
.reset(new DummyUserWallpaperDelegate());
539 // StatusAreaWidget uses Shell's CapsLockDelegate.
540 caps_lock_delegate_
.reset(delegate_
->CreateCapsLockDelegate());
542 if (!command_line
->HasSwitch(switches::kAuraNoShadows
)) {
543 resize_shadow_controller_
.reset(new internal::ResizeShadowController());
544 shadow_controller_
.reset(
545 new views::corewm::ShadowController(GetPrimaryRootWindow()));
548 // Create system_tray_notifier_ before the delegate.
549 system_tray_notifier_
.reset(new ash::SystemTrayNotifier());
551 // Initialize system_tray_delegate_ before initializing StatusAreaWidget.
552 system_tray_delegate_
.reset(delegate()->CreateSystemTrayDelegate());
553 if (!system_tray_delegate_
.get())
554 system_tray_delegate_
.reset(SystemTrayDelegate::CreateDummyDelegate());
556 // Creates StatusAreaWidget.
557 root_window_controller
->InitForPrimaryDisplay();
559 // Initialize system_tray_delegate_ after StatusAreaWidget is created.
560 system_tray_delegate_
->Initialize();
562 display_controller_
->InitSecondaryDisplays();
565 root_window_controller
->root_window_layout()->OnWindowResized();
567 // It needs to be created after OnWindowResized has been called, otherwise the
568 // widget will not paint when restoring after a browser crash. Also it needs
569 // to be created after InitSecondaryDisplays() to initialize the wallpapers in
571 user_wallpaper_delegate_
->InitializeWallpaper();
573 if (initially_hide_cursor_
)
574 cursor_manager_
.DisableMouseEvents();
575 cursor_manager_
.SetCursor(ui::kCursorPointer
);
577 // Cursor might have been hidden by somethign other than chrome.
578 // Let the first mouse event show the cursor.
579 env_filter_
->set_cursor_hidden_by_filter(true);
582 void Shell::ShowContextMenu(const gfx::Point
& location_in_screen
) {
583 // No context menus if user have not logged in.
584 if (!delegate_
->IsUserLoggedIn())
586 // No context menus when screen is locked.
587 if (IsScreenLocked())
590 aura::RootWindow
* root
=
591 wm::GetRootWindowMatching(gfx::Rect(location_in_screen
, gfx::Size()));
592 // TODO(oshima): The root and root window controller shouldn't be
593 // NULL even for the out-of-bounds |location_in_screen| (It should
594 // return the primary root). Investigate why/how this is
595 // happening. crbug.com/165214.
596 internal::RootWindowController
* rwc
= GetRootWindowController(root
);
597 CHECK(rwc
) << "root=" << root
598 << ", location:" << location_in_screen
.ToString();
600 rwc
->ShowContextMenu(location_in_screen
);
603 void Shell::ToggleAppList(aura::Window
* window
) {
604 // If the context window is not given, show it on the active root window.
606 window
= GetActiveRootWindow();
607 if (!app_list_controller_
.get())
608 app_list_controller_
.reset(new internal::AppListController
);
609 app_list_controller_
->SetVisible(!app_list_controller_
->IsVisible(), window
);
612 bool Shell::GetAppListTargetVisibility() const {
613 return app_list_controller_
.get() &&
614 app_list_controller_
->GetTargetVisibility();
617 aura::Window
* Shell::GetAppListWindow() {
618 return app_list_controller_
.get() ? app_list_controller_
->GetWindow() : NULL
;
621 bool Shell::CanLockScreen() {
622 return delegate_
->CanLockScreen();
625 bool Shell::IsScreenLocked() const {
626 return delegate_
->IsScreenLocked();
629 bool Shell::IsSystemModalWindowOpen() const {
630 if (simulate_modal_window_open_for_testing_
)
632 const std::vector
<aura::Window
*> containers
= GetContainersFromAllRootWindows(
633 internal::kShellWindowId_SystemModalContainer
, NULL
);
634 for (std::vector
<aura::Window
*>::const_iterator cit
= containers
.begin();
635 cit
!= containers
.end(); ++cit
) {
636 for (aura::Window::Windows::const_iterator wit
= (*cit
)->children().begin();
637 wit
!= (*cit
)->children().end(); ++wit
) {
638 if ((*wit
)->GetProperty(aura::client::kModalKey
) ==
639 ui::MODAL_TYPE_SYSTEM
&& (*wit
)->TargetVisibility()) {
647 views::NonClientFrameView
* Shell::CreateDefaultNonClientFrameView(
648 views::Widget
* widget
) {
649 if (CommandLine::ForCurrentProcess()->HasSwitch(
650 ::switches::kEnableNewDialogStyle
)) {
651 return new views::DialogFrameView(string16());
653 // Use translucent-style window frames for dialogs.
654 CustomFrameViewAsh
* frame_view
= new CustomFrameViewAsh
;
655 frame_view
->Init(widget
);
659 void Shell::RotateFocus(Direction direction
) {
660 focus_cycler_
->RotateFocus(
661 direction
== FORWARD
? internal::FocusCycler::FORWARD
:
662 internal::FocusCycler::BACKWARD
);
665 void Shell::SetDisplayWorkAreaInsets(Window
* contains
,
666 const gfx::Insets
& insets
) {
667 if (!display_manager_
->UpdateWorkAreaOfDisplayNearestWindow(contains
, insets
))
669 FOR_EACH_OBSERVER(ShellObserver
, observers_
,
670 OnDisplayWorkAreaInsetsChanged());
673 void Shell::OnLoginStateChanged(user::LoginStatus status
) {
674 FOR_EACH_OBSERVER(ShellObserver
, observers_
, OnLoginStateChanged(status
));
675 RootWindowControllerList controllers
= GetAllRootWindowControllers();
676 for (RootWindowControllerList::iterator iter
= controllers
.begin();
677 iter
!= controllers
.end(); ++iter
)
678 (*iter
)->OnLoginStateChanged(status
);
681 void Shell::UpdateAfterLoginStatusChange(user::LoginStatus status
) {
682 RootWindowControllerList controllers
= GetAllRootWindowControllers();
683 for (RootWindowControllerList::iterator iter
= controllers
.begin();
684 iter
!= controllers
.end(); ++iter
)
685 (*iter
)->UpdateAfterLoginStatusChange(status
);
688 void Shell::OnAppTerminating() {
689 FOR_EACH_OBSERVER(ShellObserver
, observers_
, OnAppTerminating());
692 void Shell::OnLockStateChanged(bool locked
) {
693 FOR_EACH_OBSERVER(ShellObserver
, observers_
, OnLockStateChanged(locked
));
696 void Shell::CreateLauncher() {
697 if (IsLauncherPerDisplayEnabled()) {
698 RootWindowControllerList controllers
= GetAllRootWindowControllers();
699 for (RootWindowControllerList::iterator iter
= controllers
.begin();
700 iter
!= controllers
.end(); ++iter
)
701 (*iter
)->CreateLauncher();
703 GetPrimaryRootWindowController()->CreateLauncher();
707 void Shell::ShowLauncher() {
708 if (IsLauncherPerDisplayEnabled()) {
709 RootWindowControllerList controllers
= GetAllRootWindowControllers();
710 for (RootWindowControllerList::iterator iter
= controllers
.begin();
711 iter
!= controllers
.end(); ++iter
)
712 (*iter
)->ShowLauncher();
714 GetPrimaryRootWindowController()->ShowLauncher();
718 void Shell::AddShellObserver(ShellObserver
* observer
) {
719 observers_
.AddObserver(observer
);
722 void Shell::RemoveShellObserver(ShellObserver
* observer
) {
723 observers_
.RemoveObserver(observer
);
726 void Shell::UpdateShelfVisibility() {
727 RootWindowControllerList controllers
= GetAllRootWindowControllers();
728 for (RootWindowControllerList::iterator iter
= controllers
.begin();
729 iter
!= controllers
.end(); ++iter
)
730 if ((*iter
)->shelf())
731 (*iter
)->UpdateShelfVisibility();
734 void Shell::SetShelfAutoHideBehavior(ShelfAutoHideBehavior behavior
,
735 aura::RootWindow
* root_window
) {
736 GetRootWindowController(root_window
)->SetShelfAutoHideBehavior(behavior
);
739 ShelfAutoHideBehavior
Shell::GetShelfAutoHideBehavior(
740 aura::RootWindow
* root_window
) const {
741 return GetRootWindowController(root_window
)->GetShelfAutoHideBehavior();
744 void Shell::SetShelfAlignment(ShelfAlignment alignment
,
745 aura::RootWindow
* root_window
) {
746 if (GetRootWindowController(root_window
)->SetShelfAlignment(alignment
)) {
748 ShellObserver
, observers_
, OnShelfAlignmentChanged(root_window
));
752 ShelfAlignment
Shell::GetShelfAlignment(aura::RootWindow
* root_window
) {
753 return GetRootWindowController(root_window
)->GetShelfAlignment();
756 void Shell::SetDimming(bool should_dim
) {
757 RootWindowControllerList controllers
= GetAllRootWindowControllers();
758 for (RootWindowControllerList::iterator iter
= controllers
.begin();
759 iter
!= controllers
.end(); ++iter
)
760 (*iter
)->screen_dimmer()->SetDimming(should_dim
);
763 void Shell::CreateModalBackground(aura::Window
* window
) {
764 if (!modality_filter_
.get()) {
765 modality_filter_
.reset(new internal::SystemModalContainerEventFilter(this));
766 AddPreTargetHandler(modality_filter_
.get());
768 RootWindowControllerList controllers
= GetAllRootWindowControllers();
769 for (RootWindowControllerList::iterator iter
= controllers
.begin();
770 iter
!= controllers
.end(); ++iter
)
771 (*iter
)->GetSystemModalLayoutManager(window
)->CreateModalBackground();
774 void Shell::OnModalWindowRemoved(aura::Window
* removed
) {
775 RootWindowControllerList controllers
= GetAllRootWindowControllers();
776 bool activated
= false;
777 for (RootWindowControllerList::iterator iter
= controllers
.begin();
778 iter
!= controllers
.end() && !activated
; ++iter
) {
779 activated
= (*iter
)->GetSystemModalLayoutManager(removed
)->
780 ActivateNextModalWindow();
783 RemovePreTargetHandler(modality_filter_
.get());
784 modality_filter_
.reset();
785 for (RootWindowControllerList::iterator iter
= controllers
.begin();
786 iter
!= controllers
.end(); ++iter
)
787 (*iter
)->GetSystemModalLayoutManager(removed
)->DestroyModalBackground();
791 WebNotificationTray
* Shell::GetWebNotificationTray() {
792 return GetPrimaryRootWindowController()->status_area_widget()->
793 web_notification_tray();
796 bool Shell::HasPrimaryStatusArea() {
797 return !!GetPrimaryRootWindowController()->status_area_widget();
800 SystemTray
* Shell::GetPrimarySystemTray() {
801 return GetPrimaryRootWindowController()->GetSystemTray();
804 LauncherDelegate
* Shell::GetLauncherDelegate() {
805 if (!launcher_delegate_
.get()) {
806 launcher_model_
.reset(new LauncherModel
);
807 launcher_delegate_
.reset(
808 delegate_
->CreateLauncherDelegate(launcher_model_
.get()));
810 return launcher_delegate_
.get();
813 void Shell::InitRootWindowForSecondaryDisplay(aura::RootWindow
* root
) {
814 aura::client::SetFocusClient(root
, focus_client_
.get());
815 internal::RootWindowController
* controller
=
816 new internal::RootWindowController(root
);
817 controller
->CreateContainers();
818 // Pass false for the |is_first_run_after_boot| parameter so we'll show a
819 // black background on this display instead of trying to mimic the boot splash
821 controller
->CreateSystemBackground(false);
822 InitRootWindowController(controller
);
823 if (IsLauncherPerDisplayEnabled())
824 controller
->InitForPrimaryDisplay();
825 controller
->root_window_layout()->OnWindowResized();
826 desktop_background_controller_
->OnRootWindowAdded(root
);
827 high_contrast_controller_
->OnRootWindowAdded(root
);
828 root
->ShowRootWindow();
829 // Activate new root for testing.
830 active_root_window_
= root
;
833 void Shell::DoInitialWorkspaceAnimation() {
834 return GetPrimaryRootWindowController()->workspace_controller()->
835 DoInitialAnimation();
838 aura::client::StackingClient
* Shell::stacking_client() {
839 return stacking_client_
.get();
842 void Shell::InitRootWindowController(
843 internal::RootWindowController
* controller
) {
844 aura::RootWindow
* root_window
= controller
->root_window();
845 DCHECK(activation_client_
);
846 DCHECK(visibility_controller_
.get());
847 DCHECK(drag_drop_controller_
.get());
848 DCHECK(capture_controller_
.get());
849 DCHECK(window_cycle_controller_
.get());
851 aura::client::SetFocusClient(root_window
, focus_client_
.get());
852 input_method_filter_
->SetInputMethodPropertyInRootWindow(root_window
);
853 aura::client::SetActivationClient(root_window
, activation_client_
);
854 if (views::corewm::UseFocusController()) {
855 views::corewm::FocusController
* controller
=
856 static_cast<views::corewm::FocusController
*>(activation_client_
);
857 root_window
->AddPreTargetHandler(controller
);
859 aura::client::SetVisibilityClient(root_window
, visibility_controller_
.get());
860 aura::client::SetDragDropClient(root_window
, drag_drop_controller_
.get());
861 aura::client::SetCaptureClient(root_window
, capture_controller_
.get());
862 aura::client::SetScreenPositionClient(root_window
,
863 screen_position_controller_
.get());
864 aura::client::SetCursorClient(root_window
, &cursor_manager_
);
865 aura::client::SetTooltipClient(root_window
, tooltip_controller_
.get());
866 aura::client::SetEventClient(root_window
, event_client_
.get());
868 if (nested_dispatcher_controller_
.get()) {
869 aura::client::SetDispatcherClient(root_window
,
870 nested_dispatcher_controller_
.get());
872 if (user_action_client_
.get())
873 aura::client::SetUserActionClient(root_window
, user_action_client_
.get());
875 root_window
->SetCursor(ui::kCursorPointer
);
876 controller
->InitLayoutManagers();
878 // TODO(oshima): Move the instance to RootWindowController when
879 // the extended desktop is enabled by default.
880 internal::AlwaysOnTopController
* always_on_top_controller
=
881 new internal::AlwaysOnTopController
;
882 always_on_top_controller
->SetAlwaysOnTopContainer(
883 root_window
->GetChildById(internal::kShellWindowId_AlwaysOnTopContainer
));
884 root_window
->SetProperty(internal::kAlwaysOnTopControllerKey
,
885 always_on_top_controller
);
886 if (GetPrimaryRootWindowController()->GetSystemModalLayoutManager(NULL
)->
887 has_modal_background()) {
888 controller
->GetSystemModalLayoutManager(NULL
)->CreateModalBackground();
891 window_cycle_controller_
->OnRootWindowAdded(root_window
);
894 ////////////////////////////////////////////////////////////////////////////////
897 bool Shell::CanWindowReceiveEvents(aura::Window
* window
) {
898 RootWindowControllerList controllers
= GetAllRootWindowControllers();
899 for (RootWindowControllerList::iterator iter
= controllers
.begin();
900 iter
!= controllers
.end(); ++iter
) {
901 if ((*iter
)->GetSystemModalLayoutManager(window
)->
902 CanWindowReceiveEvents(window
)) {
909 ////////////////////////////////////////////////////////////////////////////////
910 // Shell, ui::EventTarget overrides:
912 bool Shell::CanAcceptEvent(const ui::Event
& event
) {
916 ui::EventTarget
* Shell::GetParentTarget() {
920 void Shell::OnEvent(ui::Event
* event
) {
923 ////////////////////////////////////////////////////////////////////////////////
924 // Shell, aura::client::ActivationChangeObserver implementation:
926 void Shell::OnWindowActivated(aura::Window
* gained_active
,
927 aura::Window
* lost_active
) {
929 active_root_window_
= gained_active
->GetRootWindow();